codeforge-dev 1.9.0 → 1.10.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/.devcontainer/.env +3 -0
- package/.devcontainer/CHANGELOG.md +56 -0
- package/.devcontainer/CLAUDE.md +29 -8
- package/.devcontainer/README.md +61 -2
- package/.devcontainer/config/defaults/main-system-prompt.md +162 -128
- package/.devcontainer/config/defaults/rules/spec-workflow.md +10 -2
- package/.devcontainer/connect-external-terminal.sh +17 -17
- package/.devcontainer/devcontainer.json +143 -144
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +4 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +3 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +21 -11
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +186 -13
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/spec-reminder.py +2 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/SKILL.md +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-check/SKILL.md +22 -10
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/SKILL.md +7 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/references/backlog-template.md +19 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/references/roadmap-template.md +28 -8
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/SKILL.md +15 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/references/template.md +24 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-refine/SKILL.md +194 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-update/SKILL.md +19 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +19 -12
- package/.devcontainer/scripts/check-setup.sh +24 -25
- package/.devcontainer/scripts/setup-aliases.sh +88 -76
- package/.devcontainer/scripts/setup-projects.sh +172 -131
- package/.devcontainer/scripts/setup-terminal.sh +48 -0
- package/.devcontainer/scripts/setup-update-claude.sh +49 -107
- package/.devcontainer/scripts/setup.sh +4 -17
- package/README.md +2 -2
- package/package.json +1 -1
package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-refine/SKILL.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-refine
|
|
3
|
+
description: >-
|
|
4
|
+
This skill should be used when the user asks to "refine a spec",
|
|
5
|
+
"review spec assumptions", "validate spec decisions", "question the
|
|
6
|
+
spec", "iterate on the spec", "check spec for assumptions", "approve
|
|
7
|
+
the spec", "walk me through the spec", or needs iterative
|
|
8
|
+
user-driven refinement of a specification through structured
|
|
9
|
+
questioning rounds.
|
|
10
|
+
version: 0.1.0
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Iterative Spec Refinement
|
|
14
|
+
|
|
15
|
+
## Mental Model
|
|
16
|
+
|
|
17
|
+
A draft spec is a hypothesis, not a commitment. Every requirement, tech decision, and scope boundary in a draft is an assumption until the user explicitly validates it. This skill systematically mines a spec for unvalidated assumptions, presents each to the user for review via structured questions, and iterates until every decision has explicit user approval.
|
|
18
|
+
|
|
19
|
+
No implementation begins on a spec with `**Approval:** draft`. This skill is the gate.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
24
|
+
|
|
25
|
+
### Step 1: Load & Inventory
|
|
26
|
+
|
|
27
|
+
Find the target spec:
|
|
28
|
+
- If `$ARGUMENTS` contains a path or feature name, use it directly
|
|
29
|
+
- Otherwise, glob `.specs/**/*.md` and ask the user which spec to refine
|
|
30
|
+
|
|
31
|
+
Read the full spec. Catalog:
|
|
32
|
+
- Every section and whether it has content
|
|
33
|
+
- The `**Approval:**` status (should be `draft`)
|
|
34
|
+
- All requirements and their current markers (`[assumed]` vs `[user-approved]`)
|
|
35
|
+
- The `## Open Questions` section (if any)
|
|
36
|
+
- The `## Resolved Questions` section (if any)
|
|
37
|
+
|
|
38
|
+
If the spec is already `**Approval:** user-approved` and all requirements are `[user-approved]`, report this and ask if the user wants to re-review anyway.
|
|
39
|
+
|
|
40
|
+
### Step 2: Assumption Mining
|
|
41
|
+
|
|
42
|
+
Scan each section systematically for unvalidated decisions. Look for:
|
|
43
|
+
|
|
44
|
+
| Category | What to look for |
|
|
45
|
+
|----------|-----------------|
|
|
46
|
+
| **Tech decisions** | Database choices, auth mechanisms, API formats, libraries, protocols |
|
|
47
|
+
| **Scope boundaries** | What's included/excluded without stated rationale |
|
|
48
|
+
| **Performance targets** | Numbers (response times, limits, thresholds) that were assumed |
|
|
49
|
+
| **Architecture choices** | Where logic lives, service boundaries, data flow patterns |
|
|
50
|
+
| **Behavioral defaults** | Error handling, retry logic, fallback behavior, timeout values |
|
|
51
|
+
| **Unstated dependencies** | Systems, services, or libraries the spec assumes exist |
|
|
52
|
+
| **Security assumptions** | Auth requirements, data sensitivity, access control patterns |
|
|
53
|
+
|
|
54
|
+
For each assumption found, prepare a question with 2-4 alternatives including the current assumption.
|
|
55
|
+
|
|
56
|
+
Present findings via `AskUserQuestion` in rounds of 1-4 questions. Group related assumptions together. Example:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Question: "Which authentication mechanism should this feature use?"
|
|
60
|
+
Options:
|
|
61
|
+
- JWT with refresh tokens (current assumption)
|
|
62
|
+
- Session cookies with httpOnly flag
|
|
63
|
+
- OAuth2 with external provider
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Record each answer. After the user responds, check: did any answer reveal new assumptions or contradictions? If yes, add follow-up questions to the queue.
|
|
67
|
+
|
|
68
|
+
### Step 3: Requirement Validation
|
|
69
|
+
|
|
70
|
+
Walk through every requirement tagged `[assumed]`:
|
|
71
|
+
|
|
72
|
+
1. **Read the requirement** aloud to the user (via the question text)
|
|
73
|
+
2. **Assess** — is it specific? testable? complete?
|
|
74
|
+
3. **Present via AskUserQuestion** with options:
|
|
75
|
+
- Approve as-is
|
|
76
|
+
- Needs revision (user provides direction via "Other")
|
|
77
|
+
- Remove (not needed)
|
|
78
|
+
- Defer to Open Questions (not decidable yet)
|
|
79
|
+
|
|
80
|
+
Process requirements in batches of 1-4 per question round. Prioritize:
|
|
81
|
+
- Requirements with the most ambiguity first
|
|
82
|
+
- Requirements that other requirements depend on
|
|
83
|
+
- Requirements involving tech decisions or external systems
|
|
84
|
+
|
|
85
|
+
For approved requirements, update the marker from `[assumed]` to `[user-approved]`.
|
|
86
|
+
For revised requirements, rewrite per user direction and mark `[user-approved]`.
|
|
87
|
+
For removed requirements, delete them.
|
|
88
|
+
For deferred requirements, move to `## Open Questions`.
|
|
89
|
+
|
|
90
|
+
### Step 4: Acceptance Criteria Review
|
|
91
|
+
|
|
92
|
+
For each acceptance criterion:
|
|
93
|
+
1. Is it measurable and testable?
|
|
94
|
+
2. Does it map to a specific requirement?
|
|
95
|
+
3. Are there requirements without corresponding criteria?
|
|
96
|
+
|
|
97
|
+
Present gaps to the user:
|
|
98
|
+
- Missing criteria for existing requirements
|
|
99
|
+
- Criteria that don't map to any requirement
|
|
100
|
+
- Criteria with vague or unmeasurable outcomes
|
|
101
|
+
|
|
102
|
+
Get approval on each criterion or batch of related criteria.
|
|
103
|
+
|
|
104
|
+
### Step 5: Scope & Dependency Audit
|
|
105
|
+
|
|
106
|
+
Review the spec from four perspectives:
|
|
107
|
+
|
|
108
|
+
**User perspective:**
|
|
109
|
+
- Does the feature solve the stated problem?
|
|
110
|
+
- Are there user needs not addressed?
|
|
111
|
+
- Is the scope too broad or too narrow?
|
|
112
|
+
|
|
113
|
+
**Developer perspective:**
|
|
114
|
+
- Is this implementable with the current architecture?
|
|
115
|
+
- Are the key files accurate?
|
|
116
|
+
- Are there missing technical constraints?
|
|
117
|
+
|
|
118
|
+
**Security perspective:**
|
|
119
|
+
- Are there data sensitivity issues?
|
|
120
|
+
- Is authentication/authorization addressed?
|
|
121
|
+
- Are there input validation gaps?
|
|
122
|
+
|
|
123
|
+
**Operations perspective:**
|
|
124
|
+
- Deployment considerations?
|
|
125
|
+
- Monitoring and observability needs?
|
|
126
|
+
- Rollback strategy needed?
|
|
127
|
+
|
|
128
|
+
Surface any missing items via `AskUserQuestion`. Get explicit decisions on scope boundaries and dependency completeness.
|
|
129
|
+
|
|
130
|
+
### Step 6: Final Approval
|
|
131
|
+
|
|
132
|
+
1. Present a summary of all changes made during refinement:
|
|
133
|
+
- Assumptions resolved (count)
|
|
134
|
+
- Requirements approved/revised/removed
|
|
135
|
+
- New criteria added
|
|
136
|
+
- Scope changes
|
|
137
|
+
|
|
138
|
+
2. Ask for final approval via `AskUserQuestion`:
|
|
139
|
+
- "Approve spec — all decisions validated, ready for implementation"
|
|
140
|
+
- "More refinement needed — specific concerns remain"
|
|
141
|
+
|
|
142
|
+
3. On approval:
|
|
143
|
+
- Set `**Approval:** user-approved`
|
|
144
|
+
- Update `**Last Updated:**` to today
|
|
145
|
+
- Verify all requirements are tagged `[user-approved]`
|
|
146
|
+
- Populate `## Resolved Questions` with the decision trail from this session
|
|
147
|
+
|
|
148
|
+
4. On "more refinement needed":
|
|
149
|
+
- Ask what concerns remain
|
|
150
|
+
- Loop back to the relevant phase
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Convergence Rules
|
|
155
|
+
|
|
156
|
+
- After each phase, check: did answers from this phase raise new questions? If yes, run another questioning round before advancing.
|
|
157
|
+
- The skill does NOT terminate until ALL of:
|
|
158
|
+
- Every `[assumed]` requirement is resolved (approved, revised, removed, or deferred)
|
|
159
|
+
- All acceptance criteria are reviewed
|
|
160
|
+
- The user gives explicit final approval
|
|
161
|
+
- If the user wants to stop early, leave `**Approval:** draft` and note remaining items in `## Open Questions`.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Resolved Questions Format
|
|
166
|
+
|
|
167
|
+
Each resolved question follows this format:
|
|
168
|
+
|
|
169
|
+
```markdown
|
|
170
|
+
1. **[Decision topic]** — [Chosen option] (user-approved, YYYY-MM-DD)
|
|
171
|
+
- Options considered: [list]
|
|
172
|
+
- Rationale: [brief user reasoning or context]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Keep entries concise — decision + options + rationale in 2-3 lines each.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Ambiguity Policy
|
|
180
|
+
|
|
181
|
+
- If the spec has no `**Approval:**` field, treat it as `draft` and add the field.
|
|
182
|
+
- If requirements lack `[assumed]`/`[user-approved]` tags, treat all as `[assumed]`.
|
|
183
|
+
- If the user says "approve everything" without reviewing individual items, warn that blanket approval defeats the purpose — offer to fast-track by presenting summaries of each batch.
|
|
184
|
+
- If the spec is very short (< 30 lines), the full 6-phase process may be unnecessary. Adapt: merge phases 2-4 into a single review pass. Still require explicit final approval.
|
|
185
|
+
- If the user provides a feature name that matches multiple specs, list them and ask which to refine.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Anti-Patterns
|
|
190
|
+
|
|
191
|
+
- **Rubber-stamping**: Presenting assumptions and immediately suggesting "approve all." Every assumption gets its own question with real alternatives.
|
|
192
|
+
- **Leading questions**: "Should we use JWT as planned?" is leading. Present alternatives neutrally: "Which auth mechanism should this feature use? Options: JWT, sessions, OAuth2."
|
|
193
|
+
- **Skipping phases**: Every phase surfaces different types of assumptions. Don't skip phases even if earlier phases had few findings.
|
|
194
|
+
- **Silent upgrades**: Never change `[assumed]` to `[user-approved]` without presenting the item to the user first.
|
package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-update/SKILL.md
CHANGED
|
@@ -18,6 +18,16 @@ This is not optional. Every implementation ends with a spec update.
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
## Approval Gate
|
|
22
|
+
|
|
23
|
+
Before performing an as-built update, check the spec's `**Approval:**` status:
|
|
24
|
+
- If `user-approved` → proceed with the update
|
|
25
|
+
- If `draft` → warn the user: "This spec is still `draft`. It should have gone through `/spec-refine` before implementation. Run `/spec-refine` now to validate, or proceed with the as-built update if the user confirms."
|
|
26
|
+
|
|
27
|
+
This is a warning, not a blocker — the user decides whether to refine first or update as-is.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
21
31
|
## The 6-Step Workflow
|
|
22
32
|
|
|
23
33
|
### Step 1: Find the Spec
|
|
@@ -72,6 +82,8 @@ Verify paths exist before listing them. Use absolute project-relative paths.
|
|
|
72
82
|
|
|
73
83
|
- Set `**Last Updated:**` to today's date (YYYY-MM-DD)
|
|
74
84
|
- Verify `**Version:**` is correct
|
|
85
|
+
- Preserve the `**Approval:**` status — do NOT downgrade `user-approved` to `draft`
|
|
86
|
+
- If the as-built update introduces new decisions not in the original spec, add them to `## Resolved Questions` if the user confirmed them, or `## Open Questions` if they were assumed during implementation
|
|
75
87
|
|
|
76
88
|
---
|
|
77
89
|
|
|
@@ -109,7 +121,10 @@ Before finishing the update:
|
|
|
109
121
|
- [ ] Implementation Notes document deviations from original spec
|
|
110
122
|
- [ ] File paths in Key Files are accurate and verified
|
|
111
123
|
- [ ] Last Updated date is today
|
|
112
|
-
- [ ]
|
|
124
|
+
- [ ] `**Approval:**` status is preserved (not downgraded)
|
|
125
|
+
- [ ] New implementation decisions are tracked in Resolved Questions or Open Questions
|
|
126
|
+
- [ ] If the spec has grown past ~200 lines, note it and suggest splitting in a future pass
|
|
127
|
+
- [ ] If `**Approval:**` is still `draft`, user was warned and confirmed proceeding
|
|
113
128
|
- [ ] No source code was pasted inline (references only)
|
|
114
129
|
|
|
115
130
|
---
|
|
@@ -122,3 +137,6 @@ Before finishing the update:
|
|
|
122
137
|
requirements to match what was built.
|
|
123
138
|
- If acceptance criteria are ambiguous about whether they're met, note the
|
|
124
139
|
ambiguity in Discrepancies rather than checking them off optimistically.
|
|
140
|
+
- A spec-reminder advisory hook fires at Stop when code was modified but
|
|
141
|
+
specs weren't updated. If you see "[Spec Reminder]" in context, that's
|
|
142
|
+
the trigger — use this skill to resolve it.
|
|
@@ -30,11 +30,11 @@ Write specifications with a hostile reader in mind -- someone who will interpret
|
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
## Spec Sizing
|
|
33
|
+
## Spec Sizing Guidelines
|
|
34
34
|
|
|
35
35
|
Specifications are loaded into AI context windows with limited capacity. Design for consumption.
|
|
36
36
|
|
|
37
|
-
**
|
|
37
|
+
**Recommended target:** ~200 lines per spec file. When a spec grows beyond that, consider splitting into sub-specs (one per sub-feature) with a concise overview linking them. Complex features may justify longer specs — completeness matters more than hitting a number.
|
|
38
38
|
|
|
39
39
|
**Reference, don't reproduce:** Never inline source code, SQL DDL, Pydantic models, or TypeScript interfaces. Reference the file path and line range instead. The code is the source of truth — duplicated snippets go stale silently.
|
|
40
40
|
|
|
@@ -179,9 +179,10 @@ Every spec file starts with metadata:
|
|
|
179
179
|
**Version:** v0.X.0
|
|
180
180
|
**Status:** implemented | partial | planned
|
|
181
181
|
**Last Updated:** YYYY-MM-DD
|
|
182
|
+
**Approval:** draft | user-approved
|
|
182
183
|
```
|
|
183
184
|
|
|
184
|
-
Status tells you whether to trust it, version tells you where it belongs, last-updated tells you when it was last verified.
|
|
185
|
+
Status tells you whether to trust it, version tells you where it belongs, last-updated tells you when it was last verified. Approval tells you whether decisions in the spec have been explicitly validated by the user (`user-approved`) or are AI-generated hypotheses (`draft`).
|
|
185
186
|
|
|
186
187
|
### 1. Problem Statement
|
|
187
188
|
What problem does this feature solve? Who has this problem? What's the cost of not solving it? (2-3 sentences)
|
|
@@ -218,20 +219,22 @@ so that [I can detect suspicious reset patterns].
|
|
|
218
219
|
Use EARS format. Number each requirement for traceability:
|
|
219
220
|
|
|
220
221
|
```markdown
|
|
221
|
-
- FR-1: When a user requests a password reset, the system shall send a reset email
|
|
222
|
+
- FR-1 [assumed]: When a user requests a password reset, the system shall send a reset email
|
|
222
223
|
to the registered email address within 60 seconds.
|
|
223
|
-
- FR-2: The reset link shall contain a cryptographically random token (min 32 bytes).
|
|
224
|
-
- FR-3: If the reset token is expired or already used, then the system shall display
|
|
224
|
+
- FR-2 [assumed]: The reset link shall contain a cryptographically random token (min 32 bytes).
|
|
225
|
+
- FR-3 [assumed]: If the reset token is expired or already used, then the system shall display
|
|
225
226
|
an error message and offer to send a new reset email.
|
|
227
|
+
|
|
228
|
+
Tag each requirement `[assumed]` when first written. Requirements become `[user-approved]` only after explicit user validation via `/spec-refine`.
|
|
226
229
|
```
|
|
227
230
|
|
|
228
231
|
### 5. Non-Functional Requirements
|
|
229
232
|
Performance, security, scalability, accessibility:
|
|
230
233
|
|
|
231
234
|
```markdown
|
|
232
|
-
- NFR-1: The password reset endpoint shall respond within 200ms (p95).
|
|
233
|
-
- NFR-2: Reset tokens shall be stored as bcrypt hashes, not plaintext.
|
|
234
|
-
- NFR-3: The reset flow shall be accessible with screen readers (WCAG 2.1 AA).
|
|
235
|
+
- NFR-1 [assumed]: The password reset endpoint shall respond within 200ms (p95).
|
|
236
|
+
- NFR-2 [assumed]: Reset tokens shall be stored as bcrypt hashes, not plaintext.
|
|
237
|
+
- NFR-3 [assumed]: The reset flow shall be accessible with screen readers (WCAG 2.1 AA).
|
|
235
238
|
```
|
|
236
239
|
|
|
237
240
|
### 6. Edge Cases
|
|
@@ -249,13 +252,16 @@ The cases nobody thinks about until they happen:
|
|
|
249
252
|
### 7. Out of Scope
|
|
250
253
|
Explicit non-goals to prevent scope creep (can reference the Scope section or expand here).
|
|
251
254
|
|
|
252
|
-
### 8.
|
|
255
|
+
### 8. Resolved Questions
|
|
256
|
+
Decisions explicitly approved by the user via `/spec-refine`. Each entry: decision topic, chosen option, options considered, date, brief rationale. This section starts empty and is populated during the refinement process.
|
|
257
|
+
|
|
258
|
+
### 9. Key Files
|
|
253
259
|
Source files most relevant to this feature — paths an implementer should read.
|
|
254
260
|
|
|
255
|
-
###
|
|
261
|
+
### 10. Implementation Notes
|
|
256
262
|
Post-implementation only. Capture deviations from the original spec — what changed and why.
|
|
257
263
|
|
|
258
|
-
###
|
|
264
|
+
### 11. Discrepancies
|
|
259
265
|
Gaps between spec intent and actual build. Prevents the next session from re-planning decided work.
|
|
260
266
|
|
|
261
267
|
---
|
|
@@ -309,6 +315,7 @@ These defaults apply when the user does not specify a preference. State the assu
|
|
|
309
315
|
- **Edge cases:** Always include at least: empty input, maximum input, concurrent access, and external service failure.
|
|
310
316
|
- **Out of scope:** Always include an out-of-scope section, even if brief, to establish boundaries.
|
|
311
317
|
- **Numbering:** Number all requirements (FR-1, NFR-1) for traceability in code reviews and tests.
|
|
318
|
+
- **Approval markers:** All requirements start as `[assumed]`. Only `/spec-refine` with explicit user validation upgrades them to `[user-approved]`. Spec-level `**Approval:**` starts as `draft` and becomes `user-approved` only when all requirements are `[user-approved]`.
|
|
312
319
|
|
|
313
320
|
---
|
|
314
321
|
|
|
@@ -5,34 +5,37 @@
|
|
|
5
5
|
echo "CodeForge Setup Check"
|
|
6
6
|
echo "━━━━━━━━━━━━━━━━━━━━"
|
|
7
7
|
|
|
8
|
-
PASS=0
|
|
8
|
+
PASS=0
|
|
9
|
+
FAIL=0
|
|
10
|
+
WARN=0
|
|
9
11
|
|
|
10
12
|
check() {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
local label="$1" cmd="$2"
|
|
14
|
+
if eval "$cmd" >/dev/null 2>&1; then
|
|
15
|
+
printf " ✓ %s\n" "$label"
|
|
16
|
+
PASS=$((PASS + 1))
|
|
17
|
+
else
|
|
18
|
+
printf " ✗ %s\n" "$label"
|
|
19
|
+
FAIL=$((FAIL + 1))
|
|
20
|
+
fi
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
warn_check() {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
local label="$1" cmd="$2"
|
|
25
|
+
if eval "$cmd" >/dev/null 2>&1; then
|
|
26
|
+
printf " ✓ %s\n" "$label"
|
|
27
|
+
PASS=$((PASS + 1))
|
|
28
|
+
else
|
|
29
|
+
printf " ⚠ %s\n" "$label"
|
|
30
|
+
WARN=$((WARN + 1))
|
|
31
|
+
fi
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
echo ""
|
|
33
35
|
echo "Core:"
|
|
34
36
|
check "Claude Code installed" "command -v claude"
|
|
35
|
-
|
|
37
|
+
warn_check "Claude native binary" "[ -x /usr/local/bin/claude ]"
|
|
38
|
+
check "cc alias configured" "grep -q 'alias cc=' ~/.bashrc 2>/dev/null || grep -q 'alias cc=' ~/.zshrc 2>/dev/null"
|
|
36
39
|
check "Config directory exists" "[ -d '${CLAUDE_CONFIG_DIR:-/workspaces/.claude}' ]"
|
|
37
40
|
check "Settings file exists" "[ -f '${CLAUDE_CONFIG_DIR:-/workspaces/.claude}/settings.json' ]"
|
|
38
41
|
|
|
@@ -54,10 +57,6 @@ echo ""
|
|
|
54
57
|
echo "Development:"
|
|
55
58
|
warn_check "biome" "command -v biome"
|
|
56
59
|
warn_check "ruff" "command -v ruff"
|
|
57
|
-
warn_check "dprint" "command -v dprint"
|
|
58
|
-
warn_check "shfmt" "command -v shfmt"
|
|
59
|
-
warn_check "shellcheck" "command -v shellcheck"
|
|
60
|
-
warn_check "hadolint" "command -v hadolint"
|
|
61
60
|
warn_check "ast-grep" "command -v ast-grep"
|
|
62
61
|
warn_check "tmux" "command -v tmux"
|
|
63
62
|
|
|
@@ -66,7 +65,7 @@ echo "━━━━━━━━━━━━━━━━━━━━"
|
|
|
66
65
|
echo " $PASS passed, $FAIL failed, $WARN warnings"
|
|
67
66
|
|
|
68
67
|
if [ $FAIL -gt 0 ]; then
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
echo ""
|
|
69
|
+
echo " Run 'cc-tools' for detailed version info."
|
|
70
|
+
exit 1
|
|
72
71
|
fi
|
|
@@ -6,82 +6,94 @@ CLAUDE_DIR="${CLAUDE_CONFIG_DIR:?CLAUDE_CONFIG_DIR not set}"
|
|
|
6
6
|
echo "[setup-aliases] Configuring Claude aliases..."
|
|
7
7
|
|
|
8
8
|
# Simple alias definitions (not functions — functions don't behave reliably across shell contexts)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
# Aliases reference $_CLAUDE_BIN which is resolved at shell startup to prefer the native binary.
|
|
10
|
+
ALIAS_CC='alias cc='"'"'CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 command "$_CLAUDE_BIN" --system-prompt-file "$CLAUDE_CONFIG_DIR/system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions'"'"''
|
|
11
|
+
ALIAS_CLAUDE='alias claude='"'"'CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 command "$_CLAUDE_BIN" --system-prompt-file "$CLAUDE_CONFIG_DIR/system-prompt.md" --permission-mode plan --allow-dangerously-skip-permissions'"'"''
|
|
12
|
+
ALIAS_CCRAW='alias ccraw='"'"'command "$_CLAUDE_BIN"'"'"''
|
|
12
13
|
|
|
13
14
|
for rc in ~/.bashrc ~/.zshrc; do
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
if [ -f "$rc" ]; then
|
|
16
|
+
# --- Backup before modifying ---
|
|
17
|
+
cp "$rc" "${rc}.bak.$(date +%s)" 2>/dev/null || true
|
|
18
|
+
# Clean old backups (keep last 3)
|
|
19
|
+
ls -t "${rc}.bak."* 2>/dev/null | tail -n +4 | xargs rm -f 2>/dev/null || true
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
# --- Cleanup old definitions ---
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
23
|
+
# Remove old cc alias
|
|
24
|
+
if grep -q "alias cc=" "$rc" 2>/dev/null; then
|
|
25
|
+
sed -i '/alias cc=/d' "$rc"
|
|
26
|
+
echo "[setup-aliases] Removed old cc alias from $(basename $rc)"
|
|
27
|
+
fi
|
|
28
|
+
# Remove old cc function (single-line or multi-line)
|
|
29
|
+
if grep -q "^cc()" "$rc" 2>/dev/null; then
|
|
30
|
+
sed -i '/^cc() {/,/^}/d' "$rc"
|
|
31
|
+
echo "[setup-aliases] Removed old cc function from $(basename $rc)"
|
|
32
|
+
fi
|
|
33
|
+
# Remove old _claude_with_config function
|
|
34
|
+
if grep -q "^_claude_with_config()" "$rc" 2>/dev/null; then
|
|
35
|
+
sed -i '/^_claude_with_config() {/,/^}/d' "$rc"
|
|
36
|
+
echo "[setup-aliases] Removed old _claude_with_config function from $(basename $rc)"
|
|
37
|
+
fi
|
|
38
|
+
# Remove old claude function override
|
|
39
|
+
if grep -q "^claude() {" "$rc" 2>/dev/null; then
|
|
40
|
+
sed -i '/^claude() { _claude_with_config/d' "$rc"
|
|
41
|
+
echo "[setup-aliases] Removed old claude function from $(basename $rc)"
|
|
42
|
+
fi
|
|
43
|
+
# Remove old claude alias
|
|
44
|
+
if grep -q "alias claude=" "$rc" 2>/dev/null; then
|
|
45
|
+
sed -i '/alias claude=/d' "$rc"
|
|
46
|
+
fi
|
|
47
|
+
# Remove old ccraw alias
|
|
48
|
+
if grep -q "alias ccraw=" "$rc" 2>/dev/null; then
|
|
49
|
+
sed -i '/alias ccraw=/d' "$rc"
|
|
50
|
+
fi
|
|
51
|
+
# Remove old specwright alias
|
|
52
|
+
if grep -q "alias specwright=" "$rc" 2>/dev/null; then
|
|
53
|
+
sed -i '/alias specwright=/d' "$rc"
|
|
54
|
+
fi
|
|
55
|
+
# Remove old cc-tools/check-setup functions
|
|
56
|
+
if grep -q "^cc-tools()" "$rc" 2>/dev/null; then
|
|
57
|
+
sed -i '/^cc-tools() {/,/^}/d' "$rc"
|
|
58
|
+
fi
|
|
59
|
+
if grep -q "alias check-setup=" "$rc" 2>/dev/null; then
|
|
60
|
+
sed -i '/alias check-setup=/d' "$rc"
|
|
61
|
+
fi
|
|
62
|
+
# --- Add environment and aliases (idempotent) ---
|
|
63
|
+
# Guard: skip if aliases already present from a previous run
|
|
64
|
+
if grep -q '# Claude Code environment and aliases' "$rc" 2>/dev/null; then
|
|
65
|
+
echo "[setup-aliases] Aliases already present in $(basename $rc), skipping"
|
|
66
|
+
continue
|
|
67
|
+
fi
|
|
68
|
+
echo "" >>"$rc"
|
|
69
|
+
echo "# Claude Code environment and aliases (managed by setup-aliases.sh)" >>"$rc"
|
|
70
|
+
# Export CLAUDE_CONFIG_DIR so it's available in all shells (not just VS Code remoteEnv)
|
|
71
|
+
if ! grep -q 'export CLAUDE_CONFIG_DIR=' "$rc" 2>/dev/null; then
|
|
72
|
+
echo "export CLAUDE_CONFIG_DIR=\"${CLAUDE_CONFIG_DIR}\"" >>"$rc"
|
|
73
|
+
fi
|
|
74
|
+
# Export UTF-8 locale so tmux renders Unicode correctly (docker exec doesn't inherit locale)
|
|
75
|
+
if ! grep -q 'export LANG=en_US.UTF-8' "$rc" 2>/dev/null; then
|
|
76
|
+
echo 'export LANG=en_US.UTF-8' >>"$rc"
|
|
77
|
+
echo 'export LC_ALL=en_US.UTF-8' >>"$rc"
|
|
78
|
+
fi
|
|
79
|
+
# Prefer native binary over npm-installed version
|
|
80
|
+
# 'claude install' puts the binary at ~/.local/bin/claude
|
|
81
|
+
# Legacy manual installs used /usr/local/bin/claude — check both
|
|
82
|
+
cat >>"$rc" <<'CLAUDEBIN_EOF'
|
|
83
|
+
if [ -x "$HOME/.local/bin/claude" ]; then
|
|
84
|
+
_CLAUDE_BIN="$HOME/.local/bin/claude"
|
|
85
|
+
elif [ -x /usr/local/bin/claude ]; then
|
|
86
|
+
_CLAUDE_BIN=/usr/local/bin/claude
|
|
87
|
+
else
|
|
88
|
+
_CLAUDE_BIN=claude
|
|
89
|
+
fi
|
|
90
|
+
CLAUDEBIN_EOF
|
|
91
|
+
echo "$ALIAS_CC" >>"$rc"
|
|
92
|
+
echo "$ALIAS_CLAUDE" >>"$rc"
|
|
93
|
+
echo "$ALIAS_CCRAW" >>"$rc"
|
|
61
94
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if grep -q '# Claude Code environment and aliases' "$rc" 2>/dev/null; then
|
|
65
|
-
echo "[setup-aliases] Aliases already present in $(basename $rc), skipping"
|
|
66
|
-
continue
|
|
67
|
-
fi
|
|
68
|
-
echo "" >> "$rc"
|
|
69
|
-
echo "# Claude Code environment and aliases (managed by setup-aliases.sh)" >> "$rc"
|
|
70
|
-
# Export CLAUDE_CONFIG_DIR so it's available in all shells (not just VS Code remoteEnv)
|
|
71
|
-
if ! grep -q 'export CLAUDE_CONFIG_DIR=' "$rc" 2>/dev/null; then
|
|
72
|
-
echo "export CLAUDE_CONFIG_DIR=\"${CLAUDE_CONFIG_DIR}\"" >> "$rc"
|
|
73
|
-
fi
|
|
74
|
-
# Export UTF-8 locale so tmux renders Unicode correctly (docker exec doesn't inherit locale)
|
|
75
|
-
if ! grep -q 'export LANG=en_US.UTF-8' "$rc" 2>/dev/null; then
|
|
76
|
-
echo 'export LANG=en_US.UTF-8' >> "$rc"
|
|
77
|
-
echo 'export LC_ALL=en_US.UTF-8' >> "$rc"
|
|
78
|
-
fi
|
|
79
|
-
echo "$ALIAS_CC" >> "$rc"
|
|
80
|
-
echo "$ALIAS_CLAUDE" >> "$rc"
|
|
81
|
-
echo "$ALIAS_CCRAW" >> "$rc"
|
|
82
|
-
|
|
83
|
-
# cc-tools: list all available CodeForge tools with version info
|
|
84
|
-
cat >> "$rc" << 'CCTOOLS_EOF'
|
|
95
|
+
# cc-tools: list all available CodeForge tools with version info
|
|
96
|
+
cat >>"$rc" <<'CCTOOLS_EOF'
|
|
85
97
|
cc-tools() {
|
|
86
98
|
echo "CodeForge Available Tools"
|
|
87
99
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
@@ -101,12 +113,12 @@ cc-tools() {
|
|
|
101
113
|
}
|
|
102
114
|
CCTOOLS_EOF
|
|
103
115
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
116
|
+
# check-setup: alias to the health check script
|
|
117
|
+
DEVCONTAINER_SCRIPTS="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
118
|
+
echo "alias check-setup='bash ${DEVCONTAINER_SCRIPTS}/check-setup.sh'" >>"$rc"
|
|
107
119
|
|
|
108
|
-
|
|
109
|
-
|
|
120
|
+
echo "[setup-aliases] Added aliases to $(basename $rc)"
|
|
121
|
+
fi
|
|
110
122
|
done
|
|
111
123
|
|
|
112
124
|
echo "[setup-aliases] Aliases configured:"
|