@pipelex/sdk 0.48.1 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Pipelex-product wire models — the snake_case JSON shapes the hosted-product
3
- * routes (`/v1/me`, `/v1/methods` and its examples, `/v1/organizations`, `/v1/billing/*`,
3
+ * routes (`/v1/me`, `/v1/methods` and its examples, `/v1/organizations`, `/v1/branding`, `/v1/billing/*`,
4
4
  * `/v1/pipelex-api-keys`, `/v1/onboarding/submit`,
5
- * `/v1/resolve-storage-url`, `/v1/upload`, `/v1/upload/grant`, `/v1/runs`) speak.
5
+ * `/v1/resolve-storage-url`, `/v1/upload`, `/v1/upload/grant`, `/v1/files`, `/v1/runs`) speak.
6
6
  *
7
7
  * These are the management surface a consumer (today `pipelex-app`) hand-rolls.
8
8
  * The wire is snake_case; any camelCase remap is a consumer's UI concern and
@@ -359,8 +359,8 @@ export interface MethodVersionPage {
359
359
  }
360
360
  /**
361
361
  * One saved example of a method — what `createMethodExample`, `getMethodExample`,
362
- * `updateMethodExample` and both arms of `recordMethodExampleLatestRun` answer, and a row of
363
- * `listMethodExamples`.
362
+ * `updateMethodExample` and both arms of `recordMethodExampleLatestRun` and
363
+ * `saveAssistantMethodExample` answer, and a row of `listMethodExamples`.
364
364
  */
365
365
  export interface MethodExample {
366
366
  /** The example's id, `ex_…`, minted by the platform. */
@@ -399,6 +399,13 @@ export interface MethodExample {
399
399
  created_at: string;
400
400
  /** ISO-8601 UTC instant of its last change: its name, its inputs or its latest run. */
401
401
  updated_at: string;
402
+ /**
403
+ * Whether the build assistant keeps this example's inputs current with its test inputs: `true`
404
+ * on an example the assistant's save created (`saveAssistantMethodExample`), `false` on every
405
+ * other, and `false` from the first inputs change that is not the assistant's own. A rename
406
+ * leaves it as it is.
407
+ */
408
+ kept_by_assistant: boolean;
402
409
  }
403
410
  /** The create — `createMethodExample`, `POST /v1/methods/{id}/examples`. */
404
411
  export interface MethodExampleCreateInput {
@@ -465,6 +472,49 @@ export interface MethodExampleLatestRunStale {
465
472
  * method being deleted are thrown as `ApiResponseError` instead.
466
473
  */
467
474
  export type MethodExampleLatestRunResult = MethodExampleLatestRunRecorded | MethodExampleLatestRunStale;
475
+ /**
476
+ * The build assistant's save — `saveAssistantMethodExample`,
477
+ * `POST /v1/methods/{id}/examples/assistant-save`: its new test inputs, and the example it read as
478
+ * its own with the revision it read it at, both or neither.
479
+ */
480
+ export interface MethodExampleAssistantSaveInput {
481
+ /** The name a new example takes, 1 to 200 characters and not blank; an example kept current keeps its own. */
482
+ name: string;
483
+ /** The assistant's test inputs, a JSON object; a `bigint` in them is sent as its exact digits. */
484
+ inputs: Record<string, unknown>;
485
+ /**
486
+ * The assistant's example the caller read, the method's newest with `kept_by_assistant` true,
487
+ * to keep current. Omitted, or `null`, the save creates a new example.
488
+ */
489
+ example_id?: string | null;
490
+ /** The `input_revision` the caller read that example at; given with `example_id` and only with it. */
491
+ input_revision?: number | null;
492
+ }
493
+ /** What an assistant save did — the discriminant of `MethodExampleAssistantSaveResult`. */
494
+ export type MethodExampleAssistantSaveOutcome = "kept" | "created";
495
+ /**
496
+ * The named example was still the assistant's at the revision read, and now holds the inputs;
497
+ * `example` is it as it now stands, its name untouched.
498
+ */
499
+ export interface MethodExampleAssistantKept {
500
+ outcome: "kept";
501
+ example: MethodExample;
502
+ }
503
+ /**
504
+ * A new example, flagged as the assistant's, holds the inputs under the save's `name`: none was
505
+ * named, or a person's edit, another save or a deletion took the named one first.
506
+ */
507
+ export interface MethodExampleAssistantCreated {
508
+ outcome: "created";
509
+ example: MethodExample;
510
+ }
511
+ /**
512
+ * The answer of `saveAssistantMethodExample`, a `200` discriminated on `outcome`. Finding that a
513
+ * person has taken the example is the expected course of events whenever a person edits the
514
+ * assistant's inputs while it works, so it is answered rather than thrown: remember the answer's
515
+ * `example` as the assistant's from then on.
516
+ */
517
+ export type MethodExampleAssistantSaveResult = MethodExampleAssistantKept | MethodExampleAssistantCreated;
468
518
  /** Query for one page of a method's examples. */
469
519
  export interface ListMethodExamplesQuery {
470
520
  /**
@@ -513,6 +563,93 @@ export interface MembershipsResponse {
513
563
  memberships: Membership[];
514
564
  active_org_feature_flags: string[];
515
565
  }
566
+ /**
567
+ * One colour set: the button, accent and header colours, each `#rrggbb` in lower case, or `null`
568
+ * when not set. The platform always sends all three keys.
569
+ */
570
+ export interface BrandingColors {
571
+ /** The button colour. */
572
+ action: string | null;
573
+ /** The accent colour: links, the active tab, the brand ink. */
574
+ accent: string | null;
575
+ /** The header band's colour. */
576
+ header: string | null;
577
+ }
578
+ /**
579
+ * What the platform recorded about a logo when it accepted it.
580
+ *
581
+ * `content_type` is the type the platform read from the file's own bytes, never the type the
582
+ * upload declared: `image/png`, `image/jpeg`, `image/webp` or `image/svg+xml`. `width` and
583
+ * `height` are the image's size in pixels for a raster, oriented as a browser draws it, and for an
584
+ * SVG its `width` and `height` in pixels when both are in absolute units, which is the size a
585
+ * browser draws it at, else the width and height of its `viewBox`; an SVG's may be fractional.
586
+ * Their ratio is the logo's shape, which sizes its box before the image loads.
587
+ */
588
+ export interface LogoDescriptor {
589
+ /**
590
+ * The platform's own copy of the logo, `pipelex-storage://<org_id>/branding/<uuid>.<ext>`, never
591
+ * the upload URI the write sent: the platform copies a logo it accepts, under a fresh uuid each
592
+ * time, so the same bytes attached again get a new URI. Sending it back unchanged in its slot
593
+ * keeps the logo. `resolveStorageUrl` turns it into a short-lived link to its bytes.
594
+ */
595
+ uri: string;
596
+ /** The SHA-256 of the logo's bytes, 64 lower-case hexadecimal digits: a cache key for them. */
597
+ sha256: string;
598
+ content_type: string;
599
+ width: number;
600
+ height: number;
601
+ }
602
+ /**
603
+ * An organization's branding — what `getBranding` and `updateOrganizationBranding` answer.
604
+ *
605
+ * `colors` is the light set and `dark_colors` the dark one, used in dark mode only: a dark colour
606
+ * that is `null` falls back to the light colour of the same role, and a light one that is `null`
607
+ * to Pipelex's own palette. A logo is `null` when its slot is empty. A personal workspace, or a
608
+ * team that set nothing, answers every colour and logo `null`.
609
+ */
610
+ export interface OrganizationBranding {
611
+ org_id: string;
612
+ /** The organization's display name, the wordmark a client shows when it has no logo. */
613
+ org_name: string;
614
+ colors: BrandingColors;
615
+ dark_colors: BrandingColors;
616
+ /** The square logo, for the organization menu and small headers. */
617
+ square_logo: LogoDescriptor | null;
618
+ /** The wide logo, at least one and a half times as wide as it is tall, for an app's header. */
619
+ wide_logo: LogoDescriptor | null;
620
+ }
621
+ /**
622
+ * Changes to one colour set. A key set to a colour sets it, a key set to `null` clears it, and a
623
+ * key left out keeps its value. A colour is `#rrggbb` in either case, stored in lower case; the
624
+ * platform refuses anything else with a `422` `validation_failed` whose `errors[]` entry names the
625
+ * key, such as `colors.action`.
626
+ */
627
+ export interface BrandingColorsUpdate {
628
+ action?: string | null;
629
+ accent?: string | null;
630
+ header?: string | null;
631
+ }
632
+ /**
633
+ * The body of `updateOrganizationBranding`: every key optional, a value sets it, `null` clears it,
634
+ * and a key left out keeps its value, so `{}` writes nothing and answers the branding as it
635
+ * stands.
636
+ *
637
+ * - `colors` and `dark_colors` take a `BrandingColorsUpdate`, or `null` to clear all three
638
+ * colours of that set.
639
+ * - `square_logo` and `wide_logo` take the `pipelex-storage://` URI of a file the organization
640
+ * uploaded on its own (`requestUploadGrant` or `upload`) to set a new logo, the `uri` the
641
+ * branding answers for that slot to keep it, or `null` to remove it. Any other URI, a run's or
642
+ * a method's file, a stale `branding/` copy or the other slot's logo, is refused as
643
+ * `logo_not_an_upload`, so a logo cannot move between slots by its URI. The platform reads and
644
+ * measures an upload before it accepts it, keeps its own copy under `branding/`, whose URI it
645
+ * answers, and erases the copy a write replaces or clears; the upload is left as it is.
646
+ */
647
+ export interface OrganizationBrandingUpdate {
648
+ colors?: BrandingColorsUpdate | null;
649
+ dark_colors?: BrandingColorsUpdate | null;
650
+ square_logo?: string | null;
651
+ wide_logo?: string | null;
652
+ }
516
653
  export interface SubscriptionResponse {
517
654
  plan: string | null;
518
655
  status: string | null;
@@ -597,52 +734,570 @@ export interface UploadInput {
597
734
  filename: string;
598
735
  data: string;
599
736
  content_type: string;
737
+ /** What the upload is recorded as; `uploaded` when omitted. */
738
+ kind?: UploadKind;
739
+ /**
740
+ * The bare catalog id of the method a `test` file is for, required with `kind: "test"`
741
+ * and refused without it.
742
+ */
743
+ method_id?: string;
600
744
  }
745
+ /** The answer to `POST /v1/upload`: the stored file's reference, its name and its record. */
601
746
  export interface UploadedFile {
747
+ /** The file's `pipelex-storage://` reference. */
602
748
  uri: string;
749
+ /** The name as sent. */
603
750
  filename: string;
751
+ /**
752
+ * The file's record, `fl_<uuid7>`, written `stored`, as an upload grant's `file_id` is.
753
+ * Absent from a deployment that predates file records, which answers none.
754
+ */
755
+ file_id?: string;
604
756
  }
757
+ /**
758
+ * What an upload is recorded as: `uploaded`, a person's file, or `test`, a test input
759
+ * made for one method, which names that method in `method_id`.
760
+ */
761
+ export type UploadKind = "uploaded" | "test";
605
762
  /**
606
763
  * What an upload grant is requested for — `POST /v1/upload/grant`. The file is
607
764
  * described, never sent: its bytes go to storage with the grant, from wherever
608
- * they are held.
765
+ * they are held. `describeUpload` reads this description off a `File` or a `Blob`,
766
+ * its SHA-256 included.
609
767
  */
610
768
  export interface UploadGrantInput {
611
769
  /** The original filename with its extension; the stored object keeps the extension. */
612
770
  filename: string;
613
771
  /**
614
- * MIME type, signed into the grant so the upload must carry it. Omitted, `null`
615
- * or empty, none is signed — a browser's `File.type` is empty for a type it
616
- * does not know, and means the same.
772
+ * The MIME type the file is declared as. The platform types the stored object by
773
+ * the name's extension and never stores this one, which serves only a name with no
774
+ * extension. Omitted, `null` or empty, none is declared — a browser's `File.type` is
775
+ * empty for a type it does not know, and means the same.
617
776
  */
618
777
  content_type?: string | null;
619
778
  /** The file's exact size in bytes. The grant accepts a body of this size and no other. */
620
779
  size: number;
780
+ /**
781
+ * The SHA-256 of the file's bytes, as 64 lowercase hexadecimal digits. With it, the
782
+ * object is named after its bytes, so a file the organization already holds is not
783
+ * sent again: the grant answers `stored: true`. Without it, the grant always names a
784
+ * new object and asks for the bytes. Any other string is a `422`, and so is a `size`
785
+ * other than the one the organization holds those bytes at (`blob_mismatch`).
786
+ */
787
+ sha256?: string;
788
+ /** What the upload is recorded as; `uploaded` when omitted. */
789
+ kind?: UploadKind;
790
+ /**
791
+ * The bare catalog id of the method a `test` file is for, required with `kind: "test"`
792
+ * and refused without it.
793
+ */
794
+ method_id?: string;
621
795
  }
622
796
  /**
623
- * A presigned, create-only `PUT` for one new object in the caller's organization,
624
- * and the `pipelex-storage://` URI that object will carry. A bearer capability
625
- * until `expires_at`: whoever holds it can write that one object, once, so it is
797
+ * The answer to an upload grant request: the file's record and `pipelex-storage://`
798
+ * URI, and either the news that the organization already holds the bytes
799
+ * (`stored: true`) or a presigned, create-only `PUT` to send them with. **Branch on
800
+ * `stored`, never on whether `url` is present.** A grant with a target is a bearer
801
+ * capability until `expires_at`: whoever holds it can write that one object, so it is
626
802
  * never logged. `uploadWithGrant` (also on the browser-safe `@pipelex/sdk/upload`
627
- * entry) is the sender.
803
+ * entry) is the sender, and sends nothing for a stored grant.
628
804
  */
629
805
  export interface UploadGrant {
630
- /** The reference the object carries — it names nothing until the `PUT` has succeeded. */
806
+ /**
807
+ * The file's record, `fl_<uuid7>`, `stored` once the bytes are and `pending` before.
808
+ * Absent from a deployment that predates file records, which answers none.
809
+ */
810
+ file_id?: string;
811
+ /**
812
+ * The reference the file carries. With `stored: false`, it names nothing until the
813
+ * `PUT` has succeeded.
814
+ */
631
815
  uri: string;
632
- /** Where to `PUT` the file, as the raw request body. */
633
- url: string;
634
816
  /**
635
- * The signed headers to send unchanged: `If-None-Match: *`, the `Content-Type`
636
- * when one was declared, and the provenance `x-amz-meta-*` values. `Content-Length`
637
- * is signed too but is not listed — the body sets it, so the body must be
638
- * exactly the declared size.
817
+ * `true` when the organization already holds these bytes: nothing is to be sent, and
818
+ * `uri` and `file_id` name the file now. `false` when the bytes go to `url`. Absent from
819
+ * a deployment that predates hashed uploads, whose grant is always a target, so an
820
+ * absent `stored` reads as `false`, as `uploadWithGrant` reads it.
639
821
  */
640
- headers: Record<string, string>;
641
- /** ISO-8601 UTC instant after which storage refuses the `PUT`. */
642
- expires_at: string;
822
+ stored?: boolean;
823
+ /** Where to `PUT` the file, as the raw request body; `null` when `stored`. */
824
+ url: string | null;
825
+ /**
826
+ * The signed headers to send unchanged, `null` when `stored`: `If-None-Match: *`,
827
+ * the `Content-Type` the name's extension implies, the provenance `x-amz-meta-*`
828
+ * values and, when the grant was asked for with a `sha256`, the checksum
829
+ * `x-amz-checksum-sha256`, which storage holds the body to. `Content-Length` is
830
+ * signed too but is not listed — the body sets it, so the body must be exactly the
831
+ * declared size.
832
+ */
833
+ headers: Record<string, string> | null;
834
+ /** ISO-8601 UTC instant after which storage refuses the `PUT`; `null` when `stored`. */
835
+ expires_at: string | null;
643
836
  /** The largest file any grant allows, in bytes (the service's upload cap). */
644
837
  max_bytes: number;
645
838
  }
839
+ /**
840
+ * What made a file: `uploaded`, a person's upload or a run's inline input; `generated`, a file a
841
+ * run made whose result reaches it; `test`, a test input made for one method, which its
842
+ * `origin.method_id` names.
843
+ */
844
+ export type FileKind = "uploaded" | "generated" | "test";
845
+ /**
846
+ * Who or what made a file, as far as the platform knows it. Each kind fills a different part, and
847
+ * the rest is `null`: an upload names the surface it came through; a generated file or a run's
848
+ * inline input names the run, its method and the version or draft that ran; a test file names the
849
+ * surface it came through and the method it was made for. The member a file is attributed to is
850
+ * the record's `created_by`, never repeated here.
851
+ */
852
+ export interface FileOrigin {
853
+ /**
854
+ * The surface an upload came through, as its request's `User-Agent` declared it (`app`, `mcp`,
855
+ * `cli`, `n8n`, `hook`, `sdk`, `raw_http`, and more as surfaces are added); `null` for a run's
856
+ * files. Self-declared, so it is provenance to show, never authority.
857
+ */
858
+ surface: string | null;
859
+ /** The run that made the file; `null` for an upload. */
860
+ run_id: string | null;
861
+ /** The method whose run made the file, or the method a test file was made for; `null` otherwise. */
862
+ method_id: string | null;
863
+ /**
864
+ * The published version number or `"draft"` that ran, for a file made by a saved method's run;
865
+ * `null` otherwise.
866
+ */
867
+ method_version: number | "draft" | null;
868
+ }
869
+ /**
870
+ * One row of a file list, what a list or a picker shows. A list never holds a file a run made
871
+ * along the way, nor an upload whose bytes have not been seen stored.
872
+ */
873
+ export interface FileSummary {
874
+ /** The record's id, `fl_…`. */
875
+ file_id: string;
876
+ /** The `pipelex-storage://` address of the bytes, which a run's inputs take as they take any address. */
877
+ uri: string;
878
+ /** The name shown and used for downloads; it starts as the name the file arrived with and changes with a rename. */
879
+ name: string;
880
+ /** The MIME type the object is stored under. */
881
+ media_type: string;
882
+ /** The format key the list's `format` filter matches: `pdf`, `docx`, `image`, `html` and the rest of the runtime's table. */
883
+ format: string;
884
+ /** The byte size. */
885
+ size: number;
886
+ kind: FileKind;
887
+ origin: FileOrigin;
888
+ /** ISO-8601 instant the record was made. */
889
+ created_at: string;
890
+ /** The member the file is attributed to: the uploader, or the member who started the run that made it. */
891
+ created_by: string;
892
+ }
893
+ /**
894
+ * Query for one page of an organization's files — `GET /v1/files`. Every member is optional, and
895
+ * each is sent only when given, so an empty string is sent and refused by the API rather than
896
+ * dropped into an unfiltered list.
897
+ *
898
+ * `methodId`, `runId` and `createdBy` choose which list serves the page: a method's list, a
899
+ * run's own list, one member's, or, with none of them, the organization's. The other members
900
+ * filter whichever list serves it, after the index read, so a filtered page can hold fewer rows
901
+ * than `limit`, or none, and still carry a `nextCursor`.
902
+ */
903
+ export interface ListFilesQuery {
904
+ /** A case-insensitive search in a file's name and the name it arrived with, applied server-side; at most 200 characters. */
905
+ q?: string;
906
+ /** Only the files of this kind. */
907
+ kind?: FileKind;
908
+ /**
909
+ * Only the files of one of these format keys (`pdf`, `image`, …), sent as one repeated
910
+ * `format=` parameter per value; at most 100. An empty list names no format and is a
911
+ * `RequestArgumentError` before any request, since sent as no parameter it would list every
912
+ * format.
913
+ */
914
+ format?: readonly string[];
915
+ /**
916
+ * Only the files of one of these MIME types (`image/png`, …), sent as one repeated
917
+ * `media_type=` parameter per value; at most 100. An empty list is refused as `format`'s is.
918
+ */
919
+ mediaType?: readonly string[];
920
+ /** The method's list, by its bare catalog id: the files its runs and examples took or made. Sent as `method_id`. */
921
+ methodId?: string;
922
+ /**
923
+ * The run's own list: its final outputs and its inline inputs, in the order of their addresses
924
+ * rather than newest first. Beside `methodId`, the run's list when the method is the run's own,
925
+ * and an empty page otherwise. The files a run took from the organization as inputs are not in
926
+ * it. Sent as `run_id`.
927
+ */
928
+ runId?: string;
929
+ /** One member's files by user id, or `"me"` for the caller's own: their uploads and their runs' outputs. Sent as `created_by`. */
930
+ createdBy?: string;
931
+ /**
932
+ * Only the files created at or after this INSTANT, ISO-8601 with a UTC offset
933
+ * (`2026-10-01T00:00:00Z`), inclusive. A bare date or a naive timestamp is refused by the API
934
+ * with a `400`. Sent as `created_from`.
935
+ */
936
+ createdFrom?: string;
937
+ /** Only the files created at or before this instant. Same rules as `createdFrom`. Sent as `created_to`. */
938
+ createdTo?: string;
939
+ /** Page size, from 1 to 200; the API defaults to 50 and refuses one outside that range with a `422`. */
940
+ limit?: number;
941
+ /** Opaque `nextCursor` from the previous page, bound to the list and the filters that issued it. */
942
+ cursor?: string;
943
+ }
944
+ /**
945
+ * One page of an organization's files, newest first (in the order of their addresses under
946
+ * `runId`).
947
+ *
948
+ * `nextCursor` is opaque — pass it straight back to `listFiles` with the same filters to
949
+ * continue; `null` means this was the last page. A filtered page can hold fewer rows than
950
+ * `limit`, or none, and still carry a `nextCursor`: only a `null` cursor ends the list, and
951
+ * `iterateFiles` keeps following the cursor through such a page. There is deliberately no total.
952
+ */
953
+ export interface FilePage {
954
+ items: FileSummary[];
955
+ nextCursor: string | null;
956
+ }
957
+ /**
958
+ * For a file a run made, whether the run's result reaches it: `final`, an output of the run, or
959
+ * `intermediate`, a file made along the way, which no list holds.
960
+ */
961
+ export type FileRole = "final" | "intermediate";
962
+ /** Whether a file's bytes are stored: `stored`, or `pending` while an upload's bytes have not been seen. */
963
+ export type FileState = "stored" | "pending";
964
+ /**
965
+ * One file's whole record — what `renameFile` answers, each record `getFilesByUri` lists, and the
966
+ * `file` of a run's file entry; `getFile` answers it with its methods and uses (`FileDetail`). It
967
+ * is a `FileSummary` with the members a list leaves out.
968
+ */
969
+ export interface FileRecord extends FileSummary {
970
+ /**
971
+ * The address the record was written under, once another run or an example took the file and
972
+ * the platform copied it into the organization's `assets/`; `uri` is then the copy's. `null`
973
+ * until then.
974
+ */
975
+ source_uri: string | null;
976
+ /** The name the file arrived with, never changed: a rename changes `name` alone. */
977
+ original_name: string;
978
+ /**
979
+ * The SHA-256 of the bytes in lowercase hexadecimal, or `null` for a file stored before every
980
+ * writer sent one.
981
+ */
982
+ sha256: string | null;
983
+ /** For a file a run made, `final` or `intermediate`; `null` for the other kinds. */
984
+ role: FileRole | null;
985
+ /** `stored`, or `pending` while an upload's bytes have not been seen. */
986
+ state: FileState;
987
+ }
988
+ /** What holds an address a use links: a run that took it as an input, or an example that holds it. */
989
+ export type FileUseHolderType = "run" | "example";
990
+ /**
991
+ * An address taken as an input by a run, or held by an example. A use names an address, not a
992
+ * record, so every record holding the address shows the same uses; a file a run made names that
993
+ * run in its `origin`, never as a use.
994
+ */
995
+ export interface FileUse {
996
+ /** The `pipelex-storage://` address used. */
997
+ uri: string;
998
+ holder_type: FileUseHolderType;
999
+ /** The run's id or the example's id. */
1000
+ holder_id: string;
1001
+ /** The method of the run or of the example; `null` for a run of no saved method. */
1002
+ method_id: string | null;
1003
+ /** ISO-8601 instant the use was recorded. */
1004
+ created_at: string;
1005
+ }
1006
+ /**
1007
+ * One page of a file's uses, the examples that hold its address first, then the runs that took
1008
+ * it. It is a member of `FileDetail`, as the platform serializes it: pass `next_cursor` back to
1009
+ * `getFile` as `usesCursor` for the next page; `null` means there is none.
1010
+ */
1011
+ export interface FileUsePage {
1012
+ items: FileUse[];
1013
+ next_cursor: string | null;
1014
+ }
1015
+ /** One file with what links it to the organization's methods, runs and examples — `getFile`. */
1016
+ export interface FileDetail extends FileRecord {
1017
+ /** The methods whose list of files holds this one, because one of their runs or examples took or made it. */
1018
+ method_ids: string[];
1019
+ /** One page of the file's uses. */
1020
+ uses: FileUsePage;
1021
+ }
1022
+ /** Query of `getFile`, for the page of the file's uses it answers. */
1023
+ export interface GetFileQuery {
1024
+ /** How many uses the page holds, from 1 to 200; the API defaults to 50. Sent as `uses_limit`. */
1025
+ usesLimit?: number;
1026
+ /** The previous answer's `uses.next_cursor`. Sent as `uses_cursor`. */
1027
+ usesCursor?: string;
1028
+ }
1029
+ /** Options of `getFilesByUri`. */
1030
+ export interface GetFilesByUriOptions {
1031
+ /**
1032
+ * The run whose input the address is: the records of the member who started it come first, so
1033
+ * a run's inputs show the name its starter gave the file. Sent as `run_id`.
1034
+ */
1035
+ runId?: string;
1036
+ }
1037
+ /**
1038
+ * The records holding one address — `getFilesByUri` — in the order a surface picks the one to
1039
+ * show, the first being it. Empty for an address no record holds, such as a file stored before
1040
+ * the platform kept records.
1041
+ */
1042
+ export interface FileRecordList {
1043
+ items: FileRecord[];
1044
+ }
1045
+ /** The rename — `renameFile`, `PATCH /v1/files/{file_id}`. */
1046
+ export interface FileRenameInput {
1047
+ /**
1048
+ * The new name, at most 512 characters. The platform removes the characters no list or header
1049
+ * can show, trims the ends, refuses a name with nothing left, and adds the file's own extension,
1050
+ * the one its `original_name` ends with, when the name does not end with it, case aside.
1051
+ */
1052
+ name: string;
1053
+ }
1054
+ /** One file to link — `linkFiles` — named by exactly one of its record's id and its address. */
1055
+ export type FileLinkTarget = {
1056
+ file_id: string;
1057
+ uri?: never;
1058
+ } | {
1059
+ uri: string;
1060
+ file_id?: never;
1061
+ };
1062
+ /**
1063
+ * Why one file got no link — a value, never a thrown error. `code` is `not_found` (an unknown file,
1064
+ * or one deleted meanwhile), `conflict` (a file whose upload has not finished), `invalid_storage_uri`
1065
+ * (a malformed address) or `forbidden` (another organization's address); `detail` is the sentence
1066
+ * a person reads.
1067
+ */
1068
+ export interface FileLinkError {
1069
+ code: string;
1070
+ detail: string;
1071
+ }
1072
+ /**
1073
+ * One requested file's link, or why it has none. Either the link members are set and `error` is
1074
+ * `null`, or `error` is set and they are `null`. Branch on `error`, never on the HTTP status: the
1075
+ * request is a `200` whenever every file got a verdict.
1076
+ */
1077
+ export type FileLink = {
1078
+ /**
1079
+ * The record linked: the one asked for, or for an address, the record whose name the link
1080
+ * carries; `null` for an address no record holds, a file stored before records existed.
1081
+ */
1082
+ file_id: string | null;
1083
+ /** The address the link reads. */
1084
+ uri: string;
1085
+ /** The name the download saves under, which the link's `Content-Disposition` carries. */
1086
+ name: string;
1087
+ /** The file's type, which decides whether a browser shows it in place or downloads it. */
1088
+ media_type: string;
1089
+ /** A presigned `GET` of the file, valid for fifteen minutes; a bearer capability, so keep it out of logs. */
1090
+ url: string;
1091
+ /** ISO-8601 UTC instant the link stops working. */
1092
+ expires_at: string;
1093
+ error: null;
1094
+ } | {
1095
+ /** The file id as requested, or `null` when the file was named by its address. */
1096
+ file_id: string | null;
1097
+ /** The address as requested, or `null` when the file was named by its id. */
1098
+ uri: string | null;
1099
+ name: null;
1100
+ media_type: null;
1101
+ url: null;
1102
+ expires_at: null;
1103
+ error: FileLinkError;
1104
+ };
1105
+ /** The answer of `linkFiles`: exactly one `FileLink` per requested file, in the request's order. */
1106
+ export interface FileLinksResult {
1107
+ items: FileLink[];
1108
+ }
1109
+ /**
1110
+ * Where an archive stands: `queued` and `building`, read it again shortly; `ready`, its `url`
1111
+ * downloads the zip; `failed`, its `failure` says why, and a new request is the remedy.
1112
+ */
1113
+ export type FileArchiveState = "queued" | "building" | "ready" | "failed";
1114
+ /** How an archive's files were chosen: `files`, by their ids, or `run`, as one run's files. */
1115
+ export type FileArchiveSource = "files" | "run";
1116
+ /**
1117
+ * Why an archive failed: `file_gone`, a selected file was deleted before the zip was ready;
1118
+ * `build_failed`, the build failed or did not finish within the hour. Asking again is the remedy
1119
+ * for both.
1120
+ */
1121
+ export type FileArchiveFailureCode = "file_gone" | "build_failed";
1122
+ /** What a failed archive says about its failure. */
1123
+ export interface FileArchiveFailure {
1124
+ code: FileArchiveFailureCode;
1125
+ /** A sentence for a person, naming the file when one was gone. */
1126
+ detail: string;
1127
+ }
1128
+ /**
1129
+ * One zip of an organization's files — what `requestFileArchive` (`queued`) and `getFileArchive`
1130
+ * answer. An archive is never a file: no list shows it, and it is gone a day after it was asked
1131
+ * for, past `expires_at`, when reading it answers `404`.
1132
+ */
1133
+ export interface FileArchive {
1134
+ /** The archive's id, `arc_…`. */
1135
+ archive_id: string;
1136
+ /** The name the zip downloads under, ending in `.zip`. */
1137
+ name: string;
1138
+ state: FileArchiveState;
1139
+ source: FileArchiveSource;
1140
+ /** The run whose files the archive holds, for a `run` archive; `null` otherwise. */
1141
+ run_id: string | null;
1142
+ /** How many files the zip holds. */
1143
+ file_count: number;
1144
+ /** The files' total size in bytes, before compression. */
1145
+ total_bytes: number;
1146
+ /** ISO-8601 instant the archive was asked for. */
1147
+ created_at: string;
1148
+ /** ISO-8601 instant after which the archive is gone and reads as unknown, a day after `created_at`. */
1149
+ expires_at: string;
1150
+ /** The zip's own size in bytes, once it is ready; `null` until then. */
1151
+ archive_bytes: number | null;
1152
+ /** ISO-8601 instant the zip was complete; `null` until then. */
1153
+ ready_at: string | null;
1154
+ /** Why the archive failed; `null` unless `state` is `failed`. */
1155
+ failure: FileArchiveFailure | null;
1156
+ /**
1157
+ * A presigned `GET` of the zip, valid for fifteen minutes and signed with a `Content-Disposition`
1158
+ * naming `name`, set only on a read of a `ready` archive; each read signs a fresh one. A bearer
1159
+ * capability, so keep it out of logs.
1160
+ */
1161
+ url: string | null;
1162
+ /** ISO-8601 instant `url` stops working; `null` without a link. */
1163
+ url_expires_at: string | null;
1164
+ }
1165
+ /**
1166
+ * The request — `requestFileArchive`, `POST /v1/files/archives` — naming the files by exactly one
1167
+ * of `file_ids` and `run_id`.
1168
+ *
1169
+ * - `file_ids`: any of the organization's files, in the order the zip holds them, at least one; an
1170
+ * id given twice is zipped once. At most 500 files once duplicates are removed and 1,000 ids
1171
+ * listed.
1172
+ * - `run_id`: a run of the organization, whose zip holds what went in and what came out, never a
1173
+ * file it made along the way nor an input given as a web link.
1174
+ *
1175
+ * `name` is the name the zip downloads under, `.zip` added when it does not end with it; omitted,
1176
+ * or with nothing usable left once the platform cleans it, the platform names it
1177
+ * `files-<run_id>.zip` or `files-<YYYYMMDD-HHMMSS>.zip`.
1178
+ */
1179
+ export type FileArchiveRequest = {
1180
+ file_ids: readonly string[];
1181
+ run_id?: never;
1182
+ name?: string;
1183
+ } | {
1184
+ run_id: string;
1185
+ file_ids?: never;
1186
+ name?: string;
1187
+ };
1188
+ /**
1189
+ * The cap a `422` `file_archive_too_large` names, read from the refusal's
1190
+ * `ApiResponseError.problemDocument.limit`: `max_files` (500) or `max_total_bytes`
1191
+ * (2,000,000,000), its `value`, and what the selection `reached`. For a run, the count stops as
1192
+ * soon as it passes the cap, so `reached` is one more than `max_files` and means "at least".
1193
+ */
1194
+ export interface FileArchiveLimit {
1195
+ name: "max_files" | "max_total_bytes";
1196
+ value: number;
1197
+ reached: number;
1198
+ }
1199
+ /**
1200
+ * The copy of a file into a method's draft — `copyFileIntoDraft`,
1201
+ * `POST /v1/methods/{id}/draft/files/from-file`, "Add to method files".
1202
+ */
1203
+ export interface DraftFileFromFileInput {
1204
+ /** The file to copy, one of the organization's, `fl_…`. */
1205
+ file_id: string;
1206
+ /** The tree path the file takes in the draft, such as `assets/logo.png`; a file already there is replaced. */
1207
+ path: string;
1208
+ /**
1209
+ * The draft token (`MethodData.updated_at`) the caller last read, echoed verbatim: a draft that
1210
+ * moved since is refused with a `409` `method_update_conflict`. Omitted, the file is added to the
1211
+ * draft as it stands when the request is served, never erasing another save.
1212
+ */
1213
+ expected_updated_at?: string;
1214
+ }
1215
+ /**
1216
+ * What the copy did in the organization's blob store, the field the answer is discriminated on:
1217
+ * `copied`, the bytes were copied under their SHA-256, or `already_held`, the store held them and
1218
+ * nothing was copied.
1219
+ */
1220
+ export type DraftFileBlob = "copied" | "already_held";
1221
+ /** The copied file as the draft's tree now names it. */
1222
+ export interface DraftFileAdded {
1223
+ /** Its tree path. */
1224
+ path: string;
1225
+ /** The SHA-256 of its bytes, in lowercase hexadecimal. */
1226
+ sha256: string;
1227
+ /** Its size in bytes. */
1228
+ size: number;
1229
+ }
1230
+ /**
1231
+ * The answer of `copyFileIntoDraft`, a `200` discriminated on `blob`; both arms carry the file as
1232
+ * the draft names it and the method as the draft write stored it, with its new draft token.
1233
+ */
1234
+ export interface DraftFileFromFileResult {
1235
+ blob: DraftFileBlob;
1236
+ file: DraftFileAdded;
1237
+ method: MethodData;
1238
+ }
1239
+ /** Whether a run's records are all written: `listed`, or `listing` while the platform is still recording them. */
1240
+ export type RunFilesState = "listing" | "listed";
1241
+ /** Where a file sits in its run: what went in, what came out, or what was made along the way. */
1242
+ export type RunFileMark = "input" | "final" | "intermediate";
1243
+ /** One file of a run, with its mark and the record a surface shows for it. */
1244
+ export interface RunFileEntry {
1245
+ mark: RunFileMark;
1246
+ /**
1247
+ * For an input given by its address, the run's input that held it; `null` for an inline input
1248
+ * and for the files the run made.
1249
+ */
1250
+ input_name: string | null;
1251
+ /**
1252
+ * The address the run took or wrote; a record a take moved to a copy says where it lives now in
1253
+ * its own `uri`.
1254
+ */
1255
+ uri: string;
1256
+ /**
1257
+ * The record a surface shows for the file: for an input, the one of the member who started the
1258
+ * run first, then the caller's, then the oldest. `null` for an input address no record holds,
1259
+ * such as a file stored before records existed.
1260
+ */
1261
+ file: FileRecord | null;
1262
+ }
1263
+ /** A web link the run's inputs held, which gets no record: the platform neither fetched nor kept what it served. */
1264
+ export interface RunInputLink {
1265
+ /** The run's input that held the link. */
1266
+ input_name: string;
1267
+ /** The link, as the run was given it. */
1268
+ url: string;
1269
+ /** Why the link matters to a replay of the run: it must still serve the same file. */
1270
+ warning: string;
1271
+ }
1272
+ /** Query of `listRunFiles`, paging the run's own records. */
1273
+ export interface ListRunFilesQuery {
1274
+ /** How many of the run's own records the page holds at most, from 1 to 200; the API defaults to 50. */
1275
+ limit?: number;
1276
+ /** Opaque `nextCursor` from the previous page. */
1277
+ cursor?: string;
1278
+ }
1279
+ /**
1280
+ * One page of a run's files, sorted by where they sit in the run — `listRunFiles`.
1281
+ *
1282
+ * The inputs given by their address and the web links come on the first page only; the run's own
1283
+ * records, its inline inputs, its final outputs and the files it made along the way, are paged by
1284
+ * address. `nextCursor` is opaque — pass it straight back to `listRunFiles`; `null` is the last
1285
+ * page. `state` is `listing` until the platform has recorded every file of the run, a few seconds
1286
+ * after it ends, so a client showing a run that just ended reads it again until it is `listed`.
1287
+ */
1288
+ export interface RunFilesPage {
1289
+ pipeline_run_id: string;
1290
+ state: RunFilesState;
1291
+ /** What went in: the inputs by address (first page only), then the inline inputs. */
1292
+ inputs: RunFileEntry[];
1293
+ /** What came out: the run's final outputs. */
1294
+ outputs: RunFileEntry[];
1295
+ /** What was made along the way. */
1296
+ intermediates: RunFileEntry[];
1297
+ /** The web links the inputs held (first page only). */
1298
+ links: RunInputLink[];
1299
+ nextCursor: string | null;
1300
+ }
646
1301
  /**
647
1302
  * A run's record — the base of `RunDetail`, which `getRunDetail` returns. The run-history list
648
1303
  * does not return it: its rows are the slimmer `RunHistoryItem`.