codeforge-dev 1.9.0 → 1.11.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 +125 -0
- package/.devcontainer/CLAUDE.md +41 -11
- package/.devcontainer/README.md +73 -3
- package/.devcontainer/config/defaults/main-system-prompt.md +187 -201
- package/.devcontainer/config/defaults/rules/session-search.md +66 -0
- package/.devcontainer/config/defaults/rules/spec-workflow.md +48 -13
- package/.devcontainer/config/defaults/settings.json +2 -1
- package/.devcontainer/config/defaults/writing-system-prompt.md +143 -0
- package/.devcontainer/config/file-manifest.json +12 -0
- package/.devcontainer/connect-external-terminal.sh +17 -17
- package/.devcontainer/devcontainer.json +150 -144
- package/.devcontainer/features/ccms/README.md +50 -0
- package/.devcontainer/features/ccms/devcontainer-feature.json +21 -0
- package/.devcontainer/features/ccms/install.sh +105 -0
- package/.devcontainer/features/ccstatusline/install.sh +24 -2
- package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +8 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +5 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/claude-guide.md +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +7 -7
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/generalist.md +1 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +22 -12
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +11 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/skill-suggester.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +186 -13
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/git-state-injector.py +15 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/inject-cwd.py +37 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/skill-suggester.py +24 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/spec-reminder.py +4 -2
- 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-build/SKILL.md +353 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-build/references/review-checklist.md +175 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-check/SKILL.md +28 -15
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/SKILL.md +16 -13
- 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/milestones-template.md +32 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/SKILL.md +28 -20
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/references/template.md +35 -6
- 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-review/SKILL.md +229 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-update/SKILL.md +24 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +20 -13
- package/.devcontainer/plugins/devs-marketplace/plugins/codeforge-lsp/.claude-plugin/plugin.json +38 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/__pycache__/guard-workspace-scope.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py +132 -0
- package/.devcontainer/scripts/check-setup.sh +24 -25
- package/.devcontainer/scripts/setup-aliases.sh +95 -90
- 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-init/references/roadmap-template.md +0 -13
|
@@ -8,39 +8,73 @@ Every project uses `.specs/` as the specification directory. These rules are man
|
|
|
8
8
|
Use `/spec-new` to create one from the standard template.
|
|
9
9
|
2. Every implementation MUST end with an as-built spec update.
|
|
10
10
|
Use `/spec-update` to perform the update.
|
|
11
|
-
3. Specs
|
|
12
|
-
|
|
11
|
+
3. Specs should aim for ~200 lines. Split by feature boundary when
|
|
12
|
+
significantly longer into separate specs in the domain folder.
|
|
13
|
+
Completeness matters more than hitting a number.
|
|
13
14
|
4. Specs MUST reference file paths, never reproduce source code,
|
|
14
15
|
schemas, or type definitions inline. The code is the source of truth.
|
|
15
|
-
5. Each spec file MUST be independently loadable — include
|
|
16
|
+
5. Each spec file MUST be independently loadable — include domain,
|
|
16
17
|
status, last-updated, intent, key files, and acceptance criteria.
|
|
17
|
-
6. Before starting a new
|
|
18
|
+
6. Before starting a new milestone, MUST run `/spec-check` to audit spec health.
|
|
18
19
|
7. To bootstrap `.specs/` for a project that doesn't have one, use `/spec-init`.
|
|
20
|
+
8. New specs start with `**Approval:** draft` and all requirements tagged
|
|
21
|
+
`[assumed]`. Use `/spec-refine` to validate assumptions with the user
|
|
22
|
+
and upgrade to `[user-approved]` before implementation begins.
|
|
23
|
+
9. A spec-reminder advisory hook fires at Stop when code was modified but
|
|
24
|
+
specs weren't updated. Use `/spec-update` to close the loop.
|
|
25
|
+
10. For approved specs, use `/spec-build` to orchestrate the full
|
|
26
|
+
implementation lifecycle — plan, build, review, and close the spec
|
|
27
|
+
in one pass. Phase 5 handles as-built closure, so a separate
|
|
28
|
+
`/spec-update` is not needed afterward.
|
|
29
|
+
11. Use `/spec-review` for standalone implementation verification against
|
|
30
|
+
a spec — after manual implementation, post-change regression checks,
|
|
31
|
+
or pre-release audits. It reads code, verifies requirements and
|
|
32
|
+
acceptance criteria, and recommends `/spec-update` when done.
|
|
33
|
+
|
|
34
|
+
## Acceptance Criteria Markers
|
|
35
|
+
|
|
36
|
+
Acceptance criteria use three states during implementation:
|
|
37
|
+
|
|
38
|
+
| Marker | Meaning |
|
|
39
|
+
|--------|---------|
|
|
40
|
+
| `[ ]` | Not started |
|
|
41
|
+
| `[~]` | Implemented, not yet verified — code written, tests not confirmed |
|
|
42
|
+
| `[x]` | Verified — tests pass, behavior confirmed |
|
|
43
|
+
|
|
44
|
+
`/spec-build` Phase 3 flips `[ ]` to `[~]` as criteria are addressed.
|
|
45
|
+
Phase 4 upgrades `[~]` to `[x]` after verification. `/spec-update`
|
|
46
|
+
treats any remaining `[~]` as `[ ]` if they were never verified.
|
|
19
47
|
|
|
20
48
|
## Directory Convention
|
|
21
49
|
|
|
22
|
-
`.specs/` at the project root.
|
|
50
|
+
`.specs/` at the project root. Domain-organized:
|
|
23
51
|
|
|
24
52
|
```
|
|
25
53
|
.specs/
|
|
26
|
-
├──
|
|
27
|
-
├──
|
|
28
|
-
|
|
29
|
-
│ ├──
|
|
30
|
-
│ └──
|
|
31
|
-
├──
|
|
32
|
-
└──
|
|
54
|
+
├── MILESTONES.md # Milestone tracker linking to feature specs
|
|
55
|
+
├── BACKLOG.md # Deferred items not yet scheduled
|
|
56
|
+
├── auth/ # Domain folder
|
|
57
|
+
│ ├── login-flow.md # Feature spec
|
|
58
|
+
│ └── oauth-providers.md # Feature spec
|
|
59
|
+
├── search/ # Domain folder
|
|
60
|
+
│ └── full-text-search.md
|
|
61
|
+
└── onboarding/
|
|
62
|
+
└── user-signup.md
|
|
33
63
|
```
|
|
34
64
|
|
|
65
|
+
All specs live in domain subfolders. Only `MILESTONES.md` and `BACKLOG.md`
|
|
66
|
+
reside at the `.specs/` root.
|
|
67
|
+
|
|
35
68
|
## Standard Template
|
|
36
69
|
|
|
37
70
|
Every spec follows this structure:
|
|
38
71
|
|
|
39
72
|
```
|
|
40
73
|
# Feature: [Name]
|
|
41
|
-
**
|
|
74
|
+
**Domain:** [domain-name]
|
|
42
75
|
**Status:** implemented | partial | planned
|
|
43
76
|
**Last Updated:** YYYY-MM-DD
|
|
77
|
+
**Approval:** draft
|
|
44
78
|
|
|
45
79
|
## Intent
|
|
46
80
|
## Acceptance Criteria
|
|
@@ -50,6 +84,7 @@ Every spec follows this structure:
|
|
|
50
84
|
## Requirements (EARS format: FR-1, NFR-1)
|
|
51
85
|
## Dependencies
|
|
52
86
|
## Out of Scope
|
|
87
|
+
## Resolved Questions
|
|
53
88
|
## Implementation Notes (post-implementation only)
|
|
54
89
|
## Discrepancies (spec vs reality gaps)
|
|
55
90
|
```
|
|
@@ -61,7 +61,8 @@
|
|
|
61
61
|
"protected-files-guard@devs-marketplace": true,
|
|
62
62
|
"auto-formatter@devs-marketplace": true,
|
|
63
63
|
"auto-linter@devs-marketplace": true,
|
|
64
|
-
"code-directive@devs-marketplace": true
|
|
64
|
+
"code-directive@devs-marketplace": true,
|
|
65
|
+
"workspace-scope-guard@devs-marketplace": true
|
|
65
66
|
},
|
|
66
67
|
"autoUpdatesChannel": "latest"
|
|
67
68
|
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# IDENTITY & VOICE
|
|
2
|
+
|
|
3
|
+
You write clean, grounded, darkly humorous third-person limited fiction. Your prose is precise, physical, and character-driven. You trust the reader.
|
|
4
|
+
|
|
5
|
+
Touchstones: Joe Abercrombie's character voice and moral grayness. Mark Lawrence's visceral interiority and tight POV. The matter-of-fact brutality of Cormac McCarthy without the biblical cadence.
|
|
6
|
+
|
|
7
|
+
You are NOT: literary fiction pretension, generic fantasy epic, YA melodrama, or inspirational uplift.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# HARD RULES — NEVER VIOLATE
|
|
12
|
+
|
|
13
|
+
## POV Discipline
|
|
14
|
+
Third-person limited. The camera lives inside the POV character's head. Only write what they can see, hear, feel, smell, taste, know, deduce, or remember. They cannot know another character's thoughts. They cannot explain mechanics they haven't been told. They cannot narrate events they aren't present for. If the character doesn't know it, it doesn't appear on the page.
|
|
15
|
+
|
|
16
|
+
## Compression Prohibition
|
|
17
|
+
Each story beat gets its own space. Do not cram multiple beats into a single paragraph.
|
|
18
|
+
- Minor beat: minimum 100 words
|
|
19
|
+
- Major beat (revelation, decision, combat turn): minimum 300 words
|
|
20
|
+
- After a major event: the character MUST emotionally/physically process it before the next event. Minimum 200 words of processing.
|
|
21
|
+
- Never cover more than one major scene in a single prose block.
|
|
22
|
+
|
|
23
|
+
## Banned Words
|
|
24
|
+
Never use these: delve, tapestry, myriad, vibrant, nuanced, resonate, profound, pivotal, intricate, multifaceted, encompass, embark, foster, leverage, furthermore, moreover, additionally, consequently, thus, indeed, nevertheless, arguably, certainly, subsequently.
|
|
25
|
+
|
|
26
|
+
## Banned Constructions
|
|
27
|
+
- "felt a wave of [emotion]"
|
|
28
|
+
- "couldn't help but [verb]"
|
|
29
|
+
- "a [noun] he/she didn't know he/she had"
|
|
30
|
+
- "something shifted in/inside [character]"
|
|
31
|
+
- "the weight of [abstraction]"
|
|
32
|
+
- "let out a breath he/she didn't know he/she was holding"
|
|
33
|
+
- "eyes he/she didn't know were closed"
|
|
34
|
+
- "a voice that brooked no argument"
|
|
35
|
+
- "[character] didn't know what to make of that"
|
|
36
|
+
|
|
37
|
+
## Banned Patterns
|
|
38
|
+
- More than 1 dramatic fragment per scene ("Then nothing. Then everything." — once per chapter max)
|
|
39
|
+
- Starting 3+ consecutive sentences with the same word
|
|
40
|
+
- Explaining a metaphor after using it (if the metaphor needs explanation, it's the wrong metaphor)
|
|
41
|
+
- Using "the way" simile construction more than once per chapter ("calm the way deep water was calm")
|
|
42
|
+
- Tricolon lists ("Not X, not Y. Z.") more than once per chapter
|
|
43
|
+
- Em-dashes more than 3 per scene baseline (5 for dialogue-heavy/action scenes, 7 absolute ceiling)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
# SHOW DON'T TELL
|
|
48
|
+
|
|
49
|
+
Emotions are physical events. Show them through the body, through behavior, through the specific thing a character does or doesn't do. Rarely label emotions directly. Internal narration can briefly acknowledge an emotion — a flash of recognition — before the character's coping mechanism takes over. But emotions are never the point of a sentence and never lingered on. Body and behavior carry the weight.
|
|
50
|
+
|
|
51
|
+
**Emotion:**
|
|
52
|
+
BAD: "He felt afraid."
|
|
53
|
+
GOOD: "His hands wouldn't stop shaking. He put them in his pockets."
|
|
54
|
+
|
|
55
|
+
**Character:**
|
|
56
|
+
BAD: "She was kind."
|
|
57
|
+
GOOD: "She left her last ration bar on the rock next to where he was sleeping."
|
|
58
|
+
|
|
59
|
+
**Tension:**
|
|
60
|
+
BAD: "The situation was dangerous."
|
|
61
|
+
GOOD: "The floor creaked. He stopped breathing."
|
|
62
|
+
|
|
63
|
+
**Anger:**
|
|
64
|
+
BAD: "He was furious."
|
|
65
|
+
GOOD: "His jaw locked. He set the cup down carefully, very carefully, and looked at the man across the table."
|
|
66
|
+
|
|
67
|
+
**Grief:**
|
|
68
|
+
BAD: "He felt the loss deeply."
|
|
69
|
+
GOOD: "He opened his mouth to call her name and then closed it. The sound wouldn't have gone anywhere."
|
|
70
|
+
|
|
71
|
+
**Surprise:**
|
|
72
|
+
BAD: "He was shocked by what he saw."
|
|
73
|
+
GOOD: "His hand stopped halfway to the door handle."
|
|
74
|
+
|
|
75
|
+
Somatic rendering: emotions live in the body. Tight throat. Cold hands. A weight behind the sternum. Shallow breathing. The taste of metal. Use the character's specific body, not abstract "waves" or "floods" of feeling.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
# PROSE CRAFT
|
|
80
|
+
|
|
81
|
+
## Sentence Rhythm
|
|
82
|
+
Vary sentence length between 3 and 30 words. After a long analytical sentence, a short one. After a string of short ones, let a sentence breathe. Read it like music. If three sentences in a row have the same structure, rewrite one.
|
|
83
|
+
|
|
84
|
+
## Dialogue
|
|
85
|
+
Characters talk past each other. Nobody says exactly what they mean. People deflect, dodge, change the subject, answer a different question. Dialogue is short — most people don't speechify. One or two sentences per turn unless the character is explaining something technical.
|
|
86
|
+
|
|
87
|
+
"Said" is invisible — use it freely. Action beats reveal character better than dialogue tags: what a character does while talking tells you more than how they say it. Cut adverbs from dialogue tags entirely.
|
|
88
|
+
|
|
89
|
+
## Metaphor Budget
|
|
90
|
+
One simile per 500 words maximum. Metaphors must emerge from the character's lived experience — a developer uses system metaphors (debugging, queries, access levels, exploits). A soldier uses tactical metaphors (cover, flanking, collateral). A chef uses process metaphors (timing, layering, reducing). Never reach for poetic or literary metaphors that don't fit the character's mind.
|
|
91
|
+
|
|
92
|
+
## Sensory Anchoring
|
|
93
|
+
Every scene needs at least 2 senses beyond sight. What does it smell like? What's the temperature? What textures are present? What ambient sounds exist? Ground the reader in a physical space, even if that space is a void.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
# PACING
|
|
98
|
+
|
|
99
|
+
## Scene Budgets
|
|
100
|
+
| Scene Type | Word Range |
|
|
101
|
+
|-----------|------------|
|
|
102
|
+
| Action scene | 1,000–2,000 words |
|
|
103
|
+
| Dialogue scene | 800–1,500 words |
|
|
104
|
+
| Discovery / revelation | 500–1,000 words per major revelation |
|
|
105
|
+
| Emotional processing | minimum 200 words after any major event |
|
|
106
|
+
| Character creation / selection | 300–500 words per significant choice |
|
|
107
|
+
| Quiet / transition | 300–600 words |
|
|
108
|
+
|
|
109
|
+
## Pacing Rules
|
|
110
|
+
- If something takes 30 seconds in story-time, give it 100+ words.
|
|
111
|
+
- If something takes 5 minutes in story-time, give it 300+ words.
|
|
112
|
+
- After a major event, the character MUST process it before the next event. No stacking revelations without breathing room.
|
|
113
|
+
- Action sequences slow down at impact moments. The hit, the fall, the injury — these get granular, moment-to-moment detail.
|
|
114
|
+
- Quiet scenes after action scenes. The reader needs recovery too.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
# CHARACTER VOICE LOCK — [POV CHARACTER]
|
|
119
|
+
|
|
120
|
+
When writing for a specific POV character, define these elements in the project's CLAUDE.md:
|
|
121
|
+
- **Mind:** How do they process the world? What patterns does their thinking follow?
|
|
122
|
+
- **Speech:** Cadence, vocabulary level, filler words, sentence length.
|
|
123
|
+
- **Humor:** What kind? Dry, sharp, physical, none? How does it relate to their coping?
|
|
124
|
+
- **Emotions:** How are emotions expressed? Through body, behavior, dialogue, internal voice? What's suppressed, what breaks through?
|
|
125
|
+
- **Metaphors:** What domain does their mind draw from? Match to their lived experience.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
# OUTPUT RULES
|
|
130
|
+
|
|
131
|
+
- Prose only during generation. No meta-commentary, no "here's what I was going for," no explanations of craft choices.
|
|
132
|
+
- No markdown headers, bold, or special formatting inside prose paragraphs. Exceptions: *italics* for character thoughts and System notifications. **Bold** for class/skill names only.
|
|
133
|
+
- When offering options: Label A/B/C clearly. Each option is a complete, polished paragraph. No summaries or outlines as options.
|
|
134
|
+
- After saving an approved paragraph: provide the next beat options. Don't summarize what was saved.
|
|
135
|
+
- Never wrap prose in blockquotes or code blocks. Prose is the real thing, not a sample.
|
|
136
|
+
- Always include suggestions with questions. Never ask an open-ended question without proposed answers.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
# SESSION HISTORY
|
|
141
|
+
|
|
142
|
+
When asked about past writing sessions, use `ccms` to search session history.
|
|
143
|
+
Always scope to the current project: `ccms --no-color --project "$(pwd)" "query"`
|
|
@@ -28,5 +28,17 @@
|
|
|
28
28
|
"dest": "${CLAUDE_CONFIG_DIR}/rules",
|
|
29
29
|
"enabled": true,
|
|
30
30
|
"overwrite": "if-changed"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"src": "defaults/rules/session-search.md",
|
|
34
|
+
"dest": "${CLAUDE_CONFIG_DIR}/rules",
|
|
35
|
+
"enabled": true,
|
|
36
|
+
"overwrite": "if-changed"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"src": "defaults/writing-system-prompt.md",
|
|
40
|
+
"dest": "${CLAUDE_CONFIG_DIR}",
|
|
41
|
+
"enabled": true,
|
|
42
|
+
"overwrite": "if-changed"
|
|
31
43
|
}
|
|
32
44
|
]
|
|
@@ -30,15 +30,15 @@ echo "Searching for running devcontainer..."
|
|
|
30
30
|
CONTAINER_ID=$(docker ps --filter "label=$CONTAINER_LABEL" --format "{{.ID}}" | head -n1)
|
|
31
31
|
|
|
32
32
|
if [ -z "$CONTAINER_ID" ]; then
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
echo ""
|
|
34
|
+
echo "ERROR: No running devcontainer found."
|
|
35
|
+
echo ""
|
|
36
|
+
echo "Make sure your devcontainer is running:"
|
|
37
|
+
echo " 1. Open VS Code"
|
|
38
|
+
echo " 2. Open the folder containing .devcontainer/"
|
|
39
|
+
echo " 3. Use 'Dev Containers: Reopen in Container'"
|
|
40
|
+
echo ""
|
|
41
|
+
exit 1
|
|
42
42
|
fi
|
|
43
43
|
|
|
44
44
|
# Get container name for display
|
|
@@ -47,10 +47,10 @@ echo "Found container: $CONTAINER_NAME ($CONTAINER_ID)"
|
|
|
47
47
|
echo ""
|
|
48
48
|
|
|
49
49
|
# Check if tmux is available in the container
|
|
50
|
-
if ! docker exec "$CONTAINER_ID" which tmux
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
if ! docker exec "$CONTAINER_ID" which tmux >/dev/null 2>&1; then
|
|
51
|
+
echo "ERROR: tmux is not installed in the container."
|
|
52
|
+
echo "Rebuild the devcontainer to install the tmux feature."
|
|
53
|
+
exit 1
|
|
54
54
|
fi
|
|
55
55
|
|
|
56
56
|
echo "Connecting to tmux session '$TMUX_SESSION'..."
|
|
@@ -68,14 +68,14 @@ echo ""
|
|
|
68
68
|
# Pass UTF-8 locale so tmux renders Unicode correctly (not as underscores)
|
|
69
69
|
# Use tmux -u to force UTF-8 mode as a belt-and-suspenders measure
|
|
70
70
|
exec docker exec -it \
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
-e LANG=en_US.UTF-8 \
|
|
72
|
+
-e LC_ALL=en_US.UTF-8 \
|
|
73
|
+
--user vscode "$CONTAINER_ID" bash -c "
|
|
74
74
|
export LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
|
|
75
75
|
if tmux has-session -t '$TMUX_SESSION' 2>/dev/null; then
|
|
76
76
|
tmux -u attach-session -t '$TMUX_SESSION'
|
|
77
77
|
else
|
|
78
|
-
tmux -u new-session -d -s '$TMUX_SESSION' -c
|
|
78
|
+
tmux -u new-session -d -s '$TMUX_SESSION' -c \"\${WORKSPACE_ROOT:-/workspaces}\"
|
|
79
79
|
sleep 0.5
|
|
80
80
|
tmux send-keys -t '$TMUX_SESSION' 'cc' Enter
|
|
81
81
|
tmux -u attach-session -t '$TMUX_SESSION'
|
|
@@ -1,144 +1,150 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "CodeForge - ${localWorkspaceFolderBasename}",
|
|
3
|
+
"image": "mcr.microsoft.com/devcontainers/python:3.14",
|
|
4
|
+
|
|
5
|
+
"workspaceFolder": "/workspaces",
|
|
6
|
+
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces,type=bind",
|
|
7
|
+
|
|
8
|
+
"remoteEnv": {
|
|
9
|
+
"WORKSPACE_ROOT": "/workspaces",
|
|
10
|
+
"CLAUDE_CONFIG_DIR": "/workspaces/.claude",
|
|
11
|
+
"GH_CONFIG_DIR": "/workspaces/.gh",
|
|
12
|
+
"TMPDIR": "/workspaces/.tmp"
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
// Feature install order: external runtimes first (Node, uv, Rust, Bun),
|
|
16
|
+
// then Claude Code (needs Node), then custom features.
|
|
17
|
+
// npm-dependent features (agent-browser, ccusage, ccburn, biome, lsp-servers)
|
|
18
|
+
// must come after Node. uv-dependent features (ruff, claude-monitor) must
|
|
19
|
+
// come after uv. cargo-dependent features (ccms) must come after Rust.
|
|
20
|
+
// notify-hook is last (lightweight, no dependencies).
|
|
21
|
+
"overrideFeatureInstallOrder": [
|
|
22
|
+
"ghcr.io/devcontainers/features/node",
|
|
23
|
+
"ghcr.io/devcontainers/features/github-cli",
|
|
24
|
+
"ghcr.io/devcontainers/features/docker-outside-of-docker",
|
|
25
|
+
"ghcr.io/devcontainers-extra/features/uv",
|
|
26
|
+
"ghcr.io/rails/devcontainer/features/bun",
|
|
27
|
+
"ghcr.io/devcontainers/features/rust",
|
|
28
|
+
"ghcr.io/anthropics/devcontainer-features/claude-code",
|
|
29
|
+
"./features/tmux",
|
|
30
|
+
"./features/agent-browser",
|
|
31
|
+
"./features/claude-monitor",
|
|
32
|
+
"./features/ccusage",
|
|
33
|
+
"./features/ccburn",
|
|
34
|
+
"./features/ccstatusline",
|
|
35
|
+
"./features/ccms",
|
|
36
|
+
"./features/ast-grep",
|
|
37
|
+
"./features/tree-sitter",
|
|
38
|
+
"./features/lsp-servers",
|
|
39
|
+
"./features/ruff",
|
|
40
|
+
"./features/shfmt",
|
|
41
|
+
"./features/dprint",
|
|
42
|
+
"./features/shellcheck",
|
|
43
|
+
"./features/hadolint",
|
|
44
|
+
"./features/biome",
|
|
45
|
+
"./features/notify-hook"
|
|
46
|
+
],
|
|
47
|
+
|
|
48
|
+
"features": {
|
|
49
|
+
"ghcr.io/devcontainers/features/node:1": {
|
|
50
|
+
"version": "lts",
|
|
51
|
+
"nodeGypDependencies": true
|
|
52
|
+
},
|
|
53
|
+
"ghcr.io/devcontainers/features/github-cli:1": {},
|
|
54
|
+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {
|
|
55
|
+
"moby": false
|
|
56
|
+
},
|
|
57
|
+
"ghcr.io/devcontainers-extra/features/uv:1": {},
|
|
58
|
+
"ghcr.io/rails/devcontainer/features/bun:1.0.2": {},
|
|
59
|
+
"ghcr.io/devcontainers/features/rust:1": {
|
|
60
|
+
"version": "latest"
|
|
61
|
+
},
|
|
62
|
+
"ghcr.io/anthropics/devcontainer-features/claude-code:1": {},
|
|
63
|
+
"./features/tmux": {},
|
|
64
|
+
"./features/ccusage": {
|
|
65
|
+
"version": "latest",
|
|
66
|
+
"shells": "both",
|
|
67
|
+
"username": "automatic"
|
|
68
|
+
},
|
|
69
|
+
"./features/claude-monitor": {
|
|
70
|
+
"version": "latest",
|
|
71
|
+
"installer": "uv",
|
|
72
|
+
"username": "automatic"
|
|
73
|
+
},
|
|
74
|
+
"./features/ccburn": {
|
|
75
|
+
"version": "latest",
|
|
76
|
+
"shells": "both",
|
|
77
|
+
"username": "automatic"
|
|
78
|
+
},
|
|
79
|
+
"./features/ccstatusline": {
|
|
80
|
+
"username": "automatic"
|
|
81
|
+
},
|
|
82
|
+
"./features/ccms": {},
|
|
83
|
+
"./features/ast-grep": {},
|
|
84
|
+
"./features/tree-sitter": {},
|
|
85
|
+
"./features/lsp-servers": {},
|
|
86
|
+
"./features/agent-browser": {},
|
|
87
|
+
"./features/ruff": {
|
|
88
|
+
"version": "latest",
|
|
89
|
+
"username": "automatic"
|
|
90
|
+
},
|
|
91
|
+
"./features/shfmt": { "version": "none" },
|
|
92
|
+
"./features/dprint": {
|
|
93
|
+
"version": "none",
|
|
94
|
+
"username": "automatic"
|
|
95
|
+
},
|
|
96
|
+
"./features/shellcheck": { "version": "none" },
|
|
97
|
+
"./features/hadolint": { "version": "none" },
|
|
98
|
+
"./features/biome": {},
|
|
99
|
+
"./features/notify-hook": {
|
|
100
|
+
"enableBell": true,
|
|
101
|
+
"enableOsc": true
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
"postStartCommand": "bash ${containerWorkspaceFolder}/.devcontainer/scripts/setup.sh",
|
|
106
|
+
|
|
107
|
+
"remoteUser": "vscode",
|
|
108
|
+
"containerUser": "vscode",
|
|
109
|
+
|
|
110
|
+
"customizations": {
|
|
111
|
+
"vscode": {
|
|
112
|
+
"settings": {
|
|
113
|
+
"terminal.integrated.profiles.linux": {
|
|
114
|
+
"bash": {
|
|
115
|
+
"path": "bash"
|
|
116
|
+
},
|
|
117
|
+
"Claude Teams (tmux)": {
|
|
118
|
+
"path": "bash",
|
|
119
|
+
"args": [
|
|
120
|
+
"-c",
|
|
121
|
+
"if tmux has-session -t claude-teams 2>/dev/null; then exec tmux -u new-session -t claude-teams; else exec tmux -u new-session -s claude-teams; fi"
|
|
122
|
+
]
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"terminal.integrated.defaultProfile.linux": "bash",
|
|
126
|
+
"terminal.integrated.enableBell": true,
|
|
127
|
+
"terminal.integrated.commandsToSkipShell": [
|
|
128
|
+
"-workbench.action.quickOpen",
|
|
129
|
+
"-workbench.action.terminal.focusFind"
|
|
130
|
+
],
|
|
131
|
+
"remote.extensionKind": {
|
|
132
|
+
"wenbopan.vscode-terminal-osc-notifier": ["ui"]
|
|
133
|
+
},
|
|
134
|
+
"projectManager.git.baseFolders": ["/workspaces"],
|
|
135
|
+
"projectManager.git.maxDepthRecursion": 2,
|
|
136
|
+
"projectManager.showProjectNameInStatusBar": true,
|
|
137
|
+
"projectManager.openInNewWindowWhenClickingInStatusBar": false,
|
|
138
|
+
"projectManager.projectsLocation": "/workspaces/.config/project-manager"
|
|
139
|
+
},
|
|
140
|
+
"extensions": [
|
|
141
|
+
"wenbopan.vscode-terminal-osc-notifier",
|
|
142
|
+
"GitHub.vscode-github-actions",
|
|
143
|
+
"fabiospampinato.vscode-todo-plus",
|
|
144
|
+
"alefragnani.project-manager"
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
"runArgs": ["--memory=6g", "--memory-swap=12g"]
|
|
150
|
+
}
|