codeforge-dev 1.7.0 → 1.8.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 (136) hide show
  1. package/.devcontainer/.env +4 -6
  2. package/.devcontainer/.env.example +29 -0
  3. package/.devcontainer/.gitignore +8 -0
  4. package/.devcontainer/.secrets.example +12 -0
  5. package/.devcontainer/CHANGELOG.md +130 -0
  6. package/.devcontainer/CLAUDE.md +56 -19
  7. package/.devcontainer/README.md +111 -56
  8. package/.devcontainer/config/{main-system-prompt.md → defaults/main-system-prompt.md} +72 -0
  9. package/.devcontainer/config/file-manifest.json +20 -0
  10. package/.devcontainer/devcontainer.json +20 -0
  11. package/.devcontainer/docs/configuration-reference.md +90 -0
  12. package/.devcontainer/docs/keybindings.md +100 -0
  13. package/.devcontainer/docs/optional-features.md +129 -0
  14. package/.devcontainer/docs/plugins.md +154 -0
  15. package/.devcontainer/docs/troubleshooting.md +128 -0
  16. package/.devcontainer/features/agent-browser/install.sh +6 -0
  17. package/.devcontainer/features/ast-grep/install.sh +6 -0
  18. package/.devcontainer/features/biome/README.md +27 -0
  19. package/.devcontainer/features/biome/install.sh +6 -0
  20. package/.devcontainer/features/ccburn/install.sh +6 -0
  21. package/.devcontainer/features/ccstatusline/devcontainer-feature.json +5 -0
  22. package/.devcontainer/features/ccstatusline/install.sh +7 -0
  23. package/.devcontainer/features/ccusage/install.sh +6 -0
  24. package/.devcontainer/features/claude-monitor/install.sh +6 -0
  25. package/.devcontainer/features/dprint/README.md +30 -0
  26. package/.devcontainer/features/dprint/devcontainer-feature.json +18 -0
  27. package/.devcontainer/features/dprint/install.sh +131 -0
  28. package/.devcontainer/features/hadolint/README.md +35 -0
  29. package/.devcontainer/features/hadolint/devcontainer-feature.json +13 -0
  30. package/.devcontainer/features/hadolint/install.sh +86 -0
  31. package/.devcontainer/features/lsp-servers/devcontainer-feature.json +5 -0
  32. package/.devcontainer/features/lsp-servers/install.sh +7 -0
  33. package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +5 -0
  34. package/.devcontainer/features/mcp-qdrant/install.sh +13 -6
  35. package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +5 -0
  36. package/.devcontainer/features/mcp-reasoner/install.sh +8 -1
  37. package/.devcontainer/features/notify-hook/devcontainer-feature.json +5 -0
  38. package/.devcontainer/features/notify-hook/install.sh +7 -0
  39. package/.devcontainer/features/ruff/README.md +26 -0
  40. package/.devcontainer/features/ruff/devcontainer-feature.json +21 -0
  41. package/.devcontainer/features/ruff/install.sh +74 -0
  42. package/.devcontainer/features/shellcheck/README.md +38 -0
  43. package/.devcontainer/features/shellcheck/devcontainer-feature.json +13 -0
  44. package/.devcontainer/features/shellcheck/install.sh +24 -0
  45. package/.devcontainer/features/shfmt/README.md +37 -0
  46. package/.devcontainer/features/shfmt/devcontainer-feature.json +13 -0
  47. package/.devcontainer/features/shfmt/install.sh +85 -0
  48. package/.devcontainer/features/splitrail/devcontainer-feature.json +5 -0
  49. package/.devcontainer/features/splitrail/install.sh +7 -0
  50. package/.devcontainer/features/tmux/install.sh +8 -0
  51. package/.devcontainer/features/tree-sitter/install.sh +6 -0
  52. package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +3 -10
  53. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +1 -1
  54. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/__pycache__/format-on-stop.cpython-314.pyc +0 -0
  55. package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py +114 -9
  56. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +1 -1
  57. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +4 -5
  58. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/__pycache__/lint-file.cpython-314.pyc +0 -0
  59. package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +478 -76
  60. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/.claude-plugin/plugin.json +1 -1
  61. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/AGENT-REDIRECTION.md +226 -0
  62. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +17 -0
  63. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/bash-exec.md +4 -4
  64. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/claude-guide.md +14 -23
  65. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/debug-logs.md +2 -0
  66. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/dependency-analyst.md +2 -0
  67. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +13 -0
  68. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/explorer.md +2 -0
  69. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/generalist.md +10 -1
  70. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/migrator.md +6 -0
  71. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/refactorer.md +4 -0
  72. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +36 -23
  73. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/statusline-config.md +3 -3
  74. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/test-writer.md +3 -0
  75. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +39 -0
  76. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/advisory-test-runner.cpython-314.pyc +0 -0
  77. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/collect-edited-files.cpython-314.pyc +0 -0
  78. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/commit-reminder.cpython-314.pyc +0 -0
  79. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/git-state-injector.cpython-314.pyc +0 -0
  80. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/redirect-builtin-agents.cpython-314.pyc +0 -0
  81. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/ticket-linker.cpython-314.pyc +0 -0
  82. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/todo-harvester.cpython-314.pyc +0 -0
  83. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +174 -0
  84. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/collect-edited-files.py +8 -6
  85. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/commit-reminder.py +90 -0
  86. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/git-state-injector.py +114 -0
  87. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/skill-suggester.py +61 -0
  88. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/ticket-linker.py +137 -0
  89. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/todo-harvester.py +130 -0
  90. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/SKILL.md +224 -0
  91. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/error-handling.md +166 -0
  92. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/rest-conventions.md +215 -0
  93. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/SKILL.md +211 -0
  94. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/references/language-patterns.md +327 -0
  95. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/SKILL.md +134 -0
  96. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/ecosystem-commands.md +264 -0
  97. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/license-compliance.md +80 -0
  98. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/SKILL.md +153 -0
  99. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/api-doc-templates.md +221 -0
  100. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/docstring-formats.md +296 -0
  101. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/SKILL.md +150 -0
  102. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/javascript-migrations.md +179 -0
  103. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/python-migrations.md +141 -0
  104. package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +32 -0
  105. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/__pycache__/block-dangerous.cpython-314.pyc +0 -0
  106. package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +1 -1
  107. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/__pycache__/guard-protected.cpython-314.pyc +0 -0
  108. package/.devcontainer/scripts/check-setup.sh +72 -0
  109. package/.devcontainer/scripts/setup-aliases.sh +43 -3
  110. package/.devcontainer/scripts/setup-auth.sh +74 -0
  111. package/.devcontainer/scripts/setup-config.sh +112 -22
  112. package/.devcontainer/scripts/setup-update-claude.sh +8 -0
  113. package/.devcontainer/scripts/setup.sh +46 -13
  114. package/README.md +23 -190
  115. package/package.json +1 -1
  116. package/setup.js +245 -71
  117. package/.devcontainer/features/claude-code/README.md +0 -498
  118. package/.devcontainer/features/claude-code/config/settings.json +0 -72
  119. package/.devcontainer/features/claude-code/config/system-prompt.md +0 -118
  120. package/.devcontainer/features/claude-code/config/world-building-sp.md +0 -1432
  121. package/.devcontainer/features/claude-code/devcontainer-feature.json +0 -42
  122. package/.devcontainer/features/claude-code/install.sh +0 -466
  123. package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +0 -7
  124. package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +0 -17
  125. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +0 -6
  126. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +0 -14
  127. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +0 -989
  128. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +0 -33
  129. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
  130. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +0 -71
  131. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +0 -68
  132. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +0 -120
  133. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +0 -133
  134. package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +0 -253
  135. /package/.devcontainer/config/{keybindings.json → defaults/keybindings.json} +0 -0
  136. /package/.devcontainer/config/{settings.json → defaults/settings.json} +0 -0
package/setup.js CHANGED
@@ -1,83 +1,257 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const fs = require('fs');
4
- const path = require('path');
3
+ const fs = require("fs");
4
+ const path = require("path");
5
5
 
6
+ // ── Default preserve list ────────────────────────────────────────
7
+ // Files in the package that should NOT overwrite user customizations.
8
+ // The package version is saved as <file>.codeforge-new for diffing.
9
+ const DEFAULT_PRESERVE = [
10
+ "config/defaults/settings.json",
11
+ "config/defaults/main-system-prompt.md",
12
+ "config/defaults/keybindings.json",
13
+ "config/file-manifest.json",
14
+ ".codeforge-preserve",
15
+ ];
16
+
17
+ // ── copyDirectory ────────────────────────────────────────────────
18
+ // Simple recursive copy (used for fresh install and --reset).
6
19
  function copyDirectory(src, dest) {
7
- if (!fs.existsSync(dest)) {
8
- fs.mkdirSync(dest, { recursive: true });
9
- }
10
-
11
- const entries = fs.readdirSync(src, { withFileTypes: true });
12
-
13
- for (const entry of entries) {
14
- const srcPath = path.join(src, entry.name);
15
- const destPath = path.join(dest, entry.name);
16
-
17
- if (entry.isDirectory()) {
18
- copyDirectory(srcPath, destPath);
19
- } else {
20
- fs.copyFileSync(srcPath, destPath);
21
- }
22
- }
20
+ if (!fs.existsSync(dest)) {
21
+ fs.mkdirSync(dest, { recursive: true });
22
+ }
23
+
24
+ const entries = fs.readdirSync(src, { withFileTypes: true });
25
+
26
+ for (const entry of entries) {
27
+ const srcPath = path.join(src, entry.name);
28
+ const destPath = path.join(dest, entry.name);
29
+
30
+ if (entry.isDirectory()) {
31
+ copyDirectory(srcPath, destPath);
32
+ } else {
33
+ fs.copyFileSync(srcPath, destPath);
34
+ }
35
+ }
23
36
  }
24
37
 
38
+ // ── loadPreserveList ─────────────────────────────────────────────
39
+ // Builds the set of relative paths to preserve during --force update.
40
+ // Combines built-in defaults with user entries from .codeforge-preserve.
41
+ function loadPreserveList(devcontainerDest) {
42
+ const preserveFile = path.join(devcontainerDest, ".codeforge-preserve");
43
+ let custom = [];
44
+
45
+ if (fs.existsSync(preserveFile)) {
46
+ custom = fs
47
+ .readFileSync(preserveFile, "utf-8")
48
+ .split("\n")
49
+ .map((line) => line.trim())
50
+ .filter((line) => line && !line.startsWith("#"));
51
+ }
52
+
53
+ return new Set([...DEFAULT_PRESERVE, ...custom]);
54
+ }
55
+
56
+ // ── syncDirectory ────────────────────────────────────────────────
57
+ // Selective overwrite: walks the package tree and copies files to dest.
58
+ // - Framework files (scripts, features, plugins): always overwrite
59
+ // - Preserved files: skip, save package version as .codeforge-new
60
+ // - devcontainer.json: overwrite, save user's as .bak
61
+ // - User-created files not in package: untouched (never visited)
62
+ function syncDirectory(src, dest, preserveSet) {
63
+ const stats = {
64
+ updated: 0,
65
+ preserved: 0,
66
+ added: 0,
67
+ backedUp: 0,
68
+ preservedFiles: [],
69
+ };
70
+
71
+ function walk(srcDir, destDir, relativeBase) {
72
+ if (!fs.existsSync(destDir)) {
73
+ fs.mkdirSync(destDir, { recursive: true });
74
+ }
75
+
76
+ const entries = fs.readdirSync(srcDir, { withFileTypes: true });
77
+
78
+ for (const entry of entries) {
79
+ const srcPath = path.join(srcDir, entry.name);
80
+ const destPath = path.join(destDir, entry.name);
81
+ const relativePath = relativeBase
82
+ ? relativeBase + "/" + entry.name
83
+ : entry.name;
84
+
85
+ if (entry.isDirectory()) {
86
+ walk(srcPath, destPath, relativePath);
87
+ continue;
88
+ }
89
+
90
+ // Special handling for devcontainer.json: overwrite + save .bak
91
+ if (relativePath === "devcontainer.json" && fs.existsSync(destPath)) {
92
+ fs.copyFileSync(destPath, destPath + ".bak");
93
+ fs.copyFileSync(srcPath, destPath);
94
+ stats.backedUp++;
95
+ stats.updated++;
96
+ continue;
97
+ }
98
+
99
+ // Preserved files: skip overwrite, save package version as .codeforge-new
100
+ if (preserveSet.has(relativePath) && fs.existsSync(destPath)) {
101
+ fs.copyFileSync(srcPath, destPath + ".codeforge-new");
102
+ stats.preserved++;
103
+ stats.preservedFiles.push(relativePath);
104
+ continue;
105
+ }
106
+
107
+ // Framework files: always overwrite (or create if new)
108
+ const isNew = !fs.existsSync(destPath);
109
+ fs.copyFileSync(srcPath, destPath);
110
+ if (isNew) {
111
+ stats.added++;
112
+ } else {
113
+ stats.updated++;
114
+ }
115
+ }
116
+ }
117
+
118
+ walk(src, dest, "");
119
+ return stats;
120
+ }
121
+
122
+ // ── main ─────────────────────────────────────────────────────────
25
123
  function main() {
26
- const args = process.argv.slice(2);
27
- const force = args.includes('--force') || args.includes('-f');
28
-
29
- const currentDir = process.cwd();
30
- const packageDir = __dirname;
31
- const devcontainerSrc = path.join(packageDir, '.devcontainer');
32
- const devcontainerDest = path.join(currentDir, '.devcontainer');
33
-
34
- console.log('🚀 Setting up CodeForge DevContainer...');
35
-
36
- // Check if .devcontainer already exists
37
- if (fs.existsSync(devcontainerDest)) {
38
- if (force) {
39
- console.log('⚠️ Removing existing .devcontainer directory...');
40
- fs.rmSync(devcontainerDest, { recursive: true, force: true });
41
- } else {
42
- console.log('⚠️ .devcontainer directory already exists.');
43
- console.log(' Use --force to overwrite, or remove it manually.');
44
- process.exit(1);
45
- }
46
- }
47
-
48
- // Check if source .devcontainer exists
49
- if (!fs.existsSync(devcontainerSrc)) {
50
- console.error('❌ Error: .devcontainer source directory not found in package.');
51
- process.exit(1);
52
- }
53
-
54
- try {
55
- // Copy .devcontainer directory
56
- copyDirectory(devcontainerSrc, devcontainerDest);
57
-
58
- console.log('✅ CodeForge DevContainer configuration installed!');
59
- console.log('');
60
- console.log('🔧 Next steps:');
61
- console.log(' 1. Open this folder in VS Code');
62
- console.log(' 2. Select "Reopen in Container" from the command palette');
63
- console.log(' 3. Run: claude');
64
- console.log('');
65
- console.log('📚 Features included:');
66
- console.log(' • Claude Code CLI with optimized tool configuration');
67
- console.log(' • MCP servers: Qdrant (vector memory), Reasoner');
68
- console.log(' • Development tools: Node.js LTS, Python 3.14, Git with delta');
69
- console.log(' • Persistent configuration and shell history');
70
- console.log('');
71
- console.log('🔗 Documentation: See .devcontainer/README.md');
72
-
73
- } catch (error) {
74
- console.error('❌ Error copying .devcontainer:', error.message);
75
- process.exit(1);
76
- }
124
+ const args = process.argv.slice(2);
125
+ const force = args.includes("--force") || args.includes("-f");
126
+ const reset = args.includes("--reset");
127
+
128
+ if (args.includes("--help") || args.includes("-h")) {
129
+ console.log("Usage: codeforge [options]");
130
+ console.log("");
131
+ console.log("Options:");
132
+ console.log(
133
+ " --force, -f Update existing .devcontainer (preserves user config)",
134
+ );
135
+ console.log(
136
+ " --reset Remove all customizations and install fresh defaults",
137
+ );
138
+ console.log(" --help, -h Show this help message");
139
+ console.log("");
140
+ console.log(
141
+ "Without flags, installs only if .devcontainer does not exist.",
142
+ );
143
+ process.exit(0);
144
+ }
145
+
146
+ const currentDir = process.cwd();
147
+ const packageDir = __dirname;
148
+ const devcontainerSrc = path.join(packageDir, ".devcontainer");
149
+ const devcontainerDest = path.join(currentDir, ".devcontainer");
150
+
151
+ console.log("");
152
+
153
+ // Check if source .devcontainer exists in the package
154
+ if (!fs.existsSync(devcontainerSrc)) {
155
+ console.error(
156
+ "Error: .devcontainer source directory not found in package.",
157
+ );
158
+ process.exit(1);
159
+ }
160
+
161
+ if (fs.existsSync(devcontainerDest)) {
162
+ if (reset) {
163
+ // Nuclear: delete everything and copy fresh
164
+ console.log("Resetting .devcontainer to package defaults...");
165
+ console.log("");
166
+ fs.rmSync(devcontainerDest, { recursive: true, force: true });
167
+ copyDirectory(devcontainerSrc, devcontainerDest);
168
+ console.log(" Reset complete. All user customizations removed.");
169
+ console.log("");
170
+ printNextSteps();
171
+ } else if (force) {
172
+ // Smart update: selective overwrite with preservation
173
+ console.log("Updating .devcontainer (preserving user config)...");
174
+ console.log("");
175
+
176
+ const preserveSet = loadPreserveList(devcontainerDest);
177
+ const stats = syncDirectory(
178
+ devcontainerSrc,
179
+ devcontainerDest,
180
+ preserveSet,
181
+ );
182
+
183
+ // Summary
184
+ console.log(` Updated: ${stats.updated} files`);
185
+ console.log(` Added: ${stats.added} new files`);
186
+ console.log(` Preserved: ${stats.preserved} user config files`);
187
+ console.log("");
188
+
189
+ if (stats.backedUp > 0) {
190
+ console.log(
191
+ " devcontainer.json updated (previous saved as devcontainer.json.bak)",
192
+ );
193
+ console.log("");
194
+ }
195
+
196
+ if (stats.preservedFiles.length > 0) {
197
+ console.log(
198
+ " Review .codeforge-new files for new defaults you may want to merge:",
199
+ );
200
+ for (const file of stats.preservedFiles) {
201
+ console.log(` ${file}.codeforge-new`);
202
+ }
203
+ console.log("");
204
+ }
205
+
206
+ printNextSteps();
207
+ } else {
208
+ // No flags: error with guidance
209
+ console.log(".devcontainer directory already exists.");
210
+ console.log("");
211
+ console.log(" --force Update (preserves your config files)");
212
+ console.log(" --reset Start fresh (removes all customizations)");
213
+ console.log("");
214
+ process.exit(1);
215
+ }
216
+ } else {
217
+ // Fresh install
218
+ console.log("Setting up CodeForge DevContainer...");
219
+ console.log("");
220
+
221
+ try {
222
+ copyDirectory(devcontainerSrc, devcontainerDest);
223
+ console.log(" CodeForge DevContainer configuration installed!");
224
+ console.log("");
225
+ printNextSteps();
226
+ printFeatures();
227
+ } catch (error) {
228
+ console.error("Error copying .devcontainer:", error.message);
229
+ process.exit(1);
230
+ }
231
+ }
232
+ }
233
+
234
+ function printNextSteps() {
235
+ console.log("Next steps:");
236
+ console.log(" 1. Open this folder in VS Code");
237
+ console.log(' 2. Select "Reopen in Container" from the command palette');
238
+ console.log(" 3. Run: claude");
239
+ console.log("");
240
+ console.log("Documentation: .devcontainer/README.md");
241
+ console.log("");
242
+ }
243
+
244
+ function printFeatures() {
245
+ console.log("Features included:");
246
+ console.log(" - Claude Code CLI with optimized tool configuration");
247
+ console.log(" - MCP servers: Qdrant (vector memory), Reasoner");
248
+ console.log(" - Development tools: Node.js LTS, Python 3.14, Go, Bun");
249
+ console.log(" - Persistent configuration and shell history");
250
+ console.log("");
77
251
  }
78
252
 
79
253
  if (require.main === module) {
80
- main();
254
+ main();
81
255
  }
82
256
 
83
- module.exports = { copyDirectory, main };
257
+ module.exports = { copyDirectory, syncDirectory, loadPreserveList, main };