@cmetech/otto 1.1.1 → 1.2.5

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 (433) hide show
  1. package/dist/coworker/persona-commands.d.ts +1 -0
  2. package/dist/coworker/persona-commands.js +5 -0
  3. package/dist/coworker/persona-commands.test.d.ts +1 -0
  4. package/dist/coworker/persona-commands.test.js +45 -0
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/extensions/coworker-artifacts/artifacts-command.js +31 -0
  7. package/dist/resources/extensions/coworker-artifacts/artifacts-singleton.js +17 -0
  8. package/dist/resources/extensions/coworker-artifacts/extension-manifest.json +13 -0
  9. package/dist/resources/extensions/coworker-artifacts/index.js +125 -0
  10. package/dist/resources/extensions/coworker-artifacts/list-tool.js +27 -0
  11. package/dist/resources/extensions/coworker-artifacts/open-tool.js +25 -0
  12. package/dist/resources/extensions/coworker-memory/extension-manifest.json +13 -0
  13. package/dist/resources/extensions/coworker-memory/index.js +219 -0
  14. package/dist/resources/extensions/coworker-memory/memorize-tool.js +10 -0
  15. package/dist/resources/extensions/coworker-memory/memory-command.js +157 -0
  16. package/dist/resources/extensions/coworker-memory/memory-singleton.js +55 -0
  17. package/dist/resources/extensions/coworker-memory/recall-tool.js +18 -0
  18. package/dist/resources/extensions/coworker-memory/session-hooks.js +45 -0
  19. package/dist/resources/extensions/coworker-scratchpad/attach-banners.js +53 -0
  20. package/dist/resources/extensions/coworker-scratchpad/extension-manifest.json +13 -0
  21. package/dist/resources/extensions/coworker-scratchpad/format-age.js +9 -0
  22. package/dist/resources/extensions/coworker-scratchpad/helpers.js +38 -0
  23. package/dist/resources/extensions/coworker-scratchpad/index.js +199 -0
  24. package/dist/resources/extensions/coworker-scratchpad/mime-bundle.js +20 -0
  25. package/dist/resources/extensions/coworker-scratchpad/scratchpad-tool.js +118 -0
  26. package/dist/resources/extensions/coworker-scratchpad/session-sidecar.js +60 -0
  27. package/dist/resources/extensions/coworker-scratchpad/sp-command.js +597 -0
  28. package/dist/resources/extensions/coworker-scratchpad/workspace-pointer.js +41 -0
  29. package/dist/resources/extensions/coworker-scratchpad/workspace-root.js +17 -0
  30. package/dist/resources/extensions/coworker-vault/audit-command.js +35 -0
  31. package/dist/resources/extensions/coworker-vault/connect-command.js +42 -0
  32. package/dist/resources/extensions/coworker-vault/datasource-command.js +50 -0
  33. package/dist/resources/extensions/coworker-vault/extension-manifest.json +12 -0
  34. package/dist/resources/extensions/coworker-vault/index.js +171 -0
  35. package/dist/resources/extensions/coworker-vault/test-helpers.js +86 -0
  36. package/dist/resources/extensions/coworker-vault/vault-singleton.js +24 -0
  37. package/dist/resources/extensions/otto/commands/release-notes/_data.js +83 -0
  38. package/dist/resources/extensions/otto/commands/release-notes/command.js +15 -4
  39. package/dist/resources/extensions/otto/index.js +31 -6
  40. package/dist/resources/extensions/shared/coworker-paths.js +8 -0
  41. package/dist/resources/extensions/slash-commands/{audit.js → audit-codebase.js} +4 -4
  42. package/dist/resources/extensions/slash-commands/extension-manifest.json +1 -1
  43. package/dist/resources/extensions/slash-commands/index.js +2 -2
  44. package/dist/resources/extensions/subagent/index.js +8 -1
  45. package/dist/resources/extensions/subagent/launch.js +37 -5
  46. package/dist/resources/extensions/subagent/run-store.js +1 -0
  47. package/dist/resources/extensions/workflow/bootstrap/register-extension.js +2 -0
  48. package/dist/resources/extensions/workflow/bootstrap/register-hooks.js +10 -0
  49. package/dist/resources/extensions/workflow/health-widget-core.js +1 -1
  50. package/dist/resources/extensions/workflow/persona-status.js +87 -0
  51. package/package.json +26 -10
  52. package/packages/contracts/package.json +1 -1
  53. package/packages/coworker-artifacts/dist/artifact-store.d.ts +25 -0
  54. package/packages/coworker-artifacts/dist/artifact-store.js +187 -0
  55. package/packages/coworker-artifacts/dist/dir-snapshot.d.ts +7 -0
  56. package/packages/coworker-artifacts/dist/dir-snapshot.js +54 -0
  57. package/packages/coworker-artifacts/dist/errors.d.ts +18 -0
  58. package/packages/coworker-artifacts/dist/errors.js +37 -0
  59. package/packages/coworker-artifacts/dist/index.d.ts +7 -0
  60. package/packages/coworker-artifacts/dist/index.js +7 -0
  61. package/packages/coworker-artifacts/dist/readme-renderer.d.ts +5 -0
  62. package/packages/coworker-artifacts/dist/readme-renderer.js +47 -0
  63. package/packages/coworker-artifacts/dist/resolve-uri.d.ts +3 -0
  64. package/packages/coworker-artifacts/dist/resolve-uri.js +29 -0
  65. package/packages/coworker-artifacts/dist/slug.d.ts +4 -0
  66. package/packages/coworker-artifacts/dist/slug.js +32 -0
  67. package/packages/coworker-artifacts/dist/types.d.ts +52 -0
  68. package/packages/coworker-artifacts/dist/types.js +1 -0
  69. package/packages/coworker-artifacts/package.json +20 -0
  70. package/packages/coworker-artifacts/src/artifact-store.test.ts +188 -0
  71. package/packages/coworker-artifacts/src/artifact-store.ts +206 -0
  72. package/packages/coworker-artifacts/src/artifacts-integration.test.ts +109 -0
  73. package/packages/coworker-artifacts/src/dir-snapshot.test.ts +71 -0
  74. package/packages/coworker-artifacts/src/dir-snapshot.ts +52 -0
  75. package/packages/coworker-artifacts/src/errors.test.ts +37 -0
  76. package/packages/coworker-artifacts/src/errors.ts +28 -0
  77. package/packages/coworker-artifacts/src/index.test.ts +22 -0
  78. package/packages/coworker-artifacts/src/index.ts +7 -0
  79. package/packages/coworker-artifacts/src/readme-renderer.test.ts +72 -0
  80. package/packages/coworker-artifacts/src/readme-renderer.ts +56 -0
  81. package/packages/coworker-artifacts/src/resolve-uri.test.ts +46 -0
  82. package/packages/coworker-artifacts/src/resolve-uri.ts +29 -0
  83. package/packages/coworker-artifacts/src/slug.test.ts +47 -0
  84. package/packages/coworker-artifacts/src/slug.ts +31 -0
  85. package/packages/coworker-artifacts/src/types.ts +61 -0
  86. package/packages/coworker-artifacts/tsconfig.json +15 -0
  87. package/packages/coworker-artifacts/tsconfig.publish.json +4 -0
  88. package/packages/coworker-memory/dist/context-injection.d.ts +9 -0
  89. package/packages/coworker-memory/dist/context-injection.js +41 -0
  90. package/packages/coworker-memory/dist/errors.d.ts +25 -0
  91. package/packages/coworker-memory/dist/errors.js +51 -0
  92. package/packages/coworker-memory/dist/index.d.ts +12 -0
  93. package/packages/coworker-memory/dist/index.js +12 -0
  94. package/packages/coworker-memory/dist/layer-a-store.d.ts +16 -0
  95. package/packages/coworker-memory/dist/layer-a-store.js +78 -0
  96. package/packages/coworker-memory/dist/local-sqlite-backend.d.ts +28 -0
  97. package/packages/coworker-memory/dist/local-sqlite-backend.js +167 -0
  98. package/packages/coworker-memory/dist/memory-backend.d.ts +14 -0
  99. package/packages/coworker-memory/dist/memory-backend.js +1 -0
  100. package/packages/coworker-memory/dist/memory-recorder.d.ts +50 -0
  101. package/packages/coworker-memory/dist/memory-recorder.js +69 -0
  102. package/packages/coworker-memory/dist/migrations/001-init.sql +38 -0
  103. package/packages/coworker-memory/dist/migrations/002-artifact-kind.sql +50 -0
  104. package/packages/coworker-memory/dist/paste-detector.d.ts +5 -0
  105. package/packages/coworker-memory/dist/paste-detector.js +14 -0
  106. package/packages/coworker-memory/dist/persona-seed.d.ts +10 -0
  107. package/packages/coworker-memory/dist/persona-seed.js +38 -0
  108. package/packages/coworker-memory/dist/recall-formatter.d.ts +2 -0
  109. package/packages/coworker-memory/dist/recall-formatter.js +14 -0
  110. package/packages/coworker-memory/dist/scope-resolver.d.ts +9 -0
  111. package/packages/coworker-memory/dist/scope-resolver.js +10 -0
  112. package/packages/coworker-memory/dist/types.d.ts +51 -0
  113. package/packages/coworker-memory/dist/types.js +2 -0
  114. package/packages/coworker-memory/dist/workspace-id.d.ts +3 -0
  115. package/packages/coworker-memory/dist/workspace-id.js +54 -0
  116. package/packages/coworker-memory/package.json +35 -0
  117. package/packages/coworker-memory/src/activator-integration.test.ts +141 -0
  118. package/packages/coworker-memory/src/context-injection.test.ts +72 -0
  119. package/packages/coworker-memory/src/context-injection.ts +57 -0
  120. package/packages/coworker-memory/src/errors.test.ts +45 -0
  121. package/packages/coworker-memory/src/errors.ts +42 -0
  122. package/packages/coworker-memory/src/index.test.ts +21 -0
  123. package/packages/coworker-memory/src/index.ts +12 -0
  124. package/packages/coworker-memory/src/layer-a-store.test.ts +85 -0
  125. package/packages/coworker-memory/src/layer-a-store.ts +88 -0
  126. package/packages/coworker-memory/src/local-sqlite-backend.test.ts +110 -0
  127. package/packages/coworker-memory/src/local-sqlite-backend.ts +185 -0
  128. package/packages/coworker-memory/src/memory-backend.ts +10 -0
  129. package/packages/coworker-memory/src/memory-integration.test.ts +89 -0
  130. package/packages/coworker-memory/src/memory-recorder.test.ts +101 -0
  131. package/packages/coworker-memory/src/memory-recorder.ts +95 -0
  132. package/packages/coworker-memory/src/migrations/001-init.sql +38 -0
  133. package/packages/coworker-memory/src/migrations/002-artifact-kind.sql +50 -0
  134. package/packages/coworker-memory/src/paste-detector.test.ts +23 -0
  135. package/packages/coworker-memory/src/paste-detector.ts +18 -0
  136. package/packages/coworker-memory/src/persona-seed.test.ts +57 -0
  137. package/packages/coworker-memory/src/persona-seed.ts +46 -0
  138. package/packages/coworker-memory/src/recall-formatter.test.ts +34 -0
  139. package/packages/coworker-memory/src/recall-formatter.ts +15 -0
  140. package/packages/coworker-memory/src/scope-resolver.test.ts +23 -0
  141. package/packages/coworker-memory/src/scope-resolver.ts +18 -0
  142. package/packages/coworker-memory/src/types.ts +61 -0
  143. package/packages/coworker-memory/src/workspace-id.test.ts +48 -0
  144. package/packages/coworker-memory/src/workspace-id.ts +56 -0
  145. package/packages/coworker-memory/tsconfig.json +15 -0
  146. package/packages/coworker-memory/tsconfig.publish.json +4 -0
  147. package/packages/coworker-persona/dist/commands.d.ts +7 -0
  148. package/packages/coworker-persona/dist/commands.js +35 -0
  149. package/packages/coworker-persona/dist/defaults/manifest.yaml +12 -0
  150. package/packages/coworker-persona/dist/defaults/steering/identity.md +3 -0
  151. package/packages/coworker-persona/dist/index.d.ts +3 -0
  152. package/packages/coworker-persona/dist/index.js +3 -0
  153. package/packages/coworker-persona/dist/manifest.d.ts +24 -0
  154. package/packages/coworker-persona/dist/manifest.js +21 -0
  155. package/packages/coworker-persona/dist/registry.d.ts +22 -0
  156. package/packages/coworker-persona/dist/registry.js +142 -0
  157. package/packages/coworker-persona/package.json +28 -0
  158. package/packages/coworker-persona/scripts/copy-defaults.cjs +17 -0
  159. package/packages/coworker-persona/src/commands.ts +47 -0
  160. package/packages/coworker-persona/src/defaults/manifest.yaml +12 -0
  161. package/packages/coworker-persona/src/defaults/steering/identity.md +3 -0
  162. package/packages/coworker-persona/src/index.ts +3 -0
  163. package/packages/coworker-persona/src/manifest.test.ts +67 -0
  164. package/packages/coworker-persona/src/manifest.ts +49 -0
  165. package/packages/coworker-persona/src/registry.test.ts +89 -0
  166. package/packages/coworker-persona/src/registry.ts +147 -0
  167. package/packages/coworker-persona/tsconfig.json +15 -0
  168. package/packages/coworker-persona/tsconfig.publish.json +4 -0
  169. package/packages/coworker-scratchpad/dist/cell-archive.d.ts +39 -0
  170. package/packages/coworker-scratchpad/dist/cell-archive.js +77 -0
  171. package/packages/coworker-scratchpad/dist/cell-tree.d.ts +14 -0
  172. package/packages/coworker-scratchpad/dist/cell-tree.js +72 -0
  173. package/packages/coworker-scratchpad/dist/child-process-runtime.d.ts +129 -0
  174. package/packages/coworker-scratchpad/dist/child-process-runtime.js +427 -0
  175. package/packages/coworker-scratchpad/dist/collector-registry.d.ts +12 -0
  176. package/packages/coworker-scratchpad/dist/collector-registry.js +29 -0
  177. package/packages/coworker-scratchpad/dist/detect-kind.d.ts +3 -0
  178. package/packages/coworker-scratchpad/dist/detect-kind.js +19 -0
  179. package/packages/coworker-scratchpad/dist/file-collector.d.ts +15 -0
  180. package/packages/coworker-scratchpad/dist/file-collector.js +99 -0
  181. package/packages/coworker-scratchpad/dist/index.d.ts +13 -0
  182. package/packages/coworker-scratchpad/dist/index.js +13 -0
  183. package/packages/coworker-scratchpad/dist/kernel-bindings.d.ts +49 -0
  184. package/packages/coworker-scratchpad/dist/kernel-bindings.js +220 -0
  185. package/packages/coworker-scratchpad/dist/kernel-entry.d.ts +1 -0
  186. package/packages/coworker-scratchpad/dist/kernel-entry.js +355 -0
  187. package/packages/coworker-scratchpad/dist/kernel-protocol.d.ts +171 -0
  188. package/packages/coworker-scratchpad/dist/kernel-protocol.js +48 -0
  189. package/packages/coworker-scratchpad/dist/kernel-spawn.d.ts +3 -0
  190. package/packages/coworker-scratchpad/dist/kernel-spawn.js +54 -0
  191. package/packages/coworker-scratchpad/dist/namespace-codec.d.ts +22 -0
  192. package/packages/coworker-scratchpad/dist/namespace-codec.js +61 -0
  193. package/packages/coworker-scratchpad/dist/scratchpad-lock.d.ts +24 -0
  194. package/packages/coworker-scratchpad/dist/scratchpad-lock.js +86 -0
  195. package/packages/coworker-scratchpad/dist/scratchpad-manager.d.ts +193 -0
  196. package/packages/coworker-scratchpad/dist/scratchpad-manager.js +866 -0
  197. package/packages/coworker-scratchpad/dist/staleness-banner.d.ts +12 -0
  198. package/packages/coworker-scratchpad/dist/staleness-banner.js +27 -0
  199. package/packages/coworker-scratchpad/package.json +31 -0
  200. package/packages/coworker-scratchpad/src/cell-archive.test.ts +150 -0
  201. package/packages/coworker-scratchpad/src/cell-archive.ts +97 -0
  202. package/packages/coworker-scratchpad/src/cell-tree.test.ts +105 -0
  203. package/packages/coworker-scratchpad/src/cell-tree.ts +90 -0
  204. package/packages/coworker-scratchpad/src/child-process-runtime.test.ts +413 -0
  205. package/packages/coworker-scratchpad/src/child-process-runtime.ts +493 -0
  206. package/packages/coworker-scratchpad/src/collector-registry.test.ts +69 -0
  207. package/packages/coworker-scratchpad/src/collector-registry.ts +33 -0
  208. package/packages/coworker-scratchpad/src/detect-kind.test.ts +33 -0
  209. package/packages/coworker-scratchpad/src/detect-kind.ts +22 -0
  210. package/packages/coworker-scratchpad/src/file-collector.test.ts +109 -0
  211. package/packages/coworker-scratchpad/src/file-collector.ts +114 -0
  212. package/packages/coworker-scratchpad/src/index.ts +74 -0
  213. package/packages/coworker-scratchpad/src/kernel-bindings.test.ts +188 -0
  214. package/packages/coworker-scratchpad/src/kernel-bindings.ts +279 -0
  215. package/packages/coworker-scratchpad/src/kernel-entry.test.ts +123 -0
  216. package/packages/coworker-scratchpad/src/kernel-entry.ts +390 -0
  217. package/packages/coworker-scratchpad/src/kernel-protocol.test.ts +105 -0
  218. package/packages/coworker-scratchpad/src/kernel-protocol.ts +230 -0
  219. package/packages/coworker-scratchpad/src/kernel-spawn.test.ts +60 -0
  220. package/packages/coworker-scratchpad/src/kernel-spawn.ts +54 -0
  221. package/packages/coworker-scratchpad/src/namespace-codec.test.ts +102 -0
  222. package/packages/coworker-scratchpad/src/namespace-codec.ts +90 -0
  223. package/packages/coworker-scratchpad/src/scratchpad-lock.test.ts +98 -0
  224. package/packages/coworker-scratchpad/src/scratchpad-lock.ts +102 -0
  225. package/packages/coworker-scratchpad/src/scratchpad-manager.test.ts +1343 -0
  226. package/packages/coworker-scratchpad/src/scratchpad-manager.ts +891 -0
  227. package/packages/coworker-scratchpad/src/staleness-banner.test.ts +53 -0
  228. package/packages/coworker-scratchpad/src/staleness-banner.ts +33 -0
  229. package/packages/coworker-scratchpad/src/vault-integration.test.ts +221 -0
  230. package/packages/coworker-scratchpad/tsconfig.json +15 -0
  231. package/packages/coworker-scratchpad/tsconfig.publish.json +4 -0
  232. package/packages/coworker-types/dist/artifacts.d.ts +31 -0
  233. package/packages/coworker-types/dist/artifacts.js +2 -0
  234. package/packages/coworker-types/dist/contracts.d.ts +32 -0
  235. package/packages/coworker-types/dist/contracts.js +1 -0
  236. package/packages/coworker-types/dist/index.d.ts +5 -0
  237. package/packages/coworker-types/dist/index.js +5 -0
  238. package/packages/coworker-types/dist/memory.d.ts +61 -0
  239. package/packages/coworker-types/dist/memory.js +3 -0
  240. package/packages/coworker-types/dist/scratchpad.d.ts +43 -0
  241. package/packages/coworker-types/dist/scratchpad.js +2 -0
  242. package/packages/coworker-types/dist/vault.d.ts +34 -0
  243. package/packages/coworker-types/dist/vault.js +2 -0
  244. package/packages/coworker-types/package.json +24 -0
  245. package/packages/coworker-types/src/artifacts.test.ts +52 -0
  246. package/packages/coworker-types/src/artifacts.ts +35 -0
  247. package/packages/coworker-types/src/contracts.test.ts +43 -0
  248. package/packages/coworker-types/src/contracts.ts +36 -0
  249. package/packages/coworker-types/src/index.ts +5 -0
  250. package/packages/coworker-types/src/memory.test.ts +50 -0
  251. package/packages/coworker-types/src/memory.ts +79 -0
  252. package/packages/coworker-types/src/scratchpad.test.ts +46 -0
  253. package/packages/coworker-types/src/scratchpad.ts +51 -0
  254. package/packages/coworker-types/src/smoke.test.ts +34 -0
  255. package/packages/coworker-types/src/vault.test.ts +49 -0
  256. package/packages/coworker-types/src/vault.ts +40 -0
  257. package/packages/coworker-types/tsconfig.json +15 -0
  258. package/packages/coworker-types/tsconfig.publish.json +4 -0
  259. package/packages/coworker-utils/dist/audit-log.d.ts +34 -0
  260. package/packages/coworker-utils/dist/audit-log.js +88 -0
  261. package/packages/coworker-utils/dist/index.d.ts +6 -0
  262. package/packages/coworker-utils/dist/index.js +6 -0
  263. package/packages/coworker-utils/dist/lease.d.ts +7 -0
  264. package/packages/coworker-utils/dist/lease.js +67 -0
  265. package/packages/coworker-utils/dist/logger.d.ts +13 -0
  266. package/packages/coworker-utils/dist/logger.js +26 -0
  267. package/packages/coworker-utils/dist/migration-runner.d.ts +7 -0
  268. package/packages/coworker-utils/dist/migration-runner.js +36 -0
  269. package/packages/coworker-utils/dist/ndjson-channel.d.ts +3 -0
  270. package/packages/coworker-utils/dist/ndjson-channel.js +38 -0
  271. package/packages/coworker-utils/dist/secret-scanner.d.ts +10 -0
  272. package/packages/coworker-utils/dist/secret-scanner.js +42 -0
  273. package/packages/coworker-utils/package.json +24 -0
  274. package/packages/coworker-utils/src/audit-log.test.ts +140 -0
  275. package/packages/coworker-utils/src/audit-log.ts +107 -0
  276. package/packages/coworker-utils/src/index.ts +6 -0
  277. package/packages/coworker-utils/src/lease.test.ts +64 -0
  278. package/packages/coworker-utils/src/lease.ts +76 -0
  279. package/packages/coworker-utils/src/logger.test.ts +50 -0
  280. package/packages/coworker-utils/src/logger.ts +45 -0
  281. package/packages/coworker-utils/src/migration-runner.test.ts +65 -0
  282. package/packages/coworker-utils/src/migration-runner.ts +50 -0
  283. package/packages/coworker-utils/src/ndjson-channel.test.ts +76 -0
  284. package/packages/coworker-utils/src/ndjson-channel.ts +41 -0
  285. package/packages/coworker-utils/src/secret-scanner.test.ts +61 -0
  286. package/packages/coworker-utils/src/secret-scanner.ts +56 -0
  287. package/packages/coworker-utils/tsconfig.json +15 -0
  288. package/packages/coworker-utils/tsconfig.publish.json +4 -0
  289. package/packages/coworker-vault/dist/data-vault.d.ts +41 -0
  290. package/packages/coworker-vault/dist/data-vault.js +223 -0
  291. package/packages/coworker-vault/dist/engine-registry.d.ts +34 -0
  292. package/packages/coworker-vault/dist/engine-registry.js +90 -0
  293. package/packages/coworker-vault/dist/engines/jira.yaml +17 -0
  294. package/packages/coworker-vault/dist/errors.d.ts +28 -0
  295. package/packages/coworker-vault/dist/errors.js +57 -0
  296. package/packages/coworker-vault/dist/index.d.ts +6 -0
  297. package/packages/coworker-vault/dist/index.js +6 -0
  298. package/packages/coworker-vault/dist/injector.d.ts +19 -0
  299. package/packages/coworker-vault/dist/injector.js +77 -0
  300. package/packages/coworker-vault/dist/types.d.ts +28 -0
  301. package/packages/coworker-vault/dist/types.js +1 -0
  302. package/packages/coworker-vault/dist/vault-keep.d.ts +4 -0
  303. package/packages/coworker-vault/dist/vault-keep.js +21 -0
  304. package/packages/coworker-vault/package.json +29 -0
  305. package/packages/coworker-vault/src/data-vault.test.ts +199 -0
  306. package/packages/coworker-vault/src/data-vault.ts +257 -0
  307. package/packages/coworker-vault/src/engine-registry.test.ts +120 -0
  308. package/packages/coworker-vault/src/engine-registry.ts +107 -0
  309. package/packages/coworker-vault/src/engines/jira.yaml +17 -0
  310. package/packages/coworker-vault/src/errors.test.ts +58 -0
  311. package/packages/coworker-vault/src/errors.ts +50 -0
  312. package/packages/coworker-vault/src/index.test.ts +24 -0
  313. package/packages/coworker-vault/src/index.ts +6 -0
  314. package/packages/coworker-vault/src/injector.test.ts +109 -0
  315. package/packages/coworker-vault/src/injector.ts +98 -0
  316. package/packages/coworker-vault/src/types.ts +33 -0
  317. package/packages/coworker-vault/src/vault-keep.test.ts +49 -0
  318. package/packages/coworker-vault/src/vault-keep.ts +31 -0
  319. package/packages/coworker-vault/tsconfig.json +15 -0
  320. package/packages/coworker-vault/tsconfig.publish.json +4 -0
  321. package/packages/daemon/package.json +3 -3
  322. package/packages/mcp-server/package.json +3 -3
  323. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  324. package/packages/native/package.json +1 -1
  325. package/packages/native/tsconfig.tsbuildinfo +1 -1
  326. package/packages/pi-agent-core/package.json +1 -1
  327. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  328. package/packages/pi-ai/package.json +1 -1
  329. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  330. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +6 -1
  331. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/extensions/runner.js +22 -3
  333. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +11 -0
  335. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  336. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.d.ts +47 -0
  337. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.d.ts.map +1 -0
  338. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.js +107 -0
  339. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.js.map +1 -0
  340. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.d.ts +19 -0
  341. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.d.ts.map +1 -0
  342. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.js +121 -0
  343. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.js.map +1 -0
  344. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  345. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +17 -1
  346. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  347. package/packages/pi-coding-agent/package.json +2 -2
  348. package/packages/pi-coding-agent/src/core/extensions/runner.ts +22 -3
  349. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +11 -0
  350. package/packages/pi-coding-agent/src/modes/rpc/raw-stdout.regression.test.ts +129 -0
  351. package/packages/pi-coding-agent/src/modes/rpc/raw-stdout.ts +117 -0
  352. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +18 -1
  353. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  354. package/packages/pi-tui/package.json +1 -1
  355. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  356. package/packages/rpc-client/package.json +2 -2
  357. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  358. package/pkg/package.json +1 -1
  359. package/scripts/install.js +6 -5
  360. package/src/resources/extensions/coworker-artifacts/artifacts-command.test.ts +54 -0
  361. package/src/resources/extensions/coworker-artifacts/artifacts-command.ts +43 -0
  362. package/src/resources/extensions/coworker-artifacts/artifacts-singleton.test.ts +25 -0
  363. package/src/resources/extensions/coworker-artifacts/artifacts-singleton.ts +29 -0
  364. package/src/resources/extensions/coworker-artifacts/extension-manifest.json +13 -0
  365. package/src/resources/extensions/coworker-artifacts/index.test.ts +46 -0
  366. package/src/resources/extensions/coworker-artifacts/index.ts +154 -0
  367. package/src/resources/extensions/coworker-artifacts/list-tool.test.ts +29 -0
  368. package/src/resources/extensions/coworker-artifacts/list-tool.ts +53 -0
  369. package/src/resources/extensions/coworker-artifacts/open-tool.test.ts +30 -0
  370. package/src/resources/extensions/coworker-artifacts/open-tool.ts +43 -0
  371. package/src/resources/extensions/coworker-memory/extension-manifest.json +13 -0
  372. package/src/resources/extensions/coworker-memory/index.test.ts +137 -0
  373. package/src/resources/extensions/coworker-memory/index.ts +257 -0
  374. package/src/resources/extensions/coworker-memory/memorize-tool.test.ts +41 -0
  375. package/src/resources/extensions/coworker-memory/memorize-tool.ts +20 -0
  376. package/src/resources/extensions/coworker-memory/memory-command.test.ts +134 -0
  377. package/src/resources/extensions/coworker-memory/memory-command.ts +131 -0
  378. package/src/resources/extensions/coworker-memory/memory-singleton.test.ts +41 -0
  379. package/src/resources/extensions/coworker-memory/memory-singleton.ts +89 -0
  380. package/src/resources/extensions/coworker-memory/recall-tool.test.ts +50 -0
  381. package/src/resources/extensions/coworker-memory/recall-tool.ts +35 -0
  382. package/src/resources/extensions/coworker-memory/session-hooks.test.ts +77 -0
  383. package/src/resources/extensions/coworker-memory/session-hooks.ts +61 -0
  384. package/src/resources/extensions/coworker-scratchpad/attach-banners.test.ts +124 -0
  385. package/src/resources/extensions/coworker-scratchpad/attach-banners.ts +67 -0
  386. package/src/resources/extensions/coworker-scratchpad/extension-manifest.json +13 -0
  387. package/src/resources/extensions/coworker-scratchpad/format-age.test.ts +30 -0
  388. package/src/resources/extensions/coworker-scratchpad/format-age.ts +6 -0
  389. package/src/resources/extensions/coworker-scratchpad/helpers.test.ts +93 -0
  390. package/src/resources/extensions/coworker-scratchpad/helpers.ts +42 -0
  391. package/src/resources/extensions/coworker-scratchpad/index.test.ts +514 -0
  392. package/src/resources/extensions/coworker-scratchpad/index.ts +207 -0
  393. package/src/resources/extensions/coworker-scratchpad/mime-bundle.test.ts +61 -0
  394. package/src/resources/extensions/coworker-scratchpad/mime-bundle.ts +23 -0
  395. package/src/resources/extensions/coworker-scratchpad/scratchpad-tool.test.ts +137 -0
  396. package/src/resources/extensions/coworker-scratchpad/scratchpad-tool.ts +165 -0
  397. package/src/resources/extensions/coworker-scratchpad/session-sidecar.test.ts +133 -0
  398. package/src/resources/extensions/coworker-scratchpad/session-sidecar.ts +68 -0
  399. package/src/resources/extensions/coworker-scratchpad/sp-command.test.ts +836 -0
  400. package/src/resources/extensions/coworker-scratchpad/sp-command.ts +602 -0
  401. package/src/resources/extensions/coworker-scratchpad/workspace-pointer.test.ts +74 -0
  402. package/src/resources/extensions/coworker-scratchpad/workspace-pointer.ts +55 -0
  403. package/src/resources/extensions/coworker-scratchpad/workspace-root.test.ts +51 -0
  404. package/src/resources/extensions/coworker-scratchpad/workspace-root.ts +16 -0
  405. package/src/resources/extensions/coworker-vault/audit-command.test.ts +109 -0
  406. package/src/resources/extensions/coworker-vault/audit-command.ts +56 -0
  407. package/src/resources/extensions/coworker-vault/connect-command.test.ts +103 -0
  408. package/src/resources/extensions/coworker-vault/connect-command.ts +69 -0
  409. package/src/resources/extensions/coworker-vault/datasource-command.test.ts +80 -0
  410. package/src/resources/extensions/coworker-vault/datasource-command.ts +81 -0
  411. package/src/resources/extensions/coworker-vault/extension-manifest.json +12 -0
  412. package/src/resources/extensions/coworker-vault/index.test.ts +82 -0
  413. package/src/resources/extensions/coworker-vault/index.ts +181 -0
  414. package/src/resources/extensions/coworker-vault/test-helpers.ts +120 -0
  415. package/src/resources/extensions/coworker-vault/vault-singleton.test.ts +27 -0
  416. package/src/resources/extensions/coworker-vault/vault-singleton.ts +40 -0
  417. package/src/resources/extensions/otto/commands/release-notes/_data.ts +97 -0
  418. package/src/resources/extensions/otto/commands/release-notes/command.ts +16 -3
  419. package/src/resources/extensions/otto/index.ts +29 -6
  420. package/src/resources/extensions/shared/coworker-paths.test.ts +40 -0
  421. package/src/resources/extensions/shared/coworker-paths.ts +10 -0
  422. package/src/resources/extensions/slash-commands/{audit.ts → audit-codebase.ts} +4 -4
  423. package/src/resources/extensions/slash-commands/extension-manifest.json +1 -1
  424. package/src/resources/extensions/slash-commands/index.ts +2 -2
  425. package/src/resources/extensions/subagent/index.ts +9 -0
  426. package/src/resources/extensions/subagent/launch.test.ts +97 -0
  427. package/src/resources/extensions/subagent/launch.ts +42 -5
  428. package/src/resources/extensions/subagent/run-store.ts +3 -1
  429. package/src/resources/extensions/workflow/bootstrap/register-extension.ts +2 -0
  430. package/src/resources/extensions/workflow/bootstrap/register-hooks.ts +10 -0
  431. package/src/resources/extensions/workflow/health-widget-core.ts +1 -1
  432. package/src/resources/extensions/workflow/persona-status.ts +109 -0
  433. package/src/resources/extensions/workflow/tests/auto-recovery.test.ts +34 -0
@@ -108,6 +108,10 @@ export default function Otto(pi) {
108
108
  const green = ANSI_BRAND_GREEN;
109
109
  const dim = ANSI_DIM;
110
110
  const reset = ANSI_RESET;
111
+ // When a TUI is rendering, raw stderr writes race with the welcome banner
112
+ // and overwrite the prompt area. Route status through `ctx.ui.setStatus`
113
+ // instead, and only fall back to stderr for headless/RPC modes.
114
+ const hasUI = ctx?.hasUI === true;
111
115
  // ── Gateway connection probe (preserved from Phase 1 Task 6) ──
112
116
  const gwUrl = process.env.OTTO_GATEWAY_URL?.trim();
113
117
  if (gwUrl) {
@@ -118,15 +122,30 @@ export default function Otto(pi) {
118
122
  clearTimeout(timer);
119
123
  const ok = r.ok;
120
124
  const host = new URL(gwUrl).host;
121
- process.stderr.write(` ${yellow}gateway:${reset} ${ok ? green : dim}routed → ${host}${reset}\n`);
125
+ if (hasUI) {
126
+ ctx?.ui.setStatus("otto-gateway", ok ? `Gateway → ${host}` : `Gateway → ${host} (down)`);
127
+ }
128
+ else {
129
+ process.stderr.write(` ${yellow}gateway:${reset} ${ok ? green : dim}routed → ${host}${reset}\n`);
130
+ }
122
131
  }
123
132
  catch {
124
133
  const host = new URL(gwUrl).host;
125
- process.stderr.write(` ${yellow}gateway:${reset} ${dim}routed → ${host} (unreachable)${reset}\n`);
134
+ if (hasUI) {
135
+ ctx?.ui.setStatus("otto-gateway", `Gateway → ${host} (unreachable)`);
136
+ }
137
+ else {
138
+ process.stderr.write(` ${yellow}gateway:${reset} ${dim}routed → ${host} (unreachable)${reset}\n`);
139
+ }
126
140
  }
127
141
  }
128
142
  else {
129
- process.stderr.write(` ${yellow}gateway:${reset} ${dim}direct (no OTTO_GATEWAY_URL set)${reset}\n`);
143
+ if (hasUI) {
144
+ ctx?.ui.setStatus("otto-gateway", undefined);
145
+ }
146
+ else {
147
+ process.stderr.write(` ${yellow}gateway:${reset} ${dim}direct (no OTTO_GATEWAY_URL set)${reset}\n`);
148
+ }
130
149
  }
131
150
  // ── LangFlow connection probe ──
132
151
  const cfg = effectiveLangFlowConfig();
@@ -135,18 +154,24 @@ export default function Otto(pi) {
135
154
  const lfHost = new URL(lfUrl).host;
136
155
  if (langflowDisabled) {
137
156
  ctx?.ui.setStatus("otto-langflow", undefined);
138
- process.stderr.write(` ${yellow}langflow:${reset} ${dim}disabled (${lfHost})${reset}\n`);
157
+ if (!hasUI) {
158
+ process.stderr.write(` ${yellow}langflow:${reset} ${dim}disabled (${lfHost})${reset}\n`);
159
+ }
139
160
  }
140
161
  else {
141
162
  const lfClient = getLangFlowClient();
142
163
  const lfVersion = await lfClient.getVersion();
143
164
  if (lfVersion) {
144
165
  ctx?.ui.setStatus("otto-langflow", `LangFlow ok v${lfVersion.version}`);
145
- process.stderr.write(` ${yellow}langflow:${reset} ${green}connected${reset} ${dim}(v${lfVersion.version} @ ${lfHost})${reset}\n`);
166
+ if (!hasUI) {
167
+ process.stderr.write(` ${yellow}langflow:${reset} ${green}connected${reset} ${dim}(v${lfVersion.version} @ ${lfHost})${reset}\n`);
168
+ }
146
169
  }
147
170
  else {
148
171
  ctx?.ui.setStatus("otto-langflow", "LangFlow offline");
149
- process.stderr.write(` ${yellow}langflow:${reset} ${dim}offline (${lfHost})${reset}\n`);
172
+ if (!hasUI) {
173
+ process.stderr.write(` ${yellow}langflow:${reset} ${dim}offline (${lfHost})${reset}\n`);
174
+ }
150
175
  }
151
176
  }
152
177
  });
@@ -0,0 +1,8 @@
1
+ import { homedir } from 'node:os';
2
+ import { join } from 'node:path';
3
+ export function getCoworkerGlobalDir() {
4
+ return process.env.OTTO_COWORKER_GLOBAL_DIR ?? join(homedir(), '.otto');
5
+ }
6
+ export function getScratchpadsRoot() {
7
+ return process.env.OTTO_SCRATCHPAD_ROOT ?? join(homedir(), '.otto', 'scratchpads');
8
+ }
@@ -1,6 +1,6 @@
1
1
  import { mkdirSync } from "node:fs";
2
- export default function auditCommand(pi) {
3
- pi.registerCommand("audit", {
2
+ export default function auditCodebaseCommand(pi) {
3
+ pi.registerCommand("audit-codebase", {
4
4
  description: "Audit the current codebase against a specific goal and write a structured report to .gsd/audits/",
5
5
  async handler(args, ctx) {
6
6
  // ── Step 1: Get the audit goal ────────────────────────────────────────
@@ -8,7 +8,7 @@ export default function auditCommand(pi) {
8
8
  if (!goal) {
9
9
  const input = await ctx.ui.input("What is the audit goal?", "e.g. understand performance bottlenecks before planning a roadmap");
10
10
  if (!input?.trim()) {
11
- ctx.ui.notify("audit: No goal provided — cancelled.", "error");
11
+ ctx.ui.notify("audit-codebase: No goal provided — cancelled.", "error");
12
12
  return;
13
13
  }
14
14
  goal = input.trim();
@@ -62,7 +62,7 @@ ${goal}
62
62
 
63
63
  ---
64
64
 
65
- *Generated by /audit — read-only recce, no code was modified.*
65
+ *Generated by /audit-codebase — read-only recce, no code was modified.*
66
66
  \`\`\`
67
67
 
68
68
  After writing the file, confirm with: "✅ Audit complete — report saved to \`${outputPath}\`"`;
@@ -6,6 +6,6 @@
6
6
  "tier": "bundled",
7
7
  "requires": { "platform": ">=2.29.0" },
8
8
  "provides": {
9
- "commands": ["create-slash-command", "create-extension", "audit", "clear"]
9
+ "commands": ["create-slash-command", "create-extension", "audit-codebase", "clear"]
10
10
  }
11
11
  }
@@ -1,10 +1,10 @@
1
1
  import createSlashCommand from "./create-slash-command.js";
2
2
  import createExtension from "./create-extension.js";
3
- import auditCommand from "./audit.js";
3
+ import auditCodebaseCommand from "./audit-codebase.js";
4
4
  import clearCommand from "./clear.js";
5
5
  export default function slashCommands(pi) {
6
6
  createSlashCommand(pi);
7
7
  createExtension(pi);
8
- auditCommand(pi);
8
+ auditCodebaseCommand(pi);
9
9
  clearCommand(pi);
10
10
  }
@@ -29,7 +29,7 @@ import { registerWorker, updateWorker } from "./worker-registry.js";
29
29
  import { loadEffectiveGSDPreferences } from "../workflow/preferences.js";
30
30
  import { emitJournalEvent } from "../workflow/journal.js";
31
31
  import { CmuxClient, shellEscape } from "../cmux/index.js";
32
- import { buildShellEnvAssignments, createSubagentLaunchPlan, isSubagentChildProcess, } from "./launch.js";
32
+ import { buildShellEnvAssignments, createSubagentLaunchPlan, isSubagentChildProcess, mintSubagentScratchpadName, } from "./launch.js";
33
33
  import { SubagentRunStore, createInitialRunRecord, createSubagentTrackingName, deriveRunStatus, } from "./run-store.js";
34
34
  export { buildSubagentProcessArgs } from "./launch.js";
35
35
  const MAX_PARALLEL_TASKS = 8;
@@ -259,6 +259,7 @@ function resultToChildArtifact(result, index, cwd) {
259
259
  index,
260
260
  agent: result.agent,
261
261
  trackingName: result.trackingName,
262
+ scratchpadName: result.scratchpadName,
262
263
  task: result.task,
263
264
  status: running ? "running" : resultStatus(result),
264
265
  exitCode: result.exitCode,
@@ -365,6 +366,8 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
365
366
  tmpPromptDir = tmp.dir;
366
367
  tmpPromptPath = tmp.filePath;
367
368
  }
369
+ const scratchpadName = mintSubagentScratchpadName(agent.name);
370
+ currentResult.scratchpadName = scratchpadName;
368
371
  const launch = createSubagentLaunchPlan({
369
372
  agent,
370
373
  task,
@@ -375,6 +378,7 @@ async function runSingleAgent(defaultCwd, agents, agentName, task, cwd, step, si
375
378
  session: sessionOverride,
376
379
  cwd,
377
380
  defaultCwd,
381
+ scratchpadName,
378
382
  });
379
383
  if (launch.session.mode === "fork")
380
384
  currentResult.sessionFile = launch.session.sessionFile;
@@ -493,6 +497,8 @@ async function runSingleAgentInCmuxSplit(cmuxClient, directionOrSurfaceId, defau
493
497
  }
494
498
  const bundledPaths = ((process.env.OTTO_BUNDLED_EXTENSION_PATHS ?? process.env.OTTO_BUNDLED_EXTENSION_PATHS) ?? "").split(path.delimiter).map((s) => s.trim()).filter(Boolean);
495
499
  const extensionArgs = bundledPaths.flatMap((p) => ["--extension", p]);
500
+ const scratchpadName = mintSubagentScratchpadName(agent.name);
501
+ currentResult.scratchpadName = scratchpadName;
496
502
  const launch = createSubagentLaunchPlan({
497
503
  agent,
498
504
  task,
@@ -503,6 +509,7 @@ async function runSingleAgentInCmuxSplit(cmuxClient, directionOrSurfaceId, defau
503
509
  session: sessionOverride,
504
510
  cwd,
505
511
  defaultCwd,
512
+ scratchpadName,
506
513
  });
507
514
  if (launch.session.mode === "fork")
508
515
  currentResult.sessionFile = launch.session.sessionFile;
@@ -1,21 +1,53 @@
1
1
  // OTTO + Subagent launch contract and child process safety helpers.
2
+ import * as crypto from "node:crypto";
2
3
  import * as fs from "node:fs";
3
4
  import * as path from "node:path";
4
5
  import { SessionManager } from "@otto/pi-coding-agent";
5
6
  export const SUBAGENT_CHILD_ENV_VAR = "OTTO_SUBAGENT_CHILD";
6
7
  export const SUBAGENT_CHILD_ENV_VALUE = "1";
8
+ export const SUBAGENT_SCRATCHPAD_ENV_VAR = "OTTO_SUBAGENT_SCRATCHPAD";
9
+ const MAX_SCRATCHPAD_AGENT_PART = 32;
10
+ export function mintSubagentScratchpadName(agentName) {
11
+ const hex = crypto.randomBytes(3).toString("hex");
12
+ // Sanitize: NFKD + strip combining marks + lowercase + non-[a-z0-9] → '-' + collapse + trim.
13
+ let sanitized = agentName
14
+ .normalize("NFKD")
15
+ .replace(/[̀-ͯ]/g, "")
16
+ .toLowerCase()
17
+ .replace(/[^a-z0-9]+/g, "-")
18
+ .replace(/-+/g, "-")
19
+ .replace(/^-+|-+$/g, "");
20
+ if (sanitized.length > MAX_SCRATCHPAD_AGENT_PART) {
21
+ sanitized = sanitized.slice(0, MAX_SCRATCHPAD_AGENT_PART).replace(/-+$/, "");
22
+ }
23
+ if (!sanitized)
24
+ return `subagent-${hex}`;
25
+ return `subagent-${sanitized}-${hex}`;
26
+ }
7
27
  export function isSubagentChildProcess(env = process.env) {
8
28
  return env[SUBAGENT_CHILD_ENV_VAR] === SUBAGENT_CHILD_ENV_VALUE;
9
29
  }
10
- export function buildSubagentProcessEnv(env = process.env) {
11
- return {
30
+ export function buildSubagentProcessEnv(env = process.env, scratchpadName) {
31
+ const next = {
12
32
  ...env,
13
33
  [SUBAGENT_CHILD_ENV_VAR]: SUBAGENT_CHILD_ENV_VALUE,
14
34
  };
35
+ if (scratchpadName) {
36
+ next[SUBAGENT_SCRATCHPAD_ENV_VAR] = scratchpadName;
37
+ }
38
+ return next;
15
39
  }
16
40
  export function buildShellEnvAssignments(env = process.env) {
17
- const value = env[SUBAGENT_CHILD_ENV_VAR];
18
- return value ? [`${SUBAGENT_CHILD_ENV_VAR}=${JSON.stringify(value)}`] : [];
41
+ const out = [];
42
+ const childValue = env[SUBAGENT_CHILD_ENV_VAR];
43
+ if (childValue) {
44
+ out.push(`${SUBAGENT_CHILD_ENV_VAR}=${JSON.stringify(childValue)}`);
45
+ }
46
+ const scratchpadValue = env[SUBAGENT_SCRATCHPAD_ENV_VAR];
47
+ if (scratchpadValue) {
48
+ out.push(`${SUBAGENT_SCRATCHPAD_ENV_VAR}=${JSON.stringify(scratchpadValue)}`);
49
+ }
50
+ return out;
19
51
  }
20
52
  export function buildSubagentProcessArgs(agent, task, tmpPromptPath, modelOverride, session = { mode: "fresh" }) {
21
53
  const args = ["--mode", "json", "-p"];
@@ -70,7 +102,7 @@ export function createSubagentLaunchPlan(input) {
70
102
  const session = input.session ?? resolveSubagentSessionArgs(input.contextMode ?? "fresh", input.parentSessionManager);
71
103
  return {
72
104
  args: buildSubagentProcessArgs(input.agent, input.task, input.tmpPromptPath, input.modelOverride, session),
73
- env: buildSubagentProcessEnv(),
105
+ env: buildSubagentProcessEnv(process.env, input.scratchpadName),
74
106
  cwd: input.cwd ?? input.defaultCwd,
75
107
  session,
76
108
  };
@@ -131,6 +131,7 @@ export function createInitialRunRecord(input) {
131
131
  index,
132
132
  agent: child.agent,
133
133
  trackingName: child.trackingName,
134
+ scratchpadName: child.scratchpadName,
134
135
  task: child.task,
135
136
  cwd: child.cwd,
136
137
  status: "queued",
@@ -19,6 +19,7 @@ import { logWarning } from "../workflow-logger.js";
19
19
  // session hook calling startAuto) would be silently dropped because Node's
20
20
  // EventEmitter does not buffer events for late subscribers.
21
21
  import { initCmuxEventListeners } from "../../cmux/index.js";
22
+ import { registerPersonaCommands } from "../persona-status.js";
22
23
  import { BRAND } from "../strings.js";
23
24
  export { writeCrashLog } from "./crash-log.js";
24
25
  export function handleRecoverableExtensionProcessError(err) {
@@ -110,6 +111,7 @@ export function registerWorkflowExtension(pi) {
110
111
  ["memory-tools", () => registerMemoryTools(pi)],
111
112
  ["exec-tools", () => registerExecTools(pi)],
112
113
  ["schedule-wakeup-tool", () => registerScheduleWakeupTool(pi)],
114
+ ["persona-commands", () => registerPersonaCommands(pi)],
113
115
  ["shortcuts", () => registerShortcuts(pi)],
114
116
  // cmux is a library (no pi), so gsd sets up the event listeners on its
115
117
  // behalf using the shared event channel contract. Registration is
@@ -299,6 +299,15 @@ async function resetAskUserQuestionsTurnCache() {
299
299
  const { resetAskUserQuestionsCache } = await import("../../ask-user-questions.js");
300
300
  resetAskUserQuestionsCache();
301
301
  }
302
+ async function initPersonaStatusChip(ctx) {
303
+ try {
304
+ const { initPersonaWidget } = await import("../persona-status.js");
305
+ await initPersonaWidget(ctx);
306
+ }
307
+ catch {
308
+ // Non-fatal: persona chip simply won't render if the registry is unavailable.
309
+ }
310
+ }
302
311
  async function syncServiceTierStatus(ctx) {
303
312
  const { getEffectiveServiceTier, formatServiceTierFooterStatus } = await import("../service-tier.js");
304
313
  ctx.ui.setStatus("gsd-fast", formatServiceTierFooterStatus(getEffectiveServiceTier(), ctx.model?.id));
@@ -424,6 +433,7 @@ export function registerHooks(pi, ecosystemHandlers) {
424
433
  approvalQuestionAbortInFlight = false;
425
434
  clearDeferredApprovalGate();
426
435
  await resetAskUserQuestionsTurnCache();
436
+ await initPersonaStatusChip(ctx);
427
437
  await syncServiceTierStatus(ctx);
428
438
  await applyDisabledModelProviderPolicy(ctx);
429
439
  await applyCompactionThresholdOverride(ctx);
@@ -50,7 +50,7 @@ function truncateMessage(msg, maxLen) {
50
50
  */
51
51
  export function buildHealthLines(data, width) {
52
52
  if (data.projectState === "none") {
53
- return [" OTTO No project loaded — cd into a project, then run /otto init"];
53
+ return [" No project loaded — cd into a project, then run /otto init"];
54
54
  }
55
55
  if (data.projectState === "initialized") {
56
56
  return [` ${BRAND} Project Initialized`];
@@ -0,0 +1,87 @@
1
+ // Wires /persona slash commands + the persona status-bar chip into Otto.
2
+ // Spec §2.5 + §5.2. Lives inside the src/resources extension boundary, so it
3
+ // imports only the @otto/coworker-persona package (never src/ modules).
4
+ import { homedir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { PersonaRegistry, handleList, handleCurrent, handleSwitch, handleReset, handleInstall, handleUninstall, } from "@otto/coworker-persona";
7
+ // Sorts ahead of alphabetic extension status keys so the chip lands leftmost
8
+ // in the footer's extension-status block.
9
+ const STATUS_KEY = "00-persona";
10
+ const SUBCOMMANDS = ["list", "current", "switch", "install", "uninstall", "reset"];
11
+ function ottoHome() {
12
+ return process.env.OTTO_HOME || join(homedir(), ".otto");
13
+ }
14
+ function getRegistry() {
15
+ return new PersonaRegistry({ ottoHome: ottoHome() });
16
+ }
17
+ function formatPersonaChip(persona) {
18
+ const { icon, label } = persona.status_line;
19
+ return `${icon} ${label}`.trim();
20
+ }
21
+ async function refreshPersonaChip(ctx, registry) {
22
+ if (!ctx.hasUI)
23
+ return;
24
+ try {
25
+ const active = await registry.activeInWorkspace(ctx.cwd);
26
+ ctx.ui.setStatus(STATUS_KEY, formatPersonaChip(active));
27
+ }
28
+ catch {
29
+ ctx.ui.setStatus(STATUS_KEY, undefined);
30
+ }
31
+ }
32
+ // Called on session_start to seed the default persona and render the chip.
33
+ export async function initPersonaWidget(ctx) {
34
+ const registry = getRegistry();
35
+ try {
36
+ await registry.ensureDefaultInstalled();
37
+ }
38
+ catch {
39
+ // Non-fatal: chip simply won't render if the default can't be installed.
40
+ }
41
+ await refreshPersonaChip(ctx, registry);
42
+ }
43
+ export function registerPersonaCommands(pi) {
44
+ pi.registerCommand("persona", {
45
+ description: "Manage Otto co-worker personas (list, current, switch, install, uninstall, reset)",
46
+ getArgumentCompletions: (prefix) => SUBCOMMANDS.filter((s) => s.startsWith(prefix)).map((s) => ({ value: s, label: s })),
47
+ handler: async (args, ctx) => {
48
+ const registry = getRegistry();
49
+ await registry.ensureDefaultInstalled();
50
+ const [sub, ...rest] = args.trim().split(/\s+/).filter(Boolean);
51
+ const ws = ctx.cwd;
52
+ try {
53
+ let lines;
54
+ switch (sub ?? "current") {
55
+ case "list":
56
+ lines = await handleList(registry, ws);
57
+ break;
58
+ case "current":
59
+ lines = await handleCurrent(registry, ws);
60
+ break;
61
+ case "switch":
62
+ lines = await handleSwitch(registry, ws, rest[0]);
63
+ await refreshPersonaChip(ctx, registry);
64
+ break;
65
+ case "reset":
66
+ lines = await handleReset(registry, ws);
67
+ await refreshPersonaChip(ctx, registry);
68
+ break;
69
+ case "install":
70
+ lines = await handleInstall(registry, rest[0]);
71
+ break;
72
+ case "uninstall":
73
+ lines = await handleUninstall(registry, rest[0], [ws]);
74
+ await refreshPersonaChip(ctx, registry);
75
+ break;
76
+ default:
77
+ ctx.ui.notify(`Unknown subcommand: ${sub}. Try: ${SUBCOMMANDS.join(", ")}`, "warning");
78
+ return;
79
+ }
80
+ ctx.ui.notify(lines.join("\n"), "info");
81
+ }
82
+ catch (err) {
83
+ ctx.ui.notify(err instanceof Error ? err.message : String(err), "error");
84
+ }
85
+ },
86
+ });
87
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmetech/otto",
3
- "version": "1.1.1",
3
+ "version": "1.2.5",
4
4
  "description": "Terminal-based developer chat assistant. Permanent hard fork of gsd-pi with LangFlow flow triggers, a flow builder, and optional gateway routing for compliance environments.",
5
5
  "keywords": [
6
6
  "ai",
@@ -65,10 +65,18 @@
65
65
  "build:pi-coding-agent": "npm run build:contracts && npm run build -w @otto/pi-coding-agent",
66
66
  "build:native-pkg": "npm run build -w @otto/native",
67
67
  "build:contracts": "npm run build -w @otto-build/contracts",
68
+ "build:coworker-types": "npm run build -w @otto/coworker-types",
69
+ "build:coworker-utils": "npm run build -w @otto/coworker-utils",
70
+ "build:coworker-memory": "npm run build -w @otto/coworker-memory",
71
+ "build:coworker-vault": "npm run build -w @otto/coworker-vault",
72
+ "build:coworker-artifacts": "npm run build -w @otto/coworker-artifacts",
73
+ "build:coworker-scratchpad": "npm run build -w @otto/coworker-scratchpad",
74
+ "build:coworker-persona": "npm run build -w @otto/coworker-persona",
75
+ "build:coworker": "npm run build:coworker-types && npm run build:coworker-utils && npm run build:coworker-memory && npm run build:coworker-vault && npm run build:coworker-artifacts && npm run build:coworker-scratchpad && npm run build:coworker-persona",
68
76
  "build:rpc-client": "npm run build -w @otto-build/rpc-client",
69
77
  "build:pi": "npm run build:contracts && npm run build:native-pkg && npm run build:pi-tui && npm run build:pi-ai && npm run build:pi-agent-core && npm run build:pi-coding-agent",
70
78
  "build:mcp-server": "npm run build -w @otto-build/mcp-server",
71
- "build:core": "npm run build:contracts && npm run build:pi && npm run build:rpc-client && npm run build:mcp-server && tsc && npm run copy-resources && npm run copy-themes && npm run copy-export-html",
79
+ "build:core": "npm run build:contracts && npm run build:coworker && npm run build:pi && npm run build:rpc-client && npm run build:mcp-server && tsc && npm run copy-resources && npm run copy-themes && npm run copy-export-html",
72
80
  "prebuild": "node scripts/sync-brand-colors.mjs && node scripts/sync-piconfig.mjs && node scripts/sync-release-notes.mjs && node scripts/generate-theme-const.mjs",
73
81
  "build": "npm run build:core",
74
82
  "sync-brand-colors": "node scripts/sync-brand-colors.mjs",
@@ -86,7 +94,7 @@
86
94
  "baseline:refactor:phase0": "npm run baseline:refactor:gate && node --import ./src/resources/extensions/workflow/tests/resolve-ts.mjs --experimental-strip-types --test src/resources/extensions/workflow/tests/derive-state-db.test.ts src/resources/extensions/workflow/tests/single-writer-invariant.test.ts src/resources/extensions/workflow/tests/auto-recovery.test.ts src/resources/extensions/workflow/tests/auto-worktree-registry.test.ts",
87
95
  "legacy:cleanup:gate": "node scripts/legacy-cleanup-gate.mjs",
88
96
  "legacy:cleanup:evidence": "node scripts/legacy-cleanup-evidence.mjs",
89
- "test:unit:compiled": "node --import ./scripts/dist-test-resolve.mjs --experimental-test-isolation=process --test-reporter=./scripts/test-reporter-compact.mjs --test \"dist-test/src/tests/*.test.js\" \"dist-test/src/resources/extensions/workflow/tests/*.test.js\" \"dist-test/src/resources/extensions/workflow/tests/*.test.mjs\" \"dist-test/src/resources/extensions/shared/tests/*.test.js\" \"dist-test/src/resources/extensions/subagent/tests/*.test.js\" \"dist-test/src/resources/extensions/claude-code-cli/tests/*.test.js\" \"dist-test/src/resources/extensions/github-sync/tests/*.test.js\" \"dist-test/src/resources/extensions/universal-config/tests/*.test.js\" \"dist-test/src/resources/extensions/visual-brief/tests/*.test.js\" \"dist-test/src/resources/extensions/voice/tests/*.test.js\" \"dist-test/src/resources/extensions/mcp-client/tests/*.test.js\" \"dist-test/src/resources/extensions/remote-questions/tests/*.test.js\"",
97
+ "test:unit:compiled": "node --import ./scripts/dist-test-resolve.mjs --experimental-test-isolation=process --test-reporter=./scripts/test-reporter-compact.mjs --test \"dist-test/src/tests/*.test.js\" \"dist-test/src/resources/extensions/workflow/tests/*.test.js\" \"dist-test/src/resources/extensions/workflow/tests/*.test.mjs\" \"dist-test/src/resources/extensions/shared/tests/*.test.js\" \"dist-test/src/resources/extensions/subagent/tests/*.test.js\" \"dist-test/src/resources/extensions/claude-code-cli/tests/*.test.js\" \"dist-test/src/resources/extensions/github-sync/tests/*.test.js\" \"dist-test/src/resources/extensions/universal-config/tests/*.test.js\" \"dist-test/src/resources/extensions/visual-brief/tests/*.test.js\" \"dist-test/src/resources/extensions/voice/tests/*.test.js\" \"dist-test/src/resources/extensions/mcp-client/tests/*.test.js\" \"dist-test/src/resources/extensions/remote-questions/tests/*.test.js\" \"dist-test/src/resources/extensions/coworker-memory/*.test.js\" \"dist-test/src/resources/extensions/coworker-vault/*.test.js\" \"dist-test/src/resources/extensions/coworker-scratchpad/*.test.js\" \"dist-test/src/resources/extensions/coworker-artifacts/*.test.js\"",
90
98
  "test:unit": "npm run test:compile && npm run test:unit:compiled",
91
99
  "test:changed:src": "node scripts/verify-changed-src-tests.mjs",
92
100
  "test:packages": "npm run test:compile && npm run test:packages:compiled",
@@ -147,17 +155,23 @@
147
155
  "@sinclair/typebox": "^0.34.41",
148
156
  "ajv": "^8.17.1",
149
157
  "ajv-formats": "^3.0.1",
158
+ "axios": "^1.16.1",
159
+ "better-sqlite3": "^11.7.0",
150
160
  "chalk": "^5.6.2",
151
161
  "chokidar": "^5.0.0",
162
+ "date-fns": "^4.4.0",
152
163
  "diff": "^8.0.2",
153
164
  "echarts": "^5.6.0",
165
+ "exceljs": "^4.4.0",
154
166
  "extract-zip": "^2.0.1",
155
167
  "file-type": "^21.1.1",
156
168
  "glob": "^13.0.1",
157
169
  "hosted-git-info": "^9.0.2",
158
170
  "ignore": "^7.0.5",
171
+ "lodash": "^4.18.1",
159
172
  "marked": "^15.0.12",
160
173
  "minimatch": "^10.2.3",
174
+ "nodejs-polars": "^0.24.1",
161
175
  "openai": "^6.26.0",
162
176
  "picomatch": "^4.0.3",
163
177
  "playwright": "^1.58.2",
@@ -167,9 +181,11 @@
167
181
  "sql.js": "^1.14.1",
168
182
  "strip-ansi": "^7.1.0",
169
183
  "undici": "^7.24.2",
170
- "yaml": "^2.8.2"
184
+ "yaml": "^2.8.2",
185
+ "zod": "^4.4.3"
171
186
  },
172
187
  "devDependencies": {
188
+ "@types/lodash": "^4.17.24",
173
189
  "@types/node": "^24.12.0",
174
190
  "@types/picomatch": "^4.0.2",
175
191
  "@types/proper-lockfile": "^4.1.4",
@@ -181,13 +197,13 @@
181
197
  },
182
198
  "optionalDependencies": {
183
199
  "@anthropic-ai/claude-agent-sdk": "0.2.83",
200
+ "@cmetech/otto-engine-darwin-arm64": "1.2.5",
201
+ "@cmetech/otto-engine-darwin-x64": "1.2.5",
202
+ "@cmetech/otto-engine-linux-arm64-gnu": "1.2.5",
203
+ "@cmetech/otto-engine-linux-x64-gnu": "1.2.5",
204
+ "@cmetech/otto-engine-win32-x64-msvc": "1.2.5",
184
205
  "fsevents": "~2.3.3",
185
- "koffi": "^2.9.0",
186
- "@cmetech/otto-engine-darwin-arm64": "1.1.1",
187
- "@cmetech/otto-engine-darwin-x64": "1.1.1",
188
- "@cmetech/otto-engine-linux-arm64-gnu": "1.1.1",
189
- "@cmetech/otto-engine-linux-x64-gnu": "1.1.1",
190
- "@cmetech/otto-engine-win32-x64-msvc": "1.1.1"
206
+ "koffi": "^2.9.0"
191
207
  },
192
208
  "overrides": {
193
209
  "gaxios": "7.1.4",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otto-build/contracts",
3
- "version": "1.1.1",
3
+ "version": "1.2.5",
4
4
  "description": "Shared public contracts for OTTO workspace boundaries",
5
5
  "license": "MIT",
6
6
  "otto": {
@@ -0,0 +1,25 @@
1
+ import type { ArtifactHandle, ArtifactKind, FileWrite, TurnEntry } from './types.js';
2
+ export interface ArtifactStoreOptions {
3
+ workspaceDir: string;
4
+ now?: () => string;
5
+ }
6
+ export declare class ArtifactStore {
7
+ private readonly workspaceDir;
8
+ private readonly now;
9
+ constructor(opts: ArtifactStoreOptions);
10
+ private rootDir;
11
+ private existingSlugs;
12
+ private handleFor;
13
+ private atomicWrite;
14
+ private readMetadata;
15
+ private readProvenance;
16
+ private fileStats;
17
+ create(kind: ArtifactKind, name: string): Promise<ArtifactHandle>;
18
+ update(handle: ArtifactHandle, files: FileWrite[]): Promise<{
19
+ files_touched: string[];
20
+ }>;
21
+ recordTurn(handle: ArtifactHandle, entry: Omit<TurnEntry, '_schema' | 'ts'> & Partial<Pick<TurnEntry, 'ts'>>): Promise<void>;
22
+ list(): Promise<ArtifactHandle[]>;
23
+ get(slug: string): Promise<ArtifactHandle | null>;
24
+ remove(slug: string, confirm: true): Promise<void>;
25
+ }