@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
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
3
4
|
import { rm } from "node:fs/promises";
|
|
4
5
|
import { cwd } from "node:process";
|
|
5
|
-
import { dirname } from "node:path";
|
|
6
|
-
import { canonicalLines, joinLines, slugify
|
|
6
|
+
import { dirname, isAbsolute, resolve, sep } from "node:path";
|
|
7
|
+
import { WORK_AGREEMENT_HEADING, canonicalLines, joinLines, slugify } from "./lib/format.mjs";
|
|
7
8
|
import { parseDocument, validateDocument } from "./lib/document.mjs";
|
|
8
9
|
import { runTransition } from "./lib/transitions.mjs";
|
|
9
10
|
import {
|
|
@@ -12,17 +13,30 @@ import {
|
|
|
12
13
|
readInput,
|
|
13
14
|
readRecord,
|
|
14
15
|
resolveRecordPath,
|
|
16
|
+
storeOf,
|
|
15
17
|
writeInitialAtomically,
|
|
16
18
|
} from "./lib/store.mjs";
|
|
17
|
-
import { renderFull, renderResume } from "./lib/views.mjs";
|
|
19
|
+
import { renderEntries, renderFull, renderResume } from "./lib/views.mjs";
|
|
20
|
+
import { checkEvidencePointers, renderRecover } from "./lib/recover.mjs";
|
|
21
|
+
import { PROJECT_LINK, Registry, TASK_ID, removalText, startCommand } from "./lib/registry.mjs";
|
|
22
|
+
import { searchRecords } from "./lib/search.mjs";
|
|
23
|
+
|
|
24
|
+
const ROOT_HELP =
|
|
25
|
+
"--record is resolved against --root, which defaults to the current directory; an absolute --record path finds its own root.";
|
|
18
26
|
|
|
19
27
|
function usage() {
|
|
20
28
|
return [
|
|
21
29
|
"Usage:",
|
|
22
30
|
" working-record.mjs init --root <path> --name <task name> [--input <file|->]",
|
|
23
|
-
" working-record.mjs view resume|full --record <record.md>",
|
|
31
|
+
" working-record.mjs view resume|recover|full --record <record.md>",
|
|
32
|
+
" working-record.mjs view entry <ID> [<ID> ...] --record <record.md>",
|
|
24
33
|
" working-record.mjs validate --record <record.md>",
|
|
25
34
|
" working-record.mjs <slice|checkpoint|decision|task> <operation> ...",
|
|
35
|
+
" working-record.mjs project <new|link|show|list|remove> ...",
|
|
36
|
+
" working-record.mjs task <create|import|search|env|here|fanout|remove> ...",
|
|
37
|
+
"",
|
|
38
|
+
ROOT_HELP,
|
|
39
|
+
"A registered task's ID (such as my-project/task-003) may be given as --record.",
|
|
26
40
|
].join("\n");
|
|
27
41
|
}
|
|
28
42
|
|
|
@@ -31,7 +45,7 @@ const COMMAND_HELP = new Map([
|
|
|
31
45
|
"slice",
|
|
32
46
|
[
|
|
33
47
|
"Usage: working-record.mjs slice <operation> ...",
|
|
34
|
-
"Operations: slice propose, slice start, slice start-direct, slice pause, slice resume, slice close, slice reopen.",
|
|
48
|
+
"Operations: slice propose, slice start, slice start-direct, slice pause, slice resume, slice close, slice reopen, slice record.",
|
|
35
49
|
"Run working-record.mjs <group> <operation> --help for options and input fields.",
|
|
36
50
|
"Use --input - to read Markdown fragments from stdin.",
|
|
37
51
|
].join("\n"),
|
|
@@ -58,19 +72,74 @@ const COMMAND_HELP = new Map([
|
|
|
58
72
|
"task",
|
|
59
73
|
[
|
|
60
74
|
"Usage: working-record.mjs task <operation> ...",
|
|
61
|
-
"Operations: task set-state.",
|
|
75
|
+
"Operations: task set-state; and for projects: task create, task import, task search, task env, task here, task fanout, task remove.",
|
|
62
76
|
"Run working-record.mjs <group> <operation> --help for options and input fields.",
|
|
63
77
|
].join("\n"),
|
|
64
78
|
],
|
|
65
79
|
[
|
|
66
80
|
"init",
|
|
67
|
-
"Usage: init --root <path> --name <task name> [--
|
|
81
|
+
"Usage: init --root <path> --name <task name> [--input <file|->]\nInput: Goal and Next useful action required; the seven Current Context headings, Work agreement (written only when given) and Recovery sources are accepted, and every line must sit under one of them. The record starts active. Use --input - to read Markdown fragments from stdin.",
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
"view",
|
|
85
|
+
"Usage: view resume|recover|full --record <record.md>\n view entry <ID> [<ID> ...] --record <record.md>\nresume: the header, Current Context, active Decisions, Current Work, Future Work, a one-line index of closed History, and Notes. recover: the resume view, then each defining artifact and Recovery source with its trigger, whether it resolves and its size, then live Git state and where it disagrees with the record: what recovery after context loss reads first. entry: the named S-NNN, C-NNN, or D-NNN entries exactly as stored. full: the file exactly as stored, valid or not.",
|
|
86
|
+
],
|
|
87
|
+
[
|
|
88
|
+
"validate",
|
|
89
|
+
"Usage: validate --record <record.md> [--strict]\nChecks the record's structure, and whether the pointers in Material updates resolve: files (from the repository root or the task folder) and commits. An unresolved pointer is a warning, since it may name a planned path or a commit not fetched yet; with --strict, one on an Evidence or Result line fails. Pointers outside the repository are listed, not checked.",
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
"project",
|
|
93
|
+
"Usage: working-record.mjs project <operation> ...\nOperations: project new, project link, project show, project list, project remove.\nA project groups tasks; its records live in a store under the Freeflow home (FREEFLOW_HOME, default ~/.freeflow), outside any repository. Create or link a project only when the user asks.",
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"project new",
|
|
97
|
+
"Usage: project new --name <name> [--cwd <directory>] [--worktrees <directory>]\nCreates the project and links the repository containing --cwd (default: the current directory) to it. --worktrees is where fan-out puts children's worktrees (default: the repository's parent directory).",
|
|
98
|
+
],
|
|
99
|
+
[
|
|
100
|
+
"project link",
|
|
101
|
+
"Usage: project link --name <name> [--cwd <directory>] [--worktrees <directory>]\nLinks another repository to an existing project; --worktrees changes where fan-out puts worktrees.",
|
|
102
|
+
],
|
|
103
|
+
[
|
|
104
|
+
"task env",
|
|
105
|
+
"Usage: task env --id <task-id> [--primary <directory>] [--add-dir <directory>] [--remove-dir <directory>]\nPrints where the task's work happens: its primary directory with its current Git branch, and additional directories. The options change it; change it only when the user asks.",
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
"task here",
|
|
109
|
+
"Usage: task here [--cwd <directory>]\nPrints the registered tasks whose primary directory contains the directory, deepest first.",
|
|
110
|
+
],
|
|
111
|
+
[
|
|
112
|
+
"task fanout",
|
|
113
|
+
"Usage: task fanout --parent <task-id> --title <title> --goal <goal> [--path <directory>] [--base <ref>] [--agent <command>]\nCreates a child of the task, a Git worktree for it on branch <project>/<task-NNN>-<slug> (at <worktrees>/<repo>-<slug> unless --path), copies .freeflow/local.json into it when it has none, and makes the worktree the child's directory. The user then starts a session there: --agent is the command that starts this host's agent (such as claude or codex), and the output ends with a command for the user to paste into a new terminal.",
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
"project show",
|
|
117
|
+
"Usage: project show [--cwd <directory>] [--name <project>]\nPrints a project and its tasks: ID, title, parent, and whether a session owns it. Without --name, the project linked to the repository containing --cwd.",
|
|
118
|
+
],
|
|
119
|
+
["project list", "Usage: project list\nPrints every project: name, number of tasks, and linked repositories."],
|
|
120
|
+
[
|
|
121
|
+
"project remove",
|
|
122
|
+
"Usage: project remove --name <project>\nMoves the project's store (every task's record) to the trash under the Freeflow home, removes the project and its tasks from the registry, and removes its .freeflow/project links. Git worktrees and branches stay; the output gives the commands to remove them. Run it only when the user asked to remove that project. Never empty the trash: the user does.",
|
|
123
|
+
],
|
|
124
|
+
[
|
|
125
|
+
"task remove",
|
|
126
|
+
"Usage: task remove --id <task ID>\nMoves the task's record, and its children's, to the trash under the Freeflow home and removes them from the registry. Task numbers are never reused. Git worktrees and branches stay; the output gives the commands to remove them. Run it only when the user asked to remove that task. Never empty the trash: the user does.",
|
|
127
|
+
],
|
|
128
|
+
[
|
|
129
|
+
"task create",
|
|
130
|
+
"Usage: task create --title <title> --goal <goal> [--parent <task-id>] [--cwd <directory>]\nCreates a registered record in the project linked to --cwd, or with --parent a child of that task in its project, and prints its ID and path. A child has no children.",
|
|
131
|
+
],
|
|
132
|
+
[
|
|
133
|
+
"task import",
|
|
134
|
+
"Usage: task import --record <record.md> --project <name>\nMoves an unregistered record's task directory into the project's store, with the next free number, and registers it. Ask the user first.",
|
|
135
|
+
],
|
|
136
|
+
[
|
|
137
|
+
"task search",
|
|
138
|
+
"Usage: task search --query <text> (--id <task-id> --scope task|tree|project | --project <name>)\nPrints matching lines with the record, entry heading and state. tree is the task's root (its parent, or itself) and the root's children. Read-only.",
|
|
68
139
|
],
|
|
69
|
-
["view", "Usage: view resume|full --record <record.md>"],
|
|
70
|
-
["validate", "Usage: validate --record <record.md>"],
|
|
71
140
|
[
|
|
72
141
|
"slice propose",
|
|
73
|
-
"Usage: slice propose --record <record.md> --title <title> --input <file|->\nInput: Intended result required; Type, Expected evidence, and Dependencies optional. Use --input - to read the fragment from stdin.",
|
|
142
|
+
"Usage: slice propose --record <record.md> --title <title> --input <file|->\nInput: Intended result required; Type, Expected evidence, and Dependencies optional. Commands set State; input never includes it. Use --input - to read the fragment from stdin.",
|
|
74
143
|
],
|
|
75
144
|
[
|
|
76
145
|
"slice start",
|
|
@@ -93,9 +162,13 @@ const COMMAND_HELP = new Map([
|
|
|
93
162
|
"slice reopen",
|
|
94
163
|
"Usage: slice reopen --record <record.md> --id <S-NNN> --next-action <text> --input <file|->\nInput: fresh Authority source, Scope, Expected evidence, Stop condition, and Starting state required. Use --input - to read the fragment from stdin.",
|
|
95
164
|
],
|
|
165
|
+
[
|
|
166
|
+
"slice record",
|
|
167
|
+
"Usage: slice record --record <record.md> --title <title> --state <completed|blocked|abandoned> --input <file|->\nRecords a Slice that finished before it could be recorded, directly into History. The Current Slice, Future Work, and Next useful action are unchanged; the ID follows recording order and the command adds Recorded: retroactively on <today>.\nInput: Occurred (YYYY-MM-DD or YYYY-MM-DD to YYYY-MM-DD), Intended result, Authority source, Result, Evidence and limits, and Task effect required; Type and Residual effects optional; Resume when required for blocked; Reason required for abandoned. Use --input - to read the fragment from stdin.",
|
|
168
|
+
],
|
|
96
169
|
[
|
|
97
170
|
"checkpoint propose",
|
|
98
|
-
"Usage: checkpoint propose --record <record.md> --title <title> --input <file|->\nInput: Type, Condition, and Applies to required. Use --input - to read the fragment from stdin.",
|
|
171
|
+
"Usage: checkpoint propose --record <record.md> --title <title> --input <file|->\nInput: Type (preserve, publish, review, decision, or continuity), Condition, and Applies to required. Use --input - to read the fragment from stdin.",
|
|
99
172
|
],
|
|
100
173
|
[
|
|
101
174
|
"checkpoint activate",
|
|
@@ -123,7 +196,9 @@ const COMMAND_HELP = new Map([
|
|
|
123
196
|
]);
|
|
124
197
|
|
|
125
198
|
function commandHelp(command, operation) {
|
|
126
|
-
|
|
199
|
+
const help = COMMAND_HELP.get([command, operation].filter(Boolean).join(" ")) ?? COMMAND_HELP.get(command);
|
|
200
|
+
if (!help) return `${usage()}\n`;
|
|
201
|
+
return command === "init" ? `${help}\n` : `${help}\n${ROOT_HELP}\n`;
|
|
127
202
|
}
|
|
128
203
|
|
|
129
204
|
class CliError extends Error {
|
|
@@ -144,7 +219,7 @@ function parseOptions(args) {
|
|
|
144
219
|
continue;
|
|
145
220
|
}
|
|
146
221
|
if (options[token] !== undefined) throw new CliError(`Duplicate option: ${token}`);
|
|
147
|
-
if (token === "--help") {
|
|
222
|
+
if (token === "--help" || token === "--strict") {
|
|
148
223
|
options[token] = true;
|
|
149
224
|
continue;
|
|
150
225
|
}
|
|
@@ -159,9 +234,9 @@ function parseOptions(args) {
|
|
|
159
234
|
function allowedOptions(command, operation) {
|
|
160
235
|
const common = new Set(["--root", "--record", "--input", "--help"]);
|
|
161
236
|
const withNextAction = new Set([...common, "--next-action"]);
|
|
162
|
-
if (command === "init") return new Set(["--root", "--name", "--
|
|
237
|
+
if (command === "init") return new Set(["--root", "--name", "--input", "--help"]);
|
|
163
238
|
if (command === "view") return new Set(["--root", "--record", "--view", "--help"]);
|
|
164
|
-
if (command === "validate") return new Set(["--root", "--record", "--help"]);
|
|
239
|
+
if (command === "validate") return new Set(["--root", "--record", "--strict", "--help"]);
|
|
165
240
|
if (command === "slice") {
|
|
166
241
|
if (operation === "propose") return new Set([...common, "--title"]);
|
|
167
242
|
if (operation === "start" || operation === "start-direct") return new Set([...withNextAction, "--title"]);
|
|
@@ -169,6 +244,7 @@ function allowedOptions(command, operation) {
|
|
|
169
244
|
if (operation === "resume") return new Set([...withNextAction, "--resolution"]);
|
|
170
245
|
if (operation === "close") return new Set([...withNextAction, "--state"]);
|
|
171
246
|
if (operation === "reopen") return new Set([...withNextAction, "--id", "--title"]);
|
|
247
|
+
if (operation === "record") return new Set([...common, "--title", "--state"]);
|
|
172
248
|
}
|
|
173
249
|
if (command === "checkpoint") {
|
|
174
250
|
if (operation === "propose") return new Set([...common, "--title"]);
|
|
@@ -183,6 +259,22 @@ function allowedOptions(command, operation) {
|
|
|
183
259
|
}
|
|
184
260
|
if (command === "task" && operation === "set-state")
|
|
185
261
|
return new Set(["--root", "--record", "--state", "--next-action", "--help"]);
|
|
262
|
+
if (command === "task" && operation === "create")
|
|
263
|
+
return new Set(["--title", "--goal", "--parent", "--cwd", "--help"]);
|
|
264
|
+
if (command === "task" && operation === "import") return new Set(["--record", "--project", "--help"]);
|
|
265
|
+
if (command === "task" && operation === "search")
|
|
266
|
+
return new Set(["--query", "--id", "--scope", "--project", "--help"]);
|
|
267
|
+
if (command === "task" && operation === "env")
|
|
268
|
+
return new Set(["--id", "--primary", "--add-dir", "--remove-dir", "--help"]);
|
|
269
|
+
if (command === "task" && operation === "here") return new Set(["--cwd", "--help"]);
|
|
270
|
+
if (command === "task" && operation === "fanout")
|
|
271
|
+
return new Set(["--parent", "--title", "--goal", "--path", "--base", "--cwd", "--agent", "--help"]);
|
|
272
|
+
if (command === "project" && (operation === "new" || operation === "link"))
|
|
273
|
+
return new Set(["--name", "--cwd", "--worktrees", "--help"]);
|
|
274
|
+
if (command === "project" && operation === "show") return new Set(["--cwd", "--name", "--help"]);
|
|
275
|
+
if (command === "project" && operation === "list") return new Set(["--help"]);
|
|
276
|
+
if (command === "task" && operation === "remove") return new Set(["--id", "--help"]);
|
|
277
|
+
if (command === "project" && operation === "remove") return new Set(["--name", "--help"]);
|
|
186
278
|
return null;
|
|
187
279
|
}
|
|
188
280
|
|
|
@@ -202,7 +294,16 @@ function requireOption(options, name) {
|
|
|
202
294
|
}
|
|
203
295
|
|
|
204
296
|
function rootOption(options) {
|
|
205
|
-
|
|
297
|
+
if (options["--root"]) return options["--root"];
|
|
298
|
+
const record = options["--record"];
|
|
299
|
+
if (record && isAbsolute(record)) {
|
|
300
|
+
const marker = `${sep}.freeflow${sep}tasks${sep}`;
|
|
301
|
+
const index = record.lastIndexOf(marker);
|
|
302
|
+
if (index > 0) return record.slice(0, index);
|
|
303
|
+
const store = storeOf(record);
|
|
304
|
+
if (store) return store;
|
|
305
|
+
}
|
|
306
|
+
return cwd();
|
|
206
307
|
}
|
|
207
308
|
|
|
208
309
|
function initialContent(skeletonLines, input) {
|
|
@@ -211,21 +312,27 @@ function initialContent(skeletonLines, input) {
|
|
|
211
312
|
const targets = new Map();
|
|
212
313
|
const names = [
|
|
213
314
|
"Goal",
|
|
315
|
+
WORK_AGREEMENT_HEADING,
|
|
214
316
|
"What defines this task",
|
|
215
317
|
"Settled",
|
|
216
318
|
"Tentative",
|
|
217
319
|
"Open",
|
|
218
320
|
"Current direction",
|
|
219
321
|
"Boundaries",
|
|
322
|
+
"Recovery sources",
|
|
220
323
|
"Next useful action",
|
|
221
324
|
];
|
|
222
325
|
const allowed = new Set(names);
|
|
326
|
+
let seenHeading = false;
|
|
223
327
|
for (let index = 0; index < inputLines.length; index += 1) {
|
|
224
328
|
const levelThree = /^### (.+?)\s*$/.exec(inputLines[index]);
|
|
329
|
+
if (!levelThree && !seenHeading && inputLines[index].trim() !== "")
|
|
330
|
+
throw new CliError(`Initialization text outside a heading would be lost: ${inputLines[index].trim()}`);
|
|
225
331
|
if (levelThree) {
|
|
226
332
|
const name = levelThree[1];
|
|
227
333
|
if (!allowed.has(name)) throw new CliError(`Unknown initialization heading: ${name}`);
|
|
228
334
|
if (targets.has(name)) throw new CliError(`Duplicate initialization heading: ${name}`);
|
|
335
|
+
seenHeading = true;
|
|
229
336
|
const content = [];
|
|
230
337
|
for (let next = index + 1; next < inputLines.length; next += 1) {
|
|
231
338
|
if (/^### /.test(inputLines[next]) || /^## /.test(inputLines[next])) break;
|
|
@@ -237,6 +344,9 @@ function initialContent(skeletonLines, input) {
|
|
|
237
344
|
if (/^## /.test(inputLines[index])) throw new CliError(`Unknown initialization heading: ${inputLines[index]}`);
|
|
238
345
|
}
|
|
239
346
|
const output = [...skeletonLines];
|
|
347
|
+
// The skeleton has no Work agreement heading: it is written only when the input gives one.
|
|
348
|
+
if (targets.has(WORK_AGREEMENT_HEADING))
|
|
349
|
+
output.splice(output.indexOf("### What defines this task"), 0, `### ${WORK_AGREEMENT_HEADING}`, "");
|
|
240
350
|
for (const name of names) {
|
|
241
351
|
const content = targets.get(name);
|
|
242
352
|
if (!content) continue;
|
|
@@ -255,10 +365,8 @@ function initialContent(skeletonLines, input) {
|
|
|
255
365
|
async function initialize(options) {
|
|
256
366
|
const root = rootOption(options);
|
|
257
367
|
const name = requireOption(options, "--name");
|
|
258
|
-
const state = options["--state"] ?? "active";
|
|
259
|
-
if (!TASK_STATES.has(state)) throw new CliError(`Invalid task state: ${state}`);
|
|
260
368
|
const input = await readInput(options["--input"], cwd());
|
|
261
|
-
const text = initialContent(canonicalLines(name
|
|
369
|
+
const text = initialContent(canonicalLines(name), input);
|
|
262
370
|
parseDocument(text);
|
|
263
371
|
const created = await createRecordPath(root, name, slugify(name));
|
|
264
372
|
try {
|
|
@@ -277,25 +385,158 @@ async function readExisting(options) {
|
|
|
277
385
|
return { root, ...loaded };
|
|
278
386
|
}
|
|
279
387
|
|
|
388
|
+
/** Projects, registered tasks and search, through the registry under the Freeflow home. */
|
|
389
|
+
async function runRegistry(command, operation, options) {
|
|
390
|
+
const registry = new Registry();
|
|
391
|
+
const where = options["--cwd"] ?? cwd();
|
|
392
|
+
// Where the user can browse the project's records, when the project link was made.
|
|
393
|
+
const browse = async () => {
|
|
394
|
+
const link = resolve(await registry.repoRoot(where), PROJECT_LINK);
|
|
395
|
+
return existsSync(link) ? ` The user can browse its records at ${link}.` : "";
|
|
396
|
+
};
|
|
397
|
+
if (command === "project" && operation === "new")
|
|
398
|
+
return `Project ${await registry.createProject(requireOption(options, "--name"), where, options["--worktrees"])} created and linked to ${await registry.repoRoot(where)}.${await browse()}\n`;
|
|
399
|
+
if (command === "project" && operation === "link")
|
|
400
|
+
return `${await registry.repoRoot(where)} linked to project ${await registry.linkProject(requireOption(options, "--name"), where, options["--worktrees"])}.${await browse()}\n`;
|
|
401
|
+
// Removal moves records to the trash; nothing here empties it, which is the user's to do (Task 006).
|
|
402
|
+
if (command === "task" && operation === "remove")
|
|
403
|
+
return `${removalText(await registry.removeTask(requireOption(options, "--id")), registry.trash)}\n`;
|
|
404
|
+
if (command === "project" && operation === "remove")
|
|
405
|
+
return `${removalText(await registry.removeProject(requireOption(options, "--name")), registry.trash)}\n`;
|
|
406
|
+
if (command === "project" && operation === "list") {
|
|
407
|
+
const data = await registry.read();
|
|
408
|
+
const projects = Object.entries(data.projects);
|
|
409
|
+
if (!projects.length) return "No projects.\n";
|
|
410
|
+
const count = (slug) => Object.values(data.tasks).filter((task) => task.project === slug).length;
|
|
411
|
+
return `${projects.map(([slug, project]) => `- ${project.name} (${slug}): ${count(slug)} task(s); repositories ${project.repos.join(", ")}`).join("\n")}\n`;
|
|
412
|
+
}
|
|
413
|
+
if (command === "project" && operation === "show") {
|
|
414
|
+
const found = options["--name"] ? await registry.project(options["--name"]) : await registry.projectFor(where);
|
|
415
|
+
if (!found)
|
|
416
|
+
return options["--name"]
|
|
417
|
+
? `No project named ${options["--name"]}.\n`
|
|
418
|
+
: `No project is linked to ${await registry.repoRoot(where)}.\n`;
|
|
419
|
+
const lines = [`Project ${found.project.name} (${found.slug}), store ${found.project.store}`];
|
|
420
|
+
for (const { id, task } of await registry.projectTasks(found.slug))
|
|
421
|
+
lines.push(
|
|
422
|
+
`- ${id} — ${task.title} (${task.record})${task.parent ? `, child of ${task.parent}` : ""}${task.owner ? `, owned by session ${task.owner.session}` : ""}`,
|
|
423
|
+
);
|
|
424
|
+
return `${lines.join("\n")}\n`;
|
|
425
|
+
}
|
|
426
|
+
if (operation === "create") {
|
|
427
|
+
const title = requireOption(options, "--title");
|
|
428
|
+
const goal = requireOption(options, "--goal");
|
|
429
|
+
const parent = options["--parent"];
|
|
430
|
+
const slug = parent ? (await registry.task(parent))?.project : (await registry.projectFor(where))?.slug;
|
|
431
|
+
if (!slug)
|
|
432
|
+
throw new CliError(parent ? `No task ${parent}.` : `No project is linked to ${await registry.repoRoot(where)}.`);
|
|
433
|
+
const primary = parent ? undefined : await registry.repoRoot(where);
|
|
434
|
+
const created = await registry.createTask(slug, title, goal, parent, primary);
|
|
435
|
+
return `${created.id}\n${created.record}\n`;
|
|
436
|
+
}
|
|
437
|
+
if (operation === "import") {
|
|
438
|
+
const record = resolve(requireOption(options, "--record"));
|
|
439
|
+
const moved = await registry.importRecord(requireOption(options, "--project"), record);
|
|
440
|
+
return `${moved.id}\n${moved.record}\n`;
|
|
441
|
+
}
|
|
442
|
+
if (operation === "env") {
|
|
443
|
+
const id = requireOption(options, "--id");
|
|
444
|
+
if (options["--primary"] || options["--add-dir"] || options["--remove-dir"])
|
|
445
|
+
await registry.setEnvironment(id, {
|
|
446
|
+
primary: options["--primary"],
|
|
447
|
+
add: options["--add-dir"],
|
|
448
|
+
remove: options["--remove-dir"],
|
|
449
|
+
});
|
|
450
|
+
const env = await registry.environment(id);
|
|
451
|
+
if (!env.primary) return `${id} has no recorded directory.\n`;
|
|
452
|
+
const facts =
|
|
453
|
+
env.exists === false
|
|
454
|
+
? ["missing"]
|
|
455
|
+
: [env.worktree ? "Git worktree" : "", env.branch ? `branch ${env.branch}` : ""];
|
|
456
|
+
const state = facts.filter(Boolean).join(", ");
|
|
457
|
+
return `${[`primary: ${env.primary}${state ? ` (${state})` : ""}`, ...env.directories.map((dir) => `also: ${dir}`)].join("\n")}\n`;
|
|
458
|
+
}
|
|
459
|
+
if (operation === "here") {
|
|
460
|
+
const found = await registry.here(where);
|
|
461
|
+
if (!found.length) return `No registered task works in ${resolve(where)}.\n`;
|
|
462
|
+
return `${found.map(({ id, task }) => `${id} — ${task.title} (${task.environment.primary})`).join("\n")}\n`;
|
|
463
|
+
}
|
|
464
|
+
if (operation === "fanout") {
|
|
465
|
+
const result = await registry.fanout(
|
|
466
|
+
requireOption(options, "--parent"),
|
|
467
|
+
requireOption(options, "--title"),
|
|
468
|
+
requireOption(options, "--goal"),
|
|
469
|
+
{ path: options["--path"], base: options["--base"], cwd: where },
|
|
470
|
+
);
|
|
471
|
+
if (result.error) throw new CliError(result.error);
|
|
472
|
+
return `${result.id}\n${result.path}\nbranch ${result.branch}${result.copiedConfig ? "; copied .freeflow/local.json" : ""}\nNext: open a new terminal and run:\n ${startCommand(result.path, options["--agent"])}${options["--agent"] ? "" : " (then start the agent there)"}\n`;
|
|
473
|
+
}
|
|
474
|
+
if (operation === "search") {
|
|
475
|
+
const query = requireOption(options, "--query");
|
|
476
|
+
let records;
|
|
477
|
+
if (options["--id"]) records = await registry.scope(options["--id"], options["--scope"] ?? "task");
|
|
478
|
+
else {
|
|
479
|
+
const slug = (await registry.read()).projects[options["--project"] ?? ""] ? options["--project"] : undefined;
|
|
480
|
+
if (!slug) throw new CliError("Give --id with --scope, or --project with a project's slug.");
|
|
481
|
+
records = (await registry.projectTasks(slug)).map(({ id, task }) => [id, task.record]);
|
|
482
|
+
}
|
|
483
|
+
return `${await searchRecords(records, query)}\n`;
|
|
484
|
+
}
|
|
485
|
+
throw new CliError(`Unknown command: ${command} ${operation}`);
|
|
486
|
+
}
|
|
487
|
+
|
|
280
488
|
async function runCore(command, rest) {
|
|
281
489
|
const { options, positionals } = parseOptions(rest);
|
|
282
490
|
const operation = positionals[0];
|
|
283
491
|
if (options["--help"]) return commandHelp(command, operation);
|
|
284
492
|
validateCommandOptions(command, operation, options);
|
|
493
|
+
if (
|
|
494
|
+
command === "project" ||
|
|
495
|
+
(command === "task" && ["create", "import", "search", "env", "here", "fanout", "remove"].includes(operation))
|
|
496
|
+
)
|
|
497
|
+
return runRegistry(command, operation, options);
|
|
498
|
+
// A registered task's ID stands for its record's path.
|
|
499
|
+
if (typeof options["--record"] === "string" && TASK_ID.test(options["--record"])) {
|
|
500
|
+
const task = await new Registry().task(options["--record"]);
|
|
501
|
+
if (!task) throw new CliError(`No task ${options["--record"]} in the registry.`);
|
|
502
|
+
options["--record"] = task.record;
|
|
503
|
+
}
|
|
285
504
|
if (command === "init") return initialize(options);
|
|
286
505
|
if (command === "view") {
|
|
287
|
-
if (positionals.length > 1) throw new CliError("View accepts only resume or full");
|
|
288
506
|
const view = positionals[0] ?? options["--view"];
|
|
289
|
-
if (!view || !["resume", "full"].includes(view))
|
|
507
|
+
if (!view || !["resume", "recover", "full", "entry"].includes(view))
|
|
508
|
+
throw new CliError("View must be resume, recover, full, or entry");
|
|
509
|
+
const ids = positionals.slice(1);
|
|
510
|
+
if (view === "entry") {
|
|
511
|
+
if (!ids.length) throw new CliError("View entry needs at least one S-NNN, C-NNN, or D-NNN ID");
|
|
512
|
+
const invalid = ids.find((id) => !/^[SCD]-\d{3,}$/.test(id));
|
|
513
|
+
if (invalid) throw new CliError(`Not an entry ID: ${invalid}`);
|
|
514
|
+
} else if (ids.length) throw new CliError(`View ${view} accepts no further arguments`);
|
|
290
515
|
const loaded = await readExisting(options);
|
|
291
516
|
if (view === "full") return renderFull(loaded.text);
|
|
517
|
+
if (view === "entry") return renderEntries(loaded.text, ids);
|
|
518
|
+
if (view === "recover") return renderRecover(loaded.text, { root: loaded.root, recordPath: loaded.path });
|
|
292
519
|
return renderResume(loaded.text);
|
|
293
520
|
}
|
|
294
521
|
if (command === "validate") {
|
|
295
522
|
if (positionals.length) throw new CliError("Validate does not accept positional arguments");
|
|
296
523
|
const loaded = await readExisting(options);
|
|
297
524
|
validateDocument(parseDocument(loaded.text));
|
|
298
|
-
|
|
525
|
+
const pointers = checkEvidencePointers(loaded.text, { root: loaded.root, recordPath: loaded.path });
|
|
526
|
+
const outside = pointers.outside.length
|
|
527
|
+
? `\n${pointers.outside.length} evidence pointer(s) outside the repository, not checked:\n${pointers.outside.map((each) => `- ${each}`).join("\n")}`
|
|
528
|
+
: "";
|
|
529
|
+
// Unresolved pointers warn: a record may name a planned path or a commit not fetched yet. --strict fails on those
|
|
530
|
+
// an Evidence or Result line claims exist.
|
|
531
|
+
const unresolved = options["--strict"] ? pointers.warnings : [...pointers.problems, ...pointers.warnings];
|
|
532
|
+
const warnings = unresolved.length
|
|
533
|
+
? `\n${unresolved.length} pointer(s) in Material updates do not resolve here (a planned path, or a commit not fetched?):\n${unresolved.map((each) => `- ${each}`).join("\n")}`
|
|
534
|
+
: "";
|
|
535
|
+
if (options["--strict"] && pointers.problems.length)
|
|
536
|
+
throw new CliError(
|
|
537
|
+
`Evidence pointers on Evidence or Result lines do not resolve:\n${pointers.problems.map((each) => `- ${each}`).join("\n")}${warnings}${outside}`,
|
|
538
|
+
);
|
|
539
|
+
return `valid\n${displayPath(loaded.root, loaded.path)}\n${pointers.checked} evidence pointer(s) checked${warnings}${outside}\n`;
|
|
299
540
|
}
|
|
300
541
|
if (positionals.length !== 1) throw new CliError(`Expected one operation for ${command}`);
|
|
301
542
|
const loaded = await readExisting(options);
|