@qball-inc/the-bulwark 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/.claude-plugin/plugin.json +43 -0
  2. package/agents/bulwark-fix-validator.md +633 -0
  3. package/agents/bulwark-implementer.md +391 -0
  4. package/agents/bulwark-issue-analyzer.md +308 -0
  5. package/agents/bulwark-standards-reviewer.md +221 -0
  6. package/agents/plan-creation-architect.md +323 -0
  7. package/agents/plan-creation-eng-lead.md +352 -0
  8. package/agents/plan-creation-po.md +300 -0
  9. package/agents/plan-creation-qa-critic.md +334 -0
  10. package/agents/product-ideation-competitive-analyzer.md +298 -0
  11. package/agents/product-ideation-idea-validator.md +268 -0
  12. package/agents/product-ideation-market-researcher.md +292 -0
  13. package/agents/product-ideation-pattern-documenter.md +308 -0
  14. package/agents/product-ideation-segment-analyzer.md +303 -0
  15. package/agents/product-ideation-strategist.md +259 -0
  16. package/agents/statusline-setup.md +97 -0
  17. package/hooks/hooks.json +59 -0
  18. package/package.json +45 -0
  19. package/scripts/hooks/cleanup-stale.sh +13 -0
  20. package/scripts/hooks/enforce-quality.sh +166 -0
  21. package/scripts/hooks/implementer-quality.sh +256 -0
  22. package/scripts/hooks/inject-protocol.sh +52 -0
  23. package/scripts/hooks/suggest-pipeline.sh +175 -0
  24. package/scripts/hooks/track-pipeline-start.sh +37 -0
  25. package/scripts/hooks/track-pipeline-stop.sh +52 -0
  26. package/scripts/init-rules.sh +35 -0
  27. package/scripts/init.sh +151 -0
  28. package/skills/anthropic-validator/SKILL.md +607 -0
  29. package/skills/anthropic-validator/references/agents-checklist.md +131 -0
  30. package/skills/anthropic-validator/references/commands-checklist.md +102 -0
  31. package/skills/anthropic-validator/references/hooks-checklist.md +151 -0
  32. package/skills/anthropic-validator/references/mcp-checklist.md +136 -0
  33. package/skills/anthropic-validator/references/plugins-checklist.md +148 -0
  34. package/skills/anthropic-validator/references/skills-checklist.md +85 -0
  35. package/skills/assertion-patterns/SKILL.md +296 -0
  36. package/skills/bug-magnet-data/SKILL.md +284 -0
  37. package/skills/bug-magnet-data/context/cli-args.md +91 -0
  38. package/skills/bug-magnet-data/context/db-query.md +104 -0
  39. package/skills/bug-magnet-data/context/file-contents.md +103 -0
  40. package/skills/bug-magnet-data/context/http-body.md +91 -0
  41. package/skills/bug-magnet-data/context/process-spawn.md +123 -0
  42. package/skills/bug-magnet-data/data/booleans/boundaries.yaml +143 -0
  43. package/skills/bug-magnet-data/data/collections/arrays.yaml +114 -0
  44. package/skills/bug-magnet-data/data/collections/objects.yaml +123 -0
  45. package/skills/bug-magnet-data/data/concurrency/race-conditions.yaml +118 -0
  46. package/skills/bug-magnet-data/data/concurrency/state-machines.yaml +115 -0
  47. package/skills/bug-magnet-data/data/dates/boundaries.yaml +137 -0
  48. package/skills/bug-magnet-data/data/dates/invalid.yaml +132 -0
  49. package/skills/bug-magnet-data/data/dates/timezone.yaml +118 -0
  50. package/skills/bug-magnet-data/data/encoding/charset.yaml +79 -0
  51. package/skills/bug-magnet-data/data/encoding/normalization.yaml +105 -0
  52. package/skills/bug-magnet-data/data/formats/email.yaml +154 -0
  53. package/skills/bug-magnet-data/data/formats/json.yaml +187 -0
  54. package/skills/bug-magnet-data/data/formats/url.yaml +165 -0
  55. package/skills/bug-magnet-data/data/language-specific/javascript.yaml +182 -0
  56. package/skills/bug-magnet-data/data/language-specific/python.yaml +174 -0
  57. package/skills/bug-magnet-data/data/language-specific/rust.yaml +148 -0
  58. package/skills/bug-magnet-data/data/numbers/boundaries.yaml +161 -0
  59. package/skills/bug-magnet-data/data/numbers/precision.yaml +89 -0
  60. package/skills/bug-magnet-data/data/numbers/special.yaml +69 -0
  61. package/skills/bug-magnet-data/data/strings/boundaries.yaml +109 -0
  62. package/skills/bug-magnet-data/data/strings/injection.yaml +208 -0
  63. package/skills/bug-magnet-data/data/strings/special-chars.yaml +190 -0
  64. package/skills/bug-magnet-data/data/strings/unicode.yaml +139 -0
  65. package/skills/bug-magnet-data/references/external-lists.md +115 -0
  66. package/skills/bulwark-brainstorm/SKILL.md +563 -0
  67. package/skills/bulwark-brainstorm/references/at-teammate-prompts.md +60 -0
  68. package/skills/bulwark-brainstorm/references/role-critical-analyst.md +78 -0
  69. package/skills/bulwark-brainstorm/references/role-development-lead.md +66 -0
  70. package/skills/bulwark-brainstorm/references/role-product-delivery-lead.md +79 -0
  71. package/skills/bulwark-brainstorm/references/role-product-manager.md +62 -0
  72. package/skills/bulwark-brainstorm/references/role-project-sme.md +59 -0
  73. package/skills/bulwark-brainstorm/references/role-technical-architect.md +66 -0
  74. package/skills/bulwark-research/SKILL.md +298 -0
  75. package/skills/bulwark-research/references/viewpoint-contrarian.md +63 -0
  76. package/skills/bulwark-research/references/viewpoint-direct-investigation.md +62 -0
  77. package/skills/bulwark-research/references/viewpoint-first-principles.md +65 -0
  78. package/skills/bulwark-research/references/viewpoint-practitioner.md +62 -0
  79. package/skills/bulwark-research/references/viewpoint-prior-art.md +66 -0
  80. package/skills/bulwark-scaffold/SKILL.md +330 -0
  81. package/skills/bulwark-statusline/SKILL.md +161 -0
  82. package/skills/bulwark-statusline/scripts/statusline.sh +144 -0
  83. package/skills/bulwark-verify/SKILL.md +519 -0
  84. package/skills/code-review/SKILL.md +428 -0
  85. package/skills/code-review/examples/anti-patterns/linting.ts +181 -0
  86. package/skills/code-review/examples/anti-patterns/security.ts +91 -0
  87. package/skills/code-review/examples/anti-patterns/standards.ts +195 -0
  88. package/skills/code-review/examples/anti-patterns/type-safety.ts +108 -0
  89. package/skills/code-review/examples/recommended/linting.ts +195 -0
  90. package/skills/code-review/examples/recommended/security.ts +154 -0
  91. package/skills/code-review/examples/recommended/standards.ts +231 -0
  92. package/skills/code-review/examples/recommended/type-safety.ts +181 -0
  93. package/skills/code-review/frameworks/angular.md +218 -0
  94. package/skills/code-review/frameworks/django.md +235 -0
  95. package/skills/code-review/frameworks/express.md +207 -0
  96. package/skills/code-review/frameworks/flask.md +298 -0
  97. package/skills/code-review/frameworks/generic.md +146 -0
  98. package/skills/code-review/frameworks/react.md +152 -0
  99. package/skills/code-review/frameworks/vue.md +244 -0
  100. package/skills/code-review/references/linting-patterns.md +221 -0
  101. package/skills/code-review/references/security-patterns.md +125 -0
  102. package/skills/code-review/references/standards-patterns.md +246 -0
  103. package/skills/code-review/references/type-safety-patterns.md +130 -0
  104. package/skills/component-patterns/SKILL.md +131 -0
  105. package/skills/component-patterns/references/pattern-cli-command.md +118 -0
  106. package/skills/component-patterns/references/pattern-database.md +166 -0
  107. package/skills/component-patterns/references/pattern-external-api.md +139 -0
  108. package/skills/component-patterns/references/pattern-file-parser.md +168 -0
  109. package/skills/component-patterns/references/pattern-http-server.md +162 -0
  110. package/skills/component-patterns/references/pattern-process-spawner.md +133 -0
  111. package/skills/continuous-feedback/SKILL.md +327 -0
  112. package/skills/continuous-feedback/references/collect-instructions.md +81 -0
  113. package/skills/continuous-feedback/references/specialize-code-review.md +82 -0
  114. package/skills/continuous-feedback/references/specialize-general.md +98 -0
  115. package/skills/continuous-feedback/references/specialize-test-audit.md +81 -0
  116. package/skills/create-skill/SKILL.md +359 -0
  117. package/skills/create-skill/references/agent-conventions.md +194 -0
  118. package/skills/create-skill/references/agent-template.md +195 -0
  119. package/skills/create-skill/references/content-guidance.md +291 -0
  120. package/skills/create-skill/references/decision-framework.md +124 -0
  121. package/skills/create-skill/references/template-pipeline.md +217 -0
  122. package/skills/create-skill/references/template-reference-heavy.md +111 -0
  123. package/skills/create-skill/references/template-research.md +210 -0
  124. package/skills/create-skill/references/template-script-driven.md +172 -0
  125. package/skills/create-skill/references/template-simple.md +80 -0
  126. package/skills/create-subagent/SKILL.md +353 -0
  127. package/skills/create-subagent/references/agent-conventions.md +268 -0
  128. package/skills/create-subagent/references/content-guidance.md +232 -0
  129. package/skills/create-subagent/references/decision-framework.md +134 -0
  130. package/skills/create-subagent/references/template-single-agent.md +192 -0
  131. package/skills/fix-bug/SKILL.md +241 -0
  132. package/skills/governance-protocol/SKILL.md +116 -0
  133. package/skills/init/SKILL.md +341 -0
  134. package/skills/issue-debugging/SKILL.md +385 -0
  135. package/skills/issue-debugging/references/anti-patterns.md +245 -0
  136. package/skills/issue-debugging/references/debug-report-schema.md +227 -0
  137. package/skills/mock-detection/SKILL.md +511 -0
  138. package/skills/mock-detection/references/false-positive-prevention.md +402 -0
  139. package/skills/mock-detection/references/stub-patterns.md +236 -0
  140. package/skills/pipeline-templates/SKILL.md +215 -0
  141. package/skills/pipeline-templates/references/code-change-workflow.md +277 -0
  142. package/skills/pipeline-templates/references/code-review.md +336 -0
  143. package/skills/pipeline-templates/references/fix-validation.md +421 -0
  144. package/skills/pipeline-templates/references/new-feature.md +335 -0
  145. package/skills/pipeline-templates/references/research-brainstorm.md +161 -0
  146. package/skills/pipeline-templates/references/research-planning.md +257 -0
  147. package/skills/pipeline-templates/references/test-audit.md +389 -0
  148. package/skills/pipeline-templates/references/test-execution-fix.md +238 -0
  149. package/skills/plan-creation/SKILL.md +497 -0
  150. package/skills/product-ideation/SKILL.md +372 -0
  151. package/skills/product-ideation/references/analysis-frameworks.md +161 -0
  152. package/skills/session-handoff/SKILL.md +139 -0
  153. package/skills/session-handoff/references/examples.md +223 -0
  154. package/skills/setup-lsp/SKILL.md +312 -0
  155. package/skills/setup-lsp/references/server-registry.md +85 -0
  156. package/skills/setup-lsp/references/troubleshooting.md +135 -0
  157. package/skills/subagent-output-templating/SKILL.md +415 -0
  158. package/skills/subagent-output-templating/references/examples.md +440 -0
  159. package/skills/subagent-prompting/SKILL.md +364 -0
  160. package/skills/subagent-prompting/references/examples.md +342 -0
  161. package/skills/test-audit/SKILL.md +531 -0
  162. package/skills/test-audit/references/known-limitations.md +41 -0
  163. package/skills/test-audit/references/priority-classification.md +30 -0
  164. package/skills/test-audit/references/prompts/deep-mode-detection.md +83 -0
  165. package/skills/test-audit/references/prompts/synthesis.md +57 -0
  166. package/skills/test-audit/references/rewrite-instructions.md +46 -0
  167. package/skills/test-audit/references/schemas/audit-output.yaml +100 -0
  168. package/skills/test-audit/references/schemas/diagnostic-output.yaml +49 -0
  169. package/skills/test-audit/scripts/data-flow-analyzer.ts +509 -0
  170. package/skills/test-audit/scripts/integration-mock-detector.ts +462 -0
  171. package/skills/test-audit/scripts/package.json +20 -0
  172. package/skills/test-audit/scripts/skip-detector.ts +211 -0
  173. package/skills/test-audit/scripts/verification-counter.ts +295 -0
  174. package/skills/test-classification/SKILL.md +310 -0
  175. package/skills/test-fixture-creation/SKILL.md +295 -0
@@ -0,0 +1,330 @@
1
+ ---
2
+ name: bulwark-scaffold
3
+ description: Initialize Bulwark infrastructure in a project. Generates Justfile, logs directory, and optional hook configuration.
4
+ user-invocable: true
5
+ ---
6
+
7
+ # Bulwark Scaffold
8
+
9
+ Initialize Bulwark infrastructure in a project by generating Justfile templates, creating the logs directory structure, and optionally configuring hooks.
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ /bulwark-scaffold [options]
15
+ ```
16
+
17
+ **Options:**
18
+ - `--force` - Overwrite existing Justfile (creates backup)
19
+ - `--no-hooks` - Skip hook configuration (hooks are generated by default)
20
+ - `--dry-run` - Show what would be generated without writing files
21
+ - `--lang=<node|python|rust|generic>` - Override language detection
22
+
23
+ **Examples:**
24
+ - `/bulwark-scaffold` - Full scaffold with Justfile + logs/ + hooks
25
+ - `/bulwark-scaffold --force` - Overwrite existing Justfile
26
+ - `/bulwark-scaffold --no-hooks` - Skip hook configuration
27
+ - `/bulwark-scaffold --dry-run` - Preview changes
28
+
29
+ ---
30
+
31
+ ## Execution Steps
32
+
33
+ ### Step 1: Parse Arguments
34
+
35
+ Extract options from `$ARGUMENTS`:
36
+ - `--force` → FORCE_OVERWRITE=true
37
+ - `--no-hooks` → SKIP_HOOKS=true
38
+ - `--dry-run` → DRY_RUN=true
39
+ - `--lang=X` → LANG_OVERRIDE=X
40
+
41
+ ### Step 2: Detect Project Language
42
+
43
+ If LANG_OVERRIDE is set, use that. Otherwise, search from current directory for manifest files:
44
+
45
+ 1. Check for `package.json` → **Node**
46
+ 2. Check for `pyproject.toml` OR `setup.py` → **Python**
47
+ 3. Check for `Cargo.toml` → **Rust**
48
+ 4. None found → **Generic**
49
+
50
+ Store result in DETECTED_LANG variable.
51
+
52
+ ### Step 3: Check for `just` and Existing Justfile
53
+
54
+ **Pre-flight: Verify `just` is installed.**
55
+
56
+ ```
57
+ Run: command -v just
58
+
59
+ IF just is NOT found:
60
+ Print:
61
+ "`just` command runner is not installed. It is required to use the generated Justfile."
62
+ ""
63
+ "Install just using one of these methods:"
64
+ " curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin"
65
+ " brew install just # macOS/Linux (Homebrew)"
66
+ " cargo install just # Rust/Cargo"
67
+ " npm install -g rust-just # npm"
68
+ " apt install just # Debian/Ubuntu"
69
+ " pacman -S just # Arch"
70
+ ""
71
+ "See https://github.com/casey/just for all installation options."
72
+
73
+ Ask user: "Install just now using the install script, or skip Justfile generation?"
74
+ - If install: Run `curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin`
75
+ - If install succeeds: Continue
76
+ - If install fails: Print error and set SKIP_JUSTFILE=true
77
+ - If skip: Set SKIP_JUSTFILE=true
78
+ ```
79
+
80
+ **Check for existing Justfile:**
81
+
82
+ ```
83
+ IF Justfile exists AND NOT FORCE_OVERWRITE:
84
+ Print: "Justfile already exists. Use --force to overwrite (creates backup)."
85
+ Set SKIP_JUSTFILE=true
86
+ ELSE IF Justfile exists AND FORCE_OVERWRITE:
87
+ Create backup: Justfile.backup-{YYYYMMDD-HHMMSS}
88
+ Set SKIP_JUSTFILE=false
89
+ ELSE:
90
+ Set SKIP_JUSTFILE=false
91
+ ```
92
+
93
+ ### Step 4: Dry Run Check
94
+
95
+ If DRY_RUN is true, display preview and exit:
96
+
97
+ ```
98
+ ## Scaffold Preview (dry-run)
99
+
100
+ **Language detected:** {DETECTED_LANG} ({manifest file or "no manifest"})
101
+
102
+ **Would create:**
103
+ - Justfile (from lib/templates/justfile-{DETECTED_LANG}.just)
104
+ - logs/
105
+ - logs/diagnostics/
106
+ - logs/validations/
107
+ - logs/debug-reports/
108
+ {IF NOT SKIP_HOOKS}
109
+ - .claude/settings.json (hooks configuration)
110
+ - .claude/skills/governance-protocol/SKILL.md
111
+ - scripts/hooks/inject-protocol.sh
112
+ - scripts/hooks/enforce-quality.sh
113
+ - scripts/hooks/suggest-pipeline.sh
114
+ {ENDIF}
115
+
116
+ **Would update:**
117
+ - .gitignore (add Bulwark patterns)
118
+
119
+ Run without --dry-run to apply changes.
120
+ ```
121
+
122
+ Then STOP execution.
123
+
124
+ ### Step 5: Generate Justfile
125
+
126
+ If NOT SKIP_JUSTFILE:
127
+
128
+ 1. Locate template: `${CLAUDE_PLUGIN_ROOT}/lib/templates/justfile-{DETECTED_LANG}.just`
129
+ - For local development: `${CLAUDE_PROJECT_DIR}/lib/templates/justfile-{DETECTED_LANG}.just`
130
+ 2. Copy template content to `Justfile` in project root
131
+
132
+ ### Step 6: Create logs/ Directory Structure
133
+
134
+ ```bash
135
+ mkdir -p logs/diagnostics logs/validations logs/debug-reports
136
+ touch logs/.gitkeep logs/diagnostics/.gitkeep logs/validations/.gitkeep logs/debug-reports/.gitkeep
137
+ ```
138
+
139
+ ### Step 7: Update .gitignore
140
+
141
+ Check if `.gitignore` exists and contains `# Bulwark logs` marker:
142
+ - If marker exists: Skip (already configured)
143
+ - If marker does not exist: Append the following patterns
144
+
145
+ **Patterns to add:**
146
+ ```gitignore
147
+
148
+ # Bulwark logs
149
+ logs/*.yaml
150
+ logs/*.log
151
+ logs/diagnostics/*.yaml
152
+ logs/validations/*.yaml
153
+ logs/debug-reports/*.yaml
154
+ !logs/.gitkeep
155
+ !logs/*/.gitkeep
156
+ ```
157
+
158
+ ### Step 8: Generate Hook Configuration (Default)
159
+
160
+ UNLESS SKIP_HOOKS is true:
161
+
162
+ **Pre-flight: Check for existing Bulwark hooks to prevent duplication.**
163
+
164
+ Plugin hooks (`hooks/hooks.json`) and settings hooks (`.claude/settings.json`) both fire at runtime. If hooks already exist in any location, adding them again causes double execution.
165
+
166
+ **Check these locations for existing Bulwark hooks** (search for `enforce-quality` or `inject-protocol`):
167
+
168
+ | Location | Scope | Notes |
169
+ |----------|-------|-------|
170
+ | `./hooks/hooks.json` | Project plugin | Bulwark installed as project-level plugin |
171
+ | `~/.claude/plugins/*/hooks/hooks.json` | User plugin | Bulwark installed at user level via `/install` |
172
+ | `.claude/settings.json` | Project settings | Previously scaffolded |
173
+ | `.claude/settings.local.json` | Project local | User-specific project overrides |
174
+ | `~/.claude/settings.json` | User settings | Global user hooks |
175
+ | `~/.claude/settings.local.json` | User local | Global user overrides |
176
+
177
+ ```
178
+ HOOKS_FOUND_IN = []
179
+
180
+ FOR each location above:
181
+ IF file exists AND contains "enforce-quality" OR "inject-protocol":
182
+ Append location to HOOKS_FOUND_IN
183
+
184
+ IF HOOKS_FOUND_IN is not empty:
185
+ Print: "Bulwark hooks already present in: {HOOKS_FOUND_IN}. Skipping hook generation to prevent duplication."
186
+ Set SKIP_HOOKS=true
187
+ ```
188
+
189
+ **If no existing hooks found**, proceed with hook generation:
190
+
191
+ Check if `.claude/settings.json` exists:
192
+ - If exists: Merge hooks into existing configuration (preserve other settings)
193
+ - If not exists: Create new file
194
+
195
+ **Hook configuration to add:**
196
+ ```json
197
+ {
198
+ "hooks": {
199
+ "SessionStart": [
200
+ {
201
+ "hooks": [
202
+ {
203
+ "type": "command",
204
+ "command": "${CLAUDE_PROJECT_DIR}/scripts/hooks/inject-protocol.sh",
205
+ "timeout": 5
206
+ }
207
+ ]
208
+ }
209
+ ],
210
+ "PostToolUse": [
211
+ {
212
+ "matcher": "Write|Edit",
213
+ "hooks": [
214
+ {
215
+ "type": "command",
216
+ "command": "${CLAUDE_PROJECT_DIR}/scripts/hooks/enforce-quality.sh",
217
+ "timeout": 60
218
+ }
219
+ ]
220
+ }
221
+ ]
222
+ }
223
+ }
224
+ ```
225
+
226
+ **Note:** SessionStart has no matcher, so it fires for all session events (start, resume, clear, compact).
227
+
228
+ **Also copy required files** (only if hooks were generated above):
229
+ 1. Copy `scripts/hooks/inject-protocol.sh` to `${CLAUDE_PROJECT_DIR}/scripts/hooks/`
230
+ 2. Copy `scripts/hooks/enforce-quality.sh` to `${CLAUDE_PROJECT_DIR}/scripts/hooks/`
231
+ 3. Copy `scripts/hooks/suggest-pipeline.sh` to `${CLAUDE_PROJECT_DIR}/scripts/hooks/`
232
+ 4. Copy `skills/governance-protocol/SKILL.md` to `${CLAUDE_PROJECT_DIR}/.claude/skills/governance-protocol/SKILL.md`
233
+
234
+ Create parent directories as needed (`mkdir -p`).
235
+
236
+ ### Step 9: Write Scaffold Log
237
+
238
+ Write to `logs/scaffold-{YYYYMMDD-HHMMSS}.yaml`:
239
+
240
+ ```yaml
241
+ metadata:
242
+ timestamp: {ISO-8601}
243
+ action: scaffold
244
+ invocation: "/bulwark-scaffold {args}"
245
+
246
+ detection:
247
+ language: {DETECTED_LANG}
248
+ manifest: {manifest path or null}
249
+ override: {LANG_OVERRIDE or null}
250
+
251
+ actions:
252
+ justfile:
253
+ action: created|skipped|overwritten
254
+ backup: {backup path or null}
255
+ template: lib/templates/justfile-{DETECTED_LANG}.just
256
+ logs_directory:
257
+ created: true
258
+ subdirectories: [diagnostics, validations, debug-reports]
259
+ gitignore:
260
+ action: created|updated|skipped
261
+ patterns_added: 7
262
+ hooks:
263
+ action: created|merged|skipped
264
+ path: .claude/settings.json
265
+ skipped_reason: {reason if skipped}
266
+
267
+ summary: |
268
+ Scaffold complete for {DETECTED_LANG} project.
269
+ ```
270
+
271
+ ### Step 10: Report Results
272
+
273
+ Present summary to user:
274
+
275
+ ```
276
+ ## Scaffold Complete
277
+
278
+ **Language:** {DETECTED_LANG}
279
+ **Justfile:** {created|skipped|overwritten (backup: path)}
280
+ **logs/:** Created with subdirectories (diagnostics, validations, debug-reports)
281
+ **.gitignore:** {updated|created|unchanged}
282
+ **Hooks:** {created|merged|skipped (--no-hooks)}
283
+ **Governance:** {installed|skipped} - Protocol injected at session start
284
+
285
+ Run `just` to see available recipes:
286
+ - `just typecheck` - Run type checker
287
+ - `just lint` - Run linter
288
+ - `just build` - Build project
289
+ - `just test` - Run tests
290
+ - `just ci` - Run all quality checks
291
+ - `just fix` - Auto-fix issues
292
+ ```
293
+
294
+ ---
295
+
296
+ ## Error Handling
297
+
298
+ | Scenario | Action |
299
+ |----------|--------|
300
+ | Cannot detect language | Print: "Could not detect language. Use --lang=node\|python\|rust\|generic" |
301
+ | Template file missing | Print: "Template not found at {path}. Bulwark installation may be corrupted." |
302
+ | Cannot create logs/ | Print: "Cannot create logs/ directory. Check permissions." |
303
+ | .gitignore write fails | Print warning, continue with other operations |
304
+ | Justfile backup fails | Print error, abort Justfile generation |
305
+
306
+ ---
307
+
308
+ ## Diagnostic Output
309
+
310
+ Write diagnostic log to `logs/diagnostics/bulwark-scaffold-{timestamp}.yaml`:
311
+
312
+ ```yaml
313
+ skill: bulwark-scaffold
314
+ timestamp: {ISO-8601}
315
+ invocation: "{full command}"
316
+ inputs:
317
+ force: {true|false}
318
+ no_hooks: {true|false}
319
+ dry_run: {true|false}
320
+ lang_override: {value or null}
321
+ detection:
322
+ language: {detected}
323
+ manifest_path: {path or null}
324
+ outputs:
325
+ justfile_created: {true|false}
326
+ logs_created: {true|false}
327
+ gitignore_updated: {true|false}
328
+ hooks_configured: {true|false}
329
+ errors: []
330
+ ```
@@ -0,0 +1,161 @@
1
+ ---
2
+ name: bulwark-statusline
3
+ description: Configure the Bulwark status line for Claude Code. Supports init, preset switching, and customization.
4
+ user-invocable: true
5
+ tools:
6
+ - Bash
7
+ - Read
8
+ - Edit
9
+ ---
10
+
11
+ # Bulwark Status Line
12
+
13
+ Configure the Bulwark multi-line status line for Claude Code.
14
+
15
+ ---
16
+
17
+ ## When to Use
18
+
19
+ Use this skill when:
20
+ - Setting up the Bulwark status line for the first time (`init`)
21
+ - Switching between status line presets (`minimal`, `developer`, `cost`)
22
+ - User asks to configure or customize the status line display
23
+
24
+ ---
25
+
26
+ ## Invocation
27
+
28
+ This skill can be invoked two ways:
29
+
30
+ | Method | Example |
31
+ |--------|---------|
32
+ | **Command** | `/bulwark-statusline minimal` |
33
+ | **Conversational** | "Change my status line to minimal" |
34
+
35
+ When invoked, **you (Claude) execute the steps** using the tools declared above (Bash, Read, Edit).
36
+
37
+ ---
38
+
39
+ ## Usage
40
+
41
+ ```
42
+ /bulwark-statusline init # Install with default (developer) preset
43
+ /bulwark-statusline minimal # Switch to minimal preset (1 line)
44
+ /bulwark-statusline developer # Switch to developer preset (3 lines)
45
+ /bulwark-statusline cost # Switch to cost preset (2 lines)
46
+ ```
47
+
48
+ ### Argument Handling
49
+
50
+ The subcommand is passed via `$1`:
51
+
52
+ ```
53
+ /bulwark-statusline init
54
+ ^^^^
55
+ $1 = "init"
56
+ ```
57
+
58
+ Parse `$1` and execute the corresponding subcommand below.
59
+
60
+ ---
61
+
62
+ ## Subcommand: init
63
+
64
+ Install the Bulwark status line for first-time setup.
65
+
66
+ **Execute these steps:**
67
+
68
+ 1. **Bash**: Create config directory
69
+ ```bash
70
+ mkdir -p ~/.bulwark
71
+ ```
72
+
73
+ 2. **Bash**: Copy default config template
74
+ ```bash
75
+ cp "${CLAUDE_PROJECT_DIR}/skills/bulwark-statusline/templates/statusline-default.yaml" ~/.bulwark/statusline.yaml
76
+ ```
77
+
78
+ 3. **Spawn statusline-setup agent** to update settings.json:
79
+ ```
80
+ Task(subagent_type="statusline-setup", prompt="
81
+ GOAL: Add statusLine configuration to .claude/settings.json
82
+ TARGET: .claude/settings.json (project level)
83
+
84
+ EXACT JSON to add at top level of settings.json:
85
+ {
86
+ \"statusLine\": {
87
+ \"type\": \"command\",
88
+ \"command\": \"${CLAUDE_PROJECT_DIR}/skills/bulwark-statusline/scripts/statusline.sh\"
89
+ }
90
+ }
91
+
92
+ If .claude/settings.json does not exist, create it with just this content.
93
+ If it exists, merge the statusLine key into the existing JSON, preserving all other keys.
94
+ ")
95
+ ```
96
+
97
+ 4. **Display to user**: "Status line installed. Restart session to activate."
98
+
99
+ ---
100
+
101
+ ## Subcommand: minimal
102
+
103
+ Switch to minimal preset (single line: model + gauge + tokens).
104
+
105
+ **Execute these steps:**
106
+
107
+ 1. **Read**: `~/.bulwark/statusline.yaml`
108
+ 2. **Edit**: Change `preset:` value to `minimal`
109
+ 3. **Display to user**: "Switched to minimal preset."
110
+
111
+ ---
112
+
113
+ ## Subcommand: developer
114
+
115
+ Switch to developer preset (3 lines).
116
+
117
+ **Lines displayed:**
118
+ - Line 1: Model + gauge + tokens
119
+ - Line 2: Last modified file
120
+ - Line 3: Git branch + pending count
121
+
122
+ **Execute these steps:**
123
+
124
+ 1. **Read**: `~/.bulwark/statusline.yaml`
125
+ 2. **Edit**: Change `preset:` value to `developer`
126
+ 3. **Display to user**: "Switched to developer preset."
127
+
128
+ ---
129
+
130
+ ## Subcommand: cost
131
+
132
+ Switch to cost preset (2 lines).
133
+
134
+ **Lines displayed:**
135
+ - Line 1: Model + gauge + tokens + cost
136
+ - Line 2: Duration
137
+
138
+ **Execute these steps:**
139
+
140
+ 1. **Read**: `~/.bulwark/statusline.yaml`
141
+ 2. **Edit**: Change `preset:` value to `cost`
142
+ 3. **Display to user**: "Switched to cost preset."
143
+
144
+ ---
145
+
146
+ ## File Locations
147
+
148
+ | File | Purpose |
149
+ |------|---------|
150
+ | `~/.bulwark/statusline.yaml` | User config (presets, colors) |
151
+ | `skills/bulwark-statusline/scripts/statusline.sh` | Main script (bundled with skill) |
152
+ | `skills/bulwark-statusline/templates/statusline-default.yaml` | Default config template |
153
+
154
+ ---
155
+
156
+ ## Notes
157
+
158
+ - Status line updates automatically on each interaction
159
+ - Multi-line output is supported
160
+ - Colors use RGB escape codes for exact hex values
161
+ - Gauge and percentage colors match threshold (green/yellow/coral)
@@ -0,0 +1,144 @@
1
+ #!/bin/bash
2
+ # Bulwark Status Line for Claude Code
3
+ # Displays multi-line status with context gauge, model info, and git status
4
+
5
+ set -euo pipefail
6
+
7
+ # === Color Definitions (RGB for exact hex colors) ===
8
+ # Foreground: \033[38;2;R;G;Bm Background: \033[48;2;R;G;Bm
9
+ RESET='\033[0m'
10
+
11
+ # Gauge colors
12
+ GAUGE_LOW='\033[38;2;175;255;175m' # #AFFFAF pastel green
13
+ GAUGE_MID='\033[38;2;255;244;176m' # #FFF4B0 pastel yellow
14
+ GAUGE_HIGH='\033[38;2;255;154;150m' # #FF9A96 pastel coral
15
+ GAUGE_EMPTY='\033[38;2;88;88;88m' # #585858 dim gray
16
+
17
+ # Model background colors (with dark foreground for contrast)
18
+ MODEL_FG='\033[38;2;30;30;30m' # Dark text on pastel bg
19
+ MODEL_OPUS='\033[48;2;196;173;237m' # #C4ADED soft purple
20
+ MODEL_SONNET='\033[48;2;172;213;243m' # #ACD5F3 soft blue
21
+ MODEL_HAIKU='\033[48;2;172;239;214m' # #ACEFD6 soft teal
22
+
23
+ # Segment colors
24
+ LABEL='\033[38;2;138;138;138m' # #8A8A8A medium gray
25
+ FILE_PATH='\033[38;2;255;215;175m' # #FFD7AF pastel peach
26
+ GIT_BRANCH='\033[38;2;135;215;255m' # #87D7FF pastel cyan
27
+
28
+ # === Read JSON from stdin ===
29
+ INPUT=$(cat)
30
+
31
+ # === Parse JSON with jq ===
32
+ MODEL=$(echo "$INPUT" | jq -r '.model.display_name // "Unknown"')
33
+ PERCENT=$(echo "$INPUT" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
34
+ CONTEXT_SIZE=$(echo "$INPUT" | jq -r '.context_window.context_window_size // 200000')
35
+ # Calculate tokens from percentage (total_input/output_tokens includes sub-agents)
36
+ PERCENT_RAW=$(echo "$INPUT" | jq -r '.context_window.used_percentage // 0')
37
+ COST=$(echo "$INPUT" | jq -r '.cost.total_cost_usd // 0')
38
+ CWD=$(echo "$INPUT" | jq -r '.workspace.current_dir // ""')
39
+
40
+ # === Calculate tokens from percentage ===
41
+ # tokens_used = (percentage / 100) * context_window_size
42
+ TOTAL_TOKENS=$(echo "$PERCENT_RAW $CONTEXT_SIZE" | awk '{printf "%.0f", ($1 / 100) * $2}')
43
+
44
+ # Format tokens (K/M suffix)
45
+ format_tokens() {
46
+ local tokens=$1
47
+ if [ "$tokens" -ge 1000000 ]; then
48
+ echo "$((tokens / 1000000))M"
49
+ elif [ "$tokens" -ge 1000 ]; then
50
+ echo "$((tokens / 1000))K"
51
+ else
52
+ echo "$tokens"
53
+ fi
54
+ }
55
+
56
+ TOKENS_USED=$(format_tokens $TOTAL_TOKENS)
57
+ TOKENS_MAX=$(format_tokens $CONTEXT_SIZE)
58
+
59
+ # Format cost
60
+ COST_FMT=$(printf "\$%.2f" "$COST")
61
+
62
+ # === Build gauge ===
63
+ GAUGE_WIDTH=10
64
+ FILLED=$((PERCENT * GAUGE_WIDTH / 100))
65
+ [ "$FILLED" -gt "$GAUGE_WIDTH" ] && FILLED=$GAUGE_WIDTH
66
+ EMPTY=$((GAUGE_WIDTH - FILLED))
67
+
68
+ # Select gauge color based on threshold
69
+ if [ "$PERCENT" -lt 60 ]; then
70
+ GAUGE_COLOR="$GAUGE_LOW"
71
+ elif [ "$PERCENT" -lt 70 ]; then
72
+ GAUGE_COLOR="$GAUGE_MID"
73
+ else
74
+ GAUGE_COLOR="$GAUGE_HIGH"
75
+ fi
76
+
77
+ # Build gauge string
78
+ GAUGE=""
79
+ for ((i=0; i<FILLED; i++)); do
80
+ GAUGE="${GAUGE}▰"
81
+ done
82
+ GAUGE_EMPTY_STR=""
83
+ for ((i=0; i<EMPTY; i++)); do
84
+ GAUGE_EMPTY_STR="${GAUGE_EMPTY_STR}▱"
85
+ done
86
+
87
+ # === Select model background color ===
88
+ case "$MODEL" in
89
+ *Opus*|*opus*)
90
+ MODEL_BG="$MODEL_OPUS"
91
+ ;;
92
+ *Sonnet*|*sonnet*)
93
+ MODEL_BG="$MODEL_SONNET"
94
+ ;;
95
+ *Haiku*|*haiku*)
96
+ MODEL_BG="$MODEL_HAIKU"
97
+ ;;
98
+ *)
99
+ MODEL_BG="$MODEL_SONNET" # Default to Sonnet color
100
+ ;;
101
+ esac
102
+
103
+ # === Get git info ===
104
+ GIT_REPO=""
105
+ GIT_BRANCH_NAME=""
106
+ GIT_PENDING=0
107
+
108
+ if [ -n "$CWD" ] && [ -d "$CWD" ]; then
109
+ cd "$CWD" 2>/dev/null || true
110
+ if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
111
+ GIT_REPO=$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "")
112
+ GIT_BRANCH_NAME=$(git branch --show-current 2>/dev/null || echo "")
113
+ GIT_PENDING=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
114
+ fi
115
+ fi
116
+
117
+ # === Get last modified file (most recent by mtime) ===
118
+ LAST_FILE=""
119
+ if [ -n "$CWD" ] && [ -d "$CWD" ]; then
120
+ cd "$CWD" 2>/dev/null || true
121
+ # Combine: modified tracked files + untracked files, sort by mtime
122
+ LAST_FILE=$( (git diff --name-only HEAD 2>/dev/null; git ls-files --others --exclude-standard 2>/dev/null) | \
123
+ xargs -I{} sh -c '[ -f "{}" ] && stat --format="%Y %n" "{}"' 2>/dev/null | \
124
+ sort -rn | head -1 | cut -d' ' -f2- || true)
125
+ fi
126
+
127
+ # === Output Lines ===
128
+
129
+ # Line 1: Model + Gauge + Tokens (percentage matches gauge color)
130
+ echo -e "${MODEL_BG}${MODEL_FG} ${MODEL} ${RESET} ${GAUGE_COLOR}${GAUGE}${RESET}${GAUGE_EMPTY}${GAUGE_EMPTY_STR}${RESET} ${GAUGE_COLOR}${PERCENT}%${RESET} (${TOKENS_USED}/${TOKENS_MAX})"
131
+
132
+ # Line 2: Last file (if available)
133
+ if [ -n "$LAST_FILE" ]; then
134
+ echo -e "${LABEL}Last file:${RESET} ${FILE_PATH}${LAST_FILE}${RESET}"
135
+ fi
136
+
137
+ # Line 3: Git info (if available)
138
+ if [ -n "$GIT_REPO" ] && [ -n "$GIT_BRANCH_NAME" ]; then
139
+ PENDING_TEXT=""
140
+ if [ "$GIT_PENDING" -gt 0 ]; then
141
+ PENDING_TEXT=" ${LABEL}(${GIT_PENDING} files pending)${RESET}"
142
+ fi
143
+ echo -e "${LABEL}Git:${RESET} ${GIT_BRANCH}${GIT_REPO}/${GIT_BRANCH_NAME}${RESET}${PENDING_TEXT}"
144
+ fi