@evalops/maestro 0.10.49 → 0.10.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent-outcome.d.ts +54 -0
- package/dist/agent/agent-outcome.d.ts.map +1 -0
- package/dist/agent/agent-outcome.js +142 -0
- package/dist/agent/agent-outcome.js.map +1 -0
- package/dist/agent/agent-resume.d.ts.map +1 -1
- package/dist/agent/agent-resume.js +3 -3
- package/dist/agent/agent-resume.js.map +1 -1
- package/dist/agent/agent-run-summary.d.ts +37 -0
- package/dist/agent/agent-run-summary.d.ts.map +1 -0
- package/dist/agent/agent-run-summary.js +15 -0
- package/dist/agent/agent-run-summary.js.map +1 -0
- package/dist/agent/agent-work-board.d.ts +82 -0
- package/dist/agent/agent-work-board.d.ts.map +1 -0
- package/dist/agent/agent-work-board.js +312 -0
- package/dist/agent/agent-work-board.js.map +1 -0
- package/dist/agent/auto-compaction.d.ts +7 -2
- package/dist/agent/auto-compaction.d.ts.map +1 -1
- package/dist/agent/auto-compaction.js +23 -10
- package/dist/agent/auto-compaction.js.map +1 -1
- package/dist/agent/mission-artifacts.d.ts +62 -0
- package/dist/agent/mission-artifacts.d.ts.map +1 -0
- package/dist/agent/mission-artifacts.js +438 -0
- package/dist/agent/mission-artifacts.js.map +1 -0
- package/dist/agent/mission-manifest.d.ts +139 -3
- package/dist/agent/mission-manifest.d.ts.map +1 -1
- package/dist/agent/mission-manifest.js +549 -3
- package/dist/agent/mission-manifest.js.map +1 -1
- package/dist/agent/mission-store.d.ts +80 -0
- package/dist/agent/mission-store.d.ts.map +1 -0
- package/dist/agent/mission-store.js +603 -0
- package/dist/agent/mission-store.js.map +1 -0
- package/dist/agent/modes.d.ts +2 -2
- package/dist/agent/modes.d.ts.map +1 -1
- package/dist/agent/modes.js +10 -3
- package/dist/agent/modes.js.map +1 -1
- package/dist/agent/providers/codex-app-server.d.ts.map +1 -1
- package/dist/agent/providers/codex-app-server.js +1 -3
- package/dist/agent/providers/codex-app-server.js.map +1 -1
- package/dist/agent/providers/google-gemini-cli.js +203 -107
- package/dist/agent/providers/google.js +100 -41
- package/dist/agent/providers/scripted.d.ts.map +1 -1
- package/dist/agent/providers/scripted.js +1 -3
- package/dist/agent/providers/scripted.js.map +1 -1
- package/dist/agent/providers/validation.d.ts.map +1 -1
- package/dist/agent/providers/validation.js +1 -3
- package/dist/agent/providers/validation.js.map +1 -1
- package/dist/agent/providers/vertex.js +203 -107
- package/dist/agent/snapshot-store.d.ts +32 -0
- package/dist/agent/snapshot-store.d.ts.map +1 -0
- package/dist/agent/snapshot-store.js +195 -0
- package/dist/agent/snapshot-store.js.map +1 -0
- package/dist/agent/specialist-profiles.d.ts +36 -0
- package/dist/agent/specialist-profiles.d.ts.map +1 -0
- package/dist/agent/specialist-profiles.js +159 -0
- package/dist/agent/specialist-profiles.js.map +1 -0
- package/dist/agent/subagent-specs.d.ts +4 -1
- package/dist/agent/subagent-specs.d.ts.map +1 -1
- package/dist/agent/subagent-specs.js +81 -8
- package/dist/agent/subagent-specs.js.map +1 -1
- package/dist/agent/swarm/coverage-gate.d.ts +37 -0
- package/dist/agent/swarm/coverage-gate.d.ts.map +1 -0
- package/dist/agent/swarm/coverage-gate.js +48 -0
- package/dist/agent/swarm/coverage-gate.js.map +1 -0
- package/dist/agent/swarm/executor.d.ts +1 -0
- package/dist/agent/swarm/executor.d.ts.map +1 -1
- package/dist/agent/swarm/executor.js +151 -15
- package/dist/agent/swarm/executor.js.map +1 -1
- package/dist/agent/swarm/orchestrator-prompt.d.ts +25 -0
- package/dist/agent/swarm/orchestrator-prompt.d.ts.map +1 -0
- package/dist/agent/swarm/orchestrator-prompt.js +48 -0
- package/dist/agent/swarm/orchestrator-prompt.js.map +1 -0
- package/dist/agent/swarm/plan-parser.d.ts.map +1 -1
- package/dist/agent/swarm/plan-parser.js +27 -2
- package/dist/agent/swarm/plan-parser.js.map +1 -1
- package/dist/agent/swarm/types.d.ts +17 -0
- package/dist/agent/swarm/types.d.ts.map +1 -1
- package/dist/agent/swarm/types.js.map +1 -1
- package/dist/agent/swarm/validation-directive.d.ts +21 -0
- package/dist/agent/swarm/validation-directive.d.ts.map +1 -0
- package/dist/agent/swarm/validation-directive.js +25 -0
- package/dist/agent/swarm/validation-directive.js.map +1 -0
- package/dist/agent/transport/tool-execution-bridge.d.ts.map +1 -1
- package/dist/agent/transport/tool-execution-bridge.js +4 -1
- package/dist/agent/transport/tool-execution-bridge.js.map +1 -1
- package/dist/api/enterprise-routes.d.ts.map +1 -1
- package/dist/api/enterprise-routes.js +87 -10
- package/dist/api/enterprise-routes.js.map +1 -1
- package/dist/api/org-settings-merge.d.ts +12 -0
- package/dist/api/org-settings-merge.d.ts.map +1 -0
- package/dist/api/org-settings-merge.js +38 -0
- package/dist/api/org-settings-merge.js.map +1 -0
- package/dist/api/user-settings-merge.d.ts +16 -0
- package/dist/api/user-settings-merge.d.ts.map +1 -0
- package/dist/api/user-settings-merge.js +37 -0
- package/dist/api/user-settings-merge.js.map +1 -0
- package/dist/app-server/daemon-lifecycle-api.d.ts.map +1 -1
- package/dist/app-server/daemon-lifecycle-api.js +1 -3
- package/dist/app-server/daemon-lifecycle-api.js.map +1 -1
- package/dist/app-server/external-agent-import-api.d.ts.map +1 -1
- package/dist/app-server/external-agent-import-api.js +1 -3
- package/dist/app-server/external-agent-import-api.js.map +1 -1
- package/dist/app-server/network-governance-api.d.ts.map +1 -1
- package/dist/app-server/network-governance-api.js +1 -3
- package/dist/app-server/network-governance-api.js.map +1 -1
- package/dist/app-server/plugin-bundle-api.d.ts.map +1 -1
- package/dist/app-server/plugin-bundle-api.js +1 -3
- package/dist/app-server/plugin-bundle-api.js.map +1 -1
- package/dist/app-server/policy-control-api.d.ts.map +1 -1
- package/dist/app-server/policy-control-api.js +1 -3
- package/dist/app-server/policy-control-api.js.map +1 -1
- package/dist/app-server/protocol-modes-api.d.ts.map +1 -1
- package/dist/app-server/protocol-modes-api.js +1 -3
- package/dist/app-server/protocol-modes-api.js.map +1 -1
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +15 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands/a2a.d.ts.map +1 -1
- package/dist/cli/commands/a2a.js +1 -3
- package/dist/cli/commands/a2a.js.map +1 -1
- package/dist/cli/commands/agents.d.ts +4 -0
- package/dist/cli/commands/agents.d.ts.map +1 -1
- package/dist/cli/commands/agents.js +149 -0
- package/dist/cli/commands/agents.js.map +1 -1
- package/dist/cli/commands/mission.d.ts +4 -0
- package/dist/cli/commands/mission.d.ts.map +1 -0
- package/dist/cli/commands/mission.js +196 -0
- package/dist/cli/commands/mission.js.map +1 -0
- package/dist/cli/commands/value.d.ts +10 -0
- package/dist/cli/commands/value.d.ts.map +1 -0
- package/dist/cli/commands/value.js +33 -0
- package/dist/cli/commands/value.js.map +1 -0
- package/dist/cli/headless-protocol.d.ts.map +1 -1
- package/dist/cli/headless-protocol.js +1 -3
- package/dist/cli/headless-protocol.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +10 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/system-prompt.d.ts.map +1 -1
- package/dist/cli/system-prompt.js +38 -7
- package/dist/cli/system-prompt.js.map +1 -1
- package/dist/cli-command-runtime.js +2 -2
- package/dist/cli-command-runtime.js.map +1 -1
- package/dist/cli-runtime.js +7798 -2805
- package/dist/cli-tui/client-tools/client-tool-controller.d.ts.map +1 -1
- package/dist/cli-tui/client-tools/client-tool-controller.js +1 -3
- package/dist/cli-tui/client-tools/client-tool-controller.js.map +1 -1
- package/dist/cli-tui/commands/undo-handlers.d.ts.map +1 -1
- package/dist/cli-tui/commands/undo-handlers.js +7 -2
- package/dist/cli-tui/commands/undo-handlers.js.map +1 -1
- package/dist/cli-tui/tui-renderer/skills-controller.d.ts +3 -0
- package/dist/cli-tui/tui-renderer/skills-controller.d.ts.map +1 -1
- package/dist/cli-tui/tui-renderer/skills-controller.js +77 -33
- package/dist/cli-tui/tui-renderer/skills-controller.js.map +1 -1
- package/dist/cli.js +4 -6
- package/dist/cli.js.map +1 -1
- package/dist/codex/app-server-client.d.ts.map +1 -1
- package/dist/codex/app-server-client.js +1 -3
- package/dist/codex/app-server-client.js.map +1 -1
- package/dist/codex/compatibility.d.ts.map +1 -1
- package/dist/codex/compatibility.js +1 -3
- package/dist/codex/compatibility.js.map +1 -1
- package/dist/codex/subagent-dispatch-table.d.ts +8 -0
- package/dist/codex/subagent-dispatch-table.d.ts.map +1 -1
- package/dist/codex/subagent-dispatch-table.js +23 -0
- package/dist/codex/subagent-dispatch-table.js.map +1 -1
- package/dist/context/manifest.d.ts.map +1 -1
- package/dist/context/manifest.js +1 -3
- package/dist/context/manifest.js.map +1 -1
- package/dist/conversation/render-model.d.ts +0 -36
- package/dist/conversation/render-model.d.ts.map +1 -1
- package/dist/conversation/render-model.js +1 -3
- package/dist/conversation/render-model.js.map +1 -1
- package/dist/customer-value/ambient-learning.d.ts +75 -0
- package/dist/customer-value/ambient-learning.d.ts.map +1 -0
- package/dist/customer-value/ambient-learning.js +472 -0
- package/dist/customer-value/ambient-learning.js.map +1 -0
- package/dist/customer-value/internal-helpers.d.ts +13 -0
- package/dist/customer-value/internal-helpers.d.ts.map +1 -0
- package/dist/customer-value/internal-helpers.js +70 -0
- package/dist/customer-value/internal-helpers.js.map +1 -0
- package/dist/customer-value/report.d.ts +282 -0
- package/dist/customer-value/report.d.ts.map +1 -0
- package/dist/customer-value/report.js +2085 -0
- package/dist/customer-value/report.js.map +1 -0
- package/dist/db/health.d.ts +1 -1
- package/dist/db/health.d.ts.map +1 -1
- package/dist/db/health.js +10 -0
- package/dist/db/health.js.map +1 -1
- package/dist/db/migrations/0009_operating_layer_evidence.sql +30 -0
- package/dist/db/migrations/meta/_journal.json +7 -0
- package/dist/db/schema.d.ts +268 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +28 -0
- package/dist/db/schema.js.map +1 -1
- package/dist/evalops/agent-bootstrap.d.ts.map +1 -1
- package/dist/evalops/agent-bootstrap.js +1 -3
- package/dist/evalops/agent-bootstrap.js.map +1 -1
- package/dist/evalops/agent-mcp-metadata.d.ts.map +1 -1
- package/dist/evalops/agent-mcp-metadata.js +1 -3
- package/dist/evalops/agent-mcp-metadata.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/installers/maestro-review-workflow.d.ts +38 -0
- package/dist/installers/maestro-review-workflow.d.ts.map +1 -0
- package/dist/installers/maestro-review-workflow.js +163 -0
- package/dist/installers/maestro-review-workflow.js.map +1 -0
- package/dist/load-env.d.ts +13 -0
- package/dist/load-env.d.ts.map +1 -1
- package/dist/load-env.js +17 -0
- package/dist/load-env.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +96 -7
- package/dist/main.js.map +1 -1
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +1 -3
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/elicitation.d.ts.map +1 -1
- package/dist/mcp/elicitation.js +1 -3
- package/dist/mcp/elicitation.js.map +1 -1
- package/dist/mcp/official-registry.d.ts.map +1 -1
- package/dist/mcp/official-registry.js +1 -3
- package/dist/mcp/official-registry.js.map +1 -1
- package/dist/mcp/workspace-trust.d.ts.map +1 -1
- package/dist/mcp/workspace-trust.js +1 -3
- package/dist/mcp/workspace-trust.js.map +1 -1
- package/dist/memory/service-client.d.ts.map +1 -1
- package/dist/memory/service-client.js +1 -3
- package/dist/memory/service-client.js.map +1 -1
- package/dist/models/config-loader.d.ts.map +1 -1
- package/dist/models/config-loader.js +1 -3
- package/dist/models/config-loader.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/index.d.ts +1 -0
- package/dist/node_modules/@evalops/contracts/dist/index.d.ts.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/index.js +1 -0
- package/dist/node_modules/@evalops/contracts/dist/index.js.map +1 -1
- package/dist/node_modules/@evalops/contracts/dist/maestro-settings.d.ts +61 -0
- package/dist/node_modules/@evalops/contracts/dist/maestro-settings.d.ts.map +1 -0
- package/dist/node_modules/@evalops/contracts/dist/maestro-settings.js +183 -0
- package/dist/node_modules/@evalops/contracts/dist/maestro-settings.js.map +1 -0
- package/dist/node_modules/@evalops/contracts/package.json +1 -1
- package/dist/node_modules/@evalops/tui/package.json +1 -1
- package/dist/oauth/connectors.d.ts.map +1 -1
- package/dist/oauth/connectors.js +1 -3
- package/dist/oauth/connectors.js.map +1 -1
- package/dist/oauth/evalops.d.ts.map +1 -1
- package/dist/oauth/evalops.js +1 -3
- package/dist/oauth/evalops.js.map +1 -1
- package/dist/platform/a2a-client.d.ts.map +1 -1
- package/dist/platform/a2a-client.js +1 -3
- package/dist/platform/a2a-client.js.map +1 -1
- package/dist/platform/a2a-cockpit.d.ts +1 -0
- package/dist/platform/a2a-cockpit.d.ts.map +1 -1
- package/dist/platform/a2a-cockpit.js +42 -11
- package/dist/platform/a2a-cockpit.js.map +1 -1
- package/dist/platform/a2a-completion-audit.d.ts +1 -1
- package/dist/platform/a2a-completion-audit.d.ts.map +1 -1
- package/dist/platform/a2a-completion-audit.js +7 -11
- package/dist/platform/a2a-completion-audit.js.map +1 -1
- package/dist/platform/a2a-maestro-peer.js +16 -0
- package/dist/platform/a2a-maestro-peer.js.map +1 -1
- package/dist/platform/a2a-peer-pairing.d.ts.map +1 -1
- package/dist/platform/a2a-peer-pairing.js +1 -3
- package/dist/platform/a2a-peer-pairing.js.map +1 -1
- package/dist/platform/a2a-peer-registry.d.ts.map +1 -1
- package/dist/platform/a2a-peer-registry.js +1 -3
- package/dist/platform/a2a-peer-registry.js.map +1 -1
- package/dist/platform/a2a-task-ledger.d.ts +20 -0
- package/dist/platform/a2a-task-ledger.d.ts.map +1 -1
- package/dist/platform/a2a-task-ledger.js +207 -11
- package/dist/platform/a2a-task-ledger.js.map +1 -1
- package/dist/platform/a2a-work-graph.d.ts.map +1 -1
- package/dist/platform/a2a-work-graph.js +1 -3
- package/dist/platform/a2a-work-graph.js.map +1 -1
- package/dist/platform/operating-layer.d.ts +127 -0
- package/dist/platform/operating-layer.d.ts.map +1 -0
- package/dist/platform/operating-layer.js +360 -0
- package/dist/platform/operating-layer.js.map +1 -0
- package/dist/platform/tool-execution-client.d.ts.map +1 -1
- package/dist/platform/tool-execution-client.js +19 -2
- package/dist/platform/tool-execution-client.js.map +1 -1
- package/dist/providers/auth.d.ts.map +1 -1
- package/dist/providers/auth.js +1 -3
- package/dist/providers/auth.js.map +1 -1
- package/dist/runtime/env.d.ts +9 -1
- package/dist/runtime/env.d.ts.map +1 -1
- package/dist/runtime/env.js +63 -1
- package/dist/runtime/env.js.map +1 -1
- package/dist/safety/policy.d.ts.map +1 -1
- package/dist/safety/policy.js +1 -4
- package/dist/safety/policy.js.map +1 -1
- package/dist/sandbox/docker-sandbox.d.ts.map +1 -1
- package/dist/sandbox/docker-sandbox.js +6 -1
- package/dist/sandbox/docker-sandbox.js.map +1 -1
- package/dist/server/handlers/hosted-runner-drain.d.ts.map +1 -1
- package/dist/server/handlers/hosted-runner-drain.js +1 -3
- package/dist/server/handlers/hosted-runner-drain.js.map +1 -1
- package/dist/server/handlers/platform-a2a-push.d.ts.map +1 -1
- package/dist/server/handlers/platform-a2a-push.js +53 -2
- package/dist/server/handlers/platform-a2a-push.js.map +1 -1
- package/dist/server/handlers/runtime-app-server-ws.d.ts.map +1 -1
- package/dist/server/handlers/runtime-app-server-ws.js +1 -3
- package/dist/server/handlers/runtime-app-server-ws.js.map +1 -1
- package/dist/server/headless-runtime-service.d.ts +16 -0
- package/dist/server/headless-runtime-service.d.ts.map +1 -1
- package/dist/server/headless-runtime-service.js +232 -206
- package/dist/server/headless-runtime-service.js.map +1 -1
- package/dist/server/hosted-agent-runtime-progress.d.ts.map +1 -1
- package/dist/server/hosted-agent-runtime-progress.js +12 -3
- package/dist/server/hosted-agent-runtime-progress.js.map +1 -1
- package/dist/server/pending-request-payload.d.ts.map +1 -1
- package/dist/server/pending-request-payload.js +1 -3
- package/dist/server/pending-request-payload.js.map +1 -1
- package/dist/server/route-auth.d.ts.map +1 -1
- package/dist/server/route-auth.js +2 -0
- package/dist/server/route-auth.js.map +1 -1
- package/dist/server/session-serialization.d.ts.map +1 -1
- package/dist/server/session-serialization.js +1 -3
- package/dist/server/session-serialization.js.map +1 -1
- package/dist/services/compliance/normalize.d.ts.map +1 -1
- package/dist/services/compliance/normalize.js +1 -3
- package/dist/services/compliance/normalize.js.map +1 -1
- package/dist/services/intelligent-router/normalize.d.ts.map +1 -1
- package/dist/services/intelligent-router/normalize.js +1 -3
- package/dist/services/intelligent-router/normalize.js.map +1 -1
- package/dist/services/revenue-attribution/normalize.d.ts.map +1 -1
- package/dist/services/revenue-attribution/normalize.js +1 -3
- package/dist/services/revenue-attribution/normalize.js.map +1 -1
- package/dist/services/traces/normalize.d.ts.map +1 -1
- package/dist/services/traces/normalize.js +1 -3
- package/dist/services/traces/normalize.js.map +1 -1
- package/dist/services/workspace-config/normalize.d.ts.map +1 -1
- package/dist/services/workspace-config/normalize.js +1 -3
- package/dist/services/workspace-config/normalize.js.map +1 -1
- package/dist/skills/composer.d.ts.map +1 -1
- package/dist/skills/composer.js +13 -1
- package/dist/skills/composer.js.map +1 -1
- package/dist/skills/index.d.ts +1 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/learned-guidelines.d.ts +33 -0
- package/dist/skills/learned-guidelines.d.ts.map +1 -0
- package/dist/skills/learned-guidelines.js +291 -0
- package/dist/skills/learned-guidelines.js.map +1 -0
- package/dist/skills/linter.d.ts.map +1 -1
- package/dist/skills/linter.js +1 -3
- package/dist/skills/linter.js.map +1 -1
- package/dist/skills/runtime-activation.d.ts +1 -0
- package/dist/skills/runtime-activation.d.ts.map +1 -1
- package/dist/skills/runtime-activation.js +2 -3
- package/dist/skills/runtime-activation.js.map +1 -1
- package/dist/skills/tool.d.ts.map +1 -1
- package/dist/skills/tool.js +26 -21
- package/dist/skills/tool.js.map +1 -1
- package/dist/skills/trust-cache.d.ts +7 -0
- package/dist/skills/trust-cache.d.ts.map +1 -1
- package/dist/skills/trust-cache.js +16 -0
- package/dist/skills/trust-cache.js.map +1 -1
- package/dist/telemetry/agent-workforce-native-event.d.ts.map +1 -1
- package/dist/telemetry/agent-workforce-native-event.js +1 -3
- package/dist/telemetry/agent-workforce-native-event.js.map +1 -1
- package/dist/telemetry/maestro-event-bus.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-bus.js +42 -81
- package/dist/telemetry/maestro-event-bus.js.map +1 -1
- package/dist/telemetry/maestro-platform-replay-fixture.d.ts.map +1 -1
- package/dist/telemetry/maestro-platform-replay-fixture.js +1 -3
- package/dist/telemetry/maestro-platform-replay-fixture.js.map +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +54 -43
- package/dist/telemetry.js.map +1 -1
- package/dist/theme/theme-loader.d.ts.map +1 -1
- package/dist/theme/theme-loader.js +1 -3
- package/dist/theme/theme-loader.js.map +1 -1
- package/dist/tools/apply-patch.d.ts.map +1 -1
- package/dist/tools/apply-patch.js +76 -8
- package/dist/tools/apply-patch.js.map +1 -1
- package/dist/tools/diff-preview.d.ts.map +1 -1
- package/dist/tools/diff-preview.js +10 -1
- package/dist/tools/diff-preview.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +17 -0
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +9 -0
- package/dist/tools/write.js.map +1 -1
- package/dist/undo/tracker.d.ts +5 -0
- package/dist/undo/tracker.d.ts.map +1 -1
- package/dist/undo/tracker.js +13 -0
- package/dist/undo/tracker.js.map +1 -1
- package/dist/utils/fs.d.ts +1 -1
- package/dist/utils/fs.d.ts.map +1 -1
- package/dist/utils/fs.js +29 -2
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/git-stash.d.ts.map +1 -1
- package/dist/utils/git-stash.js +15 -8
- package/dist/utils/git-stash.js.map +1 -1
- package/dist/utils/json.d.ts +11 -0
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js +9 -0
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/shell-env.d.ts.map +1 -1
- package/dist/utils/shell-env.js +2 -0
- package/dist/utils/shell-env.js.map +1 -1
- package/dist/utils/url-extractor-git.d.ts +26 -0
- package/dist/utils/url-extractor-git.d.ts.map +1 -0
- package/dist/utils/url-extractor-git.js +259 -0
- package/dist/utils/url-extractor-git.js.map +1 -0
- package/dist/utils/url-extractor.d.ts.map +1 -1
- package/dist/utils/url-extractor.js +23 -251
- package/dist/utils/url-extractor.js.map +1 -1
- package/dist/version.json +2 -2
- package/dist/web-server.d.ts.map +1 -1
- package/dist/web-server.js +2 -5
- package/dist/web-server.js.map +1 -1
- package/package.json +310 -306
- package/skills/incident-triage/SKILL.md +19 -1
- package/skills/install-code-review/SKILL.md +69 -0
- package/skills/security-review/SKILL.md +68 -0
- package/skills/security-review/reference/rubric.md +85 -0
|
@@ -30,10 +30,134 @@
|
|
|
30
30
|
*
|
|
31
31
|
* Pure types + helpers (manifest construction, coverage gate against
|
|
32
32
|
* validation contract assertion ids, preemption, feature lookup,
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* shape defined
|
|
33
|
+
* handoff follow-up promotion, handoff continuity gates, summary
|
|
34
|
+
* stats). No disk persistence, no worker dispatch, no orchestrator
|
|
35
|
+
* loop — those ride in follow-up PRs that consume the shape defined
|
|
36
|
+
* here.
|
|
36
37
|
*/
|
|
38
|
+
export const MISSION_FEATURE_STATUSES = [
|
|
39
|
+
"pending",
|
|
40
|
+
"in-progress",
|
|
41
|
+
"passed",
|
|
42
|
+
"failed",
|
|
43
|
+
"preempted",
|
|
44
|
+
];
|
|
45
|
+
export function isMissionFeatureStatus(value) {
|
|
46
|
+
return (typeof value === "string" &&
|
|
47
|
+
MISSION_FEATURE_STATUSES.includes(value));
|
|
48
|
+
}
|
|
49
|
+
export function isMissionFeature(value) {
|
|
50
|
+
if (!value || typeof value !== "object")
|
|
51
|
+
return false;
|
|
52
|
+
const feature = value;
|
|
53
|
+
return (typeof feature.id === "string" &&
|
|
54
|
+
feature.id.trim().length > 0 &&
|
|
55
|
+
typeof feature.description === "string" &&
|
|
56
|
+
feature.description.trim().length > 0 &&
|
|
57
|
+
isMissionFeatureStatus(feature.status) &&
|
|
58
|
+
(typeof feature.milestone === "undefined" ||
|
|
59
|
+
typeof feature.milestone === "string") &&
|
|
60
|
+
(typeof feature.skillName === "undefined" ||
|
|
61
|
+
typeof feature.skillName === "string") &&
|
|
62
|
+
Array.isArray(feature.fulfills) &&
|
|
63
|
+
feature.fulfills.every((assertion) => typeof assertion === "string") &&
|
|
64
|
+
(typeof feature.handoff === "undefined" ||
|
|
65
|
+
isMissionWorkerHandoff(feature.handoff)) &&
|
|
66
|
+
(typeof feature.handoffDismissals === "undefined" ||
|
|
67
|
+
(Array.isArray(feature.handoffDismissals) &&
|
|
68
|
+
feature.handoffDismissals.every(isMissionHandoffDismissal))) &&
|
|
69
|
+
(typeof feature.trackedHandoffItems === "undefined" ||
|
|
70
|
+
(Array.isArray(feature.trackedHandoffItems) &&
|
|
71
|
+
feature.trackedHandoffItems.every(isMissionTrackedHandoffItem))) &&
|
|
72
|
+
(typeof feature.handoffSourceFeatureId === "undefined" ||
|
|
73
|
+
typeof feature.handoffSourceFeatureId === "string") &&
|
|
74
|
+
(typeof feature.handoffFollowUpKind === "undefined" ||
|
|
75
|
+
isMissionHandoffItemKind(feature.handoffFollowUpKind)) &&
|
|
76
|
+
(typeof feature.handoffItemKey === "undefined" ||
|
|
77
|
+
typeof feature.handoffItemKey === "string"));
|
|
78
|
+
}
|
|
79
|
+
function isMissionWorkerHandoff(value) {
|
|
80
|
+
if (!value || typeof value !== "object")
|
|
81
|
+
return false;
|
|
82
|
+
const handoff = value;
|
|
83
|
+
return (typeof handoff.workerId === "string" &&
|
|
84
|
+
handoff.workerId.trim().length > 0 &&
|
|
85
|
+
typeof handoff.success === "boolean" &&
|
|
86
|
+
(typeof handoff.repoPath === "undefined" ||
|
|
87
|
+
typeof handoff.repoPath === "string") &&
|
|
88
|
+
(typeof handoff.commitId === "undefined" ||
|
|
89
|
+
typeof handoff.commitId === "string") &&
|
|
90
|
+
(typeof handoff.summary === "undefined" ||
|
|
91
|
+
typeof handoff.summary === "string") &&
|
|
92
|
+
(typeof handoff.whatWasImplemented === "undefined" ||
|
|
93
|
+
typeof handoff.whatWasImplemented === "string") &&
|
|
94
|
+
(typeof handoff.whatWasLeftUndone === "undefined" ||
|
|
95
|
+
typeof handoff.whatWasLeftUndone === "string") &&
|
|
96
|
+
(typeof handoff.discoveredIssues === "undefined" ||
|
|
97
|
+
(Array.isArray(handoff.discoveredIssues) &&
|
|
98
|
+
handoff.discoveredIssues.every(isMissionDiscoveredIssue))) &&
|
|
99
|
+
(typeof handoff.verification === "undefined" ||
|
|
100
|
+
isMissionVerification(handoff.verification)) &&
|
|
101
|
+
typeof handoff.handedOffAt === "string" &&
|
|
102
|
+
!Number.isNaN(Date.parse(handoff.handedOffAt)));
|
|
103
|
+
}
|
|
104
|
+
function isMissionDiscoveredIssue(value) {
|
|
105
|
+
if (!value || typeof value !== "object")
|
|
106
|
+
return false;
|
|
107
|
+
const issue = value;
|
|
108
|
+
return ((issue.severity === "blocking" || issue.severity === "non_blocking") &&
|
|
109
|
+
typeof issue.description === "string" &&
|
|
110
|
+
issue.description.trim().length > 0 &&
|
|
111
|
+
(typeof issue.suggestedFix === "undefined" ||
|
|
112
|
+
typeof issue.suggestedFix === "string"));
|
|
113
|
+
}
|
|
114
|
+
function isMissionVerification(value) {
|
|
115
|
+
if (!value || typeof value !== "object")
|
|
116
|
+
return false;
|
|
117
|
+
const verification = value;
|
|
118
|
+
return (typeof verification.commandsRun === "undefined" ||
|
|
119
|
+
(Array.isArray(verification.commandsRun) &&
|
|
120
|
+
verification.commandsRun.every(isMissionVerificationCommand)));
|
|
121
|
+
}
|
|
122
|
+
function isMissionVerificationCommand(value) {
|
|
123
|
+
if (!value || typeof value !== "object")
|
|
124
|
+
return false;
|
|
125
|
+
const command = value;
|
|
126
|
+
return (typeof command.command === "string" &&
|
|
127
|
+
command.command.trim().length > 0 &&
|
|
128
|
+
(typeof command.exitCode === "undefined" ||
|
|
129
|
+
typeof command.exitCode === "number") &&
|
|
130
|
+
(typeof command.observation === "undefined" ||
|
|
131
|
+
typeof command.observation === "string"));
|
|
132
|
+
}
|
|
133
|
+
function isMissionHandoffDismissal(value) {
|
|
134
|
+
if (!value || typeof value !== "object")
|
|
135
|
+
return false;
|
|
136
|
+
const dismissal = value;
|
|
137
|
+
return (isMissionHandoffItemKind(dismissal.kind) &&
|
|
138
|
+
typeof dismissal.key === "string" &&
|
|
139
|
+
dismissal.key.trim().length > 0 &&
|
|
140
|
+
typeof dismissal.justification === "string" &&
|
|
141
|
+
dismissal.justification.trim().length > 0 &&
|
|
142
|
+
typeof dismissal.dismissedAt === "string" &&
|
|
143
|
+
!Number.isNaN(Date.parse(dismissal.dismissedAt)));
|
|
144
|
+
}
|
|
145
|
+
function isMissionTrackedHandoffItem(value) {
|
|
146
|
+
if (!value || typeof value !== "object")
|
|
147
|
+
return false;
|
|
148
|
+
const item = value;
|
|
149
|
+
return (typeof item.sourceFeatureId === "string" &&
|
|
150
|
+
item.sourceFeatureId.trim().length > 0 &&
|
|
151
|
+
isMissionHandoffItemKind(item.kind) &&
|
|
152
|
+
typeof item.key === "string" &&
|
|
153
|
+
item.key.trim().length > 0 &&
|
|
154
|
+
typeof item.trackedAt === "string" &&
|
|
155
|
+
!Number.isNaN(Date.parse(item.trackedAt)) &&
|
|
156
|
+
(typeof item.note === "undefined" || typeof item.note === "string"));
|
|
157
|
+
}
|
|
158
|
+
function isMissionHandoffItemKind(value) {
|
|
159
|
+
return value === "unfinished_work" || value === "discovered_issue";
|
|
160
|
+
}
|
|
37
161
|
export const MISSION_MANIFEST_VERSION = 1;
|
|
38
162
|
/**
|
|
39
163
|
* Construct a fresh, empty manifest. Features and milestones are added
|
|
@@ -196,6 +320,266 @@ export function recordHandoff(manifest, featureId, handoff) {
|
|
|
196
320
|
}
|
|
197
321
|
return { ...manifest, features: next, updatedAt: handoff.handedOffAt };
|
|
198
322
|
}
|
|
323
|
+
/** Promote unfinished handoff work and blocking discoveries into pending features. */
|
|
324
|
+
export function appendHandoffFollowUps(manifest, featureId, options = {}) {
|
|
325
|
+
const sourceIndex = manifest.features.findIndex((f) => f.id === featureId);
|
|
326
|
+
if (sourceIndex === -1) {
|
|
327
|
+
throw new Error(`Feature id "${featureId}" not in manifest`);
|
|
328
|
+
}
|
|
329
|
+
const source = manifest.features[sourceIndex];
|
|
330
|
+
if (!source?.handoff) {
|
|
331
|
+
return manifest;
|
|
332
|
+
}
|
|
333
|
+
const followUps = buildHandoffFollowUpFeatures(manifest, source, options);
|
|
334
|
+
if (followUps.length === 0) {
|
|
335
|
+
return manifest;
|
|
336
|
+
}
|
|
337
|
+
return {
|
|
338
|
+
...manifest,
|
|
339
|
+
features: [
|
|
340
|
+
...manifest.features.slice(0, sourceIndex + 1),
|
|
341
|
+
...followUps,
|
|
342
|
+
...manifest.features.slice(sourceIndex + 1),
|
|
343
|
+
],
|
|
344
|
+
updatedAt: options.now ?? new Date().toISOString(),
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
/** Explicitly dismiss a handoff item so completion gates can distinguish intent from omission. */
|
|
348
|
+
export function dismissHandoffItem(manifest, featureId, options) {
|
|
349
|
+
const justification = normalizeFollowUpText(options.justification);
|
|
350
|
+
if (!justification) {
|
|
351
|
+
throw new Error("dismissal justification is required");
|
|
352
|
+
}
|
|
353
|
+
const feature = findFeature(manifest, featureId);
|
|
354
|
+
if (!feature) {
|
|
355
|
+
throw new Error(`Feature id "${featureId}" not in manifest`);
|
|
356
|
+
}
|
|
357
|
+
const candidates = buildHandoffContinuityRecords(feature, {
|
|
358
|
+
includeNonBlockingIssues: options.includeNonBlockingIssues,
|
|
359
|
+
});
|
|
360
|
+
if (!candidates.some((item) => item.kind === options.kind && item.key === options.key)) {
|
|
361
|
+
throw new Error(`Handoff item "${options.key}" (${options.kind}) not found on feature "${featureId}"`);
|
|
362
|
+
}
|
|
363
|
+
const dismissedAt = options.now ?? new Date().toISOString();
|
|
364
|
+
return {
|
|
365
|
+
...manifest,
|
|
366
|
+
features: manifest.features.map((current) => {
|
|
367
|
+
if (current.id !== featureId)
|
|
368
|
+
return current;
|
|
369
|
+
const existing = current.handoffDismissals ?? [];
|
|
370
|
+
const nextDismissals = [
|
|
371
|
+
...existing.filter((item) => item.kind !== options.kind || item.key !== options.key),
|
|
372
|
+
{
|
|
373
|
+
kind: options.kind,
|
|
374
|
+
key: options.key,
|
|
375
|
+
justification,
|
|
376
|
+
dismissedAt,
|
|
377
|
+
},
|
|
378
|
+
];
|
|
379
|
+
return { ...current, handoffDismissals: nextDismissals };
|
|
380
|
+
}),
|
|
381
|
+
updatedAt: dismissedAt,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
/** Assign a handoff item to an existing feature instead of creating a duplicate follow-up. */
|
|
385
|
+
export function trackHandoffItemOnFeature(manifest, sourceFeatureId, targetFeatureId, options) {
|
|
386
|
+
const source = findFeature(manifest, sourceFeatureId);
|
|
387
|
+
if (!source) {
|
|
388
|
+
throw new Error(`Feature id "${sourceFeatureId}" not in manifest`);
|
|
389
|
+
}
|
|
390
|
+
const target = findFeature(manifest, targetFeatureId);
|
|
391
|
+
if (!target) {
|
|
392
|
+
throw new Error(`Feature id "${targetFeatureId}" not in manifest`);
|
|
393
|
+
}
|
|
394
|
+
if (sourceFeatureId === targetFeatureId &&
|
|
395
|
+
target.status === "passed" &&
|
|
396
|
+
!options.requeueTarget) {
|
|
397
|
+
throw new Error(`Cannot self-track handoff item on passed feature "${targetFeatureId}"; requeue it first`);
|
|
398
|
+
}
|
|
399
|
+
if (target.status === "in-progress" && !options.requeueTarget) {
|
|
400
|
+
throw new Error(`Cannot track handoff item on in-progress feature "${targetFeatureId}"; requeue it so the worker receives the obligation`);
|
|
401
|
+
}
|
|
402
|
+
if (target.status === "passed" &&
|
|
403
|
+
!options.allowPassedTarget &&
|
|
404
|
+
!options.requeueTarget) {
|
|
405
|
+
throw new Error(`Cannot track handoff item on passed feature "${targetFeatureId}"; requeue it or choose a pending feature`);
|
|
406
|
+
}
|
|
407
|
+
const selectedRecord = buildHandoffContinuityRecords(source, {
|
|
408
|
+
includeNonBlockingIssues: options.includeNonBlockingIssues,
|
|
409
|
+
}).find((item) => item.kind === options.kind && item.key === options.key);
|
|
410
|
+
if (!selectedRecord) {
|
|
411
|
+
throw new Error(`Handoff item "${options.key}" (${options.kind}) not found on feature "${sourceFeatureId}"`);
|
|
412
|
+
}
|
|
413
|
+
if ((source.handoffDismissals ?? []).some((item) => item.kind === options.kind && item.key === options.key)) {
|
|
414
|
+
throw new Error(`Handoff item "${options.key}" (${options.kind}) was dismissed on feature "${sourceFeatureId}"`);
|
|
415
|
+
}
|
|
416
|
+
const existingFollowUp = findTrackedHandoffFollowUp(manifest, source, selectedRecord);
|
|
417
|
+
if (existingFollowUp) {
|
|
418
|
+
throw new Error(`Handoff item "${options.key}" (${options.kind}) is already tracked by follow-up feature "${existingFollowUp.id}"`);
|
|
419
|
+
}
|
|
420
|
+
const trackedAt = options.now ?? new Date().toISOString();
|
|
421
|
+
const note = normalizeFollowUpText(options.note);
|
|
422
|
+
return {
|
|
423
|
+
...manifest,
|
|
424
|
+
features: manifest.features.map((current) => {
|
|
425
|
+
const existing = current.trackedHandoffItems ?? [];
|
|
426
|
+
const nextExisting = existing.filter((item) => item.sourceFeatureId !== sourceFeatureId ||
|
|
427
|
+
item.kind !== options.kind ||
|
|
428
|
+
item.key !== options.key);
|
|
429
|
+
if (current.id !== targetFeatureId) {
|
|
430
|
+
if (nextExisting.length === existing.length)
|
|
431
|
+
return current;
|
|
432
|
+
if (nextExisting.length > 0) {
|
|
433
|
+
return { ...current, trackedHandoffItems: nextExisting };
|
|
434
|
+
}
|
|
435
|
+
const { trackedHandoffItems: _trackedHandoffItems, ...rest } = current;
|
|
436
|
+
return rest;
|
|
437
|
+
}
|
|
438
|
+
const nextTracked = [
|
|
439
|
+
...nextExisting,
|
|
440
|
+
{
|
|
441
|
+
sourceFeatureId,
|
|
442
|
+
kind: options.kind,
|
|
443
|
+
key: options.key,
|
|
444
|
+
trackedAt,
|
|
445
|
+
...(note ? { note } : {}),
|
|
446
|
+
},
|
|
447
|
+
];
|
|
448
|
+
if (options.requeueTarget) {
|
|
449
|
+
const { handoff: _handoff, ...rest } = current;
|
|
450
|
+
return {
|
|
451
|
+
...rest,
|
|
452
|
+
status: "pending",
|
|
453
|
+
trackedHandoffItems: nextTracked,
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
return { ...current, trackedHandoffItems: nextTracked };
|
|
457
|
+
}),
|
|
458
|
+
updatedAt: trackedAt,
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
/** Report whether handoff gaps are tracked, dismissed, or still dangling. */
|
|
462
|
+
export function summarizeMissionContinuity(manifest, options = {}) {
|
|
463
|
+
const tracked = [];
|
|
464
|
+
const dismissed = [];
|
|
465
|
+
const unresolved = [];
|
|
466
|
+
for (const feature of manifest.features) {
|
|
467
|
+
const records = buildHandoffContinuityRecords(feature, options);
|
|
468
|
+
const dismissalLookup = new Map((feature.handoffDismissals ?? []).map((item) => [
|
|
469
|
+
continuityLookupKey(feature.id, item.kind, item.key),
|
|
470
|
+
item,
|
|
471
|
+
]));
|
|
472
|
+
for (const record of records) {
|
|
473
|
+
const lookupKey = continuityLookupKey(feature.id, record.kind, record.key);
|
|
474
|
+
const followUp = findTrackedHandoffFollowUp(manifest, feature, record);
|
|
475
|
+
const trackingFeature = findExistingHandoffTracking(manifest, feature, record);
|
|
476
|
+
const dismissal = dismissalLookup.get(lookupKey);
|
|
477
|
+
if (dismissal) {
|
|
478
|
+
dismissed.push({
|
|
479
|
+
sourceFeatureId: feature.id,
|
|
480
|
+
kind: record.kind,
|
|
481
|
+
key: record.key,
|
|
482
|
+
severity: record.severity,
|
|
483
|
+
description: record.description,
|
|
484
|
+
status: "dismissed",
|
|
485
|
+
dismissalJustification: dismissal.justification,
|
|
486
|
+
});
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
if (followUp) {
|
|
490
|
+
tracked.push({
|
|
491
|
+
sourceFeatureId: feature.id,
|
|
492
|
+
kind: record.kind,
|
|
493
|
+
key: record.key,
|
|
494
|
+
severity: record.severity,
|
|
495
|
+
description: record.description,
|
|
496
|
+
status: "tracked",
|
|
497
|
+
followUpFeatureId: followUp.id,
|
|
498
|
+
});
|
|
499
|
+
continue;
|
|
500
|
+
}
|
|
501
|
+
if (trackingFeature) {
|
|
502
|
+
const trackedItem = trackingFeature.trackedHandoffItems?.find((item) => item.sourceFeatureId === feature.id &&
|
|
503
|
+
item.kind === record.kind &&
|
|
504
|
+
item.key === record.key);
|
|
505
|
+
tracked.push({
|
|
506
|
+
sourceFeatureId: feature.id,
|
|
507
|
+
kind: record.kind,
|
|
508
|
+
key: record.key,
|
|
509
|
+
severity: record.severity,
|
|
510
|
+
description: record.description,
|
|
511
|
+
status: "tracked",
|
|
512
|
+
trackingFeatureId: trackingFeature.id,
|
|
513
|
+
trackingNote: trackedItem?.note,
|
|
514
|
+
});
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
unresolved.push({
|
|
518
|
+
sourceFeatureId: feature.id,
|
|
519
|
+
kind: record.kind,
|
|
520
|
+
key: record.key,
|
|
521
|
+
severity: record.severity,
|
|
522
|
+
description: record.description,
|
|
523
|
+
status: "untracked",
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
const openFollowUps = manifest.features
|
|
528
|
+
.filter((feature) => feature.handoffSourceFeatureId &&
|
|
529
|
+
feature.handoffFollowUpKind &&
|
|
530
|
+
feature.status !== "passed")
|
|
531
|
+
.map((feature) => ({
|
|
532
|
+
id: feature.id,
|
|
533
|
+
status: feature.status,
|
|
534
|
+
sourceFeatureId: feature.handoffSourceFeatureId,
|
|
535
|
+
kind: feature.handoffFollowUpKind,
|
|
536
|
+
description: feature.description,
|
|
537
|
+
}));
|
|
538
|
+
const openTrackedItems = manifest.features
|
|
539
|
+
.flatMap((feature) => (feature.trackedHandoffItems ?? []).map((item) => ({
|
|
540
|
+
feature,
|
|
541
|
+
item,
|
|
542
|
+
})))
|
|
543
|
+
.filter(({ feature, item }) => feature.status !== "passed" &&
|
|
544
|
+
isTrackedItemCurrent(manifest, feature, item, options))
|
|
545
|
+
.map(({ feature, item }) => ({
|
|
546
|
+
id: feature.id,
|
|
547
|
+
status: feature.status,
|
|
548
|
+
sourceFeatureId: item.sourceFeatureId,
|
|
549
|
+
kind: item.kind,
|
|
550
|
+
key: item.key,
|
|
551
|
+
description: feature.description,
|
|
552
|
+
...(item.note ? { note: item.note } : {}),
|
|
553
|
+
}));
|
|
554
|
+
return {
|
|
555
|
+
ok: unresolved.length === 0 &&
|
|
556
|
+
openFollowUps.length === 0 &&
|
|
557
|
+
openTrackedItems.length === 0,
|
|
558
|
+
unresolved,
|
|
559
|
+
tracked,
|
|
560
|
+
dismissed,
|
|
561
|
+
openFollowUps,
|
|
562
|
+
openTrackedItems,
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
/** Final mission gate: contract coverage, all features passed, and no dangling handoff work. */
|
|
566
|
+
export function canCompleteMission(manifest, allContractAssertionIds, options = {}) {
|
|
567
|
+
const coverage = checkMissionCoverage(manifest, allContractAssertionIds);
|
|
568
|
+
const continuity = summarizeMissionContinuity(manifest, options);
|
|
569
|
+
const incompleteFeatures = manifest.features
|
|
570
|
+
.filter((feature) => feature.status !== "passed")
|
|
571
|
+
.map((feature) => ({
|
|
572
|
+
id: feature.id,
|
|
573
|
+
status: feature.status,
|
|
574
|
+
description: feature.description,
|
|
575
|
+
}));
|
|
576
|
+
return {
|
|
577
|
+
ok: coverage.ok && continuity.ok && incompleteFeatures.length === 0,
|
|
578
|
+
coverage,
|
|
579
|
+
continuity,
|
|
580
|
+
incompleteFeatures,
|
|
581
|
+
};
|
|
582
|
+
}
|
|
199
583
|
/**
|
|
200
584
|
* Preempt the in-progress feature: insert a higher-priority feature at
|
|
201
585
|
* the position before the active one, mark the active one as
|
|
@@ -264,6 +648,168 @@ function assertFeatureBasics(feature) {
|
|
|
264
648
|
throw new Error("feature.description is required");
|
|
265
649
|
}
|
|
266
650
|
}
|
|
651
|
+
function buildHandoffFollowUpFeatures(manifest, source, options) {
|
|
652
|
+
const followUps = [];
|
|
653
|
+
const existingIds = new Set(manifest.features.map((feature) => feature.id));
|
|
654
|
+
const generatedFollowUpKeys = new Set();
|
|
655
|
+
const dismissedKeys = new Set((source.handoffDismissals ?? []).map((dismissal) => handoffFollowUpKey(dismissal.kind, dismissal.key)));
|
|
656
|
+
const reserveId = (seed) => {
|
|
657
|
+
let id = seed;
|
|
658
|
+
let suffix = 2;
|
|
659
|
+
while (existingIds.has(id)) {
|
|
660
|
+
id = `${seed}-${suffix}`;
|
|
661
|
+
suffix += 1;
|
|
662
|
+
}
|
|
663
|
+
existingIds.add(id);
|
|
664
|
+
return id;
|
|
665
|
+
};
|
|
666
|
+
for (const item of buildHandoffContinuityRecords(source, options)) {
|
|
667
|
+
if (dismissedKeys.has(handoffFollowUpKey(item.kind, item.key))) {
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
if (findTrackedHandoffFollowUp(manifest, source, item)) {
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
673
|
+
if (findExistingHandoffTracking(manifest, source, item)) {
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
const followUp = createHandoffFollowUpFeature({
|
|
677
|
+
source,
|
|
678
|
+
id: reserveId(item.idSeed),
|
|
679
|
+
kind: item.kind,
|
|
680
|
+
itemKey: item.key,
|
|
681
|
+
description: item.followUpDescription,
|
|
682
|
+
});
|
|
683
|
+
if (!generatedFollowUpKeys.has(featureFollowUpKey(followUp))) {
|
|
684
|
+
followUps.push(followUp);
|
|
685
|
+
generatedFollowUpKeys.add(featureFollowUpKey(followUp));
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
return followUps;
|
|
689
|
+
}
|
|
690
|
+
function createHandoffFollowUpFeature(input) {
|
|
691
|
+
return {
|
|
692
|
+
id: input.id,
|
|
693
|
+
description: input.description,
|
|
694
|
+
status: "pending",
|
|
695
|
+
milestone: input.source.milestone,
|
|
696
|
+
skillName: input.source.skillName,
|
|
697
|
+
fulfills: [],
|
|
698
|
+
handoffSourceFeatureId: input.source.id,
|
|
699
|
+
handoffFollowUpKind: input.kind,
|
|
700
|
+
handoffItemKey: input.itemKey,
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
function buildHandoffContinuityRecords(source, options) {
|
|
704
|
+
const handoff = source.handoff;
|
|
705
|
+
if (!handoff) {
|
|
706
|
+
return [];
|
|
707
|
+
}
|
|
708
|
+
const records = [];
|
|
709
|
+
const unfinished = normalizeFollowUpText(handoff.whatWasLeftUndone);
|
|
710
|
+
if (unfinished) {
|
|
711
|
+
records.push({
|
|
712
|
+
kind: "unfinished_work",
|
|
713
|
+
key: handoffItemKey("unfinished_work", unfinished),
|
|
714
|
+
description: unfinished,
|
|
715
|
+
followUpDescription: `Finish unfinished work from ${source.id}: ${unfinished}`,
|
|
716
|
+
idSeed: `${source.id}-followup-unfinished`,
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
for (const [index, issue] of (handoff.discoveredIssues ?? []).entries()) {
|
|
720
|
+
if (issue.severity === "non_blocking" &&
|
|
721
|
+
!options.includeNonBlockingIssues) {
|
|
722
|
+
continue;
|
|
723
|
+
}
|
|
724
|
+
const description = normalizeFollowUpText(issue.description);
|
|
725
|
+
if (!description) {
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
const suggestedFix = normalizeFollowUpText(issue.suggestedFix);
|
|
729
|
+
records.push({
|
|
730
|
+
kind: "discovered_issue",
|
|
731
|
+
key: handoffItemKey("discovered_issue", `${issue.severity}:${description}:${suggestedFix ?? ""}`),
|
|
732
|
+
severity: issue.severity,
|
|
733
|
+
description: suggestedFix
|
|
734
|
+
? `${description} Suggested fix: ${suggestedFix}`
|
|
735
|
+
: description,
|
|
736
|
+
followUpDescription: suggestedFix
|
|
737
|
+
? `Resolve ${issue.severity} issue from ${source.id}: ${trimTrailingSentencePunctuation(description)}. Suggested fix: ${suggestedFix}`
|
|
738
|
+
: `Resolve ${issue.severity} issue from ${source.id}: ${description}`,
|
|
739
|
+
idSeed: `${source.id}-followup-issue-${index + 1}`,
|
|
740
|
+
});
|
|
741
|
+
}
|
|
742
|
+
return records;
|
|
743
|
+
}
|
|
744
|
+
function findTrackedHandoffFollowUp(manifest, source, record) {
|
|
745
|
+
return manifest.features.find((feature) => feature.handoffSourceFeatureId === source.id &&
|
|
746
|
+
feature.handoffFollowUpKind === record.kind &&
|
|
747
|
+
(feature.handoffItemKey === record.key ||
|
|
748
|
+
(!feature.handoffItemKey &&
|
|
749
|
+
feature.description === record.followUpDescription)));
|
|
750
|
+
}
|
|
751
|
+
function findExistingHandoffTracking(manifest, source, record) {
|
|
752
|
+
return manifest.features.find((feature) => (feature.trackedHandoffItems ?? []).some((item) => item.sourceFeatureId === source.id &&
|
|
753
|
+
item.kind === record.kind &&
|
|
754
|
+
item.key === record.key &&
|
|
755
|
+
isTrackingFreshForSource(source, item)));
|
|
756
|
+
}
|
|
757
|
+
function isTrackingFreshForSource(source, item) {
|
|
758
|
+
if (!source.handoff) {
|
|
759
|
+
return true;
|
|
760
|
+
}
|
|
761
|
+
return compareIsoInstants(item.trackedAt, source.handoff.handedOffAt) >= 0;
|
|
762
|
+
}
|
|
763
|
+
function isTrackedItemCurrent(manifest, trackingFeature, item, options) {
|
|
764
|
+
const source = findFeature(manifest, item.sourceFeatureId);
|
|
765
|
+
if (!source) {
|
|
766
|
+
return false;
|
|
767
|
+
}
|
|
768
|
+
if ((source.handoffDismissals ?? []).some((dismissal) => dismissal.kind === item.kind && dismissal.key === item.key)) {
|
|
769
|
+
return false;
|
|
770
|
+
}
|
|
771
|
+
if (!source.handoff) {
|
|
772
|
+
return trackingFeature.id === source.id;
|
|
773
|
+
}
|
|
774
|
+
const record = buildHandoffContinuityRecords(source, options).find((candidate) => candidate.kind === item.kind && candidate.key === item.key);
|
|
775
|
+
if (!record) {
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
return isTrackingFreshForSource(source, item);
|
|
779
|
+
}
|
|
780
|
+
function compareIsoInstants(a, b) {
|
|
781
|
+
const aTime = Date.parse(a);
|
|
782
|
+
const bTime = Date.parse(b);
|
|
783
|
+
if (Number.isFinite(aTime) && Number.isFinite(bTime)) {
|
|
784
|
+
return aTime - bTime;
|
|
785
|
+
}
|
|
786
|
+
return a.localeCompare(b);
|
|
787
|
+
}
|
|
788
|
+
function normalizeFollowUpText(value) {
|
|
789
|
+
if (value === undefined) {
|
|
790
|
+
return null;
|
|
791
|
+
}
|
|
792
|
+
const normalized = value.replace(/\s+/g, " ").trim();
|
|
793
|
+
if (!normalized || normalized.toLowerCase() === "none") {
|
|
794
|
+
return null;
|
|
795
|
+
}
|
|
796
|
+
return normalized;
|
|
797
|
+
}
|
|
798
|
+
function featureFollowUpKey(feature) {
|
|
799
|
+
return handoffFollowUpKey(feature.handoffFollowUpKind, feature.handoffItemKey ?? feature.description);
|
|
800
|
+
}
|
|
801
|
+
function handoffFollowUpKey(kind, description) {
|
|
802
|
+
return `${kind}:${description}`;
|
|
803
|
+
}
|
|
804
|
+
function handoffItemKey(kind, value) {
|
|
805
|
+
return `${kind}:${value.replace(/\s+/g, " ").trim().toLowerCase()}`;
|
|
806
|
+
}
|
|
807
|
+
function continuityLookupKey(sourceFeatureId, kind, itemKey) {
|
|
808
|
+
return `${sourceFeatureId}:${kind}:${itemKey}`;
|
|
809
|
+
}
|
|
810
|
+
function trimTrailingSentencePunctuation(value) {
|
|
811
|
+
return value.replace(/[.!?]+$/g, "");
|
|
812
|
+
}
|
|
267
813
|
/** Quick summary stats for UI / reporting. */
|
|
268
814
|
export function summarizeManifest(manifest) {
|
|
269
815
|
const byStatus = {
|