@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 @@
|
|
|
1
|
+
export { handleList, handleCurrent, handleSwitch, handleReset, handleInstall, handleUninstall, } from '@otto/coworker-persona';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// /persona slash-command handlers now live in @otto/coworker-persona so they
|
|
2
|
+
// can be imported from inside the src/resources extension boundary (which is
|
|
3
|
+
// compiled with rootDir: src/resources and cannot import from src/ directly).
|
|
4
|
+
// Re-exported here for the co-located unit test and external callers.
|
|
5
|
+
export { handleList, handleCurrent, handleSwitch, handleReset, handleInstall, handleUninstall, } from '@otto/coworker-persona';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import * as fs from 'node:fs/promises';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import * as os from 'node:os';
|
|
6
|
+
import { PersonaRegistry } from '@otto/coworker-persona';
|
|
7
|
+
import { handleList, handleCurrent, handleSwitch } from './persona-commands.js';
|
|
8
|
+
let tmpHome;
|
|
9
|
+
let tmpWs;
|
|
10
|
+
let registry;
|
|
11
|
+
describe('persona slash commands', () => {
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
tmpHome = await fs.mkdtemp(path.join(os.tmpdir(), 'persona-home-'));
|
|
14
|
+
tmpWs = await fs.mkdtemp(path.join(os.tmpdir(), 'persona-ws-'));
|
|
15
|
+
await fs.mkdir(path.join(tmpHome, 'personas'), { recursive: true });
|
|
16
|
+
registry = new PersonaRegistry({ ottoHome: tmpHome });
|
|
17
|
+
await registry.ensureDefaultInstalled();
|
|
18
|
+
});
|
|
19
|
+
afterEach(async () => {
|
|
20
|
+
await fs.rm(tmpHome, { recursive: true, force: true });
|
|
21
|
+
await fs.rm(tmpWs, { recursive: true, force: true });
|
|
22
|
+
});
|
|
23
|
+
it('list returns lines including the default persona with active marker', async () => {
|
|
24
|
+
const lines = await handleList(registry, tmpWs);
|
|
25
|
+
const text = lines.join('\n');
|
|
26
|
+
assert.match(text, /default/);
|
|
27
|
+
assert.match(text, /\*/); // active marker on the active persona
|
|
28
|
+
});
|
|
29
|
+
it('current shows active persona name + display_name', async () => {
|
|
30
|
+
const lines = await handleCurrent(registry, tmpWs);
|
|
31
|
+
const text = lines.join('\n');
|
|
32
|
+
assert.match(text, /default/);
|
|
33
|
+
assert.match(text, /Default Co-Worker/);
|
|
34
|
+
});
|
|
35
|
+
it('switch updates the workspace record to the requested persona', async () => {
|
|
36
|
+
await handleSwitch(registry, tmpWs, 'default');
|
|
37
|
+
const raw = await fs.readFile(path.join(tmpWs, '.otto', 'persona.json'), 'utf8');
|
|
38
|
+
const data = JSON.parse(raw);
|
|
39
|
+
assert.equal(data.active, 'default');
|
|
40
|
+
});
|
|
41
|
+
it('switch to an unknown persona returns an error line', async () => {
|
|
42
|
+
const result = await handleSwitch(registry, tmpWs, 'nonexistent').catch((e) => e.message);
|
|
43
|
+
assert.match(result, /not installed|not found/i);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
fe239844559e7ca1
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { homedir } from 'node:os';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
export function getCoworkerGlobalDir() {
|
|
4
|
+
return process.env.OTTO_COWORKER_GLOBAL_DIR ?? join(homedir(), '.otto');
|
|
5
|
+
}
|
|
6
|
+
export function getScratchpadsRoot() {
|
|
7
|
+
return process.env.OTTO_SCRATCHPAD_ROOT ?? join(homedir(), '.otto', 'scratchpads');
|
|
8
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { runListArtifacts } from './list-tool.js';
|
|
2
|
+
import { runOpenArtifact } from './open-tool.js';
|
|
3
|
+
export async function runArtifactsCommand(store, argv) {
|
|
4
|
+
const [sub, ...rest] = argv;
|
|
5
|
+
switch (sub) {
|
|
6
|
+
case 'list':
|
|
7
|
+
case undefined: {
|
|
8
|
+
const out = await runListArtifacts(store);
|
|
9
|
+
return { message: out.markdown };
|
|
10
|
+
}
|
|
11
|
+
case 'show': {
|
|
12
|
+
const slug = rest[0];
|
|
13
|
+
if (!slug)
|
|
14
|
+
throw new Error('Usage: /artifacts show <slug>');
|
|
15
|
+
const out = await runOpenArtifact(store, { slug });
|
|
16
|
+
return { message: out.markdown };
|
|
17
|
+
}
|
|
18
|
+
case 'remove': {
|
|
19
|
+
const slug = rest.find((a) => !a.startsWith('--'));
|
|
20
|
+
const confirm = rest.includes('--confirm');
|
|
21
|
+
if (!slug)
|
|
22
|
+
throw new Error('Usage: /artifacts remove <slug> --confirm');
|
|
23
|
+
if (!confirm)
|
|
24
|
+
throw new Error('Usage: /artifacts remove <slug> --confirm');
|
|
25
|
+
await store.remove(slug, true);
|
|
26
|
+
return { message: `removed: ${slug}` };
|
|
27
|
+
}
|
|
28
|
+
default:
|
|
29
|
+
throw new Error(`Unknown /artifacts subcommand: ${sub}. Try: list, show, remove.`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/resources/extensions/coworker-artifacts/artifacts-singleton.ts
|
|
2
|
+
//
|
|
3
|
+
// Factory for the per-session ArtifactStore bundle. Mirrors the Phase 3
|
|
4
|
+
// memory-singleton pattern so the activator can construct/dispose state in
|
|
5
|
+
// one place. dispose() is a no-op in v1 (ArtifactStore holds no async
|
|
6
|
+
// resources) but kept for pattern symmetry with memory + scratchpad bundles.
|
|
7
|
+
import { ArtifactStore } from '@otto/coworker-artifacts';
|
|
8
|
+
export async function createArtifactsBundle(opts) {
|
|
9
|
+
const store = new ArtifactStore({ workspaceDir: opts.workspaceDir, now: opts.now });
|
|
10
|
+
return {
|
|
11
|
+
store,
|
|
12
|
+
workspaceDir: opts.workspaceDir,
|
|
13
|
+
async dispose() {
|
|
14
|
+
/* no async resources in v1 */
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "coworker-artifacts",
|
|
3
|
+
"name": "Co-worker Artifacts",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Workspace-scoped artifact store: artifact://<slug> URIs, /artifacts slash, list_artifacts + open_artifact tools",
|
|
6
|
+
"tier": "bundled",
|
|
7
|
+
"requires": { "platform": ">=2.29.0" },
|
|
8
|
+
"provides": {
|
|
9
|
+
"tools": ["list_artifacts", "open_artifact"],
|
|
10
|
+
"commands": ["artifacts"],
|
|
11
|
+
"hooks": ["session_start", "session_shutdown"]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { createArtifactsBundle } from './artifacts-singleton.js';
|
|
3
|
+
import { runListArtifacts } from './list-tool.js';
|
|
4
|
+
import { runOpenArtifact } from './open-tool.js';
|
|
5
|
+
import { runArtifactsCommand } from './artifacts-command.js';
|
|
6
|
+
export { createArtifactsBundle };
|
|
7
|
+
// Cross-pillar export — null before session_start or after session_shutdown.
|
|
8
|
+
let activeStore = null;
|
|
9
|
+
export function getArtifactStore() {
|
|
10
|
+
return activeStore;
|
|
11
|
+
}
|
|
12
|
+
const LIST_PARAMS = Type.Object({});
|
|
13
|
+
const OPEN_PARAMS = Type.Object({
|
|
14
|
+
slug: Type.String({ description: 'The artifact slug (e.g. "report" or "report-2") to read.' }),
|
|
15
|
+
});
|
|
16
|
+
export default function coworkerArtifactsExtension(api) {
|
|
17
|
+
let bundle = null;
|
|
18
|
+
let unavailable = false;
|
|
19
|
+
api.on('session_start', async (_event, ctx) => {
|
|
20
|
+
try {
|
|
21
|
+
bundle = await createArtifactsBundle({ workspaceDir: ctx.cwd });
|
|
22
|
+
activeStore = bundle.store;
|
|
23
|
+
unavailable = false;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
unavailable = true;
|
|
27
|
+
bundle = null;
|
|
28
|
+
activeStore = null;
|
|
29
|
+
ctx.ui.notify(`artifacts unavailable: ${err.message}`, 'warning');
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
api.registerTool({
|
|
33
|
+
name: 'list_artifacts',
|
|
34
|
+
label: 'List artifacts',
|
|
35
|
+
description: 'List all artifacts in the current workspace.',
|
|
36
|
+
parameters: LIST_PARAMS,
|
|
37
|
+
async execute() {
|
|
38
|
+
if (!bundle) {
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: 'text', text: 'artifacts unavailable' }],
|
|
41
|
+
details: { error: 'unavailable' },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const out = await runListArtifacts(bundle.store);
|
|
46
|
+
return {
|
|
47
|
+
content: [{ type: 'text', text: out.markdown }],
|
|
48
|
+
details: { result_count: out.artifacts.length },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: 'text', text: `list failed: ${err.message}` }],
|
|
54
|
+
details: { error: err.message },
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
api.registerTool({
|
|
60
|
+
name: 'open_artifact',
|
|
61
|
+
label: 'Open artifact',
|
|
62
|
+
description: 'Read the contents of an artifact by slug. Returns markdown body + recent provenance.',
|
|
63
|
+
parameters: OPEN_PARAMS,
|
|
64
|
+
async execute(_toolCallId, params) {
|
|
65
|
+
if (!bundle) {
|
|
66
|
+
return {
|
|
67
|
+
content: [{ type: 'text', text: 'artifacts unavailable' }],
|
|
68
|
+
details: { error: 'unavailable' },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const out = await runOpenArtifact(bundle.store, params);
|
|
73
|
+
return {
|
|
74
|
+
content: [{ type: 'text', text: out.markdown }],
|
|
75
|
+
details: { slug: params.slug },
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
return {
|
|
80
|
+
content: [{ type: 'text', text: `open failed: ${err.message}` }],
|
|
81
|
+
details: { error: err.message },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
api.registerCommand('artifacts', {
|
|
87
|
+
description: 'Inspect artifacts: /artifacts list | show <slug> | remove <slug> --confirm',
|
|
88
|
+
getArgumentCompletions: (prefix) => {
|
|
89
|
+
const subs = [
|
|
90
|
+
{ label: 'list', description: 'List all artifacts' },
|
|
91
|
+
{ label: 'show', description: 'Show artifact body + provenance: /artifacts show <slug>' },
|
|
92
|
+
{ label: 'remove', description: 'Delete artifact: /artifacts remove <slug> --confirm' },
|
|
93
|
+
];
|
|
94
|
+
return subs
|
|
95
|
+
.filter((s) => s.label.startsWith(prefix))
|
|
96
|
+
.map((s) => ({ value: s.label, label: s.label, description: s.description }));
|
|
97
|
+
},
|
|
98
|
+
handler: async (args, ctx) => {
|
|
99
|
+
if (!bundle) {
|
|
100
|
+
ctx.ui.notify(unavailable ? 'artifacts unavailable; chat continues without it.' : 'artifacts not ready yet.', 'warning');
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const argv = args.trim().split(/\s+/).filter(Boolean);
|
|
104
|
+
try {
|
|
105
|
+
const result = await runArtifactsCommand(bundle.store, argv);
|
|
106
|
+
ctx.ui.notify(result.message, 'info');
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
ctx.ui.notify(`/artifacts failed: ${err.message}`, 'error');
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
api.on('session_shutdown', async () => {
|
|
114
|
+
if (bundle) {
|
|
115
|
+
try {
|
|
116
|
+
await bundle.dispose();
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
/* best effort */
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
bundle = null;
|
|
123
|
+
activeStore = null;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export async function runListArtifacts(store) {
|
|
2
|
+
const handles = await store.list();
|
|
3
|
+
// We need the metadata fields not on the handle — re-read each metadata.json.
|
|
4
|
+
const { readFileSync } = await import('node:fs');
|
|
5
|
+
const rows = handles.map((h) => {
|
|
6
|
+
const meta = JSON.parse(readFileSync(h.metadataPath, 'utf8'));
|
|
7
|
+
return {
|
|
8
|
+
slug: h.slug,
|
|
9
|
+
kind: h.kind,
|
|
10
|
+
name: h.name,
|
|
11
|
+
uri: h.uri,
|
|
12
|
+
created_at: meta.created_at,
|
|
13
|
+
last_updated_at: meta.last_updated_at,
|
|
14
|
+
turn_count: meta.turn_count,
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
if (rows.length === 0) {
|
|
18
|
+
return { artifacts: [], markdown: '### Artifacts (0)\n' };
|
|
19
|
+
}
|
|
20
|
+
const lines = [`### Artifacts (${rows.length})`, ''];
|
|
21
|
+
lines.push('| slug | kind | turns | last updated | uri |');
|
|
22
|
+
lines.push('|---|---|---|---|---|');
|
|
23
|
+
for (const r of rows) {
|
|
24
|
+
lines.push(`| ${r.slug} | ${r.kind} | ${r.turn_count} | ${r.last_updated_at} | \`${r.uri}\` |`);
|
|
25
|
+
}
|
|
26
|
+
return { artifacts: rows, markdown: lines.join('\n') + '\n' };
|
|
27
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ArtifactNotFound } from '@otto/coworker-artifacts';
|
|
2
|
+
export async function runOpenArtifact(store, args) {
|
|
3
|
+
const handle = await store.get(args.slug);
|
|
4
|
+
if (!handle)
|
|
5
|
+
throw new ArtifactNotFound(args.slug);
|
|
6
|
+
const { readFileSync } = await import('node:fs');
|
|
7
|
+
const body = readFileSync(handle.primaryPath, 'utf8');
|
|
8
|
+
const provRaw = readFileSync(handle.provenancePath, 'utf8');
|
|
9
|
+
const prov = JSON.parse(provRaw);
|
|
10
|
+
const tail = prov.slice(-5);
|
|
11
|
+
const lines = [];
|
|
12
|
+
lines.push(`### ${handle.name} (\`${handle.uri}\`)`);
|
|
13
|
+
lines.push('');
|
|
14
|
+
lines.push('```markdown');
|
|
15
|
+
lines.push(body);
|
|
16
|
+
lines.push('```');
|
|
17
|
+
lines.push('');
|
|
18
|
+
if (tail.length > 0) {
|
|
19
|
+
lines.push('**Recent provenance:**');
|
|
20
|
+
for (const e of tail) {
|
|
21
|
+
lines.push(`- ${e.ts} · ${e.action} · turn \`${e.turn_id}\` · ${e.user_prompt}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return { markdown: lines.join('\n') + '\n' };
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "coworker-memory",
|
|
3
|
+
"name": "Co-worker Memory",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Layered memory: Layer A (markdown rules/lessons) + Layer B (verbatim SQLite drawers) with /memory commands and memorize/recall tools",
|
|
6
|
+
"tier": "bundled",
|
|
7
|
+
"requires": { "platform": ">=2.29.0" },
|
|
8
|
+
"provides": {
|
|
9
|
+
"tools": ["memorize", "recall"],
|
|
10
|
+
"commands": ["memory"],
|
|
11
|
+
"hooks": ["session_start", "session_shutdown"]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { buildLayerAContext, } from '@otto/coworker-memory';
|
|
3
|
+
import { createMemoryBundle } from './memory-singleton.js';
|
|
4
|
+
import { runMemorize } from './memorize-tool.js';
|
|
5
|
+
import { runRecall } from './recall-tool.js';
|
|
6
|
+
import { runMemoryCommand } from './memory-command.js';
|
|
7
|
+
import { onSessionShutdown } from './session-hooks.js';
|
|
8
|
+
import { createCurrentScratchpadProvider } from '../coworker-scratchpad/sp-command.js';
|
|
9
|
+
import { getCoworkerGlobalDir, getScratchpadsRoot } from '../_coworker-paths.js';
|
|
10
|
+
export { createMemoryBundle };
|
|
11
|
+
// Cross-pillar export. Scratchpad's onDataLoad closure imports this and calls
|
|
12
|
+
// it lazily — returns null before session_start or after session_shutdown,
|
|
13
|
+
// which is the correct "no-op" signal.
|
|
14
|
+
let activeRecorder = null;
|
|
15
|
+
export function getMemoryRecorder() {
|
|
16
|
+
return activeRecorder;
|
|
17
|
+
}
|
|
18
|
+
const MEMORIZE_PARAMS = Type.Object({
|
|
19
|
+
text: Type.String({ description: 'The note text to store in Layer A memory.' }),
|
|
20
|
+
kind: Type.Union([Type.Literal('profile'), Type.Literal('rule'), Type.Literal('lesson')], { description: "Layer A kind: 'profile' (about the user), 'rule' (must-do), or 'lesson' (learned)." }),
|
|
21
|
+
scope: Type.Optional(Type.Union([Type.Literal('global'), Type.Literal('workspace')], { description: "Defaults to 'workspace' when omitted." })),
|
|
22
|
+
});
|
|
23
|
+
const RECALL_PARAMS = Type.Object({
|
|
24
|
+
query: Type.String({ description: 'Free-text query to search verbatim drawers.' }),
|
|
25
|
+
kind: Type.Optional(Type.Union([
|
|
26
|
+
Type.Literal('turn'), Type.Literal('paste'), Type.Literal('file_load'),
|
|
27
|
+
Type.Literal('ticket'), Type.Literal('email'), Type.Literal('rca'), Type.Literal('note'),
|
|
28
|
+
])),
|
|
29
|
+
wing: Type.Optional(Type.String()),
|
|
30
|
+
room: Type.Optional(Type.String()),
|
|
31
|
+
days_back: Type.Optional(Type.Number()),
|
|
32
|
+
max_results: Type.Optional(Type.Number()),
|
|
33
|
+
});
|
|
34
|
+
export default function coworkerMemoryExtension(api) {
|
|
35
|
+
let bundle = null;
|
|
36
|
+
let unavailable = false;
|
|
37
|
+
let pendingPrompt;
|
|
38
|
+
// One notify per session covers both before_agent_start inject failures and
|
|
39
|
+
// agent_start recordTurn failures — both are best-effort and must not break
|
|
40
|
+
// the chat loop. Spec §3.7.
|
|
41
|
+
let writeFailureNotified = false;
|
|
42
|
+
api.on('session_start', async (_event, ctx) => {
|
|
43
|
+
try {
|
|
44
|
+
bundle = await createMemoryBundle({
|
|
45
|
+
globalDir: getCoworkerGlobalDir(),
|
|
46
|
+
workspaceDir: ctx.cwd,
|
|
47
|
+
scopeMode: 'per-project-tagged',
|
|
48
|
+
currentScratchpadName: createCurrentScratchpadProvider({
|
|
49
|
+
scratchpadsRoot: getScratchpadsRoot(),
|
|
50
|
+
}),
|
|
51
|
+
});
|
|
52
|
+
activeRecorder = bundle.recorder;
|
|
53
|
+
unavailable = false;
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
unavailable = true;
|
|
57
|
+
bundle = null;
|
|
58
|
+
activeRecorder = null;
|
|
59
|
+
ctx.ui.notify(`memory unavailable: ${err.message}`, 'warning');
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
api.on('before_agent_start', async (event, ctx) => {
|
|
63
|
+
if (!bundle)
|
|
64
|
+
return undefined;
|
|
65
|
+
// Capture the prompt for the paired agent_start so we can record it even
|
|
66
|
+
// when there is no Layer A content to inject (block.length === 0).
|
|
67
|
+
pendingPrompt = event.prompt;
|
|
68
|
+
try {
|
|
69
|
+
const block = await buildLayerAContext({
|
|
70
|
+
mode: bundle.scopeMode,
|
|
71
|
+
globalStore: bundle.globalLayerA,
|
|
72
|
+
workspaceStore: bundle.workspaceLayerA,
|
|
73
|
+
tokenLimit: 3000,
|
|
74
|
+
});
|
|
75
|
+
if (block.length === 0)
|
|
76
|
+
return undefined;
|
|
77
|
+
return { systemPrompt: event.systemPrompt + '\n\n' + block };
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (!writeFailureNotified) {
|
|
81
|
+
ctx.ui.notify(`memory context inject failed: ${err.message}`, 'warning');
|
|
82
|
+
writeFailureNotified = true;
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
api.on('agent_start', async (event, ctx) => {
|
|
88
|
+
if (!bundle || !pendingPrompt || !event.sessionId || !event.turnId) {
|
|
89
|
+
pendingPrompt = undefined;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const userText = pendingPrompt;
|
|
93
|
+
const sessionId = event.sessionId;
|
|
94
|
+
const turnId = event.turnId;
|
|
95
|
+
pendingPrompt = undefined;
|
|
96
|
+
try {
|
|
97
|
+
await bundle.recorder.recordTurn({ sessionId, userText, turnId });
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
if (!writeFailureNotified) {
|
|
101
|
+
ctx.ui.notify(`memory write failed: ${err.message}`, 'warning');
|
|
102
|
+
writeFailureNotified = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
api.registerTool({
|
|
107
|
+
name: 'memorize',
|
|
108
|
+
label: 'Memorize',
|
|
109
|
+
description: 'Save a profile note, rule, or lesson into Layer A memory.',
|
|
110
|
+
parameters: MEMORIZE_PARAMS,
|
|
111
|
+
async execute(_toolCallId, params) {
|
|
112
|
+
if (!bundle) {
|
|
113
|
+
return {
|
|
114
|
+
content: [{ type: 'text', text: 'memory unavailable; cannot memorize.' }],
|
|
115
|
+
details: { error: 'memory unavailable' },
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const out = await runMemorize(bundle, {
|
|
120
|
+
text: params.text,
|
|
121
|
+
kind: params.kind,
|
|
122
|
+
scope: params.scope,
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
content: [{ type: 'text', text: `stored in ${out.layer_a_file}` }],
|
|
126
|
+
details: out,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
return {
|
|
131
|
+
content: [{ type: 'text', text: `memorize failed: ${err.message}` }],
|
|
132
|
+
details: { error: err.message },
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
api.registerTool({
|
|
138
|
+
name: 'recall',
|
|
139
|
+
label: 'Recall',
|
|
140
|
+
description: 'Search verbatim drawers in memory (Layer B). Returns markdown with drawer URIs.',
|
|
141
|
+
parameters: RECALL_PARAMS,
|
|
142
|
+
async execute(_toolCallId, params) {
|
|
143
|
+
if (!bundle) {
|
|
144
|
+
return {
|
|
145
|
+
content: [{ type: 'text', text: 'memory unavailable; cannot recall.' }],
|
|
146
|
+
details: { error: 'memory unavailable' },
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const args = {
|
|
151
|
+
query: params.query,
|
|
152
|
+
kind: params.kind,
|
|
153
|
+
wing: params.wing,
|
|
154
|
+
room: params.room,
|
|
155
|
+
days_back: params.days_back,
|
|
156
|
+
max_results: params.max_results,
|
|
157
|
+
};
|
|
158
|
+
const out = await runRecall(bundle, args);
|
|
159
|
+
return {
|
|
160
|
+
content: [{ type: 'text', text: out.markdown }],
|
|
161
|
+
details: { result_count: out.results.length },
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
return {
|
|
166
|
+
content: [{ type: 'text', text: `recall failed: ${err.message}` }],
|
|
167
|
+
details: { error: err.message },
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
api.registerCommand('memory', {
|
|
173
|
+
description: 'Inspect and manage co-worker memory (Layer A rules/lessons + Layer B drawers).',
|
|
174
|
+
getArgumentCompletions: (prefix) => {
|
|
175
|
+
const subcommands = [
|
|
176
|
+
{ label: 'note', description: 'Append a lesson: /memory note <text>' },
|
|
177
|
+
{ label: 'show', description: 'Show Layer A: /memory show [profile|rules|lessons] [--scope workspace|global]' },
|
|
178
|
+
{ label: 'recall', description: 'Search Layer B drawers: /memory recall <query> [--kind|--room|--wing|--limit|--days_back]' },
|
|
179
|
+
{ label: 'status', description: 'Show workspace_wing, drawer_count, db path' },
|
|
180
|
+
{ label: 'clear', description: 'Clear drawers: /memory clear --wing <wing> --confirm' },
|
|
181
|
+
{ label: 'wing', description: 'Set session wing override: /memory wing <name>' },
|
|
182
|
+
{ label: 'room', description: 'Set session room override: /memory room <name>' },
|
|
183
|
+
{ label: 'seed', description: 'Re-apply persona seed on next session_start' },
|
|
184
|
+
];
|
|
185
|
+
return subcommands
|
|
186
|
+
.filter((s) => s.label.startsWith(prefix))
|
|
187
|
+
.map((s) => ({ value: s.label, label: s.label, description: s.description }));
|
|
188
|
+
},
|
|
189
|
+
handler: async (args, ctx) => {
|
|
190
|
+
if (!bundle) {
|
|
191
|
+
ctx.ui.notify(unavailable ? 'memory unavailable; chat continues without it.' : 'memory not ready yet.', 'warning');
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const argv = args.trim().split(/\s+/).filter(Boolean);
|
|
195
|
+
try {
|
|
196
|
+
const result = await runMemoryCommand(bundle, argv);
|
|
197
|
+
ctx.ui.notify(result.message, 'info');
|
|
198
|
+
}
|
|
199
|
+
catch (err) {
|
|
200
|
+
ctx.ui.notify(`/memory failed: ${err.message}`, 'error');
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
api.on('session_shutdown', async () => {
|
|
205
|
+
if (bundle) {
|
|
206
|
+
try {
|
|
207
|
+
await onSessionShutdown(bundle);
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// dispose is best-effort; LocalSqliteBackend.close() handles double-close.
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
bundle = null;
|
|
214
|
+
activeRecorder = null;
|
|
215
|
+
pendingPrompt = undefined;
|
|
216
|
+
// writeFailureNotified persists across sessions intentionally — one notify
|
|
217
|
+
// per Otto process lifetime is enough to avoid spam.
|
|
218
|
+
});
|
|
219
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export async function runMemorize(bundle, args) {
|
|
2
|
+
const scope = args.scope ?? 'workspace';
|
|
3
|
+
const store = scope === 'global' ? bundle.globalLayerA : bundle.workspaceLayerA;
|
|
4
|
+
const ts = new Date().toISOString();
|
|
5
|
+
await store.append({ kind: args.kind, text: args.text, source: 'user', ts });
|
|
6
|
+
return {
|
|
7
|
+
stored: true,
|
|
8
|
+
layer_a_file: args.kind === 'lesson' ? 'lessons.md' : args.kind === 'rule' ? 'rules.md' : 'profile.md',
|
|
9
|
+
};
|
|
10
|
+
}
|