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.
Files changed (56) hide show
  1. package/.devcontainer/.env +3 -0
  2. package/.devcontainer/CHANGELOG.md +125 -0
  3. package/.devcontainer/CLAUDE.md +41 -11
  4. package/.devcontainer/README.md +73 -3
  5. package/.devcontainer/config/defaults/main-system-prompt.md +187 -201
  6. package/.devcontainer/config/defaults/rules/session-search.md +66 -0
  7. package/.devcontainer/config/defaults/rules/spec-workflow.md +48 -13
  8. package/.devcontainer/config/defaults/settings.json +2 -1
  9. package/.devcontainer/config/defaults/writing-system-prompt.md +143 -0
  10. package/.devcontainer/config/file-manifest.json +12 -0
  11. package/.devcontainer/connect-external-terminal.sh +17 -17
  12. package/.devcontainer/devcontainer.json +150 -144
  13. package/.devcontainer/features/ccms/README.md +50 -0
  14. package/.devcontainer/features/ccms/devcontainer-feature.json +21 -0
  15. package/.devcontainer/features/ccms/install.sh +105 -0
  16. package/.devcontainer/features/ccstatusline/install.sh +24 -2
  17. package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +8 -1
  18. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +5 -3
  19. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/claude-guide.md +1 -1
  20. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +7 -7
  21. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/generalist.md +1 -0
  22. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +22 -12
  23. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +11 -1
  24. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/skill-suggester.cpython-314.pyc +0 -0
  25. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +186 -13
  26. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/git-state-injector.py +15 -4
  27. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/inject-cwd.py +37 -0
  28. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/skill-suggester.py +24 -0
  29. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/spec-reminder.py +4 -2
  30. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/SKILL.md +1 -1
  31. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-build/SKILL.md +353 -0
  32. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-build/references/review-checklist.md +175 -0
  33. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-check/SKILL.md +28 -15
  34. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/SKILL.md +16 -13
  35. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/references/backlog-template.md +19 -3
  36. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/references/milestones-template.md +32 -0
  37. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/SKILL.md +28 -20
  38. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/references/template.md +35 -6
  39. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-refine/SKILL.md +194 -0
  40. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-review/SKILL.md +229 -0
  41. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-update/SKILL.md +24 -2
  42. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +20 -13
  43. package/.devcontainer/plugins/devs-marketplace/plugins/codeforge-lsp/.claude-plugin/plugin.json +38 -5
  44. package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/.claude-plugin/plugin.json +7 -0
  45. package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/hooks/hooks.json +17 -0
  46. package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/__pycache__/guard-workspace-scope.cpython-314.pyc +0 -0
  47. package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py +132 -0
  48. package/.devcontainer/scripts/check-setup.sh +24 -25
  49. package/.devcontainer/scripts/setup-aliases.sh +95 -90
  50. package/.devcontainer/scripts/setup-projects.sh +172 -131
  51. package/.devcontainer/scripts/setup-terminal.sh +48 -0
  52. package/.devcontainer/scripts/setup-update-claude.sh +49 -107
  53. package/.devcontainer/scripts/setup.sh +4 -17
  54. package/README.md +2 -2
  55. package/package.json +1 -1
  56. 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 MUST be 200 lines. Split by feature boundary if larger;
12
- link via a parent overview (≤50 lines).
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 version,
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 version, MUST run `/spec-check` to audit spec health.
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. Version-organized:
50
+ `.specs/` at the project root. Domain-organized:
23
51
 
24
52
  ```
25
53
  .specs/
26
- ├── v0.1.0.md # Single-file spec for small versions
27
- ├── v0.2.0/ # Directory for multi-feature versions
28
- ├── _overview.md # Feature matrix + architecture decisions
29
- │ ├── feature-a.md
30
- │ └── feature-b.md
31
- ├── ROADMAP.md # What each version delivers and why (≤150 lines)
32
- └── BACKLOG.md # Deferred items not yet scheduled
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
- **Version:** v0.X.0
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
- 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
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 > /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
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
- -e LANG=en_US.UTF-8 \
72
- -e LC_ALL=en_US.UTF-8 \
73
- --user vscode "$CONTAINER_ID" bash -c "
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 /workspaces
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
- "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, Go, 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. notify-hook is last (lightweight, no dependencies).
20
- "overrideFeatureInstallOrder": [
21
- "ghcr.io/devcontainers/features/node",
22
- "ghcr.io/devcontainers/features/github-cli",
23
- "ghcr.io/devcontainers/features/docker-outside-of-docker",
24
- "ghcr.io/devcontainers-extra/features/uv",
25
- "ghcr.io/devcontainers/features/go",
26
- "ghcr.io/rails/devcontainer/features/bun",
27
- "ghcr.io/anthropics/devcontainer-features/claude-code",
28
- "./features/tmux",
29
- "./features/agent-browser",
30
- "./features/claude-monitor",
31
- "./features/ccusage",
32
- "./features/ccburn",
33
- "./features/ccstatusline",
34
- "./features/ast-grep",
35
- "./features/tree-sitter",
36
- "./features/lsp-servers",
37
- "./features/ruff",
38
- "./features/shfmt",
39
- "./features/dprint",
40
- "./features/shellcheck",
41
- "./features/hadolint",
42
- "./features/biome",
43
- "./features/notify-hook"
44
- ],
45
-
46
- "features": {
47
- "ghcr.io/devcontainers/features/node:1": {
48
- "version": "lts",
49
- "nodeGypDependencies": true
50
- },
51
- "ghcr.io/devcontainers/features/github-cli:1": {},
52
- "ghcr.io/devcontainers/features/docker-outside-of-docker:1":
53
- {
54
- "moby": false
55
- },
56
- "ghcr.io/devcontainers-extra/features/uv:1": {},
57
- "ghcr.io/rails/devcontainer/features/bun:1.0.2": {},
58
- "ghcr.io/anthropics/devcontainer-features/claude-code:1": {},
59
- "./features/tmux": {},
60
- "./features/ccusage": {
61
- "version": "latest",
62
- "shells": "both",
63
- "username": "automatic"
64
- },
65
- "./features/claude-monitor": {
66
- "version": "latest",
67
- "installer": "uv",
68
- "username": "automatic"
69
- },
70
- "./features/ccburn": {
71
- "version": "latest",
72
- "shells": "both",
73
- "username": "automatic"
74
- },
75
- "./features/ccstatusline": {
76
- "username": "automatic"
77
- },
78
- "./features/ast-grep": {},
79
- "./features/tree-sitter": {},
80
- "./features/lsp-servers": {},
81
- "./features/agent-browser": {},
82
- "./features/ruff": {
83
- "version": "latest",
84
- "username": "automatic"
85
- },
86
- "./features/shfmt": {},
87
- "./features/dprint": {
88
- "username": "automatic"
89
- },
90
- "./features/shellcheck": {},
91
- "./features/hadolint": {},
92
- "./features/biome": {},
93
- "./features/notify-hook": {
94
- "enableBell": true,
95
- "enableOsc": true
96
- }
97
- },
98
-
99
- "postStartCommand": "bash ${containerWorkspaceFolder}/.devcontainer/scripts/setup.sh",
100
-
101
- "remoteUser": "vscode",
102
- "containerUser": "vscode",
103
-
104
- "customizations": {
105
- "vscode": {
106
- "settings": {
107
- "terminal.integrated.profiles.linux": {
108
- "bash": {
109
- "path": "bash"
110
- },
111
- "Claude Teams (tmux)": {
112
- "path": "bash",
113
- "args": ["-c", "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"]
114
- }
115
- },
116
- "terminal.integrated.defaultProfile.linux": "bash",
117
- "terminal.integrated.enableBell": true,
118
- "terminal.integrated.commandsToSkipShell": [
119
- "-workbench.action.quickOpen",
120
- "-workbench.action.terminal.focusFind"
121
- ],
122
- "remote.extensionKind": {
123
- "wenbopan.vscode-terminal-osc-notifier": ["ui"]
124
- },
125
- "projectManager.git.baseFolders": ["/workspaces"],
126
- "projectManager.git.maxDepthRecursion": 1,
127
- "projectManager.showProjectNameInStatusBar": true,
128
- "projectManager.openInNewWindowWhenClickingInStatusBar": false,
129
- "projectManager.projectsLocation": "/workspaces/.config/project-manager"
130
- },
131
- "extensions": [
132
- "wenbopan.vscode-terminal-osc-notifier",
133
- "GitHub.vscode-github-actions",
134
- "fabiospampinato.vscode-todo-plus",
135
- "alefragnani.project-manager"
136
- ]
137
- }
138
- },
139
-
140
- "runArgs": [
141
- "--memory=4g",
142
- "--memory-swap=8g"
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
+ }