@archinsight/cli 3.0.0-snapshot.5 → 3.0.0-snapshot.6

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 +9 -1
  2. package/build/index.js +841 -54
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -30,7 +30,7 @@ archinsight skill init [project-dir] [--target generic|codex|claude] [--out dir]
30
30
  - `-o, --out <file>` - write payload output to a file instead of stdout.
31
31
  - `-t, --theme <theme>` - render theme; defaults to `light`.
32
32
  - `--target <target>` - skill target for `skill init`: `generic`, `codex`, or `claude`.
33
- - `--force` - replace existing generated skill files.
33
+ - `--force` - delete and recreate the generated skill directory before writing.
34
34
  - `-V, --version` - print version.
35
35
  - `-h, --help` - print help.
36
36
 
@@ -67,9 +67,11 @@ The generic target writes a runtime-neutral guide:
67
67
  c2-containers.md
68
68
  c3-components.md
69
69
  c4-deployment.md
70
+ scaling.md
70
71
  project-structure.md
71
72
  core.md
72
73
  queries.md
74
+ query-recipes.md
73
75
  validation.md
74
76
  .core/
75
77
  *.ai
@@ -80,6 +82,12 @@ The generic target writes a runtime-neutral guide:
80
82
  c4-deployment-framework.ai
81
83
  c4-deployment.ai
82
84
  c2-containers.aiq
85
+ builtin-views/
86
+ no-filter.aiq
87
+ c1.aiq
88
+ c2.aiq
89
+ c3.aiq
90
+ c4.aiq
83
91
  ```
84
92
 
85
93
  Codex and Claude targets package the same Insight reference directly into the
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, stat, writeFile } from "node:fs/promises";
60
+ import { mkdir, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
61
61
  import path from "node:path";
62
62
  import { instance } from "@viz-js/viz";
63
63
 
@@ -34184,6 +34184,7 @@ function linkProject(request) {
34184
34184
  sourceIdentity: edge.sourceName,
34185
34185
  fromId: edge.source,
34186
34186
  toId: target.id,
34187
+ projectedAttributes: materialized.edge.attributes,
34187
34188
  ...materialized.edge.annotations === void 0 ? {} : { annotations: materialized.edge.annotations }
34188
34189
  });
34189
34190
  pendingProjections.push({
@@ -34191,6 +34192,7 @@ function linkProject(request) {
34191
34192
  fromId: edge.source,
34192
34193
  toId: target.id,
34193
34194
  attributes: edgeAttributes,
34195
+ projectedAttributes: materialized.edge.attributes,
34194
34196
  ...materialized.edge.annotations === void 0 ? {} : { annotations: materialized.edge.annotations }
34195
34197
  });
34196
34198
  }
@@ -34220,7 +34222,7 @@ function linkProject(request) {
34220
34222
  });
34221
34223
  }
34222
34224
  for (const projection of pendingProjections) {
34223
- addProjectedEdges(linkedEdges, projection.sourceIdentity, projection.fromId, projection.toId, projection.attributes, linkedElementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, void 0, projection.annotations);
34225
+ addProjectedEdges(linkedEdges, projection.sourceIdentity, projection.fromId, projection.toId, projection.attributes, linkedElementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, void 0, projection.annotations, projection.projectedAttributes);
34224
34226
  }
34225
34227
  const slotDomainTypes = typeSystem.slotDomainTypes();
34226
34228
  for (const element of elements) {
@@ -35248,7 +35250,14 @@ function resolveAttributes(owner, ownerType, attributes2, referenceAttributePosi
35248
35250
  });
35249
35251
  continue;
35250
35252
  }
35251
- result[name] = [...result[name] ?? [], { id: resolved.id, element: resolved }];
35253
+ result[name] = [...result[name] ?? [], {
35254
+ id: resolved.id,
35255
+ element: resolved,
35256
+ line: value.line,
35257
+ column: value.column,
35258
+ ...value.endLine === void 0 ? {} : { endLine: value.endLine },
35259
+ ...value.endColumn === void 0 ? {} : { endColumn: value.endColumn }
35260
+ }];
35252
35261
  }
35253
35262
  }
35254
35263
  return result;
@@ -35284,7 +35293,7 @@ function flattenAttributes(scalarAttributes, attributes2) {
35284
35293
  ...Object.fromEntries(Object.entries(attributes2).map(([name, values]) => [name, values.map((value) => value.id)]))
35285
35294
  };
35286
35295
  }
35287
- function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes2, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], visitedProjectionElements = /* @__PURE__ */ new Set()) {
35296
+ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes2, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes, visitedProjectionElements = /* @__PURE__ */ new Set()) {
35288
35297
  for (const values of Object.values(attributes2)) {
35289
35298
  for (const value of values) {
35290
35299
  if (value.element === void 0) {
@@ -35301,8 +35310,24 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
35301
35310
  if (isDirectSlotReferenceSelfProjection(value.element, fromId, toId)) {
35302
35311
  continue;
35303
35312
  }
35304
- for (const rule3 of typeSystem.projectionRules(value.element.type)) {
35305
- addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, value.element, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2);
35313
+ const rules = typeSystem.projectionRules(value.element.type);
35314
+ if (fromId === toId && rules.some(projectionRuleUsesTo)) {
35315
+ const position3 = value.line === void 0 || value.column === void 0 ? value.element : {
35316
+ line: value.line,
35317
+ column: value.column,
35318
+ ...value.endLine === void 0 ? {} : { endLine: value.endLine },
35319
+ ...value.endColumn === void 0 ? {} : { endColumn: value.endColumn }
35320
+ };
35321
+ diagnostics.push({
35322
+ code: "PROJECTION_TARGET_REQUIRED",
35323
+ message: `Projection for '${value.element.type}' uses '$to' and must be attached to a relationship, not to element '${fromId}'`,
35324
+ sourceName: sourceIdentity,
35325
+ ...diagnosticPosition2(position3)
35326
+ });
35327
+ continue;
35328
+ }
35329
+ for (const rule3 of rules) {
35330
+ addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, value.element, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2, projectedAttributes);
35306
35331
  }
35307
35332
  addProjectedEdges(
35308
35333
  linkedEdges,
@@ -35317,12 +35342,13 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
35317
35342
  diagnostics,
35318
35343
  projectionScope,
35319
35344
  annotations2,
35345
+ void 0,
35320
35346
  visitedProjectionElements
35321
35347
  );
35322
35348
  }
35323
35349
  }
35324
35350
  }
35325
- function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, values, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = []) {
35351
+ function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, values, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes) {
35326
35352
  addProjectedEdges(
35327
35353
  linkedEdges,
35328
35354
  sourceIdentity,
@@ -35335,7 +35361,8 @@ function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, v
35335
35361
  typeSystem,
35336
35362
  diagnostics,
35337
35363
  projectionScope,
35338
- annotations2
35364
+ annotations2,
35365
+ projectedAttributes
35339
35366
  );
35340
35367
  }
35341
35368
  function addEdgeScopes(scopesByCarrierId, attributes2, scope) {
@@ -35352,15 +35379,16 @@ function addEdgeScopes(scopesByCarrierId, attributes2, scope) {
35352
35379
  function isDirectSlotReferenceSelfProjection(element, fromId, toId) {
35353
35380
  return fromId === toId && element.parent === fromId && element.scalarAttributes.parentType !== void 0 && element.scalarAttributes.attributeName !== void 0;
35354
35381
  }
35355
- function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, projectionElement, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = []) {
35382
+ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, projectionElement, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes) {
35356
35383
  const sources = projectionTerm(rule3.source, fromId, toId, projectionElement, elementsById, resolvedElementAttributes, diagnostics);
35357
35384
  const targets = projectionTerm(rule3.target, fromId, toId, projectionElement, elementsById, resolvedElementAttributes, diagnostics);
35385
+ const carriedAttributes = rule3.source.kind === "from" ? projectedAttributes : void 0;
35358
35386
  for (const source of sources) {
35359
35387
  for (const target of targets) {
35360
35388
  if (!projectionRuleUsesOwner(rule3)) {
35361
35389
  const key = `${projectionElement.id}\0${source}\0${rule3.operator}\0${target}`;
35362
35390
  if (ownerIndependentProjectionKeys.has(key)) {
35363
- mergeProjectedEdgeAnnotations(linkedEdges, source, rule3.operator, target, annotations2);
35391
+ mergeProjectedEdge(linkedEdges, source, rule3.operator, target, annotations2, carriedAttributes);
35364
35392
  continue;
35365
35393
  }
35366
35394
  ownerIndependentProjectionKeys.add(key);
@@ -35375,6 +35403,7 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
35375
35403
  if (edge !== void 0) {
35376
35404
  linkedEdges[existingIndex] = {
35377
35405
  ...edge,
35406
+ attributes: mergeAttributeValues(carriedAttributes, edge.attributes),
35378
35407
  annotations: uniqueAnnotations([...edge.annotations ?? [], ...annotations2])
35379
35408
  };
35380
35409
  }
@@ -35388,7 +35417,7 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
35388
35417
  operator: rule3.operator,
35389
35418
  type,
35390
35419
  sourceIdentity,
35391
- attributes: {},
35420
+ attributes: carriedAttributes ?? {},
35392
35421
  ...listAttributesProperty(typeSystem, type),
35393
35422
  projected: true,
35394
35423
  ...projectionScope === void 0 ? {} : { projectionScope },
@@ -35397,8 +35426,8 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
35397
35426
  }
35398
35427
  }
35399
35428
  }
35400
- function mergeProjectedEdgeAnnotations(linkedEdges, source, operator, target, annotations2) {
35401
- if (annotations2.length === 0) {
35429
+ function mergeProjectedEdge(linkedEdges, source, operator, target, annotations2, attributes2) {
35430
+ if (annotations2.length === 0 && (attributes2 === void 0 || Object.keys(attributes2).length === 0)) {
35402
35431
  return;
35403
35432
  }
35404
35433
  const index = linkedEdges.findIndex((edge2) => edge2.projected === true && edge2.source === source && edge2.operator === operator && edge2.target === target);
@@ -35411,9 +35440,19 @@ function mergeProjectedEdgeAnnotations(linkedEdges, source, operator, target, an
35411
35440
  }
35412
35441
  linkedEdges[index] = {
35413
35442
  ...edge,
35443
+ attributes: mergeAttributeValues(attributes2, edge.attributes),
35414
35444
  annotations: uniqueAnnotations([...edge.annotations ?? [], ...annotations2])
35415
35445
  };
35416
35446
  }
35447
+ function mergeAttributeValues(base, override) {
35448
+ if (base === void 0 || Object.keys(base).length === 0) {
35449
+ return override;
35450
+ }
35451
+ if (Object.keys(override).length === 0) {
35452
+ return base;
35453
+ }
35454
+ return { ...base, ...override };
35455
+ }
35417
35456
  function uniqueAnnotations(annotations2) {
35418
35457
  const seen = /* @__PURE__ */ new Set();
35419
35458
  const result = [];
@@ -35438,6 +35477,12 @@ function referenceAttributesProperty(attributes2) {
35438
35477
  function projectionRuleUsesOwner(rule3) {
35439
35478
  return projectionTermUsesOwner(rule3.source) || projectionTermUsesOwner(rule3.target);
35440
35479
  }
35480
+ function projectionRuleUsesTo(rule3) {
35481
+ return projectionTermUsesTo(rule3.source) || projectionTermUsesTo(rule3.target);
35482
+ }
35483
+ function projectionTermUsesTo(term) {
35484
+ return term.kind === "to";
35485
+ }
35441
35486
  function projectionTermUsesOwner(term) {
35442
35487
  return term.kind === "from" || term.kind === "to" || term.kind === "slot";
35443
35488
  }
@@ -36029,7 +36074,8 @@ function applyDeploymentUsesCarrier(carrier, parent, context) {
36029
36074
  context.typeSystem,
36030
36075
  context.diagnostics,
36031
36076
  projectionScope,
36032
- annotations2
36077
+ annotations2,
36078
+ scope.projectedAttributes
36033
36079
  );
36034
36080
  }
36035
36081
  }
@@ -37802,7 +37848,7 @@ var QueryParser = class {
37802
37848
  };
37803
37849
 
37804
37850
  // src/version.ts
37805
- var version = "3.0.0-snapshot.5";
37851
+ var version = "3.0.0-snapshot.6";
37806
37852
 
37807
37853
  // src/index.ts
37808
37854
  var hiddenStructureTypes = /* @__PURE__ */ new Set(["List", "Nothing", "Text", "text"]);
@@ -37995,11 +38041,24 @@ async function runSkillInit(args, skillPackage) {
37995
38041
  const projectRoot = path.resolve(projectPath(args));
37996
38042
  const usesDefaultOutput = args.output === void 0;
37997
38043
  const outputRoot = path.resolve(projectRoot, args.output ?? skillPackage.defaultOutput);
38044
+ if (args.force && await exists(outputRoot)) {
38045
+ assertSafeSkillOutputRoot(projectRoot, outputRoot);
38046
+ await rm(outputRoot, { recursive: true, force: true });
38047
+ }
37998
38048
  for (const file of skillPackage.files) {
37999
38049
  await writeGeneratedFile(path.join(outputRoot, file.path), file.content, args.force);
38000
38050
  }
38001
38051
  process.stdout.write(skillPackageSuccess(projectRoot, outputRoot, skillPackage, usesDefaultOutput));
38002
38052
  }
38053
+ function assertSafeSkillOutputRoot(projectRoot, outputRoot) {
38054
+ if (outputRoot === path.parse(outputRoot).root || outputRoot === process.cwd() || outputRoot === projectRoot) {
38055
+ throw new CliError(`Refusing to delete unsafe skill output directory '${outputRoot}'. Choose a dedicated --out directory.`);
38056
+ }
38057
+ const projectRelativeToOutput = path.relative(outputRoot, projectRoot);
38058
+ if (projectRelativeToOutput !== "" && !projectRelativeToOutput.startsWith("..") && !path.isAbsolute(projectRelativeToOutput)) {
38059
+ throw new CliError(`Refusing to delete skill output directory '${outputRoot}' because it contains the project root.`);
38060
+ }
38061
+ }
38003
38062
  async function loadProject(input) {
38004
38063
  const root = path.resolve(input);
38005
38064
  const sources = await readSources(root);
@@ -38452,7 +38511,7 @@ Options:
38452
38511
  -o, --out <file> Write output to file instead of stdout; for skill init, write the guide directory.
38453
38512
  -t, --theme <theme> Render theme, default: light.
38454
38513
  --target <target> Skill target: generic, codex, or claude.
38455
- --force Replace existing generated skill files.
38514
+ --force Delete and recreate the generated skill directory.
38456
38515
  -V, --version Print version.
38457
38516
  -h, --help Show help.
38458
38517
 
@@ -38539,6 +38598,10 @@ function sharedSkillFiles() {
38539
38598
  path: "references/c4-deployment.md",
38540
38599
  content: genericC4DeploymentReference()
38541
38600
  },
38601
+ {
38602
+ path: "references/scaling.md",
38603
+ content: genericScalingReference()
38604
+ },
38542
38605
  {
38543
38606
  path: "references/project-structure.md",
38544
38607
  content: genericProjectStructureReference()
@@ -38555,6 +38618,10 @@ function sharedSkillFiles() {
38555
38618
  path: "references/queries.md",
38556
38619
  content: genericQueriesReference()
38557
38620
  },
38621
+ {
38622
+ path: "references/query-recipes.md",
38623
+ content: genericQueryRecipesReference()
38624
+ },
38558
38625
  {
38559
38626
  path: "examples/layered-architecture.ai",
38560
38627
  content: genericLayeredArchitectureExample()
@@ -38583,6 +38650,26 @@ function sharedSkillFiles() {
38583
38650
  path: "examples/c2-containers.aiq",
38584
38651
  content: genericC2QueryExample()
38585
38652
  },
38653
+ {
38654
+ path: "examples/builtin-views/no-filter.aiq",
38655
+ content: noFilterQuery
38656
+ },
38657
+ {
38658
+ path: "examples/builtin-views/c1.aiq",
38659
+ content: c1Query
38660
+ },
38661
+ {
38662
+ path: "examples/builtin-views/c2.aiq",
38663
+ content: c2Query
38664
+ },
38665
+ {
38666
+ path: "examples/builtin-views/c3.aiq",
38667
+ content: c3Query
38668
+ },
38669
+ {
38670
+ path: "examples/builtin-views/c4.aiq",
38671
+ content: c4Query
38672
+ },
38586
38673
  ...coreSkillFiles()
38587
38674
  ];
38588
38675
  }
@@ -38645,8 +38732,13 @@ If \`archinsight\` is not available, ask the user to install or expose
38645
38732
  2. Preserve indentation and the project's existing naming style.
38646
38733
  3. Model architecture from the outside inward: context, external actors/systems,
38647
38734
  systems, containers/services, components, and deployment details.
38648
- 4. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38649
- 5. Validate every Insight change with \`archinsight link . --format text\`.
38735
+ 4. When the task touches infrastructure, runtime placement, regions, or
38736
+ deployment, decide per system whether pragmatic mixed C2 or clean
38737
+ C4/deployment is appropriate.
38738
+ 5. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38739
+ 6. Keep definition/framework files separate from model files that declare
38740
+ \`context <id>\`.
38741
+ 7. Validate every Insight change with \`archinsight link . --format text\`.
38650
38742
 
38651
38743
  ## References
38652
38744
 
@@ -38664,12 +38756,16 @@ If \`archinsight\` is not available, ask the user to install or expose
38664
38756
  - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
38665
38757
  models, infrastructure inventories, environment-scoped infrastructure, or
38666
38758
  projection rules.
38759
+ - Read \`references/scaling.md\` when splitting a repository into reusable
38760
+ framework, environment, profile, system, or deployment-view files.
38667
38761
  - Read \`references/project-structure.md\` before searching for declarations,
38668
38762
  planning imports, or making broad edits.
38669
38763
  - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
38670
38764
  attributes, presentations, or projections.
38671
38765
  - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
38672
38766
  files.
38767
+ - Read \`references/query-recipes.md\` when a built-in view hides an expected
38768
+ element/edge or needs customization.
38673
38769
  - Read \`references/validation.md\` before running checks, structure inspection,
38674
38770
  or rendering.
38675
38771
  - Use \`examples/layered-architecture.ai\` as a compact valid model.
@@ -38706,12 +38802,16 @@ Treat this \`SKILL.md\` as the entrypoint. Load reference files only when needed
38706
38802
  - Read \`references/c4-deployment.md\` before adding or repairing deployment/C4
38707
38803
  models, infrastructure inventories, environment-scoped infrastructure, or
38708
38804
  projection rules.
38805
+ - Read \`references/scaling.md\` before splitting a repository into reusable
38806
+ framework, environment, profile, system, or deployment-view files.
38709
38807
  - Read \`references/project-structure.md\` before searching for declarations,
38710
38808
  planning imports, or making broad edits.
38711
38809
  - Read \`references/core.md\` and \`.core/*.ai\` before assuming available
38712
38810
  constructors, attributes, presentations, or projections.
38713
38811
  - Read \`references/queries.md\` before writing custom diagram queries or \`.aiq\`
38714
38812
  files.
38813
+ - Read \`references/query-recipes.md\` before customizing a built-in view or
38814
+ explaining why an expected element/edge is hidden.
38715
38815
  - Read \`references/validation.md\` before running checks, structure inspection,
38716
38816
  or rendering commands.
38717
38817
 
@@ -38738,11 +38838,16 @@ If \`archinsight\` is not available, ask the user to install or expose
38738
38838
  2. Preserve indentation and the project's existing naming style.
38739
38839
  3. Model architecture from the outside inward: context, external actors/systems,
38740
38840
  systems, containers/services, components, and deployment details.
38741
- 4. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38742
- 5. Use \`archinsight structure . --format text\` before broad edits when the
38841
+ 4. When the task touches infrastructure, runtime placement, regions, or
38842
+ deployment, decide per system whether pragmatic mixed C2 or clean
38843
+ C4/deployment is appropriate.
38844
+ 5. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38845
+ 6. Keep definition/framework files separate from model files that declare
38846
+ \`context <id>\`.
38847
+ 7. Use \`archinsight structure . --format text\` before broad edits when the
38743
38848
  project shape is unclear.
38744
- 6. Validate every Insight change with \`archinsight link . --format text\`.
38745
- 7. If validation fails, fix the first real syntax/type/linking error before
38849
+ 8. Validate every Insight change with \`archinsight link . --format text\`.
38850
+ 9. If validation fails, fix the first real syntax/type/linking error before
38746
38851
  adding more model content.
38747
38852
 
38748
38853
  ## References
@@ -38761,12 +38866,16 @@ If \`archinsight\` is not available, ask the user to install or expose
38761
38866
  - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
38762
38867
  models, infrastructure inventories, environment-scoped infrastructure, or
38763
38868
  projection rules.
38869
+ - Read \`references/scaling.md\` when splitting a repository into reusable
38870
+ framework, environment, profile, system, or deployment-view files.
38764
38871
  - Read \`references/project-structure.md\` before searching for declarations,
38765
38872
  planning imports, or making broad edits.
38766
38873
  - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
38767
38874
  attributes, presentations, or projections.
38768
38875
  - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
38769
38876
  files.
38877
+ - Read \`references/query-recipes.md\` when a built-in view hides an expected
38878
+ element/edge or needs customization.
38770
38879
  - Read \`references/validation.md\` before running checks, structure inspection,
38771
38880
  or rendering.
38772
38881
  - Use \`examples/layered-architecture.ai\` as a compact valid model.
@@ -38804,12 +38913,16 @@ they are needed:
38804
38913
  - Read \`references/c4-deployment.md\` before adding or repairing deployment/C4
38805
38914
  models, infrastructure inventories, environment-scoped infrastructure, or
38806
38915
  projection rules.
38916
+ - Read \`references/scaling.md\` before splitting a repository into reusable
38917
+ framework, environment, profile, system, or deployment-view files.
38807
38918
  - Read \`references/project-structure.md\` before searching for declarations,
38808
38919
  planning imports, or making broad edits.
38809
38920
  - Read \`references/core.md\` and \`.core/*.ai\` before assuming available
38810
38921
  constructors, attributes, presentations, or projections.
38811
38922
  - Read \`references/queries.md\` before writing custom diagram queries or \`.aiq\`
38812
38923
  files.
38924
+ - Read \`references/query-recipes.md\` before customizing a built-in view or
38925
+ explaining why an expected element/edge is hidden.
38813
38926
  - Read \`references/validation.md\` before asking the user to run validation,
38814
38927
  structure inspection, or rendering commands.
38815
38928
 
@@ -38836,12 +38949,17 @@ install or expose \`@archinsight/cli\` before changing \`.ai\` files.
38836
38949
  2. Preserve indentation and the project's existing naming style.
38837
38950
  3. Model architecture from the outside inward: context, external actors/systems,
38838
38951
  systems, containers/services, components, and deployment details.
38839
- 4. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38840
- 5. Use \`archinsight structure . --format text\` to inspect the current model
38952
+ 4. When the task touches infrastructure, runtime placement, regions, or
38953
+ deployment, decide per system whether pragmatic mixed C2 or clean
38954
+ C4/deployment is appropriate.
38955
+ 5. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38956
+ 6. Keep definition/framework files separate from model files that declare
38957
+ \`context <id>\`.
38958
+ 7. Use \`archinsight structure . --format text\` to inspect the current model
38841
38959
  before broad edits when the CLI is available.
38842
- 6. Validate every Insight change with \`archinsight link . --format text\` when
38960
+ 8. Validate every Insight change with \`archinsight link . --format text\` when
38843
38961
  shell access is available; otherwise ask the user to run validation.
38844
- 7. If validation fails, fix the first real syntax/type/linking error before
38962
+ 9. If validation fails, fix the first real syntax/type/linking error before
38845
38963
  adding more model content.
38846
38964
 
38847
38965
  ## Communication
@@ -38879,12 +38997,16 @@ sections of Insight unless the existing layering is already understood.
38879
38997
  - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
38880
38998
  models, infrastructure inventories, environment-scoped infrastructure, or
38881
38999
  projection rules.
39000
+ - Read \`references/scaling.md\` when splitting a repository into reusable
39001
+ framework, environment, profile, system, or deployment-view files.
38882
39002
  - Read \`references/project-structure.md\` before searching for declarations,
38883
39003
  planning imports, or making broad edits.
38884
39004
  - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
38885
39005
  attributes, presentations, or projections.
38886
39006
  - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
38887
39007
  files.
39008
+ - Read \`references/query-recipes.md\` when a built-in view hides an expected
39009
+ element/edge or needs customization.
38888
39010
  - Read \`references/validation.md\` before running checks, structure inspection,
38889
39011
  or rendering.
38890
39012
  - Use \`examples/layered-architecture.ai\` as a compact valid model.
@@ -38906,6 +39028,40 @@ function genericModelingReference() {
38906
39028
  Insight syntax is small; most mistakes are modeling mistakes. Decide the view
38907
39029
  question before changing files.
38908
39030
 
39031
+ ## Separate Definitions From Model Sources
39032
+
39033
+ Keep language/framework definitions separate from graph model files.
39034
+
39035
+ - Definition/framework files contain \`define type\`, \`define operator\`,
39036
+ \`define presentation\`, \`extend type\`, \`extend enum of\`, and
39037
+ \`extend presentation\`.
39038
+ - Model files declare \`context <id>\` and create graph objects with
39039
+ constructors such as \`system\`, \`service\`, \`component\`, \`environment\`,
39040
+ or \`deploymentProfile\`.
39041
+
39042
+ Do not mix definition declarations and \`context\` declarations in one source
39043
+ file. Put shared vocabulary in a framework file, then put concrete contexts,
39044
+ systems, environments, profiles, and links in model files. This keeps schema
39045
+ changes reviewable and avoids source-level syntax failures.
39046
+
39047
+ ## Model Source Granularity
39048
+
39049
+ Default to one primary owned system per model source file: the system you are
39050
+ about to detail with containers, services, components, and deployment
39051
+ relationships. This keeps the selected source file useful as a C2/C3/C4 view
39052
+ scope and avoids accidental mega-files.
39053
+
39054
+ Do not create one file per external actor or external system. Shared external
39055
+ dependencies are usually better modeled once in a reusable external context, or
39056
+ in a few external contexts grouped by meaning such as \`external_platforms\`,
39057
+ \`partners\`, or \`regulators\`. Import those shared declarations from system
39058
+ files that need them.
39059
+
39060
+ If a user asks for deeper splitting, use \`extend <object>\` files for the
39061
+ detail being extracted. For example, keep the main service file readable and put
39062
+ large per-service component sets in a small utility subdirectory for that
39063
+ context.
39064
+
38909
39065
  ## Projections Are Bottom-Up
38910
39066
 
38911
39067
  Built-in C1/C2/C3/C4 views are selected from the linked model. They are not
@@ -38969,14 +39125,30 @@ type hierarchy:
38969
39125
  If a nested declaration fails type checking, fix the type/ownership model rather
38970
39126
  than forcing a link or inventing a wrapper element.
38971
39127
 
38972
- ## Keep Infrastructure in the Right View
39128
+ ## Choose Infrastructure Depth Per System
38973
39129
 
38974
- Do not transcribe infrastructure into C2 just because another diagram drew it
38975
- there. Databases, queues, secret stores, compute nodes, gateways, and runtime
38976
- placement are usually deployment/C4 concerns unless the project defines them as
38977
- part of the selected view.
39130
+ Do not force every project into C4/deployment on the first pass. Most modeling
39131
+ work can proceed through C1-C3 without asking about deployment depth. When the
39132
+ task first touches infrastructure, runtime placement, regions, compute, brokers,
39133
+ gateways, storage, or deployment, ask the user or infer from the repository
39134
+ whether the affected system needs a pragmatic mixed C2 view or a clean
39135
+ C4/deployment model.
38978
39136
 
38979
- Use deployment types and projection queries when physical realization matters.
39137
+ Pragmatic mixed C2 is fast: model databases, brokers, gateways, or secret stores
39138
+ next to services when the user wants a quick single-environment diagram. The
39139
+ cost is that C2 now mixes logical containers with infrastructure, and C4 is
39140
+ effectively absent for that system.
39141
+
39142
+ Clean C4 keeps C2 logical and moves physical realization into deployment
39143
+ profiles, environments, inventory slots, and projection rules. This is more work
39144
+ up front, but it supports many-to-many deployment: one logical service can run
39145
+ in several environments whose infrastructure differs by region, provider, or
39146
+ organizational boundary.
39147
+
39148
+ This choice is per-system, not global. A critical system can use clean C4 while
39149
+ peripheral systems stay pragmatic in C2. Starting cheap is acceptable, but know
39150
+ that upgrading mixed C2 infrastructure into clean C4 is a migration, not just an
39151
+ extra attribute.
38980
39152
 
38981
39153
  ## Eventing
38982
39154
 
@@ -38984,8 +39156,10 @@ Use \`~>\` for asynchronous relationships. Model one async wire per meaningful
38984
39156
  topic or event flow between real producer and consumer elements.
38985
39157
 
38986
39158
  Do not invent a broker node just to make the diagram look familiar. If the
38987
- broker is deployment infrastructure, model it in deployment/C4. If the producer
38988
- or consumer is not known, leave a gap and report it instead of fabricating an
39159
+ chosen style is clean C4 and the broker is deployment infrastructure, model it
39160
+ in deployment/C4. If the chosen style is pragmatic mixed C2, a broker-like node
39161
+ can be acceptable, but document that the view mixes levels. If the producer or
39162
+ consumer is not known, leave a gap and report it instead of fabricating an
38989
39163
  element.
38990
39164
 
38991
39165
  ## No Fabricated Elements
@@ -39069,6 +39243,11 @@ Definition files are different from model files. They declare vocabulary:
39069
39243
  \`extend enum of\`, and \`extend presentation\`. Model files usually start with
39070
39244
  \`context <id>\` and then create graph object instances with constructors.
39071
39245
 
39246
+ Do not mix these source forms in one file. A framework/definitions file should
39247
+ contain only vocabulary/schema declarations. A model file should declare a
39248
+ \`context <id>\` and graph object instances. If both are needed, create two
39249
+ files and validate the whole project.
39250
+
39072
39251
  ## Type Definitions and Extensions
39073
39252
 
39074
39253
  Use \`define type\` to create a new graph/value type. Use \`extend type\` to add
@@ -39568,6 +39747,22 @@ the selected source file, so a C2 file should usually contain the selected
39568
39747
  \`system <id>\` declaration or an \`extend system <id>\` block with its
39569
39748
  containers/services.
39570
39749
 
39750
+ ## C2 Purity vs Pragmatic Infrastructure
39751
+
39752
+ The clean C2 answer is logical: deployable containers/services and how they
39753
+ collaborate. In that mode, databases, brokers, gateways, vaults, compute, and
39754
+ regions belong to C4/deployment.
39755
+
39756
+ Archinsight does not force that choice. For a quick or single-environment model,
39757
+ it is acceptable to put simple infrastructure-like runtime nodes into C2 when
39758
+ the user wants speed over strict layer separation. Be explicit about the
39759
+ tradeoff: the C2 view becomes mixed, C4 is not really modeled for that system,
39760
+ and many-to-many deployment across different environments will not be available
39761
+ until the model is migrated to clean C4.
39762
+
39763
+ Choose this per system. Do not make the whole repository clean or mixed just
39764
+ because one system needs that style.
39765
+
39571
39766
  ## C2 Workflow
39572
39767
 
39573
39768
  1. Run \`archinsight structure . --format text\` to find the exact system id,
@@ -39703,9 +39898,11 @@ service checkout_api
39703
39898
  description = Publishes completed checkout events
39704
39899
  \`\`\`
39705
39900
 
39706
- Do not add a broker node just to make an event diagram look familiar. A broker
39707
- is usually deployment/C4 infrastructure unless the project defines it as a
39708
- runtime system or service in the selected view.
39901
+ Do not add a broker node just to make an event diagram look familiar. In clean
39902
+ C2, a broker is usually deployment/C4 infrastructure unless the project defines
39903
+ it as a runtime system or service in the selected view. In pragmatic mixed C2,
39904
+ adding a broker can be acceptable for a quick view, but it means the diagram is
39905
+ no longer strictly logical C2.
39709
39906
 
39710
39907
  ## C2 Link Details
39711
39908
 
@@ -39726,8 +39923,9 @@ details at C2 only when they clarify the architecture; otherwise use a plain
39726
39923
  ## What Not To Put In C2
39727
39924
 
39728
39925
  - Components, classes, handlers, repositories, or UI widgets.
39729
- - Deployment nodes, pods, regions, network gateways, or secret stores unless the
39730
- project models them as C2 runtime systems.
39926
+ - Deployment nodes, pods, regions, network gateways, or secret stores in clean
39927
+ C2. Include them only when the user intentionally wants pragmatic mixed C2 or
39928
+ the project models them as C2 runtime systems.
39731
39929
  - Database tables and internal schemas.
39732
39930
  - One-off scripts or build-time tools unless they are real runtime units.
39733
39931
  - Duplicate links already represented at a lower C3 level unless the C2 view is
@@ -39736,7 +39934,8 @@ details at C2 only when they clarify the architecture; otherwise use a plain
39736
39934
  ## Common C2 Mistakes
39737
39935
 
39738
39936
  - Adding C2 nodes directly under \`context\` instead of under a \`system\`.
39739
- - Modeling infrastructure that belongs to C4/deployment.
39937
+ - Modeling infrastructure in C2 without deciding that the system is using the
39938
+ pragmatic mixed-C2 style.
39740
39939
  - Mixing C2 container/service links with C3 component links in the same source
39741
39940
  file without a clear view goal.
39742
39941
  - Forgetting \`--source <c2-file.ai>\` when rendering C2.
@@ -40056,6 +40255,7 @@ projection rules.
40056
40255
  ## Contents
40057
40256
 
40058
40257
  - What C4 Answers
40258
+ - Before You Use C4
40059
40259
  - Mental Model
40060
40260
  - C4 Workflow
40061
40261
  - Environment Inventory
@@ -40081,6 +40281,31 @@ C4 is not just another decomposition level. C1-C3 mostly describe logical
40081
40281
  architecture. C4 maps logical elements and links onto environment-local
40082
40282
  infrastructure inventory.
40083
40283
 
40284
+ ## Before You Use C4
40285
+
40286
+ C4/deployment is optional. Do not push the user into environments, projection
40287
+ rules, and infrastructure inventory when they only need a quick logical/runtime
40288
+ view.
40289
+
40290
+ If the work has reached infrastructure, runtime placement, regions, compute, or
40291
+ deployment, ask or infer the intended style for the current system:
40292
+
40293
+ - Pragmatic mixed C2: put simple infrastructure-like runtime nodes such as a
40294
+ database, broker, gateway, or vault near the services in C2. This is fast and
40295
+ easier for simple or single-environment systems, but it mixes abstraction
40296
+ levels and does not produce a real C4 model.
40297
+ - Clean C4: keep C2 logical and describe physical realization through
40298
+ \`Environment\` slots, deployment profiles, inventory, \`runsOn\`, \`uses\`,
40299
+ and projection rules. This takes more design work, but supports region/env
40300
+ differences, many-to-many deployment, and organization-specific runtime
40301
+ complexity.
40302
+
40303
+ The choice is per-system. Model a critical system with clean C4 and keep a
40304
+ peripheral system pragmatic in C2 if that matches the user's needs. If a system
40305
+ starts as mixed C2 and later needs multi-env deployment, expect a migration:
40306
+ infrastructure nodes must move into environment inventory and links must gain
40307
+ deployment/projection semantics.
40308
+
40084
40309
  ## Mental Model
40085
40310
 
40086
40311
  There are three layers:
@@ -40250,7 +40475,27 @@ Prefer C2 containers/services for most deployment mapping:
40250
40475
  Use C1 deployment only when the whole system is deployed as one unit. Use C3
40251
40476
  deployment when a component is independently deployed or has a distinct physical
40252
40477
  path. Use wire deployment when a specific logical relationship travels through
40253
- infrastructure such as a public gateway, private gateway, broker, or egress path.
40478
+ infrastructure such as a public gateway, network connection, broker, or egress
40479
+ path.
40480
+
40481
+ ## Element-Level vs Wire-Level Infrastructure
40482
+
40483
+ Attach infrastructure to an element when the projection only needs the deployed
40484
+ element itself:
40485
+
40486
+ - \`runsOn compute\`: placement/grouping.
40487
+ - \`uses storage\`: the element depends on stateful infrastructure.
40488
+ - \`uses observability\`: monitoring sidecars or collectors around the element.
40489
+
40490
+ Attach infrastructure to a wire when the projection needs a real target:
40491
+
40492
+ - \`uses publicGateway\`: expands a caller-to-service path through ingress.
40493
+ - \`uses network\`: keeps a direct source-to-target network path on C4.
40494
+ - \`uses broker\`: both producer and consumer physically connect to the broker.
40495
+
40496
+ Rule of thumb: if the infrastructure type's \`project:\` block mentions \`$to\`,
40497
+ use it on a relationship under \`links:\`. Using it on an element is invalid
40498
+ because an element deployment has no separate target endpoint.
40254
40499
 
40255
40500
  ## usesProfile, environmentsFrom, runsOn, and uses
40256
40501
 
@@ -40367,7 +40612,6 @@ deploymentProfile global_service
40367
40612
  global_edge
40368
40613
 
40369
40614
  runsOn compute
40370
- uses publicGateway
40371
40615
 
40372
40616
  deploymentProfile regional_service
40373
40617
  environments:
@@ -40384,6 +40628,11 @@ container web_app
40384
40628
  name = Web app
40385
40629
  deployment:
40386
40630
  usesProfile global_service
40631
+ links:
40632
+ -> checkout_api
40633
+ deployment:
40634
+ environmentsFrom global_service
40635
+ uses publicGateway
40387
40636
 
40388
40637
  service checkout_api
40389
40638
  name = Checkout API
@@ -40392,18 +40641,19 @@ service checkout_api
40392
40641
  uses storage
40393
40642
  \`\`\`
40394
40643
 
40395
- The profile supplies the common environment scope, placement, and standard
40644
+ The profile supplies the common environment scope, placement, and element-level
40396
40645
  infrastructure. Additional local \`uses\` entries extend the profile for that
40397
40646
  specific element. In the example, \`checkout_api\` inherits regional compute and
40398
40647
  observability from \`regional_service\`, then adds its own \`uses storage\`
40399
- because this service owns persistent state.
40648
+ because this service owns persistent state. The \`web_app -> checkout_api\` wire uses
40649
+ \`environmentsFrom global_service\` to reuse the environment list while attaching
40650
+ the path-only \`publicGateway\` projection to the relationship.
40400
40651
 
40401
- Use separate profiles when the default infrastructure differs. For example,
40402
- \`public_regional_service\` can include both \`uses observability\` and
40403
- \`uses publicGateway\`, while \`regional_worker\` may use the same environments,
40404
- compute, and observability but omit public ingress. Put path-only infrastructure
40405
- such as \`network\` on the wire deployment when it represents a specific
40406
- service-to-service path.
40652
+ Use separate profiles when the element-level defaults differ. For example,
40653
+ \`regional_service\` can include \`runsOn compute\` and \`uses observability\`,
40654
+ while \`regional_stateful_service\` can also include \`uses storage\`. Keep
40655
+ path-only infrastructure such as \`publicGateway\`, \`network\`, or \`broker\`
40656
+ on the wire deployment where the source and target are known.
40407
40657
 
40408
40658
  When an element should reuse only the environments from an archetype, use
40409
40659
  \`environmentsFrom <profile>\` instead of \`usesProfile <profile>\` and then add
@@ -40467,6 +40717,10 @@ queries commonly select projected deployment edges; a plain logical wire without
40467
40717
  deployment projection may be correct in C2/C3 but absent from the deployment
40468
40718
  layer.
40469
40719
 
40720
+ If validation reports \`PROJECTION_TARGET_REQUIRED\`, you attached a projection
40721
+ that uses \`$to\` to an element. Move that \`uses ...\` entry to the relevant
40722
+ wire and reuse the element's environment scope with \`environmentsFrom\`.
40723
+
40470
40724
  Projection terms:
40471
40725
 
40472
40726
  - \`$from\` is the logical source of the deployment use.
@@ -40551,7 +40805,6 @@ deploymentProfile public_regional_service
40551
40805
 
40552
40806
  runsOn compute
40553
40807
  uses observability
40554
- uses publicGateway
40555
40808
 
40556
40809
  service checkout_api
40557
40810
  name = Checkout API
@@ -40604,7 +40857,8 @@ logical service projects into both environments without duplicating
40604
40857
  - Logical components invented only to represent physical routing.
40605
40858
  - C3 internals unless they are independently deployed.
40606
40859
  - Cloud resources with no relationship to a deployment question.
40607
- - A broker/gateway/load balancer in C2 just because it appears in deployment.
40860
+ - A broker/gateway/load balancer in C2 just because it appears in deployment,
40861
+ unless the system intentionally uses the pragmatic mixed-C2 style.
40608
40862
 
40609
40863
  ## Common C4 Mistakes
40610
40864
 
@@ -40630,6 +40884,272 @@ Use \`examples/c4-deployment-framework.ai\` and \`examples/c4-deployment.ai\` as
40630
40884
  a compact valid C4 model when syntax is unclear.
40631
40885
  `;
40632
40886
  }
40887
+ function genericScalingReference() {
40888
+ return `# Scaling an Archinsight Repository
40889
+
40890
+ Use this reference when a project grows beyond one or two files and you need to
40891
+ reuse definitions, environments, deployment profiles, or systems without
40892
+ duplicating them.
40893
+
40894
+ ## Repository Shape
40895
+
40896
+ Prefer one shared framework per repository:
40897
+
40898
+ - one definitions/framework area for \`extend type Environment\`, custom
40899
+ infrastructure types, presentation tweaks, projection-capable infrastructure,
40900
+ and reusable deployment profiles;
40901
+ - source files grouped by context directories when the repository is large;
40902
+ - model files that usually focus on one primary owned system being detailed;
40903
+ - one or more inventory files for concrete \`environment <id>\` instances and
40904
+ their env-local infrastructure;
40905
+ - shared external contexts for external actors and systems reused by many
40906
+ systems;
40907
+ - focused deployment-view files that attach deployment profiles and per-view
40908
+ traffic paths.
40909
+
40910
+ Do not copy the same \`extend type Environment\`, infra type definitions, or
40911
+ \`deploymentProfile\` blocks into every system file. Define the vocabulary and
40912
+ reusable archetypes once, import or reference them where needed, and validate the
40913
+ whole project.
40914
+
40915
+ ## Framework Once, Use Everywhere
40916
+
40917
+ A typical deployment framework file contains only shared vocabulary: type
40918
+ definitions, type extensions, projection rules, and presentation overrides. Do
40919
+ not mix \`define type\` / \`extend type\` declarations and \`context\`
40920
+ declarations in the same source file.
40921
+
40922
+ \`\`\`insight
40923
+ define type PublicGateway of InfrastructureComponent
40924
+ constructor publicGateway
40925
+ required InfrastructureComponent cdn
40926
+ required InfrastructureComponent loadBalancer
40927
+
40928
+ project:
40929
+ $from -> cdn
40930
+ cdn -> loadBalancer
40931
+ loadBalancer -> $this
40932
+ $this -> $to
40933
+
40934
+ extend type Environment
40935
+ Compute compute
40936
+ Storage storage
40937
+ Broker broker
40938
+ PublicGateway publicGateway
40939
+ NetworkConnection network
40940
+ \`\`\`
40941
+
40942
+ Concrete inventory/profile files then declare contexts, environments, and
40943
+ profiles:
40944
+
40945
+ \`\`\`insight
40946
+ context infra
40947
+ name = Shared Infrastructure
40948
+
40949
+ environment prod_eu
40950
+ name = Production EU
40951
+ compute:
40952
+ compute ecs
40953
+ name = ECS
40954
+ technology = AWS ECS
40955
+ broker:
40956
+ broker kafka
40957
+ name = Kafka
40958
+ technology = MSK
40959
+ address = kafka.prod.eu.internal
40960
+
40961
+ deploymentProfile regional_service
40962
+ environments:
40963
+ prod_eu
40964
+
40965
+ runsOn compute
40966
+ \`\`\`
40967
+
40968
+ System files should reuse these definitions instead of recreating \`compute\`,
40969
+ \`broker\`, or profile declarations locally.
40970
+
40971
+ ## System Files and External Contexts
40972
+
40973
+ The default model file is centered on one owned system:
40974
+
40975
+ \`\`\`text
40976
+ commerce/
40977
+ checkout.ai
40978
+ catalog.ai
40979
+ fulfillment.ai
40980
+ external/
40981
+ platforms.ai
40982
+ regulators.ai
40983
+ \`\`\`
40984
+
40985
+ \`commerce/checkout.ai\` would declare \`context commerce\`, the
40986
+ \`system checkout\` focal object, and the containers/services/components needed
40987
+ to explain checkout. \`commerce/catalog.ai\` would do the same for catalog.
40988
+
40989
+ Shared external actors and systems should not be copied into every system file.
40990
+ Put them in one external context, or a few semantically grouped external
40991
+ contexts:
40992
+
40993
+ \`\`\`insight
40994
+ context external_platforms
40995
+
40996
+ external system stripe
40997
+ name = Stripe
40998
+
40999
+ external system sendgrid
41000
+ name = SendGrid
41001
+ \`\`\`
41002
+
41003
+ Then import them where needed:
41004
+
41005
+ \`\`\`insight
41006
+ context commerce
41007
+
41008
+ import stripe from context external_platforms
41009
+
41010
+ system checkout
41011
+ links:
41012
+ -> stripe from external_platforms
41013
+ \`\`\`
41014
+
41015
+ Avoid making a separate file for every external actor or vendor unless the
41016
+ external dependency itself has substantial reusable structure. A small number of
41017
+ well-named external contexts gives all repository systems one shared vocabulary
41018
+ for outside dependencies.
41019
+
41020
+ When a system file becomes too large, split details by extending the focal
41021
+ object in utility subdirectories:
41022
+
41023
+ \`\`\`text
41024
+ commerce/
41025
+ checkout.ai
41026
+ checkout-components/
41027
+ pricing.ai
41028
+ payment.ai
41029
+ inventory.ai
41030
+ \`\`\`
41031
+
41032
+ Those files should repeat the same \`context commerce\`, explicitly import the
41033
+ object being extended when it lives in another source file, and use
41034
+ \`extend service checkout_api\`, \`extend container web_app\`, or another object
41035
+ extension to add focused details.
41036
+
41037
+ ## Same-Context Cross-File Imports
41038
+
41039
+ Insight resolves unqualified ids in this order: declarations in the same source
41040
+ file, explicit imports in the same source file, then it reports an error if the
41041
+ same id exists only in another source file of the same context.
41042
+
41043
+ That means splitting one context across files still requires imports:
41044
+
41045
+ \`\`\`insight
41046
+ context services
41047
+
41048
+ deploymentProfile eu_service
41049
+ \`\`\`
41050
+
41051
+ \`\`\`insight
41052
+ context services
41053
+
41054
+ import eu_service from context services
41055
+
41056
+ system checkout
41057
+ name = Checkout
41058
+ deployment:
41059
+ usesProfile eu_service
41060
+ \`\`\`
41061
+
41062
+ This is intentional. If a file is extracted, removed, or not included in the
41063
+ project, the linker should fail with an explicit identifier/import diagnostic
41064
+ instead of silently binding to whatever remains in the context.
41065
+
41066
+ ## Inline from Context
41067
+
41068
+ When a relationship target is declared outside the current source file, prefer
41069
+ an explicit context qualifier on the link target:
41070
+
41071
+ \`\`\`insight
41072
+ context commerce
41073
+
41074
+ import payments from context external_systems
41075
+
41076
+ system checkout
41077
+ name = Checkout
41078
+ links:
41079
+ -> payments from external_systems
41080
+ technology = HTTPS
41081
+ call = POST /payments
41082
+ \`\`\`
41083
+
41084
+ The \`import <id> from context <context-id>\` line documents the dependency and
41085
+ makes the id available for attributes such as profiles and environment slots.
41086
+ The inline \`from <context-id>\` on a link target states which context owns the
41087
+ linked element. Use the same pattern for same-context cross-file links when the
41088
+ source has been split and ambiguity matters:
41089
+
41090
+ \`\`\`insight
41091
+ context services
41092
+
41093
+ import inventory_api from context services
41094
+
41095
+ system checkout_api
41096
+ links:
41097
+ -> inventory_api from services
41098
+ technology = HTTPS
41099
+ call = GET /inventory
41100
+ \`\`\`
41101
+
41102
+ This explicitness is useful during refactors: if the source file holding
41103
+ \`inventory_api\` disappears, validation points at the missing declaration
41104
+ instead of creating a hidden dependency on file layout.
41105
+
41106
+ ## C4 Multi-File Pattern
41107
+
41108
+ For C4, keep these responsibilities separate:
41109
+
41110
+ - framework file: type extensions, infra constructors, presentation/projection
41111
+ definitions;
41112
+ - inventory/profile file: concrete environments and reusable deployment
41113
+ profiles;
41114
+ - deployment-view file: the relationships whose deployment path you want to
41115
+ render for one selected view.
41116
+
41117
+ When rendering C4 with \`-s <source.ai>\`, remember that source/tab scoping is
41118
+ part of the view. Put the view-driving logical relationships in the selected
41119
+ source file, or render from the source file that owns those relationships. Keep
41120
+ imported framework and inventory reusable, but validate the rendered C4 output
41121
+ after moving traffic relationships across files:
41122
+
41123
+ \`\`\`shell
41124
+ archinsight link . --format text
41125
+ archinsight render . -c deployment_shop -s c4-deployment.ai -v c4 -f svg -o deployment-c4.svg
41126
+ \`\`\`
41127
+
41128
+ If projected infrastructure edges disappear after a split, first check whether
41129
+ the selected \`-s\` file still contains the source logical relationship or an
41130
+ intended imported deployment-view relationship. Do not fix that by duplicating
41131
+ infrastructure nodes; fix the source selection or the file boundary.
41132
+
41133
+ ## Practical Workflow
41134
+
41135
+ 1. Run \`archinsight structure . --format text\`.
41136
+ 2. Identify contexts, source files, and declaration ids before editing.
41137
+ 3. Move shared vocabulary into one framework file.
41138
+ 4. Group model files by context directory when the repository is large.
41139
+ 5. Keep each ordinary system file focused on one owned system being detailed.
41140
+ 6. Put external actors/systems in shared external contexts, not one file per
41141
+ external element.
41142
+ 7. Move reusable environments and deployment profiles into inventory/profile
41143
+ files.
41144
+ 8. Add explicit imports for every cross-file dependency, including same-context
41145
+ dependencies.
41146
+ 9. Add inline \`from <context-id>\` on relationship targets that live outside
41147
+ the current source file.
41148
+ 10. Validate with \`archinsight link . --format text\`.
41149
+ 11. Render important C1/C2/C3/C4 views with explicit \`-c\`, \`-s\`, and \`-v\`
41150
+ options.
41151
+ `;
41152
+ }
40633
41153
  function genericProjectStructureReference() {
40634
41154
  return `# Project Structure Workflow
40635
41155
 
@@ -40637,6 +41157,37 @@ Use \`archinsight structure\` before broad edits, imports, or declaration lookup
40637
41157
  Do not start with raw grep when you need to know what the linked project
40638
41158
  contains.
40639
41159
 
41160
+ ## Source File Classes
41161
+
41162
+ Keep source files in one role:
41163
+
41164
+ - definition/framework files: \`define type\`, \`define operator\`,
41165
+ \`define presentation\`, \`extend type\`, \`extend enum of\`, and
41166
+ \`extend presentation\`;
41167
+ - model files: \`context <id>\`, imports, graph object declarations,
41168
+ relationships, environments, and deployment profiles.
41169
+
41170
+ Do not mix definition/framework declarations with \`context <id>\` in one file.
41171
+ When a model needs custom vocabulary, add or edit a framework file first, then
41172
+ use the resulting constructors and attributes from model files.
41173
+
41174
+ ## Directory and File Granularity
41175
+
41176
+ For larger repositories, group model files by context directory. Inside a
41177
+ context directory, default to one primary owned system per ordinary model file:
41178
+ the system that will be detailed by containers, services, components, links, and
41179
+ deployment information.
41180
+
41181
+ External actors and systems are different. Put reusable outside dependencies in
41182
+ one external context or a few semantically grouped external contexts. Do not
41183
+ create a separate file for every external actor or vendor unless that external
41184
+ dependency has real internal structure to model.
41185
+
41186
+ If a system needs further splitting, create a utility subdirectory for focused
41187
+ \`extend <object>\` files, such as per-service component files. Import the
41188
+ extended object explicitly when it is declared in another source file. Keep the
41189
+ main system file as the readable entry point.
41190
+
40640
41191
  ## Commands
40641
41192
 
40642
41193
  Human-readable overview:
@@ -40684,6 +41235,33 @@ links:
40684
41235
  -> payments from external_systems
40685
41236
  \`\`\`
40686
41237
 
41238
+ Imports are also required when a declaration lives in another source file of the
41239
+ same context:
41240
+
41241
+ \`\`\`insight
41242
+ context services
41243
+
41244
+ import eu_service from context services
41245
+
41246
+ system checkout_api
41247
+ deployment:
41248
+ usesProfile eu_service
41249
+ \`\`\`
41250
+
41251
+ The explicit import is intentional. If the source file that declared
41252
+ \`eu_service\` is removed or excluded, validation should fail with a clear
41253
+ missing import/identifier diagnostic instead of depending on hidden file layout.
41254
+
41255
+ For links, \`from <context-id>\` on the target is an inline context qualifier:
41256
+
41257
+ \`\`\`insight
41258
+ links:
41259
+ -> inventory_api from services
41260
+ \`\`\`
41261
+
41262
+ Use it when the relationship target is owned by another context or another
41263
+ source file whose context ownership should remain visible at the call site.
41264
+
40687
41265
  Do not guess context ids from filenames. Filenames, context ids, and element ids
40688
41266
  can differ.
40689
41267
 
@@ -41141,6 +41719,16 @@ diagram needs stable layout.
41141
41719
 
41142
41720
  ## Built-In View Patterns
41143
41721
 
41722
+ Exact built-in query sources are bundled in:
41723
+
41724
+ \`\`\`text
41725
+ examples/builtin-views/no-filter.aiq
41726
+ examples/builtin-views/c1.aiq
41727
+ examples/builtin-views/c2.aiq
41728
+ examples/builtin-views/c3.aiq
41729
+ examples/builtin-views/c4.aiq
41730
+ \`\`\`
41731
+
41144
41732
  C1 usually selects systems in the selected context and rolls lower-level links
41145
41733
  up to system-level relationships.
41146
41734
 
@@ -41153,6 +41741,10 @@ and returns component relationships.
41153
41741
  C4 usually selects deployment and container nodes from \`$tab\`, uses
41154
41742
  \`OPTIONAL MATCH ROLLUP\`, and returns projected relationships.
41155
41743
 
41744
+ When a built-in view is close but hides the wrong thing, read
41745
+ \`references/query-recipes.md\`, copy the nearest built-in \`.aiq\`, and change
41746
+ the filter or grouping deliberately.
41747
+
41156
41748
  ## Authoring Rules
41157
41749
 
41158
41750
  - Start from the view question: context, containers, components, or deployment.
@@ -41163,6 +41755,189 @@ C4 usually selects deployment and container nodes from \`$tab\`, uses
41163
41755
  - Keep custom queries in \`.aiq\` files when they are reused.
41164
41756
  `;
41165
41757
  }
41758
+ function genericQueryRecipesReference() {
41759
+ return `# Query Recipes and Built-In View Customization
41760
+
41761
+ Use this reference when a built-in C1/C2/C3/C4 view is close but not quite right:
41762
+ an expected element is hidden, a relationship is missing, infrastructure is too
41763
+ noisy, or the diagram needs a different scope.
41764
+
41765
+ ## Start From Built-In Queries
41766
+
41767
+ The generated skill includes exact built-in view queries:
41768
+
41769
+ \`\`\`text
41770
+ examples/builtin-views/no-filter.aiq
41771
+ examples/builtin-views/c1.aiq
41772
+ examples/builtin-views/c2.aiq
41773
+ examples/builtin-views/c3.aiq
41774
+ examples/builtin-views/c4.aiq
41775
+ \`\`\`
41776
+
41777
+ Before inventing a query from scratch, open the nearest built-in query, copy it
41778
+ to the project, and make the smallest change.
41779
+
41780
+ \`\`\`shell
41781
+ archinsight query . -c <context-id> -s <source.ai> -q queries/custom.aiq -f text
41782
+ archinsight render . -c <context-id> -s <source.ai> -q queries/custom.aiq -f svg -o custom.svg
41783
+ \`\`\`
41784
+
41785
+ Use \`references/queries.md\` for syntax details. Use this file for common
41786
+ customization patterns.
41787
+
41788
+ ## When To Customize
41789
+
41790
+ Write or adjust a \`.aiq\` query when:
41791
+
41792
+ - the built-in view hides a node or edge that exists in \`archinsight link\`;
41793
+ - the source/tab scope is right but the view intentionally filters out a type;
41794
+ - C4 should include actors, vendors, or a special deployment path;
41795
+ - the diagram should show only one layer, one flow, or one relationship class;
41796
+ - grouping needs to change, such as grouping by parent instead of \`runsOn\`.
41797
+
41798
+ Do not compensate for a view filter by duplicating model elements. First inspect
41799
+ the built-in query and decide whether the model or the query owns the behavior.
41800
+
41801
+ ## Diagnose A Missing Element
41802
+
41803
+ 1. Validate the model:
41804
+
41805
+ \`\`\`shell
41806
+ archinsight link . --format text
41807
+ \`\`\`
41808
+
41809
+ 2. Inspect declarations and source identities:
41810
+
41811
+ \`\`\`shell
41812
+ archinsight structure . --format text
41813
+ \`\`\`
41814
+
41815
+ 3. Run the built-in query text explicitly:
41816
+
41817
+ \`\`\`shell
41818
+ archinsight query . -c <context-id> -s <source.ai> -q examples/builtin-views/c4.aiq -f text
41819
+ \`\`\`
41820
+
41821
+ 4. Check the query filters:
41822
+
41823
+ - \`node.sourceIdentity = $tab\` means the node must be declared in the selected
41824
+ source file.
41825
+ - \`node IS DeploymentElement\` hides actors and ordinary logical elements.
41826
+ - \`{projected}\` means only derived deployment projection edges are selected.
41827
+ - \`{derived}\` means only rolled-up relationships are selected.
41828
+ - \`sourceIdentity: $tab\` on an edge means the relationship/projection must come
41829
+ from the selected source.
41830
+
41831
+ ## Include External Actors In C4
41832
+
41833
+ The built-in C4 query focuses on deployment/container nodes. If a deployment
41834
+ diagram needs the external actor that starts the traffic path, copy
41835
+ \`examples/builtin-views/c4.aiq\` and widen the node and projected target filters:
41836
+
41837
+ \`\`\`cypher
41838
+ MATCH (node:Element)
41839
+ WHERE node.sourceIdentity = $tab
41840
+ AND (node IS DeploymentElement OR node IS ContainerElement OR node IS Actor)
41841
+ OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected, sourceIdentity: $tab}]->(projectedTarget:Element)
41842
+ WHERE projectedTarget IS DeploymentElement
41843
+ OR projectedTarget IS ContainerElement
41844
+ OR projectedTarget IS External
41845
+ OR projectedTarget IS Actor
41846
+ OPTIONAL MATCH (node)-[directDeploymentLink {sourceIdentity: $tab}]->(directDeploymentTarget:Element)
41847
+ WHERE node IS DeploymentElement
41848
+ AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)
41849
+ GROUP BY node.runsOn
41850
+ RETURN node, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget
41851
+ \`\`\`
41852
+
41853
+ If the actor is declared in another source file, either render from that source
41854
+ or relax the \`node.sourceIdentity = $tab\` condition intentionally.
41855
+
41856
+ ## Show Only Async Flows
41857
+
41858
+ Use edge attributes when the question is about relationship kind:
41859
+
41860
+ \`\`\`cypher
41861
+ MATCH (source:Element)-[link]->(target:Element)
41862
+ WHERE source.context = $context
41863
+ AND link.model = 'async'
41864
+ GROUP BY source.parent
41865
+ RETURN source, link, target
41866
+ \`\`\`
41867
+
41868
+ This is useful for event-stream, broker, queue, or notification diagrams. Add
41869
+ \`source.sourceIdentity = $tab\` when the query should stay scoped to one file.
41870
+
41871
+ ## Hide Deployment Infrastructure
41872
+
41873
+ When a C4-oriented source file is too noisy and you only need logical containers
41874
+ or services, select logical container elements and direct logical relationships:
41875
+
41876
+ \`\`\`cypher
41877
+ MATCH (node:ContainerElement)
41878
+ WHERE node.sourceIdentity = $tab
41879
+ OPTIONAL MATCH (node)-[link]->(target:ContainerElement)
41880
+ GROUP BY node.parent
41881
+ RETURN node, link, target
41882
+ \`\`\`
41883
+
41884
+ This is intentionally closer to C2 than C4. Use it when deployment annotations
41885
+ exist in the file but the diagram question is still logical.
41886
+
41887
+ ## Show Projected Edges Across Split Files
41888
+
41889
+ The built-in C4 query restricts projected edges to \`sourceIdentity: $tab\`. That
41890
+ is usually correct for a focused deployment-view source file, but it can hide
41891
+ projected edges when traffic relationships were split across files.
41892
+
41893
+ Copy \`examples/builtin-views/c4.aiq\` and relax only the projected edge selector:
41894
+
41895
+ \`\`\`cypher
41896
+ MATCH (node:Element)
41897
+ WHERE node.sourceIdentity = $tab
41898
+ AND (node IS DeploymentElement OR node IS ContainerElement)
41899
+ OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected}]->(projectedTarget:Element)
41900
+ WHERE projectedTarget IS DeploymentElement
41901
+ OR projectedTarget IS ContainerElement
41902
+ OR projectedTarget IS External
41903
+ OPTIONAL MATCH (node)-[directDeploymentLink {sourceIdentity: $tab}]->(directDeploymentTarget:Element)
41904
+ WHERE node IS DeploymentElement
41905
+ AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)
41906
+ GROUP BY node.runsOn
41907
+ RETURN node, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget
41908
+ \`\`\`
41909
+
41910
+ Use this deliberately. Removing the source filter can bring in projections from
41911
+ other view files, so validate the result with \`archinsight query\` before
41912
+ rendering.
41913
+
41914
+ ## Change Grouping
41915
+
41916
+ Grouping controls visual clusters. If C4 grouping by \`runsOn\` is not helpful,
41917
+ try grouping by parent:
41918
+
41919
+ \`\`\`cypher
41920
+ MATCH (node:Element)
41921
+ WHERE node.sourceIdentity = $tab
41922
+ AND (node IS DeploymentElement OR node IS ContainerElement)
41923
+ OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected, sourceIdentity: $tab}]->(projectedTarget:Element)
41924
+ WHERE projectedTarget IS DeploymentElement
41925
+ OR projectedTarget IS ContainerElement
41926
+ OR projectedTarget IS External
41927
+ GROUP BY node.parent
41928
+ RETURN node, projectedLink, projectedTarget
41929
+ \`\`\`
41930
+
41931
+ Use \`GROUP BY node.runsOn\` for deployment placement; use \`GROUP BY node.parent\`
41932
+ for logical ownership.
41933
+
41934
+ ## Working Rule
41935
+
41936
+ If a diagram looks wrong but \`archinsight link\` is clean, inspect the selected
41937
+ source, built-in query, and returned aliases before changing the model. Many
41938
+ display issues are query scope issues, not schema or linker bugs.
41939
+ `;
41940
+ }
41166
41941
  function genericLayeredArchitectureExample() {
41167
41942
  return `context shop
41168
41943
  name = Shop Platform
@@ -41490,7 +42265,6 @@ deploymentProfile public_regional_service
41490
42265
 
41491
42266
  runsOn compute
41492
42267
  uses observability
41493
- uses publicGateway
41494
42268
 
41495
42269
  environment prod
41496
42270
  name = Production
@@ -41619,11 +42393,24 @@ system storefront
41619
42393
  deployment:
41620
42394
  usesProfile regional_service
41621
42395
  uses storage
41622
- uses broker
41623
42396
  links:
42397
+ ~> order_worker
42398
+ technology = Kafka
42399
+ via = orders.events
42400
+ deployment:
42401
+ environmentsFrom regional_service
42402
+ uses broker
42403
+
41624
42404
  -> payment_provider
41625
42405
  technology = HTTPS
41626
42406
  call = POST /payments/authorizations
42407
+
42408
+ service order_worker
42409
+ name = Order Worker
42410
+ technology = Kotlin
42411
+ description = Processes order events asynchronously
42412
+ deployment:
42413
+ usesProfile regional_service
41627
42414
  `;
41628
42415
  }
41629
42416
  function genericC2QueryExample() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archinsight/cli",
3
- "version": "3.0.0-snapshot.5",
3
+ "version": "3.0.0-snapshot.6",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "repository": {