@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.
- package/.claude-plugin/plugin.json +43 -0
- package/agents/bulwark-fix-validator.md +633 -0
- package/agents/bulwark-implementer.md +391 -0
- package/agents/bulwark-issue-analyzer.md +308 -0
- package/agents/bulwark-standards-reviewer.md +221 -0
- package/agents/plan-creation-architect.md +323 -0
- package/agents/plan-creation-eng-lead.md +352 -0
- package/agents/plan-creation-po.md +300 -0
- package/agents/plan-creation-qa-critic.md +334 -0
- package/agents/product-ideation-competitive-analyzer.md +298 -0
- package/agents/product-ideation-idea-validator.md +268 -0
- package/agents/product-ideation-market-researcher.md +292 -0
- package/agents/product-ideation-pattern-documenter.md +308 -0
- package/agents/product-ideation-segment-analyzer.md +303 -0
- package/agents/product-ideation-strategist.md +259 -0
- package/agents/statusline-setup.md +97 -0
- package/hooks/hooks.json +59 -0
- package/package.json +45 -0
- package/scripts/hooks/cleanup-stale.sh +13 -0
- package/scripts/hooks/enforce-quality.sh +166 -0
- package/scripts/hooks/implementer-quality.sh +256 -0
- package/scripts/hooks/inject-protocol.sh +52 -0
- package/scripts/hooks/suggest-pipeline.sh +175 -0
- package/scripts/hooks/track-pipeline-start.sh +37 -0
- package/scripts/hooks/track-pipeline-stop.sh +52 -0
- package/scripts/init-rules.sh +35 -0
- package/scripts/init.sh +151 -0
- package/skills/anthropic-validator/SKILL.md +607 -0
- package/skills/anthropic-validator/references/agents-checklist.md +131 -0
- package/skills/anthropic-validator/references/commands-checklist.md +102 -0
- package/skills/anthropic-validator/references/hooks-checklist.md +151 -0
- package/skills/anthropic-validator/references/mcp-checklist.md +136 -0
- package/skills/anthropic-validator/references/plugins-checklist.md +148 -0
- package/skills/anthropic-validator/references/skills-checklist.md +85 -0
- package/skills/assertion-patterns/SKILL.md +296 -0
- package/skills/bug-magnet-data/SKILL.md +284 -0
- package/skills/bug-magnet-data/context/cli-args.md +91 -0
- package/skills/bug-magnet-data/context/db-query.md +104 -0
- package/skills/bug-magnet-data/context/file-contents.md +103 -0
- package/skills/bug-magnet-data/context/http-body.md +91 -0
- package/skills/bug-magnet-data/context/process-spawn.md +123 -0
- package/skills/bug-magnet-data/data/booleans/boundaries.yaml +143 -0
- package/skills/bug-magnet-data/data/collections/arrays.yaml +114 -0
- package/skills/bug-magnet-data/data/collections/objects.yaml +123 -0
- package/skills/bug-magnet-data/data/concurrency/race-conditions.yaml +118 -0
- package/skills/bug-magnet-data/data/concurrency/state-machines.yaml +115 -0
- package/skills/bug-magnet-data/data/dates/boundaries.yaml +137 -0
- package/skills/bug-magnet-data/data/dates/invalid.yaml +132 -0
- package/skills/bug-magnet-data/data/dates/timezone.yaml +118 -0
- package/skills/bug-magnet-data/data/encoding/charset.yaml +79 -0
- package/skills/bug-magnet-data/data/encoding/normalization.yaml +105 -0
- package/skills/bug-magnet-data/data/formats/email.yaml +154 -0
- package/skills/bug-magnet-data/data/formats/json.yaml +187 -0
- package/skills/bug-magnet-data/data/formats/url.yaml +165 -0
- package/skills/bug-magnet-data/data/language-specific/javascript.yaml +182 -0
- package/skills/bug-magnet-data/data/language-specific/python.yaml +174 -0
- package/skills/bug-magnet-data/data/language-specific/rust.yaml +148 -0
- package/skills/bug-magnet-data/data/numbers/boundaries.yaml +161 -0
- package/skills/bug-magnet-data/data/numbers/precision.yaml +89 -0
- package/skills/bug-magnet-data/data/numbers/special.yaml +69 -0
- package/skills/bug-magnet-data/data/strings/boundaries.yaml +109 -0
- package/skills/bug-magnet-data/data/strings/injection.yaml +208 -0
- package/skills/bug-magnet-data/data/strings/special-chars.yaml +190 -0
- package/skills/bug-magnet-data/data/strings/unicode.yaml +139 -0
- package/skills/bug-magnet-data/references/external-lists.md +115 -0
- package/skills/bulwark-brainstorm/SKILL.md +563 -0
- package/skills/bulwark-brainstorm/references/at-teammate-prompts.md +60 -0
- package/skills/bulwark-brainstorm/references/role-critical-analyst.md +78 -0
- package/skills/bulwark-brainstorm/references/role-development-lead.md +66 -0
- package/skills/bulwark-brainstorm/references/role-product-delivery-lead.md +79 -0
- package/skills/bulwark-brainstorm/references/role-product-manager.md +62 -0
- package/skills/bulwark-brainstorm/references/role-project-sme.md +59 -0
- package/skills/bulwark-brainstorm/references/role-technical-architect.md +66 -0
- package/skills/bulwark-research/SKILL.md +298 -0
- package/skills/bulwark-research/references/viewpoint-contrarian.md +63 -0
- package/skills/bulwark-research/references/viewpoint-direct-investigation.md +62 -0
- package/skills/bulwark-research/references/viewpoint-first-principles.md +65 -0
- package/skills/bulwark-research/references/viewpoint-practitioner.md +62 -0
- package/skills/bulwark-research/references/viewpoint-prior-art.md +66 -0
- package/skills/bulwark-scaffold/SKILL.md +330 -0
- package/skills/bulwark-statusline/SKILL.md +161 -0
- package/skills/bulwark-statusline/scripts/statusline.sh +144 -0
- package/skills/bulwark-verify/SKILL.md +519 -0
- package/skills/code-review/SKILL.md +428 -0
- package/skills/code-review/examples/anti-patterns/linting.ts +181 -0
- package/skills/code-review/examples/anti-patterns/security.ts +91 -0
- package/skills/code-review/examples/anti-patterns/standards.ts +195 -0
- package/skills/code-review/examples/anti-patterns/type-safety.ts +108 -0
- package/skills/code-review/examples/recommended/linting.ts +195 -0
- package/skills/code-review/examples/recommended/security.ts +154 -0
- package/skills/code-review/examples/recommended/standards.ts +231 -0
- package/skills/code-review/examples/recommended/type-safety.ts +181 -0
- package/skills/code-review/frameworks/angular.md +218 -0
- package/skills/code-review/frameworks/django.md +235 -0
- package/skills/code-review/frameworks/express.md +207 -0
- package/skills/code-review/frameworks/flask.md +298 -0
- package/skills/code-review/frameworks/generic.md +146 -0
- package/skills/code-review/frameworks/react.md +152 -0
- package/skills/code-review/frameworks/vue.md +244 -0
- package/skills/code-review/references/linting-patterns.md +221 -0
- package/skills/code-review/references/security-patterns.md +125 -0
- package/skills/code-review/references/standards-patterns.md +246 -0
- package/skills/code-review/references/type-safety-patterns.md +130 -0
- package/skills/component-patterns/SKILL.md +131 -0
- package/skills/component-patterns/references/pattern-cli-command.md +118 -0
- package/skills/component-patterns/references/pattern-database.md +166 -0
- package/skills/component-patterns/references/pattern-external-api.md +139 -0
- package/skills/component-patterns/references/pattern-file-parser.md +168 -0
- package/skills/component-patterns/references/pattern-http-server.md +162 -0
- package/skills/component-patterns/references/pattern-process-spawner.md +133 -0
- package/skills/continuous-feedback/SKILL.md +327 -0
- package/skills/continuous-feedback/references/collect-instructions.md +81 -0
- package/skills/continuous-feedback/references/specialize-code-review.md +82 -0
- package/skills/continuous-feedback/references/specialize-general.md +98 -0
- package/skills/continuous-feedback/references/specialize-test-audit.md +81 -0
- package/skills/create-skill/SKILL.md +359 -0
- package/skills/create-skill/references/agent-conventions.md +194 -0
- package/skills/create-skill/references/agent-template.md +195 -0
- package/skills/create-skill/references/content-guidance.md +291 -0
- package/skills/create-skill/references/decision-framework.md +124 -0
- package/skills/create-skill/references/template-pipeline.md +217 -0
- package/skills/create-skill/references/template-reference-heavy.md +111 -0
- package/skills/create-skill/references/template-research.md +210 -0
- package/skills/create-skill/references/template-script-driven.md +172 -0
- package/skills/create-skill/references/template-simple.md +80 -0
- package/skills/create-subagent/SKILL.md +353 -0
- package/skills/create-subagent/references/agent-conventions.md +268 -0
- package/skills/create-subagent/references/content-guidance.md +232 -0
- package/skills/create-subagent/references/decision-framework.md +134 -0
- package/skills/create-subagent/references/template-single-agent.md +192 -0
- package/skills/fix-bug/SKILL.md +241 -0
- package/skills/governance-protocol/SKILL.md +116 -0
- package/skills/init/SKILL.md +341 -0
- package/skills/issue-debugging/SKILL.md +385 -0
- package/skills/issue-debugging/references/anti-patterns.md +245 -0
- package/skills/issue-debugging/references/debug-report-schema.md +227 -0
- package/skills/mock-detection/SKILL.md +511 -0
- package/skills/mock-detection/references/false-positive-prevention.md +402 -0
- package/skills/mock-detection/references/stub-patterns.md +236 -0
- package/skills/pipeline-templates/SKILL.md +215 -0
- package/skills/pipeline-templates/references/code-change-workflow.md +277 -0
- package/skills/pipeline-templates/references/code-review.md +336 -0
- package/skills/pipeline-templates/references/fix-validation.md +421 -0
- package/skills/pipeline-templates/references/new-feature.md +335 -0
- package/skills/pipeline-templates/references/research-brainstorm.md +161 -0
- package/skills/pipeline-templates/references/research-planning.md +257 -0
- package/skills/pipeline-templates/references/test-audit.md +389 -0
- package/skills/pipeline-templates/references/test-execution-fix.md +238 -0
- package/skills/plan-creation/SKILL.md +497 -0
- package/skills/product-ideation/SKILL.md +372 -0
- package/skills/product-ideation/references/analysis-frameworks.md +161 -0
- package/skills/session-handoff/SKILL.md +139 -0
- package/skills/session-handoff/references/examples.md +223 -0
- package/skills/setup-lsp/SKILL.md +312 -0
- package/skills/setup-lsp/references/server-registry.md +85 -0
- package/skills/setup-lsp/references/troubleshooting.md +135 -0
- package/skills/subagent-output-templating/SKILL.md +415 -0
- package/skills/subagent-output-templating/references/examples.md +440 -0
- package/skills/subagent-prompting/SKILL.md +364 -0
- package/skills/subagent-prompting/references/examples.md +342 -0
- package/skills/test-audit/SKILL.md +531 -0
- package/skills/test-audit/references/known-limitations.md +41 -0
- package/skills/test-audit/references/priority-classification.md +30 -0
- package/skills/test-audit/references/prompts/deep-mode-detection.md +83 -0
- package/skills/test-audit/references/prompts/synthesis.md +57 -0
- package/skills/test-audit/references/rewrite-instructions.md +46 -0
- package/skills/test-audit/references/schemas/audit-output.yaml +100 -0
- package/skills/test-audit/references/schemas/diagnostic-output.yaml +49 -0
- package/skills/test-audit/scripts/data-flow-analyzer.ts +509 -0
- package/skills/test-audit/scripts/integration-mock-detector.ts +462 -0
- package/skills/test-audit/scripts/package.json +20 -0
- package/skills/test-audit/scripts/skip-detector.ts +211 -0
- package/skills/test-audit/scripts/verification-counter.ts +295 -0
- package/skills/test-classification/SKILL.md +310 -0
- 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
|