@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,171 @@
|
|
|
1
|
+
export type { SkippedKey } from './namespace-codec.js';
|
|
2
|
+
import type { SkippedKey } from './namespace-codec.js';
|
|
3
|
+
export interface RunRequest {
|
|
4
|
+
id: number;
|
|
5
|
+
type: 'run';
|
|
6
|
+
code: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SnapshotRequest {
|
|
9
|
+
id: number;
|
|
10
|
+
type: 'snapshot';
|
|
11
|
+
}
|
|
12
|
+
export type KernelRequest = RunRequest | SnapshotRequest;
|
|
13
|
+
export interface ResultOk {
|
|
14
|
+
id: number;
|
|
15
|
+
type: 'result';
|
|
16
|
+
ok: true;
|
|
17
|
+
value: unknown;
|
|
18
|
+
stdout: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ResultErr {
|
|
21
|
+
id: number;
|
|
22
|
+
type: 'result';
|
|
23
|
+
ok: false;
|
|
24
|
+
error: {
|
|
25
|
+
name: string;
|
|
26
|
+
message: string;
|
|
27
|
+
stack?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export type ResultResponse = ResultOk | ResultErr;
|
|
31
|
+
export interface SnapshotResultOk {
|
|
32
|
+
id: number;
|
|
33
|
+
type: 'snapshot_result';
|
|
34
|
+
ok: true;
|
|
35
|
+
skipped: SkippedKey[];
|
|
36
|
+
snapshotted_at: string;
|
|
37
|
+
}
|
|
38
|
+
export interface SnapshotResultErr {
|
|
39
|
+
id: number;
|
|
40
|
+
type: 'snapshot_result';
|
|
41
|
+
ok: false;
|
|
42
|
+
error: {
|
|
43
|
+
name: string;
|
|
44
|
+
message: string;
|
|
45
|
+
stack?: string;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export type SnapshotResult = SnapshotResultOk | SnapshotResultErr;
|
|
49
|
+
export type RecoveryNote = {
|
|
50
|
+
kind: 'namespace-absent';
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'namespace-corrupt';
|
|
53
|
+
message: string;
|
|
54
|
+
} | {
|
|
55
|
+
kind: 'cells-since-snapshot';
|
|
56
|
+
n: number;
|
|
57
|
+
} | {
|
|
58
|
+
kind: 'snapshot-failed';
|
|
59
|
+
message: string;
|
|
60
|
+
};
|
|
61
|
+
export interface DataLoadDrawer {
|
|
62
|
+
kind: 'data_load';
|
|
63
|
+
collector: string;
|
|
64
|
+
uri: string;
|
|
65
|
+
bytes: number | null;
|
|
66
|
+
rows_loaded: number | null;
|
|
67
|
+
loaded_at: string;
|
|
68
|
+
schema: null;
|
|
69
|
+
}
|
|
70
|
+
export interface ReadyEvent {
|
|
71
|
+
type: 'event';
|
|
72
|
+
event: 'ready';
|
|
73
|
+
recovery_notes?: RecoveryNote[];
|
|
74
|
+
}
|
|
75
|
+
export interface DataLoadEvent {
|
|
76
|
+
type: 'event';
|
|
77
|
+
event: 'data_load';
|
|
78
|
+
drawer: DataLoadDrawer;
|
|
79
|
+
}
|
|
80
|
+
export interface ProgressEvent {
|
|
81
|
+
type: 'event';
|
|
82
|
+
event: 'progress';
|
|
83
|
+
message?: string;
|
|
84
|
+
}
|
|
85
|
+
export interface StartupErrorEvent {
|
|
86
|
+
type: 'event';
|
|
87
|
+
event: 'startup_error';
|
|
88
|
+
kind: string;
|
|
89
|
+
error: {
|
|
90
|
+
name: string;
|
|
91
|
+
message: string;
|
|
92
|
+
stack?: string;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export interface ArtifactCreateDrawer {
|
|
96
|
+
kind: 'artifact';
|
|
97
|
+
slug: string;
|
|
98
|
+
artifact_kind: string;
|
|
99
|
+
uri: string;
|
|
100
|
+
primary_path: string;
|
|
101
|
+
created_at: string;
|
|
102
|
+
}
|
|
103
|
+
export interface ArtifactCreateRequest {
|
|
104
|
+
type: 'request';
|
|
105
|
+
request: 'artifact_create';
|
|
106
|
+
id: string;
|
|
107
|
+
kind: string;
|
|
108
|
+
name: string;
|
|
109
|
+
}
|
|
110
|
+
export interface ArtifactCreateResponseOk {
|
|
111
|
+
type: 'response';
|
|
112
|
+
request: 'artifact_create';
|
|
113
|
+
id: string;
|
|
114
|
+
ok: true;
|
|
115
|
+
slug: string;
|
|
116
|
+
uri: string;
|
|
117
|
+
primary_path: string;
|
|
118
|
+
}
|
|
119
|
+
export interface ArtifactCreateResponseErr {
|
|
120
|
+
type: 'response';
|
|
121
|
+
request: 'artifact_create';
|
|
122
|
+
id: string;
|
|
123
|
+
ok: false;
|
|
124
|
+
error: string;
|
|
125
|
+
}
|
|
126
|
+
export type ArtifactCreateResponse = ArtifactCreateResponseOk | ArtifactCreateResponseErr;
|
|
127
|
+
export interface ArtifactUpdateRequest {
|
|
128
|
+
type: 'request';
|
|
129
|
+
request: 'artifact_update';
|
|
130
|
+
id: string;
|
|
131
|
+
slug: string;
|
|
132
|
+
files: Array<{
|
|
133
|
+
path: string;
|
|
134
|
+
content: string;
|
|
135
|
+
}>;
|
|
136
|
+
}
|
|
137
|
+
export interface ArtifactUpdateResponseOk {
|
|
138
|
+
type: 'response';
|
|
139
|
+
request: 'artifact_update';
|
|
140
|
+
id: string;
|
|
141
|
+
ok: true;
|
|
142
|
+
files_touched: string[];
|
|
143
|
+
}
|
|
144
|
+
export interface ArtifactUpdateResponseErr {
|
|
145
|
+
type: 'response';
|
|
146
|
+
request: 'artifact_update';
|
|
147
|
+
id: string;
|
|
148
|
+
ok: false;
|
|
149
|
+
error: string;
|
|
150
|
+
}
|
|
151
|
+
export type ArtifactUpdateResponse = ArtifactUpdateResponseOk | ArtifactUpdateResponseErr;
|
|
152
|
+
export interface ArtifactCreateEvent {
|
|
153
|
+
type: 'event';
|
|
154
|
+
event: 'artifact_create';
|
|
155
|
+
drawer: ArtifactCreateDrawer;
|
|
156
|
+
}
|
|
157
|
+
export type KernelRpcRequest = ArtifactCreateRequest | ArtifactUpdateRequest;
|
|
158
|
+
export type KernelRpcResponse = ArtifactCreateResponse | ArtifactUpdateResponse;
|
|
159
|
+
export type KernelEvent = ReadyEvent | DataLoadEvent | ProgressEvent | StartupErrorEvent | ArtifactCreateEvent;
|
|
160
|
+
export type KernelFrame = ResultResponse | KernelEvent | SnapshotResult | KernelRpcRequest;
|
|
161
|
+
export declare function isDataLoadEvent(frame: KernelFrame): frame is DataLoadEvent;
|
|
162
|
+
export declare function isProgressEvent(frame: KernelFrame): frame is ProgressEvent;
|
|
163
|
+
export declare function isStartupErrorEvent(frame: KernelFrame): frame is StartupErrorEvent;
|
|
164
|
+
export declare function isSnapshotResult(frame: KernelFrame): frame is SnapshotResult;
|
|
165
|
+
export declare function isArtifactCreateEvent(frame: unknown): frame is ArtifactCreateEvent;
|
|
166
|
+
export declare function isArtifactCreateRequest(frame: unknown): frame is ArtifactCreateRequest;
|
|
167
|
+
export declare function isArtifactUpdateRequest(frame: unknown): frame is ArtifactUpdateRequest;
|
|
168
|
+
export declare function isArtifactCreateResponse(frame: unknown): frame is ArtifactCreateResponse;
|
|
169
|
+
export declare function isArtifactUpdateResponse(frame: unknown): frame is ArtifactUpdateResponse;
|
|
170
|
+
/** True for any `{type:'response'}` frame addressed to the kernel. */
|
|
171
|
+
export declare function isKernelRpcResponse(frame: unknown): frame is KernelRpcResponse;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// NDJSON wire protocol between the scratchpad parent runtime and the kernel child.
|
|
2
|
+
// One JSON object per line (\n terminated). See spec §2.4 + §6.3.
|
|
3
|
+
export function isDataLoadEvent(frame) {
|
|
4
|
+
return frame.type === 'event' && frame.event === 'data_load';
|
|
5
|
+
}
|
|
6
|
+
export function isProgressEvent(frame) {
|
|
7
|
+
return frame.type === 'event' && frame.event === 'progress';
|
|
8
|
+
}
|
|
9
|
+
export function isStartupErrorEvent(frame) {
|
|
10
|
+
return frame.type === 'event' && frame.event === 'startup_error';
|
|
11
|
+
}
|
|
12
|
+
export function isSnapshotResult(frame) {
|
|
13
|
+
return frame.type === 'snapshot_result';
|
|
14
|
+
}
|
|
15
|
+
export function isArtifactCreateEvent(frame) {
|
|
16
|
+
if (typeof frame !== 'object' || frame === null)
|
|
17
|
+
return false;
|
|
18
|
+
const f = frame;
|
|
19
|
+
return f.type === 'event' && f.event === 'artifact_create';
|
|
20
|
+
}
|
|
21
|
+
export function isArtifactCreateRequest(frame) {
|
|
22
|
+
if (typeof frame !== 'object' || frame === null)
|
|
23
|
+
return false;
|
|
24
|
+
const f = frame;
|
|
25
|
+
return f.type === 'request' && f.request === 'artifact_create';
|
|
26
|
+
}
|
|
27
|
+
export function isArtifactUpdateRequest(frame) {
|
|
28
|
+
if (typeof frame !== 'object' || frame === null)
|
|
29
|
+
return false;
|
|
30
|
+
const f = frame;
|
|
31
|
+
return f.type === 'request' && f.request === 'artifact_update';
|
|
32
|
+
}
|
|
33
|
+
export function isArtifactCreateResponse(frame) {
|
|
34
|
+
if (typeof frame !== 'object' || frame === null)
|
|
35
|
+
return false;
|
|
36
|
+
const f = frame;
|
|
37
|
+
return f.type === 'response' && f.request === 'artifact_create';
|
|
38
|
+
}
|
|
39
|
+
export function isArtifactUpdateResponse(frame) {
|
|
40
|
+
if (typeof frame !== 'object' || frame === null)
|
|
41
|
+
return false;
|
|
42
|
+
const f = frame;
|
|
43
|
+
return f.type === 'response' && f.request === 'artifact_update';
|
|
44
|
+
}
|
|
45
|
+
/** True for any `{type:'response'}` frame addressed to the kernel. */
|
|
46
|
+
export function isKernelRpcResponse(frame) {
|
|
47
|
+
return isArtifactCreateResponse(frame) || isArtifactUpdateResponse(frame);
|
|
48
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
const ENV_ALLOW = new Set([
|
|
4
|
+
'PATH', 'HOME', 'TERM', 'SHELL', 'TMPDIR', 'TMP', 'TEMP',
|
|
5
|
+
'LANG', 'LANGUAGE', 'PWD', 'USER', 'LOGNAME',
|
|
6
|
+
]);
|
|
7
|
+
const ENV_ALLOW_PREFIXES = ['LC_', 'XDG_', 'OTTO_', 'NODE_'];
|
|
8
|
+
const ENV_DENY = new Set([
|
|
9
|
+
'LOOP24_GATEWAY_KEY', 'ANTHROPIC_API_KEY', 'OPENAI_API_KEY',
|
|
10
|
+
'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'GITHUB_TOKEN',
|
|
11
|
+
]);
|
|
12
|
+
export function filterEnv(source = process.env) {
|
|
13
|
+
const out = {};
|
|
14
|
+
for (const [key, value] of Object.entries(source)) {
|
|
15
|
+
if (value === undefined)
|
|
16
|
+
continue;
|
|
17
|
+
if (ENV_DENY.has(key))
|
|
18
|
+
continue; // denylist overrides any allow-rule
|
|
19
|
+
if (ENV_ALLOW.has(key) || ENV_ALLOW_PREFIXES.some((p) => key.startsWith(p))) {
|
|
20
|
+
out[key] = value;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
const FORWARD_FLAGS_WITH_VALUE = new Set([
|
|
26
|
+
'--import', '--loader', '--experimental-loader', '--require', '-r', '--conditions',
|
|
27
|
+
]);
|
|
28
|
+
const FORWARD_FLAGS_BOOLEAN = new Set([
|
|
29
|
+
'--experimental-strip-types', '--experimental-transform-types', '--no-warnings',
|
|
30
|
+
]);
|
|
31
|
+
export function kernelExecArgv(execArgv = process.execArgv) {
|
|
32
|
+
const out = [];
|
|
33
|
+
for (let i = 0; i < execArgv.length; i++) {
|
|
34
|
+
const arg = execArgv[i];
|
|
35
|
+
const eq = arg.indexOf('=');
|
|
36
|
+
const flag = eq >= 0 ? arg.slice(0, eq) : arg;
|
|
37
|
+
if (FORWARD_FLAGS_WITH_VALUE.has(flag)) {
|
|
38
|
+
out.push(arg);
|
|
39
|
+
if (eq < 0 && i + 1 < execArgv.length)
|
|
40
|
+
out.push(execArgv[++i]);
|
|
41
|
+
}
|
|
42
|
+
else if (FORWARD_FLAGS_BOOLEAN.has(flag)) {
|
|
43
|
+
out.push(arg);
|
|
44
|
+
}
|
|
45
|
+
// Everything else (--test, --watch, --test-*, …) is dropped.
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
export function resolveKernelEntry() {
|
|
50
|
+
const js = fileURLToPath(new URL('./kernel-entry.js', import.meta.url));
|
|
51
|
+
if (existsSync(js))
|
|
52
|
+
return js;
|
|
53
|
+
return fileURLToPath(new URL('./kernel-entry.ts', import.meta.url));
|
|
54
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const NAMESPACE_SCHEMA_VERSION = 1;
|
|
2
|
+
export interface SkippedKey {
|
|
3
|
+
key: string;
|
|
4
|
+
ctor: string | null;
|
|
5
|
+
reason: string;
|
|
6
|
+
}
|
|
7
|
+
export interface NamespaceEnvelope {
|
|
8
|
+
schema_version: number;
|
|
9
|
+
snapshot_b64: string;
|
|
10
|
+
skipped: SkippedKey[];
|
|
11
|
+
ts: string;
|
|
12
|
+
}
|
|
13
|
+
export interface EncodeResult {
|
|
14
|
+
envelope: NamespaceEnvelope;
|
|
15
|
+
skipped: SkippedKey[];
|
|
16
|
+
}
|
|
17
|
+
export interface DecodeResult {
|
|
18
|
+
values: Record<string, unknown>;
|
|
19
|
+
skipped: SkippedKey[];
|
|
20
|
+
}
|
|
21
|
+
export declare function encodeNamespace(values: Record<string, unknown>, now: () => number): EncodeResult;
|
|
22
|
+
export declare function decodeNamespace(json: string): DecodeResult;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { serialize, deserialize } from 'node:v8';
|
|
2
|
+
export const NAMESPACE_SCHEMA_VERSION = 1;
|
|
3
|
+
function ctorName(value) {
|
|
4
|
+
if (value === null || value === undefined)
|
|
5
|
+
return null;
|
|
6
|
+
const c = value.constructor;
|
|
7
|
+
return c?.name ?? null;
|
|
8
|
+
}
|
|
9
|
+
export function encodeNamespace(values, now) {
|
|
10
|
+
const survivors = {};
|
|
11
|
+
const skipped = [];
|
|
12
|
+
for (const key of Object.keys(values)) {
|
|
13
|
+
const value = values[key];
|
|
14
|
+
try {
|
|
15
|
+
// Probe by serializing a single-key wrapper. Cheaper than per-key buffers
|
|
16
|
+
// because the survivors map is re-serialized once below.
|
|
17
|
+
serialize({ [key]: value });
|
|
18
|
+
survivors[key] = value;
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
skipped.push({
|
|
22
|
+
key,
|
|
23
|
+
ctor: ctorName(value),
|
|
24
|
+
reason: err.message,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
let snapshot_b64;
|
|
29
|
+
try {
|
|
30
|
+
snapshot_b64 = serialize(survivors).toString('base64');
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
// A value passed the per-key probe but threw on bulk serialize (e.g. a getter
|
|
34
|
+
// that throws on its second invocation). Demote every survivor to skipped so
|
|
35
|
+
// the caller still gets a usable envelope; the snapshot for this round is empty.
|
|
36
|
+
const reason = `bulk-serialize-failed: ${err.message}`;
|
|
37
|
+
for (const key of Object.keys(survivors)) {
|
|
38
|
+
skipped.push({ key, ctor: ctorName(survivors[key]), reason });
|
|
39
|
+
}
|
|
40
|
+
snapshot_b64 = serialize({}).toString('base64');
|
|
41
|
+
}
|
|
42
|
+
const envelope = {
|
|
43
|
+
schema_version: NAMESPACE_SCHEMA_VERSION,
|
|
44
|
+
snapshot_b64,
|
|
45
|
+
skipped,
|
|
46
|
+
ts: new Date(now()).toISOString(),
|
|
47
|
+
};
|
|
48
|
+
return { envelope, skipped };
|
|
49
|
+
}
|
|
50
|
+
export function decodeNamespace(json) {
|
|
51
|
+
const parsed = JSON.parse(json);
|
|
52
|
+
if (parsed.schema_version !== NAMESPACE_SCHEMA_VERSION) {
|
|
53
|
+
throw new Error(`namespace-codec: unsupported schema_version ${String(parsed.schema_version)} (expected ${NAMESPACE_SCHEMA_VERSION})`);
|
|
54
|
+
}
|
|
55
|
+
if (typeof parsed.snapshot_b64 !== 'string') {
|
|
56
|
+
throw new Error('namespace-codec: missing snapshot_b64');
|
|
57
|
+
}
|
|
58
|
+
const buf = Buffer.from(parsed.snapshot_b64, 'base64');
|
|
59
|
+
const values = deserialize(buf);
|
|
60
|
+
return { values, skipped: Array.isArray(parsed.skipped) ? parsed.skipped : [] };
|
|
61
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface LockInfo {
|
|
2
|
+
pid: number;
|
|
3
|
+
host: string;
|
|
4
|
+
acquired_at: string;
|
|
5
|
+
takeover_from?: {
|
|
6
|
+
pid: number;
|
|
7
|
+
host: string;
|
|
8
|
+
reason: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export interface AcquireOptions {
|
|
12
|
+
forceTakeover?: boolean;
|
|
13
|
+
takeoverReason?: string;
|
|
14
|
+
now?: () => number;
|
|
15
|
+
}
|
|
16
|
+
export declare class ScratchpadBusyError extends Error {
|
|
17
|
+
readonly scratchpadName: string;
|
|
18
|
+
readonly holder: LockInfo;
|
|
19
|
+
constructor(scratchpadName: string, holder: LockInfo);
|
|
20
|
+
}
|
|
21
|
+
export declare function readLock(dir: string): LockInfo | null;
|
|
22
|
+
export declare function isStaleLock(holder: LockInfo): boolean;
|
|
23
|
+
export declare function acquireLock(dir: string, options?: AcquireOptions): LockInfo;
|
|
24
|
+
export declare function releaseLock(dir: string): void;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { basename, join } from 'node:path';
|
|
3
|
+
import { hostname } from 'node:os';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
export class ScratchpadBusyError extends Error {
|
|
6
|
+
scratchpadName;
|
|
7
|
+
holder;
|
|
8
|
+
constructor(scratchpadName, holder) {
|
|
9
|
+
super(`scratchpad ${scratchpadName} is busy in another session`);
|
|
10
|
+
this.name = 'ScratchpadBusyError';
|
|
11
|
+
this.scratchpadName = scratchpadName;
|
|
12
|
+
this.holder = holder;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function lockPath(dir) {
|
|
16
|
+
return join(dir, 'lock.json');
|
|
17
|
+
}
|
|
18
|
+
export function readLock(dir) {
|
|
19
|
+
const path = lockPath(dir);
|
|
20
|
+
if (!existsSync(path))
|
|
21
|
+
return null;
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null; // corrupt lock is treated as absent (clearable on acquire)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function holderIsAlive(holder) {
|
|
30
|
+
if (holder.host !== hostname())
|
|
31
|
+
return true; // can't verify a remote PID -> assume alive
|
|
32
|
+
try {
|
|
33
|
+
process.kill(holder.pid, 0);
|
|
34
|
+
return true; // exists and signalable
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
return err.code !== 'ESRCH'; // ESRCH = no such process (dead); EPERM etc. = alive
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function isStaleLock(holder) {
|
|
41
|
+
return !holderIsAlive(holder);
|
|
42
|
+
}
|
|
43
|
+
export function acquireLock(dir, options = {}) {
|
|
44
|
+
const now = options.now ?? Date.now;
|
|
45
|
+
mkdirSync(dir, { recursive: true });
|
|
46
|
+
const path = lockPath(dir);
|
|
47
|
+
const self = { pid: process.pid, host: hostname(), acquired_at: new Date(now()).toISOString() };
|
|
48
|
+
try {
|
|
49
|
+
writeFileSync(path, JSON.stringify(self), { flag: 'wx' });
|
|
50
|
+
return self; // won the atomic create
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
if (err.code !== 'EEXIST')
|
|
54
|
+
throw err;
|
|
55
|
+
}
|
|
56
|
+
const holder = readLock(dir);
|
|
57
|
+
if (holder === null || !holderIsAlive(holder)) {
|
|
58
|
+
// corrupt or stale -> clear and retake
|
|
59
|
+
unlinkSync(path);
|
|
60
|
+
writeFileSync(path, JSON.stringify(self), { flag: 'wx' });
|
|
61
|
+
return self;
|
|
62
|
+
}
|
|
63
|
+
if (options.forceTakeover) {
|
|
64
|
+
const taken = {
|
|
65
|
+
...self,
|
|
66
|
+
takeover_from: { pid: holder.pid, host: holder.host, reason: options.takeoverReason ?? 'force-takeover' },
|
|
67
|
+
};
|
|
68
|
+
writeFileSync(path, JSON.stringify(taken)); // overwrite the live holder
|
|
69
|
+
return taken;
|
|
70
|
+
}
|
|
71
|
+
throw new ScratchpadBusyError(basename(dir), holder);
|
|
72
|
+
}
|
|
73
|
+
export function releaseLock(dir) {
|
|
74
|
+
const holder = readLock(dir);
|
|
75
|
+
if (holder === null)
|
|
76
|
+
return;
|
|
77
|
+
if (holder.pid === process.pid && holder.host === hostname()) {
|
|
78
|
+
try {
|
|
79
|
+
unlinkSync(lockPath(dir));
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// already gone
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// not ours (e.g. taken over) -> leave it
|
|
86
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import type { CredentialInjector } from '@otto/coworker-vault';
|
|
2
|
+
import type { AuditLog } from '@otto/coworker-utils';
|
|
3
|
+
import type { ArtifactStore } from '@otto/coworker-artifacts';
|
|
4
|
+
import { ChildProcessRuntime, type ChildProcessRuntimeOptions } from './child-process-runtime.js';
|
|
5
|
+
import { type LockInfo } from './scratchpad-lock.js';
|
|
6
|
+
import { CellArchive } from './cell-archive.js';
|
|
7
|
+
import type { ArtifactCreateDrawer, DataLoadDrawer } from './kernel-protocol.js';
|
|
8
|
+
export declare class ForkKernelHangError extends Error {
|
|
9
|
+
readonly srcName: string;
|
|
10
|
+
readonly pid: number;
|
|
11
|
+
constructor(srcName: string, pid: number);
|
|
12
|
+
}
|
|
13
|
+
export interface ScratchpadManagerOptions {
|
|
14
|
+
workspace: string;
|
|
15
|
+
root?: string;
|
|
16
|
+
maxLiveKernels?: number;
|
|
17
|
+
idleMs?: number;
|
|
18
|
+
sweepIntervalMs?: number;
|
|
19
|
+
now?: () => number;
|
|
20
|
+
runtimeOptions?: Omit<ChildProcessRuntimeOptions, 'workspace'>;
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
forkExitTimeoutMs?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Phase 2 Task 13: optional vault credential injector. When provided, each
|
|
25
|
+
* spawned ChildProcessRuntime receives the injector + the scratchpad's
|
|
26
|
+
* meta.bindings list. Absent => runtime spawns with no OTTO_DS_* env vars.
|
|
27
|
+
*/
|
|
28
|
+
injector?: CredentialInjector;
|
|
29
|
+
/**
|
|
30
|
+
* Phase 2 Task 14: optional audit sink for SecretScanner redactions on
|
|
31
|
+
* cell-output journal writes. When provided, every cell run's stdout is
|
|
32
|
+
* scanned BEFORE archive.append and emits one `producer: 'secret-scanner'`
|
|
33
|
+
* record per hit. Absent => redaction is a no-op (backward compat).
|
|
34
|
+
*
|
|
35
|
+
* Wiring contract: the caller is expected to pass the SAME AuditLog instance
|
|
36
|
+
* held by the CredentialInjector so secret-scanner records appear alongside
|
|
37
|
+
* vault inject/inject-skipped records in a single audit stream.
|
|
38
|
+
*/
|
|
39
|
+
audit?: AuditLog;
|
|
40
|
+
/**
|
|
41
|
+
* Phase 3 Task 19: cross-pillar hook for the memory pillar's MemoryRecorder.
|
|
42
|
+
* Invoked once per `otto.collectors.open(...).load()` call inside a cell,
|
|
43
|
+
* with the kernel's `DataLoadDrawer` and the scratchpad name that produced it.
|
|
44
|
+
* The manager fans this through every spawn of every scratchpad (the callback
|
|
45
|
+
* is closure-bound to the name at spawn time, so multi-scratchpad sessions
|
|
46
|
+
* route loads to the correct room). Absent => data_load events are dropped.
|
|
47
|
+
*/
|
|
48
|
+
onDataLoad?: (drawer: DataLoadDrawer, scratchpadName: string) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Phase 4 Task 10: cross-pillar hook for the memory pillar's MemoryRecorder.
|
|
51
|
+
* Invoked once per `otto.artifact.create(...)` call inside a cell, with the
|
|
52
|
+
* kernel's `ArtifactCreateDrawer` and the scratchpad name that produced it.
|
|
53
|
+
* Closure-bound to the name at spawn time (same pattern as onDataLoad), so
|
|
54
|
+
* multi-scratchpad sessions route artifact events to the correct room.
|
|
55
|
+
* Absent => artifact_create events are dropped (memory stays silent).
|
|
56
|
+
*/
|
|
57
|
+
onArtifactCreate?: (drawer: ArtifactCreateDrawer, scratchpadName: string) => void;
|
|
58
|
+
/**
|
|
59
|
+
* Phase 4 Task 10: lazy accessor for the ArtifactStore. The manager calls
|
|
60
|
+
* this each time it services an artifact RPC so the resolution sees the
|
|
61
|
+
* current extension activation state (callers can flip the store on/off as
|
|
62
|
+
* the artifacts extension activates/deactivates). When this returns null the
|
|
63
|
+
* RPC fails fast with "artifacts unavailable" — the kernel surfaces the
|
|
64
|
+
* error to the cell. Absent => RPC always fails (no artifact store wired).
|
|
65
|
+
*/
|
|
66
|
+
getArtifactStore?: () => ArtifactStore | null;
|
|
67
|
+
}
|
|
68
|
+
export interface AttachOptions {
|
|
69
|
+
forceTakeover?: boolean;
|
|
70
|
+
takeoverReason?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Phase 2 Task 12: optional list of binding ids (e.g. ['jira:prod']) to record
|
|
73
|
+
* in meta.json on first create. Subsequent meta writes preserve whatever's on
|
|
74
|
+
* disk via prevExtras — once persisted, bindings survive every other meta-write
|
|
75
|
+
* path. Ignored on re-attach if meta.json already has a bindings field.
|
|
76
|
+
*/
|
|
77
|
+
bindings?: string[];
|
|
78
|
+
}
|
|
79
|
+
export interface ScratchpadInfo {
|
|
80
|
+
name: string;
|
|
81
|
+
live: boolean;
|
|
82
|
+
lastUsedAt: number;
|
|
83
|
+
hasActiveCell: boolean;
|
|
84
|
+
}
|
|
85
|
+
interface Entry {
|
|
86
|
+
runtime: ChildProcessRuntime | null;
|
|
87
|
+
lock: LockInfo;
|
|
88
|
+
lastUsedAt: number;
|
|
89
|
+
archive: CellArchive;
|
|
90
|
+
kernelAtCellId: number | null;
|
|
91
|
+
}
|
|
92
|
+
export declare class ScratchpadManager {
|
|
93
|
+
protected readonly entries: Map<string, Entry>;
|
|
94
|
+
protected readonly workspace: string;
|
|
95
|
+
protected readonly root: string;
|
|
96
|
+
protected readonly maxLive: number;
|
|
97
|
+
protected readonly idleMs: number;
|
|
98
|
+
protected readonly sessionId: string | undefined;
|
|
99
|
+
protected readonly now: () => number;
|
|
100
|
+
protected readonly runtimeOptions: Omit<ChildProcessRuntimeOptions, 'workspace'>;
|
|
101
|
+
protected readonly forkExitTimeoutMs: number;
|
|
102
|
+
protected readonly injector: CredentialInjector | undefined;
|
|
103
|
+
protected readonly audit: AuditLog | undefined;
|
|
104
|
+
protected readonly onDataLoad: ((drawer: DataLoadDrawer, scratchpadName: string) => void) | undefined;
|
|
105
|
+
protected readonly onArtifactCreate: ((drawer: ArtifactCreateDrawer, scratchpadName: string) => void) | undefined;
|
|
106
|
+
protected readonly getArtifactStore: (() => ArtifactStore | null) | undefined;
|
|
107
|
+
protected disposed: boolean;
|
|
108
|
+
private sweepTimer;
|
|
109
|
+
constructor(options: ScratchpadManagerOptions);
|
|
110
|
+
protected dirFor(name: string): string;
|
|
111
|
+
private metaPath;
|
|
112
|
+
private existsOnDisk;
|
|
113
|
+
private payloadSize;
|
|
114
|
+
private writeMetaAtomic;
|
|
115
|
+
private writeMeta;
|
|
116
|
+
private appendRecoveryNotes;
|
|
117
|
+
private applySnapshotToMeta;
|
|
118
|
+
private snapshotThenDispose;
|
|
119
|
+
private ingestRecoveryNotesOnAttach;
|
|
120
|
+
private restoreLeafOnAttach;
|
|
121
|
+
private restoreKernelAtCellIdOnAttach;
|
|
122
|
+
private warmCount;
|
|
123
|
+
/**
|
|
124
|
+
* Phase 2 Task 13: read meta.bindings from disk so each fresh spawn picks up
|
|
125
|
+
* the current binding set (bindings can change between attaches via /sp use).
|
|
126
|
+
* Returns [] if meta.json doesn't exist or doesn't have a v4 bindings array.
|
|
127
|
+
*
|
|
128
|
+
* Phase 2 Task 16: also surfaced as a public read for /sp list rendering and
|
|
129
|
+
* staleness-banner emission. Stays a thin read; callers that need to mutate
|
|
130
|
+
* use addBinding / removeBinding (which atomically RMW meta.json).
|
|
131
|
+
*/
|
|
132
|
+
readBindings(name: string): string[];
|
|
133
|
+
/**
|
|
134
|
+
* Phase 2 Task 16: append a binding ref (e.g. 'jira:prod') to meta.bindings.
|
|
135
|
+
* Idempotent — adding a ref already in the list is a no-op (the meta.json
|
|
136
|
+
* write still happens so callers can detect "added" vs "noop" only via the
|
|
137
|
+
* returned tuple). Atomically rewrites meta.json via writeMetaAtomic, so
|
|
138
|
+
* concurrent writers cannot interleave. Caller is responsible for validating
|
|
139
|
+
* `ref` (sp-command uses LocalDataVault.parseRef before invoking).
|
|
140
|
+
*/
|
|
141
|
+
addBinding(name: string, ref: string): Promise<{
|
|
142
|
+
added: boolean;
|
|
143
|
+
}>;
|
|
144
|
+
/**
|
|
145
|
+
* Phase 2 Task 16: remove a binding ref from meta.bindings. Returns whether
|
|
146
|
+
* a removal happened so callers can emit "no such binding" if needed.
|
|
147
|
+
*/
|
|
148
|
+
removeBinding(name: string, ref: string): Promise<{
|
|
149
|
+
removed: boolean;
|
|
150
|
+
}>;
|
|
151
|
+
private spawnRuntime;
|
|
152
|
+
private evictLruIfNeeded;
|
|
153
|
+
create(name: string, opts?: AttachOptions): Promise<ChildProcessRuntime>;
|
|
154
|
+
getOrAttach(name: string, opts?: AttachOptions): Promise<ChildProcessRuntime>;
|
|
155
|
+
runCell(name: string, code: string, opts?: AttachOptions): Promise<{
|
|
156
|
+
value: unknown;
|
|
157
|
+
stdout: string;
|
|
158
|
+
}>;
|
|
159
|
+
/**
|
|
160
|
+
* Phase 2 Task 14: redact known-secret patterns from a cell-output string
|
|
161
|
+
* before journaling. No-op (pass-through) when no AuditLog is configured —
|
|
162
|
+
* the manager was constructed in test/legacy mode without vault wiring.
|
|
163
|
+
*/
|
|
164
|
+
private redactStdout;
|
|
165
|
+
/**
|
|
166
|
+
* Task D: Release a warm kernel's process+memory while preserving on-disk state
|
|
167
|
+
* (kernel.db, namespace.json, cells.jsonl, meta.json, lock.json). Cold-restart
|
|
168
|
+
* happens on the next attach.
|
|
169
|
+
*
|
|
170
|
+
* Without --force: refuses if a cell is mid-execution. With --force: cancels the
|
|
171
|
+
* active cell via runtime.cancel() (SIGINT → SIGTERM → SIGKILL escalation handled
|
|
172
|
+
* internally by ChildProcessRuntime). Post-cancel the kernel is dead, so we skip
|
|
173
|
+
* the snapshot — the next attach replays from cells.jsonl.
|
|
174
|
+
*/
|
|
175
|
+
evict(name: string, opts?: {
|
|
176
|
+
force?: boolean;
|
|
177
|
+
}): Promise<{
|
|
178
|
+
interrupted: boolean;
|
|
179
|
+
}>;
|
|
180
|
+
setLeaf(name: string, id: number): Promise<void>;
|
|
181
|
+
fork(srcName: string, dstName: string): Promise<void>;
|
|
182
|
+
clearHistory(name: string): Promise<void>;
|
|
183
|
+
save(name: string): Promise<void>;
|
|
184
|
+
detach(name: string, sessionId: string): Promise<void>;
|
|
185
|
+
markRecoveryNotesSeen(name: string): Promise<void>;
|
|
186
|
+
private attachUnmanaged;
|
|
187
|
+
list(): ScratchpadInfo[];
|
|
188
|
+
remove(name: string): Promise<void>;
|
|
189
|
+
evictIdle(): Promise<void>;
|
|
190
|
+
disposeAll(): Promise<void>;
|
|
191
|
+
protected assertNotDisposed(): void;
|
|
192
|
+
}
|
|
193
|
+
export {};
|