@nklisch/pi-agile-workflow 0.15.3

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 (203) hide show
  1. package/.claude-plugin/plugin.json +10 -0
  2. package/.codex-plugin/plugin.json +28 -0
  3. package/CHANGELOG.md +591 -0
  4. package/README.md +107 -0
  5. package/docs/ARCHITECTURE.md +716 -0
  6. package/docs/MIGRATION.md +419 -0
  7. package/docs/PRINCIPLES.md +464 -0
  8. package/docs/ROADMAP.md +95 -0
  9. package/docs/SPEC.md +855 -0
  10. package/docs/VISION.md +106 -0
  11. package/extensions/agile-workflow.test.ts +419 -0
  12. package/extensions/agile-workflow.ts +467 -0
  13. package/hooks/hooks.json +52 -0
  14. package/hooks/scripts/prompt-context.py +628 -0
  15. package/hooks/scripts/substrate-maintainer.py +359 -0
  16. package/hooks/scripts/test_prompt_context.py +757 -0
  17. package/package.json +30 -0
  18. package/scripts/install-work-view.sh +165 -0
  19. package/scripts/tests/agent-metadata.test.sh +75 -0
  20. package/scripts/tests/bump-version.test.sh +552 -0
  21. package/scripts/tests/channel-parity.test.sh +117 -0
  22. package/scripts/tests/convert-content-integrity.test.sh +246 -0
  23. package/scripts/tests/convert-install-routing.test.sh +159 -0
  24. package/scripts/tests/install-work-view.test.sh +411 -0
  25. package/scripts/tests/pi-package-metadata.test.sh +119 -0
  26. package/scripts/tests/work-board-shim.test.sh +239 -0
  27. package/scripts/tests/work-view-dist-version.test.sh +105 -0
  28. package/scripts/work-board.sh +64 -0
  29. package/scripts/work-view.sh +423 -0
  30. package/skills/autopilot/SKILL.md +330 -0
  31. package/skills/autopilot/agents/openai.yaml +6 -0
  32. package/skills/board/SKILL.md +62 -0
  33. package/skills/board/agents/openai.yaml +6 -0
  34. package/skills/bold-refactor/SKILL.md +244 -0
  35. package/skills/bold-refactor/agents/openai.yaml +6 -0
  36. package/skills/bug-scan/SKILL.md +378 -0
  37. package/skills/bug-scan/agents/openai.yaml +6 -0
  38. package/skills/bug-scan/references/async-promises.md +119 -0
  39. package/skills/bug-scan/references/concurrency-races.md +148 -0
  40. package/skills/bug-scan/references/data-layer.md +167 -0
  41. package/skills/bug-scan/references/error-handling.md +197 -0
  42. package/skills/bug-scan/references/gate-item-template.md +94 -0
  43. package/skills/bug-scan/references/language-footguns.md +219 -0
  44. package/skills/bug-scan/references/parked-item-template.md +103 -0
  45. package/skills/bug-scan/references/report-template.md +115 -0
  46. package/skills/bug-scan/references/resource-leaks.md +199 -0
  47. package/skills/bug-scan/references/state-closures.md +148 -0
  48. package/skills/bug-scan/references/time-numbers.md +158 -0
  49. package/skills/convert/SKILL.md +1463 -0
  50. package/skills/convert/agents/openai.yaml +6 -0
  51. package/skills/convert/references/legacy-overlap-migration.md +179 -0
  52. package/skills/deep-code-scan/SKILL.md +378 -0
  53. package/skills/deep-code-scan/agents/openai.yaml +6 -0
  54. package/skills/deep-code-scan/references/artifact-ledger.md +148 -0
  55. package/skills/deep-code-scan/references/consolidation.md +91 -0
  56. package/skills/deep-code-scan/references/decomposition.md +127 -0
  57. package/skills/deep-code-scan/references/item-templates.md +263 -0
  58. package/skills/deep-code-scan/references/lane-catalog.md +129 -0
  59. package/skills/deep-code-scan/references/review-gauntlet.md +108 -0
  60. package/skills/deep-code-scan/references/scanner-brief.md +152 -0
  61. package/skills/e2e-test-design/SKILL.md +517 -0
  62. package/skills/e2e-test-design/references/anti-tautology.md +261 -0
  63. package/skills/e2e-test-design/references/service-mocks.md +234 -0
  64. package/skills/e2e-test-design/references/test-taxonomy.md +211 -0
  65. package/skills/epic-design/SKILL.md +476 -0
  66. package/skills/epicize/SKILL.md +210 -0
  67. package/skills/epicize/agents/openai.yaml +6 -0
  68. package/skills/feature-design/SKILL.md +472 -0
  69. package/skills/fix/SKILL.md +173 -0
  70. package/skills/gate-cruft/SKILL.md +258 -0
  71. package/skills/gate-docs/SKILL.md +278 -0
  72. package/skills/gate-patterns/SKILL.md +389 -0
  73. package/skills/gate-refactor/SKILL.md +408 -0
  74. package/skills/gate-security/SKILL.md +275 -0
  75. package/skills/gate-tests/SKILL.md +367 -0
  76. package/skills/groom/SKILL.md +162 -0
  77. package/skills/groom/agents/openai.yaml +6 -0
  78. package/skills/ideate/SKILL.md +185 -0
  79. package/skills/ideate/agents/openai.yaml +6 -0
  80. package/skills/implement/SKILL.md +288 -0
  81. package/skills/implement-orchestrator/SKILL.md +604 -0
  82. package/skills/park/SKILL.md +111 -0
  83. package/skills/perf-design/SKILL.md +427 -0
  84. package/skills/perf-scout/SKILL.md +404 -0
  85. package/skills/perf-scout/agents/openai.yaml +6 -0
  86. package/skills/perf-scout/references/algorithmic-and-data-structures.md +126 -0
  87. package/skills/perf-scout/references/approximation-and-precomputation.md +136 -0
  88. package/skills/perf-scout/references/caching-and-memoization.md +123 -0
  89. package/skills/perf-scout/references/compiler-runtime-and-language.md +136 -0
  90. package/skills/perf-scout/references/database-and-storage-internals.md +144 -0
  91. package/skills/perf-scout/references/distributed-systems.md +150 -0
  92. package/skills/perf-scout/references/game-engine-and-realtime.md +136 -0
  93. package/skills/perf-scout/references/gpu-and-accelerators.md +130 -0
  94. package/skills/perf-scout/references/idea-ranking.md +75 -0
  95. package/skills/perf-scout/references/io-and-batching.md +135 -0
  96. package/skills/perf-scout/references/memory-and-data-locality.md +137 -0
  97. package/skills/perf-scout/references/parallelism-and-vectorization.md +126 -0
  98. package/skills/perf-scout/references/parked-item-template.md +117 -0
  99. package/skills/perf-scout/references/peer-review-pass.md +150 -0
  100. package/skills/perf-scout/references/report-template.md +148 -0
  101. package/skills/principles/SKILL.md +678 -0
  102. package/skills/principles/references/models.md +191 -0
  103. package/skills/principles/references/subagents.md +158 -0
  104. package/skills/prose-author/SKILL.md +185 -0
  105. package/skills/refactor-conventions-creator/SKILL.md +359 -0
  106. package/skills/refactor-conventions-creator/agents/openai.yaml +6 -0
  107. package/skills/refactor-conventions-creator/references/common-structures.md +91 -0
  108. package/skills/refactor-conventions-creator/references/common-styles.md +90 -0
  109. package/skills/refactor-design/SKILL.md +384 -0
  110. package/skills/release-deploy/SKILL.md +667 -0
  111. package/skills/release-deploy/agents/openai.yaml +6 -0
  112. package/skills/research/SKILL.md +166 -0
  113. package/skills/research/agents/openai.yaml +6 -0
  114. package/skills/review/SKILL.md +267 -0
  115. package/skills/review/references/deep-review.md +98 -0
  116. package/skills/review/references/review-lenses.md +68 -0
  117. package/skills/review/references/substrate-side-effects.md +161 -0
  118. package/skills/review/references/target-resolution.md +52 -0
  119. package/skills/scope/SKILL.md +486 -0
  120. package/work-view/Cargo.lock +486 -0
  121. package/work-view/Cargo.toml +9 -0
  122. package/work-view/crates/cli/.work-view-version +1 -0
  123. package/work-view/crates/cli/Cargo.toml +18 -0
  124. package/work-view/crates/cli/src/actionable.rs +500 -0
  125. package/work-view/crates/cli/src/args.rs +792 -0
  126. package/work-view/crates/cli/src/board/assets/board.css +855 -0
  127. package/work-view/crates/cli/src/board/assets/board.js +259 -0
  128. package/work-view/crates/cli/src/board/assets/card.js +139 -0
  129. package/work-view/crates/cli/src/board/assets/components.css +290 -0
  130. package/work-view/crates/cli/src/board/assets/dependency.js +1193 -0
  131. package/work-view/crates/cli/src/board/assets/detail.js +256 -0
  132. package/work-view/crates/cli/src/board/assets/filters.js +389 -0
  133. package/work-view/crates/cli/src/board/assets/index.html +77 -0
  134. package/work-view/crates/cli/src/board/assets/kanban.js +231 -0
  135. package/work-view/crates/cli/src/board/assets/markdown.js +260 -0
  136. package/work-view/crates/cli/src/board/assets/motion.css +131 -0
  137. package/work-view/crates/cli/src/board/assets/state.js +245 -0
  138. package/work-view/crates/cli/src/board/assets/table.js +304 -0
  139. package/work-view/crates/cli/src/board/assets/tokens.css +602 -0
  140. package/work-view/crates/cli/src/board/assets/views.js +41 -0
  141. package/work-view/crates/cli/src/board/assets.rs +162 -0
  142. package/work-view/crates/cli/src/board/feed.rs +204 -0
  143. package/work-view/crates/cli/src/board/mod.rs +246 -0
  144. package/work-view/crates/cli/src/board/open.rs +144 -0
  145. package/work-view/crates/cli/src/board/server.rs +407 -0
  146. package/work-view/crates/cli/src/main.rs +195 -0
  147. package/work-view/crates/cli/src/render.rs +354 -0
  148. package/work-view/crates/cli/src/scope.rs +157 -0
  149. package/work-view/crates/cli/src/stale.rs +581 -0
  150. package/work-view/crates/cli/tests/board-js/dependency-table.test.mjs +64 -0
  151. package/work-view/crates/cli/tests/board-js/expanded-browsing.test.mjs +79 -0
  152. package/work-view/crates/cli/tests/board-js/harness-smoke.test.mjs +11 -0
  153. package/work-view/crates/cli/tests/board-js/harness.mjs +437 -0
  154. package/work-view/crates/cli/tests/board-js/kanban-detail.test.mjs +75 -0
  155. package/work-view/crates/cli/tests/board-js/markdown-filter.test.mjs +60 -0
  156. package/work-view/crates/cli/tests/fixtures/golden/.work/CONVENTIONS.md +3 -0
  157. package/work-view/crates/cli/tests/fixtures/golden/.work/active/epics/epic-alpha.md +16 -0
  158. package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-a.md +16 -0
  159. package/work-view/crates/cli/tests/fixtures/golden/.work/active/features/feat-b.md +16 -0
  160. package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-alpha-1.md +16 -0
  161. package/work-view/crates/cli/tests/fixtures/golden/.work/active/stories/story-research-1.md +19 -0
  162. package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-done.md +16 -0
  163. package/work-view/crates/cli/tests/fixtures/golden/.work/archive/feat-shipped.md +18 -0
  164. package/work-view/crates/cli/tests/fixtures/golden/.work/backlog/idea-backlog.md +7 -0
  165. package/work-view/crates/cli/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
  166. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/CONVENTIONS.md +6 -0
  167. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-dep-done.md +17 -0
  168. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-design-ready.md +17 -0
  169. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/features/feat-impl-ready.md +17 -0
  170. package/work-view/crates/cli/tests/fixtures/ready-drafting/.work/active/stories/story-review-ready.md +17 -0
  171. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/CONVENTIONS.md +4 -0
  172. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/epics/malformed-no-closing-fence.md +8 -0
  173. package/work-view/crates/cli/tests/fixtures/with-malformed/.work/active/features/good-item.md +16 -0
  174. package/work-view/crates/cli/tests/integration.rs +2833 -0
  175. package/work-view/crates/core/Cargo.toml +13 -0
  176. package/work-view/crates/core/src/error.rs +61 -0
  177. package/work-view/crates/core/src/filter.rs +804 -0
  178. package/work-view/crates/core/src/graph.rs +324 -0
  179. package/work-view/crates/core/src/index.rs +590 -0
  180. package/work-view/crates/core/src/lib.rs +54 -0
  181. package/work-view/crates/core/src/model.rs +202 -0
  182. package/work-view/crates/core/src/parse.rs +494 -0
  183. package/work-view/crates/core/tests/fixtures/golden/.work/CONVENTIONS.md +15 -0
  184. package/work-view/crates/core/tests/fixtures/golden/.work/active/epics/epic-core.md +16 -0
  185. package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-parser.md +16 -0
  186. package/work-view/crates/core/tests/fixtures/golden/.work/active/features/feat-query.md +16 -0
  187. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/malformed-no-id.md +15 -0
  188. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-parse-unit.md +16 -0
  189. package/work-view/crates/core/tests/fixtures/golden/.work/active/stories/story-security-gate.md +16 -0
  190. package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-old.md +16 -0
  191. package/work-view/crates/core/tests/fixtures/golden/.work/archive/feat-parser.md +17 -0
  192. package/work-view/crates/core/tests/fixtures/golden/.work/backlog/idea-future-board.md +7 -0
  193. package/work-view/crates/core/tests/fixtures/golden/.work/releases/v1.0/v1.0.md +16 -0
  194. package/work-view/crates/core/tests/fixtures/precedence/.work/CONVENTIONS.md +10 -0
  195. package/work-view/crates/core/tests/fixtures/precedence/.work/archive/dup-item.md +18 -0
  196. package/work-view/crates/core/tests/fixtures/precedence/.work/releases/v2.0/dup-item.md +18 -0
  197. package/work-view/crates/core/tests/integration.rs +541 -0
  198. package/work-view/dist/.gitattributes +1 -0
  199. package/work-view/dist/README.md +42 -0
  200. package/work-view/dist/aarch64-apple-darwin/work-view +0 -0
  201. package/work-view/dist/aarch64-unknown-linux-musl/work-view +0 -0
  202. package/work-view/dist/x86_64-apple-darwin/work-view +0 -0
  203. package/work-view/dist/x86_64-unknown-linux-musl/work-view +0 -0
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env bash
2
+ # work-board-shim.test.sh — routing tests for scripts/work-board.sh.
3
+ #
4
+ # work-board.sh is a decision shim with three routing branches:
5
+ # 1. No `.work/CONVENTIONS.md` in CWD or any ancestor -> exit 2 (no substrate)
6
+ # 2. `.work/bin/work-view` missing or not executable -> exit 1 (compiled
7
+ # work-view binary required)
8
+ # 3. work-view present but FAILS `board --help` -> exit 1, does NOT
9
+ # exec the board
10
+ # 4. work-view present and PASSES `board --help` -> exec'd as
11
+ # `work-view board "$@"`
12
+ #
13
+ # Self-contained: builds temp substrate roots and stub `work-view` binaries,
14
+ # following the harness pattern from install-work-view.test.sh. Runnable locally
15
+ # and from CI. Exits non-zero if any assertion fails.
16
+
17
+ set -uo pipefail
18
+
19
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+ SHIM="${SCRIPT_DIR}/../work-board.sh"
21
+
22
+ # ---------------------------------------------------------------------------
23
+ # Counters
24
+ # ---------------------------------------------------------------------------
25
+ PASS=0
26
+ FAIL=0
27
+ ERRORS=()
28
+
29
+ assert_eq() {
30
+ local label="$1" expected="$2" actual="$3"
31
+ if [ "$expected" = "$actual" ]; then
32
+ echo " PASS: $label"
33
+ ((PASS++))
34
+ else
35
+ echo " FAIL: $label"
36
+ echo " expected: $(printf '%q' "$expected")"
37
+ echo " actual: $(printf '%q' "$actual")"
38
+ ((FAIL++))
39
+ ERRORS+=("$label")
40
+ fi
41
+ }
42
+
43
+ assert_true() {
44
+ local label="$1"
45
+ if eval "$2"; then
46
+ echo " PASS: $label"
47
+ ((PASS++))
48
+ else
49
+ echo " FAIL: $label"
50
+ echo " condition false: $2"
51
+ ((FAIL++))
52
+ ERRORS+=("$label")
53
+ fi
54
+ }
55
+
56
+ assert_false() {
57
+ local label="$1"
58
+ if ! eval "$2"; then
59
+ echo " PASS: $label"
60
+ ((PASS++))
61
+ else
62
+ echo " FAIL: $label"
63
+ echo " expected false but was true: $2"
64
+ ((FAIL++))
65
+ ERRORS+=("$label")
66
+ fi
67
+ }
68
+
69
+ # ---------------------------------------------------------------------------
70
+ # Preflight
71
+ # ---------------------------------------------------------------------------
72
+ echo ""
73
+ echo "=== Preflight: work-board.sh present ==="
74
+ assert_true "work-board.sh exists" "[ -f '$SHIM' ]"
75
+ if [ ! -f "$SHIM" ]; then
76
+ echo "ERROR: cannot locate work-board.sh at $SHIM" >&2
77
+ exit 1
78
+ fi
79
+
80
+ # ---------------------------------------------------------------------------
81
+ # new_substrate <with-conventions?> — temp dir; if first arg is "yes", seeds
82
+ # .work/CONVENTIONS.md so it reads as a substrate root.
83
+ # ---------------------------------------------------------------------------
84
+ new_substrate() {
85
+ local with_conv="${1:-yes}"
86
+ local root
87
+ root="$(mktemp -d)"
88
+ mkdir -p "${root}/.work"
89
+ if [ "$with_conv" = "yes" ]; then
90
+ printf '# Conventions\n' > "${root}/.work/CONVENTIONS.md"
91
+ fi
92
+ printf '%s' "$root"
93
+ }
94
+
95
+ # write_work_view <root> <board-help-rc> <arglog-path>
96
+ # Installs an executable .work/bin/work-view stub that:
97
+ # * exits <board-help-rc> for `board --help`
98
+ # * for any other `board ...` invocation, appends "$@" to <arglog-path> and
99
+ # exits 0 (lets us prove it was exec'd with `board "$@"`).
100
+ write_work_view() {
101
+ local root="$1" help_rc="$2" arglog="$3"
102
+ local bin="${root}/.work/bin/work-view"
103
+ mkdir -p "${root}/.work/bin"
104
+ cat > "$bin" <<EOF
105
+ #!/usr/bin/env bash
106
+ if [[ "\${1:-}" == "board" && "\${2:-}" == "--help" ]]; then
107
+ exit ${help_rc}
108
+ fi
109
+ if [[ "\${1:-}" == "board" ]]; then
110
+ shift
111
+ printf 'board %s\n' "\$*" >> "${arglog}"
112
+ exit 0
113
+ fi
114
+ exit 0
115
+ EOF
116
+ chmod +x "$bin"
117
+ }
118
+
119
+ # run_board <root> [args...] — invoke the shim from inside <root>.
120
+ # Captures stdout in $BOARD_OUT, stderr file in $BOARD_ERR, rc in $BOARD_RC.
121
+ run_board() {
122
+ local root="$1"; shift
123
+ BOARD_ERR="${root}/.board.err"
124
+ BOARD_OUT=$(
125
+ cd "$root" &&
126
+ bash "$SHIM" "$@" 2>"$BOARD_ERR"
127
+ )
128
+ BOARD_RC=$?
129
+ }
130
+
131
+ # ---------------------------------------------------------------------------
132
+ # Test group 1: no substrate ancestor -> exit 2, stderr mentions no substrate
133
+ # ---------------------------------------------------------------------------
134
+ echo ""
135
+ echo "=== Test group 1: no .work/CONVENTIONS.md ancestor -> exit 2 ==="
136
+
137
+ # A directory with NO .work/CONVENTIONS.md anywhere up to root. mktemp -d lands
138
+ # under TMPDIR; we additionally guard by removing any .work it might inherit.
139
+ NOSUB="$(mktemp -d)"
140
+ run_board "$NOSUB"
141
+ assert_eq "no-substrate exits 2" "2" "$BOARD_RC"
142
+ assert_true "no-substrate stderr mentions no substrate" \
143
+ "grep -qi 'no substrate' '$BOARD_ERR'"
144
+ rm -rf "$NOSUB"
145
+
146
+ # ---------------------------------------------------------------------------
147
+ # Test group 2: substrate present but work-view missing -> exit 1
148
+ # ---------------------------------------------------------------------------
149
+ echo ""
150
+ echo "=== Test group 2: missing/non-exec work-view -> exit 1 ==="
151
+
152
+ ROOT_MISSING="$(new_substrate yes)"
153
+ run_board "$ROOT_MISSING"
154
+ assert_eq "missing work-view exits 1" "1" "$BOARD_RC"
155
+ assert_true "missing work-view message names the compiled work-view binary" \
156
+ "grep -qi 'compiled work-view binary' '$BOARD_ERR'"
157
+ rm -rf "$ROOT_MISSING"
158
+
159
+ # Present but NOT executable (file exists, mode 0644) -> still exit 1.
160
+ ROOT_NOEXEC="$(new_substrate yes)"
161
+ mkdir -p "${ROOT_NOEXEC}/.work/bin"
162
+ printf '#!/usr/bin/env bash\nexit 0\n' > "${ROOT_NOEXEC}/.work/bin/work-view"
163
+ chmod 0644 "${ROOT_NOEXEC}/.work/bin/work-view"
164
+ run_board "$ROOT_NOEXEC"
165
+ assert_eq "non-executable work-view exits 1" "1" "$BOARD_RC"
166
+ assert_true "non-executable work-view message names the compiled work-view binary" \
167
+ "grep -qi 'compiled work-view binary' '$BOARD_ERR'"
168
+ rm -rf "$ROOT_NOEXEC"
169
+
170
+ # ---------------------------------------------------------------------------
171
+ # Test group 3: work-view fails `board --help` -> exit 1, does NOT exec board
172
+ # ---------------------------------------------------------------------------
173
+ echo ""
174
+ echo "=== Test group 3: work-view fails 'board --help' -> exit 1, no exec ==="
175
+
176
+ ROOT_FAIL="$(new_substrate yes)"
177
+ ARGLOG_FAIL="${ROOT_FAIL}/.board-args.log"
178
+ write_work_view "$ROOT_FAIL" 1 "$ARGLOG_FAIL"
179
+ run_board "$ROOT_FAIL" --port 9999
180
+ assert_eq "board-incapable work-view exits 1" "1" "$BOARD_RC"
181
+ assert_true "board-incapable message says board unsupported / refresh" \
182
+ "grep -qiE 'does not support the interactive board|refresh' '$BOARD_ERR'"
183
+ assert_false "board-incapable did NOT exec board (no arglog written)" \
184
+ "[ -f '$ARGLOG_FAIL' ]"
185
+ rm -rf "$ROOT_FAIL"
186
+
187
+ # ---------------------------------------------------------------------------
188
+ # Test group 4: work-view passes `board --help` -> exec'd as board "$@"
189
+ # ---------------------------------------------------------------------------
190
+ echo ""
191
+ echo "=== Test group 4: board-capable work-view -> exec board \"\$@\" ==="
192
+
193
+ ROOT_OK="$(new_substrate yes)"
194
+ ARGLOG_OK="${ROOT_OK}/.board-args.log"
195
+ write_work_view "$ROOT_OK" 0 "$ARGLOG_OK"
196
+ run_board "$ROOT_OK" --port 8181 --no-open
197
+ assert_eq "board-capable work-view exits 0" "0" "$BOARD_RC"
198
+ assert_true "board-capable exec'd board with forwarded args" \
199
+ "[ -f '$ARGLOG_OK' ] && grep -qx 'board --port 8181 --no-open' '$ARGLOG_OK'"
200
+ rm -rf "$ROOT_OK"
201
+
202
+ # Board-capable with NO extra args -> exec'd as `board` (empty arg tail).
203
+ ROOT_OK2="$(new_substrate yes)"
204
+ ARGLOG_OK2="${ROOT_OK2}/.board-args.log"
205
+ write_work_view "$ROOT_OK2" 0 "$ARGLOG_OK2"
206
+ run_board "$ROOT_OK2"
207
+ assert_eq "board-capable (no args) exits 0" "0" "$BOARD_RC"
208
+ assert_true "board-capable (no args) exec'd plain board" \
209
+ "[ -f '$ARGLOG_OK2' ] && grep -qx 'board ' '$ARGLOG_OK2'"
210
+ rm -rf "$ROOT_OK2"
211
+
212
+ # ---------------------------------------------------------------------------
213
+ # Test group 5: --help short-circuits before any substrate/binary check
214
+ # ---------------------------------------------------------------------------
215
+ echo ""
216
+ echo "=== Test group 5: --help prints usage, exit 0, no substrate needed ==="
217
+
218
+ NOSUB_HELP="$(mktemp -d)"
219
+ run_board "$NOSUB_HELP" --help
220
+ assert_eq "--help exits 0 even with no substrate" "0" "$BOARD_RC"
221
+ assert_true "--help prints usage" \
222
+ "printf '%s' \"\$BOARD_OUT\" | grep -qi 'launch the agile-workflow live substrate board'"
223
+ rm -rf "$NOSUB_HELP"
224
+
225
+ # ---------------------------------------------------------------------------
226
+ # Summary
227
+ # ---------------------------------------------------------------------------
228
+ echo ""
229
+ echo "============================================================"
230
+ echo "Results: ${PASS} passed, ${FAIL} failed"
231
+ if [ ${#ERRORS[@]} -gt 0 ]; then
232
+ echo "Failed tests:"
233
+ for e in "${ERRORS[@]}"; do
234
+ echo " - $e"
235
+ done
236
+ fi
237
+ echo "============================================================"
238
+
239
+ [ "$FAIL" -eq 0 ] || exit 1
@@ -0,0 +1,105 @@
1
+ #!/usr/bin/env bash
2
+ # work-view-dist-version.test.sh — guard committed prebuilt version stamps.
3
+ #
4
+ # The installer trusts supported-platform prebuilts only after their --version
5
+ # matches the plugin manifest. This test keeps the committed dist/ tree in that
6
+ # same state so a version bump cannot publish stale board-capable binaries.
7
+
8
+ set -uo pipefail
9
+
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ PLUGIN_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
12
+ PLUGIN_JSON="${PLUGIN_ROOT}/.claude-plugin/plugin.json"
13
+
14
+ PASS=0
15
+ FAIL=0
16
+ ERRORS=()
17
+
18
+ assert_true() {
19
+ local label="$1"
20
+ if eval "$2"; then
21
+ echo " PASS: $label"
22
+ ((PASS++))
23
+ else
24
+ echo " FAIL: $label"
25
+ echo " condition false: $2"
26
+ ((FAIL++))
27
+ ERRORS+=("$label")
28
+ fi
29
+ }
30
+
31
+ assert_eq() {
32
+ local label="$1" expected="$2" actual="$3"
33
+ if [ "$expected" = "$actual" ]; then
34
+ echo " PASS: $label"
35
+ ((PASS++))
36
+ else
37
+ echo " FAIL: $label"
38
+ echo " expected: $(printf '%q' "$expected")"
39
+ echo " actual: $(printf '%q' "$actual")"
40
+ ((FAIL++))
41
+ ERRORS+=("$label")
42
+ fi
43
+ }
44
+
45
+ plugin_version() {
46
+ sed -n 's/^[[:space:]]*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$PLUGIN_JSON" | head -n 1
47
+ }
48
+
49
+ echo ""
50
+ echo "=== Preflight: plugin manifest and dist binaries ==="
51
+ assert_true "plugin manifest exists" "[ -f '$PLUGIN_JSON' ]"
52
+ VERSION="$(plugin_version)"
53
+ assert_true "plugin version is readable" "[ -n '$VERSION' ]"
54
+
55
+ TRIPLES=(
56
+ x86_64-unknown-linux-musl
57
+ aarch64-unknown-linux-musl
58
+ x86_64-apple-darwin
59
+ aarch64-apple-darwin
60
+ )
61
+
62
+ echo ""
63
+ echo "=== Test group 1: all supported prebuilts embed plugin version ==="
64
+ for triple in "${TRIPLES[@]}"; do
65
+ bin="${PLUGIN_ROOT}/work-view/dist/${triple}/work-view"
66
+ assert_true "${triple} binary exists" "[ -f '$bin' ]"
67
+ assert_true "${triple} binary executable" "[ -x '$bin' ]"
68
+ assert_true "${triple} embeds work-view ${VERSION}" \
69
+ "LC_ALL=C grep -a -q 'work-view ${VERSION}\\|${VERSION}' '$bin'"
70
+ done
71
+
72
+ echo ""
73
+ echo "=== Test group 2: native Linux x86_64 binary reports version and board help ==="
74
+ HOST_S="$(uname -s 2>/dev/null || printf unknown)"
75
+ HOST_M="$(uname -m 2>/dev/null || printf unknown)"
76
+ if [ "$HOST_S" = "Linux" ] && { [ "$HOST_M" = "x86_64" ] || [ "$HOST_M" = "amd64" ]; }; then
77
+ native="${PLUGIN_ROOT}/work-view/dist/x86_64-unknown-linux-musl/work-view"
78
+ assert_eq "native --version matches plugin" "work-view ${VERSION}" "$("$native" --version)"
79
+ assert_true "native supports board --help" "'$native' board --help >/dev/null 2>&1"
80
+ else
81
+ echo " SKIP: native execution check requires Linux x86_64 host (got ${HOST_S}/${HOST_M})"
82
+ fi
83
+
84
+ echo ""
85
+ echo "=== Test group 3: repo dogfood work-view install matches plugin ==="
86
+ DOGFOOD_BIN="${PLUGIN_ROOT}/../../.work/bin/work-view"
87
+ if [ -e "$DOGFOOD_BIN" ]; then
88
+ assert_true "dogfood work-view executable" "[ -x '$DOGFOOD_BIN' ]"
89
+ assert_eq "dogfood --version matches plugin" "work-view ${VERSION}" "$("$DOGFOOD_BIN" --version)"
90
+ else
91
+ echo " SKIP: no repo dogfood .work/bin/work-view install present"
92
+ fi
93
+
94
+ echo ""
95
+ echo "============================================================"
96
+ echo "Results: ${PASS} passed, ${FAIL} failed"
97
+ if [ ${#ERRORS[@]} -gt 0 ]; then
98
+ echo "Failed tests:"
99
+ for e in "${ERRORS[@]}"; do
100
+ echo " - $e"
101
+ done
102
+ fi
103
+ echo "============================================================"
104
+
105
+ [ "$FAIL" -eq 0 ] || exit 1
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env bash
2
+ # Compatibility shim for the live substrate board.
3
+
4
+ set -euo pipefail
5
+
6
+ usage() {
7
+ cat <<'USAGE'
8
+ work-board - launch the agile-workflow live substrate board
9
+
10
+ Usage: work-board [OPTIONS]
11
+
12
+ Options are forwarded to:
13
+ .work/bin/work-view board [OPTIONS]
14
+
15
+ Common options:
16
+ --port <n> Port to bind on localhost (default: 8181)
17
+ --no-open Print the URL without opening a browser
18
+ --print Alias for --no-open
19
+ --help, -h Show this help
20
+
21
+ The interactive board requires a compiled board-capable work-view binary.
22
+ USAGE
23
+ }
24
+
25
+ find_substrate_root() {
26
+ local dir
27
+ dir="$(pwd)"
28
+ while [[ "$dir" != "/" && -n "$dir" ]]; do
29
+ if [[ -f "$dir/.work/CONVENTIONS.md" ]]; then
30
+ printf '%s\n' "$dir"
31
+ return 0
32
+ fi
33
+ dir="$(dirname "$dir")"
34
+ done
35
+ return 1
36
+ }
37
+
38
+ case "${1:-}" in
39
+ --help|-h)
40
+ usage
41
+ exit 0
42
+ ;;
43
+ esac
44
+
45
+ ROOT="$(find_substrate_root || true)"
46
+ if [[ -z "$ROOT" ]]; then
47
+ echo "work-board: no substrate found (no .work/CONVENTIONS.md in CWD or ancestor)" >&2
48
+ exit 2
49
+ fi
50
+
51
+ WORK_VIEW="$ROOT/.work/bin/work-view"
52
+ if [[ ! -x "$WORK_VIEW" ]]; then
53
+ echo "work-board: interactive board requires a compiled work-view binary at $WORK_VIEW" >&2
54
+ echo "work-board: refresh agile-workflow's work-view binary, then run .work/bin/work-view board" >&2
55
+ exit 1
56
+ fi
57
+
58
+ if "$WORK_VIEW" board --help >/dev/null 2>&1; then
59
+ exec "$WORK_VIEW" board "$@"
60
+ fi
61
+
62
+ echo "work-board: installed work-view does not support the interactive board" >&2
63
+ echo "work-board: refresh agile-workflow's compiled work-view binary, then run .work/bin/work-view board" >&2
64
+ exit 1