ultimate-pi 0.18.0 → 0.19.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/.agents/skills/harness-debate-plan/SKILL.md +1 -1
- package/.agents/skills/harness-decisions/SKILL.md +2 -3
- package/.agents/skills/harness-governor/SKILL.md +6 -5
- package/.agents/skills/harness-orchestration/SKILL.md +4 -4
- package/.agents/skills/harness-review/SKILL.md +7 -7
- package/.agents/skills/harness-sentrux-setup/SKILL.md +4 -3
- package/.agents/skills/harness-steer/SKILL.md +1 -1
- package/.agents/skills/sentrux/SKILL.md +9 -9
- package/.pi/PACKAGING.md +4 -4
- package/.pi/SYSTEM.md +54 -120
- package/.pi/agents/harness/incident-recorder.md +0 -1
- package/.pi/agents/harness/planning/decompose.md +1 -3
- package/.pi/agents/harness/planning/execution-plan-author.md +0 -2
- package/.pi/agents/harness/planning/hypothesis-validator.md +0 -2
- package/.pi/agents/harness/planning/hypothesis.md +0 -2
- package/.pi/agents/harness/planning/implementation-researcher.md +0 -2
- package/.pi/agents/harness/planning/plan-adversary.md +0 -2
- package/.pi/agents/harness/planning/plan-evaluator.md +1 -3
- package/.pi/agents/harness/planning/planning-context.md +0 -2
- package/.pi/agents/harness/planning/review-integrator.md +0 -2
- package/.pi/agents/harness/planning/sprint-contract-auditor.md +0 -2
- package/.pi/agents/harness/planning/stack-researcher.md +0 -2
- package/.pi/agents/harness/{adversary.md → reviewing/adversary.md} +0 -2
- package/.pi/agents/harness/{evaluator.md → reviewing/evaluator.md} +0 -2
- package/.pi/agents/harness/{tie-breaker.md → reviewing/tie-breaker.md} +0 -2
- package/.pi/agents/harness/{executor.md → running/executor.md} +0 -2
- package/.pi/agents/harness/sentrux-bootstrap.md +0 -1
- package/.pi/agents/harness/sentrux-steward.md +0 -2
- package/.pi/agents/harness/trace-librarian.md +0 -1
- package/.pi/extensions/00-harness-project-control.ts +133 -0
- package/.pi/extensions/00-posthog-network-bootstrap.ts +1 -1
- package/.pi/extensions/agt-kill-switch.ts +57 -0
- package/.pi/extensions/agt-prompt-guard.ts +32 -0
- package/.pi/extensions/budget-guard.ts +2 -0
- package/.pi/extensions/custom-footer.ts +46 -145
- package/.pi/extensions/custom-header.ts +1 -1
- package/.pi/extensions/custom-system-prompt.ts +1 -1
- package/.pi/extensions/debate-orchestrator.ts +7 -5
- package/.pi/extensions/harness-ask-user.ts +8 -8
- package/.pi/extensions/harness-debate-tools.ts +27 -43
- package/.pi/extensions/harness-lens.ts +94 -0
- package/.pi/extensions/harness-live-widget.ts +33 -2
- package/.pi/extensions/harness-plan-approval.ts +12 -12
- package/.pi/extensions/harness-run-context.ts +1214 -852
- package/.pi/extensions/harness-subagent-governance.ts +8 -0
- package/.pi/extensions/harness-subagent-submit.ts +36 -164
- package/.pi/extensions/harness-subagents.ts +4 -4
- package/.pi/extensions/harness-telemetry.ts +3 -1
- package/.pi/extensions/harness-web-tools.ts +3 -3
- package/.pi/extensions/observation-bus.ts +2 -0
- package/.pi/extensions/policy-gate.ts +27 -5
- package/.pi/extensions/review-integrity.ts +91 -10
- package/.pi/extensions/sentrux-rules-sync.ts +3 -1
- package/.pi/extensions/subagent-governance.ts +92 -0
- package/.pi/extensions/test-diff-integrity.ts +1 -0
- package/.pi/extensions/trace-recorder.ts +3 -1
- package/.pi/extensions/{ultimate-pi-vcc.ts → vcc-compaction.ts} +1 -1
- package/.pi/harness/README.md +6 -2
- package/.pi/harness/agents.manifest.json +38 -49
- package/.pi/harness/agents.policy.yaml +275 -0
- package/.pi/harness/corpus/graphify-kb-updater.config.json +55 -0
- package/.pi/harness/docs/adrs/0006-sentrux-dual-layer.md +2 -1
- package/.pi/harness/docs/adrs/0030-inhouse-vcc-compaction.md +1 -1
- package/.pi/harness/docs/adrs/0035-plan-phase-review-gate.md +1 -1
- package/.pi/harness/docs/adrs/0044-harness-steer-loop.md +3 -2
- package/.pi/harness/docs/adrs/0045-harness-lens-minimal-contract.md +49 -0
- package/.pi/harness/docs/adrs/0045-phase-scoped-agent-directories.md +33 -0
- package/.pi/harness/docs/adrs/0046-agt-policy-engine.md +51 -0
- package/.pi/harness/docs/adrs/0047-agt-layered-security.md +39 -0
- package/.pi/harness/docs/adrs/0048-tool-call-hook-order.md +25 -0
- package/.pi/harness/docs/adrs/0049-agents-policy-manifest.md +36 -0
- package/.pi/harness/docs/adrs/README.md +6 -0
- package/.pi/harness/docs/graphify-kb-updater-runbook.md +11 -5
- package/.pi/harness/docs/practice-map.md +2 -2
- package/.pi/harness/evolution/README.md +1 -2
- package/.pi/harness/examples/agents.policy.project.yaml +19 -0
- package/.pi/harness/examples/policies/custom-deny-bash.yaml +9 -0
- package/.pi/harness/policies/bash-denylists.yaml +5 -0
- package/.pi/harness/policies/defaults.yaml +51 -0
- package/.pi/harness/policies/orchestrator.yaml +18 -0
- package/.pi/harness/policies/phases.yaml +10 -0
- package/.pi/harness/policies/roles.yaml +5 -0
- package/.pi/harness/policies/web-guard.yaml +5 -0
- package/.pi/harness/policies/workflow-sequences.yaml +9 -0
- package/.pi/harness/sentrux/architecture.manifest.json +26 -4
- package/.pi/harness/specs/harness-spawn-context.schema.json +1 -1
- package/.pi/harness/specs/observation.schema.json +2 -1
- package/.pi/lib/agents-policy.d.mts +70 -0
- package/.pi/lib/agents-policy.mjs +325 -0
- package/.pi/lib/agents-policy.ts +19 -0
- package/.pi/lib/agt/audit-run-sink.ts +52 -0
- package/.pi/lib/agt/build-evaluation-context.ts +285 -0
- package/.pi/lib/agt/config.ts +28 -0
- package/.pi/lib/agt/delegation.ts +69 -0
- package/.pi/lib/agt/evaluate-policy.ts +56 -0
- package/.pi/lib/agt/identity-registry.ts +41 -0
- package/.pi/lib/agt/index.ts +55 -0
- package/.pi/lib/agt/kill-switch-state.ts +11 -0
- package/.pi/lib/agt/legacy-evaluate.ts +101 -0
- package/.pi/lib/agt/policy-engine.ts +154 -0
- package/.pi/lib/agt/rings.ts +21 -0
- package/.pi/lib/agt/sre-hooks.ts +45 -0
- package/.pi/lib/agt/trust-run-store.ts +26 -0
- package/.pi/lib/agt/workflow-history.ts +29 -0
- package/.pi/lib/agt-governance-active.ts +14 -0
- package/.pi/lib/agt-tool-guard.ts +78 -0
- package/.pi/lib/ask-user/dialog.ts +314 -0
- package/.pi/{extensions/lib → lib}/debate-bus-core.ts +10 -10
- package/.pi/{extensions/lib → lib}/debate-bus-state.ts +1 -1
- package/.pi/{extensions/lib → lib}/extension-load-guard.ts +21 -0
- package/.pi/lib/harness-agt-tool-guard.ts +5 -0
- package/.pi/{extensions/lib → lib}/harness-artifact-gate.ts +6 -16
- package/.pi/lib/harness-debate-core-deps.ts +14 -0
- package/.pi/lib/harness-debate-workflow-deps.ts +43 -0
- package/.pi/lib/harness-lens/.gitattributes +1 -0
- package/.pi/lib/harness-lens/clients/edit-autopatch.ts +88 -0
- package/.pi/lib/harness-lens/clients/file-kinds.ts +380 -0
- package/.pi/lib/harness-lens/clients/file-time.ts +215 -0
- package/.pi/lib/harness-lens/clients/file-utils.ts +484 -0
- package/.pi/lib/harness-lens/clients/format-service.ts +276 -0
- package/.pi/lib/harness-lens/clients/formatters.ts +1000 -0
- package/.pi/lib/harness-lens/clients/git-guard.ts +31 -0
- package/.pi/lib/harness-lens/clients/indent-retarget.ts +90 -0
- package/.pi/lib/harness-lens/clients/installer/index.ts +2368 -0
- package/.pi/lib/harness-lens/clients/latency-logger.ts +80 -0
- package/.pi/lib/harness-lens/clients/lens-config.ts +43 -0
- package/.pi/lib/harness-lens/clients/lens-events.ts +164 -0
- package/.pi/lib/harness-lens/clients/lsp/aggregation.ts +91 -0
- package/.pi/lib/harness-lens/clients/lsp/client.ts +1466 -0
- package/.pi/lib/harness-lens/clients/lsp/config.ts +216 -0
- package/.pi/lib/harness-lens/clients/lsp/edits.ts +297 -0
- package/.pi/lib/harness-lens/clients/lsp/index.ts +1355 -0
- package/.pi/lib/harness-lens/clients/lsp/interactive-install.ts +424 -0
- package/.pi/lib/harness-lens/clients/lsp/language.ts +223 -0
- package/.pi/lib/harness-lens/clients/lsp/launch.ts +939 -0
- package/.pi/lib/harness-lens/clients/lsp/lsp-index.ts +11 -0
- package/.pi/lib/harness-lens/clients/lsp/path-utils.ts +12 -0
- package/.pi/lib/harness-lens/clients/lsp/server-strategies.ts +81 -0
- package/.pi/lib/harness-lens/clients/lsp/server.ts +1971 -0
- package/.pi/lib/harness-lens/clients/path-utils.ts +182 -0
- package/.pi/lib/harness-lens/clients/pipeline.ts +360 -0
- package/.pi/lib/harness-lens/clients/project-profile.ts +117 -0
- package/.pi/lib/harness-lens/clients/runtime-agent-end.ts +112 -0
- package/.pi/lib/harness-lens/clients/runtime-config.ts +33 -0
- package/.pi/lib/harness-lens/clients/runtime-coordinator.ts +186 -0
- package/.pi/lib/harness-lens/clients/runtime-tool-result.ts +171 -0
- package/.pi/lib/harness-lens/clients/safe-spawn.ts +339 -0
- package/.pi/lib/harness-lens/clients/secrets-scanner.ts +214 -0
- package/.pi/lib/harness-lens/clients/tool-policy.ts +2072 -0
- package/.pi/lib/harness-lens/clients/types.ts +59 -0
- package/.pi/lib/harness-lens/clients/widget-state.ts +283 -0
- package/.pi/lib/harness-lens/index.ts +532 -0
- package/.pi/lib/harness-lens/tools/lsp-diagnostics.ts +706 -0
- package/.pi/lib/harness-lens/tools/lsp-navigation.ts +1246 -0
- package/.pi/{extensions/lib → lib}/harness-posthog.ts +3 -0
- package/.pi/lib/harness-project-config.ts +91 -0
- package/.pi/lib/harness-run-context-responses.ts +9 -0
- package/.pi/lib/harness-run-context.ts +1 -3
- package/.pi/{extensions/lib/spawn-policy.ts → lib/harness-spawn-policy.ts} +4 -3
- package/.pi/{extensions/lib → lib}/harness-spawn-topology.ts +5 -28
- package/.pi/lib/harness-subagent-auth.ts +51 -0
- package/.pi/{extensions/lib → lib}/harness-subagent-precheck.ts +13 -10
- package/.pi/{extensions/lib → lib}/harness-subagent-submit-pipeline.ts +3 -3
- package/.pi/lib/harness-subagent-submit-register.ts +163 -0
- package/.pi/{extensions/lib → lib}/harness-subagent-submit-registry.ts +1 -55
- package/.pi/{extensions/lib → lib}/harness-subagents-bridge.ts +53 -14
- package/.pi/{extensions/lib → lib}/harness-subprocess-bootstrap.ts +1 -1
- package/.pi/lib/harness-ui-state.ts +27 -12
- package/.pi/{extensions/lib → lib}/plan-approval/create-plan.ts +2 -2
- package/.pi/{extensions/lib → lib}/plan-approval/format-plan.ts +2 -2
- package/.pi/{extensions/lib → lib}/plan-approval/plan-review.ts +162 -201
- package/.pi/{extensions/lib → lib}/plan-approval/render.ts +1 -1
- package/.pi/{extensions/lib → lib}/plan-approval/resolve-disk.ts +2 -2
- package/.pi/{extensions/lib → lib}/plan-approval/types.ts +1 -1
- package/.pi/{extensions/lib → lib}/plan-approval/validate.ts +3 -3
- package/.pi/{extensions/lib → lib}/plan-approval-readiness.ts +3 -52
- package/.pi/{extensions/lib → lib}/plan-debate-envelope.ts +1 -1
- package/.pi/{extensions/lib → lib}/plan-debate-gate.ts +1 -1
- package/.pi/{extensions/lib → lib}/plan-debate-lane.ts +1 -4
- package/.pi/{extensions/lib → lib}/plan-messenger.ts +1 -1
- package/.pi/prompts/harness-auto.md +2 -2
- package/.pi/prompts/harness-plan.md +4 -6
- package/.pi/prompts/harness-review.md +9 -9
- package/.pi/prompts/harness-run.md +7 -7
- package/.pi/prompts/harness-setup.md +42 -68
- package/.pi/prompts/harness-steer.md +2 -2
- package/.pi/scripts/README.md +3 -5
- package/.pi/scripts/generate-agents-policy-yaml.mjs +148 -0
- package/.pi/scripts/graphify-kb-updater.mjs +48 -8
- package/.pi/scripts/harness-agents-manifest.mjs +61 -4
- package/.pi/scripts/harness-agt-doctor.ts +36 -0
- package/.pi/scripts/harness-cli-verify.sh +9 -2
- package/.pi/scripts/harness-project-toggle.mjs +129 -0
- package/.pi/scripts/harness-sentrux-cli.mjs +142 -0
- package/.pi/scripts/harness-verify.mjs +113 -39
- package/.pi/scripts/harness-web-policy-guard.mjs +2 -2
- package/.pi/scripts/validate-plan-dag.mjs +65 -74
- package/.pi/scripts/vendor-pi-vcc-settings.stub.ts +2 -2
- package/.pi/scripts/vendor-sync-pi-vcc.sh +1 -1
- package/.pi/skills/architecture/broker-domain/SKILL.md +65 -0
- package/.pi/skills/architecture/cqrs/SKILL.md +63 -0
- package/.pi/skills/architecture/event-driven/SKILL.md +60 -0
- package/.pi/skills/architecture/hexagonal-ports-adapters/SKILL.md +66 -0
- package/.pi/skills/architecture/layered/SKILL.md +68 -0
- package/.pi/skills/architecture/microkernel/SKILL.md +62 -0
- package/.pi/skills/architecture/microservices/SKILL.md +64 -0
- package/.pi/skills/architecture/modular-monolith/SKILL.md +65 -0
- package/.pi/skills/architecture/orchestration-driven-soa/SKILL.md +61 -0
- package/.pi/skills/architecture/pipeline/SKILL.md +63 -0
- package/.pi/skills/architecture/service-based/SKILL.md +64 -0
- package/.pi/skills/architecture/service-mesh/SKILL.md +60 -0
- package/.pi/skills/architecture/space-based/SKILL.md +60 -0
- package/.pi/skills/ast-grep/SKILL.md +40 -321
- package/.pi/skills/delivery/debugging-discipline/SKILL.md +36 -0
- package/.pi/skills/delivery/documentation-update/SKILL.md +33 -0
- package/.pi/skills/delivery/requirements-to-implementation/SKILL.md +34 -0
- package/.pi/skills/delivery/risk-based-verification/SKILL.md +43 -0
- package/.pi/skills/delivery/tradeoff-analysis/SKILL.md +34 -0
- package/.pi/skills/engineering/api-contract-design/SKILL.md +38 -0
- package/.pi/skills/engineering/cohesion-coupling/SKILL.md +43 -0
- package/.pi/skills/engineering/complexity-control/SKILL.md +31 -0
- package/.pi/skills/engineering/defensive-programming/SKILL.md +38 -0
- package/.pi/skills/engineering/dependency-management/SKILL.md +29 -0
- package/.pi/skills/engineering/domain-modeling/SKILL.md +32 -0
- package/.pi/skills/engineering/error-handling/SKILL.md +37 -0
- package/.pi/skills/engineering/legacy-code-seams/SKILL.md +35 -0
- package/.pi/skills/engineering/naming-and-intent/SKILL.md +29 -0
- package/.pi/skills/engineering/refactoring-safe-evolution/SKILL.md +35 -0
- package/.pi/skills/engineering/routine-function-design/SKILL.md +34 -0
- package/.pi/skills/engineering/small-change-discipline/SKILL.md +35 -0
- package/.pi/skills/lsp-navigation/SKILL.md +89 -0
- package/.pi/skills/quality/code-review-self-check/SKILL.md +35 -0
- package/.pi/skills/quality/privacy-data-handling/SKILL.md +26 -0
- package/.pi/skills/quality/security-review/SKILL.md +34 -0
- package/.pi/skills/quality/test-strategy/SKILL.md +33 -0
- package/.pi/skills/quality/testability-design/SKILL.md +33 -0
- package/.pi/skills/systems/concurrency-safety/SKILL.md +32 -0
- package/.pi/skills/systems/data-modeling-migrations/SKILL.md +31 -0
- package/.pi/skills/systems/observability-instrumentation/SKILL.md +32 -0
- package/.pi/skills/systems/performance-measurement/SKILL.md +35 -0
- package/.pi/skills/systems/reliability-design/SKILL.md +32 -0
- package/.sentrux/rules.toml +20 -4
- package/AGENTS.md +5 -0
- package/CHANGELOG.md +26 -0
- package/README.md +85 -58
- package/THIRD_PARTY_NOTICES.md +12 -21
- package/package.json +15 -7
- package/vendor/pi-subagents/src/agents.ts +45 -1
- package/vendor/pi-subagents/src/subagents.ts +866 -811
- package/vendor/pi-vcc/src/core/brief.ts +68 -99
- package/vendor/pi-vcc/src/core/settings.ts +2 -2
- package/.agents/skills/caveman/SKILL.md +0 -67
- package/.pi/agents/harness/meta-optimizer.md +0 -36
- package/.pi/agents/harness/planning/scout-graphify.md +0 -39
- package/.pi/agents/harness/planning/scout-semantic.md +0 -41
- package/.pi/agents/harness/planning/scout-structure.md +0 -37
- package/.pi/extensions/lib/ask-user/dialog.ts +0 -260
- package/.pi/extensions/lib/harness-subagent-auth.ts +0 -209
- package/.pi/extensions/lib/harness-subagent-policy.ts +0 -236
- package/.pi/extensions/pi-model-router-harness.ts +0 -42
- package/.pi/harness/evolution/meta-optimizer.mjs +0 -99
- package/.pi/harness/specs/router-tuning-proposal.schema.json +0 -114
- package/.pi/model-router.example.json +0 -36
- package/.pi/prompts/harness-critic.md +0 -10
- package/.pi/prompts/harness-eval.md +0 -10
- package/.pi/prompts/harness-router-tune.md +0 -52
- package/.pi/scripts/harness-generate-model-router.mjs +0 -327
- package/.pi/scripts/harness-model-router-routing.test.mjs +0 -97
- package/.pi/scripts/harness-sync-model-router.mjs +0 -97
- package/.pi/scripts/vendor-sync-pi-model-router.sh +0 -47
- package/vendor/pi-model-router/.prettierignore +0 -4
- package/vendor/pi-model-router/.prettierrc +0 -5
- package/vendor/pi-model-router/AGENTS.md +0 -39
- package/vendor/pi-model-router/LICENSE +0 -21
- package/vendor/pi-model-router/README.md +0 -99
- package/vendor/pi-model-router/UPSTREAM_PIN.md +0 -10
- package/vendor/pi-model-router/docs/ARCHITECTURE.md +0 -54
- package/vendor/pi-model-router/extensions/commands.ts +0 -720
- package/vendor/pi-model-router/extensions/config.ts +0 -348
- package/vendor/pi-model-router/extensions/constants.ts +0 -1
- package/vendor/pi-model-router/extensions/index.ts +0 -478
- package/vendor/pi-model-router/extensions/provider.ts +0 -580
- package/vendor/pi-model-router/extensions/routing.ts +0 -564
- package/vendor/pi-model-router/extensions/state.ts +0 -52
- package/vendor/pi-model-router/extensions/types.ts +0 -95
- package/vendor/pi-model-router/extensions/ui.ts +0 -144
- package/vendor/pi-model-router/model-router.example.json +0 -48
- package/vendor/pi-model-router/package.json +0 -48
- package/vendor/pi-model-router/tsconfig.json +0 -16
- /package/.pi/{prompts → harness/docs}/planning-rubrics.md +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/fallback.ts +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/render.ts +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/schema.ts +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/types.ts +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/validate-core.mjs +0 -0
- /package/.pi/{extensions/lib → lib}/ask-user/validate.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-cocoindex-refresh.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-paths.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-spawn-budget.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-vcc-settings.ts +0 -0
- /package/.pi/{extensions/lib → lib}/harness-web/run-cli.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-approval/dialog.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-approval/schema.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-eligibility.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-focus.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-id.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-lanes.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-round-status.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-debate-write-guard.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-review-gate.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-review-integrator-rules.ts +0 -0
- /package/.pi/{extensions/lib → lib}/plan-scope-guard.ts +0 -0
- /package/.pi/{extensions/lib → lib}/posthog-client.ts +0 -0
- /package/.pi/{extensions/lib → lib}/posthog-node.d.ts +0 -0
|
@@ -7,21 +7,26 @@ import type {
|
|
|
7
7
|
ExtensionAPI,
|
|
8
8
|
ExtensionContext,
|
|
9
9
|
} from "@earendil-works/pi-coding-agent";
|
|
10
|
-
import type { AgentConfig } from "
|
|
10
|
+
import type { AgentConfig } from "../../vendor/pi-subagents/src/agents.js";
|
|
11
11
|
import {
|
|
12
12
|
createSubagentsExtension,
|
|
13
13
|
type HarnessSubagentsOptions,
|
|
14
14
|
type SpawnAuthForward,
|
|
15
|
-
} from "
|
|
15
|
+
} from "../../vendor/pi-subagents/src/subagents.js";
|
|
16
|
+
import { subagentGovernanceExtensionPath } from "../extensions/subagent-governance.js";
|
|
17
|
+
import { getAgentKind } from "./agents-policy.mjs";
|
|
18
|
+
import {
|
|
19
|
+
delegationEnvFromBundle,
|
|
20
|
+
mintSubagentDelegation,
|
|
21
|
+
} from "./agt/delegation.js";
|
|
22
|
+
import { spawnCircuitOpen } from "./agt/sre-hooks.js";
|
|
23
|
+
import { refreshHarnessCocoindexIndex } from "./harness-cocoindex-refresh.js";
|
|
24
|
+
import { captureHarnessEvent } from "./harness-posthog.js";
|
|
16
25
|
import {
|
|
17
26
|
getLatestRunContext,
|
|
18
27
|
getRunIdFromSession,
|
|
19
28
|
type HarnessPhase,
|
|
20
|
-
} from "
|
|
21
|
-
import { parseSpawnContextFromTask } from "../../lib/harness-spawn-parse.js";
|
|
22
|
-
import { harnessSubagentSubmitExtensionPath } from "../harness-subagent-submit.js";
|
|
23
|
-
import { refreshHarnessCocoindexIndex } from "./harness-cocoindex-refresh.js";
|
|
24
|
-
import { captureHarnessEvent } from "./harness-posthog.js";
|
|
29
|
+
} from "./harness-run-context.js";
|
|
25
30
|
import {
|
|
26
31
|
checkHarnessSpawnBudget,
|
|
27
32
|
countHarnessAgentsInRequest,
|
|
@@ -29,6 +34,7 @@ import {
|
|
|
29
34
|
recordSpawnEnd,
|
|
30
35
|
recordSpawnStart,
|
|
31
36
|
} from "./harness-spawn-budget.js";
|
|
37
|
+
import { parseSpawnContextFromTask } from "./harness-spawn-parse.js";
|
|
32
38
|
import {
|
|
33
39
|
isUsableApiKey,
|
|
34
40
|
resolveConcreteSubagentModel,
|
|
@@ -111,19 +117,52 @@ async function resolveHarnessSpawnAuth(
|
|
|
111
117
|
export function createHarnessSubagentsExtension(
|
|
112
118
|
packageRoot: string,
|
|
113
119
|
): (pi: ExtensionAPI) => void {
|
|
114
|
-
const
|
|
120
|
+
const governanceExtPath = subagentGovernanceExtensionPath(packageRoot);
|
|
115
121
|
const options: HarnessSubagentsOptions = {
|
|
116
122
|
packageRoot,
|
|
117
|
-
|
|
123
|
+
subprocessGovernanceExtensionPath: governanceExtPath,
|
|
124
|
+
harnessSubprocessExtensionPath: governanceExtPath,
|
|
118
125
|
resolveSubprocessEnv: (task, agent) => {
|
|
119
|
-
|
|
126
|
+
const projectRoot = process.cwd();
|
|
127
|
+
const base: Record<string, string> = {
|
|
128
|
+
PI_HARNESS_SUBPROCESS: "1",
|
|
129
|
+
HARNESS_AGENT_ID: agent.name,
|
|
130
|
+
HARNESS_PKG_ROOT: packageRoot,
|
|
131
|
+
HARNESS_PROJECT_ROOT: projectRoot,
|
|
132
|
+
};
|
|
120
133
|
const ctx = parseSpawnContextFromTask(task);
|
|
121
|
-
if (!ctx?.run_id) return
|
|
134
|
+
if (!ctx?.run_id) return base;
|
|
135
|
+
if (spawnCircuitOpen(ctx.run_id)) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const runDir =
|
|
139
|
+
ctx.run_dir ?? join(packageRoot, ".pi", "harness", "runs", ctx.run_id);
|
|
140
|
+
const kind = getAgentKind(packageRoot, projectRoot, agent.name);
|
|
141
|
+
let delegationEnv: Record<string, string> = {};
|
|
142
|
+
try {
|
|
143
|
+
const bundle = mintSubagentDelegation({
|
|
144
|
+
runId: ctx.run_id,
|
|
145
|
+
runDir,
|
|
146
|
+
agentId: agent.name,
|
|
147
|
+
agentKind: kind,
|
|
148
|
+
});
|
|
149
|
+
delegationEnv = delegationEnvFromBundle(bundle);
|
|
150
|
+
} catch {
|
|
151
|
+
/* identity mint best-effort */
|
|
152
|
+
}
|
|
122
153
|
return {
|
|
154
|
+
...base,
|
|
123
155
|
HARNESS_RUN_ID: ctx.run_id,
|
|
124
|
-
HARNESS_RUN_DIR:
|
|
125
|
-
|
|
126
|
-
|
|
156
|
+
HARNESS_RUN_DIR: runDir,
|
|
157
|
+
HARNESS_SUBAGENT_PHASE_HINT:
|
|
158
|
+
kind === "executor"
|
|
159
|
+
? "execute"
|
|
160
|
+
: kind === "evaluator"
|
|
161
|
+
? "evaluate"
|
|
162
|
+
: kind === "adversary"
|
|
163
|
+
? "adversary"
|
|
164
|
+
: "plan",
|
|
165
|
+
...delegationEnv,
|
|
127
166
|
};
|
|
128
167
|
},
|
|
129
168
|
defaultAgentScope: "both",
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
loadRunContextForSubprocess,
|
|
14
14
|
nowIso,
|
|
15
15
|
policyBootstrapFromRunContext,
|
|
16
|
-
} from "
|
|
16
|
+
} from "./harness-run-context.js";
|
|
17
17
|
|
|
18
18
|
type PolicyState = {
|
|
19
19
|
phase: "plan" | "execute" | "evaluate" | "adversary" | "merge";
|
|
@@ -375,8 +375,6 @@ export const HARNESS_PHASE_ORDER: readonly HarnessPhase[] = [
|
|
|
375
375
|
"plan",
|
|
376
376
|
"execute",
|
|
377
377
|
"evaluate",
|
|
378
|
-
"adversary",
|
|
379
|
-
"merge",
|
|
380
378
|
] as const;
|
|
381
379
|
|
|
382
380
|
export function formatHarnessPhaseLabel(phase: HarnessPhase): string {
|
|
@@ -384,13 +382,11 @@ export function formatHarnessPhaseLabel(phase: HarnessPhase): string {
|
|
|
384
382
|
case "plan":
|
|
385
383
|
return "plan";
|
|
386
384
|
case "execute":
|
|
387
|
-
return "
|
|
385
|
+
return "run";
|
|
388
386
|
case "evaluate":
|
|
389
|
-
return "eval";
|
|
390
387
|
case "adversary":
|
|
391
|
-
return "review";
|
|
392
388
|
case "merge":
|
|
393
|
-
return "
|
|
389
|
+
return "review";
|
|
394
390
|
}
|
|
395
391
|
}
|
|
396
392
|
|
|
@@ -400,6 +396,25 @@ export function nextHarnessPhase(phase: HarnessPhase): HarnessPhase | null {
|
|
|
400
396
|
return HARNESS_PHASE_ORDER[index + 1] ?? null;
|
|
401
397
|
}
|
|
402
398
|
|
|
399
|
+
function mainPhaseCommandForStatus(state: HarnessUiState): string | null {
|
|
400
|
+
const command = state.nextRecommendedCommand;
|
|
401
|
+
if (!command) return null;
|
|
402
|
+
const normalized = command.toLowerCase();
|
|
403
|
+
|
|
404
|
+
if (normalized.includes("/harness-plan")) {
|
|
405
|
+
return normalized.includes("revise")
|
|
406
|
+
? "/harness-plan (mode: revise)"
|
|
407
|
+
: "/harness-plan";
|
|
408
|
+
}
|
|
409
|
+
if (normalized.includes("/harness-review")) return "/harness-review";
|
|
410
|
+
if (normalized.includes("/harness-run-status")) {
|
|
411
|
+
return state.phase === "execute" ? "/harness-review" : null;
|
|
412
|
+
}
|
|
413
|
+
if (normalized.includes("/harness-run")) return "/harness-run";
|
|
414
|
+
if (normalized.includes("/harness-steer")) return "/harness-run";
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
|
|
403
418
|
function truncateStatusCommand(command: string, maxLen = 40): string {
|
|
404
419
|
if (command.length <= maxLen) return command;
|
|
405
420
|
return `${command.slice(0, maxLen - 3)}...`;
|
|
@@ -430,9 +445,10 @@ export function deriveHarnessStatusHint(state: HarnessUiState): {
|
|
|
430
445
|
) {
|
|
431
446
|
return { text: "Waiting for your input", severity: "warning" };
|
|
432
447
|
}
|
|
433
|
-
|
|
448
|
+
const mainPhaseCommand = mainPhaseCommandForStatus(state);
|
|
449
|
+
if (mainPhaseCommand) {
|
|
434
450
|
return {
|
|
435
|
-
text: `Next: ${truncateStatusCommand(
|
|
451
|
+
text: `Next: ${truncateStatusCommand(mainPhaseCommand)}`,
|
|
436
452
|
severity: "accent",
|
|
437
453
|
};
|
|
438
454
|
}
|
|
@@ -450,13 +466,12 @@ export function deriveHarnessStatusHint(state: HarnessUiState): {
|
|
|
450
466
|
}
|
|
451
467
|
switch (state.phase) {
|
|
452
468
|
case "execute":
|
|
453
|
-
return { text: "
|
|
469
|
+
return { text: "Running changes", severity: "accent" };
|
|
454
470
|
case "evaluate":
|
|
455
|
-
return { text: "Running checks", severity: "accent" };
|
|
456
471
|
case "adversary":
|
|
457
|
-
return { text: "
|
|
472
|
+
return { text: "Reviewing changes", severity: "accent" };
|
|
458
473
|
case "merge":
|
|
459
|
-
return { text: "
|
|
474
|
+
return { text: "Review complete", severity: "accent" };
|
|
460
475
|
default:
|
|
461
476
|
return { text: "Planning", severity: "muted" };
|
|
462
477
|
}
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
saveProjectActiveRun,
|
|
9
9
|
saveRunContextToDisk,
|
|
10
10
|
validatePlanPacket,
|
|
11
|
-
} from "
|
|
12
|
-
import { writeYamlFile } from "
|
|
11
|
+
} from "../harness-run-context.js";
|
|
12
|
+
import { writeYamlFile } from "../harness-yaml.js";
|
|
13
13
|
import { writePlanReviewMarkdown } from "./plan-review.js";
|
|
14
14
|
|
|
15
15
|
export const CREATE_PLAN_SNIPPET = "create_plan()";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PlanPacketLike } from "
|
|
2
|
-
import { stringifyYaml } from "
|
|
1
|
+
import type { PlanPacketLike } from "../harness-run-context.js";
|
|
2
|
+
import { stringifyYaml } from "../harness-yaml.js";
|
|
3
3
|
|
|
4
4
|
/** Canonical YAML for plan_packet (same shape as plan-packet.yaml on disk). */
|
|
5
5
|
export function formatPlanPacketYaml(packet: PlanPacketLike): string {
|
|
@@ -5,14 +5,14 @@ import {
|
|
|
5
5
|
canonicalPlanReviewPath,
|
|
6
6
|
type HarnessRunContext,
|
|
7
7
|
type PlanPacketLike,
|
|
8
|
-
} from "
|
|
8
|
+
} from "../harness-run-context.js";
|
|
9
9
|
import { formatPlanPacketYaml } from "./format-plan.js";
|
|
10
10
|
import type { PlanResearchBrief } from "./types.js";
|
|
11
11
|
|
|
12
12
|
export {
|
|
13
13
|
canonicalPlanReviewPath,
|
|
14
14
|
PLAN_REVIEW_BASENAME,
|
|
15
|
-
} from "
|
|
15
|
+
} from "../harness-run-context.js";
|
|
16
16
|
|
|
17
17
|
export type PlanReviewStatus = "draft" | "approved" | "committed";
|
|
18
18
|
|
|
@@ -33,223 +33,184 @@ function strList(value: unknown): string[] {
|
|
|
33
33
|
.filter((item): item is string => Boolean(item));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
36
|
+
function pushListSection(
|
|
37
|
+
lines: string[],
|
|
38
|
+
title: string,
|
|
39
|
+
items: string[],
|
|
40
|
+
): void {
|
|
41
|
+
if (!items.length) return;
|
|
42
|
+
lines.push(`**${title}:**`);
|
|
43
|
+
for (const item of items) lines.push(`- ${item}`);
|
|
44
|
+
lines.push("");
|
|
45
|
+
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
function appendDecompositionMarkdown(
|
|
48
|
+
lines: string[],
|
|
49
|
+
decomp: Record<string, unknown>,
|
|
50
|
+
): void {
|
|
51
|
+
lines.push("## Phase 1 — Problem decomposition", "");
|
|
52
|
+
const restate = str(decomp.problem_restatement);
|
|
53
|
+
if (restate) lines.push("**What is being asked?**", "", restate, "");
|
|
54
|
+
const types = strList(decomp.problem_types);
|
|
55
|
+
if (types.length) lines.push(`**Problem type(s):** ${types.join(", ")}`, "");
|
|
56
|
+
const scope = asRecord(decomp.scope);
|
|
57
|
+
if (scope) {
|
|
58
|
+
const focus = str(scope.narrowed_focus);
|
|
59
|
+
if (focus) lines.push("**Scope:**", "", focus, "");
|
|
60
|
+
pushListSection(lines, "Excluded", strList(scope.excluded));
|
|
61
|
+
}
|
|
62
|
+
for (const [label, key] of [
|
|
63
|
+
["Hard constraints", "hard_constraints"],
|
|
64
|
+
["Soft constraints", "soft_constraints"],
|
|
65
|
+
["Success metrics", "success_metrics"],
|
|
66
|
+
] as const) {
|
|
67
|
+
pushListSection(lines, label, strList(decomp[key]));
|
|
68
|
+
}
|
|
69
|
+
const prior = asRecord(decomp.prior_art);
|
|
70
|
+
if (prior) {
|
|
71
|
+
lines.push("**Prior art:**", "");
|
|
72
|
+
const best = str(prior.best_approach);
|
|
73
|
+
const gap = str(prior.gap);
|
|
74
|
+
if (best) lines.push(`- Best approach: ${best}`);
|
|
75
|
+
if (gap) lines.push(`- Gap: ${gap}`);
|
|
76
|
+
for (const dead of strList(prior.dead_ends))
|
|
77
|
+
lines.push(`- Dead end: ${dead}`);
|
|
48
78
|
lines.push("");
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const scope = asRecord(decomp.scope);
|
|
62
|
-
if (scope) {
|
|
63
|
-
const focus = str(scope.narrowed_focus);
|
|
64
|
-
if (focus) {
|
|
65
|
-
lines.push("**Scope:**");
|
|
66
|
-
lines.push("");
|
|
67
|
-
lines.push(focus);
|
|
68
|
-
lines.push("");
|
|
69
|
-
}
|
|
70
|
-
const excluded = strList(scope.excluded);
|
|
71
|
-
if (excluded.length) {
|
|
72
|
-
lines.push("**Excluded:**");
|
|
73
|
-
for (const item of excluded) lines.push(`- ${item}`);
|
|
74
|
-
lines.push("");
|
|
75
|
-
}
|
|
76
|
-
}
|
|
79
|
+
}
|
|
80
|
+
const core = str(decomp.core_tension);
|
|
81
|
+
if (core) lines.push("**Core tension:**", "", core, "");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function appendHypothesisMarkdown(
|
|
85
|
+
lines: string[],
|
|
86
|
+
hyp: Record<string, unknown>,
|
|
87
|
+
): void {
|
|
88
|
+
lines.push("## Phase 2 — DARWIN hypothesis", "");
|
|
89
|
+
const primary = asRecord(hyp.primary);
|
|
90
|
+
if (primary) {
|
|
77
91
|
for (const [label, key] of [
|
|
78
|
-
["
|
|
79
|
-
["
|
|
80
|
-
["
|
|
92
|
+
["Claim", "claim"],
|
|
93
|
+
["Mechanism", "mechanism"],
|
|
94
|
+
["Prediction", "prediction"],
|
|
95
|
+
["Experiment", "experiment"],
|
|
96
|
+
["Resolves tension", "tension_resolution"],
|
|
81
97
|
] as const) {
|
|
82
|
-
const
|
|
83
|
-
if (
|
|
84
|
-
lines.push(`**${label}:**`);
|
|
85
|
-
for (const item of items) lines.push(`- ${item}`);
|
|
86
|
-
lines.push("");
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const prior = asRecord(decomp.prior_art);
|
|
90
|
-
if (prior) {
|
|
91
|
-
lines.push("**Prior art:**");
|
|
92
|
-
lines.push("");
|
|
93
|
-
const best = str(prior.best_approach);
|
|
94
|
-
const gap = str(prior.gap);
|
|
95
|
-
if (best) lines.push(`- Best approach: ${best}`);
|
|
96
|
-
if (gap) lines.push(`- Gap: ${gap}`);
|
|
97
|
-
for (const dead of strList(prior.dead_ends)) {
|
|
98
|
-
lines.push(`- Dead end: ${dead}`);
|
|
99
|
-
}
|
|
100
|
-
lines.push("");
|
|
101
|
-
}
|
|
102
|
-
const core = str(decomp.core_tension);
|
|
103
|
-
if (core) {
|
|
104
|
-
lines.push("**Core tension:**");
|
|
105
|
-
lines.push("");
|
|
106
|
-
lines.push(core);
|
|
107
|
-
lines.push("");
|
|
98
|
+
const text = str(primary[key]);
|
|
99
|
+
if (text) lines.push(`**${label}:** ${text}`, "");
|
|
108
100
|
}
|
|
109
101
|
}
|
|
110
|
-
|
|
111
|
-
if (
|
|
112
|
-
|
|
102
|
+
const fork = asRecord(hyp.dialectical_fork);
|
|
103
|
+
if (fork) {
|
|
104
|
+
const forkText = str(fork.fork);
|
|
105
|
+
if (forkText) lines.push(`**Dialectical fork:** ${forkText}`, "");
|
|
106
|
+
const pathA = str(fork.path_a);
|
|
107
|
+
const pathB = str(fork.path_b);
|
|
108
|
+
if (pathA) lines.push(`- **Path A:** ${pathA}`);
|
|
109
|
+
if (pathB) lines.push(`- **Path B:** ${pathB}`);
|
|
113
110
|
lines.push("");
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const text = str(primary[key]);
|
|
124
|
-
if (text) {
|
|
125
|
-
lines.push(`**${label}:** ${text}`);
|
|
126
|
-
lines.push("");
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
const fork = asRecord(hyp.dialectical_fork);
|
|
131
|
-
if (fork) {
|
|
132
|
-
const forkText = str(fork.fork);
|
|
133
|
-
if (forkText) {
|
|
134
|
-
lines.push(`**Dialectical fork:** ${forkText}`);
|
|
135
|
-
lines.push("");
|
|
136
|
-
}
|
|
137
|
-
const pathA = str(fork.path_a);
|
|
138
|
-
const pathB = str(fork.path_b);
|
|
139
|
-
if (pathA) lines.push(`- **Path A:** ${pathA}`);
|
|
140
|
-
if (pathB) lines.push(`- **Path B:** ${pathB}`);
|
|
141
|
-
lines.push("");
|
|
142
|
-
}
|
|
143
|
-
const alts = Array.isArray(hyp.alternatives) ? hyp.alternatives : [];
|
|
144
|
-
if (alts.length) {
|
|
145
|
-
lines.push("**Alternatives:**");
|
|
146
|
-
for (const alt of alts) {
|
|
147
|
-
const rec = asRecord(alt);
|
|
148
|
-
if (!rec) continue;
|
|
149
|
-
const claim = str(rec.claim);
|
|
150
|
-
const bet = str(rec.key_bet);
|
|
151
|
-
if (claim) lines.push(`- ${claim}${bet ? ` (bet: ${bet})` : ""}`);
|
|
152
|
-
}
|
|
153
|
-
lines.push("");
|
|
154
|
-
}
|
|
155
|
-
const steps = strList(hyp.recommended_next_steps);
|
|
156
|
-
if (steps.length) {
|
|
157
|
-
lines.push("**Recommended next steps:**");
|
|
158
|
-
for (const step of steps) lines.push(`1. ${step}`);
|
|
159
|
-
lines.push("");
|
|
111
|
+
}
|
|
112
|
+
const alts = Array.isArray(hyp.alternatives) ? hyp.alternatives : [];
|
|
113
|
+
if (alts.length) {
|
|
114
|
+
lines.push("**Alternatives:**");
|
|
115
|
+
for (const alt of alts) {
|
|
116
|
+
const rec = asRecord(alt);
|
|
117
|
+
const claim = rec ? str(rec.claim) : null;
|
|
118
|
+
const bet = rec ? str(rec.key_bet) : null;
|
|
119
|
+
if (claim) lines.push(`- ${claim}${bet ? ` (bet: ${bet})` : ""}`);
|
|
160
120
|
}
|
|
121
|
+
lines.push("");
|
|
161
122
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
lines.push(
|
|
123
|
+
const steps = strList(hyp.recommended_next_steps);
|
|
124
|
+
if (steps.length) {
|
|
125
|
+
lines.push("**Recommended next steps:**");
|
|
126
|
+
for (const step of steps) lines.push(`1. ${step}`);
|
|
166
127
|
lines.push("");
|
|
167
|
-
const framing = str(impl.problem_framing);
|
|
168
|
-
if (framing) {
|
|
169
|
-
lines.push("**Problem framing:**");
|
|
170
|
-
lines.push("");
|
|
171
|
-
lines.push(framing);
|
|
172
|
-
lines.push("");
|
|
173
|
-
}
|
|
174
|
-
const rec = asRecord(impl.recommended_approach);
|
|
175
|
-
if (rec) {
|
|
176
|
-
const summary = str(rec.summary);
|
|
177
|
-
const conf = str(rec.recommended_approach_confidence);
|
|
178
|
-
if (summary) {
|
|
179
|
-
lines.push(
|
|
180
|
-
`**Recommended approach**${conf ? ` (${conf} confidence)` : ""}:`,
|
|
181
|
-
);
|
|
182
|
-
lines.push("");
|
|
183
|
-
lines.push(summary);
|
|
184
|
-
lines.push("");
|
|
185
|
-
}
|
|
186
|
-
const rationale = str(rec.confidence_rationale);
|
|
187
|
-
if (rationale) {
|
|
188
|
-
lines.push(`*Rationale:* ${rationale}`);
|
|
189
|
-
lines.push("");
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
const patterns = Array.isArray(impl.solution_patterns)
|
|
193
|
-
? impl.solution_patterns
|
|
194
|
-
: [];
|
|
195
|
-
if (patterns.length) {
|
|
196
|
-
lines.push("**Solution patterns:**");
|
|
197
|
-
for (const p of patterns) {
|
|
198
|
-
const pat = asRecord(p);
|
|
199
|
-
const name = pat ? str(pat.name) : null;
|
|
200
|
-
const fit = pat ? str(pat.fit) : null;
|
|
201
|
-
if (name) lines.push(`- **${name}**${fit ? `: ${fit}` : ""}`);
|
|
202
|
-
}
|
|
203
|
-
lines.push("");
|
|
204
|
-
}
|
|
205
|
-
const openQs = strList(impl.open_questions);
|
|
206
|
-
if (openQs.length) {
|
|
207
|
-
lines.push("**Open questions:**");
|
|
208
|
-
for (const q of openQs) lines.push(`- ${q}`);
|
|
209
|
-
lines.push("");
|
|
210
|
-
}
|
|
211
|
-
const anti = strList(impl.anti_patterns);
|
|
212
|
-
if (anti.length) {
|
|
213
|
-
lines.push("**Anti-patterns:**");
|
|
214
|
-
for (const a of anti) lines.push(`- ${a}`);
|
|
215
|
-
lines.push("");
|
|
216
|
-
}
|
|
217
128
|
}
|
|
129
|
+
}
|
|
218
130
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
const rationale = str(dim.rationale) ?? "";
|
|
236
|
-
lines.push(`| ${name} | ${score}/100 | ${rationale} |`);
|
|
237
|
-
}
|
|
131
|
+
function appendImplementationMarkdown(
|
|
132
|
+
lines: string[],
|
|
133
|
+
impl: Record<string, unknown>,
|
|
134
|
+
): void {
|
|
135
|
+
lines.push("## Phase 3.5 — Implementation research", "");
|
|
136
|
+
const framing = str(impl.problem_framing);
|
|
137
|
+
if (framing) lines.push("**Problem framing:**", "", framing, "");
|
|
138
|
+
const rec = asRecord(impl.recommended_approach);
|
|
139
|
+
if (rec) {
|
|
140
|
+
const summary = str(rec.summary);
|
|
141
|
+
const conf = str(rec.recommended_approach_confidence);
|
|
142
|
+
if (summary) {
|
|
143
|
+
lines.push(
|
|
144
|
+
`**Recommended approach**${conf ? ` (${conf} confidence)` : ""}:`,
|
|
145
|
+
);
|
|
146
|
+
lines.push("", summary, "");
|
|
238
147
|
}
|
|
239
|
-
const
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
148
|
+
const rationale = str(rec.confidence_rationale);
|
|
149
|
+
if (rationale) lines.push(`*Rationale:* ${rationale}`, "");
|
|
150
|
+
}
|
|
151
|
+
const patterns = Array.isArray(impl.solution_patterns)
|
|
152
|
+
? impl.solution_patterns
|
|
153
|
+
: [];
|
|
154
|
+
if (patterns.length) {
|
|
155
|
+
lines.push("**Solution patterns:**");
|
|
156
|
+
for (const p of patterns) {
|
|
157
|
+
const pat = asRecord(p);
|
|
158
|
+
const name = pat ? str(pat.name) : null;
|
|
159
|
+
const fit = pat ? str(pat.fit) : null;
|
|
160
|
+
if (name) lines.push(`- **${name}**${fit ? `: ${fit}` : ""}`);
|
|
244
161
|
}
|
|
245
162
|
lines.push("");
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
163
|
+
}
|
|
164
|
+
pushListSection(lines, "Open questions", strList(impl.open_questions));
|
|
165
|
+
pushListSection(lines, "Anti-patterns", strList(impl.anti_patterns));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function appendEvaluationMarkdown(
|
|
169
|
+
lines: string[],
|
|
170
|
+
evalBrief: Record<string, unknown>,
|
|
171
|
+
): void {
|
|
172
|
+
lines.push("## Self-evaluation", "");
|
|
173
|
+
lines.push("| Dimension | Score | Rationale |");
|
|
174
|
+
lines.push("|-----------|-------|-----------|");
|
|
175
|
+
const dims = asRecord(evalBrief.dimensions);
|
|
176
|
+
if (dims) {
|
|
177
|
+
for (const name of [
|
|
178
|
+
"novelty",
|
|
179
|
+
"coherence",
|
|
180
|
+
"testability",
|
|
181
|
+
"impact",
|
|
182
|
+
] as const) {
|
|
183
|
+
const dim = asRecord(dims[name]);
|
|
184
|
+
if (!dim) continue;
|
|
185
|
+
const score = typeof dim.score === "number" ? String(dim.score) : "?";
|
|
186
|
+
lines.push(`| ${name} | ${score}/100 | ${str(dim.rationale) ?? ""} |`);
|
|
250
187
|
}
|
|
251
188
|
}
|
|
189
|
+
const rel = asRecord(evalBrief.relevance);
|
|
190
|
+
if (rel) {
|
|
191
|
+
const passes = rel.passes === true ? "✓" : "✗";
|
|
192
|
+
lines.push(`| Relevance | ${passes} | ${str(rel.rationale) ?? ""} |`);
|
|
193
|
+
}
|
|
194
|
+
lines.push("");
|
|
195
|
+
const summary = str(evalBrief.human_summary);
|
|
196
|
+
if (summary) lines.push(summary, "");
|
|
197
|
+
}
|
|
252
198
|
|
|
199
|
+
/** Render Darwin research sections for plan-review.md. */
|
|
200
|
+
export function formatResearchBriefMarkdown(
|
|
201
|
+
research: PlanResearchBrief | null | undefined,
|
|
202
|
+
): string {
|
|
203
|
+
if (!research) return "";
|
|
204
|
+
const lines: string[] = [];
|
|
205
|
+
const sections = [
|
|
206
|
+
[asRecord(research.decomposition), appendDecompositionMarkdown],
|
|
207
|
+
[asRecord(research.hypothesis), appendHypothesisMarkdown],
|
|
208
|
+
[asRecord(research.implementation), appendImplementationMarkdown],
|
|
209
|
+
[asRecord(research.eval), appendEvaluationMarkdown],
|
|
210
|
+
] as const;
|
|
211
|
+
for (const [section, append] of sections) {
|
|
212
|
+
if (section) append(lines, section);
|
|
213
|
+
}
|
|
253
214
|
return lines.length ? `${lines.join("\n")}\n` : "";
|
|
254
215
|
}
|
|
255
216
|
|
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
ToolRenderResultOptions,
|
|
5
5
|
} from "@earendil-works/pi-coding-agent";
|
|
6
6
|
import { Text, truncateToWidth } from "@earendil-works/pi-tui";
|
|
7
|
-
import type { PlanPacketLike } from "
|
|
7
|
+
import type { PlanPacketLike } from "../harness-run-context.js";
|
|
8
8
|
import { formatPlanPacketLines } from "./format-plan.js";
|
|
9
9
|
import type { ApprovePlanToolDetails } from "./types.js";
|
|
10
10
|
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
RESEARCH_BRIEF_BASENAME,
|
|
8
8
|
readPlanPacketFromPath,
|
|
9
9
|
validatePlanPacket,
|
|
10
|
-
} from "
|
|
11
|
-
import { readYamlFile } from "
|
|
10
|
+
} from "../harness-run-context.js";
|
|
11
|
+
import { readYamlFile } from "../harness-yaml.js";
|
|
12
12
|
import type { ApprovePlanParams, PlanResearchBrief } from "./types.js";
|
|
13
13
|
|
|
14
14
|
function isNonEmptyPacket(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { PlanPacketLike } from "../../../lib/harness-run-context.js";
|
|
2
1
|
import type { AskResponse, DialogResult } from "../ask-user/types.js";
|
|
2
|
+
import type { PlanPacketLike } from "../harness-run-context.js";
|
|
3
3
|
|
|
4
4
|
export const DEFAULT_PLAN_APPROVAL_OPTIONS = [
|
|
5
5
|
"Approve",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import type { AskResponse } from "../ask-user/types.js";
|
|
2
|
+
import { formatResultText } from "../ask-user/validate.js";
|
|
1
3
|
import {
|
|
2
4
|
type PlanPacketLike,
|
|
3
5
|
validatePlanPacket,
|
|
4
|
-
} from "
|
|
5
|
-
import type { AskResponse } from "../ask-user/types.js";
|
|
6
|
-
import { formatResultText } from "../ask-user/validate.js";
|
|
6
|
+
} from "../harness-run-context.js";
|
|
7
7
|
import type {
|
|
8
8
|
ApprovePlanParams,
|
|
9
9
|
ApprovePlanToolDetails,
|