@cmetech/otto 1.1.0 → 1.2.4

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 (425) 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-paths.js +8 -0
  7. package/dist/resources/extensions/coworker-artifacts/artifacts-command.js +31 -0
  8. package/dist/resources/extensions/coworker-artifacts/artifacts-singleton.js +17 -0
  9. package/dist/resources/extensions/coworker-artifacts/extension-manifest.json +13 -0
  10. package/dist/resources/extensions/coworker-artifacts/index.js +125 -0
  11. package/dist/resources/extensions/coworker-artifacts/list-tool.js +27 -0
  12. package/dist/resources/extensions/coworker-artifacts/open-tool.js +25 -0
  13. package/dist/resources/extensions/coworker-memory/extension-manifest.json +13 -0
  14. package/dist/resources/extensions/coworker-memory/index.js +219 -0
  15. package/dist/resources/extensions/coworker-memory/memorize-tool.js +10 -0
  16. package/dist/resources/extensions/coworker-memory/memory-command.js +157 -0
  17. package/dist/resources/extensions/coworker-memory/memory-singleton.js +55 -0
  18. package/dist/resources/extensions/coworker-memory/recall-tool.js +18 -0
  19. package/dist/resources/extensions/coworker-memory/session-hooks.js +45 -0
  20. package/dist/resources/extensions/coworker-scratchpad/attach-banners.js +53 -0
  21. package/dist/resources/extensions/coworker-scratchpad/extension-manifest.json +13 -0
  22. package/dist/resources/extensions/coworker-scratchpad/format-age.js +9 -0
  23. package/dist/resources/extensions/coworker-scratchpad/helpers.js +38 -0
  24. package/dist/resources/extensions/coworker-scratchpad/index.js +199 -0
  25. package/dist/resources/extensions/coworker-scratchpad/mime-bundle.js +20 -0
  26. package/dist/resources/extensions/coworker-scratchpad/scratchpad-tool.js +118 -0
  27. package/dist/resources/extensions/coworker-scratchpad/session-sidecar.js +60 -0
  28. package/dist/resources/extensions/coworker-scratchpad/sp-command.js +597 -0
  29. package/dist/resources/extensions/coworker-scratchpad/workspace-pointer.js +41 -0
  30. package/dist/resources/extensions/coworker-scratchpad/workspace-root.js +17 -0
  31. package/dist/resources/extensions/coworker-vault/audit-command.js +35 -0
  32. package/dist/resources/extensions/coworker-vault/connect-command.js +42 -0
  33. package/dist/resources/extensions/coworker-vault/datasource-command.js +50 -0
  34. package/dist/resources/extensions/coworker-vault/extension-manifest.json +12 -0
  35. package/dist/resources/extensions/coworker-vault/index.js +171 -0
  36. package/dist/resources/extensions/coworker-vault/test-helpers.js +86 -0
  37. package/dist/resources/extensions/coworker-vault/vault-singleton.js +24 -0
  38. package/dist/resources/extensions/otto/commands/release-notes/_data.js +82 -0
  39. package/dist/resources/extensions/otto/commands/release-notes/command.js +15 -4
  40. package/dist/resources/extensions/subagent/index.js +8 -1
  41. package/dist/resources/extensions/subagent/launch.js +37 -5
  42. package/dist/resources/extensions/subagent/run-store.js +1 -0
  43. package/dist/resources/extensions/workflow/bootstrap/register-extension.js +2 -0
  44. package/dist/resources/extensions/workflow/bootstrap/register-hooks.js +10 -0
  45. package/dist/resources/extensions/workflow/persona-status.js +87 -0
  46. package/dist/update-cmd.d.ts +19 -0
  47. package/dist/update-cmd.js +177 -6
  48. package/package.json +25 -10
  49. package/packages/contracts/package.json +1 -1
  50. package/packages/coworker-artifacts/dist/artifact-store.d.ts +25 -0
  51. package/packages/coworker-artifacts/dist/artifact-store.js +187 -0
  52. package/packages/coworker-artifacts/dist/dir-snapshot.d.ts +7 -0
  53. package/packages/coworker-artifacts/dist/dir-snapshot.js +54 -0
  54. package/packages/coworker-artifacts/dist/errors.d.ts +18 -0
  55. package/packages/coworker-artifacts/dist/errors.js +37 -0
  56. package/packages/coworker-artifacts/dist/index.d.ts +7 -0
  57. package/packages/coworker-artifacts/dist/index.js +7 -0
  58. package/packages/coworker-artifacts/dist/readme-renderer.d.ts +5 -0
  59. package/packages/coworker-artifacts/dist/readme-renderer.js +47 -0
  60. package/packages/coworker-artifacts/dist/resolve-uri.d.ts +3 -0
  61. package/packages/coworker-artifacts/dist/resolve-uri.js +29 -0
  62. package/packages/coworker-artifacts/dist/slug.d.ts +4 -0
  63. package/packages/coworker-artifacts/dist/slug.js +32 -0
  64. package/packages/coworker-artifacts/dist/types.d.ts +52 -0
  65. package/packages/coworker-artifacts/dist/types.js +1 -0
  66. package/packages/coworker-artifacts/package.json +20 -0
  67. package/packages/coworker-artifacts/src/artifact-store.test.ts +188 -0
  68. package/packages/coworker-artifacts/src/artifact-store.ts +206 -0
  69. package/packages/coworker-artifacts/src/artifacts-integration.test.ts +109 -0
  70. package/packages/coworker-artifacts/src/dir-snapshot.test.ts +71 -0
  71. package/packages/coworker-artifacts/src/dir-snapshot.ts +52 -0
  72. package/packages/coworker-artifacts/src/errors.test.ts +37 -0
  73. package/packages/coworker-artifacts/src/errors.ts +28 -0
  74. package/packages/coworker-artifacts/src/index.test.ts +22 -0
  75. package/packages/coworker-artifacts/src/index.ts +7 -0
  76. package/packages/coworker-artifacts/src/readme-renderer.test.ts +72 -0
  77. package/packages/coworker-artifacts/src/readme-renderer.ts +56 -0
  78. package/packages/coworker-artifacts/src/resolve-uri.test.ts +46 -0
  79. package/packages/coworker-artifacts/src/resolve-uri.ts +29 -0
  80. package/packages/coworker-artifacts/src/slug.test.ts +47 -0
  81. package/packages/coworker-artifacts/src/slug.ts +31 -0
  82. package/packages/coworker-artifacts/src/types.ts +61 -0
  83. package/packages/coworker-artifacts/tsconfig.json +15 -0
  84. package/packages/coworker-artifacts/tsconfig.publish.json +4 -0
  85. package/packages/coworker-memory/dist/context-injection.d.ts +9 -0
  86. package/packages/coworker-memory/dist/context-injection.js +41 -0
  87. package/packages/coworker-memory/dist/errors.d.ts +25 -0
  88. package/packages/coworker-memory/dist/errors.js +51 -0
  89. package/packages/coworker-memory/dist/index.d.ts +12 -0
  90. package/packages/coworker-memory/dist/index.js +12 -0
  91. package/packages/coworker-memory/dist/layer-a-store.d.ts +16 -0
  92. package/packages/coworker-memory/dist/layer-a-store.js +78 -0
  93. package/packages/coworker-memory/dist/local-sqlite-backend.d.ts +28 -0
  94. package/packages/coworker-memory/dist/local-sqlite-backend.js +167 -0
  95. package/packages/coworker-memory/dist/memory-backend.d.ts +14 -0
  96. package/packages/coworker-memory/dist/memory-backend.js +1 -0
  97. package/packages/coworker-memory/dist/memory-recorder.d.ts +50 -0
  98. package/packages/coworker-memory/dist/memory-recorder.js +69 -0
  99. package/packages/coworker-memory/dist/migrations/001-init.sql +38 -0
  100. package/packages/coworker-memory/dist/migrations/002-artifact-kind.sql +50 -0
  101. package/packages/coworker-memory/dist/paste-detector.d.ts +5 -0
  102. package/packages/coworker-memory/dist/paste-detector.js +14 -0
  103. package/packages/coworker-memory/dist/persona-seed.d.ts +10 -0
  104. package/packages/coworker-memory/dist/persona-seed.js +38 -0
  105. package/packages/coworker-memory/dist/recall-formatter.d.ts +2 -0
  106. package/packages/coworker-memory/dist/recall-formatter.js +14 -0
  107. package/packages/coworker-memory/dist/scope-resolver.d.ts +9 -0
  108. package/packages/coworker-memory/dist/scope-resolver.js +10 -0
  109. package/packages/coworker-memory/dist/types.d.ts +51 -0
  110. package/packages/coworker-memory/dist/types.js +2 -0
  111. package/packages/coworker-memory/dist/workspace-id.d.ts +3 -0
  112. package/packages/coworker-memory/dist/workspace-id.js +54 -0
  113. package/packages/coworker-memory/package.json +35 -0
  114. package/packages/coworker-memory/src/activator-integration.test.ts +141 -0
  115. package/packages/coworker-memory/src/context-injection.test.ts +72 -0
  116. package/packages/coworker-memory/src/context-injection.ts +57 -0
  117. package/packages/coworker-memory/src/errors.test.ts +45 -0
  118. package/packages/coworker-memory/src/errors.ts +42 -0
  119. package/packages/coworker-memory/src/index.test.ts +21 -0
  120. package/packages/coworker-memory/src/index.ts +12 -0
  121. package/packages/coworker-memory/src/layer-a-store.test.ts +85 -0
  122. package/packages/coworker-memory/src/layer-a-store.ts +88 -0
  123. package/packages/coworker-memory/src/local-sqlite-backend.test.ts +110 -0
  124. package/packages/coworker-memory/src/local-sqlite-backend.ts +185 -0
  125. package/packages/coworker-memory/src/memory-backend.ts +10 -0
  126. package/packages/coworker-memory/src/memory-integration.test.ts +89 -0
  127. package/packages/coworker-memory/src/memory-recorder.test.ts +101 -0
  128. package/packages/coworker-memory/src/memory-recorder.ts +95 -0
  129. package/packages/coworker-memory/src/migrations/001-init.sql +38 -0
  130. package/packages/coworker-memory/src/migrations/002-artifact-kind.sql +50 -0
  131. package/packages/coworker-memory/src/paste-detector.test.ts +23 -0
  132. package/packages/coworker-memory/src/paste-detector.ts +18 -0
  133. package/packages/coworker-memory/src/persona-seed.test.ts +57 -0
  134. package/packages/coworker-memory/src/persona-seed.ts +46 -0
  135. package/packages/coworker-memory/src/recall-formatter.test.ts +34 -0
  136. package/packages/coworker-memory/src/recall-formatter.ts +15 -0
  137. package/packages/coworker-memory/src/scope-resolver.test.ts +23 -0
  138. package/packages/coworker-memory/src/scope-resolver.ts +18 -0
  139. package/packages/coworker-memory/src/types.ts +61 -0
  140. package/packages/coworker-memory/src/workspace-id.test.ts +48 -0
  141. package/packages/coworker-memory/src/workspace-id.ts +56 -0
  142. package/packages/coworker-memory/tsconfig.json +15 -0
  143. package/packages/coworker-memory/tsconfig.publish.json +4 -0
  144. package/packages/coworker-persona/dist/commands.d.ts +7 -0
  145. package/packages/coworker-persona/dist/commands.js +35 -0
  146. package/packages/coworker-persona/dist/defaults/manifest.yaml +12 -0
  147. package/packages/coworker-persona/dist/defaults/steering/identity.md +3 -0
  148. package/packages/coworker-persona/dist/index.d.ts +3 -0
  149. package/packages/coworker-persona/dist/index.js +3 -0
  150. package/packages/coworker-persona/dist/manifest.d.ts +24 -0
  151. package/packages/coworker-persona/dist/manifest.js +21 -0
  152. package/packages/coworker-persona/dist/registry.d.ts +22 -0
  153. package/packages/coworker-persona/dist/registry.js +142 -0
  154. package/packages/coworker-persona/package.json +28 -0
  155. package/packages/coworker-persona/scripts/copy-defaults.cjs +17 -0
  156. package/packages/coworker-persona/src/commands.ts +47 -0
  157. package/packages/coworker-persona/src/defaults/manifest.yaml +12 -0
  158. package/packages/coworker-persona/src/defaults/steering/identity.md +3 -0
  159. package/packages/coworker-persona/src/index.ts +3 -0
  160. package/packages/coworker-persona/src/manifest.test.ts +67 -0
  161. package/packages/coworker-persona/src/manifest.ts +49 -0
  162. package/packages/coworker-persona/src/registry.test.ts +89 -0
  163. package/packages/coworker-persona/src/registry.ts +147 -0
  164. package/packages/coworker-persona/tsconfig.json +15 -0
  165. package/packages/coworker-persona/tsconfig.publish.json +4 -0
  166. package/packages/coworker-scratchpad/dist/cell-archive.d.ts +39 -0
  167. package/packages/coworker-scratchpad/dist/cell-archive.js +77 -0
  168. package/packages/coworker-scratchpad/dist/cell-tree.d.ts +14 -0
  169. package/packages/coworker-scratchpad/dist/cell-tree.js +72 -0
  170. package/packages/coworker-scratchpad/dist/child-process-runtime.d.ts +129 -0
  171. package/packages/coworker-scratchpad/dist/child-process-runtime.js +427 -0
  172. package/packages/coworker-scratchpad/dist/collector-registry.d.ts +12 -0
  173. package/packages/coworker-scratchpad/dist/collector-registry.js +29 -0
  174. package/packages/coworker-scratchpad/dist/detect-kind.d.ts +3 -0
  175. package/packages/coworker-scratchpad/dist/detect-kind.js +19 -0
  176. package/packages/coworker-scratchpad/dist/file-collector.d.ts +15 -0
  177. package/packages/coworker-scratchpad/dist/file-collector.js +99 -0
  178. package/packages/coworker-scratchpad/dist/index.d.ts +13 -0
  179. package/packages/coworker-scratchpad/dist/index.js +13 -0
  180. package/packages/coworker-scratchpad/dist/kernel-bindings.d.ts +49 -0
  181. package/packages/coworker-scratchpad/dist/kernel-bindings.js +220 -0
  182. package/packages/coworker-scratchpad/dist/kernel-entry.d.ts +1 -0
  183. package/packages/coworker-scratchpad/dist/kernel-entry.js +355 -0
  184. package/packages/coworker-scratchpad/dist/kernel-protocol.d.ts +171 -0
  185. package/packages/coworker-scratchpad/dist/kernel-protocol.js +48 -0
  186. package/packages/coworker-scratchpad/dist/kernel-spawn.d.ts +3 -0
  187. package/packages/coworker-scratchpad/dist/kernel-spawn.js +54 -0
  188. package/packages/coworker-scratchpad/dist/namespace-codec.d.ts +22 -0
  189. package/packages/coworker-scratchpad/dist/namespace-codec.js +61 -0
  190. package/packages/coworker-scratchpad/dist/scratchpad-lock.d.ts +24 -0
  191. package/packages/coworker-scratchpad/dist/scratchpad-lock.js +86 -0
  192. package/packages/coworker-scratchpad/dist/scratchpad-manager.d.ts +193 -0
  193. package/packages/coworker-scratchpad/dist/scratchpad-manager.js +866 -0
  194. package/packages/coworker-scratchpad/dist/staleness-banner.d.ts +12 -0
  195. package/packages/coworker-scratchpad/dist/staleness-banner.js +27 -0
  196. package/packages/coworker-scratchpad/package.json +31 -0
  197. package/packages/coworker-scratchpad/src/cell-archive.test.ts +150 -0
  198. package/packages/coworker-scratchpad/src/cell-archive.ts +97 -0
  199. package/packages/coworker-scratchpad/src/cell-tree.test.ts +105 -0
  200. package/packages/coworker-scratchpad/src/cell-tree.ts +90 -0
  201. package/packages/coworker-scratchpad/src/child-process-runtime.test.ts +413 -0
  202. package/packages/coworker-scratchpad/src/child-process-runtime.ts +493 -0
  203. package/packages/coworker-scratchpad/src/collector-registry.test.ts +69 -0
  204. package/packages/coworker-scratchpad/src/collector-registry.ts +33 -0
  205. package/packages/coworker-scratchpad/src/detect-kind.test.ts +33 -0
  206. package/packages/coworker-scratchpad/src/detect-kind.ts +22 -0
  207. package/packages/coworker-scratchpad/src/file-collector.test.ts +109 -0
  208. package/packages/coworker-scratchpad/src/file-collector.ts +114 -0
  209. package/packages/coworker-scratchpad/src/index.ts +74 -0
  210. package/packages/coworker-scratchpad/src/kernel-bindings.test.ts +188 -0
  211. package/packages/coworker-scratchpad/src/kernel-bindings.ts +279 -0
  212. package/packages/coworker-scratchpad/src/kernel-entry.test.ts +123 -0
  213. package/packages/coworker-scratchpad/src/kernel-entry.ts +390 -0
  214. package/packages/coworker-scratchpad/src/kernel-protocol.test.ts +105 -0
  215. package/packages/coworker-scratchpad/src/kernel-protocol.ts +230 -0
  216. package/packages/coworker-scratchpad/src/kernel-spawn.test.ts +60 -0
  217. package/packages/coworker-scratchpad/src/kernel-spawn.ts +54 -0
  218. package/packages/coworker-scratchpad/src/namespace-codec.test.ts +102 -0
  219. package/packages/coworker-scratchpad/src/namespace-codec.ts +90 -0
  220. package/packages/coworker-scratchpad/src/scratchpad-lock.test.ts +98 -0
  221. package/packages/coworker-scratchpad/src/scratchpad-lock.ts +102 -0
  222. package/packages/coworker-scratchpad/src/scratchpad-manager.test.ts +1343 -0
  223. package/packages/coworker-scratchpad/src/scratchpad-manager.ts +891 -0
  224. package/packages/coworker-scratchpad/src/staleness-banner.test.ts +53 -0
  225. package/packages/coworker-scratchpad/src/staleness-banner.ts +33 -0
  226. package/packages/coworker-scratchpad/src/vault-integration.test.ts +221 -0
  227. package/packages/coworker-scratchpad/tsconfig.json +15 -0
  228. package/packages/coworker-scratchpad/tsconfig.publish.json +4 -0
  229. package/packages/coworker-types/dist/artifacts.d.ts +31 -0
  230. package/packages/coworker-types/dist/artifacts.js +2 -0
  231. package/packages/coworker-types/dist/contracts.d.ts +32 -0
  232. package/packages/coworker-types/dist/contracts.js +1 -0
  233. package/packages/coworker-types/dist/index.d.ts +5 -0
  234. package/packages/coworker-types/dist/index.js +5 -0
  235. package/packages/coworker-types/dist/memory.d.ts +61 -0
  236. package/packages/coworker-types/dist/memory.js +3 -0
  237. package/packages/coworker-types/dist/scratchpad.d.ts +43 -0
  238. package/packages/coworker-types/dist/scratchpad.js +2 -0
  239. package/packages/coworker-types/dist/vault.d.ts +34 -0
  240. package/packages/coworker-types/dist/vault.js +2 -0
  241. package/packages/coworker-types/package.json +24 -0
  242. package/packages/coworker-types/src/artifacts.test.ts +52 -0
  243. package/packages/coworker-types/src/artifacts.ts +35 -0
  244. package/packages/coworker-types/src/contracts.test.ts +43 -0
  245. package/packages/coworker-types/src/contracts.ts +36 -0
  246. package/packages/coworker-types/src/index.ts +5 -0
  247. package/packages/coworker-types/src/memory.test.ts +50 -0
  248. package/packages/coworker-types/src/memory.ts +79 -0
  249. package/packages/coworker-types/src/scratchpad.test.ts +46 -0
  250. package/packages/coworker-types/src/scratchpad.ts +51 -0
  251. package/packages/coworker-types/src/smoke.test.ts +34 -0
  252. package/packages/coworker-types/src/vault.test.ts +49 -0
  253. package/packages/coworker-types/src/vault.ts +40 -0
  254. package/packages/coworker-types/tsconfig.json +15 -0
  255. package/packages/coworker-types/tsconfig.publish.json +4 -0
  256. package/packages/coworker-utils/dist/audit-log.d.ts +34 -0
  257. package/packages/coworker-utils/dist/audit-log.js +88 -0
  258. package/packages/coworker-utils/dist/index.d.ts +6 -0
  259. package/packages/coworker-utils/dist/index.js +6 -0
  260. package/packages/coworker-utils/dist/lease.d.ts +7 -0
  261. package/packages/coworker-utils/dist/lease.js +67 -0
  262. package/packages/coworker-utils/dist/logger.d.ts +13 -0
  263. package/packages/coworker-utils/dist/logger.js +26 -0
  264. package/packages/coworker-utils/dist/migration-runner.d.ts +7 -0
  265. package/packages/coworker-utils/dist/migration-runner.js +36 -0
  266. package/packages/coworker-utils/dist/ndjson-channel.d.ts +3 -0
  267. package/packages/coworker-utils/dist/ndjson-channel.js +38 -0
  268. package/packages/coworker-utils/dist/secret-scanner.d.ts +10 -0
  269. package/packages/coworker-utils/dist/secret-scanner.js +42 -0
  270. package/packages/coworker-utils/package.json +24 -0
  271. package/packages/coworker-utils/src/audit-log.test.ts +140 -0
  272. package/packages/coworker-utils/src/audit-log.ts +107 -0
  273. package/packages/coworker-utils/src/index.ts +6 -0
  274. package/packages/coworker-utils/src/lease.test.ts +64 -0
  275. package/packages/coworker-utils/src/lease.ts +76 -0
  276. package/packages/coworker-utils/src/logger.test.ts +50 -0
  277. package/packages/coworker-utils/src/logger.ts +45 -0
  278. package/packages/coworker-utils/src/migration-runner.test.ts +65 -0
  279. package/packages/coworker-utils/src/migration-runner.ts +50 -0
  280. package/packages/coworker-utils/src/ndjson-channel.test.ts +76 -0
  281. package/packages/coworker-utils/src/ndjson-channel.ts +41 -0
  282. package/packages/coworker-utils/src/secret-scanner.test.ts +61 -0
  283. package/packages/coworker-utils/src/secret-scanner.ts +56 -0
  284. package/packages/coworker-utils/tsconfig.json +15 -0
  285. package/packages/coworker-utils/tsconfig.publish.json +4 -0
  286. package/packages/coworker-vault/dist/data-vault.d.ts +41 -0
  287. package/packages/coworker-vault/dist/data-vault.js +223 -0
  288. package/packages/coworker-vault/dist/engine-registry.d.ts +34 -0
  289. package/packages/coworker-vault/dist/engine-registry.js +90 -0
  290. package/packages/coworker-vault/dist/engines/jira.yaml +17 -0
  291. package/packages/coworker-vault/dist/errors.d.ts +28 -0
  292. package/packages/coworker-vault/dist/errors.js +57 -0
  293. package/packages/coworker-vault/dist/index.d.ts +6 -0
  294. package/packages/coworker-vault/dist/index.js +6 -0
  295. package/packages/coworker-vault/dist/injector.d.ts +19 -0
  296. package/packages/coworker-vault/dist/injector.js +77 -0
  297. package/packages/coworker-vault/dist/types.d.ts +28 -0
  298. package/packages/coworker-vault/dist/types.js +1 -0
  299. package/packages/coworker-vault/dist/vault-keep.d.ts +4 -0
  300. package/packages/coworker-vault/dist/vault-keep.js +21 -0
  301. package/packages/coworker-vault/package.json +29 -0
  302. package/packages/coworker-vault/src/data-vault.test.ts +199 -0
  303. package/packages/coworker-vault/src/data-vault.ts +257 -0
  304. package/packages/coworker-vault/src/engine-registry.test.ts +120 -0
  305. package/packages/coworker-vault/src/engine-registry.ts +107 -0
  306. package/packages/coworker-vault/src/engines/jira.yaml +17 -0
  307. package/packages/coworker-vault/src/errors.test.ts +58 -0
  308. package/packages/coworker-vault/src/errors.ts +50 -0
  309. package/packages/coworker-vault/src/index.test.ts +24 -0
  310. package/packages/coworker-vault/src/index.ts +6 -0
  311. package/packages/coworker-vault/src/injector.test.ts +109 -0
  312. package/packages/coworker-vault/src/injector.ts +98 -0
  313. package/packages/coworker-vault/src/types.ts +33 -0
  314. package/packages/coworker-vault/src/vault-keep.test.ts +49 -0
  315. package/packages/coworker-vault/src/vault-keep.ts +31 -0
  316. package/packages/coworker-vault/tsconfig.json +15 -0
  317. package/packages/coworker-vault/tsconfig.publish.json +4 -0
  318. package/packages/daemon/package.json +3 -3
  319. package/packages/mcp-server/package.json +3 -3
  320. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  321. package/packages/native/package.json +1 -1
  322. package/packages/native/tsconfig.tsbuildinfo +1 -1
  323. package/packages/pi-agent-core/package.json +1 -1
  324. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  325. package/packages/pi-ai/package.json +1 -1
  326. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  327. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +6 -1
  328. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  329. package/packages/pi-coding-agent/dist/core/extensions/runner.js +22 -3
  330. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  331. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +11 -0
  332. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.d.ts +47 -0
  334. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.d.ts.map +1 -0
  335. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.js +107 -0
  336. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.js.map +1 -0
  337. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.d.ts +19 -0
  338. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.d.ts.map +1 -0
  339. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.js +121 -0
  340. package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.js.map +1 -0
  341. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +17 -1
  343. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  344. package/packages/pi-coding-agent/package.json +2 -2
  345. package/packages/pi-coding-agent/src/core/extensions/runner.ts +22 -3
  346. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +11 -0
  347. package/packages/pi-coding-agent/src/modes/rpc/raw-stdout.regression.test.ts +129 -0
  348. package/packages/pi-coding-agent/src/modes/rpc/raw-stdout.ts +117 -0
  349. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +18 -1
  350. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  351. package/packages/pi-tui/package.json +1 -1
  352. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  353. package/packages/rpc-client/package.json +2 -2
  354. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  355. package/pkg/package.json +1 -1
  356. package/scripts/install.js +6 -5
  357. package/src/resources/extensions/_coworker-paths.test.ts +40 -0
  358. package/src/resources/extensions/_coworker-paths.ts +10 -0
  359. package/src/resources/extensions/coworker-artifacts/artifacts-command.test.ts +54 -0
  360. package/src/resources/extensions/coworker-artifacts/artifacts-command.ts +43 -0
  361. package/src/resources/extensions/coworker-artifacts/artifacts-singleton.test.ts +25 -0
  362. package/src/resources/extensions/coworker-artifacts/artifacts-singleton.ts +29 -0
  363. package/src/resources/extensions/coworker-artifacts/extension-manifest.json +13 -0
  364. package/src/resources/extensions/coworker-artifacts/index.test.ts +46 -0
  365. package/src/resources/extensions/coworker-artifacts/index.ts +154 -0
  366. package/src/resources/extensions/coworker-artifacts/list-tool.test.ts +29 -0
  367. package/src/resources/extensions/coworker-artifacts/list-tool.ts +53 -0
  368. package/src/resources/extensions/coworker-artifacts/open-tool.test.ts +30 -0
  369. package/src/resources/extensions/coworker-artifacts/open-tool.ts +43 -0
  370. package/src/resources/extensions/coworker-memory/extension-manifest.json +13 -0
  371. package/src/resources/extensions/coworker-memory/index.test.ts +137 -0
  372. package/src/resources/extensions/coworker-memory/index.ts +257 -0
  373. package/src/resources/extensions/coworker-memory/memorize-tool.test.ts +41 -0
  374. package/src/resources/extensions/coworker-memory/memorize-tool.ts +20 -0
  375. package/src/resources/extensions/coworker-memory/memory-command.test.ts +134 -0
  376. package/src/resources/extensions/coworker-memory/memory-command.ts +131 -0
  377. package/src/resources/extensions/coworker-memory/memory-singleton.test.ts +41 -0
  378. package/src/resources/extensions/coworker-memory/memory-singleton.ts +89 -0
  379. package/src/resources/extensions/coworker-memory/recall-tool.test.ts +50 -0
  380. package/src/resources/extensions/coworker-memory/recall-tool.ts +35 -0
  381. package/src/resources/extensions/coworker-memory/session-hooks.test.ts +77 -0
  382. package/src/resources/extensions/coworker-memory/session-hooks.ts +61 -0
  383. package/src/resources/extensions/coworker-scratchpad/attach-banners.test.ts +124 -0
  384. package/src/resources/extensions/coworker-scratchpad/attach-banners.ts +67 -0
  385. package/src/resources/extensions/coworker-scratchpad/extension-manifest.json +13 -0
  386. package/src/resources/extensions/coworker-scratchpad/format-age.test.ts +30 -0
  387. package/src/resources/extensions/coworker-scratchpad/format-age.ts +6 -0
  388. package/src/resources/extensions/coworker-scratchpad/helpers.test.ts +93 -0
  389. package/src/resources/extensions/coworker-scratchpad/helpers.ts +42 -0
  390. package/src/resources/extensions/coworker-scratchpad/index.test.ts +514 -0
  391. package/src/resources/extensions/coworker-scratchpad/index.ts +207 -0
  392. package/src/resources/extensions/coworker-scratchpad/mime-bundle.test.ts +61 -0
  393. package/src/resources/extensions/coworker-scratchpad/mime-bundle.ts +23 -0
  394. package/src/resources/extensions/coworker-scratchpad/scratchpad-tool.test.ts +137 -0
  395. package/src/resources/extensions/coworker-scratchpad/scratchpad-tool.ts +165 -0
  396. package/src/resources/extensions/coworker-scratchpad/session-sidecar.test.ts +133 -0
  397. package/src/resources/extensions/coworker-scratchpad/session-sidecar.ts +68 -0
  398. package/src/resources/extensions/coworker-scratchpad/sp-command.test.ts +836 -0
  399. package/src/resources/extensions/coworker-scratchpad/sp-command.ts +602 -0
  400. package/src/resources/extensions/coworker-scratchpad/workspace-pointer.test.ts +74 -0
  401. package/src/resources/extensions/coworker-scratchpad/workspace-pointer.ts +55 -0
  402. package/src/resources/extensions/coworker-scratchpad/workspace-root.test.ts +51 -0
  403. package/src/resources/extensions/coworker-scratchpad/workspace-root.ts +16 -0
  404. package/src/resources/extensions/coworker-vault/audit-command.test.ts +109 -0
  405. package/src/resources/extensions/coworker-vault/audit-command.ts +56 -0
  406. package/src/resources/extensions/coworker-vault/connect-command.test.ts +103 -0
  407. package/src/resources/extensions/coworker-vault/connect-command.ts +69 -0
  408. package/src/resources/extensions/coworker-vault/datasource-command.test.ts +80 -0
  409. package/src/resources/extensions/coworker-vault/datasource-command.ts +81 -0
  410. package/src/resources/extensions/coworker-vault/extension-manifest.json +12 -0
  411. package/src/resources/extensions/coworker-vault/index.test.ts +82 -0
  412. package/src/resources/extensions/coworker-vault/index.ts +181 -0
  413. package/src/resources/extensions/coworker-vault/test-helpers.ts +120 -0
  414. package/src/resources/extensions/coworker-vault/vault-singleton.test.ts +27 -0
  415. package/src/resources/extensions/coworker-vault/vault-singleton.ts +40 -0
  416. package/src/resources/extensions/otto/commands/release-notes/_data.ts +96 -0
  417. package/src/resources/extensions/otto/commands/release-notes/command.ts +16 -3
  418. package/src/resources/extensions/subagent/index.ts +9 -0
  419. package/src/resources/extensions/subagent/launch.test.ts +97 -0
  420. package/src/resources/extensions/subagent/launch.ts +42 -5
  421. package/src/resources/extensions/subagent/run-store.ts +3 -1
  422. package/src/resources/extensions/workflow/bootstrap/register-extension.ts +2 -0
  423. package/src/resources/extensions/workflow/bootstrap/register-hooks.ts +10 -0
  424. package/src/resources/extensions/workflow/persona-status.ts +109 -0
  425. package/src/resources/extensions/workflow/tests/auto-recovery.test.ts +34 -0
@@ -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);
@@ -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
+ }
@@ -2,5 +2,24 @@ interface RunUpdateOptions {
2
2
  agentDir?: string;
3
3
  skillsDir?: string;
4
4
  }
5
+ /**
6
+ * Build the PowerShell bootstrap that runs the install in a detached, visible
7
+ * console window. Exported for tests. The script:
8
+ * 1. Writes an initial status file at `statusPath`.
9
+ * 2. Waits up to 30s for the parent otto.exe (parentPid) to exit so its
10
+ * DLL handles release.
11
+ * 3. Runs the install command (`npm install -g …` or `bun add -g …`).
12
+ * 4. Sweeps any orphan `.otto-*` staging dirs npm left behind.
13
+ * 5. Updates the status file with completion details.
14
+ * 6. Prints a clear "Done" message and waits for a keypress.
15
+ */
16
+ export declare function buildWindowsBootstrapScript(args: {
17
+ parentPid: number;
18
+ installCmd: string;
19
+ statusPath: string;
20
+ current: string;
21
+ latest: string;
22
+ startedAt: string;
23
+ }): string;
5
24
  export declare function runUpdate(options?: RunUpdateOptions): Promise<void>;
6
25
  export {};
@@ -1,15 +1,177 @@
1
- import { execSync } from 'node:child_process';
1
+ import { execSync, spawn } from 'node:child_process';
2
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
2
5
  import { agentDir as defaultAgentDir } from './app-paths.js';
3
6
  import { initResources } from './resource-loader.js';
4
7
  import { compareSemver, fetchLatestVersionFromRegistry, resolveInstallCommand } from './update-check.js';
5
8
  const NPM_PACKAGE = '@cmetech/otto';
9
+ function getStatusPath(agentDir) {
10
+ return join(agentDir, 'update-status.json');
11
+ }
12
+ function maybeShowPriorStatus(agentDir) {
13
+ const statusPath = getStatusPath(agentDir);
14
+ if (!existsSync(statusPath))
15
+ return;
16
+ try {
17
+ const status = JSON.parse(readFileSync(statusPath, 'utf-8'));
18
+ if (status.completedAt) {
19
+ const dim = '\x1b[2m';
20
+ const reset = '\x1b[0m';
21
+ const outcome = status.exitCode === 0 ? '✓ success' : `✗ exit ${status.exitCode}`;
22
+ process.stdout.write(`${dim}Last update: v${status.fromVersion} → v${status.toVersion} at ${status.completedAt} (${outcome})${reset}\n`);
23
+ }
24
+ }
25
+ catch {
26
+ // Ignore parse errors — file may be partial or corrupt.
27
+ }
28
+ }
29
+ /**
30
+ * Build the PowerShell bootstrap that runs the install in a detached, visible
31
+ * console window. Exported for tests. The script:
32
+ * 1. Writes an initial status file at `statusPath`.
33
+ * 2. Waits up to 30s for the parent otto.exe (parentPid) to exit so its
34
+ * DLL handles release.
35
+ * 3. Runs the install command (`npm install -g …` or `bun add -g …`).
36
+ * 4. Sweeps any orphan `.otto-*` staging dirs npm left behind.
37
+ * 5. Updates the status file with completion details.
38
+ * 6. Prints a clear "Done" message and waits for a keypress.
39
+ */
40
+ export function buildWindowsBootstrapScript(args) {
41
+ // PowerShell single-quoted strings are literal — backslashes and $ are not
42
+ // interpreted. Path values flow straight through.
43
+ const psQuote = (value) => `'${value.replace(/'/g, "''")}'`;
44
+ const status = psQuote(args.statusPath);
45
+ const current = psQuote(args.current);
46
+ const latest = psQuote(args.latest);
47
+ const startedAt = psQuote(args.startedAt);
48
+ const installCmd = args.installCmd; // run as-is — must be a valid PowerShell command line
49
+ return `# OTTO update bootstrap — auto-generated by otto update on Windows
50
+ $ErrorActionPreference = 'Continue'
51
+ $Host.UI.RawUI.WindowTitle = 'OTTO Updater'
52
+
53
+ Write-Host 'OTTO Updater — please do not close this window' -ForegroundColor Cyan
54
+ Write-Host '─────────────────────────────────────────────────'
55
+ Write-Host ''
56
+
57
+ # Write initial status
58
+ $statusPath = ${status}
59
+ $statusDir = Split-Path -Parent $statusPath
60
+ if ($statusDir -and -not (Test-Path $statusDir)) {
61
+ New-Item -ItemType Directory -Path $statusDir -Force | Out-Null
62
+ }
63
+ @{
64
+ startedAt = ${startedAt}
65
+ fromVersion = ${current}
66
+ toVersion = ${latest}
67
+ } | ConvertTo-Json | Set-Content -Path $statusPath -Encoding UTF8
68
+
69
+ # Wait for parent otto.exe (pid ${args.parentPid}) to exit, max 30s
70
+ Write-Host -NoNewline 'Waiting for OTTO to exit...'
71
+ $deadline = (Get-Date).AddSeconds(30)
72
+ while ((Get-Process -Id ${args.parentPid} -ErrorAction SilentlyContinue) -and ((Get-Date) -lt $deadline)) {
73
+ Start-Sleep -Milliseconds 300
74
+ }
75
+ if (Get-Process -Id ${args.parentPid} -ErrorAction SilentlyContinue) {
76
+ Write-Host ' timeout!' -ForegroundColor Yellow
77
+ Write-Host 'OTTO did not exit in 30s. To finish manually, run:' -ForegroundColor Yellow
78
+ Write-Host (' ' + ${psQuote(installCmd)})
79
+ Write-Host ''
80
+ Write-Host 'Press any key to close this window.'
81
+ $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
82
+ exit 1
83
+ }
84
+ Write-Host ' done.'
85
+ Write-Host ''
86
+
87
+ # Run the install
88
+ Write-Host ('Running: ' + ${psQuote(installCmd)}) -ForegroundColor Cyan
89
+ Write-Host ''
90
+ ${installCmd}
91
+ $exitCode = $LASTEXITCODE
92
+
93
+ # Sweep orphan .otto-* staging dirs npm couldn't clean up
94
+ $stagingRoot = Join-Path $env:APPDATA 'npm\\node_modules\\@cmetech'
95
+ if (Test-Path $stagingRoot) {
96
+ Get-ChildItem -Path $stagingRoot -Directory -Filter '.otto-*' -ErrorAction SilentlyContinue |
97
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
98
+ }
99
+
100
+ # Write final status
101
+ @{
102
+ startedAt = ${startedAt}
103
+ completedAt = (Get-Date -Format 'o')
104
+ fromVersion = ${current}
105
+ toVersion = ${latest}
106
+ exitCode = $exitCode
107
+ } | ConvertTo-Json | Set-Content -Path $statusPath -Encoding UTF8
108
+
109
+ Write-Host ''
110
+ if ($exitCode -eq 0) {
111
+ Write-Host ('Done. OTTO v' + ${latest} + ' installed.') -ForegroundColor Green
112
+ Write-Host 'Open any terminal and run otto to use the new version.'
113
+ } else {
114
+ Write-Host ('Install failed with exit code ' + $exitCode) -ForegroundColor Red
115
+ Write-Host ('Try manually: ' + ${psQuote(installCmd)})
116
+ }
117
+ Write-Host ''
118
+ Write-Host 'Press any key to close this window.'
119
+ $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
120
+ exit $exitCode
121
+ `;
122
+ }
123
+ function runWindowsDetachedUpdate(current, latest, installCmd, agentDir) {
124
+ const tempDir = mkdtempSync(join(tmpdir(), 'otto-update-'));
125
+ const scriptPath = join(tempDir, 'update.ps1');
126
+ const statusPath = getStatusPath(agentDir);
127
+ const startedAt = new Date().toISOString();
128
+ if (!existsSync(agentDir)) {
129
+ mkdirSync(agentDir, { recursive: true });
130
+ }
131
+ const script = buildWindowsBootstrapScript({
132
+ parentPid: process.pid,
133
+ installCmd,
134
+ statusPath,
135
+ current,
136
+ latest,
137
+ startedAt,
138
+ });
139
+ writeFileSync(scriptPath, script, 'utf-8');
140
+ const bold = '\x1b[1m';
141
+ const dim = '\x1b[2m';
142
+ const reset = '\x1b[0m';
143
+ process.stdout.write(`${dim}Updating:${reset} v${current} → ${bold}v${latest}${reset}\n\n`);
144
+ process.stdout.write('Update is running in a new window — Windows cannot replace files while OTTO is open.\n');
145
+ process.stdout.write(`When the update window shows ${bold}"Done."${reset} run \`otto\` in any terminal to use v${latest}.\n\n`);
146
+ // `cmd.exe /c start "Title" powershell.exe -File <script>`
147
+ // Node quotes args that contain spaces, so `start OTTO Updater` becomes
148
+ // `start "OTTO Updater"`, which CMD's start builtin treats as the window
149
+ // title (longstanding CMD quirk).
150
+ const child = spawn('cmd.exe', [
151
+ '/c',
152
+ 'start',
153
+ 'OTTO Updater',
154
+ 'powershell.exe',
155
+ '-NoProfile',
156
+ '-ExecutionPolicy',
157
+ 'Bypass',
158
+ '-File',
159
+ scriptPath,
160
+ ], { detached: true, stdio: 'ignore', windowsHide: false });
161
+ child.unref();
162
+ // We MUST exit so the bootstrap's pid-wait loop unblocks and DLL handles
163
+ // release. Anything after this point is unreachable.
164
+ process.exit(0);
165
+ }
6
166
  export async function runUpdate(options = {}) {
7
167
  const current = process.env.OTTO_VERSION || '0.0.0';
168
+ const agentDir = options.agentDir ?? defaultAgentDir;
8
169
  const bold = '\x1b[1m';
9
170
  const dim = '\x1b[2m';
10
171
  const green = '\x1b[32m';
11
172
  const yellow = '\x1b[33m';
12
173
  const reset = '\x1b[0m';
174
+ maybeShowPriorStatus(agentDir);
13
175
  process.stdout.write(`${dim}Current version:${reset} v${current}\n`);
14
176
  process.stdout.write(`${dim}Checking npm registry...${reset}\n`);
15
177
  const latest = await fetchLatestVersionFromRegistry();
@@ -20,15 +182,24 @@ export async function runUpdate(options = {}) {
20
182
  process.stdout.write(`${dim}Latest version:${reset} v${latest}\n`);
21
183
  if (compareSemver(latest, current) <= 0) {
22
184
  process.stdout.write(`${green}Already up to date.${reset}\n`);
23
- initResources(options.agentDir ?? defaultAgentDir, options.skillsDir);
185
+ initResources(agentDir, options.skillsDir);
24
186
  return;
25
187
  }
26
- process.stdout.write(`${dim}Updating:${reset} v${current} → ${bold}v${latest}${reset}\n`);
27
188
  const installCmd = resolveInstallCommand(`${NPM_PACKAGE}@latest`);
189
+ // On Windows, run install in a detached, visible window. The current
190
+ // process holds locks on duckdb.dll, sharp.dll, otto_engine.win32-x64.node,
191
+ // and others — npm install would log EPERM warnings and leave orphan
192
+ // .otto-* staging dirs (issue surfaced by a v1.0.7 → v1.1.0 update on
193
+ // Windows). The bootstrap waits for this process to exit, runs npm install
194
+ // cleanly, sweeps the orphans, and reports completion via a status file
195
+ // that the next `otto update` invocation surfaces.
196
+ if (process.platform === 'win32') {
197
+ runWindowsDetachedUpdate(current, latest, installCmd, agentDir);
198
+ // unreachable
199
+ }
200
+ process.stdout.write(`${dim}Updating:${reset} v${current} → ${bold}v${latest}${reset}\n`);
28
201
  try {
29
- execSync(installCmd, {
30
- stdio: 'inherit',
31
- });
202
+ execSync(installCmd, { stdio: 'inherit' });
32
203
  process.stdout.write(`\n${green}${bold}Updated to v${latest}${reset}\n`);
33
204
  }
34
205
  catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmetech/otto",
3
- "version": "1.1.0",
3
+ "version": "1.2.4",
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,22 @@
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",
150
159
  "chalk": "^5.6.2",
151
160
  "chokidar": "^5.0.0",
161
+ "date-fns": "^4.4.0",
152
162
  "diff": "^8.0.2",
153
163
  "echarts": "^5.6.0",
164
+ "exceljs": "^4.4.0",
154
165
  "extract-zip": "^2.0.1",
155
166
  "file-type": "^21.1.1",
156
167
  "glob": "^13.0.1",
157
168
  "hosted-git-info": "^9.0.2",
158
169
  "ignore": "^7.0.5",
170
+ "lodash": "^4.18.1",
159
171
  "marked": "^15.0.12",
160
172
  "minimatch": "^10.2.3",
173
+ "nodejs-polars": "^0.24.1",
161
174
  "openai": "^6.26.0",
162
175
  "picomatch": "^4.0.3",
163
176
  "playwright": "^1.58.2",
@@ -167,9 +180,11 @@
167
180
  "sql.js": "^1.14.1",
168
181
  "strip-ansi": "^7.1.0",
169
182
  "undici": "^7.24.2",
170
- "yaml": "^2.8.2"
183
+ "yaml": "^2.8.2",
184
+ "zod": "^4.4.3"
171
185
  },
172
186
  "devDependencies": {
187
+ "@types/lodash": "^4.17.24",
173
188
  "@types/node": "^24.12.0",
174
189
  "@types/picomatch": "^4.0.2",
175
190
  "@types/proper-lockfile": "^4.1.4",
@@ -181,13 +196,13 @@
181
196
  },
182
197
  "optionalDependencies": {
183
198
  "@anthropic-ai/claude-agent-sdk": "0.2.83",
199
+ "@cmetech/otto-engine-darwin-arm64": "1.2.4",
200
+ "@cmetech/otto-engine-darwin-x64": "1.2.4",
201
+ "@cmetech/otto-engine-linux-arm64-gnu": "1.2.4",
202
+ "@cmetech/otto-engine-linux-x64-gnu": "1.2.4",
203
+ "@cmetech/otto-engine-win32-x64-msvc": "1.2.4",
184
204
  "fsevents": "~2.3.3",
185
- "koffi": "^2.9.0",
186
- "@cmetech/otto-engine-darwin-arm64": "1.1.0",
187
- "@cmetech/otto-engine-darwin-x64": "1.1.0",
188
- "@cmetech/otto-engine-linux-arm64-gnu": "1.1.0",
189
- "@cmetech/otto-engine-linux-x64-gnu": "1.1.0",
190
- "@cmetech/otto-engine-win32-x64-msvc": "1.1.0"
205
+ "koffi": "^2.9.0"
191
206
  },
192
207
  "overrides": {
193
208
  "gaxios": "7.1.4",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@otto-build/contracts",
3
- "version": "1.1.0",
3
+ "version": "1.2.4",
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
+ }