pstack-claude-mirror 0.0.0-stage → 0.9.133
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/.claude-plugin/marketplace.json +16 -0
- package/CHANGES.md +1110 -0
- package/LICENSE +22 -0
- package/LICENSE-cursor-team-kit +21 -0
- package/LICENSE-mirror +27 -0
- package/LICENSE-thermos +21 -0
- package/NOTICE-skills.md +13 -0
- package/NOTICE.md +62 -0
- package/README.md +84 -2
- package/UPSTREAM-README.md +243 -0
- package/bin/pstack-claude.mjs +183 -0
- package/docs/reference.md +247 -0
- package/package.json +88 -4
- package/plugins/pstack/.antigravity-plugin/plugin.json +8 -0
- package/plugins/pstack/.claude-plugin/icon.png +0 -0
- package/plugins/pstack/.claude-plugin/plugin.json +31 -0
- package/plugins/pstack/.codex-plugin/plugin.json +52 -0
- package/plugins/pstack/.github/plugin/plugin.json +15 -0
- package/plugins/pstack/.grok-plugin/plugin.json +9 -0
- package/plugins/pstack/.muse-plugin/plugin.json +381 -0
- package/plugins/pstack/README.md +27 -0
- package/plugins/pstack/agents/comment-sicko.md +34 -0
- package/plugins/pstack/agents/poteto-agent.md +8 -0
- package/plugins/pstack/agents/thermo-nuclear-code-quality-review-subagent.md +23 -0
- package/plugins/pstack/agents/thermo-nuclear-review-subagent.md +28 -0
- package/plugins/pstack/assets/pstack-icon.png +0 -0
- package/plugins/pstack/assets/pstack-icon.prompt.txt +8 -0
- package/plugins/pstack/grok/skills/pstack-routing/SKILL.md +8 -0
- package/plugins/pstack/hooks/agy-context.awk +9 -0
- package/plugins/pstack/hooks/codex-hooks.json +17 -0
- package/plugins/pstack/hooks/copilot-context.awk +44 -0
- package/plugins/pstack/hooks/copilot-hooks.json +27 -0
- package/plugins/pstack/hooks/hooks.json +16 -0
- package/plugins/pstack/hooks/json.awk +164 -0
- package/plugins/pstack/hooks/kimi-instructions.md +17 -0
- package/plugins/pstack/hooks/muse-context.awk +31 -0
- package/plugins/pstack/hooks/pre-tool-use.awk +152 -0
- package/plugins/pstack/hooks/pre-tool-use.sh +16 -0
- package/plugins/pstack/hooks/script-contracts.awk +55 -0
- package/plugins/pstack/hooks/session-start-agy.md +17 -0
- package/plugins/pstack/hooks/session-start-context.md +15 -0
- package/plugins/pstack/hooks/session-start-copilot-setup.md +1 -0
- package/plugins/pstack/hooks/session-start-copilot-sheet.md +1 -0
- package/plugins/pstack/hooks/session-start-copilot.md +3 -0
- package/plugins/pstack/hooks/session-start-minimax.md +17 -0
- package/plugins/pstack/hooks/session-start-muse-sheet.md +1 -0
- package/plugins/pstack/hooks/session-start-muse.md +17 -0
- package/plugins/pstack/hooks/session-start-opencode.md +17 -0
- package/plugins/pstack/hooks/session-start.ps1 +105 -0
- package/plugins/pstack/hooks/session-start.sh +95 -0
- package/plugins/pstack/hooks.json +10 -0
- package/plugins/pstack/models.json +67 -0
- package/plugins/pstack/omp/index.mjs +34 -0
- package/plugins/pstack/opencode/index.js +49 -0
- package/plugins/pstack/package.json +8 -0
- package/plugins/pstack/pi/agent-files.ts +117 -0
- package/plugins/pstack/pi/agent-text.ts +99 -0
- package/plugins/pstack/pi/agent-tools.ts +148 -0
- package/plugins/pstack/pi/agents.ts +486 -0
- package/plugins/pstack/pi/ask.ts +87 -0
- package/plugins/pstack/pi/child.ts +310 -0
- package/plugins/pstack/pi/config.ts +178 -0
- package/plugins/pstack/pi/index.ts +44 -0
- package/plugins/pstack/pi/one-shot.ts +90 -0
- package/plugins/pstack/pi/path-skills.ts +54 -0
- package/plugins/pstack/pi/prompt.ts +39 -0
- package/plugins/pstack/pi/schedule.ts +254 -0
- package/plugins/pstack/pi/slash.ts +92 -0
- package/plugins/pstack/pi/sleep-wait.ts +76 -0
- package/plugins/pstack/pi/worktree.ts +74 -0
- package/plugins/pstack/skills/architect/SKILL.md +100 -0
- package/plugins/pstack/skills/architect/references/design-red-flags.md +57 -0
- package/plugins/pstack/skills/architect/references/rationale-template.md +39 -0
- package/plugins/pstack/skills/architect/references/runner-prompt.md +20 -0
- package/plugins/pstack/skills/arena/SKILL.md +66 -0
- package/plugins/pstack/skills/automate-me/SKILL.md +111 -0
- package/plugins/pstack/skills/babysit/SKILL.md +68 -0
- package/plugins/pstack/skills/benchmark-checklist/SKILL.md +38 -0
- package/plugins/pstack/skills/blast-radius/SKILL.md +49 -0
- package/plugins/pstack/skills/bro/SKILL.md +6 -0
- package/plugins/pstack/skills/correct/SKILL.md +31 -0
- package/plugins/pstack/skills/create-formal-verification-skill/SKILL.md +50 -0
- package/plugins/pstack/skills/create-verification-skill/SKILL.md +51 -0
- package/plugins/pstack/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
- package/plugins/pstack/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
- package/plugins/pstack/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
- package/plugins/pstack/skills/deslop/SKILL.md +24 -0
- package/plugins/pstack/skills/figure-it-out/SKILL.md +51 -0
- package/plugins/pstack/skills/fix-ci/SKILL.md +29 -0
- package/plugins/pstack/skills/fix-merge-conflicts/SKILL.md +32 -0
- package/plugins/pstack/skills/get-pr-comments/SKILL.md +23 -0
- package/plugins/pstack/skills/how/SKILL.md +54 -0
- package/plugins/pstack/skills/how/references/explainer-prompt.md +55 -0
- package/plugins/pstack/skills/how/references/explorer-prompt.md +35 -0
- package/plugins/pstack/skills/in-your-own-words/SKILL.md +6 -0
- package/plugins/pstack/skills/interrogate/SKILL.md +48 -0
- package/plugins/pstack/skills/ketchup/SKILL.md +42 -0
- package/plugins/pstack/skills/ketchup-video/SKILL.md +28 -0
- package/plugins/pstack/skills/maintain-formal-verification-skill/SKILL.md +65 -0
- package/plugins/pstack/skills/maintain-verification-skill/SKILL.md +46 -0
- package/plugins/pstack/skills/make-pr-easy-to-review/SKILL.md +59 -0
- package/plugins/pstack/skills/no-comments/SKILL.md +45 -0
- package/plugins/pstack/skills/poteto-help/SKILL.md +149 -0
- package/plugins/pstack/skills/poteto-help/references/prompting.md +51 -0
- package/plugins/pstack/skills/poteto-help/references/recipes.md +51 -0
- package/plugins/pstack/skills/poteto-mode/SKILL.md +174 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/autopilot-full.md +31 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/autopilot-stack.md +8 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/babysit.md +23 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/bug-fix.md +15 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/eval.md +25 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/feature.md +21 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/hillclimb.md +21 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/investigation.md +14 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/multi-phase-plan.md +158 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/opening-a-pr.md +34 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/orchestrate.md +27 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/pause-safely.md +11 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/perf-issue.md +25 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/prototype.md +14 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/refactoring.md +18 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/session-pickup.md +11 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/shipping.md +16 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/trace-forensics.md +14 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/visual-parity.md +11 -0
- package/plugins/pstack/skills/poteto-mode/playbooks/worktree-cleanup.md +12 -0
- package/plugins/pstack/skills/poteto-mode/references/agents/comment-sicko.md +34 -0
- package/plugins/pstack/skills/poteto-mode/references/agy-tools.md +99 -0
- package/plugins/pstack/skills/poteto-mode/references/bugbot-triage.md +142 -0
- package/plugins/pstack/skills/poteto-mode/references/codex-tools.md +109 -0
- package/plugins/pstack/skills/poteto-mode/references/copilot-tools.md +143 -0
- package/plugins/pstack/skills/poteto-mode/references/grok.md +50 -0
- package/plugins/pstack/skills/poteto-mode/references/kimi-tools.md +40 -0
- package/plugins/pstack/skills/poteto-mode/references/licenses/LICENSE +22 -0
- package/plugins/pstack/skills/poteto-mode/references/licenses/LICENSE-cursor-team-kit +21 -0
- package/plugins/pstack/skills/poteto-mode/references/licenses/LICENSE-thermos +21 -0
- package/plugins/pstack/skills/poteto-mode/references/licenses/NOTICE.md +13 -0
- package/plugins/pstack/skills/poteto-mode/references/merge-safety.md +43 -0
- package/plugins/pstack/skills/poteto-mode/references/minimax-tools.md +93 -0
- package/plugins/pstack/skills/poteto-mode/references/muse-tools.md +105 -0
- package/plugins/pstack/skills/poteto-mode/references/omp-tools.md +39 -0
- package/plugins/pstack/skills/poteto-mode/references/opencode-tools.md +29 -0
- package/plugins/pstack/skills/poteto-mode/references/pi-tools.md +117 -0
- package/plugins/pstack/skills/poteto-mode/references/resume-storage.md +20 -0
- package/plugins/pstack/skills/poteto-mode/scripts/.prettierignore +23 -0
- package/plugins/pstack/skills/poteto-mode/scripts/.prettierrc.json +3 -0
- package/plugins/pstack/skills/poteto-mode/scripts/bootstrap.ts +71 -0
- package/plugins/pstack/skills/poteto-mode/scripts/bun.lock +67 -0
- package/plugins/pstack/skills/poteto-mode/scripts/check-plan.mjs +214 -0
- package/plugins/pstack/skills/poteto-mode/scripts/check-plan.test.ts +115 -0
- package/plugins/pstack/skills/poteto-mode/scripts/check-playbooks.mjs +71 -0
- package/plugins/pstack/skills/poteto-mode/scripts/codex-session-effort.mjs +66 -0
- package/plugins/pstack/skills/poteto-mode/scripts/package.json +16 -0
- package/plugins/pstack/skills/poteto-mode/scripts/resume.mjs +139 -0
- package/plugins/pstack/skills/poteto-mode/scripts/tsconfig.json +14 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/cli.test.ts +383 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/cli.ts +266 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/deadline.ts +20 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.ts +157 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/fresh-install.test.ts +35 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/github.test.ts +902 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/github.ts +922 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/integrity.test.ts +887 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/landing.ts +92 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/live-merge-safety.mjs +142 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/policy.test.ts +1151 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/policy.ts +956 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/render.ts +200 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/ship-pr +6 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/shipping-cli.test.ts +159 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/shipping-cli.ts +65 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/shipping.test-helper.ts +48 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/shipping.test.ts +360 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/shipping.ts +235 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/transport.test.ts +211 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/tsconfig.json +13 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/types.compile.ts +108 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/types.ts +474 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/watch-pr +6 -0
- package/plugins/pstack/skills/poteto-mode/scripts/watch-pr/wrapper.test.ts +20 -0
- package/plugins/pstack/skills/poteto-mode/scripts/worktree-audit.mjs +434 -0
- package/plugins/pstack/skills/principle-attack-the-premise/SKILL.md +21 -0
- package/plugins/pstack/skills/principle-boundary-discipline/SKILL.md +34 -0
- package/plugins/pstack/skills/principle-build-the-lever/SKILL.md +24 -0
- package/plugins/pstack/skills/principle-encode-lessons-in-structure/SKILL.md +11 -0
- package/plugins/pstack/skills/principle-exhaust-the-design-space/SKILL.md +9 -0
- package/plugins/pstack/skills/principle-experience-first/SKILL.md +19 -0
- package/plugins/pstack/skills/principle-explain-the-number/SKILL.md +18 -0
- package/plugins/pstack/skills/principle-fix-root-causes/SKILL.md +21 -0
- package/plugins/pstack/skills/principle-foundational-thinking/SKILL.md +21 -0
- package/plugins/pstack/skills/principle-guard-the-context-window/SKILL.md +12 -0
- package/plugins/pstack/skills/principle-laziness-protocol/SKILL.md +10 -0
- package/plugins/pstack/skills/principle-make-operations-idempotent/SKILL.md +22 -0
- package/plugins/pstack/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +14 -0
- package/plugins/pstack/skills/principle-minimize-reader-load/SKILL.md +18 -0
- package/plugins/pstack/skills/principle-model-the-domain/SKILL.md +24 -0
- package/plugins/pstack/skills/principle-never-block-on-the-human/SKILL.md +15 -0
- package/plugins/pstack/skills/principle-outcome-oriented-execution/SKILL.md +21 -0
- package/plugins/pstack/skills/principle-prove-it-works/SKILL.md +27 -0
- package/plugins/pstack/skills/principle-redesign-from-first-principles/SKILL.md +16 -0
- package/plugins/pstack/skills/principle-separate-before-serializing-shared-state/SKILL.md +16 -0
- package/plugins/pstack/skills/principle-sequence-verifiable-units/SKILL.md +17 -0
- package/plugins/pstack/skills/principle-subtract-before-you-add/SKILL.md +18 -0
- package/plugins/pstack/skills/principle-test-behavior-not-implementation/SKILL.md +20 -0
- package/plugins/pstack/skills/principle-type-system-discipline/SKILL.md +13 -0
- package/plugins/pstack/skills/recall/SKILL.md +43 -0
- package/plugins/pstack/skills/reflect/SKILL.md +89 -0
- package/plugins/pstack/skills/reflect/references/divergent-reviewer.md +38 -0
- package/plugins/pstack/skills/reflect/references/judgment-reviewer.md +37 -0
- package/plugins/pstack/skills/reflect/references/synthesizer.md +56 -0
- package/plugins/pstack/skills/reflect/references/tooling-reviewer.md +48 -0
- package/plugins/pstack/skills/reflect/scripts/claude-project-dir.mjs +121 -0
- package/plugins/pstack/skills/reflect/scripts/find-transcript.mjs +218 -0
- package/plugins/pstack/skills/setup-pstack/SKILL.md +109 -0
- package/plugins/pstack/skills/setup-pstack/copilot.md +88 -0
- package/plugins/pstack/skills/setup-pstack/references/runtimes.md +75 -0
- package/plugins/pstack/skills/setup-pstack/scripts/check-sheet.awk +10 -0
- package/plugins/pstack/skills/setup-pstack/scripts/check-sheet.sh +20 -0
- package/plugins/pstack/skills/setup-pstack/scripts/read-sheet.sh +24 -0
- package/plugins/pstack/skills/setup-pstack/scripts/sheet.awk +160 -0
- package/plugins/pstack/skills/sharpen/SKILL.md +15 -0
- package/plugins/pstack/skills/show-me-your-work/SKILL.md +89 -0
- package/plugins/pstack/skills/show-me-your-work/references/decision-log-template.tsv +1 -0
- package/plugins/pstack/skills/show-me-your-work/scripts/log.sh +58 -0
- package/plugins/pstack/skills/statechart/SKILL.md +81 -0
- package/plugins/pstack/skills/statechart/references/render.md +93 -0
- package/plugins/pstack/skills/statechart/scripts/backends/cfg.ts +33 -0
- package/plugins/pstack/skills/statechart/scripts/backends/mermaid.ts +201 -0
- package/plugins/pstack/skills/statechart/scripts/backends/plain-text.ts +72 -0
- package/plugins/pstack/skills/statechart/scripts/backends/report.ts +177 -0
- package/plugins/pstack/skills/statechart/scripts/bun.lock +17 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/config.ts +276 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/dot.ts +74 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/marks.ts +93 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/messages.ts +52 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/spec.ts +114 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/trace.ts +24 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/value.ts +166 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/verdict.ts +40 -0
- package/plugins/pstack/skills/statechart/scripts/frontends/view.ts +119 -0
- package/plugins/pstack/skills/statechart/scripts/ir.ts +547 -0
- package/plugins/pstack/skills/statechart/scripts/janitor.ts +12 -0
- package/plugins/pstack/skills/statechart/scripts/package.json +11 -0
- package/plugins/pstack/skills/statechart/scripts/passes/annotate.ts +128 -0
- package/plugins/pstack/skills/statechart/scripts/passes/label.ts +269 -0
- package/plugins/pstack/skills/statechart/scripts/passes/lift.ts +85 -0
- package/plugins/pstack/skills/statechart/scripts/passes/loop-check.ts +68 -0
- package/plugins/pstack/skills/statechart/scripts/passes/paths.ts +60 -0
- package/plugins/pstack/skills/statechart/scripts/passes/reach.ts +135 -0
- package/plugins/pstack/skills/statechart/scripts/passes/region-check.ts +97 -0
- package/plugins/pstack/skills/statechart/scripts/passes/regions.ts +295 -0
- package/plugins/pstack/skills/statechart/scripts/pipeline.ts +76 -0
- package/plugins/pstack/skills/statechart/scripts/run.ts +526 -0
- package/plugins/pstack/skills/statechart/scripts/statechart +29 -0
- package/plugins/pstack/skills/statechart/scripts/statechart.ts +171 -0
- package/plugins/pstack/skills/statechart/scripts/test/ConfigOracle.java +63 -0
- package/plugins/pstack/skills/statechart/scripts/test/chart.test.ts +1210 -0
- package/plugins/pstack/skills/statechart/scripts/test/charts/Braces.mmd +7 -0
- package/plugins/pstack/skills/statechart/scripts/test/charts/Escapes.mmd +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/charts/Phases.mmd +29 -0
- package/plugins/pstack/skills/statechart/scripts/test/child-env.test.ts +15 -0
- package/plugins/pstack/skills/statechart/scripts/test/cli.test.ts +1323 -0
- package/plugins/pstack/skills/statechart/scripts/test/config-fuzz.test.ts +263 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Counter/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Counter/Counter.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Counter/Counter.tla +10 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Counter/chart.mmd +9 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Counter/graph.dot +16 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Counter/report.md +7 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Counter/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Counter/verdict-1.out +49 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/ChartRun.out +60 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/CounterAction.cfg +4 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/CounterAction.tla +22 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/chart.mmd +26 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/graph.dot +19 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/report.md +20 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/verdict-1.out +56 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/verdict-2.out +82 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterAction/verdict-3.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/ChartRun.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/CounterDeadlock.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/CounterDeadlock.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/chart.mmd +22 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/graph.dot +16 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/report.md +17 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/verdict-1.out +56 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterDeadlock/verdict-2.out +77 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/ChartRun.out +69 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/CounterFan.cfg +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/CounterFan.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/chart.mmd +85 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/graph.dot +70 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/report.md +12 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/verdict-1.out +67 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterFan/verdict-2.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/ChartRun.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/ChartRun.out +85 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/CounterGuard.cfg +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/CounterGuard.tla +13 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/chart.mmd +5 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/graph.dot +10 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/report.md +31 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/verdict-1.out +64 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterGuard/verdict-2.out +77 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/ChartRun.out +55 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/CounterInitPast.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/CounterInitPast.tla +10 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/chart.mmd +12 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/graph.dot +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/report.md +12 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/verdict-1.out +33 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPast/verdict-2.out +54 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPastHolds/ChartRun.out +54 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPastHolds/CounterInitPastHolds.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPastHolds/CounterInitPastHolds.tla +10 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPastHolds/chart.mmd +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPastHolds/graph.dot +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPastHolds/report.md +7 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPastHolds/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInitPastHolds/verdict-1.out +46 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/ChartRun.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/CounterInstance.cfg +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/CounterInstance.tla +10 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/CounterSteps.tla +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/chart.mmd +17 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/graph.dot +15 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/report.md +14 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/sany.out +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterInstance/verdict-1.out +78 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/ChartRun.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/CounterJump.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/CounterJump.tla +19 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/chart.mmd +26 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/graph.dot +22 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/report.md +12 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/verdict-1.out +58 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterJump/verdict-2.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/CounterLoop.cfg +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/CounterLoop.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/chart.mmd +17 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/graph.dot +15 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/report.md +14 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterLoop/verdict-1.out +76 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/ChartRun.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/CounterOrder.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/CounterOrder.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/chart.mmd +19 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/graph.dot +10 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/report.md +15 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/verdict-1.out +56 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterOrder/verdict-2.out +67 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/ChartRun.out +62 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/CounterRules.cfg +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/CounterRules.tla +24 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/Moves.tla +5 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/chart.mmd +22 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/graph.dot +10 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/report.md +23 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/sany.out +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/verdict-1.out +58 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/verdict-2.out +66 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/verdict-3.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/verdict-3.out +74 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterRules/verdict-4.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/ChartRun.out +58 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/CounterStart.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/CounterStart.tla +15 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/chart.mmd +18 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/graph.dot +13 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/report.md +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/verdict-1.out +33 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStart/verdict-2.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStop/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStop/CounterStop.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStop/CounterStop.tla +15 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStop/chart.mmd +7 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStop/graph.dot +13 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStop/report.md +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStop/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterStop/verdict-1.out +49 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/ChartRun.out +61 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/CounterTie.cfg +4 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/CounterTie.tla +14 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/chart.mmd +30 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/graph.dot +19 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/report.md +27 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/verdict-1.out +56 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/verdict-2.out +64 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/verdict-3.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/verdict-3.out +87 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTie/verdict-4.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/ChartRun.out +60 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/CounterTieInGraph.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/CounterTieInGraph.tla +12 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/chart.mmd +23 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/graph.dot +19 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/report.md +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/verdict-1.out +56 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterTieInGraph/verdict-2.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/ChartRun.out +61 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/CounterView.cfg +4 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/CounterView.tla +14 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/chart.mmd +23 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/graph.dot +19 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/report.md +27 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/verdict-1.out +56 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/verdict-2.out +64 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/verdict-3.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/verdict-3.out +87 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/verdict-4.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/CounterView/view.mjs +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/ChartRun.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/DieHard.cfg +4 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/DieHard.tla +38 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/chart.mmd +92 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/graph.dot +126 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/report.md +17 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/verdict-1.out +91 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/DieHard/verdict-2.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/ChartRun.out +61 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/FirstRule.cfg +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/FirstRule.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/chart.mmd +22 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/graph.dot +16 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/report.md +25 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/verdict-1.out +56 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/verdict-2.out +64 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/verdict-3.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/verdict-3.out +64 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/verdict-4.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/FirstRule/verdict-4.out +77 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/HiddenClock.cfg +4 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/HiddenClock.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/chart.mmd +13 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/graph.dot +12 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/report.md +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/HiddenClock/verdict-1.out +72 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/Login.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/Login.tla +62 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/chart.mmd +27 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/graph.dot +40 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/report.md +7 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/sany.out +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/verdict-1.out +47 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Login/view.mjs +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/LoginGuarded.cfg +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/LoginGuarded.tla +64 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/chart.mmd +28 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/graph.dot +37 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/report.md +8 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/sany.out +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/verdict-1.out +47 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginGuarded/view.mjs +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/ChartRun.out +60 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/LoginParallel.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/LoginParallel.tla +64 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/chart.mmd +44 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/graph.dot +58 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/report.md +17 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/sany.out +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/verdict-1.out +83 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/verdict-2.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/LoginParallel/view.mjs +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/ChartRun.out +60 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/MediaPlayer.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/MediaPlayer.tla +103 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/chart.mmd +43 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/graph.dot +93 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/report.md +14 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/sany.out +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/verdict-1.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/verdict-2.out +72 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayer/view.mjs +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/MediaPlayerFixed.cfg +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/MediaPlayerFixed.tla +100 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/chart.mmd +31 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/graph.dot +85 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/report.md +9 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/sany.out +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/verdict-1.out +47 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerFixed/view.mjs +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/ChartRun.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/MediaPlayer.tla +103 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/MediaPlayerProps.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/MediaPlayerProps.tla +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/chart.mmd +42 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/graph.dot +93 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/report.md +19 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-1.out +61 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-2.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-3.out +61 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-4.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-4.out +66 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-5.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-5.out +58 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-6.out +49 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/MediaPlayerProps/view.mjs +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/PickWorker/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/PickWorker/PickWorker.cfg +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/PickWorker/PickWorker.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/PickWorker/chart.mmd +5 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/PickWorker/graph.dot +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/PickWorker/report.md +7 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/PickWorker/sany.out +5 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/PickWorker/verdict-1.out +70 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/ChartRun.out +61 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/Shadow.cfg +4 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/Shadow.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/ShadowLib.tla +6 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/ShadowSub.tla +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/chart.mmd +9 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/graph.dot +16 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/report.md +8 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/sany.out +4 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/Shadow/verdict-1.out +65 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/ChartRun.out +59 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/SpacedNames.cfg +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/SpacedNames.tla +9 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/chart.mmd +23 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/graph.dot +17 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/report.md +15 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/sany.out +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/verdict-1.out +65 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/SpacedNames/verdict-2.out +75 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/ChartRun.out +69 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/TwoPhase.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/TwoPhase.tla +75 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/chart.mmd +60 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/graph.dot +297 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/report.md +20 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/sany.out +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/verdict-1.out +95 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/verdict-2.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhase/view.mjs +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/ChartRun.out +57 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/TwoPhaseFixed.cfg +3 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/TwoPhaseFixed.tla +75 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/chart.mmd +37 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/graph.dot +223 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/report.md +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/sany.out +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/verdict-1.out +47 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TwoPhaseFixed/view.mjs +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/ChartRun.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/ChartRun.out +75 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/TypeGuard.cfg +5 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/TypeGuard.tla +11 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/chart.mmd +18 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/graph.dot +14 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/report.md +29 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/verdict-1.out +64 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/TypeGuard/verdict-2.out +75 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/ChartRun.out +58 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/UserNoDeadlock.cfg +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/UserNoDeadlock.tla +8 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/chart.mmd +22 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/graph.dot +16 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/report.md +15 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/verdict-1.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/verdict-1.out +56 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/verdict-2.exit +1 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus/UserNoDeadlock/verdict-2.out +77 -0
- package/plugins/pstack/skills/statechart/scripts/test/corpus.test.ts +415 -0
- package/plugins/pstack/skills/statechart/scripts/test/differential.test.ts +565 -0
- package/plugins/pstack/skills/statechart/scripts/test/grid/Grid.cfg +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/grid/Grid.tla +9 -0
- package/plugins/pstack/skills/statechart/scripts/test/grid/sany.out +2 -0
- package/plugins/pstack/skills/statechart/scripts/test/java.ts +63 -0
- package/plugins/pstack/skills/statechart/scripts/test/labels.ts +643 -0
- package/plugins/pstack/skills/statechart/scripts/test/messages.test.ts +227 -0
- package/plugins/pstack/skills/statechart/scripts/test/pipeline.test.ts +270 -0
- package/plugins/pstack/skills/statechart/scripts/test/plain-tlc.test.ts +255 -0
- package/plugins/pstack/skills/statechart/scripts/test/render.test.ts +81 -0
- package/plugins/pstack/skills/statechart/scripts/test/tlc-out.test.ts +90 -0
- package/plugins/pstack/skills/statechart/scripts/test/tlc.ts +158 -0
- package/plugins/pstack/skills/statechart/scripts/tsconfig.json +11 -0
- package/plugins/pstack/skills/statechart/scripts/worker.ts +35 -0
- package/plugins/pstack/skills/swarm/SKILL.md +58 -0
- package/plugins/pstack/skills/tdd/SKILL.md +41 -0
- package/plugins/pstack/skills/teach/SKILL.md +28 -0
- package/plugins/pstack/skills/technical-writing/SKILL.md +105 -0
- package/plugins/pstack/skills/thermo-nuclear-code-quality-review/SKILL.md +201 -0
- package/plugins/pstack/skills/thermo-nuclear-review/SKILL.md +50 -0
- package/plugins/pstack/skills/thermos/SKILL.md +40 -0
- package/plugins/pstack/skills/typescript-best-practices/SKILL.md +32 -0
- package/plugins/pstack/skills/typescript-best-practices/references/patterns.md +328 -0
- package/plugins/pstack/skills/unslop/SKILL.md +61 -0
- package/plugins/pstack/skills/what-did-i-get-done/SKILL.md +31 -0
- package/plugins/pstack/skills/why/SKILL.md +116 -0
- package/plugins/pstack/skills/why/references/epistemics.md +79 -0
- package/plugins/pstack/skills/why/references/investigator-prompt.md +86 -0
- package/plugins/pstack/skills/why/references/source-playbook.md +17 -0
- package/plugins/pstack/skills/why/references/sources/code-archaeology.md +51 -0
- package/plugins/pstack/skills/why/references/sources/databricks.md +70 -0
- package/plugins/pstack/skills/why/references/sources/datadog.md +97 -0
- package/plugins/pstack/skills/why/references/sources/incident-postmortem.md +5 -0
- package/plugins/pstack/skills/why/references/sources/linear.md +48 -0
- package/plugins/pstack/skills/why/references/sources/notion.md +55 -0
- package/plugins/pstack/skills/why/references/sources/sentry.md +66 -0
- package/plugins/pstack/skills/why/references/sources/slack.md +17 -0
- package/plugins/pstack/skills/why/references/synthesizer-prompt.md +130 -0
- package/tools/forks.json +398 -0
- package/tools/substitutions.json +646 -0
- package/tools/upstream.json +53 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
import type { AgentRunner } from "./agents.ts";
|
|
4
|
+
import type { Settings } from "./config.ts";
|
|
5
|
+
|
|
6
|
+
const PENDING_POLL_MS = 50;
|
|
7
|
+
|
|
8
|
+
export interface OneShot {
|
|
9
|
+
exits(ctx: Pick<ExtensionContext, "mode">): boolean;
|
|
10
|
+
untilSettled(): Promise<void>;
|
|
11
|
+
assertStartsRun(prompt: string, ctx: ExtensionContext): Promise<void>;
|
|
12
|
+
dispose(): void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Why Pi would start no run for a prompt this extension sends, by the checks
|
|
16
|
+
// its prompt() makes first: an extension command runs in place, and a prompt
|
|
17
|
+
// without a model or credentials is refused. No settle follows either, and Pi
|
|
18
|
+
// reports a refusal only to its own error listeners, so a one-shot /loop
|
|
19
|
+
// waiting on the settle would never return. It cannot see an input handler
|
|
20
|
+
// that consumes the prompt.
|
|
21
|
+
async function noRunReason(pi: ExtensionAPI, prompt: string, ctx: ExtensionContext): Promise<string | undefined> {
|
|
22
|
+
if (prompt.startsWith("/")) {
|
|
23
|
+
const space = prompt.indexOf(" ");
|
|
24
|
+
const name = prompt.slice(1, space === -1 ? undefined : space);
|
|
25
|
+
if (pi.getCommands().some((command) => command.source === "extension" && command.name === name)) {
|
|
26
|
+
return `/${name} is an extension command, not a prompt`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const model = ctx.model;
|
|
30
|
+
if (!model) return "no model is selected";
|
|
31
|
+
if (ctx.modelRegistry.hasConfiguredAuth(model)) return undefined;
|
|
32
|
+
const available = await ctx.modelRegistry.getAvailableOfType("chat", model.provider);
|
|
33
|
+
return available.length ? undefined : "the selected model has no credentials";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Resolves once Pi has a queued message, which is the same condition Pi checks
|
|
37
|
+
// after agent_before_settle returns to decide whether the run continues.
|
|
38
|
+
function pendingMessage(ctx: ExtensionContext, signal: { done: boolean }): Promise<void> {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
const timer = setInterval(() => {
|
|
41
|
+
if (!signal.done && !ctx.hasPendingMessages()) return;
|
|
42
|
+
clearInterval(timer);
|
|
43
|
+
resolve();
|
|
44
|
+
}, PENDING_POLL_MS);
|
|
45
|
+
timer.unref();
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Everything that follows from "this process ends when the run settles":
|
|
50
|
+
// a background agent's notice would be lost, so the settle is held until one
|
|
51
|
+
// exits or a message arrives; /loop must wait for the run it started; a wakeup
|
|
52
|
+
// could never fire; Ctrl-C must take the children along, since pi's one SIGINT
|
|
53
|
+
// listener outside interactive mode is signal-exit's, which re-raises the signal
|
|
54
|
+
// and so skips the exit hook.
|
|
55
|
+
export function registerOneShot(pi: ExtensionAPI, settings: Settings, runner: Pick<AgentRunner, "nextExit">): OneShot {
|
|
56
|
+
// Print and json runs exit once the agent settles. A pstack child is an rpc
|
|
57
|
+
// process whose parent closes its stdin at the same moment, so it is one-shot too.
|
|
58
|
+
const exits = (ctx: Pick<ExtensionContext, "mode">) => ctx.mode === "print" || ctx.mode === "json" || settings.depth > 0;
|
|
59
|
+
const settleWaiters: (() => void)[] = [];
|
|
60
|
+
const settle = () => {
|
|
61
|
+
for (const resolve of settleWaiters.splice(0)) resolve();
|
|
62
|
+
};
|
|
63
|
+
// The exit hook in index.ts signals the children.
|
|
64
|
+
const onSigint = () => process.exit(130);
|
|
65
|
+
pi.on("session_start", (_event, ctx) => {
|
|
66
|
+
if (exits(ctx) && !process.listeners("SIGINT").includes(onSigint)) process.on("SIGINT", onSigint);
|
|
67
|
+
});
|
|
68
|
+
pi.on("agent_before_settle", async (_event, ctx) => {
|
|
69
|
+
if (!exits(ctx) || ctx.hasPendingMessages()) return;
|
|
70
|
+
const signal = { done: false };
|
|
71
|
+
await Promise.race([runner.nextExit(), pendingMessage(ctx, signal)]);
|
|
72
|
+
signal.done = true;
|
|
73
|
+
});
|
|
74
|
+
pi.on("agent_settled", settle);
|
|
75
|
+
return {
|
|
76
|
+
exits,
|
|
77
|
+
untilSettled: () => new Promise<void>((resolve) => settleWaiters.push(resolve)),
|
|
78
|
+
assertStartsRun: async (prompt, ctx) => {
|
|
79
|
+
const reason = await noRunReason(pi, prompt, ctx);
|
|
80
|
+
if (reason === undefined) return;
|
|
81
|
+
// Pi prints a command handler's throw and still exits 0.
|
|
82
|
+
process.exitCode = 1;
|
|
83
|
+
throw new Error(`No run would start: ${reason}`);
|
|
84
|
+
},
|
|
85
|
+
dispose: () => {
|
|
86
|
+
process.off("SIGINT", onSigint);
|
|
87
|
+
settle();
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { isAbsolute, join, matchesGlob, relative, resolve } from "node:path";
|
|
3
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
|
|
5
|
+
import { frontmatter } from "./agent-files.ts";
|
|
6
|
+
import type { Settings } from "./config.ts";
|
|
7
|
+
|
|
8
|
+
const FILE_TOOLS = new Set(["read", "edit", "write"]);
|
|
9
|
+
|
|
10
|
+
interface PathSkill {
|
|
11
|
+
name: string;
|
|
12
|
+
file: string;
|
|
13
|
+
globs: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function parsePaths(file: string, globs: unknown): string[] {
|
|
17
|
+
if (Array.isArray(globs) && globs.every((g): g is string => typeof g === "string")) return globs;
|
|
18
|
+
throw new Error(`${file}: paths must be a JSON array of globs`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Skills whose frontmatter names `paths:` globs, the files that should load them.
|
|
22
|
+
function pathSkills(pluginRoot: string): PathSkill[] {
|
|
23
|
+
const dir = join(pluginRoot, "skills");
|
|
24
|
+
if (!existsSync(dir)) return [];
|
|
25
|
+
const skills: PathSkill[] = [];
|
|
26
|
+
for (const name of readdirSync(dir).sort()) {
|
|
27
|
+
const file = join(dir, name, "SKILL.md");
|
|
28
|
+
if (!existsSync(file)) continue;
|
|
29
|
+
const globs = frontmatter(readFileSync(file, "utf8")).fields.paths;
|
|
30
|
+
if (globs != null) skills.push({ name, file, globs: parsePaths(file, globs) });
|
|
31
|
+
}
|
|
32
|
+
return skills;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Claude Code loads a skill with `paths:` when a matching file is touched; Pi
|
|
36
|
+
// has no such hook, so the first matching tool result carries a note instead.
|
|
37
|
+
export function registerPathSkills(pi: ExtensionAPI, settings: Settings): void {
|
|
38
|
+
const skills = pathSkills(settings.pluginRoot);
|
|
39
|
+
const noted = new Set<string>();
|
|
40
|
+
pi.on("tool_result", (event, ctx) => {
|
|
41
|
+
if (!FILE_TOOLS.has(event.toolName) || event.isError) return;
|
|
42
|
+
const raw = event.input.path;
|
|
43
|
+
if (typeof raw !== "string") return;
|
|
44
|
+
const rel = relative(ctx.cwd, isAbsolute(raw) ? raw : resolve(ctx.cwd, raw)).split("\\").join("/");
|
|
45
|
+
const skill = skills.find((s) => !noted.has(s.name) && s.globs.some((g) => matchesGlob(rel, g)));
|
|
46
|
+
if (!skill) return;
|
|
47
|
+
noted.add(skill.name);
|
|
48
|
+
const note = `pstack: ${rel} matches the ${skill.name} skill's paths. Load that skill now (read ${skill.file}) and follow it while you work on this file.`;
|
|
49
|
+
return {
|
|
50
|
+
content: [...event.content, { type: "text", text: note }],
|
|
51
|
+
structuredContent: event.structuredContent,
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
|
|
5
|
+
import { readSheet, type Settings } from "./config.ts";
|
|
6
|
+
|
|
7
|
+
const MANDATE_SECTION = "pstack-session-start";
|
|
8
|
+
const SHEET_SECTION = "pstack-models";
|
|
9
|
+
const PARALLEL_SECTION = "pstack-parallel-calls";
|
|
10
|
+
const TOOLS_SECTION = "pstack-pi-tools";
|
|
11
|
+
|
|
12
|
+
// pstack skills name Claude Code tools and models. A session with the hook off,
|
|
13
|
+
// a child agent, or a skill invoked directly may never see the pointer in
|
|
14
|
+
// poteto-mode/SKILL.md, so every session gets it here.
|
|
15
|
+
function piToolsNote(pluginRoot: string): string {
|
|
16
|
+
const file = join(pluginRoot, "skills", "poteto-mode", "references", "pi-tools.md");
|
|
17
|
+
return `pstack skills are written for Claude Code. When one names a Claude Code tool (Agent, Skill, AskUserQuestion, Bash), a bundled skill, or a Claude model, read ${file} for the Pi equivalent before following it.`;
|
|
18
|
+
}
|
|
19
|
+
// Claude Code's system prompt, word for word but for its function_calls block.
|
|
20
|
+
// pstack skills that say "one message, N Agent calls" rely on it.
|
|
21
|
+
const PARALLEL_CALLS =
|
|
22
|
+
"If you intend to call multiple tools and there are no dependencies between the calls, make all of the independent calls in the same response, otherwise you MUST wait for previous calls to finish first to determine the dependent values.";
|
|
23
|
+
|
|
24
|
+
// Claude Code runs the session hook and loads the sheet through a CLAUDE.md
|
|
25
|
+
// include; Pi has neither, so both ride as system prompt sections, set again
|
|
26
|
+
// on every agent start so compaction cannot drop them.
|
|
27
|
+
// A child gets the sheet, as a Claude Code subagent sees CLAUDE.md, but not
|
|
28
|
+
// the mandate: SessionStart does not run for subagents.
|
|
29
|
+
export function registerPromptSections(pi: ExtensionAPI, settings: Settings): void {
|
|
30
|
+
const mandateFile = join(settings.pluginRoot, "hooks", "session-start-context.md");
|
|
31
|
+
pi.on("before_agent_start", (event) => {
|
|
32
|
+
const sheet = readSheet(settings.agentDir);
|
|
33
|
+
const sections = event.systemPromptOptions.sections;
|
|
34
|
+
sections[PARALLEL_SECTION] = PARALLEL_CALLS;
|
|
35
|
+
sections[TOOLS_SECTION] = piToolsNote(settings.pluginRoot);
|
|
36
|
+
if (settings.depth === 0 && !sheet?.hookOff) sections[MANDATE_SECTION] = readFileSync(mandateFile, "utf8");
|
|
37
|
+
if (sheet) sections[SHEET_SECTION] = sheet.text;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
|
|
4
|
+
import type { OneShot } from "./one-shot.ts";
|
|
5
|
+
import { expandSlash } from "./slash.ts";
|
|
6
|
+
|
|
7
|
+
const MIN_DELAY_S = 60;
|
|
8
|
+
const MAX_DELAY_S = 3600;
|
|
9
|
+
// setInterval treats a delay above 2^31-1 ms as 1 ms.
|
|
10
|
+
const MAX_LOOP_S = 24 * 86400;
|
|
11
|
+
const IDLE_RETRY_MS = 1000;
|
|
12
|
+
// Text the agent chose (a schedule_wakeup prompt, and what a loop it re-arms sends) goes in as a custom
|
|
13
|
+
// message, not a user message. The permission classifier reads user-role messages as what the user asked
|
|
14
|
+
// for, so a user message here would let the agent write its own permission.
|
|
15
|
+
const AGENT_PROMPT_TYPE = "pstack-wakeup";
|
|
16
|
+
const LOOP_COMMAND = /^\/loop(?:\s+([\s\S]*))?$/;
|
|
17
|
+
type Send = (prompt: string) => void;
|
|
18
|
+
|
|
19
|
+
const errorText = (e: unknown) => (e instanceof Error ? e.message : String(e));
|
|
20
|
+
|
|
21
|
+
const wakeupParams = Type.Object({
|
|
22
|
+
delaySeconds: Type.Optional(Type.Number({ description: `Seconds until the wakeup (${MIN_DELAY_S}-${MAX_DELAY_S})` })),
|
|
23
|
+
prompt: Type.Optional(Type.String({ description: "The prompt to run when the wakeup fires" })),
|
|
24
|
+
reason: Type.Optional(Type.String({ description: "Why this delay, in one short sentence" })),
|
|
25
|
+
noop: Type.Optional(Type.Boolean({ description: "Mark this wakeup as a routine check; it is scheduled all the same" })),
|
|
26
|
+
stop: Type.Optional(Type.Boolean({ description: "Cancel the pending wakeup; no other field is needed" })),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// One pending wakeup, one fixed-interval loop, and one live self-paced loop per
|
|
30
|
+
// session. A due wakeup or loop tick runs the delivery its caller chose, at
|
|
31
|
+
// once when the agent is idle.
|
|
32
|
+
export class Scheduler {
|
|
33
|
+
private wakeup?: NodeJS.Timeout;
|
|
34
|
+
private loop?: NodeJS.Timeout;
|
|
35
|
+
// A self-paced loop has no timer of its own while its iteration runs, so
|
|
36
|
+
// this is what /loop stop finds then.
|
|
37
|
+
private selfPaced = false;
|
|
38
|
+
// Set by a /loop command that ends or replaces the loop while a run is in
|
|
39
|
+
// flight, until that run settles. A schedule_wakeup call names no loop, so
|
|
40
|
+
// nothing tells that run's re-arm of the old loop from any other wakeup. It
|
|
41
|
+
// is refused them all, or the loop the user just ended would come back.
|
|
42
|
+
sealed = false;
|
|
43
|
+
// A run is in flight: set by agent_start, cleared by agent_settled. Not
|
|
44
|
+
// ctx.isIdle(), which is also false during a manual compaction.
|
|
45
|
+
running = false;
|
|
46
|
+
|
|
47
|
+
scheduleWakeup(seconds: number, deliver: () => void, ctx: ExtensionContext): void {
|
|
48
|
+
this.cancelWakeup();
|
|
49
|
+
const due = () => {
|
|
50
|
+
// Pi rejects prompts during manual compaction. Keep the wakeup pending
|
|
51
|
+
// until idle, including while a run or compaction is still finishing.
|
|
52
|
+
if (!ctx.isIdle()) {
|
|
53
|
+
this.wakeup = setTimeout(due, IDLE_RETRY_MS).unref();
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
this.wakeup = undefined;
|
|
57
|
+
deliver();
|
|
58
|
+
};
|
|
59
|
+
this.wakeup = setTimeout(due, seconds * 1000);
|
|
60
|
+
this.wakeup.unref();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
cancelWakeup(): boolean {
|
|
64
|
+
const had = this.wakeup !== undefined;
|
|
65
|
+
clearTimeout(this.wakeup);
|
|
66
|
+
this.wakeup = undefined;
|
|
67
|
+
return had;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
startLoop(seconds: number, tick: () => void, ctx: ExtensionContext): void {
|
|
71
|
+
// A tick that lands mid-run is dropped, so a slow iteration cannot pile up a backlog.
|
|
72
|
+
this.loop = setInterval(() => ctx.isIdle() && tick(), seconds * 1000);
|
|
73
|
+
this.loop.unref();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private stopLoop(): boolean {
|
|
77
|
+
const had = this.loop !== undefined;
|
|
78
|
+
clearInterval(this.loop);
|
|
79
|
+
this.loop = undefined;
|
|
80
|
+
return had;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
startSelfPaced(): void {
|
|
84
|
+
this.selfPaced = true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Ends the loop and the pending wakeup. midRun says a run is in flight,
|
|
88
|
+
// which seals the wakeup slot against it.
|
|
89
|
+
stopAll(midRun = false): boolean {
|
|
90
|
+
const wakeup = this.cancelWakeup();
|
|
91
|
+
const selfPaced = this.selfPaced;
|
|
92
|
+
this.selfPaced = false;
|
|
93
|
+
if (midRun) this.sealed = true;
|
|
94
|
+
return this.stopLoop() || wakeup || selfPaced;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function clampDelay(seconds: number): number {
|
|
99
|
+
return Math.min(MAX_DELAY_S, Math.max(MIN_DELAY_S, Math.round(seconds)));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const UNIT_SECONDS: Record<string, number> = { s: 1, m: 60, h: 3600, d: 86400 };
|
|
103
|
+
|
|
104
|
+
type LoopCommand =
|
|
105
|
+
| { kind: "stop" }
|
|
106
|
+
| { kind: "usage"; reason?: string }
|
|
107
|
+
| { kind: "fixed"; seconds: number; prompt: string }
|
|
108
|
+
| { kind: "dynamic"; prompt: string };
|
|
109
|
+
|
|
110
|
+
function parseLoop(args: string): LoopCommand {
|
|
111
|
+
const text = args.trim();
|
|
112
|
+
if (!text) return { kind: "usage" };
|
|
113
|
+
if (text === "stop") return { kind: "stop" };
|
|
114
|
+
const m = /^(\d+)([smhd])(?:\s+([\s\S]+))?$/.exec(text);
|
|
115
|
+
if (m) {
|
|
116
|
+
const seconds = Number(m[1]) * UNIT_SECONDS[m[2]];
|
|
117
|
+
if (!m[3]) return { kind: "usage" };
|
|
118
|
+
if (seconds > MAX_LOOP_S) return { kind: "usage", reason: "Intervals over 24 days are not supported." };
|
|
119
|
+
return { kind: "fixed", seconds, prompt: m[3].trim() };
|
|
120
|
+
}
|
|
121
|
+
return { kind: "dynamic", prompt: text };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function dynamicPrompt(prompt: string): string {
|
|
125
|
+
return (
|
|
126
|
+
`${prompt}\n\n` +
|
|
127
|
+
`[/loop, self-paced] When this iteration is done, call schedule_wakeup with prompt "/loop ${prompt}" ` +
|
|
128
|
+
`and a delay that fits what you are waiting for (${MIN_DELAY_S} to ${MAX_DELAY_S} seconds) to run it again. ` +
|
|
129
|
+
`Skip the call to end the loop.`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// model-only exposure keeps the tool declared under codemode.mode "only".
|
|
134
|
+
export function registerSchedule(pi: ExtensionAPI, scheduler: Scheduler, oneShot: OneShot): void {
|
|
135
|
+
// The prompt's author picks the role: the user's /loop sends user messages, and text the agent chose
|
|
136
|
+
// goes in as a custom message, which the permission classifier does not read as the user's ask. Pi
|
|
137
|
+
// expands slash text only in a user message, so the agent's is expanded before it is sent.
|
|
138
|
+
const sendAsUser: Send = (prompt) => pi.sendUserMessage(prompt, { deliverAs: "followUp", expandPromptTemplates: true });
|
|
139
|
+
const sendAsAgent =
|
|
140
|
+
(ctx: ExtensionContext): Send =>
|
|
141
|
+
(prompt) => {
|
|
142
|
+
let content = prompt;
|
|
143
|
+
try {
|
|
144
|
+
content = expandSlash(pi.getCommands(), prompt);
|
|
145
|
+
} catch (e) {
|
|
146
|
+
ctx.ui.notify(`A wakeup's command could not be expanded and was sent as written: ${errorText(e)}`, "error");
|
|
147
|
+
}
|
|
148
|
+
pi.sendMessage({ customType: AGENT_PROMPT_TYPE, content, display: true }, { triggerTurn: true, deliverAs: "followUp" });
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
pi.registerTool({
|
|
152
|
+
name: "schedule_wakeup",
|
|
153
|
+
label: "Schedule wakeup",
|
|
154
|
+
exposure: "model-only",
|
|
155
|
+
description: `Schedule this session to be re-invoked with a prompt after delaySeconds (clamped to ${MIN_DELAY_S}-${MAX_DELAY_S}), once the session is idle. One wakeup is pending at a time: a new call replaces it, and stop: true cancels it. Used by /loop's self-paced mode.`,
|
|
156
|
+
parameters: wakeupParams,
|
|
157
|
+
async execute(_id, params, _signal, _onUpdate, ctx) {
|
|
158
|
+
if (params.stop) {
|
|
159
|
+
// What is pending in a sealed slot is a loop start the user asked for, not this run's.
|
|
160
|
+
const had = !scheduler.sealed && scheduler.cancelWakeup();
|
|
161
|
+
const text = had ? "Pending wakeup cancelled." : "No wakeup was pending.";
|
|
162
|
+
return { content: [{ type: "text", text }], details: { cancelled: had } };
|
|
163
|
+
}
|
|
164
|
+
if (params.delaySeconds === undefined || !params.prompt) {
|
|
165
|
+
throw new Error("schedule_wakeup needs delaySeconds and prompt unless stop is true.");
|
|
166
|
+
}
|
|
167
|
+
if (scheduler.sealed) {
|
|
168
|
+
ctx.ui.notify("A wakeup this run asked for was not scheduled: /loop ended or replaced the loop while it ran.", "warning");
|
|
169
|
+
return {
|
|
170
|
+
content: [{ type: "text", text: "Not scheduled: the user ended or replaced the loop with a /loop command during this run. Do not schedule another wakeup in this run." }],
|
|
171
|
+
details: { refused: true },
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (oneShot.exits(ctx)) {
|
|
175
|
+
throw new Error(`schedule_wakeup cannot fire in a ${ctx.mode} run: pi exits when this run ends. Finish the work in this run instead.`);
|
|
176
|
+
}
|
|
177
|
+
const seconds = clampDelay(params.delaySeconds);
|
|
178
|
+
// A custom message runs no command, so the agent's "/loop ..." re-arm runs the loop here.
|
|
179
|
+
const prompt = params.prompt;
|
|
180
|
+
const send = sendAsAgent(ctx);
|
|
181
|
+
const loop = LOOP_COMMAND.exec(prompt);
|
|
182
|
+
const deliver = loop
|
|
183
|
+
? () => void runLoop(loop[1] ?? "", ctx, send).catch((e) => ctx.ui.notify(`/loop from a wakeup failed: ${errorText(e)}`, "error"))
|
|
184
|
+
: () => send(prompt);
|
|
185
|
+
scheduler.scheduleWakeup(seconds, deliver, ctx);
|
|
186
|
+
const fireAt = new Date(Date.now() + seconds * 1000).toISOString();
|
|
187
|
+
const clamped = seconds !== params.delaySeconds ? ` (clamped from ${params.delaySeconds})` : "";
|
|
188
|
+
return {
|
|
189
|
+
content: [{ type: "text", text: `Wakeup scheduled in ${seconds}s${clamped}, at ${fireAt}. It replaces any earlier pending wakeup.` }],
|
|
190
|
+
details: { delaySeconds: seconds, fireAt, noop: params.noop === true },
|
|
191
|
+
};
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
pi.on("agent_start", () => {
|
|
196
|
+
scheduler.running = true;
|
|
197
|
+
});
|
|
198
|
+
pi.on("agent_settled", () => {
|
|
199
|
+
scheduler.running = false;
|
|
200
|
+
scheduler.sealed = false;
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
async function runLoop(args: string, ctx: ExtensionContext, send: Send): Promise<void> {
|
|
204
|
+
const cmd = parseLoop(args);
|
|
205
|
+
// Also true during a manual compaction, which no run is behind: the first
|
|
206
|
+
// prompt then waits for idle, but only a run in flight seals the slot.
|
|
207
|
+
const midRun = !ctx.isIdle();
|
|
208
|
+
// sendUserMessage only starts the run, and a one-shot run disposes the
|
|
209
|
+
// session as soon as the command returns, so there the command waits it out.
|
|
210
|
+
const fire = async (prompt: string) => {
|
|
211
|
+
// The slot is sealed against the run in flight, so the loop's first
|
|
212
|
+
// prompt takes the slot and runs once that run has settled. Its own
|
|
213
|
+
// re-arm then comes from a later run and is not refused.
|
|
214
|
+
if (midRun) {
|
|
215
|
+
scheduler.scheduleWakeup(0, () => send(prompt), ctx);
|
|
216
|
+
ctx.ui.notify("The loop starts once the session is idle.", "info");
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (!oneShot.exits(ctx)) {
|
|
220
|
+
send(prompt);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
await oneShot.assertStartsRun(prompt, ctx);
|
|
224
|
+
const settled = oneShot.untilSettled();
|
|
225
|
+
send(prompt);
|
|
226
|
+
await settled;
|
|
227
|
+
};
|
|
228
|
+
switch (cmd.kind) {
|
|
229
|
+
case "usage":
|
|
230
|
+
ctx.ui.notify(`${cmd.reason ? `${cmd.reason} ` : ""}Usage: /loop [interval like 5m or 1h] <prompt>, or /loop stop`, "info");
|
|
231
|
+
return;
|
|
232
|
+
case "stop":
|
|
233
|
+
ctx.ui.notify(scheduler.stopAll(scheduler.running) ? "Loop stopped." : "No loop was running.", "info");
|
|
234
|
+
return;
|
|
235
|
+
case "fixed": {
|
|
236
|
+
const seconds = Math.max(MIN_DELAY_S, cmd.seconds);
|
|
237
|
+
scheduler.stopAll(scheduler.running);
|
|
238
|
+
scheduler.startLoop(seconds, () => send(cmd.prompt), ctx);
|
|
239
|
+
ctx.ui.notify(`Looping every ${seconds}s. /loop stop ends it.`, "info");
|
|
240
|
+
await fire(cmd.prompt);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
case "dynamic":
|
|
244
|
+
scheduler.stopAll(scheduler.running);
|
|
245
|
+
scheduler.startSelfPaced();
|
|
246
|
+
await fire(dynamicPrompt(cmd.prompt));
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
pi.registerCommand("loop", {
|
|
251
|
+
description: "Run a prompt on an interval (/loop 5m <prompt>), self-paced (/loop <prompt>), or stop (/loop stop)",
|
|
252
|
+
handler: (args, ctx) => runLoop(args, ctx, sendAsUser),
|
|
253
|
+
});
|
|
254
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { SlashCommandInfo } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
|
|
4
|
+
// Pi expands "/skill:name args" and "/template args" only inside sendUserMessage, and its package exports
|
|
5
|
+
// none of the code that does it. This is that code from pi 1.4.0 (AgentSession._expandSkillCommand,
|
|
6
|
+
// dist/core/prompt-templates.js, and dist/utils/frontmatter.js), reading the files pi.getCommands() names,
|
|
7
|
+
// for text the extension sends as a custom message. tests/pi/slash.test.mjs checks it against the installed pi.
|
|
8
|
+
|
|
9
|
+
export function stripFrontmatter(content: string): string {
|
|
10
|
+
const normalized = content.replace(/^\uFEFF/, "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
11
|
+
if (!normalized.startsWith("---")) return normalized;
|
|
12
|
+
const endIndex = normalized.indexOf("\n---", 3);
|
|
13
|
+
return endIndex === -1 ? normalized : normalized.slice(endIndex + 4).trim();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Splits on whitespace outside quotes; a quote ends at the next quote of the same kind, and "" is an argument.
|
|
17
|
+
export function parseCommandArgs(argsString: string): string[] {
|
|
18
|
+
const args: string[] = [];
|
|
19
|
+
let current = "";
|
|
20
|
+
let hasToken = false;
|
|
21
|
+
let inQuote: string | null = null;
|
|
22
|
+
for (const char of argsString) {
|
|
23
|
+
if (inQuote) {
|
|
24
|
+
if (char === inQuote) inQuote = null;
|
|
25
|
+
else current += char;
|
|
26
|
+
} else if (char === '"' || char === "'") {
|
|
27
|
+
inQuote = char;
|
|
28
|
+
hasToken = true;
|
|
29
|
+
} else if (/\s/.test(char)) {
|
|
30
|
+
if (hasToken) {
|
|
31
|
+
args.push(current);
|
|
32
|
+
current = "";
|
|
33
|
+
hasToken = false;
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
current += char;
|
|
37
|
+
hasToken = true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (hasToken) args.push(current);
|
|
41
|
+
return args;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// $1, $@, $ARGUMENTS, ${N:-default}, ${@:-default}, ${@:N} and ${@:N:L}. A value is not substituted again.
|
|
45
|
+
export function substituteArgs(content: string, args: string[]): string {
|
|
46
|
+
const allArgs = args.join(" ");
|
|
47
|
+
return content.replace(
|
|
48
|
+
/\$\{(\d+|ARGUMENTS|@):-([^}]*)\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g,
|
|
49
|
+
(_match, defaultTarget, defaultValue, sliceStart, sliceLength, simple) => {
|
|
50
|
+
if (defaultTarget) {
|
|
51
|
+
const value = defaultTarget === "@" || defaultTarget === "ARGUMENTS" ? allArgs : args[parseInt(defaultTarget, 10) - 1];
|
|
52
|
+
return value ? value : defaultValue;
|
|
53
|
+
}
|
|
54
|
+
if (sliceStart) {
|
|
55
|
+
const start = Math.max(0, parseInt(sliceStart, 10) - 1);
|
|
56
|
+
return (sliceLength ? args.slice(start, start + parseInt(sliceLength, 10)) : args.slice(start)).join(" ");
|
|
57
|
+
}
|
|
58
|
+
if (simple === "ARGUMENTS" || simple === "@") return allArgs;
|
|
59
|
+
return args[parseInt(simple, 10) - 1] ?? "";
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function expandSkillCommand(commands: readonly SlashCommandInfo[], text: string): string {
|
|
65
|
+
if (!text.startsWith("/skill:")) return text;
|
|
66
|
+
const spaceIndex = text.indexOf(" ");
|
|
67
|
+
const name = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);
|
|
68
|
+
const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1).trim();
|
|
69
|
+
const skill = commands.find((c) => c.source === "skill" && c.name === name);
|
|
70
|
+
if (!skill) return text;
|
|
71
|
+
const { path, baseDir } = skill.sourceInfo;
|
|
72
|
+
const body = stripFrontmatter(readFileSync(path, "utf8")).trim();
|
|
73
|
+
const block = `<skill name="${name.slice("skill:".length)}" location="${path}">\nReferences are relative to ${baseDir}.\n\n${body}\n</skill>`;
|
|
74
|
+
return args ? `${block}\n\n${args}` : block;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function expandPromptTemplate(commands: readonly SlashCommandInfo[], text: string): string {
|
|
78
|
+
const match = /^\/([^\s]+)(?:\s+([\s\S]*))?$/.exec(text);
|
|
79
|
+
const template = match && commands.find((c) => c.source === "prompt" && c.name === match[1]);
|
|
80
|
+
if (!template) return text;
|
|
81
|
+
return substituteArgs(stripFrontmatter(readFileSync(template.sourceInfo.path, "utf8")), parseCommandArgs(match[2] ?? ""));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// The text a user message with this text would carry. A name pi has no skill or template for stays as written,
|
|
85
|
+
// and so does an extension command: pi runs one only from a user message, and the agent must not run one as the
|
|
86
|
+
// user. Throws when a command's file cannot be read, where pi reports the error and sends the text as written.
|
|
87
|
+
export function expandSlash(commands: readonly SlashCommandInfo[], text: string): string {
|
|
88
|
+
const spaceIndex = text.indexOf(" ");
|
|
89
|
+
const name = spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex);
|
|
90
|
+
if (text.startsWith("/") && commands.some((c) => c.source === "extension" && c.name === name)) return text;
|
|
91
|
+
return expandPromptTemplate(commands, expandSkillCommand(commands, text));
|
|
92
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// Whether a bash command line waits on a foreground `sleep`, the way a model
|
|
2
|
+
// polls for a background agent it should leave alone.
|
|
3
|
+
//
|
|
4
|
+
// A token rule, not a shell parser. After heredoc bodies, quoted strings, and
|
|
5
|
+
// comments are removed, the word `sleep` followed by a literal duration of
|
|
6
|
+
// MIN_WAIT_S or more blocks, anywhere in the line, unless that sleep itself is
|
|
7
|
+
// directly backgrounded (`sleep 30 &`, never `&&` or `&>`). It errs toward
|
|
8
|
+
// blocking: a wrongly blocked command costs one rephrased turn, a missed poll
|
|
9
|
+
// loop costs minutes. Known misses: a sleep inside a quoted script such as
|
|
10
|
+
// `bash -c 'sleep 30'`, a quoted duration (`sleep "30"`), a variable duration
|
|
11
|
+
// (`sleep $N`), and a poll loop of sleeps under two seconds. Known over-blocks:
|
|
12
|
+
// a sleep inside a backgrounded group (`(sleep 30; echo done) &`), a
|
|
13
|
+
// backgrounded sleep with a redirection before the `&`, and
|
|
14
|
+
// `timeout 5 sleep 30`. tests/pi/sleep-wait.test.mjs lists each, so changing
|
|
15
|
+
// one is a visible decision.
|
|
16
|
+
const MIN_WAIT_S = 2;
|
|
17
|
+
const SLEEP_UNITS: Record<string, number> = { "": 1, s: 1, m: 60, h: 3600, d: 86400 };
|
|
18
|
+
|
|
19
|
+
// Seconds a literal sleep argument asks for (30, 2.5, 1m, 1m30s, infinity);
|
|
20
|
+
// 0 when it is not a literal.
|
|
21
|
+
function sleepSeconds(arg: string): number {
|
|
22
|
+
if (/^inf(inity)?$/.test(arg)) return Infinity;
|
|
23
|
+
const parts = arg.match(/\d*\.?\d+[smhd]?/g);
|
|
24
|
+
if (!parts || parts.join("") !== arg) return 0;
|
|
25
|
+
return parts.reduce((sum, part) => {
|
|
26
|
+
const unit = /[smhd]$/.exec(part)?.[0] ?? "";
|
|
27
|
+
return sum + Number(part.slice(0, part.length - unit.length)) * SLEEP_UNITS[unit];
|
|
28
|
+
}, 0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// One line with its quoted strings replaced by "" and a comment cut off, in a
|
|
32
|
+
// single left-to-right pass. An unterminated quote drops the rest of the line.
|
|
33
|
+
function stripQuotesAndComment(line: string): string {
|
|
34
|
+
let out = "";
|
|
35
|
+
let quote: string | undefined;
|
|
36
|
+
for (let i = 0; i < line.length; i++) {
|
|
37
|
+
const c = line[i];
|
|
38
|
+
if (quote) {
|
|
39
|
+
if (c === "\\" && quote === '"') i++;
|
|
40
|
+
else if (c === quote) {
|
|
41
|
+
quote = undefined;
|
|
42
|
+
out += '""';
|
|
43
|
+
}
|
|
44
|
+
} else if (c === "\\") {
|
|
45
|
+
out += c + (line[i + 1] ?? "");
|
|
46
|
+
i++;
|
|
47
|
+
} else if (c === '"' || c === "'") quote = c;
|
|
48
|
+
else if (c === "#" && (i === 0 || /\s/.test(line[i - 1]))) break;
|
|
49
|
+
else out += c;
|
|
50
|
+
}
|
|
51
|
+
return out;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The command text the shell would run: heredoc bodies, quoted strings, and
|
|
55
|
+
// comments removed, one pass over the lines so the cost stays linear. The
|
|
56
|
+
// line that opens a heredoc is kept, since commands can follow the `<<`.
|
|
57
|
+
function shellText(command: string): string {
|
|
58
|
+
const kept: string[] = [];
|
|
59
|
+
let terminator: string | undefined;
|
|
60
|
+
for (const line of command.split("\n")) {
|
|
61
|
+
if (terminator !== undefined) {
|
|
62
|
+
if (line.trim() === terminator) terminator = undefined;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
kept.push(stripQuotesAndComment(line));
|
|
66
|
+
terminator = /<<-?\s*(["']?)(\w+)\1/.exec(line)?.[2];
|
|
67
|
+
}
|
|
68
|
+
return kept.join("\n");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function isForegroundWait(command: string): boolean {
|
|
72
|
+
for (const m of shellText(command).matchAll(/\bsleep\s+([^\s;|&()<>]+)\s*(&(?![&>]))?/g)) {
|
|
73
|
+
if (m[2] === undefined && sleepSeconds(m[1]) >= MIN_WAIT_S) return true;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|