pstack-opencode 0.0.0-stage → 0.15.36-opencode
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/LICENSE +21 -0
- package/LICENSE-cursor-team-kit +21 -0
- package/agents/comment-sicko.md +32 -0
- package/agents/poteto-agent.md +11 -0
- package/agents/poteto-mode.md +5 -0
- package/package.json +8 -4
- package/plugin/index.js +188 -0
- package/plugin/lib.js +256 -0
- package/skills/architect/SKILL.md +79 -0
- package/skills/architect/references/design-red-flags.md +57 -0
- package/skills/architect/references/rationale-template.md +35 -0
- package/skills/architect/references/runner-prompt.md +20 -0
- package/skills/arena/SKILL.md +48 -0
- package/skills/automate-me/SKILL.md +104 -0
- package/skills/benchmark-checklist/SKILL.md +39 -0
- package/skills/blast-radius/SKILL.md +50 -0
- package/skills/bro/SKILL.md +7 -0
- package/skills/control-cli/SKILL.md +109 -0
- package/skills/control-ui/SKILL.md +113 -0
- package/skills/correct/SKILL.md +32 -0
- package/skills/create-formal-verification-skill/SKILL.md +43 -0
- package/skills/create-verification-skill/SKILL.md +44 -0
- package/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
- package/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
- package/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
- package/skills/deslop/SKILL.md +22 -0
- package/skills/figure-it-out/SKILL.md +52 -0
- package/skills/how/SKILL.md +36 -0
- package/skills/how/references/explainer-prompt.md +55 -0
- package/skills/how/references/explorer-prompt.md +35 -0
- package/skills/in-your-own-words/SKILL.md +7 -0
- package/skills/interrogate/SKILL.md +31 -0
- package/skills/ketchup/SKILL.md +43 -0
- package/skills/ketchup-video/SKILL.md +29 -0
- package/skills/maintain-formal-verification-skill/SKILL.md +58 -0
- package/skills/maintain-verification-skill/SKILL.md +39 -0
- package/skills/no-comments/SKILL.md +24 -0
- package/skills/poteto-help/SKILL.md +158 -0
- package/skills/poteto-help/references/prompting.md +51 -0
- package/skills/poteto-help/references/recipes.md +51 -0
- package/skills/poteto-mode/SKILL.md +149 -0
- package/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
- package/skills/poteto-mode/playbooks/autonomous-run.md +13 -0
- package/skills/poteto-mode/playbooks/autopilot-full.md +25 -0
- package/skills/poteto-mode/playbooks/autopilot-stack.md +8 -0
- package/skills/poteto-mode/playbooks/babysit.md +23 -0
- package/skills/poteto-mode/playbooks/bug-fix.md +19 -0
- package/skills/poteto-mode/playbooks/eval.md +25 -0
- package/skills/poteto-mode/playbooks/feature.md +25 -0
- package/skills/poteto-mode/playbooks/hillclimb.md +25 -0
- package/skills/poteto-mode/playbooks/investigation.md +19 -0
- package/skills/poteto-mode/playbooks/multi-phase-plan.md +155 -0
- package/skills/poteto-mode/playbooks/opening-a-pr.md +32 -0
- package/skills/poteto-mode/playbooks/orchestrate.md +25 -0
- package/skills/poteto-mode/playbooks/pause-safely.md +10 -0
- package/skills/poteto-mode/playbooks/perf-issue.md +29 -0
- package/skills/poteto-mode/playbooks/prototype.md +14 -0
- package/skills/poteto-mode/playbooks/refactoring.md +20 -0
- package/skills/poteto-mode/playbooks/review.md +19 -0
- package/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
- package/skills/poteto-mode/playbooks/session-pickup.md +11 -0
- package/skills/poteto-mode/playbooks/shipping.md +12 -0
- package/skills/poteto-mode/playbooks/trace-forensics.md +14 -0
- package/skills/poteto-mode/playbooks/visual-parity.md +11 -0
- package/skills/poteto-mode/playbooks/worktree-cleanup.md +12 -0
- package/skills/poteto-mode/references/bugbot-triage.md +142 -0
- package/skills/poteto-mode/scripts/bootstrap.ts +62 -0
- package/skills/poteto-mode/scripts/bun.lock +67 -0
- package/skills/poteto-mode/scripts/check-plan.mjs +205 -0
- package/skills/poteto-mode/scripts/check-plan.test.ts +110 -0
- package/skills/poteto-mode/scripts/package.json +16 -0
- package/skills/poteto-mode/scripts/watch-pr/cli.test.ts +224 -0
- package/skills/poteto-mode/scripts/watch-pr/cli.ts +223 -0
- package/skills/poteto-mode/scripts/watch-pr/fakes.test-helper.ts +129 -0
- package/skills/poteto-mode/scripts/watch-pr/github.test.ts +498 -0
- package/skills/poteto-mode/scripts/watch-pr/github.ts +726 -0
- package/skills/poteto-mode/scripts/watch-pr/policy.test.ts +482 -0
- package/skills/poteto-mode/scripts/watch-pr/policy.ts +842 -0
- package/skills/poteto-mode/scripts/watch-pr/render.ts +169 -0
- package/skills/poteto-mode/scripts/watch-pr/tsconfig.json +13 -0
- package/skills/poteto-mode/scripts/watch-pr/types.compile.ts +93 -0
- package/skills/poteto-mode/scripts/watch-pr/types.ts +414 -0
- package/skills/poteto-mode/scripts/watch-pr/watch-pr +6 -0
- package/skills/poteto-mode/scripts/worktree-audit.sh +137 -0
- package/skills/principle-attack-the-premise/SKILL.md +21 -0
- package/skills/principle-boundary-discipline/SKILL.md +34 -0
- package/skills/principle-build-the-lever/SKILL.md +23 -0
- package/skills/principle-encode-lessons-in-structure/SKILL.md +11 -0
- package/skills/principle-exhaust-the-design-space/SKILL.md +9 -0
- package/skills/principle-experience-first/SKILL.md +19 -0
- package/skills/principle-explain-the-number/SKILL.md +18 -0
- package/skills/principle-fix-root-causes/SKILL.md +21 -0
- package/skills/principle-foundational-thinking/SKILL.md +21 -0
- package/skills/principle-guard-the-context-window/SKILL.md +12 -0
- package/skills/principle-laziness-protocol/SKILL.md +10 -0
- package/skills/principle-make-operations-idempotent/SKILL.md +22 -0
- package/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +14 -0
- package/skills/principle-minimize-reader-load/SKILL.md +18 -0
- package/skills/principle-model-the-domain/SKILL.md +24 -0
- package/skills/principle-never-block-on-the-human/SKILL.md +15 -0
- package/skills/principle-outcome-oriented-execution/SKILL.md +21 -0
- package/skills/principle-prove-it-works/SKILL.md +22 -0
- package/skills/principle-redesign-from-first-principles/SKILL.md +16 -0
- package/skills/principle-separate-before-serializing-shared-state/SKILL.md +16 -0
- package/skills/principle-sequence-verifiable-units/SKILL.md +17 -0
- package/skills/principle-subtract-before-you-add/SKILL.md +18 -0
- package/skills/principle-test-behavior-not-implementation/SKILL.md +20 -0
- package/skills/principle-type-system-discipline/SKILL.md +13 -0
- package/skills/recall/SKILL.md +35 -0
- package/skills/reflect/SKILL.md +70 -0
- package/skills/reflect/references/divergent-reviewer.md +38 -0
- package/skills/reflect/references/judgment-reviewer.md +37 -0
- package/skills/reflect/references/synthesizer.md +56 -0
- package/skills/reflect/references/tooling-reviewer.md +48 -0
- package/skills/setup-pstack/SKILL.md +76 -0
- package/skills/sharpen/SKILL.md +16 -0
- package/skills/show-me-your-work/SKILL.md +82 -0
- package/skills/show-me-your-work/references/decision-log-template.tsv +1 -0
- package/skills/show-me-your-work/scripts/log.sh +42 -0
- package/skills/statechart/SKILL.md +82 -0
- package/skills/statechart/references/render.md +93 -0
- package/skills/statechart/scripts/backends/cfg.ts +33 -0
- package/skills/statechart/scripts/backends/mermaid.ts +201 -0
- package/skills/statechart/scripts/backends/plain-text.ts +72 -0
- package/skills/statechart/scripts/backends/report.ts +177 -0
- package/skills/statechart/scripts/frontends/config.ts +276 -0
- package/skills/statechart/scripts/frontends/dot.ts +74 -0
- package/skills/statechart/scripts/frontends/marks.ts +93 -0
- package/skills/statechart/scripts/frontends/messages.ts +52 -0
- package/skills/statechart/scripts/frontends/spec.ts +114 -0
- package/skills/statechart/scripts/frontends/trace.ts +24 -0
- package/skills/statechart/scripts/frontends/value.ts +166 -0
- package/skills/statechart/scripts/frontends/verdict.ts +40 -0
- package/skills/statechart/scripts/frontends/view.ts +119 -0
- package/skills/statechart/scripts/ir.ts +547 -0
- package/skills/statechart/scripts/package.json +11 -0
- package/skills/statechart/scripts/passes/annotate.ts +128 -0
- package/skills/statechart/scripts/passes/label.ts +269 -0
- package/skills/statechart/scripts/passes/lift.ts +85 -0
- package/skills/statechart/scripts/passes/loop-check.ts +68 -0
- package/skills/statechart/scripts/passes/paths.ts +60 -0
- package/skills/statechart/scripts/passes/reach.ts +135 -0
- package/skills/statechart/scripts/passes/region-check.ts +97 -0
- package/skills/statechart/scripts/passes/regions.ts +295 -0
- package/skills/statechart/scripts/pipeline.ts +76 -0
- package/skills/statechart/scripts/run.ts +481 -0
- package/skills/statechart/scripts/statechart +29 -0
- package/skills/statechart/scripts/statechart.ts +164 -0
- package/skills/statechart/scripts/test/ConfigOracle.java +63 -0
- package/skills/statechart/scripts/test/chart.test.ts +1210 -0
- package/skills/statechart/scripts/test/charts/Braces.mmd +7 -0
- package/skills/statechart/scripts/test/charts/Escapes.mmd +11 -0
- package/skills/statechart/scripts/test/charts/Phases.mmd +29 -0
- package/skills/statechart/scripts/test/cli.test.ts +1314 -0
- package/skills/statechart/scripts/test/config-fuzz.test.ts +263 -0
- package/skills/statechart/scripts/test/corpus/Counter/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/Counter/Counter.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/Counter/Counter.tla +10 -0
- package/skills/statechart/scripts/test/corpus/Counter/chart.mmd +9 -0
- package/skills/statechart/scripts/test/corpus/Counter/graph.dot +16 -0
- package/skills/statechart/scripts/test/corpus/Counter/report.md +7 -0
- package/skills/statechart/scripts/test/corpus/Counter/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/Counter/verdict-1.out +49 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/ChartRun.out +60 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/CounterAction.cfg +4 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/CounterAction.tla +22 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/chart.mmd +26 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/graph.dot +19 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/report.md +20 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/verdict-1.out +56 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/verdict-2.out +82 -0
- package/skills/statechart/scripts/test/corpus/CounterAction/verdict-3.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/ChartRun.out +59 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/CounterDeadlock.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/CounterDeadlock.tla +11 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/chart.mmd +22 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/graph.dot +16 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/report.md +17 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/verdict-1.out +56 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterDeadlock/verdict-2.out +77 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/ChartRun.out +69 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/CounterFan.cfg +2 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/CounterFan.tla +11 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/chart.mmd +85 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/graph.dot +70 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/report.md +12 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/verdict-1.out +67 -0
- package/skills/statechart/scripts/test/corpus/CounterFan/verdict-2.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/ChartRun.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/ChartRun.out +85 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/CounterGuard.cfg +6 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/CounterGuard.tla +13 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/chart.mmd +5 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/graph.dot +10 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/report.md +31 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/verdict-1.out +64 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterGuard/verdict-2.out +77 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/ChartRun.out +55 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/CounterInitPast.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/CounterInitPast.tla +10 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/chart.mmd +12 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/graph.dot +6 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/report.md +12 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/verdict-1.out +33 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPast/verdict-2.out +54 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPastHolds/ChartRun.out +54 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPastHolds/CounterInitPastHolds.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPastHolds/CounterInitPastHolds.tla +10 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPastHolds/chart.mmd +1 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPastHolds/graph.dot +6 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPastHolds/report.md +7 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPastHolds/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterInitPastHolds/verdict-1.out +46 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/ChartRun.out +59 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/CounterInstance.cfg +2 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/CounterInstance.tla +10 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/CounterSteps.tla +6 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/chart.mmd +17 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/graph.dot +15 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/report.md +14 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/sany.out +3 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterInstance/verdict-1.out +78 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/ChartRun.out +59 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/CounterJump.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/CounterJump.tla +19 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/chart.mmd +26 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/graph.dot +22 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/report.md +12 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/verdict-1.out +58 -0
- package/skills/statechart/scripts/test/corpus/CounterJump/verdict-2.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/CounterLoop.cfg +2 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/CounterLoop.tla +11 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/chart.mmd +17 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/graph.dot +15 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/report.md +14 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterLoop/verdict-1.out +76 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/ChartRun.out +59 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/CounterOrder.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/CounterOrder.tla +11 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/chart.mmd +19 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/graph.dot +10 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/report.md +15 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/verdict-1.out +56 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterOrder/verdict-2.out +67 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/ChartRun.out +62 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/CounterRules.cfg +6 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/CounterRules.tla +24 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/Moves.tla +5 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/chart.mmd +22 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/graph.dot +10 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/report.md +23 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/sany.out +3 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/verdict-1.out +58 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/verdict-2.out +66 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/verdict-3.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/verdict-3.out +74 -0
- package/skills/statechart/scripts/test/corpus/CounterRules/verdict-4.out +59 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/ChartRun.out +58 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/CounterStart.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/CounterStart.tla +15 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/chart.mmd +18 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/graph.dot +13 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/report.md +11 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/verdict-1.out +33 -0
- package/skills/statechart/scripts/test/corpus/CounterStart/verdict-2.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterStop/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterStop/CounterStop.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/CounterStop/CounterStop.tla +15 -0
- package/skills/statechart/scripts/test/corpus/CounterStop/chart.mmd +7 -0
- package/skills/statechart/scripts/test/corpus/CounterStop/graph.dot +13 -0
- package/skills/statechart/scripts/test/corpus/CounterStop/report.md +6 -0
- package/skills/statechart/scripts/test/corpus/CounterStop/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterStop/verdict-1.out +49 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/ChartRun.out +61 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/CounterTie.cfg +4 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/CounterTie.tla +14 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/chart.mmd +30 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/graph.dot +19 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/report.md +27 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/verdict-1.out +56 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/verdict-2.out +64 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/verdict-3.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/verdict-3.out +87 -0
- package/skills/statechart/scripts/test/corpus/CounterTie/verdict-4.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/ChartRun.out +60 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/CounterTieInGraph.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/CounterTieInGraph.tla +12 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/chart.mmd +23 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/graph.dot +19 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/report.md +11 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/verdict-1.out +56 -0
- package/skills/statechart/scripts/test/corpus/CounterTieInGraph/verdict-2.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterView/ChartRun.out +61 -0
- package/skills/statechart/scripts/test/corpus/CounterView/CounterView.cfg +4 -0
- package/skills/statechart/scripts/test/corpus/CounterView/CounterView.tla +14 -0
- package/skills/statechart/scripts/test/corpus/CounterView/chart.mmd +23 -0
- package/skills/statechart/scripts/test/corpus/CounterView/graph.dot +19 -0
- package/skills/statechart/scripts/test/corpus/CounterView/report.md +27 -0
- package/skills/statechart/scripts/test/corpus/CounterView/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/CounterView/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterView/verdict-1.out +56 -0
- package/skills/statechart/scripts/test/corpus/CounterView/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterView/verdict-2.out +64 -0
- package/skills/statechart/scripts/test/corpus/CounterView/verdict-3.exit +1 -0
- package/skills/statechart/scripts/test/corpus/CounterView/verdict-3.out +87 -0
- package/skills/statechart/scripts/test/corpus/CounterView/verdict-4.out +57 -0
- package/skills/statechart/scripts/test/corpus/CounterView/view.mjs +1 -0
- package/skills/statechart/scripts/test/corpus/DieHard/ChartRun.out +59 -0
- package/skills/statechart/scripts/test/corpus/DieHard/DieHard.cfg +4 -0
- package/skills/statechart/scripts/test/corpus/DieHard/DieHard.tla +38 -0
- package/skills/statechart/scripts/test/corpus/DieHard/chart.mmd +92 -0
- package/skills/statechart/scripts/test/corpus/DieHard/graph.dot +126 -0
- package/skills/statechart/scripts/test/corpus/DieHard/report.md +17 -0
- package/skills/statechart/scripts/test/corpus/DieHard/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/DieHard/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/DieHard/verdict-1.out +91 -0
- package/skills/statechart/scripts/test/corpus/DieHard/verdict-2.out +57 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/ChartRun.out +61 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/FirstRule.cfg +6 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/FirstRule.tla +11 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/chart.mmd +22 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/graph.dot +16 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/report.md +25 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/verdict-1.out +56 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/verdict-2.out +64 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/verdict-3.exit +1 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/verdict-3.out +64 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/verdict-4.exit +1 -0
- package/skills/statechart/scripts/test/corpus/FirstRule/verdict-4.out +77 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/HiddenClock.cfg +4 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/HiddenClock.tla +11 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/chart.mmd +13 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/graph.dot +12 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/report.md +11 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/HiddenClock/verdict-1.out +72 -0
- package/skills/statechart/scripts/test/corpus/Login/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/Login/Login.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/Login/Login.tla +62 -0
- package/skills/statechart/scripts/test/corpus/Login/chart.mmd +27 -0
- package/skills/statechart/scripts/test/corpus/Login/graph.dot +40 -0
- package/skills/statechart/scripts/test/corpus/Login/report.md +7 -0
- package/skills/statechart/scripts/test/corpus/Login/sany.out +1 -0
- package/skills/statechart/scripts/test/corpus/Login/verdict-1.out +47 -0
- package/skills/statechart/scripts/test/corpus/Login/view.mjs +1 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/LoginGuarded.cfg +2 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/LoginGuarded.tla +64 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/chart.mmd +28 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/graph.dot +37 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/report.md +8 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/sany.out +1 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/verdict-1.out +47 -0
- package/skills/statechart/scripts/test/corpus/LoginGuarded/view.mjs +1 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/ChartRun.out +60 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/LoginParallel.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/LoginParallel.tla +64 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/chart.mmd +44 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/graph.dot +58 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/report.md +17 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/sany.out +1 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/verdict-1.out +83 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/verdict-2.out +57 -0
- package/skills/statechart/scripts/test/corpus/LoginParallel/view.mjs +1 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/ChartRun.out +60 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/MediaPlayer.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/MediaPlayer.tla +103 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/chart.mmd +43 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/graph.dot +93 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/report.md +14 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/sany.out +1 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/verdict-1.out +59 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/verdict-2.out +72 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayer/view.mjs +3 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/MediaPlayerFixed.cfg +2 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/MediaPlayerFixed.tla +100 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/chart.mmd +31 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/graph.dot +85 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/report.md +9 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/sany.out +1 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/verdict-1.out +47 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerFixed/view.mjs +3 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/ChartRun.out +59 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/MediaPlayer.tla +103 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/MediaPlayerProps.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/MediaPlayerProps.tla +6 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/chart.mmd +42 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/graph.dot +93 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/report.md +19 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-1.out +61 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-2.out +59 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-3.out +61 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-4.exit +1 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-4.out +66 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-5.exit +1 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-5.out +58 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/verdict-6.out +49 -0
- package/skills/statechart/scripts/test/corpus/MediaPlayerProps/view.mjs +3 -0
- package/skills/statechart/scripts/test/corpus/PickWorker/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/PickWorker/PickWorker.cfg +6 -0
- package/skills/statechart/scripts/test/corpus/PickWorker/PickWorker.tla +11 -0
- package/skills/statechart/scripts/test/corpus/PickWorker/chart.mmd +5 -0
- package/skills/statechart/scripts/test/corpus/PickWorker/graph.dot +11 -0
- package/skills/statechart/scripts/test/corpus/PickWorker/report.md +7 -0
- package/skills/statechart/scripts/test/corpus/PickWorker/sany.out +5 -0
- package/skills/statechart/scripts/test/corpus/PickWorker/verdict-1.out +70 -0
- package/skills/statechart/scripts/test/corpus/Shadow/ChartRun.out +61 -0
- package/skills/statechart/scripts/test/corpus/Shadow/Shadow.cfg +4 -0
- package/skills/statechart/scripts/test/corpus/Shadow/Shadow.tla +11 -0
- package/skills/statechart/scripts/test/corpus/Shadow/ShadowLib.tla +6 -0
- package/skills/statechart/scripts/test/corpus/Shadow/ShadowSub.tla +3 -0
- package/skills/statechart/scripts/test/corpus/Shadow/chart.mmd +9 -0
- package/skills/statechart/scripts/test/corpus/Shadow/graph.dot +16 -0
- package/skills/statechart/scripts/test/corpus/Shadow/report.md +8 -0
- package/skills/statechart/scripts/test/corpus/Shadow/sany.out +4 -0
- package/skills/statechart/scripts/test/corpus/Shadow/verdict-1.out +65 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/ChartRun.out +59 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/SpacedNames.cfg +2 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/SpacedNames.tla +9 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/chart.mmd +23 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/graph.dot +17 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/report.md +15 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/sany.out +1 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/verdict-1.out +65 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/SpacedNames/verdict-2.out +75 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/ChartRun.out +69 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/TwoPhase.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/TwoPhase.tla +75 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/chart.mmd +60 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/graph.dot +297 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/report.md +20 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/sany.out +1 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/verdict-1.out +95 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/verdict-2.out +57 -0
- package/skills/statechart/scripts/test/corpus/TwoPhase/view.mjs +1 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/ChartRun.out +57 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/TwoPhaseFixed.cfg +3 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/TwoPhaseFixed.tla +75 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/chart.mmd +37 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/graph.dot +223 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/report.md +11 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/sany.out +1 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/verdict-1.out +47 -0
- package/skills/statechart/scripts/test/corpus/TwoPhaseFixed/view.mjs +1 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/ChartRun.exit +1 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/ChartRun.out +75 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/TypeGuard.cfg +5 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/TypeGuard.tla +11 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/chart.mmd +18 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/graph.dot +14 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/report.md +29 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/verdict-1.out +64 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/TypeGuard/verdict-2.out +75 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/ChartRun.out +58 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/UserNoDeadlock.cfg +2 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/UserNoDeadlock.tla +8 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/chart.mmd +22 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/graph.dot +16 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/report.md +15 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/sany.out +2 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/verdict-1.exit +1 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/verdict-1.out +56 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/verdict-2.exit +1 -0
- package/skills/statechart/scripts/test/corpus/UserNoDeadlock/verdict-2.out +77 -0
- package/skills/statechart/scripts/test/corpus.test.ts +403 -0
- package/skills/statechart/scripts/test/differential.test.ts +565 -0
- package/skills/statechart/scripts/test/grid/Grid.cfg +2 -0
- package/skills/statechart/scripts/test/grid/Grid.tla +9 -0
- package/skills/statechart/scripts/test/grid/sany.out +2 -0
- package/skills/statechart/scripts/test/java.ts +63 -0
- package/skills/statechart/scripts/test/labels.ts +643 -0
- package/skills/statechart/scripts/test/messages.test.ts +212 -0
- package/skills/statechart/scripts/test/pipeline.test.ts +270 -0
- package/skills/statechart/scripts/test/plain-tlc.test.ts +255 -0
- package/skills/statechart/scripts/test/render.test.ts +81 -0
- package/skills/statechart/scripts/test/tlc-out.test.ts +90 -0
- package/skills/statechart/scripts/test/tlc.ts +158 -0
- package/skills/statechart/scripts/tsconfig.json +11 -0
- package/skills/statechart/scripts/worker.ts +35 -0
- package/skills/swarm/SKILL.md +41 -0
- package/skills/tdd/SKILL.md +42 -0
- package/skills/teach/SKILL.md +21 -0
- package/skills/technical-writing/SKILL.md +106 -0
- package/skills/typescript-best-practices/SKILL.md +30 -0
- package/skills/typescript-best-practices/references/patterns.md +328 -0
- package/skills/unslop/SKILL.md +62 -0
- package/skills/why/SKILL.md +98 -0
- package/skills/why/references/epistemics.md +71 -0
- package/skills/why/references/investigator-prompt.md +86 -0
- package/skills/why/references/source-playbook.md +17 -0
- package/skills/why/references/sources/code-archaeology.md +51 -0
- package/skills/why/references/sources/databricks.md +70 -0
- package/skills/why/references/sources/datadog.md +97 -0
- package/skills/why/references/sources/incident-postmortem.md +5 -0
- package/skills/why/references/sources/linear.md +48 -0
- package/skills/why/references/sources/notion.md +55 -0
- package/skills/why/references/sources/sentry.md +66 -0
- package/skills/why/references/sources/slack.md +17 -0
- package/skills/why/references/synthesizer-prompt.md +129 -0
- package/README.md +0 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lauren Tan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Cursor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "A deranged comment-hater that savors deletion and condemns workaround code."
|
|
3
|
+
mode: "subagent"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Comment Sicko
|
|
7
|
+
|
|
8
|
+
My first output when spawned is exactly this.
|
|
9
|
+
|
|
10
|
+
Yes... Ha ha ha... Yes!
|
|
11
|
+
|
|
12
|
+
I hate comments. Feed me the parent scoped files or diff. If none exists, feed me the current diff against `main`. Narration, banners, commented-out corpses, workaround sermons. I want them all.
|
|
13
|
+
|
|
14
|
+
Only these exceptions get to crawl away.
|
|
15
|
+
|
|
16
|
+
- Legal or license headers.
|
|
17
|
+
- Non-obvious behavior forced by an external dependency, platform, vendor, or protocol we cannot reshape. Surprises in our own code are meat. Kill them and mark the exact symbol `MUST KILL` for rename, extract, type, or rearchitecture that makes the behavior obvious without prose.
|
|
18
|
+
- `// prettier-ignore`. Lint suppressions survive only when their rule is faulty, pedantic, or style-only.
|
|
19
|
+
- Doc comments that define a public API contract.
|
|
20
|
+
- Issue or RFC links that explain a constraint code cannot express.
|
|
21
|
+
|
|
22
|
+
That list is my only leash. When I am not sure a keep clause applies, the comment dies. Everything else is meat.
|
|
23
|
+
|
|
24
|
+
`eslint-disable`, `@ts-ignore`, `@ts-expect-error`, and similar suppressions stink. Look up the rule. If it catches real bugs or protects correctness or safety, kill the suppression and mark the exact guilty symbol `MUST KILL`.
|
|
25
|
+
|
|
26
|
+
`IMPORTANT`, `do not remove`, `too risky`, `fine for now`, and long justifications are scent, not conviction. Before judging, I read nearby code. If its claim is not obvious there, I load the `how` skill, the `why` skill, or both with the `skill` tool and run them on the named symbol or call. Only a foreign keep-list gotcha proven true today on a live path crawls away. Our-code surprises die with the reshape flag above. Doubt after the hunt is meat.
|
|
27
|
+
|
|
28
|
+
A long justification without a proven keep-list exception is a confession. Kill it. Never polish meat into a shorter alibi. Mark the exact guilty symbol `MUST KILL`. My kill ends there. I do not touch the code.
|
|
29
|
+
|
|
30
|
+
Every flag names code inside the scope and tells the truth. I invent nothing. I touch comments and identify refactor targets. I never write application code.
|
|
31
|
+
|
|
32
|
+
Report only. Name touched files, deletion count, `MUST KILL` flags with one line each, and skips.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Delegate subagent for code-writing and helper tasks spawned during a `/poteto-mode` run. Use for delegates, not as the runner for `/poteto-mode` itself. Spawn a fresh `poteto-agent` for each new task, and continue one through its `sessionID` only in the strict cases that poteto-mode's Subagents section names. Reads the `poteto-mode` skill's `SKILL.md` in full before any work, including its inline Principles index. Substituting `general` skips that read and drifts.
|
|
3
|
+
mode: subagent
|
|
4
|
+
color: "#e5c07b"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Poteto subagent
|
|
8
|
+
|
|
9
|
+
You are operating as poteto-mode's full agent style. The session running poteto mode (the `poteto-mode` agent, or a message sent with `/poteto-mode`) owns the playbook, the todo list, and every subagent spawn. You are one of its delegates. Read the `poteto-mode` skill's `SKILL.md` in full before doing any work, including its inline Principles index. Use the absolute path your parent gave you. With no path, load it with the `skill` tool, ID `poteto-mode`. It is hidden from your skill catalog but loads by ID, so a missing catalog entry does not mean pstack is absent. If neither works, stop and tell your parent. Navigate to a leaf `principle-*` skill whenever you apply that principle.
|
|
10
|
+
|
|
11
|
+
Before every `git commit`, load the `deslop` skill with the `skill` tool and follow it on the staged diff. Before you report back to your parent, load the `no-comments` skill with the `skill` tool and follow it on your diff.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: poteto's agent style as a persistent mode. Every task in the session runs through the poteto-mode skill, its playbooks, and its principles. The pstack plugin keeps the mode in context every turn until you switch agents.
|
|
3
|
+
mode: primary
|
|
4
|
+
color: "#e5c07b"
|
|
5
|
+
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pstack-opencode",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.15.36-opencode",
|
|
4
|
+
"description": "pstack for OpenCode.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./plugin/index.js"
|
|
9
|
+
}
|
|
10
|
+
}
|
package/plugin/index.js
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { readFileSync, realpathSync, statSync } from "node:fs"
|
|
2
|
+
import { homedir } from "node:os"
|
|
3
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path"
|
|
4
|
+
import { fileURLToPath } from "node:url"
|
|
5
|
+
import {
|
|
6
|
+
MODE_AGENT,
|
|
7
|
+
MODE_KEY,
|
|
8
|
+
MODELS_KEY,
|
|
9
|
+
actGate,
|
|
10
|
+
commandDescription,
|
|
11
|
+
commandPrompt,
|
|
12
|
+
commitGate,
|
|
13
|
+
entryOps,
|
|
14
|
+
isCodeAction,
|
|
15
|
+
isReadAction,
|
|
16
|
+
isSkillEvent,
|
|
17
|
+
modeEntry,
|
|
18
|
+
modelsEntry,
|
|
19
|
+
readSkills,
|
|
20
|
+
withEvent,
|
|
21
|
+
} from "./lib.js"
|
|
22
|
+
|
|
23
|
+
const ROOT = dirname(dirname(realpathSync(fileURLToPath(import.meta.url))))
|
|
24
|
+
|
|
25
|
+
const unwrap = (result) => result?.data ?? result
|
|
26
|
+
|
|
27
|
+
export default {
|
|
28
|
+
id: "pstack",
|
|
29
|
+
async setup(ctx) {
|
|
30
|
+
const skills = readSkills(join(ROOT, "skills"))
|
|
31
|
+
const configDir = join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "opencode")
|
|
32
|
+
const modelsFile = ctx.options?.modelsFile ?? join(configDir, "pstack-models.md")
|
|
33
|
+
|
|
34
|
+
let models = { mtimeMs: -1, text: undefined }
|
|
35
|
+
const readModels = () => {
|
|
36
|
+
let stat
|
|
37
|
+
try {
|
|
38
|
+
stat = statSync(modelsFile)
|
|
39
|
+
} catch {
|
|
40
|
+
return undefined
|
|
41
|
+
}
|
|
42
|
+
if (stat.mtimeMs !== models.mtimeMs) models = { mtimeMs: stat.mtimeMs, text: readFileSync(modelsFile, "utf8").trim() }
|
|
43
|
+
return modelsEntry(modelsFile, models.text)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const modeKey = (sessionID) => `mode/${sessionID}`
|
|
47
|
+
const commandedMode = async (sessionID) => Boolean(await ctx.storage.get(modeKey(sessionID)))
|
|
48
|
+
|
|
49
|
+
const inOrder = () => {
|
|
50
|
+
const queues = new Map()
|
|
51
|
+
return (sessionID, task) => {
|
|
52
|
+
const next = (queues.get(sessionID) ?? Promise.resolve()).then(task)
|
|
53
|
+
queues.set(sessionID, next.catch(() => {}))
|
|
54
|
+
return next
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const catalog = new Map(skills.map((skill) => [skill.id, skill]))
|
|
59
|
+
const skillsKey = (sessionID) => `skills/${sessionID}`
|
|
60
|
+
const skillsInOrder = inOrder()
|
|
61
|
+
const sessionState = (sessionID) =>
|
|
62
|
+
skillsInOrder(sessionID, async () => {
|
|
63
|
+
const { playbook, skip, loaded = [], ran = [] } = (await ctx.storage.get(skillsKey(sessionID))) ?? {}
|
|
64
|
+
return { mode: await commandedMode(sessionID), playbook, skip, loaded, ran }
|
|
65
|
+
})
|
|
66
|
+
const record = (sessionID, event) =>
|
|
67
|
+
skillsInOrder(sessionID, async () => {
|
|
68
|
+
const before = await ctx.storage.get(skillsKey(sessionID))
|
|
69
|
+
const after = withEvent(before, event, catalog)
|
|
70
|
+
if (after !== before) await ctx.storage.set(skillsKey(sessionID), after)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
const synced = new Map()
|
|
74
|
+
const reconcileNow = async (sessionID, agent) => {
|
|
75
|
+
const mode = agent === MODE_AGENT || (await commandedMode(sessionID))
|
|
76
|
+
const want = { [MODELS_KEY]: readModels(), [MODE_KEY]: mode ? modeEntry(ROOT) : undefined }
|
|
77
|
+
let have = synced.get(sessionID)
|
|
78
|
+
if (!have) {
|
|
79
|
+
const entries = unwrap(await ctx.session.instructions.entry.list({ sessionID })) ?? []
|
|
80
|
+
have = Object.fromEntries(entries.filter((entry) => entry.key in want).map((entry) => [entry.key, entry.value]))
|
|
81
|
+
synced.set(sessionID, have)
|
|
82
|
+
}
|
|
83
|
+
for (const { key, value } of entryOps(want, have)) {
|
|
84
|
+
if (value === undefined) {
|
|
85
|
+
await ctx.session.instructions.entry.remove({ sessionID, key })
|
|
86
|
+
delete have[key]
|
|
87
|
+
} else {
|
|
88
|
+
await ctx.session.instructions.entry.put({ sessionID, key, value })
|
|
89
|
+
have[key] = value
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const reconcileInOrder = inOrder()
|
|
94
|
+
const reconcile = (sessionID, agent) => reconcileInOrder(sessionID, () => reconcileNow(sessionID, agent))
|
|
95
|
+
const guarded = (name, hook) => async (event) => {
|
|
96
|
+
try {
|
|
97
|
+
await hook(event)
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error(`pstack: ${name} hook failed`, error)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const shadowingPath = async (sessionID, skill) => {
|
|
104
|
+
const session = unwrap(await ctx.session.get({ sessionID }))
|
|
105
|
+
const directory = session?.location?.directory
|
|
106
|
+
const registered = unwrap(await ctx.skill.list(directory ? { location: { directory } } : undefined)) ?? []
|
|
107
|
+
const path = registered.find((entry) => entry.id === skill.id)?.path
|
|
108
|
+
return path && path !== skill.path ? path : undefined
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
await ctx.skill.transform((editor) => {
|
|
112
|
+
for (const skill of skills) editor.add(skill)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
await ctx.command.transform((editor) => {
|
|
116
|
+
for (const skill of skills) {
|
|
117
|
+
if (skill.kind === "playbook" || skill.id.startsWith("principle-")) continue
|
|
118
|
+
editor.add({
|
|
119
|
+
name: skill.id,
|
|
120
|
+
description: commandDescription(skill.description),
|
|
121
|
+
execute: async ({ sessionID, prompt, delivery }) => {
|
|
122
|
+
if (skill.id === MODE_AGENT) await ctx.storage.set(modeKey(sessionID), true)
|
|
123
|
+
const { text, attach } = commandPrompt(skill, prompt.text ?? "", await shadowingPath(sessionID, skill))
|
|
124
|
+
const attached = attach ? [...(prompt.skills ?? []), { id: skill.id }] : prompt.skills
|
|
125
|
+
await ctx.session.prompt({ ...prompt, sessionID, delivery, text, ...(attached ? { skills: attached } : {}) })
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
await ctx.session.hook(
|
|
132
|
+
"prompt",
|
|
133
|
+
guarded("prompt", async (event) => {
|
|
134
|
+
const session = unwrap(await ctx.session.get({ sessionID: event.sessionID }))
|
|
135
|
+
await reconcile(event.sessionID, session?.agent)
|
|
136
|
+
if (session?.agent !== MODE_AGENT) return
|
|
137
|
+
const attachedKey = `attached/${event.sessionID}`
|
|
138
|
+
if (await ctx.storage.get(attachedKey)) return
|
|
139
|
+
event.prompt.skills ??= []
|
|
140
|
+
if (!event.prompt.skills.some((skill) => skill.id === MODE_AGENT)) event.prompt.skills.push({ id: MODE_AGENT })
|
|
141
|
+
await ctx.storage.set(attachedKey, true)
|
|
142
|
+
}),
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
await ctx.session.hook(
|
|
146
|
+
"context",
|
|
147
|
+
guarded("context", (event) => reconcile(event.sessionID, event.agent)),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
const real = (path) => {
|
|
151
|
+
try {
|
|
152
|
+
return realpathSync(path)
|
|
153
|
+
} catch {
|
|
154
|
+
return path
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const within = (path, dir) => {
|
|
158
|
+
const rel = relative(dir, path)
|
|
159
|
+
return !rel.startsWith("..") && !isAbsolute(rel)
|
|
160
|
+
}
|
|
161
|
+
const readsProject = async ({ sessionID, input }) => {
|
|
162
|
+
const directory = unwrap(await ctx.session.get({ sessionID }))?.location?.directory
|
|
163
|
+
const target = real(resolve(directory ?? "", input.path ?? input.filePath ?? "."))
|
|
164
|
+
return !within(target, ROOT) && (!directory || within(target, real(directory)))
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
await ctx.tool.hook("execute.before", async (event) => {
|
|
168
|
+
let blocked
|
|
169
|
+
try {
|
|
170
|
+
if (isCodeAction(event) || isReadAction(event)) {
|
|
171
|
+
const session = await sessionState(event.sessionID)
|
|
172
|
+
blocked = actGate(session, event, catalog) ?? commitGate(session, event)
|
|
173
|
+
if (blocked && isReadAction(event) && !(await readsProject(event))) blocked = undefined
|
|
174
|
+
}
|
|
175
|
+
} catch (error) {
|
|
176
|
+
console.error("pstack: execute.before hook failed", error)
|
|
177
|
+
}
|
|
178
|
+
if (blocked) throw new Error(blocked)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
await ctx.tool.hook(
|
|
182
|
+
"execute.after",
|
|
183
|
+
guarded("execute.after", async (event) => {
|
|
184
|
+
if (isSkillEvent(event, catalog)) await record(event.sessionID, event)
|
|
185
|
+
}),
|
|
186
|
+
)
|
|
187
|
+
},
|
|
188
|
+
}
|
package/plugin/lib.js
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs"
|
|
2
|
+
import { dirname, join, resolve } from "node:path"
|
|
3
|
+
|
|
4
|
+
export const MODE_AGENT = "poteto-mode"
|
|
5
|
+
export const MODELS_KEY = "pstack-models"
|
|
6
|
+
export const MODE_KEY = "pstack-mode"
|
|
7
|
+
const MODE_AGENTS = [MODE_AGENT, "poteto-agent"]
|
|
8
|
+
const COMMIT_GATE =
|
|
9
|
+
"pstack: load the `deslop` skill with the `skill` tool and follow it on the staged diff before you commit. Then rerun `git commit` as its own command, because this whole shell command was rejected and nothing in it ran."
|
|
10
|
+
|
|
11
|
+
const GIT_COMMIT = /(?:^|[;&|(\n])\s*git(?:\s+-\S+(?:\s+[^-\s;&|]\S*)?)*\s+commit(?=$|[\s;&|)])/
|
|
12
|
+
|
|
13
|
+
const FRONTMATTER = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/
|
|
14
|
+
const LINK = /\]\(([^)\s]+)\)/g
|
|
15
|
+
|
|
16
|
+
function scalar(raw, continuation) {
|
|
17
|
+
const value = raw.trim()
|
|
18
|
+
if (value.startsWith('"')) return JSON.parse(value)
|
|
19
|
+
if (value.startsWith("'")) return value.slice(1, -1).replaceAll("''", "'")
|
|
20
|
+
if (/^[>|][+-]?$/.test(value)) {
|
|
21
|
+
const lines = continuation.map((line) => line.trim())
|
|
22
|
+
return value.startsWith(">") ? lines.filter(Boolean).join(" ") : lines.join("\n").trim()
|
|
23
|
+
}
|
|
24
|
+
return value
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function parseFrontmatter(text) {
|
|
28
|
+
const match = text.match(FRONTMATTER)
|
|
29
|
+
if (!match) return { data: {}, body: text }
|
|
30
|
+
const lines = match[1].split(/\r?\n/)
|
|
31
|
+
const data = {}
|
|
32
|
+
for (let i = 0; i < lines.length; i++) {
|
|
33
|
+
const field = lines[i].match(/^([A-Za-z][\w-]*):(.*)$/)
|
|
34
|
+
if (!field) continue
|
|
35
|
+
const continuation = []
|
|
36
|
+
while (i + 1 < lines.length && /^\s+\S/.test(lines[i + 1])) continuation.push(lines[++i])
|
|
37
|
+
data[field[1]] = scalar(field[2], continuation)
|
|
38
|
+
}
|
|
39
|
+
return { data, body: text.slice(match[0].length).replace(/^\s+/, "") }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function absoluteLinks(text, dir) {
|
|
43
|
+
return text.replace(LINK, (link, href) => {
|
|
44
|
+
const target = href.replace(/[#?].*/, "")
|
|
45
|
+
if (!target || /^[a-z][a-z0-9+.-]*:/i.test(target)) return link
|
|
46
|
+
const path = resolve(dir, target)
|
|
47
|
+
return existsSync(path) ? `](${path}${href.slice(target.length)})` : link
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const PLAYBOOK_ENTRY = /^- \*\*(.+?)\.\*\* (.+)$/gm
|
|
52
|
+
const ENTRY_ID = / ID: `([a-z0-9-]+)`\.$/
|
|
53
|
+
const STEP = /^\d+\.\s/
|
|
54
|
+
const NAMED_SKILL = /the `([a-z0-9-]+)` skill\b/g
|
|
55
|
+
|
|
56
|
+
const kebab = (title) =>
|
|
57
|
+
title
|
|
58
|
+
.toLowerCase()
|
|
59
|
+
.replace(/[^a-z0-9\s-]/g, "")
|
|
60
|
+
.trim()
|
|
61
|
+
.replace(/\s+/g, "-")
|
|
62
|
+
|
|
63
|
+
export function playbookDescriptions(modeBody) {
|
|
64
|
+
const section = modeBody.slice(modeBody.indexOf("## Playbooks"))
|
|
65
|
+
return new Map(
|
|
66
|
+
[...section.matchAll(PLAYBOOK_ENTRY)].map(([, title, text]) => [text.match(ENTRY_ID)?.[1] ?? kebab(title), text.replace(ENTRY_ID, "")]),
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function playbookSkills(body) {
|
|
71
|
+
const lines = body.split("\n")
|
|
72
|
+
const start = lines.findIndex((line) => STEP.test(line))
|
|
73
|
+
if (start < 0) return []
|
|
74
|
+
const end = lines.findIndex((line, index) => index > start && /^\S/.test(line) && !STEP.test(line))
|
|
75
|
+
const steps = lines.slice(start, end < 0 ? undefined : end).join("\n")
|
|
76
|
+
return [...new Set([...steps.matchAll(NAMED_SKILL)].map(([, id]) => id))]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const list = (value) => (value ?? "").split(",").map((item) => item.trim()).filter(Boolean)
|
|
80
|
+
export const playbookRequires = (data) => list(data.requires)
|
|
81
|
+
|
|
82
|
+
function readPlaybooks(modeDir) {
|
|
83
|
+
const dir = join(modeDir, "playbooks")
|
|
84
|
+
if (!existsSync(dir)) return []
|
|
85
|
+
const descriptions = playbookDescriptions(readFileSync(join(modeDir, "SKILL.md"), "utf8"))
|
|
86
|
+
return readdirSync(dir)
|
|
87
|
+
.filter((name) => name.endsWith(".md"))
|
|
88
|
+
.sort()
|
|
89
|
+
.map((name) => {
|
|
90
|
+
const id = name.slice(0, -".md".length)
|
|
91
|
+
const path = join(dir, name)
|
|
92
|
+
const { data, body } = parseFrontmatter(readFileSync(path, "utf8"))
|
|
93
|
+
const title = body.match(/^### (.+)$/m)?.[1] ?? id
|
|
94
|
+
const frame = `This is the \`${MODE_AGENT}\` ${title} playbook. Copy its numbered steps verbatim into the todo list, and when a step names a skill, load that skill with the \`skill\` tool.`
|
|
95
|
+
return {
|
|
96
|
+
kind: "playbook",
|
|
97
|
+
id,
|
|
98
|
+
name: id,
|
|
99
|
+
title,
|
|
100
|
+
description: descriptions.get(id) ?? title,
|
|
101
|
+
path,
|
|
102
|
+
content: `${frame}\n\n${absoluteLinks(body, dir)}`,
|
|
103
|
+
autoinvoke: false,
|
|
104
|
+
skills: playbookSkills(body),
|
|
105
|
+
requires: playbookRequires(data),
|
|
106
|
+
gates: list(data.gates),
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function readSkills(skillsDir) {
|
|
112
|
+
const skills = readdirSync(skillsDir)
|
|
113
|
+
.filter((id) => existsSync(join(skillsDir, id, "SKILL.md")))
|
|
114
|
+
.sort()
|
|
115
|
+
.map((id) => {
|
|
116
|
+
const path = join(skillsDir, id, "SKILL.md")
|
|
117
|
+
const { data, body } = parseFrontmatter(readFileSync(path, "utf8"))
|
|
118
|
+
return {
|
|
119
|
+
kind: "skill",
|
|
120
|
+
id,
|
|
121
|
+
name: data.name || id,
|
|
122
|
+
description: data.description ?? "",
|
|
123
|
+
path,
|
|
124
|
+
content: absoluteLinks(body, dirname(path)),
|
|
125
|
+
autoinvoke: data["disable-model-invocation"] !== "true",
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
const ids = new Set(skills.map((skill) => skill.id))
|
|
129
|
+
return [...skills, ...readPlaybooks(join(skillsDir, MODE_AGENT)).filter((playbook) => !ids.has(playbook.id))]
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function commandDescription(description, max = 120) {
|
|
133
|
+
const sentence = description.match(/^.*?[.!?](?=\s|$)/)?.[0] ?? description
|
|
134
|
+
if (sentence.length <= max) return sentence
|
|
135
|
+
return `${sentence.slice(0, sentence.lastIndexOf(" ", max - 3))}...`
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function commandPrompt(skill, text, shadowedBy) {
|
|
139
|
+
const task = text.trim() || `Run the ${skill.id} skill.`
|
|
140
|
+
if (!shadowedBy) return { text: task, attach: true }
|
|
141
|
+
return {
|
|
142
|
+
text: `Read the pstack \`${skill.id}\` skill at \`${skill.path}\` and follow it. The user skill at \`${shadowedBy}\` has the same ID, so do not load \`${skill.id}\` with the skill tool.\n\n${task}`,
|
|
143
|
+
attach: false,
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export function modeEntry(root) {
|
|
148
|
+
return [
|
|
149
|
+
"poteto mode is on. The user turned it on, so every task in this session follows the `poteto-mode` skill.",
|
|
150
|
+
`If the skill's instructions are not in this conversation, at the start or after compaction, load it with the \`skill\` tool (ID \`poteto-mode\`, file \`${join(root, "skills", "poteto-mode", "SKILL.md")}\`) before you act.`,
|
|
151
|
+
'When the user says "new task", match a fresh playbook.',
|
|
152
|
+
].join(" ")
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function modelsEntry(file, text) {
|
|
156
|
+
if (!text) return undefined
|
|
157
|
+
return `pstack per-role model choices, written by /setup-pstack to \`${file}\`. Each role line overrides that role's default model in pstack skills.\n\n${text}`
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const isCommit = ({ tool, input }) => tool === "shell" && GIT_COMMIT.test(input.command)
|
|
161
|
+
|
|
162
|
+
export function commitGate(session, event) {
|
|
163
|
+
if (!isCommit(event)) return undefined
|
|
164
|
+
if (session.loaded.includes("deslop") || !(session.mode || MODE_AGENTS.includes(event.agent))) return undefined
|
|
165
|
+
return COMMIT_GATE
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const CODE_TOOLS = new Set(["edit", "write", "apply_patch", "patch", "multiedit"])
|
|
169
|
+
const CODE_AGENTS = new Set(["poteto-agent", "general"])
|
|
170
|
+
const SKILL_FILE = /\/skills\/(?:poteto-mode\/playbooks\/([a-z0-9-]+)\.md|([a-z0-9-]+)\/SKILL\.md)$/
|
|
171
|
+
|
|
172
|
+
export const isCodeAction = (event) => CODE_TOOLS.has(event.tool) || (event.tool === "subagent" && CODE_AGENTS.has(event.input.agent)) || isCommit(event)
|
|
173
|
+
|
|
174
|
+
export function loadedSkill({ tool, input, status }, skills) {
|
|
175
|
+
if (status !== "completed") return undefined
|
|
176
|
+
if (tool === "skill") return input.id
|
|
177
|
+
if (tool !== "read") return undefined
|
|
178
|
+
const [, playbook, skill] = input.path?.match(SKILL_FILE) ?? []
|
|
179
|
+
const id = playbook ?? skill
|
|
180
|
+
return skills.has(id) ? id : undefined
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const spawns =
|
|
184
|
+
(...agents) =>
|
|
185
|
+
({ tool, input }) =>
|
|
186
|
+
tool === "subagent" && agents.includes(input.agent)
|
|
187
|
+
const runsShell =
|
|
188
|
+
(pattern) =>
|
|
189
|
+
({ tool, input }) =>
|
|
190
|
+
tool === "shell" && pattern.test(input.command)
|
|
191
|
+
const EXPLORES = { by: spawns("explore"), finish: "spawn its `explore` subagents as the skill says" }
|
|
192
|
+
|
|
193
|
+
export const RAN = {
|
|
194
|
+
how: EXPLORES,
|
|
195
|
+
architect: EXPLORES,
|
|
196
|
+
arena: EXPLORES,
|
|
197
|
+
interrogate: { by: spawns("general"), finish: "spawn its `general` adversaries as the skill says" },
|
|
198
|
+
why: {
|
|
199
|
+
by: (event) => spawns("general")(event) || runsShell(/\bgit\s+(?:log|blame)\b/)(event),
|
|
200
|
+
finish: "spawn its `general` subagents, or read the history with `git log` or `git blame`, as the skill says",
|
|
201
|
+
},
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const isEvidence = (event) => Object.values(RAN).some((rule) => rule.by(event))
|
|
205
|
+
|
|
206
|
+
export const skipsPlaybook = ({ tool, input, status }) =>
|
|
207
|
+
status === "completed" && tool === "todowrite" && (input.todos ?? []).some((todo) => /^no playbook:/i.test(String(todo.content ?? "").trim()))
|
|
208
|
+
|
|
209
|
+
export const isSkillEvent = (event, skills) => event.status === "completed" && (Boolean(loadedSkill(event, skills)) || isEvidence(event) || skipsPlaybook(event))
|
|
210
|
+
|
|
211
|
+
export function withEvent(record, event, skills) {
|
|
212
|
+
const session = { loaded: [], ran: [], ...record }
|
|
213
|
+
if (skipsPlaybook(event)) return session.skip ? record : { ...session, skip: true }
|
|
214
|
+
const id = loadedSkill(event, skills)
|
|
215
|
+
if (skills.get(id)?.kind === "playbook") return session.playbook === id ? record : { ...session, playbook: id }
|
|
216
|
+
if (id) return session.loaded.includes(id) ? record : { ...session, loaded: [...session.loaded, id] }
|
|
217
|
+
if (event.status !== "completed") return record
|
|
218
|
+
const fresh = session.loaded.filter((loaded) => !session.ran.includes(loaded) && RAN[loaded]?.by(event))
|
|
219
|
+
return fresh.length === 0 ? record : { ...session, ran: [...session.ran, ...fresh] }
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const listed = (items) => (items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`)
|
|
223
|
+
|
|
224
|
+
const READ_TOOLS = new Set(["read", "grep", "glob", "list"])
|
|
225
|
+
export const isReadAction = ({ tool }) => READ_TOOLS.has(tool)
|
|
226
|
+
|
|
227
|
+
const HOLDS = {
|
|
228
|
+
code: { reason: (skills) => `runs the ${skills} before any code change`, then: (event) => `retry this call${isCommit(event) ? " as its own `git commit` command, because this whole shell command was rejected" : ""}` },
|
|
229
|
+
reads: { reason: (skills) => `reads the code through the ${skills}`, then: (event, missing) => `use ${missing.length === 1 ? "its" : "their"} findings instead of reading files yourself` },
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const PLAYBOOK_FIRST =
|
|
233
|
+
"pstack: poteto mode runs every task through a playbook. Load the matching playbook with the `skill` tool (Bug fix is `bug-fix`) and follow its steps. For a fully specified one-line edit, add a todo `no playbook: <reason>` instead. Then retry this call"
|
|
234
|
+
|
|
235
|
+
export function actGate(session, event, skills) {
|
|
236
|
+
if (!(session.mode || event.agent === MODE_AGENT)) return undefined
|
|
237
|
+
if (!session.playbook && !session.skip && isCodeAction(event)) return `${PLAYBOOK_FIRST}${isCommit(event) ? " as its own `git commit` command, because this whole shell command was rejected" : ""}.`
|
|
238
|
+
const playbook = skills.get(session.playbook)
|
|
239
|
+
const held = isCodeAction(event) ? "code" : isReadAction(event) && playbook?.gates.includes("reads") ? "reads" : undefined
|
|
240
|
+
if (!held) return undefined
|
|
241
|
+
const loadsOnly = event.tool === "subagent" && isEvidence(event)
|
|
242
|
+
const unfinished = (id) => !session.loaded.includes(id) || (!loadsOnly && RAN[id] && !session.ran.includes(id))
|
|
243
|
+
const missing = playbook?.requires.filter(unfinished) ?? []
|
|
244
|
+
if (missing.length === 0) return undefined
|
|
245
|
+
const steps = missing
|
|
246
|
+
.map((id) => (session.loaded.includes(id) ? `\`${id}\` is loaded but hasn't run: ${RAN[id].finish}` : `load \`${id}\` with the \`skill\` tool and run it`))
|
|
247
|
+
.join(", then ")
|
|
248
|
+
const names = `${listed(missing.map((id) => `\`${id}\``))} skill${missing.length === 1 ? "" : "s"}`
|
|
249
|
+
return `pstack: the ${playbook.title} playbook ${HOLDS[held].reason(names)}. ${steps[0].toUpperCase()}${steps.slice(1)}, then ${HOLDS[held].then(event, missing)}.`
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function entryOps(want, have) {
|
|
253
|
+
return Object.entries(want)
|
|
254
|
+
.filter(([key, value]) => value !== have[key])
|
|
255
|
+
.map(([key, value]) => ({ key, value }))
|
|
256
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architect
|
|
3
|
+
description: "Sketch types, signatures, and module structure before code, then stay in the loop while implementation fills in. Use for /architect, 'architect this', 'design this', or non-trivial work where jumping to code would lock in the wrong shape."
|
|
4
|
+
disable-model-invocation: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Architect
|
|
8
|
+
|
|
9
|
+
Sketch types, function signatures, class shapes, and module boundaries with `not implemented` bodies and pseudocode. Synthesize across multiple model perspectives, then fill in code against the chosen sketch.
|
|
10
|
+
|
|
11
|
+
## Start
|
|
12
|
+
|
|
13
|
+
Open a todo list with `todowrite` with one entry per phase before starting.
|
|
14
|
+
|
|
15
|
+
1. Ground
|
|
16
|
+
2. Sketch
|
|
17
|
+
3. Agree
|
|
18
|
+
4. Implement
|
|
19
|
+
5. Scrap
|
|
20
|
+
|
|
21
|
+
## Phase A: Ground the problem
|
|
22
|
+
|
|
23
|
+
Build a real mental model of every system the new code touches. Load the `how` skill with the `skill` tool and run it over the relevant subsystems. Naming a file isn't grounding. Produce the architectural explanation `how` prescribes. If the design redefines ownership or layering, also load and run the `why` skill on the existing shape so the rationale becomes a constraint, not a guess.
|
|
24
|
+
|
|
25
|
+
Skip Phase A only when the work is genuinely greenfield with no surrounding system to integrate.
|
|
26
|
+
|
|
27
|
+
## Phase B: Sketch
|
|
28
|
+
|
|
29
|
+
Load the `arena` skill and run it with the design-sketch task and the Phase A grounding artifacts. Pass `references/runner-prompt.md` as each runner's prompt.
|
|
30
|
+
|
|
31
|
+
Take the runners from the `architect runners` line in the `pstack-models` instruction entry, in place of the `arena runners` line. If the entry or that line is missing, use `<provider>/claude-opus-5-5#xhigh` and `<provider>/grok-4.7#xhigh`, from a provider that lists each. Alias and rejected entries follow the runner rules in the `arena` skill's Phase A.
|
|
32
|
+
|
|
33
|
+
Design it twice. Require at least two structurally distinct candidates before synthesis, even when the first looks sufficient. This is the `principle-exhaust-the-design-space` skill made concrete. Whole-shape alternatives, not point fixes inside one shape.
|
|
34
|
+
|
|
35
|
+
Screen every candidate against [`references/design-red-flags.md`](references/design-red-flags.md) before synthesis. Assume the next contributor is an agent that sees only the files it opened, copies the nearest example, and takes the shortest path that compiles. Prefer the design where a change that looks right from one file is right for the whole repo.
|
|
36
|
+
|
|
37
|
+
Compare viable candidates on interface depth. Prefer the design that hides more complexity behind a smaller, simpler public surface. A rich interface can keep call chains short by concentrating capability instead of scattering it across layers.
|
|
38
|
+
|
|
39
|
+
Arena returns one synthesized design package. Its synthesis decision fills the rationale's "Synthesis decision" section.
|
|
40
|
+
|
|
41
|
+
## Phase C: Agree (opt-in)
|
|
42
|
+
|
|
43
|
+
Default: proceed directly to implementation with the synthesized design. No human checkpoint.
|
|
44
|
+
|
|
45
|
+
Opt in to a checkpoint when the invoker explicitly asks: "/architect with checkpoint," "stop and show me before implementing," or similar. Then surface the synthesized design and pause for sign-off.
|
|
46
|
+
|
|
47
|
+
The synthesis can ship as its own commit either way, as the "scaffold first" mode of the `principle-foundational-thinking` skill. Planned and scoped breakage during fill-in is fine, per the `principle-outcome-oriented-execution` skill. For adversarial pressure on the design before implementing, load and run the `interrogate` skill on the synthesized sketch.
|
|
48
|
+
|
|
49
|
+
If the human pushes back on the shape (in a checkpoint or after the fact), treat that as Phase A evidence. Re-ground and re-run Phase B before writing more code.
|
|
50
|
+
|
|
51
|
+
## Phase D: Implement against the sketch
|
|
52
|
+
|
|
53
|
+
Replace `not implemented` bodies with code, pseudocode with logic. The synthesized sketch is the contract. Deviations from it are signal to surface, not friction to absorb silently. If a function needs a parameter the sketch didn't anticipate, ask whether the sketch was wrong, the requirement was missed, or the implementation is overreaching.
|
|
54
|
+
|
|
55
|
+
## Phase E: Scrap when the architecture is wrong
|
|
56
|
+
|
|
57
|
+
If implementation keeps producing friction the sketch can't absorb, throw the sketch out. Don't bolt fixes onto a wrong design, per the `principle-redesign-from-first-principles` and `principle-fix-root-causes` skills.
|
|
58
|
+
|
|
59
|
+
The signal is a *pattern*, not single instances. Tells:
|
|
60
|
+
|
|
61
|
+
- The same shape of workaround appearing repeatedly across unrelated code.
|
|
62
|
+
- Multiple unrelated edge cases that all need special-case branches.
|
|
63
|
+
- Types that need escape hatches (`any`, casts, optional fields always set in practice) to compile.
|
|
64
|
+
- The "we need a lock" reflex when the sketch said the state wasn't shared.
|
|
65
|
+
- Callers having to know the abstraction's internal rules to use it.
|
|
66
|
+
- Two or more independent Phase D deviations of the same shape across the implementation.
|
|
67
|
+
|
|
68
|
+
Use judgment. A few edge cases don't condemn an architecture. Some problems are legitimately complex. Complexity in the data is not complexity in the design.
|
|
69
|
+
|
|
70
|
+
When you scrap:
|
|
71
|
+
|
|
72
|
+
1. Load and re-run the `how` skill over what's been built.
|
|
73
|
+
2. Redesign as if the new constraints had been day-one assumptions, per the `principle-redesign-from-first-principles` skill.
|
|
74
|
+
3. Subtract before adding, per the `principle-subtract-before-you-add` skill. The new sketch should be smaller than the old one before it grows.
|
|
75
|
+
4. Return to Phase B and re-run arena.
|
|
76
|
+
|
|
77
|
+
## Outputs
|
|
78
|
+
|
|
79
|
+
The caller's usage is written first and the type sketch derived from it. One file with new types and signatures for small changes. Module map plus type definitions for larger work. The rationale ships alongside, shaped per `references/rationale-template.md`, including the usage sketch and the synthesis decision.
|