yarramate 1.31.0 → 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.
- package/dist/adapters/likec4-export.d.ts +3 -0
- package/dist/adapters/likec4-export.js +4 -1
- package/dist/adapters/likec4-project-export.d.ts +10 -1
- package/dist/adapters/likec4-project-export.js +8 -3
- package/dist/adapters/likec4-project.d.ts +3 -0
- package/dist/adapters/likec4-project.js +4 -3
- package/dist/adapters/mcp-cli.js +2 -2
- package/dist/branding.d.ts +86 -0
- package/dist/branding.js +80 -0
- package/dist/tools/export.js +2 -1
- package/dist/tools/table.d.ts +32 -3
- package/dist/tools/table.js +86 -32
- package/dist/tools/workspace.d.ts +6 -0
- package/dist/tools-entry.d.ts +2 -1
- package/dist/tools-entry.js +2 -1
- package/dist/visual-app/assets/{elk.bundled-JlCCXIin.js → elk.bundled-DwTh4wCo.js} +1 -1
- package/dist/visual-app/assets/{index-BSwETsaq.js → index-DJYV9FNm.js} +28 -28
- package/dist/visual-app/assets/index-DYTKTQsG.css +1 -0
- package/dist/visual-app/index.html +2 -2
- package/dist/visual-app-lib/editor.js +29863 -29803
- package/dist/visual-app-lib/styles.css +1 -1
- package/dist/visual-app-lib/types/branding.d.ts +86 -0
- package/dist/visual-app-lib/types/tools/workspace.d.ts +6 -0
- package/dist/visual-app-lib/types/visual-app/App.d.ts +4 -1
- package/dist/visual-app-lib/types/visual-app/mount.d.ts +10 -0
- package/dist/workbook-entry.d.ts +1 -0
- package/dist/workbook-entry.js +1 -0
- package/dist/workbook.d.ts +3 -2
- package/dist/workbook.js +19 -4
- package/docs/CONSUMING-YARRAMATE.md +55 -0
- package/package.json +1 -1
- package/dist/visual-app/assets/index-CZSChZa6.css +0 -1
|
@@ -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
|
-
|
|
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) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { WorkspaceSource } from '../compiler.js';
|
|
2
|
+
import { type Branding } from '../branding.js';
|
|
2
3
|
import { type LikeC4PreparationDiagnostic } from './likec4-prepare.js';
|
|
3
4
|
import type { GitChangeOverlay } from './likec4-export.js';
|
|
4
5
|
import { type LikeC4ProjectDefinition, type PreparedLikeC4ProjectView } from './likec4-project.js';
|
|
@@ -26,6 +27,12 @@ export interface LikeC4ProjectExportInput {
|
|
|
26
27
|
readonly requireMappedRelationships: boolean;
|
|
27
28
|
/** The git-derived review overlay, when the CLI derived one. */
|
|
28
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;
|
|
29
36
|
}
|
|
30
37
|
export interface LikeC4ProjectExported {
|
|
31
38
|
readonly ok: true;
|
|
@@ -38,6 +45,8 @@ export interface LikeC4ProjectExported {
|
|
|
38
45
|
readonly kindMappingIdentity?: string;
|
|
39
46
|
/** Every source that fed the export, for the marker's input digests. */
|
|
40
47
|
readonly inputs: readonly WorkspaceSource[];
|
|
48
|
+
/** Echoed from the input so `generatedProjectFiles` names the project for it. */
|
|
49
|
+
readonly branding?: Branding;
|
|
41
50
|
}
|
|
42
51
|
export type LikeC4ProjectExportResult = LikeC4ProjectExported | {
|
|
43
52
|
readonly ok: false;
|
|
@@ -62,7 +71,7 @@ export interface GeneratedProjectOwnership {
|
|
|
62
71
|
}
|
|
63
72
|
export declare const ownershipOf: (exported: LikeC4ProjectExported) => GeneratedProjectOwnership;
|
|
64
73
|
export declare const inputDigestsOf: (inputs: readonly WorkspaceSource[]) => Readonly<Record<string, string>>;
|
|
65
|
-
export declare const projectNameOf: (projectIdentity: string) => string;
|
|
74
|
+
export declare const projectNameOf: (projectIdentity: string, branding?: Branding) => string;
|
|
66
75
|
/**
|
|
67
76
|
* The four files a generated project holds, exactly as the CLI writes them
|
|
68
77
|
* under its output directory: the config, the model, the specification the
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseDocument } from 'yaml';
|
|
2
|
+
import { brandSlug, resolveBranding } from '../branding.js';
|
|
2
3
|
import { sha256Hex } from '../digest.js';
|
|
3
4
|
import { LIKEC4_SPECIFICATION_SOURCE } from '../likec4-specification.generated.js';
|
|
4
5
|
import { locateSourcePath } from '../source-document.js';
|
|
@@ -165,7 +166,10 @@ export const exportLikeC4ProjectFromSources = (input) => {
|
|
|
165
166
|
}
|
|
166
167
|
renderedViewIds.add(renderedId);
|
|
167
168
|
}
|
|
168
|
-
const exported = exportLikeC4Project(definition, successfulViews,
|
|
169
|
+
const exported = exportLikeC4Project(definition, successfulViews, {
|
|
170
|
+
...(input.gitChange === undefined ? {} : { gitChange: input.gitChange }),
|
|
171
|
+
...(input.branding === undefined ? {} : { branding: input.branding }),
|
|
172
|
+
});
|
|
169
173
|
if (!exported.ok)
|
|
170
174
|
return { ok: false, diagnostics: exported.diagnostics };
|
|
171
175
|
const first = successfulViews[0];
|
|
@@ -182,6 +186,7 @@ export const exportLikeC4ProjectFromSources = (input) => {
|
|
|
182
186
|
kindMappingIdentity: `${first.prepared.kindMapping.id}@${first.prepared.kindMapping.version}`,
|
|
183
187
|
}),
|
|
184
188
|
inputs: [projectSource, ...sources, ...referencedSources.values()],
|
|
189
|
+
...(input.branding === undefined ? {} : { branding: input.branding }),
|
|
185
190
|
};
|
|
186
191
|
};
|
|
187
192
|
// ---------------------------------------------------------------------------
|
|
@@ -208,7 +213,7 @@ export const ownershipOf = (exported) => ({
|
|
|
208
213
|
export const inputDigestsOf = (inputs) => Object.fromEntries(inputs
|
|
209
214
|
.map(({ path, source }) => [path, sha256Hex(source)])
|
|
210
215
|
.sort(([left], [right]) => left.localeCompare(right)));
|
|
211
|
-
export const projectNameOf = (projectIdentity) =>
|
|
216
|
+
export const projectNameOf = (projectIdentity, branding) => `${brandSlug(resolveBranding(branding))}-${projectIdentity}`.replaceAll(/[^A-Za-z0-9_-]/g, '-');
|
|
212
217
|
/**
|
|
213
218
|
* The four files a generated project holds, exactly as the CLI writes them
|
|
214
219
|
* under its output directory: the config, the model, the specification the
|
|
@@ -218,7 +223,7 @@ export const projectNameOf = (projectIdentity) => `yarramate-${projectIdentity}`
|
|
|
218
223
|
export const generatedProjectFiles = (exported) => {
|
|
219
224
|
const configSource = `${JSON.stringify({
|
|
220
225
|
$schema: 'https://likec4.dev/schemas/config.json',
|
|
221
|
-
name: projectNameOf(exported.projectIdentity),
|
|
226
|
+
name: projectNameOf(exported.projectIdentity, exported.branding),
|
|
222
227
|
title: exported.project.title,
|
|
223
228
|
}, null, 2)}\n`;
|
|
224
229
|
const markerSource = `${JSON.stringify({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Branding } from '../branding.js';
|
|
1
2
|
import type { WorkspaceSource } from '../compiler.js';
|
|
2
3
|
import type { LikeC4PreparationResult } from './likec4-prepare.js';
|
|
3
4
|
import { type GitChangeOverlay, type LikeC4ExportResult } from './likec4-export.js';
|
|
@@ -59,5 +60,7 @@ export interface PreparedLikeC4ProjectView {
|
|
|
59
60
|
}
|
|
60
61
|
export interface LikeC4ProjectExportOptions {
|
|
61
62
|
readonly gitChange?: GitChangeOverlay;
|
|
63
|
+
/** Names the product in the model banner (#546, ADR 0158). */
|
|
64
|
+
readonly branding?: Branding;
|
|
62
65
|
}
|
|
63
66
|
export declare function exportLikeC4Project(project: LikeC4ProjectDefinition, views: readonly PreparedLikeC4ProjectView[], options?: LikeC4ProjectExportOptions): LikeC4ExportResult;
|
|
@@ -236,9 +236,10 @@ export function exportLikeC4Project(project, views, options = {}) {
|
|
|
236
236
|
if (first === undefined) {
|
|
237
237
|
throw new Error('LikeC4 project requires at least one view');
|
|
238
238
|
}
|
|
239
|
-
const model = exportLikeC4(unionProjection(project, views), first.prepared.subjectMapping, first.prepared.kindMapping,
|
|
240
|
-
? {}
|
|
241
|
-
: {
|
|
239
|
+
const model = exportLikeC4(unionProjection(project, views), first.prepared.subjectMapping, first.prepared.kindMapping, {
|
|
240
|
+
...(options.gitChange === undefined ? {} : { gitChange: options.gitChange }),
|
|
241
|
+
...(options.branding === undefined ? {} : { branding: options.branding }),
|
|
242
|
+
});
|
|
242
243
|
if (!model.ok)
|
|
243
244
|
return model;
|
|
244
245
|
const startToken = '\nviews {\n';
|
package/dist/adapters/mcp-cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { isMainModule, packageVersion, versionResult, } from '../cli-support.js'
|
|
|
7
7
|
import { runCli } from '../cli.js';
|
|
8
8
|
import { createFileSystemStore } from '../source-store.js';
|
|
9
9
|
import { loadWorkspaceManifest } from '../workspace.js';
|
|
10
|
-
import {
|
|
10
|
+
import { STDIO_PROPERTIES, TOOL_CATALOGUE, instructionsFor, runTool, } from '../tools/table.js';
|
|
11
11
|
/** The sentence the stdio rows add, because only here is there a `workspace` to name. */
|
|
12
12
|
const WORKSPACE_SENTENCE = 'Every tool takes the same optional `workspace`; omit it to use the workspace this server was started with, or .yarramate/workspace.yaml under its working directory.';
|
|
13
13
|
const CONVENTIONAL_WORKSPACE = join('.yarramate', 'workspace.yaml');
|
|
@@ -236,7 +236,7 @@ export const handleRequest = (request, context = { cwd: process.cwd(), workspace
|
|
|
236
236
|
protocolVersion: '2025-06-18',
|
|
237
237
|
capabilities: { tools: {} },
|
|
238
238
|
serverInfo: { name: 'yarramate', version: packageVersion },
|
|
239
|
-
instructions:
|
|
239
|
+
instructions: `${instructionsFor()} ${WORKSPACE_SENTENCE}`,
|
|
240
240
|
});
|
|
241
241
|
return;
|
|
242
242
|
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* White-labelling (#546, ADR 0158): one value, set once by a host, that
|
|
3
|
+
* names the product on every surface a consumer's users see - the editor
|
|
4
|
+
* shell, the tool list an agent reads, the workbook's cover sheet and the
|
|
5
|
+
* LikeC4 banner. Nothing else changes: record formats, diagnostic codes and
|
|
6
|
+
* the wire protocol are contracts, not branding, and stay `yarramate/...`
|
|
7
|
+
* and `YM...`. Absent, every surface reads exactly as it always has.
|
|
8
|
+
*
|
|
9
|
+
* Pure: no imports, so it sits under every entry (`yarramate/tools`,
|
|
10
|
+
* `yarramate/workbook`, `yarramate/visual-app`) without weight.
|
|
11
|
+
*/
|
|
12
|
+
export type BrandingLogo =
|
|
13
|
+
/** Inline markup the host wrote; rendered as the host's own SVG. */
|
|
14
|
+
{
|
|
15
|
+
readonly svg: string;
|
|
16
|
+
}
|
|
17
|
+
/** An address the page fetches; rendered as an image. */
|
|
18
|
+
| {
|
|
19
|
+
readonly url: string;
|
|
20
|
+
};
|
|
21
|
+
export interface Branding {
|
|
22
|
+
/** "ApertureX", "Halcyon Architecture". Required: a brand without a name is not one. */
|
|
23
|
+
readonly productName: string;
|
|
24
|
+
/**
|
|
25
|
+
* For tight chrome: beside the logo in the brand mark, and in the
|
|
26
|
+
* authority line ("Checked Halcyon model"). Defaults to `productName`.
|
|
27
|
+
* `null` draws the logo alone, for a wordmark that already says the name.
|
|
28
|
+
*/
|
|
29
|
+
readonly shortName?: string | null;
|
|
30
|
+
/** Beside the title in the editor shell. Nothing is drawn without one. */
|
|
31
|
+
readonly logo?: BrandingLogo;
|
|
32
|
+
/**
|
|
33
|
+
* One CSS colour for the chrome - the authority mark, the notices, the
|
|
34
|
+
* changeset controls - never the notation: what a node or an edge looks
|
|
35
|
+
* like is the style preset's, and a comparison's added/removed marks keep
|
|
36
|
+
* their own tokens.
|
|
37
|
+
*/
|
|
38
|
+
readonly accent?: string;
|
|
39
|
+
/** Where the brand mark links. Without it the mark is text, not a link. */
|
|
40
|
+
readonly docsUrl?: string;
|
|
41
|
+
/**
|
|
42
|
+
* The line under the product name, on the editor strip, the workbook's
|
|
43
|
+
* cover sheet and the LikeC4 banner. Unset: "Powered by yarramate". A
|
|
44
|
+
* string replaces it; `null` removes it, and with it every other mention
|
|
45
|
+
* of the engine those surfaces make.
|
|
46
|
+
*/
|
|
47
|
+
readonly vendorLine?: string | null;
|
|
48
|
+
/**
|
|
49
|
+
* The prefix of the tool names an agent reads: `acme` publishes
|
|
50
|
+
* `acme_design`, `acme_apply`, ... Default `yarramate`. An instruction
|
|
51
|
+
* written for `yarramate_design` will not find `acme_design`, so a host
|
|
52
|
+
* that re-prefixes owns its own agent instructions.
|
|
53
|
+
*/
|
|
54
|
+
readonly toolPrefix?: string;
|
|
55
|
+
}
|
|
56
|
+
/** `Branding` with every default applied, which is what the surfaces read. */
|
|
57
|
+
export interface ResolvedBranding {
|
|
58
|
+
readonly productName: string;
|
|
59
|
+
/** `null` when the mark is the logo alone; the authority line then says `productName`. */
|
|
60
|
+
readonly shortName: string | null;
|
|
61
|
+
readonly logo?: BrandingLogo;
|
|
62
|
+
readonly accent?: string;
|
|
63
|
+
readonly docsUrl?: string;
|
|
64
|
+
/** `null` when there is none to show. */
|
|
65
|
+
readonly vendorLine: string | null;
|
|
66
|
+
readonly toolPrefix: string;
|
|
67
|
+
/** False is the unbranded product: every surface as it was before #546. */
|
|
68
|
+
readonly branded: boolean;
|
|
69
|
+
}
|
|
70
|
+
export declare const YARRAMATE_PRODUCT_NAME = "YarraMate";
|
|
71
|
+
export declare const YARRAMATE_TOOL_PREFIX = "yarramate";
|
|
72
|
+
export declare const DEFAULT_VENDOR_LINE = "Powered by yarramate";
|
|
73
|
+
/**
|
|
74
|
+
* Applies the defaults. `undefined` is the unbranded product. A value with
|
|
75
|
+
* a blank `productName` or a `toolPrefix` no MCP client could publish is a
|
|
76
|
+
* host's configuration error and throws, at mount or serve time, rather
|
|
77
|
+
* than reaching a person as a blank name or an agent as a broken tool list.
|
|
78
|
+
*/
|
|
79
|
+
export declare const resolveBranding: (branding?: Branding) => ResolvedBranding;
|
|
80
|
+
/**
|
|
81
|
+
* The product name as an identifier segment: the LikeC4 project name is
|
|
82
|
+
* `<slug>-<project id>`, `yarramate-…` unbranded. Lower-case letters,
|
|
83
|
+
* digits and single hyphens; a name with nothing usable in it falls back
|
|
84
|
+
* to the engine's own slug rather than producing an empty segment.
|
|
85
|
+
*/
|
|
86
|
+
export declare const brandSlug: (branding: ResolvedBranding) => string;
|
package/dist/branding.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* White-labelling (#546, ADR 0158): one value, set once by a host, that
|
|
3
|
+
* names the product on every surface a consumer's users see - the editor
|
|
4
|
+
* shell, the tool list an agent reads, the workbook's cover sheet and the
|
|
5
|
+
* LikeC4 banner. Nothing else changes: record formats, diagnostic codes and
|
|
6
|
+
* the wire protocol are contracts, not branding, and stay `yarramate/...`
|
|
7
|
+
* and `YM...`. Absent, every surface reads exactly as it always has.
|
|
8
|
+
*
|
|
9
|
+
* Pure: no imports, so it sits under every entry (`yarramate/tools`,
|
|
10
|
+
* `yarramate/workbook`, `yarramate/visual-app`) without weight.
|
|
11
|
+
*/
|
|
12
|
+
export const YARRAMATE_PRODUCT_NAME = 'YarraMate';
|
|
13
|
+
export const YARRAMATE_TOOL_PREFIX = 'yarramate';
|
|
14
|
+
export const DEFAULT_VENDOR_LINE = 'Powered by yarramate';
|
|
15
|
+
/** What an MCP client accepts in a tool name, applied to the prefix alone. */
|
|
16
|
+
const TOOL_PREFIX = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
|
|
17
|
+
const UNBRANDED = {
|
|
18
|
+
productName: YARRAMATE_PRODUCT_NAME,
|
|
19
|
+
shortName: YARRAMATE_PRODUCT_NAME,
|
|
20
|
+
vendorLine: null,
|
|
21
|
+
toolPrefix: YARRAMATE_TOOL_PREFIX,
|
|
22
|
+
branded: false,
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Applies the defaults. `undefined` is the unbranded product. A value with
|
|
26
|
+
* a blank `productName` or a `toolPrefix` no MCP client could publish is a
|
|
27
|
+
* host's configuration error and throws, at mount or serve time, rather
|
|
28
|
+
* than reaching a person as a blank name or an agent as a broken tool list.
|
|
29
|
+
*/
|
|
30
|
+
export const resolveBranding = (branding) => {
|
|
31
|
+
if (branding === undefined)
|
|
32
|
+
return UNBRANDED;
|
|
33
|
+
const productName = branding.productName.trim();
|
|
34
|
+
if (productName === '') {
|
|
35
|
+
throw new TypeError('branding.productName must not be blank');
|
|
36
|
+
}
|
|
37
|
+
const toolPrefix = branding.toolPrefix ?? YARRAMATE_TOOL_PREFIX;
|
|
38
|
+
if (!TOOL_PREFIX.test(toolPrefix)) {
|
|
39
|
+
throw new TypeError(`branding.toolPrefix "${toolPrefix}" must be letters, digits and hyphens, starting with a letter or digit`);
|
|
40
|
+
}
|
|
41
|
+
const shortName = branding.shortName === null ? null : branding.shortName?.trim();
|
|
42
|
+
const vendorLine = branding.vendorLine === undefined
|
|
43
|
+
? DEFAULT_VENDOR_LINE
|
|
44
|
+
: branding.vendorLine === null || branding.vendorLine.trim() === ''
|
|
45
|
+
? null
|
|
46
|
+
: branding.vendorLine.trim();
|
|
47
|
+
return {
|
|
48
|
+
productName,
|
|
49
|
+
shortName: shortName === null
|
|
50
|
+
? null
|
|
51
|
+
: shortName === undefined || shortName === ''
|
|
52
|
+
? productName
|
|
53
|
+
: shortName,
|
|
54
|
+
...(branding.logo === undefined ? {} : { logo: branding.logo }),
|
|
55
|
+
...(branding.accent === undefined ? {} : { accent: branding.accent }),
|
|
56
|
+
...(branding.docsUrl === undefined ? {} : { docsUrl: branding.docsUrl }),
|
|
57
|
+
vendorLine,
|
|
58
|
+
toolPrefix,
|
|
59
|
+
branded: true,
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* The product name as an identifier segment: the LikeC4 project name is
|
|
64
|
+
* `<slug>-<project id>`, `yarramate-…` unbranded. Lower-case letters,
|
|
65
|
+
* digits and single hyphens; a name with nothing usable in it falls back
|
|
66
|
+
* to the engine's own slug rather than producing an empty segment.
|
|
67
|
+
*/
|
|
68
|
+
export const brandSlug = (branding) => {
|
|
69
|
+
if (!branding.branded)
|
|
70
|
+
return YARRAMATE_TOOL_PREFIX;
|
|
71
|
+
// Split on the runs and join what is left: linear, where a trim by
|
|
72
|
+
// `^-+|-+$` is polynomial on a name that is mostly hyphens (CodeQL
|
|
73
|
+
// js/polynomial-redos, the rule that bit #547's walker too).
|
|
74
|
+
const slug = (branding.shortName ?? branding.productName)
|
|
75
|
+
.toLowerCase()
|
|
76
|
+
.split(/[^a-z0-9]+/)
|
|
77
|
+
.filter((part) => part !== '')
|
|
78
|
+
.join('-');
|
|
79
|
+
return slug === '' ? YARRAMATE_TOOL_PREFIX : slug;
|
|
80
|
+
};
|
package/dist/tools/export.js
CHANGED
|
@@ -157,6 +157,7 @@ export const exportLikeC4 = (workspace, project) => guarded(() => {
|
|
|
157
157
|
return held === undefined ? undefined : { path, source: held.source };
|
|
158
158
|
},
|
|
159
159
|
requireMappedRelationships: false,
|
|
160
|
+
...(workspace.branding === undefined ? {} : { branding: workspace.branding }),
|
|
160
161
|
});
|
|
161
162
|
if (!exported.ok)
|
|
162
163
|
return failed(exported.diagnostics);
|
|
@@ -185,7 +186,7 @@ export const exportWorkbook = (workspace, projection) => guarded(() => {
|
|
|
185
186
|
...compiled.profileContext.relationshipKindLineages.keys(),
|
|
186
187
|
].sort(),
|
|
187
188
|
statuses: ['planned', 'current', 'retired'],
|
|
188
|
-
});
|
|
189
|
+
}, workspace.branding);
|
|
189
190
|
const stem = evaluated.result.projection.split('@')[0] ?? 'workbook';
|
|
190
191
|
return {
|
|
191
192
|
ok: true,
|
package/dist/tools/table.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { WorkspaceSource } from '../compiler.js';
|
|
2
2
|
import type { ToolWorkspace } from './workspace.js';
|
|
3
|
+
import { type Branding } from '../branding.js';
|
|
3
4
|
/**
|
|
4
5
|
* The tool surface, once (ADR 0156). The stdio adapter and a hosted server
|
|
5
6
|
* publish these rows; `runTool` answers a call over a store, and both
|
|
@@ -7,7 +8,18 @@ import type { ToolWorkspace } from './workspace.js';
|
|
|
7
8
|
* the network read the same names, the same schemas, the same sentences,
|
|
8
9
|
* and get the same text back.
|
|
9
10
|
*/
|
|
10
|
-
export
|
|
11
|
+
export declare const TOOL_VERBS: readonly ['ask', 'design', 'apply', 'check', 'reconcile', 'export'];
|
|
12
|
+
export type ToolVerb = (typeof TOOL_VERBS)[number];
|
|
13
|
+
/**
|
|
14
|
+
* A published name: the prefix a host chose, an underscore, the verb. The
|
|
15
|
+
* prefix is branding (#546, ADR 0158); the verb is the contract, and
|
|
16
|
+
* `runTool` dispatches on it alone.
|
|
17
|
+
*/
|
|
18
|
+
export type ToolNameFor<P extends string> = `${P}_${ToolVerb}`;
|
|
19
|
+
export type ToolName = ToolNameFor<typeof YARRAMATE_PREFIX>;
|
|
20
|
+
declare const YARRAMATE_PREFIX = "yarramate";
|
|
21
|
+
/** The verb behind a name of any prefix; `undefined` for a name that is not a tool's. */
|
|
22
|
+
export declare const toolVerbOf: (name: string) => ToolVerb | undefined;
|
|
11
23
|
/**
|
|
12
24
|
* One row per tool. Generic over the name so a host that adds tools of its
|
|
13
25
|
* own builds `[...TOOL_CATALOGUE, own]` as `ToolDefinition<string>[]` with
|
|
@@ -33,7 +45,13 @@ export interface ToolDefinition<N extends string = ToolName> {
|
|
|
33
45
|
* for the first time has never seen the skill file; the tool list is the
|
|
34
46
|
* only place it learns that design asks, apply lands, and design asks again.
|
|
35
47
|
*/
|
|
36
|
-
export declare const
|
|
48
|
+
export declare const loopFor: (branding?: Branding) => string;
|
|
49
|
+
export declare const LOOP: string;
|
|
50
|
+
/**
|
|
51
|
+
* The `initialize` instructions a server publishes, without the stdio
|
|
52
|
+
* adapter's sentence about `workspace`: the record, the one write, the loop.
|
|
53
|
+
*/
|
|
54
|
+
export declare const instructionsFor: (branding?: Branding) => string;
|
|
37
55
|
/**
|
|
38
56
|
* The two argument properties that exist only where a filesystem does:
|
|
39
57
|
* `workspace` (which manifest) and `out` (where export writes). The stdio
|
|
@@ -42,6 +60,12 @@ export declare const LOOP = "The loop: call yarramate_design for the top open qu
|
|
|
42
60
|
* words.
|
|
43
61
|
*/
|
|
44
62
|
export declare const STDIO_PROPERTIES: Readonly<Record<'workspace' | 'out', Record<string, unknown>>>;
|
|
63
|
+
/**
|
|
64
|
+
* The rows for a host's branding: the prefix in every name, in the loop
|
|
65
|
+
* sentence and wherever a description names a sibling tool. Unbranded, or
|
|
66
|
+
* branded without a `toolPrefix`, this is `TOOL_CATALOGUE` row for row.
|
|
67
|
+
*/
|
|
68
|
+
export declare const toolCatalogueFor: (branding?: Branding) => readonly ToolDefinition<string>[];
|
|
45
69
|
export declare const TOOL_CATALOGUE: readonly ToolDefinition<ToolName>[];
|
|
46
70
|
export interface ToolFile {
|
|
47
71
|
/** Relative, `/`-separated, as the CLI would write it under `out`. */
|
|
@@ -78,8 +102,13 @@ export type ToolOutcome = {
|
|
|
78
102
|
* the function the row names, renders exactly the text the stdio adapter
|
|
79
103
|
* returns for the same call. `yarramate_reconcile` answers `ok: false`
|
|
80
104
|
* with the row's `unavailable` line.
|
|
105
|
+
*
|
|
106
|
+
* `name` may carry any prefix (#546): the verb after the last underscore is
|
|
107
|
+
* what dispatches, and a refusal names the tool by the name it was called
|
|
108
|
+
* by, so an agent reading `acme_export` in its tool list reads `acme_export`
|
|
109
|
+
* in the refusal. A name with no tool verb is refused, never thrown.
|
|
81
110
|
*/
|
|
82
|
-
export declare const runTool: (name:
|
|
111
|
+
export declare const runTool: (name: string, input: Record<string, unknown>, workspace: ToolWorkspace) => ToolOutcome;
|
|
83
112
|
/** The files a text kind would write under `out`, for a caller with a filesystem. */
|
|
84
113
|
export declare const filesOf: (outcome: ToolOutcome) => readonly ToolFile[];
|
|
85
114
|
export type { WorkspaceSource };
|