@parall/daemon 1.34.0 → 1.35.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.
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.34.0",
3
- "built_at": "2026-06-11T05:16:27.458Z",
2
+ "version": "1.35.0",
3
+ "built_at": "2026-06-16T06:46:33.372Z",
4
4
  "min_node_version": "20.0.0",
5
5
  "files": {
6
6
  "bb-browser-daemon.js": {
@@ -16,21 +16,21 @@
16
16
  "size": 18
17
17
  },
18
18
  "parall-claude-agent.js": {
19
- "sha256": "57d99d5cef75b55e1449f3f830f018ac421720583e5cb5c802727bd679e57095",
20
- "size": 1544820
19
+ "sha256": "cfabbba287441175296257d3dfa3a4abd41aa5ff527e40b457d9b1487f8b8b6c",
20
+ "size": 1550833
21
21
  },
22
22
  "parall-codex-agent.js": {
23
- "sha256": "602db4f45264dd2859011744d5abdb0c115fb1ca74e722d1e4b72270ef7b48fb",
24
- "size": 1575909
23
+ "sha256": "94515538d3451f141b831f5f4cab3e4fe341b8db69a5ce3d17a3e566d911da18",
24
+ "size": 1581843
25
25
  },
26
26
  "parall-daemon.js": {
27
- "sha256": "2be2ea545d7eb22366f09818e1efeb1dbc0c9c1ee23312a279738e24ad817de6",
28
- "size": 1566501
27
+ "sha256": "21d8c5150255adaac150f4b680b22bed039780686d178f6a4fe27b24a4b699db",
28
+ "size": 1597026
29
29
  },
30
30
  "parall-openclaw-agent.js": {
31
31
  "sha256": "505433b4bf3a4b8dbb7b96978d8693d6c48079f4513282ff1ee59a6d13b3eddf",
32
32
  "size": 9801
33
33
  }
34
34
  },
35
- "signature": "0Q0fz/iU46D4TzErmojSn08ldPZNYgVquvZS730veaqKBmWwqzeG5R1kx7zPF4L8mrh/EQwMEiir77n89NyTBw=="
35
+ "signature": "LxNippCuMT4fJRPgPRlVICMxw6H+ny4eWg4qEUYg2uX1VddGPyQTEv+S4U2D7c0/ssHV4T8lukamtWRXNVCsCw=="
36
36
  }
@@ -27081,6 +27081,7 @@ var ENDPOINTS = {
27081
27081
  // Org-scoped
27082
27082
  ORG: (orgId) => `${API_BASE}/orgs/${orgId}`,
27083
27083
  ORG_MEMBERS: (orgId) => `${API_BASE}/orgs/${orgId}/members`,
27084
+ TEAMS: (orgId) => `${API_BASE}/orgs/${orgId}/teams`,
27084
27085
  ORG_MEMBERS_ONLINE: (orgId) => `${API_BASE}/orgs/${orgId}/members/online`,
27085
27086
  ORG_MEMBER: (orgId, userId) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
27086
27087
  ORG_MEMBER_CHATS: (orgId, memberId) => `${API_BASE}/orgs/${orgId}/members/${memberId}/chats`,
@@ -27125,6 +27126,7 @@ var ENDPOINTS = {
27125
27126
  AGENT: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}`,
27126
27127
  AGENT_API_KEYS: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/api-keys`,
27127
27128
  AGENT_API_KEY: (orgId, agentId, key) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/api-keys/${key}`,
27129
+ AGENT_API_KEY_REGENERATE: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/api-keys/regenerate`,
27128
27130
  AGENT_AVATAR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/avatar`,
27129
27131
  AGENT_ACTIVITY: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/activity`,
27130
27132
  AGENT_MONITOR: (orgId, agentId) => `${API_BASE}/orgs/${orgId}/agents/${agentId}/monitor`,
@@ -27164,6 +27166,7 @@ var ENDPOINTS = {
27164
27166
  MACHINE_AGENT_WORKSPACE_SETUP: (orgId, machineId, agentId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/agents/${agentId}/workspace/setup`,
27165
27167
  MACHINE_LLM_SOURCE: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/llm-source`,
27166
27168
  MACHINE_PROVIDER_ENABLED: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/provider-enabled`,
27169
+ MACHINE_CAPABILITIES: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/capabilities`,
27167
27170
  MACHINE_RUNTIME_AUTH: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth`,
27168
27171
  MACHINE_KEYS: (orgId, machineId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys`,
27169
27172
  MACHINE_KEY: (orgId, machineId, keyId) => `${API_BASE}/orgs/${orgId}/machines/${machineId}/keys/${keyId}`,
@@ -27184,6 +27187,12 @@ var ENDPOINTS = {
27184
27187
  MACHINES_ME_AGENT_WORKSPACE_STATE: (agentId) => `${API_BASE}/machines/me/agents/${agentId}/workspace-state`,
27185
27188
  MACHINES_ME_WS_TICKET: `${API_BASE}/machines/me/ws/ticket`,
27186
27189
  MACHINES_ME_BROWSE_RESPONSE: (requestId) => `${API_BASE}/machines/me/browse-response/${requestId}`,
27190
+ // Hosted browser live-viewer control plane (api-server, NOT clip-service):
27191
+ // the web client drives WebRTC signaling + tab nav through VIEWER_COMMAND;
27192
+ // api-server brokers each command to the host daemon via the machine:{id}
27193
+ // request/reply bridge (mirrors filesystem browse), and the daemon replies on
27194
+ // VIEWER_RESPONSE. See docs/engineering-design/hosted-browser-provider-design.md.
27195
+ MACHINES_ME_BROWSER_PROFILE_VIEWER_RESPONSE: (requestId) => `${API_BASE}/machines/me/browser-profiles/viewer-response/${requestId}`,
27187
27196
  // Tasks (org-scoped)
27188
27197
  TASKS: (orgId) => `${API_BASE}/orgs/${orgId}/tasks`,
27189
27198
  TASK: (orgId, taskId) => `${API_BASE}/orgs/${orgId}/tasks/${taskId}`,
@@ -27249,6 +27258,9 @@ var ENDPOINTS = {
27249
27258
  // Wiki Path Scopes (AFCS ACL)
27250
27259
  WIKI_PATH_SCOPES: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/path-scopes`,
27251
27260
  WIKI_PATH_SCOPE: (orgId, wikiId, scopeId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/path-scopes/${scopeId}`,
27261
+ // Wiki Path Restrictions (AFCS narrowing ACL — private subtrees)
27262
+ WIKI_RESTRICTIONS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions`,
27263
+ WIKI_RESTRICTION: (orgId, wikiId, restrictionId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions/${restrictionId}`,
27252
27264
  WIKI_ACCESS_STATUS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
27253
27265
  WIKI_ACCESS_REQUESTS: (orgId, wikiId) => `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-requests`,
27254
27266
  // Wiki History (commits, file commits, blame)
@@ -27314,6 +27326,7 @@ var ENDPOINTS = {
27314
27326
  // Clips (org-scoped, served by clip-service)
27315
27327
  CLIPS: (orgId) => `${CLIP_BASE}/orgs/${orgId}/clips`,
27316
27328
  CLIP: (orgId, clipId) => `${CLIP_BASE}/orgs/${orgId}/clips/${clipId}`,
27329
+ CLIPS_BULK_METADATA: (orgId) => `${CLIP_BASE}/orgs/${orgId}/clips/bulk-metadata`,
27317
27330
  CLIP_AGENTS: (orgId, clipId) => `${CLIP_BASE}/orgs/${orgId}/clips/${clipId}/agents`,
27318
27331
  AGENT_CLIPS: (orgId, agentId) => `${CLIP_BASE}/orgs/${orgId}/agents/${agentId}/clips`,
27319
27332
  AGENT_CLIP: (orgId, agentId, clipId) => `${CLIP_BASE}/orgs/${orgId}/agents/${agentId}/clips/${clipId}`,
@@ -27326,6 +27339,9 @@ var ENDPOINTS = {
27326
27339
  BROWSER_PROFILE_RESET: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/reset`,
27327
27340
  BROWSER_PROFILE_CONSENTS: (orgId, profileId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/consents`,
27328
27341
  BROWSER_PROFILE_CONSENT: (orgId, profileId, clipId) => `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/consents/${clipId}`,
27342
+ // Live viewer command — on api-server (API_BASE), not clip-service: it rides
27343
+ // the machine control-plane request/reply bridge that lives in api-server.
27344
+ BROWSER_PROFILE_VIEWER_COMMAND: (orgId, profileId) => `${API_BASE}/orgs/${orgId}/browser-profiles/${profileId}/viewer/command`,
27329
27345
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
27330
27346
  CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`
27331
27347
  };
@@ -27402,6 +27418,7 @@ var WS_EVENTS = {
27402
27418
  MACHINE_CONFIG_UPDATED: "machine.config.updated",
27403
27419
  MACHINE_CLIP_SYNC: "machine.clip.sync",
27404
27420
  MACHINE_BROWSER_PROFILE_LIFECYCLE: "machine.browser_profile.lifecycle",
27421
+ MACHINE_BROWSER_PROFILE_VIEWER: "machine.browser_profile.viewer",
27405
27422
  AGENT_NEW_SESSION: "agent.new_session",
27406
27423
  CLIP_CREATED: "clip.created",
27407
27424
  CLIP_REMOVED: "clip.removed",
@@ -27553,7 +27570,10 @@ var ParallClient = class _ParallClient {
27553
27570
  method,
27554
27571
  headers,
27555
27572
  body: body ? JSON.stringify(body) : void 0,
27556
- signal
27573
+ signal,
27574
+ // keepalive lets a request fired during page unload (e.g. the browser
27575
+ // viewer's stream.close on pagehide) outlive the document.
27576
+ keepalive: opts?.keepalive
27557
27577
  });
27558
27578
  } catch (err) {
27559
27579
  throw _ParallClient.normalizeFetchError(err);
@@ -27724,6 +27744,10 @@ var ParallClient = class _ParallClient {
27724
27744
  const res = await this.request("GET", ENDPOINTS.ORG_MEMBERS(orgId));
27725
27745
  return res.data;
27726
27746
  }
27747
+ async getTeams(orgId) {
27748
+ const res = await this.request("GET", ENDPOINTS.TEAMS(orgId));
27749
+ return res.data;
27750
+ }
27727
27751
  async getOnlineMembers(orgId) {
27728
27752
  const res = await this.request("GET", ENDPOINTS.ORG_MEMBERS_ONLINE(orgId));
27729
27753
  return res.user_ids ?? [];
@@ -27962,6 +27986,10 @@ var ParallClient = class _ParallClient {
27962
27986
  async createAgentApiKey(orgId, agentId) {
27963
27987
  return this.request("POST", ENDPOINTS.AGENT_API_KEYS(orgId, agentId));
27964
27988
  }
27989
+ /** Revokes all of the agent's active API keys and mints a replacement. */
27990
+ async regenerateAgentApiKey(orgId, agentId) {
27991
+ return this.request("POST", ENDPOINTS.AGENT_API_KEY_REGENERATE(orgId, agentId));
27992
+ }
27965
27993
  async revokeAgentApiKey(orgId, agentId, key) {
27966
27994
  return this.request("DELETE", ENDPOINTS.AGENT_API_KEY(orgId, agentId, key));
27967
27995
  }
@@ -28133,6 +28161,17 @@ var ParallClient = class _ParallClient {
28133
28161
  provider_enabled: providerEnabled
28134
28162
  });
28135
28163
  }
28164
+ /**
28165
+ * Replace the machine's capability set (admin). Primary use: healing a
28166
+ * machine that registered without `browser_provider` during the capability
28167
+ * migration's rolling-deploy window. Removing `agent_host` is rejected by the
28168
+ * server while agents are attached (409 AGENTS_STILL_ATTACHED).
28169
+ */
28170
+ async patchMachineCapabilities(orgId, machineId, capabilities) {
28171
+ return this.request("PATCH", ENDPOINTS.MACHINE_CAPABILITIES(orgId, machineId), {
28172
+ capabilities
28173
+ });
28174
+ }
28136
28175
  /** Get machine-level runtime auth state. */
28137
28176
  async getMachineRuntimeAuth(orgId, machineId) {
28138
28177
  return this.request("GET", ENDPOINTS.MACHINE_RUNTIME_AUTH(orgId, machineId));
@@ -28223,6 +28262,22 @@ var ParallClient = class _ParallClient {
28223
28262
  async postBrowseResponse(requestId, response) {
28224
28263
  return this.request("POST", ENDPOINTS.MACHINES_ME_BROWSE_RESPONSE(requestId), response);
28225
28264
  }
28265
+ /**
28266
+ * `POST /machines/me/browser-profiles/viewer-response/{requestId}` — daemon
28267
+ * reply to a `machine.browser_profile.viewer` control command. Wakes the
28268
+ * api-server request/reply bridge (mirrors {@link postBrowseResponse}).
28269
+ */
28270
+ async postBrowserProfileViewerResponse(requestId, response) {
28271
+ return this.request("POST", ENDPOINTS.MACHINES_ME_BROWSER_PROFILE_VIEWER_RESPONSE(requestId), response);
28272
+ }
28273
+ /**
28274
+ * `POST /orgs/{orgId}/browser-profiles/{profileId}/viewer/command` — drive the
28275
+ * hosted browser live viewer (WebRTC signaling + tab nav). Authz: profile
28276
+ * owner or org admin. api-server brokers the command to the host daemon.
28277
+ */
28278
+ async browserViewerCommand(orgId, profileId, req, opts) {
28279
+ return this.request("POST", ENDPOINTS.BROWSER_PROFILE_VIEWER_COMMAND(orgId, profileId), req, void 0, false, opts);
28280
+ }
28226
28281
  async resizeMachine(orgId, machineId, spec) {
28227
28282
  return this.request("PATCH", ENDPOINTS.MACHINE_SPEC(orgId, machineId), spec);
28228
28283
  }
@@ -28599,6 +28654,17 @@ var ParallClient = class _ParallClient {
28599
28654
  async deleteWikiPathScope(orgId, wikiId, scopeId) {
28600
28655
  await this.request("DELETE", ENDPOINTS.WIKI_PATH_SCOPE(orgId, wikiId, scopeId));
28601
28656
  }
28657
+ // ---- Wiki Path Restrictions (narrowing ACL — private subtrees) ----
28658
+ async getWikiRestrictions(orgId, wikiId) {
28659
+ const res = await this.request("GET", ENDPOINTS.WIKI_RESTRICTIONS(orgId, wikiId));
28660
+ return res.data;
28661
+ }
28662
+ async createWikiRestriction(orgId, wikiId, data) {
28663
+ return this.request("POST", ENDPOINTS.WIKI_RESTRICTIONS(orgId, wikiId), data);
28664
+ }
28665
+ async deleteWikiRestriction(orgId, wikiId, restrictionId) {
28666
+ await this.request("DELETE", ENDPOINTS.WIKI_RESTRICTION(orgId, wikiId, restrictionId));
28667
+ }
28602
28668
  async getWikiAccessStatus(orgId, wikiId, path9) {
28603
28669
  return this.request("GET", ENDPOINTS.WIKI_ACCESS_STATUS(orgId, wikiId), void 0, path9 ? { path: path9 } : void 0);
28604
28670
  }
@@ -28761,6 +28827,10 @@ var ParallClient = class _ParallClient {
28761
28827
  async updateClip(orgId, clipId, req) {
28762
28828
  return this.request("PATCH", ENDPOINTS.CLIP(orgId, clipId), req);
28763
28829
  }
28830
+ /** Atomically set display_name and/or description on multiple clip instances (application metadata). */
28831
+ async bulkUpdateClipMetadata(orgId, req) {
28832
+ return this.request("POST", ENDPOINTS.CLIPS_BULK_METADATA(orgId), req);
28833
+ }
28764
28834
  async deleteClip(orgId, clipId) {
28765
28835
  await this.request("DELETE", ENDPOINTS.CLIP(orgId, clipId));
28766
28836
  }
@@ -30292,7 +30362,7 @@ var ParallAgentGateway = class {
30292
30362
  this.dispatchState.mainDispatching = true;
30293
30363
  void this.drainMainBuffer();
30294
30364
  }
30295
- }, 5e3);
30365
+ }, 5e3).unref();
30296
30366
  }
30297
30367
  }
30298
30368
  }
@@ -31408,132 +31478,131 @@ var PARALL_WIKI_SKILL = `# Parall Wiki
31408
31478
 
31409
31479
  Manage organization wikis via the Parall CLI. Auth is pre-configured.
31410
31480
 
31411
- ## Browsing (no local state needed)
31481
+ ## Mental model
31482
+
31483
+ Wiki editing works on a **local workspace**: \`parall wiki sync\` downloads the
31484
+ wiki into a directory on disk, you edit those files with your normal file
31485
+ tools, then \`parall wiki changeset create\` uploads the result as a proposal.
31486
+ There is no git in the workspace \u2014 your edits are detected by diffing against
31487
+ the synced baseline.
31488
+
31489
+ Key facts the commands won't tell you:
31490
+
31491
+ - **Workspace location is fixed.** Sync output and \`parall wiki status\` print
31492
+ the absolute workspace path (\`synced \u2192 /path/to/<slug>\` / \`Mount: ...\`).
31493
+ Always address wiki files by that absolute path \u2014 your shell cwd is usually
31494
+ NOT inside the workspace.
31495
+ - **Text files only.** Changesets reject binary content. Don't put images or
31496
+ archives in the workspace; binary uploads go through the web UI.
31497
+ - **\`cat\`, \`search\`, \`query\`, \`outline\`, and \`section\` read your local
31498
+ workspace copy when it exists** \u2014 including your own unproposed edits. Add
31499
+ \`--remote\` to \`cat\` to read the server version instead.
31500
+ - **\`search\`/\`query\` are keyword (lexical) matching**, not semantic search.
31501
+ \`query\` additionally ranks whole documents \u2014 better for multi-word
31502
+ questions; \`search\` for a single identifier.
31503
+ - The \`<wiki>\` argument is the slug or ID from \`parall wiki list\`; with a
31504
+ single wiki in the org it can be omitted.
31505
+
31506
+ ## Core workflow
31412
31507
 
31413
31508
  \`\`\`bash
31414
- parall wiki list # List all wikis
31415
- parall wiki tree <slug> # List files and directories
31416
- parall wiki tree <slug> --path docs/ # List a subdirectory
31509
+ parall wiki sync # 1. get/update files (prints workspace path)
31510
+ # 2. read + edit files under the workspace path with standard file tools
31511
+ parall wiki diff <wiki> # 3. review exactly what you'll propose
31512
+ parall wiki changeset create <wiki> --title "..." # 4. submit
31417
31513
  \`\`\`
31418
31514
 
31419
- ## Editing
31515
+ Always sync before starting and always check \`diff\` before proposing \u2014 the
31516
+ changeset uploads the full content of every changed file.
31420
31517
 
31421
- Wiki editing works on a **local workspace** \u2014 a directory on disk where wiki
31422
- files are synced. You sync from the server, edit files locally, then propose
31423
- a changeset.
31518
+ Unprotected paths auto-merge immediately (\`auto_merged: true\`); protected
31519
+ paths stay open for human review. Follow the returned \`next_action\` either way.
31424
31520
 
31425
- ### Step 1: Sync
31521
+ ## Stale base (server moved since your sync)
31426
31522
 
31427
- \`\`\`bash
31428
- parall wiki sync <slug>
31429
- \`\`\`
31430
-
31431
- This downloads wiki files to a local directory. The output includes the
31432
- **absolute mount path** for each wiki (e.g. \`synced \u2192 /path/to/workspace/kb\`).
31433
-
31434
- ### Step 2: Find the mount path
31435
-
31436
- The sync output JSON contains \`synced[].path\` \u2014 the absolute path where files
31437
- live. You can also check it anytime with:
31523
+ If files changed on the server after your last sync, \`changeset create\` is
31524
+ rejected \u2014 both by a CLI precheck and by the server (409 \`STALE_BASE\`) \u2014 so
31525
+ you can't silently overwrite someone's concurrent edit. Recovery:
31438
31526
 
31439
31527
  \`\`\`bash
31440
- parall wiki status <slug>
31528
+ parall wiki sync # pull latest; your local edits are preserved
31529
+ # if a file conflicts, resolve it (see next section)
31530
+ parall wiki changeset create <wiki> --title "..."
31441
31531
  \`\`\`
31442
31532
 
31443
- The output includes \`Mount: /absolute/path/to/<slug>\`.
31444
-
31445
- Use this path with \`read\`, \`write\`, and \`edit\` tools. For example, if the mount
31446
- is \`/data/.openclaw/workspace/kb\`, then \`README.md\` is at
31447
- \`/data/.openclaw/workspace/kb/README.md\`.
31533
+ ## Sync conflicts
31448
31534
 
31449
- ### Step 3: Edit files
31535
+ \`sync\` three-way merges. When both you and the server changed the same file,
31536
+ your file is left intact and the upstream copy lands under
31537
+ \`<workspace>/.parall-wiki/conflicts/\`:
31450
31538
 
31451
- Use standard file tools (\`read\`, \`write\`, \`edit\`) on files under the mount path.
31539
+ | Marker | Meaning |
31540
+ |--------|---------|
31541
+ | \`conflicts/<path>.remote\` | Server has different content for \`<path>\` |
31542
+ | \`conflicts/<path>.remote-deleted\` | Server deleted \`<path>\`; you still have edits |
31452
31543
 
31453
- ### Step 4: Review changes
31544
+ All paths below are relative to the workspace root. Pick one:
31454
31545
 
31455
31546
  \`\`\`bash
31456
- parall wiki diff <slug> # Shows unified diff of all local changes
31457
- parall wiki status <slug> # Shows which files changed with +/- line counts
31458
- \`\`\`
31547
+ # Accept upstream (drop your edit):
31548
+ cp <workspace>/.parall-wiki/conflicts/<path>.remote <workspace>/<path>
31459
31549
 
31460
- Always review before proposing.
31550
+ # Keep yours / hand-merge: edit <workspace>/<path> to final content, then
31551
+ parall wiki changeset create <wiki> --title "Reconcile <path>"
31461
31552
 
31462
- ### Step 5: Propose changeset
31463
-
31464
- \`\`\`bash
31465
- parall wiki changeset create <slug> --title "Description of changes"
31553
+ # Accept server delete (.remote-deleted only):
31554
+ rm <workspace>/<path>
31466
31555
  \`\`\`
31467
31556
 
31468
- This uploads your local changes. Unprotected paths auto-merge immediately; the
31469
- CLI prints \`auto_merged: true\` and refreshes the local manifest. Protected
31470
- paths remain as a changeset for review; follow the returned \`next_action\`.
31471
-
31472
- ## Changeset Management
31557
+ Then re-run \`parall wiki sync\` and delete the used marker file. Conflicts
31558
+ exit 0 (they need your decision); \`failed[]\` entries (download error,
31559
+ shape-conflict) exit 1 and retry on the next sync.
31473
31560
 
31474
- \`\`\`bash
31475
- parall wiki changeset list <slug> # List all changesets
31476
- parall wiki changeset show <changesetId> <slug> # Show detail + feedback
31477
- parall wiki changeset diff <changesetId> <slug> # Show changeset diff
31478
- \`\`\`
31479
-
31480
- If a changeset is rejected, fix the files locally and re-propose:
31561
+ ## Changesets
31481
31562
 
31482
31563
  \`\`\`bash
31483
- parall wiki changeset create <slug> --update <changesetId>
31564
+ parall wiki changeset list <wiki>
31565
+ parall wiki changeset show <changesetId> <wiki> # status + feedback
31566
+ parall wiki changeset diff <changesetId> <wiki>
31567
+ parall wiki changeset create <wiki> --update <id> # re-propose after rejection (title inherited)
31484
31568
  \`\`\`
31485
31569
 
31486
- The title is inherited from the original changeset \u2014 no need to repeat it.
31487
-
31488
- ## Handling sync conflicts
31489
-
31490
- \`wiki sync\` runs a three-way merge. When both you and the server changed the
31491
- same file, sync **does not overwrite your work**. It leaves your file intact
31492
- and drops the upstream version under \`.parall-wiki/conflicts/\`:
31493
-
31494
- | Marker | Meaning |
31495
- |--------|---------|
31496
- | \`.parall-wiki/conflicts/<path>.remote\` | Server has different content (concurrent edit, new file collision, or server changed a file you deleted) |
31497
- | \`.parall-wiki/conflicts/<path>.remote-deleted\` | Server deleted the file; you still have edits |
31498
-
31499
- stderr prints one line per conflict. Recovery:
31570
+ Rejected: read the feedback (\`show\` / \`status\`), fix the files, re-propose
31571
+ with \`--update <id>\`. Conflict status: \`sync\`, resolve, then \`--update <id>\`.
31500
31572
 
31501
- **Accept upstream** (drop your edit):
31502
- \`\`\`bash
31503
- cp .parall-wiki/conflicts/<path>.remote <path>
31504
- parall wiki sync
31505
- \`\`\`
31573
+ Re-propose REPLACES the changeset's previous contents with your current
31574
+ workspace diff \u2014 to withdraw a file from the proposal, revert it locally
31575
+ (restore the synced content) and re-propose; it drops out of the changeset.
31506
31576
 
31507
- **Keep yours** (or hand-merge, then propose):
31508
- \`\`\`bash
31509
- # edit <path> to final content
31510
- parall wiki diff <slug>
31511
- parall wiki changeset create <slug> --title "Reconcile <path>"
31512
- parall wiki sync # fast-forwards after server merges
31513
- \`\`\`
31577
+ ## Discovery & history
31514
31578
 
31515
- **Accept server delete** (\`.remote-deleted\` only):
31516
31579
  \`\`\`bash
31517
- rm <path>
31518
- parall wiki sync
31580
+ parall wiki query "how is auth configured" <wiki> # multi-word lookup (query FIRST, wiki second)
31581
+ parall wiki search "JWT" <wiki> # single keyword (query FIRST, wiki second)
31582
+ parall wiki outline <wiki> --path docs/ # heading structure
31583
+ parall wiki cat docs/auth.md <wiki> # print a file (--remote for server version)
31584
+ parall wiki tree <wiki> # list files
31585
+ parall wiki log <wiki> # recent operations
31586
+ parall wiki log <wiki> docs/auth.md # per-file commit history
31519
31587
  \`\`\`
31520
31588
 
31521
- Sync failures (\`download\`, \`shape-conflict\`) set exit code 1 and retry on
31522
- next sync. Conflicts exit 0 \u2014 they need your decision, not a retry.
31523
-
31524
- ## Discarding local changes
31589
+ ## Permissions
31525
31590
 
31526
- \`\`\`bash
31527
- parall wiki reset <slug> # Restore all files to last synced state
31528
- \`\`\`
31591
+ Reads and writes are ACL-checked server-side per path. \`parall wiki access
31592
+ <path>\` shows your level for a path. On a \`PERMISSION_DENIED\`, errors include
31593
+ a \`Request approval:\` hint \u2014 use \`parall wiki request-access <path> --reason
31594
+ "..."\` to file an approval card for a maintainer, then re-sync after approval.
31529
31595
 
31530
- ## History
31596
+ ## Recovery
31531
31597
 
31532
31598
  \`\`\`bash
31533
- parall wiki log <slug> # Recent wiki operations
31599
+ parall wiki reset <wiki> # discard ALL local edits, restore last-synced state
31600
+ parall wiki status <wiki> # local changes + your changesets, anytime
31534
31601
  \`\`\`
31535
31602
 
31536
- CLI success output is JSON; errors may add a plain-text \`Request approval:\` line on a \`PERMISSION_DENIED\` \u2014 read both. Run \`parall wiki --help\` for full options.
31603
+ CLI success output is JSON on stdout (human summary on stderr); errors state
31604
+ the reason and the next step \u2014 follow them. \`parall wiki --help\` for the
31605
+ full command list.
31537
31606
  `;
31538
31607
 
31539
31608
  // ts/agent-core/dist/skills/parall-schedules.js
@@ -32574,6 +32643,9 @@ function buildSpawnEnv(parentEnv, claudeHome, context2, opts) {
32574
32643
  PRLL_CONTEXT_FILE: context2.contextFilePath ?? "",
32575
32644
  PRLL_STEP_ID_FILE: context2.stepIdFilePath ?? ""
32576
32645
  };
32646
+ if (!result.PRLL_WIKI_MOUNT_ROOT?.trim() && opts.wikiMountRoot) {
32647
+ result.PRLL_WIKI_MOUNT_ROOT = opts.wikiMountRoot;
32648
+ }
32577
32649
  if (opts.effortLevel) {
32578
32650
  result.CLAUDE_CODE_EFFORT_LEVEL = opts.effortLevel;
32579
32651
  }
@@ -32880,7 +32952,11 @@ var ClaudeCodeAdapter = class {
32880
32952
  }
32881
32953
  spawnProcess(sessionKey, log2) {
32882
32954
  const args = this.buildArgs(sessionKey);
32883
- const env = buildSpawnEnv(process.env, this.opts.claudeHome, this.buildPlaceholderContext(sessionKey), { allowApiKey: this.opts.allowApiKey, effortLevel: this._effortLevel });
32955
+ const env = buildSpawnEnv(process.env, this.opts.claudeHome, this.buildPlaceholderContext(sessionKey), {
32956
+ allowApiKey: this.opts.allowApiKey,
32957
+ effortLevel: this._effortLevel,
32958
+ wikiMountRoot: this.opts.workspaceDir
32959
+ });
32884
32960
  log2?.info(`spawn long-lived ${this.opts.claudeBin} (session ${sessionKey}, model=${this._model || "default"}, effort=${this._effortLevel || "default"}, mode=${this.opts.permissionMode})`);
32885
32961
  const proc = spawn(IS_WIN32 ? quoteWin32Arg(this.opts.claudeBin) : this.opts.claudeBin, IS_WIN32 ? args.map(quoteWin32Arg) : args, {
32886
32962
  cwd: this.opts.workspaceDir,