@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/src/cli/core.ts
CHANGED
|
@@ -81,6 +81,8 @@ const ROADMAP_FOUNDATION_BLOCK_START_RE =
|
|
|
81
81
|
/<!--\s*cbx:roadmap:foundation:start[^>]*-->/g;
|
|
82
82
|
const ROADMAP_FOUNDATION_BLOCK_END_RE =
|
|
83
83
|
/<!--\s*cbx:roadmap:foundation:end\s*-->/g;
|
|
84
|
+
const FOUNDATION_DOCS_DIR = path.join("docs", "foundation");
|
|
85
|
+
const FOUNDATION_ADR_DIR = path.join(FOUNDATION_DOCS_DIR, "adr");
|
|
84
86
|
const COPILOT_ALLOWED_SKILL_FRONTMATTER_KEYS = new Set([
|
|
85
87
|
"compatibility",
|
|
86
88
|
"description",
|
|
@@ -1312,7 +1314,7 @@ function buildEngineeringArchitectureSection(snapshot) {
|
|
|
1312
1314
|
...profile.testingStrategy.map((rule) => ` - ${rule}`),
|
|
1313
1315
|
"- Doc refresh policy:",
|
|
1314
1316
|
" - Update these managed sections when architecture, scale, boundaries, design-system rules, or testing strategy changes.",
|
|
1315
|
-
|
|
1317
|
+
` - 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.`,
|
|
1316
1318
|
"<!-- cbx:architecture:rules:end -->",
|
|
1317
1319
|
"",
|
|
1318
1320
|
].join("\n");
|
|
@@ -1436,7 +1438,7 @@ function buildRoadmapFoundationSection(snapshot, specRoots = []) {
|
|
|
1436
1438
|
"- Use this section for medium-term scaling themes, major migrations, or cross-team architecture investments.",
|
|
1437
1439
|
"",
|
|
1438
1440
|
"### Backbone Maintenance",
|
|
1439
|
-
|
|
1441
|
+
`- 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.`,
|
|
1440
1442
|
"- Link major roadmap themes back to specs and ADRs instead of burying them in chat-only planning.",
|
|
1441
1443
|
"<!-- cbx:roadmap:foundation:end -->",
|
|
1442
1444
|
"",
|
|
@@ -1578,6 +1580,45 @@ function buildRoadmapTemplate(snapshot, specRoots = []) {
|
|
|
1578
1580
|
].join("\n");
|
|
1579
1581
|
}
|
|
1580
1582
|
|
|
1583
|
+
function buildProductBuildSkeleton() {
|
|
1584
|
+
return [
|
|
1585
|
+
"# Product",
|
|
1586
|
+
"",
|
|
1587
|
+
"This file is managed by `cbx build architecture`.",
|
|
1588
|
+
"",
|
|
1589
|
+
"<!-- cbx:product:foundation:start version=1 profile=uninitialized -->",
|
|
1590
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1591
|
+
"<!-- cbx:product:foundation:end -->",
|
|
1592
|
+
"",
|
|
1593
|
+
].join("\n");
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
function buildArchitectureBuildSkeleton() {
|
|
1597
|
+
return [
|
|
1598
|
+
"# Architecture",
|
|
1599
|
+
"",
|
|
1600
|
+
"This file is managed by `cbx build architecture`.",
|
|
1601
|
+
"",
|
|
1602
|
+
"<!-- cbx:architecture:doc:start version=1 profile=uninitialized -->",
|
|
1603
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1604
|
+
"<!-- cbx:architecture:doc:end -->",
|
|
1605
|
+
"",
|
|
1606
|
+
].join("\n");
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
function buildTechBuildSkeleton() {
|
|
1610
|
+
return [
|
|
1611
|
+
"# TECH.md",
|
|
1612
|
+
"",
|
|
1613
|
+
"This file is managed by `cbx build architecture`.",
|
|
1614
|
+
"",
|
|
1615
|
+
"<!-- cbx:architecture:tech:start version=1 snapshot=uninitialized -->",
|
|
1616
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
1617
|
+
"<!-- cbx:architecture:tech:end -->",
|
|
1618
|
+
"",
|
|
1619
|
+
].join("\n");
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1581
1622
|
function buildAdrReadme() {
|
|
1582
1623
|
return [
|
|
1583
1624
|
"# Architecture Decision Records",
|
|
@@ -1663,7 +1704,7 @@ function buildEngineeringRulesManagedBlock({
|
|
|
1663
1704
|
"2. Keep architecture simple (KISS) and avoid speculative work (YAGNI).",
|
|
1664
1705
|
"3. Apply SOLID pragmatically to reduce change risk, not add ceremony.",
|
|
1665
1706
|
"4. Use clear naming with focused responsibilities and explicit boundaries.",
|
|
1666
|
-
|
|
1707
|
+
`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.`,
|
|
1667
1708
|
"6. Require validation evidence (lint/types/tests) before merge.",
|
|
1668
1709
|
"7. Use Decision Log response style.",
|
|
1669
1710
|
"8. Every Decision Log must include a `Skills Used` section listing skill, workflow, or agent names.",
|
|
@@ -1888,6 +1929,17 @@ async function upsertTaggedSectionInFile({
|
|
|
1888
1929
|
trimmed.length > 0 ? `${trimmed}\n\n${block}\n` : `${block}\n`;
|
|
1889
1930
|
}
|
|
1890
1931
|
|
|
1932
|
+
if (!exists) {
|
|
1933
|
+
if (!dryRun) {
|
|
1934
|
+
await mkdir(path.dirname(targetPath), { recursive: true });
|
|
1935
|
+
await writeFile(targetPath, nextContent, "utf8");
|
|
1936
|
+
}
|
|
1937
|
+
return {
|
|
1938
|
+
action: dryRun ? "would-create" : "created",
|
|
1939
|
+
filePath: targetPath,
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1891
1943
|
if (nextContent === original) {
|
|
1892
1944
|
return {
|
|
1893
1945
|
action: "unchanged",
|
|
@@ -1915,23 +1967,15 @@ async function upsertTaggedSectionInFile({
|
|
|
1915
1967
|
function buildArchitectureBuildMetadata({
|
|
1916
1968
|
platform,
|
|
1917
1969
|
researchMode,
|
|
1918
|
-
|
|
1919
|
-
architectureDocHash,
|
|
1920
|
-
rulesProfileHash,
|
|
1921
|
-
techSnapshotHash,
|
|
1922
|
-
roadmapProfileHash,
|
|
1970
|
+
managedDocs,
|
|
1923
1971
|
}) {
|
|
1924
1972
|
return {
|
|
1925
|
-
schemaVersion:
|
|
1973
|
+
schemaVersion: 3,
|
|
1926
1974
|
generatedBy: "cbx build architecture",
|
|
1927
1975
|
generatedAt: new Date().toISOString(),
|
|
1928
1976
|
platform,
|
|
1929
1977
|
researchMode,
|
|
1930
|
-
|
|
1931
|
-
architectureDocHash,
|
|
1932
|
-
rulesProfileHash,
|
|
1933
|
-
techSnapshotHash,
|
|
1934
|
-
roadmapProfileHash,
|
|
1978
|
+
managedDocs,
|
|
1935
1979
|
};
|
|
1936
1980
|
}
|
|
1937
1981
|
|
|
@@ -2043,6 +2087,87 @@ async function ensureArchitectureDocScaffold({
|
|
|
2043
2087
|
};
|
|
2044
2088
|
}
|
|
2045
2089
|
|
|
2090
|
+
async function ensureArchitectureBuildScaffold({
|
|
2091
|
+
workspaceRoot,
|
|
2092
|
+
dryRun = false,
|
|
2093
|
+
}) {
|
|
2094
|
+
const foundationRoot = path.join(workspaceRoot, FOUNDATION_DOCS_DIR);
|
|
2095
|
+
const productPath = path.join(foundationRoot, "PRODUCT.md");
|
|
2096
|
+
const architectureDocPath = path.join(foundationRoot, "ARCHITECTURE.md");
|
|
2097
|
+
const techMdPath = path.join(foundationRoot, "TECH.md");
|
|
2098
|
+
const adrDir = path.join(workspaceRoot, FOUNDATION_ADR_DIR);
|
|
2099
|
+
const adrReadmePath = path.join(adrDir, "README.md");
|
|
2100
|
+
const adrTemplatePath = path.join(adrDir, "0000-template.md");
|
|
2101
|
+
|
|
2102
|
+
const productResult = await upsertTaggedSectionInFile({
|
|
2103
|
+
targetPath: productPath,
|
|
2104
|
+
initialContent: `${buildProductBuildSkeleton()}\n`,
|
|
2105
|
+
block: [
|
|
2106
|
+
"<!-- cbx:product:foundation:start version=1 profile=uninitialized -->",
|
|
2107
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
2108
|
+
"<!-- cbx:product:foundation:end -->",
|
|
2109
|
+
"",
|
|
2110
|
+
].join("\n"),
|
|
2111
|
+
startPattern: PRODUCT_FOUNDATION_BLOCK_START_RE,
|
|
2112
|
+
endPattern: PRODUCT_FOUNDATION_BLOCK_END_RE,
|
|
2113
|
+
dryRun,
|
|
2114
|
+
});
|
|
2115
|
+
|
|
2116
|
+
const architectureDocResult = await upsertTaggedSectionInFile({
|
|
2117
|
+
targetPath: architectureDocPath,
|
|
2118
|
+
initialContent: `${buildArchitectureBuildSkeleton()}\n`,
|
|
2119
|
+
block: [
|
|
2120
|
+
"<!-- cbx:architecture:doc:start version=1 profile=uninitialized -->",
|
|
2121
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
2122
|
+
"<!-- cbx:architecture:doc:end -->",
|
|
2123
|
+
"",
|
|
2124
|
+
].join("\n"),
|
|
2125
|
+
startPattern: ARCHITECTURE_DOC_BLOCK_START_RE,
|
|
2126
|
+
endPattern: ARCHITECTURE_DOC_BLOCK_END_RE,
|
|
2127
|
+
dryRun,
|
|
2128
|
+
});
|
|
2129
|
+
|
|
2130
|
+
const techResult = await upsertTaggedSectionInFile({
|
|
2131
|
+
targetPath: techMdPath,
|
|
2132
|
+
initialContent: `${buildTechBuildSkeleton()}\n`,
|
|
2133
|
+
block: [
|
|
2134
|
+
"<!-- cbx:architecture:tech:start version=1 snapshot=uninitialized -->",
|
|
2135
|
+
"Replace this managed section by running `cbx build architecture --platform <codex|claude|gemini|copilot>`.",
|
|
2136
|
+
"<!-- cbx:architecture:tech:end -->",
|
|
2137
|
+
"",
|
|
2138
|
+
].join("\n"),
|
|
2139
|
+
startPattern: TECH_ARCHITECTURE_BLOCK_START_RE,
|
|
2140
|
+
endPattern: TECH_ARCHITECTURE_BLOCK_END_RE,
|
|
2141
|
+
dryRun,
|
|
2142
|
+
});
|
|
2143
|
+
|
|
2144
|
+
const adrReadmeResult = await writeTextFile({
|
|
2145
|
+
targetPath: adrReadmePath,
|
|
2146
|
+
content: `${buildAdrReadme()}\n`,
|
|
2147
|
+
overwrite: false,
|
|
2148
|
+
dryRun,
|
|
2149
|
+
});
|
|
2150
|
+
const adrTemplateResult = await writeTextFile({
|
|
2151
|
+
targetPath: adrTemplatePath,
|
|
2152
|
+
content: `${buildAdrTemplate()}\n`,
|
|
2153
|
+
overwrite: false,
|
|
2154
|
+
dryRun,
|
|
2155
|
+
});
|
|
2156
|
+
|
|
2157
|
+
return {
|
|
2158
|
+
productPath,
|
|
2159
|
+
architectureDocPath,
|
|
2160
|
+
techMdPath,
|
|
2161
|
+
adrReadmePath,
|
|
2162
|
+
adrTemplatePath,
|
|
2163
|
+
productResult,
|
|
2164
|
+
architectureDocResult,
|
|
2165
|
+
techResult,
|
|
2166
|
+
adrReadmeResult,
|
|
2167
|
+
adrTemplateResult,
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2046
2171
|
function normalizeTechPackageName(value) {
|
|
2047
2172
|
if (value === undefined || value === null) return null;
|
|
2048
2173
|
const normalized = String(value)
|
|
@@ -12711,7 +12836,7 @@ function printInstallDocumentationNotice() {
|
|
|
12711
12836
|
"- Install only wires the rule references and workflow assets.",
|
|
12712
12837
|
);
|
|
12713
12838
|
console.log(
|
|
12714
|
-
|
|
12839
|
+
`- 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.`,
|
|
12715
12840
|
);
|
|
12716
12841
|
}
|
|
12717
12842
|
|
|
@@ -12896,6 +13021,68 @@ async function listSpecPackRoots(workspaceRoot) {
|
|
|
12896
13021
|
.slice(0, 8);
|
|
12897
13022
|
}
|
|
12898
13023
|
|
|
13024
|
+
async function resolveArchitectureInspectionAnchors(
|
|
13025
|
+
workspaceRoot,
|
|
13026
|
+
snapshot,
|
|
13027
|
+
specRoots,
|
|
13028
|
+
) {
|
|
13029
|
+
const seen = new Set();
|
|
13030
|
+
const ordered = [];
|
|
13031
|
+
const pushCandidate = async (relativePath) => {
|
|
13032
|
+
const normalized = toPosixPath(relativePath);
|
|
13033
|
+
if (!normalized || seen.has(normalized)) return;
|
|
13034
|
+
if (!(await pathExists(path.join(workspaceRoot, relativePath)))) return;
|
|
13035
|
+
seen.add(normalized);
|
|
13036
|
+
ordered.push(normalized);
|
|
13037
|
+
};
|
|
13038
|
+
|
|
13039
|
+
for (const candidate of [
|
|
13040
|
+
"README.md",
|
|
13041
|
+
"package.json",
|
|
13042
|
+
"pubspec.yaml",
|
|
13043
|
+
"go.mod",
|
|
13044
|
+
"pyproject.toml",
|
|
13045
|
+
"Cargo.toml",
|
|
13046
|
+
"Dockerfile",
|
|
13047
|
+
"docker-compose.yml",
|
|
13048
|
+
"docker-compose.yaml",
|
|
13049
|
+
"compose.yaml",
|
|
13050
|
+
"cbx_config.json",
|
|
13051
|
+
".vscode/mcp.json",
|
|
13052
|
+
".gemini/settings.json",
|
|
13053
|
+
]) {
|
|
13054
|
+
await pushCandidate(candidate);
|
|
13055
|
+
}
|
|
13056
|
+
|
|
13057
|
+
for (const specRoot of specRoots.slice(0, 4)) {
|
|
13058
|
+
await pushCandidate(specRoot);
|
|
13059
|
+
}
|
|
13060
|
+
|
|
13061
|
+
for (const app of snapshot.architectureByApp || []) {
|
|
13062
|
+
if (!app?.rootPath || app.rootPath === ".") continue;
|
|
13063
|
+
await pushCandidate(app.rootPath);
|
|
13064
|
+
for (const child of [
|
|
13065
|
+
"README.md",
|
|
13066
|
+
"src",
|
|
13067
|
+
"lib",
|
|
13068
|
+
"app",
|
|
13069
|
+
"prisma",
|
|
13070
|
+
"migrations",
|
|
13071
|
+
"test",
|
|
13072
|
+
"tests",
|
|
13073
|
+
"docs",
|
|
13074
|
+
]) {
|
|
13075
|
+
await pushCandidate(path.join(app.rootPath, child));
|
|
13076
|
+
}
|
|
13077
|
+
}
|
|
13078
|
+
|
|
13079
|
+
for (const dir of snapshot.topDirs || []) {
|
|
13080
|
+
await pushCandidate(dir);
|
|
13081
|
+
}
|
|
13082
|
+
|
|
13083
|
+
return ordered.slice(0, 18);
|
|
13084
|
+
}
|
|
13085
|
+
|
|
12899
13086
|
function resolveArchitectureConditionalSkills(snapshot, specRoots, researchMode) {
|
|
12900
13087
|
const conditional = [];
|
|
12901
13088
|
const frameworks = new Set(snapshot.frameworks || []);
|
|
@@ -12958,17 +13145,17 @@ function buildArchitecturePrompt({
|
|
|
12958
13145
|
workspaceRoot,
|
|
12959
13146
|
snapshot,
|
|
12960
13147
|
specRoots,
|
|
13148
|
+
inspectionAnchors,
|
|
12961
13149
|
researchMode,
|
|
12962
13150
|
coreSkills,
|
|
12963
13151
|
conditionalSkills,
|
|
12964
13152
|
skillPathHints,
|
|
12965
13153
|
}) {
|
|
12966
|
-
const productPath =
|
|
12967
|
-
const architecturePath =
|
|
12968
|
-
const
|
|
12969
|
-
const
|
|
12970
|
-
const
|
|
12971
|
-
const adrReadmePath = "docs/adr/README.md";
|
|
13154
|
+
const productPath = `${FOUNDATION_DOCS_DIR}/PRODUCT.md`;
|
|
13155
|
+
const architecturePath = `${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md`;
|
|
13156
|
+
const techPath = `${FOUNDATION_DOCS_DIR}/TECH.md`;
|
|
13157
|
+
const adrReadmePath = `${FOUNDATION_ADR_DIR}/README.md`;
|
|
13158
|
+
const adrTemplatePath = `${FOUNDATION_ADR_DIR}/0000-template.md`;
|
|
12972
13159
|
const architectureSignals = snapshot.architectureByApp
|
|
12973
13160
|
.filter((item) => (item.architectureSignals || []).length > 0)
|
|
12974
13161
|
.map((item) => {
|
|
@@ -12980,8 +13167,8 @@ function buildArchitecturePrompt({
|
|
|
12980
13167
|
`You are running inside ${platform}.`,
|
|
12981
13168
|
"",
|
|
12982
13169
|
"Objective:",
|
|
12983
|
-
`- Inspect the repository at ${toPosixPath(workspaceRoot)} and refresh the
|
|
12984
|
-
"-
|
|
13170
|
+
`- Inspect the repository at ${toPosixPath(workspaceRoot)} and author or refresh the core foundation docs in ${productPath}, ${architecturePath}, ${techPath}, ${adrReadmePath}, and ${adrTemplatePath}.`,
|
|
13171
|
+
"- The content should be primarily AI-authored from repository inspection, not copied from placeholder scaffolding.",
|
|
12985
13172
|
"- Preserve manual content outside the managed `cbx:*` markers.",
|
|
12986
13173
|
"",
|
|
12987
13174
|
"Required skill bundle:",
|
|
@@ -13001,27 +13188,33 @@ function buildArchitecturePrompt({
|
|
|
13001
13188
|
architectureSignals.length > 0
|
|
13002
13189
|
? `- Architecture signals: ${architectureSignals.join(" | ")}`
|
|
13003
13190
|
: "- Architecture signals: none confidently inferred from the repo scan",
|
|
13191
|
+
`- Entry points: ${snapshot.entryPoints.length > 0 ? snapshot.entryPoints.slice(0, 8).join(" | ") : "none detected"}`,
|
|
13192
|
+
`- Key scripts: ${snapshot.keyScripts.length > 0 ? snapshot.keyScripts.slice(0, 8).map((item) => `${item.name}=${item.command}`).join(" | ") : "none detected"}`,
|
|
13193
|
+
`- Inspection anchors: ${inspectionAnchors.length > 0 ? inspectionAnchors.join(", ") : "no concrete anchors detected; inspect the repo root, main source trees, and manifest files manually"}`,
|
|
13004
13194
|
"",
|
|
13005
13195
|
"Execution contract:",
|
|
13006
|
-
|
|
13007
|
-
"2.
|
|
13008
|
-
"3.
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
|
|
13013
|
-
|
|
13196
|
+
"1. Inspect the repository first before writing any backbone doc content. Derive structure, product surfaces, runtime boundaries, and technical constraints from the actual codebase.",
|
|
13197
|
+
"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.",
|
|
13198
|
+
"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.",
|
|
13199
|
+
`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.`,
|
|
13200
|
+
`5. Replace or update only the content between the existing managed markers in ${productPath}, ${architecturePath}, and ${techPath}. Do not append a second marker block.`,
|
|
13201
|
+
`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.`,
|
|
13202
|
+
`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.`,
|
|
13203
|
+
`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.`,
|
|
13204
|
+
"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.",
|
|
13205
|
+
"10. Avoid placeholder filler, generic checklists, and duplicated content across files. Each doc should have a clear job.",
|
|
13206
|
+
"11. Do not create ROADMAP.md, ENGINEERING_RULES.md, or other extra docs unless the prompt explicitly asks for them.",
|
|
13014
13207
|
researchMode === "never"
|
|
13015
|
-
? "
|
|
13016
|
-
: "
|
|
13208
|
+
? "12. Stay repo-only. Do not use outside research."
|
|
13209
|
+
: "12. Use repo evidence first. Use official docs when needed. Treat Reddit or community sources only as labeled secondary evidence.",
|
|
13017
13210
|
researchMode === "always"
|
|
13018
|
-
?
|
|
13019
|
-
: "
|
|
13020
|
-
|
|
13021
|
-
`
|
|
13211
|
+
? `13. Include an external research evidence subsection in ${techPath} with clearly labeled primary and secondary evidence.`
|
|
13212
|
+
: "13. Include external research notes only if they materially informed the architecture update.",
|
|
13213
|
+
`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.`,
|
|
13214
|
+
`15. Ensure ${adrReadmePath} and ${adrTemplatePath} exist as ADR entrypoints, but keep them lean.`,
|
|
13022
13215
|
"",
|
|
13023
13216
|
"Return one JSON object on the last line with this shape:",
|
|
13024
|
-
|
|
13217
|
+
`{"files_written":["${productPath}","${architecturePath}","${techPath}","${adrReadmePath}","${adrTemplatePath}"],"research_used":false,"gaps":[],"next_actions":[]}`,
|
|
13025
13218
|
"",
|
|
13026
13219
|
"Do not emit placeholder TODOs in the managed sections.",
|
|
13027
13220
|
].join("\n");
|
|
@@ -13284,13 +13477,14 @@ async function captureFileContents(filePaths) {
|
|
|
13284
13477
|
}
|
|
13285
13478
|
|
|
13286
13479
|
async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
|
|
13287
|
-
const
|
|
13288
|
-
const
|
|
13289
|
-
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
const
|
|
13480
|
+
const productPath = path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md");
|
|
13481
|
+
const architecturePath = path.join(
|
|
13482
|
+
workspaceRoot,
|
|
13483
|
+
FOUNDATION_DOCS_DIR,
|
|
13484
|
+
"ARCHITECTURE.md",
|
|
13485
|
+
);
|
|
13486
|
+
const techPath = path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md");
|
|
13487
|
+
const adrReadmePath = path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md");
|
|
13294
13488
|
const metadataPath = path.join(
|
|
13295
13489
|
workspaceRoot,
|
|
13296
13490
|
".cbx",
|
|
@@ -13298,41 +13492,16 @@ async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
|
|
|
13298
13492
|
);
|
|
13299
13493
|
const productExists = await pathExists(productPath);
|
|
13300
13494
|
const architectureExists = await pathExists(architecturePath);
|
|
13301
|
-
const rulesExists = await pathExists(rulesPath);
|
|
13302
13495
|
const techExists = await pathExists(techPath);
|
|
13303
|
-
const roadmapExists = await pathExists(roadmapPath);
|
|
13304
13496
|
const adrReadmeExists = await pathExists(adrReadmePath);
|
|
13305
13497
|
|
|
13306
|
-
const expectedProductHash = hashStableObject(
|
|
13307
|
-
inferProductFoundationProfile(snapshot, specRoots),
|
|
13308
|
-
);
|
|
13309
|
-
const expectedArchitectureHash = hashStableObject(
|
|
13310
|
-
inferArchitectureDocProfile(snapshot, specRoots),
|
|
13311
|
-
);
|
|
13312
|
-
const expectedRulesHash = hashStableObject(
|
|
13313
|
-
inferArchitectureContractProfile(snapshot),
|
|
13314
|
-
);
|
|
13315
|
-
const expectedTechHash = hashStableObject({
|
|
13316
|
-
style: inferArchitectureContractProfile(snapshot).style,
|
|
13317
|
-
topDirs: snapshot.topDirs,
|
|
13318
|
-
frameworks: snapshot.frameworks,
|
|
13319
|
-
architectureByApp: snapshot.architectureByApp,
|
|
13320
|
-
});
|
|
13321
|
-
const expectedRoadmapHash = hashStableObject({
|
|
13322
|
-
topDirs: snapshot.topDirs,
|
|
13323
|
-
frameworks: snapshot.frameworks,
|
|
13324
|
-
specRoots,
|
|
13325
|
-
});
|
|
13326
|
-
|
|
13327
13498
|
const findings = [];
|
|
13328
13499
|
let actualProductHash = null;
|
|
13329
13500
|
let actualArchitectureHash = null;
|
|
13330
|
-
let actualRulesHash = null;
|
|
13331
13501
|
let actualTechHash = null;
|
|
13332
|
-
let actualRoadmapHash = null;
|
|
13333
13502
|
|
|
13334
13503
|
if (!productExists) {
|
|
13335
|
-
findings.push(
|
|
13504
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/PRODUCT.md is missing.`);
|
|
13336
13505
|
} else {
|
|
13337
13506
|
const content = await readFile(productPath, "utf8");
|
|
13338
13507
|
actualProductHash = extractTaggedMarkerAttribute(
|
|
@@ -13341,16 +13510,14 @@ async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
|
|
|
13341
13510
|
"profile",
|
|
13342
13511
|
);
|
|
13343
13512
|
if (!actualProductHash) {
|
|
13344
|
-
findings.push("PRODUCT.md is missing the managed product foundation block.");
|
|
13345
|
-
} else if (actualProductHash !== expectedProductHash) {
|
|
13346
13513
|
findings.push(
|
|
13347
|
-
|
|
13514
|
+
`${FOUNDATION_DOCS_DIR}/PRODUCT.md is missing the managed product foundation block.`,
|
|
13348
13515
|
);
|
|
13349
13516
|
}
|
|
13350
13517
|
}
|
|
13351
13518
|
|
|
13352
13519
|
if (!architectureExists) {
|
|
13353
|
-
findings.push(
|
|
13520
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md is missing.`);
|
|
13354
13521
|
} else {
|
|
13355
13522
|
const content = await readFile(architecturePath, "utf8");
|
|
13356
13523
|
actualArchitectureHash = extractTaggedMarkerAttribute(
|
|
@@ -13359,34 +13526,14 @@ async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
|
|
|
13359
13526
|
"profile",
|
|
13360
13527
|
);
|
|
13361
13528
|
if (!actualArchitectureHash) {
|
|
13362
|
-
findings.push("ARCHITECTURE.md is missing the managed architecture backbone block.");
|
|
13363
|
-
} else if (actualArchitectureHash !== expectedArchitectureHash) {
|
|
13364
|
-
findings.push(
|
|
13365
|
-
`ARCHITECTURE.md backbone is stale (expected ${expectedArchitectureHash}, found ${actualArchitectureHash}).`,
|
|
13366
|
-
);
|
|
13367
|
-
}
|
|
13368
|
-
}
|
|
13369
|
-
|
|
13370
|
-
if (!rulesExists) {
|
|
13371
|
-
findings.push("ENGINEERING_RULES.md is missing.");
|
|
13372
|
-
} else {
|
|
13373
|
-
const content = await readFile(rulesPath, "utf8");
|
|
13374
|
-
actualRulesHash = extractTaggedMarkerAttribute(
|
|
13375
|
-
content,
|
|
13376
|
-
ENGINEERING_ARCHITECTURE_BLOCK_START_RE,
|
|
13377
|
-
"profile",
|
|
13378
|
-
);
|
|
13379
|
-
if (!actualRulesHash) {
|
|
13380
|
-
findings.push("ENGINEERING_RULES.md is missing the managed architecture contract block.");
|
|
13381
|
-
} else if (actualRulesHash !== expectedRulesHash) {
|
|
13382
13529
|
findings.push(
|
|
13383
|
-
|
|
13530
|
+
`${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md is missing the managed architecture backbone block.`,
|
|
13384
13531
|
);
|
|
13385
13532
|
}
|
|
13386
13533
|
}
|
|
13387
13534
|
|
|
13388
13535
|
if (!techExists) {
|
|
13389
|
-
findings.push(
|
|
13536
|
+
findings.push(`${FOUNDATION_DOCS_DIR}/TECH.md is missing.`);
|
|
13390
13537
|
} else {
|
|
13391
13538
|
const content = await readFile(techPath, "utf8");
|
|
13392
13539
|
actualTechHash = extractTaggedMarkerAttribute(
|
|
@@ -13395,34 +13542,14 @@ async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
|
|
|
13395
13542
|
"snapshot",
|
|
13396
13543
|
);
|
|
13397
13544
|
if (!actualTechHash) {
|
|
13398
|
-
findings.push("TECH.md is missing the managed architecture snapshot block.");
|
|
13399
|
-
} else if (actualTechHash !== expectedTechHash) {
|
|
13400
|
-
findings.push(
|
|
13401
|
-
`TECH.md architecture snapshot is stale (expected ${expectedTechHash}, found ${actualTechHash}).`,
|
|
13402
|
-
);
|
|
13403
|
-
}
|
|
13404
|
-
}
|
|
13405
|
-
|
|
13406
|
-
if (!roadmapExists) {
|
|
13407
|
-
findings.push("ROADMAP.md is missing.");
|
|
13408
|
-
} else {
|
|
13409
|
-
const content = await readFile(roadmapPath, "utf8");
|
|
13410
|
-
actualRoadmapHash = extractTaggedMarkerAttribute(
|
|
13411
|
-
content,
|
|
13412
|
-
ROADMAP_FOUNDATION_BLOCK_START_RE,
|
|
13413
|
-
"profile",
|
|
13414
|
-
);
|
|
13415
|
-
if (!actualRoadmapHash) {
|
|
13416
|
-
findings.push("ROADMAP.md is missing the managed roadmap foundation block.");
|
|
13417
|
-
} else if (actualRoadmapHash !== expectedRoadmapHash) {
|
|
13418
13545
|
findings.push(
|
|
13419
|
-
|
|
13546
|
+
`${FOUNDATION_DOCS_DIR}/TECH.md is missing the managed architecture snapshot block.`,
|
|
13420
13547
|
);
|
|
13421
13548
|
}
|
|
13422
13549
|
}
|
|
13423
13550
|
|
|
13424
13551
|
if (!adrReadmeExists) {
|
|
13425
|
-
findings.push(
|
|
13552
|
+
findings.push(`${FOUNDATION_ADR_DIR}/README.md is missing.`);
|
|
13426
13553
|
}
|
|
13427
13554
|
|
|
13428
13555
|
const metadata = await readJsonFileIfExists(metadataPath);
|
|
@@ -13435,21 +13562,12 @@ async function readArchitectureDriftStatus(workspaceRoot, snapshot) {
|
|
|
13435
13562
|
findings,
|
|
13436
13563
|
productPath,
|
|
13437
13564
|
architecturePath,
|
|
13438
|
-
rulesPath,
|
|
13439
13565
|
techPath,
|
|
13440
|
-
roadmapPath,
|
|
13441
13566
|
adrReadmePath,
|
|
13442
13567
|
metadataPath,
|
|
13443
|
-
expectedProductHash,
|
|
13444
|
-
expectedArchitectureHash,
|
|
13445
|
-
expectedRulesHash,
|
|
13446
|
-
expectedTechHash,
|
|
13447
|
-
expectedRoadmapHash,
|
|
13448
13568
|
actualProductHash,
|
|
13449
13569
|
actualArchitectureHash,
|
|
13450
|
-
actualRulesHash,
|
|
13451
13570
|
actualTechHash,
|
|
13452
|
-
actualRoadmapHash,
|
|
13453
13571
|
};
|
|
13454
13572
|
}
|
|
13455
13573
|
|
|
@@ -13475,7 +13593,7 @@ async function runBuildArchitecture(options) {
|
|
|
13475
13593
|
console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
|
|
13476
13594
|
console.log(`Status: ${drift.stale ? "stale" : "fresh"}`);
|
|
13477
13595
|
console.log(
|
|
13478
|
-
|
|
13596
|
+
`Backbone docs: ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ${FOUNDATION_DOCS_DIR}/TECH.md, ${FOUNDATION_ADR_DIR}/README.md`,
|
|
13479
13597
|
);
|
|
13480
13598
|
if (drift.findings.length > 0) {
|
|
13481
13599
|
console.log("Findings:");
|
|
@@ -13489,25 +13607,12 @@ async function runBuildArchitecture(options) {
|
|
|
13489
13607
|
}
|
|
13490
13608
|
|
|
13491
13609
|
const managedFilePaths = [
|
|
13492
|
-
path.join(workspaceRoot, "PRODUCT.md"),
|
|
13493
|
-
path.join(workspaceRoot, "ARCHITECTURE.md"),
|
|
13494
|
-
path.join(workspaceRoot, "
|
|
13495
|
-
path.join(workspaceRoot, "
|
|
13496
|
-
path.join(workspaceRoot, "
|
|
13497
|
-
path.join(workspaceRoot, "docs", "adr", "README.md"),
|
|
13498
|
-
path.join(workspaceRoot, "docs", "adr", "0000-template.md"),
|
|
13610
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md"),
|
|
13611
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "ARCHITECTURE.md"),
|
|
13612
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md"),
|
|
13613
|
+
path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md"),
|
|
13614
|
+
path.join(workspaceRoot, FOUNDATION_ADR_DIR, "0000-template.md"),
|
|
13499
13615
|
];
|
|
13500
|
-
const filesBefore = dryRun
|
|
13501
|
-
? Object.fromEntries(managedFilePaths.map((filePath) => [filePath, null]))
|
|
13502
|
-
: await captureFileContents(managedFilePaths);
|
|
13503
|
-
|
|
13504
|
-
const scaffold = await ensureArchitectureDocScaffold({
|
|
13505
|
-
workspaceRoot,
|
|
13506
|
-
snapshot,
|
|
13507
|
-
specRoots,
|
|
13508
|
-
overwrite,
|
|
13509
|
-
dryRun,
|
|
13510
|
-
});
|
|
13511
13616
|
const coreSkills = [
|
|
13512
13617
|
"architecture-doc",
|
|
13513
13618
|
"system-design",
|
|
@@ -13525,11 +13630,17 @@ async function runBuildArchitecture(options) {
|
|
|
13525
13630
|
cwd,
|
|
13526
13631
|
skillBundle,
|
|
13527
13632
|
);
|
|
13633
|
+
const inspectionAnchors = await resolveArchitectureInspectionAnchors(
|
|
13634
|
+
workspaceRoot,
|
|
13635
|
+
snapshot,
|
|
13636
|
+
specRoots,
|
|
13637
|
+
);
|
|
13528
13638
|
const prompt = buildArchitecturePrompt({
|
|
13529
13639
|
platform,
|
|
13530
13640
|
workspaceRoot,
|
|
13531
13641
|
snapshot,
|
|
13532
13642
|
specRoots,
|
|
13643
|
+
inspectionAnchors,
|
|
13533
13644
|
researchMode,
|
|
13534
13645
|
coreSkills,
|
|
13535
13646
|
conditionalSkills,
|
|
@@ -13537,6 +13648,13 @@ async function runBuildArchitecture(options) {
|
|
|
13537
13648
|
});
|
|
13538
13649
|
const adapter = await probeArchitectureAdapter(platform, workspaceRoot);
|
|
13539
13650
|
const args = adapter.buildInvocation(prompt);
|
|
13651
|
+
const managedTargets = [
|
|
13652
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "PRODUCT.md"),
|
|
13653
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "ARCHITECTURE.md"),
|
|
13654
|
+
path.join(workspaceRoot, FOUNDATION_DOCS_DIR, "TECH.md"),
|
|
13655
|
+
path.join(workspaceRoot, FOUNDATION_ADR_DIR, "README.md"),
|
|
13656
|
+
path.join(workspaceRoot, FOUNDATION_ADR_DIR, "0000-template.md"),
|
|
13657
|
+
].map((filePath) => toPosixPath(filePath));
|
|
13540
13658
|
|
|
13541
13659
|
if (dryRun) {
|
|
13542
13660
|
const summary = {
|
|
@@ -13545,15 +13663,7 @@ async function runBuildArchitecture(options) {
|
|
|
13545
13663
|
adapter: adapter.binary,
|
|
13546
13664
|
invocation: [adapter.binary, ...args],
|
|
13547
13665
|
researchMode,
|
|
13548
|
-
managedTargets
|
|
13549
|
-
toPosixPath(scaffold.productPath),
|
|
13550
|
-
toPosixPath(scaffold.architectureDocPath),
|
|
13551
|
-
toPosixPath(scaffold.engineeringRulesPath),
|
|
13552
|
-
toPosixPath(scaffold.techMdPath),
|
|
13553
|
-
toPosixPath(scaffold.roadmapPath),
|
|
13554
|
-
toPosixPath(scaffold.adrReadmePath),
|
|
13555
|
-
toPosixPath(scaffold.adrTemplatePath),
|
|
13556
|
-
],
|
|
13666
|
+
managedTargets,
|
|
13557
13667
|
skillBundle,
|
|
13558
13668
|
};
|
|
13559
13669
|
if (emitJson) {
|
|
@@ -13564,7 +13674,7 @@ async function runBuildArchitecture(options) {
|
|
|
13564
13674
|
console.log(`Adapter: ${adapter.binary}`);
|
|
13565
13675
|
console.log(`Research mode: ${researchMode}`);
|
|
13566
13676
|
console.log(
|
|
13567
|
-
`Managed targets: ${
|
|
13677
|
+
`Managed targets: ${summary.managedTargets.join(", ")}`,
|
|
13568
13678
|
);
|
|
13569
13679
|
console.log(`Skill bundle: ${skillBundle.join(", ")}`);
|
|
13570
13680
|
console.log(`Invocation: ${[adapter.binary, ...args].join(" ")}`);
|
|
@@ -13572,6 +13682,12 @@ async function runBuildArchitecture(options) {
|
|
|
13572
13682
|
return;
|
|
13573
13683
|
}
|
|
13574
13684
|
|
|
13685
|
+
const filesBefore = await captureFileContents(managedFilePaths);
|
|
13686
|
+
const scaffold = await ensureArchitectureBuildScaffold({
|
|
13687
|
+
workspaceRoot,
|
|
13688
|
+
dryRun,
|
|
13689
|
+
});
|
|
13690
|
+
|
|
13575
13691
|
if (!emitJson) {
|
|
13576
13692
|
console.log(`Streaming ${adapter.binary} output...`);
|
|
13577
13693
|
}
|
|
@@ -13590,9 +13706,6 @@ async function runBuildArchitecture(options) {
|
|
|
13590
13706
|
.filter((filePath) => filesBefore[filePath] !== filesAfter[filePath])
|
|
13591
13707
|
.map((filePath) => toPosixPath(path.relative(workspaceRoot, filePath)));
|
|
13592
13708
|
|
|
13593
|
-
const rulesContent =
|
|
13594
|
-
filesAfter[scaffold.engineeringRulesPath] ??
|
|
13595
|
-
(await readFile(scaffold.engineeringRulesPath, "utf8"));
|
|
13596
13709
|
const techContent =
|
|
13597
13710
|
filesAfter[scaffold.techMdPath] ?? (await readFile(scaffold.techMdPath, "utf8"));
|
|
13598
13711
|
const productContent =
|
|
@@ -13600,8 +13713,6 @@ async function runBuildArchitecture(options) {
|
|
|
13600
13713
|
const architectureContent =
|
|
13601
13714
|
filesAfter[scaffold.architectureDocPath] ??
|
|
13602
13715
|
(await readFile(scaffold.architectureDocPath, "utf8"));
|
|
13603
|
-
const roadmapContent =
|
|
13604
|
-
filesAfter[scaffold.roadmapPath] ?? (await readFile(scaffold.roadmapPath, "utf8"));
|
|
13605
13716
|
|
|
13606
13717
|
const metadataPath = path.join(
|
|
13607
13718
|
workspaceRoot,
|
|
@@ -13611,36 +13722,13 @@ async function runBuildArchitecture(options) {
|
|
|
13611
13722
|
const metadata = buildArchitectureBuildMetadata({
|
|
13612
13723
|
platform,
|
|
13613
13724
|
researchMode,
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
extractTaggedMarkerAttribute(
|
|
13622
|
-
architectureContent,
|
|
13623
|
-
ARCHITECTURE_DOC_BLOCK_START_RE,
|
|
13624
|
-
"profile",
|
|
13625
|
-
) || "unknown",
|
|
13626
|
-
rulesProfileHash:
|
|
13627
|
-
extractTaggedMarkerAttribute(
|
|
13628
|
-
rulesContent,
|
|
13629
|
-
ENGINEERING_ARCHITECTURE_BLOCK_START_RE,
|
|
13630
|
-
"profile",
|
|
13631
|
-
) || "unknown",
|
|
13632
|
-
techSnapshotHash:
|
|
13633
|
-
extractTaggedMarkerAttribute(
|
|
13634
|
-
techContent,
|
|
13635
|
-
TECH_ARCHITECTURE_BLOCK_START_RE,
|
|
13636
|
-
"snapshot",
|
|
13637
|
-
) || "unknown",
|
|
13638
|
-
roadmapProfileHash:
|
|
13639
|
-
extractTaggedMarkerAttribute(
|
|
13640
|
-
roadmapContent,
|
|
13641
|
-
ROADMAP_FOUNDATION_BLOCK_START_RE,
|
|
13642
|
-
"profile",
|
|
13643
|
-
) || "unknown",
|
|
13725
|
+
managedDocs: [
|
|
13726
|
+
`${FOUNDATION_DOCS_DIR}/PRODUCT.md`,
|
|
13727
|
+
`${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md`,
|
|
13728
|
+
`${FOUNDATION_DOCS_DIR}/TECH.md`,
|
|
13729
|
+
`${FOUNDATION_ADR_DIR}/README.md`,
|
|
13730
|
+
`${FOUNDATION_ADR_DIR}/0000-template.md`,
|
|
13731
|
+
],
|
|
13644
13732
|
});
|
|
13645
13733
|
await mkdir(path.dirname(metadataPath), { recursive: true });
|
|
13646
13734
|
await writeFile(
|
|
@@ -13676,10 +13764,10 @@ async function runBuildArchitecture(options) {
|
|
|
13676
13764
|
console.log(`Adapter: ${adapter.binary}`);
|
|
13677
13765
|
console.log(`Workspace: ${toPosixPath(workspaceRoot)}`);
|
|
13678
13766
|
console.log(
|
|
13679
|
-
|
|
13767
|
+
`Managed docs: ${FOUNDATION_DOCS_DIR}/PRODUCT.md, ${FOUNDATION_DOCS_DIR}/ARCHITECTURE.md, ${FOUNDATION_DOCS_DIR}/TECH.md`,
|
|
13680
13768
|
);
|
|
13681
13769
|
console.log(
|
|
13682
|
-
|
|
13770
|
+
`ADR scaffold: ${FOUNDATION_ADR_DIR}/README.md, ${FOUNDATION_ADR_DIR}/0000-template.md`,
|
|
13683
13771
|
);
|
|
13684
13772
|
console.log(`Skill bundle: ${skillBundle.join(", ")}`);
|
|
13685
13773
|
console.log(
|