@meistrari/tela-cli 1.2.1 → 1.4.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/index.js CHANGED
@@ -129552,12 +129552,13 @@ var require_generate = __commonJS({
129552
129552
  const lines = [
129553
129553
  "/* eslint-disable */",
129554
129554
  `// @generated by tela workflow codegen; catalog-metadata-hash: ${snapshot.metadataHash}`,
129555
- "import type { WorkflowCodeFileInputValue, WorkflowCodeRemoteAgentRef, WorkflowCodeRemoteExecutableRef, WorkflowCodeRemoteModelRef } from '@meistrari/workflow-code/contracts'",
129555
+ "import type { WorkflowCodeFileInputValue, WorkflowCodeRemoteAgentRef, WorkflowCodeRemoteExecutableRef, WorkflowCodeRemoteModelRef, WorkflowCodeRemoteTemplateRef } from '@meistrari/workflow-code/contracts'",
129556
129556
  "",
129557
129557
  "declare module '@meistrari/workflow-code' {",
129558
129558
  " function remote(): {",
129559
129559
  " canvas(): WorkflowCodeRemoteCatalogRegistry['canvas']",
129560
129560
  " workflow(): WorkflowCodeRemoteCatalogRegistry['workflow']",
129561
+ " template(): WorkflowCodeRemoteCatalogRegistry['template']",
129561
129562
  " agent(): WorkflowCodeRemoteCatalogRegistry['agent']",
129562
129563
  " models(): WorkflowCodeRemoteCatalogRegistry['models']",
129563
129564
  " }",
@@ -129565,6 +129566,7 @@ var require_generate = __commonJS({
129565
129566
  " interface WorkflowCodeRemoteCatalogRegistry {",
129566
129567
  ` canvas: ${renderResourceRegistry("canvas", normalizeResources(snapshot.catalogs.canvases), diagnostics)}`,
129567
129568
  ` workflow: ${renderResourceRegistry("workflow", normalizeResources(snapshot.catalogs.workflows), diagnostics)}`,
129569
+ ` template: ${renderResourceRegistry("template", normalizeResources(snapshot.catalogs.templates), diagnostics)}`,
129568
129570
  ` agent: ${renderResourceRegistry("agent", normalizeResources(snapshot.catalogs.agents), diagnostics)}`,
129569
129571
  ` models: ${renderModelRegistry(snapshot.catalogs.llmModels)}`,
129570
129572
  " }",
@@ -129576,7 +129578,7 @@ var require_generate = __commonJS({
129576
129578
  function renderResourceRegistry(kind, resources, diagnostics) {
129577
129579
  const nameTree = buildNameTree(resources.filter(hasUniquePath).map((resource) => ({ path: resource.path, value: renderResourceRef(kind, resource) })));
129578
129580
  const byId = resources.map((resource) => `byId(id: ${quote(resource.id)}): ${renderResourceRef(kind, resource)}`).join("; ");
129579
- const unknownRef = kind === "agent" ? "WorkflowCodeRemoteAgentRef<string, unknown, unknown>" : `WorkflowCodeRemoteExecutableRef<${quote(kind)}, string, unknown, unknown, {}>`;
129581
+ const unknownRef = kind === "agent" ? "WorkflowCodeRemoteAgentRef<string, unknown, unknown>" : kind === "template" ? "WorkflowCodeRemoteTemplateRef<string, unknown, unknown>" : `WorkflowCodeRemoteExecutableRef<${quote(kind)}, string, unknown, unknown, {}>`;
129580
129582
  const members = [renderTree(nameTree), byId.length > 0 ? `{ ${byId}; byId(id: string): ${unknownRef} }` : `{ byId(id: string): ${unknownRef} }`];
129581
129583
  for (const resource of resources) {
129582
129584
  if (resource.pathStatus === "ambiguous") {
@@ -129587,13 +129589,14 @@ var require_generate = __commonJS({
129587
129589
  }
129588
129590
  function renderResourceRef(kind, resource) {
129589
129591
  const input = renderInputObject(resource.inputs);
129590
- const output = isAgent(resource) ? renderAgentOutput(resource) : renderOutput(resource.output);
129591
- if (!isAgent(resource)) {
129592
- const environments = resource.targets.map((target) => quote(target.name)).sort().join(" | ") || "never";
129593
- const targets = resource.targets.map((target) => `${quote(target.name)}: { input: ${renderInputObject(target.inputs)}, output: ${renderOutput(target.output)}, hash: ${quote(target.hash)} }`).join("; ");
129594
- return `WorkflowCodeRemoteExecutableRef<${quote(kind)}, ${quote(resource.id)}, ${input}, ${output}, { ${targets} }> & { environments: ${environments} }`;
129595
- }
129596
- return `WorkflowCodeRemoteAgentRef<${quote(resource.id)}, ${input}, ${output}>`;
129592
+ if (isAgent(resource))
129593
+ return `WorkflowCodeRemoteAgentRef<${quote(resource.id)}, ${input}, ${renderAgentOutput(resource)}>`;
129594
+ const output = renderOutput(resource.output);
129595
+ if (!("targets" in resource))
129596
+ return `WorkflowCodeRemoteTemplateRef<${quote(resource.id)}, ${input}, ${output}>`;
129597
+ const environments = resource.targets.map((target) => quote(target.name)).sort().join(" | ") || "never";
129598
+ const targets = resource.targets.map((target) => `${quote(target.name)}: { input: ${renderInputObject(target.inputs)}, output: ${renderOutput(target.output)}, hash: ${quote(target.hash)} }`).join("; ");
129599
+ return `WorkflowCodeRemoteExecutableRef<${quote(kind)}, ${quote(resource.id)}, ${input}, ${output}, { ${targets} }> & { environments: ${environments} }`;
129597
129600
  }
129598
129601
  function renderModelRegistry(models) {
129599
129602
  const named = Object.fromEntries(models.map((model) => [model.id, `WorkflowCodeRemoteModelRef<${quote(model.id)}, "llm">`]));
@@ -146369,7 +146372,12 @@ var require_remote_refs = __commonJS({
146369
146372
  const catalogDiagnostics = validateAgainstSnapshot(input.mode.snapshot, input.binding, lock, input.modelUsage);
146370
146373
  if (catalogDiagnostics.length > 0)
146371
146374
  return { value: void 0, diagnostics: catalogDiagnostics };
146372
- return { value: lock.id, diagnostics: [] };
146375
+ const outputSchema = templateOutputSchema(input.mode.snapshot, input.binding, lock.id);
146376
+ return {
146377
+ value: lock.id,
146378
+ diagnostics: [],
146379
+ ...outputSchema === void 0 ? {} : { outputSchema }
146380
+ };
146373
146381
  }
146374
146382
  function findLock(locks, binding, environment) {
146375
146383
  return locks.find((lock) => lock.kind === binding.kind && (binding.explicitId === void 0 || lock.id === binding.explicitId) && (binding.path === void 0 || samePath(lock.path, binding.path)) && (environment === void 0 || lock.environmentName === environment));
@@ -146393,10 +146401,18 @@ var require_remote_refs = __commonJS({
146393
146401
  return snapshot.catalogs.canvases.find((resource) => resource.id === id);
146394
146402
  if (binding.kind === "workflow")
146395
146403
  return snapshot.catalogs.workflows.find((resource) => resource.id === id);
146404
+ if (binding.kind === "template")
146405
+ return snapshot.catalogs.templates.find((resource) => resource.id === id);
146396
146406
  if (binding.kind === "agent")
146397
146407
  return snapshot.catalogs.agents.find((resource) => resource.id === id);
146398
146408
  return snapshot.catalogs.llmModels.find((resource) => resource.id === id);
146399
146409
  }
146410
+ function templateOutputSchema(snapshot, binding, id) {
146411
+ if (binding.kind !== "template")
146412
+ return void 0;
146413
+ const output = snapshot.catalogs.templates.find((resource) => resource.id === id)?.output;
146414
+ return isRecord3(output?.schema) ? output.schema : void 0;
146415
+ }
146400
146416
  function remoteDiagnostic(code, binding, message) {
146401
146417
  return {
146402
146418
  code,
@@ -146406,6 +146422,9 @@ var require_remote_refs = __commonJS({
146406
146422
  hint: `Remote ${binding.kind} ${binding.explicitId ?? binding.path?.join(" / ") ?? "<root>"}`
146407
146423
  };
146408
146424
  }
146425
+ function isRecord3(value) {
146426
+ return typeof value === "object" && value !== null && !Array.isArray(value);
146427
+ }
146409
146428
  function rootFallbackContractHash(input) {
146410
146429
  return (0, hash_1.hashJson)(input);
146411
146430
  }
@@ -146517,8 +146536,27 @@ var require_resolve = __commonJS({
146517
146536
  contractHash: (0, remote_refs_1.agentSemanticContractHash)({ revision: agent.revision, inputs: normalizedInputsForContract(agent.inputs), ...outputHash === void 0 ? {} : { outputContractHash: outputHash } })
146518
146537
  };
146519
146538
  }
146539
+ if (ref.kind === "template")
146540
+ return lockTemplateRef(ref, resource);
146520
146541
  return lockExecutableRef(ref, resource, ref.kind);
146521
146542
  }
146543
+ function lockTemplateRef(ref, resource) {
146544
+ const outputHash = (0, remote_refs_1.outputContractHash)(resource.output);
146545
+ return {
146546
+ declarationKey: ref.declarationKey,
146547
+ kind: "template",
146548
+ ...resource.pathStatus === "unavailable" ? {} : { path: resource.path },
146549
+ id: resource.id,
146550
+ versionId: resource.versionId,
146551
+ inputHash: (0, remote_refs_1.selectedInputHash)(resource.inputs),
146552
+ ...outputHash === void 0 ? {} : { outputContractHash: outputHash },
146553
+ contractHash: (0, remote_refs_1.rootFallbackContractHash)({
146554
+ versionId: resource.versionId,
146555
+ inputs: normalizedInputsForContract(resource.inputs),
146556
+ ...outputHash === void 0 ? {} : { outputContractHash: outputHash }
146557
+ })
146558
+ };
146559
+ }
146522
146560
  function lockExecutableRef(ref, resource, kind) {
146523
146561
  const environmentName = ref.environment ?? resource.environment ?? (resource.targets.length === 1 ? resource.targets[0]?.name : void 0);
146524
146562
  const target = environmentName === void 0 ? void 0 : resource.targets.find((item) => item.name === environmentName);
@@ -146624,6 +146662,8 @@ var require_resolve = __commonJS({
146624
146662
  function selectedInputs(resource, ref, diagnostics) {
146625
146663
  if (ref.kind === "agent")
146626
146664
  return resource.inputs;
146665
+ if (ref.kind === "template")
146666
+ return resource.inputs;
146627
146667
  const executable = resource;
146628
146668
  const environmentName = ref.environment ?? executable.environment ?? (executable.targets.length === 1 ? executable.targets[0]?.name : void 0);
146629
146669
  if (environmentName === void 0)
@@ -146639,6 +146679,8 @@ var require_resolve = __commonJS({
146639
146679
  return snapshot.catalogs.canvases;
146640
146680
  if (kind === "workflow")
146641
146681
  return snapshot.catalogs.workflows;
146682
+ if (kind === "template")
146683
+ return snapshot.catalogs.templates;
146642
146684
  if (kind === "agent")
146643
146685
  return snapshot.catalogs.agents;
146644
146686
  return snapshot.catalogs.llmModels;
@@ -154668,6 +154710,7 @@ var require_remote = __commonJS({
154668
154710
  return Object.freeze({
154669
154711
  canvas: () => createRemoteRef("canvas"),
154670
154712
  workflow: () => createRemoteRef("workflow"),
154713
+ template: () => createRemoteRef("template"),
154671
154714
  agent: () => createRemoteRef("agent"),
154672
154715
  models: () => createRemoteRef("model")
154673
154716
  });
@@ -368739,10 +368782,11 @@ var require_output_schema = __commonJS({
368739
368782
  "../../packages/workflow-code/dist/compiler/output-schema.js"(exports2) {
368740
368783
  "use strict";
368741
368784
  Object.defineProperty(exports2, "__esModule", { value: true });
368742
- exports2.CROP_OUTPUT_JSON_SCHEMA = exports2.SPLITTER_OUTPUT_JSON_SCHEMA = exports2.FILE_INPUT_JSON_SCHEMA = exports2.FILE_OUTPUT_JSON_SCHEMA = void 0;
368785
+ exports2.DOC_TEMPLATE_OUTPUT_JSON_SCHEMA = exports2.CROP_OUTPUT_JSON_SCHEMA = exports2.SPLITTER_OUTPUT_JSON_SCHEMA = exports2.FILE_INPUT_JSON_SCHEMA = exports2.FILE_OUTPUT_JSON_SCHEMA = void 0;
368743
368786
  exports2.createPromptOutputJsonSchema = createPromptOutputJsonSchema;
368744
368787
  exports2.selectOutputJsonSchema = selectOutputJsonSchema;
368745
368788
  exports2.isFileCompatibleOutputJsonSchema = isFileCompatibleOutputJsonSchema;
368789
+ exports2.isStringCompatibleOutputJsonSchema = isStringCompatibleOutputJsonSchema;
368746
368790
  exports2.FILE_OUTPUT_JSON_SCHEMA = Object.freeze({
368747
368791
  type: "object",
368748
368792
  properties: Object.freeze({
@@ -368790,6 +368834,17 @@ var require_output_schema = __commonJS({
368790
368834
  required: Object.freeze(["indexes", "originalFile", "file"])
368791
368835
  })
368792
368836
  });
368837
+ exports2.DOC_TEMPLATE_OUTPUT_JSON_SCHEMA = Object.freeze({
368838
+ type: "object",
368839
+ properties: Object.freeze({
368840
+ generatedDocument: exports2.FILE_OUTPUT_JSON_SCHEMA,
368841
+ generatedAt: Object.freeze({ type: "string" }),
368842
+ permalinkUrl: Object.freeze({ type: "string" }),
368843
+ permalinkId: Object.freeze({ type: "string" }),
368844
+ permalinkExpiresAt: Object.freeze({ anyOf: Object.freeze([{ type: "string" }, { type: "null" }]) })
368845
+ }),
368846
+ required: Object.freeze(["generatedDocument", "generatedAt"])
368847
+ });
368793
368848
  function createPromptOutputJsonSchema(schema) {
368794
368849
  return schema === void 0 || schema === null ? void 0 : { type: "object", properties: schema };
368795
368850
  }
@@ -368828,17 +368883,17 @@ var require_output_schema = __commonJS({
368828
368883
  if (schema.type !== "object" || !isRecord3(properties))
368829
368884
  return false;
368830
368885
  const stringFields = ["name", "fileUrl", "mimeType", "base64", "vaultReference"];
368831
- if (!stringFields.every((key) => !(key in properties) || isStringJsonSchema(properties[key])))
368886
+ if (!stringFields.every((key) => !(key in properties) || isStringCompatibleOutputJsonSchema(properties[key])))
368832
368887
  return false;
368833
- return isStringJsonSchema(properties.name) && ["fileUrl", "vaultReference", "base64"].some((key) => isStringJsonSchema(properties[key]));
368888
+ return isStringCompatibleOutputJsonSchema(properties.name) && ["fileUrl", "vaultReference", "base64"].some((key) => isStringCompatibleOutputJsonSchema(properties[key]));
368834
368889
  }
368835
368890
  function isFileArrayJsonSchema(schema) {
368836
368891
  return isRecord3(schema) && schema.type === "array" && isFileJsonSchema(schema.items);
368837
368892
  }
368838
- function isStringJsonSchema(schema) {
368893
+ function isStringCompatibleOutputJsonSchema(schema) {
368839
368894
  const variants = jsonSchemaVariants(schema);
368840
368895
  if (variants)
368841
- return variants.every(isStringJsonSchema);
368896
+ return variants.every(isStringCompatibleOutputJsonSchema);
368842
368897
  if (!isRecord3(schema))
368843
368898
  return false;
368844
368899
  if (schema.type !== void 0 && schema.type !== "string")
@@ -368853,9 +368908,10 @@ var require_output_schema = __commonJS({
368853
368908
  return schema.type === "string" || hasStringConst || hasStringEnum;
368854
368909
  }
368855
368910
  function jsonSchemaVariants(schema) {
368856
- if (!isRecord3(schema) || !Array.isArray(schema.anyOf) || schema.anyOf.length === 0)
368911
+ if (!isRecord3(schema))
368857
368912
  return void 0;
368858
- return schema.anyOf.every(isRecord3) ? schema.anyOf : void 0;
368913
+ const variants = Array.isArray(schema.anyOf) ? schema.anyOf : Array.isArray(schema.oneOf) ? schema.oneOf : void 0;
368914
+ return variants !== void 0 && variants.length > 0 && variants.every(isRecord3) ? variants : void 0;
368859
368915
  }
368860
368916
  function isRecord3(value) {
368861
368917
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -369331,7 +369387,8 @@ var require_extract3 = __commonJS({
369331
369387
  required: declaration.required
369332
369388
  }));
369333
369389
  const nodeBindings = input.builtNodes.slice(0, input.currentNodeIndex).flatMap((node) => {
369334
- const schema = input.nodeOutputSchemasByKey.get(node.key ?? node.name);
369390
+ const nodeId = input.nodeIdsByKey.get(node.key ?? node.name);
369391
+ const schema = nodeId === void 0 ? void 0 : input.nodeOutputSchemasById.get(nodeId);
369335
369392
  return schema ? [{ name: node.name, schema, required: true }] : [];
369336
369393
  });
369337
369394
  return [...inputBindings, ...nodeBindings];
@@ -370486,6 +370543,7 @@ var require_refs = __commonJS({
370486
370543
  exports2.resolveReferenceRecordRefs = resolveReferenceRecordRefs;
370487
370544
  exports2.resolveWorkflowRef = resolveWorkflowRef;
370488
370545
  exports2.resolveExclusiveRef = resolveExclusiveRef;
370546
+ exports2.resolveVisibleNodeIdentity = resolveVisibleNodeIdentity;
370489
370547
  var workflow_shared_1 = require_cjs2();
370490
370548
  function resolvePromptRefs(context) {
370491
370549
  const diagnostics = [];
@@ -370547,6 +370605,7 @@ var require_refs = __commonJS({
370547
370605
  return {
370548
370606
  reference: resolved.reference,
370549
370607
  inputType: "inputType" in resolved ? resolved.inputType : void 0,
370608
+ nodeId: "nodeId" in resolved ? resolved.nodeId : void 0,
370550
370609
  diagnostics: []
370551
370610
  };
370552
370611
  }
@@ -370575,17 +370634,17 @@ var require_refs = __commonJS({
370575
370634
  const candidates = context.nodeIdentitiesByKey.get(ref.targetKey) ?? [];
370576
370635
  if (candidates.length === 0)
370577
370636
  return void 0;
370578
- const visible = findVisibleCandidate(ref.targetKey, context);
370637
+ const visible = resolveVisibleNodeIdentity(ref.targetKey, context);
370579
370638
  if (visible) {
370580
370639
  const reference = workflow_shared_1.ActionOutputReferenceURI.fromStepId(visible.id);
370581
- return { reference: formatPromptReference(reference, ref) };
370640
+ return { reference: formatPromptReference(reference, ref), nodeId: visible.id };
370582
370641
  }
370583
370642
  if (candidates.some((candidate) => samePath(candidate.scopePath, context.currentNode.scopePath) && candidate.sequenceIndex >= context.currentNode.sequenceIndex)) {
370584
370643
  return "forward";
370585
370644
  }
370586
370645
  return "scope";
370587
370646
  }
370588
- function findVisibleCandidate(key, context) {
370647
+ function resolveVisibleNodeIdentity(key, context) {
370589
370648
  const currentScopeCandidate = resolvePriorCandidateInScope(key, context.currentNode.scopePath, context.currentNode.sequenceIndex, context);
370590
370649
  if (currentScopeCandidate)
370591
370650
  return currentScopeCandidate;
@@ -370710,20 +370769,43 @@ var require_modules = __commonJS({
370710
370769
  output: (0, ids_1.defaultOutputPortId)(nodeId)
370711
370770
  };
370712
370771
  }
370713
- function collectRemoteInputFacts(values, refs, inputs) {
370772
+ function collectRemoteInputFacts(values, refs, context) {
370714
370773
  const refsByInputName = new Map((refs ?? []).map((ref) => [ref.key, ref]));
370715
- const inputsByKey = new Map(inputs.map((input) => [input.key ?? input.name, input]));
370774
+ const inputsByKey = new Map(context.builtInputs.map((input) => [input.key ?? input.name, input]));
370716
370775
  const types = {};
370717
370776
  for (const [name, value] of Object.entries(values)) {
370718
370777
  const ref = refsByInputName.get(name);
370778
+ const formattedType = ref === void 0 ? void 0 : formattedRemoteInputType(ref.format);
370719
370779
  const input = ref?.targetKind === "input" ? inputsByKey.get(ref.targetKey) : void 0;
370720
- if (input !== void 0)
370780
+ if (formattedType !== void 0) {
370781
+ types[name] = formattedType;
370782
+ } else if (input !== void 0) {
370721
370783
  types[name] = input.inputType;
370722
- else if (ref === void 0 && typeof value === "string")
370784
+ } else if (ref?.targetKind === "node") {
370785
+ const resolved = (0, refs_1.resolveWorkflowRef)(ref, context);
370786
+ const selectedSchema = (0, output_schema_1.selectOutputJsonSchema)(resolved.nodeId === void 0 ? void 0 : context.nodeOutputSchemasById.get(resolved.nodeId), ref.path ?? []);
370787
+ const type2 = inferredRemoteInputType(selectedSchema, ref.format);
370788
+ if (type2 !== void 0)
370789
+ types[name] = type2;
370790
+ } else if (ref === void 0 && typeof value === "string") {
370723
370791
  types[name] = value.startsWith("vault://") ? "file" : "text";
370792
+ }
370724
370793
  }
370725
370794
  return { names: Object.keys(values), types };
370726
370795
  }
370796
+ function inferredRemoteInputType(schema, format) {
370797
+ const formattedType = formattedRemoteInputType(format);
370798
+ if (formattedType !== void 0)
370799
+ return formattedType;
370800
+ if ((0, output_schema_1.isFileCompatibleOutputJsonSchema)(schema))
370801
+ return "file";
370802
+ return (0, output_schema_1.isStringCompatibleOutputJsonSchema)(schema) ? "text" : void 0;
370803
+ }
370804
+ function formattedRemoteInputType(format) {
370805
+ if (format === "ai-xml" || format === "string")
370806
+ return "text";
370807
+ return void 0;
370808
+ }
370727
370809
  function hasValidPromptInput(node) {
370728
370810
  const input = "input" in node ? node.input : void 0;
370729
370811
  if (!input || typeof input !== "object")
@@ -370771,7 +370853,7 @@ var require_modules = __commonJS({
370771
370853
  if (!value || typeof value !== "object")
370772
370854
  return false;
370773
370855
  const candidate = value;
370774
- return typeof candidate.token === "string" && (candidate.targetKind === "input" || candidate.targetKind === "node") && typeof candidate.targetKey === "string" && (candidate.path === void 0 || Array.isArray(candidate.path));
370856
+ return typeof candidate.token === "string" && (candidate.targetKind === "input" || candidate.targetKind === "node") && typeof candidate.targetKey === "string" && (candidate.path === void 0 || Array.isArray(candidate.path) && candidate.path.every((segment) => typeof segment === "string")) && (candidate.format === void 0 || candidate.format === "ai-xml" || candidate.format === "raw" || candidate.format === "string");
370775
370857
  }
370776
370858
  function hasValidMapInput(node) {
370777
370859
  const input = "input" in node ? node.input : void 0;
@@ -370893,8 +370975,9 @@ var require_modules = __commonJS({
370893
370975
  currentNodeIndex: context.nodeIndex,
370894
370976
  inputNamesByKey: context.inputNamesByKey,
370895
370977
  nodeNamesByKey: context.nodeNamesByKey,
370978
+ nodeIdsByKey: context.nodeIdsByKey,
370896
370979
  nodeIndexesByKey: context.nodeIndexesByKey,
370897
- nodeOutputSchemasByKey: context.nodeOutputSchemasByKey
370980
+ nodeOutputSchemasById: context.nodeOutputSchemasById
370898
370981
  });
370899
370982
  context.diagnostics.push(...extracted.diagnostics);
370900
370983
  if (extracted.diagnostics.some((item) => item.severity === "error"))
@@ -371036,6 +371119,255 @@ var require_modules = __commonJS({
371036
371119
  diagnostics.push(invalidDocumentInputDiagnostic(node, "crop", "type must be pdf"));
371037
371120
  return diagnostics;
371038
371121
  }
371122
+ var DOCX_MIME_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
371123
+ var docTemplateModule = {
371124
+ kind: "doc-template",
371125
+ actionId: workflow_shared_1.WORKFLOW_ACTION_IDS.documentTemplater,
371126
+ createFailedInput() {
371127
+ return {
371128
+ vaultUrl: "vault://00000000-0000-4000-8000-000000000000",
371129
+ placeholders: [],
371130
+ outputFilename: "compilation-failed.docx",
371131
+ mustache: false,
371132
+ createPermalink: false
371133
+ };
371134
+ },
371135
+ validate(node) {
371136
+ return validateDocTemplateInput(node);
371137
+ },
371138
+ lower(node, context) {
371139
+ if (validateDocTemplateInput(node).length > 0)
371140
+ return void 0;
371141
+ const template = lowerDocTemplateSource(node.input.template, context);
371142
+ const placeholders = lowerDocTemplatePlaceholders(node, context);
371143
+ context.diagnostics.push(...template.diagnostics, ...placeholders.diagnostics);
371144
+ if (!template.reference)
371145
+ return void 0;
371146
+ const templateFilename = node.input.templateFilename ?? template.lock?.name;
371147
+ const templateFileSize = node.input.templateFileSize ?? template.lock?.size;
371148
+ context.diagnostics.push(...validateKnownTemplateMetadata(node, template.lock));
371149
+ const linearPorts = defaultLinearPorts(context.nodeId);
371150
+ return {
371151
+ node: {
371152
+ id: context.nodeId,
371153
+ name: node.name,
371154
+ actionId: workflow_shared_1.WORKFLOW_ACTION_IDS.documentTemplater,
371155
+ ports: [
371156
+ { id: linearPorts.input, dir: "in", type: "default" },
371157
+ { id: linearPorts.output, dir: "out", type: "default" }
371158
+ ],
371159
+ input: {
371160
+ vaultUrl: template.reference,
371161
+ placeholders: Object.entries(placeholders.values).map(([key, reference]) => ({ key, reference })),
371162
+ outputFilename: node.input.outputFilename,
371163
+ mustache: node.input.mustache ?? false,
371164
+ createPermalink: node.input.createPermalink ?? false,
371165
+ ...templateFilename === void 0 ? {} : { templateFilename },
371166
+ ...templateFileSize === void 0 ? {} : { templateFileSize }
371167
+ }
371168
+ },
371169
+ linearPorts,
371170
+ outputSchema: output_schema_1.DOC_TEMPLATE_OUTPUT_JSON_SCHEMA,
371171
+ vaultRefs: [...template.vaultRefs, ...placeholders.vaultRefs],
371172
+ ...(0, reference_1.isWorkflowCodeVaultReference)(template.reference) ? { vaultRequirements: [{
371173
+ reference: template.reference,
371174
+ ...templateFilename === void 0 ? {} : { expectedName: templateFilename },
371175
+ ...templateFileSize === void 0 ? {} : { expectedSize: templateFileSize },
371176
+ requiredExtension: ".docx",
371177
+ requiredMimeType: DOCX_MIME_TYPE
371178
+ }] } : {}
371179
+ };
371180
+ }
371181
+ };
371182
+ function validateDocTemplateInput(node) {
371183
+ if (!node.input || typeof node.input !== "object")
371184
+ return [invalidDocTemplateInputDiagnostic(node, "input must be an object")];
371185
+ const diagnostics = [];
371186
+ if (!isVaultSource(node.input.template) && !isExclusiveWorkflowRef(node.input.template))
371187
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "template must be vault.ref(), vault.asset(), or a workflow reference callback"));
371188
+ if (typeof node.input.outputFilename !== "string" || node.input.outputFilename.trim().length === 0)
371189
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "outputFilename must be a non-empty string"));
371190
+ if (!isRecord3(node.input.placeholders))
371191
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "placeholders must be an object"));
371192
+ else if (Object.entries(node.input.placeholders).some(([key, value]) => key.trim().length === 0 || !isReferencePlaceholder(value) && !isVaultSource(value)))
371193
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "placeholder keys must be non-empty and values must be string literals or compatible refs"));
371194
+ if (node.input.mustache !== void 0 && typeof node.input.mustache !== "boolean")
371195
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "mustache must be a boolean"));
371196
+ if (node.input.createPermalink !== void 0 && typeof node.input.createPermalink !== "boolean")
371197
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "createPermalink must be a boolean"));
371198
+ if (node.input.templateFilename !== void 0 && (typeof node.input.templateFilename !== "string" || !hasDocxExtension(node.input.templateFilename)))
371199
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "templateFilename must name a .docx file"));
371200
+ if (node.input.templateFileSize !== void 0 && (typeof node.input.templateFileSize !== "number" || !Number.isFinite(node.input.templateFileSize) || node.input.templateFileSize < 0))
371201
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "templateFileSize must be a non-negative finite number"));
371202
+ if (isVaultAsset(node.input.template)) {
371203
+ const assetName = node.input.template.name ?? node.input.template.path;
371204
+ if (!hasDocxExtension(assetName))
371205
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, "vault.asset() template must name a .docx file"));
371206
+ if (node.input.template.mimeType !== void 0 && node.input.template.mimeType !== DOCX_MIME_TYPE)
371207
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, `vault.asset() template MIME type must be ${DOCX_MIME_TYPE}`));
371208
+ }
371209
+ return diagnostics;
371210
+ }
371211
+ function invalidDocTemplateInputDiagnostic(node, detail) {
371212
+ return {
371213
+ code: "compiler.module.invalid_input",
371214
+ severity: "error",
371215
+ message: `Node ${node.name || "<unnamed>"} has invalid docTemplate input: ${detail}`
371216
+ };
371217
+ }
371218
+ function lowerDocTemplateSource(source, context) {
371219
+ if (isExclusiveWorkflowRef(source)) {
371220
+ const compatibility = validateDocTemplateSourceTarget(source, context);
371221
+ if (compatibility.length > 0)
371222
+ return { vaultRefs: [], diagnostics: compatibility };
371223
+ const resolved = (0, refs_1.resolveExclusiveRef)(source, {
371224
+ inputIdsByKey: context.inputIdsByKey,
371225
+ nodeIdentitiesByKey: context.nodeIdentitiesByKey,
371226
+ nodesByPath: context.nodesByPath,
371227
+ currentNode: context.currentNode
371228
+ });
371229
+ return { reference: resolved.reference, vaultRefs: [], diagnostics: resolved.diagnostics };
371230
+ }
371231
+ if (isVaultRef(source)) {
371232
+ if (!(0, reference_1.isWorkflowCodeVaultReference)(source.reference))
371233
+ return { vaultRefs: [], diagnostics: [invalidVaultRefDiagnostic(source.reference)] };
371234
+ return { reference: source.reference, vaultRefs: [source.reference], diagnostics: [] };
371235
+ }
371236
+ if (!isVaultAsset(source))
371237
+ return { vaultRefs: [], diagnostics: [] };
371238
+ const lock = context.vaultAssetsByKey.get((0, asset_1.workflowCodeVaultAssetKey)(context.workflowKey, source));
371239
+ if (!lock || !(0, reference_1.isWorkflowCodeVaultReference)(lock.ref)) {
371240
+ return {
371241
+ vaultRefs: [],
371242
+ diagnostics: [{
371243
+ code: "vault.asset.missing_lock",
371244
+ severity: "error",
371245
+ message: `Vault asset ${source.path} has no uploaded lock for this workflow`,
371246
+ hint: "Run tela workflow sync so the CLI can upload and lock the local asset before compilation."
371247
+ }]
371248
+ };
371249
+ }
371250
+ return {
371251
+ reference: lock.ref,
371252
+ lock,
371253
+ vaultRefs: [lock.ref],
371254
+ diagnostics: []
371255
+ };
371256
+ }
371257
+ function validateDocTemplateSourceTarget(source, context) {
371258
+ if (source.targetKind === "input") {
371259
+ const target2 = context.builtInputs.find((input) => (input.key ?? input.name) === source.targetKey);
371260
+ if (!target2 || target2.inputType === "text")
371261
+ return [];
371262
+ return [incompatibleDocTemplateSourceDiagnostic(source.targetKey)];
371263
+ }
371264
+ const target = resolveVisibleNodeOutput(source.targetKey, context);
371265
+ if (!target)
371266
+ return [];
371267
+ const directStringLlm = target.declaration?.nodeKind === "llm" && target.declaration.schema == null && (source.path?.length ?? 0) === 0;
371268
+ const selectedSchema = (0, output_schema_1.selectOutputJsonSchema)(target.schema, source.path ?? []);
371269
+ return directStringLlm || (0, output_schema_1.isStringCompatibleOutputJsonSchema)(selectedSchema) ? [] : [incompatibleDocTemplateSourceDiagnostic(source.targetKey)];
371270
+ }
371271
+ function incompatibleDocTemplateSourceDiagnostic(targetKey) {
371272
+ return {
371273
+ code: "compiler.ref.incompatible",
371274
+ severity: "error",
371275
+ message: `Template reference ${targetKey} does not select a string-compatible value for docTemplate.input.template`
371276
+ };
371277
+ }
371278
+ function lowerDocTemplatePlaceholders(node, context) {
371279
+ const diagnostics = validateDocTemplatePlaceholderCompatibility(node, context);
371280
+ const resolved = (0, refs_1.resolveReferenceRecordRefs)({
371281
+ values: node.input.placeholders,
371282
+ refs: node.placeholderRefs ?? [],
371283
+ inputIdsByKey: context.inputIdsByKey,
371284
+ inputTypesByKey: context.inputTypesByKey,
371285
+ nodeIdentitiesByKey: context.nodeIdentitiesByKey,
371286
+ nodesByPath: context.nodesByPath,
371287
+ currentNode: context.currentNode
371288
+ });
371289
+ diagnostics.push(...resolved.diagnostics);
371290
+ const values = {};
371291
+ const vaultRefs = [];
371292
+ for (const [key, value] of Object.entries(resolved.values)) {
371293
+ if (typeof value === "string") {
371294
+ values[key] = value;
371295
+ continue;
371296
+ }
371297
+ if (isVaultRef(value)) {
371298
+ if ((0, reference_1.isWorkflowCodeVaultReference)(value.reference)) {
371299
+ values[key] = value.reference;
371300
+ vaultRefs.push(value.reference);
371301
+ } else {
371302
+ diagnostics.push(invalidVaultRefDiagnostic(value.reference));
371303
+ }
371304
+ continue;
371305
+ }
371306
+ if (isVaultAsset(value)) {
371307
+ const lock = context.vaultAssetsByKey.get((0, asset_1.workflowCodeVaultAssetKey)(context.workflowKey, value));
371308
+ if (!lock || !(0, reference_1.isWorkflowCodeVaultReference)(lock.ref)) {
371309
+ diagnostics.push({
371310
+ code: "vault.asset.missing_lock",
371311
+ severity: "error",
371312
+ message: `Vault asset ${value.path} has no uploaded lock for this workflow`,
371313
+ hint: "Run tela workflow sync so the CLI can upload and lock the local asset before compilation."
371314
+ });
371315
+ } else {
371316
+ values[key] = lock.ref;
371317
+ vaultRefs.push(lock.ref);
371318
+ }
371319
+ }
371320
+ }
371321
+ return { values: Object.freeze(values), vaultRefs, diagnostics };
371322
+ }
371323
+ function validateDocTemplatePlaceholderCompatibility(node, context) {
371324
+ const diagnostics = [];
371325
+ for (const ref of node.placeholderRefs ?? []) {
371326
+ if (ref.targetKind === "input") {
371327
+ if (context.inputTypesByKey.get(ref.targetKey) === "file")
371328
+ diagnostics.push(incompatibleDocTemplatePlaceholderDiagnostic(ref.key, ref.targetKey));
371329
+ continue;
371330
+ }
371331
+ const target = resolveVisibleNodeOutput(ref.targetKey, context);
371332
+ if (!target)
371333
+ continue;
371334
+ const directStringLlm = target.declaration?.nodeKind === "llm" && target.declaration.schema == null && (ref.path?.length ?? 0) === 0;
371335
+ const selected = (0, output_schema_1.selectOutputJsonSchema)(target.schema, ref.path ?? []);
371336
+ if (!directStringLlm && !(0, output_schema_1.isStringCompatibleOutputJsonSchema)(selected))
371337
+ diagnostics.push(incompatibleDocTemplatePlaceholderDiagnostic(ref.key, ref.targetKey));
371338
+ }
371339
+ return diagnostics;
371340
+ }
371341
+ function incompatibleDocTemplatePlaceholderDiagnostic(key, targetKey) {
371342
+ return {
371343
+ code: "compiler.ref.incompatible",
371344
+ severity: "error",
371345
+ message: `Placeholder ${key} reference ${targetKey} does not select a string-compatible value`
371346
+ };
371347
+ }
371348
+ function validateKnownTemplateMetadata(node, lock) {
371349
+ if (!lock)
371350
+ return [];
371351
+ const diagnostics = [];
371352
+ if (node.input.templateFilename !== void 0 && lock.name !== void 0 && node.input.templateFilename !== lock.name)
371353
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, `templateFilename ${node.input.templateFilename} does not match locked asset name ${lock.name}`));
371354
+ if (node.input.templateFileSize !== void 0 && lock.size !== void 0 && node.input.templateFileSize !== lock.size)
371355
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, `templateFileSize ${node.input.templateFileSize} does not match locked asset size ${lock.size}`));
371356
+ if (lock.name !== void 0 && !hasDocxExtension(lock.name))
371357
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, `locked asset name ${lock.name} is not a .docx file`));
371358
+ if (lock.mimeType !== void 0 && lock.mimeType !== DOCX_MIME_TYPE)
371359
+ diagnostics.push(invalidDocTemplateInputDiagnostic(node, `locked asset MIME type ${lock.mimeType} is not ${DOCX_MIME_TYPE}`));
371360
+ return diagnostics;
371361
+ }
371362
+ function hasDocxExtension(value) {
371363
+ return value.toLowerCase().endsWith(".docx");
371364
+ }
371365
+ function isReferencePlaceholder(value) {
371366
+ return typeof value === "string";
371367
+ }
371368
+ function isVaultSource(value) {
371369
+ return isVaultRef(value) || isVaultAsset(value);
371370
+ }
371039
371371
  function validateSplitterInput(node) {
371040
371372
  if (!node.input || typeof node.input !== "object")
371041
371373
  return [invalidSplitterInputDiagnostic(node, "input must be an object")];
@@ -371150,17 +371482,34 @@ var require_modules = __commonJS({
371150
371482
  }
371151
371483
  function validateExclusiveFileTarget(file2, context, targetField) {
371152
371484
  if (file2.targetKind === "input") {
371153
- const target = context.builtInputs.find((input) => (input.key ?? input.name) === file2.targetKey);
371154
- if (!target || target.inputType === "file")
371485
+ const target2 = context.builtInputs.find((input) => (input.key ?? input.name) === file2.targetKey);
371486
+ if (!target2 || target2.inputType === "file")
371155
371487
  return [];
371156
371488
  return [incompatibleDocumentRefDiagnostic(file2.targetKey, targetField)];
371157
371489
  }
371158
- const targetIndex = context.nodeIndexesByKey.get(file2.targetKey);
371159
- if (targetIndex === void 0 || targetIndex >= context.nodeIndex)
371490
+ const target = resolveVisibleNodeOutput(file2.targetKey, context);
371491
+ if (!target)
371492
+ return [];
371493
+ const selectedSchema = (0, output_schema_1.selectOutputJsonSchema)(target.schema, file2.path ?? []);
371494
+ if (selectedSchema === void 0 && context.remoteMode.kind === "symbolic" && context.remoteTemplateNodeIds.has(target.id))
371160
371495
  return [];
371161
- const selectedSchema = (0, output_schema_1.selectOutputJsonSchema)(context.nodeOutputSchemasByKey.get(file2.targetKey), file2.path ?? []);
371162
371496
  return (0, output_schema_1.isFileCompatibleOutputJsonSchema)(selectedSchema) ? [] : [incompatibleDocumentRefDiagnostic(file2.targetKey, targetField)];
371163
371497
  }
371498
+ function resolveVisibleNodeOutput(targetKey, context) {
371499
+ const identity2 = (0, refs_1.resolveVisibleNodeIdentity)(targetKey, {
371500
+ inputIdsByKey: context.inputIdsByKey,
371501
+ nodeIdentitiesByKey: context.nodeIdentitiesByKey,
371502
+ nodesByPath: context.nodesByPath,
371503
+ currentNode: context.currentNode
371504
+ });
371505
+ if (!identity2)
371506
+ return void 0;
371507
+ return {
371508
+ id: identity2.id,
371509
+ declaration: context.nodeDeclarationsById.get(identity2.id),
371510
+ schema: context.nodeOutputSchemasById.get(identity2.id)
371511
+ };
371512
+ }
371164
371513
  function incompatibleDocumentRefDiagnostic(targetKey, targetField) {
371165
371514
  return {
371166
371515
  code: "compiler.ref.incompatible",
@@ -371195,7 +371544,7 @@ var require_modules = __commonJS({
371195
371544
  lower(node, context) {
371196
371545
  const linearPorts = defaultLinearPorts(context.nodeId);
371197
371546
  const nodeKey = node.key ?? node.name;
371198
- const inputFacts = collectRemoteInputFacts(node.input.variables, node.variableRefs, context.builtInputs);
371547
+ const inputFacts = collectRemoteInputFacts(node.input.variables, node.variableRefs, context);
371199
371548
  context.remoteRefs.push((0, remote_refs_1.collectRemoteCall)(nodeKey, "call", node.ref, node.environment, inputFacts.names, inputFacts.types));
371200
371549
  const resolvedRef = (0, remote_refs_1.resolveRemoteBinding)({ mode: context.remoteMode, binding: node.ref, nodeKey, use: "call", environment: node.environment });
371201
371550
  context.diagnostics.push(...resolvedRef.diagnostics);
@@ -371240,7 +371589,7 @@ var require_modules = __commonJS({
371240
371589
  lower(node, context) {
371241
371590
  const linearPorts = defaultLinearPorts(context.nodeId);
371242
371591
  const nodeKey = node.key ?? node.name;
371243
- const inputFacts = collectRemoteInputFacts(node.input.inputs, node.inputRefs, context.builtInputs);
371592
+ const inputFacts = collectRemoteInputFacts(node.input.inputs, node.inputRefs, context);
371244
371593
  context.remoteRefs.push((0, remote_refs_1.collectRemoteCall)(nodeKey, "call", node.ref, void 0, inputFacts.names, inputFacts.types));
371245
371594
  const resolvedRef = (0, remote_refs_1.resolveRemoteBinding)({ mode: context.remoteMode, binding: node.ref, nodeKey, use: "call" });
371246
371595
  context.diagnostics.push(...resolvedRef.diagnostics);
@@ -371284,14 +371633,107 @@ var require_modules = __commonJS({
371284
371633
  };
371285
371634
  }
371286
371635
  };
371636
+ var remoteTemplateModule = {
371637
+ kind: "remote-template",
371638
+ actionId: workflow_shared_1.WORKFLOW_ACTION_IDS.template,
371639
+ createFailedInput() {
371640
+ return { templateId: "", variables: {} };
371641
+ },
371642
+ validate(node) {
371643
+ return hasValidRemoteTemplateInput(node) ? [] : [invalidRemoteTemplateInputDiagnostic(node)];
371644
+ },
371645
+ lower(node, context) {
371646
+ if (!hasValidRemoteTemplateInput(node))
371647
+ return void 0;
371648
+ const linearPorts = defaultLinearPorts(context.nodeId);
371649
+ const nodeKey = node.key ?? node.name;
371650
+ const inputFacts = collectRemoteInputFacts(node.input.variables, node.variableRefs, context);
371651
+ context.remoteRefs.push((0, remote_refs_1.collectRemoteCall)(nodeKey, "call", node.ref, void 0, inputFacts.names, inputFacts.types));
371652
+ const resolvedRef = (0, remote_refs_1.resolveRemoteBinding)({ mode: context.remoteMode, binding: node.ref, nodeKey, use: "call" });
371653
+ context.diagnostics.push(...resolvedRef.diagnostics);
371654
+ const resolvedVariables = (0, refs_1.resolveReferenceRecordRefs)({
371655
+ values: node.input.variables,
371656
+ refs: node.variableRefs ?? [],
371657
+ inputIdsByKey: context.inputIdsByKey,
371658
+ inputTypesByKey: context.inputTypesByKey,
371659
+ nodeIdentitiesByKey: context.nodeIdentitiesByKey,
371660
+ nodesByPath: context.nodesByPath,
371661
+ currentNode: context.currentNode
371662
+ });
371663
+ context.diagnostics.push(...resolvedVariables.diagnostics);
371664
+ return {
371665
+ node: {
371666
+ id: context.nodeId,
371667
+ name: node.name,
371668
+ actionId: workflow_shared_1.WORKFLOW_ACTION_IDS.template,
371669
+ ports: [
371670
+ { id: linearPorts.input, dir: "in", type: "default" },
371671
+ { id: linearPorts.output, dir: "out", type: "default" }
371672
+ ],
371673
+ input: {
371674
+ templateId: resolvedRef.value ?? (0, remote_refs_1.symbolicRemoteMarker)(node.ref),
371675
+ variables: resolvedVariables.values,
371676
+ ...node.input.tags === void 0 ? {} : { tags: node.input.tags }
371677
+ }
371678
+ },
371679
+ linearPorts,
371680
+ ...resolvedRef.outputSchema === void 0 ? {} : { outputSchema: resolvedRef.outputSchema }
371681
+ };
371682
+ }
371683
+ };
371684
+ function hasValidRemoteTemplateInput(node) {
371685
+ const candidate = node;
371686
+ if (!isRemoteTemplateBinding(candidate.ref) || !isRecord3(candidate.input) || !isJsonRecord(candidate.input.variables))
371687
+ return false;
371688
+ return (candidate.input.tags === void 0 || Array.isArray(candidate.input.tags) && candidate.input.tags.every((tag2) => typeof tag2 === "string")) && (candidate.variableRefs === void 0 || Array.isArray(candidate.variableRefs) && candidate.variableRefs.every(isReferenceRecordRefUse));
371689
+ }
371690
+ function isRemoteTemplateBinding(value) {
371691
+ return isRecord3(value) && value.kind === "template" && (value.path === void 0 || Array.isArray(value.path) && value.path.every((item) => typeof item === "string")) && (value.explicitId === void 0 || typeof value.explicitId === "string");
371692
+ }
371693
+ function isReferenceRecordRefUse(value) {
371694
+ return isPromptRefUse(value) && typeof value.key === "string";
371695
+ }
371696
+ function isJsonRecord(value) {
371697
+ return isRecord3(value) && isJsonValue(value, /* @__PURE__ */ new Set());
371698
+ }
371699
+ function isJsonValue(value, ancestors) {
371700
+ if (value === null || typeof value === "string" || typeof value === "boolean")
371701
+ return true;
371702
+ if (typeof value === "number")
371703
+ return Number.isFinite(value);
371704
+ if (typeof value !== "object" || ancestors.has(value))
371705
+ return false;
371706
+ if (Array.isArray(value)) {
371707
+ ancestors.add(value);
371708
+ const valid2 = value.every((item) => isJsonValue(item, ancestors));
371709
+ ancestors.delete(value);
371710
+ return valid2;
371711
+ }
371712
+ const prototype2 = Object.getPrototypeOf(value);
371713
+ if (!isRecord3(value) || prototype2 !== null && Object.getPrototypeOf(prototype2) !== null)
371714
+ return false;
371715
+ ancestors.add(value);
371716
+ const valid = Object.values(value).every((item) => isJsonValue(item, ancestors));
371717
+ ancestors.delete(value);
371718
+ return valid;
371719
+ }
371720
+ function invalidRemoteTemplateInputDiagnostic(node) {
371721
+ return {
371722
+ code: "compiler.module.invalid_input",
371723
+ severity: "error",
371724
+ message: `Node ${node.name || "<unnamed>"} has invalid Template input`
371725
+ };
371726
+ }
371287
371727
  exports2.nodeModuleRegistry = /* @__PURE__ */ new Map([
371288
371728
  [llmModule.kind, llmModule],
371289
371729
  [remoteExecutableModule.kind, remoteExecutableModule],
371290
371730
  [remoteAgentModule.kind, remoteAgentModule],
371731
+ [remoteTemplateModule.kind, remoteTemplateModule],
371291
371732
  [codeModule.kind, codeModule],
371292
371733
  [mapModule.kind, mapModule],
371293
371734
  [splitterModule.kind, splitterModule],
371294
- [cropModule.kind, cropModule]
371735
+ [cropModule.kind, cropModule],
371736
+ [docTemplateModule.kind, docTemplateModule]
371295
371737
  ]);
371296
371738
  }
371297
371739
  });
@@ -371485,10 +371927,31 @@ var require_transpile = __commonJS({
371485
371927
  return createFailedSplitterNode(workflowKey, declaration);
371486
371928
  if (declaration.node.nodeKind === "crop")
371487
371929
  return createFailedCropNode(workflowKey, declaration);
371488
- if (declaration.node.nodeKind === "remote-executable" || declaration.node.nodeKind === "remote-agent")
371930
+ if (declaration.node.nodeKind === "doc-template")
371931
+ return createFailedDocTemplateNode(workflowKey, declaration);
371932
+ if (declaration.node.nodeKind === "remote-executable" || declaration.node.nodeKind === "remote-agent" || declaration.node.nodeKind === "remote-template")
371489
371933
  return createFailedRemoteNode(workflowKey, declaration);
371490
371934
  return createFailedPromptNode(workflowKey, declaration);
371491
371935
  }
371936
+ function createFailedDocTemplateNode(workflowKey, declaration) {
371937
+ const nodeId = (0, ids_1.stableNodeId)(workflowKey, declaration.node, declaration.path);
371938
+ const linearPorts = failedNodePorts(nodeId);
371939
+ const module3 = modules_1.nodeModuleRegistry.get(declaration.node.nodeKind);
371940
+ return {
371941
+ declarationIndex: declaration.ordinal,
371942
+ path: declaration.path,
371943
+ scopePath: declaration.scopePath,
371944
+ sequenceIndex: declaration.sequenceIndex,
371945
+ linearPorts,
371946
+ node: {
371947
+ id: nodeId,
371948
+ name: declaration.node.name,
371949
+ actionId: module3?.actionId ?? workflow_shared_1.WORKFLOW_ACTION_IDS.documentTemplater,
371950
+ ports: workflowNodePorts(linearPorts),
371951
+ input: module3?.createFailedInput(declaration.node) ?? {}
371952
+ }
371953
+ };
371954
+ }
371492
371955
  function createFailedRemoteNode(workflowKey, declaration) {
371493
371956
  const nodeId = (0, ids_1.stableNodeId)(workflowKey, declaration.node, declaration.path);
371494
371957
  const linearPorts = failedNodePorts(nodeId);
@@ -371752,9 +372215,11 @@ var require_transpile = __commonJS({
371752
372215
  nodeIndexesByKey.set(key, ordinal);
371753
372216
  });
371754
372217
  const { nodesByPath, nodeIdentitiesByKey } = createScopedIdentities(workflowKey, flattenedNodes);
372218
+ const nodeDeclarationsById = new Map(flattenedNodes.map(({ node, path: path3 }) => [(0, ids_1.stableNodeId)(workflowKey, node, path3), node]));
371755
372219
  const inputNamesByKey = new Map(declarationInputs.map((declaration) => [declaration.key ?? declaration.name, declaration.name]));
371756
372220
  const nodeNamesByKey = new Map(topLevelNodes.map(({ node }) => [node.key ?? node.name, node.name]));
371757
- const nodeOutputSchemasByKey = /* @__PURE__ */ new Map();
372221
+ const nodeOutputSchemasById = /* @__PURE__ */ new Map();
372222
+ const remoteTemplateNodeIds = new Set(flattenedNodes.filter(({ node }) => node.nodeKind === "remote-template").map(({ node, path: path3 }) => (0, ids_1.stableNodeId)(workflowKey, node, path3)));
371758
372223
  const buildBinding = input.declaration[contracts_1.BUILD_BINDING];
371759
372224
  const inputs = declarationInputs.map((declaration, index) => ({
371760
372225
  id: (0, ids_1.stableInputId)(workflowKey, declaration, index),
@@ -371789,9 +372254,11 @@ var require_transpile = __commonJS({
371789
372254
  },
371790
372255
  nodeIdsByKey,
371791
372256
  nodeIndexesByKey,
372257
+ nodeDeclarationsById,
371792
372258
  inputNamesByKey,
371793
372259
  nodeNamesByKey,
371794
- nodeOutputSchemasByKey,
372260
+ nodeOutputSchemasById,
372261
+ remoteTemplateNodeIds,
371795
372262
  builtInputs: declarationInputs,
371796
372263
  builtNodes: declarationNodes,
371797
372264
  source: input.source,
@@ -371803,7 +372270,7 @@ var require_transpile = __commonJS({
371803
372270
  diagnostics
371804
372271
  });
371805
372272
  if (lowered?.outputSchema !== void 0)
371806
- nodeOutputSchemasByKey.set(node.key ?? node.name, lowered.outputSchema);
372273
+ nodeOutputSchemasById.set((0, ids_1.stableNodeId)(workflowKey, node, flattened.path), lowered.outputSchema);
371807
372274
  return lowered ? {
371808
372275
  ...lowered,
371809
372276
  declarationIndex: index,
@@ -371815,6 +372282,7 @@ var require_transpile = __commonJS({
371815
372282
  const loweredModuleNodes = loweredModuleNodesByDeclaration.filter(isLoweredModuleNodeWithIndex);
371816
372283
  const vaultRefs = [...new Set(loweredModuleNodes.flatMap((item) => item.vaultRefs ?? []))].sort((left, right) => left.localeCompare(right));
371817
372284
  const vaultAssets = collectVaultAssetUses(flattenedNodes, workflowKey);
372285
+ const vaultRequirements = [...new Map(loweredModuleNodes.flatMap((item) => item.vaultRequirements ?? []).map((item) => [JSON.stringify(item), item])).values()].sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
371818
372286
  const loweredByPath = createLoweredByPath(loweredModuleNodes);
371819
372287
  const nodes = loweredModuleNodes.map((item) => item.node);
371820
372288
  const edges = createTopologyEdges(rootRecords, loweredByPath);
@@ -371857,7 +372325,8 @@ var require_transpile = __commonJS({
371857
372325
  },
371858
372326
  resources: Object.freeze({
371859
372327
  vaultRefs: Object.freeze(vaultRefs),
371860
- ...vaultAssets.length === 0 ? {} : { vaultAssets: Object.freeze(vaultAssets) }
372328
+ ...vaultAssets.length === 0 ? {} : { vaultAssets: Object.freeze(vaultAssets) },
372329
+ ...vaultRequirements.length === 0 ? {} : { vaultRequirements: Object.freeze(vaultRequirements) }
371861
372330
  }),
371862
372331
  diagnostics
371863
372332
  });
@@ -371865,9 +372334,7 @@ var require_transpile = __commonJS({
371865
372334
  function collectVaultAssetUses(records, workflowKey) {
371866
372335
  const byKey = /* @__PURE__ */ new Map();
371867
372336
  for (const { node } of records) {
371868
- if (node.nodeKind !== "splitter" && node.nodeKind !== "crop")
371869
- continue;
371870
- const values = Array.isArray(node.input.file) ? node.input.file : [node.input.file];
372337
+ const values = node.nodeKind === "doc-template" ? [node.input.template, ...Object.values(node.input.placeholders)] : node.nodeKind === "splitter" || node.nodeKind === "crop" ? Array.isArray(node.input.file) ? node.input.file : [node.input.file] : [];
371871
372338
  for (const value of values) {
371872
372339
  if (!isVaultAsset(value))
371873
372340
  continue;
@@ -372642,6 +373109,7 @@ var require_evaluate_source = __commonJS({
372642
373109
  collectWorkflowCodeAliasBindings(node, node.statements, "agent", scopedBindings.promptNodeBindings, scopedBindings.promptNodeNamespaceBindings, scopedBindings.promptNodeNamespaceMemberBindings);
372643
373110
  collectWorkflowCodeAliasBindings(node, node.statements, "llm", scopedBindings.promptNodeBindings, scopedBindings.promptNodeNamespaceBindings, scopedBindings.promptNodeNamespaceMemberBindings);
372644
373111
  collectWorkflowCodeAliasBindings(node, node.statements, "map", scopedBindings.promptNodeBindings, scopedBindings.promptNodeNamespaceBindings, scopedBindings.promptNodeNamespaceMemberBindings);
373112
+ collectWorkflowCodeAliasBindings(node, node.statements, "docTemplate", scopedBindings.promptNodeBindings, scopedBindings.promptNodeNamespaceBindings, scopedBindings.promptNodeNamespaceMemberBindings);
372645
373113
  return typescript_1.default.visitEachChild(node, createVisit(scopedBindings), context);
372646
373114
  }
372647
373115
  if (isForLikeStatement(node)) {
@@ -372810,7 +373278,7 @@ var require_evaluate_source = __commonJS({
372810
373278
  return Boolean(namespaceMemberBindings.get(root)?.has(members.join(".")));
372811
373279
  }
372812
373280
  function isPromptNodeMemberName(name) {
372813
- return name === "agent" || name === "llm" || name === "map";
373281
+ return name === "agent" || name === "docTemplate" || name === "llm" || name === "map";
372814
373282
  }
372815
373283
  function isWorkflowCodeMemberExpression(expression, memberName, memberBindings, namespaceBindings, namespaceMemberBindings) {
372816
373284
  const unwrapped = unwrapExpression(expression);
@@ -373446,6 +373914,7 @@ var require_evaluate_source = __commonJS({
373446
373914
  exportedNames.build.add("build");
373447
373915
  exportedNames.code.add("code");
373448
373916
  exportedNames.promptNodes.add("agent");
373917
+ exportedNames.promptNodes.add("docTemplate");
373449
373918
  exportedNames.promptNodes.add("llm");
373450
373919
  exportedNames.promptNodes.add("map");
373451
373920
  return;
@@ -373732,6 +374201,7 @@ const __workflowCodeApi = (() => {
373732
374201
  const remote = () => freeze({
373733
374202
  canvas: () => createRemoteRef('canvas'),
373734
374203
  workflow: () => createRemoteRef('workflow'),
374204
+ template: () => createRemoteRef('template'),
373735
374205
  agent: () => createRemoteRef('agent'),
373736
374206
  models: () => createRemoteRef('model'),
373737
374207
  })
@@ -373793,6 +374263,22 @@ const __workflowCodeApi = (() => {
373793
374263
  ...(renderedInputs.refs.length > 0 ? { inputRefs: renderedInputs.refs } : {}),
373794
374264
  })
373795
374265
  }
374266
+ const templateNode = (ref, options) => {
374267
+ assertNonEmptyString(options.name, 'template.name', options.__workflowCodeSource)
374268
+ const renderedVariables = renderReferenceRecord(options.input.variables, options.__workflowCodeSource)
374269
+ return freeze({
374270
+ kind: 'node',
374271
+ nodeKind: 'remote-template',
374272
+ name: options.name,
374273
+ ...(options.key !== undefined ? { key: options.key } : {}),
374274
+ ref: serializeRemoteRef(ref, 'template'),
374275
+ input: freeze({
374276
+ variables: renderedVariables.values,
374277
+ ...(options.input.tags !== undefined ? { tags: freeze([...options.input.tags]) } : {}),
374278
+ }),
374279
+ ...(renderedVariables.refs.length > 0 ? { variableRefs: renderedVariables.refs } : {}),
374280
+ })
374281
+ }
373796
374282
  const buildBindingKey = Symbol.for('@meistrari/workflow-code/build-binding')
373797
374283
  const codeBindingKey = Symbol.for('@meistrari/workflow-code/code-binding')
373798
374284
  const buildWorkflow = (workflow, options) => {
@@ -373926,16 +374412,46 @@ const __workflowCodeApi = (() => {
373926
374412
  }),
373927
374413
  })
373928
374414
  }
374415
+ const docTemplateNode = (options) => {
374416
+ if (!options || typeof options !== 'object' || !options.input || typeof options.input !== 'object')
374417
+ throwAuthoringDiagnostic('docTemplate.input must be an object', options && typeof options === 'object' ? options.__workflowCodeSource : undefined)
374418
+ assertNonEmptyString(options.name, 'docTemplate.name', options.__workflowCodeSource)
374419
+ assertNonEmptyString(options.input.outputFilename, 'docTemplate.input.outputFilename', options.__workflowCodeSource)
374420
+ const template = typeof options.input.template === 'function'
374421
+ ? options.input.template(exclusiveRefContext(options.__workflowCodeSource))
374422
+ : options.input.template
374423
+ if (!isVaultRef(template) && !isVaultAsset(template) && !isWorkflowRef(template))
374424
+ throwAuthoringDiagnostic('docTemplate.input.template must be vault.ref(), vault.asset(), or a workflow reference callback', options.__workflowCodeSource)
374425
+ const placeholders = renderReferenceRecord(options.input.placeholders ?? {}, options.__workflowCodeSource)
374426
+ return freeze({
374427
+ kind: 'node',
374428
+ nodeKind: 'doc-template',
374429
+ name: options.name,
374430
+ ...(options.key !== undefined ? { key: options.key } : {}),
374431
+ input: freeze({
374432
+ template,
374433
+ placeholders: placeholders.values,
374434
+ outputFilename: options.input.outputFilename,
374435
+ ...(options.input.mustache === undefined ? {} : { mustache: options.input.mustache }),
374436
+ ...(options.input.createPermalink === undefined ? {} : { createPermalink: options.input.createPermalink }),
374437
+ ...(options.input.templateFilename === undefined ? {} : { templateFilename: options.input.templateFilename }),
374438
+ ...(options.input.templateFileSize === undefined ? {} : { templateFileSize: options.input.templateFileSize }),
374439
+ }),
374440
+ ...(placeholders.refs.length === 0 ? {} : { placeholderRefs: placeholders.refs }),
374441
+ })
374442
+ }
373929
374443
  return freeze({
373930
374444
  agent: (ref, options) => publishedAgent(ref, options),
373931
374445
  build: buildWorkflow,
373932
374446
  canvas: canvasNode,
373933
374447
  code: codeNode,
373934
374448
  crop: cropNode,
374449
+ docTemplate: docTemplateNode,
373935
374450
  input: freeze({ text: (options) => baseInput('text', options), file: (options) => baseInput('file', options) }),
373936
374451
  llm: (options) => promptNode('llm', options, llmInput),
373937
374452
  map: mapNode,
373938
374453
  splitter: splitterNode,
374454
+ template: templateNode,
373939
374455
  vault: freeze({
373940
374456
  asset: (path, options = {}) => freeze({
373941
374457
  kind: 'vault-asset',
@@ -374565,8 +375081,8 @@ var require_lockfile = __commonJS({
374565
375081
  if (!validateObject(value, path3, ["declarationKey", "kind", "path", "id", "environmentName", "versionId", "revision", "inputHash", "outputContractHash", "contractHash"], diagnostics))
374566
375082
  return;
374567
375083
  validateRequiredString(value, "declarationKey", `${path3}.declarationKey`, diagnostics);
374568
- if (value.kind !== "canvas" && value.kind !== "workflow" && value.kind !== "agent" && value.kind !== "model")
374569
- pushInvalid(diagnostics, `${path3}.kind`, "kind must be canvas, workflow, agent, or model");
375084
+ if (value.kind !== "canvas" && value.kind !== "workflow" && value.kind !== "template" && value.kind !== "agent" && value.kind !== "model")
375085
+ pushInvalid(diagnostics, `${path3}.kind`, "kind must be canvas, workflow, template, agent, or model");
374570
375086
  if (value.path !== void 0)
374571
375087
  validateStringArray(value.path, `${path3}.path`, diagnostics);
374572
375088
  validateRequiredString(value, "id", `${path3}.id`, diagnostics);
@@ -376065,8 +376581,8 @@ var require_vault_preflight = __commonJS({
376065
376581
  }
376066
376582
  const results = await Promise.all(references.map(async (reference) => {
376067
376583
  try {
376068
- await input.vaultApi?.validateVaultRef({ reference });
376069
- return [];
376584
+ const metadata = await input.vaultApi?.validateVaultRef({ reference });
376585
+ return validateRequirements(reference, metadata, input.compiled);
376070
376586
  } catch (error48) {
376071
376587
  if (hasDiagnostics(error48))
376072
376588
  return error48.diagnostics;
@@ -376076,6 +376592,27 @@ var require_vault_preflight = __commonJS({
376076
376592
  const diagnostics = results.flat();
376077
376593
  return diagnostics.length > 0 ? { ok: false, diagnostics } : { ok: true, value: createValidation(references) };
376078
376594
  }
376595
+ function validateRequirements(reference, metadata, compiled) {
376596
+ if (!metadata)
376597
+ return [];
376598
+ const requirements = compiled.flatMap((item) => item.resources.vaultRequirements ?? []).filter((requirement) => requirement.reference === reference);
376599
+ const diagnostics = [];
376600
+ for (const requirement of requirements) {
376601
+ if (requirement.expectedName !== void 0 && metadata.name !== void 0 && requirement.expectedName !== metadata.name) {
376602
+ diagnostics.push((0, diagnostics_1.diagnostic)("vault.template.metadata_mismatch", "error", `Vault template ${reference} is named ${metadata.name}, not the declared ${requirement.expectedName}.`, "Update templateFilename or select the matching Vault file before syncing."));
376603
+ }
376604
+ if (requirement.expectedSize !== void 0 && metadata.size !== void 0 && requirement.expectedSize !== metadata.size) {
376605
+ diagnostics.push((0, diagnostics_1.diagnostic)("vault.template.metadata_mismatch", "error", `Vault template ${reference} has size ${metadata.size}, not the declared ${requirement.expectedSize}.`, "Update templateFileSize or select the matching Vault file before syncing."));
376606
+ }
376607
+ if (requirement.requiredExtension !== void 0 && metadata.name !== void 0 && !metadata.name.toLowerCase().endsWith(requirement.requiredExtension)) {
376608
+ diagnostics.push((0, diagnostics_1.diagnostic)("vault.template.invalid_file", "error", `Vault template ${reference} is named ${metadata.name}; docTemplate() requires a ${requirement.requiredExtension} file.`, "Upload a .docx template or correct the Vault reference before syncing."));
376609
+ }
376610
+ if (requirement.requiredMimeType !== void 0 && metadata.mimeType !== void 0 && metadata.mimeType !== requirement.requiredMimeType) {
376611
+ diagnostics.push((0, diagnostics_1.diagnostic)("vault.template.invalid_file", "error", `Vault template ${reference} has MIME type ${metadata.mimeType}; docTemplate() requires ${requirement.requiredMimeType}.`, "Upload a .docx template or correct the Vault reference before syncing."));
376612
+ }
376613
+ }
376614
+ return diagnostics;
376615
+ }
376079
376616
  function collectVaultRefs(compiled) {
376080
376617
  return [...new Set(compiled.flatMap((item) => item.resources?.vaultRefs ?? []))].sort((left, right) => left.localeCompare(right));
376081
376618
  }
@@ -376386,12 +376923,21 @@ var require_remote_api2 = __commonJS({
376386
376923
  throw workflowApiError("vault.ref.inaccessible", "The active Tela environment does not configure a Vault service URL.", "Add services.vault to the active Tela environment and retry.");
376387
376924
  }
376388
376925
  try {
376389
- await vaultRequest(`/files/${encodeURIComponent((0, reference_1.vaultReferenceId)(input.reference))}`, {
376926
+ const result = await vaultRequest(`/files/${encodeURIComponent((0, reference_1.vaultReferenceId)(input.reference))}`, {
376390
376927
  failureCode: "vault.ref.inaccessible",
376391
376928
  invalidResponseCode: "vault.ref.inaccessible",
376392
376929
  failureMessage: (status2) => `Vault reference ${input.reference} is not accessible in the active Tela context (HTTP ${status2}).`,
376393
376930
  failureHint: "Check the selected workspace, context credentials, and file permissions."
376394
376931
  });
376932
+ const metadata = isRecord3(result.metadata) ? result.metadata : {};
376933
+ const name = typeof metadata.originalFileName === "string" ? metadata.originalFileName : typeof metadata.name === "string" ? metadata.name : void 0;
376934
+ const size = typeof metadata.size === "number" ? metadata.size : typeof result.size === "number" ? result.size : void 0;
376935
+ const mimeType = typeof metadata.mimeType === "string" ? metadata.mimeType : void 0;
376936
+ return {
376937
+ ...name === void 0 ? {} : { name },
376938
+ ...size === void 0 ? {} : { size },
376939
+ ...mimeType === void 0 ? {} : { mimeType }
376940
+ };
376395
376941
  } catch (error48) {
376396
376942
  if (hasDiagnostics(error48))
376397
376943
  throw error48;
@@ -376759,18 +377305,30 @@ var require_vault_assets = __commonJS({
376759
377305
  "../../packages/workflow-code/dist/cli/sync/vault-assets.js"(exports2) {
376760
377306
  "use strict";
376761
377307
  Object.defineProperty(exports2, "__esModule", { value: true });
377308
+ exports2.snapshotPreparedWorkflowVaultAssets = snapshotPreparedWorkflowVaultAssets;
377309
+ exports2.prepareWorkflowVaultAssetUploads = prepareWorkflowVaultAssetUploads;
377310
+ exports2.uploadPreparedWorkflowVaultAssets = uploadPreparedWorkflowVaultAssets;
376762
377311
  exports2.prepareWorkflowVaultAssets = prepareWorkflowVaultAssets;
376763
377312
  var node_crypto_1 = require("node:crypto");
376764
377313
  var node_fs_1 = require("node:fs");
376765
377314
  var promises_1 = require("node:fs/promises");
376766
377315
  var node_path_1 = require("node:path");
376767
377316
  var diagnostics_1 = require_diagnostics();
376768
- async function prepareWorkflowVaultAssets(input) {
377317
+ function snapshotPreparedWorkflowVaultAssets(assets) {
377318
+ return assets.map((asset) => asset.previous ?? Object.freeze({
377319
+ ...asset.asset,
377320
+ name: asset.name,
377321
+ resolvedPath: asset.resolvedPath,
377322
+ contentHash: asset.contentHash,
377323
+ size: asset.content.byteLength,
377324
+ // The compiler only needs lock-derived local metadata at this stage.
377325
+ ref: `vault://${asset.contentHash}`,
377326
+ uploadedAt: ""
377327
+ }));
377328
+ }
377329
+ async function prepareWorkflowVaultAssetUploads(input) {
376769
377330
  if (input.assets.length === 0)
376770
377331
  return { ok: true, value: [] };
376771
- if (!input.vaultApi) {
376772
- return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.upload_failed", "error", "Vault assets cannot be uploaded because the active remote client has no Vault service.", "Configure services.vault for the active Tela environment and retry before syncing.")] };
376773
- }
376774
377332
  const existingByKey = new Map((input.existing ?? []).map((asset) => [asset.key, asset]));
376775
377333
  const prepared = [];
376776
377334
  let projectRoot;
@@ -376810,33 +377368,70 @@ var require_vault_assets = __commonJS({
376810
377368
  }
376811
377369
  const contentHash = (0, node_crypto_1.createHash)("sha256").update(content).digest("hex");
376812
377370
  const previous = existingByKey.get(asset.key);
376813
- if (previous?.contentHash === contentHash) {
376814
- prepared.push(previous);
377371
+ const name = asset.name ?? (0, node_path_1.basename)(resolvedPath);
377372
+ prepared.push(Object.freeze({
377373
+ asset,
377374
+ name,
377375
+ resolvedPath,
377376
+ content,
377377
+ contentHash,
377378
+ ...previous?.contentHash === contentHash ? { previous } : {}
377379
+ }));
377380
+ }
377381
+ return { ok: true, value: prepared };
377382
+ }
377383
+ async function uploadPreparedWorkflowVaultAssets(input) {
377384
+ if (input.assets.length === 0)
377385
+ return { ok: true, value: [] };
377386
+ if (!input.vaultApi) {
377387
+ return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.upload_failed", "error", "Vault assets cannot be uploaded because the active remote client has no Vault service.", "Configure services.vault for the active Tela environment and retry before syncing.")] };
377388
+ }
377389
+ const uploaded = [];
377390
+ for (const asset of input.assets) {
377391
+ if (asset.previous) {
377392
+ uploaded.push(asset.previous);
376815
377393
  continue;
376816
377394
  }
376817
- const name = asset.name ?? (0, node_path_1.basename)(resolvedPath);
376818
377395
  try {
376819
377396
  const ref = await input.vaultApi.uploadVaultAsset({
376820
- name,
376821
- ...asset.mimeType === void 0 ? {} : { mimeType: asset.mimeType },
376822
- content
377397
+ name: asset.name,
377398
+ ...asset.asset.mimeType === void 0 ? {} : { mimeType: asset.asset.mimeType },
377399
+ content: asset.content
376823
377400
  });
376824
- prepared.push(Object.freeze({
376825
- ...asset,
376826
- name,
376827
- resolvedPath,
376828
- contentHash,
376829
- size: content.byteLength,
377401
+ uploaded.push(Object.freeze({
377402
+ ...asset.asset,
377403
+ name: asset.name,
377404
+ resolvedPath: asset.resolvedPath,
377405
+ contentHash: asset.contentHash,
377406
+ size: asset.content.byteLength,
376830
377407
  ref,
376831
377408
  uploadedAt: input.now?.() ?? (/* @__PURE__ */ new Date()).toISOString()
376832
377409
  }));
377410
+ const persisted = await input.onUploaded?.(snapshotKnownWorkflowVaultAssets(input.assets, uploaded));
377411
+ if (persisted !== void 0 && !persisted.ok)
377412
+ return persisted;
376833
377413
  } catch (error48) {
376834
377414
  if (hasDiagnostics(error48))
376835
377415
  return { ok: false, diagnostics: error48.diagnostics };
376836
- return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.upload_failed", "error", `Vault asset ${asset.path} could not be uploaded.`, "Check the active Vault service and retry sync.")] };
377416
+ return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.upload_failed", "error", `Vault asset ${asset.asset.path} could not be uploaded.`, "Check the active Vault service and retry sync.")] };
376837
377417
  }
376838
377418
  }
376839
- return { ok: true, value: prepared };
377419
+ return { ok: true, value: uploaded };
377420
+ }
377421
+ function snapshotKnownWorkflowVaultAssets(plans, uploaded) {
377422
+ return plans.flatMap((plan, index) => {
377423
+ const snapshot = uploaded[index] ?? plan.previous;
377424
+ return snapshot === void 0 ? [] : [snapshot];
377425
+ });
377426
+ }
377427
+ async function prepareWorkflowVaultAssets(input) {
377428
+ if (input.assets.length > 0 && !input.vaultApi) {
377429
+ return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.upload_failed", "error", "Vault assets cannot be uploaded because the active remote client has no Vault service.", "Configure services.vault for the active Tela environment and retry before syncing.")] };
377430
+ }
377431
+ const prepared = await prepareWorkflowVaultAssetUploads(input);
377432
+ if (!prepared.ok)
377433
+ return prepared;
377434
+ return await uploadPreparedWorkflowVaultAssets({ assets: prepared.value, vaultApi: input.vaultApi, now: input.now });
376840
377435
  }
376841
377436
  function isWithinRoot(path3, rootDir) {
376842
377437
  const relativePath = (0, node_path_1.relative)((0, node_path_1.resolve)(rootDir), path3);
@@ -376848,6 +377443,79 @@ var require_vault_assets = __commonJS({
376848
377443
  }
376849
377444
  });
376850
377445
 
377446
+ // ../../packages/workflow-code/dist/cli/sync/vault-locks.js
377447
+ var require_vault_locks = __commonJS({
377448
+ "../../packages/workflow-code/dist/cli/sync/vault-locks.js"(exports2) {
377449
+ "use strict";
377450
+ Object.defineProperty(exports2, "__esModule", { value: true });
377451
+ exports2.createWorkflowVaultAssetLockPersister = createWorkflowVaultAssetLockPersister;
377452
+ var diagnostics_1 = require_diagnostics();
377453
+ var state_1 = require_state2();
377454
+ async function createWorkflowVaultAssetLockPersister(input) {
377455
+ const lockfilePath = (0, state_1.deriveLockfilePath)(input.cwd, input.facts);
377456
+ if (!lockfilePath.ok)
377457
+ return { ok: false, diagnostics: lockfilePath.diagnostics };
377458
+ const remote = await fetchPromptSnapshot(input.remoteApi, input.facts);
377459
+ if (!remote.ok)
377460
+ return { ok: false, diagnostics: remote.diagnostics };
377461
+ let current = input.existing;
377462
+ return {
377463
+ ok: true,
377464
+ value: {
377465
+ persist: async (vaultAssets) => {
377466
+ const plan = (0, state_1.planRemoteSnapshotWrite)(lockfilePath.value, input.facts, remote.value, current, void 0, vaultAssets);
377467
+ if (!plan.ok)
377468
+ return { ok: false, diagnostics: plan.diagnostics };
377469
+ const written = await (0, state_1.writePlannedLockfile)(plan.value);
377470
+ if (!written.ok)
377471
+ return { ok: false, diagnostics: written.diagnostics };
377472
+ current = {
377473
+ path: lockfilePath.value,
377474
+ hash: written.value.hash,
377475
+ content: plan.value.content,
377476
+ lockfile: plan.value.lockfile
377477
+ };
377478
+ return { ok: true, value: current };
377479
+ }
377480
+ }
377481
+ };
377482
+ }
377483
+ async function fetchPromptSnapshot(remoteApi, facts) {
377484
+ const promptId = facts.context.promptId;
377485
+ if (promptId === void 0) {
377486
+ return {
377487
+ ok: false,
377488
+ diagnostics: [(0, diagnostics_1.diagnostic)("state.prompt_id.missing", "error", `Workflow target ${facts.targetName} has no prompt id for context ${facts.context.key}`, "Add promptId to the active workflow context binding before retrying the upload.")]
377489
+ };
377490
+ }
377491
+ try {
377492
+ const snapshot = await remoteApi.fetchPromptSnapshot({
377493
+ promptId,
377494
+ projectId: facts.context.projectId
377495
+ });
377496
+ if (snapshot.prompt.id !== promptId) {
377497
+ return {
377498
+ ok: false,
377499
+ diagnostics: [(0, diagnostics_1.diagnostic)("sync.remote.prompt_mismatch", "error", `Remote prompt ${snapshot.prompt.id} does not match configured prompt ${promptId}`, "Check the workflow target promptId binding.")]
377500
+ };
377501
+ }
377502
+ return { ok: true, value: snapshot };
377503
+ } catch (error48) {
377504
+ return {
377505
+ ok: false,
377506
+ diagnostics: diagnosticsFromError(error48)
377507
+ };
377508
+ }
377509
+ }
377510
+ function diagnosticsFromError(error48) {
377511
+ if (error48 && typeof error48 === "object" && "diagnostics" in error48 && Array.isArray(error48.diagnostics))
377512
+ return error48.diagnostics;
377513
+ const detail = error48 instanceof Error ? ` ${error48.message}` : "";
377514
+ return [(0, diagnostics_1.diagnostic)("sync.remote.request_failed", "error", `Unable to fetch the workflow state before persisting uploaded Vault assets.${detail}`, "Check the active Tela context and retry sync.")];
377515
+ }
377516
+ }
377517
+ });
377518
+
376851
377519
  // ../../packages/workflow-code/dist/cli/sync/index.js
376852
377520
  var require_sync2 = __commonJS({
376853
377521
  "../../packages/workflow-code/dist/cli/sync/index.js"(exports2) {
@@ -376874,6 +377542,7 @@ var require_sync2 = __commonJS({
376874
377542
  __exportStar(require_remote_api2(), exports2);
376875
377543
  __exportStar(require_types5(), exports2);
376876
377544
  __exportStar(require_vault_assets(), exports2);
377545
+ __exportStar(require_vault_locks(), exports2);
376877
377546
  __exportStar(require_vault_preflight(), exports2);
376878
377547
  }
376879
377548
  });
@@ -377315,7 +377984,7 @@ var require_publish2 = __commonJS({
377315
377984
  tsconfig: configResult.value.config.tsconfig,
377316
377985
  targets: resolved.targets,
377317
377986
  rootDir: context.cwd,
377318
- vaultApi: remoteApi
377987
+ remoteApi
377319
377988
  });
377320
377989
  if (!prepared.ok)
377321
377990
  return { exitCode: 1, diagnostics: [...environmentCreationDiagnostics, ...prepared.diagnostics], compiled: prepared.compiled };
@@ -377408,7 +378077,7 @@ var require_publish2 = __commonJS({
377408
378077
  return { ok: true, targets: Object.entries(workflows).map(([name, target]) => ({ name, target })) };
377409
378078
  }
377410
378079
  async function preparePublishTargets(options2) {
377411
- const prepared = [];
378080
+ const staged = [];
377412
378081
  for (const selected of options2.targets) {
377413
378082
  const source = await (0, load_source_1.loadWorkflowSource)((0, node_path_1.dirname)(options2.configPath), selected.target, options2.configEnv, options2.tsconfig);
377414
378083
  if (!source.ok)
@@ -377452,26 +378121,75 @@ var require_publish2 = __commonJS({
377452
378121
  if (!lockfileIdentity.ok)
377453
378122
  return { ok: false, diagnostics: lockfileIdentity.diagnostics, compiled: initial };
377454
378123
  }
377455
- const vaultAssets = await (0, sync_1.prepareWorkflowVaultAssets)({
378124
+ const vaultPlans = await (0, sync_1.prepareWorkflowVaultAssetUploads)({
377456
378125
  rootDir: (0, node_path_1.dirname)(options2.configPath),
377457
378126
  assets: initial.resources.vaultAssets ?? [],
377458
- existing: existing.ok ? existing.value.lockfile.vaultAssets : void 0,
377459
- vaultApi: options2.vaultApi
378127
+ existing: existing.ok ? existing.value.lockfile.vaultAssets : void 0
377460
378128
  });
377461
- if (!vaultAssets.ok)
377462
- return { ok: false, diagnostics: vaultAssets.diagnostics, compiled: initial };
377463
- const compiled = (0, compiler_1.transpileWorkflow)({
378129
+ if (!vaultPlans.ok)
378130
+ return { ok: false, diagnostics: vaultPlans.diagnostics, compiled: initial };
378131
+ const preflight = (0, compiler_1.transpileWorkflow)({
377464
378132
  targetName: selected.name,
377465
378133
  workflowKey: selected.target.workflowKey,
377466
378134
  title: selected.target.title,
377467
378135
  declaration: source.value.declaration,
377468
378136
  source: source.value.source,
378137
+ vaultAssets: (0, sync_1.snapshotPreparedWorkflowVaultAssets)(vaultPlans.value)
378138
+ });
378139
+ if (preflight.diagnostics.some((item) => item.severity === "error"))
378140
+ return { ok: false, diagnostics: [...preflight.diagnostics], compiled: preflight };
378141
+ staged.push({
378142
+ ...selected,
378143
+ source: source.value,
378144
+ preflight,
378145
+ vaultPlans: vaultPlans.value,
378146
+ ...existing.ok ? { lockfileState: existing.value } : {}
378147
+ });
378148
+ }
378149
+ const prepared = [];
378150
+ for (const stagedTarget of staged) {
378151
+ let onUploaded;
378152
+ if (stagedTarget.vaultPlans.some((asset) => asset.previous === void 0)) {
378153
+ const persister = await (0, sync_1.createWorkflowVaultAssetLockPersister)({
378154
+ cwd: options2.rootDir,
378155
+ facts: {
378156
+ targetName: stagedTarget.name,
378157
+ workflowKey: stagedTarget.preflight.workflowKey,
378158
+ context: {
378159
+ key: stagedTarget.identity.contextKey ?? "default",
378160
+ ...stagedTarget.identity.contextId === void 0 ? {} : { id: stagedTarget.identity.contextId },
378161
+ projectId: stagedTarget.identity.projectId,
378162
+ promptId: stagedTarget.identity.promptId
378163
+ }
378164
+ },
378165
+ existing: stagedTarget.lockfileState,
378166
+ remoteApi: options2.remoteApi
378167
+ });
378168
+ if (!persister.ok)
378169
+ return { ok: false, diagnostics: persister.diagnostics, compiled: stagedTarget.preflight };
378170
+ onUploaded = persister.value.persist;
378171
+ }
378172
+ const vaultAssets = await (0, sync_1.uploadPreparedWorkflowVaultAssets)({
378173
+ assets: stagedTarget.vaultPlans,
378174
+ vaultApi: options2.remoteApi,
378175
+ ...onUploaded === void 0 ? {} : { onUploaded }
378176
+ });
378177
+ if (!vaultAssets.ok)
378178
+ return { ok: false, diagnostics: vaultAssets.diagnostics, compiled: stagedTarget.preflight };
378179
+ const compiled = (0, compiler_1.transpileWorkflow)({
378180
+ targetName: stagedTarget.name,
378181
+ workflowKey: stagedTarget.target.workflowKey,
378182
+ title: stagedTarget.target.title,
378183
+ declaration: stagedTarget.source.declaration,
378184
+ source: stagedTarget.source.source,
377469
378185
  vaultAssets: vaultAssets.value
377470
378186
  });
377471
378187
  if (compiled.diagnostics.some((item) => item.severity === "error"))
377472
378188
  return { ok: false, diagnostics: [...compiled.diagnostics], compiled };
377473
378189
  prepared.push({
377474
- ...selected,
378190
+ name: stagedTarget.name,
378191
+ target: stagedTarget.target,
378192
+ identity: stagedTarget.identity,
377475
378193
  compiled,
377476
378194
  vaultAssets: vaultAssets.value
377477
378195
  });
@@ -377683,30 +378401,14 @@ var require_sync3 = __commonJS({
377683
378401
  const existing = await (0, state_1.readLockfile)(lockPath.value);
377684
378402
  if (!existing.ok && existing.diagnostics[0]?.code !== "state.lockfile.missing")
377685
378403
  return { ok: false, diagnostics: existing.diagnostics, compiled: initialSymbolic };
377686
- const vaultAssets = await (0, sync_1.prepareWorkflowVaultAssets)({
377687
- rootDir: options2.projectDir,
377688
- assets: initialSymbolic.resources.vaultAssets ?? [],
377689
- existing: existing.ok ? existing.value.lockfile.vaultAssets : void 0,
377690
- vaultApi: options2.vaultApi
377691
- });
377692
- if (!vaultAssets.ok)
377693
- return { ok: false, diagnostics: vaultAssets.diagnostics, compiled: initialSymbolic };
377694
- const symbolic = (0, compiler_1.transpileWorkflow)({
377695
- targetName: selected.name,
377696
- workflowKey: selected.target.workflowKey,
377697
- title: selected.target.title,
377698
- declaration: sourceResult.value.declaration,
377699
- source: sourceResult.value.source,
377700
- vaultAssets: vaultAssets.value
377701
- });
377702
- if (symbolic.diagnostics.some((item) => item.severity === "error"))
377703
- return { ok: false, diagnostics: [...symbolic.diagnostics], compiled: symbolic };
377704
378404
  symbolicPrepared.push({
377705
378405
  ...selected,
377706
378406
  source: sourceResult.value,
377707
- symbolic,
377708
- compiled: symbolic,
377709
- vaultAssets: vaultAssets.value,
378407
+ symbolic: initialSymbolic,
378408
+ compiled: initialSymbolic,
378409
+ vaultAssets: [],
378410
+ ...existing.ok ? { lockfile: existing.value.lockfile } : {},
378411
+ ...existing.ok ? { lockfileState: existing.value } : {},
377710
378412
  identity: {
377711
378413
  contextKey: identity2.value.contextKey,
377712
378414
  contextId: identity2.value.contextId,
@@ -377717,7 +378419,7 @@ var require_sync3 = __commonJS({
377717
378419
  }
377718
378420
  const needsCatalog = options2.catalogApi !== void 0 || symbolicPrepared.some((item) => item.symbolic.remoteRefs.length > 0);
377719
378421
  if (!needsCatalog)
377720
- return { ok: true, targets: symbolicPrepared };
378422
+ return await prepareVaultAssetsForTargets({ ...options2, remoteApi: options2.vaultApi }, symbolicPrepared);
377721
378423
  let api;
377722
378424
  try {
377723
378425
  api = options2.catalogApi ?? await (0, catalog_1.createWorkflowCatalogApi)();
@@ -377740,49 +378442,110 @@ var require_sync3 = __commonJS({
377740
378442
  }
377741
378443
  const prepared = [];
377742
378444
  for (const item of symbolicPrepared) {
377743
- const facts = factsForPrepared(item);
377744
- const lockPath = (0, state_1.deriveLockfilePath)(options2.rootDir, facts);
377745
- if (!lockPath.ok)
377746
- return { ok: false, diagnostics: lockPath.diagnostics, compiled: item.symbolic };
377747
- const existing = await (0, state_1.readLockfile)(lockPath.value);
377748
- if (!existing.ok && existing.diagnostics[0]?.code !== "state.lockfile.missing")
377749
- return { ok: false, diagnostics: existing.diagnostics, compiled: item.symbolic };
377750
- const generated = (0, catalog_1.validateAndLockRemoteRefs)({
378445
+ const initialGenerated = (0, catalog_1.validateAndLockRemoteRefs)({
377751
378446
  contextId: snapshot.context.id,
377752
378447
  workspaceId: snapshot.context.workspaceId,
377753
378448
  snapshot,
377754
378449
  refs: item.symbolic.remoteRefs,
377755
- existing: existing.ok ? existing.value.lockfile.generatedMetadata : void 0
378450
+ existing: item.lockfile?.generatedMetadata
377756
378451
  });
377757
- if (generated.diagnostics.some((diagnostic) => diagnostic.severity === "error"))
377758
- return { ok: false, diagnostics: [...generated.diagnostics], compiled: item.symbolic };
378452
+ if (initialGenerated.diagnostics.some((diagnostic) => diagnostic.severity === "error"))
378453
+ return { ok: false, diagnostics: [...initialGenerated.diagnostics], compiled: item.symbolic };
377759
378454
  const compiled = (0, compiler_1.transpileWorkflow)({
377760
378455
  targetName: item.name,
377761
378456
  workflowKey: item.target.workflowKey,
377762
378457
  title: item.target.title,
377763
378458
  declaration: item.source.declaration,
377764
378459
  source: item.source.source,
377765
- remote: { kind: "resolved", snapshot, locks: generated.locks.refs },
378460
+ remote: { kind: "resolved", snapshot, locks: initialGenerated.locks.refs },
377766
378461
  vaultAssets: item.vaultAssets
377767
378462
  });
378463
+ const generated = (0, catalog_1.validateAndLockRemoteRefs)({
378464
+ contextId: snapshot.context.id,
378465
+ workspaceId: snapshot.context.workspaceId,
378466
+ snapshot,
378467
+ refs: compiled.remoteRefs,
378468
+ existing: item.lockfile?.generatedMetadata
378469
+ });
377768
378470
  const diagnostics = [...generated.diagnostics, ...compiled.diagnostics];
377769
- if (diagnostics.some((diagnostic) => diagnostic.severity === "error"))
378471
+ if (diagnostics.some((diagnostic) => diagnostic.severity === "error" && diagnostic.code !== "vault.asset.missing_lock"))
377770
378472
  return { ok: false, diagnostics, compiled };
377771
- prepared.push({ ...item, generatedMetadata: generated.locks, compiled });
378473
+ prepared.push({
378474
+ ...item,
378475
+ generatedMetadata: generated.locks,
378476
+ remote: { kind: "resolved", snapshot, locks: generated.locks.refs },
378477
+ compiled
378478
+ });
377772
378479
  }
377773
- return { ok: true, targets: prepared };
378480
+ return await prepareVaultAssetsForTargets({ ...options2, remoteApi: options2.vaultApi }, prepared);
377774
378481
  }
377775
- function factsForPrepared(prepared) {
377776
- return {
377777
- targetName: prepared.name,
377778
- workflowKey: prepared.symbolic.workflowKey,
377779
- context: {
377780
- key: prepared.identity.contextKey ?? "default",
377781
- ...prepared.identity.contextId === void 0 ? {} : { id: prepared.identity.contextId },
377782
- projectId: prepared.identity.projectId,
377783
- promptId: prepared.identity.promptId
378482
+ async function prepareVaultAssetsForTargets(options2, targets) {
378483
+ const staged = [];
378484
+ for (const target of targets) {
378485
+ const vaultAssets = await (0, sync_1.prepareWorkflowVaultAssetUploads)({
378486
+ rootDir: options2.projectDir,
378487
+ assets: target.symbolic.resources.vaultAssets ?? [],
378488
+ existing: target.lockfile?.vaultAssets
378489
+ });
378490
+ if (!vaultAssets.ok)
378491
+ return { ok: false, diagnostics: vaultAssets.diagnostics, compiled: target.compiled };
378492
+ const preflight = (0, compiler_1.transpileWorkflow)({
378493
+ targetName: target.name,
378494
+ workflowKey: target.target.workflowKey,
378495
+ title: target.target.title,
378496
+ declaration: target.source.declaration,
378497
+ source: target.source.source,
378498
+ ...target.remote === void 0 ? {} : { remote: target.remote },
378499
+ vaultAssets: (0, sync_1.snapshotPreparedWorkflowVaultAssets)(vaultAssets.value)
378500
+ });
378501
+ if (preflight.diagnostics.some((item) => item.severity === "error"))
378502
+ return { ok: false, diagnostics: [...preflight.diagnostics], compiled: preflight };
378503
+ staged.push({ target, vaultAssets: vaultAssets.value });
378504
+ }
378505
+ const prepared = [];
378506
+ for (const item of staged) {
378507
+ let onUploaded;
378508
+ if (item.vaultAssets.some((asset) => asset.previous === void 0)) {
378509
+ const persister = await (0, sync_1.createWorkflowVaultAssetLockPersister)({
378510
+ cwd: options2.rootDir,
378511
+ facts: {
378512
+ targetName: item.target.name,
378513
+ workflowKey: item.target.symbolic.workflowKey,
378514
+ context: {
378515
+ key: item.target.identity.contextKey ?? "default",
378516
+ ...item.target.identity.contextId === void 0 ? {} : { id: item.target.identity.contextId },
378517
+ projectId: item.target.identity.projectId,
378518
+ promptId: item.target.identity.promptId
378519
+ }
378520
+ },
378521
+ existing: item.target.lockfileState,
378522
+ remoteApi: options2.remoteApi
378523
+ });
378524
+ if (!persister.ok)
378525
+ return { ok: false, diagnostics: persister.diagnostics, compiled: item.target.compiled };
378526
+ onUploaded = persister.value.persist;
377784
378527
  }
377785
- };
378528
+ const vaultAssets = await (0, sync_1.uploadPreparedWorkflowVaultAssets)({
378529
+ assets: item.vaultAssets,
378530
+ vaultApi: options2.vaultApi,
378531
+ ...onUploaded === void 0 ? {} : { onUploaded }
378532
+ });
378533
+ if (!vaultAssets.ok)
378534
+ return { ok: false, diagnostics: vaultAssets.diagnostics, compiled: item.target.compiled };
378535
+ const compiled = (0, compiler_1.transpileWorkflow)({
378536
+ targetName: item.target.name,
378537
+ workflowKey: item.target.target.workflowKey,
378538
+ title: item.target.target.title,
378539
+ declaration: item.target.source.declaration,
378540
+ source: item.target.source.source,
378541
+ ...item.target.remote === void 0 ? {} : { remote: item.target.remote },
378542
+ vaultAssets: vaultAssets.value
378543
+ });
378544
+ if (compiled.diagnostics.some((item2) => item2.severity === "error"))
378545
+ return { ok: false, diagnostics: [...compiled.diagnostics], compiled };
378546
+ prepared.push({ ...item.target, compiled, vaultAssets: vaultAssets.value });
378547
+ }
378548
+ return { ok: true, targets: prepared };
377786
378549
  }
377787
378550
  function renderSingleSyncResult(item) {
377788
378551
  return {