claudeos-core 1.7.0 → 2.0.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/CHANGELOG.md +138 -0
- package/CONTRIBUTING.md +92 -59
- package/README.de.md +465 -240
- package/README.es.md +446 -223
- package/README.fr.md +461 -238
- package/README.hi.md +485 -261
- package/README.ja.md +440 -235
- package/README.ko.md +244 -56
- package/README.md +215 -47
- package/README.ru.md +462 -238
- package/README.vi.md +454 -230
- package/README.zh-CN.md +476 -252
- package/bin/cli.js +144 -140
- package/bin/commands/init.js +550 -46
- package/bin/commands/memory.js +426 -0
- package/bin/lib/cli-utils.js +206 -143
- package/bootstrap.sh +81 -390
- package/content-validator/index.js +436 -340
- package/lib/expected-guides.js +23 -0
- package/lib/expected-outputs.js +91 -0
- package/lib/language-config.js +35 -0
- package/lib/memory-scaffold.js +1014 -0
- package/lib/plan-parser.js +153 -149
- package/lib/staged-rules.js +118 -0
- package/manifest-generator/index.js +176 -171
- package/package.json +1 -1
- package/pass-json-validator/index.js +337 -299
- package/pass-prompts/templates/common/pass3-footer.md +16 -0
- package/pass-prompts/templates/common/pass4.md +317 -0
- package/pass-prompts/templates/common/staging-override.md +26 -0
- package/pass-prompts/templates/python-flask/pass1.md +119 -0
- package/pass-prompts/templates/python-flask/pass2.md +85 -0
- package/pass-prompts/templates/python-flask/pass3.md +103 -0
- package/plan-installer/domain-grouper.js +2 -1
- package/plan-installer/prompt-generator.js +120 -96
- package/plan-installer/scanners/scan-frontend.js +219 -10
- package/plan-installer/scanners/scan-java.js +226 -223
- package/plan-installer/scanners/scan-python.js +21 -0
- package/sync-checker/index.js +133 -132
package/bootstrap.sh
CHANGED
|
@@ -1,390 +1,81 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# ClaudeOS-Core — Bootstrap
|
|
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
|
-
echo ""
|
|
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
|
-
printf ' ❌ Unsupported language: "%s"\n' "$CLAUDEOS_LANG"
|
|
83
|
-
echo " Supported: ${SUPPORTED_LANGS[*]}"
|
|
84
|
-
echo ""
|
|
85
|
-
exit 1
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
export CLAUDEOS_LANG
|
|
89
|
-
export CLAUDEOS_ROOT="$PROJECT_ROOT"
|
|
90
|
-
|
|
91
|
-
# ─── Prerequisites check ──────────────────────────────────────
|
|
92
|
-
if ! command -v node &> /dev/null; then
|
|
93
|
-
echo ""
|
|
94
|
-
echo " ❌ Node.js not found."
|
|
95
|
-
echo " Install: https://nodejs.org/"
|
|
96
|
-
echo ""
|
|
97
|
-
exit 1
|
|
98
|
-
fi
|
|
99
|
-
|
|
100
|
-
NODE_MAJOR=$(node -e "console.log(process.versions.node.split('.')[0])" 2>/dev/null)
|
|
101
|
-
if ! [[ "$NODE_MAJOR" =~ ^[0-9]+$ ]] || [ "$NODE_MAJOR" -lt 18 ]; then
|
|
102
|
-
echo ""
|
|
103
|
-
echo " ❌ Node.js v18+ required (current: v$(node --version))"
|
|
104
|
-
echo " Install: https://nodejs.org/"
|
|
105
|
-
echo ""
|
|
106
|
-
exit 1
|
|
107
|
-
fi
|
|
108
|
-
|
|
109
|
-
if ! command -v claude &> /dev/null; then
|
|
110
|
-
echo ""
|
|
111
|
-
echo " ❌ Claude Code CLI not found."
|
|
112
|
-
echo " Install: https://code.claude.com/docs/en/overview"
|
|
113
|
-
echo " Then run: claude (and complete authentication)"
|
|
114
|
-
echo ""
|
|
115
|
-
exit 1
|
|
116
|
-
fi
|
|
117
|
-
|
|
118
|
-
## perl is no longer required — placeholder substitution now uses Node.js
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
echo ""
|
|
123
|
-
echo "╔════════════════════════════════════════════════════╗"
|
|
124
|
-
echo "║ ClaudeOS-Core — Bootstrap (3-Pass) ║"
|
|
125
|
-
echo "╚════════════════════════════════════════════════════╝"
|
|
126
|
-
echo " Project root: $PROJECT_ROOT"
|
|
127
|
-
# Find label for selected lang
|
|
128
|
-
for i in "${!SUPPORTED_LANGS[@]}"; do
|
|
129
|
-
if [ "${SUPPORTED_LANGS[$i]}" = "$CLAUDEOS_LANG" ]; then
|
|
130
|
-
echo " Language: ${LANG_LABELS[$i]} ($CLAUDEOS_LANG)"
|
|
131
|
-
break
|
|
132
|
-
fi
|
|
133
|
-
done
|
|
134
|
-
echo ""
|
|
135
|
-
|
|
136
|
-
# ─── [1] Install dependencies ────────────────────────────────────
|
|
137
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
138
|
-
echo "[1] Installing dependencies..."
|
|
139
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
140
|
-
cd "$TOOLS_DIR"
|
|
141
|
-
if [ ! -d "node_modules" ]; then
|
|
142
|
-
npm install --silent
|
|
143
|
-
fi
|
|
144
|
-
cd "$PROJECT_ROOT"
|
|
145
|
-
echo " ✅ Done"
|
|
146
|
-
echo ""
|
|
147
|
-
|
|
148
|
-
# ─── [2] Create directory structure ─────────────────────────────
|
|
149
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
150
|
-
echo "[2] Creating directory structure..."
|
|
151
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
152
|
-
mkdir -p .claude/rules/{00.core,10.backend,20.frontend,30.security-db,40.infra,50.sync}
|
|
153
|
-
mkdir -p claudeos-core/generated
|
|
154
|
-
mkdir -p claudeos-core/standard/{00.core,10.backend-api,20.frontend-ui,30.security-db,40.infra,50.verification,90.optional}
|
|
155
|
-
mkdir -p claudeos-core/skills/{00.shared,10.backend-crud/scaffold-crud-feature,20.frontend-page/scaffold-page-feature,50.testing,90.experimental}
|
|
156
|
-
mkdir -p claudeos-core/plan
|
|
157
|
-
mkdir -p claudeos-core/guide/{01.onboarding,02.usage,03.troubleshooting,04.architecture}
|
|
158
|
-
mkdir -p claudeos-core/database
|
|
159
|
-
mkdir -p claudeos-core/mcp-guide
|
|
160
|
-
echo " ✅ Done"
|
|
161
|
-
echo ""
|
|
162
|
-
|
|
163
|
-
# ─── [3] Run plan-installer (project analysis) ────────────
|
|
164
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
165
|
-
echo "[3] Analyzing project (plan-installer)..."
|
|
166
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
167
|
-
node "$TOOLS_DIR/plan-installer/index.js"
|
|
168
|
-
echo ""
|
|
169
|
-
|
|
170
|
-
# ─── Resume / Fresh selection ────────────────────────────
|
|
171
|
-
PASS1_EXISTING=$(ls -1 "$GENERATED_DIR"/pass1-*.json 2>/dev/null | wc -l | tr -d ' ')
|
|
172
|
-
PASS2_EXISTING=false
|
|
173
|
-
[ -f "$GENERATED_DIR/pass2-merged.json" ] && PASS2_EXISTING=true
|
|
174
|
-
|
|
175
|
-
if [ "$PASS1_EXISTING" -gt 0 ] || [ "$PASS2_EXISTING" = true ]; then
|
|
176
|
-
PASS2_LABEL="✗"
|
|
177
|
-
[ "$PASS2_EXISTING" = true ] && PASS2_LABEL="✓"
|
|
178
|
-
if [ "$CLAUDEOS_FORCE" = true ]; then
|
|
179
|
-
rm -f "$GENERATED_DIR"/pass1-*.json "$GENERATED_DIR"/pass2-merged.json
|
|
180
|
-
echo " 🔄 Previous results deleted (--force)"
|
|
181
|
-
echo ""
|
|
182
|
-
else
|
|
183
|
-
echo ""
|
|
184
|
-
echo " ⚠️ Previous analysis found (pass1: ${PASS1_EXISTING} completed, pass2: ${PASS2_LABEL})"
|
|
185
|
-
echo ""
|
|
186
|
-
echo " 1. Continue — Resume from where it stopped"
|
|
187
|
-
echo " 2. Fresh — Delete all and start over"
|
|
188
|
-
echo ""
|
|
189
|
-
read -rp " Enter number (1-2): " RESUME_CHOICE
|
|
190
|
-
if [ "$RESUME_CHOICE" = "2" ]; then
|
|
191
|
-
rm -f "$GENERATED_DIR"/pass1-*.json "$GENERATED_DIR"/pass2-merged.json
|
|
192
|
-
echo " 🔄 Previous results deleted"
|
|
193
|
-
fi
|
|
194
|
-
echo ""
|
|
195
|
-
fi
|
|
196
|
-
fi
|
|
197
|
-
|
|
198
|
-
# ─── [4] Pass 1: Deep analysis per domain group (multi-stack) ──────────
|
|
199
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
200
|
-
echo "[4] Pass 1 — Deep analysis per domain group..."
|
|
201
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
202
|
-
|
|
203
|
-
# Read groups from domain-groups.json
|
|
204
|
-
TOTAL_GROUPS=$(node -e "
|
|
205
|
-
const g = require(process.argv[1]);
|
|
206
|
-
console.log(g.totalGroups);
|
|
207
|
-
" "$GENERATED_DIR/domain-groups.json")
|
|
208
|
-
|
|
209
|
-
# Validate TOTAL_GROUPS is a positive integer
|
|
210
|
-
if ! [[ "$TOTAL_GROUPS" =~ ^[0-9]+$ ]] || [ "$TOTAL_GROUPS" -lt 1 ]; then
|
|
211
|
-
echo " ❌ Invalid TOTAL_GROUPS: '${TOTAL_GROUPS}'. domain-groups.json may be malformed."
|
|
212
|
-
exit 1
|
|
213
|
-
fi
|
|
214
|
-
|
|
215
|
-
for i in $(seq 1 "$TOTAL_GROUPS"); do
|
|
216
|
-
DOMAIN_LIST=$(node -e "
|
|
217
|
-
const g = require(process.argv[1]);
|
|
218
|
-
console.log(g.groups[process.argv[2] - 1].domains.join(', '));
|
|
219
|
-
" "$GENERATED_DIR/domain-groups.json" "$i")
|
|
220
|
-
EST_FILES=$(node -e "
|
|
221
|
-
const g = require(process.argv[1]);
|
|
222
|
-
console.log(g.groups[process.argv[2] - 1].estimatedFiles);
|
|
223
|
-
" "$GENERATED_DIR/domain-groups.json" "$i")
|
|
224
|
-
GROUP_TYPE=$(node -e "
|
|
225
|
-
const g = require(process.argv[1]);
|
|
226
|
-
console.log(g.groups[process.argv[2] - 1].type || 'backend');
|
|
227
|
-
" "$GENERATED_DIR/domain-groups.json" "$i")
|
|
228
|
-
|
|
229
|
-
echo ""
|
|
230
|
-
echo " [Pass 1-${i}/${TOTAL_GROUPS}] (${GROUP_TYPE}) Analyzing: ${DOMAIN_LIST} (~${EST_FILES} files)"
|
|
231
|
-
|
|
232
|
-
# Skip already completed passes
|
|
233
|
-
if [ -f "$GENERATED_DIR/pass1-${i}.json" ]; then
|
|
234
|
-
echo " ⏭️ pass1-${i}.json already exists, skipping"
|
|
235
|
-
continue
|
|
236
|
-
fi
|
|
237
|
-
|
|
238
|
-
# Select prompt by type
|
|
239
|
-
PROMPT_FILE="$GENERATED_DIR/pass1-${GROUP_TYPE}-prompt.md"
|
|
240
|
-
if [ ! -f "$PROMPT_FILE" ]; then
|
|
241
|
-
PROMPT_FILE="$GENERATED_DIR/pass1-prompt.md"
|
|
242
|
-
fi
|
|
243
|
-
# Substitute placeholders via temp file (uses Node.js for safe literal replacement)
|
|
244
|
-
TMP_PROMPT="$GENERATED_DIR/_tmp_pass1_prompt.md"
|
|
245
|
-
cp "$PROMPT_FILE" "$TMP_PROMPT"
|
|
246
|
-
export _DOMAIN_LIST="$DOMAIN_LIST"
|
|
247
|
-
export _PASS_NUM="$i"
|
|
248
|
-
export _PROJECT_ROOT="$PROJECT_ROOT"
|
|
249
|
-
node -e "
|
|
250
|
-
const fs = require('fs');
|
|
251
|
-
let c = fs.readFileSync(process.argv[1], 'utf8');
|
|
252
|
-
c = c.replace(/\{\{DOMAIN_GROUP\}\}/g, process.env._DOMAIN_LIST);
|
|
253
|
-
c = c.replace(/\{\{PASS_NUM\}\}/g, process.env._PASS_NUM);
|
|
254
|
-
c = c.replace(/\{\{PROJECT_ROOT\}\}/g, process.env._PROJECT_ROOT);
|
|
255
|
-
fs.writeFileSync(process.argv[1], c);
|
|
256
|
-
" "$TMP_PROMPT"
|
|
257
|
-
|
|
258
|
-
echo " ⏳ [Pass 1-${i}/${TOTAL_GROUPS}] Running claude -p (no output is normal, please wait)..."
|
|
259
|
-
if ! (cd "$PROJECT_ROOT" && cat "$TMP_PROMPT" | claude -p --dangerously-skip-permissions); then
|
|
260
|
-
rm -f "$TMP_PROMPT"
|
|
261
|
-
echo " ❌ Pass 1-${i} failed. Aborting."
|
|
262
|
-
exit 1
|
|
263
|
-
fi
|
|
264
|
-
rm -f "$TMP_PROMPT"
|
|
265
|
-
|
|
266
|
-
# Verify JSON was created
|
|
267
|
-
if [ ! -f "$GENERATED_DIR/pass1-${i}.json" ]; then
|
|
268
|
-
echo " ❌ pass1-${i}.json was not created. Aborting."
|
|
269
|
-
exit 1
|
|
270
|
-
fi
|
|
271
|
-
|
|
272
|
-
echo " ✅ pass1-${i}.json created"
|
|
273
|
-
done
|
|
274
|
-
unset _DOMAIN_LIST _PASS_NUM _PROJECT_ROOT
|
|
275
|
-
echo ""
|
|
276
|
-
|
|
277
|
-
# ─── [5] Pass 2: Merge analysis results ─────────────────────────
|
|
278
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
279
|
-
echo "[5] Pass 2 — Merging analysis results..."
|
|
280
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
281
|
-
|
|
282
|
-
if [ -f "$GENERATED_DIR/pass2-merged.json" ]; then
|
|
283
|
-
echo " ⏭️ pass2-merged.json already exists, skipping"
|
|
284
|
-
else
|
|
285
|
-
TMP_PASS2="$GENERATED_DIR/_tmp_pass2_prompt.md"
|
|
286
|
-
export _PROJECT_ROOT="$PROJECT_ROOT"
|
|
287
|
-
node -e "
|
|
288
|
-
const fs = require('fs');
|
|
289
|
-
let c = fs.readFileSync(process.argv[1], 'utf8');
|
|
290
|
-
c = c.replace(/\{\{PROJECT_ROOT\}\}/g, process.env._PROJECT_ROOT);
|
|
291
|
-
fs.writeFileSync(process.argv[2], c);
|
|
292
|
-
" "$GENERATED_DIR/pass2-prompt.md" "$TMP_PASS2"
|
|
293
|
-
|
|
294
|
-
echo " ⏳ [Pass 2] Running claude -p (no output is normal, please wait)..."
|
|
295
|
-
if ! (cd "$PROJECT_ROOT" && cat "$TMP_PASS2" | claude -p --dangerously-skip-permissions); then
|
|
296
|
-
rm -f "$TMP_PASS2"
|
|
297
|
-
echo " ❌ Pass 2 failed. Aborting."
|
|
298
|
-
exit 1
|
|
299
|
-
fi
|
|
300
|
-
rm -f "$TMP_PASS2"
|
|
301
|
-
|
|
302
|
-
if [ ! -f "$GENERATED_DIR/pass2-merged.json" ]; then
|
|
303
|
-
echo " ❌ pass2-merged.json was not created. Aborting."
|
|
304
|
-
exit 1
|
|
305
|
-
fi
|
|
306
|
-
|
|
307
|
-
echo " ✅ pass2-merged.json created"
|
|
308
|
-
fi
|
|
309
|
-
echo ""
|
|
310
|
-
|
|
311
|
-
# ─── [6] Pass 3: Generate + Master Plan build + verification ────────
|
|
312
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
313
|
-
echo "[6] Pass 3 — Generating all files..."
|
|
314
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
315
|
-
TMP_PASS3="$GENERATED_DIR/_tmp_pass3_prompt.md"
|
|
316
|
-
export _PROJECT_ROOT="$PROJECT_ROOT"
|
|
317
|
-
node -e "
|
|
318
|
-
const fs = require('fs');
|
|
319
|
-
let c = fs.readFileSync(process.argv[1], 'utf8');
|
|
320
|
-
c = c.replace(/\{\{PROJECT_ROOT\}\}/g, process.env._PROJECT_ROOT);
|
|
321
|
-
fs.writeFileSync(process.argv[2], c);
|
|
322
|
-
" "$GENERATED_DIR/pass3-prompt.md" "$TMP_PASS3"
|
|
323
|
-
|
|
324
|
-
echo " ⏳ [Pass 3] Running claude -p (no output is normal, please wait)..."
|
|
325
|
-
if ! (cd "$PROJECT_ROOT" && cat "$TMP_PASS3" | claude -p --dangerously-skip-permissions); then
|
|
326
|
-
rm -f "$TMP_PASS3"
|
|
327
|
-
echo " ❌ Pass 3 failed. Aborting."
|
|
328
|
-
exit 1
|
|
329
|
-
fi
|
|
330
|
-
rm -f "$TMP_PASS3"
|
|
331
|
-
|
|
332
|
-
if [ ! -f "$PROJECT_ROOT/CLAUDE.md" ]; then
|
|
333
|
-
echo " ❌ CLAUDE.md was not created. Pass 3 may have failed silently."
|
|
334
|
-
exit 1
|
|
335
|
-
fi
|
|
336
|
-
unset _PROJECT_ROOT
|
|
337
|
-
echo ""
|
|
338
|
-
|
|
339
|
-
# ─── [7] Run verification tools ───────────────────────────────
|
|
340
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
341
|
-
echo "[7] Running verification tools..."
|
|
342
|
-
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
343
|
-
|
|
344
|
-
if [ -f "$TOOLS_DIR/manifest-generator/index.js" ]; then
|
|
345
|
-
echo -n " ⏳ manifest-generator..."
|
|
346
|
-
if node "$TOOLS_DIR/manifest-generator/index.js" > /dev/null 2>&1; then
|
|
347
|
-
echo " ✅"
|
|
348
|
-
else
|
|
349
|
-
echo " ❌ (non-fatal)"
|
|
350
|
-
fi
|
|
351
|
-
fi
|
|
352
|
-
|
|
353
|
-
if [ -f "$TOOLS_DIR/health-checker/index.js" ]; then
|
|
354
|
-
echo -n " ⏳ health-checker..."
|
|
355
|
-
if node "$TOOLS_DIR/health-checker/index.js" > /dev/null 2>&1; then
|
|
356
|
-
echo " ✅"
|
|
357
|
-
else
|
|
358
|
-
echo " ⚠️ issues found (non-fatal)"
|
|
359
|
-
fi
|
|
360
|
-
fi
|
|
361
|
-
echo ""
|
|
362
|
-
|
|
363
|
-
# ─── Complete ───────────────────────────────────────────────
|
|
364
|
-
TOTAL_FILES=$(find .claude claudeos-core -type f 2>/dev/null | grep -v '/node_modules/' | grep -v '/generated/' | wc -l | tr -d ' ')
|
|
365
|
-
TOTAL_GROUPS_DONE=$TOTAL_GROUPS
|
|
366
|
-
PASS1_FILES=$(ls -1 "$GENERATED_DIR"/pass1-*.json 2>/dev/null | wc -l | tr -d ' ')
|
|
367
|
-
|
|
368
|
-
echo ""
|
|
369
|
-
echo "╔════════════════════════════════════════════════════╗"
|
|
370
|
-
echo "║ ✅ ClaudeOS-Core — Complete ║"
|
|
371
|
-
echo "║ ║"
|
|
372
|
-
printf "║ Files created: %-29s║\n" "${TOTAL_FILES}"
|
|
373
|
-
printf "║ Domains analyzed: %-29s║\n" "${TOTAL_GROUPS_DONE} groups"
|
|
374
|
-
printf "║ Analysis passes: %-29s║\n" "${PASS1_FILES} pass1 files"
|
|
375
|
-
# Find label for selected lang
|
|
376
|
-
LANG_LABEL="$CLAUDEOS_LANG"
|
|
377
|
-
for i in "${!SUPPORTED_LANGS[@]}"; do
|
|
378
|
-
if [ "${SUPPORTED_LANGS[$i]}" = "$CLAUDEOS_LANG" ]; then
|
|
379
|
-
LANG_LABEL="${LANG_LABELS[$i]}"; break
|
|
380
|
-
fi
|
|
381
|
-
done
|
|
382
|
-
printf "║ Output language: %-29s║\n" "${LANG_LABEL}"
|
|
383
|
-
echo "║ ║"
|
|
384
|
-
echo "║ Verify anytime: ║"
|
|
385
|
-
echo "║ npx claudeos-core health ║"
|
|
386
|
-
echo "║ ║"
|
|
387
|
-
echo "║ Start using: ║"
|
|
388
|
-
echo "║ \"Create a CRUD for orders\" ║"
|
|
389
|
-
echo "╚════════════════════════════════════════════════════╝"
|
|
390
|
-
echo ""
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# ClaudeOS-Core — Bootstrap
|
|
4
|
+
#
|
|
5
|
+
# Thin wrapper that forwards to `node bin/cli.js init`.
|
|
6
|
+
#
|
|
7
|
+
# The full init pipeline (plan-installer, Pass 1 multi-group, Pass 2 merge,
|
|
8
|
+
# Pass 3 file generation, Pass 4 memory scaffolding, verification) is
|
|
9
|
+
# implemented in bin/commands/init.js — this script just ensures Node.js
|
|
10
|
+
# is available, installs npm dependencies on first run, and delegates.
|
|
11
|
+
#
|
|
12
|
+
# Why delegation instead of reimplementing the pipeline in bash:
|
|
13
|
+
# - init.js supports features this script does not (and cannot reasonably
|
|
14
|
+
# reimplement): --lang (10 languages), --resume (interrupted init
|
|
15
|
+
# recovery), Pass 4 memory scaffolding with translated fallback,
|
|
16
|
+
# progress bar with ETA, stale-marker detection, clear error messages.
|
|
17
|
+
# - A single source of truth (init.js) prevents the two code paths from
|
|
18
|
+
# drifting, which was the cause of bug #21's cousin: bootstrap.sh was
|
|
19
|
+
# still advertising "3-Pass" while the CLI had moved to 4-Pass with
|
|
20
|
+
# persistent memory scaffolding.
|
|
21
|
+
#
|
|
22
|
+
# Prerequisites:
|
|
23
|
+
# - bash (this script), node (v18+), claude CLI (for the init pipeline)
|
|
24
|
+
#
|
|
25
|
+
# Usage:
|
|
26
|
+
# bash claudeos-core-tools/bootstrap.sh # interactive lang pick
|
|
27
|
+
# bash claudeos-core-tools/bootstrap.sh --lang ko # Korean
|
|
28
|
+
# bash claudeos-core-tools/bootstrap.sh --lang en --force # fresh English init
|
|
29
|
+
#
|
|
30
|
+
# Cross-platform alternative (recommended):
|
|
31
|
+
# npx claudeos-core init
|
|
32
|
+
# node claudeos-core-tools/bin/cli.js init
|
|
33
|
+
|
|
34
|
+
if [ -z "$BASH_VERSION" ]; then
|
|
35
|
+
echo "❌ This script requires bash. Run with: bash $0" >&2
|
|
36
|
+
exit 1
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
set -e
|
|
40
|
+
|
|
41
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
42
|
+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
43
|
+
TOOLS_DIR="$SCRIPT_DIR"
|
|
44
|
+
|
|
45
|
+
cd "$PROJECT_ROOT"
|
|
46
|
+
|
|
47
|
+
# ─── Prerequisites check ──────────────────────────────────────
|
|
48
|
+
if ! command -v node >/dev/null 2>&1; then
|
|
49
|
+
echo "❌ node is required but not found in PATH. Install Node.js 18+ and re-run." >&2
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)"
|
|
54
|
+
if [ "$NODE_MAJOR" -lt 18 ]; then
|
|
55
|
+
echo "❌ Node.js 18+ required (found v$(node -v 2>/dev/null))." >&2
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if ! command -v claude >/dev/null 2>&1; then
|
|
60
|
+
echo "⚠️ \`claude\` CLI not found in PATH. The init pipeline requires it." >&2
|
|
61
|
+
echo " Install & sign in: https://docs.claude.com/en/docs/claude-code/overview" >&2
|
|
62
|
+
# Don't exit — let init.js surface the exact point of failure with context.
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# ─── [1/2] Ensure npm dependencies ────────────────────────────
|
|
66
|
+
# init.js requires glob + gray-matter. If node_modules is missing (first
|
|
67
|
+
# bootstrap run for a freshly-cloned tools directory), install them.
|
|
68
|
+
if [ ! -d "$TOOLS_DIR/node_modules" ]; then
|
|
69
|
+
echo "[1/2] Installing dependencies (first bootstrap run)..."
|
|
70
|
+
(cd "$TOOLS_DIR" && npm install --silent --no-audit --no-fund) || {
|
|
71
|
+
echo "❌ npm install failed. Check network / npm registry access." >&2
|
|
72
|
+
exit 1
|
|
73
|
+
}
|
|
74
|
+
echo " ✅ Dependencies installed"
|
|
75
|
+
echo
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# ─── [2/2] Delegate to the CLI ────────────────────────────────
|
|
79
|
+
echo "[2/2] Running ClaudeOS-Core init..."
|
|
80
|
+
echo
|
|
81
|
+
exec node "$TOOLS_DIR/bin/cli.js" init "$@"
|