@archinsight/cli 3.0.0 → 3.0.1

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.
Files changed (3) hide show
  1. package/README.md +32 -10
  2. package/build/index.js +1434 -469
  3. package/package.json +3 -2
package/build/index.js CHANGED
@@ -57,7 +57,7 @@ var require_archy = __commonJS({
57
57
 
58
58
  // src/index.ts
59
59
  var import_archy = __toESM(require_archy(), 1);
60
- import { mkdir, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
60
+ import { mkdir, mkdtemp, readdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
61
61
  import path from "node:path";
62
62
  import { instance } from "@viz-js/viz";
63
63
 
@@ -22530,7 +22530,7 @@ var InsightParser = class _InsightParser extends Parser {
22530
22530
  this.state = 288;
22531
22531
  this.errorHandler.sync(this);
22532
22532
  _la = this.tokenStream.LA(1);
22533
- while ((_la & ~31) === 0 && (1 << _la & 58720512) !== 0 || (_la - 34 & ~31) === 0 && (1 << _la - 34 & 6695) !== 0) {
22533
+ while ((_la & ~31) === 0 && (1 << _la & 58720512) !== 0 || (_la - 34 & ~31) === 0 && (1 << _la - 34 & 6759) !== 0) {
22534
22534
  {
22535
22535
  {
22536
22536
  this.state = 285;
@@ -24748,10 +24748,27 @@ var InsightParser = class _InsightParser extends Parser {
24748
24748
  let localContext = new IdentifierReferenceContext(this.context, this.state);
24749
24749
  this.enterRule(localContext, 136, _InsightParser.RULE_identifierReference);
24750
24750
  try {
24751
- this.enterOuterAlt(localContext, 1);
24752
- {
24753
- this.state = 692;
24754
- this.identifier();
24751
+ this.state = 694;
24752
+ this.errorHandler.sync(this);
24753
+ switch (this.tokenStream.LA(1)) {
24754
+ case _InsightParser.PROJECT:
24755
+ case _InsightParser.PROJECTION:
24756
+ case _InsightParser.IDENTIFIER:
24757
+ this.enterOuterAlt(localContext, 1);
24758
+ {
24759
+ this.state = 692;
24760
+ this.identifier();
24761
+ }
24762
+ break;
24763
+ case _InsightParser.ANONYMOUS_ATTRIBUTE:
24764
+ this.enterOuterAlt(localContext, 2);
24765
+ {
24766
+ this.state = 693;
24767
+ this.match(_InsightParser.ANONYMOUS_ATTRIBUTE);
24768
+ }
24769
+ break;
24770
+ default:
24771
+ throw new NoViableAltException(this);
24755
24772
  }
24756
24773
  } catch (re) {
24757
24774
  if (re instanceof RecognitionException) {
@@ -24771,7 +24788,7 @@ var InsightParser = class _InsightParser extends Parser {
24771
24788
  try {
24772
24789
  this.enterOuterAlt(localContext, 1);
24773
24790
  {
24774
- this.state = 694;
24791
+ this.state = 696;
24775
24792
  this.identifier();
24776
24793
  }
24777
24794
  } catch (re) {
@@ -24792,7 +24809,7 @@ var InsightParser = class _InsightParser extends Parser {
24792
24809
  try {
24793
24810
  this.enterOuterAlt(localContext, 1);
24794
24811
  {
24795
- this.state = 696;
24812
+ this.state = 698;
24796
24813
  this.identifier();
24797
24814
  }
24798
24815
  } catch (re) {
@@ -24813,7 +24830,7 @@ var InsightParser = class _InsightParser extends Parser {
24813
24830
  try {
24814
24831
  this.enterOuterAlt(localContext, 1);
24815
24832
  {
24816
- this.state = 698;
24833
+ this.state = 700;
24817
24834
  this.identifier();
24818
24835
  }
24819
24836
  } catch (re) {
@@ -24834,7 +24851,7 @@ var InsightParser = class _InsightParser extends Parser {
24834
24851
  try {
24835
24852
  this.enterOuterAlt(localContext, 1);
24836
24853
  {
24837
- this.state = 700;
24854
+ this.state = 702;
24838
24855
  this.constructorName();
24839
24856
  }
24840
24857
  } catch (re) {
@@ -24855,7 +24872,7 @@ var InsightParser = class _InsightParser extends Parser {
24855
24872
  try {
24856
24873
  this.enterOuterAlt(localContext, 1);
24857
24874
  {
24858
- this.state = 702;
24875
+ this.state = 704;
24859
24876
  this.identifier();
24860
24877
  }
24861
24878
  } catch (re) {
@@ -24876,9 +24893,9 @@ var InsightParser = class _InsightParser extends Parser {
24876
24893
  try {
24877
24894
  this.enterOuterAlt(localContext, 1);
24878
24895
  {
24879
- this.state = 704;
24896
+ this.state = 706;
24880
24897
  this.match(_InsightParser.COMMENT);
24881
- this.state = 705;
24898
+ this.state = 707;
24882
24899
  this.match(_InsightParser.EOL);
24883
24900
  }
24884
24901
  } catch (re) {
@@ -24899,7 +24916,7 @@ var InsightParser = class _InsightParser extends Parser {
24899
24916
  try {
24900
24917
  this.enterOuterAlt(localContext, 1);
24901
24918
  {
24902
- this.state = 707;
24919
+ this.state = 709;
24903
24920
  this.match(_InsightParser.COMMENT);
24904
24921
  }
24905
24922
  } catch (re) {
@@ -24918,20 +24935,20 @@ var InsightParser = class _InsightParser extends Parser {
24918
24935
  let localContext = new TriviaContext(this.context, this.state);
24919
24936
  this.enterRule(localContext, 152, _InsightParser.RULE_trivia);
24920
24937
  try {
24921
- this.state = 711;
24938
+ this.state = 713;
24922
24939
  this.errorHandler.sync(this);
24923
24940
  switch (this.tokenStream.LA(1)) {
24924
24941
  case _InsightParser.COMMENT:
24925
24942
  this.enterOuterAlt(localContext, 1);
24926
24943
  {
24927
- this.state = 709;
24944
+ this.state = 711;
24928
24945
  this.commentLine();
24929
24946
  }
24930
24947
  break;
24931
24948
  case _InsightParser.EOL:
24932
24949
  this.enterOuterAlt(localContext, 2);
24933
24950
  {
24934
- this.state = 710;
24951
+ this.state = 712;
24935
24952
  this.match(_InsightParser.EOL);
24936
24953
  }
24937
24954
  break;
@@ -24954,7 +24971,7 @@ var InsightParser = class _InsightParser extends Parser {
24954
24971
  4,
24955
24972
  1,
24956
24973
  49,
24957
- 714,
24974
+ 716,
24958
24975
  2,
24959
24976
  0,
24960
24977
  7,
@@ -26439,6 +26456,11 @@ var InsightParser = class _InsightParser extends Parser {
26439
26456
  68,
26440
26457
  1,
26441
26458
  68,
26459
+ 3,
26460
+ 68,
26461
+ 695,
26462
+ 8,
26463
+ 68,
26442
26464
  1,
26443
26465
  69,
26444
26466
  1,
@@ -26475,7 +26497,7 @@ var InsightParser = class _InsightParser extends Parser {
26475
26497
  76,
26476
26498
  3,
26477
26499
  76,
26478
- 712,
26500
+ 714,
26479
26501
  8,
26480
26502
  76,
26481
26503
  1,
@@ -26586,7 +26608,7 @@ var InsightParser = class _InsightParser extends Parser {
26586
26608
  25,
26587
26609
  39,
26588
26610
  39,
26589
- 744,
26611
+ 747,
26590
26612
  0,
26591
26613
  157,
26592
26614
  1,
@@ -26996,55 +27018,55 @@ var InsightParser = class _InsightParser extends Parser {
26996
27018
  0,
26997
27019
  0,
26998
27020
  136,
26999
- 692,
27021
+ 694,
27000
27022
  1,
27001
27023
  0,
27002
27024
  0,
27003
27025
  0,
27004
27026
  138,
27005
- 694,
27027
+ 696,
27006
27028
  1,
27007
27029
  0,
27008
27030
  0,
27009
27031
  0,
27010
27032
  140,
27011
- 696,
27033
+ 698,
27012
27034
  1,
27013
27035
  0,
27014
27036
  0,
27015
27037
  0,
27016
27038
  142,
27017
- 698,
27039
+ 700,
27018
27040
  1,
27019
27041
  0,
27020
27042
  0,
27021
27043
  0,
27022
27044
  144,
27023
- 700,
27045
+ 702,
27024
27046
  1,
27025
27047
  0,
27026
27048
  0,
27027
27049
  0,
27028
27050
  146,
27029
- 702,
27051
+ 704,
27030
27052
  1,
27031
27053
  0,
27032
27054
  0,
27033
27055
  0,
27034
27056
  148,
27035
- 704,
27057
+ 706,
27036
27058
  1,
27037
27059
  0,
27038
27060
  0,
27039
27061
  0,
27040
27062
  150,
27041
- 707,
27063
+ 709,
27042
27064
  1,
27043
27065
  0,
27044
27066
  0,
27045
27067
  0,
27046
27068
  152,
27047
- 711,
27069
+ 713,
27048
27070
  1,
27049
27071
  0,
27050
27072
  0,
@@ -30920,25 +30942,31 @@ var InsightParser = class _InsightParser extends Parser {
30920
30942
  0,
30921
30943
  0,
30922
30944
  692,
30923
- 693,
30945
+ 695,
30924
30946
  3,
30925
30947
  122,
30926
30948
  61,
30927
30949
  0,
30928
30950
  693,
30929
- 137,
30951
+ 695,
30952
+ 5,
30953
+ 40,
30954
+ 0,
30955
+ 0,
30956
+ 694,
30957
+ 692,
30930
30958
  1,
30931
30959
  0,
30932
30960
  0,
30933
30961
  0,
30934
30962
  694,
30935
- 695,
30936
- 3,
30937
- 122,
30938
- 61,
30963
+ 693,
30964
+ 1,
30965
+ 0,
30966
+ 0,
30939
30967
  0,
30940
30968
  695,
30941
- 139,
30969
+ 137,
30942
30970
  1,
30943
30971
  0,
30944
30972
  0,
@@ -30950,7 +30978,7 @@ var InsightParser = class _InsightParser extends Parser {
30950
30978
  61,
30951
30979
  0,
30952
30980
  697,
30953
- 141,
30981
+ 139,
30954
30982
  1,
30955
30983
  0,
30956
30984
  0,
@@ -30962,7 +30990,7 @@ var InsightParser = class _InsightParser extends Parser {
30962
30990
  61,
30963
30991
  0,
30964
30992
  699,
30965
- 143,
30993
+ 141,
30966
30994
  1,
30967
30995
  0,
30968
30996
  0,
@@ -30970,11 +30998,11 @@ var InsightParser = class _InsightParser extends Parser {
30970
30998
  700,
30971
30999
  701,
30972
31000
  3,
30973
- 90,
30974
- 45,
31001
+ 122,
31002
+ 61,
30975
31003
  0,
30976
31004
  701,
30977
- 145,
31005
+ 143,
30978
31006
  1,
30979
31007
  0,
30980
31008
  0,
@@ -30982,76 +31010,88 @@ var InsightParser = class _InsightParser extends Parser {
30982
31010
  702,
30983
31011
  703,
30984
31012
  3,
30985
- 122,
30986
- 61,
31013
+ 90,
31014
+ 45,
30987
31015
  0,
30988
31016
  703,
30989
- 147,
31017
+ 145,
30990
31018
  1,
30991
31019
  0,
30992
31020
  0,
30993
31021
  0,
30994
31022
  704,
30995
31023
  705,
31024
+ 3,
31025
+ 122,
31026
+ 61,
31027
+ 0,
31028
+ 705,
31029
+ 147,
31030
+ 1,
31031
+ 0,
31032
+ 0,
31033
+ 0,
31034
+ 706,
31035
+ 707,
30996
31036
  5,
30997
31037
  46,
30998
31038
  0,
30999
31039
  0,
31000
- 705,
31001
- 706,
31040
+ 707,
31041
+ 708,
31002
31042
  5,
31003
31043
  45,
31004
31044
  0,
31005
31045
  0,
31006
- 706,
31046
+ 708,
31007
31047
  149,
31008
31048
  1,
31009
31049
  0,
31010
31050
  0,
31011
31051
  0,
31012
- 707,
31013
- 708,
31052
+ 709,
31053
+ 710,
31014
31054
  5,
31015
31055
  46,
31016
31056
  0,
31017
31057
  0,
31018
- 708,
31058
+ 710,
31019
31059
  151,
31020
31060
  1,
31021
31061
  0,
31022
31062
  0,
31023
31063
  0,
31024
- 709,
31025
- 712,
31064
+ 711,
31065
+ 714,
31026
31066
  3,
31027
31067
  148,
31028
31068
  74,
31029
31069
  0,
31030
- 710,
31031
31070
  712,
31071
+ 714,
31032
31072
  5,
31033
31073
  45,
31034
31074
  0,
31035
31075
  0,
31076
+ 713,
31036
31077
  711,
31037
- 709,
31038
31078
  1,
31039
31079
  0,
31040
31080
  0,
31041
31081
  0,
31042
- 711,
31043
- 710,
31082
+ 713,
31083
+ 712,
31044
31084
  1,
31045
31085
  0,
31046
31086
  0,
31047
31087
  0,
31048
- 712,
31088
+ 714,
31049
31089
  153,
31050
31090
  1,
31051
31091
  0,
31052
31092
  0,
31053
31093
  0,
31054
- 78,
31094
+ 79,
31055
31095
  157,
31056
31096
  162,
31057
31097
  169,
@@ -31129,7 +31169,8 @@ var InsightParser = class _InsightParser extends Parser {
31129
31169
  666,
31130
31170
  686,
31131
31171
  690,
31132
- 711
31172
+ 694,
31173
+ 713
31133
31174
  ];
31134
31175
  static __ATN;
31135
31176
  static get _ATN() {
@@ -33360,6 +33401,9 @@ var IdentifierReferenceContext = class extends ParserRuleContext {
33360
33401
  identifier() {
33361
33402
  return this.getRuleContext(0, IdentifierContext);
33362
33403
  }
33404
+ ANONYMOUS_ATTRIBUTE() {
33405
+ return this.getToken(InsightParser.ANONYMOUS_ATTRIBUTE, 0);
33406
+ }
33363
33407
  get ruleIndex() {
33364
33408
  return InsightParser.RULE_identifierReference;
33365
33409
  }
@@ -33551,6 +33595,10 @@ var TriviaContext = class extends ParserRuleContext {
33551
33595
 
33552
33596
  // ../packages/insight-language/src/generated/core-source.ts
33553
33597
  var coreSources = [
33598
+ {
33599
+ "sourceName": "core_code.ai",
33600
+ "source": "define type CodeElement of Element\n"
33601
+ },
33554
33602
  {
33555
33603
  "sourceName": "core_component.ai",
33556
33604
  "source": "define type ComponentElement of Element\n\ndefine type Component of ComponentElement\n constructor component\n\n required Text name\n Text technology\n Text responsibility\n Text description\n List of Wire links\n\n\ndefine presentation Component\n header = name\n subtitle = technology\n body = responsibility\n\n graphviz\n shape = box\n style = filled,rounded\n"
@@ -34178,7 +34226,11 @@ function validateRequiredConstructors(snapshot, diagnostics) {
34178
34226
  ));
34179
34227
  }
34180
34228
  }
34229
+ var CONSTRUCTORLESS_EXTENSION_POINT_TYPES = /* @__PURE__ */ new Set(["CodeElement"]);
34181
34230
  function requiresConstructor(snapshot, type) {
34231
+ if (CONSTRUCTORLESS_EXTENSION_POINT_TYPES.has(type)) {
34232
+ return false;
34233
+ }
34182
34234
  if (type !== "Environment" && isAssignable(snapshot, type, "Environment")) {
34183
34235
  return false;
34184
34236
  }
@@ -34894,7 +34946,7 @@ function safeId(value) {
34894
34946
  }
34895
34947
 
34896
34948
  // ../packages/insight-language/src/indexed-graph.ts
34897
- var IndexedGraph = class {
34949
+ var IndexedGraph = class _IndexedGraph {
34898
34950
  nodesById = /* @__PURE__ */ new Map();
34899
34951
  relationsById = /* @__PURE__ */ new Map();
34900
34952
  outgoingRelationsByNode = /* @__PURE__ */ new Map();
@@ -35078,6 +35130,16 @@ var IndexedGraph = class {
35078
35130
  relations() {
35079
35131
  return [...this.relationsById.values()];
35080
35132
  }
35133
+ clone() {
35134
+ const graph = new _IndexedGraph();
35135
+ for (const node of this.nodes()) {
35136
+ graph.addNode(node);
35137
+ }
35138
+ for (const relation of this.relations()) {
35139
+ graph.addRelation(relation);
35140
+ }
35141
+ return graph;
35142
+ }
35081
35143
  removeNode(nodeId2, removedNodes, removedRelations, dependentSources, removedSource) {
35082
35144
  const node = this.nodesById.get(nodeId2);
35083
35145
  if (node === void 0) {
@@ -35271,6 +35333,12 @@ function normalizeRelation(relation) {
35271
35333
 
35272
35334
  // ../packages/insight-language/src/project-linker.ts
35273
35335
  var ELEMENT_TYPE = "Element";
35336
+ var WIRE_TYPE = "Wire";
35337
+ var DEPLOYMENT_ELEMENT_TYPE = "DeploymentElement";
35338
+ var COMPONENT_ELEMENT_TYPE = "ComponentElement";
35339
+ var CONTAINER_ELEMENT_TYPE = "ContainerElement";
35340
+ var SYSTEM_TYPE = "System";
35341
+ var ACTOR_TYPE = "Actor";
35274
35342
  var ORIGINAL_LINK_OPERATOR = "originalLink";
35275
35343
  var DEPLOYMENT_PROFILE_TYPE = "DeploymentProfile";
35276
35344
  var INFRASTRUCTURE_COMPONENT_TYPE = "InfrastructureComponent";
@@ -35304,6 +35372,8 @@ function linkProject(request) {
35304
35372
  const linkedEdges = [];
35305
35373
  const ownerIndependentProjectionKeys = /* @__PURE__ */ new Set();
35306
35374
  const pendingProjections = [];
35375
+ const wireDeploymentCoverage = [];
35376
+ const deployedElementIds = /* @__PURE__ */ new Set();
35307
35377
  const linkedElementsById = /* @__PURE__ */ new Map();
35308
35378
  for (const element of elements) {
35309
35379
  linkedElementsById.set(element.id, element);
@@ -35336,6 +35406,9 @@ function linkProject(request) {
35336
35406
  continue;
35337
35407
  }
35338
35408
  const application = element.deploymentActions.length === 0 ? { deployments: [], runsOn: [], uses: [] } : resolveDeploymentApplication(element, element.deploymentActions, false, deploymentContext);
35409
+ if (application.runsOn.length > 0 || application.uses.length > 0) {
35410
+ deployedElementIds.add(element.id);
35411
+ }
35339
35412
  const inheritedDeployments = element.parent === void 0 ? [] : deploymentContext.effectiveDeploymentsByElementId.get(element.parent) ?? [];
35340
35413
  const effectiveDeployments = application.deployments.length > 0 ? application.deployments : inheritedDeployments;
35341
35414
  deploymentContext.effectiveDeploymentsByElementId.set(element.id, effectiveDeployments);
@@ -35385,6 +35458,17 @@ function linkProject(request) {
35385
35458
  diagnostics.push(...materialized.diagnostics ?? []);
35386
35459
  if (materialized.edge !== void 0) {
35387
35460
  linkedEdges.push(materialized.edge);
35461
+ const deploymentSource = deploymentViewLogicalEndpoint(edge.source, linkedElementsById, typeSystem);
35462
+ const deploymentTarget = deploymentViewLogicalEndpoint(target.id, linkedElementsById, typeSystem);
35463
+ const coverage = typeSystem.isAssignable(edgeType, WIRE_TYPE) && !typeSystem.isAssignable(edge.sourceType, DEPLOYMENT_ELEMENT_TYPE) && deploymentSource !== void 0 && deploymentTarget !== void 0 && deploymentSource !== deploymentTarget ? {
35464
+ parsed: edge,
35465
+ linked: materialized.edge,
35466
+ deploymentDefined: edge.deploymentActions.length > 0,
35467
+ projected: false
35468
+ } : void 0;
35469
+ if (coverage !== void 0) {
35470
+ wireDeploymentCoverage.push(coverage);
35471
+ }
35388
35472
  pendingProjections.push({
35389
35473
  sourceIdentity: edge.sourceName,
35390
35474
  fromId: edge.source,
@@ -35392,13 +35476,14 @@ function linkProject(request) {
35392
35476
  attributes: effectiveEdgeAttributes,
35393
35477
  projectedAttributes: materialized.edge.attributes,
35394
35478
  projectedOperator: materialized.edge.operator,
35395
- ...materialized.edge.annotations === void 0 ? {} : { annotations: materialized.edge.annotations }
35479
+ ...materialized.edge.annotations === void 0 ? {} : { annotations: materialized.edge.annotations },
35480
+ ...coverage === void 0 ? {} : { coverage }
35396
35481
  });
35397
35482
  }
35398
35483
  }
35399
35484
  }
35400
35485
  for (const projection of pendingProjections) {
35401
- addProjectedEdges(linkedEdges, projection.sourceIdentity, projection.fromId, projection.toId, projection.attributes, linkedElementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, void 0, projection.annotations, projection.projectedAttributes, projection.projectedOperator);
35486
+ addProjectedEdges(linkedEdges, projection.sourceIdentity, projection.fromId, projection.toId, projection.attributes, linkedElementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, void 0, projection.annotations, projection.projectedAttributes, projection.projectedOperator, /* @__PURE__ */ new Set(), projection.coverage);
35402
35487
  }
35403
35488
  const slotDomainTypes = typeSystem.slotDomainTypes();
35404
35489
  for (const element of elements) {
@@ -35411,7 +35496,7 @@ function linkProject(request) {
35411
35496
  const presentations = buildPresentationIndex(request.snapshot.presentations ?? [], typeSystem, diagnostics);
35412
35497
  const graph = buildIndexedGraph(documents, elements, imports, linkedEdges, typeSystem);
35413
35498
  const graphElements = elements.filter(isGraphElement);
35414
- inspectGraph(graph, graphElements, linkedEdges, resolvedElementAttributes, diagnostics);
35499
+ inspectGraph(graph, graphElements, linkedEdges, resolvedElementAttributes, typeSystem, deployedElementIds, wireDeploymentCoverage, diagnostics);
35415
35500
  const tabRoots = tabRootsBySource(documents, elementsByContextAndLocalId);
35416
35501
  for (const document of documents) {
35417
35502
  resolveAttributes(
@@ -35453,6 +35538,7 @@ function linkProject(request) {
35453
35538
  ...element.parent === void 0 ? {} : { parent: element.parent },
35454
35539
  baseTypes: typeSystem.baseTypes(element.type),
35455
35540
  attributes: flattenAttributes(element.scalarAttributes, resolvedElementAttributes.get(element.id) ?? {}),
35541
+ ...deployedElementIds.has(element.id) ? { deployed: true } : {},
35456
35542
  ...listAttributesProperty(typeSystem, element.type),
35457
35543
  ...referenceAttributesProperty(resolvedElementAttributes.get(element.id) ?? {}),
35458
35544
  ...element.note === void 0 ? {} : { note: element.note },
@@ -37168,7 +37254,7 @@ function mergeUniqueElements(left, right) {
37168
37254
  function sanitizeLocalId(value) {
37169
37255
  return value.replace(/[^A-Za-z0-9_]/g, "_");
37170
37256
  }
37171
- function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes, projectedOperator, visitedProjectionElements = /* @__PURE__ */ new Set()) {
37257
+ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes, projectedOperator, visitedProjectionElements = /* @__PURE__ */ new Set(), coverage) {
37172
37258
  for (const [attributeName, values] of Object.entries(attributes)) {
37173
37259
  if (attributeName === "_") {
37174
37260
  continue;
@@ -37205,7 +37291,7 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
37205
37291
  continue;
37206
37292
  }
37207
37293
  for (const rule3 of rules) {
37208
- addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, value.element, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2, projectedAttributes, projectedOperator);
37294
+ addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, value.element, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2, projectedAttributes, projectedOperator, coverage);
37209
37295
  }
37210
37296
  addProjectedEdges(
37211
37297
  linkedEdges,
@@ -37222,7 +37308,8 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
37222
37308
  annotations2,
37223
37309
  void 0,
37224
37310
  projectedOperator,
37225
- visitedProjectionElements
37311
+ visitedProjectionElements,
37312
+ coverage
37226
37313
  );
37227
37314
  }
37228
37315
  }
@@ -37230,7 +37317,7 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
37230
37317
  function isDirectSlotReferenceSelfProjection(element, fromId, toId) {
37231
37318
  return fromId === toId && element.parent === fromId && element.scalarAttributes.parentType !== void 0 && element.scalarAttributes.attributeName !== void 0;
37232
37319
  }
37233
- function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, projectionElement, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes, projectedOperator) {
37320
+ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, projectionElement, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes, projectedOperator, coverage) {
37234
37321
  if (!validateConcreteProjectionRule(rule3, typeSystem, diagnostics)) {
37235
37322
  return;
37236
37323
  }
@@ -37246,6 +37333,9 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
37246
37333
  );
37247
37334
  for (const source of sources) {
37248
37335
  for (const target of targets) {
37336
+ if (coverage !== void 0) {
37337
+ coverage.projected = true;
37338
+ }
37249
37339
  if (!projectionRuleUsesOwner(rule3)) {
37250
37340
  const key = `${projectionElement.id}\0${source}\0${effectiveOperator}\0${target}`;
37251
37341
  if (ownerIndependentProjectionKeys.has(key)) {
@@ -37869,12 +37959,92 @@ function unsupportedOperatorResult(operator, spelling, phase, sourceName, source
37869
37959
  }]
37870
37960
  };
37871
37961
  }
37872
- function inspectGraph(graph, elements, edges, resolvedElementAttributes, diagnostics) {
37962
+ function inspectGraph(graph, elements, edges, resolvedElementAttributes, typeSystem, deployedElementIds, wireDeploymentCoverage, diagnostics) {
37873
37963
  if (diagnostics.some((diagnostic) => diagnostic.level === void 0 || diagnostic.level === "ERROR")) {
37874
37964
  return;
37875
37965
  }
37876
37966
  reportIsolatedElements(graph, elements, edges, resolvedElementAttributes, diagnostics);
37877
37967
  reportShadowedLowerLevelEdges(graph, edges, diagnostics);
37968
+ reportIncompleteWireDeployments(wireDeploymentCoverage, diagnostics);
37969
+ reportIncompleteElementDeployments(elements, typeSystem, deployedElementIds, diagnostics);
37970
+ }
37971
+ function reportIncompleteWireDeployments(coverage, diagnostics) {
37972
+ if (!coverage.some((item) => item.deploymentDefined)) {
37973
+ return;
37974
+ }
37975
+ for (const item of coverage) {
37976
+ if (item.deploymentDefined && item.projected) {
37977
+ continue;
37978
+ }
37979
+ const source = localName(item.linked.source);
37980
+ const target = localName(item.linked.target);
37981
+ const declaration = item.linked.declaration;
37982
+ diagnostics.push({
37983
+ level: "WARNING",
37984
+ code: item.deploymentDefined ? "WIRE_DEPLOYMENT_NOT_PROJECTED" : "WIRE_MISSING_DEPLOYMENT",
37985
+ message: item.deploymentDefined ? `Wire from '${source}' to '${target}' has deployment configuration but produces no physical projection` : `Wire from '${source}' to '${target}' has no deployment configuration and is omitted from deployment views`,
37986
+ sourceName: item.parsed.sourceName,
37987
+ line: declaration?.line ?? item.parsed.line,
37988
+ column: declaration?.column ?? item.parsed.column,
37989
+ ...declaration?.endLine === void 0 ? {} : { endLine: declaration.endLine },
37990
+ ...declaration?.endColumn === void 0 ? {} : { endColumn: declaration.endColumn }
37991
+ });
37992
+ }
37993
+ }
37994
+ function reportIncompleteElementDeployments(elements, typeSystem, deployedElementIds, diagnostics) {
37995
+ const candidates = elements.flatMap((element) => {
37996
+ const family = elementDeploymentFamily(element, typeSystem);
37997
+ return family === void 0 ? [] : [{ element, family }];
37998
+ });
37999
+ const activeFamilies = new Set(candidates.filter(({ element }) => element.deploymentActions.length > 0).map(({ family }) => family));
38000
+ for (const { element, family } of candidates) {
38001
+ if (!activeFamilies.has(family) || deployedElementIds.has(element.id)) {
38002
+ continue;
38003
+ }
38004
+ diagnostics.push({
38005
+ level: "WARNING",
38006
+ code: element.deploymentActions.length > 0 ? "ELEMENT_DEPLOYMENT_NOT_PHYSICAL" : "ELEMENT_MISSING_DEPLOYMENT",
38007
+ message: element.deploymentActions.length > 0 ? `Element '${element.localId}' has deployment configuration but resolves to no physical infrastructure` : `Element '${element.localId}' has no deployment configuration and is omitted from deployment views`,
38008
+ sourceName: element.sourceName,
38009
+ ...diagnosticPosition2({
38010
+ line: element.idLine,
38011
+ column: element.idColumn,
38012
+ ...element.idEndLine === void 0 ? {} : { endLine: element.idEndLine },
38013
+ ...element.idEndColumn === void 0 ? {} : { endColumn: element.idEndColumn }
38014
+ })
38015
+ });
38016
+ }
38017
+ }
38018
+ function deploymentViewLogicalEndpoint(elementId, elementsById, typeSystem) {
38019
+ let element = elementsById.get(elementId);
38020
+ while (element !== void 0) {
38021
+ if (typeSystem.isAssignable(element.type, CONTAINER_ELEMENT_TYPE) || element.scalarAttributes.kind === "external") {
38022
+ return element.id;
38023
+ }
38024
+ element = element.parent === void 0 ? void 0 : elementsById.get(element.parent);
38025
+ }
38026
+ return void 0;
38027
+ }
38028
+ function elementDeploymentFamily(element, typeSystem) {
38029
+ if (typeSystem.isAssignable(element.type, DEPLOYMENT_ELEMENT_TYPE) || typeSystem.isAssignable(element.type, DEPLOYMENT_PROFILE_TYPE)) {
38030
+ return void 0;
38031
+ }
38032
+ if (element.scalarAttributes.kind === "external" && element.deploymentActions.length === 0) {
38033
+ return void 0;
38034
+ }
38035
+ if (typeSystem.isAssignable(element.type, COMPONENT_ELEMENT_TYPE)) {
38036
+ return COMPONENT_ELEMENT_TYPE;
38037
+ }
38038
+ if (typeSystem.isAssignable(element.type, CONTAINER_ELEMENT_TYPE)) {
38039
+ return CONTAINER_ELEMENT_TYPE;
38040
+ }
38041
+ if (typeSystem.isAssignable(element.type, ACTOR_TYPE)) {
38042
+ return ACTOR_TYPE;
38043
+ }
38044
+ if (typeSystem.isAssignable(element.type, SYSTEM_TYPE)) {
38045
+ return SYSTEM_TYPE;
38046
+ }
38047
+ return typeSystem.isAssignable(element.type, ELEMENT_TYPE) ? element.type : void 0;
37878
38048
  }
37879
38049
  function reportIsolatedElements(graph, elements, edges, resolvedElementAttributes, diagnostics) {
37880
38050
  const referenced = /* @__PURE__ */ new Set();
@@ -37982,6 +38152,14 @@ function localName(id) {
37982
38152
  return id.includes("/") ? id.slice(id.lastIndexOf("/") + 1) : id;
37983
38153
  }
37984
38154
  function resolveEdgeTarget(edge, currentContext, sourceElementsBySourceAndLocalId, elementsByContextAndLocalId, importsBySourceAndAlias, diagnostics) {
38155
+ if (edge.targetId === "_") {
38156
+ diagnostics.push(missingElement(
38157
+ edge,
38158
+ "Anonymous instance '_' cannot be referenced; give the target a named id",
38159
+ "ANONYMOUS_INSTANCE_NOT_REFERENCEABLE"
38160
+ ));
38161
+ return void 0;
38162
+ }
37985
38163
  if (edge.targetContext !== void 0) {
37986
38164
  const explicit = elementsByContextAndLocalId.get(`${edge.targetContext}\0${edge.targetId}`)?.[0];
37987
38165
  if (explicit !== void 0) {
@@ -38472,7 +38650,7 @@ function rollupMatchRows(context, inputRows, pattern, where) {
38472
38650
  if (sourceEndpoint === void 0) {
38473
38651
  continue;
38474
38652
  }
38475
- for (const targetEndpoint of rollupTargetCandidates(edge, boundRight, parentByChild)) {
38653
+ for (const targetEndpoint of rollupTargetCandidates(context, edge, boundRight, parentByChild)) {
38476
38654
  const source = queryNodeById(context.result, sourceEndpoint.id);
38477
38655
  const target = queryNodeById(context.result, targetEndpoint.id);
38478
38656
  if (source === void 0 || target === void 0) {
@@ -38482,7 +38660,7 @@ function rollupMatchRows(context, inputRows, pattern, where) {
38482
38660
  nodes: {
38483
38661
  ...row.nodes,
38484
38662
  [pattern.left.alias]: sourceEndpoint.binding,
38485
- [right.alias]: target
38663
+ [right.alias]: targetEndpoint.binding
38486
38664
  },
38487
38665
  relationships: relationship.alias === void 0 ? row.relationships : {
38488
38666
  ...row.relationships,
@@ -38493,7 +38671,7 @@ function rollupMatchRows(context, inputRows, pattern, where) {
38493
38671
  }
38494
38672
  }
38495
38673
  };
38496
- if (matchesNode(sourceEndpoint.binding, pattern.left, context) && matchesNode(target, right, context) && evaluateExpression(nextRow, where, context)) {
38674
+ if (matchesNode(sourceEndpoint.binding, pattern.left, context) && matchesNode(targetEndpoint.binding, right, context) && evaluateExpression(nextRow, where, context)) {
38497
38675
  rows.push(nextRow);
38498
38676
  break;
38499
38677
  }
@@ -38514,11 +38692,20 @@ function rollupSourceEndpoint(context, edge, pattern, bound, parentByChild) {
38514
38692
  }
38515
38693
  return nearestEndpoint(context, edge.source, pattern, void 0, parentByChild);
38516
38694
  }
38517
- function rollupTargetCandidates(edge, bound, parentByChild) {
38695
+ function rollupTargetCandidates(context, edge, bound, parentByChild) {
38518
38696
  if (bound !== void 0) {
38519
- return lineage(edge.target, parentByChild).includes(bound.id) || edgeOriginTargetLineage(edge, parentByChild).includes(bound.id) ? [{ id: bound.id }] : [];
38697
+ if (lineage(edge.target, parentByChild).includes(bound.id)) {
38698
+ return [{ id: bound.id, binding: bound }];
38699
+ }
38700
+ if (edgeOriginTargetLineage(edge, parentByChild).includes(bound.id)) {
38701
+ return queryNodeById(context.result, edge.target) === void 0 ? [] : [{ id: edge.target, binding: bound }];
38702
+ }
38703
+ return [];
38520
38704
  }
38521
- return lineage(edge.target, parentByChild).map((id) => ({ id }));
38705
+ return lineage(edge.target, parentByChild).flatMap((id) => {
38706
+ const binding = queryNodeById(context.result, id);
38707
+ return binding === void 0 ? [] : [{ id, binding }];
38708
+ });
38522
38709
  }
38523
38710
  function nearestEndpoint(context, start, pattern, where, parentByChild, binding = void 0) {
38524
38711
  for (const id of lineage(start, parentByChild)) {
@@ -38968,6 +39155,9 @@ function propertyValue(node, name) {
38968
39155
  return void 0;
38969
39156
  }
38970
39157
  const element = node.element;
39158
+ if (name === "deployed") {
39159
+ return String(element.deployed === true);
39160
+ }
38971
39161
  if (name === "id") {
38972
39162
  return element.localId;
38973
39163
  }
@@ -39528,15 +39718,49 @@ var BUILTIN_VIEW_QUERIES = {
39528
39718
  "c1": "MATCH (system:SystemElement)\nWHERE system.context = $context\nOPTIONAL MATCH (system)-[realOutboundLink]->(externalSystem:SystemElement)\nOPTIONAL MATCH (sourceSystem:SystemElement)-[realInboundLink]->(system)\nOPTIONAL MATCH (system)-[rollupOutboundLink {derived}]->(rollupSystem:SystemElement)\nOPTIONAL MATCH (rollupSourceSystem:SystemElement)-[rollupInboundLink {derived}]->(system)\nGROUP BY system.parent\nRETURN system, realOutboundLink, externalSystem, realInboundLink, sourceSystem, rollupOutboundLink, rollupSystem, rollupInboundLink, rollupSourceSystem",
39529
39719
  "c2": "MATCH (container:ContainerElement)\nWHERE container.sourceIdentity = $tab\nOPTIONAL MATCH (container)-[internalLink]->(targetContainer:ContainerElement)\nOPTIONAL MATCH (container)-[rollupOutboundLink {derived}]->(rollupContainer:ContainerElement)\nOPTIONAL MATCH (container)-[outboundLink]->(externalSystem:SystemElement)\nWHERE externalSystem IS External\nOPTIONAL MATCH (sourceSystem:SystemElement)-[inboundLink]->(container)\nWHERE sourceSystem IS External\nOPTIONAL MATCH (container)-[rollupExternalOutboundLink {derived}]->(rollupExternalSystem:SystemElement)\nWHERE rollupExternalSystem IS External\nOPTIONAL MATCH (rollupExternalSourceSystem:SystemElement)-[rollupExternalInboundLink {derived}]->(container)\nWHERE rollupExternalSourceSystem IS External\nGROUP BY container.parent\nRETURN container, internalLink, targetContainer, rollupOutboundLink, rollupContainer, outboundLink, externalSystem, inboundLink, sourceSystem, rollupExternalOutboundLink, rollupExternalSystem, rollupExternalInboundLink, rollupExternalSourceSystem",
39530
39720
  "c3": "MATCH (container:ContainerElement)-[contains:CONTAINS]->(component:ComponentElement)\nWHERE container.sourceIdentity = $tab\nOPTIONAL MATCH (component)-[link]->(targetComponent:ComponentElement)\nOPTIONAL MATCH (component)-[externalLink]->(externalSystem:SystemElement)\nWHERE externalSystem IS External\nOPTIONAL MATCH (externalSourceSystem:SystemElement)-[externalInboundLink]->(component)\nWHERE externalSourceSystem IS External\nOPTIONAL MATCH (component)-[rollupExternalLink {derived}]->(rollupExternalSystem:SystemElement)\nWHERE rollupExternalSystem IS External\nOPTIONAL MATCH (rollupExternalSourceSystem:SystemElement)-[rollupExternalInboundLink {derived}]->(component)\nWHERE rollupExternalSourceSystem IS External\nGROUP BY component.parent\nRETURN component, link, targetComponent, externalLink, externalSystem, externalInboundLink, externalSourceSystem, rollupExternalLink, rollupExternalSystem, rollupExternalInboundLink, rollupExternalSourceSystem",
39531
- "c4": "MATCH (node:Element)\nWHERE node.sourceIdentity = $tab\n AND (node IS DeploymentElement OR node IS ContainerElement OR node IS External)\nOPTIONAL MATCH (deploymentTarget:InfrastructureComponent)\nWHERE deploymentTarget IN node.uses OR deploymentTarget = node.runsOn\nOPTIONAL MATCH ROLLUP (node)-[projectedLink {projected}]->(projectedTarget:Element)\nWHERE projectedTarget IS DeploymentElement\n OR projectedTarget IS ContainerElement\n OR projectedTarget IS External\nOPTIONAL MATCH (node)-[directDeploymentLink]->(directDeploymentTarget:Element)\nWHERE node IS DeploymentElement\n AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)\nOPTIONAL MATCH (node)-[logicalPeerLink]->(logicalPeerTarget:ContainerElement)\nWHERE logicalPeerTarget.sourceIdentity <> $tab\nOPTIONAL MATCH (incomingProjectedSource:Element)-[incomingProjectedLink {projected}]->(node)\nWHERE (incomingProjectedSource IS DeploymentElement\n OR incomingProjectedSource IS ContainerElement\n OR incomingProjectedSource IS External)\n AND incomingProjectedSource.id <> node.id\nOPTIONAL MATCH ROLLUP (incomingProjectedOrigin:Element)-[incomingProjectedOriginLink {projected}]->(incomingProjectedSource)\nWHERE (incomingProjectedOrigin IS DeploymentElement\n OR incomingProjectedOrigin IS ContainerElement\n OR incomingProjectedOrigin IS External)\n AND incomingProjectedOrigin.id <> incomingProjectedSource.id\nOPTIONAL MATCH (projectedPathSource:DeploymentElement)-[projectedPathLink {projected}]->(projectedPathTarget:DeploymentElement)\nGROUP BY node.runsOn\nRETURN node, deploymentTarget, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget, logicalPeerLink, logicalPeerTarget, incomingProjectedLink, incomingProjectedSource, incomingProjectedOriginLink, incomingProjectedOrigin, projectedPathSource, projectedPathLink, projectedPathTarget"
39721
+ "c4": "MATCH (code:CodeElement)\nWHERE code.sourceIdentity = $tab\nOPTIONAL MATCH (code)-[link]->(targetCode:CodeElement)\nGROUP BY code.parent\nRETURN code, link, targetCode",
39722
+ "deployment": "MATCH (node:Element)\nWHERE node.sourceIdentity = $tab\n AND (node IS DeploymentElement\n OR ((node IS ContainerElement OR node IS External) AND node.deployed = true))\nOPTIONAL MATCH (deploymentTarget:InfrastructureComponent)\nWHERE deploymentTarget IN node.uses OR deploymentTarget = node.runsOn\nOPTIONAL MATCH ROLLUP (node)-[projectedLink {projected}]->(projectedTarget:Element)\nWHERE projectedTarget IS DeploymentElement\n OR (projectedTarget IS ContainerElement AND projectedTarget.deployed = true)\n OR projectedTarget IS External\nOPTIONAL MATCH (node)-[directDeploymentLink]->(directDeploymentTarget:Element)\nWHERE node IS DeploymentElement\n AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)\nOPTIONAL MATCH ROLLUP (incomingProjectedSource:Element)-[incomingProjectedLink {projected}]->(node)\nWHERE (incomingProjectedSource IS DeploymentElement\n OR (incomingProjectedSource IS ContainerElement AND incomingProjectedSource.deployed = true)\n OR incomingProjectedSource IS External)\n AND incomingProjectedSource.id <> node.id\nOPTIONAL MATCH (projectedPathSource:DeploymentElement)-[projectedPathLink {projected}]->(projectedPathTarget:DeploymentElement)\nGROUP BY node.runsOn\nRETURN node, deploymentTarget, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget, incomingProjectedLink, incomingProjectedSource, projectedPathSource, projectedPathLink, projectedPathTarget"
39532
39723
  };
39533
39724
 
39534
39725
  // src/version.ts
39535
- var version = "3.0.0";
39726
+ var version = "3.0.1";
39536
39727
 
39537
39728
  // src/index.ts
39538
39729
  var hiddenStructureTypes = /* @__PURE__ */ new Set(["List", "Nothing", "Text", "text"]);
39539
39730
  var viewQueries = BUILTIN_VIEW_QUERIES;
39731
+ function textFileContent(content) {
39732
+ return content.endsWith("\n") ? content : `${content}
39733
+ `;
39734
+ }
39735
+ function replaceExactlyOnce(source, expected, replacement, description) {
39736
+ const parts = source.split(expected);
39737
+ if (parts.length !== 2) {
39738
+ throw new Error(`Cannot generate ${description}: expected one matching built-in Deployment fragment, found ${parts.length - 1}`);
39739
+ }
39740
+ return `${parts[0]}${replacement}${parts[1]}`;
39741
+ }
39742
+ function deploymentInternalActorsQuery() {
39743
+ let query = viewQueries.deployment;
39744
+ query = replaceExactlyOnce(
39745
+ query,
39746
+ " OR ((node IS ContainerElement OR node IS External) AND node.deployed = true))",
39747
+ " OR ((node IS ContainerElement OR node IS External) AND node.deployed = true)\n OR node IS Actor)",
39748
+ "Deployment internal-actor query"
39749
+ );
39750
+ query = replaceExactlyOnce(
39751
+ query,
39752
+ " OR projectedTarget IS External",
39753
+ " OR projectedTarget IS External\n OR projectedTarget IS Actor",
39754
+ "Deployment internal-actor projected target filter"
39755
+ );
39756
+ query = replaceExactlyOnce(
39757
+ query,
39758
+ " OR incomingProjectedSource IS External)",
39759
+ " OR incomingProjectedSource IS External\n OR incomingProjectedSource IS Actor)",
39760
+ "Deployment internal-actor incoming source filter"
39761
+ );
39762
+ return query;
39763
+ }
39540
39764
  async function main() {
39541
39765
  const args = parseArgs(process.argv.slice(2));
39542
39766
  if (args.version) {
@@ -39667,12 +39891,54 @@ async function runSkillInit(args, skillPackage) {
39667
39891
  const projectRoot = path.resolve(projectPath(args));
39668
39892
  const usesDefaultOutput = args.output === void 0;
39669
39893
  const outputRoot = path.resolve(projectRoot, args.output ?? skillPackage.defaultOutput);
39670
- if (args.force && await exists(outputRoot)) {
39894
+ const outputExists = await exists(outputRoot);
39895
+ if (outputExists && !args.force) {
39896
+ throw new CliError(
39897
+ `Refusing to initialize skill because output directory '${outputRoot}' already exists. Pass --force to replace the complete generated skill package.`
39898
+ );
39899
+ }
39900
+ if (args.force) {
39671
39901
  assertSafeSkillOutputRoot(projectRoot, outputRoot);
39672
- await rm(outputRoot, { recursive: true, force: true });
39673
39902
  }
39674
- for (const file of skillPackage.files) {
39675
- await writeGeneratedFile(path.join(outputRoot, file.path), file.content, args.force);
39903
+ const outputParent = path.dirname(outputRoot);
39904
+ await mkdir(outputParent, { recursive: true });
39905
+ const stagingRoot = await mkdtemp(path.join(outputParent, `.${path.basename(outputRoot)}.tmp-`));
39906
+ let previousRoot;
39907
+ let installed = false;
39908
+ try {
39909
+ for (const file of skillPackage.files) {
39910
+ await writeGeneratedFile(path.join(stagingRoot, file.path), file.content);
39911
+ }
39912
+ if (!args.force && await exists(outputRoot)) {
39913
+ throw new CliError(
39914
+ `Refusing to initialize skill because output directory '${outputRoot}' was created concurrently. No generated files were installed.`
39915
+ );
39916
+ }
39917
+ if (args.force && await exists(outputRoot)) {
39918
+ previousRoot = `${stagingRoot}.previous`;
39919
+ await rename(outputRoot, previousRoot);
39920
+ }
39921
+ try {
39922
+ await rename(stagingRoot, outputRoot);
39923
+ installed = true;
39924
+ } catch (error) {
39925
+ if (previousRoot !== void 0 && !await exists(outputRoot)) {
39926
+ await rename(previousRoot, outputRoot);
39927
+ previousRoot = void 0;
39928
+ }
39929
+ throw error;
39930
+ }
39931
+ if (previousRoot !== void 0) {
39932
+ await rm(previousRoot, { recursive: true, force: true });
39933
+ previousRoot = void 0;
39934
+ }
39935
+ } finally {
39936
+ if (!installed) {
39937
+ await rm(stagingRoot, { recursive: true, force: true });
39938
+ }
39939
+ if (installed && previousRoot !== void 0 && await exists(previousRoot)) {
39940
+ await rm(previousRoot, { recursive: true, force: true });
39941
+ }
39676
39942
  }
39677
39943
  process.stdout.write(skillPackageSuccess(projectRoot, outputRoot, skillPackage, usesDefaultOutput));
39678
39944
  }
@@ -39959,9 +40225,9 @@ async function writeOutput(file, content) {
39959
40225
  await mkdir(path.dirname(path.resolve(file)), { recursive: true });
39960
40226
  await writeFile(file, content);
39961
40227
  }
39962
- async function writeGeneratedFile(file, content, force) {
39963
- if (!force && await exists(file)) {
39964
- throw new CliError(`Refusing to overwrite '${file}'. Pass --force to replace generated agent files.`);
40228
+ async function writeGeneratedFile(file, content) {
40229
+ if (await exists(file)) {
40230
+ throw new CliError(`Generated skill package contains duplicate file path '${file}'.`);
39965
40231
  }
39966
40232
  await mkdir(path.dirname(file), { recursive: true });
39967
40233
  await writeFile(file, content);
@@ -40083,7 +40349,7 @@ function viewOption(value) {
40083
40349
  if (value === void 0) {
40084
40350
  return void 0;
40085
40351
  }
40086
- if (value === "c1" || value === "c2" || value === "c3" || value === "c4" || value === "no-filter") {
40352
+ if (value === "c1" || value === "c2" || value === "c3" || value === "c4" || value === "deployment" || value === "no-filter") {
40087
40353
  return value;
40088
40354
  }
40089
40355
  throw new CliError(`Unknown view '${String(value)}'`);
@@ -40121,8 +40387,8 @@ function helpText() {
40121
40387
 
40122
40388
  Usage:
40123
40389
  archinsight link [project-dir] [--format text|json] [--out file]
40124
- archinsight render [project-dir] -c <context> [-s <source>] [-v c1|c2|c3|c4|no-filter] [-q query.aiq] [-f dot|svg|json] [-o file]
40125
- archinsight query [project-dir] -c <context> [-s <source>] [-v c1|c2|c3|c4|no-filter] [-q query.aiq] [-f text|json] [-o file]
40390
+ archinsight render [project-dir] -c <context> [-s <source>] [-v c1|c2|c3|c4|deployment|no-filter] [-q query.aiq] [-f dot|svg|json] [-o file]
40391
+ archinsight query [project-dir] -c <context> [-s <source>] [-v c1|c2|c3|c4|deployment|no-filter] [-q query.aiq] [-f text|json] [-o file]
40126
40392
  archinsight structure [project-dir] [--format text|json] [--out file]
40127
40393
  archinsight skill init [project-dir] [--target generic|codex|claude] [--out dir] [--force]
40128
40394
 
@@ -40131,13 +40397,13 @@ Options:
40131
40397
  -c, --context <id> Context id for query/render.
40132
40398
  -s, --source <file> Selected project file for queries using $tab.
40133
40399
  --tab <source> Backward-compatible alias for --source.
40134
- -v, --view <name> Built-in view: c1, c2, c3, c4, no-filter.
40400
+ -v, --view <name> Built-in view: c1, c2, c3, c4, deployment, no-filter.
40135
40401
  -q, --query <file> Query file; overrides --view.
40136
40402
  -f, --format <format> Output format.
40137
40403
  -o, --out <file> Write output to file instead of stdout; for skill init, write the guide directory.
40138
40404
  -t, --theme <theme> Render theme, default: light.
40139
40405
  --target <target> Skill target: generic, codex, or claude.
40140
- --force Delete and recreate the generated skill directory.
40406
+ --force Replace the complete generated skill directory.
40141
40407
  -V, --version Print version.
40142
40408
  -h, --help Show help.
40143
40409
 
@@ -40196,10 +40462,18 @@ function claudeSkillPackage() {
40196
40462
  }
40197
40463
  function sharedSkillFiles() {
40198
40464
  return [
40465
+ {
40466
+ path: "references/cli.md",
40467
+ content: genericCliReference()
40468
+ },
40199
40469
  {
40200
40470
  path: "references/modeling.md",
40201
40471
  content: genericModelingReference()
40202
40472
  },
40473
+ {
40474
+ path: "references/importing-models.md",
40475
+ content: genericImportingModelsReference()
40476
+ },
40203
40477
  {
40204
40478
  path: "references/syntax.md",
40205
40479
  content: genericSyntaxReference()
@@ -40221,8 +40495,12 @@ function sharedSkillFiles() {
40221
40495
  content: genericC3ComponentsReference()
40222
40496
  },
40223
40497
  {
40224
- path: "references/c4-deployment.md",
40225
- content: genericC4DeploymentReference()
40498
+ path: "references/c4-code.md",
40499
+ content: genericC4CodeReference()
40500
+ },
40501
+ {
40502
+ path: "references/deployment.md",
40503
+ content: genericDeploymentReference()
40226
40504
  },
40227
40505
  {
40228
40506
  path: "references/scaling.md",
@@ -40240,6 +40518,10 @@ function sharedSkillFiles() {
40240
40518
  path: "references/validation.md",
40241
40519
  content: genericValidationReference()
40242
40520
  },
40521
+ {
40522
+ path: "references/analysis.md",
40523
+ content: genericAnalysisReference()
40524
+ },
40243
40525
  {
40244
40526
  path: "references/queries.md",
40245
40527
  content: genericQueriesReference()
@@ -40264,42 +40546,51 @@ function sharedSkillFiles() {
40264
40546
  path: "examples/c3-components.ai",
40265
40547
  content: genericC3ComponentsExample()
40266
40548
  },
40549
+ ...genericC4CodeExampleFiles(),
40267
40550
  {
40268
- path: "examples/c4-deployment-framework.ai",
40269
- content: genericC4DeploymentFrameworkExample()
40551
+ path: "examples/deployment-framework.ai",
40552
+ content: genericDeploymentFrameworkExample()
40270
40553
  },
40271
40554
  {
40272
- path: "examples/c4-deployment-infrastructure.ai",
40273
- content: genericC4DeploymentInfrastructureExample()
40555
+ path: "examples/deployment-infrastructure.ai",
40556
+ content: genericDeploymentInfrastructureExample()
40274
40557
  },
40275
40558
  {
40276
- path: "examples/c4-deployment.ai",
40277
- content: genericC4DeploymentExample()
40559
+ path: "examples/deployment.ai",
40560
+ content: genericDeploymentExample()
40278
40561
  },
40279
- ...genericC4PrivateGatewayExampleFiles(),
40562
+ ...genericDeploymentPrivateGatewayExampleFiles(),
40280
40563
  {
40281
40564
  path: "examples/c2-containers.aiq",
40282
40565
  content: genericC2QueryExample()
40283
40566
  },
40284
40567
  {
40285
40568
  path: "examples/builtin-views/no-filter.aiq",
40286
- content: viewQueries["no-filter"]
40569
+ content: textFileContent(viewQueries["no-filter"])
40287
40570
  },
40288
40571
  {
40289
40572
  path: "examples/builtin-views/c1.aiq",
40290
- content: viewQueries.c1
40573
+ content: textFileContent(viewQueries.c1)
40291
40574
  },
40292
40575
  {
40293
40576
  path: "examples/builtin-views/c2.aiq",
40294
- content: viewQueries.c2
40577
+ content: textFileContent(viewQueries.c2)
40295
40578
  },
40296
40579
  {
40297
40580
  path: "examples/builtin-views/c3.aiq",
40298
- content: viewQueries.c3
40581
+ content: textFileContent(viewQueries.c3)
40299
40582
  },
40300
40583
  {
40301
40584
  path: "examples/builtin-views/c4.aiq",
40302
- content: viewQueries.c4
40585
+ content: textFileContent(viewQueries.c4)
40586
+ },
40587
+ {
40588
+ path: "examples/builtin-views/deployment.aiq",
40589
+ content: textFileContent(viewQueries.deployment)
40590
+ },
40591
+ {
40592
+ path: "examples/queries/deployment-internal-actors.aiq",
40593
+ content: textFileContent(deploymentInternalActorsQuery())
40303
40594
  },
40304
40595
  ...coreSkillFiles()
40305
40596
  ];
@@ -40337,42 +40628,98 @@ function skillPackageSuccess(projectRoot, outputRoot, skillPackage, usesDefaultO
40337
40628
  lines.push("");
40338
40629
  return lines.join("\n");
40339
40630
  }
40631
+ function skillCompatibilityNotice() {
40632
+ return `This package was generated by Archinsight CLI ${version}. Run
40633
+ \`archinsight --version\` before editing. If the installed version differs,
40634
+ regenerate the skill so its references, core sources, examples, and built-in
40635
+ queries match the runtime.`;
40636
+ }
40637
+ function skillReferenceRoutingGuide() {
40638
+ return `## Reference routing
40639
+
40640
+ - Read \`references/cli.md\` when the CLI is missing, its version differs from
40641
+ the generated skill, or the skill package must be regenerated.
40642
+ - Read \`references/modeling.md\` before creating or extending a
40643
+ model.
40644
+ - Read \`references/importing-models.md\` when translating an existing
40645
+ architecture description, diagram, inventory, or foreign DSL into Insight.
40646
+ - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
40647
+ - Read \`references/layered-architecture.md\` when decomposing a system across
40648
+ C1, C2, C3, C4, and Deployment views.
40649
+ - Read \`references/c1-context.md\` when working with system context models.
40650
+ - Read \`references/c2-containers.md\` when working with containers or services.
40651
+ - Read \`references/c3-components.md\` when working with component internals.
40652
+ - Infer and reuse an existing C4 Code vocabulary from the repository. Ask the
40653
+ user about entity kinds only when creating the Code layer or extending that
40654
+ vocabulary, unless the current request already makes the choice.
40655
+ - Read \`references/c4-code.md\` when defining or querying modules, packages,
40656
+ classes, functions, schemas, or other project-specific code concepts.
40657
+ - Read \`references/deployment.md\` when working with environments,
40658
+ deployments, infrastructure, placement, or projections.
40659
+ - Read \`references/scaling.md\` when splitting a repository into reusable
40660
+ framework, environment, profile, system, or view files.
40661
+ - Read \`references/project-structure.md\` before declaration lookup, imports,
40662
+ or broad file changes.
40663
+ - Read \`references/core.md\` and \`.core/*.ai\` before assuming built-in types,
40664
+ constructors, attributes, presentations, or projections.
40665
+ - Read \`references/queries.md\` before writing queries or interpreting query
40666
+ JSON.
40667
+ - Read \`references/query-recipes.md\` when a view hides expected content,
40668
+ returns unexpected content, or needs customization.
40669
+ - Read \`references/validation.md\` before validating semantic or rendered
40670
+ results.
40671
+ - Read \`references/analysis.md\` for read-only architecture analysis,
40672
+ dependency questions, impact exploration, and the boundary between Insight
40673
+ queries and analysis of their JSON output.
40674
+ - Use \`examples/layered-architecture.ai\` as a compact valid model.`;
40675
+ }
40340
40676
  function skillTaskModesGuide() {
40341
40677
  return `## Task modes
40342
40678
 
40343
40679
  Choose one mode before acting:
40344
40680
 
40345
- - **Analyze:** stay read-only. Inspect sources, run \`structure\`, \`link\`, and
40346
- the relevant query/render, then separate model, linker, query, and layout
40347
- findings with evidence.
40348
- - **Repair:** reproduce the defect first. For a visual defect, request the
40349
- current image or rendered output when it is not available. Make the smallest
40350
- model or query change and validate the same path again.
40681
+ - **Analyze:** stay read-only and follow \`references/analysis.md\`. Inspect
40682
+ sources, run \`structure\`, \`link\`, and the relevant query, then separate
40683
+ authored facts, derived relationships, deployment projections, and rendered
40684
+ presentation in the findings.
40685
+ - **Repair:** reproduce the defect first. For a visual defect, inspect
40686
+ \`archinsight query ... --format json\` before treating the image as evidence
40687
+ that the model is wrong. Request the current image or rendered output when it
40688
+ is not available, make the smallest model or query change, and validate the
40689
+ same semantic path again before rendering.
40351
40690
  - **Build or rebuild:** perform discovery before editing, then model from the
40352
40691
  outside inward and validate after each architectural layer.
40353
- - **Extend or migrate:** inventory existing ids, imports, edges, and view scope;
40354
- preserve stable identities and compare the linked/rendered result before and
40692
+ - **Extend an existing model:** inventory existing ids, imports, edges, and view
40693
+ scope; preserve stable identities and compare linked/query results before and
40355
40694
  after each focused change.
40356
-
40357
- Before any build, rebuild, or migration edit, inspect the supplied context and
40358
- ask one short, non-repetitive discovery message. Ask only for missing facts that
40359
- could materially change the model: existing descriptions, diagrams or documents,
40360
- unclear boundaries and flows, and relevant deployment constraints. Do not use a
40361
- questionnaire or ask about the audience by default. If the request already
40362
- answers everything, only invite the user to share any existing artifacts before
40363
- proceeding. Use supplied material as the source of truth; do not invent missing
40695
+ - **Import an existing model:** follow \`references/importing-models.md\`.
40696
+ Establish which source artifacts are authoritative, translate facts rather
40697
+ than drawing layout, record uncertain mappings, and validate one
40698
+ architectural layer at a time.
40699
+
40700
+ Before any build, rebuild, import, or structural edit, inspect the supplied
40701
+ context and every relevant source already available through the repository,
40702
+ attachments, configured skills, MCP integrations, or other authorized tools.
40703
+ Do not ask the user to repeat information the agent can retrieve reliably on its
40704
+ own. If a material fact is still missing after those sources are exhausted, ask
40705
+ one short, non-repetitive message containing only the one or two questions that
40706
+ could change the model. Do not use a questionnaire or ask about the audience by
40707
+ default. If the available evidence is sufficient, proceed without a discovery
40708
+ question. Use retrieved material as the source of truth; do not invent missing
40364
40709
  architecture.
40365
40710
  `;
40366
40711
  }
40367
40712
  function genericSkillGuide() {
40368
40713
  return `# Archinsight Agent Guide
40369
40714
 
40370
- Use this guide when creating, analyzing, repairing, or migrating Insight \`.ai\`
40371
- architecture models.
40715
+ Use this guide when creating, analyzing, or repairing Insight \`.ai\` models, or
40716
+ when importing an existing architecture description into Insight.
40372
40717
 
40373
40718
  Insight is its own typed architecture-as-code language. Do not infer its syntax
40374
40719
  from YAML, Mermaid, PlantUML, Structurizr, or C4 DSL.
40375
40720
 
40721
+ ${skillCompatibilityNotice()}
40722
+
40376
40723
  ## Required Tool
40377
40724
 
40378
40725
  Use the Archinsight CLI as the validation source of truth:
@@ -40382,8 +40729,8 @@ archinsight --help
40382
40729
  archinsight link . --format text
40383
40730
  \`\`\`
40384
40731
 
40385
- If \`archinsight\` is not available, ask the user to install or expose
40386
- \`@archinsight/cli\` before changing \`.ai\` files.
40732
+ If \`archinsight\` is not available, read \`references/cli.md\`. Do not install
40733
+ or update packages without the user's authorization.
40387
40734
 
40388
40735
  ${skillTaskModesGuide()}
40389
40736
 
@@ -40392,99 +40739,46 @@ ${skillTaskModesGuide()}
40392
40739
  1. Read the existing \`.ai\` files before editing.
40393
40740
  2. Preserve indentation and the project's existing naming style.
40394
40741
  3. Model architecture from the outside inward: context, external actors/systems,
40395
- systems, containers/services, components, and deployment details.
40742
+ systems, containers/services, components, project-defined code when needed,
40743
+ and deployment details.
40396
40744
  4. Do not ask about deployment depth until the task touches infrastructure,
40397
40745
  runtime placement, regions, brokers, gateways, storage, or deployment.
40398
- 5. At that point, decide per system whether pragmatic mixed C2 or clean
40399
- C4/deployment is appropriate. If modeling clean C4: attach placement/storage
40400
- to elements, attach path infrastructure that needs \`$to\` to wires, and make
40401
- pub/sub dependencies consumer-owned.
40746
+ 5. At that point, decide per system whether pragmatic mixed C2 or explicit
40747
+ deployment modeling is appropriate. For explicit deployment, attach
40748
+ placement/storage to elements, attach path infrastructure that needs \`$to\`
40749
+ to wires, and make pub/sub dependencies consumer-owned.
40402
40750
  6. If a diagram becomes noisy, adjust scope/query before changing a correct
40403
40751
  graph model.
40404
40752
  7. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
40405
40753
  8. Keep definition, context, and environment sources in separate files.
40406
40754
  9. Validate every Insight change with \`archinsight link . --format text\`.
40755
+ 10. For C2, C3, C4, Deployment, or query changes, inspect the selected graph with
40756
+ \`archinsight query ... --format json\` before rendering.
40407
40757
 
40408
- ## References
40409
-
40410
- - Read \`references/modeling.md\` before creating, migrating, or extending a
40411
- model.
40412
- - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
40413
- - Read \`references/layered-architecture.md\` when decomposing a system across
40414
- C1/C2/C3/C4-style layers.
40415
- - Read \`references/c1-context.md\` when adding or repairing system context
40416
- models: actors, owned systems, external systems, and boundary choices.
40417
- - Read \`references/c2-containers.md\` when adding or repairing
40418
- container/service-level C2 models for a selected system.
40419
- - Read \`references/c3-components.md\` when adding or repairing component-level
40420
- C3 models for a selected container or service.
40421
- - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
40422
- models, infrastructure inventories, environment-scoped infrastructure, or
40423
- projection rules.
40424
- - Read \`references/scaling.md\` when splitting a repository into reusable
40425
- framework, environment, profile, system, or deployment-view files.
40426
- - Read \`references/project-structure.md\` before searching for declarations,
40427
- planning imports, or making broad edits.
40428
- - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
40429
- attributes, presentations, or projections.
40430
- - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
40431
- files.
40432
- - Read \`references/query-recipes.md\` when a built-in view hides an expected
40433
- element/edge or needs customization.
40434
- - Read \`references/validation.md\` before running checks, structure inspection,
40435
- or rendering.
40436
- - Use \`examples/layered-architecture.ai\` as a compact valid model.
40758
+ ${skillReferenceRoutingGuide()}
40437
40759
  `;
40438
40760
  }
40439
40761
  function codexSkillGuide() {
40440
40762
  return `---
40441
40763
  name: archinsight
40442
- description: Create, edit, migrate, analyze, repair, validate, inspect, and render Archinsight Insight architecture-as-code models. Use when working with .ai Insight files, C4-style architecture models, system/container/component diagrams, deployment projections, or when the user asks to model or diagnose software architecture with Archinsight.
40764
+ description: Create, edit, import, analyze, repair, validate, inspect, and render Archinsight Insight architecture-as-code models. Use when working with .ai Insight files, migrating architecture from another DSL or diagram, C4-style architecture models, system/container/component/code diagrams, deployment projections, or when the user asks to model or diagnose software architecture with Archinsight.
40443
40765
  ---
40444
40766
 
40445
40767
  # Archinsight
40446
40768
 
40447
- Use this skill when creating, analyzing, repairing, or migrating Insight \`.ai\`
40448
- architecture models.
40769
+ Use this skill when creating, analyzing, or repairing Insight \`.ai\` models, or
40770
+ when importing an existing architecture description into Insight.
40449
40771
 
40450
40772
  Insight is its own typed architecture-as-code language. Do not infer its syntax
40451
40773
  from YAML, Mermaid, PlantUML, Structurizr, or C4 DSL.
40452
40774
 
40453
40775
  ## Codex Usage Notes
40454
40776
 
40455
- Treat this \`SKILL.md\` as the entrypoint. Load reference files only when needed:
40777
+ Treat this \`SKILL.md\` as the entrypoint and load routed reference files only
40778
+ when the task needs them. Use shell access to run validation. Do not silently
40779
+ install global npm packages or change machine configuration.
40456
40780
 
40457
- - Read \`references/modeling.md\` before creating, migrating, or extending a
40458
- model.
40459
- - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
40460
- - Read \`references/layered-architecture.md\` before decomposing a system across
40461
- C1/C2/C3/C4-style layers.
40462
- - Read \`references/c1-context.md\` before adding or repairing system context
40463
- models: actors, owned systems, external systems, and boundary choices.
40464
- - Read \`references/c2-containers.md\` before adding or repairing
40465
- container/service-level C2 models for a selected system.
40466
- - Read \`references/c3-components.md\` before adding or repairing component-level
40467
- C3 models for a selected container or service.
40468
- - Read \`references/c4-deployment.md\` before adding or repairing deployment/C4
40469
- models, infrastructure inventories, environment-scoped infrastructure, or
40470
- projection rules.
40471
- - Read \`references/scaling.md\` before splitting a repository into reusable
40472
- framework, environment, profile, system, or deployment-view files.
40473
- - Read \`references/project-structure.md\` before searching for declarations,
40474
- planning imports, or making broad edits.
40475
- - Read \`references/core.md\` and \`.core/*.ai\` before assuming available
40476
- constructors, attributes, presentations, or projections.
40477
- - Read \`references/queries.md\` before writing custom diagram queries or \`.aiq\`
40478
- files.
40479
- - Read \`references/query-recipes.md\` before customizing a built-in view or
40480
- explaining why an expected element/edge is hidden.
40481
- - Read \`references/validation.md\` before running checks, structure inspection,
40482
- or rendering commands.
40483
-
40484
- Use Codex shell access to validate changes when available. Do not silently
40485
- install global npm packages or change machine configuration. If \`archinsight\`
40486
- is missing, ask the user whether they want to install or expose
40487
- \`@archinsight/cli\`.
40781
+ ${skillCompatibilityNotice()}
40488
40782
 
40489
40783
  ## Required Tool
40490
40784
 
@@ -40495,8 +40789,8 @@ archinsight --help
40495
40789
  archinsight link . --format text
40496
40790
  \`\`\`
40497
40791
 
40498
- If \`archinsight\` is not available, ask the user to install or expose
40499
- \`@archinsight/cli\` before changing \`.ai\` files.
40792
+ If \`archinsight\` is not available, read \`references/cli.md\`. Do not install
40793
+ or update packages without the user's authorization.
40500
40794
 
40501
40795
  ${skillTaskModesGuide()}
40502
40796
 
@@ -40505,13 +40799,14 @@ ${skillTaskModesGuide()}
40505
40799
  1. Read the existing \`.ai\` files before editing.
40506
40800
  2. Preserve indentation and the project's existing naming style.
40507
40801
  3. Model architecture from the outside inward: context, external actors/systems,
40508
- systems, containers/services, components, and deployment details.
40802
+ systems, containers/services, components, project-defined code when needed,
40803
+ and deployment details.
40509
40804
  4. Do not ask about deployment depth until the task touches infrastructure,
40510
40805
  runtime placement, regions, brokers, gateways, storage, or deployment.
40511
- 5. At that point, decide per system whether pragmatic mixed C2 or clean
40512
- C4/deployment is appropriate. If modeling clean C4: attach placement/storage
40513
- to elements, attach path infrastructure that needs \`$to\` to wires, and make
40514
- pub/sub dependencies consumer-owned.
40806
+ 5. At that point, decide per system whether pragmatic mixed C2 or explicit
40807
+ deployment modeling is appropriate. For explicit deployment, attach
40808
+ placement/storage to elements, attach path infrastructure that needs \`$to\`
40809
+ to wires, and make pub/sub dependencies consumer-owned.
40515
40810
  6. If a diagram becomes noisy, adjust scope/query before changing a correct
40516
40811
  graph model.
40517
40812
  7. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
@@ -40519,90 +40814,36 @@ ${skillTaskModesGuide()}
40519
40814
  9. Use \`archinsight structure . --format text\` before broad edits when the
40520
40815
  project shape is unclear.
40521
40816
  10. Validate every Insight change with \`archinsight link . --format text\`.
40522
- 11. If validation fails, fix the first real syntax/type/linking error before
40523
- adding more model content.
40817
+ 11. For C2, C3, C4, Deployment, or query changes, inspect the selected graph with
40818
+ \`archinsight query ... --format json\` before rendering.
40819
+ 12. If validation fails, fix the first real syntax/type/linking error before
40820
+ adding more model content.
40524
40821
 
40525
- ## References
40526
-
40527
- - Read \`references/modeling.md\` before creating, migrating, or extending a
40528
- model.
40529
- - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
40530
- - Read \`references/layered-architecture.md\` when decomposing a system across
40531
- C1/C2/C3/C4-style layers.
40532
- - Read \`references/c1-context.md\` when adding or repairing system context
40533
- models: actors, owned systems, external systems, and boundary choices.
40534
- - Read \`references/c2-containers.md\` when adding or repairing
40535
- container/service-level C2 models for a selected system.
40536
- - Read \`references/c3-components.md\` when adding or repairing component-level
40537
- C3 models for a selected container or service.
40538
- - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
40539
- models, infrastructure inventories, environment-scoped infrastructure, or
40540
- projection rules.
40541
- - Read \`references/scaling.md\` when splitting a repository into reusable
40542
- framework, environment, profile, system, or deployment-view files.
40543
- - Read \`references/project-structure.md\` before searching for declarations,
40544
- planning imports, or making broad edits.
40545
- - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
40546
- attributes, presentations, or projections.
40547
- - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
40548
- files.
40549
- - Read \`references/query-recipes.md\` when a built-in view hides an expected
40550
- element/edge or needs customization.
40551
- - Read \`references/validation.md\` before running checks, structure inspection,
40552
- or rendering.
40553
- - Use \`examples/layered-architecture.ai\` as a compact valid model.
40822
+ ${skillReferenceRoutingGuide()}
40554
40823
  `;
40555
40824
  }
40556
40825
  function claudeSkillGuide() {
40557
40826
  return `---
40558
40827
  name: archinsight
40559
- description: Create, edit, migrate, analyze, repair, validate, inspect, and render Archinsight Insight architecture-as-code models. Use when working with .ai Insight files, C4-style architecture models, system/container/component diagrams, deployment projections, or when the user asks to model or diagnose software architecture with Archinsight.
40828
+ description: Create, edit, import, analyze, repair, validate, inspect, and render Archinsight Insight architecture-as-code models. Use when working with .ai Insight files, migrating architecture from another DSL or diagram, C4-style architecture models, system/container/component/code diagrams, deployment projections, or when the user asks to model or diagnose software architecture with Archinsight.
40560
40829
  ---
40561
40830
 
40562
40831
  # Archinsight
40563
40832
 
40564
- Use this skill when creating, analyzing, repairing, or migrating Insight \`.ai\`
40565
- architecture models.
40833
+ Use this skill when creating, analyzing, or repairing Insight \`.ai\` models, or
40834
+ when importing an existing architecture description into Insight.
40566
40835
 
40567
40836
  Insight is its own typed architecture-as-code language. Do not infer its syntax
40568
40837
  from YAML, Mermaid, PlantUML, Structurizr, or C4 DSL.
40569
40838
 
40570
40839
  ## Claude Usage Notes
40571
40840
 
40572
- Treat this \`SKILL.md\` as the entrypoint. Load the reference files only when
40573
- they are needed:
40841
+ Treat this \`SKILL.md\` as the entrypoint and load routed references only when
40842
+ the task needs them. With shell access, run validation directly. Without it, ask
40843
+ the user to run the exact command and paste the output. Do not silently install
40844
+ npm packages or change machine configuration.
40574
40845
 
40575
- - Read \`references/modeling.md\` before creating, migrating, or extending a
40576
- model.
40577
- - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
40578
- - Read \`references/layered-architecture.md\` before decomposing a system across
40579
- C1/C2/C3/C4-style layers.
40580
- - Read \`references/c1-context.md\` before adding or repairing system context
40581
- models: actors, owned systems, external systems, and boundary choices.
40582
- - Read \`references/c2-containers.md\` before adding or repairing
40583
- container/service-level C2 models for a selected system.
40584
- - Read \`references/c3-components.md\` before adding or repairing component-level
40585
- C3 models for a selected container or service.
40586
- - Read \`references/c4-deployment.md\` before adding or repairing deployment/C4
40587
- models, infrastructure inventories, environment-scoped infrastructure, or
40588
- projection rules.
40589
- - Read \`references/scaling.md\` before splitting a repository into reusable
40590
- framework, environment, profile, system, or deployment-view files.
40591
- - Read \`references/project-structure.md\` before searching for declarations,
40592
- planning imports, or making broad edits.
40593
- - Read \`references/core.md\` and \`.core/*.ai\` before assuming available
40594
- constructors, attributes, presentations, or projections.
40595
- - Read \`references/queries.md\` before writing custom diagram queries or \`.aiq\`
40596
- files.
40597
- - Read \`references/query-recipes.md\` before customizing a built-in view or
40598
- explaining why an expected element/edge is hidden.
40599
- - Read \`references/validation.md\` before asking the user to run validation,
40600
- structure inspection, or rendering commands.
40601
-
40602
- When Claude has direct shell access, run validation yourself. When Claude is
40603
- embedded in an editor without shell access, ask the user to run the exact command
40604
- and paste the output. Do not silently install npm packages or change machine
40605
- configuration.
40846
+ ${skillCompatibilityNotice()}
40606
40847
 
40607
40848
  ## Required Tool
40608
40849
 
@@ -40613,8 +40854,9 @@ archinsight --help
40613
40854
  archinsight link . --format text
40614
40855
  \`\`\`
40615
40856
 
40616
- If \`archinsight\` is not available in Claude's environment, ask the user to
40617
- install or expose \`@archinsight/cli\` before changing \`.ai\` files.
40857
+ If \`archinsight\` is not available in Claude's environment, read
40858
+ \`references/cli.md\`. Do not install or update packages without the user's
40859
+ authorization.
40618
40860
 
40619
40861
  ${skillTaskModesGuide()}
40620
40862
 
@@ -40623,13 +40865,14 @@ ${skillTaskModesGuide()}
40623
40865
  1. Read the existing \`.ai\` files before editing.
40624
40866
  2. Preserve indentation and the project's existing naming style.
40625
40867
  3. Model architecture from the outside inward: context, external actors/systems,
40626
- systems, containers/services, components, and deployment details.
40868
+ systems, containers/services, components, project-defined code when needed,
40869
+ and deployment details.
40627
40870
  4. Do not ask about deployment depth until the task touches infrastructure,
40628
40871
  runtime placement, regions, brokers, gateways, storage, or deployment.
40629
- 5. At that point, decide per system whether pragmatic mixed C2 or clean
40630
- C4/deployment is appropriate. If modeling clean C4: attach placement/storage
40631
- to elements, attach path infrastructure that needs \`$to\` to wires, and make
40632
- pub/sub dependencies consumer-owned.
40872
+ 5. At that point, decide per system whether pragmatic mixed C2 or explicit
40873
+ deployment modeling is appropriate. For explicit deployment, attach
40874
+ placement/storage to elements, attach path infrastructure that needs \`$to\`
40875
+ to wires, and make pub/sub dependencies consumer-owned.
40633
40876
  6. If a diagram becomes noisy, adjust scope/query before changing a correct
40634
40877
  graph model.
40635
40878
  7. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
@@ -40638,7 +40881,9 @@ ${skillTaskModesGuide()}
40638
40881
  before broad edits when the CLI is available.
40639
40882
  10. Validate every Insight change with \`archinsight link . --format text\` when
40640
40883
  shell access is available; otherwise ask the user to run validation.
40641
- 11. If validation fails, fix the first real syntax/type/linking error before
40884
+ 11. For C2, C3, C4, Deployment, or query changes, inspect the selected graph with
40885
+ \`archinsight query ... --format json\` before rendering.
40886
+ 12. If validation fails, fix the first real syntax/type/linking error before
40642
40887
  adding more model content.
40643
40888
 
40644
40889
  ## Communication
@@ -40660,35 +40905,7 @@ archinsight render . -c <context-id> -s <source.ai> -v c2 -f svg -o diagram.svg
40660
40905
  Report diagnostics by source, line, column, and message. Avoid rewriting large
40661
40906
  sections of Insight unless the existing layering is already understood.
40662
40907
 
40663
- ## References
40664
-
40665
- - Read \`references/modeling.md\` before creating, migrating, or extending a
40666
- model.
40667
- - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
40668
- - Read \`references/layered-architecture.md\` when decomposing a system across
40669
- C1/C2/C3/C4-style layers.
40670
- - Read \`references/c1-context.md\` when adding or repairing system context
40671
- models: actors, owned systems, external systems, and boundary choices.
40672
- - Read \`references/c2-containers.md\` when adding or repairing
40673
- container/service-level C2 models for a selected system.
40674
- - Read \`references/c3-components.md\` when adding or repairing component-level
40675
- C3 models for a selected container or service.
40676
- - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
40677
- models, infrastructure inventories, environment-scoped infrastructure, or
40678
- projection rules.
40679
- - Read \`references/scaling.md\` when splitting a repository into reusable
40680
- framework, environment, profile, system, or deployment-view files.
40681
- - Read \`references/project-structure.md\` before searching for declarations,
40682
- planning imports, or making broad edits.
40683
- - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
40684
- attributes, presentations, or projections.
40685
- - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
40686
- files.
40687
- - Read \`references/query-recipes.md\` when a built-in view hides an expected
40688
- element/edge or needs customization.
40689
- - Read \`references/validation.md\` before running checks, structure inspection,
40690
- or rendering.
40691
- - Use \`examples/layered-architecture.ai\` as a compact valid model.
40908
+ ${skillReferenceRoutingGuide()}
40692
40909
  `;
40693
40910
  }
40694
40911
  function codexOpenAiYaml() {
@@ -40701,6 +40918,85 @@ policy:
40701
40918
  allow_implicit_invocation: true
40702
40919
  `;
40703
40920
  }
40921
+ function genericCliReference() {
40922
+ return `# CLI Installation, Updates, and Skill Regeneration
40923
+
40924
+ The generated skill uses the Archinsight CLI as its parser, linker, query
40925
+ runtime, and validation authority. Check the available command before editing:
40926
+
40927
+ \`\`\`shell
40928
+ archinsight --version
40929
+ archinsight --help
40930
+ \`\`\`
40931
+
40932
+ Do not silently install or update the CLI. Package installation changes the
40933
+ developer environment or the project's dependency manifest and lockfile. Use an
40934
+ existing installation when possible; otherwise ask the user to authorize the
40935
+ appropriate installation method.
40936
+
40937
+ ## Project-Local Installation
40938
+
40939
+ Prefer a project-local dependency when the repository already manages Node.js
40940
+ developer tools this way. Respect its package manager and lockfile. For an npm
40941
+ project, the user can install or update the current release with:
40942
+
40943
+ \`\`\`shell
40944
+ npm install --save-dev @archinsight/cli@latest
40945
+ npm exec -- archinsight --version
40946
+ \`\`\`
40947
+
40948
+ Use the equivalent command for pnpm or Yarn when that package manager owns the
40949
+ repository. Do not introduce a second lockfile merely to install Archinsight.
40950
+
40951
+ ## Global Installation
40952
+
40953
+ A user who wants the \`archinsight\` command available across projects can
40954
+ install or update it globally:
40955
+
40956
+ \`\`\`shell
40957
+ npm install -g @archinsight/cli@latest
40958
+ archinsight --version
40959
+ \`\`\`
40960
+
40961
+ Global installation is a user-level machine change. Suggest it as an option;
40962
+ run it only when the user explicitly authorizes that installation scope.
40963
+
40964
+ ## Generate a New Skill Package
40965
+
40966
+ Choose the target used by the agent runtime:
40967
+
40968
+ \`\`\`shell
40969
+ archinsight skill init . --target codex
40970
+ archinsight skill init . --target claude
40971
+ archinsight skill init . --target generic
40972
+ \`\`\`
40973
+
40974
+ Without \`--out\`, these commands use the target's standard directory. A normal
40975
+ \`skill init\` requires that the complete output directory does not exist. If it
40976
+ does exist, the CLI reports \`Refusing to initialize skill because output
40977
+ directory ... already exists\` before writing any generated file.
40978
+
40979
+ ## Regenerate an Existing Skill Package
40980
+
40981
+ Use \`--force\` only for deliberate replacement of a generated package:
40982
+
40983
+ \`\`\`shell
40984
+ archinsight skill init . --target codex --force
40985
+ \`\`\`
40986
+
40987
+ The CLI generates the complete new package in a temporary sibling directory
40988
+ before replacing the target. \`--force\` removes everything under the target
40989
+ directory, including files not generated by the current release. Inspect the
40990
+ resolved target first and keep project-authored instructions outside that
40991
+ generated directory. Use \`--out <dedicated-directory>\` when the standard path
40992
+ is not appropriate.
40993
+
40994
+ Never update a generated skill by running plain \`skill init\` repeatedly or by
40995
+ copying only the files that happen to be missing. Regenerate the entire package
40996
+ with the installed CLI, then restart the agent session when its runtime discovers
40997
+ skills only at startup.
40998
+ `;
40999
+ }
40704
41000
  function genericModelingReference() {
40705
41001
  return `# Modeling Guidance
40706
41002
 
@@ -40715,8 +41011,8 @@ Keep language/framework definitions separate from graph model files.
40715
41011
  \`define enum of\`, \`define presentation\`, \`extend type\`,
40716
41012
  \`extend enum of\`, and \`extend presentation\`.
40717
41013
  - Context files begin with \`context <id>\` and describe logical architecture.
40718
- - Environment files begin with \`environment <id>\` and describe concrete
40719
- deployments and infrastructure inventory.
41014
+ - Environment files begin with exactly one \`environment <id>\`, followed by
41015
+ one or more concrete deployments and their infrastructure inventory.
40720
41016
 
40721
41017
  Each source has one role. Do not mix definitions, a context, and an environment
40722
41018
  in one file. Put shared vocabulary in framework files, logical objects and
@@ -40727,9 +41023,9 @@ source-level syntax failures.
40727
41023
  ## Model Source Granularity
40728
41024
 
40729
41025
  Default to one primary owned system per model source file: the system you are
40730
- about to detail with containers, services, components, and deployment
40731
- relationships. This keeps the selected source file useful as a C2/C3/C4 view
40732
- scope and avoids accidental mega-files.
41026
+ about to detail with containers, services, components, code, and deployment
41027
+ relationships. This keeps the selected source file useful as a C2, C3, C4, or
41028
+ Deployment view scope and avoids accidental mega-files.
40733
41029
 
40734
41030
  Do not create one file per external actor or external system. Shared external
40735
41031
  dependencies are usually better modeled once in a reusable external context, or
@@ -40744,19 +41040,19 @@ context.
40744
41040
 
40745
41041
  ## Projections Are Bottom-Up
40746
41042
 
40747
- Built-in C1/C2/C3/C4 views are selected from the linked model. They are not
40748
- separate diagrams to author by hand.
41043
+ Built-in C1, C2, C3, C4, and Deployment views are selected from the linked model.
41044
+ They are not separate diagrams to author by hand.
40749
41045
 
40750
41046
  - C1 is context-oriented and can aggregate lower-level relationships upward.
40751
- - C2, C3, and C4 are usually scoped by the selected source file through
41047
+ - C2, C3, C4, and Deployment are usually scoped by the selected source file through
40752
41048
  \`--source\` / \`$tab\`.
40753
41049
  - A file often has one focal system, container, or deployment slice for the view
40754
41050
  it is meant to render, but the exact scope is determined by the query used for
40755
41051
  visualization.
40756
41052
  - Do not try to reconstruct a deeper view from a broader one. C1 carries too
40757
- little information to recreate C2/C3 details.
41053
+ little information to recreate C2, C3, or C4 details.
40758
41054
 
40759
- If an element is missing from a C2/C3/C4 render, first check the query, selected
41055
+ If an element is missing from a C2, C3, C4, or Deployment render, first check the query, selected
40760
41056
  source file, and relationship level before assuming the model is wrong.
40761
41057
 
40762
41058
  ## Keep Relationship Levels Deliberate
@@ -40799,6 +41095,8 @@ type hierarchy:
40799
41095
  - Built-in containers/services live under systems because \`System\` declares
40800
41096
  \`List of Container _\`.
40801
41097
  - Components live where the relevant container/service type allows them.
41098
+ - Project-defined code types derive from \`CodeElement\` and live where the
41099
+ project framework exposes compatible component or code-element slots.
40802
41100
  - Custom project types can change the available constructors and allowed child
40803
41101
  slots; inspect them before writing.
40804
41102
 
@@ -40807,28 +41105,28 @@ than forcing a link or inventing a wrapper element.
40807
41105
 
40808
41106
  ## Choose Infrastructure Depth Per System
40809
41107
 
40810
- Do not force every project into C4/deployment on the first pass. Most modeling
41108
+ Do not force every project into deployment on the first pass. Most modeling
40811
41109
  work can proceed through C1-C3 without asking about deployment depth. When the
40812
41110
  task first touches infrastructure, runtime placement, regions, compute, brokers,
40813
41111
  gateways, storage, or deployment, ask the user or infer from the repository
40814
41112
  whether the affected system needs a pragmatic mixed C2 view or a clean
40815
- C4/deployment model.
41113
+ deployment model.
40816
41114
 
40817
41115
  Pragmatic mixed C2 is fast: model databases, brokers, gateways, or secret stores
40818
41116
  next to services when the user wants a quick single-environment diagram. The
40819
- cost is that C2 now mixes logical containers with infrastructure, and C4 is
40820
- effectively absent for that system.
41117
+ cost is that C2 now mixes logical containers with infrastructure, and a
41118
+ separate Deployment view is effectively absent for that system.
40821
41119
 
40822
- Clean C4 keeps C2 logical and moves physical realization into concrete
40823
- deployments, context-owned deployment profiles, inventory slots, and projection
40824
- rules. This is more work up front, but it supports many-to-many deployment: one
40825
- logical service can target several concrete deployments whose infrastructure
40826
- differs by stage, region, provider, or organizational boundary.
41120
+ Explicit deployment modeling keeps C2 logical and moves physical realization
41121
+ into concrete deployments, context-owned deployment profiles, inventory slots,
41122
+ and projection rules. This is more work up front, but it supports many-to-many
41123
+ deployment: one logical service can target several concrete deployments whose
41124
+ infrastructure differs by stage, region, provider, or organizational boundary.
40827
41125
 
40828
- This choice is per-system, not global. A critical system can use clean C4 while
40829
- peripheral systems stay pragmatic in C2. Starting cheap is acceptable, but know
40830
- that upgrading mixed C2 infrastructure into clean C4 is a migration, not just an
40831
- extra attribute.
41126
+ This choice is per-system, not global. A critical system can use explicit
41127
+ deployment modeling while peripheral systems stay pragmatic in C2. Starting
41128
+ cheap is acceptable, but upgrading mixed C2 infrastructure into explicit
41129
+ deployment modeling is a migration, not just an extra attribute.
40832
41130
 
40833
41131
  ## Eventing
40834
41132
 
@@ -40845,8 +41143,9 @@ For pub/sub, make the dependency consumer-owned:
40845
41143
  dependencies instead of editing a subscriber list on the producer.
40846
41144
 
40847
41145
  Do not invent a broker node just to make the diagram look familiar. If the
40848
- chosen style is clean C4 and the broker is deployment infrastructure, model it
40849
- in deployment/C4. If the chosen style is pragmatic mixed C2, a broker-like node
41146
+ chosen style is explicit deployment modeling and the broker is deployment
41147
+ infrastructure, model it in the deployment inventory. If the chosen style is
41148
+ pragmatic mixed C2, a broker-like node
40850
41149
  can be acceptable, but document that the view mixes levels. If the producer or
40851
41150
  consumer is not known, leave a gap and report it instead of fabricating an
40852
41151
  element.
@@ -40858,6 +41157,147 @@ no legitimate endpoint in scope, flag the uncertainty and ask for the missing
40858
41157
  boundary or owner.
40859
41158
  `;
40860
41159
  }
41160
+ function genericImportingModelsReference() {
41161
+ return `# Importing Existing Architecture Models
41162
+
41163
+ Use this reference when architecture already exists in another DSL, a diagram,
41164
+ an inventory, or prose. Import is a semantic reconstruction: the objective is
41165
+ to preserve supported architecture facts in Insight, not to reproduce the
41166
+ source file line by line or preserve its drawing coordinates.
41167
+
41168
+ ## Establish the Source Contract
41169
+
41170
+ Before writing Insight, identify which inputs are authoritative and what each
41171
+ one represents. A repository-wide model may describe ownership and identity;
41172
+ an individual diagram may be only one filtered view. An infrastructure
41173
+ inventory can describe deployed resources without explaining logical systems.
41174
+ Prose can contain facts that are absent from every diagram.
41175
+
41176
+ Create a small mapping ledger while working. For each source object, record its
41177
+ source identity, intended Insight id and type, owner or context, evidence, and
41178
+ any unresolved ambiguity. Preserve stable source ids when they are meaningful
41179
+ and valid Insight identifiers. Never merge objects solely because their display
41180
+ names look similar.
41181
+
41182
+ ## Judge the Evidence, Not Just the Format
41183
+
41184
+ Source formats provide different levels of architectural evidence.
41185
+
41186
+ PlantUML, Mermaid, and DOT are often used as drawing languages. Their text may
41187
+ be deterministic enough to reproduce one picture, while architectural identity,
41188
+ ownership, relationship meaning, and consistency across several diagrams remain
41189
+ author conventions. Treat a node or arrow found there as an observation from
41190
+ that diagram. Do not assume that repeated labels identify one object, that a
41191
+ visual boundary is semantic containment, or that an arrow carries the same
41192
+ dependency meaning in every file.
41193
+
41194
+ LikeC4, Structurizr, and other model-oriented DSLs usually provide more reliable
41195
+ identities, containment, and directed relationships. Accept facts that are
41196
+ explicitly encoded in their model, but do not treat the model as complete by
41197
+ default. A workspace or selected view may omit deployment, lower architectural
41198
+ levels, external ownership, relationship technology, operational constraints,
41199
+ or the reason a boundary was chosen. Deterministic input can still be partial
41200
+ input.
41201
+
41202
+ Inventories and generated exports are reliable only for the fields their
41203
+ producer owns. A cloud inventory can prove that a resource exists and expose
41204
+ its configuration, but it may say nothing about the logical service using it or
41205
+ the architectural dependency it realizes.
41206
+
41207
+ When required semantics are absent or contradictory, first search the relevant
41208
+ repository sources, attached artifacts, configured skills, MCP integrations,
41209
+ and other authorized information sources available to the agent. Prefer the
41210
+ most authoritative source for the fact and record conflicts instead of silently
41211
+ choosing one. Do not ask the user to provide information that can be retrieved
41212
+ reliably through those sources.
41213
+
41214
+ Only when the missing fact cannot be obtained independently should the agent
41215
+ stop that part of the translation and ask the user for context or documentation.
41216
+ Send one short message with one or two focused questions. Good questions resolve
41217
+ a specific mapping decision, for example:
41218
+
41219
+ - Does \`A -> B\` represent a runtime call, data flow, or dependency ownership?
41220
+ - Is this system external to the modeled context, or only outside the current
41221
+ diagram's focal system?
41222
+ - Is this deployment node a concrete resource, a reusable environment slot, or
41223
+ a visual grouping?
41224
+
41225
+ Continue with independent, well-supported facts while the answer is pending.
41226
+ Record unresolved mappings instead of selecting the most plausible type,
41227
+ boundary, direction, or deployment structure.
41228
+
41229
+ ## Interpret Common Sources Carefully
41230
+
41231
+ | Source concept | Likely Insight concept | Required judgment |
41232
+ | --- | --- | --- |
41233
+ | C4 person or actor | \`Actor\` or \`ExternalActor\` | Decide externality relative to the selected context. |
41234
+ | C4 software system | \`System\` or \`ExternalSystem\` | Confirm ownership and context boundary. |
41235
+ | C4 container | \`Container\` or \`Service\` | Choose the name that best communicates its runtime purpose. |
41236
+ | C4 component | \`Component\` | Confirm its owning container or service. |
41237
+ | C4 code element | Project-defined \`CodeElement\` descendant | Preserve the source vocabulary and introduce a concrete code type only when the source identifies its meaning and containment. |
41238
+ | Relationship | Insight wire | Preserve direction, kind, technology, and the object that owns the dependency. |
41239
+ | Deployment node or resource | Environment, deployment, or infrastructure component | Separate a reusable deployment scheme from a concrete resource instance. |
41240
+ | Diagram boundary | Context, owner, group, or query scope | A visual box alone does not prove semantic containment. |
41241
+
41242
+ LikeC4, Structurizr, and other C4-oriented DSLs usually provide the closest logical mapping,
41243
+ but their deployment instances and views still do not map mechanically to
41244
+ Insight profiles and projections. Mermaid, PlantUML, and DOT often provide
41245
+ visible nodes and arrows while omitting type, ownership, context, and deployment
41246
+ semantics. YAML, JSON, and cloud inventories provide structure but do not make
41247
+ field names architectural facts. Apply the evidence rules above and ask for
41248
+ missing semantics instead of deriving them from visual placement or
41249
+ serialization shape.
41250
+
41251
+ ## Import Outside In
41252
+
41253
+ 1. Inventory the source objects, relationships, boundaries, and views without
41254
+ editing them.
41255
+ 2. Define the Insight context boundary and shared external contexts.
41256
+ 3. Create project-specific definitions only when the source has a real reusable
41257
+ concept that the built-in type system does not express.
41258
+ 4. Import C1 actors, systems, and their highest-level relationships. Link the
41259
+ project and resolve identity or ownership errors.
41260
+ 5. Add C2 containers and services, then move relationships to the lowest known
41261
+ logical endpoints so built-in rollup can produce higher-level views.
41262
+ 6. Add C3 components only where the source provides component-level evidence.
41263
+ 7. If C4 is in scope, first inspect the repository for existing \`CodeElement\`
41264
+ descendants and containment slots. Reuse that vocabulary without asking. Ask
41265
+ the user which entity kinds to model only when the project has no Code layer
41266
+ or the import requires extending its vocabulary, unless the request already
41267
+ makes that choice. Add code elements only where the source identifies their
41268
+ containment and dependencies.
41269
+ 8. Build deployment models separately from concrete environments and deployments. Use
41270
+ profiles, \`runsOn\`, \`uses\`, and projections to map the logical model to
41271
+ physical infrastructure; do not turn every deployment node into a logical
41272
+ C2 element.
41273
+ 9. Split definitions, contexts, and environments into valid source roles and
41274
+ make cross-file visibility explicit with imports.
41275
+
41276
+ For a normal synchronous wire, the element that owns the dependency declares
41277
+ the wire and the arrow points from that owner to its target. Async pub/sub can
41278
+ use consumer-owned dependencies as described in \`references/modeling.md\`.
41279
+ Preserve source direction unless the target architecture semantics explicitly
41280
+ require a different ownership model, and record that decision.
41281
+
41282
+ ## Reconcile the Result
41283
+
41284
+ Validate each imported layer rather than translating the complete source before
41285
+ the first link:
41286
+
41287
+ \`\`\`shell
41288
+ archinsight link . --format text
41289
+ archinsight structure . --format json
41290
+ archinsight query . -c <context-id> -v no-filter --format json
41291
+ \`\`\`
41292
+
41293
+ Use C1, C2, C3, C4, and Deployment query JSON to compare the intended scope and
41294
+ relationships at each level. Counts can reveal omissions, but equal counts do
41295
+ not prove semantic equivalence. Compare qualified identities, types, ownership,
41296
+ wire direction, externality, and deployment projection. Keep unresolved source
41297
+ facts visible in the import report instead of fabricating declarations to make
41298
+ the model appear complete.
41299
+ `;
41300
+ }
40861
41301
  function genericSyntaxReference() {
40862
41302
  return `# Insight Syntax Reference
40863
41303
 
@@ -40885,6 +41325,11 @@ environment eu
40885
41325
  Definitions, contexts, and environments are separate source roles. Never put
40886
41326
  more than one of these roles in the same file.
40887
41327
 
41328
+ An environment source has exactly one \`environment <id>\` header. Any
41329
+ \`deployment\` declarations that follow are top-level declarations in the file,
41330
+ but the linker attaches them to that environment. Put a second environment in a
41331
+ second source file. One environment source may contain several deployments.
41332
+
40888
41333
  Use indentation to define ownership. Children belong to the nearest less-indented
40889
41334
  parent.
40890
41335
 
@@ -40900,7 +41345,7 @@ extensions, links, queries, and generated navigation refer to those identities.
40900
41345
 
40901
41346
  ## Common Elements
40902
41347
 
40903
- Use built-in constructors for C4-style architecture:
41348
+ Use built-in constructors for the C1-C3 parts of a C4 architecture:
40904
41349
 
40905
41350
  \`\`\`insight
40906
41351
  external actor customer
@@ -40929,6 +41374,11 @@ Useful built-ins include:
40929
41374
  - \`service\` for backend/container services.
40930
41375
  - \`component\` for internals of a selected container or service.
40931
41376
 
41377
+ Core has no concrete constructor for the C4 Code level. It provides the
41378
+ constructorless \`CodeElement\` base, while project definitions supply concrete
41379
+ code types and their constructors. Read \`references/c4-code.md\` before adding
41380
+ or instantiating code-level concepts.
41381
+
40932
41382
  Built-in nesting follows the core type tree, not the English noun. For example,
40933
41383
  actors and systems are context-level because their base type is a boundary
40934
41384
  element, while containers are allowed under systems because the \`System\` type
@@ -40991,6 +41441,18 @@ but reports a warning because a scattered effective schema is difficult to
40991
41441
  inspect and review. An agent should consolidate them rather than create another
40992
41442
  extension elsewhere.
40993
41443
 
41444
+ There are two valid ways to define environment slots, with different scope:
41445
+
41446
+ - \`extend type Environment\` adds one project-wide slot schema to every
41447
+ environment.
41448
+ - \`define type ApplicationEnvironment of Environment\` creates a distinct,
41449
+ constructorless environment schema. Environment declarations infer that
41450
+ subtype from its slot names when the match is unambiguous.
41451
+
41452
+ Use the base-type extension when every environment shares one contract. Use a
41453
+ named subtype when the project needs isolated environment families. Do not
41454
+ describe these forms as interchangeable.
41455
+
40994
41456
  After changing a type definition, run \`archinsight structure . --format text\`
40995
41457
  to see the updated type tree and available constructors.
40996
41458
 
@@ -41074,6 +41536,12 @@ It must be the last attribute in the type body. Compatible child declarations
41074
41536
  can then appear directly under the parent. The \`_\` symbol can also replace an
41075
41537
  object id when no source-level reference to that instance is needed.
41076
41538
 
41539
+ An anonymous instance cannot later be the target of \`runsOn\`, a typed
41540
+ reference attribute, an import, or a relationship. Give the object a stable id
41541
+ whenever another declaration must reference it. The linker reports
41542
+ \`ANONYMOUS_INSTANCE_NOT_REFERENCEABLE\` when \`_\` is used as a reference
41543
+ target.
41544
+
41077
41545
  ## Enumerations
41078
41546
 
41079
41547
  An enum uses a constructorless type as its closed value domain:
@@ -41171,7 +41639,7 @@ agents without changing the model:
41171
41639
  context checkout
41172
41640
 
41173
41641
  system checkout_platform
41174
- # Keep logical services here; deployment inventory belongs in C4 files.
41642
+ # Keep logical services here; deployment inventory belongs in deployment files.
41175
41643
  name = Checkout Platform
41176
41644
  \`\`\`
41177
41645
 
@@ -41234,7 +41702,7 @@ Available annotations:
41234
41702
  useful. The default Graphviz renderer highlights it in red.
41235
41703
 
41236
41704
  Annotations can be stacked and are preserved on projected relationships, so a
41237
- C4 projection can still show that the original logical relationship was planned
41705
+ Deployment projection can still show that the original logical relationship was planned
41238
41706
  or deprecated. Annotations cannot decorate assignments; use a comment above the
41239
41707
  assignment when you only need a local authoring hint.
41240
41708
 
@@ -41385,10 +41853,22 @@ Components should describe responsibilities, not every class or function.
41385
41853
  As with C2, a C3 file often focuses one container or service, but custom queries
41386
41854
  can intentionally choose a different scope.
41387
41855
 
41388
- ## C4: Deployment
41856
+ ## C4: Code
41857
+
41858
+ Use project-defined \`CodeElement\` descendants when a component needs a code
41859
+ view. Read \`references/c4-code.md\` before introducing modules, packages,
41860
+ classes, functions, schemas, or another code vocabulary. Keep those type and
41861
+ containment definitions separate from the context source, and use
41862
+ \`examples/c4-code\` as the minimal working pattern.
41863
+
41864
+ The built-in C4 query selects the project's code elements without prescribing
41865
+ what they mean. Model only implementation structures that explain stable
41866
+ responsibilities, interfaces, or dependencies.
41867
+
41868
+ ## Deployment
41389
41869
 
41390
41870
  Use deployment profiles and infrastructure types when physical realization is
41391
- important. Read \`references/c4-deployment.md\` before writing a real C4 model.
41871
+ important. Read \`references/deployment.md\` before writing a real deployment model.
41392
41872
 
41393
41873
  \`\`\`insight
41394
41874
  environment eu
@@ -41411,7 +41891,7 @@ only when they clarify real runtime paths. Prefer attaching deployment to C2
41411
41891
  containers/services when possible because C2 is usually the most representative
41412
41892
  logical runtime boundary.
41413
41893
 
41414
- C4/deployment files often focus one deployment slice. The rendered scope is
41894
+ deployment files often focus one deployment slice. The rendered scope is
41415
41895
  defined by the query, projection selectors, and selected source file.
41416
41896
 
41417
41897
  ## Layering Rules
@@ -41620,7 +42100,8 @@ external system analytics_platform
41620
42100
  - Treating a peer owned in the same context as \`external system\`.
41621
42101
  - Duplicating imported external systems instead of importing the shared
41622
42102
  declaration.
41623
- - Adding implementation details that belong to C2/C3/C4.
42103
+ - Adding implementation details that belong to C2, C3, or a project-defined
42104
+ code model.
41624
42105
  - Drawing a relationship without naming what capability or dependency it means.
41625
42106
  - Choosing constructors before deciding the context boundary.
41626
42107
 
@@ -41661,14 +42142,14 @@ containers/services.
41661
42142
 
41662
42143
  The clean C2 answer is logical: deployable containers/services and how they
41663
42144
  collaborate. In that mode, databases, brokers, gateways, vaults, compute, and
41664
- regions belong to C4/deployment.
42145
+ regions belong to deployment.
41665
42146
 
41666
42147
  Archinsight does not force that choice. For a quick or single-environment model,
41667
42148
  it is acceptable to put simple infrastructure-like runtime nodes into C2 when
41668
42149
  the user wants speed over strict layer separation. Be explicit about the
41669
- tradeoff: the C2 view becomes mixed, C4 is not really modeled for that system,
42150
+ tradeoff: the C2 view becomes mixed, deployment is not modeled for that system,
41670
42151
  and many-to-many deployment across different environments will not be available
41671
- until the model is migrated to clean C4.
42152
+ until the model is migrated to explicit deployment modeling.
41672
42153
 
41673
42154
  Choose this per system. Do not make the whole repository clean or mixed just
41674
42155
  because one system needs that style.
@@ -41822,7 +42303,7 @@ Do not list consumers under the producer just to answer "who listens to this
41822
42303
  topic?" That answer belongs in a query over incoming async dependencies.
41823
42304
 
41824
42305
  Do not add a broker node just to make an event diagram look familiar. In clean
41825
- C2, a broker is usually deployment/C4 infrastructure unless the project defines
42306
+ C2, a broker is usually deployment infrastructure unless the project defines
41826
42307
  it as a runtime system or service in the selected view. In pragmatic mixed C2,
41827
42308
  adding a broker can be acceptable for a quick view, but it means the diagram is
41828
42309
  no longer strictly logical C2.
@@ -42150,7 +42631,7 @@ links:
42150
42631
 
42151
42632
  Do not add a broker as a component unless the broker is actually part of the
42152
42633
  focal container/service. Shared brokers, queues, gateways, and runtime placement
42153
- usually belong to deployment/C4 or infrastructure modeling.
42634
+ usually belong to deployment or infrastructure modeling.
42154
42635
 
42155
42636
  The built-in views roll a component dependency up to its owning containers at
42156
42637
  C2 and, when it crosses system boundaries, to its owning systems at C1. Remove
@@ -42183,22 +42664,127 @@ Use \`examples/c3-components.ai\` as a compact valid C3 model when syntax is
42183
42664
  unclear.
42184
42665
  `;
42185
42666
  }
42186
- function genericC4DeploymentReference() {
42187
- return `# C4 Deployment
42667
+ function genericC4CodeReference() {
42668
+ return `# C4 Code
42669
+
42670
+ Use C4 when the task needs to explain the implementation structure inside one
42671
+ or more components. Archinsight intentionally does not prescribe whether that
42672
+ structure consists of modules, packages, namespaces, classes, functions,
42673
+ schemas, or another project vocabulary.
42674
+
42675
+ ## Determine the Modeling Vocabulary
42676
+
42677
+ Inspect project definitions and existing C4 sources before asking questions. If
42678
+ the repository already defines \`CodeElement\` descendants and containment slots
42679
+ that cover the task, infer the intended entity kinds from that vocabulary and
42680
+ reuse it without asking the user to choose again.
42681
+
42682
+ Ask the user which code entity kinds they want only when creating a new C4 Code
42683
+ layer or when the requested work requires new entity kinds or containment rules
42684
+ beyond the existing vocabulary. Do not ask when the current request already
42685
+ makes that choice. This decision cannot be inferred from implementation source
42686
+ alone because a new or expanded Code vocabulary is user-defined by design.
42687
+
42688
+ ## Core Contract
42689
+
42690
+ \`CodeElement\` is a constructorless subtype of \`Element\`. Project definitions
42691
+ derive concrete code types from it and supply their constructors, attributes,
42692
+ relationships, presentations, and containment rules. Do not instantiate
42693
+ \`CodeElement\` directly and do not assume a code ontology that the project has
42694
+ not defined.
42695
+
42696
+ Keep code types and extensions in a definitions source. A minimal framework can
42697
+ derive a module type and make code elements anonymous children of components:
42698
+
42699
+ \`\`\`insight
42700
+ define type Module of CodeElement
42701
+ constructor module
42702
+
42703
+ required Text name
42704
+ Text responsibility
42705
+ List of Wire links
42706
+ List of CodeElement children
42707
+
42708
+ extend type Component
42709
+ List of CodeElement _
42710
+ \`\`\`
42711
+
42712
+ The anonymous list allows code declarations to appear directly below a
42713
+ component without a \`code:\` wrapper. It must be the component type's only
42714
+ anonymous list and the final attribute in this extension. Use a named slot only
42715
+ when that wrapper conveys useful structure in the project's chosen vocabulary.
42716
+
42717
+ \`CodeElement\` is separate from \`ComponentElement\`. This keeps code objects out
42718
+ of C3 unless a custom query intentionally combines both levels.
42719
+
42720
+ A code type named for a schema represents a logical or source-controlled code
42721
+ artifact. A deployed database, volume, or bucket is physical infrastructure and
42722
+ uses \`Storage\` in the Deployment model. Do not use a code-level schema as a
42723
+ substitute for its physical storage instance, or model the storage instance as
42724
+ code.
42725
+
42726
+ ## Built-In View
42727
+
42728
+ The built-in \`c4\` query selects every \`CodeElement\` whose
42729
+ \`sourceIdentity\` belongs to \`$tab\`, including code contributed to roots from
42730
+ that tab through \`extend\`. It returns direct relationships between code
42731
+ elements and groups them by immediate parent. A relationship can bring its
42732
+ target code element into the result from outside the selected tab.
42733
+
42734
+ The query does not infer classes, packages, or nesting from source paths. Read
42735
+ the project's definitions and actual containment slots before editing a C4
42736
+ model. Copy \`examples/builtin-views/c4.aiq\` only when the project needs a
42737
+ different type filter or grouping rule.
42738
+
42739
+ ## Workflow
42740
+
42741
+ 1. Inspect existing definitions for \`CodeElement\` descendants and component
42742
+ containment slots.
42743
+ 2. Reuse the existing vocabulary when it covers the requested model.
42744
+ 3. If the project has no Code layer or the task requires extending its
42745
+ vocabulary, ask the user which new entity kinds and containment rules they
42746
+ want unless the request already specifies them.
42747
+ 4. Define only the confirmed additions, keeping the definition source separate
42748
+ from context sources.
42749
+ 5. Place code instances under the component slots provided by that framework.
42750
+ 6. Preserve relationship ownership: the code object containing a wire is its
42751
+ source, and the referenced object is its target.
42752
+ 7. Prefer responsibilities, stable interfaces, and important dependencies over
42753
+ an inventory of every declaration.
42754
+ 8. Validate the full project, then inspect the exact C4 graph:
42755
+
42756
+ \`\`\`shell
42757
+ archinsight link . --format text
42758
+ archinsight query . -c <context-id> -s <code-source.ai> -v c4 --format json
42759
+ archinsight render . -c <context-id> -s <code-source.ai> -v c4 -f svg -o code.svg
42760
+ \`\`\`
42761
+
42762
+ Use the self-contained \`examples/c4-code\` project when the syntax for a code
42763
+ framework or model is unclear. Deployment is a separate view selected with
42764
+ \`--view deployment\`; never use C4 as an alias for Deployment.
42765
+ `;
42766
+ }
42767
+ function genericDeploymentReference() {
42768
+ return `# Deployment
42188
42769
 
42189
- Use C4 to project the logical architecture onto physical infrastructure: where
42770
+ Use Deployment modeling to project the logical architecture onto physical infrastructure: where
42190
42771
  logical elements run, which infrastructure they use, and how their wires pass
42191
- through the physical world. Keep C1-C3 logical; deployment inventory and
42772
+ through the physical world. Keep C1-C4 logical; deployment inventory and
42192
42773
  projections supply the physical view.
42193
42774
 
42775
+ The built-in Deployment view includes a logical element only when its deployment
42776
+ resolves at least one \`runsOn\` or \`uses\` infrastructure object. A logical wire
42777
+ appears only through physical edges created by its deployment projection. A
42778
+ plain logical wire is intentionally omitted from Deployment.
42779
+
42194
42780
  Model the infrastructure immediately relevant to those logical elements and
42195
- connections. Do not expand C4 into a complete provider, transit, replication,
42781
+ connections. Do not expand a Deployment view into a complete provider, transit, replication,
42196
42782
  or network topology. Keep replication modes and deeper operational detail in
42197
42783
  \`description\`, \`technology\`, \`via\`, notes, or project-specific attributes
42198
42784
  unless an intermediate component is itself important to the architecture.
42199
42785
 
42200
42786
  When a project models deployment explicitly, databases, storage, brokers,
42201
- gateways, network connections, compute, and observability belong at C4. Leave
42787
+ gateways, network connections, compute, and observability belong in the Deployment view. Leave
42202
42788
  them at C2 only when the project deliberately chooses a compact mixed model and
42203
42789
  does not plan to describe deployment in detail.
42204
42790
 
@@ -42206,8 +42792,9 @@ does not plan to describe deployment in detail.
42206
42792
 
42207
42793
  There are four distinct concepts:
42208
42794
 
42209
- 1. \`Environment\` owns one or more named \`Deployment\` objects, such as
42210
- \`test\` and \`production\`.
42795
+ 1. One environment source starts with exactly one \`environment <id>\` and may
42796
+ own one or more named \`Deployment\` objects, such as \`test\` and
42797
+ \`production\`.
42211
42798
  2. A concrete \`Deployment\` fills infrastructure slots defined by the
42212
42799
  environment type.
42213
42800
  3. A context-owned \`DeploymentProfile\` maps logical elements to concrete
@@ -42221,9 +42808,12 @@ Do not put application deployment profiles in environment inventory files.
42221
42808
  Environment files own concrete infrastructure. The application context owns
42222
42809
  the profiles that decide where its systems, containers, and services run.
42223
42810
 
42224
- One environment can contain several deployment schemes. Profiles may select
42225
- different schemes such as \`production from eu\` and \`test from eu\` without a
42226
- conflict because these are different concrete deployments.
42811
+ Deployments are written as top-level siblings after the environment header, not
42812
+ indented inside it, but they remain owned by that environment. A second
42813
+ environment requires a second source file. One environment can contain several
42814
+ deployment schemes, and profiles may select \`production from eu\` and
42815
+ \`test from eu\` without a conflict because they are different concrete
42816
+ deployments.
42227
42817
 
42228
42818
  ## Framework and inventory
42229
42819
 
@@ -42249,6 +42839,13 @@ define type Monitoring of InfrastructureComponent
42249
42839
  constructor monitoring
42250
42840
  \`\`\`
42251
42841
 
42842
+ A project with one shared environment contract may instead use
42843
+ \`extend type Environment\` with the same slots. That extension changes the base
42844
+ type for every environment. A named subtype such as \`ApplicationEnvironment\`
42845
+ keeps the contract isolated and is preferable when the project has several
42846
+ environment families. Environment declarations infer a constructorless subtype
42847
+ from the slots used by their deployments; the match must be unambiguous.
42848
+
42252
42849
  Fill those slots inside concrete deployments:
42253
42850
 
42254
42851
  \`\`\`insight
@@ -42286,6 +42883,29 @@ deployment production
42286
42883
  An explicit object id may differ from the slot name: \`public_edge\` still fills
42287
42884
  the \`publicGateway\` slot of \`eu/production\`.
42288
42885
 
42886
+ ## Concrete infrastructure placement
42887
+
42888
+ The \`runsOn:\` attribute on an infrastructure component is a typed reference to
42889
+ one concrete, named infrastructure instance:
42890
+
42891
+ \`\`\`insight
42892
+ compute kubernetes
42893
+ name = Kubernetes
42894
+
42895
+ infrastructureComponent ingress
42896
+ name = Ingress
42897
+ runsOn:
42898
+ kubernetes
42899
+ \`\`\`
42900
+
42901
+ The target \`kubernetes\` is an object id. It must be visible in the source and
42902
+ cannot be the anonymous id \`_\`. Anonymous objects are suitable only when no
42903
+ other declaration needs to address them.
42904
+
42905
+ This reference form is different from \`runsOn compute\` inside a deployment
42906
+ profile. The profile form names an environment slot and resolves its concrete
42907
+ instance separately in every deployment selected by \`appliesTo\`.
42908
+
42289
42909
  ## Context-owned deployment profiles
42290
42910
 
42291
42911
  Declare profiles in the logical context and reference concrete deployments with
@@ -42382,6 +43002,15 @@ Components inherit effective deployments from their nearest deployed logical
42382
43002
  ancestor, normally a container or service. Put profiles on independently
42383
43003
  deployable C2 elements unless a C3 component truly has distinct placement.
42384
43004
 
43005
+ Deployment completeness checks become active only after the project starts
43006
+ using the corresponding feature. Once a deployment-relevant wire has a \`deployment\`
43007
+ block, the linker warns about other wires between different deployment endpoints with
43008
+ no deployment and about configured wires that produce no physical projection.
43009
+ A component relationship inside one container collapses to a self-relationship
43010
+ in the Deployment view and does not require a physical projection. Element checks activate
43011
+ separately by logical modeling family, so starting container placement does not
43012
+ demand artificial placement for every system, component, or external actor.
43013
+
42385
43014
  ## Projection execution semantics
42386
43015
 
42387
43016
  Projection rules belong to concrete infrastructure instances because paths can
@@ -42469,13 +43098,21 @@ Run:
42469
43098
 
42470
43099
  \`\`\`shell
42471
43100
  archinsight link . --format text
42472
- archinsight render . -c <context> -s <source.ai> -v c4 -f svg -o c4.svg
43101
+ archinsight query . -c <context> -s <logical-source.ai> -v deployment --format json
43102
+ archinsight render . -c <context> -s <logical-source.ai> -v deployment -f svg -o deployment.svg
42473
43103
  \`\`\`
42474
43104
 
43105
+ A clean link proves that syntax, types, imports, and deployment references are
43106
+ valid. It does not prove that a view selected the intended semantic graph.
43107
+ Inspect query JSON before relying on SVG: query output is the authoritative list
43108
+ of elements and edges selected for rendering.
43109
+
42475
43110
  Treat missing slots, overlapping profile deployments, non-network wire uses,
42476
- and ambiguous references as model errors. If a physical arrow is absent, check
42477
- the endpoint profiles, their \`appliesTo\` deployments, the requested network
42478
- slot, and the concrete instance projection in that order.
43111
+ and ambiguous references as model errors. Treat \`WIRE_MISSING_DEPLOYMENT\`,
43112
+ \`WIRE_DEPLOYMENT_NOT_PROJECTED\`, \`ELEMENT_MISSING_DEPLOYMENT\`, and
43113
+ \`ELEMENT_DEPLOYMENT_NOT_PHYSICAL\` as incomplete deployment coverage. If a physical
43114
+ arrow is absent, check the endpoint profiles, their \`appliesTo\` deployments,
43115
+ the requested network slot, and the concrete instance projection in that order.
42479
43116
  `;
42480
43117
  }
42481
43118
  function genericScalingReference() {
@@ -42493,8 +43130,8 @@ Prefer one shared framework per repository:
42493
43130
  types, and presentation tweaks;
42494
43131
  - source files grouped by context directories when the repository is large;
42495
43132
  - model files that usually focus on one primary owned system being detailed;
42496
- - one or more inventory files for concrete \`environment <id>\` instances and
42497
- their env-local infrastructure;
43133
+ - one or more inventory files, each with exactly one concrete
43134
+ \`environment <id>\` header and one or more deployments owned by it;
42498
43135
  - shared external contexts for external actors and systems reused by many
42499
43136
  systems;
42500
43137
  - context-owned deployment profile files that map logical elements to concrete
@@ -42505,6 +43142,12 @@ Do not copy the same environment or infrastructure type definitions into every
42505
43142
  system file. Keep concrete inventory in environment files and keep each
42506
43143
  application's deployment profiles in its logical context.
42507
43144
 
43145
+ Use \`extend type Environment\` when the repository intentionally has one slot
43146
+ contract shared by every environment. If several environment families need
43147
+ different contracts, define constructorless subtypes such as
43148
+ \`ApplicationEnvironment\` and \`DataEnvironment\` instead. Keep either form in
43149
+ the shared framework area rather than repeating it in inventory files.
43150
+
42508
43151
  ## Framework Once, Use Everywhere
42509
43152
 
42510
43153
  A typical deployment framework file contains only shared vocabulary: type
@@ -42693,9 +43336,9 @@ This explicitness is useful during refactors: if the source file holding
42693
43336
  \`inventory_api\` disappears, validation points at the missing declaration
42694
43337
  instead of creating a hidden dependency on file layout.
42695
43338
 
42696
- ## C4 Multi-File Pattern
43339
+ ## Deployment Multi-File Pattern
42697
43340
 
42698
- For C4, keep these responsibilities separate:
43341
+ For Deployment modeling, keep these responsibilities separate:
42699
43342
 
42700
43343
  - framework file: environment schemas, infrastructure constructors, and
42701
43344
  presentation definitions;
@@ -42703,15 +43346,16 @@ For C4, keep these responsibilities separate:
42703
43346
  - logical context files: deployment profiles with \`appliesTo\` references and
42704
43347
  the relationships whose network paths should render.
42705
43348
 
42706
- When rendering C4 with \`-s <source.ai>\`, remember that source/tab scoping is
43349
+ When rendering Deployment with \`-s <source.ai>\`, remember that source/tab scoping is
42707
43350
  part of the view. The selected tab includes the full model fragment rooted in
42708
43351
  that source, including relationships contributed to those roots by \`extend\`
42709
43352
  files. Keep imported framework and inventory reusable, and validate the rendered
42710
- C4 output after changing which root a traffic relationship extends:
43353
+ Deployment output after changing which root a traffic relationship extends:
42711
43354
 
42712
43355
  \`\`\`shell
42713
43356
  archinsight link . --format text
42714
- archinsight render . -c deployment_shop -s c4-deployment.ai -v c4 -f svg -o deployment-c4.svg
43357
+ archinsight query . -c deployment_shop -s deployment.ai -v deployment --format json
43358
+ archinsight render . -c deployment_shop -s deployment.ai -v deployment -f svg -o deployment.svg
42715
43359
  \`\`\`
42716
43360
 
42717
43361
  If projected infrastructure edges disappear after a split, first check whether
@@ -42735,7 +43379,7 @@ the extension target, or the file boundary.
42735
43379
  9. Prefer a named import for repeated references and an inline qualifier for a
42736
43380
  one-off relationship or list value.
42737
43381
  10. Validate with \`archinsight link . --format text\`.
42738
- 11. Render important C1/C2/C3/C4 views with explicit \`-c\`, \`-s\`, and \`-v\`
43382
+ 11. Render important C1, C2, C3, C4, and Deployment views with explicit \`-c\`, \`-s\`, and \`-v\`
42739
43383
  options.
42740
43384
  `;
42741
43385
  }
@@ -42755,8 +43399,8 @@ Keep source files in one role:
42755
43399
  \`extend enum of\`, and \`extend presentation\`;
42756
43400
  - context files: \`context <id>\`, imports, logical graph objects,
42757
43401
  relationships, object extensions, and deployment profiles;
42758
- - environment files: \`environment <id>\`, concrete deployments, and
42759
- infrastructure inventory.
43402
+ - environment files: exactly one \`environment <id>\` header followed by its
43403
+ concrete deployments and infrastructure inventory.
42760
43404
 
42761
43405
  Do not mix these three roles in one file. When a model needs custom vocabulary,
42762
43406
  add or edit a framework file first, then use the resulting constructors and
@@ -42910,6 +43554,15 @@ Interpretation:
42910
43554
  Users can define more types in project files. Always inspect project structure
42911
43555
  and project framework files before assuming only core constructors exist.
42912
43556
 
43557
+ ## Built-in Code Extension Point
43558
+
43559
+ \`core_code.ai\` declares the constructorless \`CodeElement\` base type. It is
43560
+ the only code-level ontology supplied by core. Project definitions derive
43561
+ concrete types from it and provide their constructors, attributes,
43562
+ presentations, relationships, and containment slots. Read
43563
+ \`references/c4-code.md\` before adding those definitions or using the built-in
43564
+ C4 query.
43565
+
42913
43566
  ## Built-in Deployment Infrastructure
42914
43567
 
42915
43568
  \`core_deployment.ai\` provides common infrastructure inventory types:
@@ -42928,8 +43581,19 @@ and project framework files before assuming only core constructors exist.
42928
43581
  \`$to\` or expand the relationship through relevant gateways and other
42929
43582
  first-order infrastructure.
42930
43583
 
42931
- Extend \`Environment\` with slots for these types, then fill each concrete
42932
- \`environment <id>\` with env-local instances.
43584
+ Add slots either by extending the shared \`Environment\` type or by defining a
43585
+ constructorless subtype. The extension gives every environment the same
43586
+ contract. A subtype keeps a contract isolated and is inferred from the slot
43587
+ names used by an environment's deployments.
43588
+
43589
+ Each environment source has one \`environment <id>\` header. Top-level
43590
+ \`deployment\` declarations following that header are owned by the environment,
43591
+ and each deployment fills the chosen slot contract with concrete instances.
43592
+
43593
+ The \`runsOn\` attribute on \`InfrastructureComponent\` points to one named
43594
+ infrastructure instance. The target cannot be anonymous. By contrast,
43595
+ \`runsOn compute\` inside a \`DeploymentProfile\` names the \`compute\` slot and
43596
+ resolves a concrete target separately for every selected deployment.
42933
43597
 
42934
43598
  ## Reading Type Extensions
42935
43599
 
@@ -42952,6 +43616,18 @@ Interpretation:
42952
43616
  - \`archinsight structure . --format text\` is the quickest way to inspect the
42953
43617
  effective type tree after extensions are applied.
42954
43618
 
43619
+ Use a dedicated subtype instead when different environment families need
43620
+ different slots:
43621
+
43622
+ \`\`\`insight
43623
+ define type ApplicationEnvironment of Environment
43624
+ Compute compute
43625
+ NetworkConnection network
43626
+ \`\`\`
43627
+
43628
+ The two forms are both valid but are not interchangeable: extending the base
43629
+ type is global, while defining a subtype introduces an isolated schema.
43630
+
42955
43631
  Use \`extend service checkout_api\` or another constructor form only when you
42956
43632
  intend to extend one graph object instance in a \`context\`. Use \`extend type\`
42957
43633
  when you intend to change the available vocabulary/schema for all instances of
@@ -43084,7 +43760,7 @@ and links.
43084
43760
  ## Reading Projections
43085
43761
 
43086
43762
  Projection definitions describe how deployment/runtime information is projected
43087
- into renderable graph relationships. Use them when C4/deployment diagrams are
43763
+ into renderable graph relationships. Use them when deployment diagrams are
43088
43764
  involved or when a query uses projected relationships.
43089
43765
 
43090
43766
  Rules of thumb:
@@ -43122,6 +43798,10 @@ level<TAB>code<TAB>source<TAB>line<TAB>column<TAB>message
43122
43798
  Treat \`ERROR\` as blocking. \`WARNING\` and \`NOTE\` can still be useful design
43123
43799
  feedback.
43124
43800
 
43801
+ A successful link proves that sources parse, types and imports resolve, and
43802
+ linker constraints hold. It does not prove that a built-in or custom view
43803
+ selects the intended semantic graph.
43804
+
43125
43805
  Inspect project structure:
43126
43806
 
43127
43807
  \`\`\`shell
@@ -43129,43 +43809,209 @@ archinsight structure . --format text
43129
43809
  archinsight structure . --format json
43130
43810
  \`\`\`
43131
43811
 
43132
- Render a diagram when a context id is known:
43812
+ Inspect the selected graph before rendering whenever a change affects C2, C3,
43813
+ C4, Deployment, projections, or query text:
43814
+
43815
+ \`\`\`shell
43816
+ archinsight query . -c <context-id> -s <source.ai> -v c2 --format json
43817
+ archinsight query . -c <context-id> -s <source.ai> -v c3 --format json
43818
+ archinsight query . -c <context-id> -s <source.ai> -v c4 --format json
43819
+ archinsight query . -c <context-id> -s <source.ai> -v deployment --format json
43820
+ \`\`\`
43821
+
43822
+ Then render the same context, source, and view:
43133
43823
 
43134
43824
  \`\`\`shell
43135
43825
  archinsight render . -c <context-id> -v c1 -f svg -o diagram.svg
43136
43826
  archinsight render . -c <context-id> -s <source.ai> -v c2 -f svg -o diagram.svg
43137
43827
  archinsight render . -c <context-id> -s <source.ai> -v c3 -f svg -o diagram.svg
43138
43828
  archinsight render . -c <context-id> -s <source.ai> -v c4 -f svg -o diagram.svg
43829
+ archinsight render . -c <context-id> -s <source.ai> -v deployment -f svg -o diagram.svg
43139
43830
  \`\`\`
43140
43831
 
43141
43832
  Run a custom query from a file:
43142
43833
 
43143
43834
  \`\`\`shell
43144
43835
  archinsight query . -c <context-id> -s <source.ai> -q query.aiq -f text
43836
+ archinsight query . -c <context-id> -s <source.ai> -q query.aiq -f json
43145
43837
  archinsight render . -c <context-id> -s <source.ai> -q query.aiq -f svg -o diagram.svg
43146
43838
  \`\`\`
43147
43839
 
43840
+ Use three validation layers:
43841
+
43842
+ 1. \`link\` for syntax, types, imports, and project diagnostics.
43843
+ 2. \`query --format json\` for the exact semantic elements, edges, endpoints,
43844
+ origins, and groups selected by the view.
43845
+ 3. \`render\` for presentation, Graphviz layout, labels, and styling.
43846
+
43847
+ When JSON already contains an unexpected edge, investigate query matching,
43848
+ \`ROLLUP\`, selectors, and projection origin before editing the model. When JSON
43849
+ is correct but SVG is not, investigate rendering or layout. Do not use a clean
43850
+ link or a plausible image as a substitute for semantic query inspection.
43851
+
43148
43852
  Useful built-in views:
43149
43853
 
43150
43854
  - \`c1\` for system context.
43151
43855
  - \`c2\` for containers/services in the selected source.
43152
43856
  - \`c3\` for components in the selected source.
43153
- - \`c4\` for deployment-oriented views.
43857
+ - \`c4\` for project-defined code elements in the selected source.
43858
+ - \`deployment\` for deployment-oriented views.
43154
43859
  - \`no-filter\` for the full context.
43155
43860
 
43156
- C2, C3, C4, and custom queries often depend on the active file. Pass
43861
+ C2, C3, C4, Deployment, and custom queries often depend on the active file. Pass
43157
43862
  \`--source <file>\` / \`-s <file>\` whenever the query uses \`$tab\`; otherwise
43158
43863
  the CLI may choose the first source and render a valid but wrong view.
43159
43864
 
43160
43865
  The bundled \`examples\` directory contains several independent model projects,
43161
43866
  not one project to link as a whole. Validate \`layered-architecture.ai\`, the C1,
43162
- C2, and C3 files individually. Validate the three \`c4-deployment*.ai\` files
43163
- together, and validate \`c4-private-gateway\` as its own directory.
43867
+ C2, and C3 files individually. Validate \`c4-code\` as its own directory. Validate
43868
+ the three \`deployment*.ai\` files together, and validate
43869
+ \`deployment-private-gateway\` as its own directory.
43164
43870
 
43165
43871
  If the CLI is missing, do not silently install it. Ask the user to install or
43166
43872
  expose \`@archinsight/cli\`.
43167
43873
  `;
43168
43874
  }
43875
+ function genericAnalysisReference() {
43876
+ return `# Analyzing an Insight Project
43877
+
43878
+ Use analysis mode to answer architecture questions without modifying the model.
43879
+ Start from the linked semantic graph, then use queries to select the relevant
43880
+ subgraph. Treat the rendered image as a presentation artifact, not as the
43881
+ primary analytical result.
43882
+
43883
+ ## What the Query Language Is For
43884
+
43885
+ Insight queries select nodes and relationships for inspection or rendering.
43886
+ The current subset is well suited to:
43887
+
43888
+ - inventory by context, source fragment, type, or attribute;
43889
+ - direct outgoing and incoming dependencies;
43890
+ - logical relationships rolled up to C1, C2, or C3 ownership levels;
43891
+ - external-boundary and technology-focused slices;
43892
+ - async versus sync relationship slices;
43893
+ - logical-to-physical deployment placement and projected wire paths;
43894
+ - comparing a broad context graph with a focused built-in or custom view.
43895
+
43896
+ It is not a general graph analytics language. It has no aggregation functions,
43897
+ computed return columns, variable-length paths, shortest-path operations,
43898
+ subqueries, ordering, or pagination. It cannot directly express transitive
43899
+ impact, cycle detection, centrality, counts, or the absence of a relationship.
43900
+ \`ROLLUP\` climbs containment ownership; it is not transitive dependency
43901
+ traversal.
43902
+
43903
+ For questions outside that boundary, select a sufficiently broad graph with
43904
+ \`--format json\` and analyze that JSON with the agent's ordinary data-processing
43905
+ tools. Keep this second step read-only and state clearly which result comes from
43906
+ the Insight query and which result was computed from its output.
43907
+
43908
+ ## Analysis Workflow
43909
+
43910
+ 1. Run \`archinsight link . --format text\`. Diagnostics are part of the
43911
+ evidence; do not silently analyze a partially linked model as if it were
43912
+ complete.
43913
+ 2. Run \`archinsight structure . --format json\` to establish contexts, source
43914
+ roles, types, objects, extensions, and qualified identities.
43915
+ 3. Choose the smallest query that answers the question. Use a built-in view for
43916
+ an architectural level, a focused custom query for one-hop questions, or
43917
+ \`no-filter\` for a broad logical export.
43918
+ 4. Inspect query JSON before rendering. Distinguish selected outer endpoints,
43919
+ underlying edge endpoints, derived relationships, and projection origins.
43920
+ 5. If the question needs traversal, aggregation, comparison, or absence checks,
43921
+ compute them over the exported JSON without changing the model or pretending
43922
+ the computation was supported by the query DSL.
43923
+ 6. Report the scope: context, selected source when \`$tab\` is used, query or
43924
+ built-in view, and whether derived or projected edges were included.
43925
+
43926
+ ## Inventory a Context
43927
+
43928
+ The built-in unfiltered view is the simplest broad logical export:
43929
+
43930
+ \`\`\`shell
43931
+ archinsight query . -c <context-id> -v no-filter --format json
43932
+ \`\`\`
43933
+
43934
+ Use the \`elements\` map to inventory qualified identities and types. Use
43935
+ \`edges\` for direct relationships selected by the view. Parent-based render
43936
+ groups are useful presentation metadata but do not replace element ownership in
43937
+ the linked model.
43938
+
43939
+ For a typed inventory, narrow the query:
43940
+
43941
+ \`\`\`cypher
43942
+ MATCH (service:Service)
43943
+ WHERE service.context = $context
43944
+ RETURN service
43945
+ \`\`\`
43946
+
43947
+ ## Direct Dependency Questions
43948
+
43949
+ Outgoing dependencies from one service:
43950
+
43951
+ \`\`\`cypher
43952
+ MATCH (service:Service {id: 'checkout_api', context: $context})-[dependency:REFERENCES]->(target:Element)
43953
+ RETURN service, dependency, target
43954
+ \`\`\`
43955
+
43956
+ Incoming dependencies use the same left-to-right syntax with the target bound
43957
+ on the right:
43958
+
43959
+ \`\`\`cypher
43960
+ MATCH (caller:Element)-[dependency:REFERENCES]->(service:Service {id: 'checkout_api', context: $context})
43961
+ RETURN caller, dependency, service
43962
+ \`\`\`
43963
+
43964
+ These answer one-hop questions. To find all transitively affected elements,
43965
+ export the relevant context graph and traverse its direct \`REFERENCES\` edges
43966
+ outside the query language. State whether derived and projected edges were
43967
+ excluded or analyzed separately so the same dependency is not counted at
43968
+ several architectural levels.
43969
+
43970
+ ## Analyze a Source Fragment
43971
+
43972
+ Use \`$tab\` when the question concerns the semantic fragment rooted in one
43973
+ source and its extensions:
43974
+
43975
+ \`\`\`cypher
43976
+ MATCH (element:Element)
43977
+ WHERE element.sourceIdentity = $tab
43978
+ OPTIONAL MATCH (element)-[dependency:REFERENCES]->(target:Element)
43979
+ RETURN element, dependency, target
43980
+ \`\`\`
43981
+
43982
+ Run it with \`--source <source.ai>\`. Explain that the result follows semantic
43983
+ source identity and can include declarations contributed through \`extend\`;
43984
+ it is not a raw inventory of lines physically present in that file.
43985
+
43986
+ ## Analyze Deployment Realization
43987
+
43988
+ Use the built-in Deployment query JSON when the question is how logical architecture is
43989
+ realized physically:
43990
+
43991
+ \`\`\`shell
43992
+ archinsight query . -c <context-id> -s <logical-source.ai> -v deployment --format json
43993
+ \`\`\`
43994
+
43995
+ For each projected edge, compare outer \`source\` and \`target\` with nested
43996
+ \`edge.source\` and \`edge.target\`. Use \`edge.originSource\` and
43997
+ \`edge.originTarget\` to associate physical segments with their logical wire.
43998
+ Analyze logical wires and projected segments as separate layers; otherwise one
43999
+ dependency can appear to be several independent architectural relationships.
44000
+
44001
+ ## Quality and Impact Checks
44002
+
44003
+ The query DSL cannot directly ask for nodes with no incoming edge, nodes with no
44004
+ outgoing edge, cycles, counts by type, or transitive consumers. Export a broad
44005
+ JSON graph, compute those conditions from qualified ids and direct edges, and
44006
+ then return to source declarations for confirmation. A selected view can omit
44007
+ objects by design, so absence in C1, C2, C3, C4, or Deployment is not evidence that the
44008
+ object is absent from the linked project.
44009
+
44010
+ Analysis findings should distinguish verified model facts, query-dependent
44011
+ observations, externally computed results, and unresolved interpretation. Do
44012
+ not edit the architecture merely to make an analytical query easier.
44013
+ `;
44014
+ }
43169
44015
  function genericQueriesReference() {
43170
44016
  return `# Insight Query Reference
43171
44017
 
@@ -43177,6 +44023,7 @@ diagram.
43177
44023
 
43178
44024
  \`\`\`shell
43179
44025
  archinsight query . -c <context-id> -s <source.ai> -q query.aiq -f text
44026
+ archinsight query . -c <context-id> -s <source.ai> -v deployment --format json
43180
44027
  archinsight render . -c <context-id> -s <source.ai> -q query.aiq -f svg -o diagram.svg
43181
44028
  \`\`\`
43182
44029
 
@@ -43236,8 +44083,8 @@ RETURN service
43236
44083
  \`\`\`
43237
44084
 
43238
44085
  Labels are case-sensitive and match Insight types such as \`System\`,
43239
- \`Container\`, \`Service\`, \`Component\`, \`ExternalSystem\`, and
43240
- \`DeploymentElement\`.
44086
+ \`Container\`, \`Service\`, \`Component\`, \`CodeElement\`, \`ExternalSystem\`,
44087
+ and \`DeploymentElement\`.
43241
44088
 
43242
44089
  Use properties in patterns for exact matches:
43243
44090
 
@@ -43275,6 +44122,7 @@ Supported filters include:
43275
44122
  \`\`\`cypher
43276
44123
  WHERE node.context = $context
43277
44124
  WHERE node.sourceIdentity = $tab
44125
+ WHERE node.deployed = true
43278
44126
  WHERE node IS External
43279
44127
  WHERE NOT node IS DeploymentElement
43280
44128
  WHERE edge.projected = 'true'
@@ -43289,6 +44137,10 @@ Use single quotes for string literals.
43289
44137
  \`CONTAINS\` is case-sensitive. For scalar text it performs substring matching;
43290
44138
  for a list property it tests membership. Match the stored spelling exactly.
43291
44139
 
44140
+ \`node.deployed\` is true when an element's deployment resolves to at least one
44141
+ \`runsOn\` or \`uses\` infrastructure object. The built-in Deployment view uses it to keep
44142
+ undeployed logical elements out of the physical diagram.
44143
+
43292
44144
  ## Relationship Selectors
43293
44145
 
43294
44146
  Relationship selectors are boolean flags inside relationship braces:
@@ -43299,8 +44151,78 @@ OPTIONAL MATCH (node)-[projectedLink {projected}]->(target)
43299
44151
  OPTIONAL MATCH ROLLUP (node)-[rollupLink {derived}]->(target)
43300
44152
  \`\`\`
43301
44153
 
43302
- Use \`{derived}\` for rolled-up edges from child relationships. Use
43303
- \`{projected}\` for deployment/projected edges.
44154
+ Use \`{derived}\` for relationships derived from a lower-level authored edge.
44155
+ Use \`{projected}\` for relationships created by deployment projection.
44156
+
44157
+ \`ROLLUP\` is an operation on the match, not another selector. It walks
44158
+ containment ancestry and binds the nearest endpoint compatible with the node
44159
+ pattern. A component relationship can therefore be viewed between its
44160
+ containers or systems without adding another wire to the model. The
44161
+ relationship alias retains the underlying linked edge while its outer query
44162
+ \`source\` and \`target\` describe the endpoints selected for this view.
44163
+
44164
+ For a projected physical path, \`ROLLUP\` can also use \`originSource\` and
44165
+ \`originTarget\` to discover path segments belonging to a logical wire. The
44166
+ built-in Deployment query uses this to include an incoming path such as
44167
+ \`customer -> CDN -> load balancer -> service\` while keeping every segment's
44168
+ real physical endpoints.
44169
+
44170
+ Do not infer the model solely from a rolled-up arrow. Inspect query JSON to
44171
+ distinguish selected/rendered endpoints from the underlying edge and its
44172
+ logical projection origin.
44173
+
44174
+ ## Query JSON
44175
+
44176
+ \`archinsight query --format json\` returns the semantic render graph selected
44177
+ by the query. Use it as the machine-readable check before interpreting an SVG.
44178
+ The top-level shape is:
44179
+
44180
+ - \`context\`: selected context id;
44181
+ - \`elements\`: a map keyed by query-visible, context-qualified element id;
44182
+ - \`edges\`: selected relationships;
44183
+ - \`groups\`: render groups created by \`GROUP BY\`;
44184
+ - \`externalElements\`: selected ids drawn outside the internal boundary.
44185
+
44186
+ Each edge contains two endpoint pairs:
44187
+
44188
+ - outer \`source\` and \`target\` are the endpoints that the selected graph will
44189
+ draw after rollup and grouping;
44190
+ - nested \`edge.source\` and \`edge.target\` are the endpoints of the underlying
44191
+ linked or projected edge;
44192
+ - nested \`edge.originSource\` and \`edge.originTarget\`, when present, identify
44193
+ the logical wire that produced a projected physical segment.
44194
+
44195
+ An abridged response remains ordinary JSON:
44196
+
44197
+ \`\`\`json
44198
+ {
44199
+ "context": "shop",
44200
+ "elements": {
44201
+ "shop/customer": { "id": "shop/customer", "type": "ExternalActor" },
44202
+ "eu/cloudfront": { "id": "eu/cloudfront", "type": "InfrastructureComponent" }
44203
+ },
44204
+ "edges": [
44205
+ {
44206
+ "source": "shop/customer",
44207
+ "target": "eu/cloudfront",
44208
+ "edge": {
44209
+ "source": "shop/customer",
44210
+ "target": "eu/cloudfront",
44211
+ "originSource": "shop/customer",
44212
+ "originTarget": "shop/web_app",
44213
+ "projected": true
44214
+ }
44215
+ }
44216
+ ],
44217
+ "groups": [],
44218
+ "externalElements": ["shop/customer"]
44219
+ }
44220
+ \`\`\`
44221
+
44222
+ For an unrolled physical deployment segment, the outer and nested endpoints should
44223
+ normally agree. A deliberate ownership rollup may make them differ. An edge is
44224
+ unexpected only after its outer endpoints, underlying edge, projection origin,
44225
+ and query clause have all been checked.
43304
44226
 
43305
44227
  ## Grouping
43306
44228
 
@@ -43336,7 +44258,7 @@ examples/builtin-views/no-filter.aiq
43336
44258
  examples/builtin-views/c1.aiq
43337
44259
  examples/builtin-views/c2.aiq
43338
44260
  examples/builtin-views/c3.aiq
43339
- examples/builtin-views/c4.aiq
44261
+ examples/builtin-views/deployment.aiq
43340
44262
  \`\`\`
43341
44263
 
43342
44264
  C1 usually selects systems in the selected context and rolls lower-level links
@@ -43348,8 +44270,9 @@ relationships, and includes external systems through optional/rollup matches.
43348
44270
  C3 usually starts from \`(container:ContainerElement)-[:CONTAINS]->(component)\`
43349
44271
  and returns component relationships.
43350
44272
 
43351
- C4 usually selects deployment and container nodes from \`$tab\`, uses
43352
- \`OPTIONAL MATCH ROLLUP\`, and returns projected relationships.
44273
+ Deployment selects deployment nodes and physically deployed logical nodes from \`$tab\`,
44274
+ uses \`OPTIONAL MATCH ROLLUP\`, and returns projected relationships rather than
44275
+ their raw logical wires.
43353
44276
 
43354
44277
  When a built-in view is close but hides the wrong thing, read
43355
44278
  \`references/query-recipes.md\`, copy the nearest built-in \`.aiq\`, and change
@@ -43368,9 +44291,9 @@ the filter or grouping deliberately.
43368
44291
  function genericQueryRecipesReference() {
43369
44292
  return `# Query Recipes and Built-In View Customization
43370
44293
 
43371
- Use this reference when a built-in C1/C2/C3/C4 view is close but not quite right:
43372
- an expected element is hidden, a relationship is missing, infrastructure is too
43373
- noisy, or the diagram needs a different scope.
44294
+ Use this reference when a built-in C1, C2, C3, C4, or Deployment view is close but not quite right:
44295
+ an expected element is hidden, a relationship is missing, an unexpected edge
44296
+ appears, infrastructure is too noisy, or the diagram needs a different scope.
43374
44297
 
43375
44298
  ## Start From Built-In Queries
43376
44299
 
@@ -43381,7 +44304,7 @@ examples/builtin-views/no-filter.aiq
43381
44304
  examples/builtin-views/c1.aiq
43382
44305
  examples/builtin-views/c2.aiq
43383
44306
  examples/builtin-views/c3.aiq
43384
- examples/builtin-views/c4.aiq
44307
+ examples/builtin-views/deployment.aiq
43385
44308
  \`\`\`
43386
44309
 
43387
44310
  Before inventing a query from scratch, open the nearest built-in query, copy it
@@ -43389,6 +44312,7 @@ to the project, and make the smallest change.
43389
44312
 
43390
44313
  \`\`\`shell
43391
44314
  archinsight query . -c <context-id> -s <source.ai> -q queries/custom.aiq -f text
44315
+ archinsight query . -c <context-id> -s <source.ai> -q queries/custom.aiq -f json
43392
44316
  archinsight render . -c <context-id> -s <source.ai> -q queries/custom.aiq -f svg -o custom.svg
43393
44317
  \`\`\`
43394
44318
 
@@ -43399,9 +44323,11 @@ customization patterns.
43399
44323
 
43400
44324
  Write or adjust a \`.aiq\` query when:
43401
44325
 
43402
- - the built-in view hides a node or edge that exists in \`archinsight link\`;
44326
+ - the built-in view hides a node or edge visible in the linked graph through a
44327
+ broader query;
44328
+ - the built-in query returns a node or edge outside the intended view scope;
43403
44329
  - the source/tab scope is right but the view intentionally filters out a type;
43404
- - C4 should include actors, vendors, or a special deployment path;
44330
+ - Deployment should include actors, vendors, or a special deployment path;
43405
44331
  - the diagram should show only one layer, one flow, or one relationship class;
43406
44332
  - grouping needs to change, such as grouping by parent instead of \`runsOn\`.
43407
44333
 
@@ -43426,7 +44352,7 @@ When the graph is right but the picture is noisy:
43426
44352
  Do not duplicate infrastructure or invert dependencies only to make one render
43427
44353
  look cleaner.
43428
44354
 
43429
- ## Diagnose A Missing Element
44355
+ ## Diagnose Missing Content
43430
44356
 
43431
44357
  1. Validate the model:
43432
44358
 
@@ -43440,10 +44366,10 @@ archinsight link . --format text
43440
44366
  archinsight structure . --format text
43441
44367
  \`\`\`
43442
44368
 
43443
- 3. Run the built-in query text explicitly:
44369
+ 3. Run the built-in query explicitly and inspect its JSON:
43444
44370
 
43445
44371
  \`\`\`shell
43446
- archinsight query . -c <context-id> -s <source.ai> -q examples/builtin-views/c4.aiq -f text
44372
+ archinsight query . -c <context-id> -s <source.ai> -q examples/builtin-views/deployment.aiq -f json
43447
44373
  \`\`\`
43448
44374
 
43449
44375
  4. Check the query filters:
@@ -43451,54 +44377,63 @@ archinsight query . -c <context-id> -s <source.ai> -q examples/builtin-views/c4.
43451
44377
  - \`node.sourceIdentity = $tab\` selects the semantic fragment rooted in the
43452
44378
  selected source, including contributions added to those roots through
43453
44379
  \`extend\` in other files.
43454
- - The built-in C4 node filter includes deployment elements, container elements,
43455
- and elements whose resolved \`kind\` is \`external\`. Internal actors and other
43456
- logical element families remain outside the view unless a custom query adds
43457
- them.
44380
+ - The built-in Deployment node filter includes deployment elements and logical
44381
+ container or external elements whose deployment resolves to physical
44382
+ infrastructure. External endpoints without their own placement still enter
44383
+ through projected paths attached to a deployed logical node.
43458
44384
  - \`{projected}\` means only deployment-projected edges are selected.
43459
44385
  - \`{derived}\` means only rolled-up relationships are selected.
43460
44386
  - A relationship property such as \`sourceIdentity: $tab\` is available for a
43461
- deliberately narrow custom view. The current built-in C4 query does not add
44387
+ deliberately narrow custom view. The current built-in Deployment query does not add
43462
44388
  that edge filter; the selected node scope and semantic tab closure provide
43463
44389
  the boundary.
43464
- - The built-in C4 view also returns target-side incoming projection aliases:
43465
- \`incomingProjectedLink\`, \`incomingProjectedSource\`,
43466
- \`incomingProjectedOriginLink\`, and \`incomingProjectedOrigin\`. Keep them when
43467
- the target system owns an ingress gateway.
44390
+ - The built-in Deployment view also returns the target-side incoming projection aliases
44391
+ \`incomingProjectedLink\` and \`incomingProjectedSource\`. The rollup match uses
44392
+ projection origin metadata to find every ingress segment while preserving
44393
+ the real physical endpoints of each segment.
44394
+
44395
+ ## Diagnose Unexpected Content
44396
+
44397
+ Do not start by deleting model declarations when a view contains an unexpected
44398
+ node or edge.
44399
+
44400
+ 1. Run \`archinsight link . --format text\` to separate linker errors from view
44401
+ behavior.
44402
+ 2. Run the exact built-in or custom query with \`--format json\`.
44403
+ 3. Find the edge in \`edges\` and compare:
44404
+ - outer \`source\` / \`target\`, which are drawn by the selected graph;
44405
+ - nested \`edge.source\` / \`edge.target\`, which belong to the underlying
44406
+ linked or projected edge;
44407
+ - \`edge.originSource\` / \`edge.originTarget\`, which identify the logical
44408
+ wire behind a projection;
44409
+ - \`edge.projected\` and the clause that returned its alias.
44410
+ 4. Run the nearest built-in query unchanged. If only the custom query returns
44411
+ the edge, fix the custom query. If the built-in query returns it too, reduce
44412
+ the query to the responsible \`MATCH\` clause and report a query/runtime bug.
44413
+ 5. Render only after the JSON result is understood. If JSON is correct and SVG
44414
+ is not, investigate the renderer or layout instead of changing the model.
44415
+
44416
+ \`ROLLUP\` can intentionally select ancestor endpoints for an ownership-level
44417
+ view. That is not a new model wire. A physical deployment segment, however, must retain
44418
+ its actual physical endpoints; projection origin metadata is for discovery and
44419
+ traceability, not for inventing a direct physical connection.
44420
+
44421
+ ## Include Internal Actors In Deployment
44422
+
44423
+ The built-in Deployment query includes external actors reached by a projected physical
44424
+ path. If a deployment diagram also needs internal actors, use the bundled,
44425
+ tested customization:
43468
44426
 
43469
- ## Include Internal Actors In C4
43470
-
43471
- The built-in C4 query already includes external actors when they enter its
43472
- selected scope, because they satisfy \`node IS External\`. If a deployment
43473
- diagram also needs an internal actor, copy \`examples/builtin-views/c4.aiq\` and
43474
- widen the node and projected target filters:
43475
-
43476
- \`\`\`cypher
43477
- MATCH (node:Element)
43478
- WHERE node.sourceIdentity = $tab
43479
- AND (node IS DeploymentElement OR node IS ContainerElement OR node IS Actor)
43480
- OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected}]->(projectedTarget:Element)
43481
- WHERE projectedTarget IS DeploymentElement
43482
- OR projectedTarget IS ContainerElement
43483
- OR projectedTarget IS External
43484
- OR projectedTarget IS Actor
43485
- OPTIONAL MATCH (node)-[directDeploymentLink]->(directDeploymentTarget:Element)
43486
- WHERE node IS DeploymentElement
43487
- AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)
43488
- OPTIONAL MATCH (incomingProjectedSource:Element)-[incomingProjectedLink {projected}]->(node)
43489
- WHERE (incomingProjectedSource IS DeploymentElement
43490
- OR incomingProjectedSource IS ContainerElement
43491
- OR incomingProjectedSource IS External)
43492
- AND incomingProjectedSource.id <> node.id
43493
- OPTIONAL MATCH ROLLUP (incomingProjectedOrigin:Element)-[incomingProjectedOriginLink {projected}]->(incomingProjectedSource)
43494
- WHERE (incomingProjectedOrigin IS DeploymentElement
43495
- OR incomingProjectedOrigin IS ContainerElement
43496
- OR incomingProjectedOrigin IS External)
43497
- AND incomingProjectedOrigin.id <> incomingProjectedSource.id
43498
- GROUP BY node.runsOn
43499
- RETURN node, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget, incomingProjectedLink, incomingProjectedSource, incomingProjectedOriginLink, incomingProjectedOrigin
44427
+ \`\`\`shell
44428
+ archinsight query . -c <context-id> -s <source.ai> -q examples/queries/deployment-internal-actors.aiq -f json
43500
44429
  \`\`\`
43501
44430
 
44431
+ This query is generated from the exact built-in Deployment source and changes only the
44432
+ node, projected-target, and incoming-source predicates to admit \`Actor\`.
44433
+ Because the rest comes from the current built-in query, deployment targets,
44434
+ incoming paths, and infrastructure-to-infrastructure projected path segments
44435
+ stay synchronized with Deployment behavior.
44436
+
43502
44437
  If the actor is declared in another source file, either render from that source
43503
44438
  or relax the \`node.sourceIdentity = $tab\` condition intentionally.
43504
44439
 
@@ -43519,7 +44454,7 @@ This is useful for event-stream, broker, queue, or notification diagrams. Add
43519
44454
 
43520
44455
  ## Hide Deployment Infrastructure
43521
44456
 
43522
- When a C4-oriented source file is too noisy and you only need logical containers
44457
+ When a deployment-oriented source file is too noisy and you only need logical containers
43523
44458
  or services, select logical container elements and direct logical relationships:
43524
44459
 
43525
44460
  \`\`\`cypher
@@ -43530,59 +44465,43 @@ GROUP BY node.parent
43530
44465
  RETURN node, link, target
43531
44466
  \`\`\`
43532
44467
 
43533
- This is intentionally closer to C2 than C4. Use it when deployment annotations
44468
+ This is intentionally closer to C2 than the Deployment view. Use it when deployment annotations
43534
44469
  exist in the file but the diagram question is still logical.
43535
44470
 
43536
44471
  ## Projected Edges Across Split Files
43537
44472
 
43538
- The current built-in C4 query matches \`{projected}\` edges without an explicit
44473
+ The current built-in Deployment query matches \`{projected}\` edges without an explicit
43539
44474
  \`sourceIdentity: $tab\` relationship filter. The query engine expands \`$tab\`
43540
44475
  to the roots declared by the selected source and contributions made to those
43541
44476
  roots through \`extend\`, so a normal multi-file split does not require a looser
43542
44477
  edge selector.
43543
44478
 
43544
44479
  If a project has a custom query copied from an older template, remove the edge
43545
- filter while keeping the node scope:
44480
+ filter while keeping the node scope. Start again from the bundled current query
44481
+ instead of preserving the rest of the older copy:
43546
44482
 
43547
- \`\`\`cypher
43548
- MATCH (node:Element)
43549
- WHERE node.sourceIdentity = $tab
43550
- AND (node IS DeploymentElement OR node IS ContainerElement)
43551
- OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected}]->(projectedTarget:Element)
43552
- WHERE projectedTarget IS DeploymentElement
43553
- OR projectedTarget IS ContainerElement
43554
- OR projectedTarget IS External
43555
- OPTIONAL MATCH (node)-[directDeploymentLink]->(directDeploymentTarget:Element)
43556
- WHERE node IS DeploymentElement
43557
- AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)
43558
- GROUP BY node.runsOn
43559
- RETURN node, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget
44483
+ \`\`\`text
44484
+ copy examples/builtin-views/deployment.aiq to the project's query directory
44485
+ remove sourceIdentity: $tab only from the relationship selector if an old copy has it
44486
+ keep node.sourceIdentity = $tab
43560
44487
  \`\`\`
43561
44488
 
43562
- Validate the result with \`archinsight query\`. If a path is still absent, check
43563
- that its logical relationship contributes to a root selected by the tab before
43564
- changing the model or broadening the node scope.
44489
+ Validate the result with \`archinsight query ... --format json\`. If a path is
44490
+ still absent, check that its logical relationship contributes to a root selected
44491
+ by the tab before changing the model or broadening the node scope.
43565
44492
 
43566
44493
  ## Change Grouping
43567
44494
 
43568
- Grouping controls visual clusters. If C4 grouping by \`runsOn\` is not helpful,
43569
- try grouping by parent:
44495
+ Grouping controls visual clusters. If Deployment grouping by \`runsOn\` is not helpful,
44496
+ copy the complete current \`examples/builtin-views/deployment.aiq\` and change only:
43570
44497
 
43571
44498
  \`\`\`cypher
43572
- MATCH (node:Element)
43573
- WHERE node.sourceIdentity = $tab
43574
- AND (node IS DeploymentElement OR node IS ContainerElement)
43575
- OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected}]->(projectedTarget:Element)
43576
- WHERE projectedTarget IS DeploymentElement
43577
- OR projectedTarget IS ContainerElement
43578
- OR projectedTarget IS External
43579
44499
  GROUP BY node.parent
43580
- RETURN node, projectedLink, projectedTarget
43581
44500
  \`\`\`
43582
44501
 
43583
44502
  Use \`GROUP BY node.runsOn\` for deployment placement; use \`GROUP BY node.parent\`
43584
44503
  for logical ownership. If you still need target-owned ingress paths, start from
43585
- \`examples/builtin-views/c4.aiq\` and change only the \`GROUP BY\` expression so
44504
+ \`examples/builtin-views/deployment.aiq\` and change only the \`GROUP BY\` expression so
43586
44505
  the incoming projection aliases stay in the \`RETURN\`.
43587
44506
 
43588
44507
  ## Working Rule
@@ -43853,7 +44772,53 @@ system storefront
43853
44772
  description = Consumes checkout completion events
43854
44773
  `;
43855
44774
  }
43856
- function genericC4DeploymentFrameworkExample() {
44775
+ function genericC4CodeExampleFiles() {
44776
+ return [
44777
+ {
44778
+ path: "examples/c4-code/definitions.ai",
44779
+ content: `define type Module of CodeElement
44780
+ constructor module
44781
+
44782
+ required Text name
44783
+ Text responsibility
44784
+ List of Wire links
44785
+ List of CodeElement children
44786
+
44787
+ extend type Component
44788
+ List of CodeElement _
44789
+ `
44790
+ },
44791
+ {
44792
+ path: "examples/c4-code/model.ai",
44793
+ content: `context code_sample
44794
+
44795
+ system application
44796
+ name = Application
44797
+
44798
+ service checkout
44799
+ name = Checkout
44800
+
44801
+ component order_processing
44802
+ name = Order processing
44803
+ responsibility = Coordinates checkout
44804
+ module controller
44805
+ name = Checkout controller
44806
+ responsibility = Accepts checkout commands
44807
+ links:
44808
+ -> domain
44809
+
44810
+ module domain
44811
+ name = Checkout domain
44812
+ responsibility = Applies checkout rules
44813
+ children:
44814
+ module validation
44815
+ name = Order validation
44816
+ responsibility = Validates checkout input
44817
+ `
44818
+ }
44819
+ ];
44820
+ }
44821
+ function genericDeploymentFrameworkExample() {
43857
44822
  return `define type ApplicationEnvironment of Environment
43858
44823
  ServiceProvider cloud
43859
44824
  Compute compute
@@ -43879,7 +44844,7 @@ define type Monitoring of InfrastructureComponent
43879
44844
  required InfrastructureComponent display
43880
44845
  `;
43881
44846
  }
43882
- function genericC4DeploymentInfrastructureExample() {
44847
+ function genericDeploymentInfrastructureExample() {
43883
44848
  return `environment eu
43884
44849
  name = Europe
43885
44850
 
@@ -43951,7 +44916,7 @@ deployment production
43951
44916
  target $this connectTo target display
43952
44917
  `;
43953
44918
  }
43954
- function genericC4DeploymentExample() {
44919
+ function genericDeploymentExample() {
43955
44920
  return `context deployment_shop
43956
44921
  name = Deployment Shop
43957
44922
 
@@ -44006,10 +44971,10 @@ system storefront
44006
44971
  uses egress
44007
44972
  `;
44008
44973
  }
44009
- function genericC4PrivateGatewayExampleFiles() {
44974
+ function genericDeploymentPrivateGatewayExampleFiles() {
44010
44975
  return [
44011
44976
  {
44012
- path: "examples/c4-private-gateway/deployment-framework.ai",
44977
+ path: "examples/deployment-private-gateway/deployment-framework.ai",
44013
44978
  content: `define type PrivateGateway of NetworkConnection
44014
44979
  constructor privateGateway
44015
44980
 
@@ -44023,7 +44988,7 @@ define type PrivateGatewayEnvironment of Environment
44023
44988
  `
44024
44989
  },
44025
44990
  {
44026
- path: "examples/c4-private-gateway/source-infra.ai",
44991
+ path: "examples/deployment-private-gateway/source-infra.ai",
44027
44992
  content: `environment source_env
44028
44993
  name = Source Environment
44029
44994
 
@@ -44038,7 +45003,7 @@ deployment production
44038
45003
  `
44039
45004
  },
44040
45005
  {
44041
- path: "examples/c4-private-gateway/target-infra.ai",
45006
+ path: "examples/deployment-private-gateway/target-infra.ai",
44042
45007
  content: `environment target_env
44043
45008
  name = Target Environment
44044
45009
 
@@ -44055,7 +45020,7 @@ deployment production
44055
45020
  `
44056
45021
  },
44057
45022
  {
44058
- path: "examples/c4-private-gateway/source-system.ai",
45023
+ path: "examples/deployment-private-gateway/source-system.ai",
44059
45024
  content: `context services
44060
45025
 
44061
45026
  import target from context services
@@ -44087,7 +45052,7 @@ system source_system
44087
45052
  `
44088
45053
  },
44089
45054
  {
44090
- path: "examples/c4-private-gateway/target-system.ai",
45055
+ path: "examples/deployment-private-gateway/target-system.ai",
44091
45056
  content: `context services
44092
45057
 
44093
45058
  deploymentProfile target_profile
@@ -44106,7 +45071,7 @@ system target_system
44106
45071
  `
44107
45072
  },
44108
45073
  {
44109
- path: "examples/c4-private-gateway/external.ai",
45074
+ path: "examples/deployment-private-gateway/external.ai",
44110
45075
  content: `context external
44111
45076
 
44112
45077
  external system payment