@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.
- package/dist/coworker/persona-commands.d.ts +1 -0
- package/dist/coworker/persona-commands.js +5 -0
- package/dist/coworker/persona-commands.test.d.ts +1 -0
- package/dist/coworker/persona-commands.test.js +45 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/_coworker-paths.js +8 -0
- package/dist/resources/extensions/coworker-artifacts/artifacts-command.js +31 -0
- package/dist/resources/extensions/coworker-artifacts/artifacts-singleton.js +17 -0
- package/dist/resources/extensions/coworker-artifacts/extension-manifest.json +13 -0
- package/dist/resources/extensions/coworker-artifacts/index.js +125 -0
- package/dist/resources/extensions/coworker-artifacts/list-tool.js +27 -0
- package/dist/resources/extensions/coworker-artifacts/open-tool.js +25 -0
- package/dist/resources/extensions/coworker-memory/extension-manifest.json +13 -0
- package/dist/resources/extensions/coworker-memory/index.js +219 -0
- package/dist/resources/extensions/coworker-memory/memorize-tool.js +10 -0
- package/dist/resources/extensions/coworker-memory/memory-command.js +157 -0
- package/dist/resources/extensions/coworker-memory/memory-singleton.js +55 -0
- package/dist/resources/extensions/coworker-memory/recall-tool.js +18 -0
- package/dist/resources/extensions/coworker-memory/session-hooks.js +45 -0
- package/dist/resources/extensions/coworker-scratchpad/attach-banners.js +53 -0
- package/dist/resources/extensions/coworker-scratchpad/extension-manifest.json +13 -0
- package/dist/resources/extensions/coworker-scratchpad/format-age.js +9 -0
- package/dist/resources/extensions/coworker-scratchpad/helpers.js +38 -0
- package/dist/resources/extensions/coworker-scratchpad/index.js +199 -0
- package/dist/resources/extensions/coworker-scratchpad/mime-bundle.js +20 -0
- package/dist/resources/extensions/coworker-scratchpad/scratchpad-tool.js +118 -0
- package/dist/resources/extensions/coworker-scratchpad/session-sidecar.js +60 -0
- package/dist/resources/extensions/coworker-scratchpad/sp-command.js +597 -0
- package/dist/resources/extensions/coworker-scratchpad/workspace-pointer.js +41 -0
- package/dist/resources/extensions/coworker-scratchpad/workspace-root.js +17 -0
- package/dist/resources/extensions/coworker-vault/audit-command.js +35 -0
- package/dist/resources/extensions/coworker-vault/connect-command.js +42 -0
- package/dist/resources/extensions/coworker-vault/datasource-command.js +50 -0
- package/dist/resources/extensions/coworker-vault/extension-manifest.json +12 -0
- package/dist/resources/extensions/coworker-vault/index.js +171 -0
- package/dist/resources/extensions/coworker-vault/test-helpers.js +86 -0
- package/dist/resources/extensions/coworker-vault/vault-singleton.js +24 -0
- package/dist/resources/extensions/otto/commands/release-notes/_data.js +82 -0
- package/dist/resources/extensions/otto/commands/release-notes/command.js +15 -4
- package/dist/resources/extensions/subagent/index.js +8 -1
- package/dist/resources/extensions/subagent/launch.js +37 -5
- package/dist/resources/extensions/subagent/run-store.js +1 -0
- package/dist/resources/extensions/workflow/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/workflow/bootstrap/register-hooks.js +10 -0
- package/dist/resources/extensions/workflow/persona-status.js +87 -0
- package/dist/update-cmd.d.ts +19 -0
- package/dist/update-cmd.js +177 -6
- package/package.json +25 -10
- package/packages/contracts/package.json +1 -1
- package/packages/coworker-artifacts/dist/artifact-store.d.ts +25 -0
- package/packages/coworker-artifacts/dist/artifact-store.js +187 -0
- package/packages/coworker-artifacts/dist/dir-snapshot.d.ts +7 -0
- package/packages/coworker-artifacts/dist/dir-snapshot.js +54 -0
- package/packages/coworker-artifacts/dist/errors.d.ts +18 -0
- package/packages/coworker-artifacts/dist/errors.js +37 -0
- package/packages/coworker-artifacts/dist/index.d.ts +7 -0
- package/packages/coworker-artifacts/dist/index.js +7 -0
- package/packages/coworker-artifacts/dist/readme-renderer.d.ts +5 -0
- package/packages/coworker-artifacts/dist/readme-renderer.js +47 -0
- package/packages/coworker-artifacts/dist/resolve-uri.d.ts +3 -0
- package/packages/coworker-artifacts/dist/resolve-uri.js +29 -0
- package/packages/coworker-artifacts/dist/slug.d.ts +4 -0
- package/packages/coworker-artifacts/dist/slug.js +32 -0
- package/packages/coworker-artifacts/dist/types.d.ts +52 -0
- package/packages/coworker-artifacts/dist/types.js +1 -0
- package/packages/coworker-artifacts/package.json +20 -0
- package/packages/coworker-artifacts/src/artifact-store.test.ts +188 -0
- package/packages/coworker-artifacts/src/artifact-store.ts +206 -0
- package/packages/coworker-artifacts/src/artifacts-integration.test.ts +109 -0
- package/packages/coworker-artifacts/src/dir-snapshot.test.ts +71 -0
- package/packages/coworker-artifacts/src/dir-snapshot.ts +52 -0
- package/packages/coworker-artifacts/src/errors.test.ts +37 -0
- package/packages/coworker-artifacts/src/errors.ts +28 -0
- package/packages/coworker-artifacts/src/index.test.ts +22 -0
- package/packages/coworker-artifacts/src/index.ts +7 -0
- package/packages/coworker-artifacts/src/readme-renderer.test.ts +72 -0
- package/packages/coworker-artifacts/src/readme-renderer.ts +56 -0
- package/packages/coworker-artifacts/src/resolve-uri.test.ts +46 -0
- package/packages/coworker-artifacts/src/resolve-uri.ts +29 -0
- package/packages/coworker-artifacts/src/slug.test.ts +47 -0
- package/packages/coworker-artifacts/src/slug.ts +31 -0
- package/packages/coworker-artifacts/src/types.ts +61 -0
- package/packages/coworker-artifacts/tsconfig.json +15 -0
- package/packages/coworker-artifacts/tsconfig.publish.json +4 -0
- package/packages/coworker-memory/dist/context-injection.d.ts +9 -0
- package/packages/coworker-memory/dist/context-injection.js +41 -0
- package/packages/coworker-memory/dist/errors.d.ts +25 -0
- package/packages/coworker-memory/dist/errors.js +51 -0
- package/packages/coworker-memory/dist/index.d.ts +12 -0
- package/packages/coworker-memory/dist/index.js +12 -0
- package/packages/coworker-memory/dist/layer-a-store.d.ts +16 -0
- package/packages/coworker-memory/dist/layer-a-store.js +78 -0
- package/packages/coworker-memory/dist/local-sqlite-backend.d.ts +28 -0
- package/packages/coworker-memory/dist/local-sqlite-backend.js +167 -0
- package/packages/coworker-memory/dist/memory-backend.d.ts +14 -0
- package/packages/coworker-memory/dist/memory-backend.js +1 -0
- package/packages/coworker-memory/dist/memory-recorder.d.ts +50 -0
- package/packages/coworker-memory/dist/memory-recorder.js +69 -0
- package/packages/coworker-memory/dist/migrations/001-init.sql +38 -0
- package/packages/coworker-memory/dist/migrations/002-artifact-kind.sql +50 -0
- package/packages/coworker-memory/dist/paste-detector.d.ts +5 -0
- package/packages/coworker-memory/dist/paste-detector.js +14 -0
- package/packages/coworker-memory/dist/persona-seed.d.ts +10 -0
- package/packages/coworker-memory/dist/persona-seed.js +38 -0
- package/packages/coworker-memory/dist/recall-formatter.d.ts +2 -0
- package/packages/coworker-memory/dist/recall-formatter.js +14 -0
- package/packages/coworker-memory/dist/scope-resolver.d.ts +9 -0
- package/packages/coworker-memory/dist/scope-resolver.js +10 -0
- package/packages/coworker-memory/dist/types.d.ts +51 -0
- package/packages/coworker-memory/dist/types.js +2 -0
- package/packages/coworker-memory/dist/workspace-id.d.ts +3 -0
- package/packages/coworker-memory/dist/workspace-id.js +54 -0
- package/packages/coworker-memory/package.json +35 -0
- package/packages/coworker-memory/src/activator-integration.test.ts +141 -0
- package/packages/coworker-memory/src/context-injection.test.ts +72 -0
- package/packages/coworker-memory/src/context-injection.ts +57 -0
- package/packages/coworker-memory/src/errors.test.ts +45 -0
- package/packages/coworker-memory/src/errors.ts +42 -0
- package/packages/coworker-memory/src/index.test.ts +21 -0
- package/packages/coworker-memory/src/index.ts +12 -0
- package/packages/coworker-memory/src/layer-a-store.test.ts +85 -0
- package/packages/coworker-memory/src/layer-a-store.ts +88 -0
- package/packages/coworker-memory/src/local-sqlite-backend.test.ts +110 -0
- package/packages/coworker-memory/src/local-sqlite-backend.ts +185 -0
- package/packages/coworker-memory/src/memory-backend.ts +10 -0
- package/packages/coworker-memory/src/memory-integration.test.ts +89 -0
- package/packages/coworker-memory/src/memory-recorder.test.ts +101 -0
- package/packages/coworker-memory/src/memory-recorder.ts +95 -0
- package/packages/coworker-memory/src/migrations/001-init.sql +38 -0
- package/packages/coworker-memory/src/migrations/002-artifact-kind.sql +50 -0
- package/packages/coworker-memory/src/paste-detector.test.ts +23 -0
- package/packages/coworker-memory/src/paste-detector.ts +18 -0
- package/packages/coworker-memory/src/persona-seed.test.ts +57 -0
- package/packages/coworker-memory/src/persona-seed.ts +46 -0
- package/packages/coworker-memory/src/recall-formatter.test.ts +34 -0
- package/packages/coworker-memory/src/recall-formatter.ts +15 -0
- package/packages/coworker-memory/src/scope-resolver.test.ts +23 -0
- package/packages/coworker-memory/src/scope-resolver.ts +18 -0
- package/packages/coworker-memory/src/types.ts +61 -0
- package/packages/coworker-memory/src/workspace-id.test.ts +48 -0
- package/packages/coworker-memory/src/workspace-id.ts +56 -0
- package/packages/coworker-memory/tsconfig.json +15 -0
- package/packages/coworker-memory/tsconfig.publish.json +4 -0
- package/packages/coworker-persona/dist/commands.d.ts +7 -0
- package/packages/coworker-persona/dist/commands.js +35 -0
- package/packages/coworker-persona/dist/defaults/manifest.yaml +12 -0
- package/packages/coworker-persona/dist/defaults/steering/identity.md +3 -0
- package/packages/coworker-persona/dist/index.d.ts +3 -0
- package/packages/coworker-persona/dist/index.js +3 -0
- package/packages/coworker-persona/dist/manifest.d.ts +24 -0
- package/packages/coworker-persona/dist/manifest.js +21 -0
- package/packages/coworker-persona/dist/registry.d.ts +22 -0
- package/packages/coworker-persona/dist/registry.js +142 -0
- package/packages/coworker-persona/package.json +28 -0
- package/packages/coworker-persona/scripts/copy-defaults.cjs +17 -0
- package/packages/coworker-persona/src/commands.ts +47 -0
- package/packages/coworker-persona/src/defaults/manifest.yaml +12 -0
- package/packages/coworker-persona/src/defaults/steering/identity.md +3 -0
- package/packages/coworker-persona/src/index.ts +3 -0
- package/packages/coworker-persona/src/manifest.test.ts +67 -0
- package/packages/coworker-persona/src/manifest.ts +49 -0
- package/packages/coworker-persona/src/registry.test.ts +89 -0
- package/packages/coworker-persona/src/registry.ts +147 -0
- package/packages/coworker-persona/tsconfig.json +15 -0
- package/packages/coworker-persona/tsconfig.publish.json +4 -0
- package/packages/coworker-scratchpad/dist/cell-archive.d.ts +39 -0
- package/packages/coworker-scratchpad/dist/cell-archive.js +77 -0
- package/packages/coworker-scratchpad/dist/cell-tree.d.ts +14 -0
- package/packages/coworker-scratchpad/dist/cell-tree.js +72 -0
- package/packages/coworker-scratchpad/dist/child-process-runtime.d.ts +129 -0
- package/packages/coworker-scratchpad/dist/child-process-runtime.js +427 -0
- package/packages/coworker-scratchpad/dist/collector-registry.d.ts +12 -0
- package/packages/coworker-scratchpad/dist/collector-registry.js +29 -0
- package/packages/coworker-scratchpad/dist/detect-kind.d.ts +3 -0
- package/packages/coworker-scratchpad/dist/detect-kind.js +19 -0
- package/packages/coworker-scratchpad/dist/file-collector.d.ts +15 -0
- package/packages/coworker-scratchpad/dist/file-collector.js +99 -0
- package/packages/coworker-scratchpad/dist/index.d.ts +13 -0
- package/packages/coworker-scratchpad/dist/index.js +13 -0
- package/packages/coworker-scratchpad/dist/kernel-bindings.d.ts +49 -0
- package/packages/coworker-scratchpad/dist/kernel-bindings.js +220 -0
- package/packages/coworker-scratchpad/dist/kernel-entry.d.ts +1 -0
- package/packages/coworker-scratchpad/dist/kernel-entry.js +355 -0
- package/packages/coworker-scratchpad/dist/kernel-protocol.d.ts +171 -0
- package/packages/coworker-scratchpad/dist/kernel-protocol.js +48 -0
- package/packages/coworker-scratchpad/dist/kernel-spawn.d.ts +3 -0
- package/packages/coworker-scratchpad/dist/kernel-spawn.js +54 -0
- package/packages/coworker-scratchpad/dist/namespace-codec.d.ts +22 -0
- package/packages/coworker-scratchpad/dist/namespace-codec.js +61 -0
- package/packages/coworker-scratchpad/dist/scratchpad-lock.d.ts +24 -0
- package/packages/coworker-scratchpad/dist/scratchpad-lock.js +86 -0
- package/packages/coworker-scratchpad/dist/scratchpad-manager.d.ts +193 -0
- package/packages/coworker-scratchpad/dist/scratchpad-manager.js +866 -0
- package/packages/coworker-scratchpad/dist/staleness-banner.d.ts +12 -0
- package/packages/coworker-scratchpad/dist/staleness-banner.js +27 -0
- package/packages/coworker-scratchpad/package.json +31 -0
- package/packages/coworker-scratchpad/src/cell-archive.test.ts +150 -0
- package/packages/coworker-scratchpad/src/cell-archive.ts +97 -0
- package/packages/coworker-scratchpad/src/cell-tree.test.ts +105 -0
- package/packages/coworker-scratchpad/src/cell-tree.ts +90 -0
- package/packages/coworker-scratchpad/src/child-process-runtime.test.ts +413 -0
- package/packages/coworker-scratchpad/src/child-process-runtime.ts +493 -0
- package/packages/coworker-scratchpad/src/collector-registry.test.ts +69 -0
- package/packages/coworker-scratchpad/src/collector-registry.ts +33 -0
- package/packages/coworker-scratchpad/src/detect-kind.test.ts +33 -0
- package/packages/coworker-scratchpad/src/detect-kind.ts +22 -0
- package/packages/coworker-scratchpad/src/file-collector.test.ts +109 -0
- package/packages/coworker-scratchpad/src/file-collector.ts +114 -0
- package/packages/coworker-scratchpad/src/index.ts +74 -0
- package/packages/coworker-scratchpad/src/kernel-bindings.test.ts +188 -0
- package/packages/coworker-scratchpad/src/kernel-bindings.ts +279 -0
- package/packages/coworker-scratchpad/src/kernel-entry.test.ts +123 -0
- package/packages/coworker-scratchpad/src/kernel-entry.ts +390 -0
- package/packages/coworker-scratchpad/src/kernel-protocol.test.ts +105 -0
- package/packages/coworker-scratchpad/src/kernel-protocol.ts +230 -0
- package/packages/coworker-scratchpad/src/kernel-spawn.test.ts +60 -0
- package/packages/coworker-scratchpad/src/kernel-spawn.ts +54 -0
- package/packages/coworker-scratchpad/src/namespace-codec.test.ts +102 -0
- package/packages/coworker-scratchpad/src/namespace-codec.ts +90 -0
- package/packages/coworker-scratchpad/src/scratchpad-lock.test.ts +98 -0
- package/packages/coworker-scratchpad/src/scratchpad-lock.ts +102 -0
- package/packages/coworker-scratchpad/src/scratchpad-manager.test.ts +1343 -0
- package/packages/coworker-scratchpad/src/scratchpad-manager.ts +891 -0
- package/packages/coworker-scratchpad/src/staleness-banner.test.ts +53 -0
- package/packages/coworker-scratchpad/src/staleness-banner.ts +33 -0
- package/packages/coworker-scratchpad/src/vault-integration.test.ts +221 -0
- package/packages/coworker-scratchpad/tsconfig.json +15 -0
- package/packages/coworker-scratchpad/tsconfig.publish.json +4 -0
- package/packages/coworker-types/dist/artifacts.d.ts +31 -0
- package/packages/coworker-types/dist/artifacts.js +2 -0
- package/packages/coworker-types/dist/contracts.d.ts +32 -0
- package/packages/coworker-types/dist/contracts.js +1 -0
- package/packages/coworker-types/dist/index.d.ts +5 -0
- package/packages/coworker-types/dist/index.js +5 -0
- package/packages/coworker-types/dist/memory.d.ts +61 -0
- package/packages/coworker-types/dist/memory.js +3 -0
- package/packages/coworker-types/dist/scratchpad.d.ts +43 -0
- package/packages/coworker-types/dist/scratchpad.js +2 -0
- package/packages/coworker-types/dist/vault.d.ts +34 -0
- package/packages/coworker-types/dist/vault.js +2 -0
- package/packages/coworker-types/package.json +24 -0
- package/packages/coworker-types/src/artifacts.test.ts +52 -0
- package/packages/coworker-types/src/artifacts.ts +35 -0
- package/packages/coworker-types/src/contracts.test.ts +43 -0
- package/packages/coworker-types/src/contracts.ts +36 -0
- package/packages/coworker-types/src/index.ts +5 -0
- package/packages/coworker-types/src/memory.test.ts +50 -0
- package/packages/coworker-types/src/memory.ts +79 -0
- package/packages/coworker-types/src/scratchpad.test.ts +46 -0
- package/packages/coworker-types/src/scratchpad.ts +51 -0
- package/packages/coworker-types/src/smoke.test.ts +34 -0
- package/packages/coworker-types/src/vault.test.ts +49 -0
- package/packages/coworker-types/src/vault.ts +40 -0
- package/packages/coworker-types/tsconfig.json +15 -0
- package/packages/coworker-types/tsconfig.publish.json +4 -0
- package/packages/coworker-utils/dist/audit-log.d.ts +34 -0
- package/packages/coworker-utils/dist/audit-log.js +88 -0
- package/packages/coworker-utils/dist/index.d.ts +6 -0
- package/packages/coworker-utils/dist/index.js +6 -0
- package/packages/coworker-utils/dist/lease.d.ts +7 -0
- package/packages/coworker-utils/dist/lease.js +67 -0
- package/packages/coworker-utils/dist/logger.d.ts +13 -0
- package/packages/coworker-utils/dist/logger.js +26 -0
- package/packages/coworker-utils/dist/migration-runner.d.ts +7 -0
- package/packages/coworker-utils/dist/migration-runner.js +36 -0
- package/packages/coworker-utils/dist/ndjson-channel.d.ts +3 -0
- package/packages/coworker-utils/dist/ndjson-channel.js +38 -0
- package/packages/coworker-utils/dist/secret-scanner.d.ts +10 -0
- package/packages/coworker-utils/dist/secret-scanner.js +42 -0
- package/packages/coworker-utils/package.json +24 -0
- package/packages/coworker-utils/src/audit-log.test.ts +140 -0
- package/packages/coworker-utils/src/audit-log.ts +107 -0
- package/packages/coworker-utils/src/index.ts +6 -0
- package/packages/coworker-utils/src/lease.test.ts +64 -0
- package/packages/coworker-utils/src/lease.ts +76 -0
- package/packages/coworker-utils/src/logger.test.ts +50 -0
- package/packages/coworker-utils/src/logger.ts +45 -0
- package/packages/coworker-utils/src/migration-runner.test.ts +65 -0
- package/packages/coworker-utils/src/migration-runner.ts +50 -0
- package/packages/coworker-utils/src/ndjson-channel.test.ts +76 -0
- package/packages/coworker-utils/src/ndjson-channel.ts +41 -0
- package/packages/coworker-utils/src/secret-scanner.test.ts +61 -0
- package/packages/coworker-utils/src/secret-scanner.ts +56 -0
- package/packages/coworker-utils/tsconfig.json +15 -0
- package/packages/coworker-utils/tsconfig.publish.json +4 -0
- package/packages/coworker-vault/dist/data-vault.d.ts +41 -0
- package/packages/coworker-vault/dist/data-vault.js +223 -0
- package/packages/coworker-vault/dist/engine-registry.d.ts +34 -0
- package/packages/coworker-vault/dist/engine-registry.js +90 -0
- package/packages/coworker-vault/dist/engines/jira.yaml +17 -0
- package/packages/coworker-vault/dist/errors.d.ts +28 -0
- package/packages/coworker-vault/dist/errors.js +57 -0
- package/packages/coworker-vault/dist/index.d.ts +6 -0
- package/packages/coworker-vault/dist/index.js +6 -0
- package/packages/coworker-vault/dist/injector.d.ts +19 -0
- package/packages/coworker-vault/dist/injector.js +77 -0
- package/packages/coworker-vault/dist/types.d.ts +28 -0
- package/packages/coworker-vault/dist/types.js +1 -0
- package/packages/coworker-vault/dist/vault-keep.d.ts +4 -0
- package/packages/coworker-vault/dist/vault-keep.js +21 -0
- package/packages/coworker-vault/package.json +29 -0
- package/packages/coworker-vault/src/data-vault.test.ts +199 -0
- package/packages/coworker-vault/src/data-vault.ts +257 -0
- package/packages/coworker-vault/src/engine-registry.test.ts +120 -0
- package/packages/coworker-vault/src/engine-registry.ts +107 -0
- package/packages/coworker-vault/src/engines/jira.yaml +17 -0
- package/packages/coworker-vault/src/errors.test.ts +58 -0
- package/packages/coworker-vault/src/errors.ts +50 -0
- package/packages/coworker-vault/src/index.test.ts +24 -0
- package/packages/coworker-vault/src/index.ts +6 -0
- package/packages/coworker-vault/src/injector.test.ts +109 -0
- package/packages/coworker-vault/src/injector.ts +98 -0
- package/packages/coworker-vault/src/types.ts +33 -0
- package/packages/coworker-vault/src/vault-keep.test.ts +49 -0
- package/packages/coworker-vault/src/vault-keep.ts +31 -0
- package/packages/coworker-vault/tsconfig.json +15 -0
- package/packages/coworker-vault/tsconfig.publish.json +4 -0
- package/packages/daemon/package.json +3 -3
- package/packages/mcp-server/package.json +3 -3
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +6 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +22 -3
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +11 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.d.ts +47 -0
- package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.js +107 -0
- package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.d.ts +19 -0
- package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.js +121 -0
- package/packages/pi-coding-agent/dist/modes/rpc/raw-stdout.regression.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +17 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/package.json +2 -2
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +22 -3
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +11 -0
- package/packages/pi-coding-agent/src/modes/rpc/raw-stdout.regression.test.ts +129 -0
- package/packages/pi-coding-agent/src/modes/rpc/raw-stdout.ts +117 -0
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +18 -1
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/scripts/install.js +6 -5
- package/src/resources/extensions/_coworker-paths.test.ts +40 -0
- package/src/resources/extensions/_coworker-paths.ts +10 -0
- package/src/resources/extensions/coworker-artifacts/artifacts-command.test.ts +54 -0
- package/src/resources/extensions/coworker-artifacts/artifacts-command.ts +43 -0
- package/src/resources/extensions/coworker-artifacts/artifacts-singleton.test.ts +25 -0
- package/src/resources/extensions/coworker-artifacts/artifacts-singleton.ts +29 -0
- package/src/resources/extensions/coworker-artifacts/extension-manifest.json +13 -0
- package/src/resources/extensions/coworker-artifacts/index.test.ts +46 -0
- package/src/resources/extensions/coworker-artifacts/index.ts +154 -0
- package/src/resources/extensions/coworker-artifacts/list-tool.test.ts +29 -0
- package/src/resources/extensions/coworker-artifacts/list-tool.ts +53 -0
- package/src/resources/extensions/coworker-artifacts/open-tool.test.ts +30 -0
- package/src/resources/extensions/coworker-artifacts/open-tool.ts +43 -0
- package/src/resources/extensions/coworker-memory/extension-manifest.json +13 -0
- package/src/resources/extensions/coworker-memory/index.test.ts +137 -0
- package/src/resources/extensions/coworker-memory/index.ts +257 -0
- package/src/resources/extensions/coworker-memory/memorize-tool.test.ts +41 -0
- package/src/resources/extensions/coworker-memory/memorize-tool.ts +20 -0
- package/src/resources/extensions/coworker-memory/memory-command.test.ts +134 -0
- package/src/resources/extensions/coworker-memory/memory-command.ts +131 -0
- package/src/resources/extensions/coworker-memory/memory-singleton.test.ts +41 -0
- package/src/resources/extensions/coworker-memory/memory-singleton.ts +89 -0
- package/src/resources/extensions/coworker-memory/recall-tool.test.ts +50 -0
- package/src/resources/extensions/coworker-memory/recall-tool.ts +35 -0
- package/src/resources/extensions/coworker-memory/session-hooks.test.ts +77 -0
- package/src/resources/extensions/coworker-memory/session-hooks.ts +61 -0
- package/src/resources/extensions/coworker-scratchpad/attach-banners.test.ts +124 -0
- package/src/resources/extensions/coworker-scratchpad/attach-banners.ts +67 -0
- package/src/resources/extensions/coworker-scratchpad/extension-manifest.json +13 -0
- package/src/resources/extensions/coworker-scratchpad/format-age.test.ts +30 -0
- package/src/resources/extensions/coworker-scratchpad/format-age.ts +6 -0
- package/src/resources/extensions/coworker-scratchpad/helpers.test.ts +93 -0
- package/src/resources/extensions/coworker-scratchpad/helpers.ts +42 -0
- package/src/resources/extensions/coworker-scratchpad/index.test.ts +514 -0
- package/src/resources/extensions/coworker-scratchpad/index.ts +207 -0
- package/src/resources/extensions/coworker-scratchpad/mime-bundle.test.ts +61 -0
- package/src/resources/extensions/coworker-scratchpad/mime-bundle.ts +23 -0
- package/src/resources/extensions/coworker-scratchpad/scratchpad-tool.test.ts +137 -0
- package/src/resources/extensions/coworker-scratchpad/scratchpad-tool.ts +165 -0
- package/src/resources/extensions/coworker-scratchpad/session-sidecar.test.ts +133 -0
- package/src/resources/extensions/coworker-scratchpad/session-sidecar.ts +68 -0
- package/src/resources/extensions/coworker-scratchpad/sp-command.test.ts +836 -0
- package/src/resources/extensions/coworker-scratchpad/sp-command.ts +602 -0
- package/src/resources/extensions/coworker-scratchpad/workspace-pointer.test.ts +74 -0
- package/src/resources/extensions/coworker-scratchpad/workspace-pointer.ts +55 -0
- package/src/resources/extensions/coworker-scratchpad/workspace-root.test.ts +51 -0
- package/src/resources/extensions/coworker-scratchpad/workspace-root.ts +16 -0
- package/src/resources/extensions/coworker-vault/audit-command.test.ts +109 -0
- package/src/resources/extensions/coworker-vault/audit-command.ts +56 -0
- package/src/resources/extensions/coworker-vault/connect-command.test.ts +103 -0
- package/src/resources/extensions/coworker-vault/connect-command.ts +69 -0
- package/src/resources/extensions/coworker-vault/datasource-command.test.ts +80 -0
- package/src/resources/extensions/coworker-vault/datasource-command.ts +81 -0
- package/src/resources/extensions/coworker-vault/extension-manifest.json +12 -0
- package/src/resources/extensions/coworker-vault/index.test.ts +82 -0
- package/src/resources/extensions/coworker-vault/index.ts +181 -0
- package/src/resources/extensions/coworker-vault/test-helpers.ts +120 -0
- package/src/resources/extensions/coworker-vault/vault-singleton.test.ts +27 -0
- package/src/resources/extensions/coworker-vault/vault-singleton.ts +40 -0
- package/src/resources/extensions/otto/commands/release-notes/_data.ts +96 -0
- package/src/resources/extensions/otto/commands/release-notes/command.ts +16 -3
- package/src/resources/extensions/subagent/index.ts +9 -0
- package/src/resources/extensions/subagent/launch.test.ts +97 -0
- package/src/resources/extensions/subagent/launch.ts +42 -5
- package/src/resources/extensions/subagent/run-store.ts +3 -1
- package/src/resources/extensions/workflow/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/workflow/bootstrap/register-hooks.ts +10 -0
- package/src/resources/extensions/workflow/persona-status.ts +109 -0
- package/src/resources/extensions/workflow/tests/auto-recovery.test.ts +34 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const DURATION_RE = /^(\d+)([smhd])$/;
|
|
2
|
+
const MS = {
|
|
3
|
+
s: 1000,
|
|
4
|
+
m: 60_000,
|
|
5
|
+
h: 3_600_000,
|
|
6
|
+
d: 86_400_000,
|
|
7
|
+
};
|
|
8
|
+
function resolveSince(token) {
|
|
9
|
+
if (!token)
|
|
10
|
+
return undefined;
|
|
11
|
+
const m = DURATION_RE.exec(token);
|
|
12
|
+
if (m) {
|
|
13
|
+
const n = parseInt(m[1], 10);
|
|
14
|
+
const unit = m[2];
|
|
15
|
+
return new Date(Date.now() - n * MS[unit]).toISOString();
|
|
16
|
+
}
|
|
17
|
+
return token; // treat as ISO-8601
|
|
18
|
+
}
|
|
19
|
+
export async function runAudit(bundle, q) {
|
|
20
|
+
const since = resolveSince(q.since);
|
|
21
|
+
const limit = q.limit ?? 50;
|
|
22
|
+
const out = [];
|
|
23
|
+
for await (const r of bundle.audit.read({
|
|
24
|
+
since,
|
|
25
|
+
producer: q.producer,
|
|
26
|
+
action: q.action,
|
|
27
|
+
severity: q.severity,
|
|
28
|
+
engineId: q.engine,
|
|
29
|
+
})) {
|
|
30
|
+
out.push(r);
|
|
31
|
+
if (out.length >= limit)
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/resources/extensions/coworker-vault/connect-command.ts
|
|
2
|
+
//
|
|
3
|
+
// Programmatic /connect wizard. Walks an engine's fields via a `promptProvider`
|
|
4
|
+
// callback, handles VAULT_KEEP sentinel for edits, validates required fields,
|
|
5
|
+
// and writes through LocalDataVault.set. No TUI dependencies — the TUI binding
|
|
6
|
+
// (clack/prompts) is wired separately and passes a clack-based provider.
|
|
7
|
+
import { mergeWithSentinel, assertNoSentinelInCreate, VAULT_KEEP, VaultEntryNotFound, } from '@otto/coworker-vault';
|
|
8
|
+
export async function runConnect(bundle, opts) {
|
|
9
|
+
const engine = bundle.registry.require(opts.engineId);
|
|
10
|
+
let existing;
|
|
11
|
+
try {
|
|
12
|
+
const got = await bundle.vault.get({ engine: opts.engineId, name: opts.entryName });
|
|
13
|
+
existing = got.fields;
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
if (!(err instanceof VaultEntryNotFound))
|
|
17
|
+
throw err;
|
|
18
|
+
}
|
|
19
|
+
const submitted = {};
|
|
20
|
+
for (const f of engine.fields) {
|
|
21
|
+
const defaultValue = existing && f.secret
|
|
22
|
+
? VAULT_KEEP
|
|
23
|
+
: (existing?.[f.name] ?? f.default ?? '');
|
|
24
|
+
const value = await opts.promptProvider(f.name, {
|
|
25
|
+
label: f.label,
|
|
26
|
+
secret: f.secret,
|
|
27
|
+
required: f.required,
|
|
28
|
+
defaultValue,
|
|
29
|
+
});
|
|
30
|
+
if (f.required && value.trim() === '') {
|
|
31
|
+
throw new Error(`Field "${f.name}" is required.`);
|
|
32
|
+
}
|
|
33
|
+
submitted[f.name] = value;
|
|
34
|
+
}
|
|
35
|
+
if (!existing) {
|
|
36
|
+
assertNoSentinelInCreate(engine.fields, submitted);
|
|
37
|
+
}
|
|
38
|
+
const merged = existing
|
|
39
|
+
? mergeWithSentinel(engine.fields, existing, submitted)
|
|
40
|
+
: submitted;
|
|
41
|
+
await bundle.vault.set({ engine: opts.engineId, name: opts.entryName }, merged, { forceWorkspace: opts.forceWorkspace });
|
|
42
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// src/resources/extensions/coworker-vault/datasource-command.ts
|
|
2
|
+
//
|
|
3
|
+
// Programmatic /datasource list|remove|test commands. `edit` is wired at the
|
|
4
|
+
// routing layer (Task 16) as an alias for runConnect and does not need its own
|
|
5
|
+
// function here. No TUI dependencies.
|
|
6
|
+
import { LocalDataVault, envVarName } from '@otto/coworker-vault';
|
|
7
|
+
export async function runDatasourceList(bundle, filter) {
|
|
8
|
+
const all = await bundle.vault.list();
|
|
9
|
+
const out = [];
|
|
10
|
+
for (const row of all) {
|
|
11
|
+
if (filter.engine && row.engine !== filter.engine)
|
|
12
|
+
continue;
|
|
13
|
+
const engine = bundle.registry.get(row.engine);
|
|
14
|
+
let fields = [];
|
|
15
|
+
if (engine) {
|
|
16
|
+
const entry = await bundle.vault.get({ engine: row.engine, name: row.name });
|
|
17
|
+
fields = engine.fields
|
|
18
|
+
.map((f) => ({
|
|
19
|
+
name: f.name,
|
|
20
|
+
secret: f.secret,
|
|
21
|
+
display: f.secret ? '••••••' : (entry.fields[f.name] ?? ''),
|
|
22
|
+
}))
|
|
23
|
+
.filter((f) => row.fields_set.includes(f.name));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
fields = row.fields_set.map((n) => ({ name: n, secret: false, display: '' }));
|
|
27
|
+
}
|
|
28
|
+
out.push({
|
|
29
|
+
engine: row.engine,
|
|
30
|
+
name: row.name,
|
|
31
|
+
scope: row.scope,
|
|
32
|
+
fields,
|
|
33
|
+
last_modified_at: row.last_modified_at,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
export async function runDatasourceRemove(bundle, args) {
|
|
39
|
+
const ref = LocalDataVault.parseRef(args.ref);
|
|
40
|
+
await bundle.vault.remove(ref);
|
|
41
|
+
}
|
|
42
|
+
export async function runDatasourceTest(bundle, args) {
|
|
43
|
+
const ref = LocalDataVault.parseRef(args.ref);
|
|
44
|
+
const entry = await bundle.vault.get(ref);
|
|
45
|
+
return {
|
|
46
|
+
ref: args.ref,
|
|
47
|
+
engine: ref.engine,
|
|
48
|
+
envVarNames: Object.keys(entry.fields).map((f) => envVarName(ref.engine, ref.name, f)),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "coworker-vault",
|
|
3
|
+
"name": "Co-worker Vault",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Credential vault: /connect wizard, /datasource manager, /audit reader",
|
|
6
|
+
"tier": "bundled",
|
|
7
|
+
"requires": { "platform": ">=2.29.0" },
|
|
8
|
+
"provides": {
|
|
9
|
+
"commands": ["connect", "datasource", "audit"],
|
|
10
|
+
"hooks": ["session_shutdown"]
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { createVaultBundle } from './vault-singleton.js';
|
|
2
|
+
import { runConnect } from './connect-command.js';
|
|
3
|
+
import { runDatasourceList, runDatasourceRemove, runDatasourceTest, } from './datasource-command.js';
|
|
4
|
+
import { runAudit } from './audit-command.js';
|
|
5
|
+
import { getCoworkerGlobalDir } from '../_coworker-paths.js';
|
|
6
|
+
export { createVaultBundle };
|
|
7
|
+
export default function coworkerVaultExtension(api) {
|
|
8
|
+
let bundle = null;
|
|
9
|
+
let unavailable = false;
|
|
10
|
+
api.on('session_start', async (_event, ctx) => {
|
|
11
|
+
try {
|
|
12
|
+
bundle = await createVaultBundle({
|
|
13
|
+
globalDir: getCoworkerGlobalDir(),
|
|
14
|
+
workspaceDir: ctx.cwd,
|
|
15
|
+
});
|
|
16
|
+
unavailable = false;
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
unavailable = true;
|
|
20
|
+
bundle = null;
|
|
21
|
+
ctx.ui.notify(`vault unavailable: ${err.message}`, 'warning');
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
api.registerCommand('connect', {
|
|
25
|
+
description: 'Add or edit a credential entry. Usage: /connect <engine> <name> [--workspace]',
|
|
26
|
+
handler: async (args, ctx) => {
|
|
27
|
+
if (!bundle) {
|
|
28
|
+
ctx.ui.notify(unavailable ? 'vault unavailable; chat continues without it.' : 'vault not ready yet.', 'warning');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const tokens = args.trim().split(/\s+/).filter(Boolean);
|
|
32
|
+
const flags = new Set(tokens.filter(t => t.startsWith('--')));
|
|
33
|
+
const positional = tokens.filter(t => !t.startsWith('--'));
|
|
34
|
+
const [engineId, entryName] = positional;
|
|
35
|
+
if (!engineId || !entryName) {
|
|
36
|
+
ctx.ui.notify('Usage: /connect <engine> <name> [--workspace]', 'info');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const forceWorkspace = flags.has('--workspace');
|
|
40
|
+
// Wire ctx.ui.input as the prompt provider. If hasUI is false (print/RPC
|
|
41
|
+
// mode), surface a non-error notice and bail rather than throwing.
|
|
42
|
+
if (!ctx.hasUI) {
|
|
43
|
+
ctx.ui.notify('interactive /connect requires a TTY session.', 'warning');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const promptProvider = async (field, opts) => {
|
|
47
|
+
const placeholder = opts.defaultValue ?? '';
|
|
48
|
+
const title = `${opts.label}${opts.required ? ' *' : ''}${opts.secret ? ' (hidden)' : ''}`;
|
|
49
|
+
const result = await ctx.ui.input(title, placeholder);
|
|
50
|
+
return result ?? '';
|
|
51
|
+
};
|
|
52
|
+
try {
|
|
53
|
+
await runConnect(bundle, { engineId, entryName, forceWorkspace, promptProvider });
|
|
54
|
+
ctx.ui.notify(`saved ${engineId}:${entryName}`, 'success');
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
ctx.ui.notify(`/connect failed: ${err.message}`, 'error');
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
api.registerCommand('datasource', {
|
|
62
|
+
description: '/datasource list [engine] | remove <engine:name> | test <engine:name>',
|
|
63
|
+
handler: async (args, ctx) => {
|
|
64
|
+
if (!bundle) {
|
|
65
|
+
ctx.ui.notify(unavailable ? 'vault unavailable; chat continues without it.' : 'vault not ready yet.', 'warning');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const tokens = args.trim().split(/\s+/).filter(Boolean);
|
|
69
|
+
const [sub, ...rest] = tokens;
|
|
70
|
+
try {
|
|
71
|
+
switch (sub) {
|
|
72
|
+
case undefined:
|
|
73
|
+
case 'list': {
|
|
74
|
+
const engineFilter = rest[0];
|
|
75
|
+
const rows = await runDatasourceList(bundle, engineFilter ? { engine: engineFilter } : {});
|
|
76
|
+
const lines = rows.length === 0
|
|
77
|
+
? ['no datasources configured']
|
|
78
|
+
: rows.map(r => ` ${r.engine}:${r.name} (${r.scope})`);
|
|
79
|
+
ctx.ui.notify(lines.join('\n'), 'info');
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
case 'remove': {
|
|
83
|
+
const ref = rest.join(' ').trim();
|
|
84
|
+
if (!ref) {
|
|
85
|
+
ctx.ui.notify('Usage: /datasource remove <engine:name>', 'info');
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
await runDatasourceRemove(bundle, { ref });
|
|
89
|
+
ctx.ui.notify(`removed: ${ref}`, 'success');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
case 'test': {
|
|
93
|
+
const ref = rest.join(' ').trim();
|
|
94
|
+
if (!ref) {
|
|
95
|
+
ctx.ui.notify('Usage: /datasource test <engine:name>', 'info');
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const preview = await runDatasourceTest(bundle, { ref });
|
|
99
|
+
ctx.ui.notify(`Would inject: ${preview.envVarNames.join(', ')}`, 'info');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
default:
|
|
103
|
+
ctx.ui.notify(`Unknown /datasource subcommand: ${sub}. Try: list, remove, test.`, 'warning');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
ctx.ui.notify(`/datasource failed: ${err.message}`, 'error');
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
api.registerCommand('audit', {
|
|
112
|
+
description: '/audit [--since 1h|24h|7d|ISO] [--producer P] [--engine E] [--action A] [--severity info|warn] [--limit N]',
|
|
113
|
+
handler: async (args, ctx) => {
|
|
114
|
+
if (!bundle) {
|
|
115
|
+
ctx.ui.notify(unavailable ? 'vault unavailable; chat continues without it.' : 'vault not ready yet.', 'warning');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const tokens = args.trim().split(/\s+/).filter(Boolean);
|
|
119
|
+
const q = {};
|
|
120
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
121
|
+
const t = tokens[i];
|
|
122
|
+
const next = tokens[i + 1];
|
|
123
|
+
if (t === '--since' && next) {
|
|
124
|
+
q.since = next;
|
|
125
|
+
i++;
|
|
126
|
+
}
|
|
127
|
+
else if (t === '--producer' && next) {
|
|
128
|
+
q.producer = next;
|
|
129
|
+
i++;
|
|
130
|
+
}
|
|
131
|
+
else if (t === '--engine' && next) {
|
|
132
|
+
q.engine = next;
|
|
133
|
+
i++;
|
|
134
|
+
}
|
|
135
|
+
else if (t === '--action' && next) {
|
|
136
|
+
q.action = next;
|
|
137
|
+
i++;
|
|
138
|
+
}
|
|
139
|
+
else if (t === '--severity' && next) {
|
|
140
|
+
if (next === 'info' || next === 'warn') {
|
|
141
|
+
q.severity = next;
|
|
142
|
+
}
|
|
143
|
+
i++;
|
|
144
|
+
}
|
|
145
|
+
else if (t === '--limit' && next) {
|
|
146
|
+
const n = parseInt(next, 10);
|
|
147
|
+
if (Number.isFinite(n) && n > 0)
|
|
148
|
+
q.limit = n;
|
|
149
|
+
i++;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
try {
|
|
153
|
+
const rows = await runAudit(bundle, q);
|
|
154
|
+
const lines = rows.length === 0
|
|
155
|
+
? ['no audit records match']
|
|
156
|
+
: rows.map(r => {
|
|
157
|
+
const engine = typeof r.detail?.engine === 'string' ? r.detail.engine : undefined;
|
|
158
|
+
return ` [${r.ts}] ${r.producer}/${r.action}${engine ? ` engine=${engine}` : ''}`;
|
|
159
|
+
});
|
|
160
|
+
ctx.ui.notify(lines.join('\n'), 'info');
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
ctx.ui.notify(`/audit failed: ${err.message}`, 'error');
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
api.on('session_shutdown', async () => {
|
|
168
|
+
// Phase 2 VaultBundle has no async dispose path; clearing the reference is enough.
|
|
169
|
+
bundle = null;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// src/resources/extensions/coworker-vault/test-helpers.ts
|
|
2
|
+
//
|
|
3
|
+
// Shared fake ExtensionAPI used by the coworker-vault, coworker-memory, and
|
|
4
|
+
// (eventually) cross-extension integration tests. Captures every command +
|
|
5
|
+
// tool registration + event handler so tests can fire lifecycle events and
|
|
6
|
+
// inspect ui.notify calls.
|
|
7
|
+
import { tmpdir } from 'node:os';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
export function makeFakeApi() {
|
|
10
|
+
const commands = new Map();
|
|
11
|
+
const tools = new Map();
|
|
12
|
+
const handlers = new Map();
|
|
13
|
+
const notifyCalls = [];
|
|
14
|
+
const ui = {
|
|
15
|
+
notify: (message, level) => {
|
|
16
|
+
notifyCalls.push({ message, level: level ?? 'info' });
|
|
17
|
+
},
|
|
18
|
+
confirm: async () => true,
|
|
19
|
+
input: async () => '',
|
|
20
|
+
select: async () => undefined,
|
|
21
|
+
};
|
|
22
|
+
const ctx = {
|
|
23
|
+
cwd: tmpdir(),
|
|
24
|
+
hasUI: true,
|
|
25
|
+
ui,
|
|
26
|
+
sessionManager: {
|
|
27
|
+
getSessionFile: () => join(tmpdir(), 'session.jsonl'),
|
|
28
|
+
},
|
|
29
|
+
isIdle: () => true,
|
|
30
|
+
abort: () => { },
|
|
31
|
+
hasPendingMessages: () => false,
|
|
32
|
+
shutdown: () => { },
|
|
33
|
+
getContextUsage: () => undefined,
|
|
34
|
+
compact: () => { },
|
|
35
|
+
getSystemPrompt: () => '',
|
|
36
|
+
setCompactionThresholdOverride: () => { },
|
|
37
|
+
};
|
|
38
|
+
const commandCtx = ctx;
|
|
39
|
+
const api = {
|
|
40
|
+
on(event, handler) {
|
|
41
|
+
if (!handlers.has(event))
|
|
42
|
+
handlers.set(event, []);
|
|
43
|
+
handlers.get(event).push(handler);
|
|
44
|
+
},
|
|
45
|
+
registerCommand(name, options) {
|
|
46
|
+
commands.set(name, { name, ...options });
|
|
47
|
+
},
|
|
48
|
+
registerTool(tool) {
|
|
49
|
+
tools.set(tool.name, tool);
|
|
50
|
+
},
|
|
51
|
+
sendMessage() { },
|
|
52
|
+
};
|
|
53
|
+
return { api, commands, tools, handlers, notifyCalls, ctx, commandCtx };
|
|
54
|
+
}
|
|
55
|
+
export async function fireSessionStart(fake, opts) {
|
|
56
|
+
const evt = { type: 'session_start' };
|
|
57
|
+
// Mutate the fake.ctx so handlers see the requested cwd.
|
|
58
|
+
fake.ctx.cwd = opts.cwd;
|
|
59
|
+
const list = fake.handlers.get('session_start') ?? [];
|
|
60
|
+
for (const h of list)
|
|
61
|
+
await h(evt, fake.ctx);
|
|
62
|
+
}
|
|
63
|
+
export async function fireSessionShutdown(fake) {
|
|
64
|
+
const evt = { type: 'session_shutdown' };
|
|
65
|
+
const list = fake.handlers.get('session_shutdown') ?? [];
|
|
66
|
+
for (const h of list)
|
|
67
|
+
await h(evt, fake.ctx);
|
|
68
|
+
}
|
|
69
|
+
export async function fireBeforeAgentStart(fake, prompt, systemPrompt) {
|
|
70
|
+
const evt = { type: 'before_agent_start', prompt, systemPrompt };
|
|
71
|
+
const list = fake.handlers.get('before_agent_start') ?? [];
|
|
72
|
+
let result;
|
|
73
|
+
for (const h of list) {
|
|
74
|
+
const r = await h(evt, fake.ctx);
|
|
75
|
+
if (r && typeof r === 'object' && 'systemPrompt' in r) {
|
|
76
|
+
result = r;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
export async function fireAgentStart(fake, sessionId, turnId) {
|
|
82
|
+
const evt = { type: 'agent_start', sessionId, turnId };
|
|
83
|
+
const list = fake.handlers.get('agent_start') ?? [];
|
|
84
|
+
for (const h of list)
|
|
85
|
+
await h(evt, fake.ctx);
|
|
86
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/resources/extensions/coworker-vault/vault-singleton.ts
|
|
2
|
+
//
|
|
3
|
+
// Factory that constructs the three vault collaborators (LocalDataVault, AuditLog,
|
|
4
|
+
// EngineRegistry) for given roots. Pure: side-effects are limited to whatever the
|
|
5
|
+
// underlying constructors already perform (dir creation, orphan sweeps, etc.).
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { homedir } from 'node:os';
|
|
8
|
+
import { AuditLog } from '@otto/coworker-utils';
|
|
9
|
+
import { LocalDataVault, EngineRegistry } from '@otto/coworker-vault';
|
|
10
|
+
export async function createVaultBundle(opts = {}) {
|
|
11
|
+
const globalDir = opts.globalDir ?? join(homedir(), '.otto');
|
|
12
|
+
const auditPath = join(globalDir, 'audit.jsonl');
|
|
13
|
+
const audit = new AuditLog({ path: auditPath });
|
|
14
|
+
const vault = new LocalDataVault({
|
|
15
|
+
globalDir,
|
|
16
|
+
workspaceDir: opts.workspaceDir,
|
|
17
|
+
audit,
|
|
18
|
+
});
|
|
19
|
+
const registry = await EngineRegistry.load({
|
|
20
|
+
userDir: join(globalDir, 'engines'),
|
|
21
|
+
workspaceDir: opts.workspaceDir ? join(opts.workspaceDir, 'engines') : undefined,
|
|
22
|
+
});
|
|
23
|
+
return { vault, audit, registry, globalDir, workspaceDir: opts.workspaceDir };
|
|
24
|
+
}
|
|
@@ -3,7 +3,89 @@
|
|
|
3
3
|
//
|
|
4
4
|
// To add or correct release notes, edit CHANGELOG.md and rebuild. Editing this
|
|
5
5
|
// file directly will be clobbered on the next build.
|
|
6
|
+
//
|
|
7
|
+
// Bundled releases are capped (default 20, override via OTTO_RELEASE_NOTES_CAP
|
|
8
|
+
// at build time). Older releases stay in CHANGELOG.md and on GitHub; the
|
|
9
|
+
// runtime command surfaces a link when a requested version isn't bundled.
|
|
10
|
+
export const RELEASE_NOTES_MANIFEST = {
|
|
11
|
+
truncated: false,
|
|
12
|
+
total: 13,
|
|
13
|
+
oldestBundled: '1.0.0',
|
|
14
|
+
newestBundled: '1.2.4',
|
|
15
|
+
historyUrl: 'https://github.com/cmetech/otto-cli/blob/main/CHANGELOG.md',
|
|
16
|
+
};
|
|
6
17
|
export const RELEASE_NOTES = [
|
|
18
|
+
{
|
|
19
|
+
version: '1.2.4',
|
|
20
|
+
date: '2026-06-02',
|
|
21
|
+
headline: 'Co-worker pillars go live: persistent memory (Layer A rules/lessons + Layer B verbatim drawers with FTS5 recall), workspace-scoped artifact store with `artifact://` URIs and two-turn provenance, vault\'s `/connect` `/datasource` `/audit` slash surface, and per-subagent dedicated scratchpads. Day-2 milestone — paste an incident note Monday → recall the exact words Tuesday — works end-to-end.',
|
|
22
|
+
added: [
|
|
23
|
+
'**`@otto/coworker-memory` Layer A + Layer B (Phase 3).** Workspace-scoped SQLite store at `<workspace>/.otto/memory/layer-b.db` with FTS5 BM25 ranking + WAL journaling; markdown Layer A files at `<workspace>/.otto/memory/{profile,rules,lessons}.md` with YAML frontmatter and atomic writes. Three scoping modes (global, per-project, per-project-tagged). SecretScanner split policy: Layer A blocks writes containing secrets (`LayerAWriteBlocked`); Layer B redacts (`[REDACTED:<kind>]`) and sets `redacted:true`. Persona-seed helper for one-shot bootstrap from `<persona>/memory-seed/`.',
|
|
24
|
+
'**Production activators wire memory + vault + scratchpad to Otto\'s `ExtensionAPI` (Phase 3.1).** Vault\'s `/connect <engine> <name>` interactive wizard, `/datasource list|remove|test`, and `/audit [--producer|--action|--limit|--since|--engine|--severity]` now register at extension activation — first time these are reachable in a live chat. Memory activator captures `event.prompt` in `before_agent_start`, calls `recorder.recordTurn(...)` in `agent_start` (one-time warning on failure, then silent). `/memory note <text>` appends a workspace lesson; `/memory status` reports `workspace_wing`, `drawer_count`, db path; `/memory clear --wing <w> --confirm` deletes drawers. `memorize` and `recall` LLM tools are model-callable. Layer A injects into the system prompt on `session_start` (3000-token cap; sections sorted profile → rules → lessons → truncate lowest-priority on overflow).',
|
|
25
|
+
'**`/memory show` + `/memory recall` slash surface (closes #73).** `/memory show [profile|rules|lessons] [--scope workspace|global]` dumps Layer A markdown inline; defaults to all three for per-project-tagged scope (workspace first, then global). `/memory recall <query> [--kind|--room|--wing|--limit|--days_back]` searches Layer B drawers directly from chat without going through the model\'s tool call. Memory command tab-completion lists all 8 subcommands.',
|
|
26
|
+
'**`@otto/coworker-artifacts` workspace-scoped store (Phase 4).** `report` artifact kind (markdown v1; workbook + dataset deferred). `ArtifactStore` with slug derivation (`deriveSlug` lowercase ASCII kebab, max 64 chars) + collision suffixing (`-2`, `-3`, … up to 100). Atomic writes (tmp → chmod → rename), mode 0o700 dir / 0o600 files. `DirSnapshot` (nanosecond mtime + size_bytes) drives per-turn `files_touched` via before/after diff. Append-only `provenance.json` records `{ts, action: create|update, turn_id, agent_turn_id?, user_prompt, scratchpad_name?, files_touched}` per turn. Deterministic `README.md` re-renders on every save. `resolveArtifactUri(uri, workspaceDir)` validates `^artifact://[a-z0-9][a-z0-9-]*[a-z0-9]$|^artifact://[a-z0-9]$`, rejects `..` traversal + length > 64 + non-ASCII. Production activator registers `/artifacts list|show|remove --confirm` (flag-order-agnostic) + `list_artifacts` + `open_artifact` LLM tools. Kernel-side `otto.artifact.create(kind, name)` + `otto.artifact.spillIfLarge(value, opts?)` (10 KB default threshold) via bidirectional NDJSON RPC over stdio. `kind:\'artifact\'` drawer in memory (migration 002 rebuilds the `drawers.kind` CHECK constraint) tagged with the scratchpad name as `room`, so `/memory recall <q> --kind artifact` finds them.',
|
|
27
|
+
'**Subagent-scratchpad scoping (Phase 4.5).** Subagent dispatcher mints `subagent-<sanitized-agent>-<6-hex>` per child process; the spawned `pi` reads `OTTO_SUBAGENT_SCRATCHPAD` env var at `session_start` and force-attaches before sidecar/pointer restore (validated against `^subagent-[a-z0-9-]+$`, max 80 chars). Scratchpads persist after subagent exit — parent can `/sp attach subagent-<id>` post-hoc to inspect kernel state, cells, namespace globals. Failure (invalid name, disk error) emits a warning and falls through to normal restore; never crashes `session_start`.',
|
|
28
|
+
],
|
|
29
|
+
fixed: [
|
|
30
|
+
'**Strict-tsc compatibility for activator tool registrations.** `api.registerTool<TParams, TDetails>(...)` generics are explicit union types so success-vs-error result shapes both satisfy `AgentToolResult<TDetails>`. Caught at Phase 3.1 build-gate; not at test-compile (which uses esbuild). All Phase 3.1 + Phase 4 + Phase 4.5 activators carry the pattern.',
|
|
31
|
+
'**Strict `pi` kernel-entry main loop no longer deadlocks on artifact RPC.** `await runCell(req.code)` inside the `for await (const raw of readNdjson(stdin))` loop blocked the iterator from receiving its own RPC responses. Now fire-and-forget; manager already serializes cell submissions.',
|
|
32
|
+
'**Memory migration 002 rebuilds FTS5 triggers + virtual-table rowids** after the `drawers` table rename. Without this, `recall()` on existing v1 databases would return zero results post-upgrade.',
|
|
33
|
+
'**Memory recorder `byte_count` audit field** now uses `Buffer.byteLength(content, \'utf8\')` instead of character count.',
|
|
34
|
+
'**`LayerAStore` write-then-read round-trip preserves the section heading** on subsequent appends. Title-dedup regex tolerates leading newline left by frontmatter split.',
|
|
35
|
+
'**`optionalDependencies.@cmetech/otto-engine-*` pins synced to root version.** `version-sync.test.ts` asserts equality on every build; root publish would fail npm resolution otherwise.',
|
|
36
|
+
],
|
|
37
|
+
changed: [
|
|
38
|
+
'**Memory backend `local-sqlite-backend` runs migrations conditionally.** `open()` checks `PRAGMA user_version` and applies `001-init.sql` (if version < 1) then `002-artifact-kind.sql` (if version < 2). Migration 002 rebuilds the `drawers` table with `\'artifact\'` added to the kind CHECK and re-runs FTS5 contentless-rowid alignment.',
|
|
39
|
+
'**Memory drawer kinds vocabulary** now includes `\'artifact\'`. Existing kinds (`turn`, `paste`, `file_load`, `ticket`, `email`, `rca`, `note`) unchanged.',
|
|
40
|
+
'**`/memory` command** description is a sentence; `getArgumentCompletions` lists all 8 subcommands with one-line descriptions of each.',
|
|
41
|
+
'**Audit log gains three new producers**: `memory` (write-layer-a, write-drawer, redact, block, recall, seed-applied), `vault` (set, remove, test, inject, inject-skipped — Phase 2 already had these but now reachable via slash), and `artifacts` (write, remove). All land in the shared `~/.otto/audit.jsonl`.',
|
|
42
|
+
],
|
|
43
|
+
notes: [
|
|
44
|
+
'Phase 5 (Layer C entity graph + ACC + Cerebellum + Consolidator + daily digest + `memory://` URI resolver) is the next phase — depends on Phase 3 + Phase 4 (both shipped here). Phase 6 (NOC persona bundle, integration testing, time-to-first-artifact < 5 min) follows.',
|
|
45
|
+
'Smoke checklists for the four shipped phases live at `docs/superpowers/notes/2026-06-02-{phase-2-vault,phase-3-memory,phase-4-artifacts,phase-4.5-subagent-scratchpad}-smoke.md`. Each carries a PENDING verified-live placeholder — fill in after end-to-end TUI walkthrough.',
|
|
46
|
+
'Spec + plan artifacts at `docs/superpowers/specs/2026-06-02-*` and `docs/superpowers/plans/2026-06-02-*` for every phase shipped here.',
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
version: '1.2.0',
|
|
51
|
+
date: '2026-06-01',
|
|
52
|
+
headline: 'Co-worker scratchpad Phase 1.5 polish wave: typing `otto` in a workspace where you previously attached a scratchpad now auto-restores it without `--resume`; `/sp evict` and idle-age display land; `otto.duckdb.registerDf` drops polars→DuckDB from ~8 LLM cells to 2.',
|
|
53
|
+
added: [
|
|
54
|
+
'**Workspace-pointer auto-restore (Issue #6).** New `~/.otto/scratchpads/_workspaces/<sha256-16>.json` keyed on git toplevel (else cwd). On `session_start`, when no per-session sidecar matches, falls back to the workspace pointer. The spec\'s canonical day-2 RCA scenario now works without `--resume` — typing `otto` in the same workspace surfaces `attached to <name> (from workspace, last used <relative>)`. 7-day staleness threshold; cross-workspace isolation; restored scratchpads cold-restart from disk via Phase 1\'s existing snapshot path.',
|
|
55
|
+
'**`/sp list` idle-age column (Issue #4).** Warm entries now show `active` (cell running) or `idle Xm` / `idle Xh` / `idle Xd` (floored minutes/hours/days since last use). Cold entries unchanged.',
|
|
56
|
+
'**`/sp evict <name> [--force]` slash command (Issue #4).** Releases a warm kernel without deleting the scratchpad — on-disk state (kernel.db, namespace.json, cells.jsonl) remains for cold-restart on next attach. Refuses on active cell unless `--force`. `--force` reuses the existing `runtime.cancel()` SIGINT→SIGTERM→SIGKILL escalation; skips snapshot since the kernel is dead post-cancel.',
|
|
57
|
+
'**`otto.duckdb.registerDf(name, input, opts?)` (Issue #1).** Duck-typed input detection for polars DataFrames, Arrow Tables, and arrays of records. First-10-rows null-walk schema inference covers sparse leading rows. Optional `opts.schema` override (accepts `Record<string, type>` or `Array<[col, type]>`). All-or-nothing semantics: partial-row failure drops the partial table so retries don\'t hit "Table already exists." Per-column failure attribution in error messages. `cw_scratchpad` `promptGuidelines` updated so the LLM reaches for the helper instead of API discovery — polars→DuckDB drops from ~8 cells to 2.',
|
|
58
|
+
'**Stale sidecar GC on init (Issue #67).** `sweepStaleSidecars` runs once at `session_start`. Deletes foreign-session sidecars where the referenced scratchpad is gone OR sidecar mtime is > 7 days old. Per-file try/catch isolation; current session\'s sidecar always protected.',
|
|
59
|
+
],
|
|
60
|
+
fixed: [
|
|
61
|
+
'**`meta.json` on fresh `/sp new` reflects post-spawn disk state (Issue #2).** Previously showed `kernel_db.present: false` and `size_bytes: 0` because the initial `writeMeta` fired before `kernel.db` existed on disk. Added a second `writeMeta` call after `spawnRuntime` succeeds; the first call still preserves the lock-acquire side-effect.',
|
|
62
|
+
],
|
|
63
|
+
changed: [
|
|
64
|
+
'**`/sp attach <name>` errors on typo (Issue #5).** Previously, `/sp attach <typo>` silently spawned a phantom scratchpad. Now errors with `scratchpad not found: <name>. Use /sp new <name> to create it.` Library `manager.getOrAttach` and the LLM tool path (`cw_scratchpad` action=exec) remain permissive — the asymmetry is intentional (LLM-passed names should auto-create; user-typed names should fail loud).',
|
|
65
|
+
'**Session sidecar filename format (Issue #66).** Renamed from `<sessionId>.json` to `sidecar_<sessionId>.json` for visual scan and `sidecar_*` glob. Old-format files become inert orphans (the sweep ignores anything without the `sidecar_` prefix). Users upgrading can manually `rm ~/.otto/scratchpads/_sessions/*.json` once if they want a clean slate; otherwise old files are harmless and persistent.',
|
|
66
|
+
'**`ScratchpadInfo` interface gains `hasActiveCell: boolean`.** Workspace-private package change with two internal consumers; no out-of-tree breakage.',
|
|
67
|
+
],
|
|
68
|
+
notes: [
|
|
69
|
+
'Phase 1.5 closes the open known-issues backlog from `docs/superpowers/notes/2026-06-01-coworker-phase-1-known-issues.md` (Issues #1, #2, #4, #5, #6) and GH #66, #67.',
|
|
70
|
+
'Five follow-up items filed as #68–#72 for post-merge polish (workspace-pointer GC, `/sp evict <current>` sidecar question, `formatRelativeAge`/`hasActiveCell` overlap, `detectWorkspaceRoot` memoization, and dual-`writeMeta` doc comment).',
|
|
71
|
+
'Issue #3 (LLM "ask if unsure" reliability) remains accepted as inherent LLM behavior; revisited in Phase 6 (NOC persona polish).',
|
|
72
|
+
'See the Phase 1.5 re-verify section in `docs/superpowers/notes/2026-06-01-coworker-phase-1-human-tests.md` for the 11-scenario sign-off checklist.',
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
version: '1.1.1',
|
|
77
|
+
date: '2026-05-29',
|
|
78
|
+
headline: 'Windows `otto update` no longer emits EPERM cleanup warnings or leaves orphan `.otto-*` staging dirs.',
|
|
79
|
+
added: [
|
|
80
|
+
'`update-status.json` written to `~/.otto/agent/` on every `otto update` — tracks `startedAt`, `completedAt`, `fromVersion`, `toVersion`, and `exitCode`. The next `otto update` prints "Last update: vX.Y.Z → vA.B.C at … (✓ success / ✗ exit N)" before checking the registry, so you can see whether a previous background update finished.',
|
|
81
|
+
],
|
|
82
|
+
fixed: [
|
|
83
|
+
'`otto update` on Windows would log `EPERM: operation not permitted, unlink` warnings against `duckdb.dll`, `sharp.dll`, and `otto_engine.win32-x64.node` because the running otto.exe still held DLL handles. The install still succeeded but left orphan `.otto-RouGtD54`-style staging directories under `%APPDATA%\\npm\\node_modules\\@cmetech\\`. `otto update` now spawns a detached PowerShell bootstrap in a visible "OTTO Updater" console window that waits for the parent otto.exe to exit (max 30s), runs the install with locks released, sweeps the orphan staging dirs, and writes a completion status to `~/.otto/agent/update-status.json` that the next `otto update` surfaces. macOS / Linux behavior unchanged — POSIX inode semantics handle live-process replacement without the lock issue.',
|
|
84
|
+
],
|
|
85
|
+
changed: [
|
|
86
|
+
'`/release-notes` data is now capped at the last 20 releases per npm tarball (override at build time via `OTTO_RELEASE_NOTES_CAP=<n>`; set `0` for unlimited). `CHANGELOG.md` stays the canonical full history; the runtime command shows a footer like "Bundled here: v1.0.5 → v1.2.0 (20 of 35 total). Older releases: github.com/cmetech/otto-cli/blob/main/CHANGELOG.md" when truncation is active. Keeps the shipped data file from growing unbounded as the project ages.',
|
|
87
|
+
],
|
|
88
|
+
},
|
|
7
89
|
{
|
|
8
90
|
version: '1.1.0',
|
|
9
91
|
date: '2026-05-29',
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* count badge per entry, then full detail on selection. Output is written
|
|
12
12
|
* to stdout so it lands in the chat transcript.
|
|
13
13
|
*/
|
|
14
|
-
import { RELEASE_NOTES, countItems, findReleaseByVersion, getLatestRelease, } from "./_data.js";
|
|
14
|
+
import { RELEASE_NOTES, RELEASE_NOTES_MANIFEST, countItems, findReleaseByVersion, getLatestRelease, } from "./_data.js";
|
|
15
15
|
const USAGE = `Usage:
|
|
16
16
|
/release-notes Browse all releases interactively
|
|
17
17
|
/release-notes <version> Show a specific release (e.g. 1.0.7)
|
|
@@ -29,6 +29,13 @@ function renderSection(title, items) {
|
|
|
29
29
|
const bulleted = items.map((line) => `- ${line}`).join("\n");
|
|
30
30
|
return `\n### ${title}\n${bulleted}\n`;
|
|
31
31
|
}
|
|
32
|
+
function renderCapFooter() {
|
|
33
|
+
const m = RELEASE_NOTES_MANIFEST;
|
|
34
|
+
if (!m.truncated) {
|
|
35
|
+
return `${RELEASE_NOTES.length} releases tracked.`;
|
|
36
|
+
}
|
|
37
|
+
return `Bundled here: v${m.oldestBundled} → v${m.newestBundled} (${RELEASE_NOTES.length} of ${m.total} total).\nOlder releases: ${m.historyUrl}`;
|
|
38
|
+
}
|
|
32
39
|
function renderRelease(release) {
|
|
33
40
|
const header = `# OTTO v${release.version} — ${release.date}`;
|
|
34
41
|
const headline = release.headline ? `\n_${release.headline}_\n` : "";
|
|
@@ -38,7 +45,7 @@ function renderRelease(release) {
|
|
|
38
45
|
renderSection("Changed", release.changed),
|
|
39
46
|
renderSection("Notes", release.notes),
|
|
40
47
|
].join("");
|
|
41
|
-
const tail = `\n---\n${
|
|
48
|
+
const tail = `\n---\n${renderCapFooter()}\nUse \`/release-notes\` to browse, \`/release-notes <version>\` for any other release.`;
|
|
42
49
|
return `${header}${headline}${body}${tail}\n`;
|
|
43
50
|
}
|
|
44
51
|
function renderIndex() {
|
|
@@ -48,7 +55,7 @@ function renderIndex() {
|
|
|
48
55
|
const headline = r.headline ? ` — ${r.headline}` : "";
|
|
49
56
|
return `- v${r.version} (${r.date}, ${badge})${headline}`;
|
|
50
57
|
}).join("\n");
|
|
51
|
-
return `# OTTO release index\n\n${rows}\n\nView any release with \`/release-notes <version>\`.\n`;
|
|
58
|
+
return `# OTTO release index\n\n${rows}\n\n${renderCapFooter()}\nView any release with \`/release-notes <version>\`.\n`;
|
|
52
59
|
}
|
|
53
60
|
function findByVersionToken(token) {
|
|
54
61
|
if (token === "latest")
|
|
@@ -71,7 +78,11 @@ export function registerReleaseNotesCommand(pi) {
|
|
|
71
78
|
if (trimmed && trimmed !== "list") {
|
|
72
79
|
const match = findByVersionToken(trimmed);
|
|
73
80
|
if (!match) {
|
|
74
|
-
|
|
81
|
+
const m = RELEASE_NOTES_MANIFEST;
|
|
82
|
+
const truncationHint = m.truncated
|
|
83
|
+
? `\n\nThis OTTO build bundles ${RELEASE_NOTES.length} of ${m.total} total releases (v${m.oldestBundled} → v${m.newestBundled}). For older releases, see ${m.historyUrl}`
|
|
84
|
+
: "";
|
|
85
|
+
postToChat(pi, `**No release found for \`${trimmed}\`**\n\nKnown versions: ${RELEASE_NOTES.map((r) => `v${r.version}`).join(", ")}${truncationHint}`);
|
|
75
86
|
return;
|
|
76
87
|
}
|
|
77
88
|
postToChat(pi, renderRelease(match));
|
|
@@ -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;
|