archctx 0.9.4 → 0.11.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/assets/catalog.yaml +2 -2
- package/bin/archctx.mjs +1367 -899
- package/package.json +1 -1
package/bin/archctx.mjs
CHANGED
|
@@ -173,6 +173,22 @@ var init_architecture = __esm(() => {
|
|
|
173
173
|
];
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
+
// packages/contracts/src/architecture-history.ts
|
|
177
|
+
function decodeArchitectureHistoryState(value) {
|
|
178
|
+
if (!object(value))
|
|
179
|
+
return;
|
|
180
|
+
if (value.nodes === null && value.edges === null && value.structure === null && error(value.error))
|
|
181
|
+
return value;
|
|
182
|
+
if (value.error === undefined && list(value.nodes, node) && list(value.edges, edge) && list(value.structure, structure))
|
|
183
|
+
return value;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
var ARCHITECTURE_HISTORY_SCHEMA_VERSION = "archcontext.architecture-history/v1", ARCHITECTURE_HISTORY_MERMAID_SCHEMA_VERSION = "archcontext.architecture-history-mermaid/v1", ARCHITECTURE_HISTORY_DERIVATION_VERSION = "v3", object = (v) => typeof v === "object" && v !== null && !Array.isArray(v), string = (v) => typeof v === "string", edge = (v) => object(v) && string(v.source) && string(v.target), kind = (v) => v === "capability" || v === "module" || v === "component", item = (v) => object(v) && string(v.id) && kind(v.kind) && (v.capability === null || string(v.capability)) && (v.kind !== "capability" || v.capability === v.id), structure = (v) => item(v) && object(v) && string(v.name), node = (v) => object(v) && string(v.id) && string(v.name) && (v.domain === null || string(v.domain)), errors, error = (v) => object(v) && string(v.code) && errors.includes(v.code) && (v.path === undefined || string(v.path) && isRepoRelativePosixPath(v.path)), list = (v, check) => Array.isArray(v) && v.every(check);
|
|
187
|
+
var init_architecture_history = __esm(() => {
|
|
188
|
+
init_schema();
|
|
189
|
+
errors = ["history-model-layout-unsupported", "history-model-missing", "history-model-invalid", "history-model-too-large"];
|
|
190
|
+
});
|
|
191
|
+
|
|
176
192
|
// packages/contracts/src/architecture-debt.ts
|
|
177
193
|
function architectureDebtReportIssues(report) {
|
|
178
194
|
const issues = [];
|
|
@@ -1961,6 +1977,450 @@ var init_projection = __esm(() => {
|
|
|
1961
1977
|
ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?Z$/;
|
|
1962
1978
|
});
|
|
1963
1979
|
|
|
1980
|
+
// packages/contracts/src/projection-manifest.ts
|
|
1981
|
+
function isRuntimeTopologyTargetType(type) {
|
|
1982
|
+
return typeof type === "string" && RUNTIME_TOPOLOGY_TARGET_TYPES.includes(type);
|
|
1983
|
+
}
|
|
1984
|
+
function architectureDocsProjectionManifestIssues(value) {
|
|
1985
|
+
const issues = [];
|
|
1986
|
+
const manifest = record2(value);
|
|
1987
|
+
if (!manifest)
|
|
1988
|
+
return ["manifest must be an object"];
|
|
1989
|
+
issues.push(...exactKeys(manifest, ["schemaVersion", "rendererVersion", "profile", "layoutVersion", "generatedFrom", "semanticBaseline", "targets"], ["minimumRendererVersion", "minimumProtocolVersion"], "manifest"));
|
|
1990
|
+
if (manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION)
|
|
1991
|
+
issues.push("manifest.schemaVersion is unsupported");
|
|
1992
|
+
if (!isNonEmptyString(manifest.rendererVersion))
|
|
1993
|
+
issues.push("manifest.rendererVersion must be a non-empty string");
|
|
1994
|
+
for (const [key, family] of [["minimumRendererVersion", "archcontext.docs-renderer/v"], ["minimumProtocolVersion", "archcontext.projection-request/v"]]) {
|
|
1995
|
+
if (Object.hasOwn(manifest, key) && versionNumber(manifest[key], family) === undefined)
|
|
1996
|
+
issues.push(`manifest.${key} must name a supported version family`);
|
|
1997
|
+
}
|
|
1998
|
+
if (!ARCHITECTURE_DOCS_PROJECTION_PROFILES.includes(manifest.profile))
|
|
1999
|
+
issues.push("manifest.profile is unsupported");
|
|
2000
|
+
if (manifest.layoutVersion !== ARCHITECTURE_DOCS_LAYOUT_VERSION_V1)
|
|
2001
|
+
issues.push("manifest.layoutVersion is unsupported");
|
|
2002
|
+
issues.push(...generatedFromIssues(manifest.generatedFrom, "manifest.generatedFrom"));
|
|
2003
|
+
const baseline = record2(manifest.semanticBaseline);
|
|
2004
|
+
if (!baseline)
|
|
2005
|
+
issues.push("manifest.semanticBaseline must be an object");
|
|
2006
|
+
else {
|
|
2007
|
+
issues.push(...exactKeys(baseline, ["modelDigest", "capabilities"], [], "manifest.semanticBaseline"));
|
|
2008
|
+
if (!isDigest(baseline.modelDigest))
|
|
2009
|
+
issues.push("manifest.semanticBaseline.modelDigest must be a SHA-256 digest");
|
|
2010
|
+
issues.push(...capabilityEntriesIssues(baseline.capabilities, "manifest.semanticBaseline.capabilities", true));
|
|
2011
|
+
}
|
|
2012
|
+
const targets = record2(manifest.targets);
|
|
2013
|
+
if (!targets) {
|
|
2014
|
+
issues.push("manifest.targets must be an object keyed by targetId");
|
|
2015
|
+
return issues;
|
|
2016
|
+
}
|
|
2017
|
+
const paths = new Set;
|
|
2018
|
+
const stampOwners = new Map;
|
|
2019
|
+
let topologyStamps;
|
|
2020
|
+
for (const [targetId, row] of Object.entries(targets)) {
|
|
2021
|
+
const prefix = `manifest.targets[${JSON.stringify(targetId)}]`;
|
|
2022
|
+
if (!isNonEmptyString(targetId))
|
|
2023
|
+
issues.push("manifest.targets keys must be non-empty targetIds");
|
|
2024
|
+
issues.push(...manifestTargetIssues(row, prefix));
|
|
2025
|
+
const path = record2(row)?.path;
|
|
2026
|
+
if (typeof path === "string") {
|
|
2027
|
+
if (paths.has(path))
|
|
2028
|
+
issues.push(`${prefix}.path is recorded by another target`);
|
|
2029
|
+
paths.add(path);
|
|
2030
|
+
}
|
|
2031
|
+
const stamps = record2(record2(row)?.sourceStamps) ?? {};
|
|
2032
|
+
if (isRuntimeTopologyTargetType(record2(row)?.type)) {
|
|
2033
|
+
const serialized = JSON.stringify(Object.keys(stamps).sort(compareStrings).map((nodeId) => [nodeId, stamps[nodeId]]));
|
|
2034
|
+
if (topologyStamps === undefined)
|
|
2035
|
+
topologyStamps = { targetId, stamps: serialized };
|
|
2036
|
+
else if (topologyStamps.stamps !== serialized)
|
|
2037
|
+
issues.push(`${prefix}.sourceStamps must equal the sourceStamps of ${topologyStamps.targetId}`);
|
|
2038
|
+
for (const nodeId of Object.keys(stamps)) {
|
|
2039
|
+
const owner = stampOwners.get(nodeId);
|
|
2040
|
+
if (owner !== undefined && !isRuntimeTopologyTargetType(record2(targets[owner])?.type))
|
|
2041
|
+
issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
|
|
2042
|
+
else if (owner === undefined)
|
|
2043
|
+
stampOwners.set(nodeId, targetId);
|
|
2044
|
+
}
|
|
2045
|
+
continue;
|
|
2046
|
+
}
|
|
2047
|
+
for (const nodeId of Object.keys(stamps)) {
|
|
2048
|
+
const owner = stampOwners.get(nodeId);
|
|
2049
|
+
if (owner !== undefined)
|
|
2050
|
+
issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
|
|
2051
|
+
else
|
|
2052
|
+
stampOwners.set(nodeId, targetId);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
return issues;
|
|
2056
|
+
}
|
|
2057
|
+
function architectureDocsProjectionManifestSchemaVersion(body) {
|
|
2058
|
+
let parsed;
|
|
2059
|
+
try {
|
|
2060
|
+
parsed = JSON.parse(body);
|
|
2061
|
+
} catch {
|
|
2062
|
+
return;
|
|
2063
|
+
}
|
|
2064
|
+
const schemaVersion = record2(parsed)?.schemaVersion;
|
|
2065
|
+
return typeof schemaVersion === "string" ? schemaVersion : undefined;
|
|
2066
|
+
}
|
|
2067
|
+
function isSupersededArchitectureDocsProjectionManifestSchemaVersion(schemaVersion) {
|
|
2068
|
+
return SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS.includes(schemaVersion);
|
|
2069
|
+
}
|
|
2070
|
+
function serializeArchitectureDocsProjectionManifest(manifest) {
|
|
2071
|
+
const capabilities = [...manifest.semanticBaseline.capabilities].sort((left, right) => compareStrings(left.capabilityId, right.capabilityId)).map(canonicalCapability);
|
|
2072
|
+
const capabilityBlock = JSON.stringify(capabilities, null, 2).split(`
|
|
2073
|
+
`).map((line, index) => index === 0 ? line : ` ${line}`).join(`
|
|
2074
|
+
`);
|
|
2075
|
+
const targetIds = Object.keys(manifest.targets).sort(compareStrings);
|
|
2076
|
+
const targetLines = targetIds.length === 0 ? [' "targets": {}'] : [
|
|
2077
|
+
' "targets": {',
|
|
2078
|
+
...targetIds.flatMap((targetId, index) => [
|
|
2079
|
+
` ${JSON.stringify(targetId)}:`,
|
|
2080
|
+
` ${JSON.stringify(canonicalTargetRow(manifest.targets[targetId]))}${index === targetIds.length - 1 ? "" : ","}`
|
|
2081
|
+
]),
|
|
2082
|
+
" }"
|
|
2083
|
+
];
|
|
2084
|
+
return [
|
|
2085
|
+
"{",
|
|
2086
|
+
` "schemaVersion": ${JSON.stringify(manifest.schemaVersion)},`,
|
|
2087
|
+
` "rendererVersion": ${JSON.stringify(manifest.rendererVersion)},`,
|
|
2088
|
+
...manifest.minimumRendererVersion === undefined ? [] : [` "minimumRendererVersion": ${JSON.stringify(manifest.minimumRendererVersion)},`],
|
|
2089
|
+
...manifest.minimumProtocolVersion === undefined ? [] : [` "minimumProtocolVersion": ${JSON.stringify(manifest.minimumProtocolVersion)},`],
|
|
2090
|
+
` "profile": ${JSON.stringify(manifest.profile)},`,
|
|
2091
|
+
` "layoutVersion": ${JSON.stringify(manifest.layoutVersion)},`,
|
|
2092
|
+
` "generatedFrom": ${JSON.stringify({ codeGraphPackage: manifest.generatedFrom.codeGraphPackage, codeGraphVersion: manifest.generatedFrom.codeGraphVersion })},`,
|
|
2093
|
+
' "semanticBaseline": {',
|
|
2094
|
+
` "modelDigest": ${JSON.stringify(manifest.semanticBaseline.modelDigest)},`,
|
|
2095
|
+
` "capabilities": ${capabilityBlock}`,
|
|
2096
|
+
" },",
|
|
2097
|
+
...targetLines,
|
|
2098
|
+
"}",
|
|
2099
|
+
""
|
|
2100
|
+
].join(`
|
|
2101
|
+
`);
|
|
2102
|
+
}
|
|
2103
|
+
function architectureDocsProjectionManifestSemanticState(manifest) {
|
|
2104
|
+
return architectureSemanticStateFromCapabilities(manifest.semanticBaseline.capabilities.map(({ selectorEvidenceDigest: _selectorEvidenceDigest, ...capability }) => capability));
|
|
2105
|
+
}
|
|
2106
|
+
function architectureSemanticStateFromCapabilities(capabilities) {
|
|
2107
|
+
const sorted = [...capabilities].sort((left, right) => compareStrings(left.capabilityId, right.capabilityId));
|
|
2108
|
+
return {
|
|
2109
|
+
schemaVersion: ARCHITECTURE_SEMANTIC_STATE_SCHEMA_VERSION,
|
|
2110
|
+
capabilities: sorted,
|
|
2111
|
+
semanticFingerprint: digestJson(sorted.map(({ capabilityId, semanticFingerprint }) => ({ capabilityId, semanticFingerprint }))),
|
|
2112
|
+
flowProofFingerprint: digestJson(sorted.map(({ capabilityId, flowProofFingerprint }) => ({ capabilityId, flowProofFingerprint })))
|
|
2113
|
+
};
|
|
2114
|
+
}
|
|
2115
|
+
function architectureDocsProjectionManifestSourceStamps(manifest) {
|
|
2116
|
+
const stamps = {};
|
|
2117
|
+
for (const row of Object.values(manifest.targets))
|
|
2118
|
+
Object.assign(stamps, row.sourceStamps ?? {});
|
|
2119
|
+
return stamps;
|
|
2120
|
+
}
|
|
2121
|
+
function architectureDocsProjectionManifestProofEvidence(manifest) {
|
|
2122
|
+
return {
|
|
2123
|
+
rendererVersion: manifest.rendererVersion,
|
|
2124
|
+
selectorEvidenceDigests: Object.fromEntries(manifest.semanticBaseline.capabilities.map((capability) => [capability.capabilityId, capability.selectorEvidenceDigest])),
|
|
2125
|
+
sourceStamps: architectureDocsProjectionManifestSourceStamps(manifest)
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2128
|
+
function architectureSourceStampsDigest(stamps) {
|
|
2129
|
+
return digestJson({
|
|
2130
|
+
schemaVersion: "archcontext.architecture-source-stamps/v1",
|
|
2131
|
+
stamps: Object.keys(stamps).sort(compareStrings).map((nodeId) => ({ nodeId, digest: stamps[nodeId] }))
|
|
2132
|
+
});
|
|
2133
|
+
}
|
|
2134
|
+
function architectureProjectionOutputsDigest(input) {
|
|
2135
|
+
return digestJson({
|
|
2136
|
+
schemaVersion: "archcontext.architecture-projection-outputs/v1",
|
|
2137
|
+
rendererVersion: input.rendererVersion,
|
|
2138
|
+
profile: input.profile,
|
|
2139
|
+
outputs: Object.keys(input.outputDigests).sort(compareStrings).map((targetId) => ({ targetId, outputDigest: input.outputDigests[targetId] }))
|
|
2140
|
+
});
|
|
2141
|
+
}
|
|
2142
|
+
function architectureDocsProjectionManifestDigests(manifest) {
|
|
2143
|
+
return {
|
|
2144
|
+
modelDigest: manifest.semanticBaseline.modelDigest,
|
|
2145
|
+
sourceTreeDigest: architectureSourceStampsDigest(architectureDocsProjectionManifestSourceStamps(manifest)),
|
|
2146
|
+
flowProofDigest: architectureDocsProjectionManifestSemanticState(manifest).flowProofFingerprint,
|
|
2147
|
+
projectionDigest: architectureProjectionOutputsDigest({
|
|
2148
|
+
rendererVersion: manifest.rendererVersion,
|
|
2149
|
+
profile: manifest.profile,
|
|
2150
|
+
outputDigests: Object.fromEntries(Object.entries(manifest.targets).map(([targetId, row]) => [targetId, row.outputDigest]))
|
|
2151
|
+
})
|
|
2152
|
+
};
|
|
2153
|
+
}
|
|
2154
|
+
function architectureDocsProjectionProvenanceIssues(value, prefix = "provenance") {
|
|
2155
|
+
const provenance = record2(value);
|
|
2156
|
+
if (!provenance)
|
|
2157
|
+
return [`${prefix} must be an object`];
|
|
2158
|
+
const issues = exactKeys(provenance, ["schemaVersion", "sourceTreeDigest", "modelDigest", "projectionInputDigest", "rendererVersion", "layoutVersion", "generatedFrom"], [], prefix);
|
|
2159
|
+
if (provenance.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_PROVENANCE_SCHEMA_VERSION)
|
|
2160
|
+
issues.push(`${prefix}.schemaVersion is unsupported`);
|
|
2161
|
+
for (const field of ["sourceTreeDigest", "modelDigest", "projectionInputDigest"]) {
|
|
2162
|
+
if (!isDigest(provenance[field]))
|
|
2163
|
+
issues.push(`${prefix}.${field} must be a SHA-256 digest`);
|
|
2164
|
+
}
|
|
2165
|
+
if (provenance.rendererVersion !== ARCHITECTURE_DOCS_RENDERER_VERSION)
|
|
2166
|
+
issues.push(`${prefix}.rendererVersion must be ${ARCHITECTURE_DOCS_RENDERER_VERSION}`);
|
|
2167
|
+
if (provenance.layoutVersion !== ARCHITECTURE_DOCS_LAYOUT_VERSION_V1)
|
|
2168
|
+
issues.push(`${prefix}.layoutVersion is unsupported`);
|
|
2169
|
+
issues.push(...generatedFromIssues(provenance.generatedFrom, `${prefix}.generatedFrom`));
|
|
2170
|
+
return issues;
|
|
2171
|
+
}
|
|
2172
|
+
function capabilityEntriesIssues(value, prefix, withSelectorEvidence) {
|
|
2173
|
+
if (!Array.isArray(value))
|
|
2174
|
+
return [`${prefix} must be an array`];
|
|
2175
|
+
const issues = [];
|
|
2176
|
+
const ids = value.map((entry) => record2(entry)?.capabilityId);
|
|
2177
|
+
if (!isSortedUniqueStrings(ids))
|
|
2178
|
+
issues.push(`${prefix} must be sorted and unique by capabilityId`);
|
|
2179
|
+
value.forEach((entry, index) => {
|
|
2180
|
+
const entryPrefix = `${prefix}[${index}]`;
|
|
2181
|
+
const capability = record2(entry);
|
|
2182
|
+
if (!capability) {
|
|
2183
|
+
issues.push(`${entryPrefix} must be an object`);
|
|
2184
|
+
return;
|
|
2185
|
+
}
|
|
2186
|
+
const required = ["capabilityId", "memberNodeIds", "semanticFingerprint", "flowProofFingerprint", "proofStatus", "facets", ...withSelectorEvidence ? ["selectorEvidenceDigest"] : []];
|
|
2187
|
+
issues.push(...exactKeys(capability, required, [], entryPrefix));
|
|
2188
|
+
if (!isNonEmptyString(capability.capabilityId))
|
|
2189
|
+
issues.push(`${entryPrefix}.capabilityId must be a non-empty string`);
|
|
2190
|
+
if (!Array.isArray(capability.memberNodeIds) || !isSortedUniqueStrings(capability.memberNodeIds))
|
|
2191
|
+
issues.push(`${entryPrefix}.memberNodeIds must be sorted and unique`);
|
|
2192
|
+
if (!isDigest(capability.semanticFingerprint))
|
|
2193
|
+
issues.push(`${entryPrefix}.semanticFingerprint must be a SHA-256 digest`);
|
|
2194
|
+
if (!isDigest(capability.flowProofFingerprint))
|
|
2195
|
+
issues.push(`${entryPrefix}.flowProofFingerprint must be a SHA-256 digest`);
|
|
2196
|
+
if (withSelectorEvidence && !isDigest(capability.selectorEvidenceDigest))
|
|
2197
|
+
issues.push(`${entryPrefix}.selectorEvidenceDigest must be a SHA-256 digest`);
|
|
2198
|
+
if (!isArchitectureCapabilityProofStatus(capability.proofStatus))
|
|
2199
|
+
issues.push(`${entryPrefix}.proofStatus must be a P1/P2 proof status`);
|
|
2200
|
+
const facets = record2(capability.facets);
|
|
2201
|
+
if (!facets)
|
|
2202
|
+
issues.push(`${entryPrefix}.facets must be an object`);
|
|
2203
|
+
else {
|
|
2204
|
+
issues.push(...exactKeys(facets, [...ARCHITECTURE_SEMANTIC_FACETS], [], `${entryPrefix}.facets`));
|
|
2205
|
+
for (const facet of ARCHITECTURE_SEMANTIC_FACETS) {
|
|
2206
|
+
if (!isDigest(facets[facet]))
|
|
2207
|
+
issues.push(`${entryPrefix}.facets.${facet} must be a SHA-256 digest`);
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
});
|
|
2211
|
+
return issues;
|
|
2212
|
+
}
|
|
2213
|
+
function generatedFromIssues(value, prefix) {
|
|
2214
|
+
const generatedFrom = record2(value);
|
|
2215
|
+
if (!generatedFrom)
|
|
2216
|
+
return [`${prefix} must be an object`];
|
|
2217
|
+
const issues = exactKeys(generatedFrom, ["codeGraphPackage", "codeGraphVersion"], [], prefix);
|
|
2218
|
+
for (const field of ["codeGraphPackage", "codeGraphVersion"]) {
|
|
2219
|
+
if (!isNonEmptyString(generatedFrom[field]))
|
|
2220
|
+
issues.push(`${prefix}.${field} must be a non-empty string`);
|
|
2221
|
+
}
|
|
2222
|
+
return issues;
|
|
2223
|
+
}
|
|
2224
|
+
function canonicalCapability(capability) {
|
|
2225
|
+
return {
|
|
2226
|
+
capabilityId: capability.capabilityId,
|
|
2227
|
+
memberNodeIds: [...capability.memberNodeIds],
|
|
2228
|
+
semanticFingerprint: capability.semanticFingerprint,
|
|
2229
|
+
flowProofFingerprint: capability.flowProofFingerprint,
|
|
2230
|
+
proofStatus: { p1: capability.proofStatus.p1, p2: capability.proofStatus.p2 },
|
|
2231
|
+
facets: Object.fromEntries(Object.keys(capability.facets).sort(compareStrings).map((facet) => [facet, capability.facets[facet]])),
|
|
2232
|
+
selectorEvidenceDigest: capability.selectorEvidenceDigest
|
|
2233
|
+
};
|
|
2234
|
+
}
|
|
2235
|
+
function canonicalTargetRow(row) {
|
|
2236
|
+
return {
|
|
2237
|
+
type: row.type,
|
|
2238
|
+
scope: {
|
|
2239
|
+
kind: row.scope.kind,
|
|
2240
|
+
...row.scope.id !== undefined ? { id: row.scope.id } : {},
|
|
2241
|
+
...row.scope.entityKind !== undefined ? { entityKind: row.scope.entityKind } : {}
|
|
2242
|
+
},
|
|
2243
|
+
path: row.path,
|
|
2244
|
+
ownership: row.ownership,
|
|
2245
|
+
format: row.format,
|
|
2246
|
+
outputDigest: row.outputDigest,
|
|
2247
|
+
...row.sourceStamps !== undefined ? { sourceStamps: Object.fromEntries(Object.keys(row.sourceStamps).sort(compareStrings).map((nodeId) => [nodeId, row.sourceStamps[nodeId]])) } : {},
|
|
2248
|
+
...row.scale !== undefined ? {
|
|
2249
|
+
scale: {
|
|
2250
|
+
fileCountBucket: { lower: row.scale.fileCountBucket.lower, upper: row.scale.fileCountBucket.upper },
|
|
2251
|
+
lineCountBucket: { lower: row.scale.lineCountBucket.lower, upper: row.scale.lineCountBucket.upper }
|
|
2252
|
+
}
|
|
2253
|
+
} : {}
|
|
2254
|
+
};
|
|
2255
|
+
}
|
|
2256
|
+
function isArchitectureScaleBucket(value) {
|
|
2257
|
+
const bucket = record2(value);
|
|
2258
|
+
if (!bucket || Object.keys(bucket).length !== 2)
|
|
2259
|
+
return false;
|
|
2260
|
+
const { lower, upper } = bucket;
|
|
2261
|
+
if (typeof lower !== "number" || typeof upper !== "number" || !Number.isSafeInteger(lower) || !Number.isSafeInteger(upper))
|
|
2262
|
+
return false;
|
|
2263
|
+
if (lower === 0)
|
|
2264
|
+
return upper === 1;
|
|
2265
|
+
let magnitude = 1;
|
|
2266
|
+
while (magnitude * 10 <= lower)
|
|
2267
|
+
magnitude *= 10;
|
|
2268
|
+
const mantissa = lower / magnitude;
|
|
2269
|
+
if (mantissa === 1)
|
|
2270
|
+
return upper === 2 * magnitude;
|
|
2271
|
+
if (mantissa === 2)
|
|
2272
|
+
return upper === 5 * magnitude;
|
|
2273
|
+
if (mantissa === 5)
|
|
2274
|
+
return upper === 10 * magnitude;
|
|
2275
|
+
return false;
|
|
2276
|
+
}
|
|
2277
|
+
function manifestTargetIssues(value, prefix) {
|
|
2278
|
+
const target = record2(value);
|
|
2279
|
+
if (!target)
|
|
2280
|
+
return [`${prefix} must be an object`];
|
|
2281
|
+
const issues = exactKeys(target, ["type", "scope", "path", "ownership", "format", "outputDigest"], ["sourceStamps", "scale"], prefix);
|
|
2282
|
+
if (typeof target.type !== "string" || !Object.hasOwn(TARGET_TYPES, target.type))
|
|
2283
|
+
issues.push(`${prefix}.type is unsupported`);
|
|
2284
|
+
const scope = record2(target.scope);
|
|
2285
|
+
if (!scope || typeof scope.kind !== "string" || !Object.hasOwn(SCOPE_KINDS, scope.kind))
|
|
2286
|
+
issues.push(`${prefix}.scope.kind is unsupported`);
|
|
2287
|
+
else {
|
|
2288
|
+
issues.push(...exactKeys(scope, ["kind"], ["id", "entityKind"], `${prefix}.scope`));
|
|
2289
|
+
for (const field of ["id", "entityKind"]) {
|
|
2290
|
+
if (scope[field] !== undefined && typeof scope[field] !== "string")
|
|
2291
|
+
issues.push(`${prefix}.scope.${field} must be a string`);
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
if (typeof target.path !== "string" || !isRepoRelativePosixPath(target.path))
|
|
2295
|
+
issues.push(`${prefix}.path must be a repository-relative POSIX path`);
|
|
2296
|
+
if (typeof target.ownership !== "string" || !Object.hasOwn(OWNERSHIPS, target.ownership))
|
|
2297
|
+
issues.push(`${prefix}.ownership is unsupported`);
|
|
2298
|
+
if (typeof target.format !== "string" || !Object.hasOwn(FORMATS, target.format))
|
|
2299
|
+
issues.push(`${prefix}.format is unsupported`);
|
|
2300
|
+
if (!isDigest(target.outputDigest))
|
|
2301
|
+
issues.push(`${prefix}.outputDigest must be a SHA-256 digest`);
|
|
2302
|
+
if (target.sourceStamps !== undefined && target.type !== "entity-summary" && !isRuntimeTopologyTargetType(target.type)) {
|
|
2303
|
+
issues.push(`${prefix}.sourceStamps are only allowed on entity-summary and runtime topology targets`);
|
|
2304
|
+
}
|
|
2305
|
+
if (target.scale !== undefined && target.type !== "entity-summary")
|
|
2306
|
+
issues.push(`${prefix}.scale is only allowed on entity-summary targets`);
|
|
2307
|
+
if (target.sourceStamps !== undefined) {
|
|
2308
|
+
const stamps = record2(target.sourceStamps);
|
|
2309
|
+
if (!stamps || Object.keys(stamps).length === 0)
|
|
2310
|
+
issues.push(`${prefix}.sourceStamps must be a non-empty object keyed by node id`);
|
|
2311
|
+
else {
|
|
2312
|
+
for (const [nodeId, digest] of Object.entries(stamps)) {
|
|
2313
|
+
if (!isNonEmptyString(nodeId))
|
|
2314
|
+
issues.push(`${prefix}.sourceStamps keys must be non-empty node ids`);
|
|
2315
|
+
if (!isDigest(digest))
|
|
2316
|
+
issues.push(`${prefix}.sourceStamps.${nodeId} must be a SHA-256 digest`);
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
const ownNodeId = scope?.id;
|
|
2321
|
+
const stampsOwnNode = typeof ownNodeId === "string" && record2(target.sourceStamps) !== undefined && Object.hasOwn(record2(target.sourceStamps), ownNodeId);
|
|
2322
|
+
if (stampsOwnNode !== (target.scale !== undefined))
|
|
2323
|
+
issues.push(`${prefix}.scale must be present exactly when sourceStamps stamps the target's own node`);
|
|
2324
|
+
if (target.scale !== undefined) {
|
|
2325
|
+
const scale = record2(target.scale);
|
|
2326
|
+
if (!scale)
|
|
2327
|
+
issues.push(`${prefix}.scale must be an object`);
|
|
2328
|
+
else {
|
|
2329
|
+
issues.push(...exactKeys(scale, ["fileCountBucket", "lineCountBucket"], [], `${prefix}.scale`));
|
|
2330
|
+
for (const field of ["fileCountBucket", "lineCountBucket"]) {
|
|
2331
|
+
if (!isArchitectureScaleBucket(scale[field]))
|
|
2332
|
+
issues.push(`${prefix}.scale.${field} must be a 1-2-5 magnitude bucket`);
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
return issues;
|
|
2337
|
+
}
|
|
2338
|
+
function record2(value) {
|
|
2339
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
2340
|
+
}
|
|
2341
|
+
function exactKeys(value, required, optional, prefix) {
|
|
2342
|
+
const issues = required.filter((key) => !(key in value)).map((key) => `${prefix}.${key} is required`);
|
|
2343
|
+
const allowed = new Set([...required, ...optional]);
|
|
2344
|
+
for (const key of Object.keys(value))
|
|
2345
|
+
if (!allowed.has(key))
|
|
2346
|
+
issues.push(`${prefix}.${key} is not allowed`);
|
|
2347
|
+
return issues;
|
|
2348
|
+
}
|
|
2349
|
+
function isDigest(value) {
|
|
2350
|
+
return typeof value === "string" && SHA256.test(value);
|
|
2351
|
+
}
|
|
2352
|
+
function isNonEmptyString(value) {
|
|
2353
|
+
return typeof value === "string" && value.trim() !== "";
|
|
2354
|
+
}
|
|
2355
|
+
function isSortedUniqueStrings(values) {
|
|
2356
|
+
return values.every((value, index) => typeof value === "string" && (index === 0 || values[index - 1] < value));
|
|
2357
|
+
}
|
|
2358
|
+
function compareStrings(left, right) {
|
|
2359
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
2360
|
+
}
|
|
2361
|
+
function versionNumber(value, family) {
|
|
2362
|
+
if (typeof value !== "string" || !value.startsWith(family))
|
|
2363
|
+
return;
|
|
2364
|
+
const suffix = value.slice(family.length);
|
|
2365
|
+
if (!/^[1-9][0-9]*$/.test(suffix))
|
|
2366
|
+
return;
|
|
2367
|
+
const version = Number(suffix);
|
|
2368
|
+
return Number.isSafeInteger(version) ? version : undefined;
|
|
2369
|
+
}
|
|
2370
|
+
function architectureDocsProjectionCompatibilityIssues(value, engine = {
|
|
2371
|
+
rendererVersion: ARCHITECTURE_DOCS_RENDERER_VERSION,
|
|
2372
|
+
protocolVersion: PROJECTION_REQUEST_SCHEMA_VERSION
|
|
2373
|
+
}) {
|
|
2374
|
+
const manifest = record2(value);
|
|
2375
|
+
if (!manifest)
|
|
2376
|
+
return [];
|
|
2377
|
+
const issues = [];
|
|
2378
|
+
if (["minimumRendererVersion", "minimumProtocolVersion"].some((key) => Object.hasOwn(manifest, key)) && manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION)
|
|
2379
|
+
issues.push("projection manifest floors require the current schema");
|
|
2380
|
+
if (typeof manifest.schemaVersion === "string" && manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION && !isSupersededArchitectureDocsProjectionManifestSchemaVersion(manifest.schemaVersion))
|
|
2381
|
+
issues.push("projection manifest schema is unsupported by this engine");
|
|
2382
|
+
for (const [key, family, current] of [
|
|
2383
|
+
["minimumRendererVersion", "archcontext.docs-renderer/v", engine.rendererVersion],
|
|
2384
|
+
["minimumProtocolVersion", "archcontext.projection-request/v", engine.protocolVersion]
|
|
2385
|
+
]) {
|
|
2386
|
+
if (!Object.hasOwn(manifest, key))
|
|
2387
|
+
continue;
|
|
2388
|
+
const required = versionNumber(manifest[key], family);
|
|
2389
|
+
const supported = versionNumber(current, family);
|
|
2390
|
+
if (required === undefined || supported === undefined || supported < required)
|
|
2391
|
+
issues.push(`projection manifest ${key} is unsupported by this engine`);
|
|
2392
|
+
}
|
|
2393
|
+
return issues;
|
|
2394
|
+
}
|
|
2395
|
+
var ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION = "archcontext.architecture-docs-projection-manifest/v3", SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND = "archctx docs apply --approved --profile <default|repo-harness/v1>", ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE = "docs/runbooks/architecture-documentation-projections.md", PROJECTION_MANIFEST_UPGRADE_REQUIRED = "projection-manifest-upgrade-required", PROJECTION_MANIFEST_INVALID = "projection-manifest-invalid", PROJECTION_FOOTPRINT_UNCOVERED = "projection-footprint-uncovered", ARCHITECTURE_DOCS_PROJECTION_PROVENANCE_SCHEMA_VERSION = "archcontext.architecture-docs-projection-provenance/v3", ARCHITECTURE_DOCS_LAYOUT_VERSION_V1 = "archcontext.docs-layout/v1", ARCHITECTURE_SEMANTIC_STATE_SCHEMA_VERSION = "archcontext.architecture-semantic-state/v1", ARCHITECTURE_DOCS_PROJECTION_PROFILES, SHA256, TARGET_TYPES, RUNTIME_TOPOLOGY_TARGET_TYPES, SCOPE_KINDS, OWNERSHIPS, FORMATS;
|
|
2396
|
+
var init_projection_manifest = __esm(() => {
|
|
2397
|
+
init_projection();
|
|
2398
|
+
init_schema();
|
|
2399
|
+
SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS = [
|
|
2400
|
+
"archcontext.architecture-docs-projection-manifest/v1",
|
|
2401
|
+
"archcontext.architecture-docs-projection-manifest/v2"
|
|
2402
|
+
];
|
|
2403
|
+
ARCHITECTURE_DOCS_PROJECTION_PROFILES = ["default", "repo-harness/v1"];
|
|
2404
|
+
SHA256 = /^sha256:[a-f0-9]{64}$/;
|
|
2405
|
+
TARGET_TYPES = {
|
|
2406
|
+
"architecture-index": true,
|
|
2407
|
+
"entity-summary": true,
|
|
2408
|
+
"relation-summary": true,
|
|
2409
|
+
"decision-index": true,
|
|
2410
|
+
"architecture-changelog": true,
|
|
2411
|
+
"diagram-mermaid": true,
|
|
2412
|
+
"diagram-structurizr": true,
|
|
2413
|
+
"diagram-likec4": true,
|
|
2414
|
+
"diagram-runtime-topology": true,
|
|
2415
|
+
"runtime-topology-summary": true,
|
|
2416
|
+
"agent-context": true
|
|
2417
|
+
};
|
|
2418
|
+
RUNTIME_TOPOLOGY_TARGET_TYPES = ["diagram-runtime-topology", "runtime-topology-summary"];
|
|
2419
|
+
SCOPE_KINDS = { repository: true, entity: true, relation: true, decision: true, diagram: true, changelog: true };
|
|
2420
|
+
OWNERSHIPS = { generated: true, mixed: true };
|
|
2421
|
+
FORMATS = { markdown: true, mermaid: true, "structurizr-json": true, likec4: true };
|
|
2422
|
+
});
|
|
2423
|
+
|
|
1964
2424
|
// packages/contracts/src/projection-recovery.ts
|
|
1965
2425
|
function jsonDataCopy(input, maximum) {
|
|
1966
2426
|
let measured = 0;
|
|
@@ -2085,7 +2545,7 @@ var init_projection_recovery = __esm(() => {
|
|
|
2085
2545
|
// packages/contracts/src/failure.ts
|
|
2086
2546
|
import { isNativeError } from "node:util/types";
|
|
2087
2547
|
function ownData(input, key) {
|
|
2088
|
-
if (!
|
|
2548
|
+
if (!record3(input))
|
|
2089
2549
|
throw new Error("Failure metadata must be an object");
|
|
2090
2550
|
const descriptor = Object.getOwnPropertyDescriptor(input, key);
|
|
2091
2551
|
if (!descriptor) {
|
|
@@ -2133,7 +2593,7 @@ function detailsFor(policy, input) {
|
|
|
2133
2593
|
if (policy.facts)
|
|
2134
2594
|
return localFactsFor(policy.facts, input);
|
|
2135
2595
|
const result = {};
|
|
2136
|
-
if (!
|
|
2596
|
+
if (!record3(input))
|
|
2137
2597
|
throw new Error("Failure details must be an object");
|
|
2138
2598
|
let omitted = 0;
|
|
2139
2599
|
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(input))) {
|
|
@@ -2159,7 +2619,7 @@ function detailsFor(policy, input) {
|
|
|
2159
2619
|
return result;
|
|
2160
2620
|
}
|
|
2161
2621
|
function dataRecord(value) {
|
|
2162
|
-
if (!
|
|
2622
|
+
if (!record3(value))
|
|
2163
2623
|
throw new Error("Facts must be a plain record");
|
|
2164
2624
|
const proto = Object.getPrototypeOf(value), keys = Reflect.ownKeys(value);
|
|
2165
2625
|
if (proto !== Object.prototype && proto !== null || keys.length > 16 || Object.keys(value).length !== keys.length || keys.some((key) => typeof key !== "string"))
|
|
@@ -2284,7 +2744,7 @@ function nativeFactsFor(policy, input) {
|
|
|
2284
2744
|
let omitted = 0, characters = 0;
|
|
2285
2745
|
const omit = (value) => {
|
|
2286
2746
|
omitted++;
|
|
2287
|
-
const strings = (v) => typeof v === "string" ? v.length : Array.isArray(v) ? v.reduce((n, item) => n + strings(item), 0) :
|
|
2747
|
+
const strings = (v) => typeof v === "string" ? v.length : Array.isArray(v) ? v.reduce((n, item) => n + strings(item), 0) : record3(v) ? Object.values(v).reduce((n, item) => n + strings(item), 0) : 0;
|
|
2288
2748
|
characters += strings(value);
|
|
2289
2749
|
};
|
|
2290
2750
|
const text = (value) => {
|
|
@@ -2423,7 +2883,7 @@ function budgetIssues(value, depth = 0, maxStringBytes = 256) {
|
|
|
2423
2883
|
return Number.isFinite(value) ? [] : ["detail number is not finite"];
|
|
2424
2884
|
if (Array.isArray(value))
|
|
2425
2885
|
return value.length <= 32 ? value.flatMap((item) => budgetIssues(item, depth + 1, maxStringBytes)) : ["detail list exceeds 32"];
|
|
2426
|
-
if (
|
|
2886
|
+
if (record3(value))
|
|
2427
2887
|
return Object.keys(value).length <= 16 ? Object.values(value).flatMap((item) => budgetIssues(item, depth + 1, maxStringBytes)) : ["detail object exceeds 16 fields"];
|
|
2428
2888
|
return value === null || typeof value === "boolean" ? [] : ["detail value is not JSON"];
|
|
2429
2889
|
}
|
|
@@ -2498,7 +2958,7 @@ function toEnvelope(requestId, error, stage) {
|
|
|
2498
2958
|
}
|
|
2499
2959
|
}
|
|
2500
2960
|
function normalizeFailureResult(result, stage, requestId = "failure") {
|
|
2501
|
-
if (!
|
|
2961
|
+
if (!record3(result))
|
|
2502
2962
|
return result;
|
|
2503
2963
|
try {
|
|
2504
2964
|
if (ownData(result, "ok") !== false)
|
|
@@ -2528,7 +2988,7 @@ function jsonDataSnapshot(value, depth = 0, maxStringBytes = 256) {
|
|
|
2528
2988
|
return jsonDataSnapshot(descriptor.value, depth + 1, maxStringBytes);
|
|
2529
2989
|
});
|
|
2530
2990
|
}
|
|
2531
|
-
if (
|
|
2991
|
+
if (record3(value)) {
|
|
2532
2992
|
const prototype = Object.getPrototypeOf(value);
|
|
2533
2993
|
const keys = Reflect.ownKeys(value);
|
|
2534
2994
|
if (prototype !== Object.prototype && prototype !== null || keys.length > 16 || Object.keys(value).length !== keys.length || keys.some((key) => typeof key !== "string"))
|
|
@@ -2539,7 +2999,7 @@ function jsonDataSnapshot(value, depth = 0, maxStringBytes = 256) {
|
|
|
2539
2999
|
}
|
|
2540
3000
|
function failureIssues(value) {
|
|
2541
3001
|
try {
|
|
2542
|
-
if (!
|
|
3002
|
+
if (!record3(value))
|
|
2543
3003
|
return ["failure must be an object"];
|
|
2544
3004
|
const fields = ["code", "message", "severity", "retryable", "action", "reasonCode", "details"];
|
|
2545
3005
|
const keys = Reflect.ownKeys(value);
|
|
@@ -2558,10 +3018,12 @@ function failureIssues(value) {
|
|
|
2558
3018
|
return ["failure violates its registered contract or budget"];
|
|
2559
3019
|
}
|
|
2560
3020
|
}
|
|
2561
|
-
var FAILURE_STAGES, ERROR_CLASSES, CODE_FACTS_ISSUE_MESSAGES, policies, FAILURE_POLICIES, catalogDefaults, actions, bytes = (value) => new TextEncoder().encode(value).byteLength,
|
|
3021
|
+
var FAILURE_STAGES, ERROR_CLASSES, CODE_FACTS_ISSUE_MESSAGES, policies, FAILURE_POLICIES, catalogDefaults, actions, bytes = (value) => new TextEncoder().encode(value).byteLength, record3 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), finiteNonnegative = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0, criticalKey = (key) => /id$|digest|receipt|binding|readback|lookupkey/i.test(key), localEnums, nativeEnums, nativeDiagnosticKinds, FailureError;
|
|
2562
3022
|
var init_failure = __esm(() => {
|
|
2563
3023
|
init_changeset_recovery();
|
|
2564
3024
|
init_ports();
|
|
3025
|
+
init_projection();
|
|
3026
|
+
init_projection_manifest();
|
|
2565
3027
|
init_projection_recovery();
|
|
2566
3028
|
init_schema();
|
|
2567
3029
|
FAILURE_STAGES = Object.freeze(["debt", "complete", "practice-checkpoint", "cli", "mcp", "hook-checkpoint", "failure-metadata", "public-operation", "native-export", "docs-anchors", "flows-check"]);
|
|
@@ -2576,6 +3038,7 @@ var init_failure = __esm(() => {
|
|
|
2576
3038
|
"pending-source-changes": "CodeGraph repository index has pending or unreported source changes"
|
|
2577
3039
|
});
|
|
2578
3040
|
policies = {
|
|
3041
|
+
"history-shallow-repository": { code: "AC_PRECONDITION_FAILED", message: "Architecture history requires a complete Git repository.", action: "unshallow-repository" },
|
|
2579
3042
|
"code-facts-read-not-ready": { code: "AC_CODE_FACTS_UNAVAILABLE", message: "The existing CodeGraph index does not attest to the current source population.", facts: { issues: "codeFactsIssues" }, action: "codegraph-sync", retryable: false },
|
|
2580
3043
|
"code-facts-snapshot-changed": { code: "AC_CODE_FACTS_UNAVAILABLE", message: "Source or index inputs changed while reading the private snapshot.", action: "retry-read", retryable: true, facts: {} },
|
|
2581
3044
|
"code-facts-snapshot-limit-exceeded": { code: "AC_CODE_FACTS_UNAVAILABLE", message: "The private CodeGraph snapshot exceeds its 512 MiB or 100000 entry limit.", action: "reduce-snapshot-size", retryable: false, facts: {} },
|
|
@@ -2589,7 +3052,7 @@ var init_failure = __esm(() => {
|
|
|
2589
3052
|
"model-missing": { code: "AC_MODEL_ADOPTION_REQUIRED", message: "Architecture debt requires an adopted model.", fields: ["checks"] },
|
|
2590
3053
|
"changed-path-invalid": { code: "AC_SCHEMA_INVALID", message: "Changed paths must be an array of repository-relative POSIX paths.", fields: ["checks"] },
|
|
2591
3054
|
"debt-report-invalid": { code: "AC_SCHEMA_INVALID", message: "Architecture debt evidence violates its contract.", fields: ["checks"] },
|
|
2592
|
-
"projection-manifest-upgrade-required": { code: "AC_PRECONDITION_FAILED", message:
|
|
3055
|
+
"projection-manifest-upgrade-required": { code: "AC_PRECONDITION_FAILED", message: `The committed projection manifest requires supported re-baselining. First restore the original model if missing; the manifest digest cannot recover it. With the reviewed model available, follow ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE} before running ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND}.`, facts: { manifestPath: "optional:projectionManifestPath", foundSchemaVersion: "optional:projectionManifestSchemaVersion", supportedSchemaVersion: "optional:projectionManifestSchemaVersion", upgradeCommand: "optional:projectionManifestUpgradeCommand", migrationGuide: "optional:projectionManifestMigrationGuide" } },
|
|
2593
3056
|
"projection-manifest-invalid": { code: "AC_PRECONDITION_FAILED", message: "The committed projection manifest violates its contract." },
|
|
2594
3057
|
"architecture-model-ignored": { code: "AC_PRECONDITION_FAILED", action: "commit-architecture-model", message: "Git ignore rules exclude architecture model paths, so the model cannot be committed and a manifest digest cannot rebuild it. Remove or narrow the rule, commit the model, then retry adoption. The diagnostic command prints each deciding rule.", facts: { pathCount: "uint", paths: "optional:diagnosticPaths", commands: "optional:diagnosticCommands", omittedPathCount: "uint" } },
|
|
2595
3058
|
"projection-footprint-uncovered": { code: "AC_PRECONDITION_FAILED", message: "Declared source footprints lack a projection target." },
|
|
@@ -2850,6 +3313,10 @@ var init_failure = __esm(() => {
|
|
|
2850
3313
|
upgradeAction: ["upgrade-archctx-runtime"],
|
|
2851
3314
|
upgradeCommand: ["archctx daemon upgrade"],
|
|
2852
3315
|
ownershipAction: ["remove-whole-file-outputs-and-reapply"],
|
|
3316
|
+
projectionManifestPath: [ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH],
|
|
3317
|
+
projectionManifestSchemaVersion: [...SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION],
|
|
3318
|
+
projectionManifestUpgradeCommand: [ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND],
|
|
3319
|
+
projectionManifestMigrationGuide: [ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE],
|
|
2853
3320
|
ledgerModeField: ["rolloutMode", "readMode", "writeMode"],
|
|
2854
3321
|
depsField: ["from", "into", "importNodeLimit", "edgeLimit"],
|
|
2855
3322
|
depsIssue: ["unknown-node", "invalid-limit", "missing-value"],
|
|
@@ -2974,6 +3441,7 @@ var init_failure = __esm(() => {
|
|
|
2974
3441
|
],
|
|
2975
3442
|
operation: [
|
|
2976
3443
|
"rev-parse",
|
|
3444
|
+
"log",
|
|
2977
3445
|
"ls-tree",
|
|
2978
3446
|
"ls-files",
|
|
2979
3447
|
"cat-file"
|
|
@@ -3566,450 +4034,6 @@ var PRACTICE_SCHEMA_VERSION = "archcontext.practice/v1", PRACTICE_PROFILE_SCHEMA
|
|
|
3566
4034
|
var PROJECTION_PUBLISH_RUN_SCHEMA_VERSION = "archcontext.projection-publish-run/v1", PROJECTION_PUBLISH_STATUS_SCHEMA_VERSION = "archcontext.projection-publish-status/v1", PROJECTION_PR_VERIFICATION_SCHEMA_VERSION = "archcontext.projection-pr-verification/v1", PROJECTION_WRITER_BRANCH_PREFIX = "archctx/", PROJECTION_WRITER_DEFAULT_BRANCH = "archctx/projection";
|
|
3567
4035
|
var init_projection_writer = () => {};
|
|
3568
4036
|
|
|
3569
|
-
// packages/contracts/src/projection-manifest.ts
|
|
3570
|
-
function isRuntimeTopologyTargetType(type) {
|
|
3571
|
-
return typeof type === "string" && RUNTIME_TOPOLOGY_TARGET_TYPES.includes(type);
|
|
3572
|
-
}
|
|
3573
|
-
function architectureDocsProjectionManifestIssues(value) {
|
|
3574
|
-
const issues = [];
|
|
3575
|
-
const manifest = record3(value);
|
|
3576
|
-
if (!manifest)
|
|
3577
|
-
return ["manifest must be an object"];
|
|
3578
|
-
issues.push(...exactKeys(manifest, ["schemaVersion", "rendererVersion", "profile", "layoutVersion", "generatedFrom", "semanticBaseline", "targets"], ["minimumRendererVersion", "minimumProtocolVersion"], "manifest"));
|
|
3579
|
-
if (manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION)
|
|
3580
|
-
issues.push("manifest.schemaVersion is unsupported");
|
|
3581
|
-
if (!isNonEmptyString(manifest.rendererVersion))
|
|
3582
|
-
issues.push("manifest.rendererVersion must be a non-empty string");
|
|
3583
|
-
for (const [key, family] of [["minimumRendererVersion", "archcontext.docs-renderer/v"], ["minimumProtocolVersion", "archcontext.projection-request/v"]]) {
|
|
3584
|
-
if (Object.hasOwn(manifest, key) && versionNumber(manifest[key], family) === undefined)
|
|
3585
|
-
issues.push(`manifest.${key} must name a supported version family`);
|
|
3586
|
-
}
|
|
3587
|
-
if (!ARCHITECTURE_DOCS_PROJECTION_PROFILES.includes(manifest.profile))
|
|
3588
|
-
issues.push("manifest.profile is unsupported");
|
|
3589
|
-
if (manifest.layoutVersion !== ARCHITECTURE_DOCS_LAYOUT_VERSION_V1)
|
|
3590
|
-
issues.push("manifest.layoutVersion is unsupported");
|
|
3591
|
-
issues.push(...generatedFromIssues(manifest.generatedFrom, "manifest.generatedFrom"));
|
|
3592
|
-
const baseline = record3(manifest.semanticBaseline);
|
|
3593
|
-
if (!baseline)
|
|
3594
|
-
issues.push("manifest.semanticBaseline must be an object");
|
|
3595
|
-
else {
|
|
3596
|
-
issues.push(...exactKeys(baseline, ["modelDigest", "capabilities"], [], "manifest.semanticBaseline"));
|
|
3597
|
-
if (!isDigest(baseline.modelDigest))
|
|
3598
|
-
issues.push("manifest.semanticBaseline.modelDigest must be a SHA-256 digest");
|
|
3599
|
-
issues.push(...capabilityEntriesIssues(baseline.capabilities, "manifest.semanticBaseline.capabilities", true));
|
|
3600
|
-
}
|
|
3601
|
-
const targets = record3(manifest.targets);
|
|
3602
|
-
if (!targets) {
|
|
3603
|
-
issues.push("manifest.targets must be an object keyed by targetId");
|
|
3604
|
-
return issues;
|
|
3605
|
-
}
|
|
3606
|
-
const paths = new Set;
|
|
3607
|
-
const stampOwners = new Map;
|
|
3608
|
-
let topologyStamps;
|
|
3609
|
-
for (const [targetId, row] of Object.entries(targets)) {
|
|
3610
|
-
const prefix = `manifest.targets[${JSON.stringify(targetId)}]`;
|
|
3611
|
-
if (!isNonEmptyString(targetId))
|
|
3612
|
-
issues.push("manifest.targets keys must be non-empty targetIds");
|
|
3613
|
-
issues.push(...manifestTargetIssues(row, prefix));
|
|
3614
|
-
const path = record3(row)?.path;
|
|
3615
|
-
if (typeof path === "string") {
|
|
3616
|
-
if (paths.has(path))
|
|
3617
|
-
issues.push(`${prefix}.path is recorded by another target`);
|
|
3618
|
-
paths.add(path);
|
|
3619
|
-
}
|
|
3620
|
-
const stamps = record3(record3(row)?.sourceStamps) ?? {};
|
|
3621
|
-
if (isRuntimeTopologyTargetType(record3(row)?.type)) {
|
|
3622
|
-
const serialized = JSON.stringify(Object.keys(stamps).sort(compareStrings).map((nodeId) => [nodeId, stamps[nodeId]]));
|
|
3623
|
-
if (topologyStamps === undefined)
|
|
3624
|
-
topologyStamps = { targetId, stamps: serialized };
|
|
3625
|
-
else if (topologyStamps.stamps !== serialized)
|
|
3626
|
-
issues.push(`${prefix}.sourceStamps must equal the sourceStamps of ${topologyStamps.targetId}`);
|
|
3627
|
-
for (const nodeId of Object.keys(stamps)) {
|
|
3628
|
-
const owner = stampOwners.get(nodeId);
|
|
3629
|
-
if (owner !== undefined && !isRuntimeTopologyTargetType(record3(targets[owner])?.type))
|
|
3630
|
-
issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
|
|
3631
|
-
else if (owner === undefined)
|
|
3632
|
-
stampOwners.set(nodeId, targetId);
|
|
3633
|
-
}
|
|
3634
|
-
continue;
|
|
3635
|
-
}
|
|
3636
|
-
for (const nodeId of Object.keys(stamps)) {
|
|
3637
|
-
const owner = stampOwners.get(nodeId);
|
|
3638
|
-
if (owner !== undefined)
|
|
3639
|
-
issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
|
|
3640
|
-
else
|
|
3641
|
-
stampOwners.set(nodeId, targetId);
|
|
3642
|
-
}
|
|
3643
|
-
}
|
|
3644
|
-
return issues;
|
|
3645
|
-
}
|
|
3646
|
-
function architectureDocsProjectionManifestSchemaVersion(body) {
|
|
3647
|
-
let parsed;
|
|
3648
|
-
try {
|
|
3649
|
-
parsed = JSON.parse(body);
|
|
3650
|
-
} catch {
|
|
3651
|
-
return;
|
|
3652
|
-
}
|
|
3653
|
-
const schemaVersion = record3(parsed)?.schemaVersion;
|
|
3654
|
-
return typeof schemaVersion === "string" ? schemaVersion : undefined;
|
|
3655
|
-
}
|
|
3656
|
-
function isSupersededArchitectureDocsProjectionManifestSchemaVersion(schemaVersion) {
|
|
3657
|
-
return SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS.includes(schemaVersion);
|
|
3658
|
-
}
|
|
3659
|
-
function serializeArchitectureDocsProjectionManifest(manifest) {
|
|
3660
|
-
const capabilities = [...manifest.semanticBaseline.capabilities].sort((left, right) => compareStrings(left.capabilityId, right.capabilityId)).map(canonicalCapability);
|
|
3661
|
-
const capabilityBlock = JSON.stringify(capabilities, null, 2).split(`
|
|
3662
|
-
`).map((line, index) => index === 0 ? line : ` ${line}`).join(`
|
|
3663
|
-
`);
|
|
3664
|
-
const targetIds = Object.keys(manifest.targets).sort(compareStrings);
|
|
3665
|
-
const targetLines = targetIds.length === 0 ? [' "targets": {}'] : [
|
|
3666
|
-
' "targets": {',
|
|
3667
|
-
...targetIds.flatMap((targetId, index) => [
|
|
3668
|
-
` ${JSON.stringify(targetId)}:`,
|
|
3669
|
-
` ${JSON.stringify(canonicalTargetRow(manifest.targets[targetId]))}${index === targetIds.length - 1 ? "" : ","}`
|
|
3670
|
-
]),
|
|
3671
|
-
" }"
|
|
3672
|
-
];
|
|
3673
|
-
return [
|
|
3674
|
-
"{",
|
|
3675
|
-
` "schemaVersion": ${JSON.stringify(manifest.schemaVersion)},`,
|
|
3676
|
-
` "rendererVersion": ${JSON.stringify(manifest.rendererVersion)},`,
|
|
3677
|
-
...manifest.minimumRendererVersion === undefined ? [] : [` "minimumRendererVersion": ${JSON.stringify(manifest.minimumRendererVersion)},`],
|
|
3678
|
-
...manifest.minimumProtocolVersion === undefined ? [] : [` "minimumProtocolVersion": ${JSON.stringify(manifest.minimumProtocolVersion)},`],
|
|
3679
|
-
` "profile": ${JSON.stringify(manifest.profile)},`,
|
|
3680
|
-
` "layoutVersion": ${JSON.stringify(manifest.layoutVersion)},`,
|
|
3681
|
-
` "generatedFrom": ${JSON.stringify({ codeGraphPackage: manifest.generatedFrom.codeGraphPackage, codeGraphVersion: manifest.generatedFrom.codeGraphVersion })},`,
|
|
3682
|
-
' "semanticBaseline": {',
|
|
3683
|
-
` "modelDigest": ${JSON.stringify(manifest.semanticBaseline.modelDigest)},`,
|
|
3684
|
-
` "capabilities": ${capabilityBlock}`,
|
|
3685
|
-
" },",
|
|
3686
|
-
...targetLines,
|
|
3687
|
-
"}",
|
|
3688
|
-
""
|
|
3689
|
-
].join(`
|
|
3690
|
-
`);
|
|
3691
|
-
}
|
|
3692
|
-
function architectureDocsProjectionManifestSemanticState(manifest) {
|
|
3693
|
-
return architectureSemanticStateFromCapabilities(manifest.semanticBaseline.capabilities.map(({ selectorEvidenceDigest: _selectorEvidenceDigest, ...capability }) => capability));
|
|
3694
|
-
}
|
|
3695
|
-
function architectureSemanticStateFromCapabilities(capabilities) {
|
|
3696
|
-
const sorted = [...capabilities].sort((left, right) => compareStrings(left.capabilityId, right.capabilityId));
|
|
3697
|
-
return {
|
|
3698
|
-
schemaVersion: ARCHITECTURE_SEMANTIC_STATE_SCHEMA_VERSION,
|
|
3699
|
-
capabilities: sorted,
|
|
3700
|
-
semanticFingerprint: digestJson(sorted.map(({ capabilityId, semanticFingerprint }) => ({ capabilityId, semanticFingerprint }))),
|
|
3701
|
-
flowProofFingerprint: digestJson(sorted.map(({ capabilityId, flowProofFingerprint }) => ({ capabilityId, flowProofFingerprint })))
|
|
3702
|
-
};
|
|
3703
|
-
}
|
|
3704
|
-
function architectureDocsProjectionManifestSourceStamps(manifest) {
|
|
3705
|
-
const stamps = {};
|
|
3706
|
-
for (const row of Object.values(manifest.targets))
|
|
3707
|
-
Object.assign(stamps, row.sourceStamps ?? {});
|
|
3708
|
-
return stamps;
|
|
3709
|
-
}
|
|
3710
|
-
function architectureDocsProjectionManifestProofEvidence(manifest) {
|
|
3711
|
-
return {
|
|
3712
|
-
rendererVersion: manifest.rendererVersion,
|
|
3713
|
-
selectorEvidenceDigests: Object.fromEntries(manifest.semanticBaseline.capabilities.map((capability) => [capability.capabilityId, capability.selectorEvidenceDigest])),
|
|
3714
|
-
sourceStamps: architectureDocsProjectionManifestSourceStamps(manifest)
|
|
3715
|
-
};
|
|
3716
|
-
}
|
|
3717
|
-
function architectureSourceStampsDigest(stamps) {
|
|
3718
|
-
return digestJson({
|
|
3719
|
-
schemaVersion: "archcontext.architecture-source-stamps/v1",
|
|
3720
|
-
stamps: Object.keys(stamps).sort(compareStrings).map((nodeId) => ({ nodeId, digest: stamps[nodeId] }))
|
|
3721
|
-
});
|
|
3722
|
-
}
|
|
3723
|
-
function architectureProjectionOutputsDigest(input) {
|
|
3724
|
-
return digestJson({
|
|
3725
|
-
schemaVersion: "archcontext.architecture-projection-outputs/v1",
|
|
3726
|
-
rendererVersion: input.rendererVersion,
|
|
3727
|
-
profile: input.profile,
|
|
3728
|
-
outputs: Object.keys(input.outputDigests).sort(compareStrings).map((targetId) => ({ targetId, outputDigest: input.outputDigests[targetId] }))
|
|
3729
|
-
});
|
|
3730
|
-
}
|
|
3731
|
-
function architectureDocsProjectionManifestDigests(manifest) {
|
|
3732
|
-
return {
|
|
3733
|
-
modelDigest: manifest.semanticBaseline.modelDigest,
|
|
3734
|
-
sourceTreeDigest: architectureSourceStampsDigest(architectureDocsProjectionManifestSourceStamps(manifest)),
|
|
3735
|
-
flowProofDigest: architectureDocsProjectionManifestSemanticState(manifest).flowProofFingerprint,
|
|
3736
|
-
projectionDigest: architectureProjectionOutputsDigest({
|
|
3737
|
-
rendererVersion: manifest.rendererVersion,
|
|
3738
|
-
profile: manifest.profile,
|
|
3739
|
-
outputDigests: Object.fromEntries(Object.entries(manifest.targets).map(([targetId, row]) => [targetId, row.outputDigest]))
|
|
3740
|
-
})
|
|
3741
|
-
};
|
|
3742
|
-
}
|
|
3743
|
-
function architectureDocsProjectionProvenanceIssues(value, prefix = "provenance") {
|
|
3744
|
-
const provenance = record3(value);
|
|
3745
|
-
if (!provenance)
|
|
3746
|
-
return [`${prefix} must be an object`];
|
|
3747
|
-
const issues = exactKeys(provenance, ["schemaVersion", "sourceTreeDigest", "modelDigest", "projectionInputDigest", "rendererVersion", "layoutVersion", "generatedFrom"], [], prefix);
|
|
3748
|
-
if (provenance.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_PROVENANCE_SCHEMA_VERSION)
|
|
3749
|
-
issues.push(`${prefix}.schemaVersion is unsupported`);
|
|
3750
|
-
for (const field of ["sourceTreeDigest", "modelDigest", "projectionInputDigest"]) {
|
|
3751
|
-
if (!isDigest(provenance[field]))
|
|
3752
|
-
issues.push(`${prefix}.${field} must be a SHA-256 digest`);
|
|
3753
|
-
}
|
|
3754
|
-
if (provenance.rendererVersion !== ARCHITECTURE_DOCS_RENDERER_VERSION)
|
|
3755
|
-
issues.push(`${prefix}.rendererVersion must be ${ARCHITECTURE_DOCS_RENDERER_VERSION}`);
|
|
3756
|
-
if (provenance.layoutVersion !== ARCHITECTURE_DOCS_LAYOUT_VERSION_V1)
|
|
3757
|
-
issues.push(`${prefix}.layoutVersion is unsupported`);
|
|
3758
|
-
issues.push(...generatedFromIssues(provenance.generatedFrom, `${prefix}.generatedFrom`));
|
|
3759
|
-
return issues;
|
|
3760
|
-
}
|
|
3761
|
-
function capabilityEntriesIssues(value, prefix, withSelectorEvidence) {
|
|
3762
|
-
if (!Array.isArray(value))
|
|
3763
|
-
return [`${prefix} must be an array`];
|
|
3764
|
-
const issues = [];
|
|
3765
|
-
const ids = value.map((entry) => record3(entry)?.capabilityId);
|
|
3766
|
-
if (!isSortedUniqueStrings(ids))
|
|
3767
|
-
issues.push(`${prefix} must be sorted and unique by capabilityId`);
|
|
3768
|
-
value.forEach((entry, index) => {
|
|
3769
|
-
const entryPrefix = `${prefix}[${index}]`;
|
|
3770
|
-
const capability = record3(entry);
|
|
3771
|
-
if (!capability) {
|
|
3772
|
-
issues.push(`${entryPrefix} must be an object`);
|
|
3773
|
-
return;
|
|
3774
|
-
}
|
|
3775
|
-
const required = ["capabilityId", "memberNodeIds", "semanticFingerprint", "flowProofFingerprint", "proofStatus", "facets", ...withSelectorEvidence ? ["selectorEvidenceDigest"] : []];
|
|
3776
|
-
issues.push(...exactKeys(capability, required, [], entryPrefix));
|
|
3777
|
-
if (!isNonEmptyString(capability.capabilityId))
|
|
3778
|
-
issues.push(`${entryPrefix}.capabilityId must be a non-empty string`);
|
|
3779
|
-
if (!Array.isArray(capability.memberNodeIds) || !isSortedUniqueStrings(capability.memberNodeIds))
|
|
3780
|
-
issues.push(`${entryPrefix}.memberNodeIds must be sorted and unique`);
|
|
3781
|
-
if (!isDigest(capability.semanticFingerprint))
|
|
3782
|
-
issues.push(`${entryPrefix}.semanticFingerprint must be a SHA-256 digest`);
|
|
3783
|
-
if (!isDigest(capability.flowProofFingerprint))
|
|
3784
|
-
issues.push(`${entryPrefix}.flowProofFingerprint must be a SHA-256 digest`);
|
|
3785
|
-
if (withSelectorEvidence && !isDigest(capability.selectorEvidenceDigest))
|
|
3786
|
-
issues.push(`${entryPrefix}.selectorEvidenceDigest must be a SHA-256 digest`);
|
|
3787
|
-
if (!isArchitectureCapabilityProofStatus(capability.proofStatus))
|
|
3788
|
-
issues.push(`${entryPrefix}.proofStatus must be a P1/P2 proof status`);
|
|
3789
|
-
const facets = record3(capability.facets);
|
|
3790
|
-
if (!facets)
|
|
3791
|
-
issues.push(`${entryPrefix}.facets must be an object`);
|
|
3792
|
-
else {
|
|
3793
|
-
issues.push(...exactKeys(facets, [...ARCHITECTURE_SEMANTIC_FACETS], [], `${entryPrefix}.facets`));
|
|
3794
|
-
for (const facet of ARCHITECTURE_SEMANTIC_FACETS) {
|
|
3795
|
-
if (!isDigest(facets[facet]))
|
|
3796
|
-
issues.push(`${entryPrefix}.facets.${facet} must be a SHA-256 digest`);
|
|
3797
|
-
}
|
|
3798
|
-
}
|
|
3799
|
-
});
|
|
3800
|
-
return issues;
|
|
3801
|
-
}
|
|
3802
|
-
function generatedFromIssues(value, prefix) {
|
|
3803
|
-
const generatedFrom = record3(value);
|
|
3804
|
-
if (!generatedFrom)
|
|
3805
|
-
return [`${prefix} must be an object`];
|
|
3806
|
-
const issues = exactKeys(generatedFrom, ["codeGraphPackage", "codeGraphVersion"], [], prefix);
|
|
3807
|
-
for (const field of ["codeGraphPackage", "codeGraphVersion"]) {
|
|
3808
|
-
if (!isNonEmptyString(generatedFrom[field]))
|
|
3809
|
-
issues.push(`${prefix}.${field} must be a non-empty string`);
|
|
3810
|
-
}
|
|
3811
|
-
return issues;
|
|
3812
|
-
}
|
|
3813
|
-
function canonicalCapability(capability) {
|
|
3814
|
-
return {
|
|
3815
|
-
capabilityId: capability.capabilityId,
|
|
3816
|
-
memberNodeIds: [...capability.memberNodeIds],
|
|
3817
|
-
semanticFingerprint: capability.semanticFingerprint,
|
|
3818
|
-
flowProofFingerprint: capability.flowProofFingerprint,
|
|
3819
|
-
proofStatus: { p1: capability.proofStatus.p1, p2: capability.proofStatus.p2 },
|
|
3820
|
-
facets: Object.fromEntries(Object.keys(capability.facets).sort(compareStrings).map((facet) => [facet, capability.facets[facet]])),
|
|
3821
|
-
selectorEvidenceDigest: capability.selectorEvidenceDigest
|
|
3822
|
-
};
|
|
3823
|
-
}
|
|
3824
|
-
function canonicalTargetRow(row) {
|
|
3825
|
-
return {
|
|
3826
|
-
type: row.type,
|
|
3827
|
-
scope: {
|
|
3828
|
-
kind: row.scope.kind,
|
|
3829
|
-
...row.scope.id !== undefined ? { id: row.scope.id } : {},
|
|
3830
|
-
...row.scope.entityKind !== undefined ? { entityKind: row.scope.entityKind } : {}
|
|
3831
|
-
},
|
|
3832
|
-
path: row.path,
|
|
3833
|
-
ownership: row.ownership,
|
|
3834
|
-
format: row.format,
|
|
3835
|
-
outputDigest: row.outputDigest,
|
|
3836
|
-
...row.sourceStamps !== undefined ? { sourceStamps: Object.fromEntries(Object.keys(row.sourceStamps).sort(compareStrings).map((nodeId) => [nodeId, row.sourceStamps[nodeId]])) } : {},
|
|
3837
|
-
...row.scale !== undefined ? {
|
|
3838
|
-
scale: {
|
|
3839
|
-
fileCountBucket: { lower: row.scale.fileCountBucket.lower, upper: row.scale.fileCountBucket.upper },
|
|
3840
|
-
lineCountBucket: { lower: row.scale.lineCountBucket.lower, upper: row.scale.lineCountBucket.upper }
|
|
3841
|
-
}
|
|
3842
|
-
} : {}
|
|
3843
|
-
};
|
|
3844
|
-
}
|
|
3845
|
-
function isArchitectureScaleBucket(value) {
|
|
3846
|
-
const bucket = record3(value);
|
|
3847
|
-
if (!bucket || Object.keys(bucket).length !== 2)
|
|
3848
|
-
return false;
|
|
3849
|
-
const { lower, upper } = bucket;
|
|
3850
|
-
if (typeof lower !== "number" || typeof upper !== "number" || !Number.isSafeInteger(lower) || !Number.isSafeInteger(upper))
|
|
3851
|
-
return false;
|
|
3852
|
-
if (lower === 0)
|
|
3853
|
-
return upper === 1;
|
|
3854
|
-
let magnitude = 1;
|
|
3855
|
-
while (magnitude * 10 <= lower)
|
|
3856
|
-
magnitude *= 10;
|
|
3857
|
-
const mantissa = lower / magnitude;
|
|
3858
|
-
if (mantissa === 1)
|
|
3859
|
-
return upper === 2 * magnitude;
|
|
3860
|
-
if (mantissa === 2)
|
|
3861
|
-
return upper === 5 * magnitude;
|
|
3862
|
-
if (mantissa === 5)
|
|
3863
|
-
return upper === 10 * magnitude;
|
|
3864
|
-
return false;
|
|
3865
|
-
}
|
|
3866
|
-
function manifestTargetIssues(value, prefix) {
|
|
3867
|
-
const target = record3(value);
|
|
3868
|
-
if (!target)
|
|
3869
|
-
return [`${prefix} must be an object`];
|
|
3870
|
-
const issues = exactKeys(target, ["type", "scope", "path", "ownership", "format", "outputDigest"], ["sourceStamps", "scale"], prefix);
|
|
3871
|
-
if (typeof target.type !== "string" || !Object.hasOwn(TARGET_TYPES, target.type))
|
|
3872
|
-
issues.push(`${prefix}.type is unsupported`);
|
|
3873
|
-
const scope = record3(target.scope);
|
|
3874
|
-
if (!scope || typeof scope.kind !== "string" || !Object.hasOwn(SCOPE_KINDS, scope.kind))
|
|
3875
|
-
issues.push(`${prefix}.scope.kind is unsupported`);
|
|
3876
|
-
else {
|
|
3877
|
-
issues.push(...exactKeys(scope, ["kind"], ["id", "entityKind"], `${prefix}.scope`));
|
|
3878
|
-
for (const field of ["id", "entityKind"]) {
|
|
3879
|
-
if (scope[field] !== undefined && typeof scope[field] !== "string")
|
|
3880
|
-
issues.push(`${prefix}.scope.${field} must be a string`);
|
|
3881
|
-
}
|
|
3882
|
-
}
|
|
3883
|
-
if (typeof target.path !== "string" || !isRepoRelativePosixPath(target.path))
|
|
3884
|
-
issues.push(`${prefix}.path must be a repository-relative POSIX path`);
|
|
3885
|
-
if (typeof target.ownership !== "string" || !Object.hasOwn(OWNERSHIPS, target.ownership))
|
|
3886
|
-
issues.push(`${prefix}.ownership is unsupported`);
|
|
3887
|
-
if (typeof target.format !== "string" || !Object.hasOwn(FORMATS, target.format))
|
|
3888
|
-
issues.push(`${prefix}.format is unsupported`);
|
|
3889
|
-
if (!isDigest(target.outputDigest))
|
|
3890
|
-
issues.push(`${prefix}.outputDigest must be a SHA-256 digest`);
|
|
3891
|
-
if (target.sourceStamps !== undefined && target.type !== "entity-summary" && !isRuntimeTopologyTargetType(target.type)) {
|
|
3892
|
-
issues.push(`${prefix}.sourceStamps are only allowed on entity-summary and runtime topology targets`);
|
|
3893
|
-
}
|
|
3894
|
-
if (target.scale !== undefined && target.type !== "entity-summary")
|
|
3895
|
-
issues.push(`${prefix}.scale is only allowed on entity-summary targets`);
|
|
3896
|
-
if (target.sourceStamps !== undefined) {
|
|
3897
|
-
const stamps = record3(target.sourceStamps);
|
|
3898
|
-
if (!stamps || Object.keys(stamps).length === 0)
|
|
3899
|
-
issues.push(`${prefix}.sourceStamps must be a non-empty object keyed by node id`);
|
|
3900
|
-
else {
|
|
3901
|
-
for (const [nodeId, digest] of Object.entries(stamps)) {
|
|
3902
|
-
if (!isNonEmptyString(nodeId))
|
|
3903
|
-
issues.push(`${prefix}.sourceStamps keys must be non-empty node ids`);
|
|
3904
|
-
if (!isDigest(digest))
|
|
3905
|
-
issues.push(`${prefix}.sourceStamps.${nodeId} must be a SHA-256 digest`);
|
|
3906
|
-
}
|
|
3907
|
-
}
|
|
3908
|
-
}
|
|
3909
|
-
const ownNodeId = scope?.id;
|
|
3910
|
-
const stampsOwnNode = typeof ownNodeId === "string" && record3(target.sourceStamps) !== undefined && Object.hasOwn(record3(target.sourceStamps), ownNodeId);
|
|
3911
|
-
if (stampsOwnNode !== (target.scale !== undefined))
|
|
3912
|
-
issues.push(`${prefix}.scale must be present exactly when sourceStamps stamps the target's own node`);
|
|
3913
|
-
if (target.scale !== undefined) {
|
|
3914
|
-
const scale = record3(target.scale);
|
|
3915
|
-
if (!scale)
|
|
3916
|
-
issues.push(`${prefix}.scale must be an object`);
|
|
3917
|
-
else {
|
|
3918
|
-
issues.push(...exactKeys(scale, ["fileCountBucket", "lineCountBucket"], [], `${prefix}.scale`));
|
|
3919
|
-
for (const field of ["fileCountBucket", "lineCountBucket"]) {
|
|
3920
|
-
if (!isArchitectureScaleBucket(scale[field]))
|
|
3921
|
-
issues.push(`${prefix}.scale.${field} must be a 1-2-5 magnitude bucket`);
|
|
3922
|
-
}
|
|
3923
|
-
}
|
|
3924
|
-
}
|
|
3925
|
-
return issues;
|
|
3926
|
-
}
|
|
3927
|
-
function record3(value) {
|
|
3928
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
3929
|
-
}
|
|
3930
|
-
function exactKeys(value, required, optional, prefix) {
|
|
3931
|
-
const issues = required.filter((key) => !(key in value)).map((key) => `${prefix}.${key} is required`);
|
|
3932
|
-
const allowed = new Set([...required, ...optional]);
|
|
3933
|
-
for (const key of Object.keys(value))
|
|
3934
|
-
if (!allowed.has(key))
|
|
3935
|
-
issues.push(`${prefix}.${key} is not allowed`);
|
|
3936
|
-
return issues;
|
|
3937
|
-
}
|
|
3938
|
-
function isDigest(value) {
|
|
3939
|
-
return typeof value === "string" && SHA256.test(value);
|
|
3940
|
-
}
|
|
3941
|
-
function isNonEmptyString(value) {
|
|
3942
|
-
return typeof value === "string" && value.trim() !== "";
|
|
3943
|
-
}
|
|
3944
|
-
function isSortedUniqueStrings(values) {
|
|
3945
|
-
return values.every((value, index) => typeof value === "string" && (index === 0 || values[index - 1] < value));
|
|
3946
|
-
}
|
|
3947
|
-
function compareStrings(left, right) {
|
|
3948
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
3949
|
-
}
|
|
3950
|
-
function versionNumber(value, family) {
|
|
3951
|
-
if (typeof value !== "string" || !value.startsWith(family))
|
|
3952
|
-
return;
|
|
3953
|
-
const suffix = value.slice(family.length);
|
|
3954
|
-
if (!/^[1-9][0-9]*$/.test(suffix))
|
|
3955
|
-
return;
|
|
3956
|
-
const version = Number(suffix);
|
|
3957
|
-
return Number.isSafeInteger(version) ? version : undefined;
|
|
3958
|
-
}
|
|
3959
|
-
function architectureDocsProjectionCompatibilityIssues(value, engine = {
|
|
3960
|
-
rendererVersion: ARCHITECTURE_DOCS_RENDERER_VERSION,
|
|
3961
|
-
protocolVersion: PROJECTION_REQUEST_SCHEMA_VERSION
|
|
3962
|
-
}) {
|
|
3963
|
-
const manifest = record3(value);
|
|
3964
|
-
if (!manifest)
|
|
3965
|
-
return [];
|
|
3966
|
-
const issues = [];
|
|
3967
|
-
if (["minimumRendererVersion", "minimumProtocolVersion"].some((key) => Object.hasOwn(manifest, key)) && manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION)
|
|
3968
|
-
issues.push("projection manifest floors require the current schema");
|
|
3969
|
-
if (typeof manifest.schemaVersion === "string" && manifest.schemaVersion !== ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION && !isSupersededArchitectureDocsProjectionManifestSchemaVersion(manifest.schemaVersion))
|
|
3970
|
-
issues.push("projection manifest schema is unsupported by this engine");
|
|
3971
|
-
for (const [key, family, current] of [
|
|
3972
|
-
["minimumRendererVersion", "archcontext.docs-renderer/v", engine.rendererVersion],
|
|
3973
|
-
["minimumProtocolVersion", "archcontext.projection-request/v", engine.protocolVersion]
|
|
3974
|
-
]) {
|
|
3975
|
-
if (!Object.hasOwn(manifest, key))
|
|
3976
|
-
continue;
|
|
3977
|
-
const required = versionNumber(manifest[key], family);
|
|
3978
|
-
const supported = versionNumber(current, family);
|
|
3979
|
-
if (required === undefined || supported === undefined || supported < required)
|
|
3980
|
-
issues.push(`projection manifest ${key} is unsupported by this engine`);
|
|
3981
|
-
}
|
|
3982
|
-
return issues;
|
|
3983
|
-
}
|
|
3984
|
-
var ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION = "archcontext.architecture-docs-projection-manifest/v3", SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS, PROJECTION_MANIFEST_UPGRADE_REQUIRED = "projection-manifest-upgrade-required", PROJECTION_MANIFEST_INVALID = "projection-manifest-invalid", PROJECTION_FOOTPRINT_UNCOVERED = "projection-footprint-uncovered", ARCHITECTURE_DOCS_PROJECTION_PROVENANCE_SCHEMA_VERSION = "archcontext.architecture-docs-projection-provenance/v3", ARCHITECTURE_DOCS_LAYOUT_VERSION_V1 = "archcontext.docs-layout/v1", ARCHITECTURE_SEMANTIC_STATE_SCHEMA_VERSION = "archcontext.architecture-semantic-state/v1", ARCHITECTURE_DOCS_PROJECTION_PROFILES, SHA256, TARGET_TYPES, RUNTIME_TOPOLOGY_TARGET_TYPES, SCOPE_KINDS, OWNERSHIPS, FORMATS;
|
|
3985
|
-
var init_projection_manifest = __esm(() => {
|
|
3986
|
-
init_projection();
|
|
3987
|
-
init_schema();
|
|
3988
|
-
SUPERSEDED_ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSIONS = [
|
|
3989
|
-
"archcontext.architecture-docs-projection-manifest/v1",
|
|
3990
|
-
"archcontext.architecture-docs-projection-manifest/v2"
|
|
3991
|
-
];
|
|
3992
|
-
ARCHITECTURE_DOCS_PROJECTION_PROFILES = ["default", "repo-harness/v1"];
|
|
3993
|
-
SHA256 = /^sha256:[a-f0-9]{64}$/;
|
|
3994
|
-
TARGET_TYPES = {
|
|
3995
|
-
"architecture-index": true,
|
|
3996
|
-
"entity-summary": true,
|
|
3997
|
-
"relation-summary": true,
|
|
3998
|
-
"decision-index": true,
|
|
3999
|
-
"architecture-changelog": true,
|
|
4000
|
-
"diagram-mermaid": true,
|
|
4001
|
-
"diagram-structurizr": true,
|
|
4002
|
-
"diagram-likec4": true,
|
|
4003
|
-
"diagram-runtime-topology": true,
|
|
4004
|
-
"runtime-topology-summary": true,
|
|
4005
|
-
"agent-context": true
|
|
4006
|
-
};
|
|
4007
|
-
RUNTIME_TOPOLOGY_TARGET_TYPES = ["diagram-runtime-topology", "runtime-topology-summary"];
|
|
4008
|
-
SCOPE_KINDS = { repository: true, entity: true, relation: true, decision: true, diagram: true, changelog: true };
|
|
4009
|
-
OWNERSHIPS = { generated: true, mixed: true };
|
|
4010
|
-
FORMATS = { markdown: true, mermaid: true, "structurizr-json": true, likec4: true };
|
|
4011
|
-
});
|
|
4012
|
-
|
|
4013
4037
|
// packages/contracts/src/product-version.ts
|
|
4014
4038
|
function productVersionManifest() {
|
|
4015
4039
|
return {
|
|
@@ -4095,7 +4119,7 @@ function compareVersionTriples(left, right) {
|
|
|
4095
4119
|
}
|
|
4096
4120
|
return 0;
|
|
4097
4121
|
}
|
|
4098
|
-
var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.
|
|
4122
|
+
var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.11.0", ARCHCONTEXT_PACKAGE_MANAGER = "bun@1.4.3", ARCHCONTEXT_NODE_RANGE = ">=22.22 <26", LOCAL_RUNTIME_RPC_SCHEMA_VERSION = "archcontext.runtime-rpc/v2", ARCHCONTEXT_SCHEMA_SET_VERSION = "2026-07-11.explorer-view-v2";
|
|
4099
4123
|
|
|
4100
4124
|
// packages/contracts/src/refactor.ts
|
|
4101
4125
|
function refactorNamespaceIssues(value, label = "product.id") {
|
|
@@ -5188,6 +5212,7 @@ var init_refactor = __esm(() => {
|
|
|
5188
5212
|
var init_src = __esm(() => {
|
|
5189
5213
|
init_control_plane_routes();
|
|
5190
5214
|
init_architecture();
|
|
5215
|
+
init_architecture_history();
|
|
5191
5216
|
init_architecture_debt();
|
|
5192
5217
|
init_docs_anchors();
|
|
5193
5218
|
init_github_governance();
|
|
@@ -15651,7 +15676,7 @@ import { basename, posix, resolve as resolve6 } from "node:path";
|
|
|
15651
15676
|
var composer = require_composer();
|
|
15652
15677
|
var Document = require_Document();
|
|
15653
15678
|
var Schema = require_Schema();
|
|
15654
|
-
var
|
|
15679
|
+
var errors2 = require_errors();
|
|
15655
15680
|
var Alias = require_Alias();
|
|
15656
15681
|
var identity = require_identity();
|
|
15657
15682
|
var Pair = require_Pair();
|
|
@@ -15667,9 +15692,9 @@ var visit2 = require_visit();
|
|
|
15667
15692
|
var $Composer = composer.Composer;
|
|
15668
15693
|
var $Document = Document.Document;
|
|
15669
15694
|
var $Schema = Schema.Schema;
|
|
15670
|
-
var $YAMLError =
|
|
15671
|
-
var $YAMLParseError =
|
|
15672
|
-
var $YAMLWarning =
|
|
15695
|
+
var $YAMLError = errors2.YAMLError;
|
|
15696
|
+
var $YAMLParseError = errors2.YAMLParseError;
|
|
15697
|
+
var $YAMLWarning = errors2.YAMLWarning;
|
|
15673
15698
|
var $Alias = Alias.Alias;
|
|
15674
15699
|
var $isAlias = identity.isAlias;
|
|
15675
15700
|
var $isCollection = identity.isCollection;
|
|
@@ -16013,6 +16038,114 @@ function sourceIncludeAnchors(patterns) {
|
|
|
16013
16038
|
});
|
|
16014
16039
|
return [...new Set(anchors)].sort(nativeByteCompare);
|
|
16015
16040
|
}
|
|
16041
|
+
// packages/core/projection-engine/src/architecture-history.ts
|
|
16042
|
+
init_src();
|
|
16043
|
+
var ARCHITECTURE_HISTORY_PATH = "docs/architecture/history.md";
|
|
16044
|
+
var HISTORY_DETAIL_EDGE_LIMIT = 20;
|
|
16045
|
+
var capabilityDomain = (id) => id === null ? null : /^capability\.([a-z0-9]+(?:-[a-z0-9]+)*)\.([a-z0-9]+(?:-[a-z0-9]+)*)$/.exec(id)?.[1] ?? null;
|
|
16046
|
+
var compare2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
16047
|
+
function renderHistoryMermaid(milestone, mode = "full") {
|
|
16048
|
+
if (!milestone.nodes)
|
|
16049
|
+
return null;
|
|
16050
|
+
const removed = mode === "changes" ? milestone.delta.removed.filter((node) => node.kind === "capability") : [];
|
|
16051
|
+
const nodes = mode === "changes" ? [...milestone.nodes, ...removed.map((node) => ({
|
|
16052
|
+
id: node.id,
|
|
16053
|
+
name: node.id,
|
|
16054
|
+
domain: capabilityDomain(node.id)
|
|
16055
|
+
}))].sort((a, b) => compare2(a.id, b.id)) : milestone.nodes;
|
|
16056
|
+
const keys = new Map(nodes.map((node, index) => [node.id, `n${index}`]));
|
|
16057
|
+
const label = (node) => ` ${keys.get(node.id)}["${node.name.replaceAll('"', "#quot;")}"]`;
|
|
16058
|
+
const domains = [...new Set(nodes.flatMap((node) => node.domain === null ? [] : [node.domain]))].sort();
|
|
16059
|
+
const lines = ["flowchart LR"];
|
|
16060
|
+
for (const domain of domains) {
|
|
16061
|
+
lines.push(` subgraph ${JSON.stringify(domain)}`);
|
|
16062
|
+
lines.push(...nodes.filter((node) => node.domain === domain).map((node) => ` ${label(node)}`));
|
|
16063
|
+
lines.push(" end");
|
|
16064
|
+
}
|
|
16065
|
+
lines.push(...nodes.filter((node) => node.domain === null).map(label));
|
|
16066
|
+
const added = mode === "changes" ? milestone.delta.edgesChanged.added : milestone.edges;
|
|
16067
|
+
lines.push(...added.map((edge) => ` ${keys.get(edge.source)} --> ${keys.get(edge.target)}`));
|
|
16068
|
+
if (mode === "changes")
|
|
16069
|
+
lines.push(...milestone.delta.edgesChanged.removed.map((edge) => ` ${keys.get(edge.source)} -.-> ${keys.get(edge.target)}`));
|
|
16070
|
+
if (removed.length) {
|
|
16071
|
+
lines.push(...removed.map((node) => ` class ${keys.get(node.id)} removed`));
|
|
16072
|
+
lines.push(" classDef removed stroke-dasharray: 4 4");
|
|
16073
|
+
}
|
|
16074
|
+
return lines.join(`
|
|
16075
|
+
`);
|
|
16076
|
+
}
|
|
16077
|
+
function renderHistoryDomainOverview(milestone) {
|
|
16078
|
+
if (!milestone.nodes)
|
|
16079
|
+
return null;
|
|
16080
|
+
const counts = new Map;
|
|
16081
|
+
const ensure = (domain) => {
|
|
16082
|
+
if (!counts.has(domain))
|
|
16083
|
+
counts.set(domain, 0);
|
|
16084
|
+
};
|
|
16085
|
+
for (const node of milestone.nodes) {
|
|
16086
|
+
const domain = node.domain ?? "ungrouped";
|
|
16087
|
+
counts.set(domain, (counts.get(domain) ?? 0) + 1);
|
|
16088
|
+
}
|
|
16089
|
+
const changed = new Set;
|
|
16090
|
+
for (const item of [...milestone.delta.added, ...milestone.delta.removed, ...milestone.delta.renamed]) {
|
|
16091
|
+
const domain = capabilityDomain(item.capability) ?? "ungrouped";
|
|
16092
|
+
ensure(domain);
|
|
16093
|
+
changed.add(domain);
|
|
16094
|
+
}
|
|
16095
|
+
const pairs = new Map;
|
|
16096
|
+
for (const [kind, edges] of [["added", milestone.delta.edgesChanged.added], ["removed", milestone.delta.edgesChanged.removed]]) {
|
|
16097
|
+
for (const edge of edges) {
|
|
16098
|
+
const source = capabilityDomain(edge.source) ?? "ungrouped", target = capabilityDomain(edge.target) ?? "ungrouped";
|
|
16099
|
+
ensure(source);
|
|
16100
|
+
ensure(target);
|
|
16101
|
+
changed.add(source);
|
|
16102
|
+
changed.add(target);
|
|
16103
|
+
if (source === target)
|
|
16104
|
+
continue;
|
|
16105
|
+
const key = JSON.stringify([source, target]);
|
|
16106
|
+
const pair = pairs.get(key) ?? { source, target, added: 0, removed: 0 };
|
|
16107
|
+
pair[kind]++;
|
|
16108
|
+
pairs.set(key, pair);
|
|
16109
|
+
}
|
|
16110
|
+
}
|
|
16111
|
+
const domains = [...counts.keys()].sort();
|
|
16112
|
+
const keys = new Map(domains.map((domain, index) => [domain, `d${index}`]));
|
|
16113
|
+
const lines = ["flowchart LR", ...domains.map((domain) => ` ${keys.get(domain)}["${domain} (${counts.get(domain)})"]`)];
|
|
16114
|
+
for (const pair of [...pairs.values()].sort((a, b) => compare2(a.source, b.source) || compare2(a.target, b.target))) {
|
|
16115
|
+
const arrow = pair.added === 0 ? "-.->" : "-->";
|
|
16116
|
+
lines.push(` ${keys.get(pair.source)} ${arrow}|+${pair.added} −${pair.removed}| ${keys.get(pair.target)}`);
|
|
16117
|
+
}
|
|
16118
|
+
if (changed.size) {
|
|
16119
|
+
lines.push(...domains.filter((domain) => changed.has(domain)).map((domain) => ` class ${keys.get(domain)} changed`));
|
|
16120
|
+
lines.push(" classDef changed stroke-width:3px");
|
|
16121
|
+
}
|
|
16122
|
+
return { mermaid: lines.join(`
|
|
16123
|
+
`), pairCount: pairs.size };
|
|
16124
|
+
}
|
|
16125
|
+
function projectHistoryMermaid(history) {
|
|
16126
|
+
return { schemaVersion: ARCHITECTURE_HISTORY_MERMAID_SCHEMA_VERSION, head: history.head, total: history.total, offset: history.offset, limit: history.limit, diagrams: history.milestones.map((milestone) => ({ rev: milestone.rev, mermaid: renderHistoryMermaid(milestone) })) };
|
|
16127
|
+
}
|
|
16128
|
+
function renderHistoryMarkdown(history) {
|
|
16129
|
+
const lines = ["<!-- Generated by ArchContext (archctx history). Do not edit by hand. -->", "", `Architecture history contains ${history.total} milestones. Run \`archctx history\` for the full list.`, ""];
|
|
16130
|
+
for (const milestone of [...history.milestones].reverse()) {
|
|
16131
|
+
lines.push(`## ${milestone.date.slice(0, 10)} · ${milestone.rev.slice(0, 12)}`, "", milestone.subject, "");
|
|
16132
|
+
if (milestone.error)
|
|
16133
|
+
lines.push(milestone.error.code, "");
|
|
16134
|
+
else {
|
|
16135
|
+
const delta = milestone.delta;
|
|
16136
|
+
const overview = renderHistoryDomainOverview(milestone);
|
|
16137
|
+
const edgeCount = delta.edgesChanged.added.length + delta.edgesChanged.removed.length;
|
|
16138
|
+
lines.push(`Added ${delta.added.length} · Removed ${delta.removed.length} · Renamed ${delta.renamed.length} · Edges +${delta.edgesChanged.added.length} −${delta.edgesChanged.removed.length}`, "", "```mermaid", overview.mermaid, "```", "");
|
|
16139
|
+
if (edgeCount <= HISTORY_DETAIL_EDGE_LIMIT)
|
|
16140
|
+
lines.push("```mermaid", renderHistoryMermaid(milestone, "changes"), "```", "");
|
|
16141
|
+
else
|
|
16142
|
+
lines.push(`${edgeCount} changed edges across ${overview.pairCount} domain pairs; run archctx history --ref ${milestone.rev.slice(0, 12)} --format mermaid for the full shape.`, "");
|
|
16143
|
+
}
|
|
16144
|
+
}
|
|
16145
|
+
return `${lines.join(`
|
|
16146
|
+
`)}
|
|
16147
|
+
`;
|
|
16148
|
+
}
|
|
16016
16149
|
|
|
16017
16150
|
// packages/core/projection-engine/src/index.ts
|
|
16018
16151
|
init_src();
|
|
@@ -18071,12 +18204,13 @@ function resolveArchitectureDocumentationLayout(input) {
|
|
|
18071
18204
|
});
|
|
18072
18205
|
const relationTargets = (profile === REPO_HARNESS_PROJECTION_PROFILE ? [] : input.relations).map((relation) => layoutTarget(`projection_target.relation.${stableId(relation.id)}`, "relation-summary", { kind: "relation", id: relation.id }, `docs/architecture/relations/${pathSegment(relation.id)}.md`, "mixed", "markdown"));
|
|
18073
18206
|
const topologyTargets = hasRuntimeTopologyNodes(input.nodes) ? RUNTIME_TOPOLOGY_TARGETS : [];
|
|
18074
|
-
const targets = [FIXED_TARGETS[0], ...entityTargets, ...relationTargets, ...FIXED_TARGETS.slice(1), ...topologyTargets].map((target) => ({ ...target, path: requiredPath(target.path, target.targetId) }));
|
|
18207
|
+
const targets = (profile === REPO_HARNESS_PROJECTION_PROFILE ? [...entityTargets, ...topologyTargets] : [FIXED_TARGETS[0], ...entityTargets, ...relationTargets, ...FIXED_TARGETS.slice(1), ...topologyTargets]).map((target) => ({ ...target, path: requiredPath(target.path, target.targetId) }));
|
|
18075
18208
|
assertUniqueTargets(targets);
|
|
18076
18209
|
return {
|
|
18077
18210
|
profile,
|
|
18078
18211
|
targets,
|
|
18079
18212
|
expectedPaths: [...new Set([...targets.map((target) => target.path), "docs/architecture/.projection-manifest.json"])].sort(),
|
|
18213
|
+
retiredTargetPaths: profile === REPO_HARNESS_PROJECTION_PROFILE ? FIXED_TARGETS.map((target) => target.path) : [],
|
|
18080
18214
|
orphanRoots: ["docs/architecture/modules", "docs/architecture/relations"],
|
|
18081
18215
|
entityPathByNodeId: new Map(entityTargets.map((target, index) => [targetNodes[index].id, target.path]))
|
|
18082
18216
|
};
|
|
@@ -18124,7 +18258,10 @@ function loadArchitectureFilesForLayout(root, layout) {
|
|
|
18124
18258
|
}
|
|
18125
18259
|
if (paths.has(ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)) {
|
|
18126
18260
|
const manifest = readProjectionOwnedFile(resolve5(root, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH), ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH);
|
|
18127
|
-
|
|
18261
|
+
const retired = new Set(layout.retiredTargetPaths);
|
|
18262
|
+
for (const output of committedProjectionOutputs(currentFormatManifest(manifest.body))) {
|
|
18263
|
+
if (output.ownership !== "generated" && !retired.has(output.path))
|
|
18264
|
+
continue;
|
|
18128
18265
|
if (resolveSafeRegularPath(root, output.path, false))
|
|
18129
18266
|
paths.add(output.path);
|
|
18130
18267
|
}
|
|
@@ -18132,17 +18269,20 @@ function loadArchitectureFilesForLayout(root, layout) {
|
|
|
18132
18269
|
return [...paths].sort().map((path) => readProjectionOwnedFile(resolve5(root, path), path));
|
|
18133
18270
|
}
|
|
18134
18271
|
var OUTPUT_DIGEST_PATTERN = /^sha256:[a-f0-9]{64}$/;
|
|
18135
|
-
function
|
|
18272
|
+
function committedProjectionOutputs(manifest) {
|
|
18136
18273
|
if (manifest === undefined)
|
|
18137
18274
|
return [];
|
|
18138
18275
|
const outputs = [];
|
|
18139
18276
|
for (const [targetId, row] of Object.entries(manifest.targets)) {
|
|
18140
|
-
if (
|
|
18277
|
+
if (!OUTPUT_DIGEST_PATTERN.test(row.outputDigest) || !isRepoRelativePosixPath(row.path) || !row.path.startsWith("docs/architecture/") || row.path === ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)
|
|
18141
18278
|
continue;
|
|
18142
|
-
outputs.push({ targetId, path: row.path, outputDigest: row.outputDigest });
|
|
18279
|
+
outputs.push({ targetId, path: row.path, ownership: row.ownership, outputDigest: row.outputDigest });
|
|
18143
18280
|
}
|
|
18144
18281
|
return outputs;
|
|
18145
18282
|
}
|
|
18283
|
+
function committedGeneratedOutputs(manifest) {
|
|
18284
|
+
return committedProjectionOutputs(manifest).filter((output) => output.ownership === "generated").map(({ targetId, path, outputDigest }) => ({ targetId, path, outputDigest }));
|
|
18285
|
+
}
|
|
18146
18286
|
function currentFormatManifest(body) {
|
|
18147
18287
|
let parsed;
|
|
18148
18288
|
try {
|
|
@@ -20034,9 +20174,17 @@ class ProjectionPreconditionError extends Error {
|
|
|
20034
20174
|
class ProjectionManifestUpgradeRequiredError extends ProjectionPreconditionError {
|
|
20035
20175
|
schemaVersion;
|
|
20036
20176
|
reasonCode = PROJECTION_MANIFEST_UPGRADE_REQUIRED;
|
|
20177
|
+
details;
|
|
20037
20178
|
constructor(schemaVersion) {
|
|
20038
|
-
super(`${PROJECTION_MANIFEST_UPGRADE_REQUIRED}: ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH} is ${schemaVersion}, and this archctx reads only ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION}; reach a clean projection on the earlier release first, then re-baseline once with
|
|
20179
|
+
super(`${PROJECTION_MANIFEST_UPGRADE_REQUIRED}: ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH} is ${schemaVersion}, and this archctx reads only ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION}; reach a clean projection on the earlier release first, then re-baseline once with ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND}; if that apply names whole-file outputs the earlier release wrote, remove them with git rm and run it again; ${ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE} lists the model and release preconditions`);
|
|
20039
20180
|
this.schemaVersion = schemaVersion;
|
|
20181
|
+
this.details = isSupersededArchitectureDocsProjectionManifestSchemaVersion(schemaVersion) ? {
|
|
20182
|
+
manifestPath: ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH,
|
|
20183
|
+
foundSchemaVersion: schemaVersion,
|
|
20184
|
+
supportedSchemaVersion: ARCHITECTURE_DOCS_PROJECTION_MANIFEST_SCHEMA_VERSION,
|
|
20185
|
+
upgradeCommand: ARCHITECTURE_DOCS_PROJECTION_MANIFEST_UPGRADE_COMMAND,
|
|
20186
|
+
migrationGuide: ARCHITECTURE_DOCS_PROJECTION_MANIFEST_MIGRATION_GUIDE
|
|
20187
|
+
} : {};
|
|
20040
20188
|
}
|
|
20041
20189
|
}
|
|
20042
20190
|
|
|
@@ -22177,7 +22325,7 @@ function sameOwners(left, right) {
|
|
|
22177
22325
|
|
|
22178
22326
|
// packages/core/module-statistics/src/index.ts
|
|
22179
22327
|
function evaluateDependencyConstraints(input) {
|
|
22180
|
-
const constraints = [...input.constraints].sort((left, right) =>
|
|
22328
|
+
const constraints = [...input.constraints].sort((left, right) => compare3(left.id, right.id));
|
|
22181
22329
|
const certification = certifyCodeFacts(input.codeFacts, input.worktreeDigest, input.truncated, input.importNodeLimitExceeded ?? false);
|
|
22182
22330
|
if (constraints.length === 0) {
|
|
22183
22331
|
return {
|
|
@@ -22255,7 +22403,7 @@ function evaluateDependencyConstraints(input) {
|
|
|
22255
22403
|
reasonCodes.add("unresolved-import");
|
|
22256
22404
|
if (input.workspacePackagesResolved === false)
|
|
22257
22405
|
reasonCodes.add("workspace-resolution-failed");
|
|
22258
|
-
const sortedViolations = [...violations.values()].sort((left, right) =>
|
|
22406
|
+
const sortedViolations = [...violations.values()].sort((left, right) => compare3(left.constraintId, right.constraintId) || compare3(left.fromPath, right.fromPath) || compare3(left.toPath, right.toPath));
|
|
22259
22407
|
return {
|
|
22260
22408
|
schemaVersion: "archcontext.dependency-constraint-evaluation/v1",
|
|
22261
22409
|
status: sortedViolations.length > 0 ? "violated" : reasonCodes.size > 0 ? "undetermined" : "pass",
|
|
@@ -22332,7 +22480,7 @@ function measureCapabilityDependencies(input) {
|
|
|
22332
22480
|
const cellKey = JSON.stringify([from.capability, to.capability]);
|
|
22333
22481
|
let cell = cells.get(cellKey);
|
|
22334
22482
|
if (cell === undefined) {
|
|
22335
|
-
const relationIds = [...new Set(declaringRelations.get(cellKey) ?? [])].sort(
|
|
22483
|
+
const relationIds = [...new Set(declaringRelations.get(cellKey) ?? [])].sort(compare3);
|
|
22336
22484
|
cell = { from: from.capability, to: to.capability, imports: 0, calls: null, declared: from.capability === to.capability || relationIds.length > 0, relationIds };
|
|
22337
22485
|
cells.set(cellKey, cell);
|
|
22338
22486
|
}
|
|
@@ -22340,14 +22488,14 @@ function measureCapabilityDependencies(input) {
|
|
|
22340
22488
|
attributedEdges.push({ fromPath: edge.from, toPath: edge.to, fromCapability: from.capability, toCapability: to.capability });
|
|
22341
22489
|
}
|
|
22342
22490
|
const edgeLimit = input.edgeLimit ?? CAPABILITY_DEPENDENCIES_EDGE_LIMIT;
|
|
22343
|
-
attributedEdges.sort((left, right) =>
|
|
22491
|
+
attributedEdges.sort((left, right) => compare3(left.fromPath, right.fromPath) || compare3(left.toPath, right.toPath));
|
|
22344
22492
|
const listed = attributedEdges.slice(0, edgeLimit);
|
|
22345
22493
|
return {
|
|
22346
22494
|
schemaVersion: CAPABILITY_DEPENDENCIES_SCHEMA_VERSION,
|
|
22347
22495
|
ownershipRule: "parent-chain",
|
|
22348
22496
|
filter: { from: input.from ?? null, into: input.into ?? null },
|
|
22349
|
-
capabilities: input.nodes.filter((node) => node.kind === "capability").map((node) => node.id).sort(
|
|
22350
|
-
matrix: [...cells.values()].sort((left, right) =>
|
|
22497
|
+
capabilities: input.nodes.filter((node) => node.kind === "capability").map((node) => node.id).sort(compare3),
|
|
22498
|
+
matrix: [...cells.values()].sort((left, right) => compare3(left.from, right.from) || compare3(left.to, right.to)),
|
|
22351
22499
|
imports: {
|
|
22352
22500
|
coverage: certification.coverage,
|
|
22353
22501
|
reasonCodes: [...certification.reasonCodes].sort(),
|
|
@@ -22383,7 +22531,7 @@ function isRepositoryLocalSpecifier(specifier, workspacePackages) {
|
|
|
22383
22531
|
return true;
|
|
22384
22532
|
return workspacePackages.some((workspacePackage) => specifier === workspacePackage.name || specifier.startsWith(`${workspacePackage.name}/`));
|
|
22385
22533
|
}
|
|
22386
|
-
function
|
|
22534
|
+
function compare3(left, right) {
|
|
22387
22535
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
22388
22536
|
}
|
|
22389
22537
|
function measureModuleStatistics(input) {
|
|
@@ -22468,7 +22616,7 @@ function modelDigest(model, constraints) {
|
|
|
22468
22616
|
nodes: [...model.nodes].sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0),
|
|
22469
22617
|
relations: [...model.relations].sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0),
|
|
22470
22618
|
flows: [...model.flows ?? []].sort((left, right) => left.id < right.id ? -1 : left.id > right.id ? 1 : 0),
|
|
22471
|
-
...constraints.length === 0 ? {} : { constraints: [...constraints].sort((left, right) =>
|
|
22619
|
+
...constraints.length === 0 ? {} : { constraints: [...constraints].sort((left, right) => compare3(left.id, right.id)) }
|
|
22472
22620
|
});
|
|
22473
22621
|
}
|
|
22474
22622
|
function countViolationsByNode(evaluation) {
|
|
@@ -23097,17 +23245,21 @@ function assertNativeGitRevision(ref) {
|
|
|
23097
23245
|
throw new NativeContextError("native-context-ref-unsafe", { selector: "ref" });
|
|
23098
23246
|
}
|
|
23099
23247
|
function readOnlyGit(root, operation, args, options = {}) {
|
|
23100
|
-
if (!["rev-parse", "ls-tree", "ls-files", "cat-file"].includes(operation))
|
|
23248
|
+
if (!["rev-parse", "ls-tree", "ls-files", "cat-file", "log"].includes(operation))
|
|
23101
23249
|
throw new NativeContextError("native-context-git-read-failed", { category: "unsupported-operation" });
|
|
23102
23250
|
const unsafeArguments = () => {
|
|
23103
23251
|
throw new NativeContextError("native-context-git-read-failed", { operation, category: "unsupported-read-arguments" });
|
|
23104
23252
|
};
|
|
23105
23253
|
if (operation === "rev-parse") {
|
|
23106
|
-
if (args.length === 1 &&
|
|
23254
|
+
if (args.length === 1 && ["--show-toplevel", "--is-shallow-repository"].includes(args[0])) {} else if (args.length === 1 && isGitRevisionArgument(args[0])) {} else if (args.length === 3 && args[0] === "--verify" && args[1] === "--end-of-options")
|
|
23107
23255
|
assertNativeGitRevision(args[2]);
|
|
23108
23256
|
else
|
|
23109
23257
|
unsafeArguments();
|
|
23110
23258
|
}
|
|
23259
|
+
if (operation === "log") {
|
|
23260
|
+
if (args.length !== 8 || args[0] !== "--first-parent" || args[1] !== "--reverse" || args[2] !== "-z" || args[3] !== "--format=%H%x00%cI%x00%s" || !OBJECT_ID.test(args[4]) || args[5] !== "--" || args[6] !== ".archcontext/model" || args[7] !== ".archcontext/manifest.yaml")
|
|
23261
|
+
unsafeArguments();
|
|
23262
|
+
}
|
|
23111
23263
|
if (operation === "ls-tree") {
|
|
23112
23264
|
const flags = args.slice(0, -1);
|
|
23113
23265
|
if (!flags.includes("-r") || !flags.includes("-z") || flags.some((flag) => !["-r", "-z", "-t", "-l"].includes(flag)) || new Set(flags).size !== flags.length)
|
|
@@ -23133,7 +23285,7 @@ function readOnlyGit(root, operation, args, options = {}) {
|
|
|
23133
23285
|
const env = { ...process.env, LC_ALL: "C", GIT_NO_REPLACE_OBJECTS: "1", GIT_NO_LAZY_FETCH: "1", GIT_OPTIONAL_LOCKS: "0", GIT_PAGER: "cat", GIT_ALLOW_PROTOCOL: "", GIT_TERMINAL_PROMPT: "0" };
|
|
23134
23286
|
for (const key of ["GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR", "GIT_INDEX_FILE", "GIT_OBJECT_DIRECTORY", "GIT_ALTERNATE_OBJECT_DIRECTORIES", "GIT_NAMESPACE"])
|
|
23135
23287
|
delete env[key];
|
|
23136
|
-
const result = spawnSync("git", ["--no-pager", "--no-replace-objects", "-c", "core.fsmonitor=false", operation, ...args], {
|
|
23288
|
+
const result = spawnSync("git", ["--no-pager", "--no-replace-objects", "-c", "core.fsmonitor=false", ...operation === "log" ? ["-c", "log.showSignature=false"] : [], operation, ...args], {
|
|
23137
23289
|
cwd: root,
|
|
23138
23290
|
env,
|
|
23139
23291
|
input: options.input,
|
|
@@ -23811,10 +23963,10 @@ function record5(value) {
|
|
|
23811
23963
|
function text(value) {
|
|
23812
23964
|
return typeof value === "string" && value.length > 0;
|
|
23813
23965
|
}
|
|
23814
|
-
function
|
|
23966
|
+
function node2(value) {
|
|
23815
23967
|
return record5(value) && ["id", "kind", "name", "qualifiedName", "filePath", "language"].every((key) => typeof value[key] === "string") && text(value.id) && ["startLine", "endLine", "startColumn", "endColumn", "updatedAt"].every((key) => typeof value[key] === "number" && Number.isFinite(value[key]));
|
|
23816
23968
|
}
|
|
23817
|
-
function
|
|
23969
|
+
function edge2(value) {
|
|
23818
23970
|
return record5(value) && text(value.source) && text(value.target) && (value.kind === "calls" || value.kind === "references") && (value.line === undefined || typeof value.line === "number" && Number.isFinite(value.line)) && (value.column === undefined || typeof value.column === "number" && Number.isFinite(value.column)) && (value.metadata === undefined || record5(value.metadata));
|
|
23819
23971
|
}
|
|
23820
23972
|
function fileRecord(value) {
|
|
@@ -23861,12 +24013,12 @@ function decodeReader(output, root, request) {
|
|
|
23861
24013
|
}
|
|
23862
24014
|
return result;
|
|
23863
24015
|
};
|
|
23864
|
-
const names = table(wire.names, (value) => rows(value,
|
|
24016
|
+
const names = table(wire.names, (value) => rows(value, node2));
|
|
23865
24017
|
sameKeys(names, request.names);
|
|
23866
24018
|
for (const [name, nodes] of names)
|
|
23867
24019
|
if (nodes.some((item) => item.name !== name))
|
|
23868
24020
|
unavailable();
|
|
23869
|
-
const filesByPath = table(wire.filesByPath, (value) => rows(value,
|
|
24021
|
+
const filesByPath = table(wire.filesByPath, (value) => rows(value, node2));
|
|
23870
24022
|
const sources = new Map;
|
|
23871
24023
|
const sourcePaths = new Set(request.sources.map((source) => source.path));
|
|
23872
24024
|
for (const source of request.sources) {
|
|
@@ -23880,7 +24032,7 @@ function decodeReader(output, root, request) {
|
|
|
23880
24032
|
}
|
|
23881
24033
|
}
|
|
23882
24034
|
sameKeys(filesByPath, sourcePaths);
|
|
23883
|
-
const outgoing = table(wire.outgoing, (value) => rows(value,
|
|
24035
|
+
const outgoing = table(wire.outgoing, (value) => rows(value, edge2));
|
|
23884
24036
|
sameKeys(outgoing, sources.keys());
|
|
23885
24037
|
const targetIds = new Set;
|
|
23886
24038
|
for (const [id, edges] of outgoing)
|
|
@@ -23890,7 +24042,7 @@ function decodeReader(output, root, request) {
|
|
|
23890
24042
|
targetIds.add(item.target);
|
|
23891
24043
|
}
|
|
23892
24044
|
const targets = table(wire.targets, (value) => {
|
|
23893
|
-
if (++items > MAX_ITEMS || value !== null && !
|
|
24045
|
+
if (++items > MAX_ITEMS || value !== null && !node2(value))
|
|
23894
24046
|
return unavailable();
|
|
23895
24047
|
return value;
|
|
23896
24048
|
});
|
|
@@ -25459,6 +25611,8 @@ function architectureDeltaTask(git) {
|
|
|
25459
25611
|
var CODEGRAPH_IMPORT_NODE_READ_LIMIT = 50000;
|
|
25460
25612
|
var CODEGRAPH_IMPORT_NODE_OUTPUT_BYTES = 4 * 1024;
|
|
25461
25613
|
function prepareArchitectureDocumentationProjectionSnapshot(root, model, options = {}) {
|
|
25614
|
+
if (codeGraphIndexAvailable(root))
|
|
25615
|
+
assertRepositoryCodeFactsReady(root, options.binary ? { binary: options.binary } : {});
|
|
25462
25616
|
const baseHeadSha = readProjectionHeadSha(root);
|
|
25463
25617
|
const sourceFiles = listGitVisibleFiles(root);
|
|
25464
25618
|
const worktreeDigest = architectureDocumentationProjectionWorktreeDigest(root, model, sourceFiles);
|
|
@@ -25603,7 +25757,33 @@ function prepareProjectionCodeFacts(root, model, options) {
|
|
|
25603
25757
|
}
|
|
25604
25758
|
};
|
|
25605
25759
|
}
|
|
25760
|
+
|
|
25761
|
+
class CodeGraphIndexBuildInProgressError extends Error {
|
|
25762
|
+
constructor() {
|
|
25763
|
+
super("CodeGraph index build is in progress");
|
|
25764
|
+
this.name = "CodeGraphIndexBuildInProgressError";
|
|
25765
|
+
}
|
|
25766
|
+
}
|
|
25767
|
+
function codeGraphIndexBuildInProgress(workspaceRoot) {
|
|
25768
|
+
let raw;
|
|
25769
|
+
try {
|
|
25770
|
+
raw = readFileSync7(join3(workspaceRoot, ".codegraph", "codegraph.lock"), "utf8").trim();
|
|
25771
|
+
} catch {
|
|
25772
|
+
return false;
|
|
25773
|
+
}
|
|
25774
|
+
const pid = Number.parseInt(raw, 10);
|
|
25775
|
+
if (!Number.isSafeInteger(pid) || pid <= 0 || String(pid) !== raw)
|
|
25776
|
+
return false;
|
|
25777
|
+
try {
|
|
25778
|
+
process.kill(pid, 0);
|
|
25779
|
+
return true;
|
|
25780
|
+
} catch (error) {
|
|
25781
|
+
return error.code === "EPERM";
|
|
25782
|
+
}
|
|
25783
|
+
}
|
|
25606
25784
|
function readProjectionCodeGraphStatus(invocation, root, timeout, envOverrides) {
|
|
25785
|
+
if (codeGraphIndexBuildInProgress(root))
|
|
25786
|
+
throw new CodeGraphIndexBuildInProgressError;
|
|
25607
25787
|
const output = runProjectionCodeGraph(invocation, root, ["status", "-j", root], timeout, envOverrides);
|
|
25608
25788
|
try {
|
|
25609
25789
|
return JSON.parse(output);
|
|
@@ -25922,8 +26102,9 @@ function mirrorCodeGraphInputs(root, gitDir, commonDir, destination) {
|
|
|
25922
26102
|
var CODEGRAPH_NO_DOWNLOAD_ENV = { CODEGRAPH_NO_DOWNLOAD: "1" };
|
|
25923
26103
|
function inspectRepositoryCodeFacts(root, options = {}) {
|
|
25924
26104
|
const schemaVersion = "archcontext.repository-code-facts/v1";
|
|
25925
|
-
let codeGraphVersion;
|
|
26105
|
+
let codeGraphVersion = "";
|
|
25926
26106
|
let status;
|
|
26107
|
+
let indexBuildInProgress = false;
|
|
25927
26108
|
const indexPresent = codeGraphIndexAvailable(root);
|
|
25928
26109
|
try {
|
|
25929
26110
|
const invocation = options.binary ? codeGraphCliInvocation(options.binary, root, "") : packagedCodeGraphCliInvocation();
|
|
@@ -25931,18 +26112,37 @@ function inspectRepositoryCodeFacts(root, options = {}) {
|
|
|
25931
26112
|
if (indexPresent)
|
|
25932
26113
|
status = readProjectionCodeGraphStatus(invocation, root, options.timeouts?.statusMs ?? 1e4, CODEGRAPH_NO_DOWNLOAD_ENV);
|
|
25933
26114
|
} catch (error) {
|
|
25934
|
-
|
|
25935
|
-
|
|
25936
|
-
|
|
25937
|
-
|
|
25938
|
-
|
|
25939
|
-
|
|
25940
|
-
|
|
26115
|
+
if (!(error instanceof CodeGraphIndexBuildInProgressError)) {
|
|
26116
|
+
return {
|
|
26117
|
+
schemaVersion,
|
|
26118
|
+
state: "unavailable",
|
|
26119
|
+
requiredVersion: REQUIRED_CODEGRAPH_VERSION,
|
|
26120
|
+
reasonCode: "codegraph-unavailable",
|
|
26121
|
+
message: (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 400)
|
|
26122
|
+
};
|
|
26123
|
+
}
|
|
26124
|
+
indexBuildInProgress = true;
|
|
25941
26125
|
}
|
|
25942
26126
|
const versionIssues = codeGraphVersion === REQUIRED_CODEGRAPH_VERSION ? [] : [{ code: "version-mismatch", message: CODE_FACTS_ISSUE_MESSAGES["version-mismatch"] }];
|
|
25943
26127
|
if (!indexPresent) {
|
|
25944
26128
|
return { schemaVersion, state: "index-missing", indexPresent: false, requiredVersion: REQUIRED_CODEGRAPH_VERSION, codeGraphVersion, issues: versionIssues };
|
|
25945
26129
|
}
|
|
26130
|
+
if (indexBuildInProgress) {
|
|
26131
|
+
return {
|
|
26132
|
+
schemaVersion,
|
|
26133
|
+
state: "not-ready",
|
|
26134
|
+
indexPresent: true,
|
|
26135
|
+
requiredVersion: REQUIRED_CODEGRAPH_VERSION,
|
|
26136
|
+
codeGraphVersion,
|
|
26137
|
+
indexBuiltWithVersion: null,
|
|
26138
|
+
extractionVersion: { builtWith: null, current: null },
|
|
26139
|
+
indexState: null,
|
|
26140
|
+
reindexRecommended: null,
|
|
26141
|
+
pendingRefs: null,
|
|
26142
|
+
pendingChanges: null,
|
|
26143
|
+
issues: [...versionIssues, { code: "index-incomplete", message: CODE_FACTS_ISSUE_MESSAGES["index-incomplete"] }]
|
|
26144
|
+
};
|
|
26145
|
+
}
|
|
25946
26146
|
if (typeof status !== "object" || status === null || Array.isArray(status)) {
|
|
25947
26147
|
return {
|
|
25948
26148
|
schemaVersion,
|
|
@@ -26329,6 +26529,8 @@ function selectedProducerFailure(error, stage) {
|
|
|
26329
26529
|
const details = stage === "docs-anchors" || stage === "flows-check" ? {} : { checks: ["ownership", "anchors"] };
|
|
26330
26530
|
return new FailureError(selectedProducerData(error, "code"), selectedProducerData(error, "reasonCode"), details);
|
|
26331
26531
|
}
|
|
26532
|
+
if (error instanceof ProjectionManifestUpgradeRequiredError)
|
|
26533
|
+
return new FailureError("AC_PRECONDITION_FAILED", selectedProducerData(error, "reasonCode"), selectedProducerData(error, "details"));
|
|
26332
26534
|
if (error instanceof ProjectionPreconditionError)
|
|
26333
26535
|
return new FailureError("AC_PRECONDITION_FAILED", selectedProducerData(error, "reasonCode"));
|
|
26334
26536
|
if (error instanceof ProjectionCodeFactsUnavailableError)
|
|
@@ -26346,10 +26548,10 @@ function selectedProducerFailureEnvelope(requestId, error, stage) {
|
|
|
26346
26548
|
// packages/local-runtime/runtime-daemon/src/refactor-scan.ts
|
|
26347
26549
|
init_src();
|
|
26348
26550
|
init_src();
|
|
26349
|
-
import { execFileSync as
|
|
26350
|
-
import { createHash as
|
|
26351
|
-
import { existsSync as existsSync8, readdirSync as
|
|
26352
|
-
import { join as
|
|
26551
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
26552
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
26553
|
+
import { existsSync as existsSync8, readdirSync as readdirSync7, readFileSync as readFileSync10 } from "node:fs";
|
|
26554
|
+
import { join as join7 } from "node:path";
|
|
26353
26555
|
|
|
26354
26556
|
// packages/core/refactor-assessment/src/index.ts
|
|
26355
26557
|
init_src();
|
|
@@ -27192,7 +27394,7 @@ function buildObservations(snapshot, structure, model) {
|
|
|
27192
27394
|
evidence: evidence.evidenceGap()
|
|
27193
27395
|
});
|
|
27194
27396
|
}
|
|
27195
|
-
return drafts.map((draft, index) => ({ draft, order: draft.kind === "cycle" ? index : 0 })).sort((left, right) =>
|
|
27397
|
+
return drafts.map((draft, index) => ({ draft, order: draft.kind === "cycle" ? index : 0 })).sort((left, right) => compare4(left.draft.kind, right.draft.kind) || left.order - right.order || compare4(left.draft.subjectSelectorId, right.draft.subjectSelectorId)).map(({ draft }) => ({
|
|
27196
27398
|
kind: draft.kind,
|
|
27197
27399
|
subjectSelectorId: draft.subjectSelectorId,
|
|
27198
27400
|
affectedNodeIds: draft.affectedNodeIds,
|
|
@@ -27382,13 +27584,13 @@ function signalIdFor(draft) {
|
|
|
27382
27584
|
}
|
|
27383
27585
|
function modelDigest2(model, constraints) {
|
|
27384
27586
|
return digestJson({
|
|
27385
|
-
nodes: [...model.nodes].sort((left, right) =>
|
|
27386
|
-
relations: [...model.relations].sort((left, right) =>
|
|
27387
|
-
flows: [...model.flows ?? []].sort((left, right) =>
|
|
27388
|
-
...constraints.length === 0 ? {} : { constraints: [...constraints].sort((left, right) =>
|
|
27587
|
+
nodes: [...model.nodes].sort((left, right) => compare4(left.id, right.id)),
|
|
27588
|
+
relations: [...model.relations].sort((left, right) => compare4(left.id, right.id)),
|
|
27589
|
+
flows: [...model.flows ?? []].sort((left, right) => compare4(left.id, right.id)),
|
|
27590
|
+
...constraints.length === 0 ? {} : { constraints: [...constraints].sort((left, right) => compare4(left.id, right.id)) }
|
|
27389
27591
|
});
|
|
27390
27592
|
}
|
|
27391
|
-
function
|
|
27593
|
+
function compare4(left, right) {
|
|
27392
27594
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
27393
27595
|
}
|
|
27394
27596
|
function isNumber(value) {
|
|
@@ -27400,8 +27602,117 @@ function isPresent2(value) {
|
|
|
27400
27602
|
|
|
27401
27603
|
// packages/local-runtime/model-store-yaml/src/index.ts
|
|
27402
27604
|
init_src();
|
|
27403
|
-
import { existsSync as existsSync7, lstatSync as lstatSync6, mkdirSync as
|
|
27404
|
-
import { dirname as dirname5, resolve as
|
|
27605
|
+
import { existsSync as existsSync7, lstatSync as lstatSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync6, readFileSync as readFileSync9, rmSync as rmSync5 } from "node:fs";
|
|
27606
|
+
import { dirname as dirname5, resolve as resolve13 } from "node:path";
|
|
27607
|
+
|
|
27608
|
+
// packages/local-runtime/model-store-yaml/src/architecture-history.ts
|
|
27609
|
+
init_src();
|
|
27610
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, renameSync as renameSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
27611
|
+
import { join as join5 } from "node:path";
|
|
27612
|
+
import { randomUUID } from "node:crypto";
|
|
27613
|
+
|
|
27614
|
+
// packages/local-runtime/runtime-state-paths/src/index.ts
|
|
27615
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
27616
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
27617
|
+
import { readdirSync as readdirSync5, realpathSync as realpathSync4 } from "node:fs";
|
|
27618
|
+
import { homedir } from "node:os";
|
|
27619
|
+
import { isAbsolute as isAbsolute5, join as join4, resolve as resolve11 } from "node:path";
|
|
27620
|
+
var ARCHCONTEXT_STATE_DIR_ENV = "ARCHCONTEXT_STATE_DIR";
|
|
27621
|
+
var ARCHCONTEXT_LOCAL_STORE_PATH_ENV = "ARCHCONTEXT_LOCAL_STORE_PATH";
|
|
27622
|
+
function defaultArchContextStateRoot(env = process.env, platform = process.platform, home = homedir()) {
|
|
27623
|
+
const override = env[ARCHCONTEXT_STATE_DIR_ENV];
|
|
27624
|
+
if (override)
|
|
27625
|
+
return { path: resolve11(override), source: "environment" };
|
|
27626
|
+
if (platform === "darwin")
|
|
27627
|
+
return { path: join4(home, "Library", "Application Support", "ArchContext"), source: "os-user-data" };
|
|
27628
|
+
if (platform === "win32")
|
|
27629
|
+
return { path: join4(env.LOCALAPPDATA ?? join4(home, "AppData", "Local"), "ArchContext"), source: "os-user-data" };
|
|
27630
|
+
return { path: join4(env.XDG_DATA_HOME ?? join4(home, ".local", "share"), "archcontext"), source: "os-user-data" };
|
|
27631
|
+
}
|
|
27632
|
+
function runtimeStatePaths(root = process.cwd(), env = process.env) {
|
|
27633
|
+
const repositoryRoot = readGitPath(root, ["rev-parse", "--show-toplevel"]) ?? root;
|
|
27634
|
+
const canonicalRepositoryRoot = canonicalPath(repositoryRoot);
|
|
27635
|
+
const gitCommonDir = readGitPath(canonicalRepositoryRoot, ["rev-parse", "--git-common-dir"]);
|
|
27636
|
+
const repositoryAnchor = canonicalPath(gitCommonDir ? resolveMaybeRelative(canonicalRepositoryRoot, gitCommonDir) : canonicalRepositoryRoot);
|
|
27637
|
+
const workspaceAnchor = canonicalRepositoryRoot;
|
|
27638
|
+
const storageRepositoryId = stableStorageId("repo", repositoryAnchor);
|
|
27639
|
+
const storageWorkspaceId = stableStorageId("ws", workspaceAnchor);
|
|
27640
|
+
const stateRoot = defaultArchContextStateRoot(env);
|
|
27641
|
+
const repositoryStateDir = join4(stateRoot.path, REPOSITORIES_DIR, storageRepositoryId);
|
|
27642
|
+
const workspaceStateDir = join4(repositoryStateDir, WORKTREES_DIR, storageWorkspaceId);
|
|
27643
|
+
const legacyControlDir = resolve11(canonicalRepositoryRoot, ".archcontext", ".local");
|
|
27644
|
+
return {
|
|
27645
|
+
schemaVersion: "archcontext.runtime-state-paths/v1",
|
|
27646
|
+
stateRoot: stateRoot.path,
|
|
27647
|
+
source: stateRoot.source,
|
|
27648
|
+
repositoryRoot: canonicalRepositoryRoot,
|
|
27649
|
+
repositoryAnchor,
|
|
27650
|
+
workspaceAnchor,
|
|
27651
|
+
storageRepositoryId,
|
|
27652
|
+
storageWorkspaceId,
|
|
27653
|
+
repositoryId: storageRepositoryId,
|
|
27654
|
+
workspaceId: storageWorkspaceId,
|
|
27655
|
+
repositoryStateDir,
|
|
27656
|
+
workspaceStateDir,
|
|
27657
|
+
sharedCacheDir: join4(repositoryStateDir, "shared", "cache"),
|
|
27658
|
+
localStorePath: env[ARCHCONTEXT_LOCAL_STORE_PATH_ENV] ?? join4(workspaceStateDir, "runtime.sqlite"),
|
|
27659
|
+
...daemonControlPaths(workspaceStateDir),
|
|
27660
|
+
developerReviewRunStateDir: join4(workspaceStateDir, "developer-review-runs"),
|
|
27661
|
+
legacyControlDir,
|
|
27662
|
+
legacyLocalStorePath: join4(legacyControlDir, "runtime.sqlite")
|
|
27663
|
+
};
|
|
27664
|
+
}
|
|
27665
|
+
var REPOSITORIES_DIR = "repositories";
|
|
27666
|
+
var WORKTREES_DIR = "worktrees";
|
|
27667
|
+
function daemonControlPaths(workspaceStateDir) {
|
|
27668
|
+
return {
|
|
27669
|
+
daemonConnectionPath: join4(workspaceStateDir, "archctxd.json"),
|
|
27670
|
+
daemonLockPath: join4(workspaceStateDir, "archctxd.lock"),
|
|
27671
|
+
daemonLogPath: join4(workspaceStateDir, "archctxd.log")
|
|
27672
|
+
};
|
|
27673
|
+
}
|
|
27674
|
+
function listWorkspaceStateDirs(stateRoot) {
|
|
27675
|
+
return listDirectoryNames(join4(stateRoot, REPOSITORIES_DIR)).flatMap((storageRepositoryId) => listDirectoryNames(join4(stateRoot, REPOSITORIES_DIR, storageRepositoryId, WORKTREES_DIR)).map((storageWorkspaceId) => ({
|
|
27676
|
+
storageRepositoryId,
|
|
27677
|
+
storageWorkspaceId,
|
|
27678
|
+
workspaceStateDir: join4(stateRoot, REPOSITORIES_DIR, storageRepositoryId, WORKTREES_DIR, storageWorkspaceId)
|
|
27679
|
+
})));
|
|
27680
|
+
}
|
|
27681
|
+
function listDirectoryNames(path) {
|
|
27682
|
+
try {
|
|
27683
|
+
return readdirSync5(path, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
|
|
27684
|
+
} catch (error) {
|
|
27685
|
+
if (error.code === "ENOENT")
|
|
27686
|
+
return [];
|
|
27687
|
+
throw error;
|
|
27688
|
+
}
|
|
27689
|
+
}
|
|
27690
|
+
function readGitPath(root, args) {
|
|
27691
|
+
try {
|
|
27692
|
+
const value = execFileSync3("git", args, {
|
|
27693
|
+
cwd: root,
|
|
27694
|
+
encoding: "utf8",
|
|
27695
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
27696
|
+
}).trim();
|
|
27697
|
+
return value.length > 0 ? value : undefined;
|
|
27698
|
+
} catch {
|
|
27699
|
+
return;
|
|
27700
|
+
}
|
|
27701
|
+
}
|
|
27702
|
+
function resolveMaybeRelative(base, path) {
|
|
27703
|
+
return isAbsolute5(path) ? resolve11(path) : resolve11(base, path);
|
|
27704
|
+
}
|
|
27705
|
+
function canonicalPath(path) {
|
|
27706
|
+
const resolved = resolve11(path);
|
|
27707
|
+
try {
|
|
27708
|
+
return realpathSync4.native(resolved);
|
|
27709
|
+
} catch {
|
|
27710
|
+
return resolved;
|
|
27711
|
+
}
|
|
27712
|
+
}
|
|
27713
|
+
function stableStorageId(prefix, value) {
|
|
27714
|
+
return `${prefix}.${createHash6("sha256").update(value).digest("hex").slice(0, 16)}`;
|
|
27715
|
+
}
|
|
27405
27716
|
// schemas/repo/architecture-node.schema.json
|
|
27406
27717
|
var architecture_node_schema_default = {
|
|
27407
27718
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -27522,12 +27833,6 @@ var architecture_node_schema_default = {
|
|
|
27522
27833
|
extensions: { type: "object", additionalProperties: true }
|
|
27523
27834
|
}
|
|
27524
27835
|
};
|
|
27525
|
-
|
|
27526
|
-
// packages/local-runtime/model-store-yaml/src/native-context.ts
|
|
27527
|
-
init_src();
|
|
27528
|
-
import { createHash as createHash6 } from "node:crypto";
|
|
27529
|
-
import { constants, closeSync as closeSync4, fstatSync as fstatSync2, lstatSync as lstatSync5, openSync as openSync4, readSync as readSync2, realpathSync as realpathSync4 } from "node:fs";
|
|
27530
|
-
import { join as join4, resolve as resolve11 } from "node:path";
|
|
27531
27836
|
// schemas/repo/architecture-relation.schema.json
|
|
27532
27837
|
var architecture_relation_schema_default = {
|
|
27533
27838
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -27555,6 +27860,185 @@ var architecture_relation_schema_default = {
|
|
|
27555
27860
|
extensions: { type: "object", additionalProperties: true }
|
|
27556
27861
|
}
|
|
27557
27862
|
};
|
|
27863
|
+
|
|
27864
|
+
// packages/local-runtime/model-store-yaml/src/architecture-history.ts
|
|
27865
|
+
var compare5 = nativeByteCompare;
|
|
27866
|
+
var modelRoot = ".archcontext/model";
|
|
27867
|
+
var failed = (code, path) => ({ nodes: null, edges: null, structure: null, error: { code, ...path ? { path } : {} } });
|
|
27868
|
+
var edgeKey = (e) => JSON.stringify([e.source, e.target]);
|
|
27869
|
+
function stateForRevision(root, rev, parsed) {
|
|
27870
|
+
try {
|
|
27871
|
+
let context;
|
|
27872
|
+
try {
|
|
27873
|
+
context = readGitBlobTree(root, `${rev}:.archcontext`, { sizes: false });
|
|
27874
|
+
} catch (error) {
|
|
27875
|
+
if (!(error instanceof NativeContextError) || error.reasonCode !== "native-context-git-read-failed")
|
|
27876
|
+
throw error;
|
|
27877
|
+
if (readGitBlobTree(root, rev, { sizes: false }).some((entry) => entry.path === ".archcontext" && entry.type === "tree"))
|
|
27878
|
+
throw error;
|
|
27879
|
+
return failed("history-model-missing");
|
|
27880
|
+
}
|
|
27881
|
+
const manifest = context.find((entry) => entry.path === "manifest.yaml");
|
|
27882
|
+
if (manifest && manifest.type !== "blob")
|
|
27883
|
+
return failed("history-model-layout-unsupported");
|
|
27884
|
+
const read = (entry) => {
|
|
27885
|
+
if (!parsed.has(entry.objectId)) {
|
|
27886
|
+
const body = readGitBlobs(root, [entry])[0];
|
|
27887
|
+
try {
|
|
27888
|
+
parsed.set(entry.objectId, { value: parseJsonOrStableYaml(decodeUtf8(body), entry.path) });
|
|
27889
|
+
} catch {
|
|
27890
|
+
parsed.set(entry.objectId, { invalid: true });
|
|
27891
|
+
}
|
|
27892
|
+
}
|
|
27893
|
+
return parsed.get(entry.objectId);
|
|
27894
|
+
};
|
|
27895
|
+
if (manifest) {
|
|
27896
|
+
const data = read(manifest);
|
|
27897
|
+
if (data.value?.schemaVersion !== "archcontext.manifest/v1" || data.value.model?.layout !== "split" || data.value.model.root !== modelRoot)
|
|
27898
|
+
return failed("history-model-layout-unsupported");
|
|
27899
|
+
}
|
|
27900
|
+
if (!context.some((entry) => entry.path === "model" && entry.type === "tree"))
|
|
27901
|
+
return failed("history-model-missing");
|
|
27902
|
+
const all = readGitBlobTree(root, `${rev}:${modelRoot}`, { sizes: false }).map((entry) => ({ ...entry, path: `${modelRoot}/${entry.path}` }));
|
|
27903
|
+
const nodesDir = all.find((entry) => entry.path === `${modelRoot}/nodes` && entry.type === "tree");
|
|
27904
|
+
if (!nodesDir)
|
|
27905
|
+
return failed("history-model-missing");
|
|
27906
|
+
const files = all.filter((entry) => entry.type === "blob" && (entry.path.startsWith(`${modelRoot}/nodes/`) || entry.path.startsWith(`${modelRoot}/relations/`)) && /\.ya?ml$/.test(entry.path)).sort((a, b) => compare5(a.path, b.path));
|
|
27907
|
+
const missing = [...new Map(files.filter((file) => !parsed.has(file.objectId)).map((file) => [file.objectId, file])).values()];
|
|
27908
|
+
const blobs = readGitBlobs(root, missing);
|
|
27909
|
+
missing.forEach((file, index) => {
|
|
27910
|
+
try {
|
|
27911
|
+
parsed.set(file.objectId, { value: parseJsonOrStableYaml(decodeUtf8(blobs[index]), file.path) });
|
|
27912
|
+
} catch {
|
|
27913
|
+
parsed.set(file.objectId, { invalid: true });
|
|
27914
|
+
}
|
|
27915
|
+
});
|
|
27916
|
+
const nodes = [], relations = [];
|
|
27917
|
+
const paths = new Map;
|
|
27918
|
+
for (const file of files) {
|
|
27919
|
+
const result = read(file);
|
|
27920
|
+
const isNode = file.path.startsWith(`${modelRoot}/nodes/`);
|
|
27921
|
+
if (result.invalid || result.value === undefined || !validateJsonSchema(isNode ? architecture_node_schema_default : architecture_relation_schema_default, result.value).valid)
|
|
27922
|
+
return failed("history-model-invalid", file.path);
|
|
27923
|
+
if (isNode) {
|
|
27924
|
+
const value = result.value;
|
|
27925
|
+
if (paths.has(value.id))
|
|
27926
|
+
return failed("history-model-invalid", file.path);
|
|
27927
|
+
paths.set(value.id, file.path);
|
|
27928
|
+
nodes.push(value);
|
|
27929
|
+
} else
|
|
27930
|
+
relations.push(result.value);
|
|
27931
|
+
}
|
|
27932
|
+
const byId = new Map(nodes.map((node) => [node.id, node]));
|
|
27933
|
+
for (const node of nodes) {
|
|
27934
|
+
const visited = new Set;
|
|
27935
|
+
let cursor = node;
|
|
27936
|
+
while (cursor) {
|
|
27937
|
+
if (visited.has(cursor.id))
|
|
27938
|
+
return failed("history-model-invalid", paths.get(node.id));
|
|
27939
|
+
visited.add(cursor.id);
|
|
27940
|
+
cursor = cursor.parent ? byId.get(cursor.parent) : undefined;
|
|
27941
|
+
}
|
|
27942
|
+
}
|
|
27943
|
+
const nearest = (id) => {
|
|
27944
|
+
let node = byId.get(id);
|
|
27945
|
+
while (node) {
|
|
27946
|
+
if (node.kind === "capability")
|
|
27947
|
+
return node.id;
|
|
27948
|
+
node = node.parent ? byId.get(node.parent) : undefined;
|
|
27949
|
+
}
|
|
27950
|
+
return;
|
|
27951
|
+
};
|
|
27952
|
+
const edges = new Map;
|
|
27953
|
+
for (const relation of relations) {
|
|
27954
|
+
const source = nearest(relation.source), target = nearest(relation.target);
|
|
27955
|
+
if (source && target && source !== target) {
|
|
27956
|
+
const edge = { source, target };
|
|
27957
|
+
edges.set(edgeKey(edge), edge);
|
|
27958
|
+
}
|
|
27959
|
+
}
|
|
27960
|
+
return {
|
|
27961
|
+
nodes: nodes.filter((node) => node.kind === "capability").map((node) => ({ id: node.id, name: node.name, domain: /^capability\.([a-z0-9]+(?:-[a-z0-9]+)*)\.([a-z0-9]+(?:-[a-z0-9]+)*)$/.exec(node.id)?.[1] ?? null })).sort((a, b) => compare5(a.id, b.id)),
|
|
27962
|
+
edges: [...edges.values()].sort((a, b) => compare5(a.source, b.source) || compare5(a.target, b.target)),
|
|
27963
|
+
structure: nodes.filter((node) => ["capability", "module", "component"].includes(node.kind)).map((node) => ({ id: node.id, kind: node.kind, name: node.name, capability: nearest(node.id) ?? null })).sort((a, b) => compare5(a.id, b.id))
|
|
27964
|
+
};
|
|
27965
|
+
} catch (error) {
|
|
27966
|
+
if (error instanceof NativeContextError && error.reasonCode === "native-context-limit-exceeded")
|
|
27967
|
+
return failed("history-model-too-large");
|
|
27968
|
+
throw error;
|
|
27969
|
+
}
|
|
27970
|
+
}
|
|
27971
|
+
function difference(before, after, baseRev) {
|
|
27972
|
+
const a = new Map(before.structure.map((node) => [node.id, node])), b = new Map(after.structure.map((node) => [node.id, node]));
|
|
27973
|
+
const ae = new Map(before.edges.map((edge) => [edgeKey(edge), edge])), be = new Map(after.edges.map((edge) => [edgeKey(edge), edge]));
|
|
27974
|
+
return {
|
|
27975
|
+
baseRev,
|
|
27976
|
+
added: after.structure.filter((node) => !a.has(node.id)).map(({ id, kind, capability }) => ({ id, kind, capability })),
|
|
27977
|
+
removed: before.structure.filter((node) => !b.has(node.id)).map(({ id, kind, capability }) => ({ id, kind, capability })),
|
|
27978
|
+
renamed: after.structure.flatMap((node) => {
|
|
27979
|
+
const old = a.get(node.id);
|
|
27980
|
+
return old && old.name !== node.name ? [{ id: node.id, kind: node.kind, capability: node.capability, from: old.name, to: node.name }] : [];
|
|
27981
|
+
}),
|
|
27982
|
+
edgesChanged: { added: after.edges.filter((edge) => !ae.has(edgeKey(edge))), removed: before.edges.filter((edge) => !be.has(edgeKey(edge))) }
|
|
27983
|
+
};
|
|
27984
|
+
}
|
|
27985
|
+
function readArchitectureHistory(cwd, options = {}) {
|
|
27986
|
+
const root = readNativeGitRoot(cwd);
|
|
27987
|
+
if (decodeUtf8(readOnlyGit(root, "rev-parse", ["--is-shallow-repository"])).trim() === "true")
|
|
27988
|
+
throw new FailureError("AC_PRECONDITION_FAILED", "history-shallow-repository");
|
|
27989
|
+
const head = resolveNativeGitSnapshot(root, options.ref ?? "HEAD").commitSha;
|
|
27990
|
+
const output = decodeUtf8(readOnlyGit(root, "log", ["--first-parent", "--reverse", "-z", "--format=%H%x00%cI%x00%s", head, "--", modelRoot, ".archcontext/manifest.yaml"]));
|
|
27991
|
+
const fields = output ? output.split("\x00") : [];
|
|
27992
|
+
if (fields.length && fields.pop() !== "")
|
|
27993
|
+
throw new NativeContextError("native-context-git-read-failed", { operation: "log", category: "malformed-record" });
|
|
27994
|
+
if (fields.length % 3 !== 0)
|
|
27995
|
+
throw new NativeContextError("native-context-git-read-failed", { operation: "log", category: "malformed-record" });
|
|
27996
|
+
for (let i = 0;i < fields.length; i += 3)
|
|
27997
|
+
if (!/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/.test(fields[i]))
|
|
27998
|
+
throw new NativeContextError("native-context-git-read-failed", { operation: "log", category: "malformed-record" });
|
|
27999
|
+
const parsed = new Map;
|
|
28000
|
+
const milestones = [];
|
|
28001
|
+
let previous = { nodes: [], edges: [], structure: [] };
|
|
28002
|
+
let havePrevious = false, priorError, previousMilestone = null;
|
|
28003
|
+
const cacheDir = join5(runtimeStatePaths(root, options.env).sharedCacheDir, "architecture-history", ARCHITECTURE_HISTORY_DERIVATION_VERSION);
|
|
28004
|
+
for (let i = 0;i < fields.length; i += 3) {
|
|
28005
|
+
const [rev, date, subject] = fields.slice(i, i + 3);
|
|
28006
|
+
const cache = join5(cacheDir, `${rev}.json`);
|
|
28007
|
+
let state;
|
|
28008
|
+
try {
|
|
28009
|
+
state = decodeArchitectureHistoryState(JSON.parse(readFileSync8(cache, "utf8")));
|
|
28010
|
+
} catch {}
|
|
28011
|
+
if (!state) {
|
|
28012
|
+
state = stateForRevision(root, rev, parsed);
|
|
28013
|
+
mkdirSync5(cacheDir, { recursive: true });
|
|
28014
|
+
const temporary = `${cache}.${randomUUID()}.tmp`;
|
|
28015
|
+
writeFileSync4(temporary, JSON.stringify(state));
|
|
28016
|
+
renameSync3(temporary, cache);
|
|
28017
|
+
}
|
|
28018
|
+
if (state.error) {
|
|
28019
|
+
if (priorError !== state.error.code)
|
|
28020
|
+
milestones.push({ rev, date, subject, nodes: null, edges: null, delta: null, error: state.error });
|
|
28021
|
+
priorError = state.error.code;
|
|
28022
|
+
continue;
|
|
28023
|
+
}
|
|
28024
|
+
const recovered = priorError !== undefined;
|
|
28025
|
+
priorError = undefined;
|
|
28026
|
+
const delta = difference(previous, state, previousMilestone);
|
|
28027
|
+
if (!havePrevious || recovered || delta.added.length || delta.removed.length || delta.renamed.length || delta.edgesChanged.added.length || delta.edgesChanged.removed.length) {
|
|
28028
|
+
milestones.push({ rev, date, subject, nodes: state.nodes, edges: state.edges, delta });
|
|
28029
|
+
previousMilestone = rev;
|
|
28030
|
+
previous = state;
|
|
28031
|
+
havePrevious = true;
|
|
28032
|
+
}
|
|
28033
|
+
}
|
|
28034
|
+
const offset = options.offset ?? 0, limit = options.limit ?? 200;
|
|
28035
|
+
return { schemaVersion: ARCHITECTURE_HISTORY_SCHEMA_VERSION, head, total: milestones.length, offset, limit, milestones: milestones.slice(offset, offset + limit) };
|
|
28036
|
+
}
|
|
28037
|
+
// packages/local-runtime/model-store-yaml/src/native-context.ts
|
|
28038
|
+
init_src();
|
|
28039
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
28040
|
+
import { constants, closeSync as closeSync4, fstatSync as fstatSync2, lstatSync as lstatSync5, openSync as openSync4, readSync as readSync2, realpathSync as realpathSync5 } from "node:fs";
|
|
28041
|
+
import { join as join6, resolve as resolve12 } from "node:path";
|
|
27558
28042
|
// schemas/repo/architecture-flow.schema.json
|
|
27559
28043
|
var architecture_flow_schema_default = {
|
|
27560
28044
|
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -27659,7 +28143,7 @@ var SCHEMAS = { node: architecture_node_schema_default, relation: architecture_r
|
|
|
27659
28143
|
var MANIFEST = ".archcontext/manifest.yaml";
|
|
27660
28144
|
var MODEL_KINDS = ["nodes", "relations", "flows"];
|
|
27661
28145
|
function contentDigest(bytes) {
|
|
27662
|
-
return `sha256:${
|
|
28146
|
+
return `sha256:${createHash7("sha256").update(bytes).digest("hex")}`;
|
|
27663
28147
|
}
|
|
27664
28148
|
function record6(value) {
|
|
27665
28149
|
return value !== null && typeof value === "object" && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype ? value : undefined;
|
|
@@ -27787,23 +28271,23 @@ function observePath(root, path, directory = false) {
|
|
|
27787
28271
|
const segments = path.split("/");
|
|
27788
28272
|
for (let index = -1;index < segments.length; index += 1) {
|
|
27789
28273
|
if (index >= 0)
|
|
27790
|
-
absolute =
|
|
28274
|
+
absolute = join6(absolute, segments[index]);
|
|
27791
28275
|
let stat;
|
|
27792
28276
|
try {
|
|
27793
28277
|
stat = lstatSync5(absolute, { bigint: true });
|
|
27794
28278
|
} catch (error) {
|
|
27795
28279
|
if (error.code === "ENOENT")
|
|
27796
|
-
return { exists: false, identity: identities.join("/") + "/missing", absolute:
|
|
28280
|
+
return { exists: false, identity: identities.join("/") + "/missing", absolute: resolve12(root, path) };
|
|
27797
28281
|
throw new NativeContextError("native-context-input-unreadable", { path, category: "stat" });
|
|
27798
28282
|
}
|
|
27799
28283
|
const needsDirectory = index < segments.length - 1 || directory;
|
|
27800
28284
|
if (stat.isSymbolicLink() || (needsDirectory ? !stat.isDirectory() : !stat.isFile()))
|
|
27801
28285
|
throw new NativeContextError("native-context-entry-kind-unsupported", { path, category: stat.isSymbolicLink() ? "link" : "non-regular" });
|
|
27802
|
-
if (index >= 0 &&
|
|
28286
|
+
if (index >= 0 && realpathSync5.native(absolute) !== absolute)
|
|
27803
28287
|
throw new NativeContextError("native-context-path-unsafe", { path, category: "filesystem-path-alias" });
|
|
27804
28288
|
if (needsDirectory && index >= 0) {
|
|
27805
28289
|
try {
|
|
27806
|
-
lstatSync5(
|
|
28290
|
+
lstatSync5(join6(absolute, ".git"));
|
|
27807
28291
|
throw new NativeContextError("native-context-entry-kind-unsupported", { path: segments.slice(0, index + 1).join("/"), category: "nested-repository" });
|
|
27808
28292
|
} catch (error) {
|
|
27809
28293
|
if (error instanceof NativeContextError)
|
|
@@ -28147,7 +28631,7 @@ function readNativeContext(start, selector, hooks) {
|
|
|
28147
28631
|
`, "utf8"));
|
|
28148
28632
|
return data;
|
|
28149
28633
|
}
|
|
28150
|
-
const worktreeRoot =
|
|
28634
|
+
const worktreeRoot = realpathSync5.native(root);
|
|
28151
28635
|
const head = resolveNativeGitSnapshot(worktreeRoot, "HEAD");
|
|
28152
28636
|
const snapshot = { source: "worktree", headSha: head.commitSha, headTreeOid: head.treeOid, validation: "stable-read" };
|
|
28153
28637
|
const first = new WorktreeSource(worktreeRoot, hooks, 1, head.treeOid);
|
|
@@ -28183,7 +28667,7 @@ init_src();
|
|
|
28183
28667
|
|
|
28184
28668
|
// packages/local-runtime/codegraph-adapter/src/ref-impact-facts.ts
|
|
28185
28669
|
init_src();
|
|
28186
|
-
import { createHash as
|
|
28670
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
28187
28671
|
import { createRequire as createRequire3 } from "node:module";
|
|
28188
28672
|
var nonDeclarations = new Set(["file", "import", "export", "parameter"]);
|
|
28189
28673
|
var requireFromAdapter2 = createRequire3(import.meta.url);
|
|
@@ -28217,7 +28701,7 @@ function bindSnapshotRefImpactFacts(root, model, ref, graph) {
|
|
|
28217
28701
|
for (let i = 0;i < files.length; i++) {
|
|
28218
28702
|
const file = files[i], body = blobs[i];
|
|
28219
28703
|
const content = decodeUtf8(body);
|
|
28220
|
-
if (
|
|
28704
|
+
if (createHash8("sha256").update(content).digest("hex") !== file.contentHash)
|
|
28221
28705
|
return;
|
|
28222
28706
|
lineCounts.set(file.path, content.split(`
|
|
28223
28707
|
`).length);
|
|
@@ -28696,10 +29180,10 @@ function initializeArchContextModel(root, productName = "ArchContext Project") {
|
|
|
28696
29180
|
});
|
|
28697
29181
|
files.push({ path: ".archcontext/projections/targets.json", body: `${JSON.stringify(createDefaultProjectionTargetManifest(), null, 2)}
|
|
28698
29182
|
` });
|
|
28699
|
-
|
|
29183
|
+
mkdirSync6(root, { recursive: true });
|
|
28700
29184
|
const existing = files.filter((file) => {
|
|
28701
29185
|
assertPathHasNoSymlinkSegments(root, file.path);
|
|
28702
|
-
return lstatIfExists(
|
|
29186
|
+
return lstatIfExists(resolve13(root, file.path)) !== undefined;
|
|
28703
29187
|
}).map((file) => file.path);
|
|
28704
29188
|
if (existing.length > 0)
|
|
28705
29189
|
throw new ArchContextInitRefusedError(existing);
|
|
@@ -28712,7 +29196,7 @@ function initializeArchContextModel(root, productName = "ArchContext Project") {
|
|
|
28712
29196
|
rebuildGeneratedProjection(root);
|
|
28713
29197
|
} catch (error) {
|
|
28714
29198
|
for (const path of created.reverse())
|
|
28715
|
-
rmSync5(
|
|
29199
|
+
rmSync5(resolve13(root, path), { force: true });
|
|
28716
29200
|
throw error;
|
|
28717
29201
|
}
|
|
28718
29202
|
}
|
|
@@ -28720,7 +29204,7 @@ function rebuildGeneratedProjection(root) {
|
|
|
28720
29204
|
for (const operation of planGeneratedProjection(root)) {
|
|
28721
29205
|
if (operation.operation === "delete_entity") {
|
|
28722
29206
|
assertPathHasNoSymlinkSegments(root, dirname5(operation.path));
|
|
28723
|
-
rmSync5(
|
|
29207
|
+
rmSync5(resolve13(root, operation.path), { force: true });
|
|
28724
29208
|
} else {
|
|
28725
29209
|
writeFileWithoutFollowingSymlinks({ root, path: operation.path, body: withTrailingNewline(operation.body), expectedHash: operation.expectedHash });
|
|
28726
29210
|
}
|
|
@@ -28728,12 +29212,12 @@ function rebuildGeneratedProjection(root) {
|
|
|
28728
29212
|
}
|
|
28729
29213
|
function planGeneratedProjection(root) {
|
|
28730
29214
|
const desiredBody = GENERATED_ARCHITECTURE_BODY;
|
|
28731
|
-
const desiredAbsolute =
|
|
29215
|
+
const desiredAbsolute = resolve13(root, GENERATED_ARCHITECTURE_PATH);
|
|
28732
29216
|
const operations = [];
|
|
28733
|
-
if (!existsSync7(desiredAbsolute) ||
|
|
29217
|
+
if (!existsSync7(desiredAbsolute) || readFileSync9(desiredAbsolute, "utf8") !== desiredBody) {
|
|
28734
29218
|
operations.push({
|
|
28735
29219
|
path: GENERATED_ARCHITECTURE_PATH,
|
|
28736
|
-
expectedHash: existsSync7(desiredAbsolute) ? digestJson({ body:
|
|
29220
|
+
expectedHash: existsSync7(desiredAbsolute) ? digestJson({ body: readFileSync9(desiredAbsolute, "utf8") }) : "missing",
|
|
28737
29221
|
body: desiredBody,
|
|
28738
29222
|
operation: "render_projection"
|
|
28739
29223
|
});
|
|
@@ -28741,7 +29225,7 @@ function planGeneratedProjection(root) {
|
|
|
28741
29225
|
for (const path of collectGeneratedProjectionFiles(root)) {
|
|
28742
29226
|
if (path === GENERATED_ARCHITECTURE_PATH)
|
|
28743
29227
|
continue;
|
|
28744
|
-
const body =
|
|
29228
|
+
const body = readFileSync9(resolve13(root, path), "utf8");
|
|
28745
29229
|
operations.push({
|
|
28746
29230
|
path,
|
|
28747
29231
|
expectedHash: digestJson({ body }),
|
|
@@ -28753,9 +29237,9 @@ function planGeneratedProjection(root) {
|
|
|
28753
29237
|
}
|
|
28754
29238
|
function collectGeneratedProjectionFiles(root) {
|
|
28755
29239
|
const generatedRoot = ".archcontext/generated";
|
|
28756
|
-
if (!existsSync7(
|
|
29240
|
+
if (!existsSync7(resolve13(root, generatedRoot)))
|
|
28757
29241
|
return [];
|
|
28758
|
-
const walk = (relativeDir) =>
|
|
29242
|
+
const walk = (relativeDir) => readdirSync6(resolve13(root, relativeDir), { withFileTypes: true }).flatMap((entry) => {
|
|
28759
29243
|
const child = `${relativeDir}/${entry.name}`;
|
|
28760
29244
|
if (entry.isDirectory())
|
|
28761
29245
|
return walk(child);
|
|
@@ -28766,7 +29250,7 @@ function collectGeneratedProjectionFiles(root) {
|
|
|
28766
29250
|
|
|
28767
29251
|
class YamlModelStore {
|
|
28768
29252
|
async loadManifest(workspace) {
|
|
28769
|
-
return
|
|
29253
|
+
return readFileSync9(resolve13(workspace.root, ".archcontext/manifest.yaml"), "utf8");
|
|
28770
29254
|
}
|
|
28771
29255
|
async loadModel(workspace) {
|
|
28772
29256
|
return listModelFiles(workspace.root);
|
|
@@ -28777,7 +29261,7 @@ class YamlModelStore {
|
|
|
28777
29261
|
const nodeSchemaErrors = [];
|
|
28778
29262
|
for (const required of [".archcontext/manifest.yaml", ".archcontext/product.yaml"]) {
|
|
28779
29263
|
try {
|
|
28780
|
-
|
|
29264
|
+
readFileSync9(resolve13(workspace.root, required), "utf8");
|
|
28781
29265
|
} catch {
|
|
28782
29266
|
const error = `missing ${required}`;
|
|
28783
29267
|
errors.push(error);
|
|
@@ -28874,7 +29358,7 @@ function listModelFiles(root) {
|
|
|
28874
29358
|
"docs/adr"
|
|
28875
29359
|
]);
|
|
28876
29360
|
return paths.map((path) => {
|
|
28877
|
-
const body =
|
|
29361
|
+
const body = readFileSync9(resolve13(root, path), "utf8");
|
|
28878
29362
|
return {
|
|
28879
29363
|
path,
|
|
28880
29364
|
body,
|
|
@@ -28886,7 +29370,7 @@ function listModelFiles(root) {
|
|
|
28886
29370
|
function collectArchContextFiles(root, entries) {
|
|
28887
29371
|
const files = [];
|
|
28888
29372
|
for (const entry of entries) {
|
|
28889
|
-
const absolute =
|
|
29373
|
+
const absolute = resolve13(root, entry);
|
|
28890
29374
|
if (!existsSync7(absolute))
|
|
28891
29375
|
continue;
|
|
28892
29376
|
const stat = readdirOrFile(absolute);
|
|
@@ -28900,8 +29384,8 @@ function collectArchContextFiles(root, entries) {
|
|
|
28900
29384
|
return [...new Set(files)].sort();
|
|
28901
29385
|
function walk(relativeDir) {
|
|
28902
29386
|
const out = [];
|
|
28903
|
-
const dir =
|
|
28904
|
-
for (const entry of
|
|
29387
|
+
const dir = resolve13(root, relativeDir);
|
|
29388
|
+
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
28905
29389
|
const child = `${relativeDir}/${entry.name}`;
|
|
28906
29390
|
if (entry.isDirectory())
|
|
28907
29391
|
out.push(...walk(child));
|
|
@@ -28918,7 +29402,7 @@ function isCollectableModelFile(path) {
|
|
|
28918
29402
|
}
|
|
28919
29403
|
function readdirOrFile(path) {
|
|
28920
29404
|
try {
|
|
28921
|
-
|
|
29405
|
+
readdirSync6(path);
|
|
28922
29406
|
return "directory";
|
|
28923
29407
|
} catch {
|
|
28924
29408
|
return "file";
|
|
@@ -32381,10 +32865,10 @@ function evaluateWorktreeDependencyConstraints(input) {
|
|
|
32381
32865
|
});
|
|
32382
32866
|
}
|
|
32383
32867
|
function reviewWorkspacePackages(root) {
|
|
32384
|
-
if (!existsSync8(
|
|
32868
|
+
if (!existsSync8(join7(root, "package.json")))
|
|
32385
32869
|
return { packages: [], resolved: true };
|
|
32386
32870
|
try {
|
|
32387
|
-
const manifest = JSON.parse(
|
|
32871
|
+
const manifest = JSON.parse(readFileSync10(join7(root, "package.json"), "utf8"));
|
|
32388
32872
|
const declared = Array.isArray(manifest.workspaces) ? manifest.workspaces : manifest.workspaces?.packages ?? [];
|
|
32389
32873
|
if (!Array.isArray(declared))
|
|
32390
32874
|
throw new Error("workspaces must be a list");
|
|
@@ -32397,10 +32881,10 @@ function reviewWorkspacePackages(root) {
|
|
|
32397
32881
|
const parent = /^([^*?[\]{}!]+)\/\*$/.exec(pattern)?.[1];
|
|
32398
32882
|
if (parent === undefined)
|
|
32399
32883
|
throw new Error(`unsupported workspace pattern: ${entry}`);
|
|
32400
|
-
return
|
|
32884
|
+
return readdirSync7(join7(root, parent), { withFileTypes: true }).filter((child) => child.isDirectory() && existsSync8(join7(root, parent, child.name, "package.json"))).map((child) => `${parent}/${child.name}`);
|
|
32401
32885
|
});
|
|
32402
32886
|
const packages = directories.flatMap((directory) => {
|
|
32403
|
-
const packageManifest = JSON.parse(
|
|
32887
|
+
const packageManifest = JSON.parse(readFileSync10(join7(root, ...directory.split("/"), "package.json"), "utf8"));
|
|
32404
32888
|
if (typeof packageManifest.name !== "string")
|
|
32405
32889
|
return [];
|
|
32406
32890
|
const exports = typeof packageManifest.exports === "string" ? { ".": packageManifest.exports } : Object.fromEntries(Object.entries(packageManifest.exports ?? {}).filter((entry) => typeof entry[1] === "string"));
|
|
@@ -32426,7 +32910,7 @@ function modelNodes(files) {
|
|
|
32426
32910
|
function readWorktreeFiles(root) {
|
|
32427
32911
|
let output;
|
|
32428
32912
|
try {
|
|
32429
|
-
output =
|
|
32913
|
+
output = execFileSync4("git", ["ls-files", "--cached", "--others", "--exclude-standard", "-z"], {
|
|
32430
32914
|
cwd: root,
|
|
32431
32915
|
encoding: "utf8",
|
|
32432
32916
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -32442,7 +32926,7 @@ function countFilesOutsideHead(root) {
|
|
|
32442
32926
|
return readWorktreeFiles(root).filter((path) => !head.has(path)).length;
|
|
32443
32927
|
}
|
|
32444
32928
|
function declaredWorkspacePackages(root) {
|
|
32445
|
-
return existsSync8(
|
|
32929
|
+
return existsSync8(join7(root, "package.json")) ? readWorkspacePackages(root) : [];
|
|
32446
32930
|
}
|
|
32447
32931
|
function assertRequestedStateIsCurrent(request, worktree) {
|
|
32448
32932
|
if (request.expectedHeadSha !== undefined && request.expectedHeadSha !== worktree.headSha) {
|
|
@@ -32454,13 +32938,13 @@ function assertRequestedStateIsCurrent(request, worktree) {
|
|
|
32454
32938
|
}
|
|
32455
32939
|
var REFACTOR_NAMESPACE_MANIFEST_PATH = ".archcontext/manifest.yaml";
|
|
32456
32940
|
function readRefactorNamespace(root) {
|
|
32457
|
-
const path =
|
|
32941
|
+
const path = join7(root, REFACTOR_NAMESPACE_MANIFEST_PATH);
|
|
32458
32942
|
if (!existsSync8(path)) {
|
|
32459
32943
|
throw new RefactorScanError("AC_MODEL_ADOPTION_REQUIRED", `${REFACTOR_NAMESPACE_MANIFEST_PATH} is missing; refactor recommendations are scoped by its product.id; run archctx init`, "product-id-missing");
|
|
32460
32944
|
}
|
|
32461
32945
|
let manifest;
|
|
32462
32946
|
try {
|
|
32463
|
-
manifest = parseJsonOrStableYaml(
|
|
32947
|
+
manifest = parseJsonOrStableYaml(readFileSync10(path, "utf8"), REFACTOR_NAMESPACE_MANIFEST_PATH);
|
|
32464
32948
|
} catch (error) {
|
|
32465
32949
|
throw new RefactorScanError("AC_SCHEMA_INVALID", `${REFACTOR_NAMESPACE_MANIFEST_PATH} is unreadable: ${error instanceof Error ? error.message : String(error)}`, "product-id-invalid");
|
|
32466
32950
|
}
|
|
@@ -32502,7 +32986,7 @@ function readCodeFacts(root, worktreeDigest, edgeLimit) {
|
|
|
32502
32986
|
}
|
|
32503
32987
|
function attestCodeGraphBinary(root) {
|
|
32504
32988
|
const invocation = codeGraphCliInvocation(CODEGRAPH_BINARY, root);
|
|
32505
|
-
const version =
|
|
32989
|
+
const version = execFileSync4(invocation.command, [...invocation.argsPrefix, "--version"], {
|
|
32506
32990
|
cwd: root,
|
|
32507
32991
|
encoding: "utf8",
|
|
32508
32992
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -32511,7 +32995,7 @@ function attestCodeGraphBinary(root) {
|
|
|
32511
32995
|
const binaryPath = invocation.argsPrefix[0] ?? invocation.command;
|
|
32512
32996
|
return {
|
|
32513
32997
|
version,
|
|
32514
|
-
binaryDigest: `sha256:${
|
|
32998
|
+
binaryDigest: `sha256:${createHash9("sha256").update(readFileSync10(binaryPath)).digest("hex")}`
|
|
32515
32999
|
};
|
|
32516
33000
|
}
|
|
32517
33001
|
|
|
@@ -32608,8 +33092,8 @@ function unavailable2(reasons) {
|
|
|
32608
33092
|
// packages/local-runtime/runtime-daemon/src/docs-anchors.ts
|
|
32609
33093
|
init_src();
|
|
32610
33094
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
32611
|
-
import { readFileSync as
|
|
32612
|
-
import { resolve as
|
|
33095
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
33096
|
+
import { resolve as resolve16 } from "node:path";
|
|
32613
33097
|
|
|
32614
33098
|
// packages/local-runtime/runtime-daemon/src/projection-service.ts
|
|
32615
33099
|
init_src();
|
|
@@ -33886,8 +34370,8 @@ class ChangeSetRecoveryUnresolvedError extends FailureError {
|
|
|
33886
34370
|
|
|
33887
34371
|
// packages/local-runtime/runtime-daemon/src/projection-freshness.ts
|
|
33888
34372
|
init_src();
|
|
33889
|
-
import { readFileSync as
|
|
33890
|
-
import { posix as posix3, resolve as
|
|
34373
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
34374
|
+
import { posix as posix3, resolve as resolve14 } from "node:path";
|
|
33891
34375
|
function evaluateProjectionFreshness(input) {
|
|
33892
34376
|
const { model, profile, manifest, sourceFootprints, scope } = input;
|
|
33893
34377
|
return scope.kind === "tree" ? evaluateArchitectureProjectionSnapshotFreshness({ model, profile, manifest, sourceFootprints, currentSourceTreeDigest: scope.currentSourceTreeDigest }) : evaluateArchitectureProjectionFreshness({ model, profile, manifest, sourceFootprints, nodeIds: scope.nodeIds });
|
|
@@ -33912,7 +34396,7 @@ function measureProjectionFreshness(root, options = {}) {
|
|
|
33912
34396
|
assertProjectionFreshnessChangedPaths(options.changedPaths);
|
|
33913
34397
|
const manifest = options.manifest ?? loadArchitectureProjectionManifestStamps(root);
|
|
33914
34398
|
if (manifest.status === "manifest-unreadable") {
|
|
33915
|
-
assertArchitectureDocsProjectionManifestAccepted(
|
|
34399
|
+
assertArchitectureDocsProjectionManifestAccepted(readFileSync11(resolve14(root, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH), "utf8"));
|
|
33916
34400
|
}
|
|
33917
34401
|
const model = loadNativeModelFromArchContext(root);
|
|
33918
34402
|
const profile = manifest.status === "present" ? loadArchitectureDocumentationProfile(root) : undefined;
|
|
@@ -34030,6 +34514,8 @@ function publicOperationFailure(error) {
|
|
|
34030
34514
|
failure = toEnvelope("public.operation", undefined, "public-operation").error;
|
|
34031
34515
|
} else if (error instanceof GitVisibleFilesUnavailableError)
|
|
34032
34516
|
failure = knownFailure(own2(error, "code"), own2(error, "reasonCode"));
|
|
34517
|
+
else if (error instanceof ProjectionManifestUpgradeRequiredError)
|
|
34518
|
+
failure = knownFailure("AC_PRECONDITION_FAILED", own2(error, "reasonCode"), own2(error, "details"));
|
|
34033
34519
|
else if (error instanceof ProjectionPreconditionError)
|
|
34034
34520
|
failure = knownFailure("AC_PRECONDITION_FAILED", own2(error, "reasonCode"));
|
|
34035
34521
|
else if (error instanceof ProjectionCodeFactsUnavailableError)
|
|
@@ -34056,15 +34542,15 @@ function publicOperationResult(requestId, result) {
|
|
|
34056
34542
|
}
|
|
34057
34543
|
|
|
34058
34544
|
// packages/local-runtime/runtime-daemon/src/projection-service.ts
|
|
34059
|
-
import { existsSync as existsSync9, readFileSync as
|
|
34060
|
-
import { resolve as
|
|
34545
|
+
import { existsSync as existsSync9, readFileSync as readFileSync12 } from "node:fs";
|
|
34546
|
+
import { resolve as resolve15 } from "node:path";
|
|
34061
34547
|
|
|
34062
34548
|
// packages/local-runtime/runtime-daemon/src/projection-inputs.ts
|
|
34063
|
-
import { execFileSync as
|
|
34549
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
34064
34550
|
init_src();
|
|
34065
34551
|
function readCurrentBranch(root) {
|
|
34066
34552
|
try {
|
|
34067
|
-
const branch =
|
|
34553
|
+
const branch = execFileSync5("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
|
|
34068
34554
|
cwd: root,
|
|
34069
34555
|
encoding: "utf8",
|
|
34070
34556
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -34380,7 +34866,7 @@ function architectureModelIgnoredEnvelope(requestId, root) {
|
|
|
34380
34866
|
});
|
|
34381
34867
|
}
|
|
34382
34868
|
function committedArchitectureDocsProfile(root) {
|
|
34383
|
-
return existsSync9(
|
|
34869
|
+
return existsSync9(resolve15(root, ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)) ? loadArchitectureDocumentationProfile(root) : "default";
|
|
34384
34870
|
}
|
|
34385
34871
|
function withProjectionMetadata(envelope, provenance, runtimeSnapshot, majorChange, refreshSignals, receiptDigest) {
|
|
34386
34872
|
if (!envelope.ok)
|
|
@@ -34794,8 +35280,8 @@ function runProjectionCheckCommandUnchecked(request, root) {
|
|
|
34794
35280
|
return publicFailureEnvelope("projection.run", "AC_SCHEMA_INVALID", "projection-check-mode-invalid");
|
|
34795
35281
|
}
|
|
34796
35282
|
const manifestPath = ".archcontext/manifest.yaml";
|
|
34797
|
-
if (existsSync9(
|
|
34798
|
-
const diagnostics = manifestDecisionDiagnostics([{ path: manifestPath, body:
|
|
35283
|
+
if (existsSync9(resolve15(root, manifestPath))) {
|
|
35284
|
+
const diagnostics = manifestDecisionDiagnostics([{ path: manifestPath, body: readFileSync12(resolve15(root, manifestPath), "utf8") }]);
|
|
34799
35285
|
if (diagnostics.length)
|
|
34800
35286
|
return publicFailureEnvelope("projection.run", "AC_SCHEMA_INVALID", "native-context-model-invalid", { path: manifestPath, invariant: diagnostics[0] });
|
|
34801
35287
|
}
|
|
@@ -35685,7 +36171,7 @@ function fileContentReader(root) {
|
|
|
35685
36171
|
return (path) => {
|
|
35686
36172
|
let content = cache.get(path);
|
|
35687
36173
|
if (content === undefined) {
|
|
35688
|
-
content =
|
|
36174
|
+
content = readFileSync13(resolve16(root, path), "utf8").replace(/\r\n/g, `
|
|
35689
36175
|
`);
|
|
35690
36176
|
cache.set(path, content);
|
|
35691
36177
|
}
|
|
@@ -35753,7 +36239,7 @@ function proseAnchorSymbols(reader, files, contents) {
|
|
|
35753
36239
|
|
|
35754
36240
|
// packages/local-runtime/runtime-daemon/src/architecture-debt.ts
|
|
35755
36241
|
import { existsSync as existsSync10 } from "node:fs";
|
|
35756
|
-
import { join as
|
|
36242
|
+
import { join as join8 } from "node:path";
|
|
35757
36243
|
function readArchitectureDebt(root, input = {}) {
|
|
35758
36244
|
try {
|
|
35759
36245
|
const { evidence } = readArchitectureDebtEvidence(root, input);
|
|
@@ -35779,7 +36265,7 @@ function readArchitectureDebtEvidence(root, input) {
|
|
|
35779
36265
|
const changedPaths = [...new Set(input.changedPaths ?? [])].sort();
|
|
35780
36266
|
if (changedPaths.some((path) => !isRepoRelativePosixPath(path)))
|
|
35781
36267
|
throw new ArchitectureDebtReadError("AC_SCHEMA_INVALID", "changedPaths must contain repository-relative POSIX paths", "changed-path-invalid");
|
|
35782
|
-
if (!existsSync10(
|
|
36268
|
+
if (!existsSync10(join8(root, ".archcontext/manifest.yaml")))
|
|
35783
36269
|
throw new ArchitectureDebtReadError("AC_MODEL_ADOPTION_REQUIRED", "Architecture debt requires an adopted architecture model", "model-missing");
|
|
35784
36270
|
const model = loadNativeModelFromArchContext(root);
|
|
35785
36271
|
const files = listGitVisibleFiles(root);
|
|
@@ -35922,7 +36408,7 @@ function runNativeContextCommand(args, cwd, reader = exportNativeContext) {
|
|
|
35922
36408
|
// packages/surfaces/cli/src/ref-impact.ts
|
|
35923
36409
|
init_src();
|
|
35924
36410
|
import { openSync as openSync5, closeSync as closeSync5, readSync as readSync3 } from "node:fs";
|
|
35925
|
-
import { resolve as
|
|
36411
|
+
import { resolve as resolve17 } from "node:path";
|
|
35926
36412
|
var invalid2 = (category) => {
|
|
35927
36413
|
throw new NativeContextError("native-context-arguments-invalid", { category });
|
|
35928
36414
|
};
|
|
@@ -35965,7 +36451,7 @@ function runRefImpactCommand(args, cwd, reader = readRefImpact) {
|
|
|
35965
36451
|
let text;
|
|
35966
36452
|
let fd;
|
|
35967
36453
|
try {
|
|
35968
|
-
fd = path === "-" ? 0 : openSync5(
|
|
36454
|
+
fd = path === "-" ? 0 : openSync5(resolve17(cwd, path), "r");
|
|
35969
36455
|
const bytes = Buffer.alloc(REF_IMPACT_LIMITS.diffBytes + 1);
|
|
35970
36456
|
let length = 0;
|
|
35971
36457
|
while (length < bytes.length) {
|
|
@@ -36001,6 +36487,31 @@ function runRefImpactCommand(args, cwd, reader = readRefImpact) {
|
|
|
36001
36487
|
}
|
|
36002
36488
|
}
|
|
36003
36489
|
|
|
36490
|
+
// packages/surfaces/cli/src/architecture-history.ts
|
|
36491
|
+
init_src();
|
|
36492
|
+
function runArchitectureHistoryCommand(args, cwd) {
|
|
36493
|
+
if (args.includes("--help") || args.includes("-h"))
|
|
36494
|
+
return okEnvelope("history", { usage: "archctx history [--ref <rev>] [--format json|mermaid] [--offset <n>] [--limit <n>] --json" });
|
|
36495
|
+
const values = new Map;
|
|
36496
|
+
for (let i = 0;i < args.length; i++) {
|
|
36497
|
+
const flag = args[i];
|
|
36498
|
+
if (flag === "--json")
|
|
36499
|
+
continue;
|
|
36500
|
+
if (!["--ref", "--format", "--offset", "--limit"].includes(flag) || values.has(flag) || args[i + 1] === undefined)
|
|
36501
|
+
return errorEnvelope("history", "AC_SCHEMA_INVALID", "Invalid history arguments", "cli-input-invalid");
|
|
36502
|
+
values.set(flag, args[++i]);
|
|
36503
|
+
}
|
|
36504
|
+
const format = values.get("--format") ?? "json", offsetText = values.get("--offset") ?? "0", limitText = values.get("--limit") ?? "200";
|
|
36505
|
+
if (!/^[0-9]+$/.test(offsetText) || !/^[0-9]+$/.test(limitText) || !Number.isSafeInteger(Number(offsetText)) || !Number.isSafeInteger(Number(limitText)) || Number(limitText) > 1000 || !["json", "mermaid"].includes(format))
|
|
36506
|
+
return errorEnvelope("history", "AC_SCHEMA_INVALID", "Invalid history arguments", "cli-input-invalid");
|
|
36507
|
+
try {
|
|
36508
|
+
const history = readArchitectureHistory(cwd, { ref: values.get("--ref"), offset: Number(offsetText), limit: Number(limitText) });
|
|
36509
|
+
return okEnvelope("history", format === "mermaid" ? projectHistoryMermaid(history) : history);
|
|
36510
|
+
} catch (error) {
|
|
36511
|
+
return toEnvelope("history", error, "cli");
|
|
36512
|
+
}
|
|
36513
|
+
}
|
|
36514
|
+
|
|
36004
36515
|
// packages/local-runtime/runtime-daemon/src/index.ts
|
|
36005
36516
|
init_src();
|
|
36006
36517
|
|
|
@@ -36037,7 +36548,7 @@ async function exportChangeSetReceipt(store, root, journalId) {
|
|
|
36037
36548
|
// packages/local-runtime/runtime-daemon/src/architecture-debt.ts
|
|
36038
36549
|
init_src();
|
|
36039
36550
|
import { existsSync as existsSync11 } from "node:fs";
|
|
36040
|
-
import { join as
|
|
36551
|
+
import { join as join9 } from "node:path";
|
|
36041
36552
|
function readArchitectureDebt2(root, input = {}) {
|
|
36042
36553
|
try {
|
|
36043
36554
|
const { evidence } = readArchitectureDebtEvidence2(root, input);
|
|
@@ -36051,7 +36562,7 @@ function readArchitectureDebt2(root, input = {}) {
|
|
|
36051
36562
|
}
|
|
36052
36563
|
function readCompleteTaskArchitectureDebt(root, practices) {
|
|
36053
36564
|
try {
|
|
36054
|
-
if (!existsSync11(
|
|
36565
|
+
if (!existsSync11(join9(root, ".archcontext/manifest.yaml"))) {
|
|
36055
36566
|
return checkedDebt2({
|
|
36056
36567
|
scope: { kind: "repository", changedPaths: [], capabilityIds: [] },
|
|
36057
36568
|
unavailable: Object.fromEntries(ARCHITECTURE_DEBT_CHECKS.map((check) => [check, ["model-not-adopted"]]))
|
|
@@ -36083,7 +36594,7 @@ function readArchitectureDebtEvidence2(root, input) {
|
|
|
36083
36594
|
const changedPaths = [...new Set(input.changedPaths ?? [])].sort();
|
|
36084
36595
|
if (changedPaths.some((path) => !isRepoRelativePosixPath(path)))
|
|
36085
36596
|
throw new ArchitectureDebtReadError2("AC_SCHEMA_INVALID", "changedPaths must contain repository-relative POSIX paths", "changed-path-invalid");
|
|
36086
|
-
if (!existsSync11(
|
|
36597
|
+
if (!existsSync11(join9(root, ".archcontext/manifest.yaml")))
|
|
36087
36598
|
throw new ArchitectureDebtReadError2("AC_MODEL_ADOPTION_REQUIRED", "Architecture debt requires an adopted architecture model", "model-missing");
|
|
36088
36599
|
const model = loadNativeModelFromArchContext(root);
|
|
36089
36600
|
const files = listGitVisibleFiles(root);
|
|
@@ -37716,8 +38227,8 @@ function validateRuntimeAgentProposalPlan(input) {
|
|
|
37716
38227
|
}
|
|
37717
38228
|
|
|
37718
38229
|
// packages/local-runtime/runtime-daemon/src/external-documentation.ts
|
|
37719
|
-
import { existsSync as existsSync14, readdirSync as
|
|
37720
|
-
import { resolve as
|
|
38230
|
+
import { existsSync as existsSync14, readdirSync as readdirSync10, readFileSync as readFileSync16, statSync as statSync4 } from "node:fs";
|
|
38231
|
+
import { resolve as resolve20 } from "node:path";
|
|
37721
38232
|
|
|
37722
38233
|
// packages/core/context-compiler/src/index.ts
|
|
37723
38234
|
init_src();
|
|
@@ -37725,11 +38236,11 @@ init_src();
|
|
|
37725
38236
|
// packages/core/practice-catalog/src/index.ts
|
|
37726
38237
|
init_src();
|
|
37727
38238
|
init_src();
|
|
37728
|
-
import { existsSync as existsSync12, lstatSync as lstatSync7, readdirSync as
|
|
37729
|
-
import { dirname as dirname6, relative as relative5, resolve as
|
|
38239
|
+
import { existsSync as existsSync12, lstatSync as lstatSync7, readdirSync as readdirSync8, readFileSync as readFileSync14, realpathSync as realpathSync6 } from "node:fs";
|
|
38240
|
+
import { dirname as dirname6, relative as relative5, resolve as resolve18, sep as sep3 } from "node:path";
|
|
37730
38241
|
import { fileURLToPath } from "node:url";
|
|
37731
38242
|
var PRACTICE_CATALOG_VERSION = "2026.06.0";
|
|
37732
|
-
var BUILTIN_PRACTICE_ASSETS_DIR =
|
|
38243
|
+
var BUILTIN_PRACTICE_ASSETS_DIR = resolve18(dirname6(fileURLToPath(import.meta.url)), "../assets");
|
|
37733
38244
|
var ALLOWED_CHECK_IDS = new Set([
|
|
37734
38245
|
"compatibility-contract-required",
|
|
37735
38246
|
"no-new-cycle",
|
|
@@ -37781,13 +38292,13 @@ var PRACTICE_ROOT_KEYS = new Set([
|
|
|
37781
38292
|
"overlay"
|
|
37782
38293
|
]);
|
|
37783
38294
|
function loadPracticeCatalog(options = {}) {
|
|
37784
|
-
const root = options.root ?
|
|
38295
|
+
const root = options.root ? resolve18(options.root) : process.cwd();
|
|
37785
38296
|
const builtInAssetsDir = options.builtInAssetsDir ?? BUILTIN_PRACTICE_ASSETS_DIR;
|
|
37786
38297
|
const errors = [];
|
|
37787
38298
|
const warnings = [];
|
|
37788
|
-
const builtIn = loadAssetFiles(
|
|
37789
|
-
const profiles = loadProfileFiles(
|
|
37790
|
-
const sources = loadSourceFiles(
|
|
38299
|
+
const builtIn = loadAssetFiles(resolve18(builtInAssetsDir, "practices"), "curated-static", errors);
|
|
38300
|
+
const profiles = loadProfileFiles(resolve18(builtInAssetsDir, "profiles"), errors);
|
|
38301
|
+
const sources = loadSourceFiles(resolve18(builtInAssetsDir, "sources"), errors);
|
|
37791
38302
|
const overlays = options.includeRepoOverlay === false ? [] : loadRepoOverlayAssets(root, errors);
|
|
37792
38303
|
const merged = mergeCatalogAssets(builtIn, overlays, errors, options.now ?? new Date().toISOString());
|
|
37793
38304
|
const sourceIds = new Set(sources.map((source) => source.id));
|
|
@@ -37973,7 +38484,7 @@ function loadProfileFiles(dir, errors) {
|
|
|
37973
38484
|
return profiles.sort((a, b) => a.id.localeCompare(b.id));
|
|
37974
38485
|
}
|
|
37975
38486
|
function loadRepoOverlayAssets(root, errors) {
|
|
37976
|
-
const overlayRoot =
|
|
38487
|
+
const overlayRoot = resolve18(root, ".archcontext/practices");
|
|
37977
38488
|
if (!existsSync12(overlayRoot))
|
|
37978
38489
|
return [];
|
|
37979
38490
|
const out = [];
|
|
@@ -38336,8 +38847,8 @@ function listDataFiles(dir, allowedRoot, errors) {
|
|
|
38336
38847
|
return;
|
|
38337
38848
|
}
|
|
38338
38849
|
if (stat.isDirectory()) {
|
|
38339
|
-
for (const entry of
|
|
38340
|
-
walk(
|
|
38850
|
+
for (const entry of readdirSync8(current, { withFileTypes: true }))
|
|
38851
|
+
walk(resolve18(current, entry.name));
|
|
38341
38852
|
return;
|
|
38342
38853
|
}
|
|
38343
38854
|
if (!/\.(ya?ml|json)$/.test(current))
|
|
@@ -38352,7 +38863,7 @@ function listDataFiles(dir, allowedRoot, errors) {
|
|
|
38352
38863
|
}
|
|
38353
38864
|
function parseDataFile(path, errors) {
|
|
38354
38865
|
try {
|
|
38355
|
-
const body =
|
|
38866
|
+
const body = readFileSync14(path, "utf8").replace(/^\uFEFF/, "").trim();
|
|
38356
38867
|
const withoutDocumentMarker = body.startsWith("---") ? body.replace(/^---\s*/, "").trim() : body;
|
|
38357
38868
|
return JSON.parse(withoutDocumentMarker);
|
|
38358
38869
|
} catch (error) {
|
|
@@ -38379,14 +38890,14 @@ function assertRealChild(root, path) {
|
|
|
38379
38890
|
}
|
|
38380
38891
|
function safeRealpath(path) {
|
|
38381
38892
|
try {
|
|
38382
|
-
return
|
|
38893
|
+
return realpathSync6.native(path);
|
|
38383
38894
|
} catch {
|
|
38384
|
-
return
|
|
38895
|
+
return resolve18(path);
|
|
38385
38896
|
}
|
|
38386
38897
|
}
|
|
38387
38898
|
function isRealChild(rootReal, pathReal) {
|
|
38388
38899
|
const rel = relative5(rootReal, pathReal);
|
|
38389
|
-
return rel === "" || !rel.startsWith("..") && !rel.includes(`..${sep3}`) && !
|
|
38900
|
+
return rel === "" || !rel.startsWith("..") && !rel.includes(`..${sep3}`) && !resolve18(rel).startsWith("..");
|
|
38390
38901
|
}
|
|
38391
38902
|
function displayPath(path) {
|
|
38392
38903
|
return path.split(sep3).join("/");
|
|
@@ -38950,8 +39461,8 @@ function checkResult(input, result) {
|
|
|
38950
39461
|
}
|
|
38951
39462
|
// packages/core/practice-engine/src/enforcement.ts
|
|
38952
39463
|
init_src();
|
|
38953
|
-
import { existsSync as existsSync13, lstatSync as lstatSync8, readdirSync as
|
|
38954
|
-
import { basename as basename4, join as
|
|
39464
|
+
import { existsSync as existsSync13, lstatSync as lstatSync8, readdirSync as readdirSync9, readFileSync as readFileSync15 } from "node:fs";
|
|
39465
|
+
import { basename as basename4, join as join10, relative as relative6, resolve as resolve19, sep as sep4 } from "node:path";
|
|
38955
39466
|
var ENFORCEMENT_RANK = { advisory: 0, checkpoint: 1, complete: 2 };
|
|
38956
39467
|
var POLICY_MODES = new Set(["advisory", "active", "fail-open", "fail-closed"]);
|
|
38957
39468
|
var DEFAULT_POLICY = {
|
|
@@ -38974,7 +39485,7 @@ function shouldEvaluatePracticeEnforcement(policy) {
|
|
|
38974
39485
|
return practiceEnforcementPolicyMode(policy) !== "advisory";
|
|
38975
39486
|
}
|
|
38976
39487
|
function loadPracticeEnforcementPolicy(root) {
|
|
38977
|
-
const path =
|
|
39488
|
+
const path = resolve19(root, ".archcontext/policies/practices.yaml");
|
|
38978
39489
|
if (!existsSync13(path))
|
|
38979
39490
|
return defaultPracticeEnforcementPolicy();
|
|
38980
39491
|
assertRepoPolicyFile(root, path, ".archcontext/policies/practices.yaml");
|
|
@@ -38982,7 +39493,7 @@ function loadPracticeEnforcementPolicy(root) {
|
|
|
38982
39493
|
return validatePracticeEnforcementPolicy(parsed, ".archcontext/policies/practices.yaml");
|
|
38983
39494
|
}
|
|
38984
39495
|
function loadPracticeWaivers(root) {
|
|
38985
|
-
const dir =
|
|
39496
|
+
const dir = resolve19(root, ".archcontext/waivers");
|
|
38986
39497
|
if (!existsSync13(dir))
|
|
38987
39498
|
return [];
|
|
38988
39499
|
const stat = lstatSync8(dir);
|
|
@@ -38992,10 +39503,10 @@ function loadPracticeWaivers(root) {
|
|
|
38992
39503
|
throw new Error("practice-waiver-path-not-directory");
|
|
38993
39504
|
const waivers = [];
|
|
38994
39505
|
const ownerRegistry = loadPracticeWaiverOwnerRegistry(root);
|
|
38995
|
-
for (const entry of
|
|
39506
|
+
for (const entry of readdirSync9(dir, { withFileTypes: true })) {
|
|
38996
39507
|
if (!entry.isFile() || !/\.(?:ya?ml|json)$/.test(entry.name))
|
|
38997
39508
|
continue;
|
|
38998
|
-
const path =
|
|
39509
|
+
const path = join10(dir, entry.name);
|
|
38999
39510
|
const relativePath = `.archcontext/waivers/${entry.name}`;
|
|
39000
39511
|
assertRepoPolicyFile(root, path, relativePath);
|
|
39001
39512
|
waivers.push(validatePracticeWaiver(parseJsonYamlFile(path), relativePath, { allowedOwners: ownerRegistry.owners }));
|
|
@@ -39003,17 +39514,17 @@ function loadPracticeWaivers(root) {
|
|
|
39003
39514
|
return waivers.sort((left, right) => waiverDigest(left).localeCompare(waiverDigest(right)));
|
|
39004
39515
|
}
|
|
39005
39516
|
function loadPracticeWaiverOwnerRegistry(root) {
|
|
39006
|
-
const modelDir =
|
|
39517
|
+
const modelDir = resolve19(root, ".archcontext/model/nodes");
|
|
39007
39518
|
const sources = [];
|
|
39008
39519
|
const subjects = [];
|
|
39009
39520
|
if (existsSync13(modelDir)) {
|
|
39010
39521
|
if (lstatSync8(modelDir).isSymbolicLink())
|
|
39011
39522
|
throw new Error("practice-owner-registry-symlink-denied");
|
|
39012
39523
|
for (const path of collectFiles(root, ".archcontext/model/nodes")) {
|
|
39013
|
-
const absolute =
|
|
39524
|
+
const absolute = resolve19(root, path);
|
|
39014
39525
|
if (lstatSync8(absolute).isSymbolicLink())
|
|
39015
39526
|
throw new Error(`practice-owner-registry-symlink-denied: ${path}`);
|
|
39016
|
-
const body =
|
|
39527
|
+
const body = readFileSync15(absolute, "utf8");
|
|
39017
39528
|
const lifecycleOwners = extractOwnershipOwners(body, "lifecycle");
|
|
39018
39529
|
const dataOwners = extractOwnershipOwners(body, "data");
|
|
39019
39530
|
for (const kind of ["lifecycle", "data"]) {
|
|
@@ -39288,14 +39799,14 @@ function isVagueReason(reason) {
|
|
|
39288
39799
|
return /^(temporary|cleanup later|todo|tbd|later|just in case)$/i.test(trimmed);
|
|
39289
39800
|
}
|
|
39290
39801
|
function parseJsonYamlFile(path) {
|
|
39291
|
-
const body =
|
|
39802
|
+
const body = readFileSync15(path, "utf8").replace(/^\uFEFF/, "").trim();
|
|
39292
39803
|
const withoutDocumentMarker = body.startsWith("---") ? body.replace(/^---\s*/, "").trim() : body;
|
|
39293
39804
|
return JSON.parse(withoutDocumentMarker);
|
|
39294
39805
|
}
|
|
39295
39806
|
function collectFiles(root, relativeDir) {
|
|
39296
|
-
const dir =
|
|
39807
|
+
const dir = resolve19(root, relativeDir);
|
|
39297
39808
|
const out = [];
|
|
39298
|
-
for (const entry of
|
|
39809
|
+
for (const entry of readdirSync9(dir, { withFileTypes: true })) {
|
|
39299
39810
|
const child = `${relativeDir}/${entry.name}`;
|
|
39300
39811
|
if (entry.isDirectory())
|
|
39301
39812
|
out.push(...collectFiles(root, child));
|
|
@@ -39381,8 +39892,8 @@ function assertRepoPolicyFile(root, path, relativePath) {
|
|
|
39381
39892
|
assertRepoRelativePath(relativePath);
|
|
39382
39893
|
if (lstatSync8(path).isSymbolicLink())
|
|
39383
39894
|
throw new Error(`practice-policy-symlink-denied: ${relativePath}`);
|
|
39384
|
-
const rootResolved =
|
|
39385
|
-
const pathResolved =
|
|
39895
|
+
const rootResolved = resolve19(root);
|
|
39896
|
+
const pathResolved = resolve19(path);
|
|
39386
39897
|
const rel = relative6(rootResolved, pathResolved);
|
|
39387
39898
|
if (rel === "" || rel.startsWith("..") || rel.includes(`..${sep4}`))
|
|
39388
39899
|
throw new Error(`practice-policy-path-escape: ${relativePath}`);
|
|
@@ -40742,7 +41253,7 @@ function readExactPackageVersion(root, packageName) {
|
|
|
40742
41253
|
return;
|
|
40743
41254
|
}
|
|
40744
41255
|
function readPackageLockExactVersion(root, packageName) {
|
|
40745
|
-
const lock = readJsonFile(
|
|
41256
|
+
const lock = readJsonFile(resolve20(root, "package-lock.json"));
|
|
40746
41257
|
if (!lock || typeof lock !== "object" || Array.isArray(lock))
|
|
40747
41258
|
return;
|
|
40748
41259
|
const packages = lock.packages;
|
|
@@ -40760,7 +41271,7 @@ function readPackageLockExactVersion(root, packageName) {
|
|
|
40760
41271
|
return;
|
|
40761
41272
|
}
|
|
40762
41273
|
function packageManifestPaths(root) {
|
|
40763
|
-
const paths = [
|
|
41274
|
+
const paths = [resolve20(root, "package.json")];
|
|
40764
41275
|
const rootManifest = readJsonFile(paths[0]);
|
|
40765
41276
|
for (const pattern of workspacePatternsFromManifest(rootManifest)) {
|
|
40766
41277
|
for (const path of expandWorkspacePackageJson(root, pattern))
|
|
@@ -40783,15 +41294,15 @@ function expandWorkspacePackageJson(root, pattern) {
|
|
|
40783
41294
|
if (pattern.includes("**") || pattern.startsWith("/") || pattern.includes("\\"))
|
|
40784
41295
|
return [];
|
|
40785
41296
|
if (!pattern.includes("*")) {
|
|
40786
|
-
const path =
|
|
41297
|
+
const path = resolve20(root, pattern, "package.json");
|
|
40787
41298
|
return existsSync14(path) ? [path] : [];
|
|
40788
41299
|
}
|
|
40789
41300
|
if (!pattern.endsWith("/*"))
|
|
40790
41301
|
return [];
|
|
40791
|
-
const base =
|
|
41302
|
+
const base = resolve20(root, pattern.slice(0, -2));
|
|
40792
41303
|
if (!existsSync14(base) || !statSync4(base).isDirectory())
|
|
40793
41304
|
return [];
|
|
40794
|
-
return
|
|
41305
|
+
return readdirSync10(base, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => resolve20(base, entry.name, "package.json")).filter((path) => existsSync14(path));
|
|
40795
41306
|
}
|
|
40796
41307
|
function exactVersionFromManifest(manifest, packageName) {
|
|
40797
41308
|
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest))
|
|
@@ -40810,7 +41321,7 @@ function readJsonFile(path) {
|
|
|
40810
41321
|
if (!existsSync14(path))
|
|
40811
41322
|
return;
|
|
40812
41323
|
try {
|
|
40813
|
-
return JSON.parse(
|
|
41324
|
+
return JSON.parse(readFileSync16(path, "utf8"));
|
|
40814
41325
|
} catch {
|
|
40815
41326
|
return;
|
|
40816
41327
|
}
|
|
@@ -40833,7 +41344,7 @@ function readContext7LockfileState(root) {
|
|
|
40833
41344
|
expectedHash: "missing"
|
|
40834
41345
|
};
|
|
40835
41346
|
}
|
|
40836
|
-
const body =
|
|
41347
|
+
const body = readFileSync16(path, "utf8");
|
|
40837
41348
|
const parsed = JSON.parse(body);
|
|
40838
41349
|
if (parsed.schemaVersion !== CONTEXT7_LOCKFILE_SCHEMA_VERSION || parsed.provider !== "context7" || !Array.isArray(parsed.libraries)) {
|
|
40839
41350
|
throw new Error("Invalid Context7 lockfile");
|
|
@@ -40869,7 +41380,7 @@ function writeContext7Lockfile(root, lock, expectedHash) {
|
|
|
40869
41380
|
|
|
40870
41381
|
// packages/core/application/src/index.ts
|
|
40871
41382
|
import { existsSync as existsSync15, statSync as statSync5 } from "node:fs";
|
|
40872
|
-
import { extname, resolve as
|
|
41383
|
+
import { extname, resolve as resolve21 } from "node:path";
|
|
40873
41384
|
init_src();
|
|
40874
41385
|
async function prepareTask(input) {
|
|
40875
41386
|
const confidence = computeRefactorConfidence({
|
|
@@ -41062,7 +41573,7 @@ function classifyCheckpointPath(root, path) {
|
|
|
41062
41573
|
return "ignored";
|
|
41063
41574
|
if (isGeneratedCheckpointPath(path))
|
|
41064
41575
|
return "generated";
|
|
41065
|
-
const absolute =
|
|
41576
|
+
const absolute = resolve21(root, path);
|
|
41066
41577
|
if (!existsSync15(absolute))
|
|
41067
41578
|
return "deleted";
|
|
41068
41579
|
try {
|
|
@@ -41360,14 +41871,14 @@ function parsePracticeCheckpointBaselineState(state, repositoryId, taskSessionId
|
|
|
41360
41871
|
init_src();
|
|
41361
41872
|
init_src();
|
|
41362
41873
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
41363
|
-
import { chmodSync as chmodSync3, existsSync as existsSync18, lstatSync as lstatSync9, mkdirSync as
|
|
41874
|
+
import { chmodSync as chmodSync3, existsSync as existsSync18, lstatSync as lstatSync9, mkdirSync as mkdirSync7, mkdtempSync as mkdtempSync3, readdirSync as readdirSync11, readFileSync as readFileSync18, rmSync as rmSync8, writeFileSync as writeFileSync6 } from "node:fs";
|
|
41364
41875
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
41365
|
-
import { basename as basename5, dirname as dirname7, join as
|
|
41876
|
+
import { basename as basename5, dirname as dirname7, join as join13, resolve as resolve22, sep as sep5 } from "node:path";
|
|
41366
41877
|
|
|
41367
41878
|
// packages/local-runtime/control-file-security/src/index.ts
|
|
41368
|
-
import { execFileSync as
|
|
41369
|
-
import { closeSync as closeSync6, constants as constants2, existsSync as existsSync16, fstatSync as fstatSync3, openSync as openSync6, readFileSync as
|
|
41370
|
-
import { join as
|
|
41879
|
+
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
41880
|
+
import { closeSync as closeSync6, constants as constants2, existsSync as existsSync16, fstatSync as fstatSync3, openSync as openSync6, readFileSync as readFileSync17, rmSync as rmSync6, writeFileSync as writeFileSync5 } from "node:fs";
|
|
41881
|
+
import { join as join12 } from "node:path";
|
|
41371
41882
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
41372
41883
|
var WINDOWS_CREATE_TIMEOUT_MS = 60000;
|
|
41373
41884
|
var WINDOWS_READ_TIMEOUT_MS = 1e4;
|
|
@@ -41451,7 +41962,7 @@ function windowsControlFile(operation, path, body) {
|
|
|
41451
41962
|
let output;
|
|
41452
41963
|
const startedAt = performance.now();
|
|
41453
41964
|
try {
|
|
41454
|
-
output =
|
|
41965
|
+
output = execFileSync6(join12(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"), [
|
|
41455
41966
|
"-NoLogo",
|
|
41456
41967
|
"-NoProfile",
|
|
41457
41968
|
"-NonInteractive",
|
|
@@ -41506,7 +42017,7 @@ function createPrivateControlFile(path, body) {
|
|
|
41506
42017
|
}
|
|
41507
42018
|
const fd = openSync6(path, "wx", 384);
|
|
41508
42019
|
try {
|
|
41509
|
-
|
|
42020
|
+
writeFileSync5(fd, body, "utf8");
|
|
41510
42021
|
} catch (error) {
|
|
41511
42022
|
rmSync6(path, { force: true });
|
|
41512
42023
|
throw error;
|
|
@@ -41526,7 +42037,7 @@ function readPrivateControlFile(path) {
|
|
|
41526
42037
|
const stat = fstatSync3(fd);
|
|
41527
42038
|
if (!stat.isFile() || (stat.mode & 63) !== 0)
|
|
41528
42039
|
return;
|
|
41529
|
-
return
|
|
42040
|
+
return readFileSync17(fd, "utf8");
|
|
41530
42041
|
} finally {
|
|
41531
42042
|
closeSync6(fd);
|
|
41532
42043
|
}
|
|
@@ -41603,7 +42114,7 @@ function rpcRequiredBoolean(params, index, context, label) {
|
|
|
41603
42114
|
function rpcOptionalString(params, index, context, label) {
|
|
41604
42115
|
const value = params[index];
|
|
41605
42116
|
if (value === undefined || value === null)
|
|
41606
|
-
return
|
|
42117
|
+
return;
|
|
41607
42118
|
if (typeof value !== "string")
|
|
41608
42119
|
throw rpcInputInvalid(context, `${label} must be a string`);
|
|
41609
42120
|
return value;
|
|
@@ -41611,7 +42122,7 @@ function rpcOptionalString(params, index, context, label) {
|
|
|
41611
42122
|
function rpcOptionalNumber(params, index, context, label) {
|
|
41612
42123
|
const value = params[index];
|
|
41613
42124
|
if (value === undefined || value === null)
|
|
41614
|
-
return
|
|
42125
|
+
return;
|
|
41615
42126
|
if (typeof value !== "number" || !Number.isFinite(value))
|
|
41616
42127
|
throw rpcInputInvalid(context, `${label} must be a number`);
|
|
41617
42128
|
return value;
|
|
@@ -41619,7 +42130,7 @@ function rpcOptionalNumber(params, index, context, label) {
|
|
|
41619
42130
|
function rpcOptionalStringArray(params, index, context, label) {
|
|
41620
42131
|
const value = params[index];
|
|
41621
42132
|
if (value === undefined || value === null)
|
|
41622
|
-
return
|
|
42133
|
+
return;
|
|
41623
42134
|
if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string"))
|
|
41624
42135
|
throw rpcInputInvalid(context, `${label} must be an array of strings`);
|
|
41625
42136
|
return value;
|
|
@@ -41636,7 +42147,7 @@ function rpcRequiredObject(params, index, context, label) {
|
|
|
41636
42147
|
function rpcOptionalObject(params, index, context, label) {
|
|
41637
42148
|
const value = params[index];
|
|
41638
42149
|
if (value === undefined || value === null)
|
|
41639
|
-
return
|
|
42150
|
+
return;
|
|
41640
42151
|
if (!isPlainRpcObject(value))
|
|
41641
42152
|
throw rpcInputInvalid(context, `${label} must be an object`);
|
|
41642
42153
|
return value;
|
|
@@ -42063,111 +42574,6 @@ function daemonReadiness(root) {
|
|
|
42063
42574
|
|
|
42064
42575
|
// packages/local-runtime/runtime-daemon/src/daemon-control.ts
|
|
42065
42576
|
import { existsSync as existsSync17, openSync as openSync7, rmSync as rmSync7 } from "node:fs";
|
|
42066
|
-
|
|
42067
|
-
// packages/local-runtime/runtime-state-paths/src/index.ts
|
|
42068
|
-
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
42069
|
-
import { createHash as createHash9 } from "node:crypto";
|
|
42070
|
-
import { readdirSync as readdirSync10, realpathSync as realpathSync6 } from "node:fs";
|
|
42071
|
-
import { homedir } from "node:os";
|
|
42072
|
-
import { isAbsolute as isAbsolute5, join as join11, resolve as resolve21 } from "node:path";
|
|
42073
|
-
var ARCHCONTEXT_STATE_DIR_ENV = "ARCHCONTEXT_STATE_DIR";
|
|
42074
|
-
var ARCHCONTEXT_LOCAL_STORE_PATH_ENV = "ARCHCONTEXT_LOCAL_STORE_PATH";
|
|
42075
|
-
function defaultArchContextStateRoot(env = process.env, platform = process.platform, home = homedir()) {
|
|
42076
|
-
const override = env[ARCHCONTEXT_STATE_DIR_ENV];
|
|
42077
|
-
if (override)
|
|
42078
|
-
return { path: resolve21(override), source: "environment" };
|
|
42079
|
-
if (platform === "darwin")
|
|
42080
|
-
return { path: join11(home, "Library", "Application Support", "ArchContext"), source: "os-user-data" };
|
|
42081
|
-
if (platform === "win32")
|
|
42082
|
-
return { path: join11(env.LOCALAPPDATA ?? join11(home, "AppData", "Local"), "ArchContext"), source: "os-user-data" };
|
|
42083
|
-
return { path: join11(env.XDG_DATA_HOME ?? join11(home, ".local", "share"), "archcontext"), source: "os-user-data" };
|
|
42084
|
-
}
|
|
42085
|
-
function runtimeStatePaths(root = process.cwd(), env = process.env) {
|
|
42086
|
-
const repositoryRoot = readGitPath(root, ["rev-parse", "--show-toplevel"]) ?? root;
|
|
42087
|
-
const canonicalRepositoryRoot = canonicalPath(repositoryRoot);
|
|
42088
|
-
const gitCommonDir = readGitPath(canonicalRepositoryRoot, ["rev-parse", "--git-common-dir"]);
|
|
42089
|
-
const repositoryAnchor = canonicalPath(gitCommonDir ? resolveMaybeRelative(canonicalRepositoryRoot, gitCommonDir) : canonicalRepositoryRoot);
|
|
42090
|
-
const workspaceAnchor = canonicalRepositoryRoot;
|
|
42091
|
-
const storageRepositoryId = stableStorageId("repo", repositoryAnchor);
|
|
42092
|
-
const storageWorkspaceId = stableStorageId("ws", workspaceAnchor);
|
|
42093
|
-
const stateRoot = defaultArchContextStateRoot(env);
|
|
42094
|
-
const repositoryStateDir = join11(stateRoot.path, REPOSITORIES_DIR, storageRepositoryId);
|
|
42095
|
-
const workspaceStateDir = join11(repositoryStateDir, WORKTREES_DIR, storageWorkspaceId);
|
|
42096
|
-
const legacyControlDir = resolve21(canonicalRepositoryRoot, ".archcontext", ".local");
|
|
42097
|
-
return {
|
|
42098
|
-
schemaVersion: "archcontext.runtime-state-paths/v1",
|
|
42099
|
-
stateRoot: stateRoot.path,
|
|
42100
|
-
source: stateRoot.source,
|
|
42101
|
-
repositoryRoot: canonicalRepositoryRoot,
|
|
42102
|
-
repositoryAnchor,
|
|
42103
|
-
workspaceAnchor,
|
|
42104
|
-
storageRepositoryId,
|
|
42105
|
-
storageWorkspaceId,
|
|
42106
|
-
repositoryId: storageRepositoryId,
|
|
42107
|
-
workspaceId: storageWorkspaceId,
|
|
42108
|
-
repositoryStateDir,
|
|
42109
|
-
workspaceStateDir,
|
|
42110
|
-
sharedCacheDir: join11(repositoryStateDir, "shared", "cache"),
|
|
42111
|
-
localStorePath: env[ARCHCONTEXT_LOCAL_STORE_PATH_ENV] ?? join11(workspaceStateDir, "runtime.sqlite"),
|
|
42112
|
-
...daemonControlPaths(workspaceStateDir),
|
|
42113
|
-
developerReviewRunStateDir: join11(workspaceStateDir, "developer-review-runs"),
|
|
42114
|
-
legacyControlDir,
|
|
42115
|
-
legacyLocalStorePath: join11(legacyControlDir, "runtime.sqlite")
|
|
42116
|
-
};
|
|
42117
|
-
}
|
|
42118
|
-
var REPOSITORIES_DIR = "repositories";
|
|
42119
|
-
var WORKTREES_DIR = "worktrees";
|
|
42120
|
-
function daemonControlPaths(workspaceStateDir) {
|
|
42121
|
-
return {
|
|
42122
|
-
daemonConnectionPath: join11(workspaceStateDir, "archctxd.json"),
|
|
42123
|
-
daemonLockPath: join11(workspaceStateDir, "archctxd.lock"),
|
|
42124
|
-
daemonLogPath: join11(workspaceStateDir, "archctxd.log")
|
|
42125
|
-
};
|
|
42126
|
-
}
|
|
42127
|
-
function listWorkspaceStateDirs(stateRoot) {
|
|
42128
|
-
return listDirectoryNames(join11(stateRoot, REPOSITORIES_DIR)).flatMap((storageRepositoryId) => listDirectoryNames(join11(stateRoot, REPOSITORIES_DIR, storageRepositoryId, WORKTREES_DIR)).map((storageWorkspaceId) => ({
|
|
42129
|
-
storageRepositoryId,
|
|
42130
|
-
storageWorkspaceId,
|
|
42131
|
-
workspaceStateDir: join11(stateRoot, REPOSITORIES_DIR, storageRepositoryId, WORKTREES_DIR, storageWorkspaceId)
|
|
42132
|
-
})));
|
|
42133
|
-
}
|
|
42134
|
-
function listDirectoryNames(path) {
|
|
42135
|
-
try {
|
|
42136
|
-
return readdirSync10(path, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort();
|
|
42137
|
-
} catch (error) {
|
|
42138
|
-
if (error.code === "ENOENT")
|
|
42139
|
-
return [];
|
|
42140
|
-
throw error;
|
|
42141
|
-
}
|
|
42142
|
-
}
|
|
42143
|
-
function readGitPath(root, args) {
|
|
42144
|
-
try {
|
|
42145
|
-
const value = execFileSync6("git", args, {
|
|
42146
|
-
cwd: root,
|
|
42147
|
-
encoding: "utf8",
|
|
42148
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
42149
|
-
}).trim();
|
|
42150
|
-
return value.length > 0 ? value : undefined;
|
|
42151
|
-
} catch {
|
|
42152
|
-
return;
|
|
42153
|
-
}
|
|
42154
|
-
}
|
|
42155
|
-
function resolveMaybeRelative(base, path) {
|
|
42156
|
-
return isAbsolute5(path) ? resolve21(path) : resolve21(base, path);
|
|
42157
|
-
}
|
|
42158
|
-
function canonicalPath(path) {
|
|
42159
|
-
const resolved = resolve21(path);
|
|
42160
|
-
try {
|
|
42161
|
-
return realpathSync6.native(resolved);
|
|
42162
|
-
} catch {
|
|
42163
|
-
return resolved;
|
|
42164
|
-
}
|
|
42165
|
-
}
|
|
42166
|
-
function stableStorageId(prefix, value) {
|
|
42167
|
-
return `${prefix}.${createHash9("sha256").update(value).digest("hex").slice(0, 16)}`;
|
|
42168
|
-
}
|
|
42169
|
-
|
|
42170
|
-
// packages/local-runtime/runtime-daemon/src/daemon-control.ts
|
|
42171
42577
|
function defaultDeveloperReviewRunStateDir(root = process.cwd()) {
|
|
42172
42578
|
return runtimeStatePaths(root).developerReviewRunStateDir;
|
|
42173
42579
|
}
|
|
@@ -42380,9 +42786,9 @@ class DeveloperReviewRunService {
|
|
|
42380
42786
|
challengeId: input.challenge.challengeId,
|
|
42381
42787
|
tempRoot: input.tempRoot
|
|
42382
42788
|
});
|
|
42383
|
-
|
|
42384
|
-
|
|
42385
|
-
|
|
42789
|
+
mkdirSync7(paths.stateDir, { recursive: true });
|
|
42790
|
+
mkdirSync7(paths.runRoot, { recursive: true });
|
|
42791
|
+
mkdirSync7(paths.worktreeTempRoot, { recursive: true });
|
|
42386
42792
|
const createdAt = this.clock();
|
|
42387
42793
|
writeDeveloperReviewRunOwnerMarker({
|
|
42388
42794
|
runRoot: paths.runRoot,
|
|
@@ -42506,7 +42912,7 @@ class DeveloperReviewRunService {
|
|
|
42506
42912
|
this.assertRunning();
|
|
42507
42913
|
const sourceRoot = findRepositoryRoot(input.repositoryRoot);
|
|
42508
42914
|
const safeChallengeId = safeControlFileSegment(input.challengeId);
|
|
42509
|
-
const manifestPath =
|
|
42915
|
+
const manifestPath = join13(defaultDeveloperReviewRunStateDir(sourceRoot), `${safeChallengeId}.json`);
|
|
42510
42916
|
const manifest = readDeveloperReviewRunManifest(manifestPath);
|
|
42511
42917
|
if (!manifest)
|
|
42512
42918
|
throw developerReviewRunNotOwned("persisted-manifest-missing");
|
|
@@ -42533,7 +42939,7 @@ class DeveloperReviewRunService {
|
|
|
42533
42939
|
for (const entry of readdirSync11(stateDir).sort()) {
|
|
42534
42940
|
if (!entry.endsWith(".json"))
|
|
42535
42941
|
continue;
|
|
42536
|
-
const manifestPath =
|
|
42942
|
+
const manifestPath = join13(stateDir, entry);
|
|
42537
42943
|
const stats = lstatIfExists2(manifestPath);
|
|
42538
42944
|
if (!stats || !stats.isFile()) {
|
|
42539
42945
|
recovery.rejected.push(`${entry}: not-a-regular-file`);
|
|
@@ -42561,7 +42967,7 @@ class DeveloperReviewRunService {
|
|
|
42561
42967
|
for (const entry of readdirSync11(stateDir).sort()) {
|
|
42562
42968
|
if (!entry.endsWith(".lock"))
|
|
42563
42969
|
continue;
|
|
42564
|
-
const lockPath =
|
|
42970
|
+
const lockPath = join13(stateDir, entry);
|
|
42565
42971
|
const stats = lstatIfExists2(lockPath);
|
|
42566
42972
|
if (!stats || !stats.isFile()) {
|
|
42567
42973
|
recovery.rejected.push(`${entry}: not-a-regular-file`);
|
|
@@ -42590,15 +42996,15 @@ function createDeveloperReviewRunPaths(input) {
|
|
|
42590
42996
|
const runId = `${safeChallengeId}-${randomBytes2(6).toString("hex")}`;
|
|
42591
42997
|
const stateDir = defaultDeveloperReviewRunStateDir(input.sourceRoot);
|
|
42592
42998
|
const tempParent = input.tempRoot ? resolve22(input.tempRoot) : tmpdir3();
|
|
42593
|
-
|
|
42594
|
-
const runRoot = mkdtempSync3(
|
|
42999
|
+
mkdirSync7(tempParent, { recursive: true });
|
|
43000
|
+
const runRoot = mkdtempSync3(join13(tempParent, `${DEVELOPER_REVIEW_RUN_ROOT_PREFIX}${safeChallengeId.slice(0, 32)}-`));
|
|
42595
43001
|
return {
|
|
42596
43002
|
runId,
|
|
42597
43003
|
stateDir,
|
|
42598
43004
|
runRoot,
|
|
42599
|
-
worktreeTempRoot:
|
|
42600
|
-
manifestPath:
|
|
42601
|
-
lockPath:
|
|
43005
|
+
worktreeTempRoot: join13(runRoot, "worktrees"),
|
|
43006
|
+
manifestPath: join13(stateDir, `${safeChallengeId}.json`),
|
|
43007
|
+
lockPath: join13(stateDir, `${safeChallengeId}.lock`)
|
|
42602
43008
|
};
|
|
42603
43009
|
}
|
|
42604
43010
|
function writeDeveloperReviewRunOwnerMarker(input) {
|
|
@@ -42612,7 +43018,7 @@ function writeDeveloperReviewRunOwnerMarker(input) {
|
|
|
42612
43018
|
pid: process.pid,
|
|
42613
43019
|
createdAt: input.createdAt
|
|
42614
43020
|
};
|
|
42615
|
-
writePrivateJson(
|
|
43021
|
+
writePrivateJson(join13(input.runRoot, DEVELOPER_REVIEW_RUN_OWNER_MARKER_FILE), marker, "wx");
|
|
42616
43022
|
}
|
|
42617
43023
|
function readDeveloperReviewRunOwnerMarker(path) {
|
|
42618
43024
|
const stats = lstatIfExists2(path);
|
|
@@ -42636,8 +43042,8 @@ function resolveOwnedDeveloperReviewRunTargets(run) {
|
|
|
42636
43042
|
if (!runIdSuffix || !DEVELOPER_REVIEW_RUN_ID_SUFFIX.test(runIdSuffix))
|
|
42637
43043
|
throw developerReviewRunNotOwned("run-id");
|
|
42638
43044
|
const stateDir = defaultDeveloperReviewRunStateDir(run.sourceRoot);
|
|
42639
|
-
const manifestPath =
|
|
42640
|
-
const lockPath =
|
|
43045
|
+
const manifestPath = join13(stateDir, `${safeChallengeId}.json`);
|
|
43046
|
+
const lockPath = join13(stateDir, `${safeChallengeId}.lock`);
|
|
42641
43047
|
if (resolve22(run.manifestPath) !== manifestPath)
|
|
42642
43048
|
throw developerReviewRunNotOwned("manifest-path");
|
|
42643
43049
|
if (resolve22(run.lockPath) !== lockPath)
|
|
@@ -42659,7 +43065,7 @@ function resolveOwnedDeveloperReviewRunTargets(run) {
|
|
|
42659
43065
|
if (!runRootName.startsWith(runRootPrefix) || !DEVELOPER_REVIEW_RUN_ROOT_SUFFIX.test(runRootName.slice(runRootPrefix.length))) {
|
|
42660
43066
|
throw developerReviewRunNotOwned("run-root-name");
|
|
42661
43067
|
}
|
|
42662
|
-
const worktreeTempRoot =
|
|
43068
|
+
const worktreeTempRoot = join13(runRoot, "worktrees");
|
|
42663
43069
|
if (resolve22(run.worktreeTempRoot) !== worktreeTempRoot)
|
|
42664
43070
|
throw developerReviewRunNotOwned("worktree-temp-root");
|
|
42665
43071
|
if (resolve22(run.codeGraphTemporaryState.root) !== runRoot)
|
|
@@ -42669,7 +43075,7 @@ function resolveOwnedDeveloperReviewRunTargets(run) {
|
|
|
42669
43075
|
return { stateDir, manifestPath, lockPath };
|
|
42670
43076
|
if (!runRootStats.isDirectory())
|
|
42671
43077
|
throw developerReviewRunNotOwned("run-root-not-a-directory");
|
|
42672
|
-
const marker = readDeveloperReviewRunOwnerMarker(
|
|
43078
|
+
const marker = readDeveloperReviewRunOwnerMarker(join13(runRoot, DEVELOPER_REVIEW_RUN_OWNER_MARKER_FILE));
|
|
42673
43079
|
if (!marker)
|
|
42674
43080
|
throw developerReviewRunNotOwned("run-root-owner-marker-missing");
|
|
42675
43081
|
if (marker.runId !== run.runId || marker.challengeId !== run.challengeId)
|
|
@@ -42706,8 +43112,8 @@ function writeDeveloperReviewRunManifest(manifest) {
|
|
|
42706
43112
|
writePrivateJson(manifest.manifestPath, manifest);
|
|
42707
43113
|
}
|
|
42708
43114
|
function writePrivateJson(path, value, flag = "w") {
|
|
42709
|
-
|
|
42710
|
-
|
|
43115
|
+
mkdirSync7(dirname7(path), { recursive: true });
|
|
43116
|
+
writeFileSync6(path, JSON.stringify(value, null, 2), { mode: 384, flag });
|
|
42711
43117
|
chmodSync3(path, 384);
|
|
42712
43118
|
}
|
|
42713
43119
|
function readDeveloperReviewRunManifest(path) {
|
|
@@ -42719,7 +43125,7 @@ function readDeveloperReviewRunManifest(path) {
|
|
|
42719
43125
|
}
|
|
42720
43126
|
function readJsonObject(path) {
|
|
42721
43127
|
try {
|
|
42722
|
-
const parsed = JSON.parse(
|
|
43128
|
+
const parsed = JSON.parse(readFileSync18(path, "utf8"));
|
|
42723
43129
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : undefined;
|
|
42724
43130
|
} catch {
|
|
42725
43131
|
return;
|
|
@@ -44316,8 +44722,8 @@ function uniqueStrings2(values) {
|
|
|
44316
44722
|
// packages/local-runtime/runtime-daemon/src/ledger-admin.ts
|
|
44317
44723
|
init_src();
|
|
44318
44724
|
init_src();
|
|
44319
|
-
import { existsSync as existsSync20, readFileSync as
|
|
44320
|
-
import { join as
|
|
44725
|
+
import { existsSync as existsSync20, readFileSync as readFileSync20 } from "node:fs";
|
|
44726
|
+
import { join as join15, resolve as resolve24 } from "node:path";
|
|
44321
44727
|
|
|
44322
44728
|
// packages/core/reconcile-engine/src/index.ts
|
|
44323
44729
|
function reconcileArchitectureLedgerDrift(input) {
|
|
@@ -44394,11 +44800,11 @@ init_src();
|
|
|
44394
44800
|
|
|
44395
44801
|
// packages/local-runtime/local-store-sqlite/src/index.ts
|
|
44396
44802
|
init_src();
|
|
44397
|
-
import { createHash as createHash10, randomUUID } from "node:crypto";
|
|
44398
|
-
import { chmodSync as chmodSync4, closeSync as closeSync7, copyFileSync, existsSync as existsSync19, fsyncSync as fsyncSync3, lstatSync as lstatSync10, mkdirSync as
|
|
44803
|
+
import { createHash as createHash10, randomUUID as randomUUID2 } from "node:crypto";
|
|
44804
|
+
import { chmodSync as chmodSync4, closeSync as closeSync7, copyFileSync, existsSync as existsSync19, fsyncSync as fsyncSync3, lstatSync as lstatSync10, mkdirSync as mkdirSync8, openSync as openSync8, readFileSync as readFileSync19, readSync as readSync4, realpathSync as realpathSync7, renameSync as renameSync4, rmSync as rmSync9, statfsSync, statSync as statSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
44399
44805
|
import { readdir, readFile } from "node:fs/promises";
|
|
44400
44806
|
import { createRequire as createRequire4 } from "node:module";
|
|
44401
|
-
import { dirname as dirname8, isAbsolute as isAbsolute6, join as
|
|
44807
|
+
import { dirname as dirname8, isAbsolute as isAbsolute6, join as join14, relative as relative7, resolve as resolve23 } from "node:path";
|
|
44402
44808
|
init_src();
|
|
44403
44809
|
// schemas/runtime/explorer-projection-v2.schema.json
|
|
44404
44810
|
var explorer_projection_v2_schema_default = {
|
|
@@ -45815,8 +46221,8 @@ function migrateLegacyLocalStoreIfNeeded(root = process.cwd(), env = process.env
|
|
|
45815
46221
|
}
|
|
45816
46222
|
assertTrustedLegacyLocalStoreSource(paths);
|
|
45817
46223
|
const lock = acquireLegacyMigrationLock(paths);
|
|
45818
|
-
const stagingDir =
|
|
45819
|
-
const stagingPath =
|
|
46224
|
+
const stagingDir = join14(paths.workspaceStateDir, `.runtime.sqlite.migration-${process.pid}-${randomUUID2()}`);
|
|
46225
|
+
const stagingPath = join14(stagingDir, "runtime.sqlite");
|
|
45820
46226
|
try {
|
|
45821
46227
|
if (targetExists)
|
|
45822
46228
|
quarantinedFiles.push(...quarantineExistingLocalStore(paths));
|
|
@@ -45908,7 +46314,7 @@ class SqliteLocalStore {
|
|
|
45908
46314
|
}
|
|
45909
46315
|
async beginSnapshot(snapshot) {
|
|
45910
46316
|
const db = await this.database();
|
|
45911
|
-
const snapshotId = `snapshot_${
|
|
46317
|
+
const snapshotId = `snapshot_${randomUUID2()}`;
|
|
45912
46318
|
db.prepare(`INSERT INTO snapshots
|
|
45913
46319
|
(id, repository_id, head_sha, worktree_digest, state, created_at)
|
|
45914
46320
|
VALUES (?, ?, ?, ?, ?, ?)`).run(snapshotId, snapshot.repositoryId, snapshot.headSha, snapshot.worktreeDigest, "pending", nowIso());
|
|
@@ -46246,7 +46652,7 @@ class SqliteLocalStore {
|
|
|
46246
46652
|
}
|
|
46247
46653
|
async beginChangeSet(root, draft) {
|
|
46248
46654
|
const db = await this.database();
|
|
46249
|
-
const journalId = `changeset_${
|
|
46655
|
+
const journalId = `changeset_${randomUUID2()}`;
|
|
46250
46656
|
db.prepare(`INSERT INTO changeset_journal
|
|
46251
46657
|
(journal_id, changeset_id, root, status, metadata_json, files_json, created_at, updated_at)
|
|
46252
46658
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(journalId, draft.id, root, "pending", stableJson(changeSetMetadata(draft)), "[]", nowIso(), nowIso());
|
|
@@ -49170,7 +49576,7 @@ function ftsMatchKind(query, doc) {
|
|
|
49170
49576
|
function recordArchitectureLedgerOperation(db, input) {
|
|
49171
49577
|
db.prepare(`INSERT INTO architecture_ledger_operations
|
|
49172
49578
|
(operation_id, storage_repository_id, storage_workspace_id, operation_kind, duration_ms, row_count, rebuild_reason, created_at)
|
|
49173
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(`ledger_operation_${
|
|
49579
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(`ledger_operation_${randomUUID2()}`, input.scope.repository.storageRepositoryId, architectureLedgerWorkspaceKey(input.scope.worktree), input.operationKind, Math.max(0, Math.trunc(input.durationMs)), input.rowCount, input.rebuildReason, nowIso());
|
|
49174
49580
|
}
|
|
49175
49581
|
function stableLedgerId(prefix, ...parts) {
|
|
49176
49582
|
return `${prefix}.${createHash10("sha256").update(parts.join("\x00")).digest("hex").slice(0, 24)}`;
|
|
@@ -49738,7 +50144,7 @@ function publishStagedLocalStore(stagingPath, targetPath) {
|
|
|
49738
50144
|
if (existsSync19(path))
|
|
49739
50145
|
throw new Error(`Cannot publish migrated SQLite over existing target file: ${path}`);
|
|
49740
50146
|
}
|
|
49741
|
-
|
|
50147
|
+
renameSync4(stagingPath, targetPath);
|
|
49742
50148
|
makePrivateFile(targetPath);
|
|
49743
50149
|
fsyncDirectory2(dirname8(targetPath));
|
|
49744
50150
|
}
|
|
@@ -49759,7 +50165,7 @@ function acquireLegacyMigrationLock(paths) {
|
|
|
49759
50165
|
ensurePrivateDir(dirname8(lockPath));
|
|
49760
50166
|
try {
|
|
49761
50167
|
const fd = openSync8(lockPath, "wx", 384);
|
|
49762
|
-
|
|
50168
|
+
writeFileSync7(fd, JSON.stringify({
|
|
49763
50169
|
schemaVersion: "archcontext.legacy-local-store-migration-lock/v1",
|
|
49764
50170
|
pid: process.pid,
|
|
49765
50171
|
root: paths.repositoryRoot,
|
|
@@ -49785,7 +50191,7 @@ function releaseLegacyMigrationLock(lock) {
|
|
|
49785
50191
|
}
|
|
49786
50192
|
function isStaleMigrationLock(lockPath) {
|
|
49787
50193
|
try {
|
|
49788
|
-
const parsed = JSON.parse(
|
|
50194
|
+
const parsed = JSON.parse(readFileSync19(lockPath, "utf8"));
|
|
49789
50195
|
if (typeof parsed.pid !== "number" || parsed.pid <= 0)
|
|
49790
50196
|
return true;
|
|
49791
50197
|
return !isProcessAlive(parsed.pid);
|
|
@@ -49836,7 +50242,7 @@ function acquireLocalStoreWriterOwnership(databasePath) {
|
|
|
49836
50242
|
throw error;
|
|
49837
50243
|
}
|
|
49838
50244
|
makePrivateFile(lockPath);
|
|
49839
|
-
const token =
|
|
50245
|
+
const token = randomUUID2();
|
|
49840
50246
|
writeOwnerRecord(recordPath, { pid: process.pid, databasePath, acquiredAt: nowIso(), token });
|
|
49841
50247
|
let released = false;
|
|
49842
50248
|
return {
|
|
@@ -49870,17 +50276,17 @@ function sleepSync(ms) {
|
|
|
49870
50276
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
49871
50277
|
}
|
|
49872
50278
|
function writeOwnerRecord(recordPath, record) {
|
|
49873
|
-
const tempPath = `${recordPath}.${process.pid}-${
|
|
50279
|
+
const tempPath = `${recordPath}.${process.pid}-${randomUUID2()}.tmp`;
|
|
49874
50280
|
try {
|
|
49875
|
-
|
|
49876
|
-
|
|
50281
|
+
writeFileSync7(tempPath, JSON.stringify(record, null, 2), { encoding: "utf8", mode: 384, flag: "wx" });
|
|
50282
|
+
renameSync4(tempPath, recordPath);
|
|
49877
50283
|
} catch {
|
|
49878
50284
|
rmSync9(tempPath, { force: true });
|
|
49879
50285
|
}
|
|
49880
50286
|
}
|
|
49881
50287
|
function readOwnerRecord(recordPath) {
|
|
49882
50288
|
try {
|
|
49883
|
-
const parsed = JSON.parse(
|
|
50289
|
+
const parsed = JSON.parse(readFileSync19(recordPath, "utf8"));
|
|
49884
50290
|
return parsed && typeof parsed === "object" ? parsed : undefined;
|
|
49885
50291
|
} catch {
|
|
49886
50292
|
return;
|
|
@@ -49888,7 +50294,7 @@ function readOwnerRecord(recordPath) {
|
|
|
49888
50294
|
}
|
|
49889
50295
|
function readLegacyOwnerLockPid(legacyPath) {
|
|
49890
50296
|
try {
|
|
49891
|
-
const pid = JSON.parse(
|
|
50297
|
+
const pid = JSON.parse(readFileSync19(legacyPath, "utf8"))?.pid;
|
|
49892
50298
|
return typeof pid === "number" && Number.isInteger(pid) && pid > 0 ? pid : undefined;
|
|
49893
50299
|
} catch {
|
|
49894
50300
|
return;
|
|
@@ -49903,21 +50309,21 @@ function changeSetJournalRecoveryErrorMessage(metadataJson) {
|
|
|
49903
50309
|
return "pending ChangeSet journal without a recorded recovery error";
|
|
49904
50310
|
}
|
|
49905
50311
|
function quarantineExistingLocalStore(paths) {
|
|
49906
|
-
const quarantineDir =
|
|
50312
|
+
const quarantineDir = join14(paths.workspaceStateDir, "quarantine", `runtime.sqlite-${Date.now()}-${randomUUID2()}`);
|
|
49907
50313
|
ensurePrivateDir(quarantineDir);
|
|
49908
50314
|
const quarantinedFiles = [];
|
|
49909
50315
|
for (const suffix of SQLITE_SIDECAR_SUFFIXES) {
|
|
49910
50316
|
const source = `${paths.localStorePath}${suffix}`;
|
|
49911
50317
|
if (!existsSync19(source))
|
|
49912
50318
|
continue;
|
|
49913
|
-
const target =
|
|
49914
|
-
|
|
50319
|
+
const target = join14(quarantineDir, `runtime.sqlite${suffix}`);
|
|
50320
|
+
renameSync4(source, target);
|
|
49915
50321
|
quarantinedFiles.push(target);
|
|
49916
50322
|
}
|
|
49917
50323
|
const markerPath = legacyMigrationMarkerPath(paths);
|
|
49918
50324
|
if (existsSync19(markerPath)) {
|
|
49919
|
-
const target =
|
|
49920
|
-
|
|
50325
|
+
const target = join14(quarantineDir, LEGACY_MIGRATION_MARKER_FILE);
|
|
50326
|
+
renameSync4(markerPath, target);
|
|
49921
50327
|
quarantinedFiles.push(target);
|
|
49922
50328
|
}
|
|
49923
50329
|
fsyncDirectory2(quarantineDir);
|
|
@@ -49925,16 +50331,16 @@ function quarantineExistingLocalStore(paths) {
|
|
|
49925
50331
|
return quarantinedFiles;
|
|
49926
50332
|
}
|
|
49927
50333
|
function legacyMigrationMarkerPath(paths) {
|
|
49928
|
-
return
|
|
50334
|
+
return join14(paths.workspaceStateDir, LEGACY_MIGRATION_MARKER_FILE);
|
|
49929
50335
|
}
|
|
49930
50336
|
function legacyMigrationLockPath(paths) {
|
|
49931
|
-
return
|
|
50337
|
+
return join14(paths.workspaceStateDir, LEGACY_MIGRATION_LOCK_FILE);
|
|
49932
50338
|
}
|
|
49933
50339
|
function writePrivateJson2(path, value) {
|
|
49934
50340
|
ensurePrivateDir(dirname8(path));
|
|
49935
50341
|
const fd = openSync8(path, "w", 384);
|
|
49936
50342
|
try {
|
|
49937
|
-
|
|
50343
|
+
writeFileSync7(fd, JSON.stringify(value, null, 2), "utf8");
|
|
49938
50344
|
fsyncSync3(fd);
|
|
49939
50345
|
} finally {
|
|
49940
50346
|
closeSync7(fd);
|
|
@@ -49943,7 +50349,7 @@ function writePrivateJson2(path, value) {
|
|
|
49943
50349
|
fsyncDirectory2(dirname8(path));
|
|
49944
50350
|
}
|
|
49945
50351
|
function ensurePrivateDir(path) {
|
|
49946
|
-
|
|
50352
|
+
mkdirSync8(path, { recursive: true, mode: 448 });
|
|
49947
50353
|
if (process.platform !== "win32") {
|
|
49948
50354
|
try {
|
|
49949
50355
|
chmodSync4(path, 448);
|
|
@@ -50306,7 +50712,7 @@ function recoverJournalFiles(root, files) {
|
|
|
50306
50712
|
try {
|
|
50307
50713
|
const stat = lstatSync10(absolute);
|
|
50308
50714
|
if (stat.isFile() && !stat.isSymbolicLink()) {
|
|
50309
|
-
const bytes =
|
|
50715
|
+
const bytes = readFileSync19(absolute), body = bytes.toString("utf8");
|
|
50310
50716
|
if (Buffer.from(body, "utf8").equals(bytes))
|
|
50311
50717
|
current = digestJson({ body });
|
|
50312
50718
|
}
|
|
@@ -50325,7 +50731,7 @@ function recoverJournalFiles(root, files) {
|
|
|
50325
50731
|
if (file.existed) {
|
|
50326
50732
|
if (file.backupPath && existsSync19(file.backupPath)) {
|
|
50327
50733
|
rmSync9(absolute, { recursive: true, force: true });
|
|
50328
|
-
|
|
50734
|
+
renameSync4(file.backupPath, absolute);
|
|
50329
50735
|
} else if (!existsSync19(absolute) && firstExistedByPath.get(pathKey(absolute)) === true) {
|
|
50330
50736
|
missing.push(file.path);
|
|
50331
50737
|
continue;
|
|
@@ -50383,7 +50789,7 @@ async function readRelationFiles(root, relationsDir) {
|
|
|
50383
50789
|
for (const entry of entries) {
|
|
50384
50790
|
if (!entry.isFile() || !/\.(json|ya?ml)$/.test(entry.name))
|
|
50385
50791
|
continue;
|
|
50386
|
-
const relativePath =
|
|
50792
|
+
const relativePath = join14(relationsDir, entry.name).split("\\").join("/");
|
|
50387
50793
|
relations.push(parseCrossRepoRelationFile(await readFile(resolve23(root, relativePath), "utf8"), relativePath));
|
|
50388
50794
|
}
|
|
50389
50795
|
return relations.sort((a, b) => a.id.localeCompare(b.id));
|
|
@@ -50515,7 +50921,7 @@ class LedgerAdminService {
|
|
|
50515
50921
|
}
|
|
50516
50922
|
const paths = runtimeStatePaths(repositoryRoot);
|
|
50517
50923
|
const backupCreatedAt = this.context.clock();
|
|
50518
|
-
const backupPath = uniqueRuntimeBackupPath(
|
|
50924
|
+
const backupPath = uniqueRuntimeBackupPath(join15(paths.workspaceStateDir, "backups", "ledger-migrate", safePathSegment(backupCreatedAt), "runtime.sqlite"));
|
|
50519
50925
|
const backup = await this.context.localStore.backupArchitectureLedger({ backupPath });
|
|
50520
50926
|
const append = await this.context.appendArchitectureEventsWithFeed(repositoryRoot, {
|
|
50521
50927
|
writer: "runtime-daemon",
|
|
@@ -51014,7 +51420,7 @@ function obsoleteManagedProjectionPaths(currentFiles, projectedFiles) {
|
|
|
51014
51420
|
}
|
|
51015
51421
|
function expectedFileHash(root, path) {
|
|
51016
51422
|
const absolute = resolve24(root, path);
|
|
51017
|
-
return existsSync20(absolute) ? digestJson({ body:
|
|
51423
|
+
return existsSync20(absolute) ? digestJson({ body: readFileSync20(absolute, "utf8") }) : "missing";
|
|
51018
51424
|
}
|
|
51019
51425
|
function architectureProjectionRollbackBackup(files, options = {}) {
|
|
51020
51426
|
const manifest = {
|
|
@@ -51069,12 +51475,12 @@ function isEmptyArchitectureLedgerState(state) {
|
|
|
51069
51475
|
// packages/local-runtime/runtime-daemon/src/architecture-book.ts
|
|
51070
51476
|
init_src();
|
|
51071
51477
|
import { existsSync as existsSync22 } from "node:fs";
|
|
51072
|
-
import { join as
|
|
51478
|
+
import { join as join17 } from "node:path";
|
|
51073
51479
|
|
|
51074
51480
|
// packages/local-runtime/runtime-daemon/src/refactor-decisions.ts
|
|
51075
51481
|
init_src();
|
|
51076
|
-
import { existsSync as existsSync21, lstatSync as lstatSync11, readdirSync as readdirSync12, readFileSync as
|
|
51077
|
-
import { join as
|
|
51482
|
+
import { existsSync as existsSync21, lstatSync as lstatSync11, readdirSync as readdirSync12, readFileSync as readFileSync21 } from "node:fs";
|
|
51483
|
+
import { join as join16 } from "node:path";
|
|
51078
51484
|
var REFACTOR_DECISION_SET_SCHEMA_VERSION = "archcontext.refactor-decision-set/v1";
|
|
51079
51485
|
var REFACTOR_DECISION_FILE_NAME = /^recommendation\.[a-f0-9]{16}\.json$/;
|
|
51080
51486
|
var CHANGESET_TRANSIENT_DECISION_NAME = /^recommendation\.[a-f0-9]{16}\.json\.(archctx-backup|archctx-tmp-[0-9]+-[0-9]+)$/;
|
|
@@ -51113,11 +51519,11 @@ function readRefactorDecisionSet(root) {
|
|
|
51113
51519
|
const name = path.slice(prefix.length);
|
|
51114
51520
|
if (name.includes("/"))
|
|
51115
51521
|
throw decisionReadError(`${path} must sit directly in ${REFACTOR_DECISION_DIRECTORY}`);
|
|
51116
|
-
if (!lstatSync11(
|
|
51522
|
+
if (!lstatSync11(join16(absoluteDirectory, name)).isFile())
|
|
51117
51523
|
throw decisionReadError(`${path} must be a regular file, not a directory or symlink`);
|
|
51118
51524
|
let decision;
|
|
51119
51525
|
try {
|
|
51120
|
-
decision = parseRefactorDecisionFile(path,
|
|
51526
|
+
decision = parseRefactorDecisionFile(path, readFileSync21(join16(absoluteDirectory, name), "utf8"));
|
|
51121
51527
|
} catch (error) {
|
|
51122
51528
|
throw decisionReadError(error instanceof Error ? error.message : String(error));
|
|
51123
51529
|
}
|
|
@@ -51206,7 +51612,7 @@ function buildRefactorDecision(input) {
|
|
|
51206
51612
|
function refactorDecisionWrite(root, decision) {
|
|
51207
51613
|
const path = refactorDecisionPath(decision.recommendationId);
|
|
51208
51614
|
const absolute = assertPathHasNoSymlinkSegments(root, path);
|
|
51209
|
-
const expectedHash = existsSync21(absolute) ? digestJson({ body:
|
|
51615
|
+
const expectedHash = existsSync21(absolute) ? digestJson({ body: readFileSync21(absolute, "utf8") }) : "missing";
|
|
51210
51616
|
return { path, expectedHash, body: serializeRefactorDecision(decision) };
|
|
51211
51617
|
}
|
|
51212
51618
|
function refactorDecisionIdentityIssues(decision, namespace) {
|
|
@@ -51396,7 +51802,7 @@ class ArchitectureBookService {
|
|
|
51396
51802
|
const gitScope = await this.context.architectureLedgerGitScope(root);
|
|
51397
51803
|
let refactorDecisionStatuses = new Map;
|
|
51398
51804
|
const repositoryRoot = findRepositoryRoot(root);
|
|
51399
|
-
if (replay.events.some(eventCarriesRefactorRecommendation) || existsSync22(
|
|
51805
|
+
if (replay.events.some(eventCarriesRefactorRecommendation) || existsSync22(join17(repositoryRoot, REFACTOR_DECISION_DIRECTORY))) {
|
|
51400
51806
|
try {
|
|
51401
51807
|
const decisions = readRefactorDecisionSet(repositoryRoot);
|
|
51402
51808
|
refactorDecisionStatuses = new Map(decisions.decisions.map((decision) => [decision.recommendationId, decision.status]));
|
|
@@ -51752,8 +52158,8 @@ init_src();
|
|
|
51752
52158
|
init_src();
|
|
51753
52159
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
51754
52160
|
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
51755
|
-
import { chmodSync as chmodSync5, existsSync as existsSync23, lstatSync as lstatSync12, mkdirSync as
|
|
51756
|
-
import { basename as basename6, dirname as dirname9, join as
|
|
52161
|
+
import { chmodSync as chmodSync5, existsSync as existsSync23, lstatSync as lstatSync12, mkdirSync as mkdirSync9, readFileSync as readFileSync22, renameSync as renameSync5, rmSync as rmSync10, writeFileSync as writeFileSync8 } from "node:fs";
|
|
52162
|
+
import { basename as basename6, dirname as dirname9, join as join18 } from "node:path";
|
|
51757
52163
|
|
|
51758
52164
|
// packages/local-runtime/runtime-daemon/src/investigation-transport.ts
|
|
51759
52165
|
import { spawn } from "node:child_process";
|
|
@@ -51995,7 +52401,7 @@ var AUDIT_EGRESS_POLICY_DIGEST = digestJson(AUDIT_EGRESS_POLICY);
|
|
|
51995
52401
|
function auditConsentBinding(root, env) {
|
|
51996
52402
|
const paths = runtimeStatePaths(root, env);
|
|
51997
52403
|
return {
|
|
51998
|
-
path:
|
|
52404
|
+
path: join18(paths.repositoryStateDir, AUDIT_CONSENT_FILE),
|
|
51999
52405
|
storageRepositoryId: paths.storageRepositoryId,
|
|
52000
52406
|
repositoryAnchor: paths.repositoryAnchor,
|
|
52001
52407
|
origin: readSanitizedOrigin(paths.repositoryRoot)
|
|
@@ -52043,7 +52449,7 @@ function readAuditConsentUnchecked(root, env = process.env) {
|
|
|
52043
52449
|
try {
|
|
52044
52450
|
if (!lstatSync12(binding.path).isFile())
|
|
52045
52451
|
return { granted: false, path: binding.path, reason: "unreadable" };
|
|
52046
|
-
record = JSON.parse(
|
|
52452
|
+
record = JSON.parse(readFileSync22(binding.path, "utf8"));
|
|
52047
52453
|
} catch {
|
|
52048
52454
|
return { granted: false, path: binding.path, reason: "unreadable" };
|
|
52049
52455
|
}
|
|
@@ -52081,13 +52487,13 @@ function grantAuditConsentUnchecked(root, env = process.env, now = new Date().to
|
|
|
52081
52487
|
}
|
|
52082
52488
|
function writePrivateJsonAtomically(path, value) {
|
|
52083
52489
|
const directory = dirname9(path);
|
|
52084
|
-
|
|
52085
|
-
const tempPath =
|
|
52490
|
+
mkdirSync9(directory, { recursive: true, mode: 448 });
|
|
52491
|
+
const tempPath = join18(directory, `.${basename6(path)}.${process.pid}.${randomBytes4(6).toString("hex")}.tmp`);
|
|
52086
52492
|
try {
|
|
52087
|
-
|
|
52493
|
+
writeFileSync8(tempPath, `${JSON.stringify(value, null, 2)}
|
|
52088
52494
|
`, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
52089
52495
|
chmodSync5(tempPath, 384);
|
|
52090
|
-
|
|
52496
|
+
renameSync5(tempPath, path);
|
|
52091
52497
|
} catch (error) {
|
|
52092
52498
|
rmSync10(tempPath, { force: true });
|
|
52093
52499
|
throw error;
|
|
@@ -52120,9 +52526,9 @@ function auditConsentRequiredEnvelope(requestId, reason) {
|
|
|
52120
52526
|
|
|
52121
52527
|
// packages/local-runtime/runtime-daemon/src/github-issue-executor.ts
|
|
52122
52528
|
import { execFile } from "node:child_process";
|
|
52123
|
-
import { mkdtempSync as mkdtempSync4, rmSync as rmSync11, writeFileSync as
|
|
52529
|
+
import { mkdtempSync as mkdtempSync4, rmSync as rmSync11, writeFileSync as writeFileSync9 } from "node:fs";
|
|
52124
52530
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
52125
|
-
import { join as
|
|
52531
|
+
import { join as join19 } from "node:path";
|
|
52126
52532
|
var DEFAULT_GH_EXECUTOR_TIMEOUT_MS = 30000;
|
|
52127
52533
|
var GITHUB_ISSUE_LIST_LIMIT = 100;
|
|
52128
52534
|
function createNodeGithubIssueExecutor(options = {}) {
|
|
@@ -52187,10 +52593,10 @@ function runGh(args, env, timeoutMs) {
|
|
|
52187
52593
|
});
|
|
52188
52594
|
}
|
|
52189
52595
|
async function withGithubIssueBodyFile(body, fn, deps = {}) {
|
|
52190
|
-
const writeFile = deps.writeFile ??
|
|
52191
|
-
const dir = mkdtempSync4(
|
|
52596
|
+
const writeFile = deps.writeFile ?? writeFileSync9;
|
|
52597
|
+
const dir = mkdtempSync4(join19(tmpdir4(), "archctx-gh-issue-body-"));
|
|
52192
52598
|
try {
|
|
52193
|
-
const bodyFile =
|
|
52599
|
+
const bodyFile = join19(dir, "body.md");
|
|
52194
52600
|
writeFile(bodyFile, body, { mode: 384 });
|
|
52195
52601
|
return await fn(bodyFile);
|
|
52196
52602
|
} finally {
|
|
@@ -53174,10 +53580,10 @@ function runtimeProjectionOwnedOutputDigest(projection) {
|
|
|
53174
53580
|
}
|
|
53175
53581
|
// packages/local-runtime/runtime-daemon/src/projection-writer.ts
|
|
53176
53582
|
import { execFile as execFile2, spawnSync as spawnSync6 } from "node:child_process";
|
|
53177
|
-
import { createHash as createHash11, randomUUID as
|
|
53178
|
-
import { closeSync as closeSync8, existsSync as existsSync24, mkdirSync as
|
|
53583
|
+
import { createHash as createHash11, randomUUID as randomUUID3 } from "node:crypto";
|
|
53584
|
+
import { closeSync as closeSync8, existsSync as existsSync24, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync5, openSync as openSync9, readFileSync as readFileSync23, readSync as readSync5, realpathSync as realpathSync8, renameSync as renameSync6, rmSync as rmSync12, writeFileSync as writeFileSync10 } from "node:fs";
|
|
53179
53585
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
53180
|
-
import { extname as extname2, join as
|
|
53586
|
+
import { extname as extname2, join as join20, resolve as resolve25 } from "node:path";
|
|
53181
53587
|
init_src();
|
|
53182
53588
|
var PROJECTION_PUBLISH_REQUEST_ID = "projection.publish";
|
|
53183
53589
|
var PROJECTION_PUBLISH_STATUS_REQUEST_ID = "projection.publish-status";
|
|
@@ -53190,6 +53596,10 @@ var PROJECTION_WRITER_MAX_ITERATIONS = 3;
|
|
|
53190
53596
|
var PROJECTION_WRITER_TARGETS = ["agent-context", "architecture-docs"];
|
|
53191
53597
|
var PUBLISHER_TIMEOUT_MS = 120000;
|
|
53192
53598
|
var PR_BODY_MAX_LISTED_PATHS = 200;
|
|
53599
|
+
function renderRecentHistory(root, ref, env) {
|
|
53600
|
+
const { total } = readArchitectureHistory(root, { ref, limit: 0, env });
|
|
53601
|
+
return renderHistoryMarkdown(readArchitectureHistory(root, { ref, offset: Math.max(0, total - 20), limit: 20, env }));
|
|
53602
|
+
}
|
|
53193
53603
|
|
|
53194
53604
|
class ProjectionWriterFailure extends Error {
|
|
53195
53605
|
code;
|
|
@@ -53207,8 +53617,8 @@ class ProjectionWriterFailure extends Error {
|
|
|
53207
53617
|
}
|
|
53208
53618
|
function projectionWriterPaths(repositoryRoot, remote, base, env = process.env) {
|
|
53209
53619
|
const key = createHash11("sha256").update(`${remote}\x00${base}`, "utf8").digest("hex").slice(0, 16);
|
|
53210
|
-
const dir =
|
|
53211
|
-
return { dir, baseRef: `refs/archctx/projection-writer/${key}/base`, worktree:
|
|
53620
|
+
const dir = join20(runtimeStatePaths(repositoryRoot, env).repositoryStateDir, "projection-writer", key);
|
|
53621
|
+
return { dir, baseRef: `refs/archctx/projection-writer/${key}/base`, worktree: join20(dir, "worktree"), state: join20(dir, "state.json"), lock: join20(dir, "lock") };
|
|
53212
53622
|
}
|
|
53213
53623
|
async function runProjectionPublishCommand(options) {
|
|
53214
53624
|
const env = options.env ?? process.env;
|
|
@@ -53253,7 +53663,7 @@ async function runProjectionPublishCommand(options) {
|
|
|
53253
53663
|
});
|
|
53254
53664
|
let lock;
|
|
53255
53665
|
try {
|
|
53256
|
-
|
|
53666
|
+
mkdirSync10(paths.dir, { recursive: true, mode: 448 });
|
|
53257
53667
|
lock = acquireProjectionWriterLock(paths.lock, startedAt);
|
|
53258
53668
|
} catch (error) {
|
|
53259
53669
|
const failure = asWriterFailure(error);
|
|
@@ -53362,6 +53772,12 @@ async function runLockedProjectionPublish(input) {
|
|
|
53362
53772
|
if (!["noop", "applied", "applied-partial"].includes(projectionStatus)) {
|
|
53363
53773
|
throw new ProjectionWriterFailure("AC_PRECONDITION_FAILED", "projection-apply-status-unsupported", `projection apply ended with status ${projectionStatus}; the writer publishes only noop, applied and applied-partial results`);
|
|
53364
53774
|
}
|
|
53775
|
+
const historyBody = renderRecentHistory(paths.worktree, baseSha, options.env);
|
|
53776
|
+
const historyPath = join20(paths.worktree, ARCHITECTURE_HISTORY_PATH);
|
|
53777
|
+
mkdirSync10(join20(paths.worktree, "docs/architecture"), { recursive: true });
|
|
53778
|
+
const historyTemp = `${historyPath}.${randomUUID3()}.tmp`;
|
|
53779
|
+
writeFileSync10(historyTemp, historyBody);
|
|
53780
|
+
renameSync6(historyTemp, historyPath);
|
|
53365
53781
|
const changed = worktreeChangedPaths(paths.worktree);
|
|
53366
53782
|
if (changed.length === 0) {
|
|
53367
53783
|
const tip = lsRemoteBranch(repositoryRoot, pushRemote, base, env);
|
|
@@ -53373,6 +53789,7 @@ async function runLockedProjectionPublish(input) {
|
|
|
53373
53789
|
return finish("up-to-date", { projectionStatus });
|
|
53374
53790
|
}
|
|
53375
53791
|
const written = new Set(result.files.filter((file) => file.action !== "unchanged").map((file) => file.path));
|
|
53792
|
+
written.add(ARCHITECTURE_HISTORY_PATH);
|
|
53376
53793
|
const offending = changed.filter((path) => !written.has(path) || !isProjectionOwnedPath(path, ownedPatterns));
|
|
53377
53794
|
if (offending.length > 0) {
|
|
53378
53795
|
return failed(new ProjectionWriterFailure("AC_POLICY_VIOLATION", "projection-writer-non-owned-change", `projection apply changed paths the writer may not publish: ${offending.join(", ")}`), { projectionStatus });
|
|
@@ -53475,10 +53892,10 @@ function projectionPublishBody(input) {
|
|
|
53475
53892
|
async function publishPullRequest(publisher, input) {
|
|
53476
53893
|
if (publisher.kind === "none")
|
|
53477
53894
|
return { ok: true, pullRequest: null };
|
|
53478
|
-
const dir = mkdtempSync5(
|
|
53895
|
+
const dir = mkdtempSync5(join20(tmpdir5(), "archctx-projection-pr-body-"));
|
|
53479
53896
|
try {
|
|
53480
|
-
const bodyFile =
|
|
53481
|
-
|
|
53897
|
+
const bodyFile = join20(dir, "body.md");
|
|
53898
|
+
writeFileSync10(bodyFile, projectionPublishBody(input), { mode: 384 });
|
|
53482
53899
|
const pullRequest = await publisher.ensurePullRequest({
|
|
53483
53900
|
worktree: input.worktree,
|
|
53484
53901
|
remote: input.remote,
|
|
@@ -53617,11 +54034,13 @@ function runProjectionVerifyPrCommand(options) {
|
|
|
53617
54034
|
} catch {
|
|
53618
54035
|
agentContextDiffering = [...classified.agentContextPaths];
|
|
53619
54036
|
}
|
|
54037
|
+
const historyDiffering = changedPaths.includes(ARCHITECTURE_HISTORY_PATH) && readFileAtRevision(root, headSha, ARCHITECTURE_HISTORY_PATH) !== renderRecentHistory(root, headSha) ? [ARCHITECTURE_HISTORY_PATH] : [];
|
|
53620
54038
|
const differingPaths = [...new Set([
|
|
53621
54039
|
...result.files.filter((file) => file.action !== "unchanged").map((file) => file.path),
|
|
53622
|
-
...agentContextDiffering
|
|
54040
|
+
...agentContextDiffering,
|
|
54041
|
+
...historyDiffering
|
|
53623
54042
|
])].sort();
|
|
53624
|
-
const renderEquivalent = result.status === "noop" && agentContextDiffering.length === 0;
|
|
54043
|
+
const renderEquivalent = result.status === "noop" && agentContextDiffering.length === 0 && historyDiffering.length === 0;
|
|
53625
54044
|
return verification({
|
|
53626
54045
|
verdict: renderEquivalent ? "generated-only-render-equivalent" : "generated-only-not-render-equivalent",
|
|
53627
54046
|
generatedOnly: true,
|
|
@@ -53640,7 +54059,7 @@ function classifyPullRequestPaths(root, mergeBase, headSha, changedPaths) {
|
|
|
53640
54059
|
const humanEdited = [];
|
|
53641
54060
|
const agentContext = [];
|
|
53642
54061
|
for (const path of changedPaths) {
|
|
53643
|
-
if (path === ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH)
|
|
54062
|
+
if (path === ARCHITECTURE_DOCS_PROJECTION_MANIFEST_PATH || path === ARCHITECTURE_HISTORY_PATH)
|
|
53644
54063
|
continue;
|
|
53645
54064
|
const atBase = baseTargets.get(path);
|
|
53646
54065
|
const atHead = headTargets.get(path);
|
|
@@ -53979,7 +54398,7 @@ function acquireProjectionWriterLock(lockPath, startedAt) {
|
|
|
53979
54398
|
return { kind: "busy", pid: holder.pid };
|
|
53980
54399
|
}
|
|
53981
54400
|
rmSync12(lockPath, { force: true });
|
|
53982
|
-
const record = JSON.stringify({ pid: process.pid, startedAt, token:
|
|
54401
|
+
const record = JSON.stringify({ pid: process.pid, startedAt, token: randomUUID3() }, null, 2);
|
|
53983
54402
|
createPrivateControlFile(lockPath, record);
|
|
53984
54403
|
return { kind: "acquired", record, release() {
|
|
53985
54404
|
try {
|
|
@@ -54035,7 +54454,7 @@ function readProjectionWriterState(path, remote, base) {
|
|
|
54035
54454
|
return emptyProjectionWriterState(remote, base);
|
|
54036
54455
|
let value;
|
|
54037
54456
|
try {
|
|
54038
|
-
value = JSON.parse(
|
|
54457
|
+
value = JSON.parse(readFileSync23(path, "utf8"));
|
|
54039
54458
|
} catch (error) {
|
|
54040
54459
|
throw new ProjectionWriterFailure("AC_PRECONDITION_FAILED", "projection-writer-state-invalid", `projection writer state is unreadable at ${path}: ${errorMessage(error)}`);
|
|
54041
54460
|
}
|
|
@@ -54057,9 +54476,9 @@ function readProjectionWriterState(path, remote, base) {
|
|
|
54057
54476
|
}
|
|
54058
54477
|
function writeProjectionWriterState(path, state) {
|
|
54059
54478
|
const temporary = `${path}.${process.pid}.tmp`;
|
|
54060
|
-
|
|
54479
|
+
writeFileSync10(temporary, `${JSON.stringify(state, null, 2)}
|
|
54061
54480
|
`, { encoding: "utf8", mode: 384 });
|
|
54062
|
-
|
|
54481
|
+
renameSync6(temporary, path);
|
|
54063
54482
|
}
|
|
54064
54483
|
function prepareProjectionWriterWorktree(repositoryRoot, worktree, sha) {
|
|
54065
54484
|
git(repositoryRoot, ["worktree", "prune"]);
|
|
@@ -54072,7 +54491,7 @@ function prepareProjectionWriterWorktree(repositoryRoot, worktree, sha) {
|
|
|
54072
54491
|
git(worktree, ["clean", "-ffdq"]);
|
|
54073
54492
|
}
|
|
54074
54493
|
function isRegisteredWorktree(repositoryRoot, worktree) {
|
|
54075
|
-
if (!existsSync24(
|
|
54494
|
+
if (!existsSync24(join20(worktree, ".git")))
|
|
54076
54495
|
return false;
|
|
54077
54496
|
const wanted = canonical(worktree);
|
|
54078
54497
|
return git(repositoryRoot, ["worktree", "list", "--porcelain", "-z"]).split("\x00").filter((line) => line.startsWith("worktree ")).some((line) => canonical(line.slice("worktree ".length)) === wanted);
|
|
@@ -54324,7 +54743,7 @@ function runFlowSelectorCheckCommand(cwd, options = {}) {
|
|
|
54324
54743
|
}
|
|
54325
54744
|
// packages/local-runtime/runtime-daemon/src/recommendations.ts
|
|
54326
54745
|
import { existsSync as existsSync25 } from "node:fs";
|
|
54327
|
-
import { join as
|
|
54746
|
+
import { join as join21 } from "node:path";
|
|
54328
54747
|
|
|
54329
54748
|
// packages/local-runtime/runtime-daemon/src/refactor-verify.ts
|
|
54330
54749
|
init_src();
|
|
@@ -54926,7 +55345,7 @@ class RecommendationsService {
|
|
|
54926
55345
|
});
|
|
54927
55346
|
}
|
|
54928
55347
|
readGitOnlyDecision(repositoryRoot, recommendationId, surface) {
|
|
54929
|
-
if (!existsSync25(
|
|
55348
|
+
if (!existsSync25(join21(repositoryRoot, REFACTOR_DECISION_DIRECTORY)))
|
|
54930
55349
|
return;
|
|
54931
55350
|
let decisions;
|
|
54932
55351
|
try {
|
|
@@ -55596,7 +56015,7 @@ function lifecycleEnvelope(input) {
|
|
|
55596
56015
|
});
|
|
55597
56016
|
}
|
|
55598
56017
|
function refactorDecisionsInPlay(repositoryRoot, records) {
|
|
55599
|
-
return records.some(isRefactorRecommendation) || existsSync25(
|
|
56018
|
+
return records.some(isRefactorRecommendation) || existsSync25(join21(repositoryRoot, REFACTOR_DECISION_DIRECTORY));
|
|
55600
56019
|
}
|
|
55601
56020
|
function ledgerAuditDecisionRefused(surface, record, recommendations, decisions) {
|
|
55602
56021
|
let head = record.recommendationId;
|
|
@@ -55718,14 +56137,14 @@ function recommendationActorKind(input) {
|
|
|
55718
56137
|
init_src();
|
|
55719
56138
|
init_src();
|
|
55720
56139
|
init_src();
|
|
55721
|
-
import { existsSync as existsSync26, readFileSync as
|
|
56140
|
+
import { existsSync as existsSync26, readFileSync as readFileSync25 } from "node:fs";
|
|
55722
56141
|
import { resolve as resolve27 } from "node:path";
|
|
55723
56142
|
init_src();
|
|
55724
56143
|
|
|
55725
56144
|
// packages/local-runtime/runtime-daemon/src/committed-change-acceptance.ts
|
|
55726
56145
|
init_src();
|
|
55727
56146
|
import { execFileSync as execFileSync9 } from "node:child_process";
|
|
55728
|
-
import { closeSync as closeSync9, constants as fsConstants3, fstatSync as fstatSync4, lstatSync as lstatSync13, openSync as openSync10, readdirSync as readdirSync13, readFileSync as
|
|
56147
|
+
import { closeSync as closeSync9, constants as fsConstants3, fstatSync as fstatSync4, lstatSync as lstatSync13, openSync as openSync10, readdirSync as readdirSync13, readFileSync as readFileSync24 } from "node:fs";
|
|
55729
56148
|
import { resolve as resolve26 } from "node:path";
|
|
55730
56149
|
init_src();
|
|
55731
56150
|
var SEMANTIC_MODEL_DIRECTORIES = ["nodes", "relations", "flows"];
|
|
@@ -55804,7 +56223,7 @@ function readRegularFileBytes(absolute, path) {
|
|
|
55804
56223
|
try {
|
|
55805
56224
|
if (!fstatSync4(fd).isFile())
|
|
55806
56225
|
throw new FailureError("AC_PRECONDITION_FAILED", "semantic-model-entry-not-regular");
|
|
55807
|
-
return
|
|
56226
|
+
return readFileSync24(fd);
|
|
55808
56227
|
} finally {
|
|
55809
56228
|
closeSync9(fd);
|
|
55810
56229
|
}
|
|
@@ -56307,7 +56726,7 @@ class ChangeSetAuthorityService {
|
|
|
56307
56726
|
const absolute = resolve27(session.workspace.root, path);
|
|
56308
56727
|
const body = `${JSON.stringify(waiver, null, 2)}
|
|
56309
56728
|
`;
|
|
56310
|
-
const expectedHash = existsSync26(absolute) ? digestJson({ body:
|
|
56729
|
+
const expectedHash = existsSync26(absolute) ? digestJson({ body: readFileSync25(absolute, "utf8") }) : "missing";
|
|
56311
56730
|
const draft = this.changeSetEngine.plan({
|
|
56312
56731
|
id: input.id ?? `changeset.practice-waiver-${waiverId.replace(/[^A-Za-z0-9_-]/g, "-")}`,
|
|
56313
56732
|
base: {
|
|
@@ -56747,7 +57166,7 @@ function architectureLedgerWriteAppendsEvents(mode) {
|
|
|
56747
57166
|
// packages/local-runtime/runtime-daemon/src/rpc-server.ts
|
|
56748
57167
|
init_src();
|
|
56749
57168
|
import { createServer as createServer2 } from "node:http";
|
|
56750
|
-
import { closeSync as closeSync10, existsSync as existsSync27, mkdirSync as
|
|
57169
|
+
import { closeSync as closeSync10, existsSync as existsSync27, mkdirSync as mkdirSync11 } from "node:fs";
|
|
56751
57170
|
import { dirname as dirname10 } from "node:path";
|
|
56752
57171
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
56753
57172
|
var DEFAULT_DAEMON_IDLE_TIMEOUT_MS = 30 * 60000;
|
|
@@ -56818,8 +57237,8 @@ class ArchctxRuntimeRpcServer {
|
|
|
56818
57237
|
const root = this.options.root ?? process.cwd();
|
|
56819
57238
|
const connectionPath = this.options.connectionPath ?? defaultDaemonConnectionPath(root);
|
|
56820
57239
|
const lockPath = this.options.lockPath ?? defaultDaemonLockPath(root);
|
|
56821
|
-
|
|
56822
|
-
|
|
57240
|
+
mkdirSync11(dirname10(connectionPath), { recursive: true });
|
|
57241
|
+
mkdirSync11(dirname10(lockPath), { recursive: true });
|
|
56823
57242
|
this.lockFd = acquireDaemonLock(lockPath, root);
|
|
56824
57243
|
const token = this.options.token ?? randomBytes5(18).toString("base64url");
|
|
56825
57244
|
const server = createServer2((request, response) => {
|
|
@@ -57138,7 +57557,7 @@ async function readRpcRequestBody(request, limits) {
|
|
|
57138
57557
|
}
|
|
57139
57558
|
|
|
57140
57559
|
// packages/local-runtime/runtime-daemon/src/index.ts
|
|
57141
|
-
import { existsSync as existsSync28, readFileSync as
|
|
57560
|
+
import { existsSync as existsSync28, readFileSync as readFileSync26 } from "node:fs";
|
|
57142
57561
|
import { resolve as resolve28 } from "node:path";
|
|
57143
57562
|
init_src();
|
|
57144
57563
|
|
|
@@ -57333,7 +57752,7 @@ class ArchctxDaemon {
|
|
|
57333
57752
|
const model = loadNativeModelFromArchContext(root);
|
|
57334
57753
|
const canonical = renderAgentContextProjection({ model, sourceDigest: digestJson({ model }), existingFiles: loadAgentContextProjectionFiles(root, model) });
|
|
57335
57754
|
const canonicalBody = canonical.files.find((candidate) => candidate.path === file.path)?.body;
|
|
57336
|
-
if (canonicalBody === undefined || projectionOwnedWriteBody(canonicalBody,
|
|
57755
|
+
if (canonicalBody === undefined || projectionOwnedWriteBody(canonicalBody, readFileSync26(resolve28(root, file.path), "utf8")) !== file.body) {
|
|
57337
57756
|
throw new Error(`Root contract requires canonical marker-only content: ${file.path}`);
|
|
57338
57757
|
}
|
|
57339
57758
|
}
|
|
@@ -58651,8 +59070,8 @@ function isArchContextGeneratedProjectionPath2(path) {
|
|
|
58651
59070
|
|
|
58652
59071
|
// packages/surfaces/cli/src/github-review-state.ts
|
|
58653
59072
|
init_src();
|
|
58654
|
-
import { chmodSync as chmodSync6, existsSync as existsSync29, mkdirSync as
|
|
58655
|
-
import { dirname as dirname11, join as
|
|
59073
|
+
import { chmodSync as chmodSync6, existsSync as existsSync29, mkdirSync as mkdirSync12, readFileSync as readFileSync27, rmSync as rmSync13, writeFileSync as writeFileSync11 } from "node:fs";
|
|
59074
|
+
import { dirname as dirname11, join as join23 } from "node:path";
|
|
58656
59075
|
var text2 = { type: "string", minLength: 1 };
|
|
58657
59076
|
var digest2 = { type: "string", pattern: "^sha256:[0-9a-f]{64}$" };
|
|
58658
59077
|
var record7 = (properties, required = Object.keys(properties)) => ({ type: "object", additionalProperties: false, properties, required });
|
|
@@ -58683,7 +59102,7 @@ var stateSchema = record7({
|
|
|
58683
59102
|
}, ["schemaVersion", "status", "challenge", "challengeDigest", "updatedAt"]);
|
|
58684
59103
|
function defaultGithubDeveloperReviewStatePath(cwd, pullRequestNumber) {
|
|
58685
59104
|
const suffix = pullRequestNumber ? `github-developer-review-pr-${pullRequestNumber}.json` : "github-developer-review.json";
|
|
58686
|
-
return
|
|
59105
|
+
return join23(runtimeStatePaths(cwd).workspaceStateDir, suffix);
|
|
58687
59106
|
}
|
|
58688
59107
|
function metadata(state) {
|
|
58689
59108
|
const { submission, ...rest } = state;
|
|
@@ -58737,8 +59156,8 @@ async function writeGithubDeveloperReviewState(cwd, state, secrets = []) {
|
|
|
58737
59156
|
assertNoCliSecretMaterial(state.submission);
|
|
58738
59157
|
assertNoReviewSecrets(state.submission, secrets);
|
|
58739
59158
|
}
|
|
58740
|
-
|
|
58741
|
-
|
|
59159
|
+
mkdirSync12(dirname11(path), { recursive: true });
|
|
59160
|
+
writeFileSync11(path, serialized, { mode: 384 });
|
|
58742
59161
|
if (process.platform !== "win32")
|
|
58743
59162
|
chmodSync6(path, 384);
|
|
58744
59163
|
return { state: { ...validated, ...state.submission === undefined ? {} : { submission: state.submission } }, path };
|
|
@@ -58748,7 +59167,7 @@ function readGithubDeveloperReviewState(path) {
|
|
|
58748
59167
|
return;
|
|
58749
59168
|
let parsed;
|
|
58750
59169
|
try {
|
|
58751
|
-
parsed = JSON.parse(
|
|
59170
|
+
parsed = JSON.parse(readFileSync27(path, "utf8"));
|
|
58752
59171
|
} catch {
|
|
58753
59172
|
throw new Error("github-review-state-metadata-invalid");
|
|
58754
59173
|
}
|
|
@@ -58763,7 +59182,7 @@ function discardLegacyGithubDeveloperReviewState(path) {
|
|
|
58763
59182
|
return false;
|
|
58764
59183
|
let parsed;
|
|
58765
59184
|
try {
|
|
58766
|
-
parsed = JSON.parse(
|
|
59185
|
+
parsed = JSON.parse(readFileSync27(path, "utf8"));
|
|
58767
59186
|
} catch {
|
|
58768
59187
|
throw new Error("github-review-state-metadata-invalid");
|
|
58769
59188
|
}
|
|
@@ -58865,13 +59284,14 @@ function localEgressStatus2(env = process.env, live = {}) {
|
|
|
58865
59284
|
|
|
58866
59285
|
// packages/surfaces/cli/src/main.ts
|
|
58867
59286
|
import { spawn as spawn2, spawnSync as spawnSync9 } from "child_process";
|
|
58868
|
-
import { accessSync as accessSync3, closeSync as closeSync14, constants as constants3, existsSync as existsSync35, mkdirSync as
|
|
58869
|
-
import { dirname as dirname16, join as
|
|
59287
|
+
import { accessSync as accessSync3, closeSync as closeSync14, constants as constants3, existsSync as existsSync35, mkdirSync as mkdirSync17, openSync as openSync14, readFileSync as readFileSync34, rmSync as rmSync18, statSync as statSync12 } from "fs";
|
|
59288
|
+
import { dirname as dirname16, join as join28, parse, resolve as resolve37 } from "path";
|
|
58870
59289
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
58871
59290
|
|
|
58872
59291
|
// packages/contracts/src/index.ts
|
|
58873
59292
|
init_control_plane_routes();
|
|
58874
59293
|
init_architecture();
|
|
59294
|
+
init_architecture_history();
|
|
58875
59295
|
init_architecture_debt();
|
|
58876
59296
|
init_docs_anchors();
|
|
58877
59297
|
init_github_governance();
|
|
@@ -58893,12 +59313,12 @@ init_changeset_recovery();
|
|
|
58893
59313
|
|
|
58894
59314
|
// packages/core/changeset-engine/src/index.ts
|
|
58895
59315
|
init_src();
|
|
58896
|
-
import { chmodSync as chmodSync7, closeSync as closeSync11, existsSync as existsSync30, fsyncSync as fsyncSync4, lstatSync as lstatSync14, mkdirSync as
|
|
59316
|
+
import { chmodSync as chmodSync7, closeSync as closeSync11, existsSync as existsSync30, fsyncSync as fsyncSync4, lstatSync as lstatSync14, mkdirSync as mkdirSync13, openSync as openSync11, readFileSync as readFileSync28, renameSync as renameSync7, rmSync as rmSync14, writeFileSync as writeFileSync12 } from "node:fs";
|
|
58897
59317
|
import { dirname as dirname12, isAbsolute as isAbsolute7, relative as relative8, resolve as resolve29, sep as sep6 } from "node:path";
|
|
58898
59318
|
var EMPTY_PATH_SET2 = new Set;
|
|
58899
59319
|
function planManifestFieldsOperation(root, fields) {
|
|
58900
59320
|
const absolute = assertPathHasNoSymlinkSegments2(root, MANIFEST_UPDATE_PATH);
|
|
58901
|
-
const body =
|
|
59321
|
+
const body = readFileSync28(absolute, "utf8");
|
|
58902
59322
|
const operation = { op: "update_manifest_fields", path: MANIFEST_UPDATE_PATH, expectedHash: digestJson({ body }), fields };
|
|
58903
59323
|
assertManifestUpdateOperation(operation);
|
|
58904
59324
|
renderManifestFieldsUpdate(body, fields);
|
|
@@ -59006,7 +59426,7 @@ function assertAllowedArchContextPath2(root, relativePath, scope) {
|
|
|
59006
59426
|
|
|
59007
59427
|
// packages/core/architecture-domain/src/index.ts
|
|
59008
59428
|
import { createHash as createHash12 } from "node:crypto";
|
|
59009
|
-
import { readFileSync as
|
|
59429
|
+
import { readFileSync as readFileSync29, realpathSync as realpathSync10, statSync as statSync8 } from "node:fs";
|
|
59010
59430
|
import { resolve as resolve31 } from "node:path";
|
|
59011
59431
|
init_src();
|
|
59012
59432
|
var DEFAULT_IGNORES2 = new Set([
|
|
@@ -59059,7 +59479,7 @@ function computeWorktreeDigest2(root, files, options = {}) {
|
|
|
59059
59479
|
return {
|
|
59060
59480
|
path,
|
|
59061
59481
|
size: statSync8(absolute).size,
|
|
59062
|
-
digest: createHash12("sha256").update(
|
|
59482
|
+
digest: createHash12("sha256").update(readFileSync29(absolute)).digest("hex")
|
|
59063
59483
|
};
|
|
59064
59484
|
});
|
|
59065
59485
|
return digestJson(payload);
|
|
@@ -59374,7 +59794,7 @@ var UNTRUSTED_TOOL_ESCAPE_KEYS2 = new Set([
|
|
|
59374
59794
|
]);
|
|
59375
59795
|
|
|
59376
59796
|
// packages/cloud/hardening/src/index.ts
|
|
59377
|
-
import { readdirSync as readdirSync14, readFileSync as
|
|
59797
|
+
import { readdirSync as readdirSync14, readFileSync as readFileSync30, statSync as statSync9 } from "node:fs";
|
|
59378
59798
|
import { resolve as resolve32 } from "node:path";
|
|
59379
59799
|
init_src2();
|
|
59380
59800
|
init_src();
|
|
@@ -59422,7 +59842,7 @@ function uninstallMarker(content, host) {
|
|
|
59422
59842
|
`).trim();
|
|
59423
59843
|
}
|
|
59424
59844
|
function dependencyAudit(root) {
|
|
59425
|
-
const packageJson = JSON.parse(
|
|
59845
|
+
const packageJson = JSON.parse(readFileSync30(resolve32(root, "package.json"), "utf8"));
|
|
59426
59846
|
const issues = [];
|
|
59427
59847
|
if (packageJson.engines?.node !== ARCHCONTEXT_NODE_RANGE) {
|
|
59428
59848
|
issues.push(`node engine must equal ${ARCHCONTEXT_NODE_RANGE}`);
|
|
@@ -59436,7 +59856,7 @@ function secretScan(root) {
|
|
|
59436
59856
|
continue;
|
|
59437
59857
|
if (file === "packages/cloud/hardening/src/index.ts" || file.includes("/test/"))
|
|
59438
59858
|
continue;
|
|
59439
|
-
const body =
|
|
59859
|
+
const body = readFileSync30(resolve32(root, file), "utf8");
|
|
59440
59860
|
if (/(sk-[A-Za-z0-9]{20,}|ghp_[A-Za-z0-9]{20,}|BEGIN PRIVATE KEY)/.test(body))
|
|
59441
59861
|
findings.push(file);
|
|
59442
59862
|
}
|
|
@@ -59485,10 +59905,10 @@ function listFiles(root) {
|
|
|
59485
59905
|
|
|
59486
59906
|
// packages/local-runtime/local-store-sqlite/src/index.ts
|
|
59487
59907
|
init_src();
|
|
59488
|
-
import { createHash as createHash14, randomUUID as
|
|
59489
|
-
import { chmodSync as chmodSync8, closeSync as closeSync12, copyFileSync as copyFileSync2, existsSync as existsSync32, fsyncSync as fsyncSync5, lstatSync as lstatSync15, mkdirSync as
|
|
59908
|
+
import { createHash as createHash14, randomUUID as randomUUID4 } from "node:crypto";
|
|
59909
|
+
import { chmodSync as chmodSync8, closeSync as closeSync12, copyFileSync as copyFileSync2, existsSync as existsSync32, fsyncSync as fsyncSync5, lstatSync as lstatSync15, mkdirSync as mkdirSync14, openSync as openSync12, readFileSync as readFileSync31, readSync as readSync6, realpathSync as realpathSync11, renameSync as renameSync8, rmSync as rmSync15, statfsSync as statfsSync2, statSync as statSync10, writeFileSync as writeFileSync13 } from "node:fs";
|
|
59490
59910
|
import { createRequire as createRequire5 } from "node:module";
|
|
59491
|
-
import { dirname as dirname13, isAbsolute as isAbsolute9, join as
|
|
59911
|
+
import { dirname as dirname13, isAbsolute as isAbsolute9, join as join24, relative as relative10, resolve as resolve33 } from "node:path";
|
|
59492
59912
|
init_src();
|
|
59493
59913
|
var runtimeRequire2 = createRequire5(import.meta.url);
|
|
59494
59914
|
var SQLITE_SIDECAR_SUFFIXES2 = ["", "-wal", "-shm"];
|
|
@@ -60407,8 +60827,8 @@ function recoverRuntimeStateTarget(input) {
|
|
|
60407
60827
|
}
|
|
60408
60828
|
assertRuntimeStateRecoveryDaemonStopped(paths);
|
|
60409
60829
|
const lock = acquireLegacyMigrationLock2(paths);
|
|
60410
|
-
const stagingDir =
|
|
60411
|
-
const stagingPath =
|
|
60830
|
+
const stagingDir = join24(paths.workspaceStateDir, `.runtime.sqlite.recovery-${process.pid}-${randomUUID4()}`);
|
|
60831
|
+
const stagingPath = join24(stagingDir, "runtime.sqlite");
|
|
60412
60832
|
let quarantineDirectory;
|
|
60413
60833
|
let quarantineFiles = [];
|
|
60414
60834
|
let receiptPath;
|
|
@@ -60427,7 +60847,7 @@ function recoverRuntimeStateTarget(input) {
|
|
|
60427
60847
|
throw new Error(`runtime-state-recovery-target-fingerprint-mismatch:${lockedSnapshot.fingerprint}`);
|
|
60428
60848
|
}
|
|
60429
60849
|
assertRuntimeStateRecoveryDiskBudget(inspection.availableBytes, inspection.requiredFreeBytes);
|
|
60430
|
-
quarantineDirectory =
|
|
60850
|
+
quarantineDirectory = join24(paths.workspaceStateDir, "quarantine", `runtime-state-recovery-${Date.now()}-${randomUUID4()}`);
|
|
60431
60851
|
ensurePrivateDir2(quarantineDirectory);
|
|
60432
60852
|
assertRuntimeStateRecoveryPrivatePermissions(quarantineDirectory, 448);
|
|
60433
60853
|
quarantineFiles = copyRuntimeStateRecoveryFiles(lockedSnapshot.files, quarantineDirectory);
|
|
@@ -60440,7 +60860,7 @@ function recoverRuntimeStateTarget(input) {
|
|
|
60440
60860
|
assertRuntimeStateRecoveryPrivatePermissions(stagingDir, 448);
|
|
60441
60861
|
migrateSqliteDatabaseSync2(stagingPath);
|
|
60442
60862
|
const stagingIntegrity = assertCurrentLocalStore2(stagingPath);
|
|
60443
|
-
receiptPath =
|
|
60863
|
+
receiptPath = join24(quarantineDirectory, RUNTIME_STATE_RECOVERY_RECEIPT_FILE);
|
|
60444
60864
|
writeRuntimeStateRecoveryReceipt(receiptPath, {
|
|
60445
60865
|
status: "quarantine-verified",
|
|
60446
60866
|
paths,
|
|
@@ -60504,7 +60924,7 @@ function completeRuntimeStateRecovery(input) {
|
|
|
60504
60924
|
if (resolve33(input.recovery.receiptPath) !== expectedReceiptPath) {
|
|
60505
60925
|
throw new Error("runtime-state-recovery-completion-receipt-path-mismatch");
|
|
60506
60926
|
}
|
|
60507
|
-
const parsed = JSON.parse(
|
|
60927
|
+
const parsed = JSON.parse(readFileSync31(expectedReceiptPath, "utf8"));
|
|
60508
60928
|
if (parsed.schemaVersion !== "archcontext.runtime-state-recovery-receipt/v1" || parsed.status !== "target-published-rebuild-required" || parsed.targetFingerprint !== input.recovery.targetFingerprintBefore || parsed.expectedWorktreeDigest !== input.recovery.expectedWorktreeDigest) {
|
|
60509
60929
|
throw new Error("runtime-state-recovery-completion-receipt-mismatch");
|
|
60510
60930
|
}
|
|
@@ -60558,8 +60978,8 @@ function migrateLegacyLocalStoreIfNeeded2(root = process.cwd(), env = process.en
|
|
|
60558
60978
|
}
|
|
60559
60979
|
assertTrustedLegacyLocalStoreSource2(paths);
|
|
60560
60980
|
const lock = acquireLegacyMigrationLock2(paths);
|
|
60561
|
-
const stagingDir =
|
|
60562
|
-
const stagingPath =
|
|
60981
|
+
const stagingDir = join24(paths.workspaceStateDir, `.runtime.sqlite.migration-${process.pid}-${randomUUID4()}`);
|
|
60982
|
+
const stagingPath = join24(stagingDir, "runtime.sqlite");
|
|
60563
60983
|
try {
|
|
60564
60984
|
if (targetExists)
|
|
60565
60985
|
quarantinedFiles.push(...quarantineExistingLocalStore2(paths));
|
|
@@ -61295,13 +61715,13 @@ function runtimeStateRecoveryInspection(paths, migration, status, reasonCode, fi
|
|
|
61295
61715
|
};
|
|
61296
61716
|
}
|
|
61297
61717
|
function runtimeStateRecoveryStartupProbe(paths, sourceFiles) {
|
|
61298
|
-
const probeDirectory =
|
|
61299
|
-
const probePath =
|
|
61718
|
+
const probeDirectory = join24(paths.workspaceStateDir, `.runtime.sqlite.recovery-probe-${process.pid}-${randomUUID4()}`);
|
|
61719
|
+
const probePath = join24(probeDirectory, "runtime.sqlite");
|
|
61300
61720
|
try {
|
|
61301
61721
|
ensurePrivateDir2(probeDirectory);
|
|
61302
61722
|
assertRuntimeStateRecoveryPrivatePermissions(probeDirectory, 448);
|
|
61303
61723
|
for (const source of sourceFiles.filter((file) => file.name.startsWith("runtime.sqlite") && file.name !== LEGACY_MIGRATION_MARKER_FILE2)) {
|
|
61304
|
-
const target =
|
|
61724
|
+
const target = join24(probeDirectory, source.name);
|
|
61305
61725
|
copyFileSync2(source.path, target);
|
|
61306
61726
|
makePrivateFile2(target);
|
|
61307
61727
|
}
|
|
@@ -61393,7 +61813,7 @@ function runtimeStateRecoveryAvailableBytes(path) {
|
|
|
61393
61813
|
}
|
|
61394
61814
|
function copyRuntimeStateRecoveryFiles(sourceFiles, quarantineDirectory) {
|
|
61395
61815
|
return sourceFiles.map((source) => {
|
|
61396
|
-
const target =
|
|
61816
|
+
const target = join24(quarantineDirectory, source.name);
|
|
61397
61817
|
copyFileSync2(source.path, target);
|
|
61398
61818
|
makePrivateFile2(target);
|
|
61399
61819
|
assertRuntimeStateRecoveryPrivatePermissions(target, 384);
|
|
@@ -61439,7 +61859,7 @@ function removeRuntimeStateRecoveryTargetFamily(paths) {
|
|
|
61439
61859
|
}
|
|
61440
61860
|
function restoreRuntimeStateRecoveryFiles(files, paths) {
|
|
61441
61861
|
for (const file of files) {
|
|
61442
|
-
const target = file.name === LEGACY_MIGRATION_MARKER_FILE2 ? legacyMigrationMarkerPath2(paths) :
|
|
61862
|
+
const target = file.name === LEGACY_MIGRATION_MARKER_FILE2 ? legacyMigrationMarkerPath2(paths) : join24(dirname13(paths.localStorePath), file.name);
|
|
61443
61863
|
copyFileSync2(file.path, target);
|
|
61444
61864
|
makePrivateFile2(target);
|
|
61445
61865
|
fsyncFile2(target);
|
|
@@ -61607,7 +62027,7 @@ function publishStagedLocalStore2(stagingPath, targetPath) {
|
|
|
61607
62027
|
if (existsSync32(path))
|
|
61608
62028
|
throw new Error(`Cannot publish migrated SQLite over existing target file: ${path}`);
|
|
61609
62029
|
}
|
|
61610
|
-
|
|
62030
|
+
renameSync8(stagingPath, targetPath);
|
|
61611
62031
|
makePrivateFile2(targetPath);
|
|
61612
62032
|
fsyncDirectory3(dirname13(targetPath));
|
|
61613
62033
|
}
|
|
@@ -61628,7 +62048,7 @@ function acquireLegacyMigrationLock2(paths) {
|
|
|
61628
62048
|
ensurePrivateDir2(dirname13(lockPath));
|
|
61629
62049
|
try {
|
|
61630
62050
|
const fd = openSync12(lockPath, "wx", 384);
|
|
61631
|
-
|
|
62051
|
+
writeFileSync13(fd, JSON.stringify({
|
|
61632
62052
|
schemaVersion: "archcontext.legacy-local-store-migration-lock/v1",
|
|
61633
62053
|
pid: process.pid,
|
|
61634
62054
|
root: paths.repositoryRoot,
|
|
@@ -61654,7 +62074,7 @@ function releaseLegacyMigrationLock2(lock) {
|
|
|
61654
62074
|
}
|
|
61655
62075
|
function isStaleMigrationLock2(lockPath) {
|
|
61656
62076
|
try {
|
|
61657
|
-
const parsed = JSON.parse(
|
|
62077
|
+
const parsed = JSON.parse(readFileSync31(lockPath, "utf8"));
|
|
61658
62078
|
if (typeof parsed.pid !== "number" || parsed.pid <= 0)
|
|
61659
62079
|
return true;
|
|
61660
62080
|
return !isProcessAlive(parsed.pid);
|
|
@@ -61664,21 +62084,21 @@ function isStaleMigrationLock2(lockPath) {
|
|
|
61664
62084
|
}
|
|
61665
62085
|
var LOCAL_STORE_WRITER_OWNED_ERROR = "local-store-writer-owned";
|
|
61666
62086
|
function quarantineExistingLocalStore2(paths) {
|
|
61667
|
-
const quarantineDir =
|
|
62087
|
+
const quarantineDir = join24(paths.workspaceStateDir, "quarantine", `runtime.sqlite-${Date.now()}-${randomUUID4()}`);
|
|
61668
62088
|
ensurePrivateDir2(quarantineDir);
|
|
61669
62089
|
const quarantinedFiles = [];
|
|
61670
62090
|
for (const suffix of SQLITE_SIDECAR_SUFFIXES2) {
|
|
61671
62091
|
const source = `${paths.localStorePath}${suffix}`;
|
|
61672
62092
|
if (!existsSync32(source))
|
|
61673
62093
|
continue;
|
|
61674
|
-
const target =
|
|
61675
|
-
|
|
62094
|
+
const target = join24(quarantineDir, `runtime.sqlite${suffix}`);
|
|
62095
|
+
renameSync8(source, target);
|
|
61676
62096
|
quarantinedFiles.push(target);
|
|
61677
62097
|
}
|
|
61678
62098
|
const markerPath = legacyMigrationMarkerPath2(paths);
|
|
61679
62099
|
if (existsSync32(markerPath)) {
|
|
61680
|
-
const target =
|
|
61681
|
-
|
|
62100
|
+
const target = join24(quarantineDir, LEGACY_MIGRATION_MARKER_FILE2);
|
|
62101
|
+
renameSync8(markerPath, target);
|
|
61682
62102
|
quarantinedFiles.push(target);
|
|
61683
62103
|
}
|
|
61684
62104
|
fsyncDirectory3(quarantineDir);
|
|
@@ -61686,16 +62106,16 @@ function quarantineExistingLocalStore2(paths) {
|
|
|
61686
62106
|
return quarantinedFiles;
|
|
61687
62107
|
}
|
|
61688
62108
|
function legacyMigrationMarkerPath2(paths) {
|
|
61689
|
-
return
|
|
62109
|
+
return join24(paths.workspaceStateDir, LEGACY_MIGRATION_MARKER_FILE2);
|
|
61690
62110
|
}
|
|
61691
62111
|
function legacyMigrationLockPath2(paths) {
|
|
61692
|
-
return
|
|
62112
|
+
return join24(paths.workspaceStateDir, LEGACY_MIGRATION_LOCK_FILE2);
|
|
61693
62113
|
}
|
|
61694
62114
|
function writePrivateJson3(path, value) {
|
|
61695
62115
|
ensurePrivateDir2(dirname13(path));
|
|
61696
62116
|
const fd = openSync12(path, "w", 384);
|
|
61697
62117
|
try {
|
|
61698
|
-
|
|
62118
|
+
writeFileSync13(fd, JSON.stringify(value, null, 2), "utf8");
|
|
61699
62119
|
fsyncSync5(fd);
|
|
61700
62120
|
} finally {
|
|
61701
62121
|
closeSync12(fd);
|
|
@@ -61704,7 +62124,7 @@ function writePrivateJson3(path, value) {
|
|
|
61704
62124
|
fsyncDirectory3(dirname13(path));
|
|
61705
62125
|
}
|
|
61706
62126
|
function ensurePrivateDir2(path) {
|
|
61707
|
-
|
|
62127
|
+
mkdirSync14(path, { recursive: true, mode: 448 });
|
|
61708
62128
|
if (process.platform !== "win32") {
|
|
61709
62129
|
try {
|
|
61710
62130
|
chmodSync8(path, 448);
|
|
@@ -61750,8 +62170,8 @@ function isIgnorableDirectoryFsyncError3(error) {
|
|
|
61750
62170
|
|
|
61751
62171
|
// packages/local-runtime/git-adapter/src/index.ts
|
|
61752
62172
|
import { execFileSync as execFileSync10, spawnSync as spawnSync7 } from "node:child_process";
|
|
61753
|
-
import { existsSync as existsSync33, lstatSync as lstatSync16, mkdirSync as
|
|
61754
|
-
import { dirname as dirname14, join as
|
|
62173
|
+
import { existsSync as existsSync33, lstatSync as lstatSync16, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync6, readdirSync as readdirSync15, readFileSync as readFileSync32, rmSync as rmSync16 } from "node:fs";
|
|
62174
|
+
import { dirname as dirname14, join as join25, resolve as resolve34 } from "node:path";
|
|
61755
62175
|
init_src();
|
|
61756
62176
|
var GIT_CAT_FILE_MAX_BYTES2 = 512 * 1024 * 1024;
|
|
61757
62177
|
function findRepositoryRoot2(start) {
|
|
@@ -61801,7 +62221,7 @@ function listGitVisibleFiles2(root, pathspec) {
|
|
|
61801
62221
|
}
|
|
61802
62222
|
return [...new Set(output.split("\x00").filter(Boolean))].filter((path) => {
|
|
61803
62223
|
try {
|
|
61804
|
-
return lstatSync16(
|
|
62224
|
+
return lstatSync16(join25(root, path)).isFile();
|
|
61805
62225
|
} catch {
|
|
61806
62226
|
return false;
|
|
61807
62227
|
}
|
|
@@ -61821,14 +62241,14 @@ function readHeadSha2(root) {
|
|
|
61821
62241
|
|
|
61822
62242
|
// packages/local-runtime/runtime-state-paths/src/index.ts
|
|
61823
62243
|
import { readdirSync as readdirSync16, realpathSync as realpathSync12 } from "node:fs";
|
|
61824
|
-
import { isAbsolute as isAbsolute10, join as
|
|
62244
|
+
import { isAbsolute as isAbsolute10, join as join26, resolve as resolve35 } from "node:path";
|
|
61825
62245
|
var REPOSITORIES_DIR2 = "repositories";
|
|
61826
62246
|
var WORKTREES_DIR2 = "worktrees";
|
|
61827
62247
|
function listWorkspaceStateDirs2(stateRoot) {
|
|
61828
|
-
return listDirectoryNames2(
|
|
62248
|
+
return listDirectoryNames2(join26(stateRoot, REPOSITORIES_DIR2)).flatMap((storageRepositoryId) => listDirectoryNames2(join26(stateRoot, REPOSITORIES_DIR2, storageRepositoryId, WORKTREES_DIR2)).map((storageWorkspaceId) => ({
|
|
61829
62249
|
storageRepositoryId,
|
|
61830
62250
|
storageWorkspaceId,
|
|
61831
|
-
workspaceStateDir:
|
|
62251
|
+
workspaceStateDir: join26(stateRoot, REPOSITORIES_DIR2, storageRepositoryId, WORKTREES_DIR2, storageWorkspaceId)
|
|
61832
62252
|
})));
|
|
61833
62253
|
}
|
|
61834
62254
|
function listDirectoryNames2(path) {
|
|
@@ -61844,9 +62264,9 @@ function listDirectoryNames2(path) {
|
|
|
61844
62264
|
// packages/local-runtime/codegraph-adapter/src/index.ts
|
|
61845
62265
|
init_src();
|
|
61846
62266
|
import { execFileSync as execFileSync11, spawnSync as spawnSync8 } from "node:child_process";
|
|
61847
|
-
import { accessSync as accessSync2, closeSync as closeSync13, constants as fsConstants4, existsSync as existsSync34, lstatSync as lstatSync17, mkdirSync as
|
|
62267
|
+
import { accessSync as accessSync2, closeSync as closeSync13, constants as fsConstants4, existsSync as existsSync34, lstatSync as lstatSync17, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync7, openSync as openSync13, readFileSync as readFileSync33, readdirSync as readdirSync17, readSync as readSync7, realpathSync as realpathSync13, rmSync as rmSync17, statSync as statSync11, writeFileSync as writeFileSync14 } from "node:fs";
|
|
61848
62268
|
import { createRequire as createRequire6 } from "node:module";
|
|
61849
|
-
import { basename as basename7, delimiter as delimiter2, dirname as dirname15, isAbsolute as isAbsolute11, join as
|
|
62269
|
+
import { basename as basename7, delimiter as delimiter2, dirname as dirname15, isAbsolute as isAbsolute11, join as join27, posix as posix4, relative as relative11, resolve as resolve36 } from "node:path";
|
|
61850
62270
|
init_src();
|
|
61851
62271
|
var REQUIRED_CODEGRAPH_PACKAGE2 = "@colbymchenry/codegraph";
|
|
61852
62272
|
var REQUIRED_CODEGRAPH_VERSION2 = productVersionManifest().runtime.codeGraph.requiredVersion;
|
|
@@ -61883,13 +62303,13 @@ function codeGraphCliInvocation2(binary, cwd, pathValue = process.env.PATH ?? ""
|
|
|
61883
62303
|
}
|
|
61884
62304
|
function resolveExecutable2(binary, cwd, pathValue) {
|
|
61885
62305
|
if (binary.includes("/") || binary.includes("\\")) {
|
|
61886
|
-
const path = isAbsolute11(binary) ? binary :
|
|
62306
|
+
const path = isAbsolute11(binary) ? binary : join27(cwd, binary);
|
|
61887
62307
|
return existsSync34(path) ? realpathSync13.native(path) : undefined;
|
|
61888
62308
|
}
|
|
61889
62309
|
for (const dir of pathValue.split(delimiter2)) {
|
|
61890
62310
|
if (!dir)
|
|
61891
62311
|
continue;
|
|
61892
|
-
const path =
|
|
62312
|
+
const path = join27(dir, binary);
|
|
61893
62313
|
if (isExecutablePath2(path))
|
|
61894
62314
|
return realpathSync13.native(path);
|
|
61895
62315
|
}
|
|
@@ -61909,7 +62329,7 @@ function isExecutablePath2(path) {
|
|
|
61909
62329
|
function resolvePackagedCodeGraphShim2() {
|
|
61910
62330
|
try {
|
|
61911
62331
|
const manifestPath = requireFromAdapter3.resolve(`${REQUIRED_CODEGRAPH_PACKAGE2}/package.json`);
|
|
61912
|
-
const manifest = JSON.parse(
|
|
62332
|
+
const manifest = JSON.parse(readFileSync33(manifestPath, "utf8"));
|
|
61913
62333
|
const relativeBin = manifest.bin?.codegraph;
|
|
61914
62334
|
if (manifest.version !== REQUIRED_CODEGRAPH_VERSION2 || !relativeBin)
|
|
61915
62335
|
return;
|
|
@@ -61940,7 +62360,32 @@ function readFilePrefix2(path, length) {
|
|
|
61940
62360
|
}
|
|
61941
62361
|
}
|
|
61942
62362
|
var CODEGRAPH_IMPORT_NODE_OUTPUT_BYTES2 = 4 * 1024;
|
|
62363
|
+
class CodeGraphIndexBuildInProgressError2 extends Error {
|
|
62364
|
+
constructor() {
|
|
62365
|
+
super("CodeGraph index build is in progress");
|
|
62366
|
+
this.name = "CodeGraphIndexBuildInProgressError";
|
|
62367
|
+
}
|
|
62368
|
+
}
|
|
62369
|
+
function codeGraphIndexBuildInProgress2(workspaceRoot) {
|
|
62370
|
+
let raw;
|
|
62371
|
+
try {
|
|
62372
|
+
raw = readFileSync33(join27(workspaceRoot, ".codegraph", "codegraph.lock"), "utf8").trim();
|
|
62373
|
+
} catch {
|
|
62374
|
+
return false;
|
|
62375
|
+
}
|
|
62376
|
+
const pid = Number.parseInt(raw, 10);
|
|
62377
|
+
if (!Number.isSafeInteger(pid) || pid <= 0 || String(pid) !== raw)
|
|
62378
|
+
return false;
|
|
62379
|
+
try {
|
|
62380
|
+
process.kill(pid, 0);
|
|
62381
|
+
return true;
|
|
62382
|
+
} catch (error) {
|
|
62383
|
+
return error.code === "EPERM";
|
|
62384
|
+
}
|
|
62385
|
+
}
|
|
61943
62386
|
function readProjectionCodeGraphStatus2(invocation, root, timeout, envOverrides) {
|
|
62387
|
+
if (codeGraphIndexBuildInProgress2(root))
|
|
62388
|
+
throw new CodeGraphIndexBuildInProgressError2;
|
|
61944
62389
|
const output = runProjectionCodeGraph2(invocation, root, ["status", "-j", root], timeout, envOverrides);
|
|
61945
62390
|
try {
|
|
61946
62391
|
return JSON.parse(output);
|
|
@@ -62011,8 +62456,9 @@ var CODEGRAPH_SNAPSHOT_MAX_BYTES2 = 512 * 1024 * 1024;
|
|
|
62011
62456
|
var CODEGRAPH_NO_DOWNLOAD_ENV2 = { CODEGRAPH_NO_DOWNLOAD: "1" };
|
|
62012
62457
|
function inspectRepositoryCodeFacts2(root, options = {}) {
|
|
62013
62458
|
const schemaVersion = "archcontext.repository-code-facts/v1";
|
|
62014
|
-
let codeGraphVersion;
|
|
62459
|
+
let codeGraphVersion = "";
|
|
62015
62460
|
let status;
|
|
62461
|
+
let indexBuildInProgress = false;
|
|
62016
62462
|
const indexPresent = codeGraphIndexAvailable2(root);
|
|
62017
62463
|
try {
|
|
62018
62464
|
const invocation = options.binary ? codeGraphCliInvocation2(options.binary, root, "") : packagedCodeGraphCliInvocation2();
|
|
@@ -62020,18 +62466,37 @@ function inspectRepositoryCodeFacts2(root, options = {}) {
|
|
|
62020
62466
|
if (indexPresent)
|
|
62021
62467
|
status = readProjectionCodeGraphStatus2(invocation, root, options.timeouts?.statusMs ?? 1e4, CODEGRAPH_NO_DOWNLOAD_ENV2);
|
|
62022
62468
|
} catch (error) {
|
|
62023
|
-
|
|
62024
|
-
|
|
62025
|
-
|
|
62026
|
-
|
|
62027
|
-
|
|
62028
|
-
|
|
62029
|
-
|
|
62469
|
+
if (!(error instanceof CodeGraphIndexBuildInProgressError2)) {
|
|
62470
|
+
return {
|
|
62471
|
+
schemaVersion,
|
|
62472
|
+
state: "unavailable",
|
|
62473
|
+
requiredVersion: REQUIRED_CODEGRAPH_VERSION2,
|
|
62474
|
+
reasonCode: "codegraph-unavailable",
|
|
62475
|
+
message: (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 400)
|
|
62476
|
+
};
|
|
62477
|
+
}
|
|
62478
|
+
indexBuildInProgress = true;
|
|
62030
62479
|
}
|
|
62031
62480
|
const versionIssues = codeGraphVersion === REQUIRED_CODEGRAPH_VERSION2 ? [] : [{ code: "version-mismatch", message: CODE_FACTS_ISSUE_MESSAGES["version-mismatch"] }];
|
|
62032
62481
|
if (!indexPresent) {
|
|
62033
62482
|
return { schemaVersion, state: "index-missing", indexPresent: false, requiredVersion: REQUIRED_CODEGRAPH_VERSION2, codeGraphVersion, issues: versionIssues };
|
|
62034
62483
|
}
|
|
62484
|
+
if (indexBuildInProgress) {
|
|
62485
|
+
return {
|
|
62486
|
+
schemaVersion,
|
|
62487
|
+
state: "not-ready",
|
|
62488
|
+
indexPresent: true,
|
|
62489
|
+
requiredVersion: REQUIRED_CODEGRAPH_VERSION2,
|
|
62490
|
+
codeGraphVersion,
|
|
62491
|
+
indexBuiltWithVersion: null,
|
|
62492
|
+
extractionVersion: { builtWith: null, current: null },
|
|
62493
|
+
indexState: null,
|
|
62494
|
+
reindexRecommended: null,
|
|
62495
|
+
pendingRefs: null,
|
|
62496
|
+
pendingChanges: null,
|
|
62497
|
+
issues: [...versionIssues, { code: "index-incomplete", message: CODE_FACTS_ISSUE_MESSAGES["index-incomplete"] }]
|
|
62498
|
+
};
|
|
62499
|
+
}
|
|
62035
62500
|
if (typeof status !== "object" || status === null || Array.isArray(status)) {
|
|
62036
62501
|
return {
|
|
62037
62502
|
schemaVersion,
|
|
@@ -62065,7 +62530,7 @@ function inspectRepositoryCodeFacts2(root, options = {}) {
|
|
|
62065
62530
|
};
|
|
62066
62531
|
}
|
|
62067
62532
|
function codeGraphIndexAvailable2(workspaceRoot) {
|
|
62068
|
-
return existsSync34(
|
|
62533
|
+
return existsSync34(join27(workspaceRoot, ".codegraph"));
|
|
62069
62534
|
}
|
|
62070
62535
|
var NON_DECLARATION_KINDS2 = new Set(["file", "import", "export", "parameter"]);
|
|
62071
62536
|
var RUNTIME_BUILTIN_CALL_NAMES2 = new Set([
|
|
@@ -63146,6 +63611,7 @@ var CLI_COMMAND_FLAGS = {
|
|
|
63146
63611
|
repo: { value: ["--name", "--repository-id", "--root"], boolean: [] },
|
|
63147
63612
|
resolve: { value: ["--path", "--paths-from"], boolean: [] },
|
|
63148
63613
|
impact: { value: ["--base", "--head", "--depth", "--paths-from"], boolean: [] },
|
|
63614
|
+
history: { value: ["--ref", "--format", "--offset", "--limit"], boolean: [] },
|
|
63149
63615
|
review: { value: ["--head-sha", "--posture", "--task", "--task-session-id"], boolean: [] },
|
|
63150
63616
|
state: { value: ["--expected-target-fingerprint", "--expected-worktree-digest"], boolean: ["--accept-external-projection", "--dry-run", "--from-git", "--write"] },
|
|
63151
63617
|
status: { value: [], boolean: [] },
|
|
@@ -63413,6 +63879,8 @@ function runCapabilitiesCommand() {
|
|
|
63413
63879
|
async function runCliUnchecked(command = "help", args = [], cwd, deps = {}) {
|
|
63414
63880
|
if (command === "impact")
|
|
63415
63881
|
return runRefImpactCommand(args, cwd);
|
|
63882
|
+
if (command === "history")
|
|
63883
|
+
return runArchitectureHistoryCommand(args, cwd);
|
|
63416
63884
|
if (command === "export" && args[0] === "native")
|
|
63417
63885
|
return runNativeContextCommand(args.slice(1), cwd);
|
|
63418
63886
|
const preflight = preflightCliArguments(command, args);
|
|
@@ -63727,7 +64195,7 @@ async function runCliUnchecked(command = "help", args = [], cwd, deps = {}) {
|
|
|
63727
64195
|
ok: true,
|
|
63728
64196
|
requestId: "help",
|
|
63729
64197
|
data: {
|
|
63730
|
-
commands: ["capabilities", "projection", "init", "sync", "validate", "context", "status", "daemon", "state", "repo", "landscape", "ledger", "book", "recommendations", "refactor", "explore", "prepare", "practices", "checkpoint", "hook", "hooks", "investigate", "agents", "jobs", "audit", "plan", "apply", "hash", "review", "complete", "github", "manifest", "config", "mcp", "install", "uninstall", "doctor", "update", "paths", "privacy-audit", "export", "import", "resolve", "impact", "tunnel", "flows", "deps", "constraints", "debt"],
|
|
64198
|
+
commands: ["capabilities", "projection", "init", "sync", "validate", "context", "status", "daemon", "state", "repo", "landscape", "ledger", "book", "recommendations", "refactor", "explore", "prepare", "practices", "checkpoint", "hook", "hooks", "investigate", "agents", "jobs", "audit", "plan", "apply", "hash", "review", "complete", "github", "manifest", "config", "mcp", "install", "uninstall", "doctor", "update", "paths", "privacy-audit", "export", "import", "resolve", "impact", "history", "tunnel", "flows", "deps", "constraints", "debt"],
|
|
63731
64199
|
examples: CLI_HELP_EXAMPLES
|
|
63732
64200
|
}
|
|
63733
64201
|
};
|
|
@@ -65121,7 +65589,7 @@ function auditGithubIssuesEnabled(cwd) {
|
|
|
65121
65589
|
return false;
|
|
65122
65590
|
let raw;
|
|
65123
65591
|
try {
|
|
65124
|
-
raw =
|
|
65592
|
+
raw = readFileSync34(manifestPath, "utf8");
|
|
65125
65593
|
} catch {
|
|
65126
65594
|
return false;
|
|
65127
65595
|
}
|
|
@@ -65694,7 +66162,7 @@ async function digestReviewChallenge(challenge) {
|
|
|
65694
66162
|
return reviewChallengeV2Digest(challenge);
|
|
65695
66163
|
}
|
|
65696
66164
|
function defaultGithubConnectionPath(cwd) {
|
|
65697
|
-
return
|
|
66165
|
+
return join28(dirname16(defaultDaemonConnectionPath(cwd)), "github-connection.json");
|
|
65698
66166
|
}
|
|
65699
66167
|
function sanitizeGithubConnection(record, connectionPath) {
|
|
65700
66168
|
return {
|
|
@@ -65718,7 +66186,7 @@ async function readReviewChallengeV2Arg(args, cwd, commandName = "github verify-
|
|
|
65718
66186
|
if (!inline && !challengePath)
|
|
65719
66187
|
return { ok: false, message: `${commandName} requires --challenge-json or --challenge-path` };
|
|
65720
66188
|
try {
|
|
65721
|
-
const raw = inline ??
|
|
66189
|
+
const raw = inline ?? readFileSync34(resolve37(cwd, challengePath), "utf8");
|
|
65722
66190
|
const parsed = JSON.parse(raw);
|
|
65723
66191
|
const attestation = await Promise.resolve().then(() => (init_src6(), {}));
|
|
65724
66192
|
const assertReviewChallengeV2 = assertReviewChallengeV22;
|
|
@@ -66032,7 +66500,7 @@ async function doctorReport(cwd, args = []) {
|
|
|
66032
66500
|
function doctorManifest(root) {
|
|
66033
66501
|
const path = ".archcontext/manifest.yaml";
|
|
66034
66502
|
try {
|
|
66035
|
-
return { warnings: manifestDecisionDiagnostics2([{ path, body:
|
|
66503
|
+
return { warnings: manifestDecisionDiagnostics2([{ path, body: readFileSync34(resolve37(root, path), "utf8") }]) };
|
|
66036
66504
|
} catch {
|
|
66037
66505
|
return { warnings: [] };
|
|
66038
66506
|
}
|
|
@@ -66230,8 +66698,8 @@ function runtimePathsReport(cwd) {
|
|
|
66230
66698
|
...paths,
|
|
66231
66699
|
legacyLocalStore: inspectLegacyLocalStoreMigration(cwd),
|
|
66232
66700
|
runtimeRepositoryId: repositoryFingerprint2(paths.repositoryRoot),
|
|
66233
|
-
repositoryTruthDir:
|
|
66234
|
-
codeGraphIndexDir:
|
|
66701
|
+
repositoryTruthDir: join28(paths.repositoryRoot, ".archcontext"),
|
|
66702
|
+
codeGraphIndexDir: join28(paths.repositoryRoot, ".codegraph"),
|
|
66235
66703
|
npmGlobalInstallState: "forbidden",
|
|
66236
66704
|
overrides: {
|
|
66237
66705
|
stateRootEnv: "ARCHCONTEXT_STATE_DIR",
|
|
@@ -66520,8 +66988,8 @@ async function startBackgroundDaemon(args, cwd) {
|
|
|
66520
66988
|
const recovery = discovered.recovery;
|
|
66521
66989
|
const connectionPath = defaultDaemonConnectionPath(cwd);
|
|
66522
66990
|
const controlDir = dirname16(connectionPath);
|
|
66523
|
-
const logPath =
|
|
66524
|
-
|
|
66991
|
+
const logPath = join28(controlDir, "archctxd.log");
|
|
66992
|
+
mkdirSync17(controlDir, { recursive: true });
|
|
66525
66993
|
const logFd = openSync14(logPath, "a", 384);
|
|
66526
66994
|
try {
|
|
66527
66995
|
let childExit;
|
|
@@ -66845,7 +67313,7 @@ function sleep2(ms) {
|
|
|
66845
67313
|
}
|
|
66846
67314
|
function readFileTail(path, maxBytes = 4096) {
|
|
66847
67315
|
try {
|
|
66848
|
-
const content =
|
|
67316
|
+
const content = readFileSync34(path, "utf8");
|
|
66849
67317
|
return content.slice(Math.max(0, content.length - maxBytes)).replace(/\s+/g, " ").trim();
|
|
66850
67318
|
} catch {
|
|
66851
67319
|
return "<unavailable>";
|
|
@@ -66947,7 +67415,7 @@ function cliArgumentFailure(requestId, message) {
|
|
|
66947
67415
|
};
|
|
66948
67416
|
}
|
|
66949
67417
|
function loadResolveModel(cwd) {
|
|
66950
|
-
if (!existsSync35(
|
|
67418
|
+
if (!existsSync35(join28(cwd, ".archcontext/manifest.yaml"))) {
|
|
66951
67419
|
throw new NativeContextError("native-context-model-missing", { path: ".archcontext/manifest.yaml" });
|
|
66952
67420
|
}
|
|
66953
67421
|
let model;
|
|
@@ -67003,7 +67471,7 @@ async function readResolvePathsFrom(args, cwd, deps) {
|
|
|
67003
67471
|
return { problem: "resolve --paths-from requires a file path or - for stdin" };
|
|
67004
67472
|
let content;
|
|
67005
67473
|
try {
|
|
67006
|
-
content = source === "-" ? await (deps.readStdin ? deps.readStdin() :
|
|
67474
|
+
content = source === "-" ? await (deps.readStdin ? deps.readStdin() : readFileSync34(0, "utf8")) : readFileSync34(resolve37(cwd, source), "utf8");
|
|
67007
67475
|
} catch (error) {
|
|
67008
67476
|
return { problem: `resolve --paths-from ${source} is not readable: ${error instanceof Error ? error.message : String(error)}` };
|
|
67009
67477
|
}
|
|
@@ -67091,7 +67559,7 @@ function readRepositoryInputFile(cwd, flag, file) {
|
|
|
67091
67559
|
const absolute = assertPathHasNoSymlinkSegments2(cwd, file);
|
|
67092
67560
|
if (!statSync12(absolute).isFile())
|
|
67093
67561
|
return { problem: `plan ${flag} ${file} is not a regular file` };
|
|
67094
|
-
return { content:
|
|
67562
|
+
return { content: readFileSync34(absolute, "utf8") };
|
|
67095
67563
|
} catch (error) {
|
|
67096
67564
|
return { problem: `plan ${flag} ${file} is not readable: ${error instanceof Error ? error.message : String(error)}` };
|
|
67097
67565
|
}
|
|
@@ -67112,7 +67580,7 @@ function runHashCommand(args, cwd) {
|
|
|
67112
67580
|
if (!existsSync35(absolute) || !statSync12(absolute).isFile()) {
|
|
67113
67581
|
return errorEnvelope("hash", "AC_SCHEMA_INVALID", `hash --path is not an existing file: ${path}`);
|
|
67114
67582
|
}
|
|
67115
|
-
return okEnvelope("hash", { path, hash: digestJson({ body:
|
|
67583
|
+
return okEnvelope("hash", { path, hash: digestJson({ body: readFileSync34(absolute, "utf8") }) });
|
|
67116
67584
|
}
|
|
67117
67585
|
async function readCliPlanOperations(args, cwd, deps) {
|
|
67118
67586
|
if (args.includes("--operations-file")) {
|
|
@@ -67122,7 +67590,7 @@ async function readCliPlanOperations(args, cwd, deps) {
|
|
|
67122
67590
|
const file = readFlag(args, "--operations-file");
|
|
67123
67591
|
if (!file)
|
|
67124
67592
|
return "plan --operations-file requires a path";
|
|
67125
|
-
const read = file === "-" ? { content: await (deps.readStdin ? deps.readStdin() :
|
|
67593
|
+
const read = file === "-" ? { content: await (deps.readStdin ? deps.readStdin() : readFileSync34(0, "utf8")) } : readRepositoryInputFile(cwd, "--operations-file", file);
|
|
67126
67594
|
if ("problem" in read)
|
|
67127
67595
|
return read.problem;
|
|
67128
67596
|
let parsed;
|
|
@@ -67184,7 +67652,7 @@ async function readCliPlanBody(args, cwd, deps) {
|
|
|
67184
67652
|
return { problem: "plan --body requires a value (use - to read stdin)" };
|
|
67185
67653
|
if (inline !== "-")
|
|
67186
67654
|
return inline;
|
|
67187
|
-
return deps.readStdin ? deps.readStdin() :
|
|
67655
|
+
return deps.readStdin ? deps.readStdin() : readFileSync34(0, "utf8");
|
|
67188
67656
|
}
|
|
67189
67657
|
function readFlag(args, flag) {
|
|
67190
67658
|
const index = args.indexOf(flag);
|