@cubis/foundry 0.3.79 → 0.3.80
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/dist/cli/build/commands.js +1 -1
- package/dist/cli/build/commands.js.map +1 -1
- package/dist/cli/core.js +253 -149
- package/dist/cli/core.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/build/commands.ts +1 -1
- package/src/cli/core.ts +282 -194
- package/workflows/workflows/agent-environment-setup/generated/route-manifest.json +2 -2
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/accessibility.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/architecture.toml +2 -2
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/backend.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/create.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/database.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/debug.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/devops.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/implement-track.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/migrate.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/mobile.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/onboard.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/orchestrate.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/plan.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/refactor.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/release.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/review.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/security.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/spec.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/test.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/commands/vercel.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/architecture.md +19 -19
- package/workflows/workflows/agent-environment-setup/platforms/antigravity/workflows/spec.md +2 -2
- package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/architecture.md +19 -19
- package/workflows/workflows/agent-environment-setup/platforms/claude/workflows/spec.md +2 -2
- package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/architecture.md +19 -19
- package/workflows/workflows/agent-environment-setup/platforms/codex/workflows/spec.md +2 -2
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-accessibility.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-architecture.prompt.md +2 -2
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-backend.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-create.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-database.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-debug.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-devops.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-implement-track.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-migrate.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-mobile.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-onboard.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-orchestrate.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-plan.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-refactor.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-release.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-review.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-security.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-spec.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-test.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/prompts/workflow-vercel.prompt.md +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/architecture.md +19 -19
- package/workflows/workflows/agent-environment-setup/platforms/copilot/workflows/spec.md +2 -2
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/accessibility.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/architecture.toml +2 -2
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/backend.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/create.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/database.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/debug.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/devops.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/implement-track.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/migrate.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/mobile.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/onboard.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/orchestrate.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/plan.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/refactor.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/release.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/review.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/security.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/spec.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/test.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/commands/vercel.toml +1 -1
- package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/architecture.md +19 -19
- package/workflows/workflows/agent-environment-setup/platforms/gemini/workflows/spec.md +2 -2
- package/workflows/workflows/agent-environment-setup/shared/workflows/architecture.md +19 -19
- package/workflows/workflows/agent-environment-setup/shared/workflows/spec.md +2 -2
package/dist/cli/core.js
CHANGED
|
@@ -35,6 +35,8 @@ const TECH_ARCHITECTURE_BLOCK_START_RE = /<!--\s*cbx:architecture:tech:start[^>]
|
|
|
35
35
|
const TECH_ARCHITECTURE_BLOCK_END_RE = /<!--\s*cbx:architecture:tech:end\s*-->/g;
|
|
36
36
|
const ROADMAP_FOUNDATION_BLOCK_START_RE = /<!--\s*cbx:roadmap:foundation:start[^>]*-->/g;
|
|
37
37
|
const ROADMAP_FOUNDATION_BLOCK_END_RE = /<!--\s*cbx:roadmap:foundation:end\s*-->/g;
|
|
38
|
+
const FOUNDATION_DOCS_DIR = path.join("docs", "foundation");
|
|
39
|
+
const FOUNDATION_ADR_DIR = path.join(FOUNDATION_DOCS_DIR, "adr");
|
|
38
40
|
const COPILOT_ALLOWED_SKILL_FRONTMATTER_KEYS = new Set([
|
|
39
41
|
"compatibility",
|
|
40
42
|
"description",
|
|
@@ -1127,7 +1129,7 @@ function buildEngineeringArchitectureSection(snapshot) {
|
|
|
1127
1129
|
...profile.testingStrategy.map((rule) => ` - ${rule}`),
|
|
1128
1130
|
"- Doc refresh policy:",
|
|
1129
1131
|
" - Update these managed sections when architecture, scale, boundaries, design-system rules, or testing strategy changes.",
|
|
1130
|
-
|
|
1132
|
+
` - For non-trivial work, read ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ENGINEERING_RULES.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, and ${FOUNDATION_DOCS_DIR}/TECH.md in that order when they exist.`,
|
|
1131
1133
|
"<!-- cbx:architecture:rules:end -->",
|
|
1132
1134
|
"",
|
|
1133
1135
|
].join("\n");
|
|
@@ -1239,7 +1241,7 @@ function buildRoadmapFoundationSection(snapshot, specRoots = []) {
|
|
|
1239
1241
|
"- Use this section for medium-term scaling themes, major migrations, or cross-team architecture investments.",
|
|
1240
1242
|
"",
|
|
1241
1243
|
"### Backbone Maintenance",
|
|
1242
|
-
|
|
1244
|
+
`- Keep ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ENGINEERING_RULES.md, and ${FOUNDATION_DOCS_DIR}/TECH.md aligned when direction or structure changes.`,
|
|
1243
1245
|
"- Link major roadmap themes back to specs and ADRs instead of burying them in chat-only planning.",
|
|
1244
1246
|
"<!-- cbx:roadmap:foundation:end -->",
|
|
1245
1247
|
"",
|
|
@@ -1376,6 +1378,42 @@ function buildRoadmapTemplate(snapshot, specRoots = []) {
|
|
|
1376
1378
|
"",
|
|
1377
1379
|
].join("\n");
|
|
1378
1380
|
}
|
|
1381
|
+
function buildProductBuildSkeleton() {
|
|
1382
|
+
return [
|
|
1383
|
+
"# Product",
|
|
1384
|
+
"",
|
|
1385
|
+
"This file is managed by `cbx build architecture`.",
|
|
1386
|
+
"",
|
|
1387
|
+
"<!-- cbx:product:foundation:start version=1 profile=uninitialized -->",
|
|
1388
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1389
|
+
"<!-- cbx:product:foundation:end -->",
|
|
1390
|
+
"",
|
|
1391
|
+
].join("\n");
|
|
1392
|
+
}
|
|
1393
|
+
function buildArchitectureBuildSkeleton() {
|
|
1394
|
+
return [
|
|
1395
|
+
"# Architecture",
|
|
1396
|
+
"",
|
|
1397
|
+
"This file is managed by `cbx build architecture`.",
|
|
1398
|
+
"",
|
|
1399
|
+
"<!-- cbx:architecture:doc:start version=1 profile=uninitialized -->",
|
|
1400
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1401
|
+
"<!-- cbx:architecture:doc:end -->",
|
|
1402
|
+
"",
|
|
1403
|
+
].join("\n");
|
|
1404
|
+
}
|
|
1405
|
+
function buildTechBuildSkeleton() {
|
|
1406
|
+
return [
|
|
1407
|
+
"# TECH.md",
|
|
1408
|
+
"",
|
|
1409
|
+
"This file is managed by `cbx build architecture`.",
|
|
1410
|
+
"",
|
|
1411
|
+
"<!-- cbx:architecture:tech:start version=1 snapshot=uninitialized -->",
|
|
1412
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1413
|
+
"<!-- cbx:architecture:tech:end -->",
|
|
1414
|
+
"",
|
|
1415
|
+
].join("\n");
|
|
1416
|
+
}
|
|
1379
1417
|
function buildAdrReadme() {
|
|
1380
1418
|
return [
|
|
1381
1419
|
"# Architecture Decision Records",
|
|
@@ -1450,7 +1488,7 @@ function buildEngineeringRulesManagedBlock({ platform, productFilePath, architec
|
|
|
1450
1488
|
"2. Keep architecture simple (KISS) and avoid speculative work (YAGNI).",
|
|
1451
1489
|
"3. Apply SOLID pragmatically to reduce change risk, not add ceremony.",
|
|
1452
1490
|
"4. Use clear naming with focused responsibilities and explicit boundaries.",
|
|
1453
|
-
|
|
1491
|
+
`5. For non-trivial work, read ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ENGINEERING_RULES.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, and ${FOUNDATION_DOCS_DIR}/TECH.md in that order when they exist before planning or implementation.`,
|
|
1454
1492
|
"6. Require validation evidence (lint/types/tests) before merge.",
|
|
1455
1493
|
"7. Use Decision Log response style.",
|
|
1456
1494
|
"8. Every Decision Log must include a `Skills Used` section listing skill, workflow, or agent names.",
|
|
@@ -1617,6 +1655,16 @@ async function upsertTaggedSectionInFile({ targetPath, initialContent, block, st
|
|
|
1617
1655
|
nextContent =
|
|
1618
1656
|
trimmed.length > 0 ? `${trimmed}\n\n${block}\n` : `${block}\n`;
|
|
1619
1657
|
}
|
|
1658
|
+
if (!exists) {
|
|
1659
|
+
if (!dryRun) {
|
|
1660
|
+
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
1661
|
+
await writeFile(targetPath, nextContent, "utf8");
|
|
1662
|
+
}
|
|
1663
|
+
return {
|
|
1664
|
+
action: dryRun ? "would-create" : "created",
|
|
1665
|
+
filePath: targetPath,
|
|
1666
|
+
};
|
|
1667
|
+
}
|
|
1620
1668
|
if (nextContent === original) {
|
|
1621
1669
|
return {
|
|
1622
1670
|
action: "unchanged",
|
|
@@ -1638,18 +1686,14 @@ async function upsertTaggedSectionInFile({ targetPath, initialContent, block, st
|
|
|
1638
1686
|
filePath: targetPath,
|
|
1639
1687
|
};
|
|
1640
1688
|
}
|
|
1641
|
-
function buildArchitectureBuildMetadata({ platform, researchMode,
|
|
1689
|
+
function buildArchitectureBuildMetadata({ platform, researchMode, managedDocs, }) {
|
|
1642
1690
|
return {
|
|
1643
|
-
schemaVersion:
|
|
1691
|
+
schemaVersion: 3,
|
|
1644
1692
|
generatedBy: "cbx build architecture",
|
|
1645
1693
|
generatedAt: new Date().toISOString(),
|
|
1646
1694
|
platform,
|
|
1647
1695
|
researchMode,
|
|
1648
|
-
|
|
1649
|
-
architectureDocHash,
|
|
1650
|
-
rulesProfileHash,
|
|
1651
|
-
techSnapshotHash,
|
|
1652
|
-
roadmapProfileHash,
|
|
1696
|
+
managedDocs,
|
|
1653
1697
|
};
|
|
1654
1698
|
}
|
|
1655
1699
|
async function ensureArchitectureDocScaffold({ workspaceRoot, snapshot, specRoots = [], overwrite = false, dryRun = false, }) {
|
|
@@ -1746,6 +1790,78 @@ async function ensureArchitectureDocScaffold({ workspaceRoot, snapshot, specRoot
|
|
|
1746
1790
|
adrTemplateResult,
|
|
1747
1791
|
};
|
|
1748
1792
|
}
|
|
1793
|
+
async function ensureArchitectureBuildScaffold({ workspaceRoot, dryRun = false, }) {
|
|
1794
|
+
const foundationRoot = path.join(workspaceRoot, FOUNDATION_DOCS_DIR);
|
|
1795
|
+
const productPath = path.join(foundationRoot, "PRODUCT.md");
|
|
1796
|
+
const architectureDocPath = path.join(foundationRoot, "ARCHITECTURE.md");
|
|
1797
|
+
const techMdPath = path.join(foundationRoot, "TECH.md");
|
|
1798
|
+
const adrDir = path.join(workspaceRoot, FOUNDATION_ADR_DIR);
|
|
1799
|
+
const adrReadmePath = path.join(adrDir, "README.md");
|
|
1800
|
+
const adrTemplatePath = path.join(adrDir, "0000-template.md");
|
|
1801
|
+
const productResult = await upsertTaggedSectionInFile({
|
|
1802
|
+
targetPath: productPath,
|
|
1803
|
+
initialContent: `${buildProductBuildSkeleton()}\n`,
|
|
1804
|
+
block: [
|
|
1805
|
+
"<!-- cbx:product:foundation:start version=1 profile=uninitialized -->",
|
|
1806
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1807
|
+
"<!-- cbx:product:foundation:end -->",
|
|
1808
|
+
"",
|
|
1809
|
+
].join("\n"),
|
|
1810
|
+
startPattern: PRODUCT_FOUNDATION_BLOCK_START_RE,
|
|
1811
|
+
endPattern: PRODUCT_FOUNDATION_BLOCK_END_RE,
|
|
1812
|
+
dryRun,
|
|
1813
|
+
});
|
|
1814
|
+
const architectureDocResult = await upsertTaggedSectionInFile({
|
|
1815
|
+
targetPath: architectureDocPath,
|
|
1816
|
+
initialContent: `${buildArchitectureBuildSkeleton()}\n`,
|
|
1817
|
+
block: [
|
|
1818
|
+
"<!-- cbx:architecture:doc:start version=1 profile=uninitialized -->",
|
|
1819
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1820
|
+
"<!-- cbx:architecture:doc:end -->",
|
|
1821
|
+
"",
|
|
1822
|
+
].join("\n"),
|
|
1823
|
+
startPattern: ARCHITECTURE_DOC_BLOCK_START_RE,
|
|
1824
|
+
endPattern: ARCHITECTURE_DOC_BLOCK_END_RE,
|
|
1825
|
+
dryRun,
|
|
1826
|
+
});
|
|
1827
|
+
const techResult = await upsertTaggedSectionInFile({
|
|
1828
|
+
targetPath: techMdPath,
|
|
1829
|
+
initialContent: `${buildTechBuildSkeleton()}\n`,
|
|
1830
|
+
block: [
|
|
1831
|
+
"<!-- cbx:architecture:tech:start version=1 snapshot=uninitialized -->",
|
|
1832
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1833
|
+
"<!-- cbx:architecture:tech:end -->",
|
|
1834
|
+
"",
|
|
1835
|
+
].join("\n"),
|
|
1836
|
+
startPattern: TECH_ARCHITECTURE_BLOCK_START_RE,
|
|
1837
|
+
endPattern: TECH_ARCHITECTURE_BLOCK_END_RE,
|
|
1838
|
+
dryRun,
|
|
1839
|
+
});
|
|
1840
|
+
const adrReadmeResult = await writeTextFile({
|
|
1841
|
+
targetPath: adrReadmePath,
|
|
1842
|
+
content: `${buildAdrReadme()}\n`,
|
|
1843
|
+
overwrite: false,
|
|
1844
|
+
dryRun,
|
|
1845
|
+
});
|
|
1846
|
+
const adrTemplateResult = await writeTextFile({
|
|
1847
|
+
targetPath: adrTemplatePath,
|
|
1848
|
+
content: `${buildAdrTemplate()}\n`,
|
|
1849
|
+
overwrite: false,
|
|
1850
|
+
dryRun,
|
|
1851
|
+
});
|
|
1852
|
+
return {
|
|
1853
|
+
productPath,
|
|
1854
|
+
architectureDocPath,
|
|
1855
|
+
techMdPath,
|
|
1856
|
+
adrReadmePath,
|
|
1857
|
+
adrTemplatePath,
|
|
1858
|
+
productResult,
|
|
1859
|
+
architectureDocResult,
|
|
1860
|
+
techResult,
|
|
1861
|
+
adrReadmeResult,
|
|
1862
|
+
adrTemplateResult,
|
|
1863
|
+
};
|
|
1864
|
+
}
|
|
1749
1865
|
function normalizeTechPackageName(value) {
|
|
1750
1866
|
if (value === undefined || value === null)
|
|
1751
1867
|
return null;
|
|
@@ -10248,7 +10364,7 @@ function printInstallEngineeringSummary({ engineeringResults, techResult }) {
|
|
|
10248
10364
|
function printInstallDocumentationNotice() {
|
|
10249
10365
|
console.log("\nProject backbone docs:");
|
|
10250
10366
|
console.log("- Install only wires the rule references and workflow assets.");
|
|
10251
|
-
console.log(
|
|
10367
|
+
console.log(`- Use \`cbx rules init\` to scaffold ENGINEERING_RULES.md and TECH.md, or \`cbx build architecture --platform <codex|claude|gemini|copilot>\` to generate ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ${FOUNDATION_DOCS_DIR}/TECH.md, and ADR scaffolds.`);
|
|
10252
10368
|
}
|
|
10253
10369
|
async function upsertEngineeringArtifacts({ platform, scope, overwrite = false, skipTech = false, dryRun = false, cwd = process.cwd(), }) {
|
|
10254
10370
|
const ruleFilePath = await resolveRuleFilePath(platform, scope, cwd);
|
|
@@ -10399,6 +10515,61 @@ async function listSpecPackRoots(workspaceRoot) {
|
|
|
10399
10515
|
.sort((a, b) => a.localeCompare(b))
|
|
10400
10516
|
.slice(0, 8);
|
|
10401
10517
|
}
|
|
10518
|
+
async function resolveArchitectureInspectionAnchors(workspaceRoot, snapshot, specRoots) {
|
|
10519
|
+
const seen = new Set();
|
|
10520
|
+
const ordered = [];
|
|
10521
|
+
const pushCandidate = async (relativePath) => {
|
|
10522
|
+
const normalized = toPosixPath(relativePath);
|
|
10523
|
+
if (!normalized || seen.has(normalized))
|
|
10524
|
+
return;
|
|
10525
|
+
if (!(await pathExists(path.join(workspaceRoot, relativePath))))
|
|
10526
|
+
return;
|
|
10527
|
+
seen.add(normalized);
|
|
10528
|
+
ordered.push(normalized);
|
|
10529
|
+
};
|
|
10530
|
+
for (const candidate of [
|
|
10531
|
+
"README.md",
|
|
10532
|
+
"package.json",
|
|
10533
|
+
"pubspec.yaml",
|
|
10534
|
+
"go.mod",
|
|
10535
|
+
"pyproject.toml",
|
|
10536
|
+
"Cargo.toml",
|
|
10537
|
+
"Dockerfile",
|
|
10538
|
+
"docker-compose.yml",
|
|
10539
|
+
"docker-compose.yaml",
|
|
10540
|
+
"compose.yaml",
|
|
10541
|
+
"cbx_config.json",
|
|
10542
|
+
".vscode/mcp.json",
|
|
10543
|
+
".gemini/settings.json",
|
|
10544
|
+
]) {
|
|
10545
|
+
await pushCandidate(candidate);
|
|
10546
|
+
}
|
|
10547
|
+
for (const specRoot of specRoots.slice(0, 4)) {
|
|
10548
|
+
await pushCandidate(specRoot);
|
|
10549
|
+
}
|
|
10550
|
+
for (const app of snapshot.architectureByApp || []) {
|
|
10551
|
+
if (!app?.rootPath || app.rootPath === ".")
|
|
10552
|
+
continue;
|
|
10553
|
+
await pushCandidate(app.rootPath);
|
|
10554
|
+
for (const child of [
|
|
10555
|
+
"README.md",
|
|
10556
|
+
"src",
|
|
10557
|
+
"lib",
|
|
10558
|
+
"app",
|
|
10559
|
+
"prisma",
|
|
10560
|
+
"migrations",
|
|
10561
|
+
"test",
|
|
10562
|
+
"tests",
|
|
10563
|
+
"docs",
|
|
10564
|
+
]) {
|
|
10565
|
+
await pushCandidate(path.join(app.rootPath, child));
|
|
10566
|
+
}
|
|
10567
|
+
}
|
|
10568
|
+
for (const dir of snapshot.topDirs || []) {
|
|
10569
|
+
await pushCandidate(dir);
|
|
10570
|
+
}
|
|
10571
|
+
return ordered.slice(0, 18);
|
|
10572
|
+
}
|
|
10402
10573
|
function resolveArchitectureConditionalSkills(snapshot, specRoots, researchMode) {
|
|
10403
10574
|
const conditional = [];
|
|
10404
10575
|
const frameworks = new Set(snapshot.frameworks || []);
|
|
@@ -10443,13 +10614,12 @@ async function resolveArchitectureSkillPathHints(platform, cwd, skillIds) {
|
|
|
10443
10614
|
.map((skillId) => path.join(skillsDir, skillId, "SKILL.md"))
|
|
10444
10615
|
.map((filePath) => toPosixPath(path.relative(findWorkspaceRoot(cwd), filePath)));
|
|
10445
10616
|
}
|
|
10446
|
-
function buildArchitecturePrompt({ platform, workspaceRoot, snapshot, specRoots, researchMode, coreSkills, conditionalSkills, skillPathHints, }) {
|
|
10447
|
-
const productPath =
|
|
10448
|
-
const architecturePath =
|
|
10449
|
-
const
|
|
10450
|
-
const
|
|
10451
|
-
const
|
|
10452
|
-
const adrReadmePath = "docs/adr/README.md";
|
|
10617
|
+
function buildArchitecturePrompt({ platform, workspaceRoot, snapshot, specRoots, inspectionAnchors, researchMode, coreSkills, conditionalSkills, skillPathHints, }) {
|
|
10618
|
+
const productPath = `${FOUNDATION_DOCS_DIR}/PRODUCT.md`;
|
|
10619
|
+
const architecturePath = `${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md`;
|
|
10620
|
+
const techPath = `${FOUNDATION_DOCS_DIR}/TECH.md`;
|
|
10621
|
+
const adrReadmePath = `${FOUNDATION_ADR_DIR}/README.md`;
|
|
10622
|
+
const adrTemplatePath = `${FOUNDATION_ADR_DIR}/0000-template.md`;
|
|
10453
10623
|
const architectureSignals = snapshot.architectureByApp
|
|
10454
10624
|
.filter((item) => (item.architectureSignals || []).length > 0)
|
|
10455
10625
|
.map((item) => {
|
|
@@ -10460,8 +10630,8 @@ function buildArchitecturePrompt({ platform, workspaceRoot, snapshot, specRoots,
|
|
|
10460
10630
|
`You are running inside ${platform}.`,
|
|
10461
10631
|
"",
|
|
10462
10632
|
"Objective:",
|
|
10463
|
-
`- Inspect the repository at ${toPosixPath(workspaceRoot)} and refresh the
|
|
10464
|
-
"-
|
|
10633
|
+
`- Inspect the repository at ${toPosixPath(workspaceRoot)} and author or refresh the core foundation docs in ${productPath}, ${architecturePath}, ${techPath}, ${adrReadmePath}, and ${adrTemplatePath}.`,
|
|
10634
|
+
"- The content should be primarily AI-authored from repository inspection, not copied from placeholder scaffolding.",
|
|
10465
10635
|
"- Preserve manual content outside the managed `cbx:*` markers.",
|
|
10466
10636
|
"",
|
|
10467
10637
|
"Required skill bundle:",
|
|
@@ -10481,27 +10651,33 @@ function buildArchitecturePrompt({ platform, workspaceRoot, snapshot, specRoots,
|
|
|
10481
10651
|
architectureSignals.length > 0
|
|
10482
10652
|
? `- Architecture signals: ${architectureSignals.join(" | ")}`
|
|
10483
10653
|
: "- Architecture signals: none confidently inferred from the repo scan",
|
|
10654
|
+
`- Entry points: ${snapshot.entryPoints.length > 0 ? snapshot.entryPoints.slice(0, 8).join(" | ") : "none detected"}`,
|
|
10655
|
+
`- Key scripts: ${snapshot.keyScripts.length > 0 ? snapshot.keyScripts.slice(0, 8).map((item) => `${item.name}=${item.command}`).join(" | ") : "none detected"}`,
|
|
10656
|
+
`- Inspection anchors: ${inspectionAnchors.length > 0 ? inspectionAnchors.join(", ") : "no concrete anchors detected; inspect the repo root, main source trees, and manifest files manually"}`,
|
|
10484
10657
|
"",
|
|
10485
10658
|
"Execution contract:",
|
|
10486
|
-
|
|
10487
|
-
"2.
|
|
10488
|
-
"3.
|
|
10489
|
-
|
|
10490
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
|
|
10659
|
+
"1. Inspect the repository first before writing any backbone doc content. Derive structure, product surfaces, runtime boundaries, and technical constraints from the actual codebase.",
|
|
10660
|
+
"2. Complete a real inspection pass before drafting. At minimum, inspect the concrete anchors listed above, plus any adjacent directories needed to understand the main execution paths, data boundaries, and integration surfaces.",
|
|
10661
|
+
"3. Do not infer architecture from filenames alone when you can open representative files. Read enough source to validate the main app boundaries, runtime flows, and persistence/integration patterns.",
|
|
10662
|
+
`4. Then read ${productPath}, ${architecturePath}, and ${techPath} in that order when they exist so you can preserve useful manual context and update existing managed sections cleanly.`,
|
|
10663
|
+
`5. Replace or update only the content between the existing managed markers in ${productPath}, ${architecturePath}, and ${techPath}. Do not append a second marker block.`,
|
|
10664
|
+
`6. In ${productPath}, write a concrete product foundation: product purpose, primary users/operators, main journeys, business capabilities, operational constraints, and what future contributors must preserve.`,
|
|
10665
|
+
`7. In ${architecturePath}, write a lean but detailed architecture backbone in a pragmatic arc42/C4 style: system purpose and constraints, bounded contexts, major building blocks, dependency rules, data and integration boundaries, runtime flows, deployment/operability notes, testing/debugging strategy, and only the diagram levels that add real value.`,
|
|
10666
|
+
`8. In ${techPath}, write the developer-facing technical map: stack, repo layout, key commands, entrypoints, data stores, external services, environment/config surfaces, MCP/tooling footprint, and change hotspots future agents should inspect before editing code.`,
|
|
10667
|
+
"9. Every major claim should be grounded in repository evidence. Mention concrete repo paths in the docs when a structural claim would otherwise be ambiguous.",
|
|
10668
|
+
"10. Avoid placeholder filler, generic checklists, and duplicated content across files. Each doc should have a clear job.",
|
|
10669
|
+
"11. Do not create ROADMAP.md, ENGINEERING_RULES.md, or other extra docs unless the prompt explicitly asks for them.",
|
|
10494
10670
|
researchMode === "never"
|
|
10495
|
-
? "
|
|
10496
|
-
: "
|
|
10671
|
+
? "12. Stay repo-only. Do not use outside research."
|
|
10672
|
+
: "12. Use repo evidence first. Use official docs when needed. Treat Reddit or community sources only as labeled secondary evidence.",
|
|
10497
10673
|
researchMode === "always"
|
|
10498
|
-
?
|
|
10499
|
-
: "
|
|
10500
|
-
|
|
10501
|
-
`
|
|
10674
|
+
? `13. Include an external research evidence subsection in ${techPath} with clearly labeled primary and secondary evidence.`
|
|
10675
|
+
: "13. Include external research notes only if they materially informed the architecture update.",
|
|
10676
|
+
`14. If the project clearly follows Clean Architecture, feature-first modules, DDD, modular monolith, or another stable structure, make that explicit in ${architecturePath} with evidence from the repo.`,
|
|
10677
|
+
`15. Ensure ${adrReadmePath} and ${adrTemplatePath} exist as ADR entrypoints, but keep them lean.`,
|
|
10502
10678
|
"",
|
|
10503
10679
|
"Return one JSON object on the last line with this shape:",
|
|
10504
|
-
|
|
10680
|
+
`{"files_written":["${productPath}","${architecturePath}","${techPath}","${adrReadmePath}","${adrTemplatePath}"],"research_used":false,"gaps":[],"next_actions":[]}`,
|
|
10505
10681
|
"",
|
|
10506
10682
|
"Do not emit placeholder TODOs in the managed sections.",
|
|
10507
10683
|
].join("\n");
|
|
@@ -10723,107 +10899,51 @@ async function captureFileContents(filePaths) {
|
|
|
10723
10899
|
return snapshot;
|
|
10724
10900
|
}
|
|
10725
10901
|
async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
|
|
10726
|
-
const
|
|
10727
|
-
const
|
|
10728
|
-
const
|
|
10729
|
-
const
|
|
10730
|
-
const techPath = path.join(workspaceRoot, "TECH.md");
|
|
10731
|
-
const roadmapPath = path.join(workspaceRoot, "ROADMAP.md");
|
|
10732
|
-
const adrReadmePath = path.join(workspaceRoot, "docs", "adr", "README.md");
|
|
10902
|
+
const productPath = path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md");
|
|
10903
|
+
const architecturePath = path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "ARCHITECTURE.md");
|
|
10904
|
+
const techPath = path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md");
|
|
10905
|
+
const adrReadmePath = path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md");
|
|
10733
10906
|
const metadataPath = path.join(workspaceRoot, ".cbx", ARCHITECTURE_BUILD_METADATA_FILENAME);
|
|
10734
10907
|
const productExists = await pathExists(productPath);
|
|
10735
10908
|
const architectureExists = await pathExists(architecturePath);
|
|
10736
|
-
const rulesExists = await pathExists(rulesPath);
|
|
10737
10909
|
const techExists = await pathExists(techPath);
|
|
10738
|
-
const roadmapExists = await pathExists(roadmapPath);
|
|
10739
10910
|
const adrReadmeExists = await pathExists(adrReadmePath);
|
|
10740
|
-
const expectedProductHash = hashStableObject(inferProductFoundationProfile(snapshot, specRoots));
|
|
10741
|
-
const expectedArchitectureHash = hashStableObject(inferArchitectureDocProfile(snapshot, specRoots));
|
|
10742
|
-
const expectedRulesHash = hashStableObject(inferArchitectureContractProfile(snapshot));
|
|
10743
|
-
const expectedTechHash = hashStableObject({
|
|
10744
|
-
style: inferArchitectureContractProfile(snapshot).style,
|
|
10745
|
-
topDirs: snapshot.topDirs,
|
|
10746
|
-
frameworks: snapshot.frameworks,
|
|
10747
|
-
architectureByApp: snapshot.architectureByApp,
|
|
10748
|
-
});
|
|
10749
|
-
const expectedRoadmapHash = hashStableObject({
|
|
10750
|
-
topDirs: snapshot.topDirs,
|
|
10751
|
-
frameworks: snapshot.frameworks,
|
|
10752
|
-
specRoots,
|
|
10753
|
-
});
|
|
10754
10911
|
const findings = [];
|
|
10755
10912
|
let actualProductHash = null;
|
|
10756
10913
|
let actualArchitectureHash = null;
|
|
10757
|
-
let actualRulesHash = null;
|
|
10758
10914
|
let actualTechHash = null;
|
|
10759
|
-
let actualRoadmapHash = null;
|
|
10760
10915
|
if (!productExists) {
|
|
10761
|
-
findings.push(
|
|
10916
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/PRODUCT.md is missing.`);
|
|
10762
10917
|
}
|
|
10763
10918
|
else {
|
|
10764
10919
|
const content = await readFile(productPath, "utf8");
|
|
10765
10920
|
actualProductHash = extractTaggedMarkerAttribute(content, PRODUCT_FOUNDATION_BLOCK_START_RE, "profile");
|
|
10766
10921
|
if (!actualProductHash) {
|
|
10767
|
-
findings.push(
|
|
10768
|
-
}
|
|
10769
|
-
else if (actualProductHash !== expectedProductHash) {
|
|
10770
|
-
findings.push(`PRODUCT.md foundation is stale (expected ${expectedProductHash}, found ${actualProductHash}).`);
|
|
10922
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/PRODUCT.md is missing the managed product foundation block.`);
|
|
10771
10923
|
}
|
|
10772
10924
|
}
|
|
10773
10925
|
if (!architectureExists) {
|
|
10774
|
-
findings.push(
|
|
10926
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md is missing.`);
|
|
10775
10927
|
}
|
|
10776
10928
|
else {
|
|
10777
10929
|
const content = await readFile(architecturePath, "utf8");
|
|
10778
10930
|
actualArchitectureHash = extractTaggedMarkerAttribute(content, ARCHITECTURE_DOC_BLOCK_START_RE, "profile");
|
|
10779
10931
|
if (!actualArchitectureHash) {
|
|
10780
|
-
findings.push(
|
|
10781
|
-
}
|
|
10782
|
-
else if (actualArchitectureHash !== expectedArchitectureHash) {
|
|
10783
|
-
findings.push(`ARCHITECTURE.md backbone is stale (expected ${expectedArchitectureHash}, found ${actualArchitectureHash}).`);
|
|
10784
|
-
}
|
|
10785
|
-
}
|
|
10786
|
-
if (!rulesExists) {
|
|
10787
|
-
findings.push("ENGINEERING_RULES.md is missing.");
|
|
10788
|
-
}
|
|
10789
|
-
else {
|
|
10790
|
-
const content = await readFile(rulesPath, "utf8");
|
|
10791
|
-
actualRulesHash = extractTaggedMarkerAttribute(content, ENGINEERING_ARCHITECTURE_BLOCK_START_RE, "profile");
|
|
10792
|
-
if (!actualRulesHash) {
|
|
10793
|
-
findings.push("ENGINEERING_RULES.md is missing the managed architecture contract block.");
|
|
10794
|
-
}
|
|
10795
|
-
else if (actualRulesHash !== expectedRulesHash) {
|
|
10796
|
-
findings.push(`ENGINEERING_RULES.md architecture profile is stale (expected ${expectedRulesHash}, found ${actualRulesHash}).`);
|
|
10932
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md is missing the managed architecture backbone block.`);
|
|
10797
10933
|
}
|
|
10798
10934
|
}
|
|
10799
10935
|
if (!techExists) {
|
|
10800
|
-
findings.push(
|
|
10936
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/TECH.md is missing.`);
|
|
10801
10937
|
}
|
|
10802
10938
|
else {
|
|
10803
10939
|
const content = await readFile(techPath, "utf8");
|
|
10804
10940
|
actualTechHash = extractTaggedMarkerAttribute(content, TECH_ARCHITECTURE_BLOCK_START_RE, "snapshot");
|
|
10805
10941
|
if (!actualTechHash) {
|
|
10806
|
-
findings.push(
|
|
10807
|
-
}
|
|
10808
|
-
else if (actualTechHash !== expectedTechHash) {
|
|
10809
|
-
findings.push(`TECH.md architecture snapshot is stale (expected ${expectedTechHash}, found ${actualTechHash}).`);
|
|
10810
|
-
}
|
|
10811
|
-
}
|
|
10812
|
-
if (!roadmapExists) {
|
|
10813
|
-
findings.push("ROADMAP.md is missing.");
|
|
10814
|
-
}
|
|
10815
|
-
else {
|
|
10816
|
-
const content = await readFile(roadmapPath, "utf8");
|
|
10817
|
-
actualRoadmapHash = extractTaggedMarkerAttribute(content, ROADMAP_FOUNDATION_BLOCK_START_RE, "profile");
|
|
10818
|
-
if (!actualRoadmapHash) {
|
|
10819
|
-
findings.push("ROADMAP.md is missing the managed roadmap foundation block.");
|
|
10820
|
-
}
|
|
10821
|
-
else if (actualRoadmapHash !== expectedRoadmapHash) {
|
|
10822
|
-
findings.push(`ROADMAP.md backbone is stale (expected ${expectedRoadmapHash}, found ${actualRoadmapHash}).`);
|
|
10942
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/TECH.md is missing the managed architecture snapshot block.`);
|
|
10823
10943
|
}
|
|
10824
10944
|
}
|
|
10825
10945
|
if (!adrReadmeExists) {
|
|
10826
|
-
findings.push(
|
|
10946
|
+
findings.push(`${FOUNDATION_ADR_DIR}/README.md is missing.`);
|
|
10827
10947
|
}
|
|
10828
10948
|
const metadata = await readJsonFileIfExists(metadataPath);
|
|
10829
10949
|
if (!metadata.exists) {
|
|
@@ -10834,21 +10954,12 @@ async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
|
|
|
10834
10954
|
findings,
|
|
10835
10955
|
productPath,
|
|
10836
10956
|
architecturePath,
|
|
10837
|
-
rulesPath,
|
|
10838
10957
|
techPath,
|
|
10839
|
-
roadmapPath,
|
|
10840
10958
|
adrReadmePath,
|
|
10841
10959
|
metadataPath,
|
|
10842
|
-
expectedProductHash,
|
|
10843
|
-
expectedArchitectureHash,
|
|
10844
|
-
expectedRulesHash,
|
|
10845
|
-
expectedTechHash,
|
|
10846
|
-
expectedRoadmapHash,
|
|
10847
10960
|
actualProductHash,
|
|
10848
10961
|
actualArchitectureHash,
|
|
10849
|
-
actualRulesHash,
|
|
10850
10962
|
actualTechHash,
|
|
10851
|
-
actualRoadmapHash,
|
|
10852
10963
|
};
|
|
10853
10964
|
}
|
|
10854
10965
|
async function runBuildArchitecture(options) {
|
|
@@ -10872,7 +10983,7 @@ async function runBuildArchitecture(options) {
|
|
|
10872
10983
|
console.log(`Platform: ${platform}`);
|
|
10873
10984
|
console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
|
|
10874
10985
|
console.log(`Status: ${drift.stale ? "stale" : "fresh"}`);
|
|
10875
|
-
console.log(
|
|
10986
|
+
console.log(`Backbone docs: ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ${FOUNDATION_DOCS_DIR}/TECH.md, ${FOUNDATION_ADR_DIR}/README.md`);
|
|
10876
10987
|
if (drift.findings.length > 0) {
|
|
10877
10988
|
console.log("Findings:");
|
|
10878
10989
|
for (const finding of drift.findings) {
|
|
@@ -10885,24 +10996,12 @@ async function runBuildArchitecture(options) {
|
|
|
10885
10996
|
return;
|
|
10886
10997
|
}
|
|
10887
10998
|
const managedFilePaths = [
|
|
10888
|
-
path.join(workspaceRoot, "PRODUCT.md"),
|
|
10889
|
-
path.join(workspaceRoot, "ARCHITECTURE.md"),
|
|
10890
|
-
path.join(workspaceRoot, "
|
|
10891
|
-
path.join(workspaceRoot, "
|
|
10892
|
-
path.join(workspaceRoot, "
|
|
10893
|
-
path.join(workspaceRoot, "docs", "adr", "README.md"),
|
|
10894
|
-
path.join(workspaceRoot, "docs", "adr", "0000-template.md"),
|
|
10999
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md"),
|
|
11000
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "ARCHITECTURE.md"),
|
|
11001
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md"),
|
|
11002
|
+
path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md"),
|
|
11003
|
+
path.join(workspaceRoot, FOUNDATION_ADR_DIR, "0000-template.md"),
|
|
10895
11004
|
];
|
|
10896
|
-
const filesBefore = dryRun
|
|
10897
|
-
? Object.fromEntries(managedFilePaths.map((filePath) => [filePath, null]))
|
|
10898
|
-
: await captureFileContents(managedFilePaths);
|
|
10899
|
-
const scaffold = await ensureArchitectureDocScaffold({
|
|
10900
|
-
workspaceRoot,
|
|
10901
|
-
snapshot,
|
|
10902
|
-
specRoots,
|
|
10903
|
-
overwrite,
|
|
10904
|
-
dryRun,
|
|
10905
|
-
});
|
|
10906
11005
|
const coreSkills = [
|
|
10907
11006
|
"architecture-doc",
|
|
10908
11007
|
"system-design",
|
|
@@ -10912,11 +11011,13 @@ async function runBuildArchitecture(options) {
|
|
|
10912
11011
|
const conditionalSkills = resolveArchitectureConditionalSkills(snapshot, specRoots, researchMode);
|
|
10913
11012
|
const skillBundle = [...coreSkills, ...conditionalSkills];
|
|
10914
11013
|
const skillPathHints = await resolveArchitectureSkillPathHints(platform, cwd, skillBundle);
|
|
11014
|
+
const inspectionAnchors = await resolveArchitectureInspectionAnchors(workspaceRoot, snapshot, specRoots);
|
|
10915
11015
|
const prompt = buildArchitecturePrompt({
|
|
10916
11016
|
platform,
|
|
10917
11017
|
workspaceRoot,
|
|
10918
11018
|
snapshot,
|
|
10919
11019
|
specRoots,
|
|
11020
|
+
inspectionAnchors,
|
|
10920
11021
|
researchMode,
|
|
10921
11022
|
coreSkills,
|
|
10922
11023
|
conditionalSkills,
|
|
@@ -10924,6 +11025,13 @@ async function runBuildArchitecture(options) {
|
|
|
10924
11025
|
});
|
|
10925
11026
|
const adapter = await probeArchitectureAdapter(platform, workspaceRoot);
|
|
10926
11027
|
const args = adapter.buildInvocation(prompt);
|
|
11028
|
+
const managedTargets = [
|
|
11029
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md"),
|
|
11030
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "ARCHITECTURE.md"),
|
|
11031
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md"),
|
|
11032
|
+
path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md"),
|
|
11033
|
+
path.join(workspaceRoot, FOUNDATION_ADR_DIR, "0000-template.md"),
|
|
11034
|
+
].map((filePath) => toPosixPath(filePath));
|
|
10927
11035
|
if (dryRun) {
|
|
10928
11036
|
const summary = {
|
|
10929
11037
|
platform,
|
|
@@ -10931,15 +11039,7 @@ async function runBuildArchitecture(options) {
|
|
|
10931
11039
|
adapter: adapter.binary,
|
|
10932
11040
|
invocation: [adapter.binary, ...args],
|
|
10933
11041
|
researchMode,
|
|
10934
|
-
managedTargets
|
|
10935
|
-
toPosixPath(scaffold.productPath),
|
|
10936
|
-
toPosixPath(scaffold.architectureDocPath),
|
|
10937
|
-
toPosixPath(scaffold.engineeringRulesPath),
|
|
10938
|
-
toPosixPath(scaffold.techMdPath),
|
|
10939
|
-
toPosixPath(scaffold.roadmapPath),
|
|
10940
|
-
toPosixPath(scaffold.adrReadmePath),
|
|
10941
|
-
toPosixPath(scaffold.adrTemplatePath),
|
|
10942
|
-
],
|
|
11042
|
+
managedTargets,
|
|
10943
11043
|
skillBundle,
|
|
10944
11044
|
};
|
|
10945
11045
|
if (emitJson) {
|
|
@@ -10950,12 +11050,17 @@ async function runBuildArchitecture(options) {
|
|
|
10950
11050
|
console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
|
|
10951
11051
|
console.log(`Adapter: ${adapter.binary}`);
|
|
10952
11052
|
console.log(`Research mode: ${researchMode}`);
|
|
10953
|
-
console.log(`Managed targets: ${
|
|
11053
|
+
console.log(`Managed targets: ${summary.managedTargets.join(", ")}`);
|
|
10954
11054
|
console.log(`Skill bundle: ${skillBundle.join(", ")}`);
|
|
10955
11055
|
console.log(`Invocation: ${[adapter.binary, ...args].join(" ")}`);
|
|
10956
11056
|
}
|
|
10957
11057
|
return;
|
|
10958
11058
|
}
|
|
11059
|
+
const filesBefore = await captureFileContents(managedFilePaths);
|
|
11060
|
+
const scaffold = await ensureArchitectureBuildScaffold({
|
|
11061
|
+
workspaceRoot,
|
|
11062
|
+
dryRun,
|
|
11063
|
+
});
|
|
10959
11064
|
if (!emitJson) {
|
|
10960
11065
|
console.log(`Streaming ${adapter.binary} output...`);
|
|
10961
11066
|
}
|
|
@@ -10971,22 +11076,21 @@ async function runBuildArchitecture(options) {
|
|
|
10971
11076
|
const changedFiles = managedFilePaths
|
|
10972
11077
|
.filter((filePath) => filesBefore[filePath] !== filesAfter[filePath])
|
|
10973
11078
|
.map((filePath) => toPosixPath(path.relative(workspaceRoot, filePath)));
|
|
10974
|
-
const rulesContent = filesAfter[scaffold.engineeringRulesPath] ??
|
|
10975
|
-
(await readFile(scaffold.engineeringRulesPath, "utf8"));
|
|
10976
11079
|
const techContent = filesAfter[scaffold.techMdPath] ?? (await readFile(scaffold.techMdPath, "utf8"));
|
|
10977
11080
|
const productContent = filesAfter[scaffold.productPath] ?? (await readFile(scaffold.productPath, "utf8"));
|
|
10978
11081
|
const architectureContent = filesAfter[scaffold.architectureDocPath] ??
|
|
10979
11082
|
(await readFile(scaffold.architectureDocPath, "utf8"));
|
|
10980
|
-
const roadmapContent = filesAfter[scaffold.roadmapPath] ?? (await readFile(scaffold.roadmapPath, "utf8"));
|
|
10981
11083
|
const metadataPath = path.join(workspaceRoot, ".cbx", ARCHITECTURE_BUILD_METADATA_FILENAME);
|
|
10982
11084
|
const metadata = buildArchitectureBuildMetadata({
|
|
10983
11085
|
platform,
|
|
10984
11086
|
researchMode,
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
|
|
10989
|
-
|
|
11087
|
+
managedDocs: [
|
|
11088
|
+
`${FOUNDATION_DOCS_DIR}/PRODUCT.md`,
|
|
11089
|
+
`${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md`,
|
|
11090
|
+
`${FOUNDATION_DOCS_DIR}/TECH.md`,
|
|
11091
|
+
`${FOUNDATION_ADR_DIR}/README.md`,
|
|
11092
|
+
`${FOUNDATION_ADR_DIR}/0000-template.md`,
|
|
11093
|
+
],
|
|
10990
11094
|
});
|
|
10991
11095
|
await mkdir(path.dirname(metadataPath), { recursive: true });
|
|
10992
11096
|
await writeFile(metadataPath, `${JSON.stringify(metadata, null, 2)}\n`, "utf8");
|
|
@@ -11008,8 +11112,8 @@ async function runBuildArchitecture(options) {
|
|
|
11008
11112
|
console.log(`Platform: ${platform}`);
|
|
11009
11113
|
console.log(`Adapter: ${adapter.binary}`);
|
|
11010
11114
|
console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
|
|
11011
|
-
console.log(
|
|
11012
|
-
console.log(
|
|
11115
|
+
console.log(`Managed docs: ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ${FOUNDATION_DOCS_DIR}/TECH.md`);
|
|
11116
|
+
console.log(`ADR scaffold: ${FOUNDATION_ADR_DIR}/README.md, ${FOUNDATION_ADR_DIR}/0000-template.md`);
|
|
11013
11117
|
console.log(`Skill bundle: ${skillBundle.join(", ")}`);
|
|
11014
11118
|
console.log(`Files written: ${(result.filesWritten || []).join(", ") || "(none reported)"}`);
|
|
11015
11119
|
console.log(`Research used: ${result.researchUsed ? "yes" : "no"}`);
|