halfcode-compiler.xnl 0.2.0 → 0.2.2

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.
@@ -1,561 +0,0 @@
1
- import { l as resourceRefToFqn, u as resolveObjectOperationCompilation } from "./src-DJr-I4Kc.js";
2
- import { n as parseResourceMappings, r as planResourceMappings, t as applyResourceMappingPlan } from "./src-BlKlpg0J.js";
3
- import { mkdir, rm, writeFile } from "node:fs/promises";
4
- import { dirname, join } from "node:path";
5
- //#region ../compiler-skill/src/index.ts
6
- async function compileSkillCapsule(input) {
7
- validateSkillDescriptor(input.skill);
8
- const references = input.references ?? [];
9
- for (const reference of references) validateReferencePath(reference.path);
10
- await rm(input.outputDir, {
11
- recursive: true,
12
- force: true
13
- });
14
- await mkdir(join(input.outputDir, "references"), { recursive: true });
15
- const files = [];
16
- const skillText = renderSkill(input.skill, input.registry, references);
17
- await writeFile(join(input.outputDir, "SKILL.md"), skillText);
18
- files.push("SKILL.md");
19
- for (const reference of references) {
20
- const target = join(input.outputDir, "references", reference.path);
21
- await mkdir(dirname(target), { recursive: true });
22
- await writeFile(target, reference.content);
23
- files.push(`references/${reference.path}`);
24
- }
25
- return {
26
- skillName: input.skill.name,
27
- outputRoot: input.outputDir,
28
- files
29
- };
30
- }
31
- async function compileResourceSkillCapsule(input) {
32
- const skill = input.assembly.skillCapsules.find((item) => item.fqn === input.skillFqn);
33
- if (!skill) throw new Error(`SkillCapsule not found: ${input.skillFqn}`);
34
- const schemas = schemaReader(input.schemas);
35
- const selection = selectSkillResources(input.assembly, skill);
36
- const mappings = parseResourceMappings(skill.resourceMappings?.content ?? "<ResourceMappings/>", skill.resourceMappings?.absolutePath ?? `${skill.source.logicalPath}#ResourceMappings`);
37
- const callableResources = [...selection.functions, ...selection.composedFunctions];
38
- assertCallableClosure(callableResources, schemas);
39
- assertObjectOperationArtifactClosure(selection, schemas);
40
- const generatedTargets = plannedGeneratedTargets(selection, callableResources, mappings);
41
- assertNoGeneratedTargetCollisions(generatedTargets);
42
- const resourceMappingPlan = await planResourceMappings(mappings, {
43
- moduleRoots: new Map(input.assembly.modules.map((module) => [module.id, module.resourceRootDir])),
44
- defaultSourceRoot: skill.source.directory,
45
- reservedTargetPaths: generatedTargets
46
- });
47
- await rm(input.outputDir, {
48
- recursive: true,
49
- force: true
50
- });
51
- await mkdir(input.outputDir, { recursive: true });
52
- const files = [];
53
- const referenceFiles = await writeReferenceFiles(input.outputDir, selection, schemas, mappings);
54
- files.push(...referenceFiles);
55
- const callableFiles = await writeCallableArtifacts(input.outputDir, callableResources, schemas, mappings.callableArtifactsTarget);
56
- files.push(...callableFiles);
57
- files.push(...await writeObjectOperationArtifacts(input.outputDir, selection, schemas));
58
- files.push(...await applyResourceMappingPlan(resourceMappingPlan, input.outputDir));
59
- const skillName = stringField(skill.metadata, "name") ?? lastFqnSegment(skill.fqn);
60
- const skillText = renderEjsTemplate(skill.template.content, {
61
- skill,
62
- metadata: skill.metadata,
63
- references: referenceModel(selection, mappings),
64
- renderPromptFragment: (fqn) => {
65
- return selection.promptFragments.find((item) => item.fqn === fqn)?.instruction?.content.trim() ?? "";
66
- }
67
- });
68
- await writeFile(join(input.outputDir, "SKILL.md"), skillText.trimEnd() + "\n");
69
- files.push("SKILL.md");
70
- return {
71
- skillName,
72
- outputRoot: input.outputDir,
73
- files: files.sort()
74
- };
75
- }
76
- function renderSkill(skill, registry, references) {
77
- const lines = [
78
- "---",
79
- `name: ${skill.name}`,
80
- `description: ${skill.description}`,
81
- "---",
82
- "",
83
- `# ${skill.name}`,
84
- "",
85
- skill.description,
86
- ""
87
- ];
88
- if (skill.instructions?.trim()) lines.push("## Instructions", "", skill.instructions.trim(), "");
89
- if (registry) {
90
- lines.push("## Resources", "");
91
- for (const [kind, records] of [...registry.byKind.entries()].sort(([a], [b]) => a.localeCompare(b))) {
92
- lines.push(`### ${kind}`, "");
93
- for (const record of [...records].sort((a, b) => (a.fqn ?? a.name ?? "").localeCompare(b.fqn ?? b.name ?? ""))) lines.push(`- ${record.fqn ?? record.name}: ${record.description}`);
94
- lines.push("");
95
- }
96
- }
97
- if (references.length > 0) {
98
- lines.push("## References", "");
99
- for (const reference of references) lines.push(`- references/${reference.path}`);
100
- lines.push("");
101
- }
102
- return `${lines.join("\n").trimEnd()}\n`;
103
- }
104
- function validateSkillDescriptor(skill) {
105
- if (!skill.name.trim()) throw new Error("Skill name is required");
106
- if (!skill.description.trim()) throw new Error("Skill description is required");
107
- }
108
- function validateReferencePath(path) {
109
- if (path.startsWith("/") || path.includes("\\") || path.split("/").includes("..") || path.trim() !== path || path.length === 0) throw new Error(`Invalid Skill reference path: ${path}`);
110
- }
111
- function selectSkillResources(assembly, skill) {
112
- const includes = skill.includes.length > 0 ? skill.includes : [
113
- ...assembly.functions.map((item) => ({
114
- kind: item.kind,
115
- ref: `resource://${item.fqn}`
116
- })),
117
- ...assembly.composedFunctions.map((item) => ({
118
- kind: item.kind,
119
- ref: `resource://${item.fqn}`
120
- })),
121
- ...assembly.businessObjects.map((item) => ({
122
- kind: item.kind,
123
- ref: `resource://${item.fqn}`
124
- })),
125
- ...assembly.pageObjects.map((item) => ({
126
- kind: item.kind,
127
- ref: `resource://${item.fqn}`
128
- })),
129
- ...assembly.applicationSops.map((item) => ({
130
- kind: item.kind,
131
- ref: `resource://${item.fqn}`
132
- })),
133
- ...assembly.promptFragments.map((item) => ({
134
- kind: item.kind,
135
- ref: `resource://${item.fqn}`
136
- })),
137
- ...assembly.wikiPages.map((item) => ({
138
- kind: item.kind,
139
- ref: `resource://${item.fqn}`
140
- }))
141
- ];
142
- const fqnSet = new Set(includes.map((include) => resourceRefToFqn(include.ref)));
143
- const businessObjects = assembly.businessObjects.filter((item) => fqnSet.has(item.fqn));
144
- const pageObjects = assembly.pageObjects.filter((item) => fqnSet.has(item.fqn));
145
- const businessSopRefs = new Set(businessObjects.flatMap((item) => item.sopRefs).map(resourceRefToFqn));
146
- return {
147
- assembly,
148
- functions: assembly.functions.filter((item) => fqnSet.has(item.fqn)),
149
- composedFunctions: assembly.composedFunctions.filter((item) => fqnSet.has(item.fqn)),
150
- businessObjects,
151
- pageObjects,
152
- businessObjectSops: assembly.businessObjectSops.filter((item) => businessSopRefs.has(item.fqn)),
153
- applicationSops: assembly.applicationSops.filter((item) => fqnSet.has(item.fqn)),
154
- promptFragments: assembly.promptFragments.filter((item) => fqnSet.has(item.fqn)),
155
- wikiPages: assembly.wikiPages.filter((item) => fqnSet.has(item.fqn))
156
- };
157
- }
158
- async function writeReferenceFiles(outputDir, selection, schemas, mappings) {
159
- const files = [];
160
- for (const item of selection.composedFunctions) files.push(await writeReference(outputDir, mappedResourcePath(mappings, item.kind, item.fqn), callableReferenceMarkdown(item, schemas)));
161
- for (const item of selection.functions) files.push(await writeReference(outputDir, mappedResourcePath(mappings, item.kind, item.fqn), callableReferenceMarkdown(item, schemas)));
162
- for (const item of selection.businessObjects) {
163
- const sops = selection.businessObjectSops.filter((sop) => item.sopRefs.map(resourceRefToFqn).includes(sop.fqn));
164
- files.push(await writeReference(outputDir, mappedResourcePath(mappings, item.kind, item.fqn), businessObjectMarkdown(item, sops, (kind, fqn) => mappedResourcePath(mappings, kind, fqn))));
165
- }
166
- for (const item of selection.pageObjects) files.push(await writeReference(outputDir, mappedResourcePath(mappings, item.kind, item.fqn), objectOwnerMarkdown(item)));
167
- for (const item of selection.businessObjectSops) files.push(await writeReference(outputDir, mappedResourcePath(mappings, item.kind, item.fqn), textReferenceMarkdown(item)));
168
- for (const item of selection.applicationSops) files.push(await writeReference(outputDir, mappedResourcePath(mappings, item.kind, item.fqn), textReferenceMarkdown(item)));
169
- for (const item of selection.promptFragments) files.push(await writeReference(outputDir, mappedResourcePath(mappings, item.kind, item.fqn), textReferenceMarkdown(item)));
170
- for (const item of selection.wikiPages) files.push(await writeReference(outputDir, mappedResourcePath(mappings, item.kind, item.fqn), textReferenceMarkdown(item)));
171
- return files;
172
- }
173
- function objectOwnerMarkdown(resource) {
174
- return [
175
- `# ${lastFqnSegment(resource.fqn)}`,
176
- "",
177
- `<fqn>${resource.fqn}</fqn>`,
178
- `<kind>${resource.kind}</kind>`,
179
- `<description>${resource.description}</description>`,
180
- "",
181
- "<available_operations>",
182
- ...resource.operations.map((operation) => `- ${operation.ref}: ${operation.behavior}, targets=${operation.targets.kind}, modes=${operation.invocationModes.join(",")}`),
183
- "</available_operations>",
184
- "",
185
- "<usage>",
186
- "Call `run_object_operation({ targets, invocation, config })`; action invocation uses input and mutation invocation uses desired.",
187
- "</usage>",
188
- ""
189
- ].join("\n");
190
- }
191
- async function writeReference(outputDir, path, content) {
192
- validateReferencePath(path);
193
- const target = join(outputDir, path);
194
- await mkdir(dirname(target), { recursive: true });
195
- await writeFile(target, content.trimEnd() + "\n");
196
- return path;
197
- }
198
- function callableReferenceMarkdown(resource, schemas) {
199
- return [
200
- `# ${lastFqnSegment(resource.fqn)}`,
201
- "",
202
- `<fqn>${resource.fqn}</fqn>`,
203
- `<kind>${resource.kind}</kind>`,
204
- `<description>${resource.description}</description>`,
205
- "",
206
- "<usage>",
207
- `Call \`run_callable_resource(${JSON.stringify(resource.fqn)}, input, config)\` with an input object matching <input_schema>. The host supplies runtime separately; omit config when the capability does not need it.`,
208
- "</usage>",
209
- "",
210
- "<input_schema>",
211
- "```json",
212
- JSON.stringify(schemas(resource.inputContractRef), null, 2),
213
- "```",
214
- "</input_schema>",
215
- "",
216
- "<output_schema>",
217
- "```json",
218
- JSON.stringify(schemas(resource.outputContractRef), null, 2),
219
- "```",
220
- "</output_schema>",
221
- "",
222
- "<instruction>",
223
- resource.instruction?.content.trim() ?? "",
224
- "</instruction>",
225
- ""
226
- ].join("\n");
227
- }
228
- function businessObjectMarkdown(resource, sops, mappedPath) {
229
- return [
230
- `# ${lastFqnSegment(resource.fqn)}`,
231
- "",
232
- `<fqn>${resource.fqn}</fqn>`,
233
- `<kind>${resource.kind}</kind>`,
234
- `<description>${resource.description}</description>`,
235
- "",
236
- "<available_operations>",
237
- ...resource.operations.map((operation) => `- ${operation.ref}: ${operation.behavior}, targets=${operation.targets.kind}, modes=${operation.invocationModes.join(",")}`),
238
- "</available_operations>",
239
- "",
240
- "<available_sops>",
241
- ...sops.map((item) => `- ${item.fqn}: ${mappedPath(item.kind, item.fqn)}`),
242
- "</available_sops>",
243
- "",
244
- "<usage>",
245
- "Call `run_object_operation({ targets, invocation, config })`; action invocation uses input and mutation invocation uses desired.",
246
- "</usage>",
247
- "",
248
- "<instruction>",
249
- resource.instruction?.content.trim() ?? "",
250
- "</instruction>",
251
- ""
252
- ].join("\n");
253
- }
254
- function textReferenceMarkdown(resource) {
255
- return [
256
- `# ${lastFqnSegment(resource.fqn)}`,
257
- "",
258
- `<fqn>${resource.fqn}</fqn>`,
259
- `<kind>${resource.kind}</kind>`,
260
- `<description>${resource.description}</description>`,
261
- "",
262
- resource.instruction?.content.trim() ?? "",
263
- ""
264
- ].join("\n");
265
- }
266
- async function writeCallableArtifacts(outputDir, resources, schemas, targetBase) {
267
- const files = [];
268
- const imports = [];
269
- const entries = [];
270
- for (const resource of resources) {
271
- const filePath = `${`${resource.kind}s`}/${lastFqnSegment(resource.fqn)}.js`;
272
- const target = join(outputDir, targetBase, filePath);
273
- const symbol = safeJsIdentifier(resource.fqn);
274
- await mkdir(dirname(target), { recursive: true });
275
- await writeFile(target, [
276
- `import { ${resource.codeBinding.exportName} as entry } from ${JSON.stringify(resource.codeBinding.moduleSpecifier)}`,
277
- "",
278
- "export default entry",
279
- ""
280
- ].join("\n"));
281
- files.push(`${targetBase}${filePath}`);
282
- imports.push(`import ${symbol} from ${JSON.stringify(`./${filePath}`)}`);
283
- entries.push(JSON.stringify(resource.fqn) + `: { kind: ${JSON.stringify(resource.kind)}, handler: ${symbol} }`);
284
- }
285
- const registry = resources.map((resource) => ({
286
- fqn: resource.fqn,
287
- kind: resource.kind,
288
- description: resource.description,
289
- inputContractRef: resource.inputContractRef,
290
- outputContractRef: resource.outputContractRef,
291
- inputSchema: schemas(resource.inputContractRef),
292
- outputSchema: schemas(resource.outputContractRef),
293
- module: `./${resource.kind}s/${lastFqnSegment(resource.fqn)}.js`
294
- }));
295
- await mkdir(join(outputDir, targetBase), { recursive: true });
296
- await writeFile(join(outputDir, targetBase, "registry.json"), `${JSON.stringify({ callableResources: registry }, null, 2)}\n`);
297
- files.push(`${targetBase}registry.json`);
298
- await writeFile(join(outputDir, targetBase, "bundle.js"), [
299
- "import { runWithRuntime } from \"halfcode-compiler.xnl/authoring-runtime\"",
300
- ...imports,
301
- "",
302
- `const registry = { ${entries.join(", ")} }`,
303
- "let callableRuntime",
304
- "",
305
- "/**",
306
- " * Host-only initialization boundary. Bind runtime capabilities before exposing",
307
- " * run_callable_resource to AI-authored code; runtime is never an AI argument.",
308
- " */",
309
- "export function initialize_callable_runtime(runtime) {",
310
- " if (!runtime) throw new Error(\"Callable runtime is required\")",
311
- " callableRuntime = runtime",
312
- "}",
313
- "",
314
- "/**",
315
- " * AI-facing callable entry. Callers provide only the resource identity, business",
316
- " * input, and optional invocation config; the host-owned runtime stays hidden.",
317
- " */",
318
- "export async function run_callable_resource(fqn, input, config) {",
319
- " if (!callableRuntime) throw new Error(\"Callable runtime has not been initialized\")",
320
- " return invokeCallableResource(callableRuntime, fqn, input, config)",
321
- "}",
322
- "",
323
- "/**",
324
- " * Framework-internal bridge. It activates the host runtime context and forwards",
325
- " * input/config unchanged to the deterministic resource handler.",
326
- " */",
327
- "async function invokeCallableResource(runtime, fqn, input, config) {",
328
- " const entry = registry[fqn]",
329
- " if (!entry) throw new Error(`Unknown callable resource: ${fqn}`)",
330
- " return runWithRuntime(runtime, () => entry.handler(input, config))",
331
- "}",
332
- "",
333
- "export function resolve_callable_resource(fqn) {",
334
- " const entry = registry[fqn]",
335
- " if (!entry) throw new Error(`Unknown callable resource: ${fqn}`)",
336
- " return { fqn, kind: entry.kind }",
337
- "}",
338
- ""
339
- ].join("\n"));
340
- files.push(`${targetBase}bundle.js`);
341
- return files;
342
- }
343
- async function writeObjectOperationArtifacts(outputDir, selection, schemas) {
344
- const targetBase = "objects/";
345
- const owners = [...selection.businessObjects, ...selection.pageObjects];
346
- const operations = owners.flatMap((owner) => owner.operations).sort((left, right) => left.ref.localeCompare(right.ref));
347
- const targetKinds = owners.flatMap((owner) => owner.targetKinds).sort((left, right) => left.kindFqn.localeCompare(right.kindFqn));
348
- const files = [];
349
- const imports = [];
350
- const entries = [];
351
- for (const definition of operations) {
352
- const binding = resolveObjectOperationCompilation(selection.assembly, definition.ref);
353
- const filePath = `handlers/${`${safeJsIdentifier(definition.ref)}.js`}`;
354
- const target = join(outputDir, targetBase, filePath);
355
- const symbol = safeJsIdentifier(definition.ref);
356
- await mkdir(dirname(target), { recursive: true });
357
- await writeFile(target, [
358
- `import { ${binding.codeBinding.exportName} as entry } from ${JSON.stringify(binding.codeBinding.moduleSpecifier)}`,
359
- "",
360
- "export default entry",
361
- ""
362
- ].join("\n"));
363
- files.push(`${targetBase}${filePath}`);
364
- imports.push(`import ${symbol} from ${JSON.stringify(`./${filePath}`)}`);
365
- entries.push(`${JSON.stringify(definition.ref)}: ${symbol}`);
366
- }
367
- await mkdir(join(outputDir, targetBase), { recursive: true });
368
- const registry = {
369
- targetKinds,
370
- operations: operations.map((definition) => ({
371
- ...definition,
372
- ...objectOperationContractProjection(selection.assembly, definition, schemas)
373
- }))
374
- };
375
- await writeFile(join(outputDir, targetBase, "registry.json"), `${JSON.stringify(registry, null, 2)}\n`);
376
- files.push(`${targetBase}registry.json`);
377
- await writeFile(join(outputDir, targetBase, "bundle.js"), [
378
- "import { assertObjectOperationCall } from \"halfcode-compiler.xnl\"",
379
- "import { runWithRuntime } from \"halfcode-compiler.xnl/authoring-runtime\"",
380
- "import catalog from \"./registry.json\" with { type: \"json\" }",
381
- ...imports,
382
- "",
383
- `const handlers = { ${entries.join(", ")} }`,
384
- "const definitions = Object.fromEntries(catalog.operations.map((definition) => [definition.ref, definition]))",
385
- "let objectOperationRuntime",
386
- "",
387
- "/** Host-only runtime initialization; runtime is never an AI argument. */",
388
- "export function initialize_object_operation_runtime(runtime) {",
389
- " if (!runtime) throw new Error(\"Object operation runtime is required\")",
390
- " objectOperationRuntime = runtime",
391
- "}",
392
- "",
393
- "/** AI-facing object entry with orthogonal targets, invocation and config. */",
394
- "export async function run_object_operation(call) {",
395
- " if (!objectOperationRuntime) throw new Error(\"Object operation runtime has not been initialized\")",
396
- " const operationRef = call?.invocation?.operationRef",
397
- " const definition = definitions[operationRef]",
398
- " if (!definition) throw new Error(`Unknown object operation: ${operationRef}`)",
399
- " const handler = handlers[operationRef]",
400
- " if (!handler) throw new Error(`Object operation handler is unavailable: ${operationRef}`)",
401
- " assertObjectOperationCall(call, definition)",
402
- " return runWithRuntime(objectOperationRuntime, () =>",
403
- " handler(objectOperationRuntime, call.targets, call.invocation, call.config)",
404
- " )",
405
- "}",
406
- "",
407
- "export function resolve_object_operation(operationRef) {",
408
- " const definition = definitions[operationRef]",
409
- " if (!definition) throw new Error(`Unknown object operation: ${operationRef}`)",
410
- " return definition",
411
- "}",
412
- ""
413
- ].join("\n"));
414
- files.push(`${targetBase}bundle.js`);
415
- return files;
416
- }
417
- function objectOperationContractProjection(assembly, definition, schemas) {
418
- const compilation = resolveObjectOperationCompilation(assembly, definition.ref);
419
- if (!compilation.inputContractRef || !compilation.outputContractRef) return {};
420
- return {
421
- inputContractRef: compilation.inputContractRef,
422
- outputContractRef: compilation.outputContractRef,
423
- inputSchema: schemas(compilation.inputContractRef),
424
- outputSchema: schemas(compilation.outputContractRef)
425
- };
426
- }
427
- function referenceModel(selection, mappings) {
428
- const ref = (kind, item) => ({
429
- fqn: item.fqn,
430
- description: item.description,
431
- path: mappedResourcePath(mappings, kind, item.fqn)
432
- });
433
- return {
434
- composedFunctions: selection.composedFunctions.map((item) => ref(item.kind, item)),
435
- functions: selection.functions.map((item) => ref(item.kind, item)),
436
- businessObjects: selection.businessObjects.map((item) => ({
437
- fqn: item.fqn,
438
- description: item.description,
439
- path: mappedResourcePath(mappings, item.kind, item.fqn)
440
- })),
441
- pageObjects: selection.pageObjects.map((item) => ref(item.kind, item)),
442
- applicationSops: selection.applicationSops.map((item) => ref(item.kind, item)),
443
- promptFragments: selection.promptFragments.map((item) => ref(item.kind, item)),
444
- wikiPages: selection.wikiPages.map((item) => ref(item.kind, item)),
445
- callableArtifacts: {
446
- registryPath: `${mappings.callableArtifactsTarget}registry.json`,
447
- bundlePath: `${mappings.callableArtifactsTarget}bundle.js`
448
- },
449
- objectArtifacts: {
450
- registryPath: "objects/registry.json",
451
- bundlePath: "objects/bundle.js"
452
- }
453
- };
454
- }
455
- function mappedResourcePath(mappings, kind, fqn) {
456
- return `${mappings.referenceTargets.get(kind) ?? defaultReferenceTarget(kind)}${kind === "BusinessObject" ? `${lastFqnSegment(fqn)}/BUSINESS_OBJECT.md` : kind === "PageObject" ? `${lastFqnSegment(fqn)}/PAGE_OBJECT.md` : `${lastFqnSegment(fqn)}.md`}`;
457
- }
458
- function defaultReferenceTarget(kind) {
459
- return {
460
- Function: "references/Functions/",
461
- ComposedFunction: "references/ComposedFunctions/",
462
- BusinessObject: "references/BusinessObjects/",
463
- PageObject: "references/PageObjects/",
464
- BusinessObjectSOP: "references/BusinessObjectSOPs/",
465
- ApplicationSOP: "references/ApplicationSOPs/",
466
- PromptFragment: "references/PromptFragments/",
467
- WikiPage: "references/Wiki/"
468
- }[kind] ?? `references/${kind}/`;
469
- }
470
- function schemaReader(schemas) {
471
- return (ref) => {
472
- const fqn = resourceRefToFqn(ref);
473
- if (!schemas) return void 0;
474
- if (typeof schemas.get === "function") return schemas.get(fqn);
475
- return schemas[fqn];
476
- };
477
- }
478
- function renderEjsTemplate(template, context) {
479
- let cursor = 0;
480
- let code = "let __out = '';\nconst __append = (value) => { __out += value == null ? '' : String(value) };\nwith (ctx) {\n";
481
- for (const match of template.matchAll(/<%([=-]?)([\s\S]*?)%>/g)) {
482
- code += `__append(${JSON.stringify(template.slice(cursor, match.index))});\n`;
483
- const [, mode, body] = match;
484
- if (mode === "=" || mode === "-") code += `__append(${body.trim()});\n`;
485
- else code += `${body}\n`;
486
- cursor = (match.index ?? 0) + match[0].length;
487
- }
488
- code += `__append(${JSON.stringify(template.slice(cursor))});\n`;
489
- code += "}\nreturn __out";
490
- return new Function("ctx", code)(context);
491
- }
492
- function stringField(source, name) {
493
- const value = source[name];
494
- return typeof value === "string" && value.trim() ? value : void 0;
495
- }
496
- function lastFqnSegment(fqn) {
497
- return fqn.split(".").at(-1) ?? fqn;
498
- }
499
- function safeJsIdentifier(fqn) {
500
- return fqn.replace(/[^A-Za-z0-9_$]/g, "_");
501
- }
502
- function plannedGeneratedTargets(selection, callableResources, mappings) {
503
- return [
504
- "SKILL.md",
505
- ...[
506
- ...selection.functions,
507
- ...selection.composedFunctions,
508
- ...selection.businessObjects,
509
- ...selection.pageObjects,
510
- ...selection.businessObjectSops,
511
- ...selection.applicationSops,
512
- ...selection.promptFragments,
513
- ...selection.wikiPages
514
- ].map((item) => mappedResourcePath(mappings, item.kind, item.fqn)),
515
- ...callableResources.map((resource) => {
516
- return `${mappings.callableArtifactsTarget}${resource.kind}s/${lastFqnSegment(resource.fqn)}.js`;
517
- }),
518
- `${mappings.callableArtifactsTarget}registry.json`,
519
- `${mappings.callableArtifactsTarget}bundle.js`,
520
- ...[...selection.businessObjects, ...selection.pageObjects].flatMap((owner) => owner.operations).map((operation) => `objects/handlers/${safeJsIdentifier(operation.ref)}.js`),
521
- "objects/registry.json",
522
- "objects/bundle.js"
523
- ];
524
- }
525
- function assertNoGeneratedTargetCollisions(paths) {
526
- const seen = /* @__PURE__ */ new Set();
527
- for (const path of paths) {
528
- validateReferencePath(path);
529
- if (seen.has(path)) throw new Error(`Generated Skill target collision: ${path}`);
530
- seen.add(path);
531
- }
532
- }
533
- function assertCallableClosure(resources, schemas) {
534
- const fqns = /* @__PURE__ */ new Set();
535
- for (const resource of resources) {
536
- if (fqns.has(resource.fqn)) throw new Error(`Callable resource FQN appears more than once: ${resource.fqn}`);
537
- fqns.add(resource.fqn);
538
- if (schemas(resource.inputContractRef) === void 0) throw new Error(`Callable resource ${resource.fqn} is missing input schema ${resource.inputContractRef}`);
539
- if (schemas(resource.outputContractRef) === void 0) throw new Error(`Callable resource ${resource.fqn} is missing output schema ${resource.outputContractRef}`);
540
- if (!resource.codeBinding.moduleSpecifier || !resource.codeBinding.exportName) throw new Error(`Callable resource ${resource.fqn} is missing an executable code binding`);
541
- }
542
- }
543
- function assertObjectOperationArtifactClosure(selection, schemas) {
544
- const operationRefs = /* @__PURE__ */ new Set();
545
- for (const owner of [...selection.businessObjects, ...selection.pageObjects]) for (const definition of owner.operations) {
546
- if (operationRefs.has(definition.ref)) throw new Error(`Object operation ref appears more than once: ${definition.ref}`);
547
- operationRefs.add(definition.ref);
548
- const binding = resolveObjectOperationCompilation(selection.assembly, definition.ref);
549
- if (!binding.codeBinding.moduleSpecifier || !binding.codeBinding.exportName) throw new Error(`Object operation ${definition.ref} is missing an executable code binding`);
550
- if (!binding.inputContractRef || !binding.outputContractRef) continue;
551
- if (schemas(binding.inputContractRef) === void 0) throw new Error(`Object operation ${definition.ref} is missing input schema ${binding.inputContractRef}`);
552
- if (schemas(binding.outputContractRef) === void 0) throw new Error(`Object operation ${definition.ref} is missing output schema ${binding.outputContractRef}`);
553
- }
554
- }
555
- const compilerSkillPackage = {
556
- role: "framework",
557
- area: "compiler-skill",
558
- owns: "standard Skill capsule projection"
559
- };
560
- //#endregion
561
- export { compileSkillCapsule as n, compilerSkillPackage as r, compileResourceSkillCapsule as t };