@eigenpal/cli 0.16.3 → 0.16.4

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/cli.js CHANGED
@@ -7756,10 +7756,13 @@ var init_ids = __esm(() => {
7756
7756
  CLASSIFY: "builtin/classify",
7757
7757
  CLASSIFY_PAGES: "builtin/classify-pages",
7758
7758
  VISION: "builtin/vision",
7759
+ SEARCH_FILES: "builtin/search-files",
7759
7760
  TEMPLATE: "builtin/template",
7760
7761
  PDF_EMBEDDER: "builtin/pdf-embedder",
7761
7762
  XLSX_TO_JSON: "builtin/xlsx-to-json",
7762
- JSON_TO_XLSX: "builtin/json-to-xlsx"
7763
+ JSON_TO_XLSX: "builtin/json-to-xlsx",
7764
+ ARCHIVE_LIST: "builtin/archive-list",
7765
+ ARCHIVE_EXTRACT: "builtin/archive-extract"
7763
7766
  };
7764
7767
  });
7765
7768
 
@@ -7966,7 +7969,8 @@ var init_runtime_file_ref = __esm(() => {
7966
7969
  fileId: string2().optional().describe("Legacy files-table id for db-backed handles"),
7967
7970
  ref: string2().optional().describe("Tenant-scoped storage key suffix for S3-backed handles"),
7968
7971
  path: string2().optional().describe("Local filesystem path for headless/CLI handles"),
7969
- base64: string2().optional().describe("Base64 bytes for inline handles")
7972
+ base64: string2().optional().describe("Base64 bytes for inline handles"),
7973
+ size: number2().int().nonnegative().optional().describe("Byte size when a file-producing step recorded it")
7970
7974
  }).strict();
7971
7975
  });
7972
7976
 
@@ -8264,7 +8268,8 @@ var init_parser = __esm(() => {
8264
8268
  bib: "application/x-bibtex",
8265
8269
  dbk: "application/docbook+xml",
8266
8270
  docbook: "application/docbook+xml",
8267
- fb2: "application/x-fictionbook+xml"
8271
+ fb2: "application/x-fictionbook+xml",
8272
+ zip: "application/zip"
8268
8273
  };
8269
8274
  MIME_TO_EXTENSION = Object.entries(EXTENSION_TO_MIME).reduce((acc, [ext, mime]) => {
8270
8275
  if (!(mime in acc))
@@ -53623,7 +53628,8 @@ var init_steps = __esm(() => {
53623
53628
  "ai.segment",
53624
53629
  "ai.classify",
53625
53630
  "ai.classify-pages",
53626
- "ai.vision"
53631
+ "ai.vision",
53632
+ "ai.search-files"
53627
53633
  ];
53628
53634
  TRANSFORM_STEP_TYPES = [
53629
53635
  "transform.set",
@@ -53637,7 +53643,9 @@ var init_steps = __esm(() => {
53637
53643
  "transform.json-to-xlsx",
53638
53644
  "transform.script",
53639
53645
  "transform.text-chunker",
53640
- "transform.regex-extract"
53646
+ "transform.regex-extract",
53647
+ "transform.archive-list",
53648
+ "transform.archive-extract"
53641
53649
  ];
53642
53650
  ACTION_STEP_TYPES = [
53643
53651
  "action.http",
@@ -53779,7 +53787,7 @@ function getStepSchema(stepType) {
53779
53787
  function listStepTypes() {
53780
53788
  return [...STEP_TYPES];
53781
53789
  }
53782
- var OptionalReasoningEffortSchema, AiParseConfigSchema, AiParseOutputSchema, AiExtractConfigSchema, AiExtractOutputSchema, VisionPageRangeSchema, AiVisionConfigSchema, AiVisionOutputSchema, AiSplitConfigSchema, AiSplitSectionSchema, AiSplitOutputSchema, AiSegmentConfigSchema, AiSegmentOutputSchema, AiClassifyConfigSchema, AiClassifyOutputSchema, ClassifyPagesLabelSchema2, AiClassifyPagesConfigSchema, AiClassifyPagesOutputSchema, TransformSetConfigSchema, TransformSetOutputSchema, TransformRemoveConfigSchema, TransformRemoveOutputSchema, TransformCombineConfigSchema, TransformCombineOutputSchema, TransformSplitConfigSchema, TransformSplitOutputSchema, TransformMergeConfigSchema, TransformMergeOutputSchema, TransformTemplateConfigSchema, TransformTemplateOutputSchema, TransformPdfEmbedConfigSchema, TransformPdfEmbedOutputSchema, TransformXlsxToJsonConfigSchema, TransformXlsxToJsonOutputSchema, JsonToXlsxAuthoringRowsSchema, JsonToXlsxSheetConfigSchema, TransformJsonToXlsxConfigSchema, TransformJsonToXlsxOutputSchema, TransformScriptConfigSchema, TransformScriptOutputSchema, ParsedDocPageSchema, TransformTextChunkerConfigSchema, TransformTextChunkerOutputSchema, RegexNormalizerSchema, RegexFormatSchema, REGEX_FLAGS, RegexFieldSchema, TransformRegexExtractConfigSchema, TransformRegexExtractOutputSchema, ActionHttpConfigSchema, ActionHttpOutputSchema, ActionInvokeWorkflowConfigSchema, ActionInvokeWorkflowOutputSchema, ActionWebsiteReaderConfigSchema, ActionWebsiteReaderOutputSchema, ACTION_EMAIL_MAX_ATTACHMENTS = 10, ACTION_EMAIL_MAX_ATTACHMENT_BYTES, ACTION_EMAIL_BODY_MAX_BYTES, emailBodyMaxBytes = (value) => new TextEncoder().encode(value).byteLength <= ACTION_EMAIL_BODY_MAX_BYTES, ActionEmailRecipientListSchema, ActionEmailToSchema, ActionEmailOptionalRecipientsSchema, ActionEmailAttachmentSchema, ActionEmailConfigSchema, ActionEmailOutputSchema, ControlIfConfigSchema, ControlIfOutputSchema, ControlSwitchConfigSchema, ControlSwitchOutputSchema, ControlForeachConfigSchema, ControlForeachOutputSchema, ControlParallelMapConfigSchema, ControlParallelMapOutputSchema, ControlParallelConfigSchema, ControlParallelOutputSchema, ControlWaitConfigSchema, ControlWaitOutputSchema, ControlHumanReviewConfigSchema, ControlHumanReviewOutputSchema, ControlFailConfigSchema, ControlFailOutputSchema, STEP_SCHEMAS;
53790
+ var OptionalReasoningEffortSchema, AiParseConfigSchema, AiParseOutputSchema, AiExtractConfigSchema, AiExtractOutputSchema, VisionPageRangeSchema, AiVisionConfigSchema, AiVisionOutputSchema, AI_SEARCH_FILES_DEFAULT_MAX_ITERATIONS = 12, AI_SEARCH_FILES_MAX_ITERATIONS = 50, AI_SEARCH_FILES_DEFAULT_MAX_FILES = 50, AI_SEARCH_FILES_MAX_FILES = 200, AI_SEARCH_FILES_MAX_CITATION_EXCERPT_CHARS = 2000, AiSearchFilesConfigSchema, AiSearchFilesCitationSchema, AiSearchFilesOutputSchema, AiSplitConfigSchema, AiSplitSectionSchema, AiSplitOutputSchema, AiSegmentConfigSchema, AiSegmentOutputSchema, AiClassifyConfigSchema, AiClassifyOutputSchema, ClassifyPagesLabelSchema2, AiClassifyPagesConfigSchema, AiClassifyPagesOutputSchema, TransformSetConfigSchema, TransformSetOutputSchema, TransformRemoveConfigSchema, TransformRemoveOutputSchema, TransformCombineConfigSchema, TransformCombineOutputSchema, TransformSplitConfigSchema, TransformSplitOutputSchema, TransformMergeConfigSchema, TransformMergeOutputSchema, TransformTemplateConfigSchema, TransformTemplateOutputSchema, TransformPdfEmbedConfigSchema, TransformPdfEmbedOutputSchema, TransformXlsxToJsonConfigSchema, TransformXlsxToJsonOutputSchema, JsonToXlsxAuthoringRowsSchema, JsonToXlsxSheetConfigSchema, TransformJsonToXlsxConfigSchema, TransformJsonToXlsxOutputSchema, ARCHIVE_LIST_MAX_ENTRIES = 1e4, TransformArchiveListConfigSchema, TransformArchiveListEntrySchema, TransformArchiveListOutputSchema, TransformArchiveExtractConfigSchema, TransformArchiveExtractOutputSchema, TransformScriptConfigSchema, TransformScriptOutputSchema, ParsedDocPageSchema, TransformTextChunkerConfigSchema, TransformTextChunkerOutputSchema, RegexNormalizerSchema, RegexFormatSchema, REGEX_FLAGS, RegexFieldSchema, TransformRegexExtractConfigSchema, TransformRegexExtractOutputSchema, ActionHttpConfigSchema, ActionHttpOutputSchema, ActionInvokeWorkflowConfigSchema, ActionInvokeWorkflowOutputSchema, ActionWebsiteReaderConfigSchema, ActionWebsiteReaderOutputSchema, ACTION_EMAIL_MAX_ATTACHMENTS = 10, ACTION_EMAIL_MAX_ATTACHMENT_BYTES, ACTION_EMAIL_BODY_MAX_BYTES, emailBodyMaxBytes = (value) => new TextEncoder().encode(value).byteLength <= ACTION_EMAIL_BODY_MAX_BYTES, ActionEmailRecipientListSchema, ActionEmailToSchema, ActionEmailOptionalRecipientsSchema, ActionEmailAttachmentSchema, ActionEmailConfigSchema, ActionEmailOutputSchema, ControlIfConfigSchema, ControlIfOutputSchema, ControlSwitchConfigSchema, ControlSwitchOutputSchema, ControlForeachConfigSchema, ControlForeachOutputSchema, ControlParallelMapConfigSchema, ControlParallelMapOutputSchema, ControlParallelConfigSchema, ControlParallelOutputSchema, ControlWaitConfigSchema, ControlWaitOutputSchema, ControlHumanReviewConfigSchema, ControlHumanReviewOutputSchema, ControlFailConfigSchema, ControlFailOutputSchema, STEP_SCHEMAS;
53783
53791
  var init_step_configs = __esm(() => {
53784
53792
  init_zod();
53785
53793
  init_ai_client();
@@ -53860,6 +53868,25 @@ var init_step_configs = __esm(() => {
53860
53868
  maxPages: number2().int().positive().max(100).optional().describe(`Chunk size: the maximum pages sent to the vision model in a single call. When the inspected range (or the whole document) is larger, it is split into chunks of this size and the per-chunk results are merged by a reduce pass. The reduce follows each field's DESCRIPTION: a boolean described as "present on any page" is OR-ed, one described as "true for every page" is AND-ed, and list fields are concatenated. The merge is most reliable for boolean/scalar claims; for schemas that AGGREGATE long lists across chunks it can still drop or reorder items, so prefer a bounded page range for large list extraction. Default 20, capped at 100.`)
53861
53869
  });
53862
53870
  AiVisionOutputSchema = record(string2(), unknown()).describe("Structured data matching the provided schema. The output also carries a reserved `_vision` key recording the inspected source document ref and the page indices that were rendered, so the UI can re-rasterize exactly those pages client-side. `_vision` is excluded from user-schema validation.");
53871
+ AiSearchFilesConfigSchema = object({
53872
+ archive: string2().min(1).describe("Template expression or file reference for the ZIP archive to inspect. ZIP is the only accepted format in this version."),
53873
+ query: string2().min(1).describe("Natural-language question to answer from files inside the archive."),
53874
+ root: string2().optional().describe("Optional folder prefix inside the archive. When set, only files under this path are in scope."),
53875
+ provider: string2().optional().describe("Provider ID from eigenpal.config.yaml. Falls back to the tenant default LLM provider when omitted."),
53876
+ model: string2().optional().describe("Model override (advanced)."),
53877
+ reasoningEffort: OptionalReasoningEffortSchema,
53878
+ maxIterations: number2().int().min(1).max(AI_SEARCH_FILES_MAX_ITERATIONS).default(AI_SEARCH_FILES_DEFAULT_MAX_ITERATIONS).optional().describe(`Maximum investigation turns. Default ${AI_SEARCH_FILES_DEFAULT_MAX_ITERATIONS}, capped at ${AI_SEARCH_FILES_MAX_ITERATIONS}.`),
53879
+ maxFiles: number2().int().min(1).max(AI_SEARCH_FILES_MAX_FILES).default(AI_SEARCH_FILES_DEFAULT_MAX_FILES).optional().describe(`Maximum files the step may open. Default ${AI_SEARCH_FILES_DEFAULT_MAX_FILES}, capped at ${AI_SEARCH_FILES_MAX_FILES}.`)
53880
+ });
53881
+ AiSearchFilesCitationSchema = object({
53882
+ path: string2().min(1).describe("Archive-relative path of a file the step inspected and cited."),
53883
+ excerpt: string2().max(AI_SEARCH_FILES_MAX_CITATION_EXCERPT_CHARS).optional().describe("Optional excerpt copied from the inspected file text. Omitted when no verbatim excerpt was supplied.")
53884
+ });
53885
+ AiSearchFilesOutputSchema = object({
53886
+ answer: string2().min(1).describe("The investigation answer. Citations point at inspected files; the answer text itself is model-generated."),
53887
+ citations: array(AiSearchFilesCitationSchema).describe("Citations to files the step inspected. Excerpts, when present, are copied from inspected text."),
53888
+ filesInspected: array(string2()).describe("Archive-relative paths of files the step opened during investigation.")
53889
+ });
53863
53890
  AiSplitConfigSchema = object({
53864
53891
  input: string2().describe('Template expression resolving to ai.parse output, e.g. "{{ steps.parse.output }}"'),
53865
53892
  sections: array(object({
@@ -54136,6 +54163,33 @@ var init_step_configs = __esm(() => {
54136
54163
  limits: JsonToXlsxLimitsSchema.optional()
54137
54164
  }).superRefine(refineJsonToXlsxLayout);
54138
54165
  TransformJsonToXlsxOutputSchema = JsonToXlsxOutputSchema;
54166
+ TransformArchiveListConfigSchema = object({
54167
+ archive: string2().min(1).describe("Template expression or file reference for the ZIP archive to list. ZIP is the only accepted format in this version."),
54168
+ prefix: string2().optional().describe("Optional folder prefix inside the archive after path normalization (for example invoices or invoices/)."),
54169
+ search: string2().optional().describe("Optional case-insensitive substring match on the normalized archive path."),
54170
+ offset: number2().int().min(0).optional().describe("Number of matching entries to skip after sorting. Default 0."),
54171
+ limit: number2().int().min(1).max(ARCHIVE_LIST_MAX_ENTRIES).optional().describe(`Maximum matching entries to return after sorting. Capped at ${ARCHIVE_LIST_MAX_ENTRIES}. Omit to return every matching entry up to that cap.`)
54172
+ });
54173
+ TransformArchiveListEntrySchema = object({
54174
+ path: string2().describe("Normalized archive-relative path"),
54175
+ compressedSize: number2().int().min(0).describe("Declared compressed size in bytes"),
54176
+ uncompressedSize: number2().int().min(0).describe("Declared uncompressed size in bytes")
54177
+ });
54178
+ TransformArchiveListOutputSchema = object({
54179
+ entries: array(TransformArchiveListEntrySchema).describe("Matching files, sorted by normalized path. Directories and junk paths are omitted."),
54180
+ total: number2().int().min(0).describe("Number of matching entries before offset/limit pagination.")
54181
+ });
54182
+ TransformArchiveExtractConfigSchema = object({
54183
+ archive: string2().min(1).describe("Template expression or file reference for the ZIP archive. ZIP is the only accepted format in this version."),
54184
+ path: string2().min(1).describe("Archive-relative path of the single file to extract, for example {{ item.path }} from a prior archive-list step.")
54185
+ });
54186
+ TransformArchiveExtractOutputSchema = object({
54187
+ fileId: string2().describe("File ID from the files table"),
54188
+ path: string2().describe("Normalized archive-relative path that was extracted"),
54189
+ filename: string2().describe("Basename of the extracted file"),
54190
+ mimeType: string2().describe("Detected MIME type of the extracted file"),
54191
+ size: number2().int().min(0).describe("Uncompressed size in bytes")
54192
+ });
54139
54193
  TransformScriptConfigSchema = object({
54140
54194
  inputs: record(string2(), string2()).optional().describe("Named inputs mapped from template expressions. Keys become function parameters; parameter order is independent of YAML/JSON key order: `inputs: { items, taxRate }` accepts `function script(taxRate: …, items: …): R { … }`."),
54141
54195
  function: string2().min(1).max(SCRIPT_FN_MAX_BYTES, `script function is too long (max ${(SCRIPT_FN_MAX_BYTES / 1000).toFixed(0)}k characters)`).describe("TypeScript function declaration. Must be `function script(args): R { … }` where parameter names exactly match the configured input keys in any order and `R` is a return type annotation. The annotation IS this step's output schema."),
@@ -54483,6 +54537,15 @@ var init_step_configs = __esm(() => {
54483
54537
  outputSchema: AiVisionOutputSchema,
54484
54538
  configInWith: true
54485
54539
  },
54540
+ "ai.search-files": {
54541
+ type: "ai.search-files",
54542
+ category: "ai",
54543
+ name: "Search Files",
54544
+ description: "Investigate a ZIP archive with a question and return an answer plus file citations. Read-only: the step opens files in the archive and never writes back. ZIP is the only accepted format in this version. Optionally scope the search to a folder prefix and cap how many files and investigation turns may run.",
54545
+ configSchema: AiSearchFilesConfigSchema,
54546
+ outputSchema: AiSearchFilesOutputSchema,
54547
+ configInWith: true
54548
+ },
54486
54549
  "transform.set": {
54487
54550
  type: "transform.set",
54488
54551
  category: "transform",
@@ -54591,6 +54654,24 @@ var init_step_configs = __esm(() => {
54591
54654
  outputSchema: TransformRegexExtractOutputSchema,
54592
54655
  configInWith: true
54593
54656
  },
54657
+ "transform.archive-list": {
54658
+ type: "transform.archive-list",
54659
+ category: "transform",
54660
+ name: "List Archive",
54661
+ description: "List files inside a ZIP archive. Returns sorted normalized paths with compressed and uncompressed sizes. Optionally filter by folder prefix or substring, then page with offset and limit. ZIP is the only accepted format in this version. Pair with foreach or parallel_map and transform.archive-extract to open individual files.",
54662
+ configSchema: TransformArchiveListConfigSchema,
54663
+ outputSchema: TransformArchiveListOutputSchema,
54664
+ configInWith: true
54665
+ },
54666
+ "transform.archive-extract": {
54667
+ type: "transform.archive-extract",
54668
+ category: "transform",
54669
+ name: "Extract Archive File",
54670
+ description: "Extract exactly one file from a ZIP archive and store it as a run output file. Downstream steps can pass {{ steps.extract.output }} into Parse, Vision, or another archive step. Nested ZIPs are stored as ZIP files, not unpacked. Each extraction is capped at 64 MiB. ZIP is the only accepted format in this version.",
54671
+ configSchema: TransformArchiveExtractConfigSchema,
54672
+ outputSchema: TransformArchiveExtractOutputSchema,
54673
+ configInWith: true
54674
+ },
54594
54675
  "action.http": {
54595
54676
  type: "action.http",
54596
54677
  category: "action",
@@ -67561,7 +67642,7 @@ var require_errors3 = __commonJS(function(exports) {
67561
67642
  function endsWithError(value) {
67562
67643
  return typeof value === "string" && value.substring(value.length - DOMExceptionName.Error.length) === DOMExceptionName.Error;
67563
67644
  }
67564
- function DOMException(messageOrCode, nameOrMessage) {
67645
+ function DOMException2(messageOrCode, nameOrMessage) {
67565
67646
  if (isValidDomExceptionCode(messageOrCode)) {
67566
67647
  this.name = DOMExceptionNames[messageOrCode];
67567
67648
  this.message = nameOrMessage || "";
@@ -67570,10 +67651,10 @@ var require_errors3 = __commonJS(function(exports) {
67570
67651
  this.name = endsWithError(nameOrMessage) ? nameOrMessage : DOMExceptionName.Error;
67571
67652
  }
67572
67653
  if (Error.captureStackTrace)
67573
- Error.captureStackTrace(this, DOMException);
67654
+ Error.captureStackTrace(this, DOMException2);
67574
67655
  }
67575
- extendError(DOMException, true);
67576
- Object.defineProperties(DOMException.prototype, {
67656
+ extendError(DOMException2, true);
67657
+ Object.defineProperties(DOMException2.prototype, {
67577
67658
  code: {
67578
67659
  enumerable: true,
67579
67660
  get: function() {
@@ -67614,7 +67695,7 @@ var require_errors3 = __commonJS(function(exports) {
67614
67695
  var entries = Object.entries(ExceptionCode);
67615
67696
  for (i = 0;i < entries.length; i++) {
67616
67697
  key = entries[i][0];
67617
- DOMException[key] = entries[i][1];
67698
+ DOMException2[key] = entries[i][1];
67618
67699
  }
67619
67700
  var key;
67620
67701
  var i;
@@ -67625,7 +67706,7 @@ var require_errors3 = __commonJS(function(exports) {
67625
67706
  Error.captureStackTrace(this, ParseError);
67626
67707
  }
67627
67708
  extendError(ParseError);
67628
- exports.DOMException = DOMException;
67709
+ exports.DOMException = DOMException2;
67629
67710
  exports.DOMExceptionName = DOMExceptionName;
67630
67711
  exports.ExceptionCode = ExceptionCode;
67631
67712
  exports.ParseError = ParseError;
@@ -67821,7 +67902,7 @@ var require_dom = __commonJS(function(exports) {
67821
67902
  var NAMESPACE = conventions.NAMESPACE;
67822
67903
  var PDC = Symbol();
67823
67904
  var errors = require_errors3();
67824
- var DOMException = errors.DOMException;
67905
+ var DOMException2 = errors.DOMException;
67825
67906
  var DOMExceptionName = errors.DOMExceptionName;
67826
67907
  var g = require_grammar();
67827
67908
  function checkSymbol(symbol) {
@@ -67854,7 +67935,7 @@ var require_dom = __commonJS(function(exports) {
67854
67935
  }
67855
67936
  function validateQualifiedName(qualifiedName) {
67856
67937
  if (!g.QName_exact.test(qualifiedName)) {
67857
- throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in qualified name "' + qualifiedName + '"');
67938
+ throw new DOMException2(DOMException2.INVALID_CHARACTER_ERR, 'invalid character in qualified name "' + qualifiedName + '"');
67858
67939
  }
67859
67940
  }
67860
67941
  function validateAndExtract(namespace, qualifiedName) {
@@ -67868,16 +67949,16 @@ var require_dom = __commonJS(function(exports) {
67868
67949
  localName = splitResult[1];
67869
67950
  }
67870
67951
  if (prefix !== null && namespace === null) {
67871
- throw new DOMException(DOMException.NAMESPACE_ERR, "prefix is non-null and namespace is null");
67952
+ throw new DOMException2(DOMException2.NAMESPACE_ERR, "prefix is non-null and namespace is null");
67872
67953
  }
67873
67954
  if (prefix === "xml" && namespace !== conventions.NAMESPACE.XML) {
67874
- throw new DOMException(DOMException.NAMESPACE_ERR, 'prefix is "xml" and namespace is not the XML namespace');
67955
+ throw new DOMException2(DOMException2.NAMESPACE_ERR, 'prefix is "xml" and namespace is not the XML namespace');
67875
67956
  }
67876
67957
  if ((prefix === "xmlns" || qualifiedName === "xmlns") && namespace !== conventions.NAMESPACE.XMLNS) {
67877
- throw new DOMException(DOMException.NAMESPACE_ERR, 'either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace');
67958
+ throw new DOMException2(DOMException2.NAMESPACE_ERR, 'either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace');
67878
67959
  }
67879
67960
  if (namespace === conventions.NAMESPACE.XMLNS && prefix !== "xmlns" && qualifiedName !== "xmlns") {
67880
- throw new DOMException(DOMException.NAMESPACE_ERR, 'namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns"');
67961
+ throw new DOMException2(DOMException2.NAMESPACE_ERR, 'namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns"');
67881
67962
  }
67882
67963
  return [namespace, prefix, localName];
67883
67964
  }
@@ -68084,7 +68165,7 @@ var require_dom = __commonJS(function(exports) {
68084
68165
  setNamedItem: function(attr) {
68085
68166
  var el = attr.ownerElement;
68086
68167
  if (el && el !== this._ownerElement) {
68087
- throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
68168
+ throw new DOMException2(DOMException2.INUSE_ATTRIBUTE_ERR);
68088
68169
  }
68089
68170
  var oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName);
68090
68171
  if (oldAttr === attr) {
@@ -68099,7 +68180,7 @@ var require_dom = __commonJS(function(exports) {
68099
68180
  removeNamedItem: function(localName) {
68100
68181
  var attr = this.getNamedItem(localName);
68101
68182
  if (!attr) {
68102
- throw new DOMException(DOMException.NOT_FOUND_ERR, localName);
68183
+ throw new DOMException2(DOMException2.NOT_FOUND_ERR, localName);
68103
68184
  }
68104
68185
  _removeNamedNode(this._ownerElement, this, attr);
68105
68186
  return attr;
@@ -68107,7 +68188,7 @@ var require_dom = __commonJS(function(exports) {
68107
68188
  removeNamedItemNS: function(namespaceURI, localName) {
68108
68189
  var attr = this.getNamedItemNS(namespaceURI, localName);
68109
68190
  if (!attr) {
68110
- throw new DOMException(DOMException.NOT_FOUND_ERR, namespaceURI ? namespaceURI + " : " + localName : localName);
68191
+ throw new DOMException2(DOMException2.NOT_FOUND_ERR, namespaceURI ? namespaceURI + " : " + localName : localName);
68111
68192
  }
68112
68193
  _removeNamedNode(this._ownerElement, this, attr);
68113
68194
  return attr;
@@ -68540,7 +68621,7 @@ var require_dom = __commonJS(function(exports) {
68540
68621
  }
68541
68622
  function _removeChild(parentNode, child) {
68542
68623
  if (parentNode !== child.parentNode) {
68543
- throw new DOMException(DOMException.NOT_FOUND_ERR, "child's parent is not parent");
68624
+ throw new DOMException2(DOMException2.NOT_FOUND_ERR, "child's parent is not parent");
68544
68625
  }
68545
68626
  var oldPreviousSibling = child.previousSibling;
68546
68627
  var oldNextSibling = child.nextSibling;
@@ -68596,13 +68677,13 @@ var require_dom = __commonJS(function(exports) {
68596
68677
  }
68597
68678
  function assertPreInsertionValidity1to5(parent, node, child) {
68598
68679
  if (!hasValidParentNodeType(parent)) {
68599
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Unexpected parent node type " + parent.nodeType);
68680
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Unexpected parent node type " + parent.nodeType);
68600
68681
  }
68601
68682
  if (child && child.parentNode !== parent) {
68602
- throw new DOMException(DOMException.NOT_FOUND_ERR, "child not in parent");
68683
+ throw new DOMException2(DOMException2.NOT_FOUND_ERR, "child not in parent");
68603
68684
  }
68604
68685
  if (!hasInsertableNodeType(node) || isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE) {
68605
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Unexpected node type " + node.nodeType + " for parent node type " + parent.nodeType);
68686
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Unexpected node type " + node.nodeType + " for parent node type " + parent.nodeType);
68606
68687
  }
68607
68688
  }
68608
68689
  function assertPreInsertionValidityInDocument(parent, node, child) {
@@ -68611,27 +68692,27 @@ var require_dom = __commonJS(function(exports) {
68611
68692
  if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
68612
68693
  var nodeChildElements = nodeChildNodes.filter(isElementNode);
68613
68694
  if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
68614
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "More than one element or text in fragment");
68695
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "More than one element or text in fragment");
68615
68696
  }
68616
68697
  if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) {
68617
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype");
68698
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype");
68618
68699
  }
68619
68700
  }
68620
68701
  if (isElementNode(node)) {
68621
68702
  if (!isElementInsertionPossible(parent, child)) {
68622
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype");
68703
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype");
68623
68704
  }
68624
68705
  }
68625
68706
  if (isDocTypeNode(node)) {
68626
68707
  if (find(parentChildNodes, isDocTypeNode)) {
68627
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Only one doctype is allowed");
68708
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Only one doctype is allowed");
68628
68709
  }
68629
68710
  var parentElementChild = find(parentChildNodes, isElementNode);
68630
68711
  if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
68631
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element");
68712
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element");
68632
68713
  }
68633
68714
  if (!child && parentElementChild) {
68634
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Doctype can not be appended since element is present");
68715
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Doctype can not be appended since element is present");
68635
68716
  }
68636
68717
  }
68637
68718
  }
@@ -68641,15 +68722,15 @@ var require_dom = __commonJS(function(exports) {
68641
68722
  if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
68642
68723
  var nodeChildElements = nodeChildNodes.filter(isElementNode);
68643
68724
  if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
68644
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "More than one element or text in fragment");
68725
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "More than one element or text in fragment");
68645
68726
  }
68646
68727
  if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) {
68647
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype");
68728
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype");
68648
68729
  }
68649
68730
  }
68650
68731
  if (isElementNode(node)) {
68651
68732
  if (!isElementReplacementPossible(parent, child)) {
68652
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype");
68733
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype");
68653
68734
  }
68654
68735
  }
68655
68736
  if (isDocTypeNode(node)) {
@@ -68657,11 +68738,11 @@ var require_dom = __commonJS(function(exports) {
68657
68738
  return isDocTypeNode(node) && node !== child;
68658
68739
  };
68659
68740
  if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) {
68660
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Only one doctype is allowed");
68741
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Only one doctype is allowed");
68661
68742
  }
68662
68743
  var parentElementChild = find(parentChildNodes, isElementNode);
68663
68744
  if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
68664
- throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element");
68745
+ throw new DOMException2(DOMException2.HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element");
68665
68746
  }
68666
68747
  }
68667
68748
  }
@@ -68800,7 +68881,7 @@ var require_dom = __commonJS(function(exports) {
68800
68881
  },
68801
68882
  createCDATASection: function(data) {
68802
68883
  if (data.indexOf("]]>") !== -1) {
68803
- throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'data contains "]]>"');
68884
+ throw new DOMException2(DOMException2.INVALID_CHARACTER_ERR, 'data contains "]]>"');
68804
68885
  }
68805
68886
  var node = new CDATASection(PDC);
68806
68887
  node.ownerDocument = this;
@@ -68818,7 +68899,7 @@ var require_dom = __commonJS(function(exports) {
68818
68899
  },
68819
68900
  createAttribute: function(name) {
68820
68901
  if (!g.QName_exact.test(name)) {
68821
- throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in name "' + name + '"');
68902
+ throw new DOMException2(DOMException2.INVALID_CHARACTER_ERR, 'invalid character in name "' + name + '"');
68822
68903
  }
68823
68904
  if (this.type === "html") {
68824
68905
  name = name.toLowerCase();
@@ -68837,10 +68918,10 @@ var require_dom = __commonJS(function(exports) {
68837
68918
  },
68838
68919
  createEntityReference: function(name) {
68839
68920
  if (!g.Name.test(name)) {
68840
- throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"');
68921
+ throw new DOMException2(DOMException2.INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"');
68841
68922
  }
68842
68923
  if (this.type === "html") {
68843
- throw new DOMException("document is an html document", DOMExceptionName.NotSupportedError);
68924
+ throw new DOMException2("document is an html document", DOMExceptionName.NotSupportedError);
68844
68925
  }
68845
68926
  var node = new EntityReference(PDC);
68846
68927
  node.ownerDocument = this;
@@ -69297,7 +69378,7 @@ var require_dom = __commonJS(function(exports) {
69297
69378
  case DOCUMENT_NODE:
69298
69379
  case DOCUMENT_FRAGMENT_NODE:
69299
69380
  if (requireWellFormed && n.nodeType === DOCUMENT_NODE && n.documentElement == null) {
69300
- throw new DOMException("The Document has no documentElement", DOMExceptionName.InvalidStateError);
69381
+ throw new DOMException2("The Document has no documentElement", DOMExceptionName.InvalidStateError);
69301
69382
  }
69302
69383
  return { ns: namespaces };
69303
69384
  case ATTRIBUTE_NODE:
@@ -69305,13 +69386,13 @@ var require_dom = __commonJS(function(exports) {
69305
69386
  return null;
69306
69387
  case TEXT_NODE:
69307
69388
  if (requireWellFormed && g.InvalidChar.test(n.data)) {
69308
- throw new DOMException("The Text node data contains characters outside the XML Char production", DOMExceptionName.InvalidStateError);
69389
+ throw new DOMException2("The Text node data contains characters outside the XML Char production", DOMExceptionName.InvalidStateError);
69309
69390
  }
69310
69391
  buf.push(n.data.replace(/[<&>]/g, _xmlEncoder));
69311
69392
  return null;
69312
69393
  case CDATA_SECTION_NODE:
69313
69394
  if (requireWellFormed && n.data.indexOf("]]>") !== -1) {
69314
- throw new DOMException('The CDATASection data contains "]]>"', DOMExceptionName.InvalidStateError);
69395
+ throw new DOMException2('The CDATASection data contains "]]>"', DOMExceptionName.InvalidStateError);
69315
69396
  }
69316
69397
  if (splitCDATASections) {
69317
69398
  buf.push(g.CDATA_START, n.data.replace(/]]>/g, "]]]]><![CDATA[>"), g.CDATA_END);
@@ -69322,10 +69403,10 @@ var require_dom = __commonJS(function(exports) {
69322
69403
  case COMMENT_NODE:
69323
69404
  if (requireWellFormed) {
69324
69405
  if (g.InvalidChar.test(n.data)) {
69325
- throw new DOMException("The comment node data contains characters outside the XML Char production", DOMExceptionName.InvalidStateError);
69406
+ throw new DOMException2("The comment node data contains characters outside the XML Char production", DOMExceptionName.InvalidStateError);
69326
69407
  }
69327
69408
  if (n.data.indexOf("--") !== -1 || n.data[n.data.length - 1] === "-") {
69328
- throw new DOMException('The comment node data contains "--" or ends with "-"', DOMExceptionName.InvalidStateError);
69409
+ throw new DOMException2('The comment node data contains "--" or ends with "-"', DOMExceptionName.InvalidStateError);
69329
69410
  }
69330
69411
  }
69331
69412
  buf.push(g.COMMENT_START, n.data, g.COMMENT_END);
@@ -69335,13 +69416,13 @@ var require_dom = __commonJS(function(exports) {
69335
69416
  var sysid = n.systemId;
69336
69417
  if (requireWellFormed) {
69337
69418
  if (pubid && !g.PubidLiteral_match.test(pubid)) {
69338
- throw new DOMException("DocumentType publicId is not a valid PubidLiteral", DOMExceptionName.InvalidStateError);
69419
+ throw new DOMException2("DocumentType publicId is not a valid PubidLiteral", DOMExceptionName.InvalidStateError);
69339
69420
  }
69340
69421
  if (sysid && sysid !== "." && !g.SystemLiteral_match.test(sysid)) {
69341
- throw new DOMException("DocumentType systemId is not a valid SystemLiteral", DOMExceptionName.InvalidStateError);
69422
+ throw new DOMException2("DocumentType systemId is not a valid SystemLiteral", DOMExceptionName.InvalidStateError);
69342
69423
  }
69343
69424
  if (n.internalSubset && n.internalSubset.indexOf("]>") !== -1) {
69344
- throw new DOMException('DocumentType internalSubset contains "]>"', DOMExceptionName.InvalidStateError);
69425
+ throw new DOMException2('DocumentType internalSubset contains "]>"', DOMExceptionName.InvalidStateError);
69345
69426
  }
69346
69427
  }
69347
69428
  buf.push(g.DOCTYPE_DECL_START, " ", n.name);
@@ -69361,13 +69442,13 @@ var require_dom = __commonJS(function(exports) {
69361
69442
  case PROCESSING_INSTRUCTION_NODE:
69362
69443
  if (requireWellFormed) {
69363
69444
  if (n.target.indexOf(":") !== -1 || n.target.toLowerCase() === "xml") {
69364
- throw new DOMException("The ProcessingInstruction target is not well-formed", DOMExceptionName.InvalidStateError);
69445
+ throw new DOMException2("The ProcessingInstruction target is not well-formed", DOMExceptionName.InvalidStateError);
69365
69446
  }
69366
69447
  if (g.InvalidChar.test(n.data)) {
69367
- throw new DOMException("The ProcessingInstruction data contains characters outside the XML Char production", DOMExceptionName.InvalidStateError);
69448
+ throw new DOMException2("The ProcessingInstruction data contains characters outside the XML Char production", DOMExceptionName.InvalidStateError);
69368
69449
  }
69369
69450
  if (n.data.indexOf("?>") !== -1) {
69370
- throw new DOMException('The ProcessingInstruction data contains "?>"', DOMExceptionName.InvalidStateError);
69451
+ throw new DOMException2('The ProcessingInstruction data contains "?>"', DOMExceptionName.InvalidStateError);
69371
69452
  }
69372
69453
  }
69373
69454
  buf.push("<?", n.target, " ", n.data, "?>");
@@ -71702,7 +71783,7 @@ var require_sax = __commonJS(function(exports) {
71702
71783
  var hasOwn = conventions.hasOwn;
71703
71784
  var NAMESPACE = conventions.NAMESPACE;
71704
71785
  var ParseError = errors.ParseError;
71705
- var DOMException = errors.DOMException;
71786
+ var DOMException2 = errors.DOMException;
71706
71787
  var S_TAG = 0;
71707
71788
  var S_ATTR = 1;
71708
71789
  var S_ATTR_SPACE = 2;
@@ -71887,7 +71968,7 @@ var require_sax = __commonJS(function(exports) {
71887
71968
  } catch (e) {
71888
71969
  if (e instanceof ParseError) {
71889
71970
  throw e;
71890
- } else if (e instanceof DOMException) {
71971
+ } else if (e instanceof DOMException2) {
71891
71972
  throw new ParseError(e.name + ": " + e.message, domBuilder.locator, e);
71892
71973
  }
71893
71974
  errorHandler.error("element parse error: " + e);
@@ -206141,12 +206222,12 @@ var {
206141
206222
 
206142
206223
  // src/cli.ts
206143
206224
  import { realpathSync as realpathSync4 } from "fs";
206144
- import path19 from "path";
206225
+ import path20 from "path";
206145
206226
  import { fileURLToPath as fileURLToPath8 } from "url";
206146
206227
  // package.json
206147
206228
  var package_default = {
206148
206229
  name: "@eigenpal/cli",
206149
- version: "0.16.3",
206230
+ version: "0.16.4",
206150
206231
  description: "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
206151
206232
  keywords: [
206152
206233
  "eigenpal",
@@ -206228,6 +206309,57 @@ var package_default = {
206228
206309
  import { existsSync as existsSync12 } from "node:fs";
206229
206310
  import path16 from "node:path";
206230
206311
 
206312
+ // src/lib/api-paths.ts
206313
+ var API_PREFIX = "/v1";
206314
+ function apiPath(suffix) {
206315
+ if (suffix === "/v1" || suffix.startsWith("/v1/"))
206316
+ return suffix;
206317
+ if (suffix === "/api/v1" || suffix.startsWith("/api/v1/")) {
206318
+ return `${API_PREFIX}${suffix.slice("/api/v1".length)}`;
206319
+ }
206320
+ const normalized = suffix.startsWith("/") ? suffix : `/${suffix}`;
206321
+ return `${API_PREFIX}${normalized}`;
206322
+ }
206323
+ function canonicalApiPath(path) {
206324
+ if (path === "/api/v1" || path.startsWith("/api/v1/")) {
206325
+ return `${API_PREFIX}${path.slice("/api/v1".length)}`;
206326
+ }
206327
+ return path;
206328
+ }
206329
+ function parseBaseUrl(baseUrl) {
206330
+ return new URL(baseUrl.match(/^https?:\/\//i) ? baseUrl : `https://${baseUrl}`);
206331
+ }
206332
+ function endsWithApiPrefix(basePath) {
206333
+ return basePath === "/api" || basePath.endsWith("/api");
206334
+ }
206335
+ function endsWithApiV1Prefix(basePath) {
206336
+ return basePath === "/api/v1" || basePath.endsWith("/api/v1");
206337
+ }
206338
+ function resolveRequestUrl(baseUrl, path) {
206339
+ if (/^https?:\/\//i.test(path))
206340
+ return path;
206341
+ const requestPath = canonicalApiPath(path);
206342
+ const isCanonicalV1 = requestPath === API_PREFIX || requestPath.startsWith(`${API_PREFIX}/`);
206343
+ const base = parseBaseUrl(baseUrl);
206344
+ const basePath = base.pathname.replace(/\/+$/, "");
206345
+ if (isCanonicalV1) {
206346
+ if (endsWithApiV1Prefix(basePath)) {
206347
+ const suffix = requestPath === API_PREFIX ? "" : requestPath.slice(API_PREFIX.length);
206348
+ return `${base.origin}${basePath}${suffix}`;
206349
+ }
206350
+ if (endsWithApiPrefix(basePath)) {
206351
+ return `${base.origin}${basePath}${requestPath}`;
206352
+ }
206353
+ return `${base.origin}${requestPath}`;
206354
+ }
206355
+ if (requestPath.startsWith("/api/") && (endsWithApiPrefix(basePath) || endsWithApiV1Prefix(basePath))) {
206356
+ return `${base.origin}${requestPath}`;
206357
+ }
206358
+ if (!basePath)
206359
+ return `${base.origin}${requestPath}`;
206360
+ return `${base.origin}${basePath}${requestPath}`;
206361
+ }
206362
+
206231
206363
  // src/lib/client.ts
206232
206364
  class ApiError extends Error {
206233
206365
  status;
@@ -206265,11 +206397,8 @@ class ApiClient {
206265
206397
  this.apiKey = config.apiKey;
206266
206398
  this.tenantId = config.tenantId;
206267
206399
  }
206268
- resolvePath(path) {
206269
- if (path === "/api/v1" || path.startsWith("/api/v1/")) {
206270
- return `/v1${path.slice("/api/v1".length)}`;
206271
- }
206272
- return path;
206400
+ buildUrl(path) {
206401
+ return resolveRequestUrl(this.baseUrl, path);
206273
206402
  }
206274
206403
  headers(extra = {}) {
206275
206404
  return {
@@ -206299,7 +206428,7 @@ class ApiClient {
206299
206428
  return res;
206300
206429
  }
206301
206430
  async get(path, params) {
206302
- let url = `${this.baseUrl}${this.resolvePath(path)}`;
206431
+ let url = this.buildUrl(path);
206303
206432
  if (params) {
206304
206433
  const qs = new URLSearchParams(params).toString();
206305
206434
  if (qs)
@@ -206309,7 +206438,7 @@ class ApiClient {
206309
206438
  return this.handleResponse(res, url);
206310
206439
  }
206311
206440
  async post(path, body) {
206312
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206441
+ const url = this.buildUrl(path);
206313
206442
  const res = await fetch(url, {
206314
206443
  method: "POST",
206315
206444
  headers: this.headers({ "Content-Type": "application/json" }),
@@ -206318,7 +206447,7 @@ class ApiClient {
206318
206447
  return this.handleResponse(res, url);
206319
206448
  }
206320
206449
  async put(path, body) {
206321
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206450
+ const url = this.buildUrl(path);
206322
206451
  const res = await fetch(url, {
206323
206452
  method: "PUT",
206324
206453
  headers: this.headers({ "Content-Type": "application/json" }),
@@ -206327,7 +206456,7 @@ class ApiClient {
206327
206456
  return this.handleResponse(res, url);
206328
206457
  }
206329
206458
  async patch(path, body) {
206330
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206459
+ const url = this.buildUrl(path);
206331
206460
  const res = await fetch(url, {
206332
206461
  method: "PATCH",
206333
206462
  headers: this.headers({ "Content-Type": "application/json" }),
@@ -206336,7 +206465,7 @@ class ApiClient {
206336
206465
  return this.handleResponse(res, url);
206337
206466
  }
206338
206467
  async postFormData(path, formData) {
206339
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206468
+ const url = this.buildUrl(path);
206340
206469
  const res = await fetch(url, {
206341
206470
  method: "POST",
206342
206471
  headers: this.headers(),
@@ -206345,7 +206474,7 @@ class ApiClient {
206345
206474
  return this.handleResponse(res, url);
206346
206475
  }
206347
206476
  async putFormData(path, formData) {
206348
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206477
+ const url = this.buildUrl(path);
206349
206478
  const res = await fetch(url, {
206350
206479
  method: "PUT",
206351
206480
  headers: this.headers(),
@@ -206354,7 +206483,7 @@ class ApiClient {
206354
206483
  return this.handleResponse(res, url);
206355
206484
  }
206356
206485
  async delete(path) {
206357
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206486
+ const url = this.buildUrl(path);
206358
206487
  const res = await fetch(url, {
206359
206488
  method: "DELETE",
206360
206489
  headers: this.headers()
@@ -206362,7 +206491,7 @@ class ApiClient {
206362
206491
  return this.handleResponse(res, url);
206363
206492
  }
206364
206493
  async getStream(path) {
206365
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206494
+ const url = this.buildUrl(path);
206366
206495
  const res = await fetch(url, {
206367
206496
  headers: this.headers()
206368
206497
  });
@@ -206373,7 +206502,7 @@ class ApiClient {
206373
206502
  return res;
206374
206503
  }
206375
206504
  async postStream(path, body) {
206376
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206505
+ const url = this.buildUrl(path);
206377
206506
  const res = await fetch(url, {
206378
206507
  method: "POST",
206379
206508
  headers: this.headers({ "Content-Type": "application/json" }),
@@ -206383,7 +206512,7 @@ class ApiClient {
206383
206512
  return res;
206384
206513
  }
206385
206514
  async postFormDataStream(path, formData) {
206386
- const url = `${this.baseUrl}${this.resolvePath(path)}`;
206515
+ const url = this.buildUrl(path);
206387
206516
  const res = await fetch(url, {
206388
206517
  method: "POST",
206389
206518
  headers: this.headers(),
@@ -239209,7 +239338,8 @@ var EXT_MIME = {
239209
239338
  ".msg": "application/vnd.ms-outlook",
239210
239339
  ".json": "application/json",
239211
239340
  ".xml": "application/xml",
239212
- ".html": "text/html"
239341
+ ".html": "text/html",
239342
+ ".zip": "application/zip"
239213
239343
  };
239214
239344
  function guessMimeType(filename) {
239215
239345
  return EXT_MIME[extname3(filename).toLowerCase()] || "";
@@ -241423,18 +241553,6 @@ function matchingSnippet(content, terms) {
241423
241553
  return line.replace(/^[#>*\s-]+/, "").replace(/[`[\]{}]/g, "").trim().slice(0, 140);
241424
241554
  }
241425
241555
 
241426
- // src/lib/api-paths.ts
241427
- var API_PREFIX = "/v1";
241428
- function apiPath(suffix) {
241429
- if (suffix === "/v1" || suffix.startsWith("/v1/"))
241430
- return suffix;
241431
- if (suffix === "/api/v1" || suffix.startsWith("/api/v1/")) {
241432
- return `${API_PREFIX}${suffix.slice("/api/v1".length)}`;
241433
- }
241434
- const normalized = suffix.startsWith("/") ? suffix : `/${suffix}`;
241435
- return `${API_PREFIX}${normalized}`;
241436
- }
241437
-
241438
241556
  // src/lib/email-servers-cli.ts
241439
241557
  init_src();
241440
241558
  import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
@@ -242071,7 +242189,7 @@ init_src();
242071
242189
 
242072
242190
  // src/commands/run-form-data.ts
242073
242191
  import { promises as fs16 } from "node:fs";
242074
- import path17 from "node:path";
242192
+ import path18 from "node:path";
242075
242193
 
242076
242194
  // src/lib/upload-limits.ts
242077
242195
  var DEFAULT_MULTIPART_MAX_BYTES = Math.floor(4.5 * 1024 * 1024);
@@ -242119,42 +242237,382 @@ function multipartMaxBytesFromEnv(raw = env.EIGENPAL_MULTIPART_MAX_BYTES) {
242119
242237
 
242120
242238
  // src/lib/upload-reusable-file.ts
242121
242239
  import { randomUUID } from "node:crypto";
242240
+ import { createReadStream } from "node:fs";
242241
+ import { stat as stat2 } from "node:fs/promises";
242242
+ import path17 from "node:path";
242243
+
242244
+ // src/lib/fetch-body.ts
242245
+ function isNodeReadableStream(body) {
242246
+ return typeof body.pipe === "function";
242247
+ }
242248
+ function byteViewToArrayBuffer(view) {
242249
+ if (view.buffer instanceof ArrayBuffer && view.byteOffset === 0 && view.byteLength === view.buffer.byteLength) {
242250
+ return view.buffer;
242251
+ }
242252
+ const copy = new Uint8Array(view.byteLength);
242253
+ copy.set(view);
242254
+ return copy.buffer;
242255
+ }
242256
+ function toPutBody(body) {
242257
+ if (isNodeReadableStream(body)) {
242258
+ return body;
242259
+ }
242260
+ return byteViewToArrayBuffer(body);
242261
+ }
242262
+
242263
+ // src/lib/upload-presigned-multipart.ts
242264
+ var MULTIPART_UPLOAD_CONCURRENCY = 4;
242265
+ var MULTIPART_PART_MAX_RETRIES = 4;
242266
+ var MULTIPART_PART_RETRY_BASE_MS = 250;
242267
+ function expectedPartByteLength(totalSize, partSizeBytes, partNumber, partCount) {
242268
+ if (!Number.isInteger(partNumber) || partNumber < 1 || partNumber > partCount) {
242269
+ throw new Error(`partNumber must be an integer in [1, ${partCount}]`);
242270
+ }
242271
+ if (totalSize === 0)
242272
+ return 0;
242273
+ if (partNumber < partCount)
242274
+ return partSizeBytes;
242275
+ const remainder = totalSize % partSizeBytes;
242276
+ return remainder === 0 ? partSizeBytes : remainder;
242277
+ }
242278
+ function partByteOffset(partSizeBytes, partNumber) {
242279
+ return (partNumber - 1) * partSizeBytes;
242280
+ }
242281
+ function isTransientHttpStatus(status) {
242282
+ return status === 408 || status === 429 || status >= 500 && status <= 599;
242283
+ }
242284
+ function filterStorageHeaders(headers, stripContentLength) {
242285
+ return Object.fromEntries(Object.entries(headers ?? {}).filter(([name]) => stripContentLength ? name.toLowerCase() !== "content-length" : true));
242286
+ }
242287
+ function partIsAuthoritativelyComplete(listed, partNumber, expectedSize) {
242288
+ const found = listed.find((part) => part.partNumber === partNumber);
242289
+ if (!found)
242290
+ return false;
242291
+ return found.size === expectedSize;
242292
+ }
242293
+
242294
+ class PartUploadHttpError extends Error {
242295
+ status;
242296
+ constructor(status) {
242297
+ super(`Storage part upload failed (${status})`);
242298
+ this.status = status;
242299
+ this.name = "PartUploadHttpError";
242300
+ }
242301
+ }
242302
+ function isAbortError(error) {
242303
+ return error instanceof Error && error.name === "AbortError" || typeof DOMException !== "undefined" && error instanceof DOMException && error.name === "AbortError";
242304
+ }
242305
+ function shouldAbortMultipartUploadSession(options) {
242306
+ return !options.partsReady;
242307
+ }
242308
+ function multipartCompleteRetryHint(uploadId) {
242309
+ return `Uploaded parts remain stored for ${uploadId}; retry complete and do not abort the session.`;
242310
+ }
242311
+ function annotateMultipartCompleteFailure(uploadId, error) {
242312
+ const hint = multipartCompleteRetryHint(uploadId);
242313
+ if (error instanceof Error) {
242314
+ if (!error.message.includes("retry complete")) {
242315
+ error.message = `${error.message} ${hint}`;
242316
+ }
242317
+ return error;
242318
+ }
242319
+ return new Error(`${String(error)} ${hint}`);
242320
+ }
242321
+ function isRetryablePartError(error, signal) {
242322
+ if (signal?.aborted)
242323
+ return false;
242324
+ if (isAbortError(error))
242325
+ return false;
242326
+ if (error instanceof PartUploadHttpError)
242327
+ return isTransientHttpStatus(error.status);
242328
+ return true;
242329
+ }
242330
+ async function sleep(ms, signal) {
242331
+ if (signal?.aborted)
242332
+ throw abortError(signal);
242333
+ await new Promise((resolve, reject) => {
242334
+ const timer = setTimeout(resolve, ms);
242335
+ const onAbort = () => {
242336
+ clearTimeout(timer);
242337
+ reject(abortError(signal));
242338
+ };
242339
+ signal?.addEventListener("abort", onAbort, { once: true });
242340
+ });
242341
+ }
242342
+ function abortError(signal) {
242343
+ if (signal?.reason instanceof Error)
242344
+ return signal.reason;
242345
+ return typeof DOMException !== "undefined" ? new DOMException("Upload aborted", "AbortError") : Object.assign(new Error("Upload aborted"), { name: "AbortError" });
242346
+ }
242347
+ async function mapPool(items, concurrency, signal, worker) {
242348
+ if (items.length === 0)
242349
+ return;
242350
+ let cursor = 0;
242351
+ let firstError;
242352
+ await Promise.all(Array.from({ length: Math.min(Math.max(1, concurrency), items.length) }, async () => {
242353
+ while (firstError == null) {
242354
+ if (signal?.aborted)
242355
+ throw abortError(signal);
242356
+ const index = cursor++;
242357
+ if (index >= items.length)
242358
+ return;
242359
+ try {
242360
+ await worker(items[index]);
242361
+ } catch (error) {
242362
+ firstError ??= error;
242363
+ }
242364
+ }
242365
+ }));
242366
+ if (firstError)
242367
+ throw firstError;
242368
+ }
242369
+ async function uploadPresignedMultipartParts(options) {
242370
+ const concurrency = options.concurrency ?? MULTIPART_UPLOAD_CONCURRENCY;
242371
+ let uploadedBytes = 0;
242372
+ const credited = new Set;
242373
+ const credit = (partNumber, length) => {
242374
+ if (credited.has(partNumber))
242375
+ return;
242376
+ credited.add(partNumber);
242377
+ uploadedBytes += length;
242378
+ options.onProgress?.(uploadedBytes, options.totalSize);
242379
+ };
242380
+ const pendingPartNumbers = async () => {
242381
+ const listed = await options.listParts();
242382
+ const pending = [];
242383
+ for (let partNumber = 1;partNumber <= options.partCount; partNumber++) {
242384
+ const length = expectedPartByteLength(options.totalSize, options.partSizeBytes, partNumber, options.partCount);
242385
+ if (partIsAuthoritativelyComplete(listed, partNumber, length)) {
242386
+ credit(partNumber, length);
242387
+ continue;
242388
+ }
242389
+ pending.push(partNumber);
242390
+ }
242391
+ return pending;
242392
+ };
242393
+ const uploadOne = async (partNumber) => {
242394
+ const length = expectedPartByteLength(options.totalSize, options.partSizeBytes, partNumber, options.partCount);
242395
+ const start = partByteOffset(options.partSizeBytes, partNumber);
242396
+ let lastError;
242397
+ for (let attempt = 0;attempt <= MULTIPART_PART_MAX_RETRIES; attempt++) {
242398
+ if (options.signal?.aborted)
242399
+ throw abortError(options.signal);
242400
+ try {
242401
+ const signed = await options.presignPart(partNumber);
242402
+ const partLength = Number.isInteger(signed.partSizeBytes) ? signed.partSizeBytes : length;
242403
+ await options.putPart({
242404
+ url: signed.url,
242405
+ headers: signed.headers ?? {},
242406
+ partNumber,
242407
+ start,
242408
+ length: partLength
242409
+ });
242410
+ credit(partNumber, length);
242411
+ return;
242412
+ } catch (error) {
242413
+ lastError = error;
242414
+ if (!isRetryablePartError(error, options.signal) || attempt === MULTIPART_PART_MAX_RETRIES) {
242415
+ throw error;
242416
+ }
242417
+ await sleep(MULTIPART_PART_RETRY_BASE_MS * 2 ** attempt, options.signal);
242418
+ }
242419
+ }
242420
+ throw lastError;
242421
+ };
242422
+ let pending = await pendingPartNumbers();
242423
+ if (pending.length > 0) {
242424
+ await mapPool(pending, concurrency, options.signal, uploadOne);
242425
+ }
242426
+ pending = await pendingPartNumbers();
242427
+ if (pending.length > 0) {
242428
+ await mapPool(pending, concurrency, options.signal, uploadOne);
242429
+ pending = await pendingPartNumbers();
242430
+ }
242431
+ if (pending.length > 0) {
242432
+ throw new Error(`Upload incomplete: ${pending.length} part(s) missing from storage before complete`);
242433
+ }
242434
+ }
242435
+
242436
+ // src/lib/upload-reusable-file.ts
242122
242437
  function newIdempotencyKey() {
242123
242438
  return randomUUID();
242124
242439
  }
242125
242440
  async function uploadReusableFile(client, input) {
242126
- const contentType = input.mimeType || guessMimeType(input.filename) || "application/octet-stream";
242441
+ const source = await resolveUploadSource(input);
242127
242442
  const idempotencyKey = input.idempotencyKey ?? newIdempotencyKey();
242128
242443
  const negotiation = await client.post(apiPath("/files/uploads"), {
242129
- filename: input.filename,
242130
- contentType,
242131
- size: input.content.byteLength,
242444
+ filename: source.filename,
242445
+ contentType: source.contentType,
242446
+ size: source.size,
242132
242447
  idempotencyKey,
242133
242448
  ...input.purpose ? { purpose: input.purpose } : {}
242134
242449
  });
242135
- if (input.content.byteLength > negotiation.maxFileSizeBytes) {
242450
+ if (source.size > negotiation.maxFileSizeBytes) {
242136
242451
  throw new Error(`File too large. Maximum size: ${Math.floor(negotiation.maxFileSizeBytes / (1024 * 1024))}MB`);
242137
242452
  }
242138
242453
  if (negotiation.transport === "multipart") {
242454
+ const bytes = source.kind === "buffer" ? source.content : await readWholeFile(source.filePath);
242139
242455
  const form = new FormData;
242140
- form.append("file", new Blob([input.content], { type: contentType }), input.filename);
242456
+ form.append("file", new Blob([bytes], { type: source.contentType }), source.filename);
242141
242457
  if (input.purpose)
242142
242458
  form.append("purpose", input.purpose);
242143
- return await client.postFormData(negotiation.url, form);
242459
+ return await client.postFormData(apiPath(negotiation.url), form);
242144
242460
  }
242145
- const putHeaders = Object.fromEntries(Object.entries(negotiation.headers ?? {}).filter(([name]) => name.toLowerCase() !== "content-length"));
242146
- const putResponse = await fetch(negotiation.url, {
242147
- method: "PUT",
242148
- headers: putHeaders,
242149
- body: new Uint8Array(input.content)
242150
- });
242151
- if (!putResponse.ok) {
242152
- await client.delete(apiPath(`/files/uploads/${negotiation.uploadId}`)).catch(() => {
242153
- return;
242461
+ if (negotiation.transport === "presigned-multipart") {
242462
+ return uploadPresignedMultipart(client, source, negotiation);
242463
+ }
242464
+ let putReady = false;
242465
+ try {
242466
+ const putBody = source.kind === "buffer" ? toPutBody(new Uint8Array(source.content)) : toPutBody(createReadStream(source.filePath));
242467
+ const putResponse = await putStorageObject(negotiation.url, negotiation.headers, putBody, {
242468
+ stream: source.kind === "path",
242469
+ expectedByteLength: source.size
242154
242470
  });
242155
- throw new Error(`Storage upload failed (${putResponse.status}); retry the upload`);
242471
+ if (!putResponse.ok) {
242472
+ throw new Error(`Storage upload failed (${putResponse.status}); retry the upload`);
242473
+ }
242474
+ putReady = true;
242475
+ } catch (error) {
242476
+ if (shouldAbortPresignedPutUploadSession({ putReady })) {
242477
+ await client.delete(apiPath(`/files/uploads/${negotiation.uploadId}`)).catch(() => {
242478
+ return;
242479
+ });
242480
+ }
242481
+ throw error;
242482
+ }
242483
+ try {
242484
+ return await client.post(apiPath(`/files/uploads/${negotiation.uploadId}/complete`), {});
242485
+ } catch (error) {
242486
+ throw annotatePresignedPutCompleteFailure(negotiation.uploadId, error);
242156
242487
  }
242157
- return await client.post(apiPath(`/files/uploads/${negotiation.uploadId}/complete`), {});
242488
+ }
242489
+ async function resolveUploadSource(input) {
242490
+ const contentType = input.mimeType || guessMimeType(input.filename) || "application/octet-stream";
242491
+ if ("filePath" in input && input.filePath) {
242492
+ const info = await stat2(input.filePath);
242493
+ if (!info.isFile()) {
242494
+ throw new Error(`Upload path is not a file: ${input.filePath}`);
242495
+ }
242496
+ return {
242497
+ kind: "path",
242498
+ filePath: input.filePath,
242499
+ size: info.size,
242500
+ filename: input.filename || path17.basename(input.filePath),
242501
+ contentType
242502
+ };
242503
+ }
242504
+ if (!("content" in input) || input.content === undefined) {
242505
+ throw new Error("Upload requires either content or filePath");
242506
+ }
242507
+ return {
242508
+ kind: "buffer",
242509
+ content: input.content,
242510
+ size: input.content.byteLength,
242511
+ filename: input.filename,
242512
+ contentType
242513
+ };
242514
+ }
242515
+ async function uploadPresignedMultipart(client, source, session) {
242516
+ const partsPath = apiPath(session.partsUrl);
242517
+ const completePath = apiPath(session.completeUrl);
242518
+ let partsReady = false;
242519
+ try {
242520
+ await uploadPresignedMultipartParts({
242521
+ partCount: session.partCount,
242522
+ partSizeBytes: session.partSizeBytes,
242523
+ totalSize: source.size,
242524
+ listParts: async () => {
242525
+ const body = await client.get(partsPath);
242526
+ return body.parts ?? [];
242527
+ },
242528
+ presignPart: async (partNumber) => {
242529
+ return await client.post(partsPath, { partNumber });
242530
+ },
242531
+ putPart: async ({ url, headers, start, length }) => {
242532
+ const body = source.kind === "buffer" ? toPutBody(source.content.subarray(start, start + length)) : length === 0 ? toPutBody(new Uint8Array) : toPutBody(createReadStream(source.filePath, { start, end: start + length - 1 }));
242533
+ const response = await putStorageObject(url, headers, body, {
242534
+ stream: source.kind === "path" && length > 0,
242535
+ expectedByteLength: length
242536
+ });
242537
+ if (!response.ok)
242538
+ throw new PartUploadHttpError(response.status);
242539
+ }
242540
+ });
242541
+ partsReady = true;
242542
+ return await client.post(completePath, {});
242543
+ } catch (error) {
242544
+ if (shouldAbortMultipartUploadSession({ partsReady })) {
242545
+ await client.delete(apiPath(`/files/uploads/${session.uploadId}`)).catch(() => {
242546
+ return;
242547
+ });
242548
+ throw error;
242549
+ }
242550
+ throw annotateMultipartCompleteFailure(session.uploadId, error);
242551
+ }
242552
+ }
242553
+ function destroyUnreadNodeReadable(stream) {
242554
+ const readable = stream;
242555
+ if (!readable.readableEnded && !readable.destroyed && typeof readable.destroy === "function") {
242556
+ readable.destroy();
242557
+ }
242558
+ }
242559
+ async function ensureNodeReadableFullySent(stream, expectedByteLength) {
242560
+ const readable = stream;
242561
+ if (readable.readableEnded) {
242562
+ return expectedByteLength ?? 0;
242563
+ }
242564
+ if (readable.destroyed) {
242565
+ throw new Error("Upload stream was destroyed before the request body finished sending");
242566
+ }
242567
+ let bytes = 0;
242568
+ for await (const chunk of stream) {
242569
+ bytes += typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.length;
242570
+ }
242571
+ if (expectedByteLength !== undefined && bytes !== expectedByteLength) {
242572
+ throw new Error(`Upload sent ${bytes} byte(s) but ${expectedByteLength} were expected for this part`);
242573
+ }
242574
+ return bytes;
242575
+ }
242576
+ function shouldAbortPresignedPutUploadSession(options) {
242577
+ return !options.putReady;
242578
+ }
242579
+ function presignedPutCompleteRetryHint(uploadId) {
242580
+ return `Uploaded object remains stored for ${uploadId}; retry complete and do not abort the session.`;
242581
+ }
242582
+ function annotatePresignedPutCompleteFailure(uploadId, error) {
242583
+ const hint = presignedPutCompleteRetryHint(uploadId);
242584
+ if (error instanceof Error) {
242585
+ if (!error.message.includes("retry complete")) {
242586
+ error.message = `${error.message} ${hint}`;
242587
+ }
242588
+ return error;
242589
+ }
242590
+ return new Error(`${String(error)} ${hint}`);
242591
+ }
242592
+ async function putStorageObject(url, headers, body, options) {
242593
+ const stream = options.stream && isNodeReadableStream(body);
242594
+ const init = {
242595
+ method: "PUT",
242596
+ headers: filterStorageHeaders(headers, !stream),
242597
+ body,
242598
+ ...stream ? { duplex: "half" } : {}
242599
+ };
242600
+ let response;
242601
+ try {
242602
+ response = await fetch(url, init);
242603
+ } catch (error) {
242604
+ if (stream)
242605
+ destroyUnreadNodeReadable(body);
242606
+ throw error;
242607
+ }
242608
+ if (stream) {
242609
+ await ensureNodeReadableFullySent(body, options.expectedByteLength);
242610
+ }
242611
+ return response;
242612
+ }
242613
+ async function readWholeFile(filePath) {
242614
+ const { readFile } = await import("node:fs/promises");
242615
+ return readFile(filePath);
242158
242616
  }
242159
242617
 
242160
242618
  // src/commands/run-form-data.ts
@@ -242173,12 +242631,16 @@ async function buildPreparedRunRequest(client, input) {
242173
242631
  };
242174
242632
  const localFiles = [];
242175
242633
  for (const spec of parseInputFileSpecs(input.inputFile ?? [])) {
242176
- const data = await fs16.readFile(spec.filePath);
242634
+ const info = await fs16.stat(spec.filePath);
242635
+ if (!info.isFile()) {
242636
+ throw new Error(`--input-file path is not a file: ${spec.filePath}`);
242637
+ }
242177
242638
  localFiles.push({
242178
242639
  fieldName: spec.fieldName,
242179
- content: data,
242180
- filename: path17.basename(spec.filePath),
242181
- mimeType: guessMimeType(path17.basename(spec.filePath)) || "application/octet-stream"
242640
+ filePath: spec.filePath,
242641
+ filename: path18.basename(spec.filePath),
242642
+ mimeType: guessMimeType(path18.basename(spec.filePath)) || "application/octet-stream",
242643
+ size: info.size
242182
242644
  });
242183
242645
  }
242184
242646
  for (const file of input.files ?? []) {
@@ -242187,10 +242649,11 @@ async function buildPreparedRunRequest(client, input) {
242187
242649
  fieldName: file.fieldName,
242188
242650
  content,
242189
242651
  filename: file.filename,
242190
- mimeType: file.mimeType || guessMimeType(file.filename) || "application/octet-stream"
242652
+ mimeType: file.mimeType || guessMimeType(file.filename) || "application/octet-stream",
242653
+ size: content.byteLength
242191
242654
  });
242192
242655
  }
242193
- const preUploadIndices = indicesRequiringPreUpload(localFiles.map((file) => ({ size: file.content.byteLength })));
242656
+ const preUploadIndices = indicesRequiringPreUpload(localFiles.map((file) => ({ size: file.size })));
242194
242657
  upgradeMixedFieldPreUpload(localFiles, preUploadIndices);
242195
242658
  const preUploadRefsByField = new Map;
242196
242659
  const preUploadIdempotencyKeys = localFiles.map(() => newIdempotencyKey());
@@ -242198,7 +242661,13 @@ async function buildPreparedRunRequest(client, input) {
242198
242661
  const file = localFiles[index];
242199
242662
  if (!preUploadIndices.has(index))
242200
242663
  continue;
242201
- const uploaded = await uploadReusableFile(client, {
242664
+ const uploaded = await uploadReusableFile(client, file.filePath ? {
242665
+ filePath: file.filePath,
242666
+ filename: file.filename,
242667
+ mimeType: file.mimeType,
242668
+ purpose: "run-input",
242669
+ idempotencyKey: preUploadIdempotencyKeys[index]
242670
+ } : {
242202
242671
  content: file.content,
242203
242672
  filename: file.filename,
242204
242673
  mimeType: file.mimeType,
@@ -242221,7 +242690,8 @@ async function buildPreparedRunRequest(client, input) {
242221
242690
  if (input.metadata)
242222
242691
  form.append("metadata", JSON.stringify(input.metadata));
242223
242692
  for (const file of remaining) {
242224
- appendFilePart(form, file.fieldName, file.content, file.filename, file.mimeType);
242693
+ const content = file.content ?? (file.filePath ? await fs16.readFile(file.filePath) : Buffer.alloc(0));
242694
+ appendFilePart(form, file.fieldName, content, file.filename, file.mimeType);
242225
242695
  }
242226
242696
  return { form, hasMultipartFiles: remaining.length > 0 };
242227
242697
  }
@@ -243697,7 +244167,7 @@ function looksLikeFreeform(prop) {
243697
244167
  }
243698
244168
  // src/commands/workflow/index.ts
243699
244169
  import { existsSync as existsSync23, promises as fs20 } from "node:fs";
243700
- import path18 from "node:path";
244170
+ import path19 from "node:path";
243701
244171
 
243702
244172
  // src/lib/local-templates.ts
243703
244173
  init_src();
@@ -245361,7 +245831,7 @@ async function readDirAsZip2(dir) {
245361
245831
  for (const e of entries) {
245362
245832
  if (e.name.startsWith(".") || e.name === "node_modules")
245363
245833
  continue;
245364
- const full = path18.join(current, e.name);
245834
+ const full = path19.join(current, e.name);
245365
245835
  const rel = relPrefix ? `${relPrefix}/${e.name}` : e.name;
245366
245836
  if (e.isDirectory())
245367
245837
  await walk(full, rel);
@@ -245886,7 +246356,7 @@ skip in CI). Folder layout reference: \`packages/cli/src/skill/reference/dataset
245886
246356
  }
245887
246357
  const stat = await fs20.stat(opts.file);
245888
246358
  const data = stat.isDirectory() ? await readDirAsZip2(opts.file) : new Uint8Array(await fs20.readFile(opts.file));
245889
- const filename = stat.isDirectory() ? `${path18.basename(opts.file)}.zip` : opts.file;
246359
+ const filename = stat.isDirectory() ? `${path19.basename(opts.file)}.zip` : opts.file;
245890
246360
  const formData = new FormData;
245891
246361
  formData.append("file", new Blob([data]), filename);
245892
246362
  formData.append("mode", opts.mode);
@@ -246478,7 +246948,7 @@ Behavior:
246478
246948
  const url = `/v1/automations/${workflowId}/experiments/${batchId}`;
246479
246949
  const dest = opts.pull ? opts.pullOnComplete ?? `./results-${batchId}.${opts.format}` : null;
246480
246950
  if (dest) {
246481
- const dir = path18.dirname(dest);
246951
+ const dir = path19.dirname(dest);
246482
246952
  if (!existsSync23(dir)) {
246483
246953
  error2(`Destination directory does not exist: ${dir}. Create it first or pass a path under an existing directory.`);
246484
246954
  process.exit(2);
@@ -247193,7 +247663,7 @@ function commandLineWidth(cmd) {
247193
247663
  }
247194
247664
 
247195
247665
  // src/cli.ts
247196
- var __filename3 = path19.resolve(fileURLToPath8(import.meta.url));
247666
+ var __filename3 = path20.resolve(fileURLToPath8(import.meta.url));
247197
247667
  var program2 = new Command2;
247198
247668
  var cliVersion = package_default.version === "0.0.0-placeholder" ? "dev" : package_default.version;
247199
247669
  program2.name("eigenpal").description("Eigenpal CLI — AI workflows, evals, and experiments").enablePositionalOptions().version(cliVersion, "-v, --version", "Print the CLI version and exit").option("-q, --quiet", "Suppress informational status output (success/info/dim). Errors and warnings still print; --json output is unaffected.").hook("preAction", () => {