@eigenpal/cli 0.16.3 → 0.16.5

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