@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
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Checks documentation written with the Write Docs shapes (references/documentation-shapes.md):
|
|
3
|
+
// - every repository path a document names in backticks exists;
|
|
4
|
+
// - for a document whose header has Covers and Verified at, lists covered files changed since that commit
|
|
5
|
+
// (committed or not), so a reader knows which documents may be stale.
|
|
6
|
+
// With --covering, it instead lists the documents whose Covers include each given repository path (that file, or a
|
|
7
|
+
// covered directory holding it), with their Verified at and whether they are stale, and how many searched documents
|
|
8
|
+
// have no Covers line. Without document arguments it searches the project's docs index: the first of `dev-docs/`
|
|
9
|
+
// (holding README.md), `ARCHITECTURE.md`, and `docs/` (holding README.md).
|
|
10
|
+
// With --driven, a covered change counts even when it was made together with the document: for a feature file, whose
|
|
11
|
+
// Verified at is the last commit it was driven live at, editing its text is not driving it.
|
|
12
|
+
// Usage: docs-check.mjs <file-or-directory>... [--root <repository>] [--strict] [--driven] [--json]
|
|
13
|
+
// docs-check.mjs [<file-or-directory>...] --covering <path> [--covering <path>]... [--root <repository>] [--json]
|
|
14
|
+
// Exit code 1 when a named path is missing, a header is invalid, or (with --strict) covered code changed. A --covering
|
|
15
|
+
// lookup reports and exits 0, or 2 when no documents can be found.
|
|
16
|
+
import { execFileSync } from "node:child_process";
|
|
17
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
18
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
19
|
+
import { parseArgs } from "node:util";
|
|
20
|
+
|
|
21
|
+
const { values, positionals } = parseArgs({
|
|
22
|
+
allowPositionals: true,
|
|
23
|
+
options: {
|
|
24
|
+
root: { type: "string" },
|
|
25
|
+
strict: { type: "boolean", default: false },
|
|
26
|
+
driven: { type: "boolean", default: false },
|
|
27
|
+
json: { type: "boolean", default: false },
|
|
28
|
+
covering: { type: "string", multiple: true },
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
const usage = () => {
|
|
32
|
+
console.error(
|
|
33
|
+
"Usage: docs-check.mjs <file-or-directory>... [--root <repository>] [--strict] [--driven] [--json]\n" +
|
|
34
|
+
" docs-check.mjs [<file-or-directory>...] --covering <path> [--covering <path>]... [--root <repository>] [--json]",
|
|
35
|
+
);
|
|
36
|
+
process.exit(2);
|
|
37
|
+
};
|
|
38
|
+
if (!positionals.length && !values.covering) usage();
|
|
39
|
+
|
|
40
|
+
const git = (cwd, args) => execFileSync("git", args, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
41
|
+
const root = resolve(
|
|
42
|
+
values.root ??
|
|
43
|
+
(() => {
|
|
44
|
+
try {
|
|
45
|
+
return git(process.cwd(), ["rev-parse", "--show-toplevel"]).trim();
|
|
46
|
+
} catch {
|
|
47
|
+
return process.cwd();
|
|
48
|
+
}
|
|
49
|
+
})(),
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
function markdownFiles(path) {
|
|
53
|
+
const full = resolve(path);
|
|
54
|
+
if (!existsSync(full)) return [{ missingInput: full }];
|
|
55
|
+
if (statSync(full).isFile()) return full.endsWith(".md") ? [full] : [];
|
|
56
|
+
return readdirSync(full, { withFileTypes: true }).flatMap((entry) =>
|
|
57
|
+
entry.name.startsWith(".") || entry.name === "node_modules" ? [] : markdownFiles(join(full, entry.name)),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const HEADER = /^>\s*\*\*(Covers|Tests|Verified at|User docs):\*\*\s*(.*)$/;
|
|
62
|
+
const ticks = (text) => [...text.matchAll(/`([^`\n]+)`/g)].map((match) => match[1].trim());
|
|
63
|
+
// A repository path: segments joined by "/", no spaces, no URL scheme, no placeholders or globs.
|
|
64
|
+
const PATH = /^[A-Za-z0-9_.@-]+(\/[A-Za-z0-9_.@-]+)*\/?$/;
|
|
65
|
+
const looksLikePath = (token) => PATH.test(token) && token.includes("/") && !token.includes("://");
|
|
66
|
+
// The header names paths on purpose, so a root-level file (`command-surface.json`) counts there too.
|
|
67
|
+
const headerPath = (token) => looksLikePath(token) || (PATH.test(token) && /^[^/]+\.[A-Za-z0-9]+$/.test(token));
|
|
68
|
+
// A named path outside a header counts only when its first segment exists in the repository and is not hidden or
|
|
69
|
+
// relative, so commands, examples, other tools' conventions (`.claude/skills/`), and import spellings (`./x.js`)
|
|
70
|
+
// are not mistaken for this repository's files.
|
|
71
|
+
const repoPath = (token) => !token.startsWith(".") && existsSync(join(root, token.split("/")[0]));
|
|
72
|
+
|
|
73
|
+
function check(file) {
|
|
74
|
+
const text = readFileSync(file, "utf8");
|
|
75
|
+
const header = {};
|
|
76
|
+
for (const line of text.split("\n").slice(0, 30)) {
|
|
77
|
+
const match = HEADER.exec(line);
|
|
78
|
+
if (match) header[match[1]] = match[2];
|
|
79
|
+
}
|
|
80
|
+
const errors = [];
|
|
81
|
+
const named = new Set();
|
|
82
|
+
for (const key of ["Covers", "Tests", "User docs"])
|
|
83
|
+
for (const token of header[key] ? ticks(header[key]) : [])
|
|
84
|
+
if (headerPath(token)) named.add(token);
|
|
85
|
+
else errors.push(`${key} names something that is not a repository path: ${token}`);
|
|
86
|
+
// Body paths outside fenced code blocks: code blocks hold commands and examples, not claims about this repository.
|
|
87
|
+
const prose = text.replace(/^```[\s\S]*?^```/gm, "");
|
|
88
|
+
for (const token of ticks(prose)) if (looksLikePath(token) && repoPath(token)) named.add(token);
|
|
89
|
+
// A path resolves from the repository root or, as a link would, from the document's own directory.
|
|
90
|
+
const exists = (path) => [root, dirname(file)].some((base) => existsSync(join(base, path.replace(/\/$/, ""))));
|
|
91
|
+
const missing = [...named].filter((path) => !exists(path));
|
|
92
|
+
|
|
93
|
+
let stale;
|
|
94
|
+
if (header["Verified at"] !== undefined) {
|
|
95
|
+
const commit = ticks(header["Verified at"])[0];
|
|
96
|
+
const covers = header.Covers ? ticks(header.Covers).filter(headerPath) : [];
|
|
97
|
+
if (!commit) errors.push("Verified at names no commit in backticks");
|
|
98
|
+
else if (!covers.length) errors.push("Verified at needs a Covers line naming the code it was verified against");
|
|
99
|
+
else {
|
|
100
|
+
try {
|
|
101
|
+
git(root, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
102
|
+
const lines = (args) => git(root, args).split("\n").filter(Boolean);
|
|
103
|
+
// A change made together with the document (same commit, or both uncommitted) was reviewed with it.
|
|
104
|
+
const self = relative(root, file);
|
|
105
|
+
const withDoc = new Set(lines(["log", "--format=%H", `${commit}..HEAD`, "--", self]));
|
|
106
|
+
const docDirty = lines(["status", "--porcelain", "--", self]).length > 0;
|
|
107
|
+
const changed = lines(["diff", "--name-only", commit, "--", ...covers]).filter(
|
|
108
|
+
(path) =>
|
|
109
|
+
values.driven ||
|
|
110
|
+
lines(["log", "--format=%H", `${commit}..HEAD`, "--", path]).some((each) => !withDoc.has(each)) ||
|
|
111
|
+
(!docDirty && lines(["status", "--porcelain", "--", path]).length > 0),
|
|
112
|
+
);
|
|
113
|
+
stale = { since: commit, changed };
|
|
114
|
+
} catch {
|
|
115
|
+
errors.push(`Verified at names a commit this repository does not have: ${commit}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const covers = header.Covers ? ticks(header.Covers).filter(headerPath) : [];
|
|
120
|
+
const verifiedAt = header["Verified at"] !== undefined ? (ticks(header["Verified at"])[0] ?? null) : null;
|
|
121
|
+
return { path: relative(root, file), header: Object.keys(header), covers, verifiedAt, missing, stale, errors };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// The project's docs index, in the order Write Docs' "Starting Developer Docs" names.
|
|
125
|
+
function docsIndex() {
|
|
126
|
+
if (existsSync(join(root, "dev-docs/README.md"))) return join(root, "dev-docs");
|
|
127
|
+
if (existsSync(join(root, "ARCHITECTURE.md"))) return join(root, "ARCHITECTURE.md");
|
|
128
|
+
if (existsSync(join(root, "docs", "README.md"))) return join(root, "docs");
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// A covered entry includes a path when it names that path, or names a directory holding it.
|
|
133
|
+
const includes = (covered, path) => {
|
|
134
|
+
const entry = covered.replace(/\/$/, "");
|
|
135
|
+
return path === entry || path.startsWith(`${entry}/`);
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
function covering(paths) {
|
|
139
|
+
const inputs = positionals.length ? positionals.map((input) => resolve(input)) : [docsIndex()].filter(Boolean);
|
|
140
|
+
if (!inputs.length) {
|
|
141
|
+
console.error(
|
|
142
|
+
"docs-check: no developer docs found (dev-docs/README.md, ARCHITECTURE.md, a README.md in docs/); pass the docs to search",
|
|
143
|
+
);
|
|
144
|
+
process.exit(2);
|
|
145
|
+
}
|
|
146
|
+
const documents = inputs
|
|
147
|
+
.flatMap(markdownFiles)
|
|
148
|
+
.filter((file) => typeof file === "string")
|
|
149
|
+
.map(check);
|
|
150
|
+
const queries = paths.map((path) => relative(root, resolve(root, path)).replace(/\/$/, ""));
|
|
151
|
+
const results = queries.map((path) => ({
|
|
152
|
+
path,
|
|
153
|
+
documents: documents
|
|
154
|
+
.filter((doc) => doc.covers.some((covered) => includes(covered, path)))
|
|
155
|
+
.map((doc) => ({
|
|
156
|
+
path: doc.path,
|
|
157
|
+
verifiedAt: doc.verifiedAt,
|
|
158
|
+
state: doc.stale === undefined ? "unverified" : doc.stale.changed.length ? "stale" : "current",
|
|
159
|
+
changed: doc.stale?.changed ?? [],
|
|
160
|
+
})),
|
|
161
|
+
}));
|
|
162
|
+
const withoutCovers = documents.filter((doc) => !doc.covers.length).map((doc) => doc.path);
|
|
163
|
+
if (values.json)
|
|
164
|
+
console.log(
|
|
165
|
+
JSON.stringify(
|
|
166
|
+
{
|
|
167
|
+
command: "docs-check",
|
|
168
|
+
mode: "covering",
|
|
169
|
+
root,
|
|
170
|
+
searched: inputs.map((input) => relative(root, input) || "."),
|
|
171
|
+
documents: documents.length,
|
|
172
|
+
withoutCovers,
|
|
173
|
+
paths: results,
|
|
174
|
+
},
|
|
175
|
+
null,
|
|
176
|
+
2,
|
|
177
|
+
),
|
|
178
|
+
);
|
|
179
|
+
else {
|
|
180
|
+
for (const result of results) {
|
|
181
|
+
console.log(result.path);
|
|
182
|
+
if (!result.documents.length) console.log(" no covering document");
|
|
183
|
+
for (const doc of result.documents) {
|
|
184
|
+
const changed = doc.changed.length ? `, ${doc.changed.length} covered file(s) changed since` : "";
|
|
185
|
+
console.log(` ${doc.path} (verified at ${doc.verifiedAt ?? "none"}: ${doc.state}${changed})`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
console.log(
|
|
189
|
+
`${documents.length} documents searched; ${withoutCovers.length} have no Covers line, so no lookup can find them.`,
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
process.exit(0);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (values.covering) covering(values.covering);
|
|
196
|
+
|
|
197
|
+
const documents = [];
|
|
198
|
+
const inputErrors = [];
|
|
199
|
+
for (const input of positionals)
|
|
200
|
+
for (const file of markdownFiles(input))
|
|
201
|
+
if (typeof file === "object") inputErrors.push(`no such file or directory: ${file.missingInput}`);
|
|
202
|
+
else documents.push(check(file));
|
|
203
|
+
|
|
204
|
+
const failed =
|
|
205
|
+
inputErrors.length > 0 ||
|
|
206
|
+
documents.some((doc) => doc.missing.length || doc.errors.length || (values.strict && doc.stale?.changed.length));
|
|
207
|
+
if (values.json)
|
|
208
|
+
console.log(
|
|
209
|
+
JSON.stringify({ command: "docs-check", root, status: failed ? "fail" : "pass", inputErrors, documents }, null, 2),
|
|
210
|
+
);
|
|
211
|
+
else {
|
|
212
|
+
for (const error of inputErrors) console.log(`error: ${error}`);
|
|
213
|
+
for (const doc of documents) {
|
|
214
|
+
const lines = [
|
|
215
|
+
...doc.errors.map((error) => ` error: ${error}`),
|
|
216
|
+
...doc.missing.map((path) => ` missing: ${path}`),
|
|
217
|
+
...(doc.stale?.changed.length
|
|
218
|
+
? [` ${values.strict ? "error" : "warning"}: covered code changed since ${doc.stale.since}:`]
|
|
219
|
+
: []),
|
|
220
|
+
...(doc.stale?.changed ?? []).map((path) => ` ${path}`),
|
|
221
|
+
];
|
|
222
|
+
if (lines.length) console.log(`${doc.path}\n${lines.join("\n")}`);
|
|
223
|
+
}
|
|
224
|
+
const stale = documents.filter((doc) => doc.stale?.changed.length).length;
|
|
225
|
+
console.log(
|
|
226
|
+
`${documents.length} documents checked: ${documents.filter((doc) => doc.missing.length || doc.errors.length).length} with errors, ${stale} with covered code changed since verified.`,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
process.exit(failed ? 1 : 0);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Checks that every step of a Plan names the check that will show it worked (references/spec-and-plan-shapes.md).
|
|
3
|
+
// A step is a "### Slice" or "### Step" block, or an item of the list under "Ordered actions or slices", "Steps" or
|
|
4
|
+
// another heading that holds the Plan's ordered work. A block names its check in a filled field such as "Tests or
|
|
5
|
+
// observations:", "Check:" or "Verification claim...:"; a list item names it inline ("check: ...", "verify ...",
|
|
6
|
+
// "test ...", "observe ..."). It checks presence only; whether the check could catch a wrong result is the author's
|
|
7
|
+
// and the reviewer's judgment.
|
|
8
|
+
// Usage: plan-lint.mjs <plan.md>... [--json]
|
|
9
|
+
// Exit code 0 when every step names a check, 1 when a step does not or no step was found, 2 on a usage error.
|
|
10
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
+
import { resolve } from "node:path";
|
|
12
|
+
import { parseArgs } from "node:util";
|
|
13
|
+
|
|
14
|
+
const USAGE = "Usage: plan-lint.mjs <plan.md>... [--json]";
|
|
15
|
+
let parsed;
|
|
16
|
+
try {
|
|
17
|
+
parsed = parseArgs({ allowPositionals: true, options: { json: { type: "boolean", default: false } } });
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.error(`${error.message}\n${USAGE}`);
|
|
20
|
+
process.exit(2);
|
|
21
|
+
}
|
|
22
|
+
const { values, positionals } = parsed;
|
|
23
|
+
if (!positionals.length) {
|
|
24
|
+
console.error(USAGE);
|
|
25
|
+
process.exit(2);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const STEP_HEADING = /^#{2,4}\s+(Slice|Step|Phase step|Task)\b/i;
|
|
29
|
+
const LIST_HEADING = /^(#{2,4}\s+)?(Ordered actions( or slices)?|Steps|Ordered steps|Actions|Slices|Work)\s*:?\s*$/i;
|
|
30
|
+
const CHECK_FIELD =
|
|
31
|
+
/^\s*(?:[-*]\s+)?(?:\*\*)?(?:[A-Za-z]+ and )?(Tests?( or observations)?|Checks?|Verification( claims?)?( and required boundar(y|ies))?|Verify|Observations?|Acceptance|Evidence|Final tests or observations)(?:\*\*)?\s*:(?:\*\*)?\s*(.*)$/i;
|
|
32
|
+
const INLINE_CHECK =
|
|
33
|
+
/\b(check(ed|s)?|verif(y|ied|ies)|tests?|observe[ds]?|assert|confirm(ed|s)?|run `|passes|fails?)\b/i;
|
|
34
|
+
const EMPTY = /^\s*(|-|—|none|n\/a|tbd|todo|\[.*\])\s*$/i;
|
|
35
|
+
|
|
36
|
+
function lint(file) {
|
|
37
|
+
const lines = readFileSync(file, "utf8")
|
|
38
|
+
.replace(/```[\s\S]*?```/g, (block) => block.replace(/[^\n]/g, ""))
|
|
39
|
+
.split("\n");
|
|
40
|
+
const steps = [];
|
|
41
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
42
|
+
const line = lines[index];
|
|
43
|
+
if (STEP_HEADING.test(line)) {
|
|
44
|
+
const level = /^(#+)/.exec(line)[1].length;
|
|
45
|
+
let end = index + 1;
|
|
46
|
+
while (end < lines.length && !(/^#{1,4}\s/.test(lines[end]) && /^(#+)/.exec(lines[end])[1].length <= level))
|
|
47
|
+
end += 1;
|
|
48
|
+
const body = lines.slice(index + 1, end);
|
|
49
|
+
// A field is filled on its own line, or by the list under it ("**Checks:**" then bullets).
|
|
50
|
+
const fields = body
|
|
51
|
+
.map((each, at) => {
|
|
52
|
+
const field = CHECK_FIELD.exec(each);
|
|
53
|
+
if (!field || !EMPTY.test(field.at(-1))) return field;
|
|
54
|
+
for (
|
|
55
|
+
let next = at + 1;
|
|
56
|
+
next < body.length && !/^\s*(\*\*)?[A-Z][^:]{0,60}:(\*\*)?\s*/.test(body[next]);
|
|
57
|
+
next += 1
|
|
58
|
+
) {
|
|
59
|
+
const item = /^\s*(?:[-*]|\d+[.)])\s+(\S.*)$/.exec(body[next]);
|
|
60
|
+
if (item) return [...field.slice(0, -1), item[1]];
|
|
61
|
+
}
|
|
62
|
+
return field;
|
|
63
|
+
})
|
|
64
|
+
.filter(Boolean);
|
|
65
|
+
const filled = fields.find((field) => !EMPTY.test(field.at(-1)));
|
|
66
|
+
steps.push({
|
|
67
|
+
line: index + 1,
|
|
68
|
+
step: line.replace(/^#+\s+/, "").trim(),
|
|
69
|
+
check: filled ? `${filled[1]}: ${filled.at(-1)}`.trim() : null,
|
|
70
|
+
problem: filled ? null : fields.length ? "its check field is empty" : "names no check",
|
|
71
|
+
});
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (LIST_HEADING.test(line.trim())) {
|
|
75
|
+
for (let at = index + 1; at < lines.length && !/^#{1,4}\s/.test(lines[at]); at += 1) {
|
|
76
|
+
const item = /^(\s*)(?:\d+[.)]|[-*])\s+(.*)$/.exec(lines[at]);
|
|
77
|
+
if (!item || item[1].length > 1) {
|
|
78
|
+
if (lines[at].trim() && !item && /^[A-Z][^:]{0,40}:\s*/.test(lines[at].trim())) break;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// A step's check may sit on its own nested lines.
|
|
82
|
+
const nested = [];
|
|
83
|
+
for (let next = at + 1; next < lines.length && /^\s{2,}\S/.test(lines[next]); next += 1)
|
|
84
|
+
nested.push(lines[next]);
|
|
85
|
+
const text = [item[2], ...nested].join(" ");
|
|
86
|
+
steps.push({
|
|
87
|
+
line: at + 1,
|
|
88
|
+
step: item[2].trim().slice(0, 120),
|
|
89
|
+
check: INLINE_CHECK.test(text) ? text.match(INLINE_CHECK)[0] : null,
|
|
90
|
+
problem: INLINE_CHECK.test(text) ? null : "names no check",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return { path: file, steps, problems: steps.filter((step) => step.problem) };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const results = [];
|
|
99
|
+
const inputErrors = [];
|
|
100
|
+
for (const input of positionals) {
|
|
101
|
+
const file = resolve(input);
|
|
102
|
+
if (!existsSync(file)) inputErrors.push(`no such file: ${input}`);
|
|
103
|
+
else results.push(lint(file));
|
|
104
|
+
}
|
|
105
|
+
const failed = inputErrors.length > 0 || results.some((result) => !result.steps.length || result.problems.length);
|
|
106
|
+
if (values.json)
|
|
107
|
+
console.log(
|
|
108
|
+
JSON.stringify({ command: "plan-lint", status: failed ? "fail" : "pass", inputErrors, results }, null, 2),
|
|
109
|
+
);
|
|
110
|
+
else {
|
|
111
|
+
for (const error of inputErrors) console.log(`error: ${error}`);
|
|
112
|
+
for (const result of results) {
|
|
113
|
+
if (!result.steps.length) {
|
|
114
|
+
console.log(
|
|
115
|
+
`${result.path}: no steps found (### Slice or ### Step blocks, or a list under "Ordered actions or slices" or "Steps")`,
|
|
116
|
+
);
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
console.log(`${result.path}: ${result.steps.length} step(s), ${result.problems.length} without a check`);
|
|
120
|
+
for (const step of result.problems) console.log(` line ${step.line}: ${step.step} — ${step.problem}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
process.exit(failed ? 1 : 0);
|