yarramate 1.30.1 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/adapters/likec4-cli.js +28 -317
  2. package/dist/adapters/likec4-export.d.ts +3 -0
  3. package/dist/adapters/likec4-export.js +4 -1
  4. package/dist/adapters/likec4-project-export.d.ts +83 -0
  5. package/dist/adapters/likec4-project-export.js +247 -0
  6. package/dist/adapters/likec4-project.d.ts +3 -0
  7. package/dist/adapters/likec4-project.js +4 -3
  8. package/dist/adapters/mcp-cli.d.ts +12 -7
  9. package/dist/adapters/mcp-cli.js +175 -265
  10. package/dist/adapters/visual/wire.d.ts +12 -1
  11. package/dist/apply-command.d.ts +1 -1
  12. package/dist/ask-command.js +131 -522
  13. package/dist/branding.d.ts +86 -0
  14. package/dist/branding.js +80 -0
  15. package/dist/check-command.js +79 -338
  16. package/dist/design-command.js +45 -180
  17. package/dist/digest.d.ts +13 -0
  18. package/dist/digest.js +81 -0
  19. package/dist/export-command.js +110 -173
  20. package/dist/host/editor-host.d.ts +70 -0
  21. package/dist/host/editor-host.js +1 -0
  22. package/dist/host/local-host.d.ts +123 -0
  23. package/dist/host/local-host.js +477 -0
  24. package/dist/host-entry.d.ts +15 -0
  25. package/dist/host-entry.js +12 -0
  26. package/dist/likec4-specification.generated.d.ts +1 -0
  27. package/dist/likec4-specification.generated.js +3 -0
  28. package/dist/shipped-catalogue.generated.d.ts +1 -0
  29. package/dist/shipped-catalogue.generated.js +3 -0
  30. package/dist/tools/apply.d.ts +31 -0
  31. package/dist/tools/apply.js +45 -0
  32. package/dist/tools/ask.d.ts +239 -0
  33. package/dist/tools/ask.js +466 -0
  34. package/dist/tools/check.d.ts +83 -0
  35. package/dist/tools/check.js +350 -0
  36. package/dist/tools/design.d.ts +57 -0
  37. package/dist/tools/design.js +138 -0
  38. package/dist/tools/export.d.ts +58 -0
  39. package/dist/tools/export.js +195 -0
  40. package/dist/tools/table.d.ts +114 -0
  41. package/dist/tools/table.js +377 -0
  42. package/dist/tools/workspace.d.ts +114 -0
  43. package/dist/tools/workspace.js +84 -0
  44. package/dist/tools-entry.d.ts +22 -0
  45. package/dist/tools-entry.js +19 -0
  46. package/dist/visual-app/assets/{elk.bundled-D88SKdhr.js → elk.bundled-DwTh4wCo.js} +1 -1
  47. package/dist/visual-app/assets/{index-DCXoFh-5.js → index-DJYV9FNm.js} +28 -28
  48. package/dist/visual-app/assets/index-DYTKTQsG.css +1 -0
  49. package/dist/visual-app/index.html +2 -2
  50. package/dist/visual-app-lib/editor.js +29778 -29639
  51. package/dist/visual-app-lib/styles.css +1 -1
  52. package/dist/visual-app-lib/types/adapters/visual/wire.d.ts +12 -1
  53. package/dist/visual-app-lib/types/apply-command.d.ts +1 -1
  54. package/dist/visual-app-lib/types/branding.d.ts +86 -0
  55. package/dist/visual-app-lib/types/host/editor-host.d.ts +70 -0
  56. package/dist/visual-app-lib/types/host/local-host.d.ts +123 -0
  57. package/dist/visual-app-lib/types/shipped-catalogue.generated.d.ts +1 -0
  58. package/dist/visual-app-lib/types/tools/workspace.d.ts +114 -0
  59. package/dist/visual-app-lib/types/visual-app/App.d.ts +4 -1
  60. package/dist/visual-app-lib/types/visual-app/editor-host.d.ts +1 -70
  61. package/dist/visual-app-lib/types/visual-app/local-host.d.ts +1 -123
  62. package/dist/visual-app-lib/types/visual-app/mount.d.ts +26 -1
  63. package/dist/visual-app-lib/types/visual-app/socket-host.d.ts +26 -0
  64. package/dist/visual-app-lib/types/visual-app/state.d.ts +9 -0
  65. package/dist/visual-app-lib/types/workspace-resolution.d.ts +106 -0
  66. package/dist/visual-app-lib/types/workspace.d.ts +3 -54
  67. package/dist/workbook-entry.d.ts +1 -0
  68. package/dist/workbook-entry.js +1 -0
  69. package/dist/workbook.d.ts +3 -2
  70. package/dist/workbook.js +19 -4
  71. package/dist/workspace-resolution.d.ts +106 -0
  72. package/dist/workspace-resolution.js +189 -0
  73. package/dist/workspace.d.ts +3 -54
  74. package/dist/workspace.js +11 -129
  75. package/docs/CONSUMING-YARRAMATE.md +161 -4
  76. package/package.json +10 -1
  77. package/schema/yarramate-ask-result.schema.json +4 -0
  78. package/dist/visual-app/assets/index-CZSChZa6.css +0 -1
  79. package/dist/visual-app-lib/types/visual-app/shipped-catalogue.d.ts +0 -10
@@ -9,9 +9,8 @@ import { isMainModule, resolveCliWorkspaceSources, versionResult, } from '../cli
9
9
  import { deriveChangedSubjects } from '../changed.js';
10
10
  import { compileWorkspace } from '../compiler.js';
11
11
  import { adapterMappingLocation, loadAdapterMapping, validateAdapterMapping, } from '../adapter-mapping.js';
12
- import { locateSourcePath } from '../source-document.js';
13
12
  import { prepareLikeC4Export, } from './likec4-prepare.js';
14
- import { exportLikeC4Project, loadLikeC4ProjectDefinition, } from './likec4-project.js';
13
+ import { exportLikeC4ProjectFromSources, inputDigestsOf, ownershipOf, projectNameOf, } from './likec4-project-export.js';
15
14
  import generatedProjectSchema from '../../schema/yarramate-likec4-generated-project.schema.json' with { type: 'json'
16
15
  };
17
16
  import generatedProjectV2Schema from '../../schema/yarramate-likec4-generated-project-v2.schema.json' with { type: 'json'
@@ -515,9 +514,6 @@ const checkGeneratedProject = (cwd, outputDirectory, input) => {
515
514
  stderr: '',
516
515
  };
517
516
  };
518
- const inputDigestsOf = (inputs) => Object.fromEntries(inputs
519
- .map(({ path, source }) => [path, sha256(source)])
520
- .sort(([left], [right]) => left.localeCompare(right)));
521
517
  export function runLikeC4Cli(args, cwd = process.cwd()) {
522
518
  if (args[0] === '--version') {
523
519
  return versionResult('yarramate-likec4');
@@ -653,286 +649,10 @@ export function runLikeC4Cli(args, cwd = process.cwd()) {
653
649
  path: projectionPath,
654
650
  source: readFileSync(resolve(cwd, projectionPath), 'utf8'),
655
651
  };
656
- const loadedProject = loadLikeC4ProjectDefinition(projectSource);
657
- if (!loadedProject.ok) {
658
- return {
659
- exitCode: 1,
660
- stdout: diagnosticOutput(loadedProject.diagnostics),
661
- stderr: '',
662
- };
663
- }
664
652
  const projectDirectory = dirname(resolve(cwd, projectionPath));
665
- const referencedSources = new Map();
666
- const referenceDiagnostics = [];
667
- const readProjectReference = (path, label, yamlPath, pointer) => {
668
- const existing = referencedSources.get(path);
669
- if (existing !== undefined)
670
- return existing;
671
- try {
672
- const source = {
673
- path,
674
- source: readFileSync(resolve(projectDirectory, path), 'utf8'),
675
- };
676
- referencedSources.set(path, source);
677
- return source;
678
- }
679
- catch (error) {
680
- const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, yamlPath, pointer);
681
- const absent = error instanceof Error &&
682
- 'code' in error &&
683
- error.code === 'ENOENT';
684
- referenceDiagnostics.push({
685
- severity: 'error',
686
- code: 'YMLC110',
687
- message: absent
688
- ? `LikeC4 project ${label} "${path}" does not exist`
689
- : `LikeC4 project ${label} "${path}" cannot be read`,
690
- ...location,
691
- });
692
- return undefined;
693
- }
694
- };
695
- const subjectMapping = readProjectReference(loadedProject.document.value.mapping, 'mapping', ['mapping'], '/mapping');
696
- const kindMapping = loadedProject.document.value.kindMapping === undefined
697
- ? undefined
698
- : readProjectReference(loadedProject.document.value.kindMapping, 'kind mapping', ['kindMapping'], '/kindMapping');
699
- const projections = loadedProject.document.value.views.map((view, index) => readProjectReference(view.projection, 'projection', ['views', index, 'projection'], `/views/${index}/projection`));
700
- if (referenceDiagnostics.length > 0 ||
701
- subjectMapping === undefined) {
702
- return {
703
- exitCode: 1,
704
- stdout: diagnosticOutput(referenceDiagnostics.sort((left, right) => left.path.localeCompare(right.path) ||
705
- left.line - right.line ||
706
- left.column - right.column ||
707
- left.code.localeCompare(right.code) ||
708
- left.message.localeCompare(right.message))),
709
- stderr: '',
710
- };
711
- }
712
- const preparedViews = loadedProject.document.value.views.map((view, index) => ({
713
- view,
714
- prepared: prepareLikeC4Export({
715
- sources,
716
- projection: projections[index],
717
- subjectMapping,
718
- ...(loadedProject.document.value.kindMapping === undefined
719
- ? {}
720
- : {
721
- kindMapping: kindMapping,
722
- }),
723
- ...(view.compare === undefined
724
- ? {}
725
- : { comparison: view.compare }),
726
- vocabulary: 'bundled',
727
- requireMappedRelationships: command === 'check',
728
- }),
729
- }));
730
- const failed = preparedViews.find(({ prepared }) => !prepared.ok);
731
- if (failed !== undefined && !failed.prepared.ok) {
732
- return {
733
- exitCode: 1,
734
- stdout: diagnosticOutput(failed.prepared.diagnostics),
735
- stderr: '',
736
- };
737
- }
738
- const successfulViews = preparedViews.flatMap(({ view, prepared }) => prepared.ok
739
- ? [
740
- {
741
- ...(view.id === undefined ? {} : { id: view.id }),
742
- ...(view.folder === undefined
743
- ? {}
744
- : { folder: view.folder }),
745
- prepared,
746
- ...(view.compare === undefined
747
- ? {}
748
- : { comparison: view.compare }),
749
- ...(view.dynamic === undefined
750
- ? {}
751
- : { dynamic: view.dynamic }),
752
- ...(view.deployment === undefined
753
- ? {}
754
- : { deployment: view.deployment }),
755
- },
756
- ]
757
- : []);
758
- const renderedViewIds = new Set();
759
- const deploymentIdentities = new Set();
760
- for (const [index, view] of successfulViews.entries()) {
761
- const deployment = view.deployment;
762
- if (deployment !== undefined) {
763
- const nodeIds = new Set();
764
- for (const [nodeIndex, node] of deployment.nodes.entries()) {
765
- const problem = nodeIds.has(node.id)
766
- ? `Deployment node "${node.id}" is duplicated`
767
- : deploymentIdentities.has(node.id)
768
- ? `Deployment identity "${node.id}" is duplicated`
769
- : node.parent === node.id
770
- ? `Deployment node "${node.id}" cannot parent itself`
771
- : undefined;
772
- if (problem !== undefined) {
773
- const field = nodeIds.has(node.id) || deploymentIdentities.has(node.id)
774
- ? 'id'
775
- : 'parent';
776
- const pointer = `/views/${index}/deployment/nodes/${nodeIndex}/${field}`;
777
- const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, ['views', index, 'deployment', 'nodes', nodeIndex, field], pointer);
778
- return {
779
- exitCode: 1,
780
- stdout: diagnosticOutput([{
781
- severity: 'error',
782
- code: 'YMLC109',
783
- message: problem,
784
- ...location,
785
- }]),
786
- stderr: '',
787
- };
788
- }
789
- nodeIds.add(node.id);
790
- deploymentIdentities.add(node.id);
791
- }
792
- for (const [nodeIndex, node] of deployment.nodes.entries()) {
793
- if (node.parent !== undefined &&
794
- !nodeIds.has(node.parent)) {
795
- const pointer = `/views/${index}/deployment/nodes/${nodeIndex}/parent`;
796
- const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, [
797
- 'views',
798
- index,
799
- 'deployment',
800
- 'nodes',
801
- nodeIndex,
802
- 'parent',
803
- ], pointer);
804
- return {
805
- exitCode: 1,
806
- stdout: diagnosticOutput([{
807
- severity: 'error',
808
- code: 'YMLC109',
809
- message: `Deployment parent "${node.parent}" does not exist`,
810
- ...location,
811
- }]),
812
- stderr: '',
813
- };
814
- }
815
- const nodeById = new Map(deployment.nodes.map((candidate) => [
816
- candidate.id,
817
- candidate,
818
- ]));
819
- const ancestors = new Set([node.id]);
820
- let parent = node.parent;
821
- while (parent !== undefined) {
822
- if (ancestors.has(parent)) {
823
- const pointer = `/views/${index}/deployment/nodes/${nodeIndex}/parent`;
824
- const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, [
825
- 'views',
826
- index,
827
- 'deployment',
828
- 'nodes',
829
- nodeIndex,
830
- 'parent',
831
- ], pointer);
832
- return {
833
- exitCode: 1,
834
- stdout: diagnosticOutput([{
835
- severity: 'error',
836
- code: 'YMLC109',
837
- message: `Deployment node "${node.id}" participates in a parent cycle`,
838
- ...location,
839
- }]),
840
- stderr: '',
841
- };
842
- }
843
- ancestors.add(parent);
844
- parent = nodeById.get(parent)?.parent;
845
- }
846
- }
847
- const instanceIds = new Set();
848
- for (const [instanceIndex, instance] of (deployment.instances).entries()) {
849
- const projected = view.prepared.projection.subjects.find(({ id }) => id === instance.subject);
850
- const problem = instanceIds.has(instance.id)
851
- ? `Deployment instance "${instance.id}" is duplicated`
852
- : deploymentIdentities.has(instance.id)
853
- ? `Deployment identity "${instance.id}" is duplicated`
854
- : !nodeIds.has(instance.node)
855
- ? `Deployment instance node "${instance.node}" does not exist`
856
- : projected?.type !== 'concept'
857
- ? `Deployment instance subject "${instance.subject}" is not selected as a concept by its projection`
858
- : undefined;
859
- if (problem !== undefined) {
860
- const field = instanceIds.has(instance.id) ||
861
- deploymentIdentities.has(instance.id)
862
- ? 'id'
863
- : !nodeIds.has(instance.node)
864
- ? 'node'
865
- : 'subject';
866
- const pointer = `/views/${index}/deployment/instances/${instanceIndex}/${field}`;
867
- const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, [
868
- 'views',
869
- index,
870
- 'deployment',
871
- 'instances',
872
- instanceIndex,
873
- field,
874
- ], pointer);
875
- return {
876
- exitCode: 1,
877
- stdout: diagnosticOutput([{
878
- severity: 'error',
879
- code: 'YMLC109',
880
- message: problem,
881
- ...location,
882
- }]),
883
- stderr: '',
884
- };
885
- }
886
- instanceIds.add(instance.id);
887
- deploymentIdentities.add(instance.id);
888
- }
889
- }
890
- for (const [stepIndex, step] of (view.dynamic?.steps ?? []).entries()) {
891
- const projected = view.prepared.projection.subjects.find(({ id }) => id === step.relationship);
892
- if (projected?.type !== 'relationship') {
893
- const pointer = `/views/${index}/dynamic/steps/${stepIndex}/relationship`;
894
- const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, [
895
- 'views',
896
- index,
897
- 'dynamic',
898
- 'steps',
899
- stepIndex,
900
- 'relationship',
901
- ], pointer);
902
- return {
903
- exitCode: 1,
904
- stdout: diagnosticOutput([
905
- {
906
- severity: 'error',
907
- code: 'YMLC108',
908
- message: `Dynamic step relationship "${step.relationship}" is not selected as a relationship by its projection`,
909
- ...location,
910
- },
911
- ]),
912
- stderr: '',
913
- };
914
- }
915
- }
916
- const renderedId = view.id ?? view.prepared.projection.projection.split('@')[0];
917
- if (renderedViewIds.has(renderedId)) {
918
- const field = view.id === undefined ? 'projection' : 'id';
919
- const pointer = `/views/${index}/${field}`;
920
- const location = locateSourcePath(projectSource.path, loadedProject.document.yaml, loadedProject.document.lineCounter, ['views', index, field], pointer);
921
- return {
922
- exitCode: 1,
923
- stdout: diagnosticOutput([
924
- {
925
- severity: 'error',
926
- code: 'YMLC107',
927
- message: `LikeC4 view identity "${renderedId}" is duplicated`,
928
- ...location,
929
- },
930
- ]),
931
- stderr: '',
932
- };
933
- }
934
- renderedViewIds.add(renderedId);
935
- }
653
+ // The git-derived review overlay is the CLI's own: it needs a
654
+ // repository. Everything after it runs the same pure pipeline the
655
+ // path-free entry runs (ADR 0156).
936
656
  let gitChange;
937
657
  if (changedRange !== undefined) {
938
658
  const modelDocuments = sources.flatMap((candidate) => {
@@ -958,7 +678,23 @@ export function runLikeC4Cli(args, cwd = process.cwd()) {
958
678
  modified: all.filter((id) => !derived.changed.added.includes(id)),
959
679
  };
960
680
  }
961
- const exported = exportLikeC4Project(loadedProject.document.value, successfulViews, gitChange === undefined ? {} : { gitChange });
681
+ const exported = exportLikeC4ProjectFromSources({
682
+ project: projectSource,
683
+ sources,
684
+ readReference: (path) => {
685
+ try {
686
+ return {
687
+ path,
688
+ source: readFileSync(resolve(projectDirectory, path), 'utf8'),
689
+ };
690
+ }
691
+ catch {
692
+ return undefined;
693
+ }
694
+ },
695
+ requireMappedRelationships: command === 'check',
696
+ ...(gitChange === undefined ? {} : { gitChange }),
697
+ });
962
698
  if (!exported.ok) {
963
699
  return {
964
700
  exitCode: 1,
@@ -967,51 +703,26 @@ export function runLikeC4Cli(args, cwd = process.cwd()) {
967
703
  };
968
704
  }
969
705
  if (command === 'check') {
970
- const identity = `${loadedProject.document.value.id}@${loadedProject.document.value.version}`;
971
706
  return {
972
707
  exitCode: 0,
973
708
  stdout: json
974
709
  ? checkJson(true, [])
975
- : `Checked LikeC4 project ${identity}: no errors\n`,
710
+ : `Checked LikeC4 project ${exported.projectIdentity}: no errors\n`,
976
711
  stderr: '',
977
712
  };
978
713
  }
979
- const first = successfulViews[0];
980
- const mappingIdentity = `${first.prepared.subjectMapping.id}@${first.prepared.subjectMapping.version}`;
981
- const kindMappingIdentity = first.prepared.kindMapping === undefined
982
- ? undefined
983
- : `${first.prepared.kindMapping.id}@${first.prepared.kindMapping.version}`;
984
- const projectIdentity = `${loadedProject.document.value.id}@${loadedProject.document.value.version}`;
985
- const inputDigests = inputDigestsOf([
986
- projectSource,
987
- ...sources,
988
- ...referencedSources.values(),
989
- ]);
714
+ const inputDigests = inputDigestsOf(exported.inputs);
990
715
  if (checkFreshness) {
991
716
  return checkGeneratedProject(cwd, outputDirectory, {
992
- modelSource: exported.source,
717
+ modelSource: exported.modelSource,
993
718
  inputDigests,
994
719
  });
995
720
  }
996
721
  return publishGeneratedProject(cwd, outputDirectory, {
997
- projectName: `yarramate-${projectIdentity}`.replaceAll(/[^A-Za-z0-9_-]/g, '-'),
998
- title: loadedProject.document.value.title,
999
- modelSource: exported.source,
1000
- ownership: {
1001
- format: 'yarramate/likec4-generated-project/v2',
1002
- project: projectIdentity,
1003
- mapping: mappingIdentity,
1004
- ...(kindMappingIdentity === undefined
1005
- ? {}
1006
- : { kindMapping: kindMappingIdentity }),
1007
- views: successfulViews.map(({ id, prepared, comparison }) => ({
1008
- ...(id === undefined ? {} : { id }),
1009
- projection: prepared.projection.projection,
1010
- ...(comparison === undefined
1011
- ? {}
1012
- : { comparison }),
1013
- })),
1014
- },
722
+ projectName: projectNameOf(exported.projectIdentity),
723
+ title: exported.project.title,
724
+ modelSource: exported.modelSource,
725
+ ownership: { ...ownershipOf(exported) },
1015
726
  inputDigests,
1016
727
  });
1017
728
  }
@@ -1,4 +1,5 @@
1
1
  import { type AdapterMapping } from '../adapter-mapping.js';
2
+ import { type Branding } from '../branding.js';
2
3
  import type { StateComparison } from '../architecture-state.js';
3
4
  import type { ProjectionResult } from '../projection.js';
4
5
  import type { LikeC4KindMapping } from './likec4-kind-mapping.js';
@@ -21,6 +22,8 @@ export type LikeC4ExportResult = {
21
22
  };
22
23
  export interface LikeC4ExportOptions {
23
24
  readonly comparison?: StateComparison;
25
+ /** The banner names the host's product (#546, ADR 0158); absent, the engine. */
26
+ readonly branding?: Branding;
24
27
  /** Git-derived review overlay (ADR 0066): subjects new or changed in a
25
28
  * ref range carry metadata and view styling; nothing is authored. */
26
29
  readonly gitChange?: GitChangeOverlay;
@@ -1,4 +1,5 @@
1
1
  import { adapterMappingEntryLocation, adapterMappingLocation, } from '../adapter-mapping.js';
2
+ import { resolveBranding } from '../branding.js';
2
3
  import { diagnosticOrder } from '../source-document.js';
3
4
  const identifier = /^[A-Za-z_][A-Za-z0-9_-]*$/;
4
5
  const valueFor = (claims, subject, predicate) => {
@@ -114,8 +115,10 @@ export function exportLikeC4(projection, mapping, kindMapping, options = {}) {
114
115
  diagnostics: diagnostics.sort(diagnosticOrder),
115
116
  };
116
117
  }
118
+ const brand = resolveBranding(options.branding);
117
119
  const lines = [
118
- '// Generated by YarraMate. Edit the native documents, not this file.',
120
+ `// Generated by ${brand.productName}. Edit the native documents, not this file.`,
121
+ ...(brand.vendorLine === null ? [] : [`// ${brand.vendorLine}`]),
119
122
  'model {',
120
123
  ];
121
124
  for (const concept of concepts) {
@@ -0,0 +1,83 @@
1
+ import type { WorkspaceSource } from '../compiler.js';
2
+ import { type Branding } from '../branding.js';
3
+ import { type LikeC4PreparationDiagnostic } from './likec4-prepare.js';
4
+ import type { GitChangeOverlay } from './likec4-export.js';
5
+ import { type LikeC4ProjectDefinition, type PreparedLikeC4ProjectView } from './likec4-project.js';
6
+ /**
7
+ * A LikeC4 project definition to a generated project, with no filesystem
8
+ * (ADR 0156). `yarramate-likec4 export-project` reads the definition and
9
+ * the files it names from disk, runs this, and writes what comes back;
10
+ * `yarramate/tools` reads them from a store and hands the files to whoever
11
+ * asked. The checks between preparation and export (deployment nodes,
12
+ * dynamic steps, duplicate view identities) live here so both callers
13
+ * refuse the same definitions with the same diagnostics.
14
+ */
15
+ export interface LikeC4ProjectExportInput {
16
+ /** The `yarramate/likec4-project/v1` document. */
17
+ readonly project: WorkspaceSource;
18
+ /** The workspace's compiler sources: profiles, patterns, documents. */
19
+ readonly sources: readonly WorkspaceSource[];
20
+ /**
21
+ * The mapping, kind mapping and projections the definition names, by the
22
+ * path written in the definition (relative to its directory). `undefined`
23
+ * for one the caller cannot find is reported as YMLC110.
24
+ */
25
+ readonly readReference: (path: string) => WorkspaceSource | undefined;
26
+ /** `check` refuses relationships the mapping does not cover; `export` does not. */
27
+ readonly requireMappedRelationships: boolean;
28
+ /** The git-derived review overlay, when the CLI derived one. */
29
+ readonly gitChange?: GitChangeOverlay;
30
+ /**
31
+ * The host's branding (#546, ADR 0158): the model banner and the project
32
+ * name in `likec4.config.json`. The marker file and its digests are
33
+ * machinery and keep their names.
34
+ */
35
+ readonly branding?: Branding;
36
+ }
37
+ export interface LikeC4ProjectExported {
38
+ readonly ok: true;
39
+ readonly project: LikeC4ProjectDefinition;
40
+ readonly views: readonly PreparedLikeC4ProjectView[];
41
+ /** The `model.likec4` text. */
42
+ readonly modelSource: string;
43
+ readonly projectIdentity: string;
44
+ readonly mappingIdentity: string;
45
+ readonly kindMappingIdentity?: string;
46
+ /** Every source that fed the export, for the marker's input digests. */
47
+ readonly inputs: readonly WorkspaceSource[];
48
+ /** Echoed from the input so `generatedProjectFiles` names the project for it. */
49
+ readonly branding?: Branding;
50
+ }
51
+ export type LikeC4ProjectExportResult = LikeC4ProjectExported | {
52
+ readonly ok: false;
53
+ readonly diagnostics: readonly LikeC4PreparationDiagnostic[];
54
+ };
55
+ export declare const exportLikeC4ProjectFromSources: (input: LikeC4ProjectExportInput) => LikeC4ProjectExportResult;
56
+ export declare const GENERATED_FILE_NAMES: readonly ['likec4.config.json', 'model.likec4', 'specification.likec4'];
57
+ /** The ownership marker's fields, minus the digests this module computes. */
58
+ export interface GeneratedProjectOwnership {
59
+ readonly format: 'yarramate/likec4-generated-project/v2';
60
+ readonly project: string;
61
+ readonly mapping: string;
62
+ readonly kindMapping?: string;
63
+ readonly views: readonly {
64
+ readonly id?: string;
65
+ readonly projection: string;
66
+ readonly comparison?: {
67
+ readonly from: string;
68
+ readonly to: string;
69
+ };
70
+ }[];
71
+ }
72
+ export declare const ownershipOf: (exported: LikeC4ProjectExported) => GeneratedProjectOwnership;
73
+ export declare const inputDigestsOf: (inputs: readonly WorkspaceSource[]) => Readonly<Record<string, string>>;
74
+ export declare const projectNameOf: (projectIdentity: string, branding?: Branding) => string;
75
+ /**
76
+ * The four files a generated project holds, exactly as the CLI writes them
77
+ * under its output directory: the config, the model, the specification the
78
+ * package ships, and the `yarramate.generated.json` marker with every
79
+ * digest the freshness check reads back.
80
+ */
81
+ export declare const generatedProjectFiles: (exported: LikeC4ProjectExported) => readonly WorkspaceSource[];
82
+ /** Whether a source is a project definition rather than a projection. */
83
+ export declare const isLikeC4ProjectDefinition: (source: string) => boolean;