You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e495090
Browse filesBrowse the repository at this point in the historyBrowse files
feat(workspace): headless workspace commands and a non-interactive link (#1396)
* feat(workspace): headless `workspace` commands and a non-interactive `link`
Refresh, Sync, Unlink and status existed only in the TUI's `/workspace` menu
(and Refresh/Sync over `serve`), and `link` refused to run without a TTY, so
a setup script, devcontainer or CI job had no way to link a project or see
its state.
- `altimate-code workspace status [--json]`: linked workspace, unsynced
memory, and when skills last synced. Resolves through the service when there
is no cached row, so a fresh clone reports its server-side link.
- `altimate-code workspace refresh | sync | unlink [--yes]`: thin wrappers over
`Manage.refresh/sync/unlink`, the same code as the menu and the serve routes.
`unlink` asks on a terminal and requires `--yes` otherwise.
- `altimate-code link --workspace <name|id>` and `--create [name]` link without
prompting; replacing an existing link requires `--yes`, and a failed
pre-check stops instead of retrying a conflict as a re-link.
- Exit codes: 0 ok, 1 failed, 2 request to change (not signed in, missing
`--yes`, ambiguous name), 3 not linked. The `workspace` subcommands take
`--json` and `--directory`.
- Without a terminal, link's spinners print plain lines instead of redrawing.
- Link's "did not reach the workspace" hints now name `altimate-code
workspace sync` alongside the TUI menu.
`--shared` is not included: the create-and-bind endpoint has no privacy field,
so a CLI-created workspace stays private until shared from the web app.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fJ3X7pcGT4R9yzjsJnqsV
* test: give the trace-context MCP stub the members #1308 added
`trace-context-loop.test.ts` (#1400) stubs `MCP.Service` without `listMeta` and
`snapshot`, which #1308 added to the interface, so `tsgo` fails on main and the
pre-push typecheck blocks any branch that merges it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fJ3X7pcGT4R9yzjsJnqsV
* fix(workspace): outage is not "not linked", sanitize names, idempotent link --create, handler tests (review)
Consensus review fixes: status/refresh/sync/unlink resolve the link first (service unreachable exits 1, a confirmed unlink exits 3); sync refuses an adopted link; names stripped of control characters; unlink that leaves skills behind exits 1; `--json` ok matches exit 0; `link --create` is a no-op when already linked to that name and refuses an existing namesake unless `--allow-duplicate`; headless create does not open a browser; `workspace` recorded in telemetry; handler-level tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fJ3X7pcGT4R9yzjsJnqsV
* fix(workspace): confirm an existing link on this machine, and sync only to the verified one (review)
- `link --workspace`/`--create` for the workspace already linked records the link as confirmed here instead of returning with it still unconfirmed, so `workspace sync` accepts it
- `link`'s pre-check looks up the binding with the same captured credential as the list and the bind
- The same-name `--create` no-op runs before the workspace list is fetched, and `--allow-duplicate` skips it
- `workspace sync` passes the binding it verified to the memory sweep, which refuses an unconfirmed one, and refuses a link the service could not confirm just now (exit 1)
- `workspace unlink` of a project the service already detached still clears local workspace state
- `status` says when a "not linked" answer came from the recent-miss cache, when a link is not confirmed on this machine, and when memory could not be read (instead of "off")
- A bootstrap failure after the command already reported goes to stderr only; the directory in that message is stripped of control characters
- Docs: exit-code bullets merged; `status` details described as available when known
- Tests restore the prior `process.exitCode`
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fJ3X7pcGT4R9yzjsJnqsV
* fix(workspace): unlink never deletes on a "not linked" answer; confirm a link as the captured credential (review)
- `workspace unlink` touches nothing when the service says the project is not linked: `Manage.unlink` deletes server-side, and the answer can be a cached miss that predates a new link. Reverts the local cleanup added in the previous commit; the skill sync already takes skills out of service on a confirmed unbind
- `link` confirming an existing link derives the account from the captured credential, and a refused or failed record exits 1 instead of reporting the link as confirmed
- Tests assert the list and bind run as the captured credential too
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fJ3X7pcGT4R9yzjsJnqsV
* fix(workspace): judge a confirmed link by the row written, not the seed outcome (review)
`recordApprovedBinding` returns `account-changed` both before its write and after it, when only the memory seed was skipped. `link` now checks for an approved, non-adopted row under the captured account (`isApprovedRow`) and reports the seed outcome separately.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fJ3X7pcGT4R9yzjsJnqsV
* fix(workspace): count only the approval this `link` call wrote (review)
An approved row recorded earlier no longer vouches for a later write that was refused: `isApprovedRow` also matches the `linkedAt` this call stamped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018fJ3X7pcGT4R9yzjsJnqsV
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/docs/usage/cli.md
+6Lines changed: 6 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,6 +40,7 @@ altimate --agent analyst
40
40
|`import`| Import session data |
41
41
|`session`| Session management |
42
42
|`link`| Link this project to an Altimate workspace (pilot, requires `ALTIMATE_WORKSPACE=1`) |
43
+
|`workspace`| Show, refresh, sync or unlink this project's workspace from a shell (pilot, requires `ALTIMATE_WORKSPACE=1`) |
43
44
|`trace`| List and view session traces (recordings of agent sessions) |
44
45
|`github`| GitHub integration |
45
46
|`pr`| Pull request tools |
@@ -52,6 +53,11 @@ altimate --agent analyst
52
53
Workspace features are off unless `ALTIMATE_WORKSPACE=1` is set. With it:
53
54
54
55
-`altimate-code link` links the current project to a workspace (or creates one). The sidebar then names the workspace and shows how many memories are not yet synced and when skills last synced.
56
+
- From a shell, script or CI job, without the TUI:
57
+
-`altimate-code link --workspace <name|id>` links to an existing workspace (an id is matched before a name), and `altimate-code link --create [name]` creates one (named after the repo by default) and links to it. Neither prompts. If the project is already linked to a different workspace they refuse unless `--yes` is passed. Running `--create` again when the project is already linked to a workspace of that name creates nothing, so it is safe in a devcontainer's setup command; if another workspace already has that name it refuses and names its id, unless `--allow-duplicate` is passed. Linking to the workspace the project is already linked to confirms that link on this machine, which a fresh clone needs before `workspace sync` sends its memory.
58
+
-`altimate-code workspace status [--json]` shows the linked workspace and, when known, how many saved memories have not reached it and when skills last synced.
59
+
-`altimate-code workspace refresh` pulls the workspace's skills (memory is loaded by the next session started in the project); `altimate-code workspace sync` sends memory the workspace has not received; `altimate-code workspace unlink [--yes]` detaches the project (`--yes` is required without a terminal).
60
+
- These commands accept `--directory`. Exit codes: `0` done, `1` failed (including when the workspace service could not be reached), `2` a request to change (not signed in, a re-link or unlink without `--yes` and no terminal to confirm on, or a `sync` to a link not yet confirmed on this machine), `3` the project is not linked. With `--json`, `ok` is `true` exactly when the exit code is `0`.
55
61
-`/workspace` in the TUI opens a menu: **Refresh** pulls the workspace's skills and memory into this project, **Sync** re-sends local memory the workspace never received, **Open in browser** (when a web URL is available) shows the workspace on the web, **Switch workspace** relinks the project, **Unlink** detaches it. In a project that is not linked yet, it offers **Link to a workspace** instead.
56
62
-`altimate-code skill publish <name>` uploads a project skill to the linked workspace; see [Skills](../configure/skills.md#cli-commands).
57
63
- In an ordinary session the agent is told every turn which workspace the project is linked to — or that none is, or that the link could not be verified just now. In an extension-pinned session it is told the pinned workspace instead, and that it differs from the project's own link. Either way "which workspace am I in?" has an answer, and the agent is told not to confuse it with a Databricks workspace or an IDE workspace folder.
0 commit comments