archctx 0.9.2 → 0.9.3
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "archcontext.practice-catalog-manifest/v1",
|
|
3
3
|
"catalogVersion": "2026.06.0",
|
|
4
|
-
"productVersion": "0.9.
|
|
4
|
+
"productVersion": "0.9.3",
|
|
5
5
|
"generatedAt": "1970-01-01T00:00:00.000Z",
|
|
6
6
|
"entries": [
|
|
7
7
|
{
|
|
@@ -389,5 +389,5 @@
|
|
|
389
389
|
"structurizr.dsl",
|
|
390
390
|
"twelve-factor"
|
|
391
391
|
],
|
|
392
|
-
"catalogDigest": "sha256:
|
|
392
|
+
"catalogDigest": "sha256:4fdfbd8668e8d00e0d6f46f094a86e8e0a43075927b20b7dd5e554eab899fdcf"
|
|
393
393
|
}
|
package/bin/archctx.mjs
CHANGED
|
@@ -3462,6 +3462,9 @@ var PROJECTION_PUBLISH_RUN_SCHEMA_VERSION = "archcontext.projection-publish-run/
|
|
|
3462
3462
|
var init_projection_writer = () => {};
|
|
3463
3463
|
|
|
3464
3464
|
// packages/contracts/src/projection-manifest.ts
|
|
3465
|
+
function isRuntimeTopologyTargetType(type) {
|
|
3466
|
+
return typeof type === "string" && RUNTIME_TOPOLOGY_TARGET_TYPES.includes(type);
|
|
3467
|
+
}
|
|
3465
3468
|
function architectureDocsProjectionManifestIssues(value) {
|
|
3466
3469
|
const issues = [];
|
|
3467
3470
|
const manifest = record3(value);
|
|
@@ -3497,6 +3500,7 @@ function architectureDocsProjectionManifestIssues(value) {
|
|
|
3497
3500
|
}
|
|
3498
3501
|
const paths = new Set;
|
|
3499
3502
|
const stampOwners = new Map;
|
|
3503
|
+
let topologyStamps;
|
|
3500
3504
|
for (const [targetId, row] of Object.entries(targets)) {
|
|
3501
3505
|
const prefix = `manifest.targets[${JSON.stringify(targetId)}]`;
|
|
3502
3506
|
if (!isNonEmptyString(targetId))
|
|
@@ -3508,7 +3512,23 @@ function architectureDocsProjectionManifestIssues(value) {
|
|
|
3508
3512
|
issues.push(`${prefix}.path is recorded by another target`);
|
|
3509
3513
|
paths.add(path);
|
|
3510
3514
|
}
|
|
3511
|
-
|
|
3515
|
+
const stamps = record3(record3(row)?.sourceStamps) ?? {};
|
|
3516
|
+
if (isRuntimeTopologyTargetType(record3(row)?.type)) {
|
|
3517
|
+
const serialized = JSON.stringify(Object.keys(stamps).sort(compareStrings).map((nodeId) => [nodeId, stamps[nodeId]]));
|
|
3518
|
+
if (topologyStamps === undefined)
|
|
3519
|
+
topologyStamps = { targetId, stamps: serialized };
|
|
3520
|
+
else if (topologyStamps.stamps !== serialized)
|
|
3521
|
+
issues.push(`${prefix}.sourceStamps must equal the sourceStamps of ${topologyStamps.targetId}`);
|
|
3522
|
+
for (const nodeId of Object.keys(stamps)) {
|
|
3523
|
+
const owner = stampOwners.get(nodeId);
|
|
3524
|
+
if (owner !== undefined && !isRuntimeTopologyTargetType(record3(targets[owner])?.type))
|
|
3525
|
+
issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
|
|
3526
|
+
else if (owner === undefined)
|
|
3527
|
+
stampOwners.set(nodeId, targetId);
|
|
3528
|
+
}
|
|
3529
|
+
continue;
|
|
3530
|
+
}
|
|
3531
|
+
for (const nodeId of Object.keys(stamps)) {
|
|
3512
3532
|
const owner = stampOwners.get(nodeId);
|
|
3513
3533
|
if (owner !== undefined)
|
|
3514
3534
|
issues.push(`${prefix}.sourceStamps.${nodeId} is already stamped on ${owner}`);
|
|
@@ -3763,9 +3783,11 @@ function manifestTargetIssues(value, prefix) {
|
|
|
3763
3783
|
issues.push(`${prefix}.format is unsupported`);
|
|
3764
3784
|
if (!isDigest(target.outputDigest))
|
|
3765
3785
|
issues.push(`${prefix}.outputDigest must be a SHA-256 digest`);
|
|
3766
|
-
if (
|
|
3767
|
-
issues.push(`${prefix}.sourceStamps
|
|
3786
|
+
if (target.sourceStamps !== undefined && target.type !== "entity-summary" && !isRuntimeTopologyTargetType(target.type)) {
|
|
3787
|
+
issues.push(`${prefix}.sourceStamps are only allowed on entity-summary and runtime topology targets`);
|
|
3768
3788
|
}
|
|
3789
|
+
if (target.scale !== undefined && target.type !== "entity-summary")
|
|
3790
|
+
issues.push(`${prefix}.scale is only allowed on entity-summary targets`);
|
|
3769
3791
|
if (target.sourceStamps !== undefined) {
|
|
3770
3792
|
const stamps = record3(target.sourceStamps);
|
|
3771
3793
|
if (!stamps || Object.keys(stamps).length === 0)
|
|
@@ -3854,7 +3876,7 @@ function architectureDocsProjectionCompatibilityIssues(value, engine = {
|
|
|
3854
3876
|
}
|
|
3855
3877
|
return issues;
|
|
3856
3878
|
}
|
|
3857
|
-
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, SCOPE_KINDS, OWNERSHIPS, FORMATS;
|
|
3879
|
+
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;
|
|
3858
3880
|
var init_projection_manifest = __esm(() => {
|
|
3859
3881
|
init_projection();
|
|
3860
3882
|
init_schema();
|
|
@@ -3877,6 +3899,7 @@ var init_projection_manifest = __esm(() => {
|
|
|
3877
3899
|
"runtime-topology-summary": true,
|
|
3878
3900
|
"agent-context": true
|
|
3879
3901
|
};
|
|
3902
|
+
RUNTIME_TOPOLOGY_TARGET_TYPES = ["diagram-runtime-topology", "runtime-topology-summary"];
|
|
3880
3903
|
SCOPE_KINDS = { repository: true, entity: true, relation: true, decision: true, diagram: true, changelog: true };
|
|
3881
3904
|
OWNERSHIPS = { generated: true, mixed: true };
|
|
3882
3905
|
FORMATS = { markdown: true, mermaid: true, "structurizr-json": true, likec4: true };
|
|
@@ -3967,7 +3990,7 @@ function compareVersionTriples(left, right) {
|
|
|
3967
3990
|
}
|
|
3968
3991
|
return 0;
|
|
3969
3992
|
}
|
|
3970
|
-
var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.9.
|
|
3993
|
+
var ARCHCONTEXT_PRODUCT_NAME = "archctx", ARCHCONTEXT_PRODUCT_VERSION = "0.9.3", 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";
|
|
3971
3994
|
|
|
3972
3995
|
// packages/contracts/src/refactor.ts
|
|
3973
3996
|
function refactorNamespaceIssues(value, label = "product.id") {
|
|
@@ -17788,9 +17811,10 @@ var FIXED_TARGETS = [
|
|
|
17788
17811
|
];
|
|
17789
17812
|
var RUNTIME_TOPOLOGY_DIAGRAM_PATH = "docs/architecture/diagrams/runtime-topology.mmd";
|
|
17790
17813
|
var RUNTIME_TOPOLOGY_SUMMARY_PATH = "docs/architecture/runtime-topology.md";
|
|
17814
|
+
var RUNTIME_TOPOLOGY_SCOPE_ID = "runtime-topology";
|
|
17791
17815
|
var RUNTIME_TOPOLOGY_TARGETS = [
|
|
17792
|
-
layoutTarget("projection_target.diagram.runtime-topology", "diagram-runtime-topology", { kind: "diagram", id:
|
|
17793
|
-
layoutTarget("projection_target.runtime-topology.summary", "runtime-topology-summary", { kind: "diagram", id:
|
|
17816
|
+
layoutTarget("projection_target.diagram.runtime-topology", "diagram-runtime-topology", { kind: "diagram", id: RUNTIME_TOPOLOGY_SCOPE_ID }, RUNTIME_TOPOLOGY_DIAGRAM_PATH, "generated", "mermaid"),
|
|
17817
|
+
layoutTarget("projection_target.runtime-topology.summary", "runtime-topology-summary", { kind: "diagram", id: RUNTIME_TOPOLOGY_SCOPE_ID }, RUNTIME_TOPOLOGY_SUMMARY_PATH, "generated", "markdown")
|
|
17794
17818
|
];
|
|
17795
17819
|
function hasRuntimeTopologyNodes(nodes) {
|
|
17796
17820
|
return nodes.some((node) => isRuntimeTopologyNodeKind(node.kind));
|
|
@@ -19471,6 +19495,7 @@ function renderArchitectureDocumentationProjection(input) {
|
|
|
19471
19495
|
const rendered = targetDrafts.map((draft) => {
|
|
19472
19496
|
const existing = existingByPath.get(draft.path);
|
|
19473
19497
|
const nodeId = draft.type === "entity-summary" ? draft.scope.id : undefined;
|
|
19498
|
+
const topology = isRuntimeTopologyTargetType(draft.type);
|
|
19474
19499
|
const generatedBody = renderTargetGeneratedBody(draft, model, {
|
|
19475
19500
|
scaleSignalsByNodeId,
|
|
19476
19501
|
scaleByNodeId,
|
|
@@ -19494,6 +19519,10 @@ function renderArchitectureDocumentationProjection(input) {
|
|
|
19494
19519
|
if (scale === undefined)
|
|
19495
19520
|
throw new Error(`architecture-docs-projection-scale-signal-missing: ${nodeId}`);
|
|
19496
19521
|
}
|
|
19522
|
+
} else if (topology) {
|
|
19523
|
+
const owned = Object.keys(sourceStamps).filter((stamped) => footprintOwners.get(stamped) === RUNTIME_TOPOLOGY_SCOPE_ID);
|
|
19524
|
+
if (owned.length > 0)
|
|
19525
|
+
targetStamps = Object.fromEntries(owned.map((stamped) => [stamped, sourceStamps[stamped]]));
|
|
19497
19526
|
}
|
|
19498
19527
|
const generatedBodyDigest = digestJson({ targetId: draft.targetId, body: generatedBody });
|
|
19499
19528
|
const target = projectionTarget({
|
|
@@ -19859,6 +19888,10 @@ function architectureProjectionFootprintOwners(model, profile = "default") {
|
|
|
19859
19888
|
for (const node of [...model.nodes].sort((left, right) => compareStrings3(left.id, right.id))) {
|
|
19860
19889
|
if ((nativeNodeSource(node)?.include ?? []).length === 0)
|
|
19861
19890
|
continue;
|
|
19891
|
+
if (isRuntimeTopologyNodeKind(node.kind)) {
|
|
19892
|
+
owners.set(node.id, RUNTIME_TOPOLOGY_SCOPE_ID);
|
|
19893
|
+
continue;
|
|
19894
|
+
}
|
|
19862
19895
|
const seen = new Set;
|
|
19863
19896
|
let current = node;
|
|
19864
19897
|
while (current && !targetNodeIds.has(current.id) && !seen.has(current.id)) {
|
|
@@ -20522,7 +20555,7 @@ function renderRuntimeTopologySummary(model, summaryPath) {
|
|
|
20522
20555
|
const lines = [
|
|
20523
20556
|
"# Runtime Topology",
|
|
20524
20557
|
"",
|
|
20525
|
-
"The architecture model declares this topology. No code facts verify it.",
|
|
20558
|
+
"The architecture model declares this topology. No code facts verify it: archctx never reads the configuration it describes. A change to a file a node lists in `source.include` marks this page and its diagram stale.",
|
|
20526
20559
|
"",
|
|
20527
20560
|
`- Diagram: [Mermaid](${posix.relative(posix.dirname(summaryPath), RUNTIME_TOPOLOGY_DIAGRAM_PATH)})`,
|
|
20528
20561
|
"",
|
|
@@ -20573,6 +20606,11 @@ function renderRuntimeTopologySummary(model, summaryPath) {
|
|
|
20573
20606
|
for (const relation of otherDeployments)
|
|
20574
20607
|
lines.push(`- \`${relation.source}\` -> \`${relation.target}\` — ${relation.intent}`);
|
|
20575
20608
|
}
|
|
20609
|
+
lines.push("", "## Source Anchors", "", "| Node | Source |", "| --- | --- |");
|
|
20610
|
+
for (const node of [...view.nodesById.values()].filter((entry) => isRuntimeTopologyNodeKind(entry.kind)).sort((left, right) => compareStrings3(left.id, right.id))) {
|
|
20611
|
+
const include = nativeNodeSource(node)?.include ?? [];
|
|
20612
|
+
lines.push(`| ${named(node.id)} | ${include.length === 0 ? "model-authored, no source anchor" : include.map((pattern) => `\`${cell(pattern)}\``).join(", ")} |`);
|
|
20613
|
+
}
|
|
20576
20614
|
return `${lines.join(`
|
|
20577
20615
|
`)}
|
|
20578
20616
|
`;
|
package/package.json
CHANGED
|
@@ -332,7 +332,7 @@
|
|
|
332
332
|
},
|
|
333
333
|
"sourceStamps": {
|
|
334
334
|
"type": "object",
|
|
335
|
-
"description": "entity-summary targets only: the content digest of every declared source footprint this target documents, by node id.
|
|
335
|
+
"description": "entity-summary and runtime topology targets only: the content digest of every declared source footprint this target documents, by node id. A footprint belongs to its node's nearest ancestor-or-self with an entity-summary target, so it is stamped on exactly one entity-summary row; a runtime topology node's footprint is stamped on every runtime topology row instead, and those rows carry identical stamps (ADR-0049).",
|
|
336
336
|
"additionalProperties": {
|
|
337
337
|
"$ref": "#/$defs/digest"
|
|
338
338
|
}
|
|
@@ -360,24 +360,37 @@
|
|
|
360
360
|
"properties": {
|
|
361
361
|
"type": {
|
|
362
362
|
"not": {
|
|
363
|
-
"
|
|
363
|
+
"enum": [
|
|
364
|
+
"entity-summary",
|
|
365
|
+
"diagram-runtime-topology",
|
|
366
|
+
"runtime-topology-summary"
|
|
367
|
+
]
|
|
364
368
|
}
|
|
365
369
|
}
|
|
366
370
|
}
|
|
367
371
|
},
|
|
368
372
|
"then": {
|
|
369
373
|
"not": {
|
|
370
|
-
"
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
374
|
+
"required": [
|
|
375
|
+
"sourceStamps"
|
|
376
|
+
]
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
"if": {
|
|
382
|
+
"properties": {
|
|
383
|
+
"type": {
|
|
384
|
+
"not": {
|
|
385
|
+
"const": "entity-summary"
|
|
380
386
|
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
"then": {
|
|
391
|
+
"not": {
|
|
392
|
+
"required": [
|
|
393
|
+
"scale"
|
|
381
394
|
]
|
|
382
395
|
}
|
|
383
396
|
}
|