zcode-acp-server 0.64.0 → 0.65.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -57,6 +57,7 @@ ACP editor ────── stdio ──────────┘
57
57
  | `GET /api/quota` | required | Account-level usage stats — same payload as `account/usage_stats`, no ACP connection needed. |
58
58
  | `POST /api/upgrade` | required | Trigger the hub's own staleness check — see [Hub self-upgrade](#hub-self-upgrade). |
59
59
  | `GET /api/projects` | required | Known-project list (remote session-create whitelist) — see below. |
60
+ | `GET /api/fs/list?path=` | required | One directory level for the browse-and-create flow — see [Starting a session in a new directory](#starting-a-session-in-a-new-directory). |
60
61
  | `GET /api/projects/sessions?workspacePath=` | required | A project's full session store incl. closed ones — see [Resuming a closed session](#resuming-a-closed-session). |
61
62
  | `POST /api/projects/delete {workspacePath}` | required | Soft-delete a project and all its sessions (hidden from every listing) — see [Deleting a project or session](#deleting-a-project-or-session). |
62
63
  | `POST /api/instances {workspacePath[, sessionId]}` | required | Create a bridge for one known project — a visible terminal TUI window (session-create) or one that boots into a closed session (resume, `sessionId`) — see below. |
@@ -177,6 +178,14 @@ POST {hub}/api/instances body {"workspacePath":"/Users/me/proj"}
177
178
  bound, not a security boundary: a token holder can already run any
178
179
  editor-bridge session in an arbitrary cwd; the trust boundary is the
179
180
  token itself.
181
+ - **`remote.projectRoots` widening** (bridge ≥0.65, browse-and-create): the
182
+ machine's user config may list absolute directory roots
183
+ (`"remote": {"projectRoots": ["~/Develop"]}`, `~` expanded, read live;
184
+ env fallback `ZCODE_ACP_PROJECT_ROOTS`, a `:`-separated path-list). The
185
+ POST then also accepts any existing subdirectory under a configured
186
+ root, not just known projects. Unconfigured, the known list alone stays
187
+ the whitelist. See [Starting a session in a new
188
+ directory](#starting-a-session-in-a-new-directory).
180
189
  - On create the hub incubates a VISIBLE interactive TUI (Martty) in the machine's
181
190
  terminal (ADR-0016, macOS): the project's owner gets a real local CLI
182
191
  window, and its bridge registers with the hub like any serve instance (it
@@ -212,6 +221,42 @@ POST {hub}/api/instances body {"workspacePath":"/Users/me/proj"}
212
221
  ~10 minutes after the last client detaches AND the last running turn
213
222
  finishes. Treat any vanished instance like a dead bridge.
214
223
 
224
+ ## Starting a session in a new directory
225
+
226
+ The known-project list only ever holds directories that already ran a
227
+ session. To start one somewhere new, browse the machine's directory tree
228
+ (bridge ≥0.65) and create in the picked directory — it must sit under a
229
+ configured `remote.projectRoots` root (see above):
230
+
231
+ ```text
232
+ GET {hub}/api/fs/list?path=/Users/me (path optional — default: home)
233
+ → 200 {"path":"/Users/me","parent":"/Users",
234
+ "creatable":false,
235
+ "entries":[{"name":"Develop"},{"name":"Documents"}, …],
236
+ "truncated":false}
237
+ → 400 "absolute path required" (relative path)
238
+ → 404 "directory not found" (missing path, or a file)
239
+
240
+ POST {hub}/api/instances body {"workspacePath":"/Users/me/Develop/newproj"}
241
+ → 200 {"id":"47073","reused":false} (exactly the known-project create flow)
242
+ ```
243
+
244
+ - One directory level per call; walk down via `entries[].name`, up via
245
+ `parent` (null at `/`). `path` in the answer is the RESOLVED (realpath)
246
+ spelling — navigate by it, not by what you sent (symlinks).
247
+ - Only subdirectories are listed (cap 2000; `truncated` flags the cut);
248
+ hidden (`.`-prefixed) entries ARE included — filter client-side if the
249
+ UI wants them gone.
250
+ - `creatable` tells whether a NEW session may start in the LISTED
251
+ directory itself: a known project, or under a configured project root.
252
+ With no roots configured everything still browses, but `creatable` is
253
+ true only on known projects. A create that ignores it gets the normal
254
+ 403 "unknown project".
255
+ - The create itself is the ordinary session-create flow above (visible
256
+ terminal TUI on the machine, ~20s budget). After the first session runs,
257
+ the directory enters the tasks index and appears in `GET /api/projects`
258
+ like any known project.
259
+
215
260
  ## Resuming a closed session
216
261
 
217
262
  Discovery lists only currently-running conversations. To find and reopen a
@@ -1000,6 +1045,14 @@ everything below and you get the full replay):
1000
1045
  redundant full replay on every re-entry. Null on an empty store or an
1001
1046
  id-less tail.
1002
1047
 
1048
+ A metadata-only attach (`limit 0`) is deliberately FAST over complete: the
1049
+ bridge skips the hydration settle for it, so on a freshly-resumed backend
1050
+ the meta may describe a mid-hydration PREFIX (smaller `totalMessages`,
1051
+ prefix-tail `lastMessageId`). Treat reconcile conservatively — a mismatch
1052
+ is "unknown, re-attach with a real limit"; only an exact tail-id match
1053
+ means "nothing changed". The follow-up full attach is where the settle
1054
+ runs, so it always sees the complete history.
1055
+
1003
1056
  - **`session/load_earlier`** (`{ sessionId, before, limit }`, limit defaults
1004
1057
  to 50) delivers one page of `session/update`s strictly older than `before`,
1005
1058
  oldest → newest — prepend them. Same `replayMeta` shape in the result;
package/docs/REMOTE.md CHANGED
@@ -110,7 +110,13 @@ ran a session (system temp trees, `~/.zcode` itself, and vanished
110
110
  directories filtered out), newest activity first. The list gates the POST —
111
111
  paths outside it get 403 (a convenience bound, not a security boundary: a
112
112
  token holder can already drive an editor-bridge session in any cwd; the
113
- trust boundary is the token). On create the hub incubates a VISIBLE
113
+ trust boundary is the token). The gate is WIDENED by the optional
114
+ `remote.projectRoots` config (an array of absolute directory roots, `~`
115
+ expanded, read live from the config file with the
116
+ `ZCODE_ACP_PROJECT_ROOTS` path-list as the env fallback): any existing
117
+ subdirectory under a configured root is accepted too, powering the mobile
118
+ app's browse-and-create flow. Unconfigured, the known list alone stays the
119
+ whitelist. On create the hub incubates a VISIBLE
114
120
  interactive TUI window in the machine's terminal (ADR-0016 as amended by
115
121
  ADR-0020, macOS; headless/SSH, `remote.terminal.enabled: false` in the config
116
122
  file, or `ZCODE_ACP_HUB_TERMINAL=0` falls back to the detached headless
@@ -148,6 +154,24 @@ the project's serve bridge on first listing and reuses it after. Resume is
148
154
  the normal attach flow with `session/load` on a listed backend id. See
149
155
  `docs/REMOTE-CLIENTS.md` ("Resuming a closed session") for the client contract.
150
156
 
157
+ **Directory browsing** (browse-and-create). A remote client may walk the
158
+ machine's directory tree to pick a working directory no session has used
159
+ yet:
160
+
161
+ ```text
162
+ GET /api/fs/list?path=<abs> → {path, parent, creatable, entries:[{name}], truncated}
163
+ ```
164
+
165
+ One directory level per call; an absent `path` (or `~`) lists the home dir,
166
+ the answer carries the RESOLVED (realpath) spelling. Only subdirectories
167
+ are listed (2000 cap, `truncated` flags the cut). Browsing is read-only and
168
+ unscoped — the token is the boundary, like every hub route. `creatable`
169
+ flags whether a NEW session may start in the listed directory itself: a
170
+ known project, or under a configured `remote.projectRoots` root. With no
171
+ roots configured every directory browses fine but `creatable` stays false
172
+ outside the known list. See `docs/REMOTE-CLIENTS.md` ("Starting a session
173
+ in a new directory") for the client contract.
174
+
151
175
  **Remote project/session delete** (ADR-0031). Both are soft deletes
152
176
  (tombstones in the App's tasks-index, upstream `deleteTask` semantics — the
153
177
  backend store keeps every conversation byte):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zcode-acp-server",
3
- "version": "0.64.0",
3
+ "version": "0.65.0",
4
4
  "description": "Agent Client Protocol (ACP) server bridging headless ZCode to editors like Zed and JetBrains.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",