pi-crew 0.9.16 → 0.9.17
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 +81 -0
- package/README.md +19 -0
- package/dist/build-meta.json +21790 -0
- package/dist/index.mjs +83070 -0
- package/dist/index.mjs.map +7 -0
- package/docs/A +358 -0
- package/docs/M-A +357 -0
- package/docs/REVIEW-FINDINGS-2026-06 +357 -0
- package/docs/Y +357 -0
- package/docs/a +357 -0
- package/docs/aA +358 -0
- package/docs/archive/README.md +91 -0
- package/docs/patterns/command-agent-skill.md +1 -1
- package/docs/skills/REFERENCE.md +0 -17
- package/docs//303/242mmaAAA/303/242 +357 -0
- package/index.bundle.ts +25 -0
- package/index.ts +95 -4
- package/package.json +15 -4
- package/skills/iterative-audit/SKILL.md +0 -1
- package/skills/widget-rendering/SKILL.md +17 -0
- package/src/adapters/claude-adapter.ts +1 -3
- package/src/adapters/export-util.ts +16 -16
- package/src/adapters/index.ts +5 -5
- package/src/agents/agent-config.ts +20 -14
- package/src/agents/agent-serializer.ts +1 -1
- package/src/agents/discover-agents.ts +83 -39
- package/src/benchmark/benchmark-runner.ts +51 -51
- package/src/benchmark/feedback-loop.ts +1 -1
- package/src/config/config.ts +166 -590
- package/src/config/defaults.ts +28 -2
- package/src/config/drift-detector.ts +11 -14
- package/src/config/markers.ts +201 -203
- package/src/config/resilient-parser.ts +14 -6
- package/src/config/role-tools.ts +3 -3
- package/src/config/suggestions.ts +5 -12
- package/src/config/types.ts +9 -25
- package/src/errors.ts +151 -157
- package/src/extension/action-suggestions.ts +54 -9
- package/src/extension/async-notifier.ts +43 -13
- package/src/extension/autonomous-policy.ts +77 -37
- package/src/extension/command-completions.ts +9 -8
- package/src/extension/context-status-injection.ts +14 -12
- package/src/extension/crew-autocomplete.ts +8 -16
- package/src/extension/crew-cleanup.ts +2 -1
- package/src/extension/crew-shortcuts.ts +9 -6
- package/src/extension/cross-extension-rpc.ts +136 -42
- package/src/extension/help.ts +1 -1
- package/src/extension/import-index.ts +10 -5
- package/src/extension/knowledge-injection.ts +88 -15
- package/src/extension/management.ts +89 -349
- package/src/extension/message-renderers.ts +3 -4
- package/src/extension/notification-router.ts +22 -5
- package/src/extension/notification-sink.ts +6 -3
- package/src/extension/pi-api.ts +17 -8
- package/src/extension/plan-orchestrate.ts +8 -27
- package/src/extension/project-init.ts +21 -6
- package/src/extension/register.ts +329 -975
- package/src/extension/registration/artifact-cleanup.ts +9 -4
- package/src/extension/registration/command-utils.ts +5 -1
- package/src/extension/registration/commands.ts +806 -314
- package/src/extension/registration/compaction-guard.ts +15 -15
- package/src/extension/registration/lifecycle.ts +259 -0
- package/src/extension/registration/observability.ts +293 -0
- package/src/extension/registration/subagent-helpers.ts +29 -7
- package/src/extension/registration/subagent-tools.ts +253 -44
- package/src/extension/registration/team-tool.ts +19 -84
- package/src/extension/registration/ui.ts +168 -0
- package/src/extension/registration/viewers.ts +64 -24
- package/src/extension/result-watcher.ts +18 -7
- package/src/extension/run-bundle-schema.ts +21 -6
- package/src/extension/run-export.ts +15 -6
- package/src/extension/run-import.ts +64 -29
- package/src/extension/run-index.ts +28 -9
- package/src/extension/run-maintenance.ts +32 -12
- package/src/extension/session-summary.ts +1 -1
- package/src/extension/team-manager-command.ts +64 -7
- package/src/extension/team-onboard.ts +151 -150
- package/src/extension/team-recommendation.ts +121 -21
- package/src/extension/team-tool/anchor.ts +31 -64
- package/src/extension/team-tool/api.ts +929 -141
- package/src/extension/team-tool/auto-summarize.ts +14 -26
- package/src/extension/team-tool/cache-control.ts +1 -5
- package/src/extension/team-tool/cancel.ts +138 -38
- package/src/extension/team-tool/chain-dispatch.ts +5 -13
- package/src/extension/team-tool/chain-executor.ts +29 -51
- package/src/extension/team-tool/config-patch.ts +1 -1
- package/src/extension/team-tool/context.ts +40 -20
- package/src/extension/team-tool/destructive-gate.ts +10 -5
- package/src/extension/team-tool/doctor.ts +170 -51
- package/src/extension/team-tool/explain.ts +228 -214
- package/src/extension/team-tool/failure-patterns.ts +3 -9
- package/src/extension/team-tool/goal-wrap.ts +71 -29
- package/src/extension/team-tool/goal.ts +185 -35
- package/src/extension/team-tool/handle-schedule.ts +34 -15
- package/src/extension/team-tool/handle-settings.ts +94 -56
- package/src/extension/team-tool/health-monitor.ts +27 -108
- package/src/extension/team-tool/inspect.ts +42 -9
- package/src/extension/team-tool/intent-policy.ts +4 -1
- package/src/extension/team-tool/lifecycle-actions.ts +244 -48
- package/src/extension/team-tool/orchestrate.ts +7 -18
- package/src/extension/team-tool/parallel-dispatch.ts +51 -29
- package/src/extension/team-tool/plan.ts +29 -5
- package/src/extension/team-tool/respond.ts +49 -16
- package/src/extension/team-tool/run-not-found.ts +3 -8
- package/src/extension/team-tool/run.ts +80 -317
- package/src/extension/team-tool/status.ts +135 -43
- package/src/extension/team-tool/workflow-manage.ts +92 -25
- package/src/extension/team-tool-types.ts +8 -1
- package/src/extension/team-tool.ts +142 -551
- package/src/extension/validate-resources.ts +39 -8
- package/src/hooks/registry.ts +66 -17
- package/src/hooks/types.ts +1 -1
- package/src/i18n.ts +25 -11
- package/src/observability/correlation.ts +17 -3
- package/src/observability/event-bus.ts +51 -56
- package/src/observability/event-to-metric.ts +117 -15
- package/src/observability/exporters/otlp-exporter.ts +56 -17
- package/src/observability/exporters/prometheus-exporter.ts +1 -1
- package/src/observability/metric-registry.ts +16 -4
- package/src/observability/metric-retention.ts +8 -2
- package/src/observability/metric-sink.ts +11 -3
- package/src/observability/metrics-primitives.ts +42 -9
- package/src/plugins/plugin-define.ts +2 -2
- package/src/plugins/plugin-registry.ts +25 -25
- package/src/plugins/plugins/index.ts +1 -1
- package/src/plugins/plugins/nextjs.ts +16 -16
- package/src/plugins/plugins/vite.ts +7 -11
- package/src/plugins/plugins/vitest.ts +6 -11
- package/src/runtime/adaptive-plan.ts +225 -40
- package/src/runtime/agent-control.ts +58 -15
- package/src/runtime/agent-memory.ts +15 -9
- package/src/runtime/agent-observability.ts +10 -2
- package/src/runtime/anchor-manager.ts +27 -25
- package/src/runtime/async-marker.ts +7 -1
- package/src/runtime/async-runner.ts +27 -23
- package/src/runtime/auto-summarize.ts +7 -13
- package/src/runtime/background-runner.ts +189 -251
- package/src/runtime/batch-barrier.ts +18 -16
- package/src/runtime/cancellation-token.ts +16 -6
- package/src/runtime/cancellation.ts +46 -8
- package/src/runtime/capability-inventory.ts +6 -4
- package/src/runtime/chain-parser.ts +44 -11
- package/src/runtime/chain-runner.ts +63 -69
- package/src/runtime/checkpoint.ts +12 -56
- package/src/runtime/child-pi.ts +343 -78
- package/src/runtime/coalesce-tasks.ts +268 -0
- package/src/runtime/code-summary.ts +71 -26
- package/src/runtime/compact-stages/index.ts +15 -5
- package/src/runtime/compact-stages/tail-capture-stage.ts +7 -2
- package/src/runtime/compact-stages/truncation-stage.ts +4 -1
- package/src/runtime/compaction-summary.ts +17 -10
- package/src/runtime/completion-guard.ts +33 -16
- package/src/runtime/crash-classification.ts +28 -7
- package/src/runtime/crash-recovery.ts +177 -37
- package/src/runtime/crew-agent-records.ts +145 -47
- package/src/runtime/crew-hooks.ts +9 -24
- package/src/runtime/cross-extension-rpc.ts +25 -23
- package/src/runtime/custom-tools/irc-tool.ts +43 -15
- package/src/runtime/custom-tools/submit-result-tool.ts +16 -5
- package/src/runtime/delivery-coordinator.ts +34 -7
- package/src/runtime/delta-conflict.ts +9 -21
- package/src/runtime/deterministic-ast.ts +1 -1
- package/src/runtime/diagnostic-export.ts +53 -20
- package/src/runtime/direct-run.ts +12 -2
- package/src/runtime/dwf-state-store.ts +1 -1
- package/src/runtime/dynamic-workflow-context.ts +186 -58
- package/src/runtime/dynamic-workflow-runner.ts +42 -20
- package/src/runtime/effectiveness.ts +16 -8
- package/src/runtime/errors/crew-errors.ts +7 -11
- package/src/runtime/event-stream-bridge.ts +9 -3
- package/src/runtime/foreground-control.ts +54 -14
- package/src/runtime/foreground-watchdog.ts +9 -6
- package/src/runtime/goal-achievement.ts +27 -10
- package/src/runtime/goal-evaluator.ts +54 -19
- package/src/runtime/goal-loop-runner.ts +280 -99
- package/src/runtime/goal-state-store.ts +27 -17
- package/src/runtime/green-contract.ts +11 -2
- package/src/runtime/group-join.ts +64 -31
- package/src/runtime/handoff-manager.ts +37 -42
- package/src/runtime/heartbeat-gradient.ts +10 -2
- package/src/runtime/heartbeat-watcher.ts +32 -6
- package/src/runtime/hidden-handoff.ts +12 -30
- package/src/runtime/important-line-classifier.ts +12 -2
- package/src/runtime/iteration-hooks.ts +25 -15
- package/src/runtime/live-agent-control.ts +55 -7
- package/src/runtime/live-agent-manager.ts +130 -27
- package/src/runtime/live-control-realtime.ts +23 -3
- package/src/runtime/live-irc.ts +4 -1
- package/src/runtime/live-session-health.ts +12 -4
- package/src/runtime/live-session-runtime.ts +379 -117
- package/src/runtime/manifest-cache.ts +28 -12
- package/src/runtime/mcp-proxy.ts +8 -16
- package/src/runtime/metric-parser.ts +1 -5
- package/src/runtime/model-fallback.ts +55 -18
- package/src/runtime/model-resolver.ts +2 -6
- package/src/runtime/model-scope.ts +19 -3
- package/src/runtime/notebook-helpers.ts +60 -62
- package/src/runtime/orphan-worker-registry.ts +37 -26
- package/src/runtime/output-validator.ts +18 -3
- package/src/runtime/overflow-recovery.ts +5 -4
- package/src/runtime/parallel-research.ts +29 -5
- package/src/runtime/parallel-utils.ts +9 -11
- package/src/runtime/path-overlap.ts +150 -0
- package/src/runtime/peer-dep.ts +12 -17
- package/src/runtime/per-write-validator.ts +1 -3
- package/src/runtime/phase-tracker.ts +342 -330
- package/src/runtime/pi-args.ts +26 -8
- package/src/runtime/pi-json-output.ts +1 -1
- package/src/runtime/pi-spawn.ts +30 -19
- package/src/runtime/pipeline-runner.ts +56 -55
- package/src/runtime/plan-templates.ts +5 -6
- package/src/runtime/policy-engine.ts +43 -7
- package/src/runtime/post-checks.ts +12 -4
- package/src/runtime/post-exit-stdio-guard.ts +2 -2
- package/src/runtime/process-lifecycle.ts +20 -10
- package/src/runtime/process-status.ts +16 -5
- package/src/runtime/progress-event-coalescer.ts +2 -1
- package/src/runtime/progress-tracker.ts +103 -103
- package/src/runtime/prose-compressor.ts +9 -11
- package/src/runtime/recovery-recipes.ts +118 -24
- package/src/runtime/replace.ts +25 -10
- package/src/runtime/resilient-edit.ts +10 -25
- package/src/runtime/result-extractor.ts +1 -2
- package/src/runtime/retry-executor.ts +20 -4
- package/src/runtime/retry-runner.ts +26 -50
- package/src/runtime/role-permission.ts +6 -1
- package/src/runtime/run-coalesced-task-group.ts +256 -0
- package/src/runtime/run-drift.ts +14 -15
- package/src/runtime/run-tracker.ts +6 -28
- package/src/runtime/runtime-policy.ts +1 -6
- package/src/runtime/runtime-resolver.ts +80 -15
- package/src/runtime/scheduler.ts +47 -18
- package/src/runtime/semaphore.ts +5 -7
- package/src/runtime/sensitive-paths.ts +2 -1
- package/src/runtime/session-usage.ts +1 -1
- package/src/runtime/settings-store.ts +16 -12
- package/src/runtime/sidechain-output.ts +6 -2
- package/src/runtime/single-agent-compose.ts +1 -4
- package/src/runtime/skill-effectiveness.ts +29 -97
- package/src/runtime/skill-instructions.ts +40 -83
- package/src/runtime/stale-reconciler.ts +73 -197
- package/src/runtime/stream-preview.ts +1 -1
- package/src/runtime/streaming-output.ts +1 -1
- package/src/runtime/subagent-manager.ts +44 -169
- package/src/runtime/subprocess-tool-registry.ts +4 -1
- package/src/runtime/supervisor-contact.ts +10 -5
- package/src/runtime/task-display.ts +19 -5
- package/src/runtime/task-graph-scheduler.ts +95 -21
- package/src/runtime/task-graph.ts +5 -11
- package/src/runtime/task-health.ts +54 -47
- package/src/runtime/task-id.ts +11 -18
- package/src/runtime/task-output-context.ts +265 -81
- package/src/runtime/task-packet.ts +12 -20
- package/src/runtime/task-quality.ts +6 -14
- package/src/runtime/task-runner/context-retrieval.ts +4 -13
- package/src/runtime/task-runner/live-executor.ts +114 -36
- package/src/runtime/task-runner/output-splitter.ts +152 -0
- package/src/runtime/task-runner/progress.ts +50 -12
- package/src/runtime/task-runner/prompt-builder.ts +31 -7
- package/src/runtime/task-runner/prompt-pipeline.ts +31 -7
- package/src/runtime/task-runner/result-utils.ts +3 -1
- package/src/runtime/task-runner/retrieval-orchestrator.ts +310 -0
- package/src/runtime/task-runner/run-projection.ts +27 -8
- package/src/runtime/task-runner/state-helpers.ts +29 -8
- package/src/runtime/task-runner/tail-read.ts +2 -6
- package/src/runtime/task-runner.ts +180 -326
- package/src/runtime/team-runner-artifacts.ts +13 -0
- package/src/runtime/team-runner.ts +456 -974
- package/src/runtime/tool-output-pruner.ts +6 -9
- package/src/runtime/tool-progress.ts +11 -21
- package/src/runtime/verification-gates.ts +33 -24
- package/src/runtime/verification-integrity.ts +1 -4
- package/src/runtime/verification-worktree.ts +62 -12
- package/src/runtime/worker-heartbeat.ts +5 -1
- package/src/runtime/worker-startup.ts +29 -5
- package/src/runtime/workflow-state.ts +17 -9
- package/src/runtime/workspace-lock.ts +30 -35
- package/src/runtime/workspace-tree.ts +20 -32
- package/src/runtime/yield-handler.ts +43 -9
- package/src/runtime/zombie-scanner.ts +5 -4
- package/src/schema/config-schema.ts +266 -172
- package/src/schema/team-tool-schema.ts +29 -74
- package/src/schema/validation-types.ts +25 -17
- package/src/skills/discover-skills.ts +35 -10
- package/src/skills/skill-templates.ts +109 -27
- package/src/skills/validate.ts +26 -8
- package/src/state/active-run-registry.ts +87 -28
- package/src/state/artifact-store.ts +9 -5
- package/src/state/atomic-write-v2.ts +85 -63
- package/src/state/atomic-write.ts +105 -26
- package/src/state/blob-store.ts +47 -20
- package/src/state/contracts.ts +20 -5
- package/src/state/crew-init.ts +5 -22
- package/src/state/decision-ledger.ts +19 -73
- package/src/state/event-log-rotation.ts +41 -15
- package/src/state/event-log.ts +168 -53
- package/src/state/event-reconstructor.ts +11 -1
- package/src/state/gitignore-manager.ts +2 -8
- package/src/state/health-store.ts +57 -57
- package/src/state/hook-instinct-bridge.ts +1 -1
- package/src/state/hook-integrations.ts +1 -1
- package/src/state/instinct-store.ts +17 -5
- package/src/state/jsonl-writer.ts +1 -1
- package/src/state/locks.ts +23 -9
- package/src/state/mailbox.ts +151 -28
- package/src/state/observation-store.ts +20 -14
- package/src/state/run-cache.ts +142 -135
- package/src/state/run-graph.ts +6 -15
- package/src/state/run-metrics.ts +5 -18
- package/src/state/schedule.ts +15 -9
- package/src/state/state-store.ts +129 -45
- package/src/state/task-claims.ts +12 -2
- package/src/state/tiered-eval.ts +52 -43
- package/src/state/types-eval.ts +2 -2
- package/src/state/types.ts +24 -20
- package/src/state/usage.ts +20 -4
- package/src/state/worker-atomic-writer.ts +6 -3
- package/src/subagents/index.ts +2 -2
- package/src/teams/discover-teams.ts +21 -6
- package/src/tools/safe-bash-extension.ts +5 -6
- package/src/tools/safe-bash.ts +10 -11
- package/src/types/new-api-types.ts +6 -10
- package/src/ui/agent-management-overlay.ts +52 -40
- package/src/ui/card-colors.ts +13 -4
- package/src/ui/crew-footer.ts +8 -7
- package/src/ui/crew-select-list.ts +1 -1
- package/src/ui/dashboard-panes/agents-pane.ts +41 -25
- package/src/ui/dashboard-panes/cancellation-pane.ts +1 -1
- package/src/ui/dashboard-panes/capability-pane.ts +32 -15
- package/src/ui/dashboard-panes/health-pane.ts +2 -1
- package/src/ui/dashboard-panes/metrics-pane.ts +4 -1
- package/src/ui/dashboard-panes/progress-pane.ts +12 -9
- package/src/ui/heartbeat-aggregator.ts +15 -4
- package/src/ui/keybinding-map.ts +40 -7
- package/src/ui/live-conversation-overlay.ts +36 -20
- package/src/ui/live-duration.ts +1 -4
- package/src/ui/live-run-sidebar.ts +88 -25
- package/src/ui/loaders.ts +2 -8
- package/src/ui/mascot.ts +20 -36
- package/src/ui/overlays/agent-picker-overlay.ts +11 -3
- package/src/ui/overlays/confirm-overlay.ts +4 -2
- package/src/ui/overlays/help-overlay.ts +25 -14
- package/src/ui/overlays/mailbox-compose-overlay.ts +48 -11
- package/src/ui/overlays/mailbox-compose-preview.ts +20 -5
- package/src/ui/overlays/mailbox-detail-overlay.ts +27 -6
- package/src/ui/pi-ui-compat.ts +7 -7
- package/src/ui/powerbar-publisher.ts +120 -42
- package/src/ui/render-diff.ts +10 -3
- package/src/ui/render-scheduler.ts +12 -4
- package/src/ui/run-action-dispatcher.ts +81 -18
- package/src/ui/run-dashboard.ts +172 -76
- package/src/ui/run-event-bus.ts +59 -37
- package/src/ui/run-snapshot-cache.ts +276 -86
- package/src/ui/settings-overlay.ts +361 -74
- package/src/ui/status-colors.ts +12 -1
- package/src/ui/syntax-highlight.ts +1 -1
- package/src/ui/theme-adapter.ts +16 -14
- package/src/ui/theme-discovery.ts +13 -2
- package/src/ui/tool-progress-formatter.ts +7 -7
- package/src/ui/tool-render.ts +128 -56
- package/src/ui/tool-renderers/brief-mode.ts +45 -27
- package/src/ui/tool-renderers/index.ts +109 -43
- package/src/ui/transcript-cache.ts +32 -6
- package/src/ui/transcript-entries.ts +25 -23
- package/src/ui/transcript-viewer.ts +78 -29
- package/src/ui/widget/index.ts +99 -40
- package/src/ui/widget/widget-formatters.ts +13 -6
- package/src/ui/widget/widget-model.ts +19 -8
- package/src/ui/widget/widget-renderer.ts +23 -13
- package/src/ui/widget/widget-types.ts +1 -1
- package/src/utils/bm25-search.ts +199 -199
- package/src/utils/conflict-detect.ts +22 -21
- package/src/utils/env-filter.ts +14 -7
- package/src/utils/file-coalescer.ts +5 -1
- package/src/utils/fingerprint.ts +3 -6
- package/src/utils/frontmatter.ts +3 -1
- package/src/utils/fs-watch.ts +2 -6
- package/src/utils/gh-protocol.ts +119 -44
- package/src/utils/git.ts +13 -15
- package/src/utils/guards.ts +2 -5
- package/src/utils/ids.ts +9 -2
- package/src/utils/incremental-reader.ts +14 -3
- package/src/utils/internal-error.ts +2 -1
- package/src/utils/names.ts +12 -3
- package/src/utils/paths.ts +49 -5
- package/src/utils/project-detector.ts +2 -2
- package/src/utils/redaction.ts +29 -19
- package/src/utils/resolve-shell.ts +9 -7
- package/src/utils/run-watcher-registry.ts +19 -31
- package/src/utils/safe-paths.ts +45 -24
- package/src/utils/scan-cache.ts +9 -2
- package/src/utils/session-utils.ts +2 -4
- package/src/utils/sleep.ts +12 -5
- package/src/utils/sse-parser.ts +5 -17
- package/src/utils/visual.ts +52 -32
- package/src/workflows/discover-workflows.ts +41 -109
- package/src/workflows/intermediate-store.ts +5 -21
- package/src/workflows/preflight-validator.ts +6 -33
- package/src/workflows/topology-analyzer.ts +5 -21
- package/src/workflows/workflow-config.ts +7 -6
- package/src/worktree/branch-freshness.ts +66 -8
- package/src/worktree/cleanup.ts +130 -20
- package/src/worktree/worktree-manager.ts +212 -69
- package/skills/artifact-analysis-loop/SKILL.md +0 -303
- package/skills/detection-pipeline-design/SKILL.md +0 -286
- package/skills/hunting-investigation-loop/SKILL.md +0 -402
- package/skills/incident-playbook-construction/SKILL.md +0 -384
- package/skills/security-review/SKILL.md +0 -561
- package/skills/threat-hypothesis-framework/SKILL.md +0 -176
- package/skills/ui-render-performance/SKILL.md +0 -58
- /package/docs/{followup-review-round3-2026-05-12.md → archive/followup-review-round3-2026-05-12.md} +0 -0
- /package/docs/{followup-review-round4-2026-05-13.md → archive/followup-review-round4-2026-05-13.md} +0 -0
- /package/docs/{pi-crew-bugs.md → archive/pi-crew-bugs.md} +0 -0
- /package/docs/{pi-crew-test-final.md → archive/pi-crew-test-final.md} +0 -0
- /package/docs/{pi-crew-test-results.md → archive/pi-crew-test-results.md} +0 -0
- /package/docs/{pi-crew-test-round2.md → archive/pi-crew-test-round2.md} +0 -0
- /package/docs/{pi-crew-test-round4.md → archive/pi-crew-test-round4.md} +0 -0
- /package/docs/{pi-crew-test-round5.md → archive/pi-crew-test-round5.md} +0 -0
- /package/docs/{pi-crew-test-round6.md → archive/pi-crew-test-round6.md} +0 -0
- /package/docs/{pi-crew-v0.5.10-audit-fix-plan.md → archive/pi-crew-v0.5.10-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.11-audit-fix-plan.md → archive/pi-crew-v0.5.11-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.12-audit-fix-plan.md → archive/pi-crew-v0.5.12-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.13-audit-fix-plan.md → archive/pi-crew-v0.5.13-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.14-audit-fix-plan.md → archive/pi-crew-v0.5.14-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.16-audit-fix-plan.md → archive/pi-crew-v0.5.16-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.17-audit-fix-plan.md → archive/pi-crew-v0.5.17-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.5-audit-fix-plan.md → archive/pi-crew-v0.5.5-audit-fix-plan.md} +0 -0
- /package/docs/{pi-crew-v0.5.9-audit-fix-plan.md → archive/pi-crew-v0.5.9-audit-fix-plan.md} +0 -0
- /package/docs/{pi-mono-opportunities.md → archive/pi-mono-opportunities.md} +0 -0
- /package/docs/{pi-mono-review.md → archive/pi-mono-review.md} +0 -0
- /package/docs/{pi-subagent4-comparison.md → archive/pi-subagent4-comparison.md} +0 -0
- /package/docs/{pi-subagents3-deep-analysis.md → archive/pi-subagents3-deep-analysis.md} +0 -0
|
@@ -3,8 +3,12 @@ import type { TeamToolParamsValue } from "../schema/team-tool-schema.ts";
|
|
|
3
3
|
import { resolveContainedPath } from "../utils/safe-paths.ts";
|
|
4
4
|
// Lazy-loaded to avoid pulling team-tool.ts (and its entire runtime chain) into module load.
|
|
5
5
|
import type { handleTeamTool as HandleTeamToolFn } from "./team-tool.ts";
|
|
6
|
+
|
|
6
7
|
let _cachedHandleTeamTool: typeof HandleTeamToolFn | undefined;
|
|
7
|
-
async function handleTeamTool(
|
|
8
|
+
async function handleTeamTool(
|
|
9
|
+
params: Parameters<typeof HandleTeamToolFn>[0],
|
|
10
|
+
ctx: Parameters<typeof HandleTeamToolFn>[1],
|
|
11
|
+
): Promise<Awaited<ReturnType<typeof HandleTeamToolFn>>> {
|
|
8
12
|
if (!_cachedHandleTeamTool) {
|
|
9
13
|
// LAZY: avoid pulling team-tool.ts (and its entire runtime chain) into module load.
|
|
10
14
|
const mod = await import("./team-tool.ts");
|
|
@@ -12,6 +16,7 @@ async function handleTeamTool(params: Parameters<typeof HandleTeamToolFn>[0], ct
|
|
|
12
16
|
}
|
|
13
17
|
return _cachedHandleTeamTool(params, ctx);
|
|
14
18
|
}
|
|
19
|
+
|
|
15
20
|
import { parseLiveControlRealtimeMessage, publishLiveControlRealtime } from "../runtime/live-control-realtime.ts";
|
|
16
21
|
|
|
17
22
|
export interface EventBusLike {
|
|
@@ -27,7 +32,9 @@ export interface PiCrewRpcHandle {
|
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
function requestId(raw: unknown): string | undefined {
|
|
30
|
-
return raw && typeof raw === "object" && !Array.isArray(raw) && typeof (raw as { requestId?: unknown }).requestId === "string"
|
|
35
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) && typeof (raw as { requestId?: unknown }).requestId === "string"
|
|
36
|
+
? (raw as { requestId: string }).requestId
|
|
37
|
+
: undefined;
|
|
31
38
|
}
|
|
32
39
|
|
|
33
40
|
function reply(events: EventBusLike, channel: string, id: string | undefined, payload: RpcReply): void {
|
|
@@ -38,7 +45,7 @@ function reply(events: EventBusLike, channel: string, id: string | undefined, pa
|
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
function textOf(result: Awaited<ReturnType<typeof handleTeamTool>>): string {
|
|
41
|
-
return result.content?.map((item) => item.type === "text" ? item.text : "").join("\n") ?? "";
|
|
48
|
+
return result.content?.map((item) => (item.type === "text" ? item.text : "")).join("\n") ?? "";
|
|
42
49
|
}
|
|
43
50
|
|
|
44
51
|
// SECURITY: Strictly enumerate allowed operations per RPC channel.
|
|
@@ -46,13 +53,23 @@ function textOf(result: Awaited<ReturnType<typeof handleTeamTool>>): string {
|
|
|
46
53
|
// from mutating run state without user consent.
|
|
47
54
|
const RPC_ALLOWED_OPERATIONS = new Set([
|
|
48
55
|
// Read-only manifest/plan ops
|
|
49
|
-
"metrics-snapshot",
|
|
50
|
-
"
|
|
56
|
+
"metrics-snapshot",
|
|
57
|
+
"inventory",
|
|
58
|
+
"read-manifest",
|
|
59
|
+
"list-tasks",
|
|
60
|
+
"read-task",
|
|
61
|
+
"read-events",
|
|
51
62
|
// Read-only agent ops
|
|
52
|
-
"list-agents",
|
|
53
|
-
"read-agent-
|
|
63
|
+
"list-agents",
|
|
64
|
+
"read-agent-status",
|
|
65
|
+
"read-agent-events",
|
|
66
|
+
"read-agent-transcript",
|
|
67
|
+
"read-agent-output",
|
|
68
|
+
"agent-dashboard",
|
|
54
69
|
// Mailbox read ops
|
|
55
|
-
"read-mailbox",
|
|
70
|
+
"read-mailbox",
|
|
71
|
+
"read-delivery",
|
|
72
|
+
"read-heartbeat",
|
|
56
73
|
// No mutating ops (approve-plan, cancel-plan, steer-agent, stop-agent, etc.)
|
|
57
74
|
// — these require explicit intent confirmation and are NOT allowed via RPC.
|
|
58
75
|
]);
|
|
@@ -91,20 +108,29 @@ export function resetRpcRateLimit(): void {
|
|
|
91
108
|
rpcRunTimestamps.length = 0;
|
|
92
109
|
}
|
|
93
110
|
|
|
94
|
-
function isAllowedRpcRunParams(params: TeamToolParamsValue): {
|
|
111
|
+
function isAllowedRpcRunParams(params: TeamToolParamsValue): {
|
|
112
|
+
ok: boolean;
|
|
113
|
+
error?: string;
|
|
114
|
+
} {
|
|
95
115
|
// SECURITY: Require explicit intent for any RPC-initiated run creation.
|
|
96
116
|
// This prevents malicious extensions from spawning child Pi processes silently.
|
|
97
117
|
const cfg = params.config as Record<string, unknown> | undefined;
|
|
98
118
|
const intent = cfg?.intent as string | undefined;
|
|
99
119
|
if (!intent || typeof intent !== "string" || intent.trim().length === 0) {
|
|
100
|
-
return {
|
|
120
|
+
return {
|
|
121
|
+
ok: false,
|
|
122
|
+
error: "RPC run requires config.intent (a non-empty intent string)",
|
|
123
|
+
};
|
|
101
124
|
}
|
|
102
125
|
// SECURITY: Validate cwd is within the project directory if provided.
|
|
103
126
|
if (params.cwd && typeof params.cwd === "string") {
|
|
104
127
|
try {
|
|
105
128
|
resolveContainedPath(params.cwd, ".");
|
|
106
129
|
} catch {
|
|
107
|
-
return {
|
|
130
|
+
return {
|
|
131
|
+
ok: false,
|
|
132
|
+
error: "RPC run config.cwd must be within the project directory",
|
|
133
|
+
};
|
|
108
134
|
}
|
|
109
135
|
}
|
|
110
136
|
return { ok: true };
|
|
@@ -121,10 +147,18 @@ function on(events: EventBusLike, channel: string, handler: (raw: unknown) => vo
|
|
|
121
147
|
// requirement for runs, operation allowlist for live-control reads, and cwd
|
|
122
148
|
// containment validation. A full fix requires event-bus-level origin signing.
|
|
123
149
|
|
|
124
|
-
export function registerPiCrewRpc(
|
|
150
|
+
export function registerPiCrewRpc(
|
|
151
|
+
events: EventBusLike | undefined,
|
|
152
|
+
getCtx: () => ExtensionContext | undefined,
|
|
153
|
+
): PiCrewRpcHandle | undefined {
|
|
125
154
|
if (!events) return undefined;
|
|
126
155
|
const unsubs = [
|
|
127
|
-
on(events, "pi-crew:rpc:ping", (raw) =>
|
|
156
|
+
on(events, "pi-crew:rpc:ping", (raw) =>
|
|
157
|
+
reply(events, "pi-crew:rpc:ping", requestId(raw), {
|
|
158
|
+
success: true,
|
|
159
|
+
data: { version: PI_CREW_RPC_VERSION },
|
|
160
|
+
}),
|
|
161
|
+
),
|
|
128
162
|
on(events, "pi-crew:rpc:run", async (raw) => {
|
|
129
163
|
const id = requestId(raw);
|
|
130
164
|
try {
|
|
@@ -144,24 +178,40 @@ export function registerPiCrewRpc(events: EventBusLike | undefined, getCtx: () =
|
|
|
144
178
|
const ALLOWED_RPC_RUN_KEYS = new Set(["goal", "team", "workflow", "async", "cwd", "config", "skill", "model"]);
|
|
145
179
|
let params: TeamToolParamsValue;
|
|
146
180
|
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
147
|
-
const filtered: Record<string, unknown> = {
|
|
181
|
+
const filtered: Record<string, unknown> = {
|
|
182
|
+
...(raw as object),
|
|
183
|
+
};
|
|
148
184
|
// Strip any keys not in the allowlist to prevent injection of unexpected fields
|
|
149
185
|
for (const key of Object.keys(filtered)) {
|
|
150
186
|
if (!ALLOWED_RPC_RUN_KEYS.has(key)) delete filtered[key];
|
|
151
187
|
}
|
|
152
|
-
params = {
|
|
188
|
+
params = {
|
|
189
|
+
...filtered,
|
|
190
|
+
action: "run",
|
|
191
|
+
} as TeamToolParamsValue;
|
|
153
192
|
} else {
|
|
154
193
|
params = { action: "run" };
|
|
155
194
|
}
|
|
156
195
|
const permission = isAllowedRpcRunParams(params);
|
|
157
196
|
if (!permission.ok) {
|
|
158
|
-
reply(events, "pi-crew:rpc:run", id, {
|
|
197
|
+
reply(events, "pi-crew:rpc:run", id, {
|
|
198
|
+
success: false,
|
|
199
|
+
error: permission.error ?? "permission denied",
|
|
200
|
+
});
|
|
159
201
|
return;
|
|
160
202
|
}
|
|
161
203
|
const result = await handleTeamTool(params, ctx);
|
|
162
|
-
reply(
|
|
204
|
+
reply(
|
|
205
|
+
events,
|
|
206
|
+
"pi-crew:rpc:run",
|
|
207
|
+
id,
|
|
208
|
+
result.isError ? { success: false, error: textOf(result) } : { success: true, data: result.details },
|
|
209
|
+
);
|
|
163
210
|
} catch (error) {
|
|
164
|
-
reply(events, "pi-crew:rpc:run", id, {
|
|
211
|
+
reply(events, "pi-crew:rpc:run", id, {
|
|
212
|
+
success: false,
|
|
213
|
+
error: error instanceof Error ? error.message : String(error),
|
|
214
|
+
});
|
|
165
215
|
}
|
|
166
216
|
}),
|
|
167
217
|
on(events, "pi-crew:rpc:status", async (raw) => {
|
|
@@ -171,38 +221,82 @@ export function registerPiCrewRpc(events: EventBusLike | undefined, getCtx: () =
|
|
|
171
221
|
if (!ctx) throw new Error("No active pi-crew session context.");
|
|
172
222
|
const runId = raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as { runId?: string }).runId : undefined;
|
|
173
223
|
const result = await handleTeamTool({ action: "status", runId }, ctx);
|
|
174
|
-
reply(
|
|
224
|
+
reply(
|
|
225
|
+
events,
|
|
226
|
+
"pi-crew:rpc:status",
|
|
227
|
+
id,
|
|
228
|
+
result.isError
|
|
229
|
+
? { success: false, error: textOf(result) }
|
|
230
|
+
: {
|
|
231
|
+
success: true,
|
|
232
|
+
data: {
|
|
233
|
+
text: textOf(result),
|
|
234
|
+
details: result.details,
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
);
|
|
175
238
|
} catch (error) {
|
|
176
|
-
reply(events, "pi-crew:rpc:status", id, {
|
|
239
|
+
reply(events, "pi-crew:rpc:status", id, {
|
|
240
|
+
success: false,
|
|
241
|
+
error: error instanceof Error ? error.message : String(error),
|
|
242
|
+
});
|
|
177
243
|
}
|
|
178
244
|
}),
|
|
179
245
|
on(events, "pi-crew:live-control", (raw) => {
|
|
180
246
|
const request = parseLiveControlRealtimeMessage(raw);
|
|
181
247
|
if (request) publishLiveControlRealtime(request);
|
|
182
248
|
}),
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
const result = await handleTeamTool({ action: "api", runId: typeof obj.runId === "string" ? obj.runId : undefined, config: { operation: rawOp, agentId: obj.agentId, message: obj.message, prompt: obj.prompt } }, ctx);
|
|
201
|
-
reply(events, "pi-crew:rpc:live-control", id, result.isError ? { success: false, error: textOf(result) } : { success: true, data: { text: textOf(result), details: result.details } });
|
|
202
|
-
} catch (error) {
|
|
203
|
-
reply(events, "pi-crew:rpc:live-control", id, { success: false, error: error instanceof Error ? error.message : String(error) });
|
|
249
|
+
on(events, "pi-crew:rpc:live-control", async (raw) => {
|
|
250
|
+
const id = requestId(raw);
|
|
251
|
+
try {
|
|
252
|
+
const ctx = getCtx();
|
|
253
|
+
if (!ctx) throw new Error("No active pi-crew session context.");
|
|
254
|
+
const obj = raw && typeof raw === "object" && !Array.isArray(raw) ? (raw as Record<string, unknown>) : {};
|
|
255
|
+
const rawOp = typeof obj.operation === "string" ? obj.operation : "steer-agent";
|
|
256
|
+
// SECURITY: Reject any operation not in the explicit allowlist.
|
|
257
|
+
// Mutating ops (approve-plan, cancel-plan, steer-agent, stop-agent, etc.)
|
|
258
|
+
// require user consent and are blocked here.
|
|
259
|
+
if (!isAllowedRpcOperation(rawOp)) {
|
|
260
|
+
reply(events, "pi-crew:rpc:live-control", id, {
|
|
261
|
+
success: false,
|
|
262
|
+
error: `RPC operation '${rawOp}' is not allowed. Allowed: ${[...RPC_ALLOWED_OPERATIONS].join(", ")}`,
|
|
263
|
+
});
|
|
264
|
+
return;
|
|
204
265
|
}
|
|
205
|
-
|
|
266
|
+
const result = await handleTeamTool(
|
|
267
|
+
{
|
|
268
|
+
action: "api",
|
|
269
|
+
runId: typeof obj.runId === "string" ? obj.runId : undefined,
|
|
270
|
+
config: {
|
|
271
|
+
operation: rawOp,
|
|
272
|
+
agentId: obj.agentId,
|
|
273
|
+
message: obj.message,
|
|
274
|
+
prompt: obj.prompt,
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
ctx,
|
|
278
|
+
);
|
|
279
|
+
reply(
|
|
280
|
+
events,
|
|
281
|
+
"pi-crew:rpc:live-control",
|
|
282
|
+
id,
|
|
283
|
+
result.isError
|
|
284
|
+
? { success: false, error: textOf(result) }
|
|
285
|
+
: {
|
|
286
|
+
success: true,
|
|
287
|
+
data: {
|
|
288
|
+
text: textOf(result),
|
|
289
|
+
details: result.details,
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
);
|
|
293
|
+
} catch (error) {
|
|
294
|
+
reply(events, "pi-crew:rpc:live-control", id, {
|
|
295
|
+
success: false,
|
|
296
|
+
error: error instanceof Error ? error.message : String(error),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}),
|
|
206
300
|
];
|
|
207
301
|
return { unsubscribe: () => unsubs.forEach((unsub) => unsub()) };
|
|
208
302
|
}
|
package/src/extension/help.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { projectCrewRoot, userCrewRoot } from "../utils/paths.ts";
|
|
4
3
|
import { DEFAULT_PATHS } from "../config/defaults.ts";
|
|
4
|
+
import { projectCrewRoot, userCrewRoot } from "../utils/paths.ts";
|
|
5
5
|
import { isSafePathId, resolveRealContainedPath } from "../utils/safe-paths.ts";
|
|
6
6
|
|
|
7
7
|
export interface ImportedRunIndexEntry {
|
|
@@ -30,7 +30,10 @@ function readEntry(root: string, scope: "project" | "user", runId: string): Impo
|
|
|
30
30
|
if (!fs.existsSync(bundlePath)) return undefined;
|
|
31
31
|
try {
|
|
32
32
|
const raw = JSON.parse(fs.readFileSync(bundlePath, "utf-8")) as Record<string, unknown>;
|
|
33
|
-
const manifest =
|
|
33
|
+
const manifest =
|
|
34
|
+
raw.manifest && typeof raw.manifest === "object" && !Array.isArray(raw.manifest)
|
|
35
|
+
? (raw.manifest as Record<string, unknown>)
|
|
36
|
+
: {};
|
|
34
37
|
return {
|
|
35
38
|
runId,
|
|
36
39
|
scope,
|
|
@@ -55,7 +58,8 @@ function collect(root: string, scope: "project" | "user"): ImportedRunIndexEntry
|
|
|
55
58
|
} catch {
|
|
56
59
|
return [];
|
|
57
60
|
}
|
|
58
|
-
return fs
|
|
61
|
+
return fs
|
|
62
|
+
.readdirSync(root)
|
|
59
63
|
.filter((entry) => isSafePathId(entry))
|
|
60
64
|
.map((entry) => readEntry(root, scope, entry))
|
|
61
65
|
.filter((entry): entry is ImportedRunIndexEntry => entry !== undefined);
|
|
@@ -64,6 +68,7 @@ function collect(root: string, scope: "project" | "user"): ImportedRunIndexEntry
|
|
|
64
68
|
export function listImportedRuns(cwd: string): ImportedRunIndexEntry[] {
|
|
65
69
|
const projectRoot = path.join(projectCrewRoot(cwd), DEFAULT_PATHS.state.importsSubdir);
|
|
66
70
|
const userRoot = path.join(userCrewRoot(), DEFAULT_PATHS.state.importsSubdir);
|
|
67
|
-
return [...collect(userRoot, "user"), ...collect(projectRoot, "project")]
|
|
68
|
-
|
|
71
|
+
return [...collect(userRoot, "user"), ...collect(projectRoot, "project")].sort((a, b) =>
|
|
72
|
+
(b.importedAt ?? "").localeCompare(a.importedAt ?? ""),
|
|
73
|
+
);
|
|
69
74
|
}
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import * as fs from "node:fs";
|
|
24
24
|
import * as path from "node:path";
|
|
25
|
-
import type { BeforeAgentStartEvent, ExtensionAPI } from "./pi-api.ts";
|
|
26
25
|
import { projectCrewRoot } from "../utils/paths.ts";
|
|
26
|
+
import type { BeforeAgentStartEvent, ExtensionAPI } from "./pi-api.ts";
|
|
27
27
|
|
|
28
28
|
/** The knowledge file, relative to the project crew root. */
|
|
29
29
|
export const KNOWLEDGE_FILENAME = "knowledge.md";
|
|
@@ -73,10 +73,45 @@ interface KnowledgeSection {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
const STOPWORDS = new Set([
|
|
76
|
-
"the",
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
76
|
+
"the",
|
|
77
|
+
"a",
|
|
78
|
+
"an",
|
|
79
|
+
"is",
|
|
80
|
+
"are",
|
|
81
|
+
"of",
|
|
82
|
+
"to",
|
|
83
|
+
"in",
|
|
84
|
+
"for",
|
|
85
|
+
"and",
|
|
86
|
+
"or",
|
|
87
|
+
"not",
|
|
88
|
+
"with",
|
|
89
|
+
"this",
|
|
90
|
+
"that",
|
|
91
|
+
"it",
|
|
92
|
+
"be",
|
|
93
|
+
"on",
|
|
94
|
+
"at",
|
|
95
|
+
"by",
|
|
96
|
+
"do",
|
|
97
|
+
"does",
|
|
98
|
+
"how",
|
|
99
|
+
"what",
|
|
100
|
+
"when",
|
|
101
|
+
"from",
|
|
102
|
+
"fix",
|
|
103
|
+
"fixes",
|
|
104
|
+
"fixed",
|
|
105
|
+
"v0",
|
|
106
|
+
"v1",
|
|
107
|
+
"released",
|
|
108
|
+
"progress",
|
|
109
|
+
"uncommitted",
|
|
110
|
+
"not",
|
|
111
|
+
"pushed",
|
|
112
|
+
"published",
|
|
113
|
+
"session",
|
|
114
|
+
"post",
|
|
80
115
|
]);
|
|
81
116
|
|
|
82
117
|
/** Tokenize header text into a Set of lowercased non-stopword tokens. */
|
|
@@ -91,20 +126,33 @@ function tokenizeHeader(header: string): Set<string> {
|
|
|
91
126
|
}
|
|
92
127
|
|
|
93
128
|
/** Parse knowledge.md into (conventions, sessionLog) sections by H2 header. */
|
|
94
|
-
function parseKnowledgeSections(content: string): {
|
|
129
|
+
function parseKnowledgeSections(content: string): {
|
|
130
|
+
conventions: KnowledgeSection[];
|
|
131
|
+
sessionLog: KnowledgeSection[];
|
|
132
|
+
} {
|
|
95
133
|
const lines = content.split(/\r?\n/);
|
|
96
134
|
const sections: KnowledgeSection[] = [];
|
|
97
135
|
let current: { header: string; lines: string[] } | null = null;
|
|
98
136
|
for (const line of lines) {
|
|
99
137
|
const m = /^##\s+(.+?)\s*$/.exec(line);
|
|
100
138
|
if (m) {
|
|
101
|
-
if (current)
|
|
139
|
+
if (current)
|
|
140
|
+
sections.push({
|
|
141
|
+
header: current.header,
|
|
142
|
+
body: current.lines.join("\n"),
|
|
143
|
+
headerTokens: tokenizeHeader(current.header),
|
|
144
|
+
});
|
|
102
145
|
current = { header: m[1]!, lines: [line] };
|
|
103
146
|
} else if (current) {
|
|
104
147
|
current.lines.push(line);
|
|
105
148
|
}
|
|
106
149
|
}
|
|
107
|
-
if (current)
|
|
150
|
+
if (current)
|
|
151
|
+
sections.push({
|
|
152
|
+
header: current.header,
|
|
153
|
+
body: current.lines.join("\n"),
|
|
154
|
+
headerTokens: tokenizeHeader(current.header),
|
|
155
|
+
});
|
|
108
156
|
|
|
109
157
|
// Classify: a section is a CONVENTION if its header starts-with one of the
|
|
110
158
|
// known convention titles. Once we leave the convention run (first non-
|
|
@@ -168,7 +216,12 @@ function selectSessionLog(query: string, sessionLog: KnowledgeSection[], budgetB
|
|
|
168
216
|
const scored = sessionLog
|
|
169
217
|
.map((sec, idx) => {
|
|
170
218
|
const overlap = [...queryTokens].filter((t) => sec.headerTokens.has(t));
|
|
171
|
-
return {
|
|
219
|
+
return {
|
|
220
|
+
sec,
|
|
221
|
+
score: overlap.reduce((sum, t) => sum + (idf.get(t) ?? 0), 0),
|
|
222
|
+
idx,
|
|
223
|
+
hasOverlap: overlap.length > 0,
|
|
224
|
+
};
|
|
172
225
|
})
|
|
173
226
|
.filter((x) => x.hasOverlap);
|
|
174
227
|
if (scored.length === 0) return [];
|
|
@@ -188,7 +241,10 @@ function selectSessionLog(query: string, sessionLog: KnowledgeSection[], budgetB
|
|
|
188
241
|
// a head-sliced copy of the single best match so the query isn't empty.
|
|
189
242
|
if (selected.length === 0 && bestMatch) {
|
|
190
243
|
const sliced = bestMatch.sec.body.slice(0, Math.max(0, budgetBytes));
|
|
191
|
-
selected.push({
|
|
244
|
+
selected.push({
|
|
245
|
+
...bestMatch.sec,
|
|
246
|
+
body: `${sliced}\n\n<!-- section truncated (session-log budget ${budgetBytes} bytes). Full file: use \`read\`. -->`,
|
|
247
|
+
});
|
|
192
248
|
}
|
|
193
249
|
return selected;
|
|
194
250
|
}
|
|
@@ -225,13 +281,23 @@ export function readKnowledge(cwd: string, query?: KnowledgeQuery): string {
|
|
|
225
281
|
|
|
226
282
|
// Section-aware path: cache parsed sections, select per-query.
|
|
227
283
|
const cachedSections = sectionCache.get(p);
|
|
228
|
-
let parsed: {
|
|
284
|
+
let parsed: {
|
|
285
|
+
conventions: KnowledgeSection[];
|
|
286
|
+
sessionLog: KnowledgeSection[];
|
|
287
|
+
};
|
|
229
288
|
if (cachedSections && cachedSections.key === cacheKey) {
|
|
230
|
-
parsed = {
|
|
289
|
+
parsed = {
|
|
290
|
+
conventions: cachedSections.conventions,
|
|
291
|
+
sessionLog: cachedSections.sessionLog,
|
|
292
|
+
};
|
|
231
293
|
} else {
|
|
232
294
|
const content = fs.readFileSync(p, "utf8").trim();
|
|
233
295
|
parsed = parseKnowledgeSections(content);
|
|
234
|
-
sectionCache.set(p, {
|
|
296
|
+
sectionCache.set(p, {
|
|
297
|
+
key: cacheKey,
|
|
298
|
+
conventions: parsed.conventions,
|
|
299
|
+
sessionLog: parsed.sessionLog,
|
|
300
|
+
});
|
|
235
301
|
}
|
|
236
302
|
|
|
237
303
|
const queryText = [query.goal, query.taskText].filter(Boolean).join(" \n ");
|
|
@@ -245,7 +311,9 @@ export function readKnowledge(cwd: string, query?: KnowledgeQuery): string {
|
|
|
245
311
|
// Always: section-index of ALL session-log headers (recovery safety net).
|
|
246
312
|
if (parsed.sessionLog.length > 0) {
|
|
247
313
|
const indexLines = parsed.sessionLog.map((s) => ` - ${s.header}`);
|
|
248
|
-
parts.push(
|
|
314
|
+
parts.push(
|
|
315
|
+
`<!-- Session-log sections in knowledge.md (not injected unless matched above — use \`read\` for detail):\n${indexLines.join("\n")}\nFull file: ${p} -->`,
|
|
316
|
+
);
|
|
249
317
|
}
|
|
250
318
|
return parts.join("\n").trim();
|
|
251
319
|
} catch {
|
|
@@ -311,7 +379,12 @@ export function buildKnowledgeFragment(cwd: string, query?: KnowledgeQuery): str
|
|
|
311
379
|
*/
|
|
312
380
|
export function registerKnowledgeInjection(pi: ExtensionAPI): void {
|
|
313
381
|
pi.on("before_agent_start", (event: BeforeAgentStartEvent) => {
|
|
314
|
-
const options =
|
|
382
|
+
const options =
|
|
383
|
+
(
|
|
384
|
+
event as BeforeAgentStartEvent & {
|
|
385
|
+
systemPromptOptions?: { cwd?: unknown };
|
|
386
|
+
}
|
|
387
|
+
).systemPromptOptions ?? {};
|
|
315
388
|
const cwd = typeof options.cwd === "string" ? options.cwd : process.cwd();
|
|
316
389
|
const fragment = buildKnowledgeFragment(cwd);
|
|
317
390
|
if (!fragment) return undefined;
|