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.
- package/.devcontainer/.env +4 -6
- package/.devcontainer/.env.example +29 -0
- package/.devcontainer/.gitignore +8 -0
- package/.devcontainer/.secrets.example +12 -0
- package/.devcontainer/CHANGELOG.md +130 -0
- package/.devcontainer/CLAUDE.md +56 -19
- package/.devcontainer/README.md +111 -56
- package/.devcontainer/config/{main-system-prompt.md → defaults/main-system-prompt.md} +72 -0
- package/.devcontainer/config/file-manifest.json +20 -0
- package/.devcontainer/devcontainer.json +20 -0
- package/.devcontainer/docs/configuration-reference.md +90 -0
- package/.devcontainer/docs/keybindings.md +100 -0
- package/.devcontainer/docs/optional-features.md +129 -0
- package/.devcontainer/docs/plugins.md +154 -0
- package/.devcontainer/docs/troubleshooting.md +128 -0
- package/.devcontainer/features/agent-browser/install.sh +6 -0
- package/.devcontainer/features/ast-grep/install.sh +6 -0
- package/.devcontainer/features/biome/README.md +27 -0
- package/.devcontainer/features/biome/install.sh +6 -0
- package/.devcontainer/features/ccburn/install.sh +6 -0
- package/.devcontainer/features/ccstatusline/devcontainer-feature.json +5 -0
- package/.devcontainer/features/ccstatusline/install.sh +7 -0
- package/.devcontainer/features/ccusage/install.sh +6 -0
- package/.devcontainer/features/claude-monitor/install.sh +6 -0
- package/.devcontainer/features/dprint/README.md +30 -0
- package/.devcontainer/features/dprint/devcontainer-feature.json +18 -0
- package/.devcontainer/features/dprint/install.sh +131 -0
- package/.devcontainer/features/hadolint/README.md +35 -0
- package/.devcontainer/features/hadolint/devcontainer-feature.json +13 -0
- package/.devcontainer/features/hadolint/install.sh +86 -0
- package/.devcontainer/features/lsp-servers/devcontainer-feature.json +5 -0
- package/.devcontainer/features/lsp-servers/install.sh +7 -0
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +5 -0
- package/.devcontainer/features/mcp-qdrant/install.sh +13 -6
- package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +5 -0
- package/.devcontainer/features/mcp-reasoner/install.sh +8 -1
- package/.devcontainer/features/notify-hook/devcontainer-feature.json +5 -0
- package/.devcontainer/features/notify-hook/install.sh +7 -0
- package/.devcontainer/features/ruff/README.md +26 -0
- package/.devcontainer/features/ruff/devcontainer-feature.json +21 -0
- package/.devcontainer/features/ruff/install.sh +74 -0
- package/.devcontainer/features/shellcheck/README.md +38 -0
- package/.devcontainer/features/shellcheck/devcontainer-feature.json +13 -0
- package/.devcontainer/features/shellcheck/install.sh +24 -0
- package/.devcontainer/features/shfmt/README.md +37 -0
- package/.devcontainer/features/shfmt/devcontainer-feature.json +13 -0
- package/.devcontainer/features/shfmt/install.sh +85 -0
- package/.devcontainer/features/splitrail/devcontainer-feature.json +5 -0
- package/.devcontainer/features/splitrail/install.sh +7 -0
- package/.devcontainer/features/tmux/install.sh +8 -0
- package/.devcontainer/features/tree-sitter/install.sh +6 -0
- package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +3 -10
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/__pycache__/format-on-stop.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py +114 -9
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +4 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/__pycache__/lint-file.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +478 -76
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/AGENT-REDIRECTION.md +226 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/bash-exec.md +4 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/claude-guide.md +14 -23
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/debug-logs.md +2 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/dependency-analyst.md +2 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +13 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/explorer.md +2 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/generalist.md +10 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/migrator.md +6 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/refactorer.md +4 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +36 -23
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/statusline-config.md +3 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/test-writer.md +3 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +39 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/advisory-test-runner.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/collect-edited-files.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/commit-reminder.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/git-state-injector.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/redirect-builtin-agents.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/ticket-linker.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/todo-harvester.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +174 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/collect-edited-files.py +8 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/commit-reminder.py +90 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/git-state-injector.py +114 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/skill-suggester.py +61 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/ticket-linker.py +137 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/todo-harvester.py +130 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/SKILL.md +224 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/error-handling.md +166 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/rest-conventions.md +215 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/SKILL.md +211 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/references/language-patterns.md +327 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/SKILL.md +134 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/ecosystem-commands.md +264 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/license-compliance.md +80 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/SKILL.md +153 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/api-doc-templates.md +221 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/docstring-formats.md +296 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/SKILL.md +150 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/javascript-migrations.md +179 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/python-migrations.md +141 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +32 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/__pycache__/block-dangerous.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/__pycache__/guard-protected.cpython-314.pyc +0 -0
- package/.devcontainer/scripts/check-setup.sh +72 -0
- package/.devcontainer/scripts/setup-aliases.sh +43 -3
- package/.devcontainer/scripts/setup-auth.sh +74 -0
- package/.devcontainer/scripts/setup-config.sh +112 -22
- package/.devcontainer/scripts/setup-update-claude.sh +8 -0
- package/.devcontainer/scripts/setup.sh +46 -13
- package/README.md +23 -190
- package/package.json +1 -1
- package/setup.js +245 -71
- package/.devcontainer/features/claude-code/README.md +0 -498
- package/.devcontainer/features/claude-code/config/settings.json +0 -72
- package/.devcontainer/features/claude-code/config/system-prompt.md +0 -118
- package/.devcontainer/features/claude-code/config/world-building-sp.md +0 -1432
- package/.devcontainer/features/claude-code/devcontainer-feature.json +0 -42
- package/.devcontainer/features/claude-code/install.sh +0 -466
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +0 -7
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +0 -17
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +0 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +0 -14
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +0 -989
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +0 -33
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +0 -71
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +0 -68
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +0 -120
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +0 -133
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +0 -253
- /package/.devcontainer/config/{keybindings.json → defaults/keybindings.json} +0 -0
- /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(
|
|
4
|
-
const path = require(
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
254
|
+
main();
|
|
81
255
|
}
|
|
82
256
|
|
|
83
|
-
module.exports = { copyDirectory, main };
|
|
257
|
+
module.exports = { copyDirectory, syncDirectory, loadPreserveList, main };
|