@narumitw/pi-sync 0.57.11 → 0.57.12

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.
Files changed (71) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +27 -21
  3. package/dist/chunks/{agent-candidate-OCDPRI5G.ts → agent-candidate-U2NU3GUX.ts} +2 -2
  4. package/dist/chunks/{agent-plan-P5B5RGZ7.ts → agent-plan-3YXDIJXO.ts} +13 -10
  5. package/dist/chunks/agent-plan-3YXDIJXO.ts.map +7 -0
  6. package/dist/chunks/{agent-runner-WMSCKSCB.ts → agent-runner-FCRV2Z75.ts} +11 -10
  7. package/dist/chunks/agent-runner-FCRV2Z75.ts.map +7 -0
  8. package/dist/chunks/{agent-store-RJSMNOYP.ts → agent-store-7GINKTS7.ts} +2 -2
  9. package/dist/chunks/{agent-store-RJSMNOYP.ts.map → agent-store-7GINKTS7.ts.map} +2 -2
  10. package/dist/chunks/{agent-sync-EUK2CPSS.ts → agent-sync-P6AWQXGK.ts} +2 -2
  11. package/dist/chunks/{chunk-67INJPKR.ts → chunk-CQD2TJHE.ts} +4 -4
  12. package/dist/chunks/{chunk-67INJPKR.ts.map → chunk-CQD2TJHE.ts.map} +2 -2
  13. package/dist/chunks/{chunk-7OLLPPLU.ts → chunk-MMQIEDZ6.ts} +6 -6
  14. package/dist/chunks/{chunk-7OLLPPLU.ts.map → chunk-MMQIEDZ6.ts.map} +2 -2
  15. package/dist/chunks/{chunk-NLWS55B6.ts → chunk-QPC5HT3A.ts} +2 -2
  16. package/dist/chunks/{chunk-NLWS55B6.ts.map → chunk-QPC5HT3A.ts.map} +1 -1
  17. package/dist/chunks/{chunk-DRTC4PKM.ts → chunk-S5OCYVPS.ts} +2 -2
  18. package/dist/chunks/{chunk-DRTC4PKM.ts.map → chunk-S5OCYVPS.ts.map} +2 -2
  19. package/dist/chunks/{chunk-3IYAPMST.ts → chunk-U6GXGY5G.ts} +2 -2
  20. package/dist/chunks/{chunk-CPT2BN6N.ts → chunk-XEODG2PE.ts} +2 -2
  21. package/dist/chunks/{chunk-F7E3VFXU.ts → chunk-ZC3IHFNM.ts} +6 -6
  22. package/dist/chunks/{chunk-F7E3VFXU.ts.map → chunk-ZC3IHFNM.ts.map} +2 -2
  23. package/dist/chunks/{command-handler-F2E7A5T5.ts → command-handler-VKLZBRLO.ts} +9 -9
  24. package/dist/chunks/{command-handler-F2E7A5T5.ts.map → command-handler-VKLZBRLO.ts.map} +2 -2
  25. package/dist/chunks/{conflict-review-2QMO2K6Q.ts → conflict-review-GXA6Y7KY.ts} +2 -2
  26. package/dist/chunks/{continuous-record-AH7JGYKM.ts → continuous-record-EPHGR2DU.ts} +2 -2
  27. package/dist/chunks/{continuous-sync-VRMXCA5X.ts → continuous-sync-TTOSJCQU.ts} +3 -3
  28. package/dist/chunks/{manager-ui-LM7DSJ2Y.ts → manager-ui-INVMAFEN.ts} +146 -176
  29. package/dist/chunks/manager-ui-INVMAFEN.ts.map +7 -0
  30. package/dist/chunks/{setup-switch-PIPXYPCW.ts → setup-switch-KLGESLQX.ts} +3 -3
  31. package/dist/chunks/{setup-wizard-RR5U3SUB.ts → setup-wizard-ZQAK35BP.ts} +3 -3
  32. package/dist/chunks/{sync-operations-CV3TULLD.ts → sync-operations-TMGQHBF5.ts} +4 -4
  33. package/dist/chunks/{sync-operations-CV3TULLD.ts.map → sync-operations-TMGQHBF5.ts.map} +2 -2
  34. package/dist/index.ts +6 -6
  35. package/docs/agent-continuous-hardening.md +5 -5
  36. package/docs/agent-mode-verification.md +3 -3
  37. package/docs/agent-quality-verification.md +3 -3
  38. package/docs/continuous-sync-verification.md +2 -2
  39. package/docs/settings.md +9 -5
  40. package/docs/tui-contract.md +20 -3
  41. package/package.json +3 -3
  42. package/skills/configure-pi-sync/SKILL.md +3 -1
  43. package/skills/configure-pi-sync/references/configuration.md +48 -37
  44. package/src/commands/command-execution.ts +3 -3
  45. package/src/commands/command.ts +1 -1
  46. package/src/settings/settings-types.ts +1 -1
  47. package/src/sync/agent-candidate.ts +3 -3
  48. package/src/sync/agent-plan.ts +11 -8
  49. package/src/sync/agent-runner.ts +10 -9
  50. package/src/sync/agent-store.ts +1 -1
  51. package/src/sync/agent-sync.ts +2 -2
  52. package/src/sync/continuous-record.ts +1 -1
  53. package/src/sync/merged-sync.ts +4 -4
  54. package/src/sync/sync-mutations.ts +1 -1
  55. package/src/ui/agent-mode-setting.ts +6 -6
  56. package/src/ui/manager-state.ts +1 -1
  57. package/src/ui/settings-ui.ts +19 -55
  58. package/src/ui/setup/setup-switcher.ts +2 -2
  59. package/src/ui/sync-setups-ui.ts +2 -2
  60. package/dist/chunks/agent-plan-P5B5RGZ7.ts.map +0 -7
  61. package/dist/chunks/agent-runner-WMSCKSCB.ts.map +0 -7
  62. package/dist/chunks/manager-ui-LM7DSJ2Y.ts.map +0 -7
  63. /package/dist/chunks/{agent-candidate-OCDPRI5G.ts.map → agent-candidate-U2NU3GUX.ts.map} +0 -0
  64. /package/dist/chunks/{agent-sync-EUK2CPSS.ts.map → agent-sync-P6AWQXGK.ts.map} +0 -0
  65. /package/dist/chunks/{chunk-3IYAPMST.ts.map → chunk-U6GXGY5G.ts.map} +0 -0
  66. /package/dist/chunks/{chunk-CPT2BN6N.ts.map → chunk-XEODG2PE.ts.map} +0 -0
  67. /package/dist/chunks/{conflict-review-2QMO2K6Q.ts.map → conflict-review-GXA6Y7KY.ts.map} +0 -0
  68. /package/dist/chunks/{continuous-record-AH7JGYKM.ts.map → continuous-record-EPHGR2DU.ts.map} +0 -0
  69. /package/dist/chunks/{continuous-sync-VRMXCA5X.ts.map → continuous-sync-TTOSJCQU.ts.map} +0 -0
  70. /package/dist/chunks/{setup-switch-PIPXYPCW.ts.map → setup-switch-KLGESLQX.ts.map} +0 -0
  71. /package/dist/chunks/{setup-wizard-RR5U3SUB.ts.map → setup-wizard-ZQAK35BP.ts.map} +0 -0
@@ -15,7 +15,7 @@ This skill provides guidance only, even when the request asks you to apply a cha
15
15
  Read the relevant headings in the [settings reference](references/configuration.md), not the user's private settings file.
16
16
  Use **Settings ownership and required fields**, **Complete version 3 example**, and **Required backend shapes** for schema, backend, and destination questions.
17
17
  Use **Included content** for path selection and session privacy.
18
- Use **Required backend shapes**, **Automatic startup transfer**, **Experimental Agent mode**, and **Experimental Continuous sync** to distinguish automatic controls.
18
+ Use **Required backend shapes**, **Automatic startup transfer**, **Autonomous sync**, and **Continuous sync** to distinguish automatic controls.
19
19
  Use **Settings field merge and machine-local fields** and **Content merge and partial progress** for versions 4 and 5.
20
20
  Use **Diagnostics** and **Unsupported old settings and recovery** for diagnostic side effects and recovery boundaries.
21
21
  If the reference does not establish an answer, state the missing evidence instead of inventing a field, default, migration, or compatibility guarantee.
@@ -34,6 +34,8 @@ These are instruction limits, not an OS sandbox or a guarantee that the agent ca
34
34
 
35
35
  For a question, give the supported setting name, scope, accepted value, default when applicable, and material effect from the reference.
36
36
  Do not equate `sync.automatic`, `sync.automaticTransfer`, `sync.agentMode`, and `sync.continuous`.
37
+ Map Autonomous sync to the unchanged `sync.agentMode` key.
38
+ Explain its authorization for eligible startup and Sync now transfers without another transfer confirmation before its model assistance for supported conflicts.
37
39
 
38
40
  For setup or a requested edit, explain that this skill cannot apply it and identify the corresponding `/sync` manager action for the user.
39
41
  Ask at most one question at a time when the backend, destination, or included content is not sufficiently clear.
@@ -7,8 +7,8 @@ The configuration skill provides guidance only; the user performs settings chang
7
7
  - [Required backend shapes](#required-backend-shapes)
8
8
  - [Status display](#status-display)
9
9
  - [Secret scanning](#secret-scanning)
10
- - [Experimental Agent mode](#experimental-agent-mode)
11
- - [Experimental Continuous sync](#experimental-continuous-sync)
10
+ - [Autonomous sync](#autonomous-sync)
11
+ - [Continuous sync](#continuous-sync)
12
12
  - [Included content](#included-content)
13
13
  - [Unsupported old settings and recovery](#unsupported-old-settings-and-recovery)
14
14
 
@@ -55,14 +55,20 @@ Global settings apply to all setups on this device; they are not remote policy.
55
55
  | Content/partial policy | `sync.mergeContent`, `sync.partialSync` | Enabling either requires version 5. |
56
56
 
57
57
  Do not downgrade version 4 or 5 merely because an option is turned off.
58
- The four automatic controls have separate effects: `automatic` enables startup observation and selected-content shutdown pushes when sessions are included; `automaticTransfer` enables one eligible startup transfer; `agentMode` authorizes autonomous merged sync and model disclosure; `continuous` adds recurring work only with Agent mode enabled.
58
+ The four automatic controls have separate effects:
59
+
60
+ - **Automatic sync** (`sync.automatic`) enables startup observation and selected-content shutdown pushes when sessions are included.
61
+ - **Startup transfer** (`sync.automaticTransfer`) enables one eligible startup transfer.
62
+ - **Autonomous sync** (`sync.agentMode`, unchanged) authorizes eligible startup and **Sync now** transfers without another transfer confirmation, plus model assistance and disclosure for supported conflicts.
63
+ - **Continuous sync** (`sync.continuous`) adds recurring work only with Autonomous sync enabled.
64
+
59
65
  None of these controls is enabled by invoking the configuration skill.
60
66
 
61
67
  ### Editing in the manager
62
68
 
63
- Open `/sync` → **Settings** and choose **Sync content**, **Sync behavior**, **Storage & setups**, or **Advanced**.
64
- **All settings (search)** provides cross-category typing-to-search over the same rows.
65
- **Included paths** and **Compare included paths** are adjacent in Sync content; the latter compares path policies, not file contents.
69
+ Open `/sync` → **Settings** to go directly to **Pi Sync Settings**.
70
+ The screen has one searchable flat list with all 16 rows in their existing order and no category navigation or headings.
71
+ **Included paths** and **Compare included paths** are adjacent; the latter compares path policies, not file contents.
66
72
  **Storage location** edits the current setup's coordinates, while **Manage sync setups** and **Manage storage connections** retain the catalog and affected-setup reviews.
67
73
  Returning from catalog management refreshes the rows; switching or removing the owning setup closes its old Settings screen.
68
74
 
@@ -70,7 +76,7 @@ Descriptions identify the owner: this setup, all setups on this device, or share
70
76
  Simple choices report Saving and the durable Saved or failed/rejected result, preserve the selected row and search during refresh, and restore their previous value if saving fails.
71
77
  Escape closes the screen without undoing successful saves.
72
78
  Complex values retain their input/review flows.
73
- This navigation change does not alter schema, defaults, automatic-sync behavior, or experimental opt-ins.
79
+ This navigation change does not alter schema, defaults, automatic-sync behavior, or explicit opt-ins.
74
80
 
75
81
  The manager separates current state from transfer, inspection, and management actions.
76
82
  **Check remote status** and **View differences** invoke the existing read/check routes only when selected.
@@ -179,7 +185,7 @@ This check does not contact the server or discover setups configured only on oth
179
185
  Every setup requires `sync.include` and explicit `sync.automatic`.
180
186
  Setup asks for automatic sync with Off first; existing values are not rewritten.
181
187
  When enabled, the current setup receives one background startup check in TUI/RPC, including reload/new/resume/fork.
182
- Startup no longer performs automatic transfers or opens dialogs; review changes through `/sync`.
188
+ Automatic sync alone does not perform startup transfers or open dialogs; review changes through `/sync`.
183
189
  Print/JSON skip startup checks.
184
190
  Checks compare local hashes and remote metadata against the last sync baseline, so revision changes and missing baselines require review rather than proving a file conflict.
185
191
 
@@ -219,14 +225,14 @@ It accepts:
219
225
  ### Status display
220
226
 
221
227
  The global `showStatus` setting accepts a boolean and defaults to `true` when omitted from an existing version 3 document.
222
- Set it through **/sync → Settings → Advanced → Show sync status**; changes are saved and applied immediately for every setup.
228
+ Set it through **/sync → Settings → Show sync status**; changes are saved and applied immediately for every setup.
223
229
  When `false`, pi-sync clears and suppresses status text for background checks, manual and automatic transfers, and review attention.
224
230
  TUI review widgets and TUI/RPC notifications remain available, and lifecycle cleanup still clears any stale status owned by pi-sync.
225
231
 
226
232
  ### Debug startup timings
227
233
 
228
234
  The top-level user setting `debug` accepts only `true` or `false` and defaults to `false`.
229
- Edit `<getAgentDir()>/pi-sync.json` (normally `~/.pi/agent/pi-sync.json`) or use **/sync → Settings → Advanced → Debug startup timings**.
235
+ Edit `<getAgentDir()>/pi-sync.json` (normally `~/.pi/agent/pi-sync.json`) or use **/sync → Settings → Debug startup timings**.
230
236
  UI changes save immediately through the existing ordered, atomic settings writer; both manual and UI changes take effect on the next session start, including `/reload`, new, resume, and fork.
231
237
  There is no project or environment override.
232
238
 
@@ -255,7 +261,7 @@ Set `debug` to `false` or remove it, then start a new session to disable reports
255
261
  ### Secret scanning
256
262
 
257
263
  The global `skipSecretScan` setting accepts a boolean and defaults to `false`, including when omitted from an existing version 3 document.
258
- Set it through **/sync → Settings → Advanced → Skip secret scan**; changes are saved immediately and apply to subsequent pushes for every sync setup, including automatic pushes.
264
+ Set it through **/sync → Settings → Skip secret scan**; changes are saved immediately and apply to subsequent pushes for every sync setup, including automatic pushes.
259
265
  When `true`, pushes skip the local secret scan; other safety checks and confirmations remain unchanged.
260
266
  Enable it only after reviewing the destination and selected content because files containing secrets can be uploaded.
261
267
  `/sync doctor` still scans and reports possible secrets regardless of this setting.
@@ -295,7 +301,7 @@ RPC remains a read-only summary with the manual `sync.include` path.
295
301
 
296
302
  Every new snapshot stores the normalized included-content selection separately from the files that happened to exist.
297
303
  This preserves selected-but-missing paths without syncing `pi-sync.json`, storage credentials, automatic-sync preferences, or setup names.
298
- **Settings → Sync content → Compare included paths** opens the same review-first flow as a manager operation when local and remote lists differ.
304
+ **Settings → Compare included paths** opens the same review-first flow as a manager operation when local and remote lists differ.
299
305
  Adoption revalidates the remote head, immutable snapshot, and complete reviewed setup configuration, including the shared connection and credentials, before one atomic settings update.
300
306
  Cancelling the network check leaves the content list unchanged.
301
307
  A settings save that has started its atomic replacement can still finish; later cancellation does not undo it.
@@ -317,7 +323,7 @@ Pull protects the currently open session file; restart Pi or resume a pulled ses
317
323
  ### Automatic startup transfer
318
324
 
319
325
  `sync.automaticTransfer` is optional and accepts only a boolean; absent means `false`.
320
- Set it through **/sync → Settings → Sync behavior → Startup transfer**.
326
+ Set it through **/sync → Settings → Startup transfer**.
321
327
  It is separate from `sync.automatic`: the legacy setting retains observation and selected-content shutdown behavior.
322
328
 
323
329
  When explicitly enabled, one startup transfer waits for an idle boundary in TUI/RPC.
@@ -345,27 +351,30 @@ Turning **Startup transfer** off does not revert transfers or remove backups/jou
345
351
  For interrupted operations, follow [merge recovery](https://github.com/narumiruna/pi-extensions/blob/main/packages/pi-sync/docs/merge-implementation-audit.md).
346
352
  Unknown fields remain preserved and malformed/invalid files block saves, just as for the existing policy.
347
353
 
348
- ### Experimental Agent mode
354
+ <a id="experimental-agent-mode"></a>
349
355
 
350
- `sync.agentMode` is an optional per-setup boolean, default `false`, in settings versions 3, 4, and 5.
351
- Open **Settings → Sync behavior → Agent mode (experimental)** and review the setup, destination, selected paths, model disclosure, costs, and autonomous writes before enabling.
356
+ ### Autonomous sync
357
+
358
+ Autonomous sync uses the unchanged `sync.agentMode` key, an optional per-setup boolean, default `false`, in settings versions 3, 4, and 5.
359
+ Open **Settings → Autonomous sync** and review the setup, destination, selected paths, transfer authorization, model disclosure, costs, and autonomous writes before enabling.
352
360
  RPC users can explicitly set the same field in the private settings file.
353
361
  Setting it to `true` is authorization, not just a display preference.
354
362
 
355
- Agent mode authorizes one eligible merged sync at the next session start and the same autonomous flow from **Sync now** or `/sync sync`.
356
- It can publish and replace/delete selected content without another transfer confirmation.
363
+ Autonomous sync authorizes one eligible merged sync at the next session startup and the same flow from **Sync now** or `/sync sync`, without another transfer confirmation.
364
+ It can publish, replace, or delete selected local and remote content.
365
+ The selected Pi model resolves supported text and settings conflicts; eligible conflict content is sent to its provider and may incur costs.
357
366
  It is independent of `sync.automatic` and `sync.automaticTransfer`; neither existing preference is changed.
358
- Disabling Startup transfer alone does not disable Agent mode.
367
+ Disabling Startup transfer alone does not disable Autonomous sync.
359
368
  Saving never starts a transfer from Settings.
360
369
  The atomic write cannot be cancelled after its final cancellation check.
361
370
  A completed save remains in effect after cancellation or session replacement; reopen Settings to read the saved value.
362
371
  TUI/RPC are supported; print/JSON and shutdown do not start a resolver.
363
- Agent mode alone adds no polling or daemon.
372
+ Autonomous sync alone adds no polling or daemon.
364
373
  Separately enabled Continuous sync provides recurring work while Pi remains open.
365
374
 
366
375
  An accepted baseline, matching included-content/local-field policies, and conditional or lease-protected publication remain required.
367
376
  First-source selection, policy migrations, explicit push/pull, and rollback keep their existing reviewed flows.
368
- `--yes` does not enable Agent mode or authorize model disclosure.
377
+ `--yes` does not enable Autonomous sync or authorize model disclosure.
369
378
  Completed transfers never reload resources automatically.
370
379
 
371
380
  The resolver uses the initiating session's selected model through Pi's public provider/authentication registry.
@@ -378,14 +387,14 @@ Parent model prompts and tools are not changed.
378
387
  This is configuration isolation, not an OS sandbox or proof of semantic correctness.
379
388
 
380
389
  Eligible text is global `AGENTS.md` and `.md`/`.txt` files under `prompts/` or `skills/`.
381
- Global `settings.json` uses the existing strict JSON, numeric, coupled-field, unknown-field, and machine-local-field policies. In Agent mode, `packages` merges by source identity and selects the higher explicit SemVer version for each npm package present on both sides, even when one side has not changed from the verified ancestor. No registry lookup occurs. Equal SemVer precedence does not select a winner: one-sided source edits are preserved, and divergent edits require atomic selection. Package filters must match. An existing local or remote array keeps its JSON spelling when it matches the merged result. Accepted settings files keep their bytes unless a package override is required; that override changes only the `packages` value. The ordered npm identity list can change on one side, or identically on both sides; conflicting order or membership changes retain atomic selection. This preserves insertion positions and resource precedence. Non-npm entries must remain unchanged across all three versions for per-package merging. Changed Git refs and local path aliases retain atomic selection instead of being combined as separate sources. Delete/upgrade conflicts, duplicate identities, incompatible filters, version ranges and tags also retain the existing atomic selection rules when deterministic merging is not possible. Other arrays and nested objects remain atomic.
390
+ Global `settings.json` uses the existing strict JSON, numeric, coupled-field, unknown-field, and machine-local-field policies. With Autonomous sync enabled, `packages` merges by source identity and selects the higher explicit SemVer version for each npm package present on both sides, even when one side has not changed from the verified ancestor. No registry lookup occurs. Equal SemVer precedence does not select a winner: one-sided source edits are preserved, and divergent edits require atomic selection. Package filters must match. An existing local or remote array keeps its JSON spelling when it matches the merged result. Accepted settings files keep their bytes unless a package override is required; that override changes only the `packages` value. The ordered npm identity list can change on one side, or identically on both sides; conflicting order or membership changes retain atomic selection. This preserves insertion positions and resource precedence. Non-npm entries must remain unchanged across all three versions for per-package merging. Changed Git refs and local path aliases retain atomic selection instead of being combined as separate sources. Delete/upgrade conflicts, duplicate identities, incompatible filters, version ranges and tags also retain the existing atomic selection rules when deterministic merging is not possible. Other arrays and nested objects remain atomic.
382
391
  Code/scripts, keybindings, binaries, unknown formats, session histories, deletion/modification conflicts, path collisions, and session-root transitions are not model-resolved.
383
392
  Existing deterministic merges still follow their own explicit settings.
384
393
  Unsupported or refused groups remain unresolved; only an explicitly enabled `partialSync` policy permits progress around them.
385
394
  Preserving versions does not mean a conflict is resolved.
386
395
 
387
396
  A verified accepted ancestor is required.
388
- Enabling Agent mode cannot recover historical ancestor bytes that were never retained.
397
+ Enabling Autonomous sync cannot recover historical ancestor bytes that were never retained.
389
398
  If the original accepted bytes are still available on both sides, a conflict-free sync can seed the text ancestors for future runs; otherwise use the existing reviewed recovery flow rather than inventing a base from current edits.
390
399
 
391
400
  Bounds are 8 KiB per input file, 16 conflict paths/units, 24 KiB of serialized model evidence, 16 KiB of candidate output, 8,192 maximum output tokens (or the selected model's smaller positive output limit), and one provider request per candidate attempt. A separately confirmed refusal retry can request the same candidate evidence again.
@@ -398,7 +407,7 @@ These limits are not an exact currency spending cap; in-flight disclosure or cha
398
407
 
399
408
  The existing possible-secret scanner always checks model evidence, even when `skipSecretScan` permits uploads without scanning.
400
409
  It is a heuristic, not a guarantee that all secrets are detected.
401
- Do not enable Agent mode for content you cannot disclose to the selected provider.
410
+ Do not enable Autonomous sync for content you cannot disclose to the selected provider.
402
411
  Provider errors and model reasoning are not copied into status or persistent records.
403
412
 
404
413
  Pi sessions sharing one agent directory use one local resolver claim.
@@ -417,7 +426,7 @@ They can contain merged text; retain them as private data.
417
426
  Different candidates are retained without automatic retention pruning.
418
427
  Ordinary **Sync now** and `/sync sync` reuse a valid cached refusal without another provider request.
419
428
  The manager's **Retry refused model result…** action separately reviews the setup, destination, conflict paths, selected model, disclosure and cost before one fresh request for that exact refusal.
420
- It requires foreground TUI/RPC, Agent mode, an accepted baseline and no pending journal; use ordinary Sync now or reviewed recovery first when those prerequisites are absent.
429
+ It requires foreground TUI/RPC, Autonomous sync, an accepted baseline and no pending journal; use ordinary Sync now or reviewed recovery first when those prerequisites are absent.
421
430
  Changed evidence, settings, model, session or cached bytes invalidate the review without disclosure.
422
431
  A repeated refusal, invalid response or failed pre-publication replacement retains the original result.
423
432
  A complete validated result replaces the active candidate only after the original refusal is archived privately in the same directory.
@@ -432,23 +441,25 @@ Pi-sync's cross-process operation lock excludes other pi-sync transfers, not arb
432
441
  Pi file mutation queues coordinate participating writers only within one process.
433
442
  Checks near rename reduce stale writes but do not provide an atomic compare-and-swap against another Pi process or editor.
434
443
  Session JSONL is not rewritten by the model; other active session writers remain subject to the existing protection limitations.
435
- Do not use Agent mode as a guarantee of lossless live editing.
444
+ Do not use Autonomous sync as a guarantee of lossless live editing.
436
445
 
437
- Turn Agent mode Off to prevent subsequent requests and invalidate pending authorization.
446
+ Turn Autonomous sync Off to prevent subsequent requests and invalidate pending authorization.
438
447
  Keep backups, snapshots, conflicts and pending journals; disabling does not undo completed work or erase history.
439
448
  Unknown publication outcomes use the existing journal reconciliation and never authorize blind republishing.
440
449
  Pending journals can be reconciled on a read/check/write/verify backend because recovery does not publish.
441
- New autonomous transfers still require conditional or lease-protected publication; turn Agent mode Off before a reviewed manual transfer on a weaker backend.
450
+ New autonomous transfers still require conditional or lease-protected publication; turn Autonomous sync Off before a reviewed manual transfer on a weaker backend.
442
451
  If recovery is blocked, retain evidence and use the existing reviewed recovery routes.
443
452
  Finish/reconcile pending merge journals before a downgrade.
444
453
  No Pi core changes or other extension are required.
445
454
 
446
- ### Experimental Continuous sync
455
+ <a id="experimental-continuous-sync"></a>
456
+
457
+ ### Continuous sync
447
458
 
448
459
  `sync.continuous` is an optional per-setup boolean, default `false`, in settings versions 3, 4 and 5.
449
- Open **Settings → Sync behavior → Continuous sync (experimental)** after enabling Agent mode.
460
+ Open **Settings → Continuous sync** after enabling Autonomous sync.
450
461
  RPC users can set the field explicitly in the private settings file.
451
- Existing Agent mode consent does not enable recurring requests.
462
+ Existing Autonomous sync consent does not enable recurring requests.
452
463
 
453
464
  The separate review names the setup, storage connection, destination, included paths, recurring costs and automatic writes.
454
465
  An elected idle session uses its selected Pi model; a different session can use a different provider/model.
@@ -460,8 +471,8 @@ Reopen Settings to read the saved value.
460
471
 
461
472
  Monitoring starts at an eligible TUI/RPC session startup, after awaited local transaction recovery, or after a foreground `/sync` command or manager closes.
462
473
  It replaces the duplicate one-shot startup transfer, not the legacy shutdown policy.
463
- Turning Continuous sync off stops its work without disabling Agent mode.
464
- Turning Agent mode off also stops monitoring; a saved Continuous sync On value remains ineffective until Agent mode is enabled again.
474
+ Turning Continuous sync off stops its work without disabling Autonomous sync.
475
+ Turning Autonomous sync off also stops monitoring; a saved Continuous sync On value remains ineffective until Autonomous sync is enabled again.
465
476
 
466
477
  A control-file change during monitoring is detected by a watcher or the five-second local control check.
467
478
  If monitoring is already off, external enablement requires the next session start or a foreground `/sync` command.
@@ -560,14 +571,14 @@ Preserve journals, backups and unresolved versions when proof is unavailable.
560
571
 
561
572
  Turn Continuous sync off and drain its owner before downgrade.
562
573
  Reconcile pending transfers with the current release.
563
- Existing Agent mode and shutdown preferences remain separately effective.
574
+ Existing Autonomous sync and shutdown preferences remain separately effective.
564
575
  Private scheduler records are separate from baseline/journal formats and remain retained; no automatic filesystem rollback or state migration is performed.
565
576
 
566
577
  For implementation evidence and test scope, see [Continuous sync verification](https://github.com/narumiruna/pi-extensions/blob/main/packages/pi-sync/docs/continuous-sync-verification.md).
567
578
 
568
579
  ### Settings field merge and machine-local fields
569
580
 
570
- `sync.mergeSettings` is experimental, defaults to `false`, and is available in the owning Settings screen.
581
+ `sync.mergeSettings` is an explicit opt-in, defaults to `false`, and is available through **Settings → Merge settings fields** for the current setup.
571
582
  With a verified accepted ancestor, global `settings.json` root fields merge conservatively: absent differs from null, arrays/nested objects are atomic, and provider/model and other coupled fields form one unit.
572
583
  Unknown fields are preserved.
573
584
  Pi accepts plain UTF-8 JSON with an optional BOM, not JSONC; duplicate/prototype-sensitive keys, invalid encodings, migration-dependent syntax, and over-bound inputs require directional review.
@@ -616,8 +627,8 @@ Never reinterpret portable snapshots with an old binary.
616
627
 
617
628
  ### Content merge and partial progress
618
629
 
619
- `sync.mergeContent` and `sync.partialSync` are independent experimental booleans, both default `false`.
620
- The owning **Advanced → Content merge / partial progress** setting offers Off, Merge only, Merge + partial, and Partial only and confirms an explicit settings-version-5 upgrade.
630
+ `sync.mergeContent` and `sync.partialSync` are independent opt-in booleans, both default `false`.
631
+ The owning **Settings → Content merge / partial progress** setting offers Off, Merge only, Merge + partial, and Partial only and confirms an explicit settings-version-5 upgrade.
621
632
  Manual configuration must also declare version 5.
622
633
  Settings version 5 retains the portable-policy behavior of version 4; moving from a legacy setup can require the existing separately confirmed directional policy migration.
623
634
  Disabling options retains the schema and recovery evidence.
@@ -266,11 +266,11 @@ async function showConfig(ctx: ExtensionCommandContext, options: CommandOptions)
266
266
  ...storageLines,
267
267
  `storage path: ${config.storagePath}`,
268
268
  `automatic sync: ${automaticSyncSummary(config.automatic)}`,
269
- `settings field merge: ${config.mergeSettings ? "On (experimental)" : "Off"}`,
269
+ `settings field merge: ${config.mergeSettings ? "On" : "Off"}`,
270
270
  `machine-local settings.json fields: ${(config.localFields ?? []).map(safeTerminalText).join(", ") || "none"}`,
271
271
  `startup transfer: ${startupTransferSummary(config)}`,
272
- `agent mode: ${config.agentMode ? "On (experimental)" : "Off"}`,
273
- `continuous sync: ${config.continuous ? (config.agentMode ? "On (experimental)" : "paused; Agent mode is Off") : "Off"}`,
272
+ `autonomous sync: ${config.agentMode ? "On" : "Off"}`,
273
+ `continuous sync: ${config.continuous ? (config.agentMode ? "On" : "paused; Autonomous sync is Off") : "Off"}`,
274
274
  `included content: ${config.include.join(", ") || "none"}`,
275
275
  `sessions: ${config.include.includes("sessions") ? "included" : "not included"}`,
276
276
  `settings file: ${localConfigPath()}`,
@@ -236,7 +236,7 @@ export function usage() {
236
236
  `Automatic sync: ${AUTOMATIC_SYNC_DESCRIPTION}`,
237
237
  `Startup transfer: ${STARTUP_TRANSFER_DESCRIPTION}`,
238
238
  "Automatic transfer at startup is a separate opt-in: one conflict-free established-baseline transfer at idle in TUI/RPC, with conditional/lease publication and no resource reload.",
239
- "Experimental Continuous sync is a separate default-Off opt-in in Settings. It requires Agent mode, monitors while Pi is open, and can incur recurring network/model costs. Safety blocks and durable automatic request limits remain.",
239
+ "Continuous sync is a separate default-Off opt-in in Settings. It requires Autonomous sync, monitors while Pi is open, and can incur recurring network/model costs. Safety blocks and durable automatic request limits remain.",
240
240
  "Settings: use /sync init or edit storage connections and sync setups in ~/.pi/agent/pi-sync.json (or the configured Pi agent directory). Version 1 and version 2 settings are unsupported and are never rewritten.",
241
241
  ].join("\n");
242
242
  }
@@ -81,7 +81,7 @@ export interface SyncPolicySettings {
81
81
  automatic: boolean;
82
82
  /** Explicit opt-in, separate from the legacy observe/shutdown policy. */
83
83
  automaticTransfer?: boolean;
84
- /** Experimental autonomous merged-sync authorization. */
84
+ /** Autonomous merged-sync authorization. */
85
85
  agentMode?: boolean;
86
86
  /** Separate explicit authorization for recurring background work. */
87
87
  continuous?: boolean;
@@ -93,7 +93,7 @@ export function buildAgentEvidence(
93
93
  const evidence: AgentEvidence = { units: [], files: [], unsupported: [] };
94
94
  if (plan.kind !== "planned") return evidence;
95
95
  if (plan.conflicts.length > AGENT_MAX_UNITS)
96
- throw new Error("Agent mode paused: too many conflict paths for bounded analysis.");
96
+ throw new Error("Autonomous sync paused: too many conflict paths for bounded analysis.");
97
97
  for (const conflict of plan.conflicts) {
98
98
  try {
99
99
  if (conflict.reason !== "both-changed") throw new Error("unsupported conflict");
@@ -159,7 +159,7 @@ export function buildAgentEvidence(
159
159
  }
160
160
  }
161
161
  if (evidence.units.length > AGENT_MAX_UNITS || Buffer.byteLength(JSON.stringify(evidence.units)) > AGENT_INPUT_BYTES)
162
- throw new Error("Agent mode paused: conflict evidence exceeds its input bound.");
162
+ throw new Error("Autonomous sync paused: conflict evidence exceeds its input bound.");
163
163
  // Scan only the actual disclosure image; skipSecretScan never authorizes model disclosure.
164
164
  if (
165
165
  scanSnapshot({
@@ -169,7 +169,7 @@ export function buildAgentEvidence(
169
169
  ),
170
170
  }).length
171
171
  )
172
- throw new Error("Agent mode paused: possible secrets in model evidence; nothing was disclosed.");
172
+ throw new Error("Autonomous sync paused: possible secrets in model evidence; nothing was disclosed.");
173
173
  return evidence;
174
174
  }
175
175
 
@@ -34,24 +34,27 @@ export async function resolveAgentPlan(
34
34
  return plan;
35
35
  }
36
36
  if (!ctx.hasUI || (ctx.mode !== "tui" && ctx.mode !== "rpc"))
37
- throw new Error("Agent mode paused: TUI/RPC is required.");
37
+ throw new Error("Autonomous sync paused: TUI/RPC is required.");
38
38
  const ancestors = (await readMergeAncestors(config, state)) ?? [];
39
39
  await validate();
40
40
  let evidence: ReturnType<typeof buildAgentEvidence>;
41
41
  try {
42
42
  evidence = buildAgentEvidence(plan, local, remote, ancestors);
43
43
  } catch {
44
- throw new ContinuousError("unsafe", "Agent mode paused: unsafe or unsupported conflict evidence.");
44
+ throw new ContinuousError("unsafe", "Autonomous sync paused: unsafe or unsupported conflict evidence.");
45
45
  }
46
46
  if (!config.partialSync && evidence.unsupported.length)
47
- throw new ContinuousError("unsafe", "Agent mode paused: unsupported conflicts prevent an all-or-nothing transfer.");
47
+ throw new ContinuousError(
48
+ "unsafe",
49
+ "Autonomous sync paused: unsupported conflicts prevent an all-or-nothing transfer.",
50
+ );
48
51
  if (!evidence.files.length) {
49
52
  if (options.agentRetryRefusal)
50
53
  throw new ContinuousError("unsafe", "No eligible cached refusal for the current evidence. Use Sync now.");
51
54
  if (config.partialSync) return plan;
52
55
  throw new ContinuousError(
53
56
  "unsafe",
54
- "Agent mode paused: unsupported conflict or missing verified ancestor; evidence is unchanged.",
57
+ "Autonomous sync paused: unsupported conflict or missing verified ancestor; evidence is unchanged.",
55
58
  );
56
59
  }
57
60
  if (!evidence.units.length) {
@@ -59,7 +62,7 @@ export async function resolveAgentPlan(
59
62
  throw new ContinuousError("unsafe", "No eligible cached refusal for the current evidence. Use Sync now.");
60
63
  return applyAgentCandidate(plan, evidence, { version: 1, results: [] });
61
64
  }
62
- if (!ctx.model) throw new ContinuousError("model", "Agent mode paused: select an available model first.");
65
+ if (!ctx.model) throw new ContinuousError("model", "Autonomous sync paused: select an available model first.");
63
66
  const model = digest(ctx.model);
64
67
  const key = digest([
65
68
  1,
@@ -75,7 +78,7 @@ export async function resolveAgentPlan(
75
78
  try {
76
79
  return applyAgentCandidate(plan, evidence, options.agentAcceptance.candidate);
77
80
  } catch {
78
- throw new ContinuousError("unsafe", "Agent mode paused: candidate refused or unsupported conflict remains.");
81
+ throw new ContinuousError("unsafe", "Autonomous sync paused: candidate refused or unsupported conflict remains.");
79
82
  }
80
83
  }
81
84
  const validateEvidence = async (signal = options.signal) => {
@@ -85,7 +88,7 @@ export async function resolveAgentPlan(
85
88
  signal?.throwIfAborted();
86
89
  };
87
90
  await check();
88
- if (digest(ctx.model) !== model) throw new Error("Agent mode paused: selected model changed.");
91
+ if (digest(ctx.model) !== model) throw new Error("Autonomous sync paused: selected model changed.");
89
92
  const current = await createSnapshot(config.snapshotIdentity, { ...snapshotOptions, signal });
90
93
  await check();
91
94
  const currentState = await readStateForConfig(config);
@@ -98,7 +101,7 @@ export async function resolveAgentPlan(
98
101
  !currentHead ||
99
102
  !backend.sameRevision(head.revision, currentHead.revision)
100
103
  )
101
- throw new ContinuousError("stale", "Agent mode paused: conflict evidence changed; retry a fresh sync.");
104
+ throw new ContinuousError("stale", "Autonomous sync paused: conflict evidence changed; retry a fresh sync.");
102
105
  };
103
106
  throw new AgentResolutionRequired(key, evidence, validateEvidence);
104
107
  }
@@ -39,9 +39,9 @@ export async function runAgentResolver(
39
39
  beforeRequest?: (signal: AbortSignal) => Promise<void>,
40
40
  ): Promise<string> {
41
41
  const model = ctx.model;
42
- if (!model) throw new ContinuousError("model", "Agent mode paused: select an available model first.");
42
+ if (!model) throw new ContinuousError("model", "Autonomous sync paused: select an available model first.");
43
43
  if (!Number.isSafeInteger(model.maxTokens) || model.maxTokens < 0)
44
- throw new Error("Agent mode paused: selected model has an invalid output limit.");
44
+ throw new Error("Autonomous sync paused: selected model has an invalid output limit.");
45
45
  // Pi uses zero for unknown limits, including virtual models. Its registry caps routed requests.
46
46
  const maxTokens = model.maxTokens > 0 ? Math.min(AGENT_MAX_TOKENS, model.maxTokens) : AGENT_MAX_TOKENS;
47
47
  const controller = new AbortController();
@@ -74,7 +74,7 @@ export async function runAgentResolver(
74
74
  },
75
75
  });
76
76
  const childModel = runtime.getModel(provider, "resolver");
77
- if (!childModel) throw new Error("Agent mode paused: resolver model unavailable.");
77
+ if (!childModel) throw new Error("Autonomous sync paused: resolver model unavailable.");
78
78
  ({ session } = await createAgentSession({
79
79
  cwd: ctx.cwd,
80
80
  model: childModel,
@@ -104,7 +104,7 @@ export async function runAgentResolver(
104
104
  });
105
105
  child.agent.streamFunction = async (_model, context, options) => {
106
106
  ownedSignal.throwIfAborted();
107
- if (++calls > 1) throw new Error("Agent mode paused: one provider request per candidate is permitted.");
107
+ if (++calls > 1) throw new Error("Autonomous sync paused: one provider request per candidate is permitted.");
108
108
  await validate(ownedSignal);
109
109
  ownedSignal.throwIfAborted();
110
110
  if (beforeRequest) {
@@ -146,15 +146,16 @@ export async function runAgentResolver(
146
146
  last.stopReason !== "stop" ||
147
147
  last.content.some((block) => block.type !== "text" && block.type !== "thinking")
148
148
  )
149
- throw new Error("Agent mode paused: incomplete, failed or tool-bearing model output.");
149
+ throw new Error("Autonomous sync paused: incomplete, failed or tool-bearing model output.");
150
150
  const output = last.content
151
151
  .filter((block) => block.type === "text")
152
152
  .map((block) => block.text)
153
153
  .join("");
154
- if (Buffer.byteLength(output) > AGENT_OUTPUT_BYTES) throw new Error("Agent mode paused: output bound exceeded.");
154
+ if (Buffer.byteLength(output) > AGENT_OUTPUT_BYTES)
155
+ throw new Error("Autonomous sync paused: output bound exceeded.");
155
156
  if (ctx.hasUI)
156
157
  ctx.ui.notify(
157
- `Pi Sync agent candidate: ${last.usage.totalTokens} tokens. Semantic correctness is not guaranteed.`,
158
+ `Pi Sync resolver candidate: ${last.usage.totalTokens} tokens. Semantic correctness is not guaranteed.`,
158
159
  "info",
159
160
  );
160
161
  return output;
@@ -169,13 +170,13 @@ export async function runAgentResolver(
169
170
  if (failure.retry)
170
171
  throw new ContinuousError(
171
172
  failure.kind,
172
- "Agent mode paused: transient resolver transport failure.",
173
+ "Autonomous sync paused: transient resolver transport failure.",
173
174
  failure.delay,
174
175
  );
175
176
  // Provider errors can quote submitted content or auth; never surface their payload.
176
177
  throw new ContinuousError(
177
178
  "model",
178
- "Agent mode paused: resolver failed or returned unusable output. Check model access and retry later.",
179
+ "Autonomous sync paused: resolver failed or returned unusable output. Check model access and retry later.",
179
180
  );
180
181
  } finally {
181
182
  clearTimeout(timer);
@@ -92,7 +92,7 @@ export async function withAgentClaim<T>(fn: (assertOwner: () => Promise<void>) =
92
92
  await withClaimGuard(async () => {
93
93
  const existing = await readClaim();
94
94
  if (existing && alive(existing.pid))
95
- throw new ContinuousError("contention", "Agent mode deferred: another local resolver is running.");
95
+ throw new ContinuousError("contention", "Autonomous sync deferred: another local resolver is running.");
96
96
  // A durability failure can occur after rename: cleanup must own partial initialization too.
97
97
  armed = true;
98
98
  await writeJson(paths().claim, claim);
@@ -89,7 +89,7 @@ export async function withAgentSyncLock<T>(
89
89
  try {
90
90
  candidate = parseAgentCandidate(raw, request.evidence);
91
91
  } catch {
92
- throw new ContinuousError("model", "Agent mode paused: invalid resolver output; evidence retained.");
92
+ throw new ContinuousError("model", "Autonomous sync paused: invalid resolver output; evidence retained.");
93
93
  }
94
94
  if (retry && candidate.results.some((row) => "refuse" in row))
95
95
  throw new ContinuousError("model", "The model refused again. The previous refusal was retained.");
@@ -132,7 +132,7 @@ export async function withAgentSyncLock<T>(
132
132
  request = error;
133
133
  }
134
134
  }
135
- throw new ContinuousError("stale", "Agent mode paused: content changed repeatedly; retry later.");
135
+ throw new ContinuousError("stale", "Autonomous sync paused: content changed repeatedly; retry later.");
136
136
  } finally {
137
137
  options.signal?.removeEventListener("abort", onAbort);
138
138
  if (!options.signal?.aborted) clearStatus();
@@ -210,7 +210,7 @@ function hasReservationCapacity(record: ContinuousRecord, now: number): boolean
210
210
  /** Read-only status: no directory creation, lease, mutation, request reservation or provider call. */
211
211
  export async function continuousStatusLines(config: AnySyncConfig, clock: () => number = Date.now): Promise<string[]> {
212
212
  if (!config.continuous) return ["Continuous sync: Off"];
213
- if (!config.agentMode) return ["Continuous sync: paused; enable Agent mode first"];
213
+ if (!config.agentMode) return ["Continuous sync: paused; enable Autonomous sync first"];
214
214
  try {
215
215
  const binding = await continuousBinding(config);
216
216
  const document = await readContinuousPrivateDocument(`${binding}.json`);
@@ -102,7 +102,7 @@ export async function mergeSync(
102
102
  options.agentRetryRefusal &&
103
103
  (!config.agentMode || options.auto || options.background || !ctx.hasUI || !["tui", "rpc"].includes(ctx.mode))
104
104
  )
105
- throw new Error("Refused-candidate retry requires foreground Agent mode in TUI or RPC.");
105
+ throw new Error("Refused-candidate retry requires foreground Autonomous sync in TUI or RPC.");
106
106
  };
107
107
  const config = await loadConfig(options.setup);
108
108
  validateOwner(config);
@@ -131,7 +131,7 @@ export async function mergeSync(
131
131
  throw new Error("Session storage root changed during transfer; evidence retained for review.");
132
132
  }
133
133
  if (config.agentMode && JSON.stringify(ctx.model) !== modelToken)
134
- throw new Error("Agent mode paused: selected model changed during transfer.");
134
+ throw new Error("Autonomous sync paused: selected model changed during transfer.");
135
135
  if (options.auto && (!startupTransferEnabled(latest) || !ctx.isIdle()))
136
136
  throw new Error("Automatic transfer is no longer authorized at this idle boundary.");
137
137
  });
@@ -171,7 +171,7 @@ export async function mergeSync(
171
171
  // Recovery above never publishes. This gate applies only to new autonomous transfers.
172
172
  if ((options.auto || config.agentMode) && backend.capability === "read-check-write-verify") {
173
173
  throw new Error(
174
- "Automatic transfer requires conditional publication or a lease; this backend supports only read/check/write/verify. Disable Agent mode and use manual sync.",
174
+ "Automatic transfer requires conditional publication or a lease; this backend supports only read/check/write/verify. Disable Autonomous sync and use manual sync.",
175
175
  );
176
176
  }
177
177
  const textBudget = { remaining: TEXT_MERGE_WORK_LIMIT };
@@ -353,7 +353,7 @@ export async function mergeSync(
353
353
  if (plan.kind !== "planned" || (plan.conflicts.length && !config.partialSync))
354
354
  throw new ContinuousError(
355
355
  "unsafe",
356
- "Agent mode paused: unsupported or refused conflict groups remain; no transfer was performed.",
356
+ "Autonomous sync paused: unsupported or refused conflict groups remain; no transfer was performed.",
357
357
  );
358
358
  }
359
359
  if (
@@ -433,7 +433,7 @@ export async function syncBoth(
433
433
  options.background?.validate(config);
434
434
  if (options.agentRetryRefusal) {
435
435
  if (!config.agentMode || options.auto || options.background || !ctx.hasUI)
436
- throw new Error("Enable Agent mode and use the foreground manager to retry a cached refusal.");
436
+ throw new Error("Enable Autonomous sync and use the foreground manager to retry a cached refusal.");
437
437
  const state = await readStateForConfig(config);
438
438
  validateMutation();
439
439
  const pending = await readMergeJournal(config);
@@ -6,10 +6,10 @@ import { confirmMergeReview } from "./merge-review.js";
6
6
  import { safeTerminalText } from "./terminal-text.js";
7
7
 
8
8
  export const AGENT_MODE_DESCRIPTION =
9
- "This setup, experimental: one autonomous merged sync next startup and on Sync now. Sends eligible conflict text to the selected Pi model; may incur costs and replace/delete selected local and remote content without transfer prompts. No automatic reload. Unsupported conflicts pause.";
9
+ "This setup: sync eligible changes at session startup and on Sync now without transfer confirmation. Use the selected Pi model to resolve supported text and settings conflicts. Eligible conflict content may be sent to its provider and incur costs. Selected local and remote content can be replaced or deleted. Unresolved conflicts pause unless partial sync permits independent progress. Continuous sync is a separate opt-in. No automatic reload.";
10
10
 
11
11
  export const CONTINUOUS_DESCRIPTION =
12
- "This setup, experimental: recurring sync while Pi is open. Requires Agent mode. Watches selected files, checks the remote every 60–66 seconds, and retries temporary failures. Local changes and retries can cause extra requests between polls. May disclose conflict text and incur model/storage costs. No automatic reload.";
12
+ "This setup: recurring sync while Pi is open. Requires Autonomous sync. Watches selected files, checks the remote every 60–66 seconds, and retries temporary failures. Local changes and retries can cause extra requests between polls. May disclose conflict text and incur model/storage costs. No automatic reload.";
13
13
 
14
14
  export function saveContinuousMode(
15
15
  ctx: ExtensionCommandContext,
@@ -33,8 +33,8 @@ export async function saveAgentMode(
33
33
  const setup = settings.syncSetups[setupName];
34
34
  if (!setup || settings.activeSyncSetup !== setupName) throw new Error("Current sync setup changed; reopen Settings.");
35
35
  const continuous = preference === "continuous";
36
- const label = continuous ? "Continuous sync" : "Agent mode";
37
- if (enabled && continuous && !setup.sync.agentMode) throw new Error("Enable Agent mode before Continuous sync.");
36
+ const label = continuous ? "Continuous sync" : "Autonomous sync";
37
+ if (enabled && continuous && !setup.sync.agentMode) throw new Error("Enable Autonomous sync before Continuous sync.");
38
38
  if (Boolean(setup.sync[preference]) === enabled) return true;
39
39
  if (enabled) {
40
40
  const summary = [
@@ -59,7 +59,7 @@ export async function saveAgentMode(
59
59
  if (
60
60
  !(await confirmMergeReview(
61
61
  ctx,
62
- `Enable experimental ${label}?`,
62
+ `Enable ${label}?`,
63
63
  summary,
64
64
  signal,
65
65
  () => !signal?.aborted,
@@ -80,7 +80,7 @@ export async function saveAgentMode(
80
80
  settings.storageConnections[setup.storage.connection],
81
81
  )
82
82
  )
83
- throw new Error("Sync setup or connection changed during Agent mode review; reopen Settings.");
83
+ throw new Error("Sync setup or connection changed during Autonomous sync review; reopen Settings.");
84
84
  return {
85
85
  ...current,
86
86
  syncSetups: { ...current.syncSetups, [setupName]: { ...setup, sync: { ...setup.sync, [preference]: enabled } } },
@@ -165,7 +165,7 @@ export async function describeManagerState(
165
165
  `Included: ${selection.builtIns.length} built-in group${selection.builtIns.length === 1 ? "" : "s"} · ${selection.custom.length} extra path${selection.custom.length === 1 ? "" : "s"} · Sessions ${selection.sessions ? "on" : "off"}`,
166
166
  `Automatic sync: ${automaticSyncSummary(config.automatic)}`,
167
167
  `Startup transfer: ${startupTransferSummary(config)}`,
168
- `Agent mode: ${config.agentMode ? "On (experimental; autonomous merged sync)" : "Off"}`,
168
+ `Autonomous sync: ${config.agentMode ? "On (autonomous merged sync)" : "Off"}`,
169
169
  ...(config.continuous ? await (await import("../sync/continuous-record.js")).continuousStatusLines(config) : []),
170
170
  `Last applied: ${lastAppliedSnapshot}`,
171
171
  ...(noSyncedContent