@hassangameryt/freeflow 0.7.3 → 0.9.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/plugins/marketplace.json +2 -2
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +3 -3
- package/.cursor-plugin/plugin.json +1 -1
- package/NOTICE +14 -0
- package/README.md +101 -159
- package/capabilities/cognitive-routing/SKILL.md +47 -210
- package/capabilities/cognitive-routing/references/coordinator.md +163 -0
- package/capabilities/cognitive-routing/references/worker.md +38 -0
- package/capabilities/compaction/SKILL.md +49 -0
- package/capabilities/compaction/references/summary-format.md +250 -0
- package/capabilities/messaging/SKILL.md +49 -0
- package/capabilities/task-memory/SKILL.md +87 -0
- package/command-surface.json +8 -52
- package/gemini-extension.json +1 -1
- package/hooks/claude/hooks.json +13 -3
- package/hooks/codex/hooks.json +2 -1
- package/hooks/shared/runtime-context.mjs +73 -83
- package/licenses/Apache-2.0.txt +55 -0
- package/package.json +42 -12
- package/pi-extension/README.md +41 -0
- package/pi-extension/dist/ask-user/ask.js +108 -0
- package/pi-extension/dist/ask-user/form.js +250 -0
- package/pi-extension/dist/ask-user/questions.js +66 -0
- package/pi-extension/dist/ask-user/tool.js +124 -0
- package/pi-extension/dist/cognitive-routing/assembler.js +417 -0
- package/pi-extension/dist/cognitive-routing/bootstrap.js +90 -0
- package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/config.js +8 -6
- package/pi-extension/dist/cognitive-routing/economics.js +45 -0
- package/pi-extension/dist/cognitive-routing/event-schema.js +388 -0
- package/pi-extension/dist/{session-sources/events.js → cognitive-routing/event-store.js} +107 -41
- package/pi-extension/dist/cognitive-routing/gate.js +256 -0
- package/pi-extension/dist/cognitive-routing/handlers.js +901 -0
- package/pi-extension/dist/cognitive-routing/handoffs.js +350 -0
- package/pi-extension/dist/cognitive-routing/model-control.js +476 -0
- package/pi-extension/dist/cognitive-routing/projection.js +520 -0
- package/pi-extension/dist/cognitive-routing/provenance.js +83 -0
- package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/render.js +15 -15
- package/pi-extension/dist/cognitive-routing/runtime.js +398 -0
- package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/schemas.js +47 -11
- package/pi-extension/dist/cognitive-routing/session.js +223 -0
- package/pi-extension/dist/{session-sources → cognitive-routing}/sources.js +126 -87
- package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/state.js +55 -386
- package/pi-extension/dist/cognitive-routing/status.js +81 -0
- package/pi-extension/dist/cognitive-routing/tools.js +74 -0
- package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/types.js +14 -11
- package/pi-extension/dist/compaction/carry.js +205 -0
- package/pi-extension/dist/compaction/config.js +24 -0
- package/pi-extension/dist/compaction/controller.js +494 -0
- package/pi-extension/dist/compaction/harness.js +93 -0
- package/pi-extension/dist/compaction/results.js +159 -0
- package/pi-extension/dist/compaction/thresholds.js +35 -0
- package/pi-extension/dist/compaction/tool.js +57 -0
- package/pi-extension/dist/host/branch.js +13 -0
- package/pi-extension/dist/host/canonical.js +12 -0
- package/pi-extension/dist/host/catalog.js +62 -0
- package/pi-extension/dist/host/config-validation.js +233 -0
- package/pi-extension/dist/host/config.js +361 -0
- package/pi-extension/dist/host/inbound.js +142 -0
- package/pi-extension/dist/host/projection-tags.js +60 -0
- package/pi-extension/dist/host/prompts.js +93 -0
- package/pi-extension/dist/{session-sources → host}/read-only-session.js +117 -1
- package/pi-extension/dist/{runtime → host}/request-history.js +125 -39
- package/pi-extension/dist/host/rows.js +25 -0
- package/pi-extension/dist/host/runtime-state.js +204 -0
- package/pi-extension/dist/host/section-keeper.js +85 -0
- package/pi-extension/dist/host/settings/freeflow-command.js +2323 -0
- package/pi-extension/dist/{settings/settings-tui.js → host/settings/settings-view.js} +205 -73
- package/pi-extension/dist/host/staging.js +28 -0
- package/pi-extension/dist/host/status.js +115 -0
- package/pi-extension/dist/index.js +1004 -188
- package/pi-extension/dist/messaging/config.js +27 -0
- package/pi-extension/dist/messaging/messaging.js +398 -0
- package/pi-extension/dist/messaging/registry.js +57 -0
- package/pi-extension/dist/messaging/render.js +90 -0
- package/pi-extension/dist/messaging/tools.js +109 -0
- package/pi-extension/dist/messaging/transport.js +101 -0
- package/pi-extension/dist/provider-support/cache/anchor.js +21 -0
- package/pi-extension/dist/provider-support/cache/anthropic.js +102 -0
- package/pi-extension/dist/provider-support/cache/health.js +73 -0
- package/pi-extension/dist/provider-support/cache/index.js +58 -0
- package/pi-extension/dist/provider-support/cache/keepalive.js +222 -0
- package/pi-extension/dist/provider-support/cache/monitor.js +17 -0
- package/pi-extension/dist/provider-support/cache/openai-responses.js +48 -0
- package/pi-extension/dist/provider-support/effort.js +13 -0
- package/pi-extension/dist/provider-support/index.js +44 -3
- package/pi-extension/dist/provider-support/{astra → openai}/adapter.js +46 -29
- package/pi-extension/dist/provider-support/{astra → openai}/history.js +10 -8
- package/pi-extension/dist/provider-support/{astra → openai}/index.js +8 -4
- package/pi-extension/dist/provider-support/{astra → openai}/session-state.js +29 -38
- package/pi-extension/dist/provider-support/routes.js +17 -0
- package/pi-extension/dist/task-memory/config.js +49 -0
- package/pi-extension/dist/task-memory/registry.js +119 -0
- package/pi-extension/dist/task-memory/render.js +107 -0
- package/pi-extension/dist/task-memory/runtime.js +994 -0
- package/pi-extension/dist/task-memory/tool.js +233 -0
- package/pi-extension/dist/tool-execution/apply-patch/grammar.js +23 -0
- package/pi-extension/dist/tool-execution/apply-patch/match.js +38 -0
- package/pi-extension/dist/tool-execution/apply-patch/parser.js +177 -0
- package/pi-extension/dist/tool-execution/apply-patch/plan.js +201 -0
- package/pi-extension/dist/tool-execution/apply-patch/tool.js +84 -0
- package/pi-extension/dist/tool-execution/background.js +430 -0
- package/pi-extension/dist/tool-execution/bash-guard.js +23 -0
- package/pi-extension/dist/tool-execution/config.js +33 -0
- package/pi-extension/dist/tool-execution/edit-messages.js +120 -0
- package/pi-extension/dist/tool-execution/file-state.js +138 -0
- package/pi-extension/dist/tool-execution/file-tracking.js +163 -0
- package/pi-extension/dist/tool-execution/guidance-notices.js +124 -0
- package/pi-extension/dist/tool-execution/prompt.js +54 -0
- package/pi-extension/dist/tool-execution/skill-reads.js +143 -0
- package/pi-extension/dist/tool-execution/tools.js +16 -0
- package/pi-extension/freeflow/README.md +9 -0
- package/runtime/prompts/cognitive-routing.md +4 -4
- package/runtime/prompts/core.md +29 -72
- package/runtime/prompts/interaction-contract.md +18 -8
- package/runtime/prompts/tool-execution.md +25 -0
- package/runtime/prompts/working-method.md +25 -0
- package/skills/deliver-work/SKILL.md +76 -0
- package/skills/deliver-work/references/branch-closeout.md +134 -0
- package/skills/deliver-work/references/commit.md +83 -0
- package/skills/deliver-work/references/launch.md +94 -0
- package/skills/deliver-work/references/release.md +85 -0
- package/skills/deliver-work/scripts/commit-state.mjs +139 -0
- package/skills/deliver-work/scripts/delivery-state.mjs +107 -0
- package/skills/deliver-work/scripts/lib/git-state.mjs +178 -0
- package/skills/deliver-work/scripts/push-route.mjs +122 -0
- package/skills/deliver-work/scripts/release-preflight.mjs +177 -0
- package/skills/discuss-work/SKILL.md +148 -0
- package/skills/{discuss → discuss-work}/references/discussion-continuity.md +13 -50
- package/skills/discuss-work/references/learning-action.md +36 -0
- package/skills/discuss-work/scripts/choices.mjs +101 -0
- package/skills/discuss-work/scripts/lib/choices.mjs +159 -0
- package/skills/evaluate-behavior/SKILL.md +107 -0
- package/skills/evaluate-behavior/references/authoring.md +381 -0
- package/skills/evaluate-behavior/references/coding-tasks.md +145 -0
- package/skills/evaluate-behavior/references/conversations-pipelines-judges.md +177 -0
- package/skills/evaluate-behavior/references/design-and-measurement.md +273 -0
- package/skills/evaluate-behavior/references/running-and-evidence.md +245 -0
- package/skills/evaluate-behavior/scripts/claude-guard.mjs +76 -0
- package/skills/evaluate-behavior/scripts/guard-rules.mjs +309 -0
- package/skills/evaluate-behavior/scripts/lib/agreement.mjs +90 -0
- package/skills/evaluate-behavior/scripts/lib/arms.mjs +55 -0
- package/skills/evaluate-behavior/scripts/lib/budget.mjs +87 -0
- package/skills/evaluate-behavior/scripts/lib/build-source.mjs +287 -0
- package/skills/evaluate-behavior/scripts/lib/clear.mjs +74 -0
- package/skills/evaluate-behavior/scripts/lib/container.mjs +395 -0
- package/skills/evaluate-behavior/scripts/lib/decision.mjs +418 -0
- package/skills/evaluate-behavior/scripts/lib/definitions.mjs +1072 -0
- package/skills/evaluate-behavior/scripts/lib/freeflow.mjs +103 -0
- package/skills/evaluate-behavior/scripts/lib/grade-command.mjs +591 -0
- package/skills/evaluate-behavior/scripts/lib/grade-comparison.mjs +90 -0
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-interaction.mjs +19 -18
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-support.mjs +32 -5
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/grade-workspace.mjs +28 -12
- package/skills/evaluate-behavior/scripts/lib/grade.mjs +101 -0
- package/skills/evaluate-behavior/scripts/lib/hooks.mjs +98 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/confinement.mjs +196 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/constraints.mjs +111 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/index.mjs +48 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/isolation.mjs +74 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/launch.mjs +123 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/model-call.mjs +73 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/recorder.mjs +178 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/session.mjs +494 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/claude-code/skills.mjs +81 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/index.mjs +31 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/names.mjs +3 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/confinement.mjs +173 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/host.mjs +148 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/index.mjs +70 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/isolation.mjs +81 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/model-call.mjs +79 -0
- package/skills/evaluate-behavior/scripts/lib/hosts/pi/process.mjs +241 -0
- package/skills/{evaluate-skill/scripts/lib → evaluate-behavior/scripts/lib/hosts/pi}/rpc.mjs +144 -26
- package/skills/evaluate-behavior/scripts/lib/identity.mjs +82 -0
- package/skills/evaluate-behavior/scripts/lib/judge.mjs +688 -0
- package/skills/evaluate-behavior/scripts/lib/metrics.mjs +332 -0
- package/skills/evaluate-behavior/scripts/lib/model-call.mjs +17 -0
- package/skills/evaluate-behavior/scripts/lib/participants.mjs +616 -0
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/process.mjs +22 -0
- package/skills/evaluate-behavior/scripts/lib/queue.mjs +54 -0
- package/skills/evaluate-behavior/scripts/lib/reference.mjs +343 -0
- package/skills/evaluate-behavior/scripts/lib/reuse.mjs +277 -0
- package/skills/evaluate-behavior/scripts/lib/review.mjs +933 -0
- package/skills/evaluate-behavior/scripts/lib/runner.mjs +732 -0
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/sandbox.mjs +121 -14
- package/skills/evaluate-behavior/scripts/lib/scan-shell.mjs +457 -0
- package/skills/evaluate-behavior/scripts/lib/scan.mjs +479 -0
- package/skills/evaluate-behavior/scripts/lib/seal.mjs +91 -0
- package/skills/evaluate-behavior/scripts/lib/shell.mjs +560 -0
- package/skills/evaluate-behavior/scripts/lib/source-override.mjs +64 -0
- package/skills/evaluate-behavior/scripts/lib/subject-file.mjs +88 -0
- package/skills/{evaluate-skill/scripts/lib/pi.mjs → evaluate-behavior/scripts/lib/subject.mjs} +239 -262
- package/skills/evaluate-behavior/scripts/lib/task-copy.mjs +124 -0
- package/skills/evaluate-behavior/scripts/lib/trials.mjs +524 -0
- package/skills/evaluate-behavior/scripts/lib/validity.mjs +68 -0
- package/skills/evaluate-behavior/scripts/lib/view-html.mjs +454 -0
- package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/view.mjs +218 -11
- package/skills/evaluate-behavior/scripts/pi-command-tool.mjs +159 -0
- package/skills/evaluate-behavior/scripts/pi-container-route.mjs +23 -0
- package/skills/evaluate-behavior/scripts/pi-guard.mjs +77 -0
- package/skills/evaluate-behavior/scripts/pi-login-refresh.mjs +31 -0
- package/skills/evaluate-behavior/scripts/skill-eval.mjs +586 -0
- package/skills/execute-work/SKILL.md +96 -72
- package/skills/execute-work/references/code-practices.md +27 -49
- package/skills/execute-work/references/design.md +271 -0
- package/skills/execute-work/references/diagnose.md +117 -0
- package/skills/execute-work/references/migration.md +108 -0
- package/skills/execute-work/references/simplify.md +65 -0
- package/skills/execute-work/scripts/self-review.mjs +422 -0
- package/skills/execute-work/scripts/touch-map.mjs +290 -0
- package/skills/review-work/SKILL.md +94 -64
- package/skills/review-work/references/adjudication.md +94 -0
- package/skills/review-work/references/artifact.md +198 -0
- package/skills/review-work/references/evals-and-judges.md +66 -0
- package/skills/review-work/references/work.md +177 -0
- package/skills/review-work/scripts/check-brief.mjs +128 -0
- package/skills/review-work/scripts/review-packet.mjs +233 -0
- package/skills/setup-freeflow/SKILL.md +69 -16
- package/skills/track-work/SKILL.md +135 -151
- package/skills/track-work/references/handoff.md +190 -0
- package/skills/track-work/references/projects.md +51 -0
- package/skills/track-work/references/working-record-format.md +201 -344
- package/skills/track-work/scripts/lib/document.mjs +79 -19
- package/skills/track-work/scripts/lib/format.mjs +18 -1
- package/skills/track-work/scripts/lib/recover.mjs +254 -0
- package/skills/track-work/scripts/lib/registry.mjs +656 -0
- package/skills/track-work/scripts/lib/search.mjs +40 -0
- package/skills/track-work/scripts/lib/store.mjs +53 -21
- package/skills/track-work/scripts/lib/transitions.mjs +79 -4
- package/skills/track-work/scripts/lib/views.mjs +50 -1
- package/skills/track-work/scripts/working-record.mjs +263 -22
- package/skills/verify-work/SKILL.md +64 -47
- package/skills/verify-work/references/feature-map.md +120 -0
- package/skills/verify-work/references/runtime-evidence.md +203 -0
- package/skills/verify-work/references/test-design.md +27 -6
- package/skills/verify-work/scripts/test-changes.mjs +246 -0
- package/skills/write-docs/SKILL.md +171 -0
- package/skills/write-docs/references/documentation-shapes.md +184 -0
- package/skills/write-docs/references/spec-and-plan-shapes.md +308 -0
- package/skills/write-docs/scripts/artifact-check.mjs +148 -0
- package/skills/write-docs/scripts/docs-check.mjs +229 -0
- package/skills/write-docs/scripts/plan-lint.mjs +123 -0
- package/skills/write-skill/SKILL.md +165 -165
- package/skills/write-skill/references/activation-and-wording.md +143 -0
- package/skills/write-skill/references/placement-and-dependencies.md +154 -0
- package/skills/write-skill/scripts/lib/compare.mjs +701 -0
- package/skills/write-skill/scripts/lib/similarity.mjs +56 -0
- package/skills/write-skill/scripts/lib/skill-author.mjs +197 -3
- package/skills/write-skill/scripts/skill-author.mjs +67 -8
- package/capabilities/context-virtualization/SKILL.md +0 -103
- package/capabilities/conversation-history/SKILL.md +0 -53
- package/hooks/tests/check-host-adapters.test.mjs +0 -82
- package/hooks/tests/check-runtime-context-hook.sh +0 -212
- package/pi-extension/dist/cognitive-routing-v2/projection.js +0 -330
- package/pi-extension/dist/cognitive-routing-v2/runtime.js +0 -2181
- package/pi-extension/dist/cognitive-routing-v2/tools.js +0 -60
- package/pi-extension/dist/context-virtualization/commands.js +0 -89
- package/pi-extension/dist/context-virtualization/projector.js +0 -42
- package/pi-extension/dist/context-virtualization/runtime.js +0 -378
- package/pi-extension/dist/context-virtualization/state.js +0 -57
- package/pi-extension/dist/context-virtualization/types.js +0 -10
- package/pi-extension/dist/conversation-history/passages.js +0 -66
- package/pi-extension/dist/conversation-history/ranking.js +0 -105
- package/pi-extension/dist/conversation-history/runtime.js +0 -226
- package/pi-extension/dist/conversation-history/search.js +0 -56
- package/pi-extension/dist/conversation-history/types.js +0 -1
- package/pi-extension/dist/freeflow-context/resolver.js +0 -120
- package/pi-extension/dist/freeflow-context/runtime.js +0 -80
- package/pi-extension/dist/freeflow-context/source-projector.js +0 -95
- package/pi-extension/dist/freeflow-context/tool.js +0 -314
- package/pi-extension/dist/freeflow-context/types.js +0 -12
- package/pi-extension/dist/freeflow-context/visibility.js +0 -28
- package/pi-extension/dist/integrations/mcp-config.js +0 -29
- package/pi-extension/dist/runtime/runtime-context.js +0 -754
- package/pi-extension/dist/runtime/runtime-identity.js +0 -5
- package/pi-extension/dist/session-sources/provenance.js +0 -32
- package/pi-extension/dist/settings/settings-ui.js +0 -1360
- package/pi-extension/dist/ui/text-component.js +0 -57
- package/pi-extension/src/cognitive-routing-v2/budget.ts +0 -42
- package/pi-extension/src/cognitive-routing-v2/config.ts +0 -173
- package/pi-extension/src/cognitive-routing-v2/projection.ts +0 -375
- package/pi-extension/src/cognitive-routing-v2/render.ts +0 -277
- package/pi-extension/src/cognitive-routing-v2/runtime.ts +0 -2241
- package/pi-extension/src/cognitive-routing-v2/schemas.ts +0 -180
- package/pi-extension/src/cognitive-routing-v2/state.ts +0 -839
- package/pi-extension/src/cognitive-routing-v2/tools.ts +0 -62
- package/pi-extension/src/cognitive-routing-v2/types.ts +0 -254
- package/pi-extension/src/context-virtualization/commands.ts +0 -111
- package/pi-extension/src/context-virtualization/projector.ts +0 -62
- package/pi-extension/src/context-virtualization/runtime.ts +0 -428
- package/pi-extension/src/context-virtualization/state.ts +0 -79
- package/pi-extension/src/context-virtualization/types.ts +0 -92
- package/pi-extension/src/conversation-history/passages.ts +0 -81
- package/pi-extension/src/conversation-history/ranking.ts +0 -155
- package/pi-extension/src/conversation-history/runtime.ts +0 -250
- package/pi-extension/src/conversation-history/search.ts +0 -79
- package/pi-extension/src/conversation-history/types.ts +0 -31
- package/pi-extension/src/freeflow-context/resolver.ts +0 -139
- package/pi-extension/src/freeflow-context/runtime.ts +0 -100
- package/pi-extension/src/freeflow-context/source-projector.ts +0 -106
- package/pi-extension/src/freeflow-context/tool.ts +0 -366
- package/pi-extension/src/freeflow-context/types.ts +0 -70
- package/pi-extension/src/freeflow-context/visibility.ts +0 -53
- package/pi-extension/src/index.ts +0 -390
- package/pi-extension/src/integrations/mcp-config.ts +0 -32
- package/pi-extension/src/provider-support/astra/adapter.ts +0 -108
- package/pi-extension/src/provider-support/astra/history.ts +0 -145
- package/pi-extension/src/provider-support/astra/index.ts +0 -12
- package/pi-extension/src/provider-support/astra/session-state.ts +0 -113
- package/pi-extension/src/provider-support/index.ts +0 -5
- package/pi-extension/src/runtime/request-history.ts +0 -243
- package/pi-extension/src/runtime/runtime-context.ts +0 -860
- package/pi-extension/src/runtime/runtime-identity.ts +0 -8
- package/pi-extension/src/session-sources/events.ts +0 -230
- package/pi-extension/src/session-sources/provenance.ts +0 -39
- package/pi-extension/src/session-sources/read-only-session.ts +0 -170
- package/pi-extension/src/session-sources/sources.ts +0 -334
- package/pi-extension/src/settings/settings-tui.ts +0 -501
- package/pi-extension/src/settings/settings-ui.ts +0 -1652
- package/pi-extension/src/ui/text-component.ts +0 -66
- package/pi-extension/tests/cache-reuse/history.test.js +0 -117
- package/pi-extension/tests/cache-reuse/native.test.js +0 -91
- package/pi-extension/tests/cache-reuse/settings.test.js +0 -211
- package/pi-extension/tests/cognitive-routing-v2/communication.test.js +0 -577
- package/pi-extension/tests/cognitive-routing-v2/compaction-input.test.js +0 -183
- package/pi-extension/tests/cognitive-routing-v2/delegation.test.js +0 -557
- package/pi-extension/tests/cognitive-routing-v2/native.test.js +0 -474
- package/pi-extension/tests/cognitive-routing-v2/performance.test.js +0 -87
- package/pi-extension/tests/cognitive-routing-v2/persistence.test.js +0 -300
- package/pi-extension/tests/cognitive-routing-v2/projection.test.js +0 -241
- package/pi-extension/tests/cognitive-routing-v2/recovery.test.js +0 -1034
- package/pi-extension/tests/cognitive-routing-v2/render.test.js +0 -244
- package/pi-extension/tests/cognitive-routing-v2/runtime.test.js +0 -423
- package/pi-extension/tests/cognitive-routing-v2/stabilization.test.js +0 -521
- package/pi-extension/tests/cognitive-routing-v2/state.test.js +0 -586
- package/pi-extension/tests/context-virtualization/extension.test.js +0 -775
- package/pi-extension/tests/context-virtualization/projector.test.js +0 -110
- package/pi-extension/tests/context-virtualization/runtime.test.js +0 -230
- package/pi-extension/tests/conversation-history/runtime.test.js +0 -98
- package/pi-extension/tests/conversation-history/search.test.js +0 -97
- package/pi-extension/tests/fixtures/pi-host.js +0 -4
- package/pi-extension/tests/fixtures/routing-native.js +0 -191
- package/pi-extension/tests/integration/mode-free-core.test.js +0 -220
- package/pi-extension/tests/integration/pi-extension.test.js +0 -1447
- package/pi-extension/tests/integration/prompt-architecture.test.js +0 -447
- package/pi-extension/tests/integration/unaffected-regressions.test.js +0 -478
- package/pi-extension/tests/provider-support/astra-boundaries.test.js +0 -75
- package/pi-extension/tests/provider-support/astra.test.js +0 -306
- package/pi-extension/tests/provider-support/cli.test.js +0 -92
- package/pi-extension/tests/provider-support/native.test.js +0 -183
- package/pi-extension/tests/settings/settings-tui.test.js +0 -243
- package/pi-extension/tsconfig.json +0 -16
- package/plugin.json +0 -33
- package/runtime/prompts/context-virtualization.md +0 -3
- package/runtime/prompts/conversation-history.md +0 -3
- package/skills/action-selection/SKILL.md +0 -100
- package/skills/action-selection/references/trajectory-stalls.md +0 -71
- package/skills/bypass/SKILL.md +0 -153
- package/skills/commit-work/SKILL.md +0 -145
- package/skills/commit-work/references/git-state-edges.md +0 -94
- package/skills/commit-work/references/simple-push.md +0 -92
- package/skills/commit-work/references/staging-decisions.md +0 -106
- package/skills/decision-gate/SKILL.md +0 -106
- package/skills/design-for-depth/SKILL.md +0 -117
- package/skills/design-for-depth/references/design-pressure-signals.md +0 -182
- package/skills/design-for-depth/references/implementation-decisions.md +0 -76
- package/skills/design-for-depth/references/interface-design-loop.md +0 -136
- package/skills/design-for-depth/references/module-and-dependency-design.md +0 -147
- package/skills/design-for-depth/references/software-design-philosophy.md +0 -202
- package/skills/design-for-depth/references/state-and-failure-boundaries.md +0 -136
- package/skills/diagnose-failure/SKILL.md +0 -125
- package/skills/diagnose-failure/references/diagnostic-loop-catalog.md +0 -48
- package/skills/diagnose-failure/references/flaky-and-performance-diagnosis.md +0 -51
- package/skills/discuss/SKILL.md +0 -116
- package/skills/evaluate-skill/SKILL.md +0 -219
- package/skills/evaluate-skill/references/evaluation-definition-schema.md +0 -385
- package/skills/evaluate-skill/references/evaluation-design.md +0 -112
- package/skills/evaluate-skill/references/execution-and-evidence.md +0 -90
- package/skills/evaluate-skill/references/review-and-revision.md +0 -92
- package/skills/evaluate-skill/scripts/lib/definitions.mjs +0 -407
- package/skills/evaluate-skill/scripts/lib/grade-comparison.mjs +0 -60
- package/skills/evaluate-skill/scripts/lib/grade.mjs +0 -64
- package/skills/evaluate-skill/scripts/lib/runner.mjs +0 -368
- package/skills/evaluate-skill/scripts/pi-guard.mjs +0 -164
- package/skills/evaluate-skill/scripts/skill-eval.mjs +0 -102
- package/skills/execute-work/references/execute-work-edges.md +0 -68
- package/skills/finish-branch/SKILL.md +0 -117
- package/skills/finish-branch/references/integration-options.md +0 -80
- package/skills/handoff/SKILL.md +0 -82
- package/skills/handoff/references/handoff-templates.md +0 -150
- package/skills/launch-work/SKILL.md +0 -116
- package/skills/launch-work/references/launch-readiness.md +0 -85
- package/skills/migration-work/SKILL.md +0 -115
- package/skills/migration-work/references/migration-lifecycle.md +0 -82
- package/skills/release-work/SKILL.md +0 -118
- package/skills/release-work/references/release-evidence.md +0 -78
- package/skills/review-artifact/SKILL.md +0 -142
- package/skills/review-artifact/references/adjudicate-artifact-review.md +0 -101
- package/skills/review-artifact/references/independent-artifact-reviewer-contract.md +0 -159
- package/skills/review-work/references/adjudicate-work-review.md +0 -97
- package/skills/review-work/references/independent-work-reviewer-contract.md +0 -139
- package/skills/review-work/references/security-risk-lens.md +0 -69
- package/skills/setup-freeflow/references/activation-contract.md +0 -109
- package/skills/setup-freeflow/references/host-setup.md +0 -67
- package/skills/simplify-code/SKILL.md +0 -85
- package/skills/simplify-code/references/simplification-patterns.md +0 -70
- package/skills/verify-work/references/browser-runtime-evidence.md +0 -55
- package/skills/verify-work/references/integration-evidence.md +0 -47
- package/skills/verify-work/references/performance-evidence.md +0 -57
- package/skills/workflow/SKILL.md +0 -127
- package/skills/workflow/references/domain-skill-composition.md +0 -43
- package/skills/write-plan/SKILL.md +0 -92
- package/skills/write-plan/references/plan-shapes.md +0 -156
- package/skills/write-skill/references/activation-boundaries.md +0 -104
- package/skills/write-skill/references/agent-first-instructions.md +0 -121
- package/skills/write-skill/references/progressive-disclosure.md +0 -127
- package/skills/write-skill/references/skill-dependency-graphs.md +0 -190
- package/skills/write-spec/SKILL.md +0 -92
- package/skills/write-spec/references/artifact-standards.md +0 -86
- package/skills/write-spec/references/decision-records.md +0 -78
- package/skills/write-spec/references/spec-shapes.md +0 -143
- /package/pi-extension/dist/{cognitive-routing-v2 → cognitive-routing}/budget.js +0 -0
- /package/skills/{evaluate-skill → evaluate-behavior}/scripts/lib/evidence.mjs +0 -0
- /package/skills/{evaluate-skill → evaluate-behavior}/scripts/pi-observer.mjs +0 -0
package/skills/{evaluate-skill/scripts/lib/pi.mjs → evaluate-behavior/scripts/lib/subject.mjs}
RENAMED
|
@@ -1,23 +1,15 @@
|
|
|
1
|
+
// One subject: the host-neutral part of running an arm's agent. It materializes the declared environment, fixture,
|
|
2
|
+
// runtime and Freeflow settings, asks the arm's host adapter (hosts/) to launch the agent, and turns what the host
|
|
3
|
+
// observed into the arm's run record. Everything that depends on the host program lives in its adapter.
|
|
4
|
+
|
|
1
5
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { spawn } from "node:child_process";
|
|
3
|
-
import { once } from "node:events";
|
|
4
|
-
import { createWriteStream } from "node:fs";
|
|
5
6
|
import { mkdir, readFile, realpath } from "node:fs/promises";
|
|
6
7
|
import path from "node:path";
|
|
7
|
-
import { fileURLToPath } from "node:url";
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
pipeStream,
|
|
14
|
-
processGroupExists,
|
|
15
|
-
signalProcessTree,
|
|
16
|
-
TERMINATION_GRACE_MS,
|
|
17
|
-
waitForForcedKill,
|
|
18
|
-
writeStream,
|
|
19
|
-
} from "./process.mjs";
|
|
20
|
-
import { runRpcBodySession, runRpcDescriptionSession } from "./rpc.mjs";
|
|
9
|
+
import { baseProcessEnvironment } from "./process.mjs";
|
|
10
|
+
import { writeFreeflowSettings } from "./freeflow.mjs";
|
|
11
|
+
import { runMetrics } from "./hooks.mjs";
|
|
12
|
+
import { hostAdapter } from "./hosts/index.mjs";
|
|
21
13
|
import {
|
|
22
14
|
fingerprintDirectory,
|
|
23
15
|
materializeEnvironment,
|
|
@@ -26,29 +18,17 @@ import {
|
|
|
26
18
|
snapshotWorkspace,
|
|
27
19
|
verifyEnvironment,
|
|
28
20
|
verifyRuntime,
|
|
21
|
+
WORKSPACE,
|
|
29
22
|
workspaceChanges,
|
|
30
23
|
} from "./sandbox.mjs";
|
|
31
24
|
|
|
32
|
-
const guardExtension = fileURLToPath(new URL("../pi-guard.mjs", import.meta.url));
|
|
33
|
-
const observerExtension = fileURLToPath(new URL("../pi-observer.mjs", import.meta.url));
|
|
34
|
-
const HOST_COMMANDS = { pi: "pi", piflow: "piflow" };
|
|
35
|
-
const BASE_PROCESS_ENVIRONMENT_KEYS = [
|
|
36
|
-
"PATH",
|
|
37
|
-
"HOME",
|
|
38
|
-
"TMPDIR",
|
|
39
|
-
"TMP",
|
|
40
|
-
"TEMP",
|
|
41
|
-
"LANG",
|
|
42
|
-
"LC_ALL",
|
|
43
|
-
"XDG_CONFIG_HOME",
|
|
44
|
-
"XDG_DATA_HOME",
|
|
45
|
-
"XDG_CACHE_HOME",
|
|
46
|
-
"PIFLOW_CODING_AGENT_DIR",
|
|
47
|
-
"PIFLOW_CODING_AGENT_SESSION_DIR",
|
|
48
|
-
"PI_PACKAGE_DIR",
|
|
49
|
-
"PI_OFFLINE",
|
|
50
|
-
];
|
|
51
25
|
const TURN_WORKSPACE_KINDS = new Set(["path", "changed-paths", "file-text", "json"]);
|
|
26
|
+
// Tools whose commands run in the subject's container when it has one: bash, and Freeflow's background commands.
|
|
27
|
+
const CONTAINER_SHELL_TOOLS = new Set(["bash", "bash_background", "monitor"]);
|
|
28
|
+
// Freeflow's background commands save their output under the subject's temp directory and name that file to the
|
|
29
|
+
// model, which reads it with read or from bash; with them declared, that directory is readable (and, in a container,
|
|
30
|
+
// mounted read-only at its own path).
|
|
31
|
+
const BACKGROUND_TOOLS = new Set(["bash_background", "monitor"]);
|
|
52
32
|
|
|
53
33
|
export class VariantSetupError extends Error {
|
|
54
34
|
constructor(message) {
|
|
@@ -57,39 +37,91 @@ export class VariantSetupError extends Error {
|
|
|
57
37
|
}
|
|
58
38
|
}
|
|
59
39
|
|
|
60
|
-
export async function runDescription({
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
40
|
+
export async function runDescription({
|
|
41
|
+
group,
|
|
42
|
+
variant,
|
|
43
|
+
root,
|
|
44
|
+
variantDirectory,
|
|
45
|
+
fixture,
|
|
46
|
+
runtime,
|
|
47
|
+
freeflow,
|
|
48
|
+
hostExtensions,
|
|
49
|
+
signal,
|
|
50
|
+
extendEnvironment = null,
|
|
51
|
+
}) {
|
|
52
|
+
const options = { group, variant, root, variantDirectory, fixture, runtime, freeflow, hostExtensions, signal };
|
|
53
|
+
options.extendEnvironment = extendEnvironment;
|
|
54
|
+
if (group.input.turns !== undefined) return runPersistentDescription(options);
|
|
55
|
+
return runOneShotDescription(options);
|
|
65
56
|
}
|
|
66
57
|
|
|
67
|
-
export async function runBody({
|
|
68
|
-
|
|
58
|
+
export async function runBody({
|
|
59
|
+
group,
|
|
60
|
+
variant,
|
|
61
|
+
root,
|
|
62
|
+
variantDirectory,
|
|
63
|
+
fixture,
|
|
64
|
+
runtime,
|
|
65
|
+
freeflow,
|
|
66
|
+
hostExtensions,
|
|
67
|
+
signal,
|
|
68
|
+
extendEnvironment = null,
|
|
69
|
+
nextPrompt = null,
|
|
70
|
+
}) {
|
|
71
|
+
const options = { group, variant, root, variantDirectory, fixture, runtime, freeflow, hostExtensions, signal };
|
|
72
|
+
options.extendEnvironment = extendEnvironment;
|
|
69
73
|
const subject = await prepareSubject(options, "rpc");
|
|
70
|
-
const before = await fingerprintDirectory(subject.workspace);
|
|
74
|
+
const before = await fingerprintDirectory(subject.workspace, WORKSPACE);
|
|
71
75
|
const declaredPrompts = group.input.prompt === undefined ? [...group.input.turns] : [group.input.prompt];
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
:
|
|
85
|
-
|
|
76
|
+
// A container environment runs the subject's bash and declared commands in a container of its own, removed even
|
|
77
|
+
// when the run is cancelled. A group with neither needs no subject container; its graders still run in the image.
|
|
78
|
+
const usesContainer =
|
|
79
|
+
group.tools.some((tool) => CONTAINER_SHELL_TOOLS.has(tool)) || (group.commands?.length ?? 0) > 0;
|
|
80
|
+
const declaredContainer = usesContainer ? group.variants[variant].shell?.container : undefined;
|
|
81
|
+
let container = null;
|
|
82
|
+
if (declaredContainer !== undefined) {
|
|
83
|
+
const { containerTarget, startContainer } = await import("./container.mjs");
|
|
84
|
+
// The subject's declared resources are mounted read-only at the paths it was given, so its bash can run a
|
|
85
|
+
// skill's scripts; the workspace is the only writable mount.
|
|
86
|
+
container = await startContainer({
|
|
87
|
+
container: declaredContainer,
|
|
88
|
+
workspace: subject.workspace,
|
|
89
|
+
resources: subject.resourceRoots,
|
|
90
|
+
});
|
|
91
|
+
subject.processEnvironment.SKILL_EVAL_CONTAINER = containerTarget(container);
|
|
92
|
+
}
|
|
93
|
+
let observation;
|
|
94
|
+
try {
|
|
95
|
+
observation = await subject.adapter.runSession({
|
|
96
|
+
subject,
|
|
97
|
+
command: subject.host.command,
|
|
98
|
+
settings: subject.isolation.settings,
|
|
99
|
+
args: subject.args,
|
|
100
|
+
cwd: subject.workspace,
|
|
101
|
+
eventsFile: subject.eventsFile,
|
|
102
|
+
stderrFile: subject.stderrFile,
|
|
103
|
+
signal,
|
|
104
|
+
prompts: declaredPrompts,
|
|
105
|
+
resumeBefore: group.input.resume_before ?? [],
|
|
106
|
+
targetPath: subject.environment.targetPath,
|
|
107
|
+
environment: subject.processEnvironment,
|
|
108
|
+
nextPrompt,
|
|
109
|
+
afterTurn: needsTurnWorkspaceEvidence(group)
|
|
110
|
+
? (turn) => snapshotWorkspace({ workspace: subject.workspace, variantDirectory, turn, before })
|
|
111
|
+
: null,
|
|
112
|
+
});
|
|
113
|
+
} finally {
|
|
114
|
+
await container?.remove();
|
|
115
|
+
}
|
|
86
116
|
const contextObservation = await readContextObservations(
|
|
87
117
|
subject.contextObservationPath,
|
|
88
118
|
subject.requiresContextObservation,
|
|
89
119
|
);
|
|
90
120
|
observation.contextObservationArtifact = contextObservation.artifact;
|
|
121
|
+
if (contextObservation.error) (observation.protocolErrors ??= []).push(contextObservation.error);
|
|
91
122
|
await verifySubjectResources(subject, observation);
|
|
92
|
-
|
|
123
|
+
// Links the subject made are recorded with their targets, never followed, so an installer's link cannot lose the run.
|
|
124
|
+
const after = await fingerprintDirectory(subject.workspace, WORKSPACE);
|
|
93
125
|
|
|
94
126
|
const turns = [];
|
|
95
127
|
for (const [index, turn] of observation.turns.entries()) {
|
|
@@ -106,6 +138,9 @@ export async function runBody({ group, variant, root, variantDirectory, fixture,
|
|
|
106
138
|
assistantError: turn.assistantError,
|
|
107
139
|
settled: turn.settled,
|
|
108
140
|
workspace: turn.workspace ?? null,
|
|
141
|
+
...(turn.resumed ? { resumed: turn.resumed } : {}),
|
|
142
|
+
// Runs Pi started on its own after this turn's prompt (an extension's notice), whose activity is part of it.
|
|
143
|
+
...(turn.unpromptedRuns ? { unpromptedRuns: turn.unpromptedRuns } : {}),
|
|
109
144
|
});
|
|
110
145
|
}
|
|
111
146
|
|
|
@@ -142,7 +177,7 @@ function bodyRun(options, subject, observation, input, effects) {
|
|
|
142
177
|
}
|
|
143
178
|
|
|
144
179
|
function subjectRun({ group, variant }, subject, observation) {
|
|
145
|
-
|
|
180
|
+
const run = {
|
|
146
181
|
schema_version: 1,
|
|
147
182
|
variant,
|
|
148
183
|
state: subjectRunState(observation),
|
|
@@ -150,8 +185,9 @@ function subjectRun({ group, variant }, subject, observation) {
|
|
|
150
185
|
completedAt: new Date().toISOString(),
|
|
151
186
|
workspace: subject.workspace,
|
|
152
187
|
tools: [...group.tools],
|
|
188
|
+
commands: group.commands ?? [],
|
|
153
189
|
model: {
|
|
154
|
-
declared: group.model ?? null,
|
|
190
|
+
declared: group.variants[variant].model ?? null,
|
|
155
191
|
observed: observation.model,
|
|
156
192
|
},
|
|
157
193
|
resources: {
|
|
@@ -160,9 +196,14 @@ function subjectRun({ group, variant }, subject, observation) {
|
|
|
160
196
|
skills: subject.environment.skills,
|
|
161
197
|
context: subject.environment.context,
|
|
162
198
|
runtime: subject.runtime,
|
|
199
|
+
freeflow: subject.freeflow,
|
|
200
|
+
hostExtensions: subject.hostExtensions,
|
|
163
201
|
contextDelivery: subject.environment.contextDelivery,
|
|
164
202
|
targetPath: subject.environment.targetPath,
|
|
203
|
+
// Everything the subject's tools could read: the workspace first, then its declared resources.
|
|
204
|
+
readableRoots: [subject.workspaceRoot, ...subject.resourceRoots],
|
|
165
205
|
},
|
|
206
|
+
isolation: subject.isolation,
|
|
166
207
|
contextObservationArtifact: observation.contextObservationArtifact ?? null,
|
|
167
208
|
response: observation.response,
|
|
168
209
|
transcript: observation.transcript,
|
|
@@ -181,17 +222,24 @@ function subjectRun({ group, variant }, subject, observation) {
|
|
|
181
222
|
stderr: subject.stderrFile,
|
|
182
223
|
},
|
|
183
224
|
};
|
|
225
|
+
// Run-metrics hooks derive their fields from what this run already recorded.
|
|
226
|
+
const metrics = runMetrics({ group, arm: variant, subject, observation, run });
|
|
227
|
+
if (metrics !== null) run.metrics = metrics;
|
|
228
|
+
return run;
|
|
184
229
|
}
|
|
185
230
|
|
|
186
231
|
async function runOneShotDescription(options) {
|
|
187
232
|
const subject = await prepareSubject(options, "json");
|
|
188
|
-
const observation = await
|
|
233
|
+
const observation = await subject.adapter.runOneShot({
|
|
234
|
+
subject,
|
|
189
235
|
command: subject.host.command,
|
|
190
236
|
args: subject.args,
|
|
191
237
|
cwd: subject.workspace,
|
|
192
238
|
eventsFile: subject.eventsFile,
|
|
193
239
|
stderrFile: subject.stderrFile,
|
|
194
240
|
signal: options.signal,
|
|
241
|
+
// Pi takes the prompt as its last argument (`args`); a host that reads prompts from stdin takes it here.
|
|
242
|
+
prompts: [options.group.input.prompt],
|
|
195
243
|
environment: subject.processEnvironment,
|
|
196
244
|
});
|
|
197
245
|
const contextObservation = await readContextObservations(
|
|
@@ -199,12 +247,14 @@ async function runOneShotDescription(options) {
|
|
|
199
247
|
subject.requiresContextObservation,
|
|
200
248
|
);
|
|
201
249
|
observation.contextObservationArtifact = contextObservation.artifact;
|
|
250
|
+
if (contextObservation.error) (observation.protocolErrors ??= []).push(contextObservation.error);
|
|
202
251
|
await verifySubjectResources(subject, observation);
|
|
203
252
|
const successfulReadPaths = await canonicalReadPaths(observation.successfulReads, subject.workspace);
|
|
204
253
|
const targetRead =
|
|
205
254
|
subject.environment.targetPath !== null && successfulReadPaths.includes(subject.environment.targetPath);
|
|
206
255
|
return descriptionRun(options, subject, observation, {
|
|
207
256
|
input: { prompt: options.group.input.prompt },
|
|
257
|
+
toolActivity: observation.toolActivity ?? [],
|
|
208
258
|
activation: {
|
|
209
259
|
targetRead,
|
|
210
260
|
firstReadTurn: targetRead ? 1 : null,
|
|
@@ -216,8 +266,10 @@ async function runOneShotDescription(options) {
|
|
|
216
266
|
|
|
217
267
|
async function runPersistentDescription(options) {
|
|
218
268
|
const subject = await prepareSubject(options, "rpc");
|
|
219
|
-
const observation = await
|
|
269
|
+
const observation = await subject.adapter.runSession({
|
|
270
|
+
subject,
|
|
220
271
|
command: subject.host.command,
|
|
272
|
+
settings: subject.isolation.settings,
|
|
221
273
|
args: subject.args,
|
|
222
274
|
cwd: subject.workspace,
|
|
223
275
|
eventsFile: subject.eventsFile,
|
|
@@ -231,6 +283,7 @@ async function runPersistentDescription(options) {
|
|
|
231
283
|
subject.requiresContextObservation,
|
|
232
284
|
);
|
|
233
285
|
observation.contextObservationArtifact = contextObservation.artifact;
|
|
286
|
+
if (contextObservation.error) (observation.protocolErrors ??= []).push(contextObservation.error);
|
|
234
287
|
await verifySubjectResources(subject, observation);
|
|
235
288
|
|
|
236
289
|
const turns = [];
|
|
@@ -264,59 +317,139 @@ async function runPersistentDescription(options) {
|
|
|
264
317
|
});
|
|
265
318
|
}
|
|
266
319
|
|
|
267
|
-
async function prepareSubject(
|
|
320
|
+
async function prepareSubject(
|
|
321
|
+
{
|
|
322
|
+
group,
|
|
323
|
+
variant,
|
|
324
|
+
root,
|
|
325
|
+
variantDirectory,
|
|
326
|
+
fixture: fixtureSnapshot,
|
|
327
|
+
runtime,
|
|
328
|
+
freeflow = null,
|
|
329
|
+
hostExtensions = [],
|
|
330
|
+
extendEnvironment = null,
|
|
331
|
+
},
|
|
332
|
+
mode,
|
|
333
|
+
) {
|
|
268
334
|
const workspace = path.join(variantDirectory, "workspace");
|
|
269
335
|
|
|
270
336
|
let environment;
|
|
271
337
|
let fixture;
|
|
272
338
|
let materializedRuntime;
|
|
339
|
+
let adapter;
|
|
340
|
+
let isolation;
|
|
273
341
|
try {
|
|
274
342
|
environment = await materializeEnvironment({
|
|
275
343
|
environment: group.variants[variant],
|
|
276
344
|
root,
|
|
277
345
|
variantDirectory,
|
|
278
346
|
});
|
|
347
|
+
// A pipeline stage adds what it declares it sees from earlier stages as further declared context.
|
|
348
|
+
if (extendEnvironment !== null) await extendEnvironment(environment, variantDirectory);
|
|
279
349
|
materializedRuntime = await materializeRuntime({ runtime, variantDirectory });
|
|
350
|
+
// Runtime environment literals may differ between arms (definitions.mjs); each subject gets its arm's own.
|
|
351
|
+
const literal = group.variants[variant].runtimeLiteral;
|
|
352
|
+
if (literal !== undefined) materializedRuntime.environment = { ...materializedRuntime.environment, literal };
|
|
280
353
|
fixture = await materializeFixture({ fixture: fixtureSnapshot, workspace });
|
|
354
|
+
// Written before the workspace's starting state is taken, so they never count as the subject's changes.
|
|
355
|
+
if (freeflow !== null) await writeFreeflowSettings(workspace, freeflow);
|
|
356
|
+
adapter = hostAdapter(materializedRuntime.host);
|
|
357
|
+
isolation = await adapter.prepareIsolation(variantDirectory, group.variants[variant].model?.model ?? null, {
|
|
358
|
+
settings: adapter.effectiveSettings(group.variants[variant].hostSettings ?? {}),
|
|
359
|
+
});
|
|
281
360
|
} catch (error) {
|
|
282
361
|
if (error instanceof VariantSetupError) throw error;
|
|
283
362
|
throw new VariantSetupError(error instanceof Error ? error.message : String(error));
|
|
284
363
|
}
|
|
285
364
|
|
|
286
|
-
const host = { name: materializedRuntime.host, command:
|
|
365
|
+
const host = { name: materializedRuntime.host, command: adapter.command };
|
|
287
366
|
const contextObservationPath = path.join(variantDirectory, "context-observations.jsonl");
|
|
288
367
|
const requiresContextObservation = group.expectations.some((expectation) => expectation.kind === "context-text");
|
|
289
368
|
const sessionDirectory = path.join(variantDirectory, "session");
|
|
290
369
|
if (materializedRuntime.session) await mkdir(sessionDirectory, { recursive: true });
|
|
291
|
-
const args = piArguments(group, environment, materializedRuntime, mode, requiresContextObservation, sessionDirectory);
|
|
292
370
|
const allowedRoots = [
|
|
293
371
|
await realpath(workspace),
|
|
294
372
|
...environment.skills.map((skill) => skill.path),
|
|
295
373
|
...environment.context.map((entry) => entry.path),
|
|
296
374
|
...materializedRuntime.extensions.flatMap((bundle) => bundle.resources.map((resource) => resource.path)),
|
|
375
|
+
// Freeflow points the subject at its own skills and references inside the package.
|
|
376
|
+
...(freeflow === null ? [] : [freeflow.packageRoot]),
|
|
377
|
+
...(group.tools.some((tool) => BACKGROUND_TOOLS.has(tool)) && isolation.environment.TMPDIR
|
|
378
|
+
? [isolation.environment.TMPDIR]
|
|
379
|
+
: []),
|
|
297
380
|
];
|
|
381
|
+
let launch;
|
|
382
|
+
try {
|
|
383
|
+
launch = await adapter.prepareLaunch({
|
|
384
|
+
group,
|
|
385
|
+
variant,
|
|
386
|
+
environment,
|
|
387
|
+
runtime: materializedRuntime,
|
|
388
|
+
mode,
|
|
389
|
+
observeContext: requiresContextObservation,
|
|
390
|
+
contextObservationPath,
|
|
391
|
+
sessionDirectory,
|
|
392
|
+
model: group.variants[variant].model,
|
|
393
|
+
freeflowEntry: freeflow?.entry ?? null,
|
|
394
|
+
hostExtensions,
|
|
395
|
+
workspace,
|
|
396
|
+
variantDirectory,
|
|
397
|
+
allowedRoots,
|
|
398
|
+
isolation: isolation.evidence,
|
|
399
|
+
});
|
|
400
|
+
} catch (error) {
|
|
401
|
+
if (error instanceof VariantSetupError) throw error;
|
|
402
|
+
throw new VariantSetupError(error instanceof Error ? error.message : String(error));
|
|
403
|
+
}
|
|
298
404
|
return {
|
|
299
|
-
|
|
405
|
+
adapter,
|
|
406
|
+
args: launch.args,
|
|
300
407
|
environment,
|
|
408
|
+
hostExtensions,
|
|
409
|
+
freeflow:
|
|
410
|
+
freeflow === null
|
|
411
|
+
? null
|
|
412
|
+
: {
|
|
413
|
+
ref: freeflow.ref,
|
|
414
|
+
commit: freeflow.commit,
|
|
415
|
+
package: freeflow.package,
|
|
416
|
+
tarballSha256: freeflow.tarballSha256,
|
|
417
|
+
metadata: freeflow.metadata,
|
|
418
|
+
repository: freeflow.repository,
|
|
419
|
+
personal: freeflow.personal,
|
|
420
|
+
},
|
|
421
|
+
// Where the built Freeflow package lies, so metrics can tell its skill reads apart; not recorded in run.json.
|
|
422
|
+
freeflowRoot: freeflow?.packageRoot ?? null,
|
|
301
423
|
runtime: materializedRuntime,
|
|
302
424
|
host,
|
|
303
425
|
fixture,
|
|
304
426
|
workspace,
|
|
427
|
+
workspaceRoot: allowedRoots[0],
|
|
428
|
+
// Every readable root but the workspace: the declared skills, context, runtime resources and Freeflow's package.
|
|
429
|
+
resourceRoots: allowedRoots.slice(1),
|
|
305
430
|
contextObservationPath,
|
|
306
431
|
requiresContextObservation,
|
|
307
432
|
sessionDirectory,
|
|
308
433
|
eventsFile: path.join(variantDirectory, "events.jsonl"),
|
|
309
434
|
stderrFile: path.join(variantDirectory, "stderr.log"),
|
|
310
435
|
startedAt: new Date().toISOString(),
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
436
|
+
isolation: isolation.evidence,
|
|
437
|
+
processEnvironment: {
|
|
438
|
+
...createProcessEnvironment({
|
|
439
|
+
runtime: materializedRuntime,
|
|
440
|
+
group,
|
|
441
|
+
workspace,
|
|
442
|
+
allowedRoots,
|
|
443
|
+
contextManifestPath: environment.contextDelivery.manifestPath,
|
|
444
|
+
contextObservationPath,
|
|
445
|
+
requiresContextObservation,
|
|
446
|
+
hostEnvironment: launch.environment,
|
|
447
|
+
}),
|
|
448
|
+
// A declared shell lets the guard allow bash; its isolation extension runs it.
|
|
449
|
+
...(group.variants[variant].shell ? { SKILL_EVAL_SHELL: JSON.stringify(group.variants[variant].shell) } : {}),
|
|
450
|
+
// Last, so nothing inherited or declared can point the subject back at the parent's home or Pi settings.
|
|
451
|
+
...isolation.environment,
|
|
452
|
+
},
|
|
320
453
|
};
|
|
321
454
|
}
|
|
322
455
|
|
|
@@ -328,21 +461,22 @@ function createProcessEnvironment({
|
|
|
328
461
|
contextManifestPath,
|
|
329
462
|
contextObservationPath,
|
|
330
463
|
requiresContextObservation,
|
|
464
|
+
hostEnvironment,
|
|
331
465
|
}) {
|
|
332
|
-
const processEnvironment =
|
|
333
|
-
BASE_PROCESS_ENVIRONMENT_KEYS.flatMap((key) => (process.env[key] === undefined ? [] : [[key, process.env[key]]])),
|
|
334
|
-
);
|
|
466
|
+
const processEnvironment = baseProcessEnvironment();
|
|
335
467
|
Object.assign(processEnvironment, {
|
|
336
468
|
PWD: workspace,
|
|
337
469
|
...runtime.environment.literal,
|
|
338
|
-
|
|
339
|
-
|
|
470
|
+
// The host's own variables, such as Pi's version check and telemetry switches, after declared literals.
|
|
471
|
+
...hostEnvironment,
|
|
340
472
|
SKILL_EVAL_ALLOWED_ROOTS: JSON.stringify(allowedRoots),
|
|
341
473
|
SKILL_EVAL_WRITABLE_ROOT: workspace,
|
|
342
474
|
SKILL_EVAL_ALLOWED_TOOLS: JSON.stringify(group.tools),
|
|
343
475
|
SKILL_EVAL_CONTEXT_MANIFEST: contextManifestPath ?? "",
|
|
344
476
|
SKILL_EVAL_HOST: runtime.host,
|
|
477
|
+
SKILL_EVAL_PROMPT_MODE: runtime.prompt,
|
|
345
478
|
});
|
|
479
|
+
if (group.commands !== undefined) processEnvironment.SKILL_EVAL_COMMANDS = JSON.stringify(group.commands);
|
|
346
480
|
for (const key of runtime.environment.inherit) {
|
|
347
481
|
if (process.env[key] === undefined) {
|
|
348
482
|
throw new VariantSetupError(`inherited runtime environment variable is unavailable: ${key}`);
|
|
@@ -353,24 +487,39 @@ function createProcessEnvironment({
|
|
|
353
487
|
return processEnvironment;
|
|
354
488
|
}
|
|
355
489
|
|
|
490
|
+
// A missing or malformed observation fails the subject but keeps everything the process already reported:
|
|
491
|
+
// transcript, response, usage, and process evidence stay in run.json.
|
|
356
492
|
async function readContextObservations(file, required) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
493
|
+
let contents;
|
|
494
|
+
try {
|
|
495
|
+
contents = await readFile(file, "utf8");
|
|
496
|
+
} catch (error) {
|
|
497
|
+
if (error?.code !== "ENOENT") throw error;
|
|
498
|
+
if (!required) return { observations: [], artifact: null, error: null };
|
|
499
|
+
return {
|
|
500
|
+
observations: [],
|
|
501
|
+
artifact: null,
|
|
502
|
+
error: { reason: "context-observer-missing", message: "context observer produced no evidence" },
|
|
503
|
+
};
|
|
504
|
+
}
|
|
364
505
|
const observations = [];
|
|
365
506
|
for (const line of contents.split("\n").filter(Boolean)) {
|
|
366
507
|
try {
|
|
367
508
|
observations.push(JSON.parse(line));
|
|
368
509
|
} catch (error) {
|
|
369
|
-
|
|
510
|
+
return {
|
|
511
|
+
observations: [],
|
|
512
|
+
artifact: null,
|
|
513
|
+
error: {
|
|
514
|
+
reason: "context-observation-malformed",
|
|
515
|
+
message: `context observation is malformed: ${error instanceof Error ? error.message : String(error)}`,
|
|
516
|
+
},
|
|
517
|
+
};
|
|
370
518
|
}
|
|
371
519
|
}
|
|
372
520
|
return {
|
|
373
521
|
observations,
|
|
522
|
+
error: null,
|
|
374
523
|
artifact:
|
|
375
524
|
contents === ""
|
|
376
525
|
? null
|
|
@@ -397,11 +546,12 @@ async function verifySubjectResources(subject, observation) {
|
|
|
397
546
|
}
|
|
398
547
|
}
|
|
399
548
|
|
|
400
|
-
function descriptionRun(options, subject, observation, { input, activation }) {
|
|
549
|
+
function descriptionRun(options, subject, observation, { input, activation, toolActivity }) {
|
|
401
550
|
return {
|
|
402
551
|
...subjectRun(options, subject, observation),
|
|
403
552
|
evaluationType: "description",
|
|
404
553
|
...input,
|
|
554
|
+
...(toolActivity === undefined ? {} : { toolActivity }),
|
|
405
555
|
activation,
|
|
406
556
|
};
|
|
407
557
|
}
|
|
@@ -420,179 +570,6 @@ function subjectRunState(observation) {
|
|
|
420
570
|
return "infrastructure-failed";
|
|
421
571
|
}
|
|
422
572
|
|
|
423
|
-
function piArguments(group, environment, runtime, mode, observeContext, sessionDirectory) {
|
|
424
|
-
const args = ["--mode", mode];
|
|
425
|
-
if (mode === "json") args.push("-p");
|
|
426
|
-
if (runtime.session) args.push("--session-dir", sessionDirectory);
|
|
427
|
-
else args.push("--no-session");
|
|
428
|
-
args.push("--no-extensions", "--extension", guardExtension);
|
|
429
|
-
for (const bundle of runtime.extensions) args.push("--extension", bundle.entry);
|
|
430
|
-
if (observeContext) args.push("--extension", observerExtension);
|
|
431
|
-
args.push("--no-skills", "--no-prompt-templates", "--no-themes", "--no-context-files", "--no-approve");
|
|
432
|
-
if (group.tools.length === 0) args.push("--no-tools");
|
|
433
|
-
else args.push("--tools", group.tools.join(","));
|
|
434
|
-
for (const skill of environment.skills) args.push("--skill", skill.path);
|
|
435
|
-
if (group.model?.model) args.push("--model", group.model.model);
|
|
436
|
-
if (group.model?.thinking) args.push("--thinking", group.model.thinking);
|
|
437
|
-
if (mode === "json") args.push(group.input.prompt);
|
|
438
|
-
return args;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
async function runPiProcess({ command, args, cwd, eventsFile, stderrFile, signal, environment }) {
|
|
442
|
-
const child = spawn(command, args, {
|
|
443
|
-
cwd,
|
|
444
|
-
detached: process.platform !== "win32",
|
|
445
|
-
env: environment,
|
|
446
|
-
shell: false,
|
|
447
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
448
|
-
});
|
|
449
|
-
const events = createWriteStream(eventsFile, { encoding: "utf8" });
|
|
450
|
-
const stderr = createWriteStream(stderrFile, { encoding: "utf8" });
|
|
451
|
-
const transcript = [];
|
|
452
|
-
const calls = new Map();
|
|
453
|
-
const successfulReads = [];
|
|
454
|
-
const parseErrors = [];
|
|
455
|
-
const protocolErrors = [];
|
|
456
|
-
let settled = false;
|
|
457
|
-
let response = "";
|
|
458
|
-
let usage = null;
|
|
459
|
-
let assistantError = null;
|
|
460
|
-
let observedModel = null;
|
|
461
|
-
let buffer = "";
|
|
462
|
-
let eventLine = 0;
|
|
463
|
-
const processGroupId = child.pid;
|
|
464
|
-
let watchdog;
|
|
465
|
-
let forcedKill;
|
|
466
|
-
/** @type {Promise<void> | null} */
|
|
467
|
-
let forcedKillPromise = null;
|
|
468
|
-
let terminationReason = null;
|
|
469
|
-
|
|
470
|
-
const resetWatchdog = () => {
|
|
471
|
-
clearTimeout(watchdog);
|
|
472
|
-
watchdog = setTimeout(() => requestTermination("no-progress-watchdog"), NO_PROGRESS_MS);
|
|
473
|
-
watchdog.unref();
|
|
474
|
-
};
|
|
475
|
-
const requestTermination = (reason) => {
|
|
476
|
-
if (terminationReason !== null) return;
|
|
477
|
-
terminationReason = reason;
|
|
478
|
-
signalProcessTree(processGroupId, child, "SIGTERM");
|
|
479
|
-
if (process.platform !== "win32") {
|
|
480
|
-
forcedKillPromise = new Promise((resolve) => {
|
|
481
|
-
forcedKill = setTimeout(() => {
|
|
482
|
-
signalProcessTree(processGroupId, child, "SIGKILL");
|
|
483
|
-
resolve();
|
|
484
|
-
}, TERMINATION_GRACE_MS);
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
};
|
|
488
|
-
const onAbort = () => requestTermination("cancelled");
|
|
489
|
-
if (signal?.aborted) onAbort();
|
|
490
|
-
else signal?.addEventListener("abort", onAbort, { once: true });
|
|
491
|
-
resetWatchdog();
|
|
492
|
-
|
|
493
|
-
const stderrTask = pipeStream(child.stderr, stderr, resetWatchdog);
|
|
494
|
-
const stdoutTask = (async () => {
|
|
495
|
-
for await (const chunk of child.stdout) {
|
|
496
|
-
resetWatchdog();
|
|
497
|
-
buffer += chunk.toString("utf8");
|
|
498
|
-
while (true) {
|
|
499
|
-
const newline = buffer.indexOf("\n");
|
|
500
|
-
if (newline === -1) break;
|
|
501
|
-
const line = buffer.slice(0, newline);
|
|
502
|
-
buffer = buffer.slice(newline + 1);
|
|
503
|
-
await writeStream(events, `${line}\n`);
|
|
504
|
-
observeLine(line.endsWith("\r") ? line.slice(0, -1) : line);
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
if (buffer.length > 0) {
|
|
508
|
-
await writeStream(events, buffer);
|
|
509
|
-
observeLine(buffer.endsWith("\r") ? buffer.slice(0, -1) : buffer);
|
|
510
|
-
}
|
|
511
|
-
events.end();
|
|
512
|
-
await once(events, "finish");
|
|
513
|
-
})();
|
|
514
|
-
|
|
515
|
-
function observeLine(line) {
|
|
516
|
-
eventLine += 1;
|
|
517
|
-
if (line.trim() === "") return;
|
|
518
|
-
let event;
|
|
519
|
-
try {
|
|
520
|
-
event = JSON.parse(line);
|
|
521
|
-
} catch {
|
|
522
|
-
parseErrors.push({ line: eventLine, reason: "invalid-json" });
|
|
523
|
-
return;
|
|
524
|
-
}
|
|
525
|
-
if (event.type === "extension_error") {
|
|
526
|
-
protocolErrors.push({
|
|
527
|
-
reason: "extension-error",
|
|
528
|
-
extensionPath: event.extensionPath ?? null,
|
|
529
|
-
event: event.event ?? null,
|
|
530
|
-
error: event.error ?? null,
|
|
531
|
-
});
|
|
532
|
-
requestTermination("protocol-error");
|
|
533
|
-
}
|
|
534
|
-
if (event.type === "agent_settled") settled = true;
|
|
535
|
-
if (event.type === "tool_execution_start") {
|
|
536
|
-
calls.set(event.toolCallId, { toolName: event.toolName, args: event.args });
|
|
537
|
-
}
|
|
538
|
-
if (event.type === "tool_execution_end" && !event.isError) {
|
|
539
|
-
const call = calls.get(event.toolCallId);
|
|
540
|
-
if (call?.toolName === "read" && typeof call.args?.path === "string") {
|
|
541
|
-
successfulReads.push(call.args.path);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
if (event.type === "message_end" && event.message) {
|
|
545
|
-
transcript.push(event.message);
|
|
546
|
-
if (event.message.role === "assistant") {
|
|
547
|
-
response = messageText(event.message);
|
|
548
|
-
usage = mergeUsage(usage, event.message.usage);
|
|
549
|
-
observedModel = {
|
|
550
|
-
provider: event.message.provider ?? null,
|
|
551
|
-
model: event.message.model ?? null,
|
|
552
|
-
};
|
|
553
|
-
assistantError =
|
|
554
|
-
event.message.stopReason === "error" || event.message.stopReason === "aborted"
|
|
555
|
-
? (event.message.errorMessage ?? `assistant stopped with ${event.message.stopReason}`)
|
|
556
|
-
: null;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
let exitCode = null;
|
|
562
|
-
let exitSignal = null;
|
|
563
|
-
try {
|
|
564
|
-
const [code, closedSignal] = await once(child, "close");
|
|
565
|
-
exitCode = code;
|
|
566
|
-
exitSignal = closedSignal;
|
|
567
|
-
await Promise.all([stdoutTask, stderrTask]);
|
|
568
|
-
} catch (error) {
|
|
569
|
-
requestTermination("process-error");
|
|
570
|
-
throw error;
|
|
571
|
-
} finally {
|
|
572
|
-
clearTimeout(watchdog);
|
|
573
|
-
if (forcedKillPromise !== null) {
|
|
574
|
-
if (processGroupExists(processGroupId)) await waitForForcedKill(forcedKillPromise);
|
|
575
|
-
else clearTimeout(forcedKill);
|
|
576
|
-
}
|
|
577
|
-
signal?.removeEventListener("abort", onAbort);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
return {
|
|
581
|
-
exitCode,
|
|
582
|
-
signal: exitSignal,
|
|
583
|
-
settled,
|
|
584
|
-
assistantError,
|
|
585
|
-
model: observedModel,
|
|
586
|
-
terminationReason,
|
|
587
|
-
parseErrors,
|
|
588
|
-
protocolErrors,
|
|
589
|
-
successfulReads,
|
|
590
|
-
transcript,
|
|
591
|
-
response,
|
|
592
|
-
usage,
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
|
|
596
573
|
async function canonicalReadPaths(paths, cwd) {
|
|
597
574
|
const canonical = [];
|
|
598
575
|
for (const rawPath of paths) {
|