@meistrari/tela-cli 1.0.0 → 1.1.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
@@ -50516,6 +50516,18 @@ var require_reference = __commonJS({
50516
50516
  }
50517
50517
  });
50518
50518
 
50519
+ // ../../packages/workflow-code/dist/vault/asset.js
50520
+ var require_asset = __commonJS({
50521
+ "../../packages/workflow-code/dist/vault/asset.js"(exports2) {
50522
+ "use strict";
50523
+ Object.defineProperty(exports2, "__esModule", { value: true });
50524
+ exports2.workflowCodeVaultAssetKey = workflowCodeVaultAssetKey;
50525
+ function workflowCodeVaultAssetKey(workflowKey, asset) {
50526
+ return JSON.stringify([workflowKey, asset.path, asset.name ?? null, asset.mimeType ?? null]);
50527
+ }
50528
+ }
50529
+ });
50530
+
50519
50531
  // ../../node_modules/.pnpm/source-map@0.6.1/node_modules/source-map/lib/base64.js
50520
50532
  var require_base64 = __commonJS({
50521
50533
  "../../node_modules/.pnpm/source-map@0.6.1/node_modules/source-map/lib/base64.js"(exports2) {
@@ -264499,7 +264511,7 @@ var require_output_schema = __commonJS({
264499
264511
  "../../packages/workflow-code/dist/compiler/output-schema.js"(exports2) {
264500
264512
  "use strict";
264501
264513
  Object.defineProperty(exports2, "__esModule", { value: true });
264502
- exports2.SPLITTER_OUTPUT_JSON_SCHEMA = exports2.FILE_INPUT_JSON_SCHEMA = exports2.FILE_OUTPUT_JSON_SCHEMA = void 0;
264514
+ exports2.CROP_OUTPUT_JSON_SCHEMA = exports2.SPLITTER_OUTPUT_JSON_SCHEMA = exports2.FILE_INPUT_JSON_SCHEMA = exports2.FILE_OUTPUT_JSON_SCHEMA = void 0;
264503
264515
  exports2.createPromptOutputJsonSchema = createPromptOutputJsonSchema;
264504
264516
  exports2.selectOutputJsonSchema = selectOutputJsonSchema;
264505
264517
  exports2.isFileCompatibleOutputJsonSchema = isFileCompatibleOutputJsonSchema;
@@ -264535,6 +264547,21 @@ var require_output_schema = __commonJS({
264535
264547
  required: Object.freeze(["startPage", "endPage", "pages", "originalFile", "file", "description", "fileType"])
264536
264548
  })
264537
264549
  });
264550
+ exports2.CROP_OUTPUT_JSON_SCHEMA = Object.freeze({
264551
+ type: "array",
264552
+ items: Object.freeze({
264553
+ type: "object",
264554
+ properties: Object.freeze({
264555
+ indexes: Object.freeze({
264556
+ type: "array",
264557
+ items: Object.freeze({ anyOf: Object.freeze([{ type: "integer" }, { type: "string" }]) })
264558
+ }),
264559
+ originalFile: exports2.FILE_OUTPUT_JSON_SCHEMA,
264560
+ file: exports2.FILE_OUTPUT_JSON_SCHEMA
264561
+ }),
264562
+ required: Object.freeze(["indexes", "originalFile", "file"])
264563
+ })
264564
+ });
264538
264565
  function createPromptOutputJsonSchema(schema) {
264539
264566
  return schema === void 0 || schema === null ? void 0 : { type: "object", properties: schema };
264540
264567
  }
@@ -266379,6 +266406,7 @@ var require_modules = __commonJS({
266379
266406
  var workflow_shared_1 = require_cjs2();
266380
266407
  var remote_1 = require_remote();
266381
266408
  var reference_1 = require_reference();
266409
+ var asset_1 = require_asset();
266382
266410
  var extract_1 = require_extract3();
266383
266411
  var imports_1 = require_imports();
266384
266412
  var remote_refs_1 = require_remote_refs();
@@ -266699,7 +266727,7 @@ var require_modules = __commonJS({
266699
266727
  lower(node, context) {
266700
266728
  if (validateSplitterInput(node).length > 0)
266701
266729
  return void 0;
266702
- const loweredFile = lowerSplitterFile(node.input.file, context);
266730
+ const loweredFile = lowerDocumentFile(node.input.file, context, "splitter.input.file");
266703
266731
  context.diagnostics.push(...loweredFile.diagnostics);
266704
266732
  if (loweredFile.value === void 0)
266705
266733
  return void 0;
@@ -266728,10 +266756,62 @@ var require_modules = __commonJS({
266728
266756
  };
266729
266757
  }
266730
266758
  };
266759
+ var cropModule = {
266760
+ kind: "crop",
266761
+ actionId: workflow_shared_1.WORKFLOW_ACTION_IDS.documentCropper,
266762
+ createFailedInput() {
266763
+ return {
266764
+ file: { fileUrl: "https://workflow-code.invalid/compilation-failed" },
266765
+ indexes: [],
266766
+ type: "pdf"
266767
+ };
266768
+ },
266769
+ validate(node) {
266770
+ return validateCropInput(node);
266771
+ },
266772
+ lower(node, context) {
266773
+ if (validateCropInput(node).length > 0)
266774
+ return void 0;
266775
+ const loweredFile = lowerDocumentFile(node.input.file, context, "crop.input.file");
266776
+ context.diagnostics.push(...loweredFile.diagnostics);
266777
+ if (loweredFile.value === void 0)
266778
+ return void 0;
266779
+ const linearPorts = defaultLinearPorts(context.nodeId);
266780
+ return {
266781
+ node: {
266782
+ id: context.nodeId,
266783
+ name: node.name,
266784
+ actionId: workflow_shared_1.WORKFLOW_ACTION_IDS.documentCropper,
266785
+ ports: [
266786
+ { id: linearPorts.input, dir: "in", type: "default" },
266787
+ { id: linearPorts.output, dir: "out", type: "default" }
266788
+ ],
266789
+ input: {
266790
+ file: loweredFile.value,
266791
+ indexes: node.input.indexes,
266792
+ type: node.input.type ?? "pdf"
266793
+ }
266794
+ },
266795
+ linearPorts,
266796
+ outputSchema: output_schema_1.CROP_OUTPUT_JSON_SCHEMA,
266797
+ vaultRefs: loweredFile.vaultRefs
266798
+ };
266799
+ }
266800
+ };
266801
+ function validateCropInput(node) {
266802
+ if (!node.input || typeof node.input !== "object")
266803
+ return [invalidDocumentInputDiagnostic(node, "crop", "input must be an object")];
266804
+ const diagnostics = validateDocumentFile(node, "crop");
266805
+ if (!Array.isArray(node.input.indexes) || !node.input.indexes.every((index) => typeof index === "string" || typeof index === "number" && Number.isInteger(index)))
266806
+ diagnostics.push(invalidDocumentInputDiagnostic(node, "crop", "indexes must be an array of integers or strings"));
266807
+ if (node.input.type !== void 0 && node.input.type !== "pdf")
266808
+ diagnostics.push(invalidDocumentInputDiagnostic(node, "crop", "type must be pdf"));
266809
+ return diagnostics;
266810
+ }
266731
266811
  function validateSplitterInput(node) {
266732
266812
  if (!node.input || typeof node.input !== "object")
266733
266813
  return [invalidSplitterInputDiagnostic(node, "input must be an object")];
266734
- const diagnostics = validateSplitterFile(node);
266814
+ const diagnostics = validateDocumentFile(node, "splitter");
266735
266815
  if (node.input.chunkSize !== void 0 && (typeof node.input.chunkSize !== "number" || !Number.isFinite(node.input.chunkSize)))
266736
266816
  diagnostics.push(invalidSplitterInputDiagnostic(node, "chunkSize must be a finite number"));
266737
266817
  if (node.input.type !== void 0 && node.input.type !== "pdf" && node.input.type !== "csv")
@@ -266744,21 +266824,43 @@ var require_modules = __commonJS({
266744
266824
  diagnostics.push(invalidSplitterInputDiagnostic(node, "customPromptMode must be always or fallback"));
266745
266825
  return diagnostics;
266746
266826
  }
266747
- function validateSplitterFile(node) {
266827
+ function validateDocumentFile(node, moduleName) {
266748
266828
  const file = node.input.file;
266749
266829
  if (isExclusiveWorkflowRef(file))
266750
266830
  return [];
266751
266831
  if (isVaultRef(file))
266752
266832
  return (0, reference_1.isWorkflowCodeVaultReference)(file.reference) ? [] : [invalidVaultRefDiagnostic(file.reference)];
266753
- if (Array.isArray(file) && file.every(isVaultRef))
266754
- return file.flatMap((item) => (0, reference_1.isWorkflowCodeVaultReference)(item.reference) ? [] : [invalidVaultRefDiagnostic(item.reference)]);
266755
- return [invalidSplitterInputDiagnostic(node, "file must be an exclusive workflow reference, vault.ref(), or an array of vault.ref() values")];
266833
+ if (isVaultAsset(file))
266834
+ return validateVaultAsset(file);
266835
+ if (Array.isArray(file) && file.every((item) => isVaultRef(item) || isVaultAsset(item))) {
266836
+ return file.flatMap((item) => {
266837
+ if (isVaultRef(item))
266838
+ return (0, reference_1.isWorkflowCodeVaultReference)(item.reference) ? [] : [invalidVaultRefDiagnostic(item.reference)];
266839
+ return validateVaultAsset(item);
266840
+ });
266841
+ }
266842
+ return [invalidDocumentInputDiagnostic(node, moduleName, "file must be an exclusive workflow reference, vault.ref(), vault.asset(), or an array of Vault values")];
266843
+ }
266844
+ function validateVaultAsset(asset) {
266845
+ if (typeof asset.path !== "string" || asset.path.trim().length === 0)
266846
+ return [invalidVaultAssetDiagnostic("path must be a non-empty string")];
266847
+ if (asset.name !== void 0 && (typeof asset.name !== "string" || asset.name.trim().length === 0))
266848
+ return [invalidVaultAssetDiagnostic("name must be a non-empty string when present")];
266849
+ if (asset.mimeType !== void 0 && (typeof asset.mimeType !== "string" || asset.mimeType.trim().length === 0))
266850
+ return [invalidVaultAssetDiagnostic("mimeType must be a non-empty string when present")];
266851
+ return [];
266852
+ }
266853
+ function invalidVaultAssetDiagnostic(detail) {
266854
+ return { code: "compiler.module.invalid_input", severity: "error", message: `Vault asset is invalid: ${detail}` };
266756
266855
  }
266757
266856
  function invalidSplitterInputDiagnostic(node, detail) {
266857
+ return invalidDocumentInputDiagnostic(node, "splitter", detail);
266858
+ }
266859
+ function invalidDocumentInputDiagnostic(node, moduleName, detail) {
266758
266860
  return {
266759
266861
  code: "compiler.module.invalid_input",
266760
266862
  severity: "error",
266761
- message: `Node ${node.name || "<unnamed>"} has invalid splitter input: ${detail}`
266863
+ message: `Node ${node.name || "<unnamed>"} has invalid ${moduleName} input: ${detail}`
266762
266864
  };
266763
266865
  }
266764
266866
  function invalidVaultRefDiagnostic(reference) {
@@ -266769,7 +266871,7 @@ var require_modules = __commonJS({
266769
266871
  hint: "Use a vault:// reference containing a UUID v4 or SHA-256 file ID."
266770
266872
  };
266771
266873
  }
266772
- function lowerSplitterFile(file, context) {
266874
+ function lowerDocumentFile(file, context, targetField) {
266773
266875
  if (isVaultRef(file) && (0, reference_1.isWorkflowCodeVaultReference)(file.reference)) {
266774
266876
  return {
266775
266877
  value: vaultTransportFile(file.reference),
@@ -266777,17 +266879,21 @@ var require_modules = __commonJS({
266777
266879
  diagnostics: []
266778
266880
  };
266779
266881
  }
266882
+ if (isVaultAsset(file))
266883
+ return lowerVaultAsset(file, context);
266780
266884
  if (Array.isArray(file)) {
266781
- const refs = file.map((item) => item.reference).filter(reference_1.isWorkflowCodeVaultReference);
266885
+ const lowered = file.map((item) => isVaultRef(item) ? (0, reference_1.isWorkflowCodeVaultReference)(item.reference) ? { ref: item.reference, value: vaultTransportFile(item.reference) } : void 0 : lowerVaultAssetValue(item, context));
266886
+ if (lowered.includes(void 0))
266887
+ return { vaultRefs: lowered.flatMap((item) => item?.ref ?? []), diagnostics: [missingVaultAssetDiagnostic()] };
266782
266888
  return {
266783
- value: refs.map(vaultTransportFile),
266784
- vaultRefs: refs,
266889
+ value: lowered.map((item) => item?.value),
266890
+ vaultRefs: lowered.flatMap((item) => item?.ref ?? []),
266785
266891
  diagnostics: []
266786
266892
  };
266787
266893
  }
266788
266894
  if (!isExclusiveWorkflowRef(file))
266789
266895
  return { vaultRefs: [], diagnostics: [] };
266790
- const compatibility = validateExclusiveFileTarget(file, context);
266896
+ const compatibility = validateExclusiveFileTarget(file, context, targetField);
266791
266897
  if (compatibility.length > 0)
266792
266898
  return { vaultRefs: [], diagnostics: compatibility };
266793
266899
  const resolved = (0, refs_1.resolveExclusiveRef)(file, {
@@ -266798,24 +266904,40 @@ var require_modules = __commonJS({
266798
266904
  });
266799
266905
  return { value: resolved.reference, vaultRefs: [], diagnostics: [...resolved.diagnostics] };
266800
266906
  }
266801
- function validateExclusiveFileTarget(file, context) {
266907
+ function lowerVaultAsset(asset, context) {
266908
+ const lowered = lowerVaultAssetValue(asset, context);
266909
+ return lowered ? { value: lowered.value, vaultRefs: [lowered.ref], diagnostics: [] } : { vaultRefs: [], diagnostics: [missingVaultAssetDiagnostic(asset.path)] };
266910
+ }
266911
+ function lowerVaultAssetValue(asset, context) {
266912
+ const snapshot = context.vaultAssetsByKey.get((0, asset_1.workflowCodeVaultAssetKey)(context.workflowKey, asset));
266913
+ return snapshot === void 0 || !(0, reference_1.isWorkflowCodeVaultReference)(snapshot.ref) ? void 0 : { ref: snapshot.ref, value: vaultTransportFile(snapshot.ref) };
266914
+ }
266915
+ function missingVaultAssetDiagnostic(path2) {
266916
+ return {
266917
+ code: "vault.asset.missing_lock",
266918
+ severity: "error",
266919
+ message: `Vault asset${path2 === void 0 ? "" : ` ${path2}`} has no uploaded lock for this workflow`,
266920
+ hint: "Run tela workflow sync so the CLI can upload and lock the local asset before compilation."
266921
+ };
266922
+ }
266923
+ function validateExclusiveFileTarget(file, context, targetField) {
266802
266924
  if (file.targetKind === "input") {
266803
266925
  const target = context.builtInputs.find((input) => (input.key ?? input.name) === file.targetKey);
266804
266926
  if (!target || target.inputType === "file")
266805
266927
  return [];
266806
- return [incompatibleSplitterRefDiagnostic(file.targetKey)];
266928
+ return [incompatibleDocumentRefDiagnostic(file.targetKey, targetField)];
266807
266929
  }
266808
266930
  const targetIndex = context.nodeIndexesByKey.get(file.targetKey);
266809
266931
  if (targetIndex === void 0 || targetIndex >= context.nodeIndex)
266810
266932
  return [];
266811
266933
  const selectedSchema = (0, output_schema_1.selectOutputJsonSchema)(context.nodeOutputSchemasByKey.get(file.targetKey), file.path ?? []);
266812
- return (0, output_schema_1.isFileCompatibleOutputJsonSchema)(selectedSchema) ? [] : [incompatibleSplitterRefDiagnostic(file.targetKey)];
266934
+ return (0, output_schema_1.isFileCompatibleOutputJsonSchema)(selectedSchema) ? [] : [incompatibleDocumentRefDiagnostic(file.targetKey, targetField)];
266813
266935
  }
266814
- function incompatibleSplitterRefDiagnostic(targetKey) {
266936
+ function incompatibleDocumentRefDiagnostic(targetKey, targetField) {
266815
266937
  return {
266816
266938
  code: "compiler.ref.incompatible",
266817
266939
  severity: "error",
266818
- message: `Exclusive reference ${targetKey} does not select a file or file array value for splitter.input.file`
266940
+ message: `Exclusive reference ${targetKey} does not select a file or file array value for ${targetField}`
266819
266941
  };
266820
266942
  }
266821
266943
  function vaultTransportFile(reference) {
@@ -266827,6 +266949,9 @@ var require_modules = __commonJS({
266827
266949
  function isVaultRef(value) {
266828
266950
  return isRecord2(value) && value.kind === "vault-ref";
266829
266951
  }
266952
+ function isVaultAsset(value) {
266953
+ return isRecord2(value) && value.kind === "vault-asset";
266954
+ }
266830
266955
  function isRecord2(value) {
266831
266956
  return typeof value === "object" && value !== null && !Array.isArray(value);
266832
266957
  }
@@ -266937,7 +267062,8 @@ var require_modules = __commonJS({
266937
267062
  [remoteAgentModule.kind, remoteAgentModule],
266938
267063
  [codeModule.kind, codeModule],
266939
267064
  [mapModule.kind, mapModule],
266940
- [splitterModule.kind, splitterModule]
267065
+ [splitterModule.kind, splitterModule],
267066
+ [cropModule.kind, cropModule]
266941
267067
  ]);
266942
267068
  }
266943
267069
  });
@@ -267067,6 +267193,7 @@ var require_transpile = __commonJS({
267067
267193
  var hash_1 = require_hash();
267068
267194
  var modules_1 = require_modules();
267069
267195
  var validation_1 = require_validation();
267196
+ var asset_1 = require_asset();
267070
267197
  function isInputLike(input) {
267071
267198
  return Boolean(input) && typeof input === "object";
267072
267199
  }
@@ -267128,6 +267255,8 @@ var require_transpile = __commonJS({
267128
267255
  return createFailedMapNode(workflowKey, declaration);
267129
267256
  if (declaration.node.nodeKind === "splitter")
267130
267257
  return createFailedSplitterNode(workflowKey, declaration);
267258
+ if (declaration.node.nodeKind === "crop")
267259
+ return createFailedCropNode(workflowKey, declaration);
267131
267260
  if (declaration.node.nodeKind === "remote-executable" || declaration.node.nodeKind === "remote-agent")
267132
267261
  return createFailedRemoteNode(workflowKey, declaration);
267133
267262
  return createFailedPromptNode(workflowKey, declaration);
@@ -267172,6 +267301,29 @@ var require_transpile = __commonJS({
267172
267301
  }
267173
267302
  };
267174
267303
  }
267304
+ function createFailedCropNode(workflowKey, declaration) {
267305
+ const nodeId = (0, ids_1.stableNodeId)(workflowKey, declaration.node, declaration.path);
267306
+ const linearPorts = failedNodePorts(nodeId);
267307
+ const module3 = modules_1.nodeModuleRegistry.get(declaration.node.nodeKind);
267308
+ return {
267309
+ declarationIndex: declaration.ordinal,
267310
+ path: declaration.path,
267311
+ scopePath: declaration.scopePath,
267312
+ sequenceIndex: declaration.sequenceIndex,
267313
+ linearPorts,
267314
+ node: {
267315
+ id: nodeId,
267316
+ name: declaration.node.name,
267317
+ actionId: module3?.actionId ?? workflow_shared_1.WORKFLOW_ACTION_IDS.documentCropper,
267318
+ ports: workflowNodePorts(linearPorts),
267319
+ input: module3?.createFailedInput(declaration.node) ?? {
267320
+ file: { fileUrl: "https://workflow-code.invalid/compilation-failed" },
267321
+ indexes: [],
267322
+ type: "pdf"
267323
+ }
267324
+ }
267325
+ };
267326
+ }
267175
267327
  function createFailedCodeNode(workflowKey, declaration) {
267176
267328
  const nodeId = (0, ids_1.stableNodeId)(workflowKey, declaration.node, declaration.path);
267177
267329
  const linearPorts = failedNodePorts(nodeId);
@@ -267351,6 +267503,7 @@ var require_transpile = __commonJS({
267351
267503
  });
267352
267504
  }
267353
267505
  const workflowKey = sourceWorkflowKey;
267506
+ const vaultAssetsByKey = new Map((input.vaultAssets ?? []).map((asset) => [asset.key, asset]));
267354
267507
  const declarationInputs = input.declaration.inputs.filter(isInputLike);
267355
267508
  const declarationNodes = input.declaration.nodes.filter(isNodeLike);
267356
267509
  const rootRecords = createNodeRecords(declarationNodes);
@@ -267414,6 +267567,7 @@ var require_transpile = __commonJS({
267414
267567
  builtInputs: declarationInputs,
267415
267568
  builtNodes: declarationNodes,
267416
267569
  source: input.source,
267570
+ vaultAssetsByKey,
267417
267571
  buildSource: buildBinding?.source,
267418
267572
  childNodeIdsByParentId,
267419
267573
  remoteMode,
@@ -267432,6 +267586,7 @@ var require_transpile = __commonJS({
267432
267586
  });
267433
267587
  const loweredModuleNodes = loweredModuleNodesByDeclaration.filter(isLoweredModuleNodeWithIndex);
267434
267588
  const vaultRefs = [...new Set(loweredModuleNodes.flatMap((item) => item.vaultRefs ?? []))].sort((left, right) => left.localeCompare(right));
267589
+ const vaultAssets = collectVaultAssetUses(flattenedNodes, workflowKey);
267435
267590
  const loweredByPath = createLoweredByPath(loweredModuleNodes);
267436
267591
  const nodes = loweredModuleNodes.map((item) => item.node);
267437
267592
  const edges = createTopologyEdges(rootRecords, loweredByPath);
@@ -267472,10 +267627,31 @@ var require_transpile = __commonJS({
267472
267627
  source: (0, hash_1.hashJson)(sourceHashInput),
267473
267628
  compiled: (0, hash_1.hashJson)({ intermediate, payload, remoteRefs, remoteMode: remoteMode.kind })
267474
267629
  },
267475
- resources: Object.freeze({ vaultRefs: Object.freeze(vaultRefs) }),
267630
+ resources: Object.freeze({
267631
+ vaultRefs: Object.freeze(vaultRefs),
267632
+ ...vaultAssets.length === 0 ? {} : { vaultAssets: Object.freeze(vaultAssets) }
267633
+ }),
267476
267634
  diagnostics
267477
267635
  });
267478
267636
  }
267637
+ function collectVaultAssetUses(records, workflowKey) {
267638
+ const byKey = /* @__PURE__ */ new Map();
267639
+ for (const { node } of records) {
267640
+ if (node.nodeKind !== "splitter" && node.nodeKind !== "crop")
267641
+ continue;
267642
+ const values = Array.isArray(node.input.file) ? node.input.file : [node.input.file];
267643
+ for (const value of values) {
267644
+ if (!isVaultAsset(value))
267645
+ continue;
267646
+ const key = (0, asset_1.workflowCodeVaultAssetKey)(workflowKey, value);
267647
+ byKey.set(key, Object.freeze({ ...value, key }));
267648
+ }
267649
+ }
267650
+ return [...byKey.values()].sort((left, right) => left.key.localeCompare(right.key));
267651
+ }
267652
+ function isVaultAsset(value) {
267653
+ return value !== null && typeof value === "object" && !Array.isArray(value) && value.kind === "vault-asset";
267654
+ }
267479
267655
  }
267480
267656
  });
267481
267657
 
@@ -267866,6 +268042,134 @@ var require_load_config = __commonJS({
267866
268042
  }
267867
268043
  });
267868
268044
 
268045
+ // ../../packages/workflow-code/dist/cli/config/resolve-target-identity.js
268046
+ var require_resolve_target_identity = __commonJS({
268047
+ "../../packages/workflow-code/dist/cli/config/resolve-target-identity.js"(exports2) {
268048
+ "use strict";
268049
+ Object.defineProperty(exports2, "__esModule", { value: true });
268050
+ exports2.resolveWorkflowTargetIdentity = resolveWorkflowTargetIdentity;
268051
+ exports2.resolveWorkflowTargetLockIdentity = resolveWorkflowTargetLockIdentity;
268052
+ var tela_local_config_1 = require_dist();
268053
+ var diagnostics_1 = require_diagnostics();
268054
+ var format_config_path_1 = require_format_config_path();
268055
+ async function resolveWorkflowTargetIdentity(targetName, target, options = {}) {
268056
+ const lockIdentity = await resolveWorkflowTargetLockIdentity(targetName, target, options);
268057
+ if (!lockIdentity.ok)
268058
+ return lockIdentity;
268059
+ const diagnostics = validateResolvedBinding(targetName, lockIdentity.value);
268060
+ if (diagnostics.length > 0)
268061
+ return { ok: false, diagnostics };
268062
+ return {
268063
+ ok: true,
268064
+ value: {
268065
+ ...lockIdentity.value,
268066
+ projectId: lockIdentity.value.projectId
268067
+ }
268068
+ };
268069
+ }
268070
+ async function resolveWorkflowTargetLockIdentity(targetName, target, options = {}) {
268071
+ const contexts = target.contexts;
268072
+ if (contexts && Object.keys(contexts).length > 0) {
268073
+ const contextResult = await resolveActiveContext(options);
268074
+ if (!contextResult.ok)
268075
+ return contextResult;
268076
+ const candidateKeys = contextBindingCandidateKeys(contextResult.value);
268077
+ const contextBinding = findContextBinding(contexts, candidateKeys);
268078
+ if (!contextBinding) {
268079
+ return {
268080
+ ok: false,
268081
+ diagnostics: [(0, diagnostics_1.diagnostic)("config.context_binding.missing", "error", `Workflow target ${targetName} has no binding for active Tela context ${contextResult.value.id}`, missingContextBindingHint(targetName, Object.keys(contexts), candidateKeys))]
268082
+ };
268083
+ }
268084
+ const [contextKey, binding] = contextBinding;
268085
+ const diagnostics2 = validateResolvedBinding(targetName, binding, { requireProjectId: false });
268086
+ if (diagnostics2.length > 0)
268087
+ return { ok: false, diagnostics: diagnostics2 };
268088
+ return {
268089
+ ok: true,
268090
+ value: {
268091
+ contextId: contextResult.value.id,
268092
+ contextKey,
268093
+ ...binding.projectId === void 0 ? {} : { projectId: binding.projectId },
268094
+ ...binding.promptId === void 0 ? {} : { promptId: binding.promptId },
268095
+ source: "context"
268096
+ }
268097
+ };
268098
+ }
268099
+ const diagnostics = validateResolvedBinding(targetName, target, { requireProjectId: false });
268100
+ if (diagnostics.length > 0)
268101
+ return { ok: false, diagnostics };
268102
+ return {
268103
+ ok: true,
268104
+ value: {
268105
+ ...target.projectId === void 0 ? {} : { projectId: target.projectId },
268106
+ ...target.promptId === void 0 ? {} : { promptId: target.promptId },
268107
+ source: "legacy"
268108
+ }
268109
+ };
268110
+ }
268111
+ function findContextBinding(contexts, candidateKeys) {
268112
+ for (const contextKey of candidateKeys) {
268113
+ const binding = contexts[contextKey];
268114
+ if (binding !== void 0)
268115
+ return [contextKey, binding];
268116
+ }
268117
+ return void 0;
268118
+ }
268119
+ async function resolveActiveContext(options) {
268120
+ try {
268121
+ const config = options.localConfig ?? await (0, tela_local_config_1.loadConfig)();
268122
+ return { ok: true, value: (0, tela_local_config_1.resolveContext)(config) };
268123
+ } catch (error) {
268124
+ return {
268125
+ ok: false,
268126
+ diagnostics: [(0, diagnostics_1.diagnostic)("config.context.resolve_failed", "error", "Unable to resolve active Tela Local context for Workflow Code command", resolveContextHint(error))]
268127
+ };
268128
+ }
268129
+ }
268130
+ function contextBindingCandidateKeys(context) {
268131
+ return uniqueStrings([
268132
+ context.id,
268133
+ context.context.environmentId,
268134
+ context.environment.label.toLowerCase(),
268135
+ environmentAlias(context.context.environmentId),
268136
+ context.environment.kind === "local" ? "dev" : void 0
268137
+ ]);
268138
+ }
268139
+ function environmentAlias(environmentId) {
268140
+ if (environmentId === "production")
268141
+ return "prod";
268142
+ if (environmentId === "development")
268143
+ return "dev";
268144
+ return void 0;
268145
+ }
268146
+ function validateResolvedBinding(targetName, binding, options = {}) {
268147
+ const diagnostics = [];
268148
+ if (options.requireProjectId !== false && (!binding.projectId || typeof binding.projectId !== "string")) {
268149
+ diagnostics.push((0, diagnostics_1.diagnostic)("config.workflow.project_id.missing", "error", `Workflow target ${targetName} must resolve a non-empty projectId`, `Set \`${(0, format_config_path_1.formatConfigPath)("workflows", targetName, "projectId")}\` to a non-empty Tela project id, or add \`${(0, format_config_path_1.formatConfigPath)("workflows", targetName, "contexts", "<context>", "projectId")}\` for the active Tela context. Check contexts with \`tela context list\`.`));
268150
+ }
268151
+ if (binding.promptId !== void 0 && (typeof binding.promptId !== "string" || binding.promptId.length === 0)) {
268152
+ diagnostics.push((0, diagnostics_1.diagnostic)("config.workflow.prompt_id.invalid", "error", `Workflow target ${targetName} promptId must be a non-empty string when provided`, `Set \`${(0, format_config_path_1.formatConfigPath)("workflows", targetName, "promptId")}\` to a non-empty Tela prompt id from the Tela UI, or remove it if no existing prompt should be bound.`));
268153
+ }
268154
+ return diagnostics;
268155
+ }
268156
+ function missingContextBindingHint(targetName, configuredKeys, triedKeys) {
268157
+ const preferredKey = triedKeys[0] ?? "<context>";
268158
+ return [
268159
+ `Add one of the tried keys under \`${(0, format_config_path_1.formatConfigPath)("workflows", targetName, "contexts")}\`, for example \`${(0, format_config_path_1.formatObjectKey)(preferredKey)}: { projectId: 'proj_...' }\`, or switch context with \`tela context use <context-id>\`.`,
268160
+ `Configured bindings: ${configuredKeys.join(", ") || "(none)"}. Tried: ${triedKeys.join(", ") || "(none)"}.`
268161
+ ].join(" ");
268162
+ }
268163
+ function resolveContextHint(error) {
268164
+ const detail = error instanceof Error && error.message.trim() ? ` Detail: ${error.message}` : "";
268165
+ return `Run \`tela context list\` to see configured contexts, then choose one with \`tela context use <context-id>\`. If no contexts exist, add one in Tela Dock/local setup before running workflow commands.${detail}`;
268166
+ }
268167
+ function uniqueStrings(values) {
268168
+ return Array.from(new Set(values.filter((value) => Boolean(value))));
268169
+ }
268170
+ }
268171
+ });
268172
+
267869
268173
  // ../../packages/workflow-code/dist/cli/source/evaluate-source.js
267870
268174
  var require_evaluate_source = __commonJS({
267871
268175
  "../../packages/workflow-code/dist/cli/source/evaluate-source.js"(exports2) {
@@ -269122,14 +269426,15 @@ const __workflowCodeApi = (() => {
269122
269426
  paths(target) { return createPathProxy([], target.kind, target.key ?? target.name) },
269123
269427
  })
269124
269428
  const isVaultRef = (value) => value && typeof value === 'object' && !Array.isArray(value) && value.kind === 'vault-ref'
269429
+ const isVaultAsset = (value) => value && typeof value === 'object' && !Array.isArray(value) && value.kind === 'vault-asset'
269125
269430
  const isWorkflowRef = (value) => value && typeof value === 'object' && !Array.isArray(value) && value.kind === 'workflow-ref'
269126
- const renderExclusiveFileSource = (input, source) => {
269431
+ const renderExclusiveFileSource = (input, field, source) => {
269127
269432
  const value = typeof input === 'function' ? input(exclusiveRefContext(source)) : input
269128
- if (isVaultRef(value) || isWorkflowRef(value))
269433
+ if (isVaultRef(value) || isVaultAsset(value) || isWorkflowRef(value))
269129
269434
  return value
269130
- if (Array.isArray(value) && value.every(isVaultRef))
269435
+ if (Array.isArray(value) && value.every(item => isVaultRef(item) || isVaultAsset(item)))
269131
269436
  return freeze([...value])
269132
- throwAuthoringDiagnostic('splitter.input.file must be a workflow file reference, vault.ref(), or an array of vault.ref() values', source)
269437
+ throwAuthoringDiagnostic(\`\${field} must be a workflow file reference, vault.ref(), or an array of vault.ref() values\`, source)
269133
269438
  }
269134
269439
  const renderReferenceRecord = (input, source) => {
269135
269440
  if (typeof input !== 'function')
@@ -269358,7 +269663,7 @@ const __workflowCodeApi = (() => {
269358
269663
  if (!options || typeof options !== 'object' || !options.input || typeof options.input !== 'object')
269359
269664
  throwAuthoringDiagnostic('splitter.input must be an object', options && typeof options === 'object' ? options.__workflowCodeSource : undefined)
269360
269665
  assertNonEmptyString(options.name, 'splitter.name', options.__workflowCodeSource)
269361
- const file = renderExclusiveFileSource(options.input.file, options.__workflowCodeSource)
269666
+ const file = renderExclusiveFileSource(options.input.file, 'splitter.input.file', options.__workflowCodeSource)
269362
269667
  return freeze({
269363
269668
  kind: 'node',
269364
269669
  nodeKind: 'splitter',
@@ -269374,16 +269679,42 @@ const __workflowCodeApi = (() => {
269374
269679
  }),
269375
269680
  })
269376
269681
  }
269682
+ const cropNode = (options) => {
269683
+ if (!options || typeof options !== 'object' || !options.input || typeof options.input !== 'object')
269684
+ throwAuthoringDiagnostic('crop.input must be an object', options && typeof options === 'object' ? options.__workflowCodeSource : undefined)
269685
+ assertNonEmptyString(options.name, 'crop.name', options.__workflowCodeSource)
269686
+ const file = renderExclusiveFileSource(options.input.file, 'crop.input.file', options.__workflowCodeSource)
269687
+ if (!Array.isArray(options.input.indexes))
269688
+ throwAuthoringDiagnostic('crop.input.indexes must be an array', options.__workflowCodeSource)
269689
+ return freeze({
269690
+ kind: 'node',
269691
+ nodeKind: 'crop',
269692
+ name: options.name,
269693
+ ...(options.key !== undefined ? { key: options.key } : {}),
269694
+ input: freeze({
269695
+ file,
269696
+ indexes: freeze([...options.input.indexes]),
269697
+ ...(options.input.type !== undefined ? { type: options.input.type } : {}),
269698
+ }),
269699
+ })
269700
+ }
269377
269701
  return freeze({
269378
269702
  agent: (ref, options) => publishedAgent(ref, options),
269379
269703
  build: buildWorkflow,
269380
269704
  canvas: canvasNode,
269381
269705
  code: codeNode,
269706
+ crop: cropNode,
269382
269707
  input: freeze({ text: (options) => baseInput('text', options), file: (options) => baseInput('file', options) }),
269383
269708
  llm: (options) => promptNode('llm', options, llmInput),
269384
269709
  map: mapNode,
269385
269710
  splitter: splitterNode,
269386
269711
  vault: freeze({
269712
+ asset: (path, options = {}) => freeze({
269713
+ kind: 'vault-asset',
269714
+ path,
269715
+ ...(options.name === undefined ? {} : { name: options.name }),
269716
+ ...(options.mimeType === undefined ? {} : { mimeType: options.mimeType }),
269717
+ }),
269387
269718
  ref: (reference) => freeze({ kind: 'vault-ref', reference }),
269388
269719
  }),
269389
269720
  remote,
@@ -269854,6 +270185,745 @@ var require_load_source = __commonJS({
269854
270185
  }
269855
270186
  });
269856
270187
 
270188
+ // ../../packages/workflow-code/dist/cli/state/lockfile.js
270189
+ var require_lockfile = __commonJS({
270190
+ "../../packages/workflow-code/dist/cli/state/lockfile.js"(exports2) {
270191
+ "use strict";
270192
+ Object.defineProperty(exports2, "__esModule", { value: true });
270193
+ exports2.deriveLockfilePath = deriveLockfilePath;
270194
+ exports2.readLockfile = readLockfile;
270195
+ exports2.validateWorkflowLockfile = validateWorkflowLockfile;
270196
+ exports2.serializeLockfile = serializeLockfile;
270197
+ exports2.planLockfileWrite = planLockfileWrite;
270198
+ var promises_1 = require("node:fs/promises");
270199
+ var node_path_1 = require("node:path");
270200
+ var diagnostics_1 = require_diagnostics();
270201
+ var reference_1 = require_reference();
270202
+ var hash_1 = require_hash();
270203
+ var path_segments_1 = require_path_segments();
270204
+ var LOCKFILE_VERSION = 1;
270205
+ var VALID_VERSION_STATUSES = /* @__PURE__ */ new Set(["draft", "consolidated", "published"]);
270206
+ function deriveLockfilePath(rootDir, facts) {
270207
+ const workflowDiagnostic = validatePathSegment("workflowKey", facts.workflowKey);
270208
+ const contextDiagnostic = validatePathSegment("contextKey", facts.context.key);
270209
+ const diagnostics = [workflowDiagnostic, contextDiagnostic].filter((item) => item !== void 0);
270210
+ if (diagnostics.length > 0)
270211
+ return { ok: false, diagnostics };
270212
+ return {
270213
+ ok: true,
270214
+ value: (0, node_path_1.join)(rootDir, ".tela", "workflows", facts.workflowKey, "contexts", facts.context.key, "lock.json")
270215
+ };
270216
+ }
270217
+ async function readLockfile(path2) {
270218
+ let content;
270219
+ try {
270220
+ content = await (0, promises_1.readFile)(path2, "utf8");
270221
+ } catch (error) {
270222
+ if (isNodeError(error) && error.code === "ENOENT") {
270223
+ return {
270224
+ ok: false,
270225
+ diagnostics: [(0, diagnostics_1.diagnostic)("state.lockfile.missing", "error", `Workflow state lockfile does not exist at ${path2}`, "Run a remote workflow command that can fetch and persist remote state for the active context.")]
270226
+ };
270227
+ }
270228
+ throw error;
270229
+ }
270230
+ let parsed;
270231
+ try {
270232
+ parsed = JSON.parse(content);
270233
+ } catch (error) {
270234
+ const detail = error instanceof Error ? ` ${error.message}` : "";
270235
+ return {
270236
+ ok: false,
270237
+ diagnostics: [(0, diagnostics_1.diagnostic)("state.lockfile.invalid", "error", `Workflow state lockfile at ${path2} is not valid JSON.${detail}`, "Regenerate the active-context workflow state lockfile from fresh remote state.")]
270238
+ };
270239
+ }
270240
+ const validation = validateWorkflowLockfile(parsed, path2);
270241
+ if (!validation.ok)
270242
+ return validation;
270243
+ return {
270244
+ ok: true,
270245
+ value: {
270246
+ path: path2,
270247
+ hash: (0, hash_1.hashString)(content),
270248
+ content,
270249
+ lockfile: validation.value
270250
+ }
270251
+ };
270252
+ }
270253
+ function validateWorkflowLockfile(value, path2 = "<lockfile>") {
270254
+ const diagnostics = validateLockfileShape(value, path2);
270255
+ if (diagnostics.length > 0)
270256
+ return { ok: false, diagnostics };
270257
+ return { ok: true, value };
270258
+ }
270259
+ function serializeLockfile(lockfile) {
270260
+ return `${JSON.stringify(orderLockfile(lockfile), null, 2)}
270261
+ `;
270262
+ }
270263
+ function planLockfileWrite(path2, lockfile, existing) {
270264
+ return {
270265
+ path: path2,
270266
+ ...existing === void 0 ? {} : { expectedPreviousHash: existing.hash },
270267
+ lockfile,
270268
+ content: serializeLockfile(lockfile)
270269
+ };
270270
+ }
270271
+ function validatePathSegment(name, value) {
270272
+ if ((0, path_segments_1.isSafeStatePathSegment)(value))
270273
+ return void 0;
270274
+ return (0, diagnostics_1.diagnostic)("state.lockfile.invalid", "error", `Workflow state lockfile ${name} is not a safe filesystem path segment`, "Workflow and context keys must be one filesystem segment using only letters, numbers, `_`, or `-`.");
270275
+ }
270276
+ function validateLockfileShape(value, path2) {
270277
+ const diagnostics = [];
270278
+ validateLockfile(value, path2, diagnostics);
270279
+ return diagnostics;
270280
+ }
270281
+ function validateLockfile(value, path2, diagnostics) {
270282
+ if (!validateObject(value, path2, ["version", "targetName", "workflowKey", "context", "remote", "generatedMetadata", "vaultAssets", "pendingSync", "lastSynced"], diagnostics))
270283
+ return;
270284
+ if (value.version !== LOCKFILE_VERSION)
270285
+ pushInvalid(diagnostics, path2, "version must be 1");
270286
+ validateRequiredString(value, "targetName", `${path2}.targetName`, diagnostics);
270287
+ validateRequiredString(value, "workflowKey", `${path2}.workflowKey`, diagnostics);
270288
+ validateContext(value.context, `${path2}.context`, diagnostics);
270289
+ validateRemote(value.remote, `${path2}.remote`, diagnostics);
270290
+ if (value.generatedMetadata !== void 0)
270291
+ validateGeneratedMetadata(value.generatedMetadata, `${path2}.generatedMetadata`, diagnostics);
270292
+ if (value.vaultAssets !== void 0)
270293
+ validateVaultAssets(value.vaultAssets, `${path2}.vaultAssets`, diagnostics);
270294
+ if (value.pendingSync !== void 0)
270295
+ validatePendingSync(value.pendingSync, `${path2}.pendingSync`, diagnostics);
270296
+ if (value.lastSynced !== void 0)
270297
+ validateLastSynced(value.lastSynced, `${path2}.lastSynced`, diagnostics);
270298
+ }
270299
+ function validateVaultAssets(value, path2, diagnostics) {
270300
+ if (!Array.isArray(value)) {
270301
+ pushInvalid(diagnostics, path2, "must be an array");
270302
+ return;
270303
+ }
270304
+ value.forEach((asset, index) => {
270305
+ const assetPath = `${path2}[${index}]`;
270306
+ if (!validateObject(asset, assetPath, ["kind", "key", "path", "resolvedPath", "contentHash", "size", "name", "mimeType", "ref", "uploadedAt"], diagnostics))
270307
+ return;
270308
+ if (asset.kind !== "vault-asset")
270309
+ pushInvalid(diagnostics, `${assetPath}.kind`, "must be vault-asset");
270310
+ validateRequiredString(asset, "key", `${assetPath}.key`, diagnostics);
270311
+ validateRequiredString(asset, "path", `${assetPath}.path`, diagnostics);
270312
+ validateOptionalString(asset, "resolvedPath", `${assetPath}.resolvedPath`, diagnostics);
270313
+ validateOptionalString(asset, "contentHash", `${assetPath}.contentHash`, diagnostics);
270314
+ validateOptionalNumber(asset, "size", `${assetPath}.size`, diagnostics);
270315
+ validateOptionalString(asset, "name", `${assetPath}.name`, diagnostics);
270316
+ validateOptionalString(asset, "mimeType", `${assetPath}.mimeType`, diagnostics);
270317
+ if (!(0, reference_1.isWorkflowCodeVaultReference)(asset.ref))
270318
+ pushInvalid(diagnostics, `${assetPath}.ref`, "must be a vault:// UUID v4 or SHA-256 reference");
270319
+ validateRequiredString(asset, "uploadedAt", `${assetPath}.uploadedAt`, diagnostics);
270320
+ });
270321
+ }
270322
+ function validateGeneratedMetadata(value, path2, diagnostics) {
270323
+ if (!validateObject(value, path2, ["version", "contextId", "workspaceId", "catalogHash", "refs"], diagnostics))
270324
+ return;
270325
+ if (value.version !== LOCKFILE_VERSION)
270326
+ pushInvalid(diagnostics, `${path2}.version`, "version must be 1");
270327
+ validateRequiredString(value, "contextId", `${path2}.contextId`, diagnostics);
270328
+ validateRequiredString(value, "workspaceId", `${path2}.workspaceId`, diagnostics);
270329
+ validateRequiredString(value, "catalogHash", `${path2}.catalogHash`, diagnostics);
270330
+ if (!Array.isArray(value.refs)) {
270331
+ pushInvalid(diagnostics, `${path2}.refs`, "must be an array");
270332
+ return;
270333
+ }
270334
+ value.refs.forEach((ref, index) => validateLockedRemoteRef(ref, `${path2}.refs[${index}]`, diagnostics));
270335
+ }
270336
+ function validateLockedRemoteRef(value, path2, diagnostics) {
270337
+ if (!validateObject(value, path2, ["declarationKey", "kind", "path", "id", "environmentName", "versionId", "revision", "inputHash", "outputContractHash", "contractHash"], diagnostics))
270338
+ return;
270339
+ validateRequiredString(value, "declarationKey", `${path2}.declarationKey`, diagnostics);
270340
+ if (value.kind !== "canvas" && value.kind !== "workflow" && value.kind !== "agent" && value.kind !== "model")
270341
+ pushInvalid(diagnostics, `${path2}.kind`, "kind must be canvas, workflow, agent, or model");
270342
+ if (value.path !== void 0)
270343
+ validateStringArray(value.path, `${path2}.path`, diagnostics);
270344
+ validateRequiredString(value, "id", `${path2}.id`, diagnostics);
270345
+ validateOptionalString(value, "environmentName", `${path2}.environmentName`, diagnostics);
270346
+ validateOptionalString(value, "versionId", `${path2}.versionId`, diagnostics);
270347
+ validateOptionalString(value, "revision", `${path2}.revision`, diagnostics);
270348
+ validateOptionalString(value, "inputHash", `${path2}.inputHash`, diagnostics);
270349
+ validateOptionalString(value, "outputContractHash", `${path2}.outputContractHash`, diagnostics);
270350
+ validateRequiredString(value, "contractHash", `${path2}.contractHash`, diagnostics);
270351
+ }
270352
+ function validateContext(value, path2, diagnostics) {
270353
+ if (!validateObject(value, path2, ["key", "id", "projectId", "promptId"], diagnostics))
270354
+ return;
270355
+ validateRequiredString(value, "key", `${path2}.key`, diagnostics);
270356
+ validateOptionalString(value, "id", `${path2}.id`, diagnostics);
270357
+ validateRequiredString(value, "projectId", `${path2}.projectId`, diagnostics);
270358
+ validateRequiredString(value, "promptId", `${path2}.promptId`, diagnostics);
270359
+ }
270360
+ function validateRemote(value, path2, diagnostics) {
270361
+ if (!validateObject(value, path2, ["fetchedAt", "contentHash", "prompt", "version", "codegen"], diagnostics))
270362
+ return;
270363
+ validateRequiredString(value, "fetchedAt", `${path2}.fetchedAt`, diagnostics);
270364
+ validateRequiredString(value, "contentHash", `${path2}.contentHash`, diagnostics);
270365
+ validatePrompt(value.prompt, `${path2}.prompt`, diagnostics);
270366
+ validateRemoteVersion(value.version, `${path2}.version`, diagnostics);
270367
+ if (value.codegen !== void 0)
270368
+ validateCodegen(value.codegen, `${path2}.codegen`, diagnostics);
270369
+ }
270370
+ function validatePrompt(value, path2, diagnostics) {
270371
+ if (!validateObject(value, path2, ["id", "title", "currentVersionId", "currentVersionIndex", "publishedVersionId", "publishedVersionIndex"], diagnostics))
270372
+ return;
270373
+ validateRequiredString(value, "id", `${path2}.id`, diagnostics);
270374
+ validateOptionalString(value, "title", `${path2}.title`, diagnostics);
270375
+ validateRequiredString(value, "currentVersionId", `${path2}.currentVersionId`, diagnostics);
270376
+ validateRequiredNumber(value, "currentVersionIndex", `${path2}.currentVersionIndex`, diagnostics);
270377
+ validateOptionalString(value, "publishedVersionId", `${path2}.publishedVersionId`, diagnostics);
270378
+ validateOptionalNumber(value, "publishedVersionIndex", `${path2}.publishedVersionIndex`, diagnostics);
270379
+ }
270380
+ function validateRemoteVersion(value, path2, diagnostics) {
270381
+ if (!validateObject(value, path2, ["id", "versionIndex", "status", "contentHash", "compiledHash", "publishedEnvironmentNames"], diagnostics))
270382
+ return;
270383
+ validateRequiredString(value, "id", `${path2}.id`, diagnostics);
270384
+ validateRequiredNumber(value, "versionIndex", `${path2}.versionIndex`, diagnostics);
270385
+ if (typeof value.status !== "string" || !VALID_VERSION_STATUSES.has(value.status))
270386
+ pushInvalid(diagnostics, `${path2}.status`, "status must be draft, consolidated, or published");
270387
+ validateRequiredString(value, "contentHash", `${path2}.contentHash`, diagnostics);
270388
+ validateOptionalString(value, "compiledHash", `${path2}.compiledHash`, diagnostics);
270389
+ validateOptionalStringArray(value, "publishedEnvironmentNames", `${path2}.publishedEnvironmentNames`, diagnostics);
270390
+ }
270391
+ function validateCodegen(value, path2, diagnostics) {
270392
+ if (!validateObject(value, path2, ["templateVariables", "canvasVariables", "modelIds", "toolIds", "outputSchemasHash"], diagnostics))
270393
+ return;
270394
+ validateOptionalStringArray(value, "templateVariables", `${path2}.templateVariables`, diagnostics);
270395
+ validateOptionalStringArray(value, "canvasVariables", `${path2}.canvasVariables`, diagnostics);
270396
+ validateOptionalStringArray(value, "modelIds", `${path2}.modelIds`, diagnostics);
270397
+ validateOptionalStringArray(value, "toolIds", `${path2}.toolIds`, diagnostics);
270398
+ validateOptionalString(value, "outputSchemasHash", `${path2}.outputSchemasHash`, diagnostics);
270399
+ }
270400
+ function validateLifecycleMetadata(value, path2, diagnostics) {
270401
+ if (!validateObject(value, path2, ["operation", "targetVersionId", "idempotencyKey", "requestHash"], diagnostics))
270402
+ return;
270403
+ if (value.operation !== "edit")
270404
+ pushInvalid(diagnostics, `${path2}.operation`, "operation must be edit");
270405
+ validateRequiredString(value, "targetVersionId", `${path2}.targetVersionId`, diagnostics);
270406
+ validateRequiredString(value, "idempotencyKey", `${path2}.idempotencyKey`, diagnostics);
270407
+ validateRequiredString(value, "requestHash", `${path2}.requestHash`, diagnostics);
270408
+ }
270409
+ function validatePendingSync(value, path2, diagnostics) {
270410
+ if (!validateObject(value, path2, ["operation", "targetVersionId", "idempotencyKey", "requestHash", "sourceHash", "compiledHash", "createdAt", "mutationAttemptedAt"], diagnostics))
270411
+ return;
270412
+ validateLifecycleMetadata({
270413
+ operation: value.operation,
270414
+ targetVersionId: value.targetVersionId,
270415
+ idempotencyKey: value.idempotencyKey,
270416
+ requestHash: value.requestHash
270417
+ }, path2, diagnostics);
270418
+ validateRequiredString(value, "sourceHash", `${path2}.sourceHash`, diagnostics);
270419
+ validateRequiredString(value, "compiledHash", `${path2}.compiledHash`, diagnostics);
270420
+ validateRequiredString(value, "createdAt", `${path2}.createdAt`, diagnostics);
270421
+ validateOptionalString(value, "mutationAttemptedAt", `${path2}.mutationAttemptedAt`, diagnostics);
270422
+ }
270423
+ function validateLastSynced(value, path2, diagnostics) {
270424
+ if (!validateObject(value, path2, ["versionId", "versionIndex", "sourceHash", "compiledHash", "syncedAt", "lifecycle"], diagnostics))
270425
+ return;
270426
+ validateRequiredString(value, "versionId", `${path2}.versionId`, diagnostics);
270427
+ validateRequiredNumber(value, "versionIndex", `${path2}.versionIndex`, diagnostics);
270428
+ validateRequiredString(value, "sourceHash", `${path2}.sourceHash`, diagnostics);
270429
+ validateRequiredString(value, "compiledHash", `${path2}.compiledHash`, diagnostics);
270430
+ validateRequiredString(value, "syncedAt", `${path2}.syncedAt`, diagnostics);
270431
+ validateLifecycleMetadata(value.lifecycle, `${path2}.lifecycle`, diagnostics);
270432
+ }
270433
+ function validateObject(value, path2, expectedKeys, diagnostics) {
270434
+ if (!isRecord2(value)) {
270435
+ pushInvalid(diagnostics, path2, "expected object");
270436
+ return false;
270437
+ }
270438
+ const expected = new Set(expectedKeys);
270439
+ for (const key of Object.keys(value)) {
270440
+ if (!expected.has(key))
270441
+ pushInvalid(diagnostics, `${path2}.${key}`, "unknown field");
270442
+ }
270443
+ return true;
270444
+ }
270445
+ function validateRequiredString(record, key, path2, diagnostics) {
270446
+ const value = record[key];
270447
+ if (typeof value !== "string" || value.length === 0)
270448
+ pushInvalid(diagnostics, path2, "must be a non-empty string");
270449
+ }
270450
+ function validateOptionalString(record, key, path2, diagnostics) {
270451
+ const value = record[key];
270452
+ if (value !== void 0 && (typeof value !== "string" || value.length === 0))
270453
+ pushInvalid(diagnostics, path2, "must be a non-empty string when present");
270454
+ }
270455
+ function validateRequiredNumber(record, key, path2, diagnostics) {
270456
+ const value = record[key];
270457
+ if (typeof value !== "number" || !Number.isFinite(value))
270458
+ pushInvalid(diagnostics, path2, "must be a finite number");
270459
+ }
270460
+ function validateOptionalNumber(record, key, path2, diagnostics) {
270461
+ const value = record[key];
270462
+ if (value !== void 0 && (typeof value !== "number" || !Number.isFinite(value)))
270463
+ pushInvalid(diagnostics, path2, "must be a finite number when present");
270464
+ }
270465
+ function validateOptionalStringArray(record, key, path2, diagnostics) {
270466
+ const value = record[key];
270467
+ if (value === void 0)
270468
+ return;
270469
+ validateStringArray(value, path2, diagnostics);
270470
+ }
270471
+ function validateStringArray(value, path2, diagnostics) {
270472
+ if (!Array.isArray(value)) {
270473
+ pushInvalid(diagnostics, path2, "must be an array of strings when present");
270474
+ return;
270475
+ }
270476
+ if (!value.every((item) => typeof item === "string" && item.length > 0))
270477
+ pushInvalid(diagnostics, path2, "must contain only non-empty strings");
270478
+ }
270479
+ function pushInvalid(diagnostics, path2, detail) {
270480
+ diagnostics.push((0, diagnostics_1.diagnostic)("state.lockfile.invalid", "error", `Workflow state lockfile ${path2} is invalid: ${detail}`, "Regenerate the active-context workflow state lockfile from fresh remote state."));
270481
+ }
270482
+ function orderLockfile(lockfile) {
270483
+ return {
270484
+ version: lockfile.version,
270485
+ targetName: lockfile.targetName,
270486
+ workflowKey: lockfile.workflowKey,
270487
+ context: {
270488
+ key: lockfile.context.key,
270489
+ ...lockfile.context.id === void 0 ? {} : { id: lockfile.context.id },
270490
+ projectId: lockfile.context.projectId,
270491
+ promptId: lockfile.context.promptId
270492
+ },
270493
+ remote: orderRemote(lockfile.remote),
270494
+ ...lockfile.generatedMetadata === void 0 ? {} : { generatedMetadata: orderGeneratedMetadata(lockfile.generatedMetadata) },
270495
+ ...lockfile.vaultAssets === void 0 ? {} : { vaultAssets: [...lockfile.vaultAssets].sort((left, right) => left.key.localeCompare(right.key)) },
270496
+ ...lockfile.pendingSync === void 0 ? {} : { pendingSync: {
270497
+ operation: lockfile.pendingSync.operation,
270498
+ targetVersionId: lockfile.pendingSync.targetVersionId,
270499
+ idempotencyKey: lockfile.pendingSync.idempotencyKey,
270500
+ requestHash: lockfile.pendingSync.requestHash,
270501
+ sourceHash: lockfile.pendingSync.sourceHash,
270502
+ compiledHash: lockfile.pendingSync.compiledHash,
270503
+ createdAt: lockfile.pendingSync.createdAt,
270504
+ ...lockfile.pendingSync.mutationAttemptedAt === void 0 ? {} : { mutationAttemptedAt: lockfile.pendingSync.mutationAttemptedAt }
270505
+ } },
270506
+ ...lockfile.lastSynced === void 0 ? {} : { lastSynced: {
270507
+ versionId: lockfile.lastSynced.versionId,
270508
+ versionIndex: lockfile.lastSynced.versionIndex,
270509
+ sourceHash: lockfile.lastSynced.sourceHash,
270510
+ compiledHash: lockfile.lastSynced.compiledHash,
270511
+ syncedAt: lockfile.lastSynced.syncedAt,
270512
+ lifecycle: {
270513
+ operation: lockfile.lastSynced.lifecycle.operation,
270514
+ targetVersionId: lockfile.lastSynced.lifecycle.targetVersionId,
270515
+ idempotencyKey: lockfile.lastSynced.lifecycle.idempotencyKey,
270516
+ requestHash: lockfile.lastSynced.lifecycle.requestHash
270517
+ }
270518
+ } }
270519
+ };
270520
+ }
270521
+ function orderGeneratedMetadata(metadata) {
270522
+ return {
270523
+ version: metadata.version,
270524
+ contextId: metadata.contextId,
270525
+ workspaceId: metadata.workspaceId,
270526
+ catalogHash: metadata.catalogHash,
270527
+ refs: [...metadata.refs].sort((left, right) => left.declarationKey.localeCompare(right.declarationKey) || left.kind.localeCompare(right.kind) || left.id.localeCompare(right.id)).map((ref) => ({
270528
+ declarationKey: ref.declarationKey,
270529
+ kind: ref.kind,
270530
+ ...ref.path === void 0 ? {} : { path: [...ref.path] },
270531
+ id: ref.id,
270532
+ ...ref.environmentName === void 0 ? {} : { environmentName: ref.environmentName },
270533
+ ...ref.versionId === void 0 ? {} : { versionId: ref.versionId },
270534
+ ...ref.revision === void 0 ? {} : { revision: ref.revision },
270535
+ ...ref.inputHash === void 0 ? {} : { inputHash: ref.inputHash },
270536
+ ...ref.outputContractHash === void 0 ? {} : { outputContractHash: ref.outputContractHash },
270537
+ contractHash: ref.contractHash
270538
+ }))
270539
+ };
270540
+ }
270541
+ function orderRemote(remote) {
270542
+ return {
270543
+ fetchedAt: remote.fetchedAt,
270544
+ contentHash: remote.contentHash,
270545
+ prompt: {
270546
+ id: remote.prompt.id,
270547
+ ...remote.prompt.title === void 0 ? {} : { title: remote.prompt.title },
270548
+ currentVersionId: remote.prompt.currentVersionId,
270549
+ currentVersionIndex: remote.prompt.currentVersionIndex,
270550
+ ...remote.prompt.publishedVersionId === void 0 ? {} : { publishedVersionId: remote.prompt.publishedVersionId },
270551
+ ...remote.prompt.publishedVersionIndex === void 0 ? {} : { publishedVersionIndex: remote.prompt.publishedVersionIndex }
270552
+ },
270553
+ version: {
270554
+ id: remote.version.id,
270555
+ versionIndex: remote.version.versionIndex,
270556
+ status: remote.version.status,
270557
+ contentHash: remote.version.contentHash,
270558
+ ...remote.version.compiledHash === void 0 ? {} : { compiledHash: remote.version.compiledHash },
270559
+ ...remote.version.publishedEnvironmentNames === void 0 ? {} : { publishedEnvironmentNames: [...remote.version.publishedEnvironmentNames].sort((left, right) => left.localeCompare(right)) }
270560
+ },
270561
+ ...remote.codegen === void 0 ? {} : { codegen: {
270562
+ ...remote.codegen.templateVariables === void 0 ? {} : { templateVariables: remote.codegen.templateVariables },
270563
+ ...remote.codegen.canvasVariables === void 0 ? {} : { canvasVariables: remote.codegen.canvasVariables },
270564
+ ...remote.codegen.modelIds === void 0 ? {} : { modelIds: remote.codegen.modelIds },
270565
+ ...remote.codegen.toolIds === void 0 ? {} : { toolIds: remote.codegen.toolIds },
270566
+ ...remote.codegen.outputSchemasHash === void 0 ? {} : { outputSchemasHash: remote.codegen.outputSchemasHash }
270567
+ } }
270568
+ };
270569
+ }
270570
+ function isRecord2(value) {
270571
+ return typeof value === "object" && value !== null && !Array.isArray(value);
270572
+ }
270573
+ function isNodeError(error) {
270574
+ return error instanceof Error && "code" in error;
270575
+ }
270576
+ }
270577
+ });
270578
+
270579
+ // ../../packages/workflow-code/dist/cli/state/planning.js
270580
+ var require_planning = __commonJS({
270581
+ "../../packages/workflow-code/dist/cli/state/planning.js"(exports2) {
270582
+ "use strict";
270583
+ Object.defineProperty(exports2, "__esModule", { value: true });
270584
+ exports2.validateLockfileIdentity = validateLockfileIdentity;
270585
+ exports2.resolvePromptId = resolvePromptId;
270586
+ exports2.isLocalSynced = isLocalSynced;
270587
+ exports2.isFreshRemoteConfirmed = isFreshRemoteConfirmed;
270588
+ exports2.detectRemoteDivergence = detectRemoteDivergence;
270589
+ exports2.planRemoteSnapshotWrite = planRemoteSnapshotWrite;
270590
+ exports2.planSyncResultWrite = planSyncResultWrite;
270591
+ var diagnostics_1 = require_diagnostics();
270592
+ var lockfile_1 = require_lockfile();
270593
+ function validateLockfileIdentity(lockfile, facts, path2 = "<lockfile>") {
270594
+ const mismatches = [];
270595
+ pushMismatch(mismatches, "targetName", lockfile.targetName, facts.targetName);
270596
+ pushMismatch(mismatches, "workflowKey", lockfile.workflowKey, facts.workflowKey);
270597
+ pushMismatch(mismatches, "context.key", lockfile.context.key, facts.context.key);
270598
+ pushMismatch(mismatches, "context.projectId", lockfile.context.projectId, facts.context.projectId);
270599
+ if (facts.context.id !== void 0 && lockfile.context.id !== void 0)
270600
+ pushMismatch(mismatches, "context.id", lockfile.context.id, facts.context.id);
270601
+ if (facts.context.promptId !== void 0)
270602
+ pushMismatch(mismatches, "context.promptId", lockfile.context.promptId, facts.context.promptId);
270603
+ if (mismatches.length > 0) {
270604
+ return {
270605
+ ok: false,
270606
+ diagnostics: [(0, diagnostics_1.diagnostic)("state.lockfile.identity_mismatch", "error", `Workflow state lockfile at ${path2} does not match the selected workflow target/context`, `Mismatched fields: ${mismatches.join(", ")}. Use the lockfile for the active workflow/context only.`)]
270607
+ };
270608
+ }
270609
+ return { ok: true, value: lockfile };
270610
+ }
270611
+ function resolvePromptId(facts, lockfile) {
270612
+ if (facts.context.promptId !== void 0)
270613
+ return { ok: true, value: facts.context.promptId };
270614
+ if (lockfile !== void 0) {
270615
+ const identity = validateLockfileIdentity(lockfile, facts);
270616
+ if (!identity.ok)
270617
+ return { ok: false, diagnostics: identity.diagnostics };
270618
+ return { ok: true, value: lockfile.context.promptId };
270619
+ }
270620
+ return {
270621
+ ok: false,
270622
+ 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 or run a command that creates/binds the prompt before requiring existing remote prompt state.")]
270623
+ };
270624
+ }
270625
+ function isLocalSynced(lockfile, local) {
270626
+ const lastSynced = lockfile.lastSynced;
270627
+ return lastSynced !== void 0 && lastSynced.sourceHash === local.sourceHash && lastSynced.compiledHash === local.compiledHash;
270628
+ }
270629
+ function isFreshRemoteConfirmed(lockfile, remote) {
270630
+ return lockfile.lastSynced !== void 0 && remote.version.id === lockfile.lastSynced.versionId && remote.version.versionIndex === lockfile.lastSynced.versionIndex && remote.contentHash === lockfile.remote.contentHash;
270631
+ }
270632
+ function detectRemoteDivergence(lockfile, remote) {
270633
+ if (lockfile.lastSynced === void 0)
270634
+ return [];
270635
+ if (remote.version.id === lockfile.lastSynced.versionId && remote.version.versionIndex === lockfile.lastSynced.versionIndex && remote.contentHash === lockfile.remote.contentHash) {
270636
+ return [];
270637
+ }
270638
+ return [(0, diagnostics_1.diagnostic)("state.remote.diverged", "warning", `Remote workflow content for ${lockfile.workflowKey}/${lockfile.context.key} differs from the last synced lockfile state`, "Confirm before overwriting remote changes, or pass --yes to continue non-interactively.")];
270639
+ }
270640
+ function planRemoteSnapshotWrite(path2, facts, remote, existing, generatedMetadata, vaultAssets) {
270641
+ const lockfile = buildLockfile(facts, remote, existing?.lockfile, generatedMetadata, vaultAssets);
270642
+ if (!lockfile.ok)
270643
+ return { ok: false, diagnostics: lockfile.diagnostics };
270644
+ return { ok: true, value: (0, lockfile_1.planLockfileWrite)(path2, lockfile.value, existing) };
270645
+ }
270646
+ function planSyncResultWrite(path2, facts, remote, syncResult, existing, generatedMetadata, vaultAssets) {
270647
+ const consistency = validateRemoteVersionMatchesSyncResult(remote, syncResult.versionId, syncResult.versionIndex, syncResult.compiledHash);
270648
+ if (!consistency.ok)
270649
+ return { ok: false, diagnostics: consistency.diagnostics };
270650
+ const lockfile = buildLockfile(facts, remote, existing?.lockfile, generatedMetadata, vaultAssets);
270651
+ if (!lockfile.ok)
270652
+ return { ok: false, diagnostics: lockfile.diagnostics };
270653
+ const { pendingSync: _pendingSync, ...syncedLockfile } = lockfile.value;
270654
+ return {
270655
+ ok: true,
270656
+ value: (0, lockfile_1.planLockfileWrite)(path2, {
270657
+ ...syncedLockfile,
270658
+ lastSynced: {
270659
+ versionId: syncResult.versionId,
270660
+ versionIndex: syncResult.versionIndex,
270661
+ sourceHash: syncResult.sourceHash,
270662
+ compiledHash: syncResult.compiledHash,
270663
+ syncedAt: syncResult.syncedAt,
270664
+ lifecycle: syncResult.lifecycle
270665
+ }
270666
+ }, existing)
270667
+ };
270668
+ }
270669
+ function buildLockfile(facts, remote, existing, generatedMetadata, vaultAssets) {
270670
+ if (existing !== void 0) {
270671
+ const identity = validateLockfileIdentity(existing, facts);
270672
+ if (!identity.ok)
270673
+ return { ok: false, diagnostics: identity.diagnostics };
270674
+ }
270675
+ const promptId = resolvePromptId(facts, existing);
270676
+ if (!promptId.ok)
270677
+ return { ok: false, diagnostics: promptId.diagnostics };
270678
+ return {
270679
+ ok: true,
270680
+ value: {
270681
+ version: 1,
270682
+ targetName: facts.targetName,
270683
+ workflowKey: facts.workflowKey,
270684
+ context: {
270685
+ key: facts.context.key,
270686
+ ...facts.context.id === void 0 ? {} : { id: facts.context.id },
270687
+ projectId: facts.context.projectId,
270688
+ promptId: promptId.value
270689
+ },
270690
+ remote,
270691
+ ...generatedMetadata === void 0 ? existing?.generatedMetadata === void 0 ? {} : { generatedMetadata: existing.generatedMetadata } : { generatedMetadata },
270692
+ ...vaultAssets === void 0 ? existing?.vaultAssets === void 0 ? {} : { vaultAssets: existing.vaultAssets } : { vaultAssets },
270693
+ ...existing?.pendingSync === void 0 ? {} : { pendingSync: existing.pendingSync },
270694
+ ...existing?.lastSynced === void 0 ? {} : { lastSynced: existing.lastSynced }
270695
+ }
270696
+ };
270697
+ }
270698
+ function validateRemoteVersionMatchesSyncResult(remote, versionId, versionIndex, compiledHash) {
270699
+ const remoteVersion = remote.version;
270700
+ if (remoteVersion !== void 0 && remoteVersion.id === versionId && remoteVersion.versionIndex === versionIndex && remoteVersion.compiledHash === compiledHash) {
270701
+ return { ok: true, value: void 0 };
270702
+ }
270703
+ return {
270704
+ ok: false,
270705
+ diagnostics: [(0, diagnostics_1.diagnostic)("state.remote.inconsistent", "error", "Workflow sync result does not match the supplied fresh remote snapshot", `Expected remote.version.id ${versionId}, remote.version.versionIndex ${versionIndex}, and remote.version.compiledHash ${compiledHash}. Pass the post-sync remote snapshot before writing state.`)]
270706
+ };
270707
+ }
270708
+ function pushMismatch(mismatches, field, actual, expected) {
270709
+ if (actual !== expected)
270710
+ mismatches.push(`${field} expected ${expected} but found ${actual}`);
270711
+ }
270712
+ }
270713
+ });
270714
+
270715
+ // ../../packages/workflow-code/dist/cli/state/types.js
270716
+ var require_types4 = __commonJS({
270717
+ "../../packages/workflow-code/dist/cli/state/types.js"(exports2) {
270718
+ "use strict";
270719
+ Object.defineProperty(exports2, "__esModule", { value: true });
270720
+ }
270721
+ });
270722
+
270723
+ // ../../packages/workflow-code/dist/cli/state/write.js
270724
+ var require_write = __commonJS({
270725
+ "../../packages/workflow-code/dist/cli/state/write.js"(exports2) {
270726
+ "use strict";
270727
+ Object.defineProperty(exports2, "__esModule", { value: true });
270728
+ exports2.writePlannedLockfile = writePlannedLockfile;
270729
+ var node_crypto_1 = require("node:crypto");
270730
+ var promises_1 = require("node:fs/promises");
270731
+ var node_path_1 = require("node:path");
270732
+ var diagnostics_1 = require_diagnostics();
270733
+ var path_segments_1 = require_path_segments();
270734
+ async function writePlannedLockfile(plan) {
270735
+ const safeParent = await prepareSafeLockfileParent(plan.path);
270736
+ if (!safeParent.ok)
270737
+ return safeParent;
270738
+ const lockPath = `${safeParent.value.lockfilePath}.lock`;
270739
+ const lock = await acquireWriteLock(lockPath, plan.path);
270740
+ if (!lock.ok)
270741
+ return lock;
270742
+ const tempPath = `${safeParent.value.lockfilePath}.${process.pid}.${Date.now()}.tmp`;
270743
+ try {
270744
+ const current = await readCurrentHash(safeParent.value.lockfilePath);
270745
+ if (current !== plan.expectedPreviousHash) {
270746
+ return {
270747
+ ok: false,
270748
+ diagnostics: [(0, diagnostics_1.diagnostic)("state.write.conflict", "error", `Workflow state lockfile changed before write at ${plan.path}`, "Re-read the active-context lockfile, recompute the planned write, and retry.")]
270749
+ };
270750
+ }
270751
+ await (0, promises_1.writeFile)(tempPath, plan.content, { encoding: "utf8", flag: "wx" });
270752
+ await (0, promises_1.rename)(tempPath, safeParent.value.lockfilePath);
270753
+ return {
270754
+ ok: true,
270755
+ value: {
270756
+ path: plan.path,
270757
+ hash: hashContent(plan.content)
270758
+ }
270759
+ };
270760
+ } catch (error) {
270761
+ await (0, promises_1.unlink)(tempPath).catch(() => void 0);
270762
+ throw error;
270763
+ } finally {
270764
+ await lock.value.close();
270765
+ await (0, promises_1.unlink)(lockPath).catch(() => void 0);
270766
+ }
270767
+ }
270768
+ async function prepareSafeLockfileParent(path2) {
270769
+ const parts = parseLockfilePath(path2);
270770
+ if (!parts.ok)
270771
+ return parts;
270772
+ let current = parts.value.rootDir;
270773
+ for (const segment of [".tela", "workflows", parts.value.workflowKey, "contexts", parts.value.contextKey]) {
270774
+ current = (0, node_path_1.join)(current, segment);
270775
+ const directory = await ensureDirectoryWithoutSymlink(current, path2);
270776
+ if (!directory.ok)
270777
+ return directory;
270778
+ }
270779
+ const containment = await verifyRealStateContainment(parts.value, path2);
270780
+ if (!containment.ok)
270781
+ return containment;
270782
+ const target = await rejectExistingTargetSymlink(parts.value.lockfilePath, path2);
270783
+ if (!target.ok)
270784
+ return target;
270785
+ return parts;
270786
+ }
270787
+ function parseLockfilePath(path2) {
270788
+ const lockfilePath = (0, node_path_1.resolve)(path2);
270789
+ const parsed = (0, node_path_1.parse)(lockfilePath);
270790
+ const segments = lockfilePath.slice(parsed.root.length).split(node_path_1.sep).filter((segment) => segment.length > 0);
270791
+ const lockfileIndex = segments.length - 1;
270792
+ const contextIndex = segments.length - 2;
270793
+ const contextsIndex = segments.length - 3;
270794
+ const workflowIndex = segments.length - 4;
270795
+ const workflowsIndex = segments.length - 5;
270796
+ const stateIndex = segments.length - 6;
270797
+ if (stateIndex < 0 || segments[stateIndex] !== ".tela" || segments[workflowsIndex] !== "workflows" || segments[contextsIndex] !== "contexts" || segments[lockfileIndex] !== "lock.json" || !(0, path_segments_1.isSafeStatePathSegment)(segments[workflowIndex]) || !(0, path_segments_1.isSafeStatePathSegment)(segments[contextIndex])) {
270798
+ return unsafePath(path2, "Expected lockfile path shape .tela/workflows/{workflowKey}/contexts/{contextKey}/lock.json");
270799
+ }
270800
+ const rootDir = (0, node_path_1.join)(parsed.root, ...segments.slice(0, stateIndex));
270801
+ const workflowKey = segments[workflowIndex];
270802
+ const contextKey = segments[contextIndex];
270803
+ const stateDir = (0, node_path_1.join)(rootDir, ".tela");
270804
+ const parentDir = (0, node_path_1.join)(stateDir, "workflows", workflowKey, "contexts", contextKey);
270805
+ return {
270806
+ ok: true,
270807
+ value: {
270808
+ rootDir,
270809
+ stateDir,
270810
+ parentDir,
270811
+ lockfilePath: (0, node_path_1.join)(parentDir, "lock.json"),
270812
+ workflowKey,
270813
+ contextKey
270814
+ }
270815
+ };
270816
+ }
270817
+ async function ensureDirectoryWithoutSymlink(path2, targetPath) {
270818
+ try {
270819
+ const stats2 = await (0, promises_1.lstat)(path2);
270820
+ if (stats2.isSymbolicLink())
270821
+ return unsafePath(targetPath, `Path component ${path2} is a symbolic link`);
270822
+ if (!stats2.isDirectory())
270823
+ return unsafePath(targetPath, `Path component ${path2} is not a directory`);
270824
+ return { ok: true, value: void 0 };
270825
+ } catch (error) {
270826
+ if (!isNodeError(error) || error.code !== "ENOENT")
270827
+ throw error;
270828
+ }
270829
+ try {
270830
+ await (0, promises_1.mkdir)(path2);
270831
+ } catch (error) {
270832
+ if (!isNodeError(error) || error.code !== "EEXIST")
270833
+ throw error;
270834
+ }
270835
+ const stats = await (0, promises_1.lstat)(path2);
270836
+ if (stats.isSymbolicLink())
270837
+ return unsafePath(targetPath, `Path component ${path2} is a symbolic link`);
270838
+ if (!stats.isDirectory())
270839
+ return unsafePath(targetPath, `Path component ${path2} is not a directory`);
270840
+ return { ok: true, value: void 0 };
270841
+ }
270842
+ async function verifyRealStateContainment(parts, targetPath) {
270843
+ const stateDir = await (0, promises_1.realpath)(parts.stateDir);
270844
+ const parentDir = await (0, promises_1.realpath)(parts.parentDir);
270845
+ const parentRelativePath = (0, node_path_1.relative)(stateDir, parentDir);
270846
+ if (parentRelativePath === "" || !parentRelativePath.startsWith("..") && !(0, node_path_1.isAbsolute)(parentRelativePath))
270847
+ return { ok: true, value: void 0 };
270848
+ return unsafePath(targetPath, `Resolved parent directory ${parentDir} escapes state directory ${stateDir}`);
270849
+ }
270850
+ async function rejectExistingTargetSymlink(path2, targetPath) {
270851
+ try {
270852
+ const stats = await (0, promises_1.lstat)(path2);
270853
+ if (stats.isSymbolicLink())
270854
+ return unsafePath(targetPath, `Existing lockfile ${path2} is a symbolic link`);
270855
+ return { ok: true, value: void 0 };
270856
+ } catch (error) {
270857
+ if (isNodeError(error) && error.code === "ENOENT")
270858
+ return { ok: true, value: void 0 };
270859
+ throw error;
270860
+ }
270861
+ }
270862
+ function unsafePath(path2, detail) {
270863
+ return {
270864
+ ok: false,
270865
+ diagnostics: [(0, diagnostics_1.diagnostic)("state.write.unsafe_path", "error", `Workflow state lockfile path is unsafe at ${path2}`, `${detail}. Use the derived workflow state path under .tela/workflows. This writer rejects pre-existing symlinked state components for CLI path hygiene, but does not sandbox concurrent local filesystem mutation of parent directories.`)]
270866
+ };
270867
+ }
270868
+ async function acquireWriteLock(lockPath, targetPath) {
270869
+ try {
270870
+ return { ok: true, value: await (0, promises_1.open)(lockPath, "wx") };
270871
+ } catch (error) {
270872
+ if (isNodeError(error) && error.code === "EEXIST") {
270873
+ return {
270874
+ ok: false,
270875
+ diagnostics: [(0, diagnostics_1.diagnostic)("state.write.conflict", "error", `Workflow state lockfile is already being written at ${targetPath}`, `Wait for the in-progress write to finish, then re-read and retry. If the previous process crashed, remove stale lock file ${lockPath} and retry.`)]
270876
+ };
270877
+ }
270878
+ throw error;
270879
+ }
270880
+ }
270881
+ async function readCurrentHash(path2) {
270882
+ try {
270883
+ return hashContent(await (0, promises_1.readFile)(path2));
270884
+ } catch (error) {
270885
+ if (isNodeError(error) && error.code === "ENOENT")
270886
+ return void 0;
270887
+ throw error;
270888
+ }
270889
+ }
270890
+ function hashContent(content) {
270891
+ return (0, node_crypto_1.createHash)("sha256").update(content).digest("hex");
270892
+ }
270893
+ function isNodeError(error) {
270894
+ return error instanceof Error && "code" in error;
270895
+ }
270896
+ }
270897
+ });
270898
+
270899
+ // ../../packages/workflow-code/dist/cli/state/index.js
270900
+ var require_state = __commonJS({
270901
+ "../../packages/workflow-code/dist/cli/state/index.js"(exports2) {
270902
+ "use strict";
270903
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o2, m3, k, k2) {
270904
+ if (k2 === void 0) k2 = k;
270905
+ var desc = Object.getOwnPropertyDescriptor(m3, k);
270906
+ if (!desc || ("get" in desc ? !m3.__esModule : desc.writable || desc.configurable)) {
270907
+ desc = { enumerable: true, get: function() {
270908
+ return m3[k];
270909
+ } };
270910
+ }
270911
+ Object.defineProperty(o2, k2, desc);
270912
+ }) : (function(o2, m3, k, k2) {
270913
+ if (k2 === void 0) k2 = k;
270914
+ o2[k2] = m3[k];
270915
+ }));
270916
+ var __exportStar = exports2 && exports2.__exportStar || function(m3, exports3) {
270917
+ for (var p3 in m3) if (p3 !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p3)) __createBinding(exports3, m3, p3);
270918
+ };
270919
+ Object.defineProperty(exports2, "__esModule", { value: true });
270920
+ __exportStar(require_lockfile(), exports2);
270921
+ __exportStar(require_planning(), exports2);
270922
+ __exportStar(require_types4(), exports2);
270923
+ __exportStar(require_write(), exports2);
270924
+ }
270925
+ });
270926
+
269857
270927
  // ../../packages/workflow-code/dist/cli/commands/select-target.js
269858
270928
  var require_select_target = __commonJS({
269859
270929
  "../../packages/workflow-code/dist/cli/commands/select-target.js"(exports2) {
@@ -269907,7 +270977,9 @@ var require_compile = __commonJS({
269907
270977
  var node_path_1 = require("node:path");
269908
270978
  var compiler_1 = require_compiler();
269909
270979
  var load_config_1 = require_load_config();
270980
+ var resolve_target_identity_1 = require_resolve_target_identity();
269910
270981
  var load_source_1 = require_load_source();
270982
+ var state_1 = require_state();
269911
270983
  var ui_1 = require_ui2();
269912
270984
  var select_target_1 = require_select_target();
269913
270985
  async function compileCommand(context) {
@@ -269922,13 +270994,58 @@ var require_compile = __commonJS({
269922
270994
  const sourceResult = await (0, load_source_1.loadWorkflowSource)((0, node_path_1.dirname)(configResult.value.path), selected.target, configResult.value.env, configResult.value.config.tsconfig);
269923
270995
  if (!sourceResult.ok)
269924
270996
  return { exitCode: 1, diagnostics: sourceResult.diagnostics };
269925
- const compiled = (0, compiler_1.transpileWorkflow)({
270997
+ const initial = (0, compiler_1.transpileWorkflow)({
269926
270998
  targetName: selected.name,
269927
270999
  workflowKey: selected.target.workflowKey,
269928
271000
  title: selected.target.title,
269929
271001
  declaration: sourceResult.value.declaration,
269930
271002
  source: sourceResult.value.source
269931
271003
  });
271004
+ const hasNonVaultAssetErrors = initial.diagnostics.some((item) => item.severity === "error" && item.code !== "vault.asset.missing_lock");
271005
+ if (initial.resources.vaultAssets === void 0 || hasNonVaultAssetErrors)
271006
+ return compileResult(configResult.value.path, selected.name, initial);
271007
+ const identity = await (0, resolve_target_identity_1.resolveWorkflowTargetLockIdentity)(selected.name, selected.target);
271008
+ if (!identity.ok)
271009
+ return { exitCode: 1, diagnostics: identity.diagnostics, compiled: initial };
271010
+ const lockPathFacts = {
271011
+ targetName: selected.name,
271012
+ workflowKey: initial.workflowKey,
271013
+ context: {
271014
+ key: identity.value.contextKey ?? "default",
271015
+ ...identity.value.contextId === void 0 ? {} : { id: identity.value.contextId },
271016
+ projectId: identity.value.projectId ?? "",
271017
+ ...identity.value.promptId === void 0 ? {} : { promptId: identity.value.promptId }
271018
+ }
271019
+ };
271020
+ const lockPath = (0, state_1.deriveLockfilePath)(context.cwd, lockPathFacts);
271021
+ if (!lockPath.ok)
271022
+ return { exitCode: 1, diagnostics: lockPath.diagnostics, compiled: initial };
271023
+ const existing = await (0, state_1.readLockfile)(lockPath.value);
271024
+ if (!existing.ok && existing.diagnostics[0]?.code !== "state.lockfile.missing")
271025
+ return { exitCode: 1, diagnostics: existing.diagnostics, compiled: initial };
271026
+ if (existing.ok) {
271027
+ const facts = {
271028
+ ...lockPathFacts,
271029
+ context: {
271030
+ ...lockPathFacts.context,
271031
+ projectId: identity.value.projectId ?? existing.value.lockfile.context.projectId
271032
+ }
271033
+ };
271034
+ const lockfileIdentity = (0, state_1.validateLockfileIdentity)(existing.value.lockfile, facts, lockPath.value);
271035
+ if (!lockfileIdentity.ok)
271036
+ return { exitCode: 1, diagnostics: lockfileIdentity.diagnostics, compiled: initial };
271037
+ }
271038
+ const compiled = (0, compiler_1.transpileWorkflow)({
271039
+ targetName: selected.name,
271040
+ workflowKey: selected.target.workflowKey,
271041
+ title: selected.target.title,
271042
+ declaration: sourceResult.value.declaration,
271043
+ source: sourceResult.value.source,
271044
+ vaultAssets: existing.ok ? existing.value.lockfile.vaultAssets : void 0
271045
+ });
271046
+ return compileResult(configResult.value.path, selected.name, compiled);
271047
+ }
271048
+ function compileResult(configPath, targetName, compiled) {
269932
271049
  const hasErrors = compiled.diagnostics.some((item) => item.severity === "error");
269933
271050
  return {
269934
271051
  exitCode: hasErrors ? 1 : 0,
@@ -269939,8 +271056,8 @@ var require_compile = __commonJS({
269939
271056
  },
269940
271057
  render: () => (0, ui_1.resultCard)("Workflow compile", [
269941
271058
  (0, ui_1.section)("Summary", (0, ui_1.kvList)([
269942
- { label: "Config", value: configResult.value.path },
269943
- { label: "Target", value: selected.name },
271059
+ { label: "Config", value: configPath },
271060
+ { label: "Target", value: targetName },
269944
271061
  { label: "Workflow key", value: compiled.workflowKey },
269945
271062
  { label: "Nodes", value: String(compiled.intermediate.graph.nodes.length) },
269946
271063
  { label: "Edges", value: String(compiled.intermediate.graph.edges.length) },
@@ -270657,830 +271774,6 @@ var require_not_implemented = __commonJS({
270657
271774
  }
270658
271775
  });
270659
271776
 
270660
- // ../../packages/workflow-code/dist/cli/config/resolve-target-identity.js
270661
- var require_resolve_target_identity = __commonJS({
270662
- "../../packages/workflow-code/dist/cli/config/resolve-target-identity.js"(exports2) {
270663
- "use strict";
270664
- Object.defineProperty(exports2, "__esModule", { value: true });
270665
- exports2.resolveWorkflowTargetIdentity = resolveWorkflowTargetIdentity;
270666
- var tela_local_config_1 = require_dist();
270667
- var diagnostics_1 = require_diagnostics();
270668
- var format_config_path_1 = require_format_config_path();
270669
- async function resolveWorkflowTargetIdentity(targetName, target, options = {}) {
270670
- const contexts = target.contexts;
270671
- if (contexts && Object.keys(contexts).length > 0) {
270672
- const contextResult = await resolveActiveContext(options);
270673
- if (!contextResult.ok)
270674
- return contextResult;
270675
- const candidateKeys = contextBindingCandidateKeys(contextResult.value);
270676
- const contextBinding = findContextBinding(contexts, candidateKeys);
270677
- if (!contextBinding) {
270678
- return {
270679
- ok: false,
270680
- diagnostics: [(0, diagnostics_1.diagnostic)("config.context_binding.missing", "error", `Workflow target ${targetName} has no binding for active Tela context ${contextResult.value.id}`, missingContextBindingHint(targetName, Object.keys(contexts), candidateKeys))]
270681
- };
270682
- }
270683
- const [contextKey, binding] = contextBinding;
270684
- const diagnostics2 = validateResolvedBinding(targetName, binding);
270685
- if (diagnostics2.length > 0)
270686
- return { ok: false, diagnostics: diagnostics2 };
270687
- return {
270688
- ok: true,
270689
- value: {
270690
- contextId: contextResult.value.id,
270691
- contextKey,
270692
- projectId: binding.projectId,
270693
- ...binding.promptId === void 0 ? {} : { promptId: binding.promptId },
270694
- source: "context"
270695
- }
270696
- };
270697
- }
270698
- const diagnostics = validateResolvedBinding(targetName, target);
270699
- if (diagnostics.length > 0)
270700
- return { ok: false, diagnostics };
270701
- const projectId = target.projectId;
270702
- return {
270703
- ok: true,
270704
- value: {
270705
- projectId,
270706
- ...target.promptId === void 0 ? {} : { promptId: target.promptId },
270707
- source: "legacy"
270708
- }
270709
- };
270710
- }
270711
- function findContextBinding(contexts, candidateKeys) {
270712
- for (const contextKey of candidateKeys) {
270713
- const binding = contexts[contextKey];
270714
- if (binding !== void 0)
270715
- return [contextKey, binding];
270716
- }
270717
- return void 0;
270718
- }
270719
- async function resolveActiveContext(options) {
270720
- try {
270721
- const config = options.localConfig ?? await (0, tela_local_config_1.loadConfig)();
270722
- return { ok: true, value: (0, tela_local_config_1.resolveContext)(config, { env: options.env }) };
270723
- } catch (error) {
270724
- return {
270725
- ok: false,
270726
- diagnostics: [(0, diagnostics_1.diagnostic)("config.context.resolve_failed", "error", "Unable to resolve active Tela Local context for Workflow Code command", resolveContextHint(error))]
270727
- };
270728
- }
270729
- }
270730
- function contextBindingCandidateKeys(context) {
270731
- return uniqueStrings([
270732
- context.id,
270733
- context.context.environmentId,
270734
- context.environment.label.toLowerCase(),
270735
- environmentAlias(context.context.environmentId),
270736
- context.environment.kind === "local" ? "dev" : void 0
270737
- ]);
270738
- }
270739
- function environmentAlias(environmentId) {
270740
- if (environmentId === "production")
270741
- return "prod";
270742
- if (environmentId === "development")
270743
- return "dev";
270744
- return void 0;
270745
- }
270746
- function validateResolvedBinding(targetName, binding) {
270747
- const diagnostics = [];
270748
- if (!binding.projectId || typeof binding.projectId !== "string") {
270749
- diagnostics.push((0, diagnostics_1.diagnostic)("config.workflow.project_id.missing", "error", `Workflow target ${targetName} must resolve a non-empty projectId`, `Set \`${(0, format_config_path_1.formatConfigPath)("workflows", targetName, "projectId")}\` to a non-empty Tela project id, or add \`${(0, format_config_path_1.formatConfigPath)("workflows", targetName, "contexts", "<context>", "projectId")}\` for the active Tela context. Check contexts with \`tela context list\`.`));
270750
- }
270751
- if (binding.promptId !== void 0 && (typeof binding.promptId !== "string" || binding.promptId.length === 0)) {
270752
- diagnostics.push((0, diagnostics_1.diagnostic)("config.workflow.prompt_id.invalid", "error", `Workflow target ${targetName} promptId must be a non-empty string when provided`, `Set \`${(0, format_config_path_1.formatConfigPath)("workflows", targetName, "promptId")}\` to a non-empty Tela prompt id from the Tela UI, or remove it if no existing prompt should be bound.`));
270753
- }
270754
- return diagnostics;
270755
- }
270756
- function missingContextBindingHint(targetName, configuredKeys, triedKeys) {
270757
- const preferredKey = triedKeys[0] ?? "<context>";
270758
- return [
270759
- `Add one of the tried keys under \`${(0, format_config_path_1.formatConfigPath)("workflows", targetName, "contexts")}\`, for example \`${(0, format_config_path_1.formatObjectKey)(preferredKey)}: { projectId: 'proj_...' }\`, or switch context with \`tela context use <context-id>\`.`,
270760
- `Configured bindings: ${configuredKeys.join(", ") || "(none)"}. Tried: ${triedKeys.join(", ") || "(none)"}.`
270761
- ].join(" ");
270762
- }
270763
- function resolveContextHint(error) {
270764
- const detail = error instanceof Error && error.message.trim() ? ` Detail: ${error.message}` : "";
270765
- return `Run \`tela context list\` to see configured contexts, then choose one with \`tela context use <context-id>\`. If no contexts exist, add one in Tela Dock/local setup before running workflow commands.${detail}`;
270766
- }
270767
- function uniqueStrings(values) {
270768
- return Array.from(new Set(values.filter((value) => Boolean(value))));
270769
- }
270770
- }
270771
- });
270772
-
270773
- // ../../packages/workflow-code/dist/cli/state/lockfile.js
270774
- var require_lockfile = __commonJS({
270775
- "../../packages/workflow-code/dist/cli/state/lockfile.js"(exports2) {
270776
- "use strict";
270777
- Object.defineProperty(exports2, "__esModule", { value: true });
270778
- exports2.deriveLockfilePath = deriveLockfilePath;
270779
- exports2.readLockfile = readLockfile;
270780
- exports2.validateWorkflowLockfile = validateWorkflowLockfile;
270781
- exports2.serializeLockfile = serializeLockfile;
270782
- exports2.planLockfileWrite = planLockfileWrite;
270783
- var promises_1 = require("node:fs/promises");
270784
- var node_path_1 = require("node:path");
270785
- var diagnostics_1 = require_diagnostics();
270786
- var hash_1 = require_hash();
270787
- var path_segments_1 = require_path_segments();
270788
- var LOCKFILE_VERSION = 1;
270789
- var VALID_VERSION_STATUSES = /* @__PURE__ */ new Set(["draft", "consolidated", "published"]);
270790
- function deriveLockfilePath(rootDir, facts) {
270791
- const workflowDiagnostic = validatePathSegment("workflowKey", facts.workflowKey);
270792
- const contextDiagnostic = validatePathSegment("contextKey", facts.context.key);
270793
- const diagnostics = [workflowDiagnostic, contextDiagnostic].filter((item) => item !== void 0);
270794
- if (diagnostics.length > 0)
270795
- return { ok: false, diagnostics };
270796
- return {
270797
- ok: true,
270798
- value: (0, node_path_1.join)(rootDir, ".tela", "workflows", facts.workflowKey, "contexts", facts.context.key, "lock.json")
270799
- };
270800
- }
270801
- async function readLockfile(path2) {
270802
- let content;
270803
- try {
270804
- content = await (0, promises_1.readFile)(path2, "utf8");
270805
- } catch (error) {
270806
- if (isNodeError(error) && error.code === "ENOENT") {
270807
- return {
270808
- ok: false,
270809
- diagnostics: [(0, diagnostics_1.diagnostic)("state.lockfile.missing", "error", `Workflow state lockfile does not exist at ${path2}`, "Run a remote workflow command that can fetch and persist remote state for the active context.")]
270810
- };
270811
- }
270812
- throw error;
270813
- }
270814
- let parsed;
270815
- try {
270816
- parsed = JSON.parse(content);
270817
- } catch (error) {
270818
- const detail = error instanceof Error ? ` ${error.message}` : "";
270819
- return {
270820
- ok: false,
270821
- diagnostics: [(0, diagnostics_1.diagnostic)("state.lockfile.invalid", "error", `Workflow state lockfile at ${path2} is not valid JSON.${detail}`, "Regenerate the active-context workflow state lockfile from fresh remote state.")]
270822
- };
270823
- }
270824
- const validation = validateWorkflowLockfile(parsed, path2);
270825
- if (!validation.ok)
270826
- return validation;
270827
- return {
270828
- ok: true,
270829
- value: {
270830
- path: path2,
270831
- hash: (0, hash_1.hashString)(content),
270832
- content,
270833
- lockfile: validation.value
270834
- }
270835
- };
270836
- }
270837
- function validateWorkflowLockfile(value, path2 = "<lockfile>") {
270838
- const diagnostics = validateLockfileShape(value, path2);
270839
- if (diagnostics.length > 0)
270840
- return { ok: false, diagnostics };
270841
- return { ok: true, value };
270842
- }
270843
- function serializeLockfile(lockfile) {
270844
- return `${JSON.stringify(orderLockfile(lockfile), null, 2)}
270845
- `;
270846
- }
270847
- function planLockfileWrite(path2, lockfile, existing) {
270848
- return {
270849
- path: path2,
270850
- ...existing === void 0 ? {} : { expectedPreviousHash: existing.hash },
270851
- lockfile,
270852
- content: serializeLockfile(lockfile)
270853
- };
270854
- }
270855
- function validatePathSegment(name, value) {
270856
- if ((0, path_segments_1.isSafeStatePathSegment)(value))
270857
- return void 0;
270858
- return (0, diagnostics_1.diagnostic)("state.lockfile.invalid", "error", `Workflow state lockfile ${name} is not a safe filesystem path segment`, "Workflow and context keys must be one filesystem segment using only letters, numbers, `_`, or `-`.");
270859
- }
270860
- function validateLockfileShape(value, path2) {
270861
- const diagnostics = [];
270862
- validateLockfile(value, path2, diagnostics);
270863
- return diagnostics;
270864
- }
270865
- function validateLockfile(value, path2, diagnostics) {
270866
- if (!validateObject(value, path2, ["version", "targetName", "workflowKey", "context", "remote", "generatedMetadata", "pendingSync", "lastSynced"], diagnostics))
270867
- return;
270868
- if (value.version !== LOCKFILE_VERSION)
270869
- pushInvalid(diagnostics, path2, "version must be 1");
270870
- validateRequiredString(value, "targetName", `${path2}.targetName`, diagnostics);
270871
- validateRequiredString(value, "workflowKey", `${path2}.workflowKey`, diagnostics);
270872
- validateContext(value.context, `${path2}.context`, diagnostics);
270873
- validateRemote(value.remote, `${path2}.remote`, diagnostics);
270874
- if (value.generatedMetadata !== void 0)
270875
- validateGeneratedMetadata(value.generatedMetadata, `${path2}.generatedMetadata`, diagnostics);
270876
- if (value.pendingSync !== void 0)
270877
- validatePendingSync(value.pendingSync, `${path2}.pendingSync`, diagnostics);
270878
- if (value.lastSynced !== void 0)
270879
- validateLastSynced(value.lastSynced, `${path2}.lastSynced`, diagnostics);
270880
- }
270881
- function validateGeneratedMetadata(value, path2, diagnostics) {
270882
- if (!validateObject(value, path2, ["version", "contextId", "workspaceId", "catalogHash", "refs"], diagnostics))
270883
- return;
270884
- if (value.version !== LOCKFILE_VERSION)
270885
- pushInvalid(diagnostics, `${path2}.version`, "version must be 1");
270886
- validateRequiredString(value, "contextId", `${path2}.contextId`, diagnostics);
270887
- validateRequiredString(value, "workspaceId", `${path2}.workspaceId`, diagnostics);
270888
- validateRequiredString(value, "catalogHash", `${path2}.catalogHash`, diagnostics);
270889
- if (!Array.isArray(value.refs)) {
270890
- pushInvalid(diagnostics, `${path2}.refs`, "must be an array");
270891
- return;
270892
- }
270893
- value.refs.forEach((ref, index) => validateLockedRemoteRef(ref, `${path2}.refs[${index}]`, diagnostics));
270894
- }
270895
- function validateLockedRemoteRef(value, path2, diagnostics) {
270896
- if (!validateObject(value, path2, ["declarationKey", "kind", "path", "id", "environmentName", "versionId", "revision", "inputHash", "outputContractHash", "contractHash"], diagnostics))
270897
- return;
270898
- validateRequiredString(value, "declarationKey", `${path2}.declarationKey`, diagnostics);
270899
- if (value.kind !== "canvas" && value.kind !== "workflow" && value.kind !== "agent" && value.kind !== "model")
270900
- pushInvalid(diagnostics, `${path2}.kind`, "kind must be canvas, workflow, agent, or model");
270901
- if (value.path !== void 0)
270902
- validateStringArray(value.path, `${path2}.path`, diagnostics);
270903
- validateRequiredString(value, "id", `${path2}.id`, diagnostics);
270904
- validateOptionalString(value, "environmentName", `${path2}.environmentName`, diagnostics);
270905
- validateOptionalString(value, "versionId", `${path2}.versionId`, diagnostics);
270906
- validateOptionalString(value, "revision", `${path2}.revision`, diagnostics);
270907
- validateOptionalString(value, "inputHash", `${path2}.inputHash`, diagnostics);
270908
- validateOptionalString(value, "outputContractHash", `${path2}.outputContractHash`, diagnostics);
270909
- validateRequiredString(value, "contractHash", `${path2}.contractHash`, diagnostics);
270910
- }
270911
- function validateContext(value, path2, diagnostics) {
270912
- if (!validateObject(value, path2, ["key", "id", "projectId", "promptId"], diagnostics))
270913
- return;
270914
- validateRequiredString(value, "key", `${path2}.key`, diagnostics);
270915
- validateOptionalString(value, "id", `${path2}.id`, diagnostics);
270916
- validateRequiredString(value, "projectId", `${path2}.projectId`, diagnostics);
270917
- validateRequiredString(value, "promptId", `${path2}.promptId`, diagnostics);
270918
- }
270919
- function validateRemote(value, path2, diagnostics) {
270920
- if (!validateObject(value, path2, ["fetchedAt", "contentHash", "prompt", "version", "codegen"], diagnostics))
270921
- return;
270922
- validateRequiredString(value, "fetchedAt", `${path2}.fetchedAt`, diagnostics);
270923
- validateRequiredString(value, "contentHash", `${path2}.contentHash`, diagnostics);
270924
- validatePrompt(value.prompt, `${path2}.prompt`, diagnostics);
270925
- validateRemoteVersion(value.version, `${path2}.version`, diagnostics);
270926
- if (value.codegen !== void 0)
270927
- validateCodegen(value.codegen, `${path2}.codegen`, diagnostics);
270928
- }
270929
- function validatePrompt(value, path2, diagnostics) {
270930
- if (!validateObject(value, path2, ["id", "title", "currentVersionId", "currentVersionIndex", "publishedVersionId", "publishedVersionIndex"], diagnostics))
270931
- return;
270932
- validateRequiredString(value, "id", `${path2}.id`, diagnostics);
270933
- validateOptionalString(value, "title", `${path2}.title`, diagnostics);
270934
- validateRequiredString(value, "currentVersionId", `${path2}.currentVersionId`, diagnostics);
270935
- validateRequiredNumber(value, "currentVersionIndex", `${path2}.currentVersionIndex`, diagnostics);
270936
- validateOptionalString(value, "publishedVersionId", `${path2}.publishedVersionId`, diagnostics);
270937
- validateOptionalNumber(value, "publishedVersionIndex", `${path2}.publishedVersionIndex`, diagnostics);
270938
- }
270939
- function validateRemoteVersion(value, path2, diagnostics) {
270940
- if (!validateObject(value, path2, ["id", "versionIndex", "status", "contentHash", "compiledHash", "publishedEnvironmentNames"], diagnostics))
270941
- return;
270942
- validateRequiredString(value, "id", `${path2}.id`, diagnostics);
270943
- validateRequiredNumber(value, "versionIndex", `${path2}.versionIndex`, diagnostics);
270944
- if (typeof value.status !== "string" || !VALID_VERSION_STATUSES.has(value.status))
270945
- pushInvalid(diagnostics, `${path2}.status`, "status must be draft, consolidated, or published");
270946
- validateRequiredString(value, "contentHash", `${path2}.contentHash`, diagnostics);
270947
- validateOptionalString(value, "compiledHash", `${path2}.compiledHash`, diagnostics);
270948
- validateOptionalStringArray(value, "publishedEnvironmentNames", `${path2}.publishedEnvironmentNames`, diagnostics);
270949
- }
270950
- function validateCodegen(value, path2, diagnostics) {
270951
- if (!validateObject(value, path2, ["templateVariables", "canvasVariables", "modelIds", "toolIds", "outputSchemasHash"], diagnostics))
270952
- return;
270953
- validateOptionalStringArray(value, "templateVariables", `${path2}.templateVariables`, diagnostics);
270954
- validateOptionalStringArray(value, "canvasVariables", `${path2}.canvasVariables`, diagnostics);
270955
- validateOptionalStringArray(value, "modelIds", `${path2}.modelIds`, diagnostics);
270956
- validateOptionalStringArray(value, "toolIds", `${path2}.toolIds`, diagnostics);
270957
- validateOptionalString(value, "outputSchemasHash", `${path2}.outputSchemasHash`, diagnostics);
270958
- }
270959
- function validateLifecycleMetadata(value, path2, diagnostics) {
270960
- if (!validateObject(value, path2, ["operation", "targetVersionId", "idempotencyKey", "requestHash"], diagnostics))
270961
- return;
270962
- if (value.operation !== "edit")
270963
- pushInvalid(diagnostics, `${path2}.operation`, "operation must be edit");
270964
- validateRequiredString(value, "targetVersionId", `${path2}.targetVersionId`, diagnostics);
270965
- validateRequiredString(value, "idempotencyKey", `${path2}.idempotencyKey`, diagnostics);
270966
- validateRequiredString(value, "requestHash", `${path2}.requestHash`, diagnostics);
270967
- }
270968
- function validatePendingSync(value, path2, diagnostics) {
270969
- if (!validateObject(value, path2, ["operation", "targetVersionId", "idempotencyKey", "requestHash", "sourceHash", "compiledHash", "createdAt", "mutationAttemptedAt"], diagnostics))
270970
- return;
270971
- validateLifecycleMetadata({
270972
- operation: value.operation,
270973
- targetVersionId: value.targetVersionId,
270974
- idempotencyKey: value.idempotencyKey,
270975
- requestHash: value.requestHash
270976
- }, path2, diagnostics);
270977
- validateRequiredString(value, "sourceHash", `${path2}.sourceHash`, diagnostics);
270978
- validateRequiredString(value, "compiledHash", `${path2}.compiledHash`, diagnostics);
270979
- validateRequiredString(value, "createdAt", `${path2}.createdAt`, diagnostics);
270980
- validateOptionalString(value, "mutationAttemptedAt", `${path2}.mutationAttemptedAt`, diagnostics);
270981
- }
270982
- function validateLastSynced(value, path2, diagnostics) {
270983
- if (!validateObject(value, path2, ["versionId", "versionIndex", "sourceHash", "compiledHash", "syncedAt", "lifecycle"], diagnostics))
270984
- return;
270985
- validateRequiredString(value, "versionId", `${path2}.versionId`, diagnostics);
270986
- validateRequiredNumber(value, "versionIndex", `${path2}.versionIndex`, diagnostics);
270987
- validateRequiredString(value, "sourceHash", `${path2}.sourceHash`, diagnostics);
270988
- validateRequiredString(value, "compiledHash", `${path2}.compiledHash`, diagnostics);
270989
- validateRequiredString(value, "syncedAt", `${path2}.syncedAt`, diagnostics);
270990
- validateLifecycleMetadata(value.lifecycle, `${path2}.lifecycle`, diagnostics);
270991
- }
270992
- function validateObject(value, path2, expectedKeys, diagnostics) {
270993
- if (!isRecord2(value)) {
270994
- pushInvalid(diagnostics, path2, "expected object");
270995
- return false;
270996
- }
270997
- const expected = new Set(expectedKeys);
270998
- for (const key of Object.keys(value)) {
270999
- if (!expected.has(key))
271000
- pushInvalid(diagnostics, `${path2}.${key}`, "unknown field");
271001
- }
271002
- return true;
271003
- }
271004
- function validateRequiredString(record, key, path2, diagnostics) {
271005
- const value = record[key];
271006
- if (typeof value !== "string" || value.length === 0)
271007
- pushInvalid(diagnostics, path2, "must be a non-empty string");
271008
- }
271009
- function validateOptionalString(record, key, path2, diagnostics) {
271010
- const value = record[key];
271011
- if (value !== void 0 && (typeof value !== "string" || value.length === 0))
271012
- pushInvalid(diagnostics, path2, "must be a non-empty string when present");
271013
- }
271014
- function validateRequiredNumber(record, key, path2, diagnostics) {
271015
- const value = record[key];
271016
- if (typeof value !== "number" || !Number.isFinite(value))
271017
- pushInvalid(diagnostics, path2, "must be a finite number");
271018
- }
271019
- function validateOptionalNumber(record, key, path2, diagnostics) {
271020
- const value = record[key];
271021
- if (value !== void 0 && (typeof value !== "number" || !Number.isFinite(value)))
271022
- pushInvalid(diagnostics, path2, "must be a finite number when present");
271023
- }
271024
- function validateOptionalStringArray(record, key, path2, diagnostics) {
271025
- const value = record[key];
271026
- if (value === void 0)
271027
- return;
271028
- validateStringArray(value, path2, diagnostics);
271029
- }
271030
- function validateStringArray(value, path2, diagnostics) {
271031
- if (!Array.isArray(value)) {
271032
- pushInvalid(diagnostics, path2, "must be an array of strings when present");
271033
- return;
271034
- }
271035
- if (!value.every((item) => typeof item === "string" && item.length > 0))
271036
- pushInvalid(diagnostics, path2, "must contain only non-empty strings");
271037
- }
271038
- function pushInvalid(diagnostics, path2, detail) {
271039
- diagnostics.push((0, diagnostics_1.diagnostic)("state.lockfile.invalid", "error", `Workflow state lockfile ${path2} is invalid: ${detail}`, "Regenerate the active-context workflow state lockfile from fresh remote state."));
271040
- }
271041
- function orderLockfile(lockfile) {
271042
- return {
271043
- version: lockfile.version,
271044
- targetName: lockfile.targetName,
271045
- workflowKey: lockfile.workflowKey,
271046
- context: {
271047
- key: lockfile.context.key,
271048
- ...lockfile.context.id === void 0 ? {} : { id: lockfile.context.id },
271049
- projectId: lockfile.context.projectId,
271050
- promptId: lockfile.context.promptId
271051
- },
271052
- remote: orderRemote(lockfile.remote),
271053
- ...lockfile.generatedMetadata === void 0 ? {} : { generatedMetadata: orderGeneratedMetadata(lockfile.generatedMetadata) },
271054
- ...lockfile.pendingSync === void 0 ? {} : { pendingSync: {
271055
- operation: lockfile.pendingSync.operation,
271056
- targetVersionId: lockfile.pendingSync.targetVersionId,
271057
- idempotencyKey: lockfile.pendingSync.idempotencyKey,
271058
- requestHash: lockfile.pendingSync.requestHash,
271059
- sourceHash: lockfile.pendingSync.sourceHash,
271060
- compiledHash: lockfile.pendingSync.compiledHash,
271061
- createdAt: lockfile.pendingSync.createdAt,
271062
- ...lockfile.pendingSync.mutationAttemptedAt === void 0 ? {} : { mutationAttemptedAt: lockfile.pendingSync.mutationAttemptedAt }
271063
- } },
271064
- ...lockfile.lastSynced === void 0 ? {} : { lastSynced: {
271065
- versionId: lockfile.lastSynced.versionId,
271066
- versionIndex: lockfile.lastSynced.versionIndex,
271067
- sourceHash: lockfile.lastSynced.sourceHash,
271068
- compiledHash: lockfile.lastSynced.compiledHash,
271069
- syncedAt: lockfile.lastSynced.syncedAt,
271070
- lifecycle: {
271071
- operation: lockfile.lastSynced.lifecycle.operation,
271072
- targetVersionId: lockfile.lastSynced.lifecycle.targetVersionId,
271073
- idempotencyKey: lockfile.lastSynced.lifecycle.idempotencyKey,
271074
- requestHash: lockfile.lastSynced.lifecycle.requestHash
271075
- }
271076
- } }
271077
- };
271078
- }
271079
- function orderGeneratedMetadata(metadata) {
271080
- return {
271081
- version: metadata.version,
271082
- contextId: metadata.contextId,
271083
- workspaceId: metadata.workspaceId,
271084
- catalogHash: metadata.catalogHash,
271085
- refs: [...metadata.refs].sort((left, right) => left.declarationKey.localeCompare(right.declarationKey) || left.kind.localeCompare(right.kind) || left.id.localeCompare(right.id)).map((ref) => ({
271086
- declarationKey: ref.declarationKey,
271087
- kind: ref.kind,
271088
- ...ref.path === void 0 ? {} : { path: [...ref.path] },
271089
- id: ref.id,
271090
- ...ref.environmentName === void 0 ? {} : { environmentName: ref.environmentName },
271091
- ...ref.versionId === void 0 ? {} : { versionId: ref.versionId },
271092
- ...ref.revision === void 0 ? {} : { revision: ref.revision },
271093
- ...ref.inputHash === void 0 ? {} : { inputHash: ref.inputHash },
271094
- ...ref.outputContractHash === void 0 ? {} : { outputContractHash: ref.outputContractHash },
271095
- contractHash: ref.contractHash
271096
- }))
271097
- };
271098
- }
271099
- function orderRemote(remote) {
271100
- return {
271101
- fetchedAt: remote.fetchedAt,
271102
- contentHash: remote.contentHash,
271103
- prompt: {
271104
- id: remote.prompt.id,
271105
- ...remote.prompt.title === void 0 ? {} : { title: remote.prompt.title },
271106
- currentVersionId: remote.prompt.currentVersionId,
271107
- currentVersionIndex: remote.prompt.currentVersionIndex,
271108
- ...remote.prompt.publishedVersionId === void 0 ? {} : { publishedVersionId: remote.prompt.publishedVersionId },
271109
- ...remote.prompt.publishedVersionIndex === void 0 ? {} : { publishedVersionIndex: remote.prompt.publishedVersionIndex }
271110
- },
271111
- version: {
271112
- id: remote.version.id,
271113
- versionIndex: remote.version.versionIndex,
271114
- status: remote.version.status,
271115
- contentHash: remote.version.contentHash,
271116
- ...remote.version.compiledHash === void 0 ? {} : { compiledHash: remote.version.compiledHash },
271117
- ...remote.version.publishedEnvironmentNames === void 0 ? {} : { publishedEnvironmentNames: [...remote.version.publishedEnvironmentNames].sort((left, right) => left.localeCompare(right)) }
271118
- },
271119
- ...remote.codegen === void 0 ? {} : { codegen: {
271120
- ...remote.codegen.templateVariables === void 0 ? {} : { templateVariables: remote.codegen.templateVariables },
271121
- ...remote.codegen.canvasVariables === void 0 ? {} : { canvasVariables: remote.codegen.canvasVariables },
271122
- ...remote.codegen.modelIds === void 0 ? {} : { modelIds: remote.codegen.modelIds },
271123
- ...remote.codegen.toolIds === void 0 ? {} : { toolIds: remote.codegen.toolIds },
271124
- ...remote.codegen.outputSchemasHash === void 0 ? {} : { outputSchemasHash: remote.codegen.outputSchemasHash }
271125
- } }
271126
- };
271127
- }
271128
- function isRecord2(value) {
271129
- return typeof value === "object" && value !== null && !Array.isArray(value);
271130
- }
271131
- function isNodeError(error) {
271132
- return error instanceof Error && "code" in error;
271133
- }
271134
- }
271135
- });
271136
-
271137
- // ../../packages/workflow-code/dist/cli/state/planning.js
271138
- var require_planning = __commonJS({
271139
- "../../packages/workflow-code/dist/cli/state/planning.js"(exports2) {
271140
- "use strict";
271141
- Object.defineProperty(exports2, "__esModule", { value: true });
271142
- exports2.validateLockfileIdentity = validateLockfileIdentity;
271143
- exports2.resolvePromptId = resolvePromptId;
271144
- exports2.isLocalSynced = isLocalSynced;
271145
- exports2.isFreshRemoteConfirmed = isFreshRemoteConfirmed;
271146
- exports2.detectRemoteDivergence = detectRemoteDivergence;
271147
- exports2.planRemoteSnapshotWrite = planRemoteSnapshotWrite;
271148
- exports2.planSyncResultWrite = planSyncResultWrite;
271149
- var diagnostics_1 = require_diagnostics();
271150
- var lockfile_1 = require_lockfile();
271151
- function validateLockfileIdentity(lockfile, facts, path2 = "<lockfile>") {
271152
- const mismatches = [];
271153
- pushMismatch(mismatches, "targetName", lockfile.targetName, facts.targetName);
271154
- pushMismatch(mismatches, "workflowKey", lockfile.workflowKey, facts.workflowKey);
271155
- pushMismatch(mismatches, "context.key", lockfile.context.key, facts.context.key);
271156
- pushMismatch(mismatches, "context.projectId", lockfile.context.projectId, facts.context.projectId);
271157
- if (facts.context.id !== void 0 && lockfile.context.id !== void 0)
271158
- pushMismatch(mismatches, "context.id", lockfile.context.id, facts.context.id);
271159
- if (facts.context.promptId !== void 0)
271160
- pushMismatch(mismatches, "context.promptId", lockfile.context.promptId, facts.context.promptId);
271161
- if (mismatches.length > 0) {
271162
- return {
271163
- ok: false,
271164
- diagnostics: [(0, diagnostics_1.diagnostic)("state.lockfile.identity_mismatch", "error", `Workflow state lockfile at ${path2} does not match the selected workflow target/context`, `Mismatched fields: ${mismatches.join(", ")}. Use the lockfile for the active workflow/context only.`)]
271165
- };
271166
- }
271167
- return { ok: true, value: lockfile };
271168
- }
271169
- function resolvePromptId(facts, lockfile) {
271170
- if (facts.context.promptId !== void 0)
271171
- return { ok: true, value: facts.context.promptId };
271172
- if (lockfile !== void 0) {
271173
- const identity = validateLockfileIdentity(lockfile, facts);
271174
- if (!identity.ok)
271175
- return { ok: false, diagnostics: identity.diagnostics };
271176
- return { ok: true, value: lockfile.context.promptId };
271177
- }
271178
- return {
271179
- ok: false,
271180
- 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 or run a command that creates/binds the prompt before requiring existing remote prompt state.")]
271181
- };
271182
- }
271183
- function isLocalSynced(lockfile, local) {
271184
- const lastSynced = lockfile.lastSynced;
271185
- return lastSynced !== void 0 && lastSynced.sourceHash === local.sourceHash && lastSynced.compiledHash === local.compiledHash;
271186
- }
271187
- function isFreshRemoteConfirmed(lockfile, remote) {
271188
- return lockfile.lastSynced !== void 0 && remote.version.id === lockfile.lastSynced.versionId && remote.version.versionIndex === lockfile.lastSynced.versionIndex && remote.contentHash === lockfile.remote.contentHash;
271189
- }
271190
- function detectRemoteDivergence(lockfile, remote) {
271191
- if (lockfile.lastSynced === void 0)
271192
- return [];
271193
- if (remote.version.id === lockfile.lastSynced.versionId && remote.version.versionIndex === lockfile.lastSynced.versionIndex && remote.contentHash === lockfile.remote.contentHash) {
271194
- return [];
271195
- }
271196
- return [(0, diagnostics_1.diagnostic)("state.remote.diverged", "warning", `Remote workflow content for ${lockfile.workflowKey}/${lockfile.context.key} differs from the last synced lockfile state`, "Confirm before overwriting remote changes, or pass --yes to continue non-interactively.")];
271197
- }
271198
- function planRemoteSnapshotWrite(path2, facts, remote, existing, generatedMetadata) {
271199
- const lockfile = buildLockfile(facts, remote, existing?.lockfile, generatedMetadata);
271200
- if (!lockfile.ok)
271201
- return { ok: false, diagnostics: lockfile.diagnostics };
271202
- return { ok: true, value: (0, lockfile_1.planLockfileWrite)(path2, lockfile.value, existing) };
271203
- }
271204
- function planSyncResultWrite(path2, facts, remote, syncResult, existing, generatedMetadata) {
271205
- const consistency = validateRemoteVersionMatchesSyncResult(remote, syncResult.versionId, syncResult.versionIndex, syncResult.compiledHash);
271206
- if (!consistency.ok)
271207
- return { ok: false, diagnostics: consistency.diagnostics };
271208
- const lockfile = buildLockfile(facts, remote, existing?.lockfile, generatedMetadata);
271209
- if (!lockfile.ok)
271210
- return { ok: false, diagnostics: lockfile.diagnostics };
271211
- const { pendingSync: _pendingSync, ...syncedLockfile } = lockfile.value;
271212
- return {
271213
- ok: true,
271214
- value: (0, lockfile_1.planLockfileWrite)(path2, {
271215
- ...syncedLockfile,
271216
- lastSynced: {
271217
- versionId: syncResult.versionId,
271218
- versionIndex: syncResult.versionIndex,
271219
- sourceHash: syncResult.sourceHash,
271220
- compiledHash: syncResult.compiledHash,
271221
- syncedAt: syncResult.syncedAt,
271222
- lifecycle: syncResult.lifecycle
271223
- }
271224
- }, existing)
271225
- };
271226
- }
271227
- function buildLockfile(facts, remote, existing, generatedMetadata) {
271228
- if (existing !== void 0) {
271229
- const identity = validateLockfileIdentity(existing, facts);
271230
- if (!identity.ok)
271231
- return { ok: false, diagnostics: identity.diagnostics };
271232
- }
271233
- const promptId = resolvePromptId(facts, existing);
271234
- if (!promptId.ok)
271235
- return { ok: false, diagnostics: promptId.diagnostics };
271236
- return {
271237
- ok: true,
271238
- value: {
271239
- version: 1,
271240
- targetName: facts.targetName,
271241
- workflowKey: facts.workflowKey,
271242
- context: {
271243
- key: facts.context.key,
271244
- ...facts.context.id === void 0 ? {} : { id: facts.context.id },
271245
- projectId: facts.context.projectId,
271246
- promptId: promptId.value
271247
- },
271248
- remote,
271249
- ...generatedMetadata === void 0 ? existing?.generatedMetadata === void 0 ? {} : { generatedMetadata: existing.generatedMetadata } : { generatedMetadata },
271250
- ...existing?.pendingSync === void 0 ? {} : { pendingSync: existing.pendingSync },
271251
- ...existing?.lastSynced === void 0 ? {} : { lastSynced: existing.lastSynced }
271252
- }
271253
- };
271254
- }
271255
- function validateRemoteVersionMatchesSyncResult(remote, versionId, versionIndex, compiledHash) {
271256
- const remoteVersion = remote.version;
271257
- if (remoteVersion !== void 0 && remoteVersion.id === versionId && remoteVersion.versionIndex === versionIndex && remoteVersion.compiledHash === compiledHash) {
271258
- return { ok: true, value: void 0 };
271259
- }
271260
- return {
271261
- ok: false,
271262
- diagnostics: [(0, diagnostics_1.diagnostic)("state.remote.inconsistent", "error", "Workflow sync result does not match the supplied fresh remote snapshot", `Expected remote.version.id ${versionId}, remote.version.versionIndex ${versionIndex}, and remote.version.compiledHash ${compiledHash}. Pass the post-sync remote snapshot before writing state.`)]
271263
- };
271264
- }
271265
- function pushMismatch(mismatches, field, actual, expected) {
271266
- if (actual !== expected)
271267
- mismatches.push(`${field} expected ${expected} but found ${actual}`);
271268
- }
271269
- }
271270
- });
271271
-
271272
- // ../../packages/workflow-code/dist/cli/state/types.js
271273
- var require_types4 = __commonJS({
271274
- "../../packages/workflow-code/dist/cli/state/types.js"(exports2) {
271275
- "use strict";
271276
- Object.defineProperty(exports2, "__esModule", { value: true });
271277
- }
271278
- });
271279
-
271280
- // ../../packages/workflow-code/dist/cli/state/write.js
271281
- var require_write = __commonJS({
271282
- "../../packages/workflow-code/dist/cli/state/write.js"(exports2) {
271283
- "use strict";
271284
- Object.defineProperty(exports2, "__esModule", { value: true });
271285
- exports2.writePlannedLockfile = writePlannedLockfile;
271286
- var node_crypto_1 = require("node:crypto");
271287
- var promises_1 = require("node:fs/promises");
271288
- var node_path_1 = require("node:path");
271289
- var diagnostics_1 = require_diagnostics();
271290
- var path_segments_1 = require_path_segments();
271291
- async function writePlannedLockfile(plan) {
271292
- const safeParent = await prepareSafeLockfileParent(plan.path);
271293
- if (!safeParent.ok)
271294
- return safeParent;
271295
- const lockPath = `${safeParent.value.lockfilePath}.lock`;
271296
- const lock = await acquireWriteLock(lockPath, plan.path);
271297
- if (!lock.ok)
271298
- return lock;
271299
- const tempPath = `${safeParent.value.lockfilePath}.${process.pid}.${Date.now()}.tmp`;
271300
- try {
271301
- const current = await readCurrentHash(safeParent.value.lockfilePath);
271302
- if (current !== plan.expectedPreviousHash) {
271303
- return {
271304
- ok: false,
271305
- diagnostics: [(0, diagnostics_1.diagnostic)("state.write.conflict", "error", `Workflow state lockfile changed before write at ${plan.path}`, "Re-read the active-context lockfile, recompute the planned write, and retry.")]
271306
- };
271307
- }
271308
- await (0, promises_1.writeFile)(tempPath, plan.content, { encoding: "utf8", flag: "wx" });
271309
- await (0, promises_1.rename)(tempPath, safeParent.value.lockfilePath);
271310
- return {
271311
- ok: true,
271312
- value: {
271313
- path: plan.path,
271314
- hash: hashContent(plan.content)
271315
- }
271316
- };
271317
- } catch (error) {
271318
- await (0, promises_1.unlink)(tempPath).catch(() => void 0);
271319
- throw error;
271320
- } finally {
271321
- await lock.value.close();
271322
- await (0, promises_1.unlink)(lockPath).catch(() => void 0);
271323
- }
271324
- }
271325
- async function prepareSafeLockfileParent(path2) {
271326
- const parts = parseLockfilePath(path2);
271327
- if (!parts.ok)
271328
- return parts;
271329
- let current = parts.value.rootDir;
271330
- for (const segment of [".tela", "workflows", parts.value.workflowKey, "contexts", parts.value.contextKey]) {
271331
- current = (0, node_path_1.join)(current, segment);
271332
- const directory = await ensureDirectoryWithoutSymlink(current, path2);
271333
- if (!directory.ok)
271334
- return directory;
271335
- }
271336
- const containment = await verifyRealStateContainment(parts.value, path2);
271337
- if (!containment.ok)
271338
- return containment;
271339
- const target = await rejectExistingTargetSymlink(parts.value.lockfilePath, path2);
271340
- if (!target.ok)
271341
- return target;
271342
- return parts;
271343
- }
271344
- function parseLockfilePath(path2) {
271345
- const lockfilePath = (0, node_path_1.resolve)(path2);
271346
- const parsed = (0, node_path_1.parse)(lockfilePath);
271347
- const segments = lockfilePath.slice(parsed.root.length).split(node_path_1.sep).filter((segment) => segment.length > 0);
271348
- const lockfileIndex = segments.length - 1;
271349
- const contextIndex = segments.length - 2;
271350
- const contextsIndex = segments.length - 3;
271351
- const workflowIndex = segments.length - 4;
271352
- const workflowsIndex = segments.length - 5;
271353
- const stateIndex = segments.length - 6;
271354
- if (stateIndex < 0 || segments[stateIndex] !== ".tela" || segments[workflowsIndex] !== "workflows" || segments[contextsIndex] !== "contexts" || segments[lockfileIndex] !== "lock.json" || !(0, path_segments_1.isSafeStatePathSegment)(segments[workflowIndex]) || !(0, path_segments_1.isSafeStatePathSegment)(segments[contextIndex])) {
271355
- return unsafePath(path2, "Expected lockfile path shape .tela/workflows/{workflowKey}/contexts/{contextKey}/lock.json");
271356
- }
271357
- const rootDir = (0, node_path_1.join)(parsed.root, ...segments.slice(0, stateIndex));
271358
- const workflowKey = segments[workflowIndex];
271359
- const contextKey = segments[contextIndex];
271360
- const stateDir = (0, node_path_1.join)(rootDir, ".tela");
271361
- const parentDir = (0, node_path_1.join)(stateDir, "workflows", workflowKey, "contexts", contextKey);
271362
- return {
271363
- ok: true,
271364
- value: {
271365
- rootDir,
271366
- stateDir,
271367
- parentDir,
271368
- lockfilePath: (0, node_path_1.join)(parentDir, "lock.json"),
271369
- workflowKey,
271370
- contextKey
271371
- }
271372
- };
271373
- }
271374
- async function ensureDirectoryWithoutSymlink(path2, targetPath) {
271375
- try {
271376
- const stats2 = await (0, promises_1.lstat)(path2);
271377
- if (stats2.isSymbolicLink())
271378
- return unsafePath(targetPath, `Path component ${path2} is a symbolic link`);
271379
- if (!stats2.isDirectory())
271380
- return unsafePath(targetPath, `Path component ${path2} is not a directory`);
271381
- return { ok: true, value: void 0 };
271382
- } catch (error) {
271383
- if (!isNodeError(error) || error.code !== "ENOENT")
271384
- throw error;
271385
- }
271386
- try {
271387
- await (0, promises_1.mkdir)(path2);
271388
- } catch (error) {
271389
- if (!isNodeError(error) || error.code !== "EEXIST")
271390
- throw error;
271391
- }
271392
- const stats = await (0, promises_1.lstat)(path2);
271393
- if (stats.isSymbolicLink())
271394
- return unsafePath(targetPath, `Path component ${path2} is a symbolic link`);
271395
- if (!stats.isDirectory())
271396
- return unsafePath(targetPath, `Path component ${path2} is not a directory`);
271397
- return { ok: true, value: void 0 };
271398
- }
271399
- async function verifyRealStateContainment(parts, targetPath) {
271400
- const stateDir = await (0, promises_1.realpath)(parts.stateDir);
271401
- const parentDir = await (0, promises_1.realpath)(parts.parentDir);
271402
- const parentRelativePath = (0, node_path_1.relative)(stateDir, parentDir);
271403
- if (parentRelativePath === "" || !parentRelativePath.startsWith("..") && !(0, node_path_1.isAbsolute)(parentRelativePath))
271404
- return { ok: true, value: void 0 };
271405
- return unsafePath(targetPath, `Resolved parent directory ${parentDir} escapes state directory ${stateDir}`);
271406
- }
271407
- async function rejectExistingTargetSymlink(path2, targetPath) {
271408
- try {
271409
- const stats = await (0, promises_1.lstat)(path2);
271410
- if (stats.isSymbolicLink())
271411
- return unsafePath(targetPath, `Existing lockfile ${path2} is a symbolic link`);
271412
- return { ok: true, value: void 0 };
271413
- } catch (error) {
271414
- if (isNodeError(error) && error.code === "ENOENT")
271415
- return { ok: true, value: void 0 };
271416
- throw error;
271417
- }
271418
- }
271419
- function unsafePath(path2, detail) {
271420
- return {
271421
- ok: false,
271422
- diagnostics: [(0, diagnostics_1.diagnostic)("state.write.unsafe_path", "error", `Workflow state lockfile path is unsafe at ${path2}`, `${detail}. Use the derived workflow state path under .tela/workflows. This writer rejects pre-existing symlinked state components for CLI path hygiene, but does not sandbox concurrent local filesystem mutation of parent directories.`)]
271423
- };
271424
- }
271425
- async function acquireWriteLock(lockPath, targetPath) {
271426
- try {
271427
- return { ok: true, value: await (0, promises_1.open)(lockPath, "wx") };
271428
- } catch (error) {
271429
- if (isNodeError(error) && error.code === "EEXIST") {
271430
- return {
271431
- ok: false,
271432
- diagnostics: [(0, diagnostics_1.diagnostic)("state.write.conflict", "error", `Workflow state lockfile is already being written at ${targetPath}`, `Wait for the in-progress write to finish, then re-read and retry. If the previous process crashed, remove stale lock file ${lockPath} and retry.`)]
271433
- };
271434
- }
271435
- throw error;
271436
- }
271437
- }
271438
- async function readCurrentHash(path2) {
271439
- try {
271440
- return hashContent(await (0, promises_1.readFile)(path2));
271441
- } catch (error) {
271442
- if (isNodeError(error) && error.code === "ENOENT")
271443
- return void 0;
271444
- throw error;
271445
- }
271446
- }
271447
- function hashContent(content) {
271448
- return (0, node_crypto_1.createHash)("sha256").update(content).digest("hex");
271449
- }
271450
- function isNodeError(error) {
271451
- return error instanceof Error && "code" in error;
271452
- }
271453
- }
271454
- });
271455
-
271456
- // ../../packages/workflow-code/dist/cli/state/index.js
271457
- var require_state = __commonJS({
271458
- "../../packages/workflow-code/dist/cli/state/index.js"(exports2) {
271459
- "use strict";
271460
- var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o2, m3, k, k2) {
271461
- if (k2 === void 0) k2 = k;
271462
- var desc = Object.getOwnPropertyDescriptor(m3, k);
271463
- if (!desc || ("get" in desc ? !m3.__esModule : desc.writable || desc.configurable)) {
271464
- desc = { enumerable: true, get: function() {
271465
- return m3[k];
271466
- } };
271467
- }
271468
- Object.defineProperty(o2, k2, desc);
271469
- }) : (function(o2, m3, k, k2) {
271470
- if (k2 === void 0) k2 = k;
271471
- o2[k2] = m3[k];
271472
- }));
271473
- var __exportStar = exports2 && exports2.__exportStar || function(m3, exports3) {
271474
- for (var p3 in m3) if (p3 !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p3)) __createBinding(exports3, m3, p3);
271475
- };
271476
- Object.defineProperty(exports2, "__esModule", { value: true });
271477
- __exportStar(require_lockfile(), exports2);
271478
- __exportStar(require_planning(), exports2);
271479
- __exportStar(require_types4(), exports2);
271480
- __exportStar(require_write(), exports2);
271481
- }
271482
- });
271483
-
271484
271777
  // ../../packages/workflow-code/dist/cli/sync/hash.js
271485
271778
  var require_hash2 = __commonJS({
271486
271779
  "../../packages/workflow-code/dist/cli/sync/hash.js"(exports2) {
@@ -271640,7 +271933,7 @@ var require_engine = __commonJS({
271640
271933
  const lastSynced = existing.lockfile.lastSynced;
271641
271934
  if (lastSynced === void 0)
271642
271935
  return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("sync.lockfile.inconsistent", "error", "Workflow lockfile sync predicates passed without lastSynced metadata.")] };
271643
- if (options.generatedMetadata !== void 0 && JSON.stringify(existing.lockfile.generatedMetadata) !== JSON.stringify(options.generatedMetadata)) {
271936
+ if (options.generatedMetadata !== void 0 && JSON.stringify(existing.lockfile.generatedMetadata) !== JSON.stringify(options.generatedMetadata) || options.vaultAssets !== void 0 && JSON.stringify(existing.lockfile.vaultAssets) !== JSON.stringify(options.vaultAssets)) {
271644
271937
  const noopPlan = (0, state_1.planSyncResultWrite)(lockfilePath.value, options.facts, remoteBefore.value, {
271645
271938
  versionId: remoteBefore.value.version.id,
271646
271939
  versionIndex: remoteBefore.value.version.versionIndex,
@@ -271648,7 +271941,7 @@ var require_engine = __commonJS({
271648
271941
  compiledHash: options.compiled.hashes.compiled,
271649
271942
  syncedAt: lastSynced.syncedAt,
271650
271943
  lifecycle: lastSynced.lifecycle
271651
- }, existing, options.generatedMetadata);
271944
+ }, existing, options.generatedMetadata, options.vaultAssets);
271652
271945
  if (!noopPlan.ok)
271653
271946
  return { ok: false, diagnostics: noopPlan.diagnostics };
271654
271947
  const noopWrite = await (0, state_1.writePlannedLockfile)(noopPlan.value);
@@ -271698,6 +271991,7 @@ var require_engine = __commonJS({
271698
271991
  },
271699
271992
  remote: remoteBefore.value,
271700
271993
  ...options.generatedMetadata === void 0 ? {} : { generatedMetadata: options.generatedMetadata },
271994
+ ...options.vaultAssets === void 0 ? {} : { vaultAssets: options.vaultAssets },
271701
271995
  pendingSync: pending.value,
271702
271996
  ...existing?.lockfile.lastSynced === void 0 ? {} : { lastSynced: existing.lockfile.lastSynced }
271703
271997
  };
@@ -271745,7 +272039,7 @@ var require_engine = __commonJS({
271745
272039
  idempotencyKey: pending.value.idempotencyKey,
271746
272040
  requestHash: pending.value.requestHash
271747
272041
  }
271748
- }, currentState, options.generatedMetadata);
272042
+ }, currentState, options.generatedMetadata, options.vaultAssets);
271749
272043
  if (!syncPlan.ok)
271750
272044
  return { ok: false, diagnostics: syncPlan.diagnostics };
271751
272045
  const written = await (0, state_1.writePlannedLockfile)(syncPlan.value);
@@ -271853,9 +272147,10 @@ var require_remote_api2 = __commonJS({
271853
272147
  const credential = await (0, tela_local_config_1.refreshUserSessionCredential)(session.resolved.environment, session.credentialRef, session.credential, credentials);
271854
272148
  const baseUrl = trimTrailingSlash((0, tela_local_config_1.getServiceUrl)(session, "api"));
271855
272149
  const headers = (0, tela_local_config_1.createTelaRequestHeaders)(credential);
271856
- const request = createJsonRequester(baseUrl, headers, options.fetchImpl ?? fetch);
272150
+ const fetchImpl = options.fetchImpl ?? fetch;
272151
+ const request = createJsonRequester(baseUrl, headers, fetchImpl);
271857
272152
  const vaultServiceUrl = session.resolved.environment.services.vault;
271858
- const vaultRequest = vaultServiceUrl === void 0 ? void 0 : createJsonRequester(trimTrailingSlash(vaultServiceUrl), headers, options.fetchImpl ?? fetch);
272153
+ const vaultRequest = vaultServiceUrl === void 0 ? void 0 : createJsonRequester(trimTrailingSlash(vaultServiceUrl), headers, fetchImpl);
271859
272154
  const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
271860
272155
  return {
271861
272156
  async validateVaultRef(input) {
@@ -271875,6 +272170,39 @@ var require_remote_api2 = __commonJS({
271875
272170
  throw workflowApiError("vault.ref.inaccessible", `Vault reference ${input.reference} could not be validated in the active Tela context.`, "Check the selected workspace, context credentials, Vault service URL, and network access.");
271876
272171
  }
271877
272172
  },
272173
+ async uploadVaultAsset(input) {
272174
+ if (!vaultRequest) {
272175
+ throw workflowApiError("vault.asset.upload_failed", "The active Tela environment does not configure a Vault service URL.", "Add services.vault to the active Tela environment and retry.");
272176
+ }
272177
+ const created = await vaultRequest("/files", {
272178
+ method: "POST",
272179
+ body: {
272180
+ fileName: input.name,
272181
+ size: input.content.byteLength,
272182
+ ...input.mimeType === void 0 ? {} : { mimeType: input.mimeType }
272183
+ },
272184
+ failureCode: "vault.asset.upload_failed",
272185
+ invalidResponseCode: "vault.asset.upload_failed",
272186
+ failureMessage: (status) => `Vault could not register local asset ${input.name} (HTTP ${status}).`
272187
+ });
272188
+ const id = requireString(created, "id");
272189
+ const uploadUrl = requireString(created, "uploadUrl");
272190
+ const reference = `vault://${id}`;
272191
+ if (!(0, reference_1.isWorkflowCodeVaultReference)(reference)) {
272192
+ throw workflowApiError("vault.asset.upload_failed", "Vault returned an invalid file reference while registering a local asset.", "Retry sync after checking that the active Vault service is compatible with Workflow Code.");
272193
+ }
272194
+ const uploadBuffer = new ArrayBuffer(input.content.byteLength);
272195
+ new Uint8Array(uploadBuffer).set(input.content);
272196
+ const upload = await fetchImpl(uploadUrl, {
272197
+ method: "PUT",
272198
+ headers: input.mimeType === void 0 ? void 0 : { "Content-Type": input.mimeType },
272199
+ body: new Blob([uploadBuffer], input.mimeType === void 0 ? void 0 : { type: input.mimeType })
272200
+ });
272201
+ if (!upload.ok) {
272202
+ throw workflowApiError("vault.asset.upload_failed", `Vault upload for local asset ${input.name} failed with HTTP ${upload.status}.`, "Retry sync after checking Vault availability and file permissions.");
272203
+ }
272204
+ return reference;
272205
+ },
271878
272206
  async fetchPromptSnapshot(input) {
271879
272207
  const prompt = await request(`/prompt/${encodeURIComponent(input.promptId)}`);
271880
272208
  validatePromptMatchesBinding(prompt, input);
@@ -272198,6 +272526,100 @@ var require_types5 = __commonJS({
272198
272526
  }
272199
272527
  });
272200
272528
 
272529
+ // ../../packages/workflow-code/dist/cli/sync/vault-assets.js
272530
+ var require_vault_assets = __commonJS({
272531
+ "../../packages/workflow-code/dist/cli/sync/vault-assets.js"(exports2) {
272532
+ "use strict";
272533
+ Object.defineProperty(exports2, "__esModule", { value: true });
272534
+ exports2.prepareWorkflowVaultAssets = prepareWorkflowVaultAssets;
272535
+ var node_crypto_1 = require("node:crypto");
272536
+ var node_fs_1 = require("node:fs");
272537
+ var promises_1 = require("node:fs/promises");
272538
+ var node_path_1 = require("node:path");
272539
+ var diagnostics_1 = require_diagnostics();
272540
+ async function prepareWorkflowVaultAssets(input) {
272541
+ if (input.assets.length === 0)
272542
+ return { ok: true, value: [] };
272543
+ if (!input.vaultApi) {
272544
+ 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.")] };
272545
+ }
272546
+ const existingByKey = new Map((input.existing ?? []).map((asset) => [asset.key, asset]));
272547
+ const prepared = [];
272548
+ let projectRoot;
272549
+ try {
272550
+ projectRoot = await (0, promises_1.realpath)(input.rootDir);
272551
+ } catch {
272552
+ return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.file_missing", "error", "The Workflow Code project directory is unavailable.", "Run sync from a project containing workflow-code.config.ts.")] };
272553
+ }
272554
+ for (const asset of input.assets) {
272555
+ const declaredPath = (0, node_path_1.resolve)(projectRoot, asset.path);
272556
+ if (!isWithinRoot(declaredPath, projectRoot)) {
272557
+ return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.file_missing", "error", `Vault asset path ${asset.path} resolves outside the Workflow Code project.`, "Use a relative path inside the project containing workflow-code.config.ts.")] };
272558
+ }
272559
+ let resolvedPath;
272560
+ let content;
272561
+ try {
272562
+ resolvedPath = await (0, promises_1.realpath)(declaredPath);
272563
+ if (!isWithinRoot(resolvedPath, projectRoot)) {
272564
+ return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.file_missing", "error", `Vault asset path ${asset.path} resolves outside the Workflow Code project.`, "Use a regular file inside the project containing workflow-code.config.ts.")] };
272565
+ }
272566
+ const file = await (0, promises_1.open)(resolvedPath, node_fs_1.constants.O_RDONLY | node_fs_1.constants.O_NOFOLLOW);
272567
+ try {
272568
+ const metadata = await file.stat();
272569
+ if (!metadata.isFile())
272570
+ throw new Error("path is not a regular file");
272571
+ const openedPath = await (0, promises_1.realpath)(resolvedPath);
272572
+ const pathMetadata = await (0, promises_1.lstat)(resolvedPath);
272573
+ if (!isWithinRoot(openedPath, projectRoot) || !pathMetadata.isFile() || pathMetadata.dev !== metadata.dev || pathMetadata.ino !== metadata.ino) {
272574
+ throw new Error("path changed while opening");
272575
+ }
272576
+ content = await file.readFile();
272577
+ } finally {
272578
+ await file.close();
272579
+ }
272580
+ } catch {
272581
+ return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("vault.asset.file_missing", "error", `Vault asset ${asset.path} is unavailable.`, "Add a regular file at the declared path or update vault.asset().")] };
272582
+ }
272583
+ const contentHash = (0, node_crypto_1.createHash)("sha256").update(content).digest("hex");
272584
+ const previous = existingByKey.get(asset.key);
272585
+ if (previous?.contentHash === contentHash) {
272586
+ prepared.push(previous);
272587
+ continue;
272588
+ }
272589
+ const name = asset.name ?? (0, node_path_1.basename)(resolvedPath);
272590
+ try {
272591
+ const ref = await input.vaultApi.uploadVaultAsset({
272592
+ name,
272593
+ ...asset.mimeType === void 0 ? {} : { mimeType: asset.mimeType },
272594
+ content
272595
+ });
272596
+ prepared.push(Object.freeze({
272597
+ ...asset,
272598
+ name,
272599
+ resolvedPath,
272600
+ contentHash,
272601
+ size: content.byteLength,
272602
+ ref,
272603
+ uploadedAt: input.now?.() ?? (/* @__PURE__ */ new Date()).toISOString()
272604
+ }));
272605
+ } catch (error) {
272606
+ if (hasDiagnostics(error))
272607
+ return { ok: false, diagnostics: error.diagnostics };
272608
+ 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.")] };
272609
+ }
272610
+ }
272611
+ return { ok: true, value: prepared };
272612
+ }
272613
+ function isWithinRoot(path2, rootDir) {
272614
+ const relativePath = (0, node_path_1.relative)((0, node_path_1.resolve)(rootDir), path2);
272615
+ return relativePath === "" || !relativePath.startsWith("..") && !(0, node_path_1.isAbsolute)(relativePath);
272616
+ }
272617
+ function hasDiagnostics(error) {
272618
+ return error !== null && typeof error === "object" && "diagnostics" in error && Array.isArray(error.diagnostics);
272619
+ }
272620
+ }
272621
+ });
272622
+
272201
272623
  // ../../packages/workflow-code/dist/cli/sync/index.js
272202
272624
  var require_sync2 = __commonJS({
272203
272625
  "../../packages/workflow-code/dist/cli/sync/index.js"(exports2) {
@@ -272223,6 +272645,7 @@ var require_sync2 = __commonJS({
272223
272645
  __exportStar(require_hash2(), exports2);
272224
272646
  __exportStar(require_remote_api2(), exports2);
272225
272647
  __exportStar(require_types5(), exports2);
272648
+ __exportStar(require_vault_assets(), exports2);
272226
272649
  __exportStar(require_vault_preflight(), exports2);
272227
272650
  }
272228
272651
  });
@@ -272295,6 +272718,7 @@ var require_engine2 = __commonJS({
272295
272718
  cwd: options.cwd,
272296
272719
  facts: options.facts,
272297
272720
  compiled: options.compiled,
272721
+ vaultAssets: options.vaultAssets,
272298
272722
  remoteApi: options.remoteApi,
272299
272723
  vaultApi: options.vaultApi,
272300
272724
  vaultValidation: vaultValidation.value,
@@ -272609,6 +273033,7 @@ var require_publish2 = __commonJS({
272609
273033
  var publish_1 = require_publish();
272610
273034
  var load_source_1 = require_load_source();
272611
273035
  var sync_1 = require_sync2();
273036
+ var state_1 = require_state();
272612
273037
  var ui_1 = require_ui2();
272613
273038
  var select_target_1 = require_select_target();
272614
273039
  var ALLOWED_FLAGS = /* @__PURE__ */ new Set(["config", "env", "environment", "yes", "create-environment-if-missing"]);
@@ -272634,30 +273059,19 @@ var require_publish2 = __commonJS({
272634
273059
  const selected = selectPublishTargets(configResult.value.config.workflows, context.passthrough);
272635
273060
  if (!selected.ok)
272636
273061
  return { exitCode: 1, diagnostics: selected.diagnostics };
272637
- const prepared = await preparePublishTargets({
272638
- configPath: configResult.value.path,
272639
- configEnv: configResult.value.env,
272640
- tsconfig: configResult.value.config.tsconfig,
272641
- targets: selected.targets
272642
- });
272643
- if (!prepared.ok)
272644
- return { exitCode: 1, diagnostics: prepared.diagnostics, compiled: prepared.compiled };
273062
+ const resolved = await resolvePublishTargets(selected.targets);
273063
+ if (!resolved.ok)
273064
+ return { exitCode: 1, diagnostics: resolved.diagnostics };
272645
273065
  let remoteApi;
272646
273066
  try {
272647
273067
  remoteApi = context.remoteApi ?? await (0, sync_1.createWorkflowRemoteApi)({
272648
- contextId: prepared.targets[0]?.identity.contextId
273068
+ contextId: resolved.targets[0]?.identity.contextId
272649
273069
  });
272650
273070
  } catch (error) {
272651
273071
  return { exitCode: 1, diagnostics: diagnosticsFromError(error) };
272652
273072
  }
272653
- const vaultValidation = await (0, sync_1.preflightCompiledVaultRefs)({
272654
- compiled: prepared.targets.map((item) => item.compiled),
272655
- vaultApi: remoteApi
272656
- });
272657
- if (!vaultValidation.ok)
272658
- return { exitCode: 1, diagnostics: vaultValidation.diagnostics };
272659
273073
  const preparedEnvironments = await (0, publish_1.preparePublishEnvironments)({
272660
- targets: prepared.targets.map((item) => ({ targetName: item.name, promptId: item.identity.promptId })),
273074
+ targets: resolved.targets.map((item) => ({ targetName: item.name, promptId: item.identity.promptId })),
272661
273075
  environmentName: environment.value,
272662
273076
  remoteApi,
272663
273077
  createIfMissing: context.flags["create-environment-if-missing"] === true,
@@ -272667,6 +273081,22 @@ var require_publish2 = __commonJS({
272667
273081
  return { exitCode: 1, diagnostics: preparedEnvironments.diagnostics };
272668
273082
  const environmentsByTarget = new Map(preparedEnvironments.value.map((item) => [item.targetName, item.environment]));
272669
273083
  const environmentCreationDiagnostics = preparedEnvironments.value.filter((item) => item.environment.created).map((item) => (0, diagnostics_1.diagnostic)("publish.environment.created", "info", `Environment "${item.environment.name}" was created for workflow "${item.targetName}".`));
273084
+ const prepared = await preparePublishTargets({
273085
+ configPath: configResult.value.path,
273086
+ configEnv: configResult.value.env,
273087
+ tsconfig: configResult.value.config.tsconfig,
273088
+ targets: resolved.targets,
273089
+ rootDir: context.cwd,
273090
+ vaultApi: remoteApi
273091
+ });
273092
+ if (!prepared.ok)
273093
+ return { exitCode: 1, diagnostics: [...environmentCreationDiagnostics, ...prepared.diagnostics], compiled: prepared.compiled };
273094
+ const vaultValidation = await (0, sync_1.preflightCompiledVaultRefs)({
273095
+ compiled: prepared.targets.map((item) => item.compiled),
273096
+ vaultApi: remoteApi
273097
+ });
273098
+ if (!vaultValidation.ok)
273099
+ return { exitCode: 1, diagnostics: [...environmentCreationDiagnostics, ...vaultValidation.diagnostics] };
272670
273100
  const completed = [];
272671
273101
  for (const item of prepared.targets) {
272672
273102
  const preparedEnvironment = environmentsByTarget.get(item.name);
@@ -272686,6 +273116,7 @@ var require_publish2 = __commonJS({
272686
273116
  }
272687
273117
  },
272688
273118
  compiled: item.compiled,
273119
+ vaultAssets: item.vaultAssets,
272689
273120
  remoteApi,
272690
273121
  vaultApi: remoteApi,
272691
273122
  vaultValidation: vaultValidation.value,
@@ -272751,27 +273182,85 @@ var require_publish2 = __commonJS({
272751
273182
  async function preparePublishTargets(options) {
272752
273183
  const prepared = [];
272753
273184
  for (const selected of options.targets) {
272754
- const identity = await (0, resolve_target_identity_1.resolveWorkflowTargetIdentity)(selected.name, selected.target);
272755
- if (!identity.ok)
272756
- return { ok: false, diagnostics: identity.diagnostics };
272757
- if (!identity.value.promptId) {
272758
- return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("publish.prompt_id.missing", "error", `Workflow target ${selected.name} has no promptId for the active context`, "Add promptId to the active workflow context binding before publishing.")] };
272759
- }
272760
273185
  const source = await (0, load_source_1.loadWorkflowSource)((0, node_path_1.dirname)(options.configPath), selected.target, options.configEnv, options.tsconfig);
272761
273186
  if (!source.ok)
272762
273187
  return { ok: false, diagnostics: source.diagnostics };
272763
- const compiled = (0, compiler_1.transpileWorkflow)({
273188
+ const initial = (0, compiler_1.transpileWorkflow)({
272764
273189
  targetName: selected.name,
272765
273190
  workflowKey: selected.target.workflowKey,
272766
273191
  title: selected.target.title,
272767
273192
  declaration: source.value.declaration,
272768
273193
  source: source.value.source
272769
273194
  });
273195
+ const blockingDiagnostics = initial.diagnostics.filter((item) => item.severity === "error" && item.code !== "vault.asset.missing_lock");
273196
+ if (blockingDiagnostics.length > 0)
273197
+ return { ok: false, diagnostics: [...initial.diagnostics], compiled: initial };
273198
+ const lockPath = (0, state_1.deriveLockfilePath)(options.rootDir, {
273199
+ targetName: selected.name,
273200
+ workflowKey: initial.workflowKey,
273201
+ context: {
273202
+ key: selected.identity.contextKey ?? "default",
273203
+ ...selected.identity.contextId === void 0 ? {} : { id: selected.identity.contextId },
273204
+ projectId: selected.identity.projectId,
273205
+ promptId: selected.identity.promptId
273206
+ }
273207
+ });
273208
+ if (!lockPath.ok)
273209
+ return { ok: false, diagnostics: lockPath.diagnostics, compiled: initial };
273210
+ const existing = await (0, state_1.readLockfile)(lockPath.value);
273211
+ if (!existing.ok && existing.diagnostics[0]?.code !== "state.lockfile.missing")
273212
+ return { ok: false, diagnostics: existing.diagnostics, compiled: initial };
273213
+ if (existing.ok) {
273214
+ const lockfileIdentity = (0, state_1.validateLockfileIdentity)(existing.value.lockfile, {
273215
+ targetName: selected.name,
273216
+ workflowKey: initial.workflowKey,
273217
+ context: {
273218
+ key: selected.identity.contextKey ?? "default",
273219
+ ...selected.identity.contextId === void 0 ? {} : { id: selected.identity.contextId },
273220
+ projectId: selected.identity.projectId,
273221
+ promptId: selected.identity.promptId
273222
+ }
273223
+ }, lockPath.value);
273224
+ if (!lockfileIdentity.ok)
273225
+ return { ok: false, diagnostics: lockfileIdentity.diagnostics, compiled: initial };
273226
+ }
273227
+ const vaultAssets = await (0, sync_1.prepareWorkflowVaultAssets)({
273228
+ rootDir: (0, node_path_1.dirname)(options.configPath),
273229
+ assets: initial.resources.vaultAssets ?? [],
273230
+ existing: existing.ok ? existing.value.lockfile.vaultAssets : void 0,
273231
+ vaultApi: options.vaultApi
273232
+ });
273233
+ if (!vaultAssets.ok)
273234
+ return { ok: false, diagnostics: vaultAssets.diagnostics, compiled: initial };
273235
+ const compiled = (0, compiler_1.transpileWorkflow)({
273236
+ targetName: selected.name,
273237
+ workflowKey: selected.target.workflowKey,
273238
+ title: selected.target.title,
273239
+ declaration: source.value.declaration,
273240
+ source: source.value.source,
273241
+ vaultAssets: vaultAssets.value
273242
+ });
272770
273243
  if (compiled.diagnostics.some((item) => item.severity === "error"))
272771
273244
  return { ok: false, diagnostics: [...compiled.diagnostics], compiled };
272772
273245
  prepared.push({
272773
273246
  ...selected,
272774
273247
  compiled,
273248
+ vaultAssets: vaultAssets.value
273249
+ });
273250
+ }
273251
+ return { ok: true, targets: prepared };
273252
+ }
273253
+ async function resolvePublishTargets(targets) {
273254
+ const resolved = [];
273255
+ for (const target of targets) {
273256
+ const identity = await (0, resolve_target_identity_1.resolveWorkflowTargetIdentity)(target.name, target.target);
273257
+ if (!identity.ok)
273258
+ return { ok: false, diagnostics: identity.diagnostics };
273259
+ if (!identity.value.promptId) {
273260
+ return { ok: false, diagnostics: [(0, diagnostics_1.diagnostic)("publish.prompt_id.missing", "error", `Workflow target ${target.name} has no promptId for the active context`, "Add promptId to the active workflow context binding before publishing.")] };
273261
+ }
273262
+ resolved.push({
273263
+ ...target,
272775
273264
  identity: {
272776
273265
  contextKey: identity.value.contextKey,
272777
273266
  contextId: identity.value.contextId,
@@ -272780,7 +273269,7 @@ var require_publish2 = __commonJS({
272780
273269
  }
272781
273270
  });
272782
273271
  }
272783
- return { ok: true, targets: prepared };
273272
+ return { ok: true, targets: resolved };
272784
273273
  }
272785
273274
  function publishSummary(item) {
272786
273275
  return (0, ui_1.kvList)([
@@ -272844,22 +273333,24 @@ var require_sync3 = __commonJS({
272844
273333
  const selectedResult = selectSyncWorkflowTargets(configResult.value.config.workflows, context.passthrough);
272845
273334
  if (!selectedResult.ok)
272846
273335
  return { exitCode: 1, diagnostics: selectedResult.diagnostics };
273336
+ let remoteApi;
273337
+ try {
273338
+ remoteApi = context.remoteApi ?? await (0, sync_1.createWorkflowRemoteApi)();
273339
+ } catch (error) {
273340
+ return { exitCode: 1, diagnostics: diagnosticsFromError(error, "sync.remote.configure_failed") };
273341
+ }
272847
273342
  const preparedResult = await prepareSyncTargets({
272848
273343
  configPath: configResult.value.path,
272849
273344
  configEnv: configResult.value.env,
272850
273345
  tsconfig: configResult.value.config.tsconfig,
272851
273346
  targets: selectedResult.targets,
272852
273347
  rootDir: context.cwd,
272853
- catalogApi: context.catalogApi
273348
+ projectDir: (0, node_path_1.dirname)(configResult.value.path),
273349
+ catalogApi: context.catalogApi,
273350
+ vaultApi: remoteApi
272854
273351
  });
272855
273352
  if (!preparedResult.ok)
272856
273353
  return { exitCode: 1, diagnostics: preparedResult.diagnostics, compiled: preparedResult.compiled };
272857
- let remoteApi;
272858
- try {
272859
- remoteApi = context.remoteApi ?? await (0, sync_1.createWorkflowRemoteApi)({ env: configResult.value.env });
272860
- } catch (error) {
272861
- return { exitCode: 1, diagnostics: diagnosticsFromError(error, "sync.remote.configure_failed") };
272862
- }
272863
273354
  const vaultValidation = await (0, sync_1.preflightCompiledVaultRefs)({
272864
273355
  compiled: preparedResult.targets.map((item) => item.compiled),
272865
273356
  vaultApi: remoteApi
@@ -272882,6 +273373,7 @@ var require_sync3 = __commonJS({
272882
273373
  },
272883
273374
  compiled: prepared.compiled,
272884
273375
  generatedMetadata: prepared.generatedMetadata,
273376
+ vaultAssets: prepared.vaultAssets,
272885
273377
  remoteApi,
272886
273378
  vaultApi: remoteApi,
272887
273379
  vaultValidation: vaultValidation.value,
@@ -272928,7 +273420,7 @@ var require_sync3 = __commonJS({
272928
273420
  async function prepareSyncTargets(options) {
272929
273421
  const symbolicPrepared = [];
272930
273422
  for (const selected of options.targets) {
272931
- const identity = await (0, resolve_target_identity_1.resolveWorkflowTargetIdentity)(selected.name, selected.target, { env: options.configEnv });
273423
+ const identity = await (0, resolve_target_identity_1.resolveWorkflowTargetIdentity)(selected.name, selected.target);
272932
273424
  if (!identity.ok)
272933
273425
  return { ok: false, diagnostics: identity.diagnostics };
272934
273426
  if (!identity.value.promptId) {
@@ -272937,13 +273429,48 @@ var require_sync3 = __commonJS({
272937
273429
  const sourceResult = await (0, load_source_1.loadWorkflowSource)((0, node_path_1.dirname)(options.configPath), selected.target, options.configEnv, options.tsconfig);
272938
273430
  if (!sourceResult.ok)
272939
273431
  return { ok: false, diagnostics: sourceResult.diagnostics };
272940
- const symbolic = (0, compiler_1.transpileWorkflow)({
273432
+ const initialSymbolic = (0, compiler_1.transpileWorkflow)({
272941
273433
  targetName: selected.name,
272942
273434
  workflowKey: selected.target.workflowKey,
272943
273435
  title: selected.target.title,
272944
273436
  declaration: sourceResult.value.declaration,
272945
273437
  source: sourceResult.value.source
272946
273438
  });
273439
+ const blockingDiagnostics = initialSymbolic.diagnostics.filter((item) => item.severity === "error" && item.code !== "vault.asset.missing_lock");
273440
+ if (blockingDiagnostics.length > 0)
273441
+ return { ok: false, diagnostics: [...initialSymbolic.diagnostics], compiled: initialSymbolic };
273442
+ const facts = {
273443
+ targetName: selected.name,
273444
+ workflowKey: initialSymbolic.workflowKey,
273445
+ context: {
273446
+ key: identity.value.contextKey ?? "default",
273447
+ ...identity.value.contextId === void 0 ? {} : { id: identity.value.contextId },
273448
+ projectId: identity.value.projectId,
273449
+ promptId: identity.value.promptId
273450
+ }
273451
+ };
273452
+ const lockPath = (0, state_1.deriveLockfilePath)(options.rootDir, facts);
273453
+ if (!lockPath.ok)
273454
+ return { ok: false, diagnostics: lockPath.diagnostics, compiled: initialSymbolic };
273455
+ const existing = await (0, state_1.readLockfile)(lockPath.value);
273456
+ if (!existing.ok && existing.diagnostics[0]?.code !== "state.lockfile.missing")
273457
+ return { ok: false, diagnostics: existing.diagnostics, compiled: initialSymbolic };
273458
+ const vaultAssets = await (0, sync_1.prepareWorkflowVaultAssets)({
273459
+ rootDir: options.projectDir,
273460
+ assets: initialSymbolic.resources.vaultAssets ?? [],
273461
+ existing: existing.ok ? existing.value.lockfile.vaultAssets : void 0,
273462
+ vaultApi: options.vaultApi
273463
+ });
273464
+ if (!vaultAssets.ok)
273465
+ return { ok: false, diagnostics: vaultAssets.diagnostics, compiled: initialSymbolic };
273466
+ const symbolic = (0, compiler_1.transpileWorkflow)({
273467
+ targetName: selected.name,
273468
+ workflowKey: selected.target.workflowKey,
273469
+ title: selected.target.title,
273470
+ declaration: sourceResult.value.declaration,
273471
+ source: sourceResult.value.source,
273472
+ vaultAssets: vaultAssets.value
273473
+ });
272947
273474
  if (symbolic.diagnostics.some((item) => item.severity === "error"))
272948
273475
  return { ok: false, diagnostics: [...symbolic.diagnostics], compiled: symbolic };
272949
273476
  symbolicPrepared.push({
@@ -272951,6 +273478,7 @@ var require_sync3 = __commonJS({
272951
273478
  source: sourceResult.value,
272952
273479
  symbolic,
272953
273480
  compiled: symbolic,
273481
+ vaultAssets: vaultAssets.value,
272954
273482
  identity: {
272955
273483
  contextKey: identity.value.contextKey,
272956
273484
  contextId: identity.value.contextId,
@@ -272964,7 +273492,7 @@ var require_sync3 = __commonJS({
272964
273492
  return { ok: true, targets: symbolicPrepared };
272965
273493
  let api;
272966
273494
  try {
272967
- api = options.catalogApi ?? await (0, catalog_1.createWorkflowCatalogApi)({ env: options.configEnv });
273495
+ api = options.catalogApi ?? await (0, catalog_1.createWorkflowCatalogApi)();
272968
273496
  } catch (error) {
272969
273497
  return { ok: false, diagnostics: diagnosticsFromError(error, "metadata.catalog.authentication_failed") };
272970
273498
  }
@@ -273006,7 +273534,8 @@ var require_sync3 = __commonJS({
273006
273534
  title: item.target.title,
273007
273535
  declaration: item.source.declaration,
273008
273536
  source: item.source.source,
273009
- remote: { kind: "resolved", snapshot, locks: generated.locks.refs }
273537
+ remote: { kind: "resolved", snapshot, locks: generated.locks.refs },
273538
+ vaultAssets: item.vaultAssets
273010
273539
  });
273011
273540
  const diagnostics = [...generated.diagnostics, ...compiled.diagnostics];
273012
273541
  if (diagnostics.some((diagnostic) => diagnostic.severity === "error"))