claudeos-core 2.4.3 → 2.5.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 +93 -0
- package/README.de.md +9 -9
- package/README.es.md +9 -9
- package/README.fr.md +9 -9
- package/README.hi.md +10 -10
- package/README.ja.md +9 -9
- package/README.ko.md +10 -10
- package/README.md +9 -9
- package/README.ru.md +9 -9
- package/README.vi.md +9 -9
- package/README.zh-CN.md +9 -9
- package/bin/commands/init.js +121 -24
- package/bin/commands/lint.js +2 -0
- package/bin/commands/memory.js +10 -3
- package/content-validator/index.js +82 -13
- package/lib/env-parser.js +50 -12
- package/lib/memory-scaffold.js +35 -16
- package/manifest-generator/index.js +15 -4
- package/package.json +1 -1
- package/pass-prompts/templates/angular/pass3.md +2 -1
- package/pass-prompts/templates/common/claude-md-scaffold.md +1 -1
- package/pass-prompts/templates/common/pass3a-facts.md +11 -9
- package/pass-prompts/templates/common/pass4.md +3 -3
- package/pass-prompts/templates/java-spring/pass3.md +3 -3
- package/pass-prompts/templates/kotlin-spring/pass3.md +2 -2
- package/pass-prompts/templates/node-express/pass3.md +1 -1
- package/pass-prompts/templates/node-fastify/pass3.md +1 -0
- package/pass-prompts/templates/node-nestjs/pass3.md +1 -0
- package/pass-prompts/templates/node-nextjs/pass3.md +1 -1
- package/pass-prompts/templates/node-vite/pass3.md +1 -0
- package/pass-prompts/templates/python-django/pass3.md +1 -1
- package/pass-prompts/templates/python-fastapi/pass3.md +1 -1
- package/pass-prompts/templates/python-flask/pass3.md +1 -0
- package/pass-prompts/templates/vue-nuxt/pass3.md +1 -0
- package/plan-installer/domain-grouper.js +4 -1
- package/plan-installer/index.js +26 -7
- package/plan-installer/pass3-context-builder.js +10 -0
- package/plan-installer/prompt-generator.js +18 -2
- package/plan-installer/scanners/scan-frontend.js +67 -6
- package/plan-installer/scanners/scan-java.js +145 -14
- package/plan-installer/scanners/scan-kotlin.js +68 -3
- package/plan-installer/scanners/scan-node.js +115 -0
- package/plan-installer/scanners/scan-python.js +56 -0
- package/plan-installer/source-paths.js +61 -0
- package/plan-installer/stack-detector.js +262 -24
- package/plan-installer/structure-scanner.js +15 -4
package/lib/memory-scaffold.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
const path = require("path");
|
|
12
12
|
const fs = require("fs");
|
|
13
|
+
const crypto = require("crypto");
|
|
13
14
|
const { ensureDir, existsSafe, writeFileSafe, readFileSafe } = require("./safe-fs");
|
|
14
15
|
|
|
15
16
|
// ─── Language labels — single source of truth: lib/language-config.js ──
|
|
@@ -58,6 +59,18 @@ function writeCache(cacheFile, cache) {
|
|
|
58
59
|
} catch (_e) { /* best-effort */ }
|
|
59
60
|
}
|
|
60
61
|
|
|
62
|
+
// v2.5.0 — Cache entries are keyed by content name AND a hash of the English
|
|
63
|
+
// source. Pre-v2.5.0 the key was the bare name (`MEMORY_FILES.compaction.md`),
|
|
64
|
+
// so whenever a static-fallback text changed between releases, a project that
|
|
65
|
+
// already had `fallback-cache-<lang>.json` kept serving the translation of the
|
|
66
|
+
// OLD English text forever. Hashing the source makes a text change a cache
|
|
67
|
+
// miss automatically; stale entries under the old key shape are simply never
|
|
68
|
+
// read again.
|
|
69
|
+
function cacheKeyFor(contentKey, englishContent) {
|
|
70
|
+
const h = crypto.createHash("sha1").update(String(englishContent), "utf8").digest("hex").slice(0, 12);
|
|
71
|
+
return `${contentKey}@${h}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
61
74
|
// Translate English static content to the requested language via Claude CLI.
|
|
62
75
|
//
|
|
63
76
|
// Behavior contract:
|
|
@@ -81,6 +94,15 @@ function translateIfNeeded(englishContent, lang, contentKey, cacheFile) {
|
|
|
81
94
|
);
|
|
82
95
|
}
|
|
83
96
|
|
|
97
|
+
// Cache hit → return immediately. Checked BEFORE the env-skip below: a hit
|
|
98
|
+
// never shells out, so the skip has nothing to prevent, and this keeps the
|
|
99
|
+
// cache path unit-testable under CLAUDEOS_SKIP_TRANSLATION=1.
|
|
100
|
+
const cache = readCache(cacheFile);
|
|
101
|
+
const key = cacheKeyFor(contentKey, englishContent);
|
|
102
|
+
if (cache[key] && typeof cache[key] === "string" && cache[key].trim().length > 0) {
|
|
103
|
+
return cache[key];
|
|
104
|
+
}
|
|
105
|
+
|
|
84
106
|
// M2: CI / deterministic-test escape hatch. When
|
|
85
107
|
// CLAUDEOS_SKIP_TRANSLATION=1 is set, throw instead of shelling out to
|
|
86
108
|
// `claude -p`. This makes the "translation fails without real Claude CLI"
|
|
@@ -95,12 +117,6 @@ function translateIfNeeded(englishContent, lang, contentKey, cacheFile) {
|
|
|
95
117
|
);
|
|
96
118
|
}
|
|
97
119
|
|
|
98
|
-
// Cache hit → return immediately
|
|
99
|
-
const cache = readCache(cacheFile);
|
|
100
|
-
if (cache[contentKey] && typeof cache[contentKey] === "string" && cache[contentKey].trim().length > 0) {
|
|
101
|
-
return cache[contentKey];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
120
|
// Lazy-load CLI utils to avoid a circular dependency at module-load time.
|
|
105
121
|
let runClaudeCapture;
|
|
106
122
|
try {
|
|
@@ -256,8 +272,9 @@ Translate now. Output only the translated document.`;
|
|
|
256
272
|
);
|
|
257
273
|
}
|
|
258
274
|
|
|
259
|
-
// Success — save to cache for future init runs
|
|
260
|
-
|
|
275
|
+
// Success — save to cache for future init runs (content-hashed key; must
|
|
276
|
+
// be recomputed here — this function does not share translateIfNeeded's scope).
|
|
277
|
+
cache[cacheKeyFor(contentKey, englishContent)] = cleaned;
|
|
261
278
|
writeCache(cacheFile, cache);
|
|
262
279
|
|
|
263
280
|
const elapsed = ((Date.now() - t0) / 1000).toFixed(1);
|
|
@@ -282,7 +299,7 @@ _Format: \`## <pattern-id>\` with Frequency / Last Seen / Importance / Fix._
|
|
|
282
299
|
|
|
283
300
|
"compaction.md": `# Compaction Strategy
|
|
284
301
|
|
|
285
|
-
_4-stage compaction rules for \`decision-log.md\` and
|
|
302
|
+
_4-stage compaction rules for \`failure-patterns.md\`. \`decision-log.md\` is append-only and never compacted._
|
|
286
303
|
_Run via \`npx claudeos-core memory compact\`._
|
|
287
304
|
|
|
288
305
|
## Preservation Priority
|
|
@@ -431,8 +448,8 @@ Before analysis or evaluation, review this table and do not repeat these pattern
|
|
|
431
448
|
| 8 | Making quantitative judgments based on unverified numbers, then reversing when challenged | No speculation-based quantitative claims |
|
|
432
449
|
| 9 | Judging a standard document as "low practical value" without reading it | No judgment before verification |
|
|
433
450
|
| 10 | Proposing to merge/reduce same-layer intentional duplication | Different perspectives on the same topic in different files is intentional. Rule accessibility > token saving |
|
|
434
|
-
| 11 | Suggesting an import or package name without verifying it exists in the dependency manifest | Hallucinated module/named export. Verify by reading \`package.json\` / \`pom.xml\` / \`build.gradle\` / \`pyproject.toml\` / \`requirements.txt\` before recommending an import |
|
|
435
|
-
| 12 | Mixing API signatures from different major versions of the same library | Verify by checking the manifest AND lockfile for the exact installed version (lockfile pins the truth): \`package-lock.json\`/\`pnpm-lock.yaml\`/\`yarn.lock\`, \`gradle.lockfile\`/\`gradle/libs.versions.toml\`, \`poetry.lock\`/\`Pipfile.lock\`/\`uv.lock\`, or fall back to the manifest (\`pom.xml\`/\`build.gradle\`/\`package.json\`/\`pyproject.toml\`) |
|
|
451
|
+
| 11 | Suggesting an import or package name without verifying it exists in the dependency manifest | Hallucinated module/named export. Verify by reading \`package.json\` / \`pom.xml\` / \`build.gradle\` / \`build.gradle.kts\` / \`pyproject.toml\` / \`requirements.txt\` before recommending an import |
|
|
452
|
+
| 12 | Mixing API signatures from different major versions of the same library | Verify by checking the manifest AND lockfile for the exact installed version (lockfile pins the truth): \`package-lock.json\`/\`pnpm-lock.yaml\`/\`yarn.lock\`, \`gradle.lockfile\`/\`gradle/libs.versions.toml\`, \`poetry.lock\`/\`Pipfile.lock\`/\`uv.lock\`, or fall back to the manifest (\`pom.xml\`/\`build.gradle\`/\`build.gradle.kts\`/\`package.json\`/\`pyproject.toml\`) |
|
|
436
453
|
| 13 | Editing one environment config file without checking sibling parity | Verify by \`Glob\` for the config family before a partial edit. Backend: \`.env*\`, \`application-*.yml/.properties\`, \`*settings.py\`. Frontend: \`environment*.ts\` (Angular), \`next.config.*\`, \`vite.config.*\`, \`nuxt.config.*\`, \`.env.local\`/\`.env.production\` |
|
|
437
454
|
| 14 | Mixing server/client component boundaries (SSR frameworks) — using client-only APIs (\`useState\`, \`useEffect\`, \`window\`, \`localStorage\`) in a server component, or server-only operations (DB access, secret reads, filesystem) in a client component | Read the file's boundary directive before adding code: Next.js App Router (\`"use client"\` opt-in), Nuxt (server vs client composables), Remix (\`loader\`/\`action\` exports). N/A for pure SPA or pure backend projects |
|
|
438
455
|
| 15 | Inventing component prop names or function arguments without reading the target's interface | Read the target's prop type definition (\`interface Props\`, \`defineProps<>\`, function signature) or method signature before invoking. Hallucinated props may compile in loose-TS code and crash at runtime |
|
|
@@ -450,9 +467,8 @@ Before analysis or evaluation, review this table and do not repeat these pattern
|
|
|
450
467
|
- **Do not modify onboarding/guide documents (\`claudeos-core/guide/\`) unless specifically requested.**
|
|
451
468
|
- Do not clean up surrounding code during bug fixes, or add unnecessary refactoring during feature additions.
|
|
452
469
|
- **Empty directories may be intentional placeholders — verify markers before flagging or removing.** Markers of intent: a \`.gitkeep\` / \`KEEP_EMPTY.md\` file inside, the directory listed in CLAUDE.md as planned, or referenced by an active plan/standard/skills document. If none of these exist, an empty directory may be neglect — ask the user before deleting.
|
|
453
|
-
- **\`plan/\` master documents are internal sync management tools.** Do not suggest removing them. "DO NOT Read" means "AI should not read directly", not "the file is unnecessary".
|
|
454
470
|
- **Do not duplicate into memory what is already directly verifiable in code, config files, or rule documents.** Configuration values, paths, and names already recorded in CLAUDE.md, rules, or standard must not be redundantly stored in memory. Examples — backend: port numbers, pool sizes, handler names, transaction propagation modes; frontend: dev server port, build output dir, env var prefix (\`VITE_\`/\`NEXT_PUBLIC_\`/\`REACT_APP_\`), route definitions, bundle size budgets.
|
|
455
|
-
- **Do not directly read internal document directories (\`guide/\`, \`
|
|
471
|
+
- **Do not directly read internal document directories (\`guide/\`, \`generated/\`, \`mcp-guide/\`) for routine context loading.** \`.claude/rules/\` and \`claudeos-core/standard/\` already contain the essential content. *Exception: read directly when the user explicitly asks about these contents, or when debugging an issue requires inspecting them.*
|
|
456
472
|
- **Established codebase conventions take precedence over textbook-ideal patterns.** Propose modernization, refactoring, or "current best practices" migration ONLY when the user explicitly requests it (e.g., "modernize", "migrate to v3", "refactor to current best practices"). Otherwise, follow the existing pattern even if you would write it differently in a greenfield project.
|
|
457
473
|
|
|
458
474
|
## Project Architecture — Hands Off
|
|
@@ -464,7 +480,7 @@ This project uses the CLAUDE.md → rules → standard 3-layer architecture, plu
|
|
|
464
480
|
- **Memory (\`claudeos-core/memory/\`, on-demand) and Rules (\`.claude/rules/\`, auto-loaded by path match) are never simultaneously loaded by default.** Similar content between them is NOT duplication. Do not propose "memory cleanup", "dedupe memory vs rules", or "consolidate memory into rules" — they have different roles (on-demand history/context vs auto-loaded enforcement).
|
|
465
481
|
- **Multi-rule load provides reinforcement.** Do not label co-loaded defensive rules as "redundant" — the reinforcement effect is intentional and the context cost is negligible.
|
|
466
482
|
- **Rules \`paths: ["**/*"]\` — do not propose conditional path conversion for core rules.** When developing new features (no matching files exist yet), conditional paths would prevent rules from loading, risking non-standard code generation.
|
|
467
|
-
- **\`00.standard-reference.md\`
|
|
483
|
+
- **\`00.standard-reference.md\` is a paths-only index of \`claudeos-core/standard/\`.** When a standard file is added, add its path there (one line, no description). Do not add rule files, skill files, memory files, or "DO NOT Read" lists to it — those belong elsewhere, and every extra line is reloaded on every edit.
|
|
468
484
|
- **Minor wording or item count differences across layers are NOT "inconsistency risks".** If no information is missing, trivial expression differences are not a problem.
|
|
469
485
|
|
|
470
486
|
## Planned References — No "Missing" Judgment
|
|
@@ -577,8 +593,8 @@ paths:
|
|
|
577
593
|
|
|
578
594
|
# Compaction Strategy (\`memory/compaction.md\`)
|
|
579
595
|
|
|
580
|
-
Reference document defining the 4-stage compaction policy.
|
|
581
|
-
Executed by \`npx claudeos-core memory compact\`.
|
|
596
|
+
Reference document defining the 4-stage compaction policy for \`failure-patterns.md\`.
|
|
597
|
+
Executed by \`npx claudeos-core memory compact\`. \`decision-log.md\` is never compacted (append-only).
|
|
582
598
|
|
|
583
599
|
## Rules
|
|
584
600
|
|
|
@@ -1055,4 +1071,7 @@ module.exports = {
|
|
|
1055
1071
|
scaffoldMasterPlans,
|
|
1056
1072
|
scaffoldDocWritingGuide,
|
|
1057
1073
|
scaffoldSkillsManifest,
|
|
1074
|
+
// Exported for test visibility (v2.5.0: content-hashed translation cache).
|
|
1075
|
+
translateIfNeeded,
|
|
1076
|
+
_cacheKeyFor: cacheKeyFor,
|
|
1058
1077
|
};
|
|
@@ -166,10 +166,21 @@ async function main() {
|
|
|
166
166
|
// Deterministically reconcile MANIFEST.md ↔ CLAUDE.md §6 cross-references
|
|
167
167
|
// that LLM stages routinely drift on. Failure here is logged but not
|
|
168
168
|
// fatal — manifest-generator's primary outputs above are already on disk.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
//
|
|
170
|
+
// OPT-IN ONLY. This step WRITES to CLAUDE.md and MANIFEST.md. It must not
|
|
171
|
+
// run from `npx claudeos-core health` (documented as a read-only gate that
|
|
172
|
+
// users wire into CI / pre-commit) — a health check that dirties the
|
|
173
|
+
// working tree is a trap. `init` passes `--sync-skills` after Pass 3/4;
|
|
174
|
+
// everything else gets a pure metadata generation run. The flag is the ONLY
|
|
175
|
+
// switch — an environment variable would be inherited by `health`'s child
|
|
176
|
+
// process and silently re-enable writes from a shell that exported it.
|
|
177
|
+
const syncRequested = process.argv.includes("--sync-skills");
|
|
178
|
+
if (syncRequested) {
|
|
179
|
+
try {
|
|
180
|
+
syncSkillsCatalog(ROOT);
|
|
181
|
+
} catch (e) {
|
|
182
|
+
console.log(` ⚠️ skills-sync: unexpected error (${e.message || e})`);
|
|
183
|
+
}
|
|
173
184
|
}
|
|
174
185
|
|
|
175
186
|
// ─── Initialize stale-report.json (preserve existing sub-tool results) ──
|
package/package.json
CHANGED
|
@@ -85,6 +85,7 @@ Generation targets:
|
|
|
85
85
|
- `60.memory/*` rules: forward reference — Pass 4 will generate 4 files (01.decision-log, 02.failure-patterns, 03.compaction, 04.auto-rule-update), each with file-specific `paths`. Pass 3 must STILL list ```.claude/rules/60.memory/*``` as a row in CLAUDE.md Section 6 Rules table so developers/Claude see the category exists.
|
|
86
86
|
- `70.domains/*` rules (multi-domain projects only): per-domain rules at `.claude/rules/70.domains/{type}/{domain}-rules.md` (where `{type}` is `backend` or `frontend`, ALWAYS present even in single-stack projects for uniform layout + zero-migration future-proofing), each with a `paths:` glob scoped to that domain's source directories so the rule auto-loads only when editing files within the relevant domain. Folder name is PLURAL (`domains/`) — collection of N per-domain files — and each file inside uses the SINGULAR domain name (`{domain}-rules.md`). DO NOT use `60.domains/` (collides with `60.memory/`) and DO NOT skip the `{type}/` sub-folder. See pass3-footer.md "Per-domain folder convention" for the full rationale.
|
|
87
87
|
- MUST generate `.claude/rules/00.core/00.standard-reference.md` as a directory of all standard files
|
|
88
|
+
(paths only, grouped by category). Include the FORWARD REFERENCE `claudeos-core/standard/00.core/04.doc-writing-guide.md` under `## Core` — Pass 4 generates it; omitting it leaves an index gap the moment Pass 4 runs. Do NOT add a "DO NOT Read" section here — CLAUDE.md Section 7 is the single source of truth.
|
|
88
89
|
|
|
89
90
|
4. .claude/rules/50.sync/ (2 sync rules)
|
|
90
91
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
@@ -94,7 +95,7 @@ Generation targets:
|
|
|
94
95
|
- 02.skills-sync.md — Remind AI to update MANIFEST.md when skills are modified
|
|
95
96
|
|
|
96
97
|
5. claudeos-core/skills/ (active domains only)
|
|
97
|
-
- 20.frontend-page/01.scaffold-feature
|
|
98
|
+
- 20.frontend-page/01.scaffold-page-feature.md (orchestrator — Angular feature module scaffolding; stem MUST match the `scaffold-page-feature/` sub-folder so content-validator pairs them)
|
|
98
99
|
- 20.frontend-page/scaffold-page-feature/01~08 (sub-skills: module, component, service, routing, template, test, style, index)
|
|
99
100
|
- 00.shared/MANIFEST.md (skill registry)
|
|
100
101
|
|
|
@@ -277,7 +277,7 @@ Unlike rules that auto-load via `paths` glob, this layer is referenced **on-dema
|
|
|
277
277
|
2. **Skim recent decisions**: Skim recent entries in `decision-log.md` to avoid overwriting architectural decisions that have already been agreed upon.
|
|
278
278
|
3. **Record new decisions**: When making a significant design decision (choosing between competing patterns, adopting or rejecting a library, fixing a convention, etc.), append to `decision-log.md`.
|
|
279
279
|
4. **Record repeated errors**: If the same error occurs ≥2 times and the root cause is non-obvious, register it in `failure-patterns.md` with a new pattern-id.
|
|
280
|
-
5. **Periodic compaction**: When
|
|
280
|
+
5. **Periodic compaction**: When `failure-patterns.md` approaches 400 lines or has not been tidied up for over a month, run `npx claudeos-core memory compact` (`decision-log.md` is append-only and is never compacted).
|
|
281
281
|
6. **Review rule-update proposals**: Review proposals in `auto-rule-update.md` with confidence ≥ 0.70. When accepting, edit the corresponding rule file and log the decision in `decision-log.md`.
|
|
282
282
|
|
|
283
283
|
**Session Resume (after auto-compact or restart)**: Claude Code's auto-compact feature may truncate session context mid-work, and a restarted session starts with a fresh context window. When resuming work:
|
|
@@ -125,11 +125,15 @@ IMPORT, not redefine.
|
|
|
125
125
|
- ...
|
|
126
126
|
- ...
|
|
127
127
|
|
|
128
|
-
## Allowed Source Paths (v2.
|
|
128
|
+
## Allowed Source Paths (v2.5.0+ — WRITTEN BY THE ORCHESTRATOR)
|
|
129
129
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
130
|
+
**Do NOT write this section yourself.** After you finish, the Node.js
|
|
131
|
+
orchestrator appends `## Allowed Source Paths` to this file directly from
|
|
132
|
+
`project-analysis.json` — byte-exact, every run. Anything you write under
|
|
133
|
+
that heading will be replaced. Skip it and save the tokens.
|
|
134
|
+
|
|
135
|
+
The remainder of this section documents the shape the orchestrator emits,
|
|
136
|
+
so Pass 3b/3c/3d know what to expect:
|
|
133
137
|
|
|
134
138
|
- Header: whether the list is in `full` mode (individual file paths) or
|
|
135
139
|
`rollup` mode (parent directories, used when the project exceeds the
|
|
@@ -175,11 +179,9 @@ fall back to pass2-merged.json verification per file)` instead.
|
|
|
175
179
|
3. **Exact values only.** Every class name, method name, package path, and
|
|
176
180
|
file path must be verbatim from the analysis data. If a value is not
|
|
177
181
|
captured in the analysis, write `(not in analysis)` — do NOT guess.
|
|
178
|
-
4. **Allowed Source Paths section
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
path you drop here becomes a path they can fabricate later without
|
|
182
|
-
the downstream validator catching it until after Pass 3 completes.
|
|
182
|
+
4. **Do not write the `## Allowed Source Paths` section.** The orchestrator
|
|
183
|
+
injects it verbatim from `project-analysis.json` once this step ends
|
|
184
|
+
(v2.5.0+). It is deterministic by design — no LLM copying involved.
|
|
183
185
|
5. **Do NOT write any other files.** CLAUDE.md, standard/, rules/, etc.
|
|
184
186
|
come in later Pass 3 steps. Writing them here is a bug.
|
|
185
187
|
6. **Do NOT read source code.** All information comes from the three JSON
|
|
@@ -191,7 +191,7 @@ Baseline template (translate per above, then append the project-specific section
|
|
|
191
191
|
```markdown
|
|
192
192
|
# Compaction Strategy
|
|
193
193
|
|
|
194
|
-
_4-stage compaction rules for `decision-log.md` and
|
|
194
|
+
_4-stage compaction rules for `failure-patterns.md`. `decision-log.md` is append-only and never compacted._
|
|
195
195
|
_Run via `npx claudeos-core memory compact`._
|
|
196
196
|
|
|
197
197
|
## Preservation Priority
|
|
@@ -266,7 +266,7 @@ Body (write in **{{LANG_NAME}}**) must cover:
|
|
|
266
266
|
Frontmatter: `name: AI Work Rules`, `paths: ["**/*"]`
|
|
267
267
|
Body (write in **{{LANG_NAME}}**) must cover:
|
|
268
268
|
- Accuracy over token saving; verify before claiming
|
|
269
|
-
-
|
|
269
|
+
- 17 hallucination prevention patterns (see memory-scaffold static fallback `RULE_FILES_00["52.ai-work-rules.md"]` for the reference table)
|
|
270
270
|
- No unsolicited suggestions; ask when unsure
|
|
271
271
|
- Memory vs Rules — no duplication judgment (Memory is on-demand, Rules are auto-loaded)
|
|
272
272
|
- Planned references — no "missing" judgment
|
|
@@ -374,7 +374,7 @@ After all files are written, create:
|
|
|
374
374
|
"standardFiles": [
|
|
375
375
|
"claudeos-core/standard/00.core/XX.doc-writing-guide.md"
|
|
376
376
|
],
|
|
377
|
-
"claudeMdAppended":
|
|
377
|
+
"claudeMdAppended": false,
|
|
378
378
|
"seededDecisions": <integer count of seed entries written to decision-log.md>
|
|
379
379
|
}
|
|
380
380
|
```
|
|
@@ -89,7 +89,7 @@ Generation targets:
|
|
|
89
89
|
- 30.security-db/01.security-auth.md — Authentication, authorization, CORS
|
|
90
90
|
- 30.security-db/02.database-schema.md — DDL, migrations, audit columns
|
|
91
91
|
- 30.security-db/03.common-utilities.md — Common utilities, constants, Base classes
|
|
92
|
-
- 40.infra/01.environment-config.md — Profiles, environment variables, configuration management
|
|
92
|
+
- 40.infra/01.environment-config.md — Profiles, environment variables, configuration management, build scripts (`build.gradle` / `build.gradle.kts` / `pom.xml`) and the Gradle version catalog
|
|
93
93
|
- 40.infra/02.logging-monitoring.md — Logging standards, monitoring, alerts
|
|
94
94
|
- 40.infra/03.cicd-deployment.md — CI/CD pipeline, deployment strategy
|
|
95
95
|
- 80.verification/01.development-verification.md — Build, startup, API testing
|
|
@@ -113,7 +113,7 @@ Generation targets:
|
|
|
113
113
|
- `00.core/*` rules: `paths: ["**/*"]` — always loaded (architecture, naming are universally needed)
|
|
114
114
|
- `10.backend/*` rules: `paths: ["**/*"]` — always loaded (backend rules needed for any source editing)
|
|
115
115
|
- `30.security-db/*` rules: `paths: ["**/*"]` — always loaded (cross-cutting concerns)
|
|
116
|
-
- `40.infra/01.environment-config-rules.md` paths: `["**/*.properties", "**/*.yml", "**/*.yaml", "**/.env*", "**/config/**", "**/application*.properties"]` — Spring config files
|
|
116
|
+
- `40.infra/01.environment-config-rules.md` paths: `["**/*.properties", "**/*.yml", "**/*.yaml", "**/.env*", "**/config/**", "**/application*.properties", "**/*.gradle", "**/*.gradle.kts", "**/gradle/libs.versions.toml", "**/pom.xml"]` — Spring config files + build scripts (Groovy and Kotlin DSL) + version catalog
|
|
117
117
|
- `40.infra/02.logging-monitoring-rules.md` paths: `["**/*.java", "**/logback*.xml", "**/logback*.groovy", "**/log4j*.xml", "**/log4j*.properties", "**/log4jdbc*.properties"]` — source code where logs live + log config (covers Logback XML/Groovy DSL, Log4j/Log4j2 XML/properties, and log4jdbc JDBC-logging adapter properties)
|
|
118
118
|
- `40.infra/03.cicd-deployment-rules.md` paths: `["**/*.yml", "**/*.yaml", "**/Dockerfile*", "**/*.gradle*", "**/pom.xml", "**/*.java"]` — CI / build config + source
|
|
119
119
|
- `50.sync/*` rules: `paths: ["**/claudeos-core/**", "**/.claude/**"]` — loaded only when editing claudeos-core files
|
|
@@ -155,7 +155,7 @@ Generation targets:
|
|
|
155
155
|
List only the standard files that were actually generated above. Include frontend standards only if frontend was detected. NOTE: `00.core/04.doc-writing-guide.md` is a FORWARD REFERENCE — Pass 4 will generate it; include it anyway. Do NOT add a "DO NOT Read" section here — that information lives in CLAUDE.md Section 7 (the single source of truth).
|
|
156
156
|
|
|
157
157
|
4. .claude/rules/50.sync/ (2 sync rules — AI fallback reminders)
|
|
158
|
-
- NOTE: These rules remind AI to
|
|
158
|
+
- NOTE: These rules remind AI to keep standard ↔ rules ↔ MANIFEST in sync when it edits any of them (`npx claudeos-core health` reports drift). Do NOT reference `npx claudeos-core refresh` — it is a no-op since v2.1.0.
|
|
159
159
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
160
160
|
Do NOT generate a separate 02.rules-sync.md mirror file — redundant.
|
|
161
161
|
Express the mapping as a naming convention (standard/<N>.<dir>/<M>.<n>.md ↔
|
|
@@ -118,7 +118,7 @@ Generation targets:
|
|
|
118
118
|
- `00.core/*` rules: `paths: ["**/*"]` — always loaded (architecture, naming are universally needed)
|
|
119
119
|
- `10.backend/*` rules: `paths: ["**/*"]` — always loaded (backend rules needed for any source editing)
|
|
120
120
|
- `30.security-db/*` rules: `paths: ["**/*"]` — always loaded (cross-cutting concerns)
|
|
121
|
-
- `40.infra/01.environment-config-rules.md` paths: `["**/*.properties", "**/*.yml", "**/*.yaml", "**/.env*", "**/config/**", "**/application*.properties"]` — Spring config files
|
|
121
|
+
- `40.infra/01.environment-config-rules.md` paths: `["**/*.properties", "**/*.yml", "**/*.yaml", "**/.env*", "**/config/**", "**/application*.properties", "**/*.gradle", "**/*.gradle.kts", "**/gradle/libs.versions.toml", "**/pom.xml"]` — Spring config files + build scripts (Groovy and Kotlin DSL) + version catalog
|
|
122
122
|
- `40.infra/02.logging-monitoring-rules.md` paths: `["**/*.kt", "**/*.kts", "**/logback*.xml", "**/logback*.groovy", "**/log4j*.xml", "**/log4j*.properties", "**/log4jdbc*.properties"]` — source code where logs live + log config (covers Logback XML/Groovy DSL, Log4j/Log4j2 XML/properties, and log4jdbc JDBC-logging adapter properties)
|
|
123
123
|
- `40.infra/03.cicd-deployment-rules.md` paths: `["**/*.yml", "**/*.yaml", "**/Dockerfile*", "**/*.gradle*", "**/*.kt", "**/*.kts"]` — CI / build config + source
|
|
124
124
|
- `50.sync/*` rules: `paths: ["**/claudeos-core/**", "**/.claude/**"]` — loaded only when editing claudeos-core files
|
|
@@ -162,7 +162,7 @@ Generation targets:
|
|
|
162
162
|
List only the standard files that were actually generated above. Include frontend standards only if frontend was detected. NOTE: `00.core/04.doc-writing-guide.md` is a FORWARD REFERENCE — Pass 4 will generate it; include it anyway. Do NOT add a "DO NOT Read" section here — that information lives in CLAUDE.md Section 7 (the single source of truth).
|
|
163
163
|
|
|
164
164
|
4. .claude/rules/50.sync/ (2 sync rules — AI fallback reminders)
|
|
165
|
-
- NOTE: These rules remind AI to
|
|
165
|
+
- NOTE: These rules remind AI to keep standard ↔ rules ↔ MANIFEST in sync when it edits any of them (`npx claudeos-core health` reports drift). Do NOT reference `npx claudeos-core refresh` — it is a no-op since v2.1.0.
|
|
166
166
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
167
167
|
Do NOT generate a separate 02.rules-sync.md mirror file — redundant.
|
|
168
168
|
Express the mapping as a naming convention (standard/<N>.<dir>/<M>.<n>.md ↔
|
|
@@ -130,7 +130,7 @@ Generation targets:
|
|
|
130
130
|
List only the standard files that were actually generated above. NOTE: `00.core/04.doc-writing-guide.md` is a FORWARD REFERENCE — Pass 4 will generate it; include it anyway. Do NOT add a "DO NOT Read" section here — that information lives in CLAUDE.md Section 7 (the single source of truth).
|
|
131
131
|
|
|
132
132
|
4. .claude/rules/50.sync/ (2 sync rules — AI fallback reminders)
|
|
133
|
-
- NOTE: These rules remind AI to
|
|
133
|
+
- NOTE: These rules remind AI to keep standard ↔ rules ↔ MANIFEST in sync when it edits any of them (`npx claudeos-core health` reports drift). Do NOT reference `npx claudeos-core refresh` — it is a no-op since v2.1.0.
|
|
134
134
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
135
135
|
Do NOT generate a separate 02.rules-sync.md mirror file — redundant.
|
|
136
136
|
Express the mapping as a naming convention (standard/<N>.<dir>/<M>.<n>.md ↔
|
|
@@ -89,6 +89,7 @@ Generation targets:
|
|
|
89
89
|
- `60.memory/*` rules: forward reference — Pass 4 will generate 4 files (01.decision-log, 02.failure-patterns, 03.compaction, 04.auto-rule-update), each with file-specific `paths`. Pass 3 must STILL list ```.claude/rules/60.memory/*``` as a row in CLAUDE.md Section 6 Rules table so developers/Claude see the category exists.
|
|
90
90
|
- `70.domains/*` rules (multi-domain projects only): per-domain rules at `.claude/rules/70.domains/{type}/{domain}-rules.md` (where `{type}` is `backend` or `frontend`, ALWAYS present even in single-stack projects for uniform layout + zero-migration future-proofing), each with a `paths:` glob scoped to that domain's source directories so the rule auto-loads only when editing files within the relevant domain. Folder name is PLURAL (`domains/`) — collection of N per-domain files — and each file inside uses the SINGULAR domain name (`{domain}-rules.md`). DO NOT use `60.domains/` (collides with `60.memory/`) and DO NOT skip the `{type}/` sub-folder. See pass3-footer.md "Per-domain folder convention" for the full rationale.
|
|
91
91
|
- MUST generate `.claude/rules/00.core/00.standard-reference.md` as a directory of all standard files
|
|
92
|
+
(paths only, grouped by category). Include the FORWARD REFERENCE `claudeos-core/standard/00.core/04.doc-writing-guide.md` under `## Core` — Pass 4 generates it; omitting it leaves an index gap the moment Pass 4 runs. Do NOT add a "DO NOT Read" section here — CLAUDE.md Section 7 is the single source of truth.
|
|
92
93
|
|
|
93
94
|
4. .claude/rules/50.sync/ (2 sync rules)
|
|
94
95
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
@@ -97,6 +97,7 @@ Generation targets:
|
|
|
97
97
|
- `60.memory/*` rules: forward reference — Pass 4 will generate 4 files (01.decision-log, 02.failure-patterns, 03.compaction, 04.auto-rule-update), each with file-specific `paths`. Pass 3 must STILL list ```.claude/rules/60.memory/*``` as a row in CLAUDE.md Section 6 Rules table so developers/Claude see the category exists.
|
|
98
98
|
- `70.domains/*` rules (multi-domain projects only): per-domain rules at `.claude/rules/70.domains/{type}/{domain}-rules.md` (where `{type}` is `backend` or `frontend`, ALWAYS present even in single-stack projects for uniform layout + zero-migration future-proofing), each with a `paths:` glob scoped to that domain's source directories so the rule auto-loads only when editing files within the relevant domain. Folder name is PLURAL (`domains/`) — collection of N per-domain files — and each file inside uses the SINGULAR domain name (`{domain}-rules.md`). DO NOT use `60.domains/` (collides with `60.memory/`) and DO NOT skip the `{type}/` sub-folder. See pass3-footer.md "Per-domain folder convention" for the full rationale.
|
|
99
99
|
- MUST generate `.claude/rules/00.core/00.standard-reference.md` — directory of all standard files.
|
|
100
|
+
(paths only, grouped by category). Include the FORWARD REFERENCE `claudeos-core/standard/00.core/04.doc-writing-guide.md` under `## Core` — Pass 4 generates it; omitting it leaves an index gap the moment Pass 4 runs. Do NOT add a "DO NOT Read" section here — CLAUDE.md Section 7 is the single source of truth.
|
|
100
101
|
List only the standard files that were actually generated above.
|
|
101
102
|
|
|
102
103
|
4. .claude/rules/50.sync/ (2 sync rules)
|
|
@@ -132,7 +132,7 @@ Generation targets:
|
|
|
132
132
|
List only the standard files that were actually generated above. NOTE: `00.core/04.doc-writing-guide.md` is a FORWARD REFERENCE — Pass 4 will generate it; include it anyway. Do NOT add a "DO NOT Read" section here — that information lives in CLAUDE.md Section 7 (the single source of truth).
|
|
133
133
|
|
|
134
134
|
4. .claude/rules/50.sync/ (2 sync rules — AI fallback reminders)
|
|
135
|
-
- NOTE: These rules remind AI to
|
|
135
|
+
- NOTE: These rules remind AI to keep standard ↔ rules ↔ MANIFEST in sync when it edits any of them (`npx claudeos-core health` reports drift). Do NOT reference `npx claudeos-core refresh` — it is a no-op since v2.1.0.
|
|
136
136
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
137
137
|
Do NOT generate a separate 02.rules-sync.md mirror file — redundant.
|
|
138
138
|
Express the mapping as a naming convention (standard/<N>.<dir>/<M>.<n>.md ↔
|
|
@@ -83,6 +83,7 @@ Generation targets:
|
|
|
83
83
|
- `60.memory/*` rules: forward reference — Pass 4 will generate 4 files (01.decision-log, 02.failure-patterns, 03.compaction, 04.auto-rule-update), each with file-specific `paths`. Pass 3 must STILL list ```.claude/rules/60.memory/*``` as a row in CLAUDE.md Section 6 Rules table so developers/Claude see the category exists.
|
|
84
84
|
- `70.domains/*` rules (multi-domain projects only): per-domain rules at `.claude/rules/70.domains/{type}/{domain}-rules.md` (where `{type}` is `backend` or `frontend`, ALWAYS present even in single-stack projects for uniform layout + zero-migration future-proofing), each with a `paths:` glob scoped to that domain's source directories so the rule auto-loads only when editing files within the relevant domain. Folder name is PLURAL (`domains/`) — collection of N per-domain files — and each file inside uses the SINGULAR domain name (`{domain}-rules.md`). DO NOT use `60.domains/` (collides with `60.memory/`) and DO NOT skip the `{type}/` sub-folder. See pass3-footer.md "Per-domain folder convention" for the full rationale.
|
|
85
85
|
- MUST generate `.claude/rules/00.core/00.standard-reference.md` — directory of all standard files.
|
|
86
|
+
(paths only, grouped by category). Include the FORWARD REFERENCE `claudeos-core/standard/00.core/04.doc-writing-guide.md` under `## Core` — Pass 4 generates it; omitting it leaves an index gap the moment Pass 4 runs. Do NOT add a "DO NOT Read" section here — CLAUDE.md Section 7 is the single source of truth.
|
|
86
87
|
|
|
87
88
|
4. .claude/rules/50.sync/ (2 sync rules)
|
|
88
89
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
@@ -131,7 +131,7 @@ Generation targets:
|
|
|
131
131
|
List only the standard files that were actually generated above. NOTE: `00.core/04.doc-writing-guide.md` is a FORWARD REFERENCE — Pass 4 will generate it; include it anyway. Do NOT add a "DO NOT Read" section here — that information lives in CLAUDE.md Section 7 (the single source of truth).
|
|
132
132
|
|
|
133
133
|
4. .claude/rules/50.sync/ (2 sync rules — AI fallback reminders)
|
|
134
|
-
- NOTE: These rules remind AI to
|
|
134
|
+
- NOTE: These rules remind AI to keep standard ↔ rules ↔ MANIFEST in sync when it edits any of them (`npx claudeos-core health` reports drift). Do NOT reference `npx claudeos-core refresh` — it is a no-op since v2.1.0.
|
|
135
135
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
136
136
|
Do NOT generate a separate 02.rules-sync.md mirror file — redundant.
|
|
137
137
|
Express the mapping as a naming convention (standard/<N>.<dir>/<M>.<n>.md ↔
|
|
@@ -132,7 +132,7 @@ Generation targets:
|
|
|
132
132
|
List only the standard files that were actually generated above. NOTE: `00.core/04.doc-writing-guide.md` is a FORWARD REFERENCE — Pass 4 will generate it; include it anyway. Do NOT add a "DO NOT Read" section here — that information lives in CLAUDE.md Section 7 (the single source of truth).
|
|
133
133
|
|
|
134
134
|
4. .claude/rules/50.sync/ (2 sync rules — AI fallback reminders)
|
|
135
|
-
- NOTE: These rules remind AI to
|
|
135
|
+
- NOTE: These rules remind AI to keep standard ↔ rules ↔ MANIFEST in sync when it edits any of them (`npx claudeos-core health` reports drift). Do NOT reference `npx claudeos-core refresh` — it is a no-op since v2.1.0.
|
|
136
136
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
137
137
|
Do NOT generate a separate 02.rules-sync.md mirror file — redundant.
|
|
138
138
|
Express the mapping as a naming convention (standard/<N>.<dir>/<M>.<n>.md ↔
|
|
@@ -84,6 +84,7 @@ Generation targets:
|
|
|
84
84
|
- `60.memory/*` rules: forward reference — Pass 4 will generate 4 files (01.decision-log, 02.failure-patterns, 03.compaction, 04.auto-rule-update), each with file-specific `paths`. Pass 3 must STILL list ```.claude/rules/60.memory/*``` as a row in CLAUDE.md Section 6 Rules table so developers/Claude see the category exists.
|
|
85
85
|
- `70.domains/*` rules (multi-domain projects only): per-domain rules at `.claude/rules/70.domains/{type}/{domain}-rules.md` (where `{type}` is `backend` or `frontend`, ALWAYS present even in single-stack projects for uniform layout + zero-migration future-proofing), each with a `paths:` glob scoped to that domain's source directories so the rule auto-loads only when editing files within the relevant domain. Folder name is PLURAL (`domains/`) — collection of N per-domain files — and each file inside uses the SINGULAR domain name (`{domain}-rules.md`). DO NOT use `60.domains/` (collides with `60.memory/`) and DO NOT skip the `{type}/` sub-folder. See pass3-footer.md "Per-domain folder convention" for the full rationale.
|
|
86
86
|
- MUST generate `.claude/rules/00.core/00.standard-reference.md` — directory of all standard files
|
|
87
|
+
(paths only, grouped by category). Include the FORWARD REFERENCE `claudeos-core/standard/00.core/04.doc-writing-guide.md` under `## Core` — Pass 4 generates it; omitting it leaves an index gap the moment Pass 4 runs. Do NOT add a "DO NOT Read" section here — CLAUDE.md Section 7 is the single source of truth.
|
|
87
88
|
|
|
88
89
|
4. .claude/rules/50.sync/ (2 sync rules)
|
|
89
90
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
@@ -82,6 +82,7 @@ Generation targets:
|
|
|
82
82
|
- `60.memory/*` rules: forward reference — Pass 4 will generate 4 files (01.decision-log, 02.failure-patterns, 03.compaction, 04.auto-rule-update), each with file-specific `paths`. Pass 3 must STILL list ```.claude/rules/60.memory/*``` as a row in CLAUDE.md Section 6 Rules table so developers/Claude see the category exists.
|
|
83
83
|
- `70.domains/*` rules (multi-domain projects only): per-domain rules at `.claude/rules/70.domains/{type}/{domain}-rules.md` (where `{type}` is `backend` or `frontend`, ALWAYS present even in single-stack projects for uniform layout + zero-migration future-proofing), each with a `paths:` glob scoped to that domain's source directories so the rule auto-loads only when editing files within the relevant domain. Folder name is PLURAL (`domains/`) — collection of N per-domain files — and each file inside uses the SINGULAR domain name (`{domain}-rules.md`). DO NOT use `60.domains/` (collides with `60.memory/`) and DO NOT skip the `{type}/` sub-folder. See pass3-footer.md "Per-domain folder convention" for the full rationale.
|
|
84
84
|
- MUST generate `.claude/rules/00.core/00.standard-reference.md` — directory of all standard files
|
|
85
|
+
(paths only, grouped by category). Include the FORWARD REFERENCE `claudeos-core/standard/00.core/04.doc-writing-guide.md` under `## Core` — Pass 4 generates it; omitting it leaves an index gap the moment Pass 4 runs. Do NOT add a "DO NOT Read" section here — CLAUDE.md Section 7 is the single source of truth.
|
|
85
86
|
|
|
86
87
|
4. .claude/rules/50.sync/ (2 sync rules)
|
|
87
88
|
- 01.doc-sync.md — Bidirectional standard ↔ rules sync reminder (both directions in ONE rule).
|
|
@@ -103,7 +103,10 @@ function selectTemplates(stack) {
|
|
|
103
103
|
if (stack.frontend === "nextjs") {
|
|
104
104
|
templates.frontend = "node-nextjs";
|
|
105
105
|
} else if (stack.frontend === "react") {
|
|
106
|
-
|
|
106
|
+
// `framework === "vite"` only when no backend framework was detected;
|
|
107
|
+
// `frontendBundler === "vite"` (v2.5.0) covers Spring/Django + React/Vite
|
|
108
|
+
// repos (root or `frontend/` sub-directory) where `framework` is the backend.
|
|
109
|
+
templates.frontend = (stack.framework === "vite" || stack.frontendBundler === "vite") ? "node-vite" : "node-nextjs";
|
|
107
110
|
} else if (stack.frontend === "vue") {
|
|
108
111
|
templates.frontend = "vue-nuxt";
|
|
109
112
|
} else if (stack.frontend === "angular") {
|
package/plan-installer/index.js
CHANGED
|
@@ -37,7 +37,7 @@ async function main() {
|
|
|
37
37
|
if (!stack.language && !stack.framework) {
|
|
38
38
|
console.warn("\n ⚠️ No language or framework detected.");
|
|
39
39
|
console.warn(" Supported: Java, Kotlin, TypeScript, JavaScript, Python");
|
|
40
|
-
console.warn(" Ensure you have build.gradle, package.json, pyproject.toml, or requirements.txt in the project root.\n");
|
|
40
|
+
console.warn(" Ensure you have build.gradle(.kts), pom.xml, package.json, pyproject.toml, or requirements.txt in the project root.\n");
|
|
41
41
|
}
|
|
42
42
|
console.log(` Frontend: ${stack.frontend || "none"} ${stack.frontendVersion || ""}`);
|
|
43
43
|
// v2.4.0 — when a project ships more than one DB driver (e.g. Oracle +
|
|
@@ -115,7 +115,7 @@ async function main() {
|
|
|
115
115
|
// Phase 6: Prompt generation
|
|
116
116
|
const lang = process.env.CLAUDEOS_LANG || "en";
|
|
117
117
|
console.log(` [Phase 6] Generating prompts (lang: ${lang})...`);
|
|
118
|
-
generatePrompts(templates, lang, TEMPLATES_DIR, GENERATED_DIR);
|
|
118
|
+
generatePrompts(templates, lang, TEMPLATES_DIR, GENERATED_DIR, stack);
|
|
119
119
|
console.log();
|
|
120
120
|
|
|
121
121
|
// Save outputs
|
|
@@ -127,15 +127,34 @@ async function main() {
|
|
|
127
127
|
// the project declares no port of its own. This is a last-resort
|
|
128
128
|
// default; prefer that stack-detector extract it from .env.example
|
|
129
129
|
// to keep CLAUDE.md truthful to what the project actually runs.
|
|
130
|
-
|
|
130
|
+
//
|
|
131
|
+
// v2.5.0 — backend port and frontend dev-server port are resolved
|
|
132
|
+
// SEPARATELY. Pre-v2.5.0 the single chain (`stack.frontend === "angular"
|
|
133
|
+
// ? 4200 …`) handed a Spring/Django backend the Angular/Next dev-server
|
|
134
|
+
// port whenever a SPA lived beside it. Now:
|
|
135
|
+
// stack.port — the backend's port when a backend exists; for a
|
|
136
|
+
// frontend-only project it is the dev-server port.
|
|
137
|
+
// stack.frontendPort — the SPA's dev-server port whenever a frontend
|
|
138
|
+
// exists: sub-directory `.env*` (stack-detector) →
|
|
139
|
+
// root `.env*` PORT for a root SPA → convention.
|
|
140
|
+
// Same definition as stack-detector's env-port split: a JVM/Python project
|
|
141
|
+
// is a backend even when no framework was recognized (plain Maven/Gradle
|
|
142
|
+
// project without Spring Boot coordinates).
|
|
143
|
+
const hasBackend = (!!stack.framework && stack.framework !== "vite") || ["java", "kotlin", "python"].includes(stack.language);
|
|
144
|
+
const backendDefaultPort = (stack.framework === "fastapi" || stack.framework === "django") ? 8000
|
|
131
145
|
: stack.framework === "flask" ? 5000
|
|
132
|
-
: stack.framework === "vite" ? 5173
|
|
133
|
-
: stack.frontend === "angular" ? 4200
|
|
134
|
-
: stack.frontend === "nextjs" ? 3000
|
|
135
146
|
: (stack.framework === "express" || stack.framework === "nestjs" || stack.framework === "fastify") ? 3000 : 8080;
|
|
147
|
+
const frontendDefaultPort = (stack.frontendBundler === "vite" || stack.framework === "vite") ? 5173
|
|
148
|
+
: stack.frontend === "angular" ? 4200
|
|
149
|
+
: 3000;
|
|
150
|
+
const frontendPort = !stack.frontend ? null
|
|
151
|
+
: stack.frontendPort ? stack.frontendPort
|
|
152
|
+
: (!hasBackend && stack.port) ? stack.port
|
|
153
|
+
: frontendDefaultPort;
|
|
154
|
+
const defaultPort = hasBackend ? backendDefaultPort : (stack.frontend ? frontendPort : backendDefaultPort);
|
|
136
155
|
const analysis = {
|
|
137
156
|
analyzedAt: new Date().toISOString(), lang,
|
|
138
|
-
stack: { ...stack, port: stack.port || defaultPort },
|
|
157
|
+
stack: { ...stack, port: stack.port || defaultPort, ...(frontendPort ? { frontendPort } : {}) },
|
|
139
158
|
templates, isMultiStack, rootPackage,
|
|
140
159
|
domains, backendDomains, frontendDomains, frontend,
|
|
141
160
|
activeDomains: active,
|
|
@@ -159,6 +159,16 @@ function buildPass3Context(generatedDir) {
|
|
|
159
159
|
orm: stack.orm || null,
|
|
160
160
|
frontend: stack.frontend || null,
|
|
161
161
|
frontendVersion: stack.frontendVersion || null,
|
|
162
|
+
// v2.5.0 — sub-directory SPA (`frontend/`, `client/`, …). Pass 3 must
|
|
163
|
+
// cite frontend paths under this prefix; null when the SPA is at root.
|
|
164
|
+
frontendRoot: stack.frontendRoot || null,
|
|
165
|
+
frontendBundler: stack.frontendBundler || null,
|
|
166
|
+
// Sub-directory SPA's own .env facts (port / API target); null when
|
|
167
|
+
// the SPA is at root or declares no env file.
|
|
168
|
+
frontendPort: stack.frontendPort || null,
|
|
169
|
+
frontendEnvInfo: stack.frontendEnvInfo
|
|
170
|
+
? { source: stack.frontendEnvInfo.source || null, port: stack.frontendEnvInfo.port || null, apiTarget: stack.frontendEnvInfo.apiTarget || null }
|
|
171
|
+
: null,
|
|
162
172
|
port: extractPort(analysis),
|
|
163
173
|
},
|
|
164
174
|
|
|
@@ -15,14 +15,30 @@ const { readFileSafe, readJsonSafe, existsSafe, writeFileSafe } = require("../li
|
|
|
15
15
|
* @param {string} templatesDir - path to pass-prompts/templates/
|
|
16
16
|
* @param {string} generatedDir - path to claudeos-core/generated/
|
|
17
17
|
*/
|
|
18
|
-
function generatePrompts(templates, lang, templatesDir, generatedDir) {
|
|
18
|
+
function generatePrompts(templates, lang, templatesDir, generatedDir, stack) {
|
|
19
19
|
const commonDir = path.join(templatesDir, "common");
|
|
20
20
|
const headerPath = path.join(commonDir, "header.md");
|
|
21
21
|
const footerPath = path.join(commonDir, "pass3-footer.md");
|
|
22
22
|
const langPath = path.join(commonDir, "lang-instructions.json");
|
|
23
23
|
const stagingOverridePath = path.join(commonDir, "staging-override.md");
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
let header = existsSafe(headerPath) ? readFileSafe(headerPath) : "";
|
|
26
|
+
// v2.5.0 — Sub-directory SPA. When stack-detector found the frontend under
|
|
27
|
+
// `frontend/` (stack.frontendRoot), every prompt must know that the
|
|
28
|
+
// frontend examples in the stack templates (`app/dashboard/page.tsx`,
|
|
29
|
+
// `src/components/...`) live under that prefix. Without this line the
|
|
30
|
+
// model looks for `app/` at the project root, finds nothing, and either
|
|
31
|
+
// guesses or reports the frontend as absent. The scanner-side allowlist
|
|
32
|
+
// already carries the prefixed paths; this keeps Pass 1/2 consistent.
|
|
33
|
+
const frontendRoot = stack && typeof stack.frontendRoot === "string" && stack.frontendRoot.trim()
|
|
34
|
+
? stack.frontendRoot.replace(/\\/g, "/").replace(/\/+$/, "")
|
|
35
|
+
: null;
|
|
36
|
+
if (frontendRoot) {
|
|
37
|
+
header += `Frontend source root: {{PROJECT_ROOT}}/${frontendRoot}/\n` +
|
|
38
|
+
`The frontend application lives in the \`${frontendRoot}/\` sub-directory (own package.json). ` +
|
|
39
|
+
`Every frontend path in these instructions (\`app/\`, \`pages/\`, \`src/\`, \`components/\`, config files) ` +
|
|
40
|
+
`is relative to \`${frontendRoot}/\`; cite it as \`${frontendRoot}/app/...\` when writing project-relative paths.\n\n---\n\n`;
|
|
41
|
+
}
|
|
26
42
|
const footer = existsSafe(footerPath) ? readFileSafe(footerPath) : "";
|
|
27
43
|
// Injected into pass3/pass4 prompts — redirects .claude/rules/* writes to
|
|
28
44
|
// claudeos-core/generated/.staged-rules/* to bypass Claude Code's sensitive-
|