@justjoshn/pi-pstack 0.15.36-pi.1 → 0.15.36-pi.7

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.
Files changed (114) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +15 -12
  3. package/agents/ci-watcher.md +27 -0
  4. package/agents/thermo-nuclear-code-quality-review.md +23 -0
  5. package/assets/logo.png +0 -0
  6. package/automations/benny/FOR_AGENTS.md +1 -1
  7. package/automations/benny/README.md +2 -2
  8. package/automations/benny/skills/setup-benny/SKILL.md +5 -5
  9. package/bin/pstack-routines-supervisor +9 -0
  10. package/docs/guide/07-overnight.md +1 -1
  11. package/docs/guide/09-make-it-yours.md +1 -1
  12. package/docs/guide/10-recipes-and-pitfalls.md +1 -1
  13. package/docs/native-gaps.md +11 -5
  14. package/docs/parity-reverse-engineering.md +94 -0
  15. package/package.json +41 -6
  16. package/packaging/install-supervisor-unit.sh +164 -0
  17. package/packaging/launchd/com.pstack.routines-supervisor.plist.example +24 -0
  18. package/packaging/systemd/pstack-routines-supervisor.service.example +15 -0
  19. package/skills/architect/SKILL.md +1 -1
  20. package/skills/architect/references/runner-prompt.md +1 -1
  21. package/skills/arena/SKILL.md +3 -3
  22. package/skills/check-compiler-errors/SKILL.md +23 -0
  23. package/skills/create-skill/SKILL.md +515 -29
  24. package/skills/fix-ci/SKILL.md +29 -0
  25. package/skills/fix-merge-conflicts/SKILL.md +32 -0
  26. package/skills/get-pr-comments/SKILL.md +23 -0
  27. package/skills/how/SKILL.md +1 -1
  28. package/skills/ketchup-video/SKILL.md +2 -2
  29. package/skills/loop-on-ci/SKILL.md +50 -0
  30. package/skills/make-bot-ui/SKILL.md +2 -2
  31. package/skills/make-pr-easy-to-review/SKILL.md +59 -0
  32. package/skills/new-branch-and-pr/SKILL.md +29 -0
  33. package/skills/no-inline-imports/SKILL.md +12 -0
  34. package/skills/poteto-help/SKILL.md +4 -4
  35. package/skills/poteto-mode/playbooks/multi-phase-plan.md +1 -1
  36. package/skills/poteto-mode/playbooks/orchestrate.md +1 -1
  37. package/skills/pr-review-canvas/SKILL.md +176 -0
  38. package/skills/pr-review-canvas/renderer.js +170 -0
  39. package/skills/pr-review-canvas/styles.css +96 -0
  40. package/skills/pr-review-canvas/template.html +18 -0
  41. package/skills/reflect/SKILL.md +1 -1
  42. package/skills/review-and-ship/SKILL.md +41 -0
  43. package/skills/run-smoke-tests/SKILL.md +42 -0
  44. package/skills/statechart/scripts/test/cli.test.ts +1 -1
  45. package/skills/swarm/SKILL.md +2 -2
  46. package/skills/thermo-nuclear-code-quality-review/SKILL.md +192 -0
  47. package/skills/typescript-exhaustive-switch/SKILL.md +10 -0
  48. package/skills/verify-this/SKILL.md +74 -0
  49. package/skills/weekly-review/SKILL.md +32 -0
  50. package/skills/what-did-i-get-done/SKILL.md +31 -0
  51. package/skills/why/SKILL.md +1 -1
  52. package/skills/workflow-from-chats/SKILL.md +50 -0
  53. package/src/mode.ts +3 -3
  54. package/src/paths.ts +13 -0
  55. package/src/pi-command.ts +12 -0
  56. package/src/rule.ts +4 -4
  57. package/src/sections.ts +2 -1
  58. package/src/subscriptions/durable-store.ts +482 -0
  59. package/src/subscriptions/durable-types.ts +41 -0
  60. package/src/subscriptions/ensure-supervisor.ts +67 -0
  61. package/src/subscriptions/index.ts +231 -271
  62. package/src/subscriptions/supervisor-main.ts +88 -0
  63. package/src/subscriptions/supervisor.ts +271 -0
  64. package/src/subscriptions/webhook.ts +22 -9
  65. package/src/task/card.ts +29 -0
  66. package/src/task/records.ts +3 -8
  67. package/src/task/runner.ts +9 -14
  68. package/src/task/tool.ts +18 -21
  69. package/src/todo.ts +1 -2
  70. package/scripts/live-e2e.mjs +0 -257
  71. package/test/aliases.test.ts +0 -57
  72. package/test/ask.test.ts +0 -85
  73. package/test/autocomplete.test.ts +0 -39
  74. package/test/e2e/aliases.e2e.test.ts +0 -81
  75. package/test/e2e/ask.e2e.test.ts +0 -135
  76. package/test/e2e/harness.ts +0 -179
  77. package/test/e2e/host.e2e.test.ts +0 -193
  78. package/test/e2e/lifecycle.e2e.test.ts +0 -99
  79. package/test/e2e/mode.e2e.test.ts +0 -160
  80. package/test/e2e/package.e2e.test.ts +0 -67
  81. package/test/e2e/task.e2e.test.ts +0 -734
  82. package/test/e2e/todo.e2e.test.ts +0 -59
  83. package/test/fixtures/cursor-askquestion-calls.json +0 -806
  84. package/test/fixtures/fake-pi.mjs +0 -96
  85. package/test/fixtures/image-model.ts +0 -16
  86. package/test/fixtures/list-models.ts +0 -15
  87. package/test/fixtures/readonly-shell-exit.ts +0 -17
  88. package/test/fixtures/scripted-model.ts +0 -113
  89. package/test/loop.test.ts +0 -209
  90. package/test/mode.test.ts +0 -143
  91. package/test/plan.test.ts +0 -126
  92. package/test/readonly-shell-security.test.ts +0 -84
  93. package/test/readonly-shell.test.ts +0 -44
  94. package/test/records.test.ts +0 -143
  95. package/test/registry.test.ts +0 -18
  96. package/test/resources.test.ts +0 -162
  97. package/test/rule.test.ts +0 -92
  98. package/test/scripts.test.ts +0 -182
  99. package/test/sections.test.ts +0 -56
  100. package/test/subscriptions-cron.test.ts +0 -60
  101. package/test/subscriptions.test.ts +0 -598
  102. package/test/task-agents.test.ts +0 -49
  103. package/test/task-card.test.ts +0 -34
  104. package/test/task-fork.test.ts +0 -233
  105. package/test/task-format.test.ts +0 -65
  106. package/test/task-model.test.ts +0 -141
  107. package/test/task-runner.test.ts +0 -259
  108. package/test/task-schema.test.ts +0 -50
  109. package/test/task-status.test.ts +0 -155
  110. package/test/task-worktree.test.ts +0 -106
  111. package/test/todo.test.ts +0 -74
  112. package/test/visualize.test.ts +0 -152
  113. package/tsconfig.json +0 -5
  114. package/vitest.config.ts +0 -16
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env bash
2
+ # Install a per-workspace user unit so pstack-routines-supervisor survives reboot.
3
+ # Idempotent: re-run overwrites the same unit path and reloads it.
4
+ set -euo pipefail
5
+
6
+ usage() {
7
+ echo "Usage: $0 --workspace <abs-path> [--bin <abs-path>]" >&2
8
+ exit 2
9
+ }
10
+
11
+ workspace=""
12
+ bin=""
13
+ while [[ $# -gt 0 ]]; do
14
+ case "$1" in
15
+ --workspace)
16
+ [[ $# -ge 2 ]] || usage
17
+ workspace=$2
18
+ shift 2
19
+ ;;
20
+ --bin)
21
+ [[ $# -ge 2 ]] || usage
22
+ bin=$2
23
+ shift 2
24
+ ;;
25
+ -h|--help)
26
+ usage
27
+ ;;
28
+ *)
29
+ usage
30
+ ;;
31
+ esac
32
+ done
33
+
34
+ [[ -n "$workspace" ]] || usage
35
+ [[ "$workspace" = /* ]] || {
36
+ echo "error: --workspace must be an absolute path" >&2
37
+ exit 2
38
+ }
39
+ [[ -d "$workspace" ]] || {
40
+ echo "error: workspace is not a directory: $workspace" >&2
41
+ exit 1
42
+ }
43
+
44
+ here=$(cd "$(dirname "$0")" && pwd)
45
+ if [[ -z "$bin" ]]; then
46
+ bin=$(cd "$here/../bin" && pwd)/pstack-routines-supervisor
47
+ fi
48
+ [[ "$bin" = /* ]] || {
49
+ echo "error: --bin must be an absolute path" >&2
50
+ exit 2
51
+ }
52
+ [[ -x "$bin" ]] || {
53
+ echo "error: supervisor bin missing or not executable: $bin" >&2
54
+ exit 1
55
+ }
56
+
57
+ # Short content hash so labels stay stable across re-runs for the same path.
58
+ safe_hash=$(printf '%s' "$workspace" | shasum -a 256 | cut -c1-12)
59
+ os=$(uname -s)
60
+
61
+ install_darwin() {
62
+ local label="com.pstack.routines-supervisor.${safe_hash}"
63
+ local plist_dir="$HOME/Library/LaunchAgents"
64
+ local plist="$plist_dir/${label}.plist"
65
+ local uid domain
66
+ uid=$(id -u)
67
+ domain="gui/${uid}"
68
+
69
+ mkdir -p "$plist_dir"
70
+ cat >"$plist" <<EOF
71
+ <?xml version="1.0" encoding="UTF-8"?>
72
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
73
+ <plist version="1.0">
74
+ <dict>
75
+ <key>Label</key>
76
+ <string>${label}</string>
77
+ <key>ProgramArguments</key>
78
+ <array>
79
+ <string>${bin}</string>
80
+ <string>--workspace</string>
81
+ <string>${workspace}</string>
82
+ </array>
83
+ <key>WorkingDirectory</key>
84
+ <string>${workspace}</string>
85
+ <key>KeepAlive</key>
86
+ <true/>
87
+ <key>RunAtLoad</key>
88
+ <true/>
89
+ <key>StandardOutPath</key>
90
+ <string>/tmp/pstack-routines-supervisor-${safe_hash}.log</string>
91
+ <key>StandardErrorPath</key>
92
+ <string>/tmp/pstack-routines-supervisor-${safe_hash}.err</string>
93
+ </dict>
94
+ </plist>
95
+ EOF
96
+
97
+ launchctl bootout "${domain}/${label}" 2>/dev/null || true
98
+ if launchctl bootstrap "$domain" "$plist" 2>/dev/null; then
99
+ launchctl enable "${domain}/${label}" 2>/dev/null || true
100
+ launchctl kickstart -k "${domain}/${label}" 2>/dev/null || true
101
+ else
102
+ # Older launchctl: load -w is enough for KeepAlive + RunAtLoad.
103
+ launchctl unload -w "$plist" 2>/dev/null || true
104
+ launchctl load -w "$plist"
105
+ fi
106
+
107
+ echo "Installed launchd agent: $plist"
108
+ echo " label: $label"
109
+ echo " bin: $bin"
110
+ echo " workspace: $workspace"
111
+ echo "Uninstall:"
112
+ echo " launchctl bootout ${domain}/${label} 2>/dev/null || launchctl unload -w \"$plist\""
113
+ echo " rm -f \"$plist\""
114
+ }
115
+
116
+ install_linux() {
117
+ local unit_name="pstack-routines-supervisor-${safe_hash}.service"
118
+ local unit_dir="$HOME/.config/systemd/user"
119
+ local unit="$unit_dir/$unit_name"
120
+
121
+ mkdir -p "$unit_dir"
122
+ cat >"$unit" <<EOF
123
+ [Unit]
124
+ Description=pstack durable routines supervisor (${safe_hash})
125
+ After=default.target
126
+
127
+ [Service]
128
+ Type=simple
129
+ WorkingDirectory=${workspace}
130
+ ExecStart=${bin} --workspace ${workspace}
131
+ Restart=on-failure
132
+ RestartSec=3
133
+
134
+ [Install]
135
+ WantedBy=default.target
136
+ EOF
137
+
138
+ systemctl --user daemon-reload
139
+ systemctl --user enable --now "$unit_name"
140
+
141
+ echo "Installed systemd user unit: $unit"
142
+ echo " unit: $unit_name"
143
+ echo " bin: $bin"
144
+ echo " workspace: $workspace"
145
+ echo "If no login session is open after reboot, enable linger so the user unit still starts:"
146
+ echo " loginctl enable-linger \"$(id -un)\""
147
+ echo "Uninstall:"
148
+ echo " systemctl --user disable --now $unit_name"
149
+ echo " rm -f \"$unit\""
150
+ echo " systemctl --user daemon-reload"
151
+ }
152
+
153
+ case "$os" in
154
+ Darwin)
155
+ install_darwin
156
+ ;;
157
+ Linux)
158
+ install_linux
159
+ ;;
160
+ *)
161
+ echo "error: unsupported OS: $os (need Darwin or Linux)" >&2
162
+ exit 1
163
+ ;;
164
+ esac
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>Label</key>
6
+ <string>com.pstack.routines-supervisor</string>
7
+ <key>ProgramArguments</key>
8
+ <array>
9
+ <string>/absolute/path/to/node_modules/@justjoshn/pi-pstack/bin/pstack-routines-supervisor</string>
10
+ <string>--workspace</string>
11
+ <string>/absolute/path/to/your/repo</string>
12
+ </array>
13
+ <key>WorkingDirectory</key>
14
+ <string>/absolute/path/to/your/repo</string>
15
+ <key>KeepAlive</key>
16
+ <true/>
17
+ <key>RunAtLoad</key>
18
+ <true/>
19
+ <key>StandardOutPath</key>
20
+ <string>/tmp/pstack-routines-supervisor.log</string>
21
+ <key>StandardErrorPath</key>
22
+ <string>/tmp/pstack-routines-supervisor.err</string>
23
+ </dict>
24
+ </plist>
@@ -0,0 +1,15 @@
1
+ # Does not require root. Reboot survival needs linger enabled for the user when no login session is open.
2
+
3
+ [Unit]
4
+ Description=pstack durable routines supervisor
5
+ After=default.target
6
+
7
+ [Service]
8
+ Type=simple
9
+ WorkingDirectory=/absolute/path/to/your/repo
10
+ ExecStart=/absolute/path/to/node_modules/@justjoshn/pi-pstack/bin/pstack-routines-supervisor --workspace /absolute/path/to/your/repo
11
+ Restart=on-failure
12
+ RestartSec=3
13
+
14
+ [Install]
15
+ WantedBy=default.target
@@ -28,7 +28,7 @@ Skip Phase A only when the work is genuinely greenfield with no surrounding syst
28
28
 
29
29
  Run the **arena** skill with the design-sketch task and the Phase A grounding artifacts. Pass `references/runner-prompt.md` as each runner's prompt.
30
30
 
31
- Take the runners from the `architect runners` line in the model rule (`~/.pi/agent/pstack/pstack-models.md`), in place of the `arena runners` line. If the rule or that line is missing, use `claude-opus-5-5:xhigh` and `grok-4.7:xhigh`. Alias and rejected entries follow the runner rules in the **arena** skill's Phase A.
31
+ Take the runners from the `architect runners` line in the model rule at the path the system prompt names, in place of the `arena runners` line. If the rule or that line is missing, use `claude-opus-5-5:xhigh` and `grok-4.7:xhigh`. Alias and rejected entries follow the runner rules in the **arena** skill's Phase A.
32
32
 
33
33
  Design it twice. Require at least two structurally distinct candidates before synthesis, even when the first looks sufficient. This is the **exhaust-the-design-space** principle skill made concrete. Whole-shape alternatives, not point fixes inside one shape.
34
34
 
@@ -1,6 +1,6 @@
1
1
  # Architect runner prompt
2
2
 
3
- The orchestrator passes this file through to every parallel candidate runner during Phase B and fills in the variable inputs around it: the task, the Phase A grounding artifacts, the isolated working directory, and the path to write outputs. The working directory is a git worktree when available, otherwise a per-runner subdirectory under the sketch dir. What matters is independence between candidates.
3
+ The orchestrator passes this file through to every parallel candidate runner during Phase B and fills in the variable inputs around it: the task, the Phase A grounding artifacts, the isolated working directory, and the path to write outputs. The working directory is a git worktree when available, otherwise a per-runner subdirectory under the sketch dir. Worktrees and scratch directories share the host machine. Use the distinct ports, output directories, and writable cache paths assigned in the brief for concurrent runtime candidates. Report a missing assignment before starting a conflicting process. If the design requires stronger machine isolation, report it as unavailable.
4
4
 
5
5
  You are producing one candidate design in architect's parallel exploration. Read the **architect** skill in full first. That's the workflow you're inside. Output a candidate design package: type sketch, function signatures, module map, and prose rationale shaped per [`rationale-template.md`](rationale-template.md).
6
6
 
@@ -14,8 +14,8 @@ Every candidate gets the same prompt, so the prompt is the contract.
14
14
 
15
15
  1. State the artifact each candidate is producing.
16
16
  2. Derive the rubric, 3-6 concrete gradeable criteria for what success looks like on *this* task. It is the picker's tool in Phase D. Candidates only see the task.
17
- 3. Pick the runners. Use the `arena runners` line in `~/.pi/agent/pstack/pstack-models.md`. If the rule or that line is missing, default to one each on `claude-opus-5-5:xhigh` and `grok-4.7:xhigh`. An `auto` or `inherit-parent` entry in this line means the parent model, so omit `model` for it. If the Task tool rejects a configured entry, run that seat on its family's default and say so. Families go by the model id after the provider: `claude-*` and `grok-*`. If the family has no default, or the Task tool rejects that default, use the closest valid slug of the same family from its error message, or drop the seat and say so when there is none. If dropped seats leave fewer than two runners, add runners until there are two, or one when the line has one entry. Run each added runner on a remaining runner's model, or omit `model` so it runs on the parent model when none remain, and say so. Spawn more runners when the arena covers multiple design directions. Use the same model N times when the work is generation-bound rather than judgment-sensitive. Pick each subagent's reasoning level (the `:<level>` suffix), and fast or standard speed when the model has a `-fast` variant, for the job, per the Subagents section of the **poteto-mode** skill.
18
- 4. Give each candidate its own output location (a git worktree where possible, otherwise `/tmp/arena-<slug>/candidate-<n>/`), per the **separate-before-serializing-shared-state** principle skill.
17
+ 3. Pick the runners. Use the `arena runners` line in the model rule at the path the system prompt names. If the rule or that line is missing, default to one each on `claude-opus-5-5:xhigh` and `grok-4.7:xhigh`. An `auto` or `inherit-parent` entry in this line means the parent model, so omit `model` for it. If the Task tool rejects a configured entry, run that seat on its family's default and say so. Families go by the model id after the provider: `claude-*` and `grok-*`. If the family has no default, or the Task tool rejects that default, use the closest valid slug of the same family from its error message, or drop the seat and say so when there is none. If dropped seats leave fewer than two runners, add runners until there are two, or one when the line has one entry. Run each added runner on a remaining runner's model, or omit `model` so it runs on the parent model when none remain, and say so. Spawn more runners when the arena covers multiple design directions. Use the same model N times when the work is generation-bound rather than judgment-sensitive. Pick each subagent's reasoning level (the `:<level>` suffix), and fast or standard speed when the model has a `-fast` variant, for the job, per the Subagents section of the **poteto-mode** skill.
18
+ 4. Give each candidate its own output location (a git worktree where possible, otherwise `/tmp/arena-<slug>/candidate-<n>/`), per the **separate-before-serializing-shared-state** principle skill. Worktrees share this machine. Assign distinct ports, output directories, and writable cache paths for concurrent runtime candidates. If stronger machine isolation is required, report it as unavailable.
19
19
 
20
20
  ## Phase B: Fan out
21
21
 
@@ -25,7 +25,7 @@ If a candidate produces no output, proceed with N-1 and note the dropout.
25
25
 
26
26
  ## Phase C: Cross-judge
27
27
 
28
- After all Phase B candidates complete, choose one model from the `arena cross-judge pool` line in `~/.pi/agent/pstack/pstack-models.md`. If the rule or that line is missing, choose from `claude-opus-5-5:xhigh` and `grok-4.7:xhigh`. Spawn one readonly judge subagent. The judge is never from the parent's family, as Phase A step 3 defines families. Try only the entries from another family, in pool order. An `auto` or `inherit-parent` entry is the parent model, so it never judges. With the default pool, a Claude parent gets `grok-4.7:xhigh`. A parent from any other family gets `claude-opus-5-5:xhigh` first. If the Task tool rejects an entry, use a valid slug of the same model at the closest level or speed from the error message, or move to the next entry when there is none. If no entry from another family runs, try the default pool's entries from another family the same way. If none of those runs, skip the judge, pick the base alone in Phase D, and say so. If you do not know the parent's model, try the pool's real slugs in pool order and say that the family check did not run. The judge sees the rubric and the candidates by path label, scores each criterion, and recommends a base with rationale. It runs in parallel with your reading in Phase D. Don't spawn it while candidates are still writing.
28
+ After all Phase B candidates complete, choose one model from the `arena cross-judge pool` line in the model rule at the path the system prompt names. If the rule or that line is missing, choose from `claude-opus-5-5:xhigh` and `grok-4.7:xhigh`. Spawn one readonly judge subagent. The judge is never from the parent's family, as Phase A step 3 defines families. Try only the entries from another family, in pool order. An `auto` or `inherit-parent` entry is the parent model, so it never judges. With the default pool, a Claude parent gets `grok-4.7:xhigh`. A parent from any other family gets `claude-opus-5-5:xhigh` first. If the Task tool rejects an entry, use a valid slug of the same model at the closest level or speed from the error message, or move to the next entry when there is none. If no entry from another family runs, try the default pool's entries from another family the same way. If none of those runs, skip the judge, pick the base alone in Phase D, and say so. If you do not know the parent's model, try the pool's real slugs in pool order and say that the family check did not run. The judge sees the rubric and the candidates by path label, scores each criterion, and recommends a base with rationale. It runs in parallel with your reading in Phase D. Don't spawn it while candidates are still writing.
29
29
 
30
30
  ## Phase D: Pick a base
31
31
 
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: check-compiler-errors
3
+ description: Run compile and type-check commands and report failures
4
+ ---
5
+
6
+ # Check compiler errors
7
+
8
+ ## Trigger
9
+
10
+ Compile or type-check failures are blocking local validation or CI.
11
+
12
+ ## Workflow
13
+
14
+ 1. Run the repo's compile and type-check commands.
15
+ 2. Summarize errors by file and type.
16
+ 3. Fix the highest-confidence issues first.
17
+ 4. Re-run checks until clean or blocked.
18
+
19
+ ## Output
20
+
21
+ - Current compile and type-check status
22
+ - Error summary grouped by file and category
23
+ - Fixes applied and remaining blockers