gentle-pi 4.2.0 → 4.4.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.
Files changed (334) hide show
  1. package/README.md +340 -138
  2. package/assets/agents/gentle-ai-explore.md +1 -0
  3. package/assets/agents/gentle-ai-verify.md +6 -4
  4. package/assets/agents/gentle-ai-worker.md +7 -1
  5. package/assets/design-canvas/canvas.css +648 -0
  6. package/assets/design-canvas/canvas.js +1497 -0
  7. package/assets/design-canvas/index.html +88 -0
  8. package/assets/design-canvas/inspector.js +290 -0
  9. package/assets/orchestrator-delegation-reference.md +163 -0
  10. package/assets/orchestrator-delegation.md +25 -176
  11. package/assets/orchestrator-tracking.md +1 -1
  12. package/assets/orchestrator-verification.md +14 -8
  13. package/assets/orchestrator-writer.md +5 -1
  14. package/assets/orchestrator.md +11 -11
  15. package/bin/engram-guard +1 -1
  16. package/bin/gentle-shell.mjs +237 -139
  17. package/contracts/review-provider-contract-mirror/provider-contract.lock.json +8 -7
  18. package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/README.md +7 -0
  19. package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/manifest.json +11 -2
  20. package/contracts/review-provider-contract-mirror/v1.4.0/bundle/routing/pi.md +92 -0
  21. package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/generated/provider-capabilities.baseline.json +8 -1
  22. package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/generated/provider-roles.baseline.json +1 -1
  23. package/docs/assets/diagrams/agent-orchestration.svg +54 -15
  24. package/docs/assets/diagrams/gentleman-workflow.svg +69 -11
  25. package/docs/assets/diagrams/measured-routing.svg +49 -0
  26. package/docs/assets/diagrams/native-review.svg +52 -12
  27. package/docs/assets/diagrams/odd-workflow.svg +128 -66
  28. package/docs/assets/diagrams/permission-modes.svg +51 -0
  29. package/docs/assets/features/audio-notifications.png +0 -0
  30. package/docs/assets/features/command-palette.png +0 -0
  31. package/docs/bundled-install.md +65 -30
  32. package/docs/delegated-verification.md +16 -8
  33. package/docs/gentle-agents-activity.md +16 -6
  34. package/docs/gentle-music.md +61 -0
  35. package/docs/gentle-shell-uninstall.md +8 -1
  36. package/docs/gentle-shell.md +80 -9
  37. package/docs/install-wizard.md +37 -6
  38. package/docs/permission-modes.md +8 -3
  39. package/docs/readme-reference.md +120 -28
  40. package/docs/session-profile-format.md +26 -0
  41. package/docs/voice.md +259 -0
  42. package/docs/yolo-mode.md +38 -10
  43. package/extensions/ask-user-choice.ts +4 -1
  44. package/extensions/codegraph-tools.ts +68 -6
  45. package/extensions/gentle-agents.ts +270 -48
  46. package/extensions/gentle-ai.ts +490 -113
  47. package/extensions/gentle-design.ts +158 -0
  48. package/extensions/gentle-herdr-activity.ts +2 -3
  49. package/extensions/gentle-music.ts +289 -0
  50. package/extensions/gentle-shell.ts +359 -85
  51. package/extensions/gentle-todo.ts +43 -9
  52. package/extensions/gentle-voice.ts +11 -0
  53. package/extensions/quiet-tools.ts +1 -1
  54. package/extensions/session-scratch.ts +384 -0
  55. package/extensions/skill-registry.ts +63 -8
  56. package/extensions/startup-banner.ts +2 -3
  57. package/lib/agent-home.ts +8 -3
  58. package/lib/agent-profiles.ts +26 -0
  59. package/lib/agents-config.ts +35 -0
  60. package/lib/agents-protocol.ts +60 -1
  61. package/lib/agents-runner.ts +107 -9
  62. package/lib/agents-session-transport.ts +101 -6
  63. package/lib/agents-view.ts +3 -1
  64. package/lib/agents-widget.ts +14 -1
  65. package/lib/auto-permission-memory.ts +48 -18
  66. package/lib/auto-permission-runtime.ts +21 -6
  67. package/lib/bounded-writer-admission.ts +51 -0
  68. package/lib/clipboard-image.ts +147 -0
  69. package/lib/command-palette-catalog.ts +2 -4
  70. package/lib/commit-slice-signal.ts +100 -0
  71. package/lib/context-backstop.ts +120 -0
  72. package/lib/delivered-test-lint.ts +80 -0
  73. package/lib/design-canvas-server.ts +947 -0
  74. package/lib/design-comments.ts +437 -0
  75. package/lib/design-handoffs.ts +313 -0
  76. package/lib/design-open-browser.ts +58 -0
  77. package/lib/design-sources.ts +120 -0
  78. package/lib/destructive-command-guard.ts +120 -9
  79. package/lib/external-editor.ts +31 -0
  80. package/lib/gauge-theme.ts +146 -0
  81. package/lib/gentle-ai-binary.ts +28 -7
  82. package/lib/gentle-design.ts +513 -0
  83. package/lib/gentle-shell-bundled.ts +146 -36
  84. package/lib/gentle-shell-import-pi.ts +233 -0
  85. package/lib/gentle-shell-launcher.ts +154 -15
  86. package/lib/gentle-shell-startup-update.ts +61 -9
  87. package/lib/gentle-shell-uninstall.ts +51 -2
  88. package/lib/herdr-activity.ts +24 -0
  89. package/lib/image-attachments.ts +150 -0
  90. package/lib/inprocess-reviewer.ts +33 -2
  91. package/lib/nan-provider.ts +3 -0
  92. package/lib/native-review-cli.ts +20 -5
  93. package/lib/notification-audio-native.ts +149 -13
  94. package/lib/notification-audio.ts +4 -0
  95. package/lib/notification-pulse-worker.ts +82 -18
  96. package/lib/notification-service.ts +5 -1
  97. package/lib/orchestrator-discovery.ts +5 -1
  98. package/lib/orchestrator-presence.ts +87 -8
  99. package/lib/orchestrator-scope.ts +31 -3
  100. package/lib/orchestrator-state.ts +11 -3
  101. package/lib/permission-mode-policy.ts +2 -2
  102. package/lib/provider-contract-bundle.ts +99 -53
  103. package/lib/review-candidate-view-owner.ts +29 -19
  104. package/lib/review-candidate-view.ts +36 -2
  105. package/lib/review-host-relay.ts +11 -2
  106. package/lib/review-reminder-receipt.ts +24 -1
  107. package/lib/review-risk-assessment.ts +43 -38
  108. package/lib/review-session-standing-permission.ts +3 -1
  109. package/lib/session-profile-append-controller.ts +713 -0
  110. package/lib/session-profile-disk-reader.ts +182 -0
  111. package/lib/session-profile-freeze.ts +30 -1
  112. package/lib/session-profile-persistence.ts +15 -7
  113. package/lib/session-scratch.ts +523 -0
  114. package/lib/session-worktree-registry.ts +7 -0
  115. package/lib/shell-bar.ts +29 -28
  116. package/lib/shell-changes-view.ts +80 -13
  117. package/lib/shell-changes.ts +81 -5
  118. package/lib/shell-gauge.ts +49 -6
  119. package/lib/shell-prompt.ts +4 -4
  120. package/lib/shell-sidebar-layout.ts +26 -6
  121. package/lib/shell-todo.ts +24 -5
  122. package/lib/shell-usage-view.ts +5 -1
  123. package/lib/shell-usage.ts +7 -7
  124. package/lib/verifier-admission.ts +30 -0
  125. package/lib/vim-editor-adapter.ts +11 -8
  126. package/lib/voice-artifacts.ts +188 -0
  127. package/lib/voice-command.ts +576 -0
  128. package/lib/voice-install.ts +455 -0
  129. package/lib/voice-platform.ts +99 -0
  130. package/lib/voice-push-to-talk.ts +262 -0
  131. package/lib/voice-session.ts +460 -0
  132. package/lib/voice-settings.ts +50 -0
  133. package/lib/voice-ui.ts +158 -0
  134. package/lib/yolo-session-policy.ts +58 -22
  135. package/lib/yolo-temp-scratch.ts +69 -0
  136. package/package.json +1 -2
  137. package/runtime/gentle-ai-binary.mjs +28 -7
  138. package/runtime/gentle-shell-bundled.mjs +145 -35
  139. package/runtime/gentle-shell-import-pi.mjs +234 -0
  140. package/runtime/gentle-shell-launcher.mjs +152 -13
  141. package/runtime/gentle-shell-startup-update.mjs +61 -9
  142. package/runtime/gentle-shell-uninstall.mjs +51 -2
  143. package/runtime/native-review-cli.mjs +19 -4
  144. package/runtime/review-risk-assessment.mjs +43 -38
  145. package/scripts/build-runtime-modules.mjs +1 -0
  146. package/scripts/bundled-engram-migration.mjs +119 -0
  147. package/scripts/gentle-ai-installer.mjs +10 -10
  148. package/scripts/installer-downloads.mjs +7 -7
  149. package/scripts/installer-preflight.mjs +5 -3
  150. package/scripts/installer-server.mjs +14 -4
  151. package/scripts/installer-windows.mjs +37 -7
  152. package/scripts/main-channel.mjs +94 -19
  153. package/scripts/pi-update.mjs +34 -6
  154. package/scripts/run-test-suite.mjs +5 -0
  155. package/scripts/verify-package-files.mjs +43 -13
  156. package/scripts/voice-worker.cjs +476 -0
  157. package/skills/design/SKILL.md +110 -0
  158. package/skills/gentle-ai/SKILL.md +3 -3
  159. package/skills/work-unit-commits/SKILL.md +5 -3
  160. package/tests/agent-profiles.test.ts +24 -0
  161. package/tests/agent-risk-escalation.test.ts +37 -10
  162. package/tests/agents-config.test.ts +61 -0
  163. package/tests/agents-fake-child.ts +8 -1
  164. package/tests/agents-protocol.test.ts +32 -0
  165. package/tests/agents-runner.test.ts +485 -7
  166. package/tests/agents-session-transport.test.ts +53 -3
  167. package/tests/ask-user-choice.test.ts +30 -0
  168. package/tests/auto-mode.test.ts +17 -0
  169. package/tests/auto-permission-memory-diagnostics.test.ts +56 -0
  170. package/tests/auto-permission-runtime.test.ts +85 -1
  171. package/tests/autonomous-guard.test.ts +142 -0
  172. package/tests/bounded-writer-admission.test.ts +11 -3
  173. package/tests/bundled-install.test.ts +3 -3
  174. package/tests/card-content-policy.test.ts +19 -9
  175. package/tests/child-safety.test.ts +39 -0
  176. package/tests/clipboard-image.test.ts +114 -0
  177. package/tests/codegraph-tools.test.ts +123 -2
  178. package/tests/command-palette.test.ts +15 -5
  179. package/tests/commit-slice-signal.test.ts +162 -0
  180. package/tests/context-backstop.test.ts +225 -0
  181. package/tests/delegate-for-reason-contract.test.ts +92 -24
  182. package/tests/delivered-test-lint.test.ts +105 -0
  183. package/tests/design-canvas-assets.test.ts +710 -0
  184. package/tests/design-canvas-server.test.ts +1096 -0
  185. package/tests/design-comments.test.ts +201 -0
  186. package/tests/design-handoffs.test.ts +282 -0
  187. package/tests/design-open-browser.test.ts +70 -0
  188. package/tests/design-sources.test.ts +132 -0
  189. package/tests/destructive-command-guard.test.ts +85 -1
  190. package/tests/engram-safety.test.ts +132 -57
  191. package/tests/external-editor.test.ts +84 -0
  192. package/tests/fixtures/primary-session-prompt/gentleman.golden.md +143 -0
  193. package/tests/fixtures/provider-contract-bundle/v1.4.0/README.md +29 -0
  194. package/tests/fixtures/provider-contract-bundle/v1.4.0/manifest.json +83 -0
  195. package/tests/fixtures/provider-contract-bundle/v1.4.0/orchestration/pi.md +70 -0
  196. package/tests/fixtures/provider-contract-bundle/v1.4.0/routing/pi.md +92 -0
  197. package/tests/fixtures/provider-contract-bundle/v1.4.0/schemas/lens.schema.json +16 -0
  198. package/tests/fixtures/provider-contract-bundle/v1.4.0/schemas/refuter.schema.json +1 -0
  199. package/tests/fixtures/provider-contract-bundle/v1.4.0/schemas/targeted-validator.schema.json +1 -0
  200. package/tests/fixtures/provider-contract-bundle/v1.4.0/vectors/lens.json +1 -0
  201. package/tests/fixtures/provider-contract-bundle/v1.4.0/vectors/refuter.json +1 -0
  202. package/tests/fixtures/provider-contract-bundle/v1.4.0/vectors/targeted-validator.json +1 -0
  203. package/tests/gauge-theme.test.ts +120 -0
  204. package/tests/gentle-agents.test.ts +645 -21
  205. package/tests/gentle-ai-binary.test.ts +1 -1
  206. package/tests/gentle-ai-child-guards.test.ts +61 -0
  207. package/tests/gentle-ai-doctor-herdr.test.ts +94 -0
  208. package/tests/gentle-ai-installer.test.ts +51 -51
  209. package/tests/gentle-ai.test.ts +292 -13
  210. package/tests/gentle-design.test.ts +1313 -0
  211. package/tests/gentle-music.test.ts +335 -0
  212. package/tests/gentle-shell-bin.test.ts +163 -0
  213. package/tests/gentle-shell-bundled.test.ts +392 -176
  214. package/tests/gentle-shell-import-pi.test.ts +262 -0
  215. package/tests/gentle-shell-launcher.test.ts +107 -2
  216. package/tests/gentle-shell-startup-update.test.ts +77 -1
  217. package/tests/gentle-shell-uninstall.test.ts +89 -0
  218. package/tests/gentle-shell.test.ts +225 -17
  219. package/tests/gentle-todo.test.ts +190 -0
  220. package/tests/headless-delivery-question.test.ts +58 -0
  221. package/tests/herdr-activity.test.ts +34 -1
  222. package/tests/image-attachments.test.ts +119 -0
  223. package/tests/image-paste-chips.test.ts +236 -0
  224. package/tests/inprocess-reviewer.test.ts +55 -2
  225. package/tests/installer-bundles.test.ts +12 -6
  226. package/tests/installer-posix-bootstrap.test.ts +8 -8
  227. package/tests/installer-preflight.test.ts +16 -0
  228. package/tests/installer-server.test.ts +10 -2
  229. package/tests/installer-windows-bootstrap.test.ts +94 -7
  230. package/tests/installer-windows-diagnostics.test.ts +111 -0
  231. package/tests/main-channel-upgrade.test.ts +232 -2
  232. package/tests/main-channel.test.ts +140 -21
  233. package/tests/nan-provider.test.ts +36 -0
  234. package/tests/native-review-capability-contract.test.ts +17 -4
  235. package/tests/native-review-parity.test.ts +23 -2
  236. package/tests/no-self-pause-contract.test.ts +5 -2
  237. package/tests/notification-audio-native.test.ts +128 -9
  238. package/tests/notification-customize.test.ts +17 -5
  239. package/tests/odd-integration.test.ts +5 -1
  240. package/tests/odd-routing-canonical-ratchet.test.ts +128 -162
  241. package/tests/odd-routing-contract.test.ts +115 -30
  242. package/tests/orchestrator-budget.test.ts +22 -8
  243. package/tests/orchestrator-discovery.test.ts +29 -0
  244. package/tests/orchestrator-presence.test.ts +100 -2
  245. package/tests/orchestrator-rdd-ownership.test.ts +3 -1
  246. package/tests/orchestrator-scope.test.ts +80 -0
  247. package/tests/orchestrator-state.test.ts +29 -0
  248. package/tests/orchestrator-status-publication-contract.test.ts +12 -8
  249. package/tests/package-files.test.ts +34 -0
  250. package/tests/package-manifest.test.ts +24 -20
  251. package/tests/permission-mode-policy.test.ts +10 -1
  252. package/tests/pi-update-launcher.test.ts +21 -2
  253. package/tests/pi-update.test.ts +99 -4
  254. package/tests/primary-session-prompt.test.ts +101 -0
  255. package/tests/provider-contract-bundle.test.ts +118 -0
  256. package/tests/provider-contract-mirror.test.ts +24 -0
  257. package/tests/quiet-tool-rendering.test.ts +23 -0
  258. package/tests/rdd-aware-verification-contract.test.ts +29 -11
  259. package/tests/rdd-status-line.test.ts +79 -0
  260. package/tests/review-agent-end-preflight.test.ts +6 -0
  261. package/tests/review-candidate-view.test.ts +49 -0
  262. package/tests/review-contract-prompt.test.ts +5 -2
  263. package/tests/review-controller-native-routing.test.ts +14 -1
  264. package/tests/review-controller.test.ts +1 -1
  265. package/tests/review-host-relay-routing.test.ts +147 -3
  266. package/tests/review-host-relay.test.ts +9 -2
  267. package/tests/review-json-arguments.test.ts +20 -3
  268. package/tests/review-loadout-rdd-off-sdk.test.ts +258 -0
  269. package/tests/review-owner-identity.test.ts +132 -0
  270. package/tests/review-relay-transport-agent.test.ts +26 -0
  271. package/tests/review-reminder-receipt.test.ts +31 -1
  272. package/tests/review-risk-assessment.test.ts +163 -76
  273. package/tests/review-session-standing-permission-controller.test.ts +14 -1
  274. package/tests/review-session-standing-permission.test.ts +27 -1
  275. package/tests/run-test-suite.test.ts +15 -0
  276. package/tests/runtime-harness.mjs +16 -6
  277. package/tests/session-changes-shell.test.ts +1 -1
  278. package/tests/session-changes.test.ts +2 -1
  279. package/tests/session-profile-append-controller-fork.test.ts +458 -0
  280. package/tests/session-profile-append-controller-pi.test.ts +290 -0
  281. package/tests/session-profile-append-controller.test.ts +731 -0
  282. package/tests/session-profile-disk-reader-pi.test.ts +183 -0
  283. package/tests/session-profile-disk-reader.test.ts +311 -0
  284. package/tests/session-profile-freeze.test.ts +23 -0
  285. package/tests/session-scratch.test.ts +1011 -0
  286. package/tests/session-subject-routing-contract.test.ts +2 -1
  287. package/tests/session-worktree-registry.test.ts +13 -1
  288. package/tests/shell-bar.test.ts +21 -2
  289. package/tests/shell-changes-view.test.ts +137 -1
  290. package/tests/shell-changes.test.ts +148 -1
  291. package/tests/shell-gauge.test.ts +42 -0
  292. package/tests/shell-prompt.test.ts +3 -3
  293. package/tests/shell-render-cache.test.ts +134 -1
  294. package/tests/shell-sidebar-layout.test.ts +50 -0
  295. package/tests/short-check-routing-contract.test.ts +1 -1
  296. package/tests/skill-collision-prefixes.test.ts +3 -1
  297. package/tests/skill-registry-watcher.test.ts +17 -5
  298. package/tests/skill-registry.test.ts +47 -3
  299. package/tests/small-task-inline-contract.test.ts +37 -0
  300. package/tests/standalone-config-home.test.ts +324 -0
  301. package/tests/startup-banner.test.ts +5 -4
  302. package/tests/startup-home-repo.test.ts +34 -0
  303. package/tests/support/orchestrator-modules.ts +1 -0
  304. package/tests/task-size-routing-contract.test.ts +70 -10
  305. package/tests/test-scratch-contract.test.ts +102 -0
  306. package/tests/test-strength-contract.test.ts +36 -1
  307. package/tests/tool-batching-contract.test.ts +64 -0
  308. package/tests/verification-proportionality.test.ts +46 -0
  309. package/tests/verifier-admission.test.ts +154 -0
  310. package/tests/verify-agent-contract.test.ts +8 -8
  311. package/tests/voice-command.test.ts +773 -0
  312. package/tests/voice-install.test.ts +323 -0
  313. package/tests/voice-platform.test.ts +176 -0
  314. package/tests/voice-push-to-talk.test.ts +444 -0
  315. package/tests/voice-session.test.ts +434 -0
  316. package/tests/voice-settings.test.ts +49 -0
  317. package/tests/voice-ui.test.ts +97 -0
  318. package/tests/voice-worker.test.ts +445 -0
  319. package/tests/weak-model-economy-prompt.test.ts +32 -0
  320. package/tests/windows-hidden-processes.test.ts +30 -2
  321. package/tests/writer-edit-surface-scope.test.ts +3 -0
  322. package/tests/writer-feature-document-admission.test.ts +156 -0
  323. package/tests/yolo-customize.test.ts +5 -1
  324. package/tests/yolo-mode.test.ts +19 -1
  325. package/tests/yolo-session-policy-capture.test.ts +104 -0
  326. package/tests/yolo-temp-scratch.test.ts +71 -0
  327. package/scripts/mirror-odd-routing.mjs +0 -242
  328. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/orchestration/pi.md +0 -0
  329. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/schemas/lens.schema.json +0 -0
  330. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/schemas/refuter.schema.json +0 -0
  331. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/schemas/targeted-validator.schema.json +0 -0
  332. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/vectors/lens.json +0 -0
  333. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/vectors/refuter.json +0 -0
  334. /package/contracts/review-provider-contract-mirror/{v1.3.0 → v1.4.0}/bundle/vectors/targeted-validator.json +0 -0
@@ -49,7 +49,11 @@ Aliases are display hints, never authentication or routing identities.
49
49
 
50
50
  Aliases are optional envelope metadata in the existing branch-local state record,
51
51
  restored with `getBranch()` on start/reload/tree navigation. State replacement or
52
- withdrawal preserves them; no subject preserves both. Subject-only declarations
52
+ withdrawal preserves them; no subject preserves both. When a publication includes
53
+ `state.work` with an explicit `topic` and no `subject`, the topic refreshes Current
54
+ (the first such classification also sets Initial on a new record); an explicit
55
+ `subject` in the same publication wins, and state-only refreshes never re-derive
56
+ the alias from previously stored work. Subject-only declarations
53
57
  preserve state contents, recorded cwd and `recordedAt`: old progress is not a fresh
54
58
  status update. Publish subject and state together when changing work. New records
55
59
  use null/null until the first declaration; legacy records without aliases keep
@@ -104,7 +108,9 @@ receipts. Complete model-facing output and permissions remain unchanged.
104
108
 
105
109
  `orchestrator_session_id` also accepts optional `state`: strings named `objective`,
106
110
  `progress`, `decisions`, and `blockers` (2,048 UTF-8 bytes total). An object replaces
107
- all fields, `null` withdraws, and omission leaves the current record unchanged.
111
+ all fields, `null` withdraws, and omission leaves the current record unchanged. An object
112
+ without `progress` keeps the automatic todo progress line still published (dropped only
113
+ when the merge would exceed the byte budget); an explicit `progress` replaces it.
108
114
  Extra keys, controls, and oversized input are rejected before naming or persistence;
109
115
  records additionally fit 4 KiB. Never include credentials, internal instructions,
110
116
  or raw prompts. Whitelisting is not automatic secret redaction.
@@ -266,10 +272,14 @@ are unchanged; caller replacement prevents a stale `recorded` result.
266
272
  Call `orchestrator_consult` with required stable `recipient_session_id`, optional
267
273
  `kind: "metadata"` (default), and optional existing opaque catalog `cursor`.
268
274
  No free-form question, owner request, human picker or read-consent dialog is used
269
- for this profile's explicitly published data. Publish `subject` and `state` together
270
- before work beyond small direct tasks; update at task changes and completion. Keep
271
- small direct tasks exempt. Batch with setup/progress; do not add a model turn solely
272
- to publish or emit per-tool/token updates.
275
+ for this profile's explicitly published data. Declare a `subject` before work beyond
276
+ small direct tasks. Progress is published automatically: after each todo write the
277
+ runtime sets `progress` to `<done>/<total> done`, merged into the owner's curated
278
+ fields, so the model never spends a turn reporting status. Todo titles are private work
279
+ text and are never published; a cleared list removes the line, and a withdrawn state
280
+ stays withdrawn until the owner publishes again.
281
+ Keep small direct tasks exempt. Do not add a model turn solely to publish or emit
282
+ per-tool/token updates.
273
283
 
274
284
  Use `objective` for the goal, `progress` for current and next scope, and `blockers`
275
285
  for anything preventing progress. Use `state.work` for relevant area/topic and
@@ -0,0 +1,61 @@
1
+ # Gentle Music
2
+
3
+ `/gentle:music` plays [gentle-stream](https://github.com/Gentleman-Programming/gentle-stream) music from inside Gentle Shell.
4
+
5
+ ## Open the player
6
+
7
+ ```text
8
+ /gentle:music
9
+ /gentle:music rainy lo-fi night
10
+ ```
11
+
12
+ The command hands the whole terminal to gentle-stream's own TUI, the same way Pi's external editor (`ctrl+g`) does. Any text after the command is passed as the mood (`--mood`), and the session's current model is passed as `--model provider/id`, so gentle-stream interprets the mood with the model you already use.
13
+
14
+ Leave the player with:
15
+
16
+ | Key | Result |
17
+ | :-- | :-- |
18
+ | `b` | Back to Pi; the music keeps playing. |
19
+ | `q` | Back to Pi; the music stops. |
20
+
21
+ Pi returns exactly as it was: the draft, the transcript, and the layout are redrawn. While the player is open, `ctrl+c` goes to gentle-stream, not to Pi. If gentle-stream exits with an error, Pi shows a short notice.
22
+
23
+ Opening `/gentle:music` again while music plays attaches to the same music.
24
+
25
+ ## Control the music without leaving Pi
26
+
27
+ A single control word runs `gentle-stream ctl …` in the background and shows the result as a notice. The terminal stays with Pi.
28
+
29
+ | Command | Result |
30
+ | :-- | :-- |
31
+ | `/gentle:music next` | Next track. |
32
+ | `/gentle:music pause` | Pause. |
33
+ | `/gentle:music play` | Resume. |
34
+ | `/gentle:music stop` | Stop the music. |
35
+ | `/gentle:music status` | One line, for example `♪ Neon Rain · synthwave · playing`, or `nothing is playing`. |
36
+
37
+ Only an exact single word is a control word. `/gentle:music next to the sea` opens the player with the mood `next to the sea`.
38
+
39
+ ## Stopping on exit
40
+
41
+ When you quit Pi after using `/gentle:music`, Gentle Shell runs `gentle-stream ctl stop` so no music outlives the shell. It waits at most about 2 seconds. Starting a new session, resuming, forking, or reloading keeps the music playing.
42
+
43
+ ## Installation
44
+
45
+ Gentle Shell looks for gentle-stream in this order:
46
+
47
+ 1. `gentle-stream` on `PATH`.
48
+ 2. `uvx`, running gentle-stream straight from its repository (the first run downloads it).
49
+ 3. `uv`, through `uv tool run`.
50
+
51
+ With none of them, `/gentle:music` explains how to install and does nothing else. Install [uv](https://docs.astral.sh/uv/getting-started/installation/), or install gentle-stream permanently:
52
+
53
+ ```bash
54
+ uv tool install 'gentle-stream[samples] @ git+https://github.com/Gentleman-Programming/gentle-stream'
55
+ ```
56
+
57
+ ## Limits
58
+
59
+ - The player needs the interactive terminal. In RPC, JSON, and print modes, `/gentle:music` shows a notice and does nothing.
60
+ - There is no default shortcut.
61
+ - gentle-stream starts its own `gentle-shell` process to interpret moods; Gentle Shell does not pass its own launcher path.
@@ -36,6 +36,11 @@ In this order:
36
36
  `GENTLE_SHELL_HOME` directory is removed only when Gentle Shell created it
37
37
  (its `.gentle-shell-home` marker, or its setup record in
38
38
  `~/.gentle-shell/config.json`); otherwise it is listed as kept.
39
+ - `~/.gentle-shell/gentle-ai`: the isolated home's own settings (profiles,
40
+ banner and the other preferences). The `gentle-ai` folder next to a
41
+ `GENTLE_SHELL_HOME` is only listed as kept, since it may not be Gentle
42
+ Shell's. When `GENTLE_PI_CONFIG_HOME` names it, the config home rules
43
+ below apply instead.
39
44
  - `~/.gentle-shell/config.json`: the launcher settings.
40
45
  2. **Shared Gentle AI configuration**, only when you accept it (see below).
41
46
  3. **The `gentle-pi` package**, with the package manager that owns it:
@@ -43,7 +48,9 @@ In this order:
43
48
  `npm uninstall -g gentle-pi`.
44
49
  4. **`~/.gentle-shell`**, only when it is empty.
45
50
 
46
- The config home is `GENTLE_PI_CONFIG_HOME`, or `~/.pi/gentle-ai`.
51
+ The config home is `GENTLE_PI_CONFIG_HOME`, or `~/.pi/gentle-ai`: the one Pi
52
+ with Gentle AI, `--link` and custom homes use, and where the main channel keeps
53
+ its builds. The isolated home's own folder is removed with the data above.
47
54
 
48
55
  ## Shared configuration
49
56
 
@@ -8,10 +8,19 @@ Source map: [shell extension](../extensions/gentle-shell.ts), [shell bar](../lib
8
8
 
9
9
  ## Updating Pi safely
10
10
 
11
- Run `gentle-shell update` to update the Pi this launcher runs. Shell verifies npm/pnpm global listing JSON and canonical package roots before installing exactly one supplying package. This supports pnpm v11 linked stores without relying on `PNPM_HOME` containment. When the launcher runs its adjacent Pi peer, the supplier is the listed `gentle-pi` package itself: Shell is reinstalled at its current version so the package manager re-resolves the peer, because updating a separate global Pi never changes the peer a Shell install runs. A Pi found on `PATH` or through `GENTLE_SHELL_PI` is updated through its own listed global package; a package-manager shim is followed to the single `cli.js` it names. Pi and Shell are never combined into a comma install.
11
+ Run `gentle-shell update` to update the Pi this launcher runs. It also works when that Pi is older than the required minimum version, which every other command refuses. Shell verifies npm/pnpm global listing JSON and canonical package roots before installing exactly one supplying package. This supports pnpm v11 linked stores without relying on `PNPM_HOME` containment. When the launcher runs its adjacent Pi peer, the supplier is the listed `gentle-pi` package itself: Shell is reinstalled at its current version so the package manager re-resolves the peer, because updating a separate global Pi never changes the peer a Shell install runs. A main-channel Shell (`<version>-main.<sha12>`) is never published, so it is reinstalled from the tarball `gentle-shell upgrade --channel main` packed under `<config home>/main/packages/` (an absolute `GENTLE_PI_CONFIG_HOME`, else `~/.pi/gentle-ai`; a relative override is refused); when that tarball is missing, `update` installs nothing and names the rebuild path (`gentle-shell upgrade --channel release`, then `--channel main`), because `upgrade --channel main` alone is a no-op when already at the latest main. A Pi found on `PATH` or through `GENTLE_SHELL_PI` is updated through its own listed global package; a package-manager shim is followed to the single `cli.js` it names. Pi and Shell are never combined into a comma install.
12
12
 
13
13
  Unknown or ambiguous ownership, npm source/link packages, and pnpm groups shared with other top-level packages refuse without installation changes. Separate groups in one aggregated listing are allowed. After the install, Shell reads the supplied Pi version back from a fresh listing and reports whether it changed. pnpm installs only releases older than its `minimumReleaseAge` setting (pnpm 11 defaults to 4320 minutes), so a very recent Pi release is picked up once it is old enough; Shell reports that rule instead of overriding it. Package managers run from the system temporary directory so a project's `packageManager` pin never changes which pnpm answers. Use the supplying package manager for source checkouts or unsupported layouts. `gentle-shell update --extensions-only` remains an extension-only Pi command; prefix-bundled Pi still updates with `gentle-shell upgrade`. See [managing packages](readme-reference.md#managing-packages) for the ownership contract.
14
14
 
15
+ When the install fails, `update` names the package manager and the exact command it ran, then one sanitized line of that manager's own output. That line is the last error line (`Error:` or an `ERR_` code) in its stdout or stderr, stderr's when both have one, because npm prints its error on stderr while pnpm 11 prints `ERR_PNPM_*` on stdout. A warning on stderr never hides that error. Without any error line, it is the last line of stderr, else of stdout. Terminal escapes and control characters are removed, your home directory becomes `~`, and the line is at most 300 characters. For example:
16
+
17
+ ```text
18
+ gentle-shell update: pnpm (/usr/local/bin/pnpm) could not install /Users/you/.pi/gentle-ai/main/packages/gentle-pi-<version>.tgz
19
+ [ERR_PNPM_INVALID_VERSION_UNION] Invalid versions union. Found: "gentle-pi@file:...". Use exact versions only.
20
+ ```
21
+
22
+ `ERR_PNPM_INVALID_VERSION_UNION` during `update` usually means more than one pnpm is installed: an older pnpm on `PATH` cannot read the `allowBuilds` key a newer pnpm wrote to the global `pnpm-workspace.yaml`. Keep a single standalone pnpm.
23
+
15
24
  ## v2.6.0 workspace updates
16
25
 
17
26
  The [v2.6.0 release](https://github.com/Gentleman-Programming/gentle-pi/releases/tag/v2.6.0) makes the workspace state more durable and inspectable:
@@ -21,7 +30,7 @@ The [v2.6.0 release](https://github.com/Gentleman-Programming/gentle-pi/releases
21
30
  - The Agents List and Details views preserve the orchestrator/session hierarchy and completion, abort, and lost-exit history. Parent-child queries and notifications have an explicit handoff path, while model, effort, and usage stay observable per task.
22
31
  - Named `/gentle:profiles` atomically route the orchestrator separately from packaged and review roles; see the [technical reference](readme-reference.md#agent-model-profiles) for the profile model.
23
32
 
24
- The source checkout prepares `gentle-pi` `4.0.0` with a package-local Gentle AI `v4.1.1` pin; this does not imply that the package release has been published.
33
+ The source checkout prepares `gentle-pi` `4.0.0` with a package-local Gentle AI `v4.3.1` pin; this does not imply that the package release has been published.
25
34
 
26
35
  ## Shell interactions and runtime behavior
27
36
 
@@ -36,12 +45,12 @@ At 140 columns or wider, fullscreen defaults to a live header over a transcript-
36
45
  ```
37
46
 
38
47
  - The header carries live session data: session identity on the left (brand, cwd, branch, dirty count, model · effort · profile) and the two live counters right-aligned (the context gauge and session cost). The effort reads `auto` for NaN models that manage their reasoning depth themselves (DeepSeek V4 Flash, Qwen 3.8 Flash, MiMo), with a one-time notice explaining that the selected level does not change the depth. It never shows the working/thinking state or extension statuses — those stay in the prompt indicator and the Status surface. When the terminal is too narrow for everything, segments give way in a fixed order — profile, then effort, then the whole cwd/branch/dirty group — before the counters are touched; below that, only the brand survives, and below that the header renders nothing.
39
- - The right rail scrolls **Status → Changes → TODO**. Cards cache their rendered content until their own digest or an explicit invalidation changes. `neon` keeps the rounded border and accent title; `float` uses a tone background, a full-height `▎` accent, one-column transparent margins, painted padding above and below, and a blank painted separator between heading and body. Warning/error/success panels retain their tone colors.
48
+ - The right rail scrolls **Status → Changes → Agents → TODO**. Cards cache their rendered content until their own digest or an explicit invalidation changes. `neon` keeps the rounded border and accent title; `float` uses a tone background, a full-height `▎` accent, one-column transparent margins, painted padding above and below, and a blank painted separator between heading and body. Warning/error/success panels retain their tone colors.
40
49
  - The Status card carries Project (cwd, branch, session name, active profile), Changes, and Integrations (other extensions' statuses); its live digest detects changes without requiring an event. Model, effort, context, cost, and the per-model usage table live in the header instead — the header ticks every frame, so duplicating them in a card would just make that card repaint every frame too.
41
- - Gentle Agents is not part of the rail in any mode: its one card stays above the editor, where it already lived, with fixed right-aligned columns for `model · effort`, tokens, cost, and elapsed, each sized to the widest value among the shown tasks — so the numbers line up vertically even when one row's values are much shorter than another's. A queued task fills only the elapsed column with the word `queued`, leaving the other columns blank rather than overwriting the row.
50
+ - Gentle Agents follows TODO: while the fullscreen rail is showing, the Agents card moves into it and lists every shown task; without the rail (narrow fullscreen or regular mode) it stays above the editor. Its card has fixed right-aligned columns for `model · effort`, tokens, cost, and elapsed, each sized to the widest value among the shown tasks — so the numbers line up vertically even when one row's values are much shorter than another's. A queued task fills only the elapsed column with the word `queued`, leaving the other columns blank rather than overwriting the row.
42
51
  - The sidebar reuses its last frame until something it paints changes, so silent frames stay cheap; a per-section cache means one card's changing digest (or the header's) never forces an unrelated card to redraw.
43
52
  - Header placement is configurable. Above input, the float header has a full-width background, painted padding above and below its content, and a transparent `▔` bottom edge. Below input, the float footer groups Changes (when the session's roots have uncommitted work), header data, and locally owned integration statuses under one upper edge; it never duplicates statuses owned by the rail.
44
- - Below 140 columns, fullscreen has no sidebar. A configured top header owns the narrow status surface; otherwise the bottom bar owns it, unless Status is hidden. Regular mode keeps the compact one-line bottom bar and the above-editor Agents widget, without a fullscreen header or sidebar.
53
+ - Below 140 columns, fullscreen has no sidebar. A configured top header owns the narrow status surface; otherwise the bottom bar owns it, unless Status is hidden. The Agents and TODO cards then return above the editor. Regular mode keeps the compact one-line bottom bar and the above-editor Agents widget, without a fullscreen header or sidebar.
45
54
 
46
55
  The regular-mode compact bar replaces pi's three-line footer with a single line of segments:
47
56
 
@@ -66,8 +75,32 @@ The prompt follows the selected card style. `neon` keeps pi's editor in its roun
66
75
  - The petal is still with a `waiting for input` label in float while pi waits, spins with a `working` label while the agent works, and turns amber with a `queued` label when messages are waiting behind the current turn. In float it lives inside the painted top row; in neon it lives in the top rule. Pi's own "Working" row above the editor is hidden.
67
76
  - The empty-editor typing hint appears only while the editor is empty; Esc/queued hints remain inside the painted top row even with a nonempty float draft. Widths below 10 columns or a missing/unusable background keep the complete neon prompt path.
68
77
  - With Vim editing off, the prompt selects text natively: `shift+home` / `shift+end` select to the line edge and `alt+e` selects the whole draft; backspace, delete, a printable key or a paste replaces the selection in one undoable edit. `alt+a` also selects all, but only when no extension shortcut claims it: by default it opens Gentle Agents. A registered extension shortcut always wins over these selection keys.
78
+ - Pi's paste-image key (`app.clipboard.pasteImage`: `ctrl+v`, or `alt+v` on Windows) turns a clipboard image into an `[Image#N]` chip instead of a temp-file path. One Backspace or Delete removes the whole chip; cursor and word motions, word deletion, wrapping and Vim NORMAL treat it as one unit. On submit, every chip still in the draft is sent as a real image attachment, so the model sees it without calling `read`. A deleted chip is never sent. The bytes stay in memory; no temp file is written. See [Pasted images](#pasted-images).
69
79
  - If another extension already installed a custom editor, Gentle Shell leaves it alone.
70
80
 
81
+ ### Pasted images
82
+
83
+ While a draft holds chips, a strip above the prompt lists each one:
84
+
85
+ ```text
86
+ [Image#1] png · 1280×720 · 84 KB
87
+ ```
88
+
89
+ - **Preview:** terminals with an image protocol (Kitty, Ghostty, WezTerm, Warp, iTerm2) draw a small thumbnail under each label while the agent is idle. While it works, and in terminals or multiplexers that hide the protocol (such as tmux), the label alone is shown, so streaming never re-sends the image to the terminal.
90
+ - **Clipboard sources:** the native clipboard on macOS and Windows; `wl-paste` or `xclip` on Linux. On WSL, a Windows screenshot (`Win+Shift+S`) is read from the Windows clipboard through `powershell.exe`, because the Linux clipboard never receives it.
91
+ - **What stays Pi's:** files copied in a file manager, text, and image formats other than PNG, JPEG, WebP and GIF go through Pi's own paste handler unchanged.
92
+ - **Models without image input:** the strip warns before you send. If you send anyway, each chip becomes `[Image#N omitted: the current model does not accept images]` and a notice explains why, so nothing is dropped silently.
93
+ - **Numbering:** numbers keep counting up for the whole session, so a chip recalled from prompt history never points at a newer image. A recalled chip is plain text; paste the image again to attach it.
94
+ - **Sending while the clipboard is read:** reading the Windows clipboard on WSL takes about a second. If you send the message before it finishes, the image is discarded with a notice instead of landing in the next draft; paste again to attach it.
95
+ - **Vim NORMAL:** the paste key enters INSERT and pastes the chip. NORMAL motions step over a chip as one unit; an operator whose range covers a chip removes it whole.
96
+ - **Terminals that capture the paste key:** some terminals keep `ctrl+v` for their own paste, and nothing reaches Pi when the clipboard holds only an image (Warp on Windows does this). Bind a second key in `~/.pi/agent/keybindings.json`, then restart:
97
+
98
+ ```json
99
+ { "app.clipboard.pasteImage": ["ctrl+v", "alt+v"] }
100
+ ```
101
+
102
+ ### Changes
103
+
71
104
  Changes shows the **current Git state** — working tree against HEAD, untracked files included — of the session's repository and of every worktree or repository its subagents used that still exists. Nothing is scanned at startup; the list fills at the first turn end or when the panel opens, then refreshes at each turn end and while the panel is open. Fullscreen, the sidebar, and mouse interaction are unchanged.
72
105
 
73
106
  ```text
@@ -90,12 +123,13 @@ Captured evidence (`gentle-pi.session-change/v1`) is still stored for session st
90
123
 
91
124
  ### Browse changes
92
125
 
93
- `/gentle:changes` or `alt+g` opens the two-pane viewer. Worktrees are accordion groups on the left; each file row leads with its name, then its line counts and its directory. Selecting a file shows its full path on the first row of the right pane (clipped from the left so the name stays visible) and its diff against HEAD below it; untracked files show their full content.
126
+ `/gentle:changes` or `alt+g` opens the two-pane viewer full screen, like Gentle Agents. Worktrees are accordion groups on the left; each file row leads with its status marker (`M` modified, `A` new and staged, `U` new and untracked, `D` deleted, `R` renamed), then its name, its line counts and its directory. Selecting a file shows its full path on the first row of the right pane (clipped from the left so the name stays visible) and its diff against HEAD below it; untracked files show their full content.
94
127
 
95
128
  - `j`/`k` or arrows navigate. On a group, Enter, Space or Right expands it; Left returns to its parent or collapses it. `ctrl+j/k` or Page Up/Down scroll the diff; Escape or `q` closes.
129
+ - `F` toggles diff-only mode at any width: the file list and its separator hide so the diff uses the full width. There `j`/`k` still move between files (across worktrees; the path row shows which), the scroll keys and the wheel scroll the diff, `o`/Enter and `r` keep working, the first Escape returns to the file list, and `q` closes. Every opening starts with the file list visible.
96
130
  - Fullscreen left-click selects files; mouse wheels scroll the file list and diff independently. Hovering an unselected row (worktree or file, in either pane's list) paints it in the same shared hover role every clickable surface in the shell uses; it never opens or selects the file, and never overrides the already-selected row's own role.
97
131
  - Opening, pressing `r`, and the overlay's refresh cadence re-read each root's Git status; a same-line-count edit reloads the open diff.
98
- - On a file, `o` or Enter opens the actual current file in `$VISUAL` or `$EDITOR`, with its worktree as cwd.
132
+ - On a file, `o` or Enter opens the actual current file in `$VISUAL` or `$EDITOR`, with its worktree as cwd. Editor launches pass paths as literal arguments, never through a shell. On Windows, configure a direct executable (for example `notepad.exe`); `.cmd`/`.bat` editor shims are refused. Launch failures appear as warnings after the terminal UI is restored. This also applies when opening an Agents session transcript. Editor commands retain literal-space splitting: quoted executable paths and shell expressions are not supported.
99
133
  - `GENTLE_PI_SHELL_CHANGES_KEY` rebinds the shortcut; `off` disables it. `GENTLE_PI_SHELL_CHANGES_POLL_MS` controls how often the open overlay re-reads Git. `GENTLE_PI_SHELL_CHANGES_WATCH_MS` no longer enables filesystem polling.
100
134
  - No uncommitted changes in the session's roots means no widget and an informational notice.
101
135
 
@@ -254,7 +288,7 @@ In the isolated Gentle Shell home, `settings.json` does not declare gentle-pi; t
254
288
  - Presence refresh is paged while the overlay is open. Graceful shutdown withdraws an instance; after abrupt closure its last heartbeat may remain visible for up to 15 seconds plus the time to complete the next directory refresh. A recent heartbeat is a heuristic, not proof that a process is alive. Same-profile, same-user processes share retained activity text; this is not an authorization channel.
255
289
  - `alt+s` confirms stopping the current active or queued subagents owned by the current process. `GENTLE_PI_AGENTS_STOP_KEY` rebinds it; `off` disables it.
256
290
  - Finished tasks are written to `~/.pi/agent/gentle-agents/tasks/` (one JSON per task, newest `history_max_tasks` kept, default 200) and come back on demand for `subagent_result` and `subagent_continue`; an id looked up this way from an unrelated session never enters the overlay or becomes cancellable. Child sessions live under `~/.pi/agent/gentle-agents/sessions/`.
257
- - `ctrl+shift+a` collapses the card to its first row (`GENTLE_PI_AGENTS_KEY`), `GENTLE_PI_AGENTS_VIEW_KEY` rebinds the overlay, `GENTLE_PI_AGENTS_PI` overrides the pi command used for children, and `GENTLE_PI_AGENTS=0` disables the tools and the card.
291
+ - `ctrl+shift+a` or a left click on the card's `▾ Collapse` / `▸ Expand` header control collapses the card to its first row (`GENTLE_PI_AGENTS_KEY` rebinds the key), `GENTLE_PI_AGENTS_VIEW_KEY` rebinds the overlay, `GENTLE_PI_AGENTS_PI` overrides the pi command used for children, and `GENTLE_PI_AGENTS=0` disables the tools and the card.
258
292
 
259
293
  ### Background jobs
260
294
 
@@ -291,7 +325,7 @@ The `todo` tool and its card replace the third-party todo extension (remove `npm
291
325
  The runtime helps keep the list current beyond a static tool description:
292
326
 
293
327
  - `write` replaces the whole list in one call, so the model rewrites the plan instead of patching it; `add`, `update`, `clear`, and `list` remain for single moves.
294
- - Each agent run's system prompt carries the same byte-stable rules block (in_progress before starting, done right after finishing, update before ending the run), so the cached prompt prefix never changes because of the list. While tasks stay open, the current list reaches the model as a hidden, request-local message at the end of each request; it is never persisted and never enters the system prompt, so status, title, note and ordering changes cost only the tail of the request.
328
+ - Each agent run's system prompt carries the same byte-stable rules block (in_progress before starting, done right after finishing, update before ending the run), so the cached prompt prefix never changes because of the list. While tasks stay open, the current list reaches the model as a hidden conversation message appended whenever the list changes, and closing the list appends a hidden "no open tasks" marker; the list never enters the system prompt and requests stay append-only, so status, title, note and ordering changes cost only the tail of the conversation and keep the provider prompt cache (Anthropic breakpoints, openai-codex input deltas) warm. When the conversation no longer holds the current list (after compaction, branch navigation, or in a session recorded before this behavior), the next request carries it once and it is appended again.
295
329
  - A list that goes two agent runs untouched while pending or in-progress tasks remain turns amber with `stale · N turns` on the card; that age is shown to the human only.
296
330
  - Within a long run, after four tool-use model turns without a successful todo write, the next model request receives one hidden, request-local reminder to review the plan. A successful `write`, `add`, `update`, or `clear` resets and rearms it; `list` and rejected writes do not. The turn containing the write does not count toward the threshold. Empty, finished and blocked-only plans receive no reminder. Reminder tracking restarts when the session loads; it does not change the existing card freshness, persist a message, start an extra model turn, change task statuses, or connect to subagents.
297
331
 
@@ -328,6 +362,43 @@ Expanded cards reserve at most one third of the terminal height (up to 16 rows,
328
362
  - Only top-level session files are read: subagent runs are not included, and the panel says so. The first opening scans every file; later openings reread only files that changed.
329
363
  - There is no default shortcut. Set `GENTLE_PI_STATS_VIEW_KEY` (for example `alt+t`) to bind one; `off` or empty leaves it unbound.
330
364
 
365
+ ### Gentle Design
366
+
367
+ `/gentle:design <brief>` asks the session model to design the brief with the bundled `gentle-design` skill. It works with any provider: the model writes several clearly different directions (3 by default), each labeled with its tradeoff, as self-contained HTML artboards under `design/<slug>/`, plus a `design.json` manifest. Artboards inline their CSS, JS, and SVG and use system fonts, so they open offline in any browser. When `design/system.md` exists, the skill follows its tokens. Ask for changes to one artboard and only that file changes; "save and try a different approach" adds an artboard and keeps the others.
368
+
369
+ You do not need the command: ask in plain language for a screen, mockup, landing page, or a few visual directions, and the session uses the gentle-design skill by default with any provider. After it writes or changes a design under `design/<slug>/`, the model opens the canvas on it (or refreshes the running one) through the `gentle_design` tool, unless you ask it not to. The same tool lists the designs and their artboards, shows whether the canvas is running and at which URL, stops the canvas, and starts the handoff of an artboard (`<slug>/<artboard>`) to the project's real stack, using exactly the text `/gentle:design implement` sends. Briefs and the design-system sync go through the skill itself. The `/gentle:design` subcommands remain available as optional shortcuts, and they share the same canvas server as the tool. Delegated subagents (`GENTLE_PI_AGENTS_CHILD=1`) do not get the default design flow.
370
+
371
+ The canvas opens in navigation mode: the mouse wheel, trackpad, and drag always pan or zoom the canvas, even over an artboard, and Ctrl/Cmd + wheel zooms. Hovering an artboard shows "Click to use this design"; clicking it enters focus mode, which shows that artboard at its designed width at 100% and lets it own the pointer and keyboard, so its own scrolling, hovers, buttons, and inputs behave like the real page. While an artboard is in focus, the comments panel hides to make room, the rest of the canvas is dimmed and does not pan or zoom, and an artboard taller than the window scrolls inside its frame. To return to navigation mode, press the floating "Back to canvas" button or `Shift+Esc`, which works even while typing inside the artboard; plain `Esc` stays with the design, and the previous zoom, position, and comments panel are restored. Comment mode keeps working in both modes: a click picks an element instead of entering focus mode.
372
+
373
+ - While the agent is busy, the run is queued as a follow-up.
374
+ - `/gentle:design open [slug]` shows a design on a local canvas in the default browser: every artboard side by side at its manifest size, with its title and tradeoff; zoom with the buttons or Ctrl/Cmd + wheel, pan by dragging or scrolling, and Fit to the window. The canvas reloads an artboard when its file changes and the whole design when `design.json` changes. Without a slug it opens the most recent design. The URL is always printed; when the browser cannot be opened, open it manually.
375
+ - `/gentle:design` with no arguments opens the most recent design (by `design.json` modification time) the same way. When the project has no design yet but has `design/system.html`, it and `open` show the canvas with only the system board; with neither, they print usage.
376
+ - Comments: turn on Comment mode, click an element in an artboard, and type a comment. Every comment is saved in `design/<slug>/comments.json` with its artboard, CSS selector, text excerpt, date, and status (`open` or `resolved`), so any agent or later session can read it.
377
+ - **Send now** (the default) also sends the session one message with the design, the comment id, the artboard file, the selector, the excerpt, and the comment; while the agent is busy, it is queued as a follow-up.
378
+ - A comment can carry one screenshot, useful for what only shows between states, such as an animation or a transition: paste an image into the comment popover, drop one onto it, or use **Attach screenshot** (PNG, JPEG, WebP, or GIF, up to 5 MB). It is saved as `design/<slug>/.screenshots/<id>.<ext>`, named in the comment's optional `screenshot` field, shown as a thumbnail in the Comments panel, and reaches the session as an image attached to the comment message (a Send all message attaches at most 6; the rest are named for the read tool).
379
+ - **Collect** only saves the comment. **Send all (N)** then sends every open, unsent comment as one message. The canvas remembers the mode while the canvas server runs.
380
+ - A numbered pin marks each commented element and follows zoom and pan. The Comments panel lists open and resolved comments; selecting one highlights its pin and scrolls the canvas to it, and each comment can be resolved or reopened there. A comment whose element no longer exists shows as **Detached**.
381
+ - The agent applies a comment by editing only that artboard, then marks it resolved with the `gentle_design_comments` tool (`list` and `resolve`), or by editing `comments.json` when it has no tool. The canvas updates live when the file changes, whoever wrote it. Pi's `sendUserMessage` is fire-and-forget, so the canvas reports a delivery as failed (the comment stays saved and unsent) only when sending throws synchronously; a failure later inside the session is not visible to the canvas.
382
+ - `/gentle:design stop` closes the canvas; quitting or replacing the session closes it too. There is one canvas server per session, and a second `open` reuses it.
383
+ - `open` reuses the canvas tab that is already open: while a canvas page is connected, the command and the `gentle_design` tool tell that page to show the requested design and reload it from disk (keeping zoom, pan, and focus mode when it is the same design), and report "Design canvas refreshed" with the URL. The browser opens a new tab only when no canvas page is connected, for example after you closed it or when the server had to start.
384
+ - `/gentle:design sync` (it takes no arguments; extra words warn and send nothing) asks the session model to capture the project's design system with the same skill (queued as a follow-up while the agent is busy). It reads, and never edits, the project's design sources: CSS custom properties (`:root`, `@theme`, `[data-theme]`), the Tailwind config or v4 `@theme`, component library folders, existing token files, and fonts. It writes two files:
385
+ - `design/system.md`: colors (token, value, usage), typography, spacing, radius, shadows, and component rules, each with the path it came from. Later design runs use only these tokens, and the skill checks every finished artboard's colors and fonts against them and fixes any deviation.
386
+ - `design/system.html`: a self-contained 1440 px artboard that renders those tokens and the core components.
387
+
388
+ When the project has no design sources, the model says so and proposes a minimal starter system instead of inventing project tokens.
389
+
390
+ You rarely need to run `sync` yourself. Before a new design, the skill calls the `gentle_design` tool's `list` action, which reports the project's design sources (the first 20 paths and a total) and the state of `design/system.md`. When the project has design sources but no `design/system.md`, the model syncs first, says so in one line, and then designs with those tokens. When the project has no design sources, it designs freely. When a source changed after `design/system.md` was written (by modification time), the model names it, says the tokens may be outdated, and offers to sync again; it re-syncs only with your OK. A design source is a `tailwind.config.{js,cjs,mjs,ts}`; a `.css`, `.scss`, or `.pcss` file that uses `@theme` or declares a custom property in a `:root` or `[data-theme]` rule; a `.json`, `.js`, `.ts`, or `.css` file whose name has `tokens` as a whole word (`tokens.json`, `design-tokens.ts`, `theme.tokens.css`; never `token.ts`, `refreshToken.ts`, `tokenizer.ts`, or a `.test`/`.spec` file); or a `theme.js`/`theme.ts` that exports a `colors` key. The detection walk skips `node_modules`, `dist`, `build`, `out`, `coverage`, every dot-directory (such as `.git`, `.next`, `.worktrees`), and the project's own `design/` folder; it does not follow symlinks, goes at most 6 directories deep, stops after 5000 files, and reads at most 256 KiB of each file.
391
+ - When `design/system.html` exists, the canvas shows it as the first board of every design, labeled **Design system** with "Project tokens (design/system.md)", and reloads it when the file changes. Comment mode does not apply to that board (its tooltip says so): change the system by updating the design sources and running `sync` again.
392
+ - `/gentle:design implement <slug>/<artboard>`, or **Implement this** on an artboard's header in the canvas (after a confirm step; never on the system board), sends the session one handoff message, queued as a follow-up while the agent is busy. Both send the same text: the artboard path, title, and tradeoff; an instruction to build it in the project's real stack with the artboard as the visual spec, mapped to existing components rather than copied; `design/system.md` as the token source when it exists; and every open comment on that artboard, to apply and then resolve with `gentle_design_comments`. An unknown design or artboard warns with the valid `<slug>/<artboard>` values and sends nothing. An invalid `feature` link in `design.json` is reported as a warning, and the handoff goes out unlinked. The handoff itself commits nothing.
393
+ - ODD link: a design that comes from a tracked ODD feature records it in `design.json` as `"feature": "odd/tasks/<feature>.md"`, and the skill appends a Log entry naming the design to that document; small, untracked work has no `feature` and stays standalone. The canvas top bar shows **Feature: <path>** for a linked design, and the handoff asks to track the implementation in that document instead of sizing it from scratch. Only a relative `odd/tasks/<name>.md` path is accepted; any other value is ignored and reported as a warning in the canvas.
394
+ - Handoff state: every handoff (the canvas button, the command, or the tool's `implement`) is recorded in `design/<slug>/handoffs.json` before it is sent, and the handed-off artboard becomes the design's **chosen** direction: its header shows a **Chosen** badge and an accent frame, and the other artboards show **Alternative**. Handing off another artboard moves the mark. After **Send**, a toast confirms it, and the artboard's header shows **Queued** (the agent was busy) or **Implementing…** (it was idle), then **In progress** and **Implemented ✓** as the agent reports them with the `gentle_design` tool's `handoff` action, which the handoff message asks it to call. The canvas updates live, the badge names the linked feature document, and `list` reports each design's chosen artboard and handoff states. When the agent marks an artboard implemented with the `previewUrl` of the running app, **Compare** shows the artboard and the app side by side at the artboard's size, at 100%, with **Scale to fit** when the pair is wider than the window; exit with **Back to canvas** or `Shift+Esc`. The preview must be an `http`/`https` URL on `localhost`, `127.0.0.1`, or `[::1]` (any port, no credentials, at most 2048 characters); the tool and the server refuse anything else. Prefer `localhost` or `127.0.0.1`: CSP has no IPv6 source form, so browsers do not frame a `[::1]` preview, and Compare says so and offers the new tab. An app that refuses to be framed (`X-Frame-Options` or `frame-ancestors`) still opens with **Open in new tab**, which the Compare view always shows.
395
+
396
+ The canvas server binds `127.0.0.1` on a random port and needs a random per-server token in every URL. It rejects any `Host` other than its own loopback address, accepts every write (comments, Send all, resolve/reopen, Implement) only with its own `Origin` (`http://127.0.0.1:<port>` or `http://localhost:<port>`), a JSON body, and bounded lengths, keeps at most 500 comments per design, and serves only files under `design/` in the session cwd (design folders, plus exactly `design/system.html` for the system board), resolved by real path so neither `..` nor a symlink can escape. Artboards run in iframes sandboxed without `allow-same-origin`, so they cannot read the canvas or post comments themselves. The canvas may frame only loopback origins (its `frame-src`), and the Compare preview frame keeps its own origin (`allow-scripts allow-same-origin allow-forms allow-popups`, never top navigation) only because it is another origin than the canvas: the canvas refuses a preview on its own port, and sends no referrer, so the app never sees the token. No other network traffic is involved. The server and the tool write `comments.json` and `handoffs.json` one at a time through an atomic replace, and never overwrite a file they cannot parse.
397
+
398
+ ### Gentle Music
399
+
400
+ `/gentle:music [mood]` hands the terminal to the [gentle-stream](https://github.com/Gentleman-Programming/gentle-stream) player, like Pi's external editor, passing the mood and the session model. In the player, `b` returns to Pi with the music playing and `q` returns and stops it. `/gentle:music next`, `pause`, `play`, `stop`, and `status` control the music without leaving Pi. Quitting Pi after using the command stops the music. gentle-stream runs from `PATH`, or through `uvx`/`uv` when it is not installed. See [Gentle Music](gentle-music.md).
401
+
331
402
  ### Bridge providers
332
403
 
333
404
  Idle Claude Bridge continuation uses the normal user-prompt lifecycle so prompt preparation and tool declarations are retained. Gentle Agents hides only its exact, uniquely generated reserved wake in Pi's interactive transcript; child result and query cards remain visible. Native providers keep their hidden `display: false` custom wake.
@@ -59,7 +59,7 @@ it lets the window close.
59
59
  Current requirements come from `package.json` and
60
60
  [`gentle-ai-installer.mjs`](../scripts/gentle-ai-installer.mjs): Node ≥22.19.0,
61
61
  Pi ≥1.2.0, pnpm acquisition 11.1.1, Gentle Shell package 4.0.0 and package-local
62
- Gentle AI 4.1.1. Windows native source builds require Go ≥1.25.10 when the
62
+ Gentle AI 4.3.1. Windows native source builds require Go ≥1.25.10 when the
63
63
  required usable native binary is missing. A reusable binary does not require Go.
64
64
  When a build needs Go and the user's Go is missing, older or unchecked, the installer uses
65
65
  its own [pinned Go](#pinned-go) instead of blocking.
@@ -787,9 +787,13 @@ publishes main builds, so main is built on this computer
787
787
  Gentleman-Programming/gentle-ai (GitHub API, raw SHA), runs
788
788
  `go install github.com/gentleman-programming/gentle-ai/v4/cmd/gentle-ai@<sha>`
789
789
  in a sealed Go environment (`GOPROXY=https://proxy.golang.org`,
790
- `GOSUMDB=sum.golang.org`, `GOTOOLCHAIN=local`, `GOFLAGS=-modcacherw`), requires
791
- the binary's version to end in that commit's first 12 characters, keeps it
792
- under `<config home>/main/gentle-ai/<sha>/` and registers it as the
790
+ `GOSUMDB=sum.golang.org`, `GOTOOLCHAIN=local`, `GOFLAGS=-modcacherw`),
791
+ asks Go (`go list -m -json`, same environment) which module version that
792
+ commit is (a release tag such as `v4.2.0`, or a pseudo-version) and requires
793
+ its origin to be that exact commit, requires the binary to embed that module
794
+ version (`go version -m`) and to report it, all in the `.build` work
795
+ folder, and only then moves it to `<config home>/main/gentle-ai/<sha>/`
796
+ (a failed rebuild leaves an already registered build in place) and registers it as the
793
797
  `gentle-pi.dev-binary/v1` override, which never falls back to the pinned
794
798
  binary silently.
795
799
  2. `install-shell-main`: downloads the latest `main` commit's source tarball,
@@ -812,8 +816,28 @@ publishes main builds, so main is built on this computer
812
816
  a version it cannot check) it builds with the pinned Go under
813
817
  `<config home>/tools/go`, downloading and verifying it there with the same
814
818
  `acquireGo` as the wizard when no earlier run published it, and only when
815
- Gentle AI is rebuilt. A failed download stops with `main-requires-tools`
816
- before anything is built; the user's Go is never run for the build.
819
+ Gentle AI is rebuilt. A failed download stops the Gentle AI build with
820
+ `main-requires-tools` before it starts (a main Shell that moved is still
821
+ installed, as below); the user's Go is never run for the build.
822
+ - When the Gentle AI step of `gentle-shell upgrade --channel main` fails (the
823
+ build, its verification, or getting the pinned Go) and the main Shell moved,
824
+ the upgrade still packs and installs that Shell, records no channel, prints
825
+ `Updated Gentle Shell to the latest main (<sha12>); Gentle AI was not updated.`
826
+ and exits 1 with the original error (code and message) followed by
827
+ `; Gentle Shell was updated to main <sha12> but Gentle AI was not: run
828
+ gentle-shell upgrade --channel main to finish`. The retry then rebuilds Gentle
829
+ AI with the new Shell's code, so a fix in the main-channel upgrade path reaches
830
+ an install whose own copy of it is broken; a cause the new Shell does not fix
831
+ (a Go download that keeps failing, for example) still has to be resolved first. Until then Gentle AI stays the
832
+ previously registered main build or the pinned binary: a rejected build is
833
+ never registered. When the Shell install fails as well, its error is reported
834
+ with `; Gentle AI was not updated either (<Gentle AI error>)`. An unexpected
835
+ error that has no main-channel code (a filesystem `EACCES`, for example) is
836
+ reported as `main-upgrade-incomplete` with its own message and the same
837
+ suffix, so neither the retry advice nor either error is lost. When the Shell
838
+ is already current, a failed Gentle AI step fails as before, with nothing
839
+ installed or recorded. The wizard's runner is the one bundled with the
840
+ downloaded installer and does not get this behavior from a newer main.
817
841
  - Trust: Gentle AI source is verified by Go's checksum database; the Gentle Shell
818
842
  source is fetched over TLS from GitHub by exact commit SHA, with no pinned
819
843
  digest. Main builds are development builds.
@@ -1029,6 +1053,13 @@ again, or add `$PNPM_HOME/bin` to PATH manually. For `acquire-go`, a detail
1029
1053
  starting with `Conflicting Go destination: ` selects
1030
1054
  `guidance.goDestinationConflict`: a folder from an earlier, interrupted run is in
1031
1055
  the way and is never replaced; remove that folder and run the installer again.
1056
+ For `install-version` and `install-global`, a detail with `spawn UNKNOWN` selects
1057
+ `guidance.codeIntegrityBlocked`: libuv reports a Windows code integrity refusal
1058
+ (Smart App Control, CodeIntegrity event 3077) of the `gentle-ai.exe` that
1059
+ gentle-pi's postinstall builds as `spawn UNKNOWN`. Windows has no per-program
1060
+ exception, so the guidance offers WSL or turning Smart App Control off (on
1061
+ Windows 11 it cannot be turned back on without reinstalling Windows) instead of
1062
+ network and registry advice.
1032
1063
  `scripts/installer-runner.mjs` exports the frozen
1033
1064
  arrays `blockedReasons` and `failedSteps`; a test requires guidance for exactly
1034
1065
  those entries, and the runner tests check that every reason and step their
@@ -52,15 +52,16 @@ Changing the default does **not** change the current session. To return this ses
52
52
  | --- | --- |
53
53
  | **Normal** | Existing permission behavior; the default when no valid global preference exists. |
54
54
  | **Auto** | A separate reviewer using the current session model checks eligible actions against live user intent before execution. Local reads are classified too; locality does not exempt an action from explicit restrictions. |
55
- | **YOLO** | Standing permission for ordinary already-authorized work and delivery; no Auto classifier. Destructive and independent consent boundaries remain. [Full YOLO details](yolo-mode.md). |
55
+ | **YOLO** | Standing permission for ordinary already-authorized work and delivery; no Auto classifier. Destructive and independent consent boundaries remain, except recursive removal of the session's own [temp scratch](yolo-mode.md#temp-scratch-removal). [Full YOLO details](yolo-mode.md). |
56
+ | **Super Yolo** | No permission prompts at all, including data-loss confirmations and configured guardrail actions. The only remaining line is the sensitive-path guard: read/write/edit of `.env`, `.ssh`, keychains, `*.pem/*.key/*.p12/*.pfx`, `secrets/` and cloud credential files stays hard-blocked. Code-level catastrophic denies (`rm -rf /`, `--no-preserve-root`, `git reset --hard`, forced clean, force push) also remain. |
56
57
 
57
58
  ## Commands and menu
58
59
 
59
60
  | Command | Effect |
60
61
  | --- | --- |
61
- | `/gentle:mode normal`, `auto`, or `yolo` | Select exactly one mode for the current interactive primary session. |
62
+ | `/gentle:mode normal`, `auto`, `yolo`, or `super-yolo` | Select exactly one mode for the current interactive primary session. |
62
63
  | `/gentle:mode status` or `/gentle:mode` | Show current mode and saved default. |
63
- | `/gentle:mode default normal`, `auto`, or `yolo` | Save the default for new primary sessions, leaving the current mode unchanged. |
64
+ | `/gentle:mode default normal`, `auto`, `yolo`, or `super-yolo` | Save the default for new primary sessions, leaving the current mode unchanged. |
64
65
  | `/gentle:yolo enable`, `disable`, or `status` | Existing shortcut; enable selects YOLO, disable selects Normal. |
65
66
 
66
67
  In `/gentle:customize` → **Editor**, use **Session permissions** to change the current mode, or **Default permissions** to save a future-session preference. The original **YOLO: ON/OFF · session only** row still toggles the live mode; it does not save a default. Browsing, previews, and closing the menu do not grant permission.
@@ -116,6 +117,10 @@ The **Auto checks** status and `gentle-auto-permission` session entries account
116
117
 
117
118
  The dedicated `permission-mode.json` in Gentle Pi's resolved user config home contains a strict versioned preference. Saving uses a private atomic replacement; malformed or unreadable existing preferences fall back to Normal and refuse an overwrite until repaired. Use the human command/menu path rather than asking model tools to edit this authority file.
118
119
 
120
+ Model `write`/`edit` calls keep the config home protected except for the main-channel updater's `dev-binary.json`, `channel.json`, `main/` and `tools/go`. Those destinations select or build executable code, so they still require authorization under the current mode's ordinary checks; Auto classifies them and can deny an update. They are not automatically allowed. Permission preferences, global and project `runtime-guardrails.json`, their parent directories and symlink aliases resolving to them stay blocked even if a classifier would allow the action. Other config-home state, including model routing, persona and privacy preferences, remains protected.
121
+
122
+ Shell recognition remains deliberately conservative: commands mentioning the config home or policy filenames can still be blocked. This change does not relax shell protection, authorize routing around a denial, or turn the hook into a sandbox.
123
+
119
124
  Live mode selection is bound to the SessionManager, session ID and canonical Git clone identity, or the canonical workspace directory outside Git. Session replacement, shutdown and reload revoke live callbacks and pending actions. A newly initialized primary session may select its saved default; this is a new application of the global preference, not restoration of an old session grant. Disable the saved default as well if future sessions must stay Normal.
120
125
 
121
126
  ## Limits