Skip to content

Commit acb869c

Browse files
committed
feat: add full snapshots and stronger restore
1 parent 4f3784d commit acb869c

33 files changed

Lines changed: 652 additions & 84 deletions

.github/workflows/publish-python.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,12 @@ jobs:
113113
echo "::notice::Skipped PyPI upload. Configure PYPI_API_TOKEN or run this workflow with publish_to_pypi=true after setting up PyPI Trusted Publishing."
114114
115115
- name: Publish to npm registry
116-
if: ${{ env.NPM_TOKEN != '' && inputs.publish_to_npm == 'true' }}
116+
if: ${{ env.NPM_TOKEN != '' && (github.event_name == 'release' || inputs.publish_to_npm == 'true') }}
117117
run: |
118118
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
119119
npm publish dist/cc-branch-*.tgz --access public
120120
121121
- name: Report npm skip
122-
if: ${{ env.NPM_TOKEN == '' || inputs.publish_to_npm != 'true' }}
122+
if: ${{ env.NPM_TOKEN == '' || (github.event_name != 'release' && inputs.publish_to_npm != 'true') }}
123123
run: |
124-
echo "::notice::Skipped npm registry upload. Configure NPM_TOKEN and run this workflow with publish_to_npm=true to publish cc-branch to npm."
124+
echo "::notice::Skipped npm registry upload. Configure NPM_TOKEN; workflow_dispatch also requires publish_to_npm=true."

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.4.0] - 2026-06-14
9+
10+
### Added
11+
- Added file-level workspace snapshots with `cc-branch snapshot create --include-files`, restore preview file diffs, and `snapshot restore --state-only`.
12+
- Added `cc-branch session restore --session-id` and matching Web API support for binding a specific agent-native session.
13+
- Added remote agent selection to the desktop/Web SSH Add Project flow.
14+
- Added automatic npm registry publishing on GitHub release events when `NPM_TOKEN` is configured.
15+
16+
### Changed
17+
- Workspace snapshot file capture now prunes heavy runtime/build directories and enforces bounded file-size and total-size limits.
18+
819
## [1.3.0] - 2026-06-14
920

1021
### Added
@@ -62,6 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6273
- Tmux and direct-layout workspace execution, SSH targets, opener integrations, diagnostics, and local project index.
6374
- Desktop release packaging with bundled backend sidecar and GitHub release verification.
6475

76+
[1.4.0]: https://github.com/GeminiLight/cc-branch/releases/tag/v1.4.0
6577
[1.3.0]: https://github.com/GeminiLight/cc-branch/releases/tag/v1.3.0
6678
[1.1.5]: https://github.com/GeminiLight/cc-branch/releases/tag/v1.1.5
6779
[1.1.4]: https://github.com/GeminiLight/cc-branch/releases/tag/v1.1.4

apps/desktop/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@cc-branch/desktop",
33
"private": true,
4-
"version": "1.3.0",
4+
"version": "1.4.0",
55
"type": "module",
66
"scripts": {
77
"tauri": "tauri",

apps/desktop/src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/desktop/src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "cc-branch"
3-
version = "1.3.0"
3+
version = "1.4.0"
44
description = "CC Branch Desktop App"
55
authors = ["GeminiLight"]
66
license = "MIT"

apps/desktop/src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "CC Branch",
4-
"version": "1.3.0",
4+
"version": "1.4.0",
55
"identifier": "com.gemini-light.cc-branch",
66
"build": {
77
"frontendDist": "../../web/dist",

apps/package-lock.json

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@cc-branch/apps",
33
"private": true,
4-
"version": "1.3.0",
4+
"version": "1.4.0",
55
"type": "module",
66
"scripts": {
77
"dev": "cd web && npm run dev",

apps/web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@cc-branch/web",
33
"private": true,
4-
"version": "1.3.0",
4+
"version": "1.4.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

apps/web/src/api/client.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ describe("HTTPClient workspace scope", () => {
474474
const client = new HTTPClient();
475475
await client.getAgentBus({ projectPath: "/tmp/demo", target: "dev:planner" });
476476
await client.markAgentInboxRead({ projectPath: "/tmp/demo" }, "dev:planner");
477-
await client.restoreSessions({ projectPath: "/tmp/demo" });
477+
await client.restoreSessions({ projectPath: "/tmp/demo" }, { sessionId: "session-1", dryRun: true });
478478

479479
expect(fetchMock).toHaveBeenNthCalledWith(
480480
1,
@@ -496,7 +496,7 @@ describe("HTTPClient workspace scope", () => {
496496
{
497497
method: "POST",
498498
headers: { "Content-Type": "application/json" },
499-
body: "{}",
499+
body: JSON.stringify({ session_id: "session-1", dry_run: true }),
500500
},
501501
);
502502
});
@@ -535,8 +535,8 @@ describe("HTTPClient workspace scope", () => {
535535

536536
const client = new HTTPClient();
537537
await client.getSnapshots({ projectPath: "/tmp/demo" });
538-
await client.createSnapshot({ projectPath: "/tmp/demo" }, "after-change");
539-
await client.restoreSnapshot({ projectPath: "/tmp/demo" }, "snap-1");
538+
await client.createSnapshot({ projectPath: "/tmp/demo" }, "after-change", { includeFiles: true });
539+
await client.restoreSnapshot({ projectPath: "/tmp/demo" }, "snap-1", { restoreFiles: false });
540540
await client.getWorktrees({ projectPath: "/tmp/demo" });
541541
await client.setupWorktree({ projectPath: "/tmp/demo" }, { target: "dev:planner", branch: "cc-branch/dev-planner" });
542542
await client.finishWorktree({ projectPath: "/tmp/demo" }, "dev:planner");
@@ -545,11 +545,11 @@ describe("HTTPClient workspace scope", () => {
545545
expect(fetchMock).toHaveBeenNthCalledWith(1, "/api/snapshots?project_path=%2Ftmp%2Fdemo", { signal: undefined });
546546
expect(fetchMock).toHaveBeenNthCalledWith(2, "/api/snapshots/create?project_path=%2Ftmp%2Fdemo", expect.objectContaining({
547547
method: "POST",
548-
body: JSON.stringify({ name: "after-change" }),
548+
body: JSON.stringify({ name: "after-change", include_files: true }),
549549
}));
550550
expect(fetchMock).toHaveBeenNthCalledWith(3, "/api/snapshots/restore?project_path=%2Ftmp%2Fdemo", expect.objectContaining({
551551
method: "POST",
552-
body: JSON.stringify({ id: "snap-1" }),
552+
body: JSON.stringify({ id: "snap-1", restore_files: false }),
553553
}));
554554
expect(fetchMock).toHaveBeenNthCalledWith(4, "/api/worktrees?project_path=%2Ftmp%2Fdemo", { signal: undefined });
555555
expect(fetchMock).toHaveBeenNthCalledWith(5, "/api/worktrees/setup?project_path=%2Ftmp%2Fdemo", expect.objectContaining({

0 commit comments

Comments
 (0)