@selesai/code 0.13.39 → 0.14.0
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/CHANGELOG.md +3 -0
- package/dist/bun/runtime-setup.js +4 -1
- package/dist/cli/args.d.ts +3 -1
- package/dist/cli/args.js +76 -33
- package/dist/cli/auth-check.d.ts +18 -0
- package/dist/cli/auth-check.js +49 -0
- package/dist/cli/credential-print.d.ts +5 -15
- package/dist/cli/credential-print.js +42 -82
- package/dist/cli/file-processor.d.ts +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/list-models.d.ts +1 -1
- package/dist/cli/list-models.js +2 -2
- package/dist/cli/startup-ui.js +38 -30
- package/dist/config.d.ts +35 -6
- package/dist/config.js +95 -17
- package/dist/core/agent-session-custom-tools.test.js +64 -0
- package/dist/core/agent-session-length-continuation.test.js +7 -3
- package/dist/core/agent-session-runtime.js +2 -2
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.js +14 -0
- package/dist/core/agent-session.d.ts +180 -40
- package/dist/core/agent-session.js +1061 -485
- package/dist/core/auth-storage.d.ts +25 -15
- package/dist/core/auth-storage.js +242 -66
- package/dist/core/bash-executor.js +42 -52
- package/dist/core/bug-report.js +1 -1
- package/dist/core/cache-warmer.d.ts +1 -0
- package/dist/core/cache-warmer.js +15 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/compaction.d.ts +3 -1
- package/dist/core/compaction/compaction.js +156 -79
- package/dist/core/compaction/utils.d.ts +2 -1
- package/dist/core/compaction/utils.js +25 -18
- package/dist/core/crash-log.d.ts +5 -0
- package/dist/core/crash-log.js +69 -0
- package/dist/core/defaults.d.ts +1 -1
- package/dist/core/defaults.js +1 -1
- package/dist/core/export-html/template.css +10 -0
- package/dist/core/export-html/template.js +72 -18
- package/dist/core/export-html/tool-renderer.d.ts +3 -3
- package/dist/core/export-html/tool-renderer.js +5 -3
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/loader.js +138 -55
- package/dist/core/extensions/runner.d.ts +38 -5
- package/dist/core/extensions/runner.js +220 -7
- package/dist/core/extensions/types.d.ts +438 -51
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/virtual-modules.js +6 -0
- package/dist/core/extensions/wrapper.d.ts +2 -2
- package/dist/core/extensions/wrapper.js +3 -3
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/handoff.d.ts +0 -1
- package/dist/core/handoff.js +0 -1
- package/dist/core/http-dispatcher.js +5 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/intercom-rpc.d.ts +135 -0
- package/dist/core/intercom-rpc.js +64 -0
- package/dist/core/keybindings.d.ts +25 -24
- package/dist/core/keybindings.js +27 -6
- package/dist/core/mcp-servers.d.ts +134 -0
- package/dist/core/mcp-servers.js +223 -0
- package/dist/core/model-config.d.ts +122 -5
- package/dist/core/model-config.js +35 -1
- package/dist/core/model-registry.d.ts +23 -15
- package/dist/core/model-registry.js +46 -22
- package/dist/core/model-resolver.d.ts +6 -5
- package/dist/core/model-resolver.js +51 -21
- package/dist/core/model-runtime.d.ts +73 -14
- package/dist/core/model-runtime.js +398 -104
- package/dist/core/models-store.d.ts +12 -7
- package/dist/core/models-store.js +85 -15
- package/dist/core/nested-tool-calls.d.ts +102 -0
- package/dist/core/nested-tool-calls.js +178 -0
- package/dist/core/package-manager.d.ts +8 -1
- package/dist/core/package-manager.js +144 -61
- package/dist/core/package-manager.test.js +5 -5
- package/dist/core/pi-manifest.d.ts +9 -0
- package/dist/core/pi-manifest.js +25 -0
- package/dist/core/prompt-templates.d.ts +6 -1
- package/dist/core/prompt-templates.js +61 -35
- package/dist/core/provider-composer.d.ts +44 -19
- package/dist/core/provider-composer.js +166 -64
- package/dist/core/radius.d.ts +2 -0
- package/dist/core/radius.js +2 -0
- package/dist/core/release-rpc.d.ts +137 -0
- package/dist/core/release-rpc.js +77 -0
- package/dist/core/remote-catalog-provider.d.ts +8 -1
- package/dist/core/remote-catalog-provider.js +25 -13
- package/dist/core/resource-loader.d.ts +12 -1
- package/dist/core/resource-loader.js +180 -45
- package/dist/core/runtime-credentials.d.ts +5 -5
- package/dist/core/runtime-credentials.js +11 -8
- package/dist/core/sdk.d.ts +16 -7
- package/dist/core/sdk.js +57 -24
- package/dist/core/session-manager.d.ts +45 -9
- package/dist/core/session-manager.js +124 -31
- package/dist/core/settings-diagnostics.d.ts +8 -0
- package/dist/core/settings-diagnostics.js +20 -0
- package/dist/core/settings-manager.d.ts +62 -32
- package/dist/core/settings-manager.js +147 -69
- package/dist/core/skills.d.ts +5 -2
- package/dist/core/skills.js +58 -35
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/source-info.d.ts +8 -0
- package/dist/core/source-info.js +16 -0
- package/dist/core/subagent-rpc.d.ts +110 -0
- package/dist/core/subagent-rpc.js +60 -0
- package/dist/core/system-prompt.d.ts +9 -3
- package/dist/core/system-prompt.js +9 -12
- package/dist/core/system-prompt.test.js +2 -7
- package/dist/core/tools/bash.d.ts +12 -0
- package/dist/core/tools/bash.js +33 -2
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit.d.ts +4 -0
- package/dist/core/tools/edit.js +31 -11
- package/dist/core/tools/find.d.ts +7 -0
- package/dist/core/tools/find.js +16 -19
- package/dist/core/tools/grep.d.ts +4 -0
- package/dist/core/tools/grep.js +5 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.js +11 -2
- package/dist/core/tools/ls.d.ts +4 -0
- package/dist/core/tools/ls.js +5 -1
- package/dist/core/tools/output-accumulator.d.ts +11 -0
- package/dist/core/tools/output-accumulator.js +40 -10
- package/dist/core/tools/read.d.ts +17 -2
- package/dist/core/tools/read.js +23 -2
- package/dist/core/tools/render-utils.d.ts +6 -0
- package/dist/core/tools/render-utils.js +26 -0
- package/dist/core/tools/renderers/bash.js +19 -35
- package/dist/core/tools/renderers/edit.js +5 -4
- package/dist/core/tools/renderers/index.d.ts +2 -2
- package/dist/core/tools/renderers/read.js +3 -2
- package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
- package/dist/core/tools/tool-definition-wrapper.js +3 -1
- package/dist/core/tools/truncate.d.ts +14 -0
- package/dist/core/tools/truncate.js +29 -0
- package/dist/core/tools/write.d.ts +4 -0
- package/dist/core/tools/write.js +6 -2
- package/dist/core/trust-manager.js +3 -1
- package/dist/core/usage-totals.d.ts +2 -0
- package/dist/core/usage-totals.js +23 -0
- package/dist/core/virtual-models.d.ts +116 -0
- package/dist/core/virtual-models.js +123 -0
- package/dist/defaults/models.json +32 -0
- package/dist/defaults/settings.json +1 -9
- package/dist/extensions/agent-browser.ts +9 -0
- package/dist/extensions/codemode/execute.d.ts +15 -0
- package/dist/extensions/codemode/execute.js +633 -0
- package/dist/extensions/codemode/execute.lazy.d.ts +2 -0
- package/dist/extensions/codemode/execute.lazy.js +2 -0
- package/dist/extensions/codemode/index.d.ts +20 -0
- package/dist/extensions/codemode/index.js +31 -0
- package/dist/extensions/codemode/renderer.d.ts +11 -0
- package/dist/extensions/codemode/renderer.js +136 -0
- package/dist/extensions/codemode/tool.d.ts +129 -0
- package/dist/extensions/codemode/tool.js +275 -0
- package/dist/extensions/context-compaction-reminder.ts +1 -1
- package/dist/extensions/grep-app/index.ts +2 -10
- package/dist/extensions/herdr-agent-state.ts +1 -1
- package/dist/extensions/{pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts → index.d.ts} +0 -1
- package/dist/extensions/index.js +12 -0
- package/dist/extensions/jev/classifier-context.ts +54 -0
- package/dist/extensions/jev/classifier.test.ts +85 -0
- package/dist/extensions/jev/classifier.ts +105 -0
- package/dist/extensions/jev/decisions.test.ts +35 -47
- package/dist/extensions/jev/decisions.ts +58 -104
- package/dist/extensions/jev/test-support.ts +33 -38
- package/dist/extensions/jev-advisory-lifecycle.test.ts +12 -12
- package/dist/extensions/jev-advisory-memory.test.ts +9 -9
- package/dist/extensions/jev-advisory-recommendations.test.ts +8 -8
- package/dist/extensions/jev-ask-tool.test.ts +41 -45
- package/dist/extensions/jev-ask-tool.ts +10 -38
- package/dist/extensions/jev-find-source.test.ts +26 -0
- package/dist/extensions/jev-find-source.ts +58 -19
- package/dist/{core → extensions}/llama/client.d.ts +2 -0
- package/dist/{core → extensions}/llama/client.js +7 -3
- package/dist/{core → extensions}/llama/index.js +13 -2
- package/dist/{core → extensions}/llama/provider.d.ts +1 -1
- package/dist/extensions/llama/provider.js +235 -0
- package/dist/extensions/mcp/cli.d.ts +20 -0
- package/dist/extensions/mcp/cli.js +496 -0
- package/dist/extensions/mcp/cli.lazy.d.ts +2 -0
- package/dist/extensions/mcp/cli.lazy.js +2 -0
- package/dist/extensions/mcp/config.d.ts +83 -0
- package/dist/extensions/mcp/config.js +193 -0
- package/dist/extensions/mcp/index.d.ts +78 -0
- package/dist/extensions/mcp/index.js +1201 -0
- package/dist/extensions/mcp/log.d.ts +15 -0
- package/dist/extensions/mcp/log.js +65 -0
- package/dist/extensions/mcp/oauth.d.ts +97 -0
- package/dist/extensions/mcp/oauth.js +401 -0
- package/dist/extensions/mcp/resources.d.ts +41 -0
- package/dist/extensions/mcp/resources.js +260 -0
- package/dist/extensions/mcp/runtime.d.ts +96 -0
- package/dist/extensions/mcp/runtime.js +412 -0
- package/dist/extensions/mcp/runtime.lazy.d.ts +2 -0
- package/dist/extensions/mcp/runtime.lazy.js +2 -0
- package/dist/extensions/mcp/tools.d.ts +86 -0
- package/dist/extensions/mcp/tools.js +252 -0
- package/dist/extensions/mcp/ui.d.ts +59 -0
- package/dist/extensions/mcp/ui.js +185 -0
- package/dist/extensions/package.json +1 -1
- package/dist/extensions/pi-graft/tools.ts +6 -0
- package/dist/extensions/pi-hermes-memory/CHANGELOG.md +25 -0
- package/dist/extensions/pi-hermes-memory/README.md +140 -4
- package/dist/extensions/pi-hermes-memory/package-lock.json +624 -2720
- package/dist/extensions/pi-hermes-memory/package.json +9 -7
- package/dist/extensions/pi-hermes-memory/scripts/benchmark-memory-startup.mjs +72 -0
- package/dist/extensions/pi-hermes-memory/scripts/check-production-install.mjs +107 -0
- package/dist/extensions/pi-hermes-memory/src/auto-consolidation-warning.ts +2 -1
- package/dist/extensions/pi-hermes-memory/src/config.ts +35 -0
- package/dist/extensions/pi-hermes-memory/src/constants.ts +62 -15
- package/dist/extensions/pi-hermes-memory/src/handlers/auto-consolidate.ts +374 -50
- package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +7 -4
- package/dist/extensions/pi-hermes-memory/src/handlers/correction-detector.ts +19 -14
- package/dist/extensions/pi-hermes-memory/src/handlers/insights.ts +75 -1
- package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +322 -22
- package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +8 -0
- package/dist/extensions/pi-hermes-memory/src/handlers/session-flush.ts +193 -54
- package/dist/extensions/pi-hermes-memory/src/handlers/skills-command.ts +6 -2
- package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +33 -5
- package/dist/extensions/pi-hermes-memory/src/index.ts +116 -47
- package/dist/extensions/pi-hermes-memory/src/memory-initialization.ts +101 -0
- package/dist/extensions/pi-hermes-memory/src/store/atomic-lock-coordinator.ts +10 -2
- package/dist/extensions/pi-hermes-memory/src/store/db.ts +34 -9
- package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +44 -8
- package/dist/extensions/pi-hermes-memory/src/store/schema.ts +3 -1
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +141 -0
- package/dist/extensions/pi-hermes-memory/src/store/standing-instructions.ts +17 -6
- package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +20 -10
- package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +1 -17
- package/dist/extensions/pi-hermes-memory/src/tools/session-search-tool.ts +2 -10
- package/dist/extensions/pi-hermes-memory/src/tools/skill-tool.ts +4 -8
- package/dist/extensions/pi-hermes-memory/src/types.ts +48 -0
- package/dist/extensions/pi-hermes-memory/tests/config.test.ts +108 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/auto-consolidate.test.ts +1185 -42
- package/dist/extensions/pi-hermes-memory/tests/handlers/insights.test.ts +57 -1
- package/dist/extensions/pi-hermes-memory/tests/handlers/lazy-memory-hooks.test.ts +128 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +844 -1
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +16 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-flush.test.ts +512 -3
- package/dist/extensions/pi-hermes-memory/tests/handlers/skills-command.test.ts +38 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/sync-markdown-memories.test.ts +183 -2
- package/dist/extensions/pi-hermes-memory/tests/handlers/system-prompt.test.ts +1 -3
- package/dist/extensions/pi-hermes-memory/tests/index.test.ts +17 -0
- package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +21 -0
- package/dist/extensions/pi-hermes-memory/tests/lazy-startup.test.ts +313 -0
- package/dist/extensions/pi-hermes-memory/tests/memory-initialization.test.ts +182 -0
- package/dist/extensions/pi-hermes-memory/tests/prompt-injection.test.ts +184 -0
- package/dist/extensions/pi-hermes-memory/tests/skill-discovery-contract.test.ts +60 -0
- package/dist/extensions/pi-hermes-memory/tests/store/atomic-lock-lazy-probe.test.ts +80 -0
- package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +2 -0
- package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +79 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +268 -0
- package/dist/extensions/pi-hermes-memory/tests/store/standing-instructions.test.ts +29 -0
- package/dist/extensions/pi-hermes-memory/tests/store/usage-tracking.test.ts +170 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +80 -1
- package/dist/extensions/pi-hermes-memory/tests/tools/skill-tool.test.ts +51 -0
- package/dist/extensions/pi-intercom/CHANGELOG.md +66 -0
- package/dist/extensions/pi-intercom/README.md +115 -12
- package/dist/extensions/pi-intercom/broker/broker.ts +304 -24
- package/dist/extensions/pi-intercom/broker/client.ts +9 -2
- package/dist/extensions/pi-intercom/broker/cross-machine-provenance.test.ts +63 -0
- package/dist/extensions/pi-intercom/broker/mailbox-persistence.test.ts +523 -0
- package/dist/extensions/pi-intercom/broker/paths.test.ts +4 -4
- package/dist/extensions/pi-intercom/broker/paths.ts +4 -2
- package/dist/extensions/pi-intercom/broker/protocol.ts +64 -0
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +58 -169
- package/dist/extensions/pi-intercom/broker/spawn.ts +40 -87
- package/dist/extensions/pi-intercom/cli.mjs +6 -0
- package/dist/extensions/pi-intercom/cli.test.ts +428 -0
- package/dist/extensions/pi-intercom/cli.ts +343 -0
- package/dist/extensions/pi-intercom/config.test.ts +61 -1
- package/dist/extensions/pi-intercom/config.ts +53 -2
- package/dist/extensions/pi-intercom/cross-machine-discovery.test.ts +218 -0
- package/dist/extensions/pi-intercom/cross-machine-discovery.ts +140 -0
- package/dist/extensions/pi-intercom/cross-machine-envelope.test.ts +106 -0
- package/dist/extensions/pi-intercom/cross-machine-envelope.ts +92 -0
- package/dist/extensions/pi-intercom/cross-machine-integration.test.ts +25 -0
- package/dist/extensions/pi-intercom/cross-machine-transport.test.ts +106 -0
- package/dist/extensions/pi-intercom/cross-machine-transport.ts +110 -0
- package/dist/extensions/pi-intercom/extension-api.ts +24 -0
- package/dist/extensions/pi-intercom/handover.test.ts +88 -0
- package/dist/extensions/pi-intercom/handover.ts +115 -0
- package/dist/extensions/pi-intercom/herdr-location.test.ts +173 -0
- package/dist/extensions/pi-intercom/herdr-location.ts +137 -0
- package/dist/extensions/pi-intercom/human-priority.pi.test.ts +489 -0
- package/dist/extensions/pi-intercom/index.ts +770 -172
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +869 -21
- package/dist/extensions/pi-intercom/package.json +12 -2
- package/dist/extensions/pi-intercom/project-agent.ts +1 -1
- package/dist/extensions/pi-intercom/release-readiness.test.ts +116 -0
- package/dist/extensions/pi-intercom/release-readiness.ts +93 -0
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +26 -2
- package/dist/extensions/pi-intercom/test/handover-picker.test.ts +134 -0
- package/dist/extensions/pi-intercom/test/inline-message.test.ts +43 -0
- package/dist/extensions/pi-intercom/types.d.ts +247 -0
- package/dist/extensions/pi-intercom/types.js +2 -0
- package/dist/extensions/pi-intercom/types.ts +39 -1
- package/dist/extensions/pi-intercom/ui/handover-picker.ts +318 -0
- package/dist/extensions/pi-intercom/ui/inline-message.ts +10 -3
- package/dist/extensions/pi-intercom/ui/session-list.ts +28 -15
- package/dist/extensions/pi-subagents/.github/workflows/release.yml +5 -1
- package/dist/extensions/pi-subagents/.github/workflows/test.yml +188 -18
- package/dist/extensions/pi-subagents/CHANGELOG.md +514 -1
- package/dist/extensions/pi-subagents/README.md +7 -5
- package/dist/extensions/pi-subagents/VISION.md +6 -0
- package/dist/extensions/pi-subagents/agents/reviewer.md +7 -5
- package/dist/extensions/pi-subagents/agents/worker.md +1 -1
- package/dist/extensions/pi-subagents/docs/agents.md +75 -35
- package/dist/extensions/pi-subagents/docs/configuration.md +156 -25
- package/dist/extensions/pi-subagents/docs/extension-api.md +121 -29
- package/dist/extensions/pi-subagents/docs/missions.md +46 -14
- package/dist/extensions/pi-subagents/docs/models.md +22 -84
- package/dist/extensions/pi-subagents/docs/observability.md +57 -24
- package/dist/extensions/pi-subagents/docs/standalone-background.md +59 -0
- package/dist/extensions/pi-subagents/docs/tool-reference.md +167 -116
- package/dist/extensions/pi-subagents/docs/watchdog.md +41 -10
- package/dist/extensions/pi-subagents/docs/workflows.md +239 -163
- package/dist/extensions/pi-subagents/examples/typed-gate/.pi/agents/classifier.md +14 -0
- package/dist/extensions/pi-subagents/examples/typed-gate/README.md +42 -0
- package/dist/extensions/pi-subagents/examples/typed-gate/classify +38 -0
- package/dist/extensions/pi-subagents/examples/typed-gate/workflow.js +32 -0
- package/dist/extensions/pi-subagents/index.ts +11 -3
- package/dist/extensions/pi-subagents/inspector-runner.mjs +3 -3
- package/dist/extensions/pi-subagents/package-lock.json +517 -1129
- package/dist/extensions/pi-subagents/package.json +22 -11
- package/dist/extensions/pi-subagents/prompts/council.md +7 -4
- package/dist/extensions/pi-subagents/prompts/parallel-review.md +2 -2
- package/dist/extensions/pi-subagents/prompts/review-loop.md +2 -2
- package/dist/extensions/pi-subagents/runner-peer-loader.mjs +21 -0
- package/dist/extensions/pi-subagents/runner-peer-preload.mjs +30 -0
- package/dist/extensions/pi-subagents/scripts/build-package.mjs +79 -0
- package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +2 -2
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +46 -27
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +11 -7
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +78 -73
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +4 -5
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +10 -2
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +69 -67
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/review-and-validation.md +3 -3
- package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +21 -10
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +113 -113
- package/dist/extensions/pi-subagents/src/agents/agent-memory.ts +91 -4
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +15 -9
- package/dist/extensions/pi-subagents/src/agents/agents.ts +432 -193
- package/dist/extensions/pi-subagents/src/agents/chain-serializer.ts +6 -1
- package/dist/extensions/pi-subagents/src/agents/global-npm-root.ts +58 -0
- package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +5 -2
- package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +22 -18
- package/dist/extensions/pi-subagents/src/agents/skills.ts +43 -10
- package/dist/extensions/pi-subagents/src/api/delegation.ts +20 -1
- package/dist/extensions/pi-subagents/src/api/inspectors.ts +27 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +140 -62
- package/dist/extensions/pi-subagents/src/api/required-child-extensions.ts +6 -0
- package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +24 -40
- package/dist/extensions/pi-subagents/src/extension/control-notices.ts +4 -1
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +18 -15
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +87 -13
- package/dist/extensions/pi-subagents/src/extension/herdr-pi-bridge.ts +162 -0
- package/dist/extensions/pi-subagents/src/extension/index.ts +331 -269
- package/dist/extensions/pi-subagents/src/extension/observability.ts +164 -0
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +76 -37
- package/dist/extensions/pi-subagents/src/extension/release-readiness.ts +367 -0
- package/dist/extensions/pi-subagents/src/extension/reply-workflow-script.ts +67 -0
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +42 -12
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +116 -205
- package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +13 -5
- package/dist/extensions/pi-subagents/src/extension/tool-activation.ts +146 -0
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +77 -90
- package/dist/extensions/pi-subagents/src/extension/upgrade-notice.ts +40 -0
- package/dist/extensions/pi-subagents/src/inspectors/actions.ts +148 -0
- package/dist/extensions/pi-subagents/src/inspectors/ghostty/actions.ts +74 -0
- package/dist/extensions/pi-subagents/src/inspectors/ghostty/plugin.ts +29 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +100 -180
- package/dist/extensions/pi-subagents/src/inspectors/herdr/plugin.ts +20 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +2 -2
- package/dist/extensions/pi-subagents/src/inspectors/{herdr/inspector-runner.ts → inspector-runner.ts} +13 -13
- package/dist/extensions/pi-subagents/src/inspectors/plugins.ts +75 -0
- package/dist/extensions/pi-subagents/src/inspectors/{herdr/session-roots-codec.ts → session-roots-codec.ts} +4 -15
- package/dist/extensions/pi-subagents/src/inspectors/{herdr/shell-command.ts → shell-command.ts} +1 -1
- package/dist/extensions/pi-subagents/src/inspectors/types.ts +51 -0
- package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +38 -53
- package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +7 -1
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +53 -9
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +69 -55
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +7 -2
- package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +45 -32
- package/dist/extensions/pi-subagents/src/missions/store.ts +11 -2
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +1 -44
- package/dist/extensions/pi-subagents/src/policy/authority.ts +5 -1
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +30 -18
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +59 -9
- package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +18 -2
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +463 -248
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +112 -66
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +33 -20
- package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +47 -17
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -5
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +24 -11
- package/dist/extensions/pi-subagents/src/runs/background/await-async-run.ts +78 -0
- package/dist/extensions/pi-subagents/src/runs/background/binary-bootstrap.ts +66 -0
- package/dist/extensions/pi-subagents/src/runs/background/calendar-schedule.ts +90 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +19 -38
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +62 -3
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +82 -10
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +272 -24
- package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +30 -3
- package/dist/extensions/pi-subagents/src/runs/background/pid-namespace.ts +18 -0
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal-candidate.ts +98 -0
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +18 -97
- package/dist/extensions/pi-subagents/src/runs/background/result-delivery-ownership.ts +269 -7
- package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +14 -5
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +77 -22
- package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +4 -3
- package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +15 -3
- package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +126 -45
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +11 -6
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +18 -7
- package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +43 -51
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +8 -1
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/background/runner-http-dispatcher.ts +119 -0
- package/dist/extensions/pi-subagents/src/runs/background/runner-startup-failure.ts +56 -0
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +297 -69
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +67 -16
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +21 -3
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner-bootstrap.ts +276 -0
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +660 -578
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +177 -29
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +77 -28
- package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +10 -4
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +7 -13
- package/dist/extensions/pi-subagents/src/runs/background/workflow-terminal-proof.ts +41 -23
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +19 -8
- package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +130 -7
- package/dist/extensions/pi-subagents/src/runs/foreground/command-action.ts +41 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +267 -385
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +4 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +6 -10
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1158 -413
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +200 -74
- package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +133 -34
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +6 -1
- package/dist/extensions/pi-subagents/src/runs/shared/child-commands.ts +228 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +18 -18
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch-plan.ts +16 -4
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +55 -12
- package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +6 -3
- package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +11 -1
- package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +367 -74
- package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +50 -86
- package/dist/extensions/pi-subagents/src/runs/shared/claude-code-adapter.ts +288 -0
- package/dist/extensions/pi-subagents/src/runs/shared/codex-exec-adapter.ts +129 -0
- package/dist/extensions/pi-subagents/src/runs/shared/cursor-agent-adapter.ts +114 -0
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +5 -5
- package/dist/extensions/pi-subagents/src/runs/shared/effective-system-prompt.ts +33 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-contract.ts +49 -10
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +61 -9
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +16 -9
- package/dist/extensions/pi-subagents/src/runs/shared/external-job-bridge.ts +55 -1
- package/dist/extensions/pi-subagents/src/runs/shared/git-environment.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-connection.ts +134 -0
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-external-adapters.ts +169 -0
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-machine.ts +279 -0
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-pi-protocol.ts +59 -0
- package/dist/extensions/pi-subagents/src/runs/shared/herdr-placed-run.ts +263 -0
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-config-sources.ts +6 -2
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +108 -13
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-grant.ts +23 -7
- package/dist/extensions/pi-subagents/src/runs/shared/model-resolution-diagnostic.ts +76 -0
- package/dist/extensions/pi-subagents/src/runs/shared/{model-fallback.ts → model-resolution.ts} +65 -245
- package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +30 -11
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +24 -3
- package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +55 -7
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +14 -4
- package/dist/extensions/pi-subagents/src/runs/shared/partial-output.ts +48 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +12 -4
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +88 -1
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +12 -3
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +160 -9
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +49 -35
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +58 -19
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +21 -0
- package/dist/extensions/pi-subagents/src/runs/shared/usage-reconciliation.ts +73 -0
- package/dist/extensions/pi-subagents/src/runs/shared/workflow-async-child-guidance.ts +18 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-apply.ts +160 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +42 -20
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-lock.ts +29 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +27 -4
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +94 -26
- package/dist/extensions/pi-subagents/src/shared/child-cache-retention.ts +43 -0
- package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +5 -3
- package/dist/extensions/pi-subagents/src/shared/disabled-features.ts +123 -0
- package/dist/extensions/pi-subagents/src/shared/extension-context.ts +14 -1
- package/dist/extensions/pi-subagents/src/shared/file-lease.ts +74 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +27 -77
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +70 -10
- package/dist/extensions/pi-subagents/src/shared/model-info.ts +10 -1
- package/dist/extensions/pi-subagents/src/shared/opencode-session-headers.ts +30 -0
- package/dist/extensions/pi-subagents/src/shared/owner-record.ts +107 -0
- package/dist/extensions/pi-subagents/src/shared/package-version.ts +17 -0
- package/dist/extensions/pi-subagents/src/shared/parent-wake.ts +66 -0
- package/dist/extensions/pi-subagents/src/shared/process-identity.ts +87 -0
- package/dist/extensions/pi-subagents/src/shared/pruned-fork.ts +71 -58
- package/dist/extensions/pi-subagents/src/shared/required-child-extensions.ts +115 -0
- package/dist/extensions/pi-subagents/src/shared/settings-file-lease.ts +36 -0
- package/dist/extensions/pi-subagents/src/shared/settings.ts +7 -4
- package/dist/extensions/pi-subagents/src/shared/shortcuts.ts +1 -5
- package/dist/extensions/pi-subagents/src/shared/types.ts +155 -48
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +28 -2
- package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +15 -1
- package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +19 -4
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +13 -2
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +15 -15
- package/dist/extensions/pi-subagents/src/slash/subagent-cost.ts +46 -9
- package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +29 -16
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +201 -26
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +33 -16
- package/dist/extensions/pi-subagents/src/tui/render.ts +334 -103
- package/dist/extensions/pi-subagents/src/tui/running-tone.ts +28 -0
- package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +27 -28
- package/dist/extensions/pi-subagents/src/watchdog/diff-tool.ts +47 -12
- package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +2 -2
- package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +22 -2
- package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +17 -17
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +24 -8
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +43 -39
- package/dist/extensions/pi-subagents/src/watchdog/render.ts +2 -2
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +127 -78
- package/dist/extensions/pi-subagents/src/watchdog/rules.ts +1 -1
- package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +107 -31
- package/dist/extensions/pi-subagents/src/watchdog/scope.ts +1 -1
- package/dist/extensions/pi-subagents/src/watchdog/settings.ts +22 -14
- package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +14 -13
- package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +35 -6
- package/dist/extensions/pi-subagents/src/watchdog/types.ts +6 -4
- package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +2 -2
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +500 -65
- package/dist/extensions/pi-subagents/src/workflows/structured-workflow-scripts.ts +177 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +8 -2
- package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +5 -3
- package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +70 -10
- package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +57 -18
- package/dist/extensions/pi-subagents/src/workflows/workflow-reuse.ts +120 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-revival.ts +123 -0
- package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +5 -2
- package/dist/extensions/pi-subagents/test/fixtures/cwd-workflow-child.ts +37 -0
- package/dist/extensions/pi-subagents/test/fixtures/herdr-allocation-lock-child.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/herdr-provision-child.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/native-nested-wait-provider.ts +76 -0
- package/dist/extensions/pi-subagents/test/fixtures/runner-bootstrap-harness.ts +36 -0
- package/dist/extensions/pi-subagents/test/fixtures/schedule-history-writer.mjs +48 -0
- package/dist/extensions/pi-subagents/test/fixtures/settings-race-writer.mjs +57 -0
- package/dist/extensions/pi-subagents/test/fixtures/workflow-cwd-access-failure.ts +33 -0
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +40 -7
- package/dist/extensions/pi-subagents/test/integration/async-attention-clearing.test.ts +192 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +435 -276
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +435 -397
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +918 -497
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +264 -17
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +185 -22
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +3 -2
- package/dist/extensions/pi-subagents/test/integration/claude-code-dispatch.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/integration/deadline-checkpoint.test.ts +126 -0
- package/dist/extensions/pi-subagents/test/integration/doctor-executor.test.ts +29 -1
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +450 -13
- package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +10 -6
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +105 -86
- package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +403 -18
- package/dist/extensions/pi-subagents/test/integration/inline-workflow-visibility.test.ts +351 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +195 -10
- package/dist/extensions/pi-subagents/test/integration/model-resolution-diagnostic.test.ts +108 -0
- package/dist/extensions/pi-subagents/test/integration/nested-async-wait.test.ts +61 -0
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +5 -4
- package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +6 -4
- package/dist/extensions/pi-subagents/test/integration/render-widget-mouse.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +242 -16
- package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +221 -4
- package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +1435 -248
- package/dist/extensions/pi-subagents/test/integration/single-execution.part-2.test.ts +454 -515
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +140 -21
- package/dist/extensions/pi-subagents/test/integration/stop-all-background.test.ts +142 -0
- package/dist/extensions/pi-subagents/test/integration/structured-workflows.test.ts +105 -0
- package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +90 -11
- package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +18 -15
- package/dist/extensions/pi-subagents/test/integration/workflow-worktree-admission.test.ts +100 -0
- package/dist/extensions/pi-subagents/test/smoke/clean-install.mjs +106 -0
- package/dist/extensions/pi-subagents/test/smoke/npm-background.mjs +43 -0
- package/dist/extensions/pi-subagents/test/smoke/packed-runner-selection.mjs +42 -0
- package/dist/extensions/pi-subagents/test/smoke/runner-loader-capability.mjs +50 -0
- package/dist/extensions/pi-subagents/test/smoke/sdk-child.ts +57 -0
- package/dist/extensions/pi-subagents/test/smoke/{pi085-extension.ts → sdk-extension.ts} +2 -2
- package/dist/extensions/pi-subagents/test/smoke/standalone-background.mjs +140 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-fault.ts +43 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-matrix.mjs +65 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-observer.ts +8 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-parent.ts +220 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-provider.ts +58 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-release.json +8 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-revival.ts +109 -0
- package/dist/extensions/pi-subagents/test/smoke/standalone-shared.ts +79 -0
- package/dist/extensions/pi-subagents/test/smoke/tool-activation.test.ts +128 -0
- package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +6 -25
- package/dist/extensions/pi-subagents/test/support/async-result-timeout-evidence.ts +61 -0
- package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +130 -9
- package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +15 -7
- package/dist/extensions/pi-subagents/test/support/helpers.ts +11 -14
- package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +21 -3
- package/dist/extensions/pi-subagents/test/support/native-peer-loader.mjs +15 -0
- package/dist/extensions/pi-subagents/test/support/node-command.ts +29 -6
- package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +5 -3
- package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +7 -15
- package/dist/extensions/pi-subagents/test/support/watchdog-stable-host-loader.mjs +23 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +158 -155
- package/dist/extensions/pi-subagents/test/unit/active-async-capacity.test.ts +52 -1
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +21 -17
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +105 -36
- package/dist/extensions/pi-subagents/test/unit/advertisement-barrier.test.ts +151 -0
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -2
- package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +33 -3
- package/dist/extensions/pi-subagents/test/unit/agent-end-auto-drain.test.ts +149 -0
- package/dist/extensions/pi-subagents/test/unit/agent-exclude-dirs.test.ts +246 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +62 -87
- package/dist/extensions/pi-subagents/test/unit/agent-global-root-override.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +398 -48
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +126 -1
- package/dist/extensions/pi-subagents/test/unit/agent-name-resolution.test.ts +75 -0
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +94 -42
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +73 -3
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +428 -2
- package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +112 -1
- package/dist/extensions/pi-subagents/test/unit/async-result-timeout-evidence.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +92 -4
- package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +58 -6
- package/dist/extensions/pi-subagents/test/unit/async-run-history.test.ts +123 -0
- package/dist/extensions/pi-subagents/test/unit/async-spawn-package-dir.test.ts +203 -0
- package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +26 -35
- package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +185 -0
- package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +9 -1
- package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +106 -1
- package/dist/extensions/pi-subagents/test/unit/await-async-run.test.ts +202 -0
- package/dist/extensions/pi-subagents/test/unit/binary-async-spawn.test.ts +115 -0
- package/dist/extensions/pi-subagents/test/unit/binary-pi-spawn.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/calendar-schedule.test.ts +70 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +38 -0
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +10 -2
- package/dist/extensions/pi-subagents/test/unit/changelog-format.test.ts +11 -0
- package/dist/extensions/pi-subagents/test/unit/child-cache-retention.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/unit/child-commands.test.ts +243 -0
- package/dist/extensions/pi-subagents/test/unit/child-external-job-bridge.test.ts +126 -0
- package/dist/extensions/pi-subagents/test/unit/child-launch-plan.test.ts +12 -1
- package/dist/extensions/pi-subagents/test/unit/child-lifecycle.test.ts +36 -0
- package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-commands.test.ts +162 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-host-sdk.test.ts +226 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-parent-providers.test.ts +200 -0
- package/dist/extensions/pi-subagents/test/unit/child-session-queued.test.ts +260 -0
- package/dist/extensions/pi-subagents/test/unit/child-tool-plan-permission-system.test.ts +3 -98
- package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +222 -1
- package/dist/extensions/pi-subagents/test/unit/claude-code-adapter.test.ts +314 -0
- package/dist/extensions/pi-subagents/test/unit/claude-code-dispatch.test.ts +182 -0
- package/dist/extensions/pi-subagents/test/unit/codex-exec-adapter.test.ts +157 -0
- package/dist/extensions/pi-subagents/test/unit/command-action.test.ts +50 -0
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +25 -11
- package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +7 -1
- package/dist/extensions/pi-subagents/test/unit/cursor-agent-adapter.test.ts +220 -0
- package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +104 -32
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +138 -1
- package/dist/extensions/pi-subagents/test/unit/disabled-features.test.ts +227 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +48 -9
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +7 -4
- package/dist/extensions/pi-subagents/test/unit/extension-lazy-loading.test.ts +21 -0
- package/dist/extensions/pi-subagents/test/unit/extension-maintenance-lifecycle.test.ts +66 -0
- package/dist/extensions/pi-subagents/test/unit/extension-module-preload.test.ts +49 -0
- package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +104 -3
- package/dist/extensions/pi-subagents/test/unit/file-lease.test.ts +17 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +316 -0
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +58 -7
- package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +25 -96
- package/dist/extensions/pi-subagents/test/unit/ghostty-inspector.test.ts +92 -0
- package/dist/extensions/pi-subagents/test/unit/global-npm-root.test.ts +108 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-connection.test.ts +43 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-external-adapters.test.ts +89 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +11 -20
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +113 -19
- package/dist/extensions/pi-subagents/test/unit/herdr-machine.test.ts +161 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-native-placement.test.ts +187 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-session-roots-codec.test.ts +7 -12
- package/dist/extensions/pi-subagents/test/unit/herdr-shell-command.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +182 -87
- package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +68 -49
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +295 -135
- package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/inspector-authority-policy.test.ts +144 -0
- package/dist/extensions/pi-subagents/test/unit/inspector-registration.test.ts +128 -0
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +49 -1
- package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-grant.test.ts +74 -1
- package/dist/extensions/pi-subagents/test/unit/mcp-direct-tool-resolution.test.ts +112 -0
- package/dist/extensions/pi-subagents/test/unit/mission-global-projection.test.ts +215 -0
- package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +65 -1
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +2 -1
- package/dist/extensions/pi-subagents/test/unit/model-resolution-diagnostic.test.ts +78 -0
- package/dist/extensions/pi-subagents/test/unit/model-resolution.test.ts +153 -0
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +43 -1
- package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +1 -21
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +279 -2
- package/dist/extensions/pi-subagents/test/unit/nested-control-fanout.test.ts +73 -0
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +297 -3
- package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +431 -23
- package/dist/extensions/pi-subagents/test/unit/observability.test.ts +198 -0
- package/dist/extensions/pi-subagents/test/unit/opencode-session-headers.test.ts +32 -0
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +89 -21
- package/dist/extensions/pi-subagents/test/unit/owned-process-tree.test.ts +31 -1
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +18 -24
- package/dist/extensions/pi-subagents/test/unit/parent-wake.test.ts +206 -0
- package/dist/extensions/pi-subagents/test/unit/partial-output.test.ts +53 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +216 -32
- package/dist/extensions/pi-subagents/test/unit/pi-spawn-host-root.test.ts +82 -0
- package/dist/extensions/pi-subagents/test/unit/pi-subagents-policy-guidance.test.ts +28 -0
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +193 -104
- package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +16 -1
- package/dist/extensions/pi-subagents/test/unit/process-identity.test.ts +75 -0
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +17 -1
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +89 -9
- package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +6 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-audit-provider-routing.test.ts +69 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +23 -1
- package/dist/extensions/pi-subagents/test/unit/pruned-fork.test.ts +117 -3
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +35 -14
- package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +3 -2
- package/dist/extensions/pi-subagents/test/unit/release-readiness.test.ts +715 -0
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +261 -9
- package/dist/extensions/pi-subagents/test/unit/reply-workflow-script.test.ts +37 -0
- package/dist/extensions/pi-subagents/test/unit/required-child-extensions.test.ts +114 -0
- package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +11 -1
- package/dist/extensions/pi-subagents/test/unit/result-takeover.test.ts +332 -0
- package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +22 -2
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +125 -18
- package/dist/extensions/pi-subagents/test/unit/run-child-session.test.ts +230 -0
- package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +50 -1
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +301 -4
- package/dist/extensions/pi-subagents/test/unit/runner-bootstrap.test.ts +182 -0
- package/dist/extensions/pi-subagents/test/unit/runner-http-dispatcher.test.ts +136 -0
- package/dist/extensions/pi-subagents/test/unit/runner-peer-loader.test.ts +68 -0
- package/dist/extensions/pi-subagents/test/unit/runner-peer-symlinks.test.ts +50 -0
- package/dist/extensions/pi-subagents/test/unit/running-tone.test.ts +13 -0
- package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +155 -4
- package/dist/extensions/pi-subagents/test/unit/schedule-claim-initialization.test.ts +71 -0
- package/dist/extensions/pi-subagents/test/unit/schedule-claim-preservation.test.ts +98 -0
- package/dist/extensions/pi-subagents/test/unit/schedule-history-transactions.test.ts +201 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-mission.test.ts +317 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +412 -11
- package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +2 -8
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +70 -71
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +748 -5
- package/dist/extensions/pi-subagents/test/unit/session-liveness-delivery.test.ts +337 -0
- package/dist/extensions/pi-subagents/test/unit/settings-atomic-save.test.ts +419 -0
- package/dist/extensions/pi-subagents/test/unit/settings-transactions.test.ts +88 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +13 -1
- package/dist/extensions/pi-subagents/test/unit/skills-disable-model-invocation.test.ts +164 -0
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +35 -2
- package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +334 -9
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +170 -0
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +34 -5
- package/dist/extensions/pi-subagents/test/unit/structured-output-validation.test.ts +199 -0
- package/dist/extensions/pi-subagents/test/unit/structured-workflow-resources.test.ts +241 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +47 -38
- package/dist/extensions/pi-subagents/test/unit/subagent-cost.test.ts +97 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +343 -44
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +410 -11
- package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +459 -22
- package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +43 -3
- package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +11 -1
- package/dist/extensions/pi-subagents/test/unit/tool-activation-stale-peer.test.ts +32 -0
- package/dist/extensions/pi-subagents/test/unit/tool-activation.test.ts +313 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -89
- package/dist/extensions/pi-subagents/test/unit/typed-gate-output.test.ts +141 -0
- package/dist/extensions/pi-subagents/test/unit/upgrade-notice.test.ts +31 -0
- package/dist/extensions/pi-subagents/test/unit/usage-reconciliation-owners.test.ts +66 -0
- package/dist/extensions/pi-subagents/test/unit/usage-reconciliation.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +195 -1
- package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +48 -45
- package/dist/extensions/pi-subagents/test/unit/watchdog-compaction-scope.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-diff-tool.test.ts +48 -3
- package/dist/extensions/pi-subagents/test/unit/watchdog-native-scheduling.test.ts +107 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +95 -7
- package/dist/extensions/pi-subagents/test/unit/watchdog-register-child.test.ts +79 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +7 -4
- package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +111 -24
- package/dist/extensions/pi-subagents/test/unit/watchdog-rules.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +283 -2
- package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +3 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +12 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-stable-host-layout.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +30 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-turn-delta.test.ts +39 -2
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +18 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +8 -4
- package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +10 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +6 -3
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +44 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +28 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-revival.test.ts +85 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-scripts-feature.test.ts +177 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-terminal-proof.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-worktree-admission.test.ts +29 -0
- package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +343 -4
- package/dist/extensions/pi-subagents/test/unit/worktree-lock.test.ts +123 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +252 -22
- package/dist/extensions/pi-subagents/tsconfig.build.json +13 -0
- package/dist/extensions/pi-tool-display/tests/custom-tool-overrides.test.ts +1 -1
- package/dist/extensions/pi-tool-display/tests/tool-overrides-config.test.ts +1 -1
- package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +24 -1
- package/dist/extensions/pi-tool-display/tests/tool-overrides-registration.test.ts +6 -2
- package/dist/extensions/pi-web-agent/src/extension.ts +1 -5
- package/dist/extensions/pi-zentui/.github/workflows/ci.yml +67 -4
- package/dist/extensions/pi-zentui/AGENTS.md +3 -2
- package/dist/extensions/pi-zentui/README.md +60 -32
- package/dist/extensions/pi-zentui/docs/configuration.md +662 -51
- package/dist/extensions/pi-zentui/docs/footer-format.md +174 -5
- package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-editor.ts +15 -4
- package/dist/extensions/pi-zentui/extensions/zentui/average-token-rate.ts +146 -0
- package/dist/extensions/pi-zentui/extensions/zentui/codex-quota-display.ts +34 -0
- package/dist/extensions/pi-zentui/extensions/zentui/codex-quota.ts +298 -0
- package/dist/extensions/pi-zentui/extensions/zentui/component-colors.ts +172 -0
- package/dist/extensions/pi-zentui/extensions/zentui/component-settings.ts +243 -0
- package/dist/extensions/pi-zentui/extensions/zentui/config.ts +851 -114
- package/dist/extensions/pi-zentui/extensions/zentui/custom-value-colors.ts +93 -0
- package/dist/extensions/pi-zentui/extensions/zentui/custom-variable-demand.ts +61 -0
- package/dist/extensions/pi-zentui/extensions/zentui/custom-variable-format.ts +80 -0
- package/dist/extensions/pi-zentui/extensions/zentui/custom-variables.ts +152 -0
- package/dist/extensions/pi-zentui/extensions/zentui/editor-metadata-format.ts +138 -23
- package/dist/extensions/pi-zentui/extensions/zentui/editor-mouse.ts +89 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status-controller.ts +148 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status-settings.ts +40 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +109 -1
- package/dist/extensions/pi-zentui/extensions/zentui/footer-format.ts +203 -23
- package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +80 -3
- package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +1 -1
- package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +432 -125
- package/dist/extensions/pi-zentui/extensions/zentui/format.ts +92 -4
- package/dist/extensions/pi-zentui/extensions/zentui/git.ts +47 -30
- package/dist/extensions/pi-zentui/extensions/zentui/github-status.ts +575 -0
- package/dist/extensions/pi-zentui/extensions/zentui/host-project-changes.ts +25 -0
- package/dist/extensions/pi-zentui/extensions/zentui/host-template-values.ts +29 -0
- package/dist/extensions/pi-zentui/extensions/zentui/icons.ts +53 -13
- package/dist/extensions/pi-zentui/extensions/zentui/index.ts +778 -258
- package/dist/extensions/pi-zentui/extensions/zentui/interaction-summary.ts +70 -5
- package/dist/extensions/pi-zentui/extensions/zentui/layered-editor.ts +55 -0
- package/dist/extensions/pi-zentui/extensions/zentui/live-context.ts +6 -1
- package/dist/extensions/pi-zentui/extensions/zentui/live-metadata-demand.ts +72 -0
- package/dist/extensions/pi-zentui/extensions/zentui/live-metadata-display.ts +21 -0
- package/dist/extensions/pi-zentui/extensions/zentui/live-metadata.ts +255 -0
- package/dist/extensions/pi-zentui/extensions/zentui/minimalist-editor.ts +476 -36
- package/dist/extensions/pi-zentui/extensions/zentui/minimalist-settings.ts +118 -0
- package/dist/extensions/pi-zentui/extensions/zentui/minimalist-template.ts +177 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-editor-frame.ts +148 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-statusline.ts +569 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-template-lookups.ts +344 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-template-metrics.ts +91 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-template-modes.ts +323 -0
- package/dist/extensions/pi-zentui/extensions/zentui/omp-ui.ts +210 -0
- package/dist/extensions/pi-zentui/extensions/zentui/package-version.ts +30 -12
- package/dist/extensions/pi-zentui/extensions/zentui/project-demand.ts +46 -0
- package/dist/extensions/pi-zentui/extensions/zentui/project-discovery.ts +58 -0
- package/dist/extensions/pi-zentui/extensions/zentui/project-refresh.ts +10 -3
- package/dist/extensions/pi-zentui/extensions/zentui/project-state.ts +37 -0
- package/dist/extensions/pi-zentui/extensions/zentui/repository-root.ts +1 -0
- package/dist/extensions/pi-zentui/extensions/zentui/runtime.ts +119 -43
- package/dist/extensions/pi-zentui/extensions/zentui/selector-border.ts +40 -29
- package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +1268 -722
- package/dist/extensions/pi-zentui/extensions/zentui/settings-keys.ts +59 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-list-selection.ts +13 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-previews.ts +11 -4
- package/dist/extensions/pi-zentui/extensions/zentui/state.ts +24 -11
- package/dist/extensions/pi-zentui/extensions/zentui/style.ts +6 -0
- package/dist/extensions/pi-zentui/extensions/zentui/telemetry.ts +113 -11
- package/dist/extensions/pi-zentui/extensions/zentui/thinking-experimental.ts +234 -46
- package/dist/extensions/pi-zentui/extensions/zentui/thinking-steps.ts +20 -5
- package/dist/extensions/pi-zentui/extensions/zentui/token-rate.ts +313 -0
- package/dist/extensions/pi-zentui/extensions/zentui/turn-summary-format.ts +59 -0
- package/dist/extensions/pi-zentui/extensions/zentui/turn-summary-rate.ts +52 -0
- package/dist/extensions/pi-zentui/extensions/zentui/ui.ts +640 -172
- package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +72 -34
- package/dist/extensions/pi-zentui/extensions/zentui/user-message.ts +219 -34
- package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +495 -119
- package/dist/extensions/pi-zentui/omp.ts +157 -0
- package/dist/extensions/pi-zentui/package-lock.json +3762 -1507
- package/dist/extensions/pi-zentui/package.json +50 -12
- package/dist/extensions/pi-zentui/test/accent-rail-editor.test.ts +13 -2
- package/dist/extensions/pi-zentui/test/average-token-rate.test.ts +297 -0
- package/dist/extensions/pi-zentui/test/behavior-compatibility.mjs +89 -0
- package/dist/extensions/pi-zentui/test/codex-quota-lifecycle.test.ts +284 -0
- package/dist/extensions/pi-zentui/test/codex-quota-rendering.test.ts +466 -0
- package/dist/extensions/pi-zentui/test/codex-quota.test.ts +440 -0
- package/dist/extensions/pi-zentui/test/component-colors.test.ts +554 -0
- package/dist/extensions/pi-zentui/test/component-settings.test.ts +364 -0
- package/dist/extensions/pi-zentui/test/config-component-independence.test.ts +402 -0
- package/dist/extensions/pi-zentui/test/config-extension-status-choice.test.ts +233 -0
- package/dist/extensions/pi-zentui/test/config-hidden-extension-status-colors.test.ts +118 -0
- package/dist/extensions/pi-zentui/test/config-hidden-extension-status-placement.test.ts +142 -0
- package/dist/extensions/pi-zentui/test/config-minimalist-templates.test.ts +240 -0
- package/dist/extensions/pi-zentui/test/config-template-variables.test.ts +85 -0
- package/dist/extensions/pi-zentui/test/config.test.ts +80 -17
- package/dist/extensions/pi-zentui/test/custom-value-colors-integration.test.ts +453 -0
- package/dist/extensions/pi-zentui/test/custom-value-colors.test.ts +399 -0
- package/dist/extensions/pi-zentui/test/custom-variable-alias-prototypes.test.ts +177 -0
- package/dist/extensions/pi-zentui/test/custom-variable-consumers.test.ts +194 -0
- package/dist/extensions/pi-zentui/test/custom-variable-demand.test.ts +169 -0
- package/dist/extensions/pi-zentui/test/custom-variable-probe-reservation.test.ts +141 -0
- package/dist/extensions/pi-zentui/test/custom-variables-lifecycle.integration.test.ts +365 -0
- package/dist/extensions/pi-zentui/test/custom-variables.test.ts +330 -0
- package/dist/extensions/pi-zentui/test/editor-metadata-format.test.ts +121 -0
- package/dist/extensions/pi-zentui/test/editor-mouse.test.ts +507 -0
- package/dist/extensions/pi-zentui/test/editor-viewport-indicators.test.ts +247 -20
- package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +204 -260
- package/dist/extensions/pi-zentui/test/extension-status-controller.test.ts +323 -0
- package/dist/extensions/pi-zentui/test/extension-status-lifecycle.integration.test.ts +466 -0
- package/dist/extensions/pi-zentui/test/extension-status-settings.test.ts +79 -0
- package/dist/extensions/pi-zentui/test/footer-alignment.test.ts +135 -0
- package/dist/extensions/pi-zentui/test/footer-authority.test.ts +69 -0
- package/dist/extensions/pi-zentui/test/footer-auto-compaction.test.ts +148 -0
- package/dist/extensions/pi-zentui/test/footer-format-cache.test.ts +186 -0
- package/dist/extensions/pi-zentui/test/footer-format.test.ts +154 -4
- package/dist/extensions/pi-zentui/test/footer-hidden.test.ts +312 -0
- package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +22 -0
- package/dist/extensions/pi-zentui/test/footer-layout.test.ts +80 -0
- package/dist/extensions/pi-zentui/test/footer-thinking-level.test.ts +123 -0
- package/dist/extensions/pi-zentui/test/format.test.ts +75 -1
- package/dist/extensions/pi-zentui/test/git-probes.test.ts +182 -0
- package/dist/extensions/pi-zentui/test/github-status.test.ts +931 -0
- package/dist/extensions/pi-zentui/test/host-template-surfaces.test.ts +287 -0
- package/dist/extensions/pi-zentui/test/icons.test.ts +86 -16
- package/dist/extensions/pi-zentui/test/layered-editor.test.ts +53 -0
- package/dist/extensions/pi-zentui/test/live-context-integration.test.ts +154 -7
- package/dist/extensions/pi-zentui/test/live-context.test.ts +45 -0
- package/dist/extensions/pi-zentui/test/live-metadata-lifecycle.integration.test.ts +963 -0
- package/dist/extensions/pi-zentui/test/live-metadata.test.ts +767 -0
- package/dist/extensions/pi-zentui/test/minimalist-cache-hit-colors.test.ts +183 -0
- package/dist/extensions/pi-zentui/test/minimalist-editor.test.ts +222 -4
- package/dist/extensions/pi-zentui/test/minimalist-settings.test.ts +103 -0
- package/dist/extensions/pi-zentui/test/minimalist-templates.test.ts +489 -0
- package/dist/extensions/pi-zentui/test/omp-editor-composers.test.ts +324 -0
- package/dist/extensions/pi-zentui/test/omp-statusline.test.ts +579 -0
- package/dist/extensions/pi-zentui/test/omp-template-lookups.test.ts +630 -0
- package/dist/extensions/pi-zentui/test/omp-template-metrics.test.ts +72 -0
- package/dist/extensions/pi-zentui/test/omp-template-modes.test.ts +557 -0
- package/dist/extensions/pi-zentui/test/omp-ui.test.ts +93 -0
- package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
- package/dist/extensions/pi-zentui/test/pi-version-policy.test.ts +37 -0
- package/dist/extensions/pi-zentui/test/project-demand-integration.test.ts +542 -0
- package/dist/extensions/pi-zentui/test/project-discovery.test.ts +412 -0
- package/dist/extensions/pi-zentui/test/project-refresh.test.ts +44 -0
- package/dist/extensions/pi-zentui/test/project-state.test.ts +38 -1
- package/dist/extensions/pi-zentui/test/responsive-dependencies.test.ts +7 -7
- package/dist/extensions/pi-zentui/test/runtime.test.ts +127 -2
- package/dist/extensions/pi-zentui/test/selesai-v030-gate.json +939 -0
- package/dist/extensions/pi-zentui/test/settings-command.test.ts +1330 -82
- package/dist/extensions/pi-zentui/test/settings-keys.test.ts +41 -0
- package/dist/extensions/pi-zentui/test/settings-list-selection.test.ts +88 -0
- package/dist/extensions/pi-zentui/test/settings-previews.test.ts +4 -1
- package/dist/extensions/pi-zentui/test/state.test.ts +15 -1
- package/dist/extensions/pi-zentui/test/telemetry-lifecycle-integration.test.ts +214 -12
- package/dist/extensions/pi-zentui/test/telemetry-snapshot.test.ts +246 -0
- package/dist/extensions/pi-zentui/test/thinking-experimental-cache.test.ts +246 -0
- package/dist/extensions/pi-zentui/test/thinking-experimental-rows.test.ts +22 -0
- package/dist/extensions/pi-zentui/test/thinking-experimental-tui.mjs +113 -51
- package/dist/extensions/pi-zentui/test/thinking-experimental.test.ts +576 -76
- package/dist/extensions/pi-zentui/test/thinking-steps.test.ts +23 -0
- package/dist/extensions/pi-zentui/test/token-rate.test.ts +450 -0
- package/dist/extensions/pi-zentui/test/turn-summary-format.test.ts +207 -0
- package/dist/extensions/pi-zentui/test/turn-summary-lifecycle.integration.test.ts +72 -5
- package/dist/extensions/pi-zentui/test/turn-summary-rate.test.ts +158 -0
- package/dist/extensions/pi-zentui/test/usage-lifecycle-integration.test.ts +421 -0
- package/dist/extensions/pi-zentui/test/usage-snapshot.test.ts +154 -0
- package/dist/extensions/pi-zentui/test/user-message-cache.test.ts +239 -0
- package/dist/extensions/pi-zentui/test/user-message-native-reduced-capabilities.test.ts +61 -0
- package/dist/extensions/pi-zentui/test/user-message-native.test.ts +447 -0
- package/dist/extensions/pi-zentui/test/user-message-styles.test.ts +2 -2
- package/dist/extensions/pi-zentui/test/working-line-editor-placement.test.ts +317 -0
- package/dist/extensions/pi-zentui/test/working-line-generation-cache.test.ts +238 -0
- package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +674 -179
- package/dist/extensions/pi-zentui/test/working-line-message-ownership.test.ts +239 -0
- package/dist/extensions/pi-zentui/test/working-line-metric-animation.test.ts +284 -0
- package/dist/extensions/pi-zentui/test/working-line-placement.test.ts +298 -0
- package/dist/extensions/pi-zentui/test/working-line.test.ts +386 -18
- package/dist/extensions/pi-zentui/test/wrapped-editor-consumers.integration.test.ts +579 -0
- package/dist/extensions/pi-zentui/test/wrapped-editor-usage.integration.test.ts +298 -0
- package/dist/extensions/pi-zentui/tsconfig.json +1 -1
- package/dist/extensions/pi-zentui/vitest.host.config.ts +33 -0
- package/dist/extensions/question/index.ts +1 -5
- package/dist/extensions/rtk.test.ts +28 -15
- package/dist/extensions/rtk.ts +22 -22
- package/dist/extensions/skills-index/index.test.ts +99 -0
- package/dist/extensions/skills-index/index.ts +105 -0
- package/dist/extensions/skills-index/package.json +9 -0
- package/dist/extensions/tokenin-onboarding.ts +52 -210
- package/dist/extensions/tool-search/index.d.ts +11 -0
- package/dist/extensions/tool-search/index.js +14 -0
- package/dist/extensions/tool-search/tool.d.ts +72 -0
- package/dist/extensions/tool-search/tool.js +188 -0
- package/dist/index.d.ts +21 -9
- package/dist/index.js +17 -5
- package/dist/main.d.ts +10 -0
- package/dist/main.js +107 -43
- package/dist/migrations.js +4 -3
- package/dist/modes/index.d.ts +2 -1
- package/dist/modes/interactive/bug-report.js +4 -0
- package/dist/modes/interactive/components/armin.d.ts +3 -0
- package/dist/modes/interactive/components/armin.js +7 -5
- package/dist/modes/interactive/components/assistant-message.js +1 -1
- package/dist/modes/interactive/components/auth-url.d.ts +13 -0
- package/dist/modes/interactive/components/auth-url.js +36 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
- package/dist/modes/interactive/components/bash-execution.js +17 -14
- package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
- package/dist/modes/interactive/components/branch-summary-message.js +5 -2
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -1
- package/dist/modes/interactive/components/compaction-summary-message.js +5 -2
- package/dist/modes/interactive/components/config-selector.js +13 -3
- package/dist/modes/interactive/components/custom-editor.js +7 -0
- package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
- package/dist/modes/interactive/components/custom-entry.js +8 -2
- package/dist/modes/interactive/components/custom-message.js +1 -0
- package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
- package/dist/modes/interactive/components/first-time-setup.js +8 -2
- package/dist/modes/interactive/components/footer.d.ts +7 -0
- package/dist/modes/interactive/components/footer.js +44 -4
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +2 -0
- package/dist/modes/interactive/components/login-dialog.js +11 -5
- package/dist/modes/interactive/components/mermaid.d.ts +10 -0
- package/dist/modes/interactive/components/mermaid.js +74 -0
- package/dist/modes/interactive/components/model-selector.d.ts +14 -9
- package/dist/modes/interactive/components/model-selector.js +79 -31
- package/dist/modes/interactive/components/oauth-selector.d.ts +8 -2
- package/dist/modes/interactive/components/oauth-selector.js +24 -21
- package/dist/modes/interactive/components/pi-logo.d.ts +18 -0
- package/dist/modes/interactive/components/pi-logo.js +36 -0
- package/dist/modes/interactive/components/radius-login-selector.d.ts +14 -0
- package/dist/modes/interactive/components/radius-login-selector.js +84 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +8 -11
- package/dist/modes/interactive/components/settings-selector.js +60 -102
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
- package/dist/modes/interactive/components/themed-text.d.ts +16 -0
- package/dist/modes/interactive/components/themed-text.js +28 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +11 -18
- package/dist/modes/interactive/components/tool-execution.js +34 -47
- package/dist/modes/interactive/components/tree-selector.js +7 -0
- package/dist/modes/interactive/components/user-message.d.ts +3 -1
- package/dist/modes/interactive/components/user-message.js +14 -6
- package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
- package/dist/modes/interactive/components/visual-truncate.js +39 -6
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/interactive-mode.d.ts +41 -8
- package/dist/modes/interactive/interactive-mode.js +854 -492
- package/dist/modes/interactive/program-status-reporter.d.ts +33 -0
- package/dist/modes/interactive/program-status-reporter.js +109 -0
- package/dist/modes/interactive/theme/dark.json +59 -72
- package/dist/modes/interactive/theme/light.json +57 -69
- package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
- package/dist/modes/interactive/theme/system-theme.js +545 -0
- package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
- package/dist/modes/interactive/theme/theme-controller.js +127 -47
- package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-json.js +3 -1
- package/dist/modes/interactive/theme/theme-schema.json +7 -2
- package/dist/modes/interactive/theme/theme.d.ts +66 -39
- package/dist/modes/interactive/theme/theme.js +243 -320
- package/dist/modes/interactive/tui-renderer.d.ts +2 -1
- package/dist/modes/interactive/tui-renderer.js +1 -0
- package/dist/modes/json-event.d.ts +33 -0
- package/dist/modes/json-event.js +28 -0
- package/dist/modes/print-mode.js +12 -2
- package/dist/modes/rpc/intercom-bridge.d.ts +14 -0
- package/dist/modes/rpc/intercom-bridge.js +75 -0
- package/dist/modes/rpc/intercom-bridge.test.js +65 -0
- package/dist/modes/rpc/release-bridge.d.ts +35 -0
- package/dist/modes/rpc/release-bridge.js +159 -0
- package/dist/modes/rpc/release-bridge.test.d.ts +1 -0
- package/dist/modes/rpc/release-bridge.test.js +347 -0
- package/dist/modes/rpc/rpc-client.d.ts +43 -27
- package/dist/modes/rpc/rpc-client.js +97 -37
- package/dist/modes/rpc/rpc-intercom-transport.test.d.ts +1 -0
- package/dist/modes/rpc/rpc-intercom-transport.test.js +85 -0
- package/dist/modes/rpc/rpc-mode.d.ts +1 -13
- package/dist/modes/rpc/rpc-mode.js +250 -34
- package/dist/modes/rpc/rpc-release-transport.test.d.ts +1 -0
- package/dist/modes/rpc/rpc-release-transport.test.js +329 -0
- package/dist/modes/rpc/rpc-subagent-transport.test.d.ts +1 -0
- package/dist/modes/rpc/rpc-subagent-transport.test.js +60 -0
- package/dist/modes/rpc/rpc-types.d.ts +22 -23
- package/dist/modes/rpc/rpc-types.js +0 -6
- package/dist/modes/rpc/subagent-bridge.d.ts +23 -0
- package/dist/modes/rpc/subagent-bridge.js +93 -0
- package/dist/modes/rpc/test-fixtures/intercom-host.d.ts +1 -0
- package/dist/modes/rpc/test-fixtures/intercom-host.js +13 -0
- package/dist/package-manager-cli.js +16 -5
- package/dist/rpc-entry.js +1 -0
- package/dist/skills/pi-subagents/SKILL.md +109 -35
- package/dist/skills/pi-subagents/references/constraints-and-recipes.md +38 -238
- package/dist/skills/pi-subagents/references/execution-controls.md +181 -83
- package/dist/skills/pi-subagents/references/management-authoring-rpc.md +9 -9
- package/dist/skills/pi-subagents/references/multi-lane-orchestration.md +24 -2
- package/dist/skills/pi-subagents/references/prompting-and-roles.md +121 -91
- package/dist/skills/pi-subagents/references/review-and-validation.md +73 -0
- package/dist/utils/ansi.d.ts +8 -0
- package/dist/utils/ansi.js +30 -11
- package/dist/utils/clipboard-image.js +14 -17
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.js +17 -11
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/image-convert.d.ts +12 -0
- package/dist/utils/image-convert.js +45 -6
- package/dist/utils/image-resize-core.d.ts +12 -0
- package/dist/utils/image-resize-core.js +5 -0
- package/dist/utils/image-resize-worker.js +3 -2
- package/dist/utils/image-resize.js +9 -10
- package/dist/utils/mime.js +1 -1
- package/dist/utils/output-files.d.ts +14 -0
- package/dist/utils/output-files.js +29 -0
- package/dist/utils/paths.d.ts +6 -3
- package/dist/utils/paths.js +28 -5
- package/dist/utils/shell.d.ts +1 -3
- package/dist/utils/shell.js +3 -30
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.js +68 -2
- package/dist/utils/tool-result-images.d.ts +20 -0
- package/dist/utils/tool-result-images.js +47 -0
- package/dist/utils/tools-manager.d.ts +5 -0
- package/dist/utils/tools-manager.js +6 -6
- package/dist/utils/version-check.d.ts +4 -0
- package/dist/utils/version-check.js +20 -2
- package/docs/cli-integration.md +104 -0
- package/docs/cli.md +333 -0
- package/docs/codemode.md +230 -0
- package/docs/configuration.md +47 -0
- package/docs/environment-variables.md +5 -0
- package/docs/extensions.md +107 -30
- package/docs/json.md +8 -4
- package/docs/keybindings.md +10 -10
- package/docs/mcp.md +262 -0
- package/docs/models.md +104 -3
- package/docs/providers.md +20 -2
- package/docs/rpc-subagent.schema.json +491 -0
- package/docs/rpc.md +223 -13
- package/docs/sdk.md +41 -33
- package/docs/security.md +21 -20
- package/docs/settings.md +18 -46
- package/docs/terminal-setup.md +14 -0
- package/docs/virtual-models.md +114 -0
- package/examples/extensions/jev-router.ts +113 -0
- package/examples/extensions/tokenin-usage-widget.ts +124 -0
- package/examples/rpc-client.ts +35 -0
- package/examples/sdk/14-codemode-mcp.ts +67 -0
- package/package.json +16 -8
- package/dist/core/agent-session-auto-handoff.test.js +0 -195
- package/dist/core/built-in-extensions.d.ts +0 -2
- package/dist/core/built-in-extensions.js +0 -2
- package/dist/core/llama/provider.js +0 -143
- package/dist/core/settings-manager-auto-handoff.test.js +0 -53
- package/dist/extensions/capability-gateway/catalog.ts +0 -177
- package/dist/extensions/capability-gateway/index.test.ts +0 -226
- package/dist/extensions/capability-gateway/index.ts +0 -669
- package/dist/extensions/capability-gateway/integration.test.ts +0 -803
- package/dist/extensions/capability-gateway/package.json +0 -16
- package/dist/extensions/capability-gateway/routing.test.ts +0 -574
- package/dist/extensions/capability-gateway/routing.ts +0 -403
- package/dist/extensions/pi-subagents/runner-server-preload.mjs +0 -13
- package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +0 -89
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +0 -259
- package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +0 -312
- package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +0 -374
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +0 -69
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +0 -307
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +0 -211
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +0 -17
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +0 -57
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +0 -18
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +0 -9
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +0 -20
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +0 -96
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +0 -119
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +0 -85
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +0 -620
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +0 -56
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +0 -32
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +0 -49
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +0 -93
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +0 -128
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +0 -7
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +0 -38
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +0 -9
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +0 -29
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +0 -37
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +0 -34
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +0 -171
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +0 -1261
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +0 -20
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +0 -54
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +0 -13
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +0 -358
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +0 -77
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +0 -512
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +0 -43
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +0 -121
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +0 -82
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +0 -17
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +0 -7
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +0 -210
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +0 -54
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +0 -4
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +0 -55
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +0 -30
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +0 -206
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +0 -106
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +0 -19
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +0 -356
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +0 -297
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +0 -60
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +0 -18
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +0 -28
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +0 -68
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +0 -106
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +0 -51
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +0 -6
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +0 -35
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +0 -37
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +0 -40
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +0 -37
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +0 -52
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +0 -35
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +0 -24
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +0 -14
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +0 -70
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +0 -26
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +0 -36
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +0 -19
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +0 -61
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +0 -42
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +0 -35
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +0 -33
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +0 -9
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +0 -34
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +0 -34
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +0 -102
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +0 -14
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +0 -21
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +0 -19
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +0 -20
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +0 -26
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +0 -25
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +0 -32
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +0 -34
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +0 -13
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +0 -52
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +0 -54
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +0 -33
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +0 -42
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +0 -95
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +0 -77
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +0 -17
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +0 -28
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +0 -11
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +0 -11
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +0 -63
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +0 -94
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +0 -23
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +0 -30
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +0 -14
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +0 -24
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +0 -394
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +0 -29
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +0 -120
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +0 -28
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +0 -17
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +0 -246
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +0 -20
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +0 -457
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +0 -8
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +0 -22
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +0 -18
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +0 -11
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +0 -11
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +0 -4
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +0 -4
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +0 -8
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +0 -26
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +0 -7
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +0 -10
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +0 -18
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +0 -30
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +0 -16
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +0 -9
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +0 -31
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +0 -21
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +0 -31
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +0 -5
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +0 -12
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +0 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +0 -3
- package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +0 -31
- package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +0 -74
- package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +0 -150
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +0 -766
- package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +0 -327
- package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +0 -309
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +0 -1093
- package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +0 -94
- package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +0 -1329
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +0 -153
- package/dist/extensions/pi-zentui/extensions/zentui/accent-rail-layout-patch.ts +0 -457
- package/dist/extensions/pi-zentui/test/accent-rail-layout-patch.test.ts +0 -669
- package/dist/extensions/pi-zentui/test/thinking-experimental-docs.test.ts +0 -51
- package/dist/modes/interactive/components/daxnuts.d.ts +0 -22
- package/dist/modes/interactive/components/daxnuts.js +0 -139
- /package/dist/core/{agent-session-auto-handoff.test.d.ts → agent-session-custom-tools.test.d.ts} +0 -0
- /package/dist/{core → extensions}/llama/huggingface.d.ts +0 -0
- /package/dist/{core → extensions}/llama/huggingface.js +0 -0
- /package/dist/{core → extensions}/llama/index.d.ts +0 -0
- /package/dist/{core → extensions}/llama/ui.d.ts +0 -0
- /package/dist/{core → extensions}/llama/ui.js +0 -0
- /package/dist/{core/settings-manager-auto-handoff.test.d.ts → modes/rpc/intercom-bridge.test.d.ts} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Unit tests for auto-consolidation — triggerConsolidation and /memory-consolidate command.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { describe, it, beforeEach, before, after } from "node:test";
|
|
5
|
+
import { describe, it, beforeEach, afterEach, before, after } from "node:test";
|
|
6
6
|
import assert from "node:assert/strict";
|
|
7
7
|
import { readFileSync } from "node:fs";
|
|
8
8
|
import * as fs from "node:fs/promises";
|
|
@@ -12,22 +12,30 @@ import { registerConsolidateCommand, triggerConsolidation } from "../../src/hand
|
|
|
12
12
|
import { resolveWatchedChildPiInvocation } from "../../src/handlers/pi-child-process.js";
|
|
13
13
|
import { MemoryStore } from "../../src/store/memory-store.js";
|
|
14
14
|
import { AtomicLockCoordinator } from "../../src/store/atomic-lock-coordinator.js";
|
|
15
|
-
import {
|
|
15
|
+
import { DatabaseManager } from "../../src/store/db.js";
|
|
16
|
+
import { addMemory, recordSearchHits } from "../../src/store/sqlite-memory-store.js";
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_CONSOLIDATION_CHUNK_CHARS,
|
|
19
|
+
MAX_CONSOLIDATION_ROUNDS,
|
|
20
|
+
DEFAULT_CONSOLIDATION_TIMEOUT_MS,
|
|
21
|
+
ENTRY_DELIMITER,
|
|
22
|
+
} from "../../src/constants.js";
|
|
23
|
+
import { takeChunk } from "../../src/handlers/auto-consolidate.js";
|
|
16
24
|
|
|
17
25
|
// ─── Mock infrastructure ───
|
|
18
26
|
|
|
19
27
|
let execCalls: any[];
|
|
20
28
|
let directCalls: unknown[][];
|
|
21
29
|
|
|
22
|
-
const directTransportLlmConfig = { reviewTransport: "direct" as const };
|
|
30
|
+
const directTransportLlmConfig = { reviewTransport: "direct" as const, consolidationChunking: true };
|
|
23
31
|
|
|
24
32
|
function createDirectCtx(): { model: unknown; modelRegistry: unknown; _tag: string } {
|
|
25
33
|
return { model: {}, modelRegistry: {}, _tag: "consolidation-direct-ctx" };
|
|
26
34
|
}
|
|
27
35
|
|
|
28
36
|
function makeDirectDeps(
|
|
29
|
-
result: { ok: boolean; appliedCount: number } | "throw",
|
|
30
|
-
): { runDirectMemoryCompletion: (...args: unknown[]) => Promise<{ ok: boolean; appliedCount: number }> } {
|
|
37
|
+
result: { ok: boolean; appliedCount: number; fallbackReason?: string } | "throw",
|
|
38
|
+
): { runDirectMemoryCompletion: (...args: unknown[]) => Promise<{ ok: boolean; appliedCount: number; fallbackReason?: string }> } {
|
|
31
39
|
return {
|
|
32
40
|
runDirectMemoryCompletion: async (...args: unknown[]) => {
|
|
33
41
|
directCalls.push(args);
|
|
@@ -94,6 +102,11 @@ const mockStore = {
|
|
|
94
102
|
getAllFailureEntries: () => ["failure lesson 1", "failure lesson 2"],
|
|
95
103
|
getStorageIdentity: async (target: string) => path.join("mock-store", target),
|
|
96
104
|
loadFromDisk: async () => {},
|
|
105
|
+
// Mechanics tests exercise the subprocess handshake, so the fixture store
|
|
106
|
+
// reports itself over its capacity goal — a healthy store would clean-no-op
|
|
107
|
+
// before spawning a child.
|
|
108
|
+
capacityGoal: () => 10,
|
|
109
|
+
capacityUsage: () => 1000,
|
|
97
110
|
} as any;
|
|
98
111
|
|
|
99
112
|
async function settle(ms = 10) {
|
|
@@ -139,13 +152,18 @@ async function runManualConsolidate(timeoutMs?: number): Promise<void> {
|
|
|
139
152
|
// ─── Tests ───
|
|
140
153
|
|
|
141
154
|
describe("triggerConsolidation", () => {
|
|
142
|
-
beforeEach(() => {
|
|
155
|
+
beforeEach(async () => {
|
|
143
156
|
execCalls = [];
|
|
157
|
+
// Fresh lock dir per test: the shared lock file couples otherwise
|
|
158
|
+
// independent tests through lease-release timing on Windows.
|
|
159
|
+
process.env.PI_HERMES_CONSOLIDATION_LOCK_DIR = await fs.mkdtemp(
|
|
160
|
+
path.join(os.tmpdir(), "pi-consolidation-locks-"),
|
|
161
|
+
);
|
|
144
162
|
});
|
|
145
163
|
|
|
146
164
|
it("builds prompt with current entries and calls pi.exec", async () => {
|
|
147
165
|
const pi = createMockPi();
|
|
148
|
-
await triggerConsolidation(pi, mockStore, "memory");
|
|
166
|
+
await triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
149
167
|
|
|
150
168
|
assert.strictEqual(execCalls.length, 1, "should call pi.exec once");
|
|
151
169
|
const args = logicalChildArgs(execCalls[0]);
|
|
@@ -157,12 +175,12 @@ describe("triggerConsolidation", () => {
|
|
|
157
175
|
assert.ok(prompt.includes("memory"), "prompt should reference target");
|
|
158
176
|
});
|
|
159
177
|
|
|
160
|
-
it("
|
|
178
|
+
it("reports an honest no-shrink result when the child exits 0 without shrinking", async () => {
|
|
161
179
|
const pi = createMockPi({ code: 0, stdout: "Done", stderr: "" });
|
|
162
|
-
const result = await triggerConsolidation(pi, mockStore, "memory");
|
|
180
|
+
const result = await triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
163
181
|
|
|
164
|
-
assert.strictEqual(result.consolidated,
|
|
165
|
-
assert.
|
|
182
|
+
assert.strictEqual(result.consolidated, false, "exit 0 without shrinking is not success");
|
|
183
|
+
assert.ok(result.error?.includes("could not shrink the remaining"), result.error);
|
|
166
184
|
});
|
|
167
185
|
|
|
168
186
|
it("clears a failed release before the next consolidation", async () => {
|
|
@@ -177,12 +195,12 @@ describe("triggerConsolidation", () => {
|
|
|
177
195
|
|
|
178
196
|
try {
|
|
179
197
|
const pi = createMockPi();
|
|
180
|
-
const first = await triggerConsolidation(pi, mockStore, "memory");
|
|
181
|
-
const second = await triggerConsolidation(pi, mockStore, "memory");
|
|
198
|
+
const first = await triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
199
|
+
const second = await triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
182
200
|
|
|
183
|
-
assert.strictEqual(first.consolidated,
|
|
184
|
-
assert.strictEqual(second.consolidated,
|
|
185
|
-
assert.strictEqual(execCalls.length, 2);
|
|
201
|
+
assert.strictEqual(first.consolidated, false, "a no-shrink child is honestly reported");
|
|
202
|
+
assert.strictEqual(second.consolidated, false);
|
|
203
|
+
assert.strictEqual(execCalls.length, 2, "release clearing must not block the next consolidation");
|
|
186
204
|
assert.ok(deleteAttempts >= 4);
|
|
187
205
|
} finally {
|
|
188
206
|
prototype.deleteOwnedLock = originalDeleteOwnedLock;
|
|
@@ -206,9 +224,9 @@ describe("triggerConsolidation", () => {
|
|
|
206
224
|
} as any;
|
|
207
225
|
|
|
208
226
|
await withLockWait("0", async () => {
|
|
209
|
-
const first = triggerConsolidation(pi, mockStore, "memory");
|
|
227
|
+
const first = triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
210
228
|
await execStarted;
|
|
211
|
-
const second = triggerConsolidation(pi, mockStore, "memory");
|
|
229
|
+
const second = triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
212
230
|
const raced = await Promise.race([
|
|
213
231
|
second.then((result) => ({ result })),
|
|
214
232
|
settle(100).then(() => ({ timeout: true as const })),
|
|
@@ -244,16 +262,20 @@ describe("triggerConsolidation", () => {
|
|
|
244
262
|
} as any;
|
|
245
263
|
|
|
246
264
|
await withLockWait("2000", async () => {
|
|
247
|
-
const first = triggerConsolidation(pi, mockStore, "memory");
|
|
265
|
+
const first = triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
248
266
|
await firstExecStarted;
|
|
249
|
-
const second = triggerConsolidation(pi, mockStore, "memory");
|
|
267
|
+
const second = triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
250
268
|
await settle(20);
|
|
251
269
|
releaseExecs.forEach((release) => release());
|
|
252
270
|
|
|
253
271
|
const [firstResult, secondResult] = await Promise.all([first, second]);
|
|
254
|
-
|
|
255
|
-
|
|
272
|
+
// The mock children never shrink the store, so both runs honestly
|
|
273
|
+
// report a no-shrink partial — the mechanic under test is that the
|
|
274
|
+
// queued caller WAITS and runs its own child instead of hard-failing.
|
|
275
|
+
assert.strictEqual(firstResult.consolidated, false);
|
|
276
|
+
assert.strictEqual(secondResult.consolidated, false, "the queued caller should run its own round, not hard-fail");
|
|
256
277
|
assert.strictEqual(secondResult.deferred, undefined);
|
|
278
|
+
assert.ok(secondResult.error?.includes("could not shrink the remaining"), secondResult.error);
|
|
257
279
|
assert.strictEqual(execCalls.length, 2);
|
|
258
280
|
});
|
|
259
281
|
});
|
|
@@ -266,6 +288,8 @@ describe("triggerConsolidation", () => {
|
|
|
266
288
|
getAllFailureEntries: () => [],
|
|
267
289
|
getStorageIdentity: async (target: string) => path.join("shrinking-store", target),
|
|
268
290
|
loadFromDisk: async () => { entries = ["merged"]; },
|
|
291
|
+
capacityGoal: () => 10,
|
|
292
|
+
capacityUsage: () => entries.join(ENTRY_DELIMITER).length,
|
|
269
293
|
} as any;
|
|
270
294
|
|
|
271
295
|
const releaseExecs: Array<() => void> = [];
|
|
@@ -284,9 +308,9 @@ describe("triggerConsolidation", () => {
|
|
|
284
308
|
} as any;
|
|
285
309
|
|
|
286
310
|
await withLockWait("2000", async () => {
|
|
287
|
-
const first = triggerConsolidation(pi, shrinkingStore, "memory");
|
|
311
|
+
const first = triggerConsolidation(pi, shrinkingStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
288
312
|
await firstExecStarted;
|
|
289
|
-
const second = triggerConsolidation(pi, shrinkingStore, "memory");
|
|
313
|
+
const second = triggerConsolidation(pi, shrinkingStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
290
314
|
await settle(20);
|
|
291
315
|
releaseExecs.forEach((release) => release());
|
|
292
316
|
|
|
@@ -302,8 +326,17 @@ describe("triggerConsolidation", () => {
|
|
|
302
326
|
memoryDir: path.join(root, name),
|
|
303
327
|
memoryCharLimit: 5_000,
|
|
304
328
|
userCharLimit: 5_000,
|
|
329
|
+
memoryMode: "policy-only",
|
|
305
330
|
} as any));
|
|
306
331
|
await Promise.all(stores.map((store) => store.loadFromDisk()));
|
|
332
|
+
// Seed both stores over their capacity goal — a healthy store is a clean
|
|
333
|
+
// no-op and would never reach the concurrent-children mechanic under test.
|
|
334
|
+
for (const store of stores) {
|
|
335
|
+
for (let i = 0; i < 10; i++) {
|
|
336
|
+
const r = await store.add("memory", `concurrent-store-entry-${i}-${"x".repeat(580)}`);
|
|
337
|
+
assert.ok(r.success, `seed ${i} should succeed`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
307
340
|
|
|
308
341
|
let started = 0;
|
|
309
342
|
let markFirstStarted!: () => void;
|
|
@@ -316,7 +349,10 @@ describe("triggerConsolidation", () => {
|
|
|
316
349
|
started++;
|
|
317
350
|
if (started === 1) markFirstStarted();
|
|
318
351
|
if (started === 2) markBothStarted();
|
|
319
|
-
|
|
352
|
+
if (started <= 2) {
|
|
353
|
+
// Round 1 of each store hangs until both children have started.
|
|
354
|
+
await new Promise<void>((resolve) => { releases.push(resolve); });
|
|
355
|
+
}
|
|
320
356
|
return { code: 0, stdout: "Done", stderr: "" };
|
|
321
357
|
},
|
|
322
358
|
} as any;
|
|
@@ -334,16 +370,16 @@ describe("triggerConsolidation", () => {
|
|
|
334
370
|
await Promise.allSettled([first, second]);
|
|
335
371
|
|
|
336
372
|
assert.strictEqual(raced, "both-started");
|
|
337
|
-
assert.
|
|
373
|
+
assert.ok(started >= 2, "both distinct stores must run their own child");
|
|
338
374
|
} finally {
|
|
339
375
|
releases.forEach((release) => release());
|
|
340
|
-
await fs.rm(root, { recursive: true, force: true });
|
|
376
|
+
await fs.rm(root, { recursive: true, force: true }).catch(() => {});
|
|
341
377
|
}
|
|
342
378
|
});
|
|
343
379
|
|
|
344
380
|
it("returns { consolidated: false } on failure (non-zero exit code)", async () => {
|
|
345
381
|
const pi = createMockPi({ code: 1, stdout: "", stderr: "some error" });
|
|
346
|
-
const result = await triggerConsolidation(pi, mockStore, "memory");
|
|
382
|
+
const result = await triggerConsolidation(pi, mockStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
347
383
|
|
|
348
384
|
assert.strictEqual(result.consolidated, false);
|
|
349
385
|
assert.ok(result.error, "should have error message");
|
|
@@ -440,10 +476,10 @@ it("returns { consolidated: false } when pi.exec throws", async () => {
|
|
|
440
476
|
undefined,
|
|
441
477
|
60000,
|
|
442
478
|
"memory",
|
|
443
|
-
{ llmModelOverride: "openrouter/deepseek/deepseek-v4-flash" },
|
|
479
|
+
{ llmModelOverride: "openrouter/deepseek/deepseek-v4-flash", consolidationChunking: true },
|
|
444
480
|
);
|
|
445
481
|
|
|
446
|
-
assert.strictEqual(result.consolidated,
|
|
482
|
+
assert.strictEqual(result.consolidated, false, "the mock child shrinks nothing — reported honestly");
|
|
447
483
|
assert.strictEqual(execCalls.length, 2, "should retry once without overrides");
|
|
448
484
|
assert.deepStrictEqual(logicalChildArgs(execCalls[0]).slice(0, 6), [
|
|
449
485
|
"-p",
|
|
@@ -478,14 +514,14 @@ it("returns { consolidated: false } when pi.exec throws", async () => {
|
|
|
478
514
|
undefined,
|
|
479
515
|
60000,
|
|
480
516
|
"memory",
|
|
481
|
-
{ llmModelOverride: "openrouter/deepseek/deepseek-v4-flash" },
|
|
517
|
+
{ llmModelOverride: "openrouter/deepseek/deepseek-v4-flash", consolidationChunking: true },
|
|
482
518
|
);
|
|
483
519
|
|
|
484
520
|
assert.strictEqual(result.consolidated, false);
|
|
485
521
|
assert.strictEqual(execCalls.length, 1, "should not retry generic consolidation failures");
|
|
486
522
|
});
|
|
487
523
|
|
|
488
|
-
it("handles empty entries
|
|
524
|
+
it("handles empty entries as a clean no-op", async () => {
|
|
489
525
|
const emptyStore = {
|
|
490
526
|
getMemoryEntries: () => [],
|
|
491
527
|
getUserEntries: () => [],
|
|
@@ -494,10 +530,11 @@ it("returns { consolidated: false } when pi.exec throws", async () => {
|
|
|
494
530
|
} as any;
|
|
495
531
|
|
|
496
532
|
const pi = createMockPi();
|
|
497
|
-
await triggerConsolidation(pi, emptyStore, "memory");
|
|
533
|
+
const result = await triggerConsolidation(pi, emptyStore, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
498
534
|
|
|
499
|
-
|
|
500
|
-
assert.
|
|
535
|
+
assert.strictEqual(execCalls.length, 0, "an empty store spawns no child");
|
|
536
|
+
assert.strictEqual(result.consolidated, true);
|
|
537
|
+
assert.strictEqual(result.rounds, 0);
|
|
501
538
|
});
|
|
502
539
|
|
|
503
540
|
describe("direct transport", () => {
|
|
@@ -551,11 +588,38 @@ it("returns { consolidated: false } when pi.exec throws", async () => {
|
|
|
551
588
|
makeDirectDeps({ ok: true, appliedCount: 0 }),
|
|
552
589
|
);
|
|
553
590
|
|
|
554
|
-
assert.strictEqual(result.consolidated,
|
|
591
|
+
assert.strictEqual(result.consolidated, false, "the fallback child shrank nothing — reported honestly");
|
|
592
|
+
assert.ok(result.error?.includes("could not shrink the remaining"), result.error);
|
|
555
593
|
assert.strictEqual(directCalls.length, 1);
|
|
556
594
|
assert.strictEqual(execCalls.length, 1, "empty direct result must fall back to subprocess");
|
|
557
595
|
});
|
|
558
596
|
|
|
597
|
+
it("returns terminal on empty_response without acquiring the lock or spawning a child (#235)", async () => {
|
|
598
|
+
const pi = createMockPi();
|
|
599
|
+
const directCtx = createDirectCtx();
|
|
600
|
+
const result = await triggerConsolidation(
|
|
601
|
+
pi,
|
|
602
|
+
mockStore,
|
|
603
|
+
"memory",
|
|
604
|
+
undefined,
|
|
605
|
+
60000,
|
|
606
|
+
"memory",
|
|
607
|
+
directTransportLlmConfig,
|
|
608
|
+
directCtx,
|
|
609
|
+
null,
|
|
610
|
+
null,
|
|
611
|
+
makeDirectDeps({ ok: true, appliedCount: 0, fallbackReason: "empty_response" }),
|
|
612
|
+
);
|
|
613
|
+
|
|
614
|
+
// An empty completion is terminal: the subprocess child would run the
|
|
615
|
+
// same model against the same server-side thinking default and fail
|
|
616
|
+
// the same way (#197), so it must not even be attempted.
|
|
617
|
+
assert.strictEqual(result.consolidated, false);
|
|
618
|
+
assert.match(result.error ?? "", /returned an empty completion; no consolidation attempted/);
|
|
619
|
+
assert.strictEqual(directCalls.length, 1);
|
|
620
|
+
assert.strictEqual(execCalls.length, 0, "empty completion is terminal — no subprocess");
|
|
621
|
+
});
|
|
622
|
+
|
|
559
623
|
it("falls back to subprocess when direct transport returns ok false", async () => {
|
|
560
624
|
const pi = createMockPi();
|
|
561
625
|
const directCtx = createDirectCtx();
|
|
@@ -573,7 +637,7 @@ it("returns { consolidated: false } when pi.exec throws", async () => {
|
|
|
573
637
|
makeDirectDeps({ ok: false, appliedCount: 0 }),
|
|
574
638
|
);
|
|
575
639
|
|
|
576
|
-
assert.strictEqual(result.consolidated,
|
|
640
|
+
assert.strictEqual(result.consolidated, false, "the fallback child shrank nothing — reported honestly");
|
|
577
641
|
assert.strictEqual(directCalls.length, 1);
|
|
578
642
|
assert.strictEqual(execCalls.length, 1, "failed direct result must fall back to subprocess");
|
|
579
643
|
});
|
|
@@ -595,7 +659,7 @@ it("returns { consolidated: false } when pi.exec throws", async () => {
|
|
|
595
659
|
makeDirectDeps("throw"),
|
|
596
660
|
);
|
|
597
661
|
|
|
598
|
-
assert.strictEqual(result.consolidated,
|
|
662
|
+
assert.strictEqual(result.consolidated, false, "the fallback child shrank nothing — reported honestly");
|
|
599
663
|
assert.strictEqual(directCalls.length, 1);
|
|
600
664
|
assert.strictEqual(execCalls.length, 1, "thrown direct error must fall back to subprocess");
|
|
601
665
|
});
|
|
@@ -616,7 +680,7 @@ it("returns { consolidated: false } when pi.exec throws", async () => {
|
|
|
616
680
|
makeDirectDeps({ ok: true, appliedCount: 3 }),
|
|
617
681
|
);
|
|
618
682
|
|
|
619
|
-
assert.strictEqual(result.consolidated,
|
|
683
|
+
assert.strictEqual(result.consolidated, false, "the fallback child shrank nothing — reported honestly");
|
|
620
684
|
assert.strictEqual(directCalls.length, 0, "direct path must be skipped without directCtx");
|
|
621
685
|
assert.strictEqual(execCalls.length, 1, "subprocess-only path must still consolidate");
|
|
622
686
|
});
|
|
@@ -651,9 +715,11 @@ describe("registerConsolidateCommand", () => {
|
|
|
651
715
|
getUserEntries: () => [],
|
|
652
716
|
getStorageIdentity: async (target: string) => path.join("project-store", target),
|
|
653
717
|
loadFromDisk: async () => { projectReloaded = true; },
|
|
718
|
+
capacityGoal: () => 10,
|
|
719
|
+
capacityUsage: () => 100,
|
|
654
720
|
} as any;
|
|
655
721
|
|
|
656
|
-
registerConsolidateCommand(pi, mockStore, 60000, projectStore, "demo-project");
|
|
722
|
+
registerConsolidateCommand(pi, mockStore, 60000, projectStore, "demo-project", { consolidationChunking: true });
|
|
657
723
|
await handler({}, {
|
|
658
724
|
signal: undefined,
|
|
659
725
|
ui: {
|
|
@@ -677,8 +743,8 @@ describe("registerConsolidateCommand", () => {
|
|
|
677
743
|
assert.ok(statuses.some(([key, text]) => key === "pi-hermes-memory:consolidation" && text?.includes("Consolidating memory")), "should publish busy progress");
|
|
678
744
|
assert.deepStrictEqual(statuses.at(-1), ["pi-hermes-memory:consolidation", undefined], "should clear busy progress when done");
|
|
679
745
|
const finalNotification = notifications[notifications.length - 1] ?? "";
|
|
680
|
-
assert.ok(finalNotification.includes("failure:
|
|
681
|
-
assert.ok(finalNotification.includes("project:demo-project:
|
|
746
|
+
assert.ok(finalNotification.includes("failure: ❌"), "final notification should include the failure result");
|
|
747
|
+
assert.ok(finalNotification.includes("project:demo-project: ❌"), "final notification should include the project result");
|
|
682
748
|
});
|
|
683
749
|
|
|
684
750
|
it("passes the configured timeout through to the manual consolidate child", async () => {
|
|
@@ -987,4 +1053,1081 @@ describe("MemoryStore auto-consolidation integration", () => {
|
|
|
987
1053
|
"a successful-but-ineffective consolidation is not a consolidation failure",
|
|
988
1054
|
);
|
|
989
1055
|
});
|
|
1056
|
+
|
|
1057
|
+
it("add() surfaces a partial consolidation note when the retry still fails", async () => {
|
|
1058
|
+
const store = await storeWithConsolidator("partial", async () => (
|
|
1059
|
+
{ consolidated: true, partial: true, rounds: 1, error: "time budget exhausted" } as any
|
|
1060
|
+
));
|
|
1061
|
+
|
|
1062
|
+
const result = await store.add("memory", "b".repeat(20));
|
|
1063
|
+
|
|
1064
|
+
assert.ok(!result.success, "add should still fail when nothing was freed");
|
|
1065
|
+
assert.ok(
|
|
1066
|
+
result.error!.includes("Consolidation is incomplete: time budget exhausted"),
|
|
1067
|
+
result.error,
|
|
1068
|
+
);
|
|
1069
|
+
assert.ok(
|
|
1070
|
+
!result.error!.includes("attempted but failed"),
|
|
1071
|
+
"partial progress is not a consolidation failure",
|
|
1072
|
+
);
|
|
1073
|
+
});
|
|
1074
|
+
});
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
/** Simulate the child by rewriting the store markdown file directly. */
|
|
1078
|
+
async function removeEntryFromDisk(store: MemoryStore, strippedText: string): Promise<void> {
|
|
1079
|
+
const filePath = path.join((store as any).memoryDir, "MEMORY.md");
|
|
1080
|
+
const raw = await fs.readFile(filePath, "utf-8");
|
|
1081
|
+
const blocks = raw.split(ENTRY_DELIMITER);
|
|
1082
|
+
const marker = strippedText.slice(0, 40);
|
|
1083
|
+
const kept = blocks.filter((block) => !block.includes(marker));
|
|
1084
|
+
assert.ok(kept.length < blocks.length, `child should find entry '${marker}' in the store file`);
|
|
1085
|
+
await fs.writeFile(filePath, kept.join(ENTRY_DELIMITER), "utf-8");
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
function parsePromptBatch(prompt: string): string[] {
|
|
1089
|
+
const marker = "--- Current Memory Entries ---";
|
|
1090
|
+
const start = prompt.indexOf(marker);
|
|
1091
|
+
assert.ok(start >= 0, "prompt should contain the entries section");
|
|
1092
|
+
const end = prompt.indexOf("Use memory_add", start);
|
|
1093
|
+
const body = prompt.slice(start + marker.length, end);
|
|
1094
|
+
return body
|
|
1095
|
+
.split(ENTRY_DELIMITER)
|
|
1096
|
+
.map((entry) => entry.trim())
|
|
1097
|
+
.filter((entry) => entry.length > 0 && entry !== "(empty)");
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
// ─── Chunked subprocess consolidation ───
|
|
1102
|
+
|
|
1103
|
+
describe("chunked subprocess consolidation", () => {
|
|
1104
|
+
let MEMORY_ROOT = "";
|
|
1105
|
+
let storeSeq = 0;
|
|
1106
|
+
|
|
1107
|
+
before(async () => {
|
|
1108
|
+
MEMORY_ROOT = await fs.mkdtemp(path.join(os.tmpdir(), "pi-consolidation-chunk-"));
|
|
1109
|
+
});
|
|
1110
|
+
|
|
1111
|
+
after(async () => {
|
|
1112
|
+
try { await fs.rm(MEMORY_ROOT, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
beforeEach(() => {
|
|
1116
|
+
execCalls = [];
|
|
1117
|
+
});
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* A real on-disk store in its OWN fresh directory (shared dirs leak entries
|
|
1121
|
+
* between tests and change the batch math), with a realistic 5000-char
|
|
1122
|
+
* capacity goal. policy-only lets seeds exceed the cap so the chunked path
|
|
1123
|
+
* has work to do. Entries are uniquely marked because memory-tool removal
|
|
1124
|
+
* matches by normalized substring — look-alike filler would cross-match.
|
|
1125
|
+
*/
|
|
1126
|
+
async function makeOverChunkStore(entryCount: number, entryChars = 600, memoryCharLimit = 5000): Promise<MemoryStore> {
|
|
1127
|
+
const memoryDir = path.join(MEMORY_ROOT, `store-${++storeSeq}`);
|
|
1128
|
+
const store = new MemoryStore({
|
|
1129
|
+
memoryCharLimit,
|
|
1130
|
+
userCharLimit: 100,
|
|
1131
|
+
memoryMode: "policy-only",
|
|
1132
|
+
nudgeInterval: 10,
|
|
1133
|
+
reviewEnabled: false,
|
|
1134
|
+
flushOnCompact: false,
|
|
1135
|
+
flushOnShutdown: false,
|
|
1136
|
+
flushMinTurns: 6,
|
|
1137
|
+
autoConsolidate: false,
|
|
1138
|
+
correctionDetection: false,
|
|
1139
|
+
nudgeToolCalls: 15,
|
|
1140
|
+
memoryDir,
|
|
1141
|
+
});
|
|
1142
|
+
await store.loadFromDisk();
|
|
1143
|
+
for (let i = 0; i < entryCount; i++) {
|
|
1144
|
+
const filler = "y".repeat(Math.max(0, entryChars - `chunk-entry-${i}-`.length));
|
|
1145
|
+
const result = await store.add("memory", `chunk-entry-${i}-${filler}`);
|
|
1146
|
+
assert.ok(result.success, `seed add #${i} should succeed`);
|
|
1147
|
+
}
|
|
1148
|
+
return store;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* Mock child that behaves like a real `pi -p` consolidation subprocess: it
|
|
1153
|
+
* reads its prompt, edits the store FILE on disk (not the parent's memory —
|
|
1154
|
+
* the parent's reload must observe what a separate process wrote), and
|
|
1155
|
+
* exits. Scripted per round.
|
|
1156
|
+
*/
|
|
1157
|
+
function createChunkedChildPi(
|
|
1158
|
+
store: MemoryStore,
|
|
1159
|
+
script: Array<"shrink" | "noop" | "fail">,
|
|
1160
|
+
) {
|
|
1161
|
+
let round = 0;
|
|
1162
|
+
return {
|
|
1163
|
+
on: () => {},
|
|
1164
|
+
exec: async (...args: any[]) => {
|
|
1165
|
+
execCalls.push(captureExecArgs(args));
|
|
1166
|
+
const action = script[Math.min(round, script.length - 1)];
|
|
1167
|
+
round++;
|
|
1168
|
+
if (action === "fail") {
|
|
1169
|
+
return { code: 124, stdout: "", stderr: "", killed: true };
|
|
1170
|
+
}
|
|
1171
|
+
if (action === "shrink") {
|
|
1172
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1173
|
+
const batch = parsePromptBatch(prompt);
|
|
1174
|
+
assert.ok(batch.length > 0, "child prompt should contain at least one entry");
|
|
1175
|
+
await removeEntryFromDisk(store, batch[0]);
|
|
1176
|
+
}
|
|
1177
|
+
return { code: 0, stdout: "Consolidated", stderr: "" };
|
|
1178
|
+
},
|
|
1179
|
+
registerTool: () => {},
|
|
1180
|
+
registerCommand: () => {},
|
|
1181
|
+
} as any;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
function batchFromExecCall(call: any[]): string[] {
|
|
1185
|
+
return parsePromptBatch(call[1].at(-1) as string);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
it("treats a small healthy store as a clean no-op", async () => {
|
|
1189
|
+
// Tiny store, well under its capacity goal: nothing to shrink, no child
|
|
1190
|
+
// spawned, clean success (rounds: 0) — not a ❌ failure.
|
|
1191
|
+
const store = await makeOverChunkStore(2, 20);
|
|
1192
|
+
const pi = createMockPi();
|
|
1193
|
+
|
|
1194
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1195
|
+
|
|
1196
|
+
assert.strictEqual(execCalls.length, 0, "a healthy store spawns no child");
|
|
1197
|
+
assert.strictEqual(result.consolidated, true);
|
|
1198
|
+
assert.strictEqual(result.rounds, 0);
|
|
1199
|
+
assert.strictEqual(result.error, undefined);
|
|
1200
|
+
});
|
|
1201
|
+
|
|
1202
|
+
it("runs small over-goal stores as one unscoped decisive round", async () => {
|
|
1203
|
+
// 6 entries ≈ 3879 encoded chars: under the 4000 chunk size (one prompt)
|
|
1204
|
+
// but over the 3000 capacity goal — the legacy single-shot call, unscoped.
|
|
1205
|
+
const store = await makeOverChunkStore(6, 600, 3000);
|
|
1206
|
+
const pi = createChunkedChildPi(store, ["shrink"]);
|
|
1207
|
+
|
|
1208
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1209
|
+
|
|
1210
|
+
assert.strictEqual(execCalls.length, 1, "a store that fits one prompt gets exactly one child");
|
|
1211
|
+
const prompt = childPrompt(execCalls[0]);
|
|
1212
|
+
assert.ok(prompt.includes("chunk-entry-0") && prompt.includes("chunk-entry-5"), "decisive prompt carries the whole store");
|
|
1213
|
+
assert.ok(!prompt.includes("covers ONLY the entries listed above"), "decisive round is unscoped");
|
|
1214
|
+
assert.strictEqual(result.consolidated, true);
|
|
1215
|
+
assert.strictEqual(result.rounds, 1);
|
|
1216
|
+
assert.strictEqual(result.partial, true, "still over the goal after one round — visible, not silent");
|
|
1217
|
+
});
|
|
1218
|
+
|
|
1219
|
+
it("reports a clean single-round run when the decisive round reaches the goal", async () => {
|
|
1220
|
+
const store = await makeOverChunkStore(6, 600, 3000);
|
|
1221
|
+
// Decisive round merges two entries away → 4 entries ≈ 2585 chars ≤ goal.
|
|
1222
|
+
const pi: any = {
|
|
1223
|
+
on: () => {},
|
|
1224
|
+
exec: async (...args: any[]) => {
|
|
1225
|
+
execCalls.push(captureExecArgs(args));
|
|
1226
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1227
|
+
const batch = parsePromptBatch(prompt);
|
|
1228
|
+
await removeEntryFromDisk(store, batch[0]);
|
|
1229
|
+
await removeEntryFromDisk(store, batch[1]);
|
|
1230
|
+
return { code: 0, stdout: "Consolidated", stderr: "" };
|
|
1231
|
+
},
|
|
1232
|
+
registerTool: () => {},
|
|
1233
|
+
registerCommand: () => {},
|
|
1234
|
+
};
|
|
1235
|
+
|
|
1236
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1237
|
+
|
|
1238
|
+
assert.strictEqual(execCalls.length, 1);
|
|
1239
|
+
assert.strictEqual(result.consolidated, true);
|
|
1240
|
+
assert.strictEqual(result.partial, false, "goal met, no failure — a clean run");
|
|
1241
|
+
assert.strictEqual(result.error, undefined);
|
|
1242
|
+
assert.strictEqual(store.getMemoryEntries().length, 4);
|
|
1243
|
+
});
|
|
1244
|
+
|
|
1245
|
+
it("treats an over-chunk but under-goal store as a clean no-op (cap units, not prompt units)", async () => {
|
|
1246
|
+
// 7 entries ≈ 4526 ENCODED chars: over the 4000-char prompt budget but
|
|
1247
|
+
// UNDER the 5000-char capacity goal measured in cap units (encoded
|
|
1248
|
+
// entries). 8 entries (≈ 5173) would cross the goal and run rounds.
|
|
1249
|
+
const store = await makeOverChunkStore(7);
|
|
1250
|
+
const pi = createChunkedChildPi(store, ["shrink"]);
|
|
1251
|
+
|
|
1252
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1253
|
+
|
|
1254
|
+
assert.strictEqual(execCalls.length, 0, "nothing needs to shrink toward the capacity goal");
|
|
1255
|
+
assert.strictEqual(result.consolidated, true);
|
|
1256
|
+
assert.strictEqual(result.rounds, 0);
|
|
1257
|
+
assert.strictEqual(result.error, undefined);
|
|
1258
|
+
assert.strictEqual(store.getMemoryEntries().length, 7);
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
it("completes an over-goal store in bounded rounds with the default per-round timeout", async () => {
|
|
1262
|
+
const store = await makeOverChunkStore(10); // ≈ 6367 encoded chars > 5000 goal
|
|
1263
|
+
const pi = createChunkedChildPi(store, ["shrink", "shrink", "shrink"]);
|
|
1264
|
+
|
|
1265
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1266
|
+
|
|
1267
|
+
// Each round removes one entry (−647 encoded chars): 6367 → 5730 → 5093 →
|
|
1268
|
+
// 4456 ≤ goal. The walk advances past each consumed slice.
|
|
1269
|
+
assert.strictEqual(execCalls.length, 3);
|
|
1270
|
+
assert.strictEqual(result.consolidated, true);
|
|
1271
|
+
assert.strictEqual(result.rounds, 3);
|
|
1272
|
+
assert.ok(!result.partial, "goal met with no failure is a clean run");
|
|
1273
|
+
assert.strictEqual(result.error, undefined, "goal met with no failure carries no error");
|
|
1274
|
+
assert.strictEqual(store.getMemoryEntries().length, 7);
|
|
1275
|
+
for (const call of execCalls) {
|
|
1276
|
+
const batch = batchFromExecCall(call);
|
|
1277
|
+
const batchChars = batch.join(ENTRY_DELIMITER).length;
|
|
1278
|
+
assert.ok(batchChars <= DEFAULT_CONSOLIDATION_CHUNK_CHARS, `round prompt ${batchChars} must fit one chunk`);
|
|
1279
|
+
// Rounds share the trigger budget: round 1 gets the full per-round
|
|
1280
|
+
// timeout, later rounds get what remains (still ≥ the round floor).
|
|
1281
|
+
const roundTimeout = Number(call[1][1]);
|
|
1282
|
+
assert.ok(roundTimeout > 0 && roundTimeout <= DEFAULT_CONSOLIDATION_TIMEOUT_MS, `round timeout ${roundTimeout}`);
|
|
1283
|
+
assert.strictEqual(call[2].timeout, roundTimeout + 5000);
|
|
1284
|
+
}
|
|
1285
|
+
});
|
|
1286
|
+
|
|
1287
|
+
it("keeps walking forward: round 2 slices after round 1's slice, not from the top", async () => {
|
|
1288
|
+
const store = await makeOverChunkStore(10);
|
|
1289
|
+
const batches: string[][] = [];
|
|
1290
|
+
const pi: any = {
|
|
1291
|
+
on: () => {},
|
|
1292
|
+
exec: async (...args: any[]) => {
|
|
1293
|
+
execCalls.push(captureExecArgs(args));
|
|
1294
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1295
|
+
const batch = parsePromptBatch(prompt);
|
|
1296
|
+
batches.push(batch);
|
|
1297
|
+
await removeEntryFromDisk(store, batch[0]);
|
|
1298
|
+
return { code: 0, stdout: "Consolidated", stderr: "" };
|
|
1299
|
+
},
|
|
1300
|
+
registerTool: () => {},
|
|
1301
|
+
registerCommand: () => {},
|
|
1302
|
+
};
|
|
1303
|
+
|
|
1304
|
+
await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1305
|
+
|
|
1306
|
+
assert.ok(batches.length >= 2, "expected multiple rounds");
|
|
1307
|
+
// The discriminating check vs an offset-reset mutant: the walk must move
|
|
1308
|
+
// FORWARD — round 2 starts after round 1's slice. Later rounds may revisit
|
|
1309
|
+
// entries after index shifts (documented approximation).
|
|
1310
|
+
const overlap = batches[1].filter((entry) => batches[0].includes(entry));
|
|
1311
|
+
assert.strictEqual(overlap.length, 0, `round 2 re-processed ${overlap.length} entries from round 1 — the walk must advance`);
|
|
1312
|
+
});
|
|
1313
|
+
|
|
1314
|
+
it("resumes after a killed round: partial progress persists and a second trigger finishes", async () => {
|
|
1315
|
+
const store = await makeOverChunkStore(11); // ≈ 6663 chars > 5000 goal
|
|
1316
|
+
const originalEntries = [...store.getMemoryEntries()];
|
|
1317
|
+
const pi = createChunkedChildPi(store, ["shrink", "fail"]);
|
|
1318
|
+
|
|
1319
|
+
const first = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1320
|
+
consolidationChunkChars: 2500,
|
|
1321
|
+
consolidationChunking: true,
|
|
1322
|
+
consolidationChunking: true,
|
|
1323
|
+
});
|
|
1324
|
+
|
|
1325
|
+
assert.strictEqual(execCalls.length, 2, "round 1 succeeds, round 2 is killed");
|
|
1326
|
+
assert.strictEqual(first.consolidated, true, "one completed round is real progress on disk");
|
|
1327
|
+
assert.strictEqual(first.partial, true, "a killed run must not read as a clean success");
|
|
1328
|
+
assert.strictEqual(first.rounds, 1);
|
|
1329
|
+
assert.ok(first.error?.includes("terminated"), first.error);
|
|
1330
|
+
assert.ok(first.error?.includes("1 earlier round shrank the store"), first.error);
|
|
1331
|
+
assert.ok(first.error?.includes("chars over its 5000-char capacity goal"), first.error);
|
|
1332
|
+
assert.strictEqual(store.getMemoryEntries().length, 10);
|
|
1333
|
+
|
|
1334
|
+
// The retried add / next trigger resumes from current disk state and
|
|
1335
|
+
// finishes the job.
|
|
1336
|
+
execCalls = [];
|
|
1337
|
+
const second = await triggerConsolidation(
|
|
1338
|
+
createChunkedChildPi(store, ["shrink", "shrink"]),
|
|
1339
|
+
store,
|
|
1340
|
+
"memory",
|
|
1341
|
+
undefined,
|
|
1342
|
+
DEFAULT_CONSOLIDATION_TIMEOUT_MS,
|
|
1343
|
+
"memory",
|
|
1344
|
+
{ consolidationChunkChars: 2500, consolidationChunking: true },
|
|
1345
|
+
);
|
|
1346
|
+
|
|
1347
|
+
assert.strictEqual(second.consolidated, true);
|
|
1348
|
+
assert.strictEqual(second.error, undefined);
|
|
1349
|
+
assert.ok(!second.partial);
|
|
1350
|
+
assert.strictEqual(second.rounds, 3);
|
|
1351
|
+
const survivors = store.getMemoryEntries();
|
|
1352
|
+
assert.strictEqual(survivors.length, 7, "resume finishes the shrink below the capacity goal");
|
|
1353
|
+
const removed = originalEntries.filter((entry) => !survivors.includes(entry));
|
|
1354
|
+
assert.ok(
|
|
1355
|
+
originalEntries.every((entry) => survivors.includes(entry) || removed.includes(entry)),
|
|
1356
|
+
"no entry may vanish or be invented by chunking",
|
|
1357
|
+
);
|
|
1358
|
+
});
|
|
1359
|
+
|
|
1360
|
+
it("walks unshrinkable slices and reports the store still over its goal", async () => {
|
|
1361
|
+
const store = await makeOverChunkStore(9); // ≈ 5733 encoded chars > 5000 goal
|
|
1362
|
+
const pi = createChunkedChildPi(store, ["noop"]);
|
|
1363
|
+
|
|
1364
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1365
|
+
consolidationChunkChars: 2500,
|
|
1366
|
+
consolidationChunking: true,
|
|
1367
|
+
consolidationChunking: true,
|
|
1368
|
+
});
|
|
1369
|
+
|
|
1370
|
+
assert.strictEqual(execCalls.length, MAX_CONSOLIDATION_ROUNDS, "the round cap fires on a store that never shrinks");
|
|
1371
|
+
assert.strictEqual(result.consolidated, false, "nothing shrank — success must not be claimed");
|
|
1372
|
+
assert.ok(result.error?.includes("could not shrink the store toward its 5000-char capacity goal"), result.error);
|
|
1373
|
+
assert.ok(result.error?.includes("distinct facts"), result.error);
|
|
1374
|
+
assert.strictEqual(store.getMemoryEntries().length, 9, "a noop child must not lose entries");
|
|
1375
|
+
});
|
|
1376
|
+
|
|
1377
|
+
it("reports a first-round kill exactly like the single-shot path", async () => {
|
|
1378
|
+
const store = await makeOverChunkStore(9);
|
|
1379
|
+
const pi = createChunkedChildPi(store, ["fail"]);
|
|
1380
|
+
|
|
1381
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1382
|
+
consolidationChunkChars: 2500,
|
|
1383
|
+
consolidationChunking: true,
|
|
1384
|
+
consolidationChunking: true,
|
|
1385
|
+
});
|
|
1386
|
+
|
|
1387
|
+
assert.strictEqual(execCalls.length, 1);
|
|
1388
|
+
assert.strictEqual(result.consolidated, false);
|
|
1389
|
+
assert.strictEqual(result.partial, undefined);
|
|
1390
|
+
assert.ok(result.error?.includes("terminated"), result.error);
|
|
1391
|
+
});
|
|
1392
|
+
|
|
1393
|
+
it("reports out-of-scope deletions without resurrecting them", async () => {
|
|
1394
|
+
// The parent cannot tell a rogue child deletion from a legitimate
|
|
1395
|
+
// cross-slice dedup or a concurrent writer — so deletions outside the
|
|
1396
|
+
// slice are reported, never re-added (resurrection would ping-pong across
|
|
1397
|
+
// triggers and fights legitimate dedup, the #226 class).
|
|
1398
|
+
const store = await makeOverChunkStore(9); // ≈ 5451 chars
|
|
1399
|
+
const seeds = store.getMemoryEntries();
|
|
1400
|
+
const outOfScopeEntry = seeds[6];
|
|
1401
|
+
const pi = {
|
|
1402
|
+
on: () => {},
|
|
1403
|
+
exec: async (...args: any[]) => {
|
|
1404
|
+
execCalls.push(captureExecArgs(args));
|
|
1405
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1406
|
+
const batch = parsePromptBatch(prompt);
|
|
1407
|
+
// The rogue child removes its own head AND an entry it was never shown.
|
|
1408
|
+
await removeEntryFromDisk(store, batch[0]);
|
|
1409
|
+
await removeEntryFromDisk(store, outOfScopeEntry);
|
|
1410
|
+
return { code: 0, stdout: "Consolidated", stderr: "" };
|
|
1411
|
+
},
|
|
1412
|
+
registerTool: () => {},
|
|
1413
|
+
registerCommand: () => {},
|
|
1414
|
+
} as any;
|
|
1415
|
+
|
|
1416
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1417
|
+
consolidationChunkChars: 2500,
|
|
1418
|
+
consolidationChunking: true,
|
|
1419
|
+
consolidationChunking: true,
|
|
1420
|
+
});
|
|
1421
|
+
|
|
1422
|
+
assert.strictEqual(execCalls.length, 1);
|
|
1423
|
+
const survivors = store.getMemoryEntries();
|
|
1424
|
+
assert.ok(!survivors.includes(outOfScopeEntry), "out-of-scope deletions are reported, never resurrected");
|
|
1425
|
+
assert.ok(result.error?.includes("out-of-scope entr"), result.error);
|
|
1426
|
+
assert.ok(result.error?.includes("concurrent writer"), result.error);
|
|
1427
|
+
assert.strictEqual(result.partial, true, "a scope deviation keeps the run partial");
|
|
1428
|
+
});
|
|
1429
|
+
|
|
1430
|
+
it("stops before the first round when the time budget cannot fit a round", async () => {
|
|
1431
|
+
const store = await makeOverChunkStore(9);
|
|
1432
|
+
const pi = createChunkedChildPi(store, ["shrink"]);
|
|
1433
|
+
|
|
1434
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, 5, "memory", {
|
|
1435
|
+
consolidationChunkChars: 2500,
|
|
1436
|
+
consolidationChunking: true,
|
|
1437
|
+
consolidationChunking: true,
|
|
1438
|
+
});
|
|
1439
|
+
|
|
1440
|
+
assert.strictEqual(execCalls.length, 0, "a budget that cannot fit a round spawns no child");
|
|
1441
|
+
assert.strictEqual(result.consolidated, false);
|
|
1442
|
+
assert.ok(result.error?.includes("time budget (5ms) exhausted"), result.error);
|
|
1443
|
+
});
|
|
1444
|
+
|
|
1445
|
+
describe("takeChunk", () => {
|
|
1446
|
+
it("packs whole entries up to the char budget", () => {
|
|
1447
|
+
const entries = ["a".repeat(30), "b".repeat(30), "c".repeat(30)];
|
|
1448
|
+
const batch = takeChunk(entries, 70); // each entry costs 30 + delimiter
|
|
1449
|
+
assert.strictEqual(batch.length, 2);
|
|
1450
|
+
assert.strictEqual(batch.join(ENTRY_DELIMITER).length <= 70, true);
|
|
1451
|
+
});
|
|
1452
|
+
|
|
1453
|
+
it("lets an oversized entry travel alone", () => {
|
|
1454
|
+
const oversized = "x".repeat(3000);
|
|
1455
|
+
assert.deepStrictEqual(takeChunk([oversized, "small"], 2500), [oversized]);
|
|
1456
|
+
});
|
|
1457
|
+
|
|
1458
|
+
it("keeps an exactly-fitting entry", () => {
|
|
1459
|
+
const exact = "y".repeat(2497); // 2497 + 3 delimiter chars = 2500
|
|
1460
|
+
assert.deepStrictEqual(takeChunk([exact], 2500), [exact]);
|
|
1461
|
+
});
|
|
1462
|
+
});
|
|
1463
|
+
|
|
1464
|
+
it("gives the decisive final round the whole remaining store, unscoped", async () => {
|
|
1465
|
+
// Small cap: goal (3000) < chunk (4000), so the loop reaches a state where
|
|
1466
|
+
// the remaining store fits one prompt while still over the goal — that
|
|
1467
|
+
// decisive round must run unscoped, with full context.
|
|
1468
|
+
const store = await makeOverChunkStore(8, 600, 3000); // ≈ 4845 chars > 3000 goal
|
|
1469
|
+
let sawUnscopedFullPrompt = false;
|
|
1470
|
+
const pi: any = {
|
|
1471
|
+
on: () => {},
|
|
1472
|
+
exec: async (...args: any[]) => {
|
|
1473
|
+
execCalls.push(captureExecArgs(args));
|
|
1474
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1475
|
+
const batch = parsePromptBatch(prompt);
|
|
1476
|
+
const scoped = prompt.includes("covers ONLY the entries listed above");
|
|
1477
|
+
if (batch.length === store.getMemoryEntries().length && !scoped) {
|
|
1478
|
+
sawUnscopedFullPrompt = true;
|
|
1479
|
+
return { code: 0, stdout: "Consolidated", stderr: "" }; // decisive round may decline
|
|
1480
|
+
}
|
|
1481
|
+
await removeEntryFromDisk(store, batch[0]);
|
|
1482
|
+
return { code: 0, stdout: "Consolidated", stderr: "" };
|
|
1483
|
+
},
|
|
1484
|
+
registerTool: () => {},
|
|
1485
|
+
registerCommand: () => {},
|
|
1486
|
+
};
|
|
1487
|
+
|
|
1488
|
+
await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1489
|
+
|
|
1490
|
+
assert.ok(sawUnscopedFullPrompt, "once the remaining store fits one prompt, the round must be unscoped and whole");
|
|
1491
|
+
});
|
|
1492
|
+
});
|
|
1493
|
+
|
|
1494
|
+
// ─── Chunked prompt scoping ───
|
|
1495
|
+
|
|
1496
|
+
describe("chunked prompt scoping", () => {
|
|
1497
|
+
let MEMORY_DIR = "";
|
|
1498
|
+
|
|
1499
|
+
before(async () => {
|
|
1500
|
+
MEMORY_DIR = await fs.mkdtemp(path.join(os.tmpdir(), "pi-consolidation-scope-"));
|
|
1501
|
+
});
|
|
1502
|
+
|
|
1503
|
+
after(async () => {
|
|
1504
|
+
try { await fs.rm(MEMORY_DIR, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
1505
|
+
});
|
|
1506
|
+
|
|
1507
|
+
beforeEach(() => {
|
|
1508
|
+
execCalls = [];
|
|
1509
|
+
});
|
|
1510
|
+
|
|
1511
|
+
it("adds the scope guard only to chunked-round prompts", async () => {
|
|
1512
|
+
const store = new MemoryStore({
|
|
1513
|
+
memoryCharLimit: 5000,
|
|
1514
|
+
userCharLimit: 100,
|
|
1515
|
+
memoryMode: "policy-only",
|
|
1516
|
+
nudgeInterval: 10,
|
|
1517
|
+
reviewEnabled: false,
|
|
1518
|
+
flushOnCompact: false,
|
|
1519
|
+
flushOnShutdown: false,
|
|
1520
|
+
flushMinTurns: 6,
|
|
1521
|
+
autoConsolidate: false,
|
|
1522
|
+
correctionDetection: false,
|
|
1523
|
+
nudgeToolCalls: 15,
|
|
1524
|
+
memoryDir: MEMORY_DIR,
|
|
1525
|
+
});
|
|
1526
|
+
await store.loadFromDisk();
|
|
1527
|
+
for (let i = 0; i < 9; i++) {
|
|
1528
|
+
await store.add("memory", `scope-entry-${i}-${"z".repeat(580)}`); // ≈ 5382 chars > 5000 goal
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
const pi = {
|
|
1532
|
+
on: () => {},
|
|
1533
|
+
exec: async (...args: any[]) => {
|
|
1534
|
+
execCalls.push(captureExecArgs(args));
|
|
1535
|
+
return { code: 0, stdout: "done", stderr: "" };
|
|
1536
|
+
},
|
|
1537
|
+
registerTool: () => {},
|
|
1538
|
+
registerCommand: () => {},
|
|
1539
|
+
} as any;
|
|
1540
|
+
|
|
1541
|
+
await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1542
|
+
|
|
1543
|
+
const prompts = execCalls.map((call) => call[1].at(-1) as string);
|
|
1544
|
+
assert.ok(prompts.length >= 1, "over-chunk store should run at least one chunked round");
|
|
1545
|
+
for (const prompt of prompts) {
|
|
1546
|
+
assert.ok(
|
|
1547
|
+
prompt.includes("covers ONLY the entries listed above"),
|
|
1548
|
+
"every chunked-round prompt must carry the scope guard",
|
|
1549
|
+
);
|
|
1550
|
+
assert.ok(
|
|
1551
|
+
prompt.includes("Do NOT add, modify, or remove any entry that is not listed above"),
|
|
1552
|
+
"chunked-round prompt must forbid out-of-scope mutations",
|
|
1553
|
+
);
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
execCalls = [];
|
|
1557
|
+
// Same store, now under one chunk (chunkChars raised): single-shot keeps
|
|
1558
|
+
// the unscoped wording.
|
|
1559
|
+
await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1560
|
+
consolidationChunkChars: 100_000,
|
|
1561
|
+
});
|
|
1562
|
+
assert.strictEqual(execCalls.length, 1);
|
|
1563
|
+
const singleShotPrompt = execCalls[0][1].at(-1) as string;
|
|
1564
|
+
assert.ok(
|
|
1565
|
+
!singleShotPrompt.includes("covers ONLY the entries listed above"),
|
|
1566
|
+
"single-shot prompt must stay unchanged",
|
|
1567
|
+
);
|
|
1568
|
+
});
|
|
1569
|
+
});
|
|
1570
|
+
|
|
1571
|
+
// ─── Legacy-inject (cap-enforced) chunked path ───
|
|
1572
|
+
|
|
1573
|
+
describe("chunked consolidation in legacy-inject mode", () => {
|
|
1574
|
+
let MEMORY_ROOT = "";
|
|
1575
|
+
let seq = 0;
|
|
1576
|
+
|
|
1577
|
+
before(async () => {
|
|
1578
|
+
MEMORY_ROOT = await fs.mkdtemp(path.join(os.tmpdir(), "pi-consolidation-legacy-"));
|
|
1579
|
+
});
|
|
1580
|
+
|
|
1581
|
+
after(async () => {
|
|
1582
|
+
try { await fs.rm(MEMORY_ROOT, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
1583
|
+
});
|
|
1584
|
+
|
|
1585
|
+
beforeEach(() => {
|
|
1586
|
+
execCalls = [];
|
|
1587
|
+
});
|
|
1588
|
+
|
|
1589
|
+
it("runs the chunked loop against a cap-enforced over-limit store without re-entering caps", async () => {
|
|
1590
|
+
// Auto-consolidation only auto-runs in legacy-inject mode, and only when
|
|
1591
|
+
// the store is over its limit — so this is the mode the loop must be
|
|
1592
|
+
// proven in. A policy-only seed store fills the directory past the
|
|
1593
|
+
// smaller legacy cap; a second legacy-mode instance over the same
|
|
1594
|
+
// directory then consolidates an over-limit store. The loop mutates
|
|
1595
|
+
// nothing through store.add(), so no cap rejection and no nested
|
|
1596
|
+
// consolidation trigger can occur (previously the out-of-scope restore
|
|
1597
|
+
// re-entered exactly that path from inside the held lease).
|
|
1598
|
+
const memoryDir = path.join(MEMORY_ROOT, `legacy-${++seq}`);
|
|
1599
|
+
const seeder = new MemoryStore({
|
|
1600
|
+
memoryCharLimit: 5000,
|
|
1601
|
+
userCharLimit: 100,
|
|
1602
|
+
memoryMode: "policy-only",
|
|
1603
|
+
nudgeInterval: 10,
|
|
1604
|
+
reviewEnabled: false,
|
|
1605
|
+
flushOnCompact: false,
|
|
1606
|
+
flushOnShutdown: false,
|
|
1607
|
+
flushMinTurns: 6,
|
|
1608
|
+
autoConsolidate: false,
|
|
1609
|
+
correctionDetection: false,
|
|
1610
|
+
nudgeToolCalls: 15,
|
|
1611
|
+
memoryDir,
|
|
1612
|
+
});
|
|
1613
|
+
await seeder.loadFromDisk();
|
|
1614
|
+
for (let i = 0; i < 8; i++) {
|
|
1615
|
+
const r = await seeder.add("memory", `seed-${i}-${"x".repeat(72)}`);
|
|
1616
|
+
assert.ok(r.success, `seed ${i} should succeed`);
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
// Legacy-inject view of the same directory: cap 300, store now over it.
|
|
1620
|
+
const store = new MemoryStore({
|
|
1621
|
+
memoryCharLimit: 300,
|
|
1622
|
+
userCharLimit: 100,
|
|
1623
|
+
nudgeInterval: 10,
|
|
1624
|
+
reviewEnabled: false,
|
|
1625
|
+
flushOnCompact: false,
|
|
1626
|
+
flushOnShutdown: false,
|
|
1627
|
+
flushMinTurns: 6,
|
|
1628
|
+
autoConsolidate: false,
|
|
1629
|
+
correctionDetection: false,
|
|
1630
|
+
nudgeToolCalls: 15,
|
|
1631
|
+
memoryDir,
|
|
1632
|
+
});
|
|
1633
|
+
await store.loadFromDisk();
|
|
1634
|
+
const before = store.getMemoryEntries();
|
|
1635
|
+
assert.strictEqual(before.length, 8);
|
|
1636
|
+
assert.ok(before.join(ENTRY_DELIMITER).length > 300, "store must be over the legacy cap");
|
|
1637
|
+
|
|
1638
|
+
const pi = (() => {
|
|
1639
|
+
let round = 0;
|
|
1640
|
+
const script = ["shrink", "shrink", "noop"];
|
|
1641
|
+
return {
|
|
1642
|
+
on: () => {},
|
|
1643
|
+
exec: async (...args: any[]) => {
|
|
1644
|
+
execCalls.push(captureExecArgs(args));
|
|
1645
|
+
const action = script[Math.min(round, script.length - 1)];
|
|
1646
|
+
round++;
|
|
1647
|
+
if (action === "shrink") {
|
|
1648
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1649
|
+
const marker = "--- Current Memory Entries ---";
|
|
1650
|
+
const start = prompt.indexOf(marker);
|
|
1651
|
+
const body = prompt.slice(start + marker.length, prompt.indexOf("Use memory_add", start));
|
|
1652
|
+
const batch = body.split(ENTRY_DELIMITER).map((e) => e.trim()).filter((e) => e && e !== "(empty)");
|
|
1653
|
+
await removeEntryFromDisk(store, batch[0]);
|
|
1654
|
+
}
|
|
1655
|
+
return { code: 0, stdout: "Consolidated", stderr: "" };
|
|
1656
|
+
},
|
|
1657
|
+
registerTool: () => {},
|
|
1658
|
+
registerCommand: () => {},
|
|
1659
|
+
} as any;
|
|
1660
|
+
})();
|
|
1661
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1662
|
+
consolidationChunkChars: 500,
|
|
1663
|
+
consolidationChunking: true,
|
|
1664
|
+
});
|
|
1665
|
+
|
|
1666
|
+
assert.strictEqual(result.consolidated, true);
|
|
1667
|
+
assert.strictEqual(result.partial, true, "still over the 300-char goal after the walk");
|
|
1668
|
+
assert.ok(result.error?.includes("could not shrink the remaining"), result.error);
|
|
1669
|
+
assert.ok(!result.error?.includes("another session is consolidating"), "no nested-consolidation stall may surface");
|
|
1670
|
+
const survivors = store.getMemoryEntries();
|
|
1671
|
+
assert.strictEqual(survivors.length, 6, "rounds shrank the store through the child's file edits");
|
|
1672
|
+
const removed = before.filter((entry) => !survivors.includes(entry));
|
|
1673
|
+
assert.strictEqual(removed.length, 2);
|
|
1674
|
+
});
|
|
1675
|
+
});
|
|
1676
|
+
|
|
1677
|
+
describe("/memory-consolidate partial display", () => {
|
|
1678
|
+
it("shows ⚠️ partial with the reason when a round fails after earlier progress", async () => {
|
|
1679
|
+
const memoryDir = await fs.mkdtemp(path.join(os.tmpdir(), "pi-consolidation-partial-ui-"));
|
|
1680
|
+
try {
|
|
1681
|
+
const store = new MemoryStore({
|
|
1682
|
+
memoryCharLimit: 5000,
|
|
1683
|
+
userCharLimit: 100,
|
|
1684
|
+
memoryMode: "policy-only",
|
|
1685
|
+
nudgeInterval: 10,
|
|
1686
|
+
reviewEnabled: false,
|
|
1687
|
+
flushOnCompact: false,
|
|
1688
|
+
flushOnShutdown: false,
|
|
1689
|
+
flushMinTurns: 6,
|
|
1690
|
+
autoConsolidate: false,
|
|
1691
|
+
correctionDetection: false,
|
|
1692
|
+
nudgeToolCalls: 15,
|
|
1693
|
+
memoryDir,
|
|
1694
|
+
});
|
|
1695
|
+
await store.loadFromDisk();
|
|
1696
|
+
for (let i = 0; i < 11; i++) {
|
|
1697
|
+
await store.add("memory", `partial-ui-${i}-${"x".repeat(580)}`); // ≈ 6663 chars > 5000 goal
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
execCalls = [];
|
|
1701
|
+
let handler: ManualCommandHandler | undefined;
|
|
1702
|
+
const pi = {
|
|
1703
|
+
on: () => {},
|
|
1704
|
+
exec: async (...args: any[]) => {
|
|
1705
|
+
execCalls.push(captureExecArgs(args));
|
|
1706
|
+
const round = execCalls.length;
|
|
1707
|
+
if (round === 1) {
|
|
1708
|
+
const prompt = execCalls[0][1].at(-1) as string;
|
|
1709
|
+
const batch = parsePromptBatch(prompt);
|
|
1710
|
+
await removeEntryFromDisk(store, batch[0]);
|
|
1711
|
+
return { code: 0, stdout: "ok", stderr: "" };
|
|
1712
|
+
}
|
|
1713
|
+
return { code: 124, stdout: "", stderr: "", killed: true };
|
|
1714
|
+
},
|
|
1715
|
+
registerTool: () => {},
|
|
1716
|
+
registerCommand: (_name: string, command: { handler: ManualCommandHandler }) => {
|
|
1717
|
+
handler = command.handler;
|
|
1718
|
+
},
|
|
1719
|
+
} as unknown as Parameters<typeof registerConsolidateCommand>[0];
|
|
1720
|
+
|
|
1721
|
+
registerConsolidateCommand(pi, store, DEFAULT_CONSOLIDATION_TIMEOUT_MS, null, null, {
|
|
1722
|
+
consolidationChunkChars: 2500,
|
|
1723
|
+
consolidationChunking: true,
|
|
1724
|
+
consolidationChunking: true,
|
|
1725
|
+
});
|
|
1726
|
+
assert.ok(handler, "command handler should be registered");
|
|
1727
|
+
|
|
1728
|
+
const notifications: string[] = [];
|
|
1729
|
+
await handler!({}, { signal: undefined, ui: { notify: (msg: string) => notifications.push(msg) } });
|
|
1730
|
+
|
|
1731
|
+
const summary = notifications[notifications.length - 1] ?? "";
|
|
1732
|
+
assert.ok(summary.includes("memory: ✅ consolidated (1 round) ⚠️ partial:"), summary);
|
|
1733
|
+
assert.ok(summary.includes("terminated"), summary);
|
|
1734
|
+
} finally {
|
|
1735
|
+
await fs.rm(memoryDir, { recursive: true, force: true }).catch(() => {});
|
|
1736
|
+
}
|
|
1737
|
+
});
|
|
1738
|
+
});
|
|
1739
|
+
|
|
1740
|
+
// ─── Third-review follow-ups: budget starvation, slice growth, reload throw, abort, shrink-then-fail ───
|
|
1741
|
+
|
|
1742
|
+
describe("chunked consolidation edge behavior", () => {
|
|
1743
|
+
let MEMORY_ROOT = "";
|
|
1744
|
+
let seq = 0;
|
|
1745
|
+
|
|
1746
|
+
before(async () => {
|
|
1747
|
+
MEMORY_ROOT = await fs.mkdtemp(path.join(os.tmpdir(), "pi-consolidation-edge-"));
|
|
1748
|
+
});
|
|
1749
|
+
|
|
1750
|
+
after(async () => {
|
|
1751
|
+
try { await fs.rm(MEMORY_ROOT, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
1752
|
+
});
|
|
1753
|
+
|
|
1754
|
+
beforeEach(() => {
|
|
1755
|
+
execCalls = [];
|
|
1756
|
+
});
|
|
1757
|
+
|
|
1758
|
+
function fileChild(store: MemoryStore, onRound: (batch: string[], round: number) => Promise<"shrink" | "grow" | "noop" | "fail">) {
|
|
1759
|
+
let round = 0;
|
|
1760
|
+
return {
|
|
1761
|
+
on: () => {},
|
|
1762
|
+
exec: async (...args: any[]) => {
|
|
1763
|
+
execCalls.push(captureExecArgs(args));
|
|
1764
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1765
|
+
const batch = parsePromptBatch(prompt);
|
|
1766
|
+
round++;
|
|
1767
|
+
const action = onRound(batch, round);
|
|
1768
|
+
return action.then((a: string) => (a === "fail" ? { code: 124, stdout: "", stderr: "", killed: true } : { code: 0, stdout: "ok", stderr: "" }));
|
|
1769
|
+
},
|
|
1770
|
+
registerTool: () => {},
|
|
1771
|
+
registerCommand: () => {},
|
|
1772
|
+
} as any;
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
async function makeStore(entryCount: number, cap = 5000): Promise<MemoryStore> {
|
|
1776
|
+
const memoryDir = path.join(MEMORY_ROOT, `edge-${++seq}`);
|
|
1777
|
+
const store = new MemoryStore({
|
|
1778
|
+
memoryCharLimit: cap, userCharLimit: 100, memoryMode: "policy-only", nudgeInterval: 10,
|
|
1779
|
+
reviewEnabled: false, flushOnCompact: false, flushOnShutdown: false, flushMinTurns: 6,
|
|
1780
|
+
autoConsolidate: false, correctionDetection: false, nudgeToolCalls: 15, memoryDir,
|
|
1781
|
+
} as any);
|
|
1782
|
+
await store.loadFromDisk();
|
|
1783
|
+
for (let i = 0; i < entryCount; i++) {
|
|
1784
|
+
const r = await store.add("memory", `edge-entry-${i}-` + "y".repeat(580));
|
|
1785
|
+
if (!r.success) throw new Error(`seed ${i}`);
|
|
1786
|
+
}
|
|
1787
|
+
return store;
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
it("a growing round is walked past, not rewarded", async () => {
|
|
1791
|
+
const store = await makeStore(9); // ≈ 5820 encoded chars > 5000 goal
|
|
1792
|
+
const pi: any = {
|
|
1793
|
+
on: () => {}, registerTool: () => {}, registerCommand: () => {},
|
|
1794
|
+
exec: async (...args: any[]) => {
|
|
1795
|
+
execCalls.push(captureExecArgs(args));
|
|
1796
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1797
|
+
const batch = parsePromptBatch(prompt);
|
|
1798
|
+
if (batch.length > 0) await store.remove("memory", batch[0]);
|
|
1799
|
+
// ...and the rogue/growing child also adds a fresh entry.
|
|
1800
|
+
await store.add("memory", `grown-entry-${roundCounter}-` + "z".repeat(580));
|
|
1801
|
+
return { code: 0, stdout: "ok", stderr: "" };
|
|
1802
|
+
},
|
|
1803
|
+
registerTool: () => {}, registerCommand: () => {},
|
|
1804
|
+
};
|
|
1805
|
+
let roundCounter = 0;
|
|
1806
|
+
// NOTE: roundCounter is captured by the closure above via hoisting of let.
|
|
1807
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1808
|
+
consolidationChunkChars: 2500,
|
|
1809
|
+
consolidationChunking: true,
|
|
1810
|
+
consolidationChunking: true,
|
|
1811
|
+
});
|
|
1812
|
+
|
|
1813
|
+
assert.strictEqual(result.consolidated, true);
|
|
1814
|
+
assert.ok(store.getMemoryEntries().length <= 9, "a growing round must not grow the store: removal offsets its addition");
|
|
1815
|
+
assert.ok(result.rounds !== undefined && result.rounds <= MAX_CONSOLIDATION_ROUNDS, "bounded rounds");
|
|
1816
|
+
});
|
|
1817
|
+
|
|
1818
|
+
it("loadFromDisk failure between rounds is reported and stops the walk", async () => {
|
|
1819
|
+
const store = await makeStore(9);
|
|
1820
|
+
const pi: any = {
|
|
1821
|
+
on: () => {}, registerTool: () => {}, registerCommand: () => {},
|
|
1822
|
+
exec: async (...args: any[]) => {
|
|
1823
|
+
execCalls.push(captureExecArgs(args));
|
|
1824
|
+
return { code: 0, stdout: "ok", stderr: "" };
|
|
1825
|
+
},
|
|
1826
|
+
registerTool: () => {}, registerCommand: () => {},
|
|
1827
|
+
};
|
|
1828
|
+
(store as any).loadFromDisk = async () => {
|
|
1829
|
+
throw new Error("injected reload failure");
|
|
1830
|
+
};
|
|
1831
|
+
|
|
1832
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1833
|
+
consolidationChunkChars: 2500,
|
|
1834
|
+
consolidationChunking: true,
|
|
1835
|
+
consolidationChunking: true,
|
|
1836
|
+
});
|
|
1837
|
+
|
|
1838
|
+
assert.strictEqual(result.consolidated, false);
|
|
1839
|
+
assert.ok(result.error?.includes("could not reload memory after a consolidation round"), result.error);
|
|
1840
|
+
assert.strictEqual(execCalls.length, 1);
|
|
1841
|
+
});
|
|
1842
|
+
|
|
1843
|
+
it("abort landing between rounds stops the walk with an honest note", async () => {
|
|
1844
|
+
const store = await makeStore(9);
|
|
1845
|
+
const controller = new AbortController();
|
|
1846
|
+
const pi: any = {
|
|
1847
|
+
on: () => {}, registerTool: () => {}, registerCommand: () => {},
|
|
1848
|
+
exec: async (...args: any[]) => {
|
|
1849
|
+
execCalls.push(captureExecArgs(args));
|
|
1850
|
+
controller.abort(); // abort lands between rounds, not during a child
|
|
1851
|
+
return { code: 0, stdout: "ok", stderr: "" };
|
|
1852
|
+
},
|
|
1853
|
+
registerTool: () => {}, registerCommand: () => {},
|
|
1854
|
+
};
|
|
1855
|
+
|
|
1856
|
+
const result = await triggerConsolidation(pi, store, "memory", controller.signal, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1857
|
+
consolidationChunkChars: 2500,
|
|
1858
|
+
consolidationChunking: true,
|
|
1859
|
+
consolidationChunking: true,
|
|
1860
|
+
});
|
|
1861
|
+
|
|
1862
|
+
assert.strictEqual(execCalls.length, 1, "abort between rounds must stop the walk");
|
|
1863
|
+
assert.strictEqual(result.consolidated, false, "nothing completed before the abort");
|
|
1864
|
+
assert.ok(result.error?.includes("aborted between consolidation rounds"), result.error);
|
|
1865
|
+
});
|
|
1866
|
+
|
|
1867
|
+
it("a round that shrinks on disk and then fails reports partial, not total failure", async () => {
|
|
1868
|
+
const store = await makeStore(9);
|
|
1869
|
+
const pi: any = {
|
|
1870
|
+
on: () => {}, registerTool: () => {}, registerCommand: () => {},
|
|
1871
|
+
exec: async (...args: any[]) => {
|
|
1872
|
+
execCalls.push(captureExecArgs(args));
|
|
1873
|
+
const prompt = execCalls[execCalls.length - 1][1].at(-1) as string;
|
|
1874
|
+
const batch = parsePromptBatch(prompt);
|
|
1875
|
+
// The child merges its slice, THEN dies — the shrink is real and on disk.
|
|
1876
|
+
await store.remove("memory", batch[0]);
|
|
1877
|
+
return { code: 124, stdout: "", stderr: "", killed: true };
|
|
1878
|
+
},
|
|
1879
|
+
registerTool: () => {}, registerCommand: () => {},
|
|
1880
|
+
};
|
|
1881
|
+
|
|
1882
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
1883
|
+
consolidationChunkChars: 2500,
|
|
1884
|
+
consolidationChunking: true,
|
|
1885
|
+
consolidationChunking: true,
|
|
1886
|
+
});
|
|
1887
|
+
|
|
1888
|
+
assert.strictEqual(result.consolidated, true, "the on-disk shrink is real progress");
|
|
1889
|
+
assert.strictEqual(result.partial, true, "…but the run ended in failure and must say so");
|
|
1890
|
+
assert.strictEqual(result.rounds, 0, "no round completed successfully");
|
|
1891
|
+
assert.ok(result.error?.includes("The failing round still shrank the store by"), result.error);
|
|
1892
|
+
assert.ok(store.getMemoryEntries().length < 9, "the shrink persisted");
|
|
1893
|
+
});
|
|
1894
|
+
|
|
1895
|
+
it("starving rounds share the budget: per-round timeouts shrink until the gate trips", { timeout: 60000 }, async () => {
|
|
1896
|
+
const store = await makeStore(17); // ≈ 11K encoded chars, needs several rounds
|
|
1897
|
+
const watchdogTimeouts: number[] = [];
|
|
1898
|
+
const pi: any = {
|
|
1899
|
+
on: () => {}, registerTool: () => {}, registerCommand: () => {},
|
|
1900
|
+
exec: async (...args: any[]) => {
|
|
1901
|
+
execCalls.push(captureExecArgs(args));
|
|
1902
|
+
const call = execCalls[execCalls.length - 1];
|
|
1903
|
+
watchdogTimeouts.push(Number(call[1][1]));
|
|
1904
|
+
const prompt = call[1].at(-1) as string;
|
|
1905
|
+
const batch = parsePromptBatch(prompt);
|
|
1906
|
+
await new Promise((r) => setTimeout(r, 800)); // child works for 0.8s per round
|
|
1907
|
+
if (batch.length > 0) await store.remove("memory", batch[0]);
|
|
1908
|
+
return { code: 0, stdout: "ok", stderr: "" };
|
|
1909
|
+
},
|
|
1910
|
+
registerTool: () => {}, registerCommand: () => {},
|
|
1911
|
+
};
|
|
1912
|
+
|
|
1913
|
+
const result = await triggerConsolidation(pi, store, "memory", undefined, 11500, "memory", {
|
|
1914
|
+
consolidationChunkChars: 2500,
|
|
1915
|
+
consolidationChunking: true,
|
|
1916
|
+
consolidationChunking: true,
|
|
1917
|
+
});
|
|
1918
|
+
|
|
1919
|
+
assert.ok(watchdogTimeouts.length >= 2, "multiple rounds before the budget gate");
|
|
1920
|
+
for (let i = 1; i < watchdogTimeouts.length; i++) {
|
|
1921
|
+
assert.ok(
|
|
1922
|
+
watchdogTimeouts[i] < watchdogTimeouts[i - 1],
|
|
1923
|
+
`round ${i + 1} must get a STRICTLY SMALLER share of the shared budget (got ${watchdogTimeouts[i - 1]} → ${watchdogTimeouts[i]}) — a mutant passing the full timeout every round fails here`,
|
|
1924
|
+
);
|
|
1925
|
+
}
|
|
1926
|
+
assert.ok(result.error?.includes("time budget (11500ms) exhausted"), result.error);
|
|
1927
|
+
});
|
|
1928
|
+
});
|
|
1929
|
+
|
|
1930
|
+
// ─── Usage signals (PR-2 promotion gate) ───
|
|
1931
|
+
|
|
1932
|
+
const SIGNAL_ENTRY_RECALLED = "usage-signal entry alpha — recalled by search often";
|
|
1933
|
+
const SIGNAL_ENTRY_NEVER = "usage-signal entry beta — never recalled by search";
|
|
1934
|
+
const SIGNALS_HEADER = "--- Usage Signals (memory_search recall tracking) ---";
|
|
1935
|
+
const SIGNALS_GUIDANCE = "Treat these as tie-breakers, not removal orders";
|
|
1936
|
+
|
|
1937
|
+
function makeUsageStore(entries: string[]) {
|
|
1938
|
+
return {
|
|
1939
|
+
getMemoryEntries: () => [...entries],
|
|
1940
|
+
getUserEntries: () => [],
|
|
1941
|
+
getAllFailureEntries: () => [],
|
|
1942
|
+
getStorageIdentity: async (target: string) => path.join("usage-store", target),
|
|
1943
|
+
loadFromDisk: async () => {},
|
|
1944
|
+
capacityGoal: () => 10,
|
|
1945
|
+
capacityUsage: () => 1000,
|
|
1946
|
+
} as any;
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
function todayStr(): string {
|
|
1950
|
+
return new Date().toISOString().split("T")[0];
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1953
|
+
describe("consolidation usage signals", () => {
|
|
1954
|
+
let usageDb: DatabaseManager;
|
|
1955
|
+
let usageDir = "";
|
|
1956
|
+
|
|
1957
|
+
beforeEach(async () => {
|
|
1958
|
+
// This describe is top-level (appended after the others), so the
|
|
1959
|
+
// triggerConsolidation describe's beforeEach does not apply: reset the
|
|
1960
|
+
// shared exec capture and lock dir here too.
|
|
1961
|
+
execCalls = [];
|
|
1962
|
+
process.env.PI_HERMES_CONSOLIDATION_LOCK_DIR = await fs.mkdtemp(
|
|
1963
|
+
path.join(os.tmpdir(), "pi-consolidation-locks-"),
|
|
1964
|
+
);
|
|
1965
|
+
usageDir = await fs.mkdtemp(path.join(os.tmpdir(), "pi-usage-signal-consolidation-"));
|
|
1966
|
+
usageDb = new DatabaseManager(usageDir);
|
|
1967
|
+
});
|
|
1968
|
+
|
|
1969
|
+
afterEach(() => {
|
|
1970
|
+
try { usageDb.close(); } catch { /* already closed by the test */ }
|
|
1971
|
+
try { fs.rmSync(usageDir, { recursive: true, force: true }); } catch { /* best effort */ }
|
|
1972
|
+
});
|
|
1973
|
+
|
|
1974
|
+
it("keeps the subprocess prompt byte-identical when the database has no tracking data", async () => {
|
|
1975
|
+
addMemory(usageDb, SIGNAL_ENTRY_NEVER, "memory"); // zero hits → no signals
|
|
1976
|
+
const store = makeUsageStore([SIGNAL_ENTRY_NEVER]);
|
|
1977
|
+
|
|
1978
|
+
const piWithDb = createMockPi();
|
|
1979
|
+
await triggerConsolidation(piWithDb, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true }, null, usageDb);
|
|
1980
|
+
const withDbPrompt = childPrompt(execCalls[0]);
|
|
1981
|
+
|
|
1982
|
+
execCalls = [];
|
|
1983
|
+
const piNoDb = createMockPi();
|
|
1984
|
+
await triggerConsolidation(piNoDb, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true });
|
|
1985
|
+
const noDbPrompt = childPrompt(execCalls[0]);
|
|
1986
|
+
|
|
1987
|
+
assert.strictEqual(withDbPrompt, noDbPrompt, "prompt must be identical with a dataless database attached");
|
|
1988
|
+
assert.ok(!withDbPrompt.includes(SIGNALS_HEADER));
|
|
1989
|
+
|
|
1990
|
+
});
|
|
1991
|
+
|
|
1992
|
+
it("annotates recalled and never-recalled entries once tracking data exists", async () => {
|
|
1993
|
+
const recalledRow = addMemory(usageDb, SIGNAL_ENTRY_RECALLED, "memory");
|
|
1994
|
+
addMemory(usageDb, SIGNAL_ENTRY_NEVER, "memory");
|
|
1995
|
+
recordSearchHits(usageDb, [recalledRow.id]);
|
|
1996
|
+
const store = makeUsageStore([SIGNAL_ENTRY_RECALLED, SIGNAL_ENTRY_NEVER]);
|
|
1997
|
+
|
|
1998
|
+
const pi = createMockPi();
|
|
1999
|
+
await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true }, null, usageDb);
|
|
2000
|
+
|
|
2001
|
+
const prompt = childPrompt(execCalls[0]);
|
|
2002
|
+
assert.ok(prompt.includes(SIGNALS_HEADER), "usage signals header present");
|
|
2003
|
+
assert.ok(prompt.includes(`recalled 1x, last ${todayStr()}: "${SIGNAL_ENTRY_RECALLED}"`), "recalled entry annotated with count + date");
|
|
2004
|
+
assert.ok(prompt.includes(`never recalled: "${SIGNAL_ENTRY_NEVER}"`), "never-recalled entry annotated");
|
|
2005
|
+
assert.ok(prompt.includes(SIGNALS_GUIDANCE), "tie-breaker guidance present");
|
|
2006
|
+
// The real entry list stays untouched (child copies entry text from there).
|
|
2007
|
+
assert.ok(prompt.includes(`--- Current Memory Entries ---\n${SIGNAL_ENTRY_RECALLED}\n§\n${SIGNAL_ENTRY_NEVER}\n\n${SIGNALS_HEADER}`));
|
|
2008
|
+
|
|
2009
|
+
});
|
|
2010
|
+
|
|
2011
|
+
it("omits the section when consolidationUsageSignals is off even with data", async () => {
|
|
2012
|
+
const recalledRow = addMemory(usageDb, SIGNAL_ENTRY_RECALLED, "memory");
|
|
2013
|
+
recordSearchHits(usageDb, [recalledRow.id]);
|
|
2014
|
+
const store = makeUsageStore([SIGNAL_ENTRY_RECALLED]);
|
|
2015
|
+
|
|
2016
|
+
const pi = createMockPi();
|
|
2017
|
+
await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true, consolidationUsageSignals: false }, null, usageDb);
|
|
2018
|
+
|
|
2019
|
+
const prompt = childPrompt(execCalls[0]);
|
|
2020
|
+
assert.ok(!prompt.includes(SIGNALS_HEADER), "kill-switch must suppress the section");
|
|
2021
|
+
|
|
2022
|
+
});
|
|
2023
|
+
|
|
2024
|
+
it("annotates only the presented batch in chunked rounds", async () => {
|
|
2025
|
+
const entries: string[] = [];
|
|
2026
|
+
for (let i = 0; i < 12; i++) {
|
|
2027
|
+
entries.push(`usage chunk entry ${String(i).padStart(2, "0")} — ${"filler prose for sizing ".repeat(3)}end-${i}`);
|
|
2028
|
+
}
|
|
2029
|
+
const store = makeUsageStore(entries);
|
|
2030
|
+
const rows = entries.map((entry) => addMemory(usageDb, entry, "memory"));
|
|
2031
|
+
recordSearchHits(usageDb, [rows[10].id]); // only a TAIL entry has usage data
|
|
2032
|
+
|
|
2033
|
+
const pi = createMockPi();
|
|
2034
|
+
await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", {
|
|
2035
|
+
consolidationChunking: true,
|
|
2036
|
+
consolidationChunkChars: 500,
|
|
2037
|
+
}, null, usageDb);
|
|
2038
|
+
|
|
2039
|
+
assert.ok(execCalls.length >= 3, `expected multiple rounds, got ${execCalls.length}`);
|
|
2040
|
+
const firstPrompt = childPrompt(execCalls[0]);
|
|
2041
|
+
assert.ok(!firstPrompt.includes(SIGNALS_HEADER), "a batch with no tracked entries gets no section");
|
|
2042
|
+
const annotatedAt = execCalls.findIndex((_, i) => childPrompt(execCalls[i]).includes("recalled 1x"));
|
|
2043
|
+
assert.ok(annotatedAt > 0, "the round containing the tracked entry carries the section");
|
|
2044
|
+
const annotatedPrompt = childPrompt(execCalls[annotatedAt]);
|
|
2045
|
+
assert.ok(annotatedPrompt.includes(`recalled 1x, last ${todayStr()}: "${entries[10].slice(0, 77)}...`), "tail entry annotated when it reaches a batch");
|
|
2046
|
+
|
|
2047
|
+
});
|
|
2048
|
+
|
|
2049
|
+
it("embeds the same section in the direct-transport userPrompt", async () => {
|
|
2050
|
+
const recalledRow = addMemory(usageDb, SIGNAL_ENTRY_RECALLED, "memory");
|
|
2051
|
+
recordSearchHits(usageDb, [recalledRow.id]);
|
|
2052
|
+
const store = makeUsageStore([SIGNAL_ENTRY_RECALLED]);
|
|
2053
|
+
|
|
2054
|
+
directCalls = [];
|
|
2055
|
+
const pi = createMockPi();
|
|
2056
|
+
const deps = makeDirectDeps({ ok: true, appliedCount: 1 });
|
|
2057
|
+
const result = await triggerConsolidation(
|
|
2058
|
+
pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory",
|
|
2059
|
+
directTransportLlmConfig, createDirectCtx() as any, usageDb, null, deps,
|
|
2060
|
+
);
|
|
2061
|
+
|
|
2062
|
+
assert.strictEqual(result.consolidated, true);
|
|
2063
|
+
assert.strictEqual(directCalls.length, 1, "direct transport used, no subprocess needed");
|
|
2064
|
+
const options = (directCalls[0][3] ?? directCalls[0][directCalls[0].length - 1]) as { userPrompt: string };
|
|
2065
|
+
assert.ok(options.userPrompt.includes(SIGNALS_HEADER), "direct prompt carries the section");
|
|
2066
|
+
assert.ok(options.userPrompt.includes(`recalled 1x, last ${todayStr()}: "${SIGNAL_ENTRY_RECALLED}"`));
|
|
2067
|
+
|
|
2068
|
+
});
|
|
2069
|
+
});
|
|
2070
|
+
|
|
2071
|
+
describe("consolidation usage signals — large all-recalled store (review blocker)", () => {
|
|
2072
|
+
let usageDb: DatabaseManager;
|
|
2073
|
+
let usageDir = "";
|
|
2074
|
+
|
|
2075
|
+
beforeEach(async () => {
|
|
2076
|
+
// Top-level describe: reset the shared exec capture and lock dir here too.
|
|
2077
|
+
execCalls = [];
|
|
2078
|
+
process.env.PI_HERMES_CONSOLIDATION_LOCK_DIR = await fs.mkdtemp(
|
|
2079
|
+
path.join(os.tmpdir(), "pi-consolidation-locks-"),
|
|
2080
|
+
);
|
|
2081
|
+
usageDir = await fs.mkdtemp(path.join(os.tmpdir(), "pi-usage-signal-cap-"));
|
|
2082
|
+
usageDb = new DatabaseManager(usageDir);
|
|
2083
|
+
});
|
|
2084
|
+
|
|
2085
|
+
afterEach(() => {
|
|
2086
|
+
try { usageDb.close(); } catch { /* already closed by the test */ }
|
|
2087
|
+
try { fs.rmSync(usageDir, { recursive: true, force: true }); } catch { /* best effort */ }
|
|
2088
|
+
});
|
|
2089
|
+
|
|
2090
|
+
it("caps the tracked half, ranks by hits, and folds the remainder into a summary line", async () => {
|
|
2091
|
+
// 40 entries, EVERY one recalled (the mature-store shape where the old
|
|
2092
|
+
// uncapped tracked half grew with the store: 40 tracked lines). Each entry
|
|
2093
|
+
// ~120 chars so the whole store fits one decisive prompt (chunking off).
|
|
2094
|
+
const entries: string[] = [];
|
|
2095
|
+
for (let i = 0; i < 40; i++) {
|
|
2096
|
+
entries.push(`mature-store entry ${String(i).padStart(2, "0")} — ${"recalled prose for sizing ".repeat(3)}end-${i}`);
|
|
2097
|
+
}
|
|
2098
|
+
const store = makeUsageStore(entries);
|
|
2099
|
+
const rows = entries.map((entry) => addMemory(usageDb, entry, "memory"));
|
|
2100
|
+
for (const row of rows) {
|
|
2101
|
+
const hits = 1 + (rows.indexOf(row) % 5); // 1..5 hits, entry 39 has 5
|
|
2102
|
+
for (let i = 0; i < hits; i++) recordSearchHits(usageDb, [row.id]);
|
|
2103
|
+
}
|
|
2104
|
+
// Highest count is on the LAST store entry — sorting must still surface it.
|
|
2105
|
+
for (let i = 0; i < 95; i++) recordSearchHits(usageDb, [rows[39].id]);
|
|
2106
|
+
|
|
2107
|
+
const pi = createMockPi();
|
|
2108
|
+
// One decisive whole-store round: all 40 tracked entries in ONE prompt —
|
|
2109
|
+
// the mature-store shape the owner measured at 270% of the chunk budget.
|
|
2110
|
+
await triggerConsolidation(pi, store, "memory", undefined, DEFAULT_CONSOLIDATION_TIMEOUT_MS, "memory", { consolidationChunking: true, consolidationChunkChars: 999999 }, null, usageDb);
|
|
2111
|
+
|
|
2112
|
+
const prompt = childPrompt(execCalls[0]);
|
|
2113
|
+
const sectionStart = prompt.indexOf("--- Usage Signals (memory_search recall tracking) ---");
|
|
2114
|
+
assert.ok(sectionStart > 0, "signals section present");
|
|
2115
|
+
const section = prompt.slice(sectionStart, prompt.indexOf("Use memory_add", sectionStart));
|
|
2116
|
+
|
|
2117
|
+
const trackedLines = section.split("\n").filter((l) => l.startsWith("- recalled "));
|
|
2118
|
+
assert.strictEqual(trackedLines.length, 20, `tracked half capped at 20 (got ${trackedLines.length})`);
|
|
2119
|
+
assert.match(section, /\(\+20 more recalled entries omitted — showing the top 20 by recall count\)/, "remainder folded into a summary line");
|
|
2120
|
+
// Ranked by hits: the 100-hit entry must top the kept half despite being
|
|
2121
|
+
// LAST in store order, and the kept half is non-increasing by count.
|
|
2122
|
+
assert.match(trackedLines[0], /- recalled 100x, last \d{4}-\d{2}-\d{2}: "mature-store entry 39/);
|
|
2123
|
+
const counts = trackedLines.map((l) => Number(l.match(/- recalled (\d+)x/)![1]));
|
|
2124
|
+
for (let i = 1; i < counts.length; i++) {
|
|
2125
|
+
assert.ok(counts[i] <= counts[i - 1], `kept half must be sorted by hits desc (got ${counts[i - 1]} -> ${counts[i]})`);
|
|
2126
|
+
}
|
|
2127
|
+
// Never-recalled half is empty here — no never-recalled summary expected.
|
|
2128
|
+
assert.ok(!section.includes("have no recorded recalls"));
|
|
2129
|
+
// Bounded section: constant line count, not store-proportional.
|
|
2130
|
+
assert.ok(section.length < 4500, `section bounded (got ${section.length} chars)`);
|
|
2131
|
+
usageDb.close();
|
|
2132
|
+
});
|
|
990
2133
|
});
|