@usenaive-sdk/blueprints 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,9 +3,9 @@ var ALPHABET = "0123456789abcdefghjkmnpqrstvwxyz";
3
3
  var SUFFIX_LENGTH = 26;
4
4
  var SUFFIX_PATTERN = new RegExp(`^[${ALPHABET}]{${SUFFIX_LENGTH},}$`);
5
5
  function isId(prefix, value) {
6
- const head = `${prefix}_`;
7
- if (!value.startsWith(head)) return false;
8
- return SUFFIX_PATTERN.test(value.slice(head.length).toLowerCase());
6
+ const head2 = `${prefix}_`;
7
+ if (!value.startsWith(head2)) return false;
8
+ return SUFFIX_PATTERN.test(value.slice(head2.length).toLowerCase());
9
9
  }
10
10
 
11
11
  // ../core/src/errors.ts
@@ -15,6 +15,8 @@ var CODES = {
15
15
  unauthorized: ["authentication", 401],
16
16
  forbidden: ["permission", 403],
17
17
  not_found: ["not_found", 404],
18
+ /** The path exists; the method does not. The response carries `Allow` (§3). */
19
+ method_not_allowed: ["invalid_request", 405],
18
20
  budget_exceeded: ["quota", 402],
19
21
  insufficient_credits: ["quota", 402],
20
22
  /**
@@ -114,10 +116,6 @@ function decimalStringFromMicro(amount) {
114
116
  return `${amount < 0 ? "-" : ""}${absolute / BigInt(USD)}.${fraction}`;
115
117
  }
116
118
 
117
- // ../core/src/session-token.ts
118
- var SESSION_TTL_SECONDS = 30 * 24 * 60 * 60;
119
- var encoder = new TextEncoder();
120
-
121
119
  // ../core/src/schema/audit-actions.ts
122
120
  var AUDIT_ACTIONS_SHIPPED = [
123
121
  "agent.updated",
@@ -143,6 +141,8 @@ var AUDIT_ACTIONS_P1 = [
143
141
  "computer.resumed",
144
142
  "computer.snapshot_created",
145
143
  "computer.updated",
144
+ "computer.taken_over",
145
+ "computer.handed_back",
146
146
  "browser.live_view_opened",
147
147
  "deployment.created",
148
148
  "deployment.updated",
@@ -181,6 +181,8 @@ var AUDIT_ACTIONS_P2 = [
181
181
  "connection.auth_config_created",
182
182
  "connection.auth_config_deleted",
183
183
  "domain.created",
184
+ "domain.purchased",
185
+ "domain.purchase_refunded",
184
186
  "domain.verified",
185
187
  "domain.deleted",
186
188
  "email.created",
@@ -278,7 +280,7 @@ var JsonSchemaDocument = z.record(z.string(), z.unknown()).refine((schema) => sc
278
280
  var WindowSchema = z.enum(["immediate", "priority", "loose"]);
279
281
  var TOKEN_TIERS = ["input", "cache_write", "cache_read", "output", "reasoning"];
280
282
  var TokenTierSchema = z.enum(TOKEN_TIERS);
281
- var TOOL_TIERS = ["search", "media", "social", "browser", "storage"];
283
+ var TOOL_TIERS = ["search", "media", "social", "browser", "storage", "email"];
282
284
  var LINE_ITEM_TIERS = [...TOKEN_TIERS, "computer", ...TOOL_TIERS];
283
285
  var LineItemTierSchema = z.enum(LINE_ITEM_TIERS);
284
286
  var TokenUsageSchema = z.object({
@@ -308,11 +310,41 @@ import { z as z4 } from "zod";
308
310
 
309
311
  // ../core/src/schema/org.ts
310
312
  import { z as z3 } from "zod";
313
+ var DEFAULT_ORG_TIMEZONE = "America/New_York";
314
+ function canonicalZone(name) {
315
+ if (!name.includes("/") && name !== "UTC") return void 0;
316
+ try {
317
+ const zone = new Intl.DateTimeFormat("en-US", { timeZone: name }).resolvedOptions().timeZone;
318
+ return zone === "UTC" || Intl.supportedValuesOf("timeZone").includes(zone) ? zone : void 0;
319
+ } catch {
320
+ return void 0;
321
+ }
322
+ }
323
+ var TimezoneSchema = z3.string().transform((name, ctx) => {
324
+ const zone = canonicalZone(name);
325
+ if (zone === void 0) {
326
+ ctx.addIssue({ code: "custom", message: "not a timezone; use an IANA name such as America/Los_Angeles" });
327
+ return z3.NEVER;
328
+ }
329
+ return zone;
330
+ });
311
331
  var OrganizationSchema = z3.object({
312
332
  id: idOf("org"),
313
333
  object: z3.literal("organization"),
314
334
  name: z3.string(),
315
335
  balance_micro_usd: MicroUsdField,
336
+ /**
337
+ * The company's timezone, an IANA name (`America/New_York`, §20.6). Times the company chooses or
338
+ * reads are in it: a new routine's zone, when a post goes out. `America/New_York` until changed.
339
+ * Defaulted so a reply from a control plane older than 0088 (or a rolled-back Worker) still parses
340
+ * in a newer SDK/CLI rather than throwing on every `orgs.get/list/update`.
341
+ */
342
+ timezone: z3.string().min(1).default(DEFAULT_ORG_TIMEZONE),
343
+ /**
344
+ * The company's logo, an SVG a person or an agent drew (§20.7), passed by `checkLogoSvg`. `null`
345
+ * until one is set. Defaulted so a reply from a control plane older than 0093 still parses.
346
+ */
347
+ logo_svg: z3.string().nullable().default(null),
316
348
  created_at: Timestamp
317
349
  });
318
350
  var RoleSchema = z3.enum(["owner", "admin", "member"]);
@@ -664,7 +696,7 @@ function normaliseMultiagent(value) {
664
696
  }
665
697
  var HandoffsField = z6.union([z6.boolean(), z6.literal("team"), z6.array(z6.string().min(1)).max(50)]);
666
698
  var handoffsOf = (config) => config.handoffs ?? true;
667
- var handoffsEnabled = (handoffs) => handoffs === true || handoffs === "team" || handoffs !== false && handoffs.length > 0;
699
+ var handoffsEnabled = (handoffs) => handoffs !== false;
668
700
  var agentConfigShape = {
669
701
  model: z6.string(),
670
702
  window: WindowSchema,
@@ -701,8 +733,131 @@ var AgentSchema = z6.object({
701
733
  });
702
734
 
703
735
  // ../core/src/schema/session.ts
736
+ import { z as z8 } from "zod";
737
+
738
+ // ../core/src/schema/social.ts
704
739
  import { z as z7 } from "zod";
705
- var SessionStatusSchema = z7.enum([
740
+ var SOCIAL_PLATFORMS = [
741
+ "bluesky",
742
+ "facebook",
743
+ "instagram",
744
+ "linkedin",
745
+ "mastodon",
746
+ "pinterest",
747
+ "reddit",
748
+ "threads",
749
+ "tiktok",
750
+ "x",
751
+ "youtube"
752
+ ];
753
+ var SOCIAL_APPS = /* @__PURE__ */ new Set([...SOCIAL_PLATFORMS, "twitter"]);
754
+ var SOCIAL_TEXT_PLATFORMS = [
755
+ "bluesky",
756
+ "facebook",
757
+ "linkedin",
758
+ "mastodon",
759
+ "threads",
760
+ "x"
761
+ ];
762
+ var SOCIAL_MEDIA_PLATFORMS = ["instagram", "tiktok", "youtube"];
763
+ var SOCIAL_VISIBILITIES = ["public", "unlisted", "private"];
764
+ var SOCIAL_VISIBILITY_PLATFORMS = ["mastodon", "youtube"];
765
+ var SocialVisibilitySchema = z7.enum(SOCIAL_VISIBILITIES);
766
+ var SOCIAL_VISIBILITY_RULE = `visibility is ${SOCIAL_VISIBILITIES.join(", ")} and only ${SOCIAL_VISIBILITY_PLATFORMS.join(" and ")} accept it; omit it and the post publishes at the account's own default, which on a video channel is normally public`;
767
+ var SocialPlatformSchema = z7.enum(SOCIAL_PLATFORMS);
768
+ var SocialTextPlatformSchema = z7.enum(SOCIAL_TEXT_PLATFORMS);
769
+ var isText = (platform) => SOCIAL_TEXT_PLATFORMS.includes(platform);
770
+ var isMedia = (platform) => SOCIAL_MEDIA_PLATFORMS.includes(platform);
771
+ var SOCIAL_PLATFORM_RULE = `${SOCIAL_TEXT_PLATFORMS.join(", ")} take a text-only post; ${SOCIAL_MEDIA_PLATFORMS.join(", ")} may be named only when the post carries media_urls or file_ids; ${SOCIAL_PLATFORMS.filter((platform) => !isText(platform) && !isMedia(platform)).join(", ")} cannot be posted to`;
772
+ var SocialAccountSchema = z7.object({
773
+ id: z7.string().min(1),
774
+ object: z7.literal("social_account"),
775
+ identity_id: idOf("idn"),
776
+ platform: SocialPlatformSchema,
777
+ username: z7.string().nullable(),
778
+ display_name: z7.string().nullable(),
779
+ avatar_url: z7.url().nullable(),
780
+ connected_at: Timestamp.nullable()
781
+ });
782
+ var SocialPostStatusSchema = z7.enum([
783
+ "draft",
784
+ "scheduled",
785
+ "processing",
786
+ "posted",
787
+ "failed",
788
+ "deleted"
789
+ ]);
790
+ var SocialPostSchema = z7.object({
791
+ id: z7.string().min(1),
792
+ object: z7.literal("social_post"),
793
+ identity_id: idOf("idn"),
794
+ title: z7.string(),
795
+ platforms: z7.array(SocialPlatformSchema),
796
+ status: SocialPostStatusSchema,
797
+ scheduled_at: Timestamp.nullable(),
798
+ posted_at: Timestamp.nullable(),
799
+ error: z7.string().nullable()
800
+ });
801
+ var SocialUploadSchema = z7.object({
802
+ id: z7.string().min(1),
803
+ object: z7.literal("social_upload"),
804
+ identity_id: idOf("idn"),
805
+ type: z7.enum(["image", "video", "document"]),
806
+ url: z7.url().nullable()
807
+ });
808
+ var SocialAnalyticsSchema = z7.object({
809
+ object: z7.literal("social_analytics"),
810
+ identity_id: idOf("idn"),
811
+ resource_id: z7.string().min(1),
812
+ platform: SocialPlatformSchema.nullable(),
813
+ data: z7.unknown()
814
+ });
815
+ var SocialCommentSchema = z7.object({
816
+ id: z7.string().min(1),
817
+ object: z7.literal("social_comment"),
818
+ identity_id: idOf("idn"),
819
+ post_id: z7.string().min(1),
820
+ platforms: z7.array(SocialPlatformSchema),
821
+ status: SocialPostStatusSchema,
822
+ posted_at: Timestamp.nullable(),
823
+ data: z7.unknown()
824
+ });
825
+ var POST_STATUSES = ["pending", "scheduled", "posted", "failed"];
826
+ var PostStatusSchema = z7.enum(POST_STATUSES);
827
+ var PostSchema = z7.object({
828
+ object: z7.literal("post"),
829
+ id: z7.string().min(1),
830
+ status: PostStatusSchema,
831
+ identity_id: z7.string().nullable(),
832
+ agent_id: z7.string().nullable(),
833
+ session_id: z7.string().nullable(),
834
+ tool_call_id: z7.string().nullable(),
835
+ content: z7.string().nullable(),
836
+ platforms: z7.array(z7.string()),
837
+ file_ids: z7.array(z7.string()),
838
+ media_urls: z7.array(z7.string()),
839
+ visibility: SocialVisibilitySchema.nullable(),
840
+ scheduled_at: Timestamp.nullable(),
841
+ posted_at: Timestamp.nullable(),
842
+ url: z7.string().nullable(),
843
+ error: z7.string().nullable(),
844
+ /** The latest stored reading, `{metric: value}`; `null` before `social.post_metrics` read any. */
845
+ metrics: z7.record(z7.string(), z7.number()).nullable(),
846
+ measured_at: Timestamp.nullable(),
847
+ /** Pending only: the earlier post this call would repeat — same identity, network and file. */
848
+ duplicate_of: z7.object({
849
+ id: z7.string(),
850
+ status: PostStatusSchema,
851
+ platform: z7.string(),
852
+ at: Timestamp.nullable(),
853
+ agent_id: z7.string().nullable(),
854
+ session_id: z7.string().nullable()
855
+ }).nullable(),
856
+ created_at: Timestamp
857
+ });
858
+
859
+ // ../core/src/schema/session.ts
860
+ var SessionStatusSchema = z8.enum([
706
861
  "queued",
707
862
  "running",
708
863
  "idle",
@@ -710,7 +865,23 @@ var SessionStatusSchema = z7.enum([
710
865
  "failed",
711
866
  "cancelled"
712
867
  ]);
713
- var StopReasonSchema = z7.enum([
868
+ var SessionModeSchema = z8.enum(["plan", "build"]);
869
+ var PLAN_MAX_CHARS = 2e4;
870
+ var PlanSchema = z8.object({
871
+ object: z8.literal("plan"),
872
+ markdown: z8.string().max(PLAN_MAX_CHARS),
873
+ version: z8.number().int().nonnegative(),
874
+ by: z8.enum(["agent", "owner"]).nullable()
875
+ });
876
+ var PlanWriteSchema = z8.object({
877
+ markdown: z8.string().max(PLAN_MAX_CHARS),
878
+ base_version: z8.number().int().nonnegative()
879
+ });
880
+ var ProposePlanSchema = z8.object({
881
+ version: z8.number().int().positive(),
882
+ spends_or_publishes: z8.array(z8.string().min(1).max(200)).max(10).optional()
883
+ });
884
+ var StopReasonSchema = z8.enum([
714
885
  "end_turn",
715
886
  "awaiting_input",
716
887
  "awaiting_approval",
@@ -736,27 +907,27 @@ var StopReasonSchema = z7.enum([
736
907
  */
737
908
  "awaiting_answer"
738
909
  ]);
739
- var ThreadRoleSchema = z7.enum(["coordinator", "member"]);
740
- var MessageSchema = z7.object({
741
- role: z7.enum(["system", "user", "assistant", "tool"]),
742
- content: z7.string(),
743
- tool_call_id: z7.string().optional()
910
+ var ThreadRoleSchema = z8.enum(["coordinator", "member"]);
911
+ var MessageSchema = z8.object({
912
+ role: z8.enum(["system", "user", "assistant", "tool"]),
913
+ content: z8.string(),
914
+ tool_call_id: z8.string().optional()
744
915
  });
745
- var ToolImageSchema = z7.object({
916
+ var ToolImageSchema = z8.object({
746
917
  file_id: idOf("fil"),
747
- url: z7.string().url().describe("A short-lived signed read for the file's bytes."),
748
- media_type: z7.enum(["image/png", "image/jpeg", "image/gif", "image/webp"])
918
+ url: z8.string().url().describe("A short-lived signed read for the file's bytes."),
919
+ media_type: z8.enum(["image/png", "image/jpeg", "image/gif", "image/webp"])
749
920
  });
750
- var ToolResultSchema = z7.object({
751
- output: z7.unknown(),
752
- is_error: z7.boolean().optional(),
753
- content: z7.string().optional(),
754
- images: z7.array(ToolImageSchema).max(12).optional()
921
+ var ToolResultSchema = z8.object({
922
+ output: z8.unknown(),
923
+ is_error: z8.boolean().optional(),
924
+ content: z8.string().optional(),
925
+ images: z8.array(ToolImageSchema).max(12).optional()
755
926
  });
756
927
  var QuestionFieldBase = {
757
- key: z7.string().min(1).max(64),
758
- label: z7.string().min(1).max(200),
759
- help: z7.string().max(500).optional(),
928
+ key: z8.string().min(1).max(64),
929
+ label: z8.string().min(1).max(200),
930
+ help: z8.string().max(500).optional(),
760
931
  /**
761
932
  * A field that may be left blank, and it defaults to **false** — the rule "every field must be
762
933
  * answered" (`assertAnswers`) is still the rule, and this is the one documented way out of it.
@@ -776,60 +947,112 @@ var QuestionFieldBase = {
776
947
  * required on the OUTPUT type — so every hand-written `QuestionField` in the codebase, and every
777
948
  * one written after it, would have to spell out the flag it does not use.
778
949
  */
779
- optional: z7.boolean().optional()
950
+ optional: z8.boolean().optional()
780
951
  };
781
- var QuestionFieldSchema = z7.discriminatedUnion("type", [
782
- z7.object({
952
+ var QuestionFieldSchema = z8.discriminatedUnion("type", [
953
+ z8.object({
783
954
  ...QuestionFieldBase,
784
- type: z7.literal("text"),
785
- placeholder: z7.string().max(200).optional()
955
+ type: z8.literal("text"),
956
+ placeholder: z8.string().max(200).optional()
786
957
  }),
787
- z7.object({
958
+ z8.object({
788
959
  ...QuestionFieldBase,
789
- type: z7.literal("choice"),
960
+ type: z8.literal("choice"),
790
961
  /**
791
962
  * Plain strings: the option is both the value and the label, because the answer is read back by
792
963
  * a model, which wants the words and not an id. Fewer than two is not a choice, and more than
793
964
  * twelve is a list — which belongs in the prompt.
794
965
  */
795
- options: z7.array(z7.string().min(1).max(200)).min(2).max(12),
796
- multiple: z7.boolean().default(false),
966
+ options: z8.array(z8.string().min(1).max(200)).min(2).max(12),
967
+ multiple: z8.boolean().default(false),
797
968
  /**
798
969
  * The free-text escape, and it defaults to **true** on purpose: the agent wrote the options and
799
970
  * the agent is the one that does not know the answer, so an operator must always be able to say
800
971
  * something it did not think of. A question that truly admits only its list opts out explicitly.
801
972
  */
802
- other: z7.boolean().default(true)
973
+ other: z8.boolean().default(true),
974
+ /**
975
+ * A PICTURE OR A LINE FOR AN OPTION (ADR-1103): a template's "how it looks" shows its looks, and
976
+ * a niche says what it means in one line. Each names its option by its words; one naming no
977
+ * option is ignored, never refused. With a picture on any option the dashboard draws the choice
978
+ * as a grid of pictures. `image` is `https://`, or a path on the dashboard itself. An array
979
+ * and not a map, because a model's tool schema cannot always take a map. An older reader drops
980
+ * it and draws the plain list.
981
+ */
982
+ details: z8.array(
983
+ z8.object({
984
+ option: z8.string().min(1).max(200),
985
+ note: z8.string().min(1).max(120).optional(),
986
+ image: z8.string().max(500).regex(/^\/(?!\/)/, "an image is a path on the dashboard").optional()
987
+ })
988
+ ).max(12).optional()
989
+ }),
990
+ /**
991
+ * THE PERSON'S OWN MEDIA (ADR-1103): "show us what you like". The dashboard offers an upload for
992
+ * images or a video, which land in the organization's files, and a box for a link. The answer is
993
+ * the list: `fil_` ids and `https://` links, which an agent opens with `files_get`, `view_image`
994
+ * or the browser. `placeholder` is the link box's.
995
+ */
996
+ z8.object({
997
+ ...QuestionFieldBase,
998
+ type: z8.literal("media"),
999
+ placeholder: z8.string().max(200).optional()
803
1000
  })
804
1001
  ]);
805
- var QuestionSchema = z7.object({
806
- prompt: z7.string().min(1).max(1e3),
807
- fields: z7.array(QuestionFieldSchema).min(1).max(3)
808
- });
809
- var AnswersSchema = z7.record(
810
- z7.string().min(1).max(64),
811
- z7.union([z7.string().max(2e3), z7.array(z7.string().max(2e3)).min(1).max(12)])
812
- ).refine((answers) => Object.keys(answers).length <= 3, {
813
- message: "a question has at most 3 fields, so an answer has at most 3 keys"
814
- });
815
- var PendingActionSchema = z7.object({
816
- kind: z7.enum(["tool", "question"]).default("tool"),
817
- tool_call_id: z7.string(),
818
- name: z7.string(),
819
- args: z7.record(z7.string(), z7.unknown()),
1002
+ var ConnectFieldSchema = z8.object({
1003
+ ...QuestionFieldBase,
1004
+ type: z8.literal("connect"),
1005
+ platforms: z8.array(SocialPlatformSchema).min(1).max(6)
1006
+ });
1007
+ var AskFieldSchema = z8.discriminatedUnion("type", [...QuestionFieldSchema.options, ConnectFieldSchema]);
1008
+ var QUESTION_FIELDS_MAX = 3;
1009
+ var QuestionSchema = z8.object({
1010
+ prompt: z8.string().min(1).max(1e3),
1011
+ fields: z8.array(AskFieldSchema).min(1).max(QUESTION_FIELDS_MAX, {
1012
+ message: `a question has at most ${QUESTION_FIELDS_MAX} fields \u2014 ask the rest in a second question once these are answered`
1013
+ })
1014
+ }).refine((question) => question.fields.length === 1 || question.fields.every((field) => field.type !== "connect"), {
1015
+ // A connect card answers itself when the accounts land (ADR-1102); a field beside it would need
1016
+ // a Send the card does not have.
1017
+ message: "a connect field is a question of its own: ask anything else in a separate question",
1018
+ path: ["fields"]
1019
+ });
1020
+ var answersOf = (max, message3) => z8.record(
1021
+ z8.string().min(1).max(64),
1022
+ z8.union([z8.string().max(2e3), z8.array(z8.string().max(2e3)).min(1).max(12)])
1023
+ ).refine((answers) => Object.keys(answers).length <= max, { message: message3 });
1024
+ var AnswersSchema = answersOf(
1025
+ QUESTION_FIELDS_MAX,
1026
+ `a question has at most ${QUESTION_FIELDS_MAX} fields, so an answer has at most ${QUESTION_FIELDS_MAX} keys`
1027
+ );
1028
+ var TEMPLATE_QUESTIONS_MAX = 4;
1029
+ var InstallAnswersSchema = answersOf(
1030
+ TEMPLATE_QUESTIONS_MAX,
1031
+ `a template asks at most ${TEMPLATE_QUESTIONS_MAX} questions, so an install has at most ${TEMPLATE_QUESTIONS_MAX} answers`
1032
+ );
1033
+ var PendingActionSchema = z8.object({
1034
+ kind: z8.enum(["tool", "question"]).default("tool"),
1035
+ tool_call_id: z8.string(),
1036
+ name: z8.string(),
1037
+ args: z8.record(z8.string(), z8.unknown()),
820
1038
  /**
821
1039
  * Present iff `kind` is `"question"`, and it is the parse of `args` rather than a second source
822
1040
  * of truth: `args` is what the model called and therefore what replays byte-identically, while
823
1041
  * `question` is what a renderer reads without having to know that `ask_operator`'s arguments
824
1042
  * happen to be the question. Same content, two jobs.
825
1043
  */
826
- question: QuestionSchema.optional()
1044
+ question: QuestionSchema.optional(),
1045
+ /**
1046
+ * The helper's thread a coordinator adopted this call from (§28, B-3; ADR-1101): the dashboard
1047
+ * marks that helper as waiting on you. Absent on the session's own calls.
1048
+ */
1049
+ thread_id: idOf("ses").optional()
827
1050
  });
828
- var SessionSchema = z7.object({
1051
+ var SessionSchema = z8.object({
829
1052
  id: idOf("ses"),
830
- object: z7.literal("session"),
1053
+ object: z8.literal("session"),
831
1054
  agent_id: idOf("agt"),
832
- agent_version: z7.number().int().positive(),
1055
+ agent_version: z8.number().int().positive(),
833
1056
  deployment_id: idOf("dep").nullable(),
834
1057
  /**
835
1058
  * The persona this session acts as (`canonical-spec §22`). Chosen per task from the personas the
@@ -852,50 +1075,73 @@ var SessionSchema = z7.object({
852
1075
  parent_session_id: idOf("ses").nullable(),
853
1076
  root_session_id: idOf("ses").nullable(),
854
1077
  thread_role: ThreadRoleSchema.nullable(),
1078
+ /**
1079
+ * The model the latest send picked (§7 `model`), or `null` when none has and the session runs its
1080
+ * pinned version's model (§10, ADR-0832). Defaulted so a reply from an older control plane parses.
1081
+ */
1082
+ model: z8.string().nullable().default(null),
1083
+ /** Plan mode (§7.5, §10): defaulted so a reply from an older control plane parses as `build`. */
1084
+ mode: SessionModeSchema.default("build"),
855
1085
  status: SessionStatusSchema,
856
1086
  stop_reason: StopReasonSchema.nullable(),
857
1087
  window: WindowSchema,
858
1088
  budget_micro_usd: MicroUsdField.nonnegative(),
859
1089
  consumed_micro_usd: MicroUsdField.nonnegative(),
860
1090
  token_usage: TokenUsageSchema,
861
- pending_actions: z7.array(PendingActionSchema),
1091
+ pending_actions: z8.array(PendingActionSchema),
862
1092
  output_schema: JsonSchemaDocument.nullable(),
863
- structured_output: z7.record(z7.string(), z7.unknown()).nullable(),
864
- last_seq: z7.number().int().nonnegative(),
1093
+ structured_output: z8.record(z8.string(), z8.unknown()).nullable(),
1094
+ last_seq: z8.number().int().nonnegative(),
865
1095
  metadata: Metadata,
866
1096
  started_at: Timestamp.nullable(),
867
1097
  ended_at: Timestamp.nullable(),
868
1098
  created_at: Timestamp
869
1099
  });
870
- var SendMessageSchema = z7.object({
871
- message: z7.string(),
872
- interrupt: z7.boolean().optional(),
873
- queue: z7.boolean().optional(),
874
- idempotency_key: z7.string().optional()
1100
+ var SendMessageSchema = z8.object({
1101
+ message: z8.string(),
1102
+ interrupt: z8.boolean().optional(),
1103
+ queue: z8.boolean().optional(),
1104
+ /** A catalogue id: this session runs on it from this message's turn on (§7, ADR-0832). */
1105
+ model: z8.string().min(1).optional(),
1106
+ /** Plan mode from this message's turn on (§7.5, ADR-0905). */
1107
+ mode: SessionModeSchema.optional(),
1108
+ idempotency_key: z8.string().optional()
875
1109
  }).refine((body) => !(body.interrupt === true && body.queue === true), {
876
1110
  message: "a send is either an interrupt or queued, not both",
877
1111
  path: ["queue"]
878
1112
  });
879
- var SendAcceptedSchema = z7.object({
880
- session_id: z7.string(),
1113
+ var SendAcceptedSchema = z8.object({
1114
+ session_id: z8.string(),
881
1115
  status: SessionStatusSchema,
882
- accepted_seq: z7.number().int().nonnegative()
1116
+ accepted_seq: z8.number().int().nonnegative()
883
1117
  });
884
- var ToolConfirmationSchema = z7.object({
885
- tool_call_id: z7.string(),
886
- decision: z7.enum(["allow", "deny"]),
887
- reason: z7.string().optional(),
888
- scope: z7.enum(["call", "session"]).default("call")
1118
+ var ToolConfirmationSchema = z8.object({
1119
+ tool_call_id: z8.string(),
1120
+ decision: z8.enum(["allow", "deny"]),
1121
+ reason: z8.string().optional(),
1122
+ scope: z8.enum(["call", "session"]).default("call"),
1123
+ /**
1124
+ * THE PERSON'S OWN ANSWERS for a template install they approve (ADR-1030): the call runs with
1125
+ * these in place of the `answers` the agent proposed, and with nothing else changed. A modifier on
1126
+ * `allow`, like `scope`: absent is the call as proposed. The route refuses it on a deny, on a session
1127
+ * grant, on any other tool, and on answers the template's questions refuse (`answerProblems`).
1128
+ */
1129
+ answers: InstallAnswersSchema.optional()
889
1130
  });
890
- var SessionAnswerSchema = z7.object({
891
- tool_call_id: z7.string(),
892
- answers: z7.record(z7.string(), z7.union([z7.string(), z7.array(z7.string())]))
1131
+ var SessionAnswerSchema = z8.object({
1132
+ tool_call_id: z8.string(),
1133
+ answers: z8.record(z8.string(), z8.union([z8.string(), z8.array(z8.string())]))
893
1134
  });
894
1135
 
895
1136
  // ../core/src/schema/event.ts
896
- import { z as z8 } from "zod";
897
- var EventTypeSchema = z8.enum([
1137
+ import { z as z9 } from "zod";
1138
+ var EventTypeSchema = z9.enum([
898
1139
  "message.delta",
1140
+ /**
1141
+ * The agent's answer (no `role`), or a user row `{ role: "user", content, client_message_id? }` (§8).
1142
+ * A user row the runtime wrote itself — a media job's result, a tool grant — carries
1143
+ * `from: "platform"` and is the platform's notice, not a caller's words (§8, ADR-0870).
1144
+ */
899
1145
  "message.completed",
900
1146
  /** A caller's message, durable in the inbox and not yet admitted to a turn (§7, §8): `{ client_message_id, content }`. */
901
1147
  "message.accepted",
@@ -904,19 +1150,28 @@ var EventTypeSchema = z8.enum([
904
1150
  "tool.started",
905
1151
  "tool.completed",
906
1152
  "tool.confirm",
1153
+ /** A person's decision on a parked call, stamped with the inbox write that delivers it (§8, ADR-0764). */
1154
+ "tool.confirm.resolved",
1155
+ /** A person's answer to a parked question, stamped the same way (§7.1, §8, ADR-1049). */
1156
+ "tool.confirm.answered",
907
1157
  "session.running",
908
1158
  "session.usage",
909
1159
  "session.idle",
910
1160
  /** A failed attempt the loop will retry (§8): `{ attempt, in_ms, code }`. */
911
1161
  "session.retrying",
1162
+ /** The session's mode changed (§7.5): `{ mode: "plan" | "build" }`. */
1163
+ "session.mode",
1164
+ /** A write to the session's plan, by the agent or its owner (§7.5): the plan object. */
1165
+ "plan.updated",
912
1166
  /**
913
1167
  * The turn ran, but without something it needed (§8): `{ reason, detail? }`.
914
1168
  *
915
1169
  * Emitted for a turn whose sandbox could not be woken. That turn used to be indistinguishable
916
1170
  * from a success — the model was handed the failure as a tool result, answered around it from the
917
1171
  * transcript, and the session ended `idle`/`end_turn` with no field anywhere saying the
918
- * filesystem had been unavailable. This is the field. `reason` is open on purpose; today the only
919
- * value is `"sandbox_unavailable"`.
1172
+ * filesystem had been unavailable. This is the field. `reason` is open on purpose; today it is
1173
+ * `"sandbox_unavailable"`, `"vendor_resume_unavailable"`, or `"app_tools_unavailable"` — an app the
1174
+ * agent's toolset names gave no tools this turn (§29.5, `runtime-do app-mcp-tools.ts`).
920
1175
  *
921
1176
  * `detail` is the boot failure's own message, and it is here because `reason` alone reads the
922
1177
  * same for a vendor outage and for a fault of ours. Staging round 3 spent its whole budget
@@ -995,63 +1250,78 @@ var EventTypeSchema = z8.enum([
995
1250
  "card.refunded",
996
1251
  "card.credentials_revealed"
997
1252
  ]);
998
- var EventSchema = z8.object({
1253
+ var EventSchema = z9.object({
999
1254
  id: idOf("evt"),
1000
- seq: z8.number().int().positive(),
1255
+ seq: z9.number().int().positive(),
1001
1256
  type: EventTypeSchema,
1002
1257
  session_id: idOf("ses"),
1003
- data: z8.record(z8.string(), z8.unknown()),
1258
+ data: z9.record(z9.string(), z9.unknown()),
1004
1259
  created_at: Timestamp
1005
1260
  });
1006
- var ThreadEventDataSchema = z8.looseObject({ thread_id: idOf("ses") });
1007
- var SessionUsageDataSchema = z8.object({
1261
+ var ThreadEventDataSchema = z9.looseObject({ thread_id: idOf("ses") });
1262
+ var ToolConfirmResolvedDataSchema = z9.object({
1263
+ tool_call_id: z9.string(),
1264
+ decision: z9.enum(["allow", "deny"]),
1265
+ reason: z9.string().nullable(),
1266
+ scope: z9.enum(["call", "session"]),
1267
+ actor: PrincipalSchema.nullable(),
1268
+ decided_at: Timestamp,
1269
+ proposed_args: z9.record(z9.string(), z9.unknown()).nullable(),
1270
+ final_args: z9.record(z9.string(), z9.unknown()).nullable()
1271
+ });
1272
+ var ToolConfirmAnsweredDataSchema = z9.object({
1273
+ tool_call_id: z9.string(),
1274
+ answers: AnswersSchema,
1275
+ answered_at: Timestamp
1276
+ });
1277
+ var SessionUsageDataSchema = z9.object({
1008
1278
  token_usage: TokenUsageSchema,
1009
1279
  consumed_micro_usd: MicroUsdField.nonnegative(),
1010
- active_seconds: z8.number().nonnegative(),
1011
- tool_calls: z8.number().int().nonnegative()
1280
+ active_seconds: z9.number().nonnegative(),
1281
+ tool_calls: z9.number().int().nonnegative()
1012
1282
  });
1013
1283
 
1014
1284
  // ../core/src/schema/board.ts
1015
- import { z as z9 } from "zod";
1285
+ import { z as z10 } from "zod";
1016
1286
  var BOARD_STATUSES = ["todo", "doing", "blocked", "done"];
1017
- var BoardStatusSchema = z9.enum(BOARD_STATUSES);
1018
- var BoardCountsSchema = z9.object({
1019
- todo: z9.number().int().nonnegative(),
1020
- doing: z9.number().int().nonnegative(),
1021
- blocked: z9.number().int().nonnegative(),
1022
- done: z9.number().int().nonnegative()
1023
- });
1024
- var BoardSchema = z9.object({
1287
+ var BoardStatusSchema = z10.enum(BOARD_STATUSES);
1288
+ var BoardCountsSchema = z10.object({
1289
+ todo: z10.number().int().nonnegative(),
1290
+ doing: z10.number().int().nonnegative(),
1291
+ blocked: z10.number().int().nonnegative(),
1292
+ done: z10.number().int().nonnegative()
1293
+ });
1294
+ var BoardSchema = z10.object({
1025
1295
  id: idOf("brd"),
1026
- object: z9.literal("board"),
1296
+ object: z10.literal("board"),
1027
1297
  agent_id: idOf("agt"),
1028
1298
  cards: BoardCountsSchema,
1029
1299
  created_at: Timestamp
1030
1300
  });
1031
- var BoardCardSchema = z9.object({
1301
+ var BoardCardSchema = z10.object({
1032
1302
  id: idOf("crd"),
1033
- object: z9.literal("board_card"),
1303
+ object: z10.literal("board_card"),
1034
1304
  board_id: idOf("brd"),
1035
- title: z9.string().min(1),
1305
+ title: z10.string().min(1),
1036
1306
  /** The brief — what was asked. */
1037
- body: z9.string(),
1307
+ body: z10.string(),
1038
1308
  /** What the holder wrote back; a `done` carries one. */
1039
- note: z9.string().nullable().default(null),
1309
+ note: z10.string().nullable().default(null),
1040
1310
  status: BoardStatusSchema,
1041
- assignee: z9.string().nullable(),
1311
+ assignee: z10.string().nullable(),
1042
1312
  /** The cards this one waits on. A `blocked` card with an empty list is stuck on the world. */
1043
- blocked_by: z9.array(idOf("crd")),
1313
+ blocked_by: z10.array(idOf("crd")),
1044
1314
  // The wake fields default on read: a reader whose API predates one still gets the card (§28.11).
1045
1315
  woken_session_id: idOf("ses").nullable().default(null),
1046
1316
  reported_status: BoardStatusSchema.nullable().default(null),
1047
1317
  /** Sessions the board has started for this card; the third is its last (§28.18). */
1048
- wake_count: z9.number().int().nonnegative().default(0),
1318
+ wake_count: z10.number().int().nonnegative().default(0),
1049
1319
  created_at: Timestamp,
1050
1320
  updated_at: Timestamp
1051
1321
  });
1052
- var BoardCommentSchema = z9.object({
1322
+ var BoardCommentSchema = z10.object({
1053
1323
  id: idOf("bcm"),
1054
- object: z9.literal("board_comment"),
1324
+ object: z10.literal("board_comment"),
1055
1325
  card_id: idOf("crd"),
1056
1326
  /**
1057
1327
  * Who wrote it, as an id the server derived — never a name the caller supplied. A member's
@@ -1059,42 +1329,42 @@ var BoardCommentSchema = z9.object({
1059
1329
  * `key_` principal. The prefix is what lets a reader tell an agent's comment from a person's,
1060
1330
  * which is the distinction a free-text author field could not make and could be used to forge.
1061
1331
  */
1062
- author: z9.string(),
1063
- body: z9.string(),
1332
+ author: z10.string(),
1333
+ body: z10.string(),
1064
1334
  created_at: Timestamp
1065
1335
  });
1066
1336
 
1067
1337
  // ../core/src/schema/identity.ts
1068
- import { z as z10 } from "zod";
1338
+ import { z as z11 } from "zod";
1069
1339
  var IDENTITY_NAME_MAX = 128;
1070
1340
  var IDENTITY_DESCRIPTION_MAX = 1024;
1071
- var IdentitySchema = z10.object({
1341
+ var IdentitySchema = z11.object({
1072
1342
  id: idOf("idn"),
1073
- object: z10.literal("identity"),
1343
+ object: z11.literal("identity"),
1074
1344
  /** Human-facing persona name. Surfaced to the model so it acts in character. */
1075
- name: z10.string().min(1).max(IDENTITY_NAME_MAX),
1345
+ name: z11.string().min(1).max(IDENTITY_NAME_MAX),
1076
1346
  /** What the persona is for. The model reads it to choose tone, scope and endpoint. */
1077
- description: z10.string().max(IDENTITY_DESCRIPTION_MAX).nullable(),
1347
+ description: z11.string().max(IDENTITY_DESCRIPTION_MAX).nullable(),
1078
1348
  /** Inbox addresses (`localpart@domain`) this identity owns. */
1079
- emails: z10.array(z10.string()),
1349
+ emails: z11.array(z11.string()),
1080
1350
  /** Provisioned numbers in E.164. */
1081
- phones: z10.array(z10.string()),
1351
+ phones: z11.array(z11.string()),
1082
1352
  /** Verified web domains reachable through this identity's inboxes. */
1083
- domains: z10.array(z10.string()),
1353
+ domains: z11.array(z11.string()),
1084
1354
  /** `conn_` ids of authorized third-party connections. */
1085
- connections: z10.array(z10.string()),
1355
+ connections: z11.array(z11.string()),
1086
1356
  metadata: Metadata,
1087
1357
  created_at: Timestamp,
1088
1358
  updated_at: Timestamp
1089
1359
  });
1090
1360
 
1091
1361
  // ../core/src/schema/resource.ts
1092
- import { z as z12 } from "zod";
1362
+ import { z as z13 } from "zod";
1093
1363
 
1094
1364
  // ../core/src/schema/files-library.ts
1095
- import { z as z11 } from "zod";
1365
+ import { z as z12 } from "zod";
1096
1366
  var FILE_KINDS = ["image", "video", "audio", "document", "other"];
1097
- var FileKindSchema = z11.enum(FILE_KINDS);
1367
+ var FileKindSchema = z12.enum(FILE_KINDS);
1098
1368
  var FILE_SOURCE_TYPES = [
1099
1369
  "upload",
1100
1370
  "url_import",
@@ -1104,176 +1374,186 @@ var FILE_SOURCE_TYPES = [
1104
1374
  "screenshot",
1105
1375
  "speech_generation"
1106
1376
  ];
1107
- var FileSourceTypeSchema = z11.enum(FILE_SOURCE_TYPES);
1108
- var FileSourceSchema = z11.object({
1377
+ var FileSourceTypeSchema = z12.enum(FILE_SOURCE_TYPES);
1378
+ var FileSourceSchema = z12.object({
1109
1379
  type: FileSourceTypeSchema,
1110
- job_id: z11.union([idOf("med"), idOf("clj")]).nullable(),
1111
- url: z11.string().url().nullable()
1112
- });
1113
- var FileTagsSchema = z11.array(z11.string().min(1).max(64)).max(32);
1114
- var FileLibraryFieldsSchema = z11.object({
1115
- title: z11.string().max(256).nullable().default(null),
1116
- description: z11.string().max(4096).nullable().default(null),
1380
+ job_id: z12.union([idOf("med"), idOf("clj")]).nullable(),
1381
+ url: z12.string().url().nullable(),
1382
+ /** What a generator was asked with (§36.1, ADR-0886); absent on every other writer's row. */
1383
+ model: z12.string().nullable().optional(),
1384
+ prompt: z12.string().nullable().optional()
1385
+ });
1386
+ var FileTagsSchema = z12.array(z12.string().min(1).max(64)).max(32);
1387
+ var FileLibraryFieldsSchema = z12.object({
1388
+ title: z12.string().max(256).nullable().default(null),
1389
+ description: z12.string().max(4096).nullable().default(null),
1117
1390
  tags: FileTagsSchema.default([]),
1118
1391
  kind: FileKindSchema.default("other"),
1119
1392
  source: FileSourceSchema.nullable().default(null),
1120
1393
  thumbnail_file_id: idOf("fil").nullable().default(null),
1121
- width: z11.number().int().positive().nullable().default(null),
1122
- height: z11.number().int().positive().nullable().default(null),
1123
- duration_seconds: z11.number().nonnegative().nullable().default(null)
1394
+ width: z12.number().int().positive().nullable().default(null),
1395
+ height: z12.number().int().positive().nullable().default(null),
1396
+ duration_seconds: z12.number().nonnegative().nullable().default(null)
1124
1397
  });
1125
- var UpdateFileSchema = z11.object({
1126
- title: z11.string().max(256).nullable().optional(),
1127
- description: z11.string().max(4096).nullable().optional(),
1398
+ var UpdateFileSchema = z12.object({
1399
+ title: z12.string().max(256).nullable().optional(),
1400
+ description: z12.string().max(4096).nullable().optional(),
1128
1401
  tags: FileTagsSchema.optional()
1129
1402
  });
1130
- var ImportFileSchema = z11.object({
1131
- url: z11.string().url().startsWith("http"),
1132
- title: z11.string().max(256).optional(),
1133
- description: z11.string().max(4096).optional(),
1403
+ var ImportFileSchema = z12.object({
1404
+ url: z12.string().url().startsWith("http"),
1405
+ title: z12.string().max(256).optional(),
1406
+ description: z12.string().max(4096).optional(),
1134
1407
  tags: FileTagsSchema.optional()
1135
1408
  });
1136
1409
 
1137
1410
  // ../core/src/schema/resource.ts
1138
- var ComputerStatusSchema = z12.enum(["creating", "running", "paused", "failed", "destroyed"]);
1139
- var VolumeSchema = z12.object({
1411
+ var ComputerStatusSchema = z13.enum(["creating", "running", "paused", "failed", "destroyed"]);
1412
+ var VolumeSchema = z13.object({
1140
1413
  id: idOf("vol"),
1141
- size_gb: z12.number().int().positive(),
1142
- mount_path: z12.string()
1414
+ size_gb: z13.number().int().positive(),
1415
+ mount_path: z13.string()
1143
1416
  });
1144
- var ComputerSchema = z12.object({
1417
+ var ComputerSchema = z13.object({
1145
1418
  id: idOf("cmp"),
1146
- object: z12.literal("computer"),
1147
- name: z12.string(),
1148
- vcpu: z12.number().int().positive(),
1149
- memory_mb: z12.number().int().positive(),
1150
- disk_gb: z12.number().int().positive(),
1419
+ object: z13.literal("computer"),
1420
+ name: z13.string(),
1421
+ vcpu: z13.number().int().positive(),
1422
+ memory_mb: z13.number().int().positive(),
1423
+ disk_gb: z13.number().int().positive(),
1151
1424
  status: ComputerStatusSchema,
1152
1425
  // core-gaps: U2-browser-api — the whole option object (§32.2); `{ allowed_domains }` still parses.
1153
1426
  browser: BrowserOptionsSchema.nullable(),
1154
1427
  volume: VolumeSchema.nullable(),
1155
1428
  snapshot_id: idOf("snp").nullable(),
1429
+ /**
1430
+ * The agent this computer belongs to (§41.8, ADR-0849); `null` for one made by `POST /v1/computers`.
1431
+ * Defaulted so a reply from an older control plane parses.
1432
+ */
1433
+ agent_id: idOf("agt").nullable().default(null),
1156
1434
  created_at: Timestamp
1157
1435
  });
1158
- var SnapshotSchema = z12.object({
1436
+ var SnapshotSchema = z13.object({
1159
1437
  snapshot_id: idOf("snp"),
1160
1438
  computer_id: idOf("cmp"),
1161
1439
  created_at: Timestamp
1162
1440
  });
1163
- var ComputerProbeSchema = z12.object({
1441
+ var ComputerProbeSchema = z13.object({
1164
1442
  sampled_at: Timestamp,
1165
- uptime_seconds: z12.number().int().nonnegative(),
1166
- processes: z12.number().int().nonnegative(),
1167
- load_1m: z12.number().nonnegative(),
1168
- memory_used_mb: z12.number().int().nonnegative(),
1169
- memory_total_mb: z12.number().int().positive(),
1170
- disk_used_gb: z12.number().nonnegative(),
1171
- disk_total_gb: z12.number().positive()
1172
- });
1173
- var ComputerInspectSchema = z12.object({
1174
- object: z12.literal("computer_inspect"),
1443
+ uptime_seconds: z13.number().int().nonnegative(),
1444
+ processes: z13.number().int().nonnegative(),
1445
+ load_1m: z13.number().nonnegative(),
1446
+ memory_used_mb: z13.number().int().nonnegative(),
1447
+ memory_total_mb: z13.number().int().positive(),
1448
+ disk_used_gb: z13.number().nonnegative(),
1449
+ disk_total_gb: z13.number().positive()
1450
+ });
1451
+ var ComputerInspectSchema = z13.object({
1452
+ object: z13.literal("computer_inspect"),
1175
1453
  id: idOf("cmp"),
1176
1454
  status: ComputerStatusSchema,
1177
1455
  last_active_at: Timestamp.nullable(),
1178
1456
  /** Where the provider's file API is rooted (§41.1); `null` when it does not say. */
1179
- home: z12.string().min(1).nullable(),
1457
+ home: z13.string().min(1).nullable(),
1180
1458
  probe: ComputerProbeSchema.nullable()
1181
1459
  });
1182
1460
  var COMMAND_OUTPUT_CAP = 65536;
1183
- var ComputerCommandSchema = z12.object({
1461
+ var ComputerCommandSchema = z13.object({
1184
1462
  id: idOf("cmd"),
1185
- object: z12.literal("computer_command"),
1463
+ object: z13.literal("computer_command"),
1186
1464
  computer_id: idOf("cmp"),
1187
- command: z12.string(),
1188
- exit_code: z12.number().int().nullable(),
1189
- timed_out: z12.boolean(),
1190
- duration_ms: z12.number().int().nonnegative(),
1191
- stdout: z12.string().max(COMMAND_OUTPUT_CAP),
1192
- stderr: z12.string().max(COMMAND_OUTPUT_CAP),
1193
- truncated: z12.boolean(),
1465
+ command: z13.string(),
1466
+ exit_code: z13.number().int().nullable(),
1467
+ timed_out: z13.boolean(),
1468
+ duration_ms: z13.number().int().nonnegative(),
1469
+ stdout: z13.string().max(COMMAND_OUTPUT_CAP),
1470
+ stderr: z13.string().max(COMMAND_OUTPUT_CAP),
1471
+ truncated: z13.boolean(),
1194
1472
  actor: PrincipalSchema,
1195
1473
  created_at: Timestamp
1196
1474
  });
1197
- var ExecStreamFrameSchema = z12.union([
1198
- z12.object({ stdout: z12.string() }),
1199
- z12.object({ stderr: z12.string() }),
1200
- z12.object({
1201
- exit: z12.object({
1202
- exit_code: z12.number().int().nullable(),
1203
- timed_out: z12.boolean(),
1204
- duration_ms: z12.number().int().nonnegative(),
1475
+ var ExecStreamFrameSchema = z13.union([
1476
+ z13.object({ stdout: z13.string() }),
1477
+ z13.object({ stderr: z13.string() }),
1478
+ z13.object({
1479
+ exit: z13.object({
1480
+ exit_code: z13.number().int().nullable(),
1481
+ timed_out: z13.boolean(),
1482
+ duration_ms: z13.number().int().nonnegative(),
1205
1483
  command_id: idOf("cmd")
1206
1484
  })
1207
1485
  })
1208
1486
  ]);
1209
- var FileEntryTypeSchema = z12.enum(["file", "directory", "symlink", "other"]);
1210
- var FileEntrySchema = z12.object({
1211
- name: z12.string().min(1),
1212
- path: z12.string().min(1),
1487
+ var FileEntryTypeSchema = z13.enum(["file", "directory", "symlink", "other"]);
1488
+ var FileEntrySchema = z13.object({
1489
+ name: z13.string().min(1),
1490
+ path: z13.string().min(1),
1213
1491
  type: FileEntryTypeSchema,
1214
- size_bytes: z12.number().int().nonnegative(),
1492
+ size_bytes: z13.number().int().nonnegative(),
1215
1493
  /** POSIX `st_mode`. */
1216
- mode: z12.number().int().nonnegative(),
1494
+ mode: z13.number().int().nonnegative(),
1217
1495
  modified_at: Timestamp.nullable()
1218
1496
  });
1219
- var ComputerUpdateSchema = z12.strictObject({ name: z12.string().min(1).max(200) });
1220
- var SkillSchema = z12.object({
1497
+ var ComputerUpdateSchema = z13.strictObject({ name: z13.string().min(1).max(200) });
1498
+ var SkillSchema = z13.object({
1221
1499
  id: idOf("skl"),
1222
- object: z12.literal("skill"),
1223
- name: z12.string(),
1224
- description: z12.string().nullable(),
1225
- latest_version: z12.number().int().positive(),
1500
+ object: z13.literal("skill"),
1501
+ name: z13.string(),
1502
+ description: z13.string().nullable(),
1503
+ latest_version: z13.number().int().positive(),
1226
1504
  created_at: Timestamp
1227
1505
  });
1228
- var ResolvedSkillRefSchema = z12.object({
1506
+ var ResolvedSkillRefSchema = z13.object({
1229
1507
  /** The reference exactly as the agent version wrote it: `slug` or `slug@N`. */
1230
- ref: z12.string().min(1),
1231
- slug: z12.string().min(1),
1232
- version: z12.number().int().positive(),
1233
- description: z12.string(),
1234
- storage_key: z12.string().min(1)
1235
- });
1236
- var SkillVersionSchema = z12.object({
1237
- version: z12.number().int().positive(),
1238
- sha256: z12.string().regex(/^[0-9a-f]{64}$/),
1239
- size_bytes: z12.number().int().nonnegative(),
1508
+ ref: z13.string().min(1),
1509
+ slug: z13.string().min(1),
1510
+ version: z13.number().int().positive(),
1511
+ description: z13.string(),
1512
+ storage_key: z13.string().min(1)
1513
+ });
1514
+ var SkillVersionSchema = z13.object({
1515
+ version: z13.number().int().positive(),
1516
+ sha256: z13.string().regex(/^[0-9a-f]{64}$/),
1517
+ size_bytes: z13.number().int().nonnegative(),
1240
1518
  created_at: Timestamp
1241
1519
  });
1242
- var SkillCatalogEntrySchema = z12.object({
1243
- object: z12.literal("skill_catalog_entry"),
1244
- slug: z12.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1245
- version: z12.number().int().positive(),
1246
- name: z12.string().min(1),
1247
- description: z12.string(),
1248
- tags: z12.array(z12.string().min(1)),
1249
- content_hash: z12.string().regex(/^[0-9a-f]{64}$/),
1520
+ var SkillCatalogEntrySchema = z13.object({
1521
+ object: z13.literal("skill_catalog_entry"),
1522
+ slug: z13.string().regex(/^[a-z0-9][a-z0-9-]*$/),
1523
+ version: z13.number().int().positive(),
1524
+ name: z13.string().min(1),
1525
+ description: z13.string(),
1526
+ tags: z13.array(z13.string().min(1)),
1527
+ content_hash: z13.string().regex(/^[0-9a-f]{64}$/),
1250
1528
  published_at: Timestamp
1251
1529
  });
1252
- var SkillCatalogVersionSchema = SkillCatalogEntrySchema.extend({ content: z12.string() });
1253
- var FileSchema = z12.object({
1530
+ var SkillCatalogVersionSchema = SkillCatalogEntrySchema.extend({ content: z13.string() });
1531
+ var FileSchema = z13.object({
1254
1532
  id: idOf("fil"),
1255
- object: z12.literal("file"),
1256
- name: z12.string(),
1257
- content_type: z12.string(),
1258
- size_bytes: z12.number().int().nonnegative(),
1259
- scope: z12.enum(["session", "published"]),
1533
+ object: z13.literal("file"),
1534
+ name: z13.string(),
1535
+ content_type: z13.string(),
1536
+ size_bytes: z13.number().int().nonnegative(),
1537
+ scope: z13.enum(["session", "published"]),
1260
1538
  session_id: idOf("ses").nullable(),
1261
- sha256: z12.string().regex(/^[0-9a-f]{64}$/),
1539
+ sha256: z13.string().regex(/^[0-9a-f]{64}$/),
1262
1540
  created_at: Timestamp,
1263
1541
  // The asset-library fields (`canonical-spec §36.1`), all nullable or defaulted.
1264
- ...FileLibraryFieldsSchema.shape
1542
+ ...FileLibraryFieldsSchema.shape,
1543
+ /** The agent of `session_id`, joined at read (§36.1, ADR-0887); a writer never sets it. */
1544
+ agent_id: idOf("agt").nullable().optional()
1265
1545
  });
1266
- var ScheduleStatusSchema = z12.enum(["scheduled", "paused", "unscheduled"]);
1267
- var DeploymentSchema = z12.object({
1546
+ var ScheduleStatusSchema = z13.enum(["scheduled", "paused", "unscheduled"]);
1547
+ var DeploymentSchema = z13.object({
1268
1548
  id: idOf("dep"),
1269
- object: z12.literal("deployment"),
1549
+ object: z13.literal("deployment"),
1270
1550
  agent_id: idOf("agt"),
1271
1551
  /** A pin. `null` tracks the agent's `current_version` on every fire (§12). */
1272
- agent_version: z12.number().int().positive().nullable(),
1273
- cron: z12.string(),
1552
+ agent_version: z13.number().int().positive().nullable(),
1553
+ cron: z13.string(),
1274
1554
  /** IANA zone the `cron` is read in. "0 9 * * 1" means 09:00 *here*, across DST (ADR-0074). */
1275
- timezone: z12.string(),
1276
- input_template: z12.string(),
1555
+ timezone: z13.string(),
1556
+ input_template: z13.string(),
1277
1557
  budget_micro_usd: MicroUsdField.nonnegative(),
1278
1558
  window: WindowSchema,
1279
1559
  /**
@@ -1283,21 +1563,21 @@ var DeploymentSchema = z12.object({
1283
1563
  * those endpoints, and a signed delivery over cleartext is not a delivery. Until the push was
1284
1564
  * wired this field went nowhere, so nothing can be relying on an `http://` value (ADR-0161).
1285
1565
  */
1286
- on_idle: z12.url().startsWith("https://", { error: "a webhook URL must be https" }).nullable(),
1566
+ on_idle: z13.url().startsWith("https://", { error: "a webhook URL must be https" }).nullable(),
1287
1567
  /**
1288
1568
  * The persona every fire speaks as, or `null` to run as nobody (§22). Written as an `idn_` id
1289
1569
  * **or** the persona's name, the way a session names one, and always echoed as the id: a fire at
1290
1570
  * 3am must not be silenced by someone renaming the persona at noon.
1291
1571
  */
1292
1572
  identity: idOf("idn").nullable(),
1293
- enabled: z12.boolean(),
1573
+ enabled: z13.boolean(),
1294
1574
  /** Derived per deploy, never stored — the row cannot know whether a clock is watching it. */
1295
1575
  schedule_status: ScheduleStatusSchema,
1296
1576
  /** The next fire, or `null` when nothing will fire it (`schedule_status` says which). */
1297
1577
  next_run_at: Timestamp.nullable(),
1298
1578
  created_at: Timestamp
1299
1579
  });
1300
- var DeploymentRunSchema = z12.object({
1580
+ var DeploymentRunSchema = z13.object({
1301
1581
  id: idOf("run"),
1302
1582
  session_id: idOf("ses"),
1303
1583
  status: SessionStatusSchema,
@@ -1305,62 +1585,62 @@ var DeploymentRunSchema = z12.object({
1305
1585
  });
1306
1586
 
1307
1587
  // ../core/src/schema/comms.ts
1308
- import { z as z13 } from "zod";
1309
- var DomainKindSchema = z13.enum(["system", "external", "purchased"]);
1310
- var DomainStatusSchema = z13.enum(["pending_dns", "active", "failed"]);
1311
- var DomainDnsStatusSchema = z13.enum(["pending_verification", "provisioned", "failed"]);
1312
- var DomainInboundStatusSchema = z13.enum(["pending", "verified", "failed"]);
1313
- var DomainAppConnectStatusSchema = z13.enum(["pending", "connected", "failed"]);
1314
- var DnsRecordSchema = z13.object({
1315
- type: z13.enum(["TXT", "CNAME", "MX"]),
1316
- host: z13.string(),
1317
- value: z13.string(),
1318
- priority: z13.number().int().nullable(),
1588
+ import { z as z14 } from "zod";
1589
+ var DomainKindSchema = z14.enum(["system", "external", "purchased"]);
1590
+ var DomainStatusSchema = z14.enum(["pending_dns", "active", "failed"]);
1591
+ var DomainDnsStatusSchema = z14.enum(["pending_verification", "provisioned", "failed"]);
1592
+ var DomainInboundStatusSchema = z14.enum(["pending", "verified", "failed"]);
1593
+ var DomainAppConnectStatusSchema = z14.enum(["pending", "connected", "failed"]);
1594
+ var DnsRecordSchema = z14.object({
1595
+ type: z14.enum(["TXT", "CNAME", "MX"]),
1596
+ host: z14.string(),
1597
+ value: z14.string(),
1598
+ priority: z14.number().int().nullable(),
1319
1599
  /** Vetta owns this record: `_dmarc`, DKIM, inbound MX. The agent may read it, never write it. */
1320
- managed: z13.boolean()
1600
+ managed: z14.boolean()
1321
1601
  });
1322
- var DomainSchema = z13.object({
1602
+ var DomainSchema = z14.object({
1323
1603
  id: idOf("dom"),
1324
- object: z13.literal("domain"),
1604
+ object: z14.literal("domain"),
1325
1605
  /** A domain belongs to the **organization**, not to one identity: two identities share one. */
1326
- name: z13.string(),
1606
+ name: z14.string(),
1327
1607
  kind: DomainKindSchema,
1328
1608
  status: DomainStatusSchema,
1329
1609
  dns_status: DomainDnsStatusSchema,
1330
1610
  inbound_status: DomainInboundStatusSchema,
1331
1611
  app_connect_status: DomainAppConnectStatusSchema,
1332
- records: z13.array(DnsRecordSchema),
1612
+ records: z14.array(DnsRecordSchema),
1333
1613
  last_verified_at: Timestamp.nullable(),
1334
1614
  created_at: Timestamp
1335
1615
  });
1336
- var EmailInboxSchema = z13.object({
1616
+ var EmailInboxSchema = z14.object({
1337
1617
  id: idOf("eml"),
1338
- object: z13.literal("email_inbox"),
1618
+ object: z14.literal("email_inbox"),
1339
1619
  identity_id: idOf("idn"),
1340
1620
  domain_id: idOf("dom"),
1341
- address: z13.string(),
1342
- localpart: z13.string(),
1621
+ address: z14.string(),
1622
+ localpart: z14.string(),
1343
1623
  /** Inbound routing keys off this: mail to the address wakes exactly this agent. */
1344
1624
  owning_agent_id: idOf("agt"),
1345
- status: z13.enum(["active", "disabled"]),
1625
+ status: z14.enum(["active", "disabled"]),
1346
1626
  created_at: Timestamp
1347
1627
  });
1348
- var PhoneTierSchema = z13.enum(["sole_prop", "standard"]);
1349
- var BrandStatusSchema = z13.enum(["none", "pending_verification", "verified", "rejected"]);
1350
- var CampaignStatusSchema = z13.enum(["none", "pending", "approved", "rejected"]);
1351
- var PhoneNumberSchema = z13.object({
1628
+ var PhoneTierSchema = z14.enum(["sole_prop", "standard"]);
1629
+ var BrandStatusSchema = z14.enum(["none", "pending_verification", "verified", "rejected"]);
1630
+ var CampaignStatusSchema = z14.enum(["none", "pending", "approved", "rejected"]);
1631
+ var PhoneNumberSchema = z14.object({
1352
1632
  id: idOf("pho"),
1353
- object: z13.literal("phone_number"),
1633
+ object: z14.literal("phone_number"),
1354
1634
  identity_id: idOf("idn"),
1355
- e164: z13.string(),
1356
- country: z13.string(),
1357
- capabilities: z13.object({
1635
+ e164: z14.string(),
1636
+ country: z14.string(),
1637
+ capabilities: z14.object({
1358
1638
  /** Live the moment the number is bought — inbound never waits on carrier registration. */
1359
- sms_inbound: z13.boolean(),
1639
+ sms_inbound: z14.boolean(),
1360
1640
  /** True **iff** `campaign_status === "approved"`. Nothing else may set it. */
1361
- sms_outbound: z13.boolean(),
1641
+ sms_outbound: z14.boolean(),
1362
1642
  /** Voice is not a P2 capability; the field exists so its absence is explicit. */
1363
- voice: z13.literal(false)
1643
+ voice: z14.literal(false)
1364
1644
  }),
1365
1645
  tier: PhoneTierSchema,
1366
1646
  brand_status: BrandStatusSchema,
@@ -1368,46 +1648,66 @@ var PhoneNumberSchema = z13.object({
1368
1648
  provisioned_at: Timestamp.nullable(),
1369
1649
  created_at: Timestamp
1370
1650
  });
1371
- var InboundMessageSchema = z13.object({
1651
+ var InboundMessageSchema = z14.object({
1372
1652
  id: idOf("inb"),
1373
- object: z13.literal("inbound_message"),
1374
- channel: z13.enum(["email", "sms"]),
1653
+ object: z14.literal("inbound_message"),
1654
+ channel: z14.enum(["email", "sms"]),
1375
1655
  identity_id: idOf("idn"),
1376
1656
  /** The `eml_`/`pho_` endpoint it arrived at — the persona is decided by *where*, not by *who*. */
1377
- endpoint_id: z13.string(),
1378
- from: z13.string(),
1379
- to: z13.string(),
1380
- subject: z13.string().nullable(),
1381
- text: z13.string(),
1657
+ endpoint_id: z14.string(),
1658
+ from: z14.string(),
1659
+ to: z14.string(),
1660
+ subject: z14.string().nullable(),
1661
+ text: z14.string(),
1382
1662
  /** SPF/DKIM/DMARC for mail, carrier origin for SMS. Kept for the audit of why it was accepted. */
1383
- auth: z13.record(z13.string(), z13.string()),
1663
+ auth: z14.record(z14.string(), z14.string()),
1384
1664
  /** The session this message woke. Null until the wake seam lands (see ADR-0120). */
1385
1665
  session_id: idOf("ses").nullable(),
1386
- received_at: Timestamp
1666
+ received_at: Timestamp,
1667
+ /**
1668
+ * When a person marked it read (`POST …/messages/{mid}/read`); `null` is unread. Defaulted so a
1669
+ * reply from an older control plane parses (ADR-1076).
1670
+ */
1671
+ read_at: Timestamp.nullable().default(null)
1672
+ });
1673
+ var OutboundMessageSchema = z14.object({
1674
+ id: idOf("out"),
1675
+ object: z14.literal("outbound_message"),
1676
+ channel: InboundMessageSchema.shape.channel,
1677
+ identity_id: idOf("idn"),
1678
+ /** The `eml_` endpoint it was sent from. */
1679
+ endpoint_id: z14.string(),
1680
+ from: z14.string(),
1681
+ to: z14.array(z14.string()),
1682
+ subject: z14.string().nullable(),
1683
+ text: z14.string(),
1684
+ sent_by_agent_id: idOf("agt").nullable(),
1685
+ actor: PrincipalSchema.nullable(),
1686
+ sent_at: Timestamp
1387
1687
  });
1388
1688
 
1389
1689
  // ../core/src/schema/app.ts
1390
- import { z as z14 } from "zod";
1391
- var AppTypeSchema = z14.enum(["frontend_only", "fullstack"]);
1392
- var AppStatusSchema = z14.enum(["provisioning", "active", "error"]);
1393
- var AppMcpPathSchema = z14.string().regex(/^\/\S*$/, "must be an absolute path beginning with /").max(128);
1394
- var AppSchema = z14.object({
1690
+ import { z as z15 } from "zod";
1691
+ var AppTypeSchema = z15.enum(["frontend_only", "fullstack"]);
1692
+ var AppStatusSchema = z15.enum(["provisioning", "active", "error"]);
1693
+ var AppMcpPathSchema = z15.string().regex(/^\/\S*$/, "must be an absolute path beginning with /").max(128);
1694
+ var AppSchema = z15.object({
1395
1695
  id: idOf("app"),
1396
- object: z14.literal("app"),
1397
- name: z14.string(),
1398
- description: z14.string().nullable(),
1696
+ object: z15.literal("app"),
1697
+ name: z15.string(),
1698
+ description: z15.string().nullable(),
1399
1699
  type: AppTypeSchema,
1400
1700
  /**
1401
1701
  * The customer's own project name that made this app, or `null` for one made outside a project
1402
1702
  * (ADR-0375). Customer-visible, unlike the provider handles: it is the word the customer typed,
1403
1703
  * and the refusal that guards a name quotes it.
1404
1704
  */
1405
- project: z14.string().nullable(),
1705
+ project: z15.string().nullable(),
1406
1706
  status: AppStatusSchema,
1407
1707
  /** The address the app answers on — platform hostname until a custom domain connects. */
1408
- url: z14.string().nullable(),
1708
+ url: z15.string().nullable(),
1409
1709
  /** White-label words when `status` is `error`; never the provider's. */
1410
- error: z14.string().nullable(),
1710
+ error: z15.string().nullable(),
1411
1711
  /** Where the app serves MCP, or `null`. The bearer token for it is a server column. */
1412
1712
  mcp: AppMcpPathSchema.nullable(),
1413
1713
  /**
@@ -1415,75 +1715,80 @@ var AppSchema = z14.object({
1415
1715
  * than linking its `url` (`§29.1`)? True when the platform holds the app's `DASHBOARD_TOKEN`
1416
1716
  * or a secret of that name exists on the app; derived on read, never stored.
1417
1717
  */
1418
- dashboard: z14.boolean(),
1718
+ dashboard: z15.boolean(),
1419
1719
  created_at: Timestamp
1420
1720
  });
1421
- var AppDeploymentStatusSchema = z14.enum(["queued", "building", "ready", "error"]);
1422
- var AppDeploymentSchema = z14.object({
1721
+ var AppDeploymentStatusSchema = z15.enum(["queued", "building", "ready", "error"]);
1722
+ var AppDeploymentSchema = z15.object({
1423
1723
  id: idOf("apd"),
1424
- object: z14.literal("app_deployment"),
1724
+ object: z15.literal("app_deployment"),
1425
1725
  app_id: idOf("app"),
1426
1726
  status: AppDeploymentStatusSchema,
1427
- url: z14.string().nullable(),
1428
- error: z14.string().nullable(),
1727
+ url: z15.string().nullable(),
1728
+ error: z15.string().nullable(),
1429
1729
  /** The client's opaque digest of the files, echoed verbatim so it can skip an unchanged deploy. */
1430
- content_hash: z14.string().nullable(),
1730
+ content_hash: z15.string().nullable(),
1431
1731
  created_at: Timestamp
1432
1732
  });
1433
- var AppDeploymentFilesSchema = z14.object({
1434
- object: z14.literal("app_deployment_files"),
1733
+ var AppDeploymentFilesSchema = z15.object({
1734
+ object: z15.literal("app_deployment_files"),
1435
1735
  deployment_id: idOf("apd"),
1436
- files: z14.record(z14.string().min(1), z14.string())
1736
+ files: z15.record(z15.string().min(1), z15.string())
1437
1737
  });
1438
- var AppSecretSchema = z14.object({
1439
- object: z14.literal("app_secret"),
1440
- name: z14.string(),
1738
+ var AppSecretSchema = z15.object({
1739
+ object: z15.literal("app_secret"),
1740
+ name: z15.string(),
1441
1741
  /** The client's opaque digest of the value, echoed verbatim so it can skip an unchanged write. */
1442
- value_hash: z14.string().nullable(),
1742
+ value_hash: z15.string().nullable(),
1443
1743
  created_at: Timestamp
1444
1744
  });
1445
- var AppEntrySchema = z14.object({
1446
- object: z14.literal("app_entry"),
1447
- url: z14.string(),
1448
- ticket: z14.string()
1745
+ var AppEntrySchema = z15.object({
1746
+ object: z15.literal("app_entry"),
1747
+ url: z15.string(),
1748
+ ticket: z15.string()
1449
1749
  });
1450
- var AppAccessSchema = z14.object({
1451
- object: z14.literal("app_access"),
1452
- url: z14.string().nullable(),
1453
- password: z14.string().nullable()
1750
+ var AppAccessSchema = z15.object({
1751
+ object: z15.literal("app_access"),
1752
+ url: z15.string().nullable(),
1753
+ password: z15.string().nullable()
1454
1754
  });
1455
- var AppDomainStatusSchema = z14.enum(["pending", "connected", "failed"]);
1456
- var AppDomainSchema = z14.object({
1457
- object: z14.literal("app_domain"),
1755
+ var AppDomainStatusSchema = z15.enum(["pending", "connected", "failed"]);
1756
+ var AppDomainSchema = z15.object({
1757
+ object: z15.literal("app_domain"),
1458
1758
  app_id: idOf("app"),
1459
1759
  domain_id: idOf("dom"),
1460
- domain: z14.string(),
1760
+ domain: z15.string(),
1461
1761
  status: AppDomainStatusSchema,
1462
1762
  created_at: Timestamp
1463
1763
  });
1464
1764
  var ENV_NAME = /^[A-Z_][A-Z0-9_]*$/;
1465
1765
  var APP_NAME = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/;
1766
+ var AppPermissionsSchema = z15.object({
1767
+ object: z15.literal("app_permissions"),
1768
+ app_id: idOf("app"),
1769
+ scopes: z15.array(z15.string())
1770
+ });
1466
1771
 
1467
1772
  // ../core/src/schema/install.ts
1468
- import { z as z15 } from "zod";
1469
- var BlueprintInstallSourceSchema = z15.enum(["studio", "cli"]);
1470
- var BlueprintInstallStatusSchema = z15.enum(["pending", "applied", "failed"]);
1471
- var ResourceActionSchema = z15.enum(["created", "updated", "unchanged", "deleted", "refused"]);
1472
- var ResourceReportSchema = z15.object({
1473
- name: z15.string().min(1),
1773
+ import { z as z16 } from "zod";
1774
+ var BlueprintInstallSourceSchema = z16.enum(["studio", "cli"]);
1775
+ var BlueprintInstallStatusSchema = z16.enum(["pending", "applied", "failed"]);
1776
+ var ResourceActionSchema = z16.enum(["created", "updated", "unchanged", "deleted", "refused"]);
1777
+ var ResourceReportSchema = z16.object({
1778
+ name: z16.string().min(1),
1474
1779
  action: ResourceActionSchema,
1475
1780
  /** The `agt_`/`app_`/`ses_`… the line resolved to. Absent on a refusal that never got an id. */
1476
- id: z15.string().optional(),
1781
+ id: z16.string().optional(),
1477
1782
  /** An app's hostname once its build went live; `null` while it has none. Apps only. */
1478
- url: z15.string().nullable().optional(),
1783
+ url: z16.string().nullable().optional(),
1479
1784
  /**
1480
1785
  * What a TASK is called and who owes it. `name` is the declaration key (`first-render`), which is
1481
1786
  * how a re-apply finds the same card and is not a sentence anybody wants read to them. The
1482
1787
  * dashboard's opening message lists the team's work, so it needs the title the board shows and the
1483
1788
  * seat that holds it. Tasks only.
1484
1789
  */
1485
- title: z15.string().optional(),
1486
- assignee: z15.string().optional(),
1790
+ title: z16.string().optional(),
1791
+ assignee: z16.string().optional(),
1487
1792
  /**
1488
1793
  * A SCHEDULE'S brief, in one short line — the opening sentence of its `input_template`. A
1489
1794
  * schedules line is named `<agent> @ <cron>`, which says when something runs and nothing at all
@@ -1491,50 +1796,50 @@ var ResourceReportSchema = z15.object({
1491
1796
  * Written here rather than read back from the deployment so the receipt stays the one read the
1492
1797
  * welcome needs. Schedules only.
1493
1798
  */
1494
- summary: z15.string().optional(),
1495
- reason: z15.string().optional()
1496
- });
1497
- var BlueprintReportSchema = z15.object({
1498
- skills: z15.array(ResourceReportSchema),
1499
- identities: z15.array(ResourceReportSchema),
1500
- vaults: z15.array(ResourceReportSchema),
1501
- apps: z15.array(ResourceReportSchema),
1502
- agents: z15.array(ResourceReportSchema),
1503
- schedules: z15.array(ResourceReportSchema),
1504
- intake: z15.array(ResourceReportSchema),
1799
+ summary: z16.string().optional(),
1800
+ reason: z16.string().optional()
1801
+ });
1802
+ var BlueprintReportSchema = z16.object({
1803
+ skills: z16.array(ResourceReportSchema),
1804
+ identities: z16.array(ResourceReportSchema),
1805
+ vaults: z16.array(ResourceReportSchema),
1806
+ apps: z16.array(ResourceReportSchema),
1807
+ agents: z16.array(ResourceReportSchema),
1808
+ schedules: z16.array(ResourceReportSchema),
1809
+ intake: z16.array(ResourceReportSchema),
1505
1810
  /** One line per declared task (§31.11), `id` the card's `crd_`. Defaulted so older rows parse. */
1506
- tasks: z15.array(ResourceReportSchema).default([]),
1507
- skipped: z15.array(z15.string()),
1508
- deselected: z15.array(z15.string()).default([])
1811
+ tasks: z16.array(ResourceReportSchema).default([]),
1812
+ skipped: z16.array(z16.string()),
1813
+ deselected: z16.array(z16.string()).default([])
1509
1814
  });
1510
- var BlueprintSelectionSchema = z15.object({
1511
- agents: z15.array(z15.string().min(1)),
1512
- apps: z15.array(z15.string().min(1))
1815
+ var BlueprintSelectionSchema = z16.object({
1816
+ agents: z16.array(z16.string().min(1)),
1817
+ apps: z16.array(z16.string().min(1))
1513
1818
  });
1514
- var BlueprintInstallSchema = z15.object({
1819
+ var BlueprintInstallSchema = z16.object({
1515
1820
  id: idOf("bpi"),
1516
- object: z15.literal("blueprint_install"),
1821
+ object: z16.literal("blueprint_install"),
1517
1822
  /** The customer's own `defineProject({ name })` — the same word `app.project` stamps (§29.2). */
1518
- project: z15.string().min(1),
1823
+ project: z16.string().min(1),
1519
1824
  /** The pair the declaration resolved to; `null` for a declaration that names no blueprint. */
1520
- blueprint: z15.string().nullable(),
1521
- template: z15.string().nullable(),
1825
+ blueprint: z16.string().nullable(),
1826
+ template: z16.string().nullable(),
1522
1827
  /**
1523
1828
  * Applies, not versions of anything: 1 on the first apply, +1 on each one after, whichever writer
1524
1829
  * made it. It is not an agent version and it never rolls back.
1525
1830
  */
1526
- revision: z15.number().int().positive(),
1831
+ revision: z16.number().int().positive(),
1527
1832
  /**
1528
1833
  * The blueprint artifact version this came from, or `null` when it was applied from a working
1529
1834
  * tree — an operator editing a clone has no version to name.
1530
1835
  */
1531
- artifact_version: z15.string().nullable(),
1836
+ artifact_version: z16.string().nullable(),
1532
1837
  /**
1533
1838
  * The setup answers this project was configured with (§7.1 fields, keyed by their `key`), so a
1534
1839
  * re-apply does not re-ask and both writers configure from the same answers. Configuration only:
1535
1840
  * a secret is a vault credential (§23) or an app secret (§29.2), and neither is ever an answer.
1536
1841
  */
1537
- answers: z15.record(z15.string(), z15.unknown()),
1842
+ answers: z16.record(z16.string(), z16.unknown()),
1538
1843
  /**
1539
1844
  * NO `declaration` ON THE WIRE, and that is the reconciliation of §29.6 with §31.1.
1540
1845
  *
@@ -1562,8 +1867,11 @@ var BlueprintInstallSchema = z15.object({
1562
1867
  */
1563
1868
  report: BlueprintReportSchema.nullable(),
1564
1869
  status: BlueprintInstallStatusSchema,
1565
- /** Why a `failed` run threw, in one sentence; `null` on every other row. Never a stack or a key. */
1566
- failure: z15.string().nullable(),
1870
+ /**
1871
+ * Why a `failed` run threw, in one sentence — or, on an `applied` row, which `required` agent or
1872
+ * app the apply refused and why (§29.6). `null` otherwise. Never a stack or a key.
1873
+ */
1874
+ failure: z16.string().nullable(),
1567
1875
  /**
1568
1876
  * The `selection` the apply carried, or `null` — every row written before §31.2 and every apply
1569
1877
  * that omitted it, both meaning "everything". Defaulted so those rows parse unchanged.
@@ -1571,119 +1879,37 @@ var BlueprintInstallSchema = z15.object({
1571
1879
  selection: BlueprintSelectionSchema.nullable().default(null),
1572
1880
  /** When the answers were last edited through `PATCH …/installs/{id}` (§31.8); `null` if never. */
1573
1881
  context_updated_at: Timestamp.nullable().default(null),
1882
+ /**
1883
+ * What this install's agent, app, identity and vault names start with (§29.6, ADR-1104): `""`
1884
+ * when its template's names were free in the organization, `"<project>-"` when any was already
1885
+ * another project's. Decided once, by the apply that created the row, and never again. `null` is
1886
+ * an install from before that rule, or one a working tree recorded: its names are the template's.
1887
+ * Optional only so a Worker from before the field still parses; this API always sends it.
1888
+ */
1889
+ name_prefix: z16.string().nullable().optional(),
1574
1890
  applied_at: Timestamp,
1575
1891
  created_at: Timestamp
1576
1892
  });
1577
- var ProjectContextAnswerSchema = z15.object({
1578
- key: z15.string().min(1),
1579
- label: z15.string(),
1580
- value: z15.union([z15.string(), z15.array(z15.string())])
1581
- });
1582
- var ProjectContextSchema = z15.object({
1583
- object: z15.literal("project_context"),
1584
- project: z15.string().min(1),
1585
- blueprint: z15.string().nullable(),
1586
- template: z15.string().nullable(),
1587
- artifact_version: z15.string().nullable(),
1588
- answers: z15.array(ProjectContextAnswerSchema),
1589
- apps: z15.array(z15.object({ name: z15.string().min(1), url: z15.string().nullable() })),
1590
- agents: z15.array(z15.object({ name: z15.string().min(1), role: z15.string().nullable() })),
1893
+ var ProjectContextAnswerSchema = z16.object({
1894
+ key: z16.string().min(1),
1895
+ label: z16.string(),
1896
+ value: z16.union([z16.string(), z16.array(z16.string())])
1897
+ });
1898
+ var ProjectContextSchema = z16.object({
1899
+ object: z16.literal("project_context"),
1900
+ project: z16.string().min(1),
1901
+ blueprint: z16.string().nullable(),
1902
+ template: z16.string().nullable(),
1903
+ artifact_version: z16.string().nullable(),
1904
+ answers: z16.array(ProjectContextAnswerSchema),
1905
+ apps: z16.array(z16.object({ name: z16.string().min(1), url: z16.string().nullable() })),
1906
+ agents: z16.array(z16.object({ name: z16.string().min(1), role: z16.string().nullable() })),
1591
1907
  /** `context_updated_at` once the answers have been edited, `applied_at` until then. */
1592
1908
  updated_at: Timestamp
1593
1909
  });
1594
1910
 
1595
1911
  // ../core/src/schema/blueprint.ts
1596
1912
  import { z as z17 } from "zod";
1597
-
1598
- // ../core/src/schema/social.ts
1599
- import { z as z16 } from "zod";
1600
- var SOCIAL_PLATFORMS = [
1601
- "bluesky",
1602
- "facebook",
1603
- "instagram",
1604
- "linkedin",
1605
- "mastodon",
1606
- "pinterest",
1607
- "reddit",
1608
- "threads",
1609
- "tiktok",
1610
- "x",
1611
- "youtube"
1612
- ];
1613
- var SOCIAL_APPS = /* @__PURE__ */ new Set([...SOCIAL_PLATFORMS, "twitter"]);
1614
- var SOCIAL_TEXT_PLATFORMS = [
1615
- "bluesky",
1616
- "facebook",
1617
- "linkedin",
1618
- "mastodon",
1619
- "threads",
1620
- "x"
1621
- ];
1622
- var SOCIAL_MEDIA_PLATFORMS = ["instagram", "tiktok", "youtube"];
1623
- var SOCIAL_VISIBILITIES = ["public", "unlisted", "private"];
1624
- var SOCIAL_VISIBILITY_PLATFORMS = ["mastodon", "youtube"];
1625
- var SocialVisibilitySchema = z16.enum(SOCIAL_VISIBILITIES);
1626
- var SOCIAL_VISIBILITY_RULE = `visibility is ${SOCIAL_VISIBILITIES.join(", ")} and only ${SOCIAL_VISIBILITY_PLATFORMS.join(" and ")} accept it; omit it and the post publishes at the account's own default, which on a video channel is normally public`;
1627
- var SocialPlatformSchema = z16.enum(SOCIAL_PLATFORMS);
1628
- var SocialTextPlatformSchema = z16.enum(SOCIAL_TEXT_PLATFORMS);
1629
- var isText = (platform) => SOCIAL_TEXT_PLATFORMS.includes(platform);
1630
- var isMedia = (platform) => SOCIAL_MEDIA_PLATFORMS.includes(platform);
1631
- var SOCIAL_PLATFORM_RULE = `${SOCIAL_TEXT_PLATFORMS.join(", ")} take a text-only post; ${SOCIAL_MEDIA_PLATFORMS.join(", ")} may be named only when the post carries media_urls or file_ids; ${SOCIAL_PLATFORMS.filter((platform) => !isText(platform) && !isMedia(platform)).join(", ")} cannot be posted to`;
1632
- var SocialAccountSchema = z16.object({
1633
- id: z16.string().min(1),
1634
- object: z16.literal("social_account"),
1635
- identity_id: idOf("idn"),
1636
- platform: SocialPlatformSchema,
1637
- username: z16.string().nullable(),
1638
- display_name: z16.string().nullable(),
1639
- avatar_url: z16.url().nullable(),
1640
- connected_at: Timestamp.nullable()
1641
- });
1642
- var SocialPostStatusSchema = z16.enum([
1643
- "draft",
1644
- "scheduled",
1645
- "processing",
1646
- "posted",
1647
- "failed",
1648
- "deleted"
1649
- ]);
1650
- var SocialPostSchema = z16.object({
1651
- id: z16.string().min(1),
1652
- object: z16.literal("social_post"),
1653
- identity_id: idOf("idn"),
1654
- title: z16.string(),
1655
- platforms: z16.array(SocialPlatformSchema),
1656
- status: SocialPostStatusSchema,
1657
- scheduled_at: Timestamp.nullable(),
1658
- posted_at: Timestamp.nullable(),
1659
- error: z16.string().nullable()
1660
- });
1661
- var SocialUploadSchema = z16.object({
1662
- id: z16.string().min(1),
1663
- object: z16.literal("social_upload"),
1664
- identity_id: idOf("idn"),
1665
- type: z16.enum(["image", "video", "document"]),
1666
- url: z16.url().nullable()
1667
- });
1668
- var SocialAnalyticsSchema = z16.object({
1669
- object: z16.literal("social_analytics"),
1670
- identity_id: idOf("idn"),
1671
- resource_id: z16.string().min(1),
1672
- platform: SocialPlatformSchema.nullable(),
1673
- data: z16.unknown()
1674
- });
1675
- var SocialCommentSchema = z16.object({
1676
- id: z16.string().min(1),
1677
- object: z16.literal("social_comment"),
1678
- identity_id: idOf("idn"),
1679
- post_id: z16.string().min(1),
1680
- platforms: z16.array(SocialPlatformSchema),
1681
- status: SocialPostStatusSchema,
1682
- posted_at: Timestamp.nullable(),
1683
- data: z16.unknown()
1684
- });
1685
-
1686
- // ../core/src/schema/blueprint.ts
1687
1913
  var BlueprintScheduleSchema = z17.object({
1688
1914
  agent: z17.string().min(1),
1689
1915
  cron: z17.string().min(1),
@@ -1715,16 +1941,9 @@ var BlueprintAppSchema = z17.object({
1715
1941
  /** Whether an install may deselect it (§31.2). Optional: the rollout argument above. */
1716
1942
  required: z17.boolean().optional()
1717
1943
  });
1718
- var BlueprintIdentityConnectionsSchema = z17.object({
1719
- social: z17.object({
1720
- from: z17.string().min(1),
1721
- map: z17.record(z17.string().min(1), SocialPlatformSchema)
1722
- }).optional()
1723
- });
1724
1944
  var BlueprintIdentitySchema = z17.object({
1725
1945
  name: z17.string().min(1),
1726
- description: z17.string().nullable(),
1727
- connections: BlueprintIdentityConnectionsSchema.optional()
1946
+ description: z17.string().nullable()
1728
1947
  });
1729
1948
  var ContentHashSchema = z17.string().regex(/^[0-9a-f]{64}$/, "a lowercase sha-256 hex digest");
1730
1949
  var BlueprintTreeSchema = z17.object({
@@ -1742,11 +1961,18 @@ var BlueprintArtifactSchema = z17.object({
1742
1961
  /** The blueprint repository's own released version. Stored, never parsed (ADR-0401). */
1743
1962
  version: z17.string().min(1),
1744
1963
  /**
1745
- * The built trees, one per deployable app, ordered as the declaration orders its apps. Never
1746
- * empty: an artifact that built nothing is not an artifact, and the column behind it says so
1747
- * (migration 0040) exactly as the single `content_hash` it replaces was `not null`.
1964
+ * What a person calls the template, one line on what its crew does, and the networks it publishes
1965
+ * to — printed, never provisioned (§31.5, ADR-0921). `platforms` is decoration: where the crew
1966
+ * posts is the accounts connected to its persona. Optional for the §31.5 rollout reason.
1967
+ */
1968
+ title: z17.string().min(1).optional(),
1969
+ description: z17.string().min(1).optional(),
1970
+ platforms: z17.array(SocialPlatformSchema).optional(),
1971
+ /**
1972
+ * The built trees, one per deployable app, ordered as the declaration orders its apps. Empty for
1973
+ * a data-only blueprint: it declares no app, builds nothing, and still ships a crew (ADR-0900).
1748
1974
  */
1749
- trees: z17.array(BlueprintTreeSchema).min(1),
1975
+ trees: z17.array(BlueprintTreeSchema),
1750
1976
  /**
1751
1977
  * The setup questions, asked by the studio **before** provisioning. `QuestionField` (§7.1) is
1752
1978
  * reused rather than restated: a setup question and a question a parked agent asks are the same
@@ -1800,6 +2026,13 @@ var VaultCredentialSchema = z18.object({
1800
2026
  host: z18.string().nullable(),
1801
2027
  /** The exact MCP server URL an `mcp_*` token is matched to. */
1802
2028
  mcp_server_url: z18.url().nullable(),
2029
+ /**
2030
+ * The one agent this credential may be injected into (ADR-1097). `null` is any agent that
2031
+ * declares `mcp_server_url` — except the platform's own `/v1/mcp`, whose key is never injected
2032
+ * unbound. Set at create, by `admin`, and immutable like the rest. Defaults to `null` so a
2033
+ * client reading a control plane older than the field still parses the row.
2034
+ */
2035
+ agent_id: idOf("agt").nullable().default(null),
1803
2036
  placeholder_ref: z18.string(),
1804
2037
  expires_at: Timestamp.nullable(),
1805
2038
  last_injected_at: Timestamp.nullable(),
@@ -1847,7 +2080,12 @@ var SessionHandoffSchema = z19.object({
1847
2080
  var ChannelBriefSchema = z19.object({
1848
2081
  root_session_id: idOf("ses"),
1849
2082
  name: z19.string().min(1),
1850
- members: z19.array(z19.string().min(1))
2083
+ members: z19.array(z19.string().min(1)),
2084
+ /**
2085
+ * The receiver's own name, so it can tell the part of a post addressed to it from a teammate's
2086
+ * (ADR-1099). Optional: a brief pinned before it existed still parses.
2087
+ */
2088
+ you: z19.string().min(1).optional()
1851
2089
  });
1852
2090
  var ChannelPostRequestSchema = z19.object({
1853
2091
  message: z19.string().min(1).max(2e4)
@@ -1858,37 +2096,241 @@ var ChannelPostSchema = z19.object({
1858
2096
  queued: z19.boolean()
1859
2097
  });
1860
2098
 
1861
- // ../core/src/schema/media.ts
2099
+ // ../core/src/schema/show.ts
1862
2100
  import { z as z20 } from "zod";
1863
- var MEDIA_JOB_KINDS = ["video", "clip", "transcription"];
1864
- var MediaJobKindSchema = z20.enum(MEDIA_JOB_KINDS);
1865
- var MediaJobStatusSchema = z20.enum(["queued", "processing", "completed", "failed"]);
1866
- var PublicUrl = z20.string().url().startsWith("http");
1867
- var Score = z20.number().int().min(0).max(100);
1868
- var Seconds = z20.number().nonnegative();
1869
- var VideoResultSchema = z20.object({
1870
- files: z20.array(
2101
+ var SHOW_SOURCES = ["spend_by_day", "post_views", "roadmap", "schedule"];
2102
+ var ShowSourceSchema = z20.enum(SHOW_SOURCES);
2103
+ var ShowArgsSchema = z20.object({
2104
+ source: ShowSourceSchema.describe(
2105
+ "What to show: spend_by_day (company spend per day, a line), post_views (views per recent post, bars), roadmap (the board's work by status), schedule (routines and scheduled posts over the next 7 days)."
2106
+ ),
2107
+ days: z20.number().int().min(2).max(30).optional().describe("spend_by_day only: days back, today included. Default 14.")
2108
+ });
2109
+ var Day = z20.string().regex(/^\d{4}-\d{2}-\d{2}$/);
2110
+ var Count = z20.number().int().nonnegative();
2111
+ var head = { title: z20.string().min(1), as_of: Timestamp, timezone: z20.string().min(1) };
2112
+ var SpendByDayViewSchema = z20.object({
2113
+ source: z20.literal("spend_by_day"),
2114
+ ...head,
2115
+ days: z20.array(z20.object({ day: Day, micro_usd: Count })).min(2).max(30)
2116
+ });
2117
+ var PostViewsViewSchema = z20.object({
2118
+ source: z20.literal("post_views"),
2119
+ ...head,
2120
+ posts: z20.array(z20.object({ post_id: z20.string().min(1), label: z20.string(), networks: z20.array(z20.string()), posted_at: Timestamp, views: Count })).max(12)
2121
+ });
2122
+ var RoadmapViewSchema = z20.object({
2123
+ source: z20.literal("roadmap"),
2124
+ ...head,
2125
+ groups: z20.array(
1871
2126
  z20.object({
2127
+ status: BoardStatusSchema,
2128
+ count: Count,
2129
+ cards: z20.array(z20.object({ title: z20.string(), assignee: z20.string().nullable(), waits_on: z20.array(z20.string()) })).max(5)
2130
+ })
2131
+ )
2132
+ });
2133
+ var ScheduleViewSchema = z20.object({
2134
+ source: z20.literal("schedule"),
2135
+ ...head,
2136
+ days: z20.array(
2137
+ z20.object({
2138
+ day: Day,
2139
+ count: Count,
2140
+ items: z20.array(
2141
+ z20.discriminatedUnion("kind", [
2142
+ z20.object({ kind: z20.literal("routine"), at: Timestamp, agent: z20.string(), text: z20.string(), runs: z20.number().int().min(1).max(100) }),
2143
+ z20.object({ kind: z20.literal("post"), at: Timestamp, networks: z20.array(z20.string()), text: z20.string() })
2144
+ ])
2145
+ ).max(8)
2146
+ })
2147
+ ).max(7)
2148
+ });
2149
+ var ShowViewSchema = z20.discriminatedUnion("source", [
2150
+ SpendByDayViewSchema,
2151
+ PostViewsViewSchema,
2152
+ RoadmapViewSchema,
2153
+ ScheduleViewSchema
2154
+ ]);
2155
+
2156
+ // ../core/src/schema/compose.ts
2157
+ import { z as z22 } from "zod";
2158
+
2159
+ // ../core/src/schema/catalog.ts
2160
+ import { z as z21 } from "zod";
2161
+ var Key = z21.string().regex(/^[A-Za-z][A-Za-z0-9_-]{0,39}$/, "an element key is a short name: a letter, then letters, digits, - or _");
2162
+ var Count2 = z21.number().int().nonnegative();
2163
+ var DIGIT = "words only: a digit is refused, because every number on the card is read by code from a $source binding";
2164
+ var words = (max) => z21.string().trim().min(1).max(max).regex(/^[^0-9]*$/, DIGIT).refine((text) => !new RegExp("\\p{N}", "u").test(text), DIGIT);
2165
+ var Days = z21.number().int().min(1).max(30).default(7).describe("The window: today and the days before it, on the company's clock. Default 7.");
2166
+ function bound(sources2, shape) {
2167
+ const example = JSON.stringify({ $source: sources2[0] });
2168
+ return z21.strictObject(
2169
+ { $source: z21.enum(sources2), ...shape },
2170
+ { error: (issue) => issue.code === "invalid_type" ? `must be a binding such as ${example}: a literal value is refused, code reads every number` : void 0 }
2171
+ );
2172
+ }
2173
+ var Bound = {
2174
+ value: bound(["views_total", "spend_total"], { days: Days }).describe(
2175
+ "views_total: the latest views of the posts published in the window. spend_total: the company's spend in the window (the CEO only)."
2176
+ ),
2177
+ delta: bound(["views_change"], {}).describe(
2178
+ "views_change: the value's views_total against the same number of days before it, as a percentage. Its window is the value's."
2179
+ ),
2180
+ series: bound(["spend_by_day"], { days: z21.number().int().min(2).max(30).default(14) }).describe("spend_by_day: the company's spend per day (the CEO only)."),
2181
+ bars: bound(["post_views"], { limit: z21.number().int().min(1).max(12).default(5).describe("How many posts, newest first. Default 5.") }).describe(
2182
+ "post_views: each recent post's latest views, newest first."
2183
+ ),
2184
+ progress: bound(["posts_this_week"], {}).describe("posts_this_week: posts published since Monday against the weekly cadence from the company's setup."),
2185
+ board: bound(["roadmap"], {}).describe("roadmap: the board's work by status."),
2186
+ week: bound(["schedule"], {}).describe("schedule: routines and scheduled posts over the next 7 days."),
2187
+ media: z21.union([bound(["latest_media"], { count: z21.number().int().min(1).max(4).default(1) }), z21.array(idOf("fil")).min(1).max(4)]).describe('{"$source":"latest_media","count":1} for the newest posted pictures or clips, or up to 4 fil_ ids.')
2188
+ };
2189
+ var SpendDay = z21.strictObject({ day: z21.string().regex(/^\d{4}-\d{2}-\d{2}$/), micro_usd: Count2 });
2190
+ var Resolved = {
2191
+ value: z21.discriminatedUnion("$source", [
2192
+ z21.strictObject({ $source: z21.literal("views_total"), days: z21.number().int(), value: Count2, posts: Count2 }),
2193
+ z21.strictObject({ $source: z21.literal("spend_total"), days: z21.number().int(), value: Count2 })
2194
+ ]),
2195
+ delta: z21.strictObject({ $source: z21.literal("views_change"), days: z21.number().int(), current: Count2, previous: Count2 }),
2196
+ series: z21.strictObject({ $source: z21.literal("spend_by_day"), days: z21.number().int(), points: z21.array(SpendDay).min(2).max(30) }),
2197
+ bars: z21.strictObject({ $source: z21.literal("post_views"), limit: z21.number().int(), posts: PostViewsViewSchema.shape.posts }),
2198
+ progress: z21.strictObject({ $source: z21.literal("posts_this_week"), value: Count2, max: z21.number().int().positive(), cadence: z21.string() }),
2199
+ board: z21.strictObject({ $source: z21.literal("roadmap"), groups: RoadmapViewSchema.shape.groups }),
2200
+ week: z21.strictObject({ $source: z21.literal("schedule"), days: ScheduleViewSchema.shape.days }),
2201
+ media: z21.array(z21.strictObject({ id: idOf("fil"), kind: z21.enum(["image", "video"]) })).min(1).max(4)
2202
+ };
2203
+ var box = { children: z21.array(Key).min(1).max(12) };
2204
+ var leaf = { children: z21.array(Key).max(0).optional() };
2205
+ var label = words(40).optional();
2206
+ var element = (type, props, children, about) => z21.strictObject({ type: z21.literal(type), props: z21.strictObject(props), ...children }).describe(about);
2207
+ function catalog(slot) {
2208
+ return {
2209
+ Card: element("Card", { title: words(60) }, box, "The card, with a short title. It is the root, and only the root."),
2210
+ Stack: element("Stack", {}, box, "Children one under another."),
2211
+ Grid: element("Grid", { columns: z21.literal([1, 2, 3]) }, box, "Children side by side, 1 to 3 columns."),
2212
+ Metric: element("Metric", { label: words(40), value: slot.value, delta: slot.delta.optional() }, leaf, "One big number with a label, and optionally its change."),
2213
+ LineChart: element("LineChart", { label, series: slot.series }, leaf, "A line over days."),
2214
+ BarList: element("BarList", { label, bars: slot.bars }, leaf, "One bar per post."),
2215
+ Progress: element("Progress", { label: words(40), progress: slot.progress }, leaf, "A value against its goal, as a bar."),
2216
+ Roadmap: element("Roadmap", { label, board: slot.board }, leaf, "The board grouped by status."),
2217
+ Schedule: element("Schedule", { label, week: slot.week }, leaf, "The week ahead, day by day."),
2218
+ Media: element("Media", { label, files: slot.media }, leaf, "Pictures or clips the company holds."),
2219
+ Text: element("Text", { text: words(240) }, leaf, "A short note in words.")
2220
+ };
2221
+ }
2222
+ var unknownComponent = (names) => ({
2223
+ error: (issue) => issue.code === "invalid_union" ? `unknown component: use one of ${names.join(", ")}` : void 0
2224
+ });
2225
+ function tree(rootType, max, spec2, ctx) {
2226
+ const refuse2 = (message3, path = []) => ctx.addIssue({ code: "custom", message: message3, path });
2227
+ const keys = Object.keys(spec2.elements);
2228
+ const has = (key) => Object.hasOwn(spec2.elements, key);
2229
+ if (keys.length > max) return refuse2(`at most ${max} elements`, ["elements"]);
2230
+ const root = has(spec2.root) ? spec2.elements[spec2.root] : void 0;
2231
+ if (!root) return refuse2(`root names "${spec2.root}", which is not in elements`, ["root"]);
2232
+ if (root.type !== rootType) return refuse2(`the root must be a ${rootType}`, ["root"]);
2233
+ const parent = /* @__PURE__ */ new Map();
2234
+ for (const key of keys) {
2235
+ for (const child of spec2.elements[key].children ?? []) {
2236
+ if (!has(child)) return refuse2(`"${child}" is not in elements`, ["elements", key, "children"]);
2237
+ if (child === spec2.root || parent.has(child)) return refuse2(`"${child}" has more than one parent`, ["elements", key, "children"]);
2238
+ if (spec2.elements[child].type === rootType) return refuse2(`a ${rootType} is the root only; group with Stack or Grid`, ["elements", child, "type"]);
2239
+ parent.set(child, key);
2240
+ }
2241
+ }
2242
+ const reached = /* @__PURE__ */ new Set([spec2.root]);
2243
+ for (const key of reached) for (const child of spec2.elements[key].children ?? []) reached.add(child);
2244
+ const lost = keys.find((key) => !reached.has(key));
2245
+ if (lost) refuse2(`"${lost}" is not under the root`, ["elements", lost]);
2246
+ }
2247
+ var spec = (element2, rootType, max) => z21.strictObject({ root: Key, elements: z21.record(Key, element2) }).superRefine((value, ctx) => tree(rootType, max, value, ctx));
2248
+
2249
+ // ../core/src/schema/compose.ts
2250
+ var COMPOSE_COMPONENTS = ["Card", "Stack", "Grid", "Metric", "LineChart", "BarList", "Progress", "Roadmap", "Schedule", "Media", "Text"];
2251
+ var MAX_COMPOSE_ELEMENTS = 24;
2252
+ var BoundComponents = catalog(Bound);
2253
+ var ComposeSpecSchema = spec(
2254
+ z22.discriminatedUnion(
2255
+ "type",
2256
+ [
2257
+ BoundComponents.Card,
2258
+ BoundComponents.Stack,
2259
+ BoundComponents.Grid,
2260
+ BoundComponents.Metric,
2261
+ BoundComponents.LineChart,
2262
+ BoundComponents.BarList,
2263
+ BoundComponents.Progress,
2264
+ BoundComponents.Roadmap,
2265
+ BoundComponents.Schedule,
2266
+ BoundComponents.Media,
2267
+ BoundComponents.Text
2268
+ ],
2269
+ unknownComponent(COMPOSE_COMPONENTS)
2270
+ ),
2271
+ "Card",
2272
+ MAX_COMPOSE_ELEMENTS
2273
+ );
2274
+ var ComposeArgsSchema = z22.object({
2275
+ spec: ComposeSpecSchema.describe(
2276
+ 'A json-render spec: { "root": key, "elements": { key: { "type", "props", "children"? } } }. The root is one Card.'
2277
+ )
2278
+ });
2279
+ var ComposedComponents = catalog(Resolved);
2280
+ var ComposedSpecSchema = spec(
2281
+ z22.discriminatedUnion(
2282
+ "type",
2283
+ [
2284
+ ComposedComponents.Card,
2285
+ ComposedComponents.Stack,
2286
+ ComposedComponents.Grid,
2287
+ ComposedComponents.Metric,
2288
+ ComposedComponents.LineChart,
2289
+ ComposedComponents.BarList,
2290
+ ComposedComponents.Progress,
2291
+ ComposedComponents.Roadmap,
2292
+ ComposedComponents.Schedule,
2293
+ ComposedComponents.Media,
2294
+ ComposedComponents.Text
2295
+ ],
2296
+ unknownComponent(COMPOSE_COMPONENTS)
2297
+ ),
2298
+ "Card",
2299
+ MAX_COMPOSE_ELEMENTS
2300
+ );
2301
+ var ComposedSchema = z22.object({ as_of: Timestamp, timezone: z22.string().min(1), spec: ComposedSpecSchema });
2302
+
2303
+ // ../core/src/schema/media.ts
2304
+ import { z as z23 } from "zod";
2305
+ var MEDIA_JOB_KINDS = ["video", "clip", "transcription"];
2306
+ var MediaJobKindSchema = z23.enum(MEDIA_JOB_KINDS);
2307
+ var MediaJobStatusSchema = z23.enum(["queued", "processing", "completed", "failed"]);
2308
+ var PublicUrl = z23.string().url().startsWith("http");
2309
+ var Score = z23.number().int().min(0).max(100);
2310
+ var Seconds = z23.number().nonnegative();
2311
+ var VideoResultSchema = z23.object({
2312
+ files: z23.array(
2313
+ z23.object({
1872
2314
  file_id: idOf("fil"),
1873
- content_type: z20.string(),
1874
- width: z20.number().int().positive().nullable(),
1875
- height: z20.number().int().positive().nullable(),
2315
+ content_type: z23.string(),
2316
+ width: z23.number().int().positive().nullable(),
2317
+ height: z23.number().int().positive().nullable(),
1876
2318
  duration_seconds: Seconds.nullable()
1877
2319
  })
1878
2320
  )
1879
2321
  });
1880
- var ViralityScoreSchema = z20.object({
2322
+ var ViralityScoreSchema = z23.object({
1881
2323
  total: Score,
1882
2324
  shareability: Score,
1883
2325
  hook_strength: Score,
1884
2326
  story_quality: Score,
1885
2327
  emotional_impact: Score
1886
2328
  });
1887
- var ClipResultSchema = z20.object({
1888
- clips: z20.array(
1889
- z20.object({
2329
+ var ClipResultSchema = z23.object({
2330
+ clips: z23.array(
2331
+ z23.object({
1890
2332
  file_id: idOf("fil"),
1891
- title: z20.string(),
2333
+ title: z23.string(),
1892
2334
  start_seconds: Seconds,
1893
2335
  end_seconds: Seconds,
1894
2336
  duration_seconds: Seconds,
@@ -1896,189 +2338,192 @@ var ClipResultSchema = z20.object({
1896
2338
  })
1897
2339
  )
1898
2340
  });
1899
- var TranscriptSchema = z20.object({
1900
- text: z20.string(),
1901
- language: z20.string().nullable(),
2341
+ var TranscriptSchema = z23.object({
2342
+ text: z23.string(),
2343
+ language: z23.string().nullable(),
1902
2344
  duration_seconds: Seconds.nullable(),
1903
- segments: z20.array(z20.object({ start_seconds: Seconds, end_seconds: Seconds, text: z20.string() }))
2345
+ segments: z23.array(z23.object({ start_seconds: Seconds, end_seconds: Seconds, text: z23.string() }))
1904
2346
  });
1905
- var MediaJobResultSchema = z20.union([VideoResultSchema, ClipResultSchema, TranscriptSchema]);
1906
- var MediaJobSchema = z20.object({
2347
+ var MediaJobResultSchema = z23.union([VideoResultSchema, ClipResultSchema, TranscriptSchema]);
2348
+ var MediaJobSchema = z23.object({
1907
2349
  id: idOf("med"),
1908
- object: z20.literal("media_job"),
2350
+ object: z23.literal("media_job"),
1909
2351
  kind: MediaJobKindSchema,
1910
2352
  status: MediaJobStatusSchema,
1911
- model: z20.string().nullable(),
1912
- input: z20.record(z20.string(), z20.unknown()),
2353
+ model: z23.string().nullable(),
2354
+ input: z23.record(z23.string(), z23.unknown()),
1913
2355
  result: MediaJobResultSchema.nullable(),
1914
- error: z20.object({ code: z20.string(), message: z20.string() }).nullable(),
2356
+ error: z23.object({ code: z23.string(), message: z23.string() }).nullable(),
1915
2357
  cost_micro_usd: MicroUsdField.nullable(),
1916
2358
  session_id: idOf("ses").nullable(),
1917
2359
  created_at: Timestamp,
1918
2360
  completed_at: Timestamp.nullable()
1919
2361
  });
1920
- var ImageRequestSchema = z20.object({
1921
- model: z20.string().min(1).optional(),
1922
- prompt: z20.string().min(1),
1923
- image_urls: z20.array(PublicUrl).max(4).optional(),
1924
- aspect_ratio: z20.string().optional(),
1925
- seed: z20.number().int().optional(),
1926
- n: z20.number().int().min(1).max(4).default(1)
1927
- });
1928
- var VideoRequestSchema = z20.object({
1929
- model: z20.string().min(1),
1930
- prompt: z20.string().min(1),
1931
- image_urls: z20.array(PublicUrl).max(1).optional(),
1932
- aspect_ratio: z20.string().optional(),
1933
- seed: z20.number().int().optional(),
1934
- seconds: z20.number().int().min(1).max(60).optional()
1935
- });
1936
- var ImageGenerationSchema = z20.object({
1937
- object: z20.literal("image_generation"),
1938
- model: z20.string(),
1939
- files: z20.array(FileSchema),
2362
+ var ImageRequestSchema = z23.object({
2363
+ model: z23.string().min(1).optional(),
2364
+ prompt: z23.string().min(1),
2365
+ image_urls: z23.array(PublicUrl).max(4).optional(),
2366
+ aspect_ratio: z23.string().optional(),
2367
+ seed: z23.number().int().optional(),
2368
+ n: z23.number().int().min(1).max(4).default(1)
2369
+ });
2370
+ var VideoRequestSchema = z23.object({
2371
+ /** Omitted: the platform's video default while the catalogue publishes it (`resolveModel`, §33.2). */
2372
+ model: z23.string().min(1).optional(),
2373
+ prompt: z23.string().min(1),
2374
+ image_urls: z23.array(PublicUrl).max(1).optional(),
2375
+ /** The source clip of a video-to-video edit (ADR-0814). */
2376
+ video_url: PublicUrl.optional(),
2377
+ aspect_ratio: z23.string().optional(),
2378
+ seed: z23.number().int().optional(),
2379
+ seconds: z23.number().int().min(1).max(60).optional()
2380
+ });
2381
+ var ImageGenerationSchema = z23.object({
2382
+ object: z23.literal("image_generation"),
2383
+ model: z23.string(),
2384
+ files: z23.array(FileSchema),
1940
2385
  cost_micro_usd: MicroUsdField
1941
2386
  });
1942
- var ClipLength = z20.number().int().min(5).max(180);
1943
- var ClipRequestSchema = z20.object({
2387
+ var ClipLength = z23.number().int().min(5).max(180);
2388
+ var ClipRequestSchema = z23.object({
1944
2389
  video_url: PublicUrl,
1945
- aspect_ratio: z20.enum(["9:16", "16:9"]).default("9:16"),
1946
- remove_silence: z20.boolean().default(false),
1947
- caption_preset: z20.enum(["none", "clean", "bold", "karaoke"]).default("none"),
1948
- language: z20.string().min(2).optional(),
2390
+ aspect_ratio: z23.enum(["9:16", "16:9"]).default("9:16"),
2391
+ remove_silence: z23.boolean().default(false),
2392
+ caption_preset: z23.enum(["none", "clean", "bold", "karaoke"]).default("none"),
2393
+ language: z23.string().min(2).optional(),
1949
2394
  min_seconds: ClipLength.default(15),
1950
2395
  max_seconds: ClipLength.default(60),
1951
- title: z20.string().min(1).optional()
2396
+ title: z23.string().min(1).optional()
1952
2397
  });
1953
- var AudioFormatSchema = z20.enum(["mp3", "wav", "ogg"]);
1954
- var TranscriptionRequestSchema = z20.object({
1955
- model: z20.string().min(1).optional(),
2398
+ var AudioFormatSchema = z23.enum(["mp3", "wav", "ogg"]);
2399
+ var TranscriptionRequestSchema = z23.object({
2400
+ model: z23.string().min(1).optional(),
1956
2401
  file_id: idOf("fil").optional(),
1957
2402
  url: PublicUrl.optional(),
1958
- language: z20.string().min(2).optional(),
1959
- timestamps: z20.boolean().default(true)
2403
+ language: z23.string().min(2).optional(),
2404
+ timestamps: z23.boolean().default(true)
1960
2405
  }).refine((request) => request.file_id === void 0 !== (request.url === void 0), {
1961
2406
  error: "exactly one of file_id or url",
1962
2407
  path: ["file_id"]
1963
2408
  });
1964
- var SpeechRequestSchema = z20.object({
1965
- model: z20.string().min(1).optional(),
1966
- text: z20.string().min(1).max(4096),
1967
- voice: z20.string().min(1).optional(),
2409
+ var SpeechRequestSchema = z23.object({
2410
+ model: z23.string().min(1).optional(),
2411
+ text: z23.string().min(1).max(4096),
2412
+ voice: z23.string().min(1).optional(),
1968
2413
  format: AudioFormatSchema.default("mp3"),
1969
- speed: z20.number().min(0.5).max(2).optional()
2414
+ speed: z23.number().min(0.5).max(2).optional()
1970
2415
  });
1971
- var SpeechToSpeechRequestSchema = z20.object({
1972
- model: z20.string().min(1).optional(),
2416
+ var SpeechToSpeechRequestSchema = z23.object({
2417
+ model: z23.string().min(1).optional(),
1973
2418
  file_id: idOf("fil"),
1974
- voice: z20.string().min(1).optional(),
2419
+ voice: z23.string().min(1).optional(),
1975
2420
  format: AudioFormatSchema.default("mp3")
1976
2421
  });
1977
- var SpeechGenerationSchema = z20.object({
1978
- object: z20.literal("speech_generation"),
1979
- model: z20.string(),
2422
+ var SpeechGenerationSchema = z23.object({
2423
+ object: z23.literal("speech_generation"),
2424
+ model: z23.string(),
1980
2425
  file: FileSchema,
1981
2426
  duration_seconds: Seconds.nullable(),
1982
2427
  cost_micro_usd: MicroUsdField
1983
2428
  });
1984
2429
 
1985
2430
  // ../core/src/schema/app-data.ts
1986
- import { z as z21 } from "zod";
1987
- var DbTableSchema = z21.object({
1988
- object: z21.literal("db_table"),
1989
- name: z21.string(),
1990
- schema: z21.string().default("public"),
1991
- rows: z21.number().int().nonnegative().nullable(),
1992
- size_bytes: z21.number().int().nonnegative().nullable()
1993
- });
1994
- var DbMigrationSchema = z21.object({
2431
+ import { z as z24 } from "zod";
2432
+ var DbTableSchema = z24.object({
2433
+ object: z24.literal("db_table"),
2434
+ name: z24.string(),
2435
+ schema: z24.string().default("public"),
2436
+ rows: z24.number().int().nonnegative().nullable(),
2437
+ size_bytes: z24.number().int().nonnegative().nullable()
2438
+ });
2439
+ var DbMigrationSchema = z24.object({
1995
2440
  id: idOf("dbm"),
1996
- object: z21.literal("db_migration"),
1997
- name: z21.string(),
1998
- sha256: z21.string().regex(/^[0-9a-f]{64}$/),
2441
+ object: z24.literal("db_migration"),
2442
+ name: z24.string(),
2443
+ sha256: z24.string().regex(/^[0-9a-f]{64}$/),
1999
2444
  applied_at: Timestamp,
2000
- statements: z21.number().int().nonnegative()
2445
+ statements: z24.number().int().nonnegative()
2001
2446
  });
2002
- var ApplyDbMigrationSchema = z21.object({
2003
- name: z21.string().min(1).max(128).regex(/^[a-z0-9][a-z0-9_-]*$/),
2004
- sql: z21.string().min(1)
2447
+ var ApplyDbMigrationSchema = z24.object({
2448
+ name: z24.string().min(1).max(128).regex(/^[a-z0-9][a-z0-9_-]*$/),
2449
+ sql: z24.string().min(1)
2005
2450
  });
2006
2451
  var DB_REST_METHODS = ["GET", "POST", "PATCH", "PUT", "DELETE", "HEAD"];
2007
- var DbRestMethodSchema = z21.enum(DB_REST_METHODS);
2452
+ var DbRestMethodSchema = z24.enum(DB_REST_METHODS);
2008
2453
  var BUCKET_NAME = /^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/;
2009
- var BucketSchema = z21.object({
2010
- object: z21.literal("bucket"),
2011
- name: z21.string().regex(BUCKET_NAME),
2012
- public: z21.boolean(),
2454
+ var BucketSchema = z24.object({
2455
+ object: z24.literal("bucket"),
2456
+ name: z24.string().regex(BUCKET_NAME),
2457
+ public: z24.boolean(),
2013
2458
  created_at: Timestamp
2014
2459
  });
2015
- var CreateBucketSchema = z21.object({
2016
- name: z21.string().regex(BUCKET_NAME, { error: "3\u201363 lowercase letters, digits and hyphens" }),
2017
- public: z21.boolean().default(false)
2018
- });
2019
- var StorageObjectSchema = z21.object({
2020
- object: z21.literal("storage_object"),
2021
- bucket: z21.string(),
2022
- key: z21.string().min(1),
2023
- size_bytes: z21.number().int().nonnegative(),
2024
- content_type: z21.string(),
2025
- etag: z21.string().nullable(),
2460
+ var CreateBucketSchema = z24.object({
2461
+ name: z24.string().regex(BUCKET_NAME, { error: "3\u201363 lowercase letters, digits and hyphens" }),
2462
+ public: z24.boolean().default(false)
2463
+ });
2464
+ var StorageObjectSchema = z24.object({
2465
+ object: z24.literal("storage_object"),
2466
+ bucket: z24.string(),
2467
+ key: z24.string().min(1),
2468
+ size_bytes: z24.number().int().nonnegative(),
2469
+ content_type: z24.string(),
2470
+ etag: z24.string().nullable(),
2026
2471
  updated_at: Timestamp
2027
2472
  });
2028
- var SignedUrlMethodSchema = z21.enum(["PUT", "GET"]);
2029
- var SignedUrlSchema = z21.object({
2030
- object: z21.literal("signed_url"),
2031
- url: z21.string().url(),
2473
+ var SignedUrlMethodSchema = z24.enum(["PUT", "GET"]);
2474
+ var SignedUrlSchema = z24.object({
2475
+ object: z24.literal("signed_url"),
2476
+ url: z24.string().url(),
2032
2477
  method: SignedUrlMethodSchema,
2033
2478
  expires_at: Timestamp
2034
2479
  });
2035
- var CreateUploadUrlSchema = z21.object({
2036
- content_type: z21.string().min(1),
2037
- expires_seconds: z21.number().int().min(60).max(3600).default(900)
2480
+ var CreateUploadUrlSchema = z24.object({
2481
+ content_type: z24.string().min(1),
2482
+ expires_seconds: z24.number().int().min(60).max(3600).default(900)
2038
2483
  });
2039
2484
 
2040
2485
  // ../core/src/schema/stock-photo.ts
2041
- import { z as z22 } from "zod";
2486
+ import { z as z25 } from "zod";
2042
2487
  var STOCK_PHOTO_ORIENTATIONS = ["landscape", "portrait", "square"];
2043
2488
  var STOCK_PHOTO_SIZES = ["small", "medium", "large"];
2044
- var StockPhotoQuerySchema = z22.object({
2045
- query: z22.string().min(1).max(200),
2046
- count: z22.coerce.number().int().min(1).max(30).default(10),
2047
- orientation: z22.enum(STOCK_PHOTO_ORIENTATIONS).optional(),
2048
- color: z22.string().min(1).max(32).optional(),
2049
- size: z22.enum(STOCK_PHOTO_SIZES).optional()
2050
- });
2051
- var StockPhotoSchema = z22.object({
2052
- object: z22.literal("stock_photo"),
2053
- id: z22.string().min(1),
2054
- width: z22.number().int().positive(),
2055
- height: z22.number().int().positive(),
2056
- url: z22.string().url(),
2057
- preview_url: z22.string().url(),
2058
- alt: z22.string().nullable(),
2059
- photographer: z22.string().nullable(),
2060
- attribution_url: z22.string().url().nullable(),
2061
- dominant_color: z22.string().nullable()
2489
+ var StockPhotoQuerySchema = z25.object({
2490
+ query: z25.string().min(1).max(200),
2491
+ count: z25.coerce.number().int().min(1).max(30).default(10),
2492
+ orientation: z25.enum(STOCK_PHOTO_ORIENTATIONS).optional(),
2493
+ color: z25.string().min(1).max(32).optional(),
2494
+ size: z25.enum(STOCK_PHOTO_SIZES).optional()
2495
+ });
2496
+ var StockPhotoSchema = z25.object({
2497
+ object: z25.literal("stock_photo"),
2498
+ id: z25.string().min(1),
2499
+ width: z25.number().int().positive(),
2500
+ height: z25.number().int().positive(),
2501
+ url: z25.string().url(),
2502
+ preview_url: z25.string().url(),
2503
+ alt: z25.string().nullable(),
2504
+ photographer: z25.string().nullable(),
2505
+ attribution_url: z25.string().url().nullable(),
2506
+ dominant_color: z25.string().nullable()
2062
2507
  });
2063
2508
 
2064
2509
  // ../core/src/schema/creator.ts
2065
- import { z as z23 } from "zod";
2066
- var CreatorCodeSchema = z23.string().regex(/^[a-z0-9]{3,24}$/, "3 to 24 lowercase letters or digits");
2067
- var PayoutMethodSchema = z23.enum(["wise", "paypal"]);
2068
- var PayoutDetailsSchema = z23.object({
2510
+ import { z as z26 } from "zod";
2511
+ var CreatorCodeSchema = z26.string().regex(/^[a-z0-9]{3,24}$/, "3 to 24 lowercase letters or digits");
2512
+ var PayoutMethodSchema = z26.enum(["wise", "paypal"]);
2513
+ var PayoutDetailsSchema = z26.object({
2069
2514
  method: PayoutMethodSchema,
2070
- account: z23.string().min(1).max(320)
2515
+ account: z26.string().min(1).max(320)
2071
2516
  });
2072
- var CreatorStatusSchema = z23.enum(["active", "suspended"]);
2073
- var CreatorSchema = z23.object({
2517
+ var CreatorStatusSchema = z26.enum(["active", "suspended"]);
2518
+ var CreatorSchema = z26.object({
2074
2519
  id: idOf("crt"),
2075
- object: z23.literal("creator"),
2076
- email: z23.email(),
2077
- display_name: z23.string().min(1).max(80),
2520
+ object: z26.literal("creator"),
2521
+ email: z26.email(),
2522
+ display_name: z26.string().min(1).max(80),
2078
2523
  code: CreatorCodeSchema,
2079
2524
  status: CreatorStatusSchema,
2080
2525
  payout: PayoutDetailsSchema.nullable(),
2081
- clicks: z23.number().int().nonnegative(),
2526
+ clicks: z26.number().int().nonnegative(),
2082
2527
  created_at: Timestamp,
2083
2528
  updated_at: Timestamp
2084
2529
  });
@@ -2086,28 +2531,28 @@ var IdentityCreatorSchema = CreatorSchema.pick({
2086
2531
  id: true,
2087
2532
  status: true
2088
2533
  });
2089
- var CreatorApplicationStatusSchema = z23.enum([
2534
+ var CreatorApplicationStatusSchema = z26.enum([
2090
2535
  "pending",
2091
2536
  "approved",
2092
2537
  "rejected"
2093
2538
  ]);
2094
- var CreatorApplicationSchema = z23.object({
2539
+ var CreatorApplicationSchema = z26.object({
2095
2540
  id: idOf("cra"),
2096
- object: z23.literal("creator_application"),
2097
- email: z23.email(),
2098
- display_name: z23.string().min(1).max(80),
2099
- pitch: z23.string().min(1).max(2e3),
2100
- links: z23.array(z23.url({ protocol: /^https$/ })).max(5),
2541
+ object: z26.literal("creator_application"),
2542
+ email: z26.email(),
2543
+ display_name: z26.string().min(1).max(80),
2544
+ pitch: z26.string().min(1).max(2e3),
2545
+ links: z26.array(z26.url({ protocol: /^https$/ })).max(5),
2101
2546
  status: CreatorApplicationStatusSchema,
2102
- note: z23.string().nullable(),
2547
+ note: z26.string().nullable(),
2103
2548
  creator_id: idOf("crt").nullable(),
2104
2549
  created_at: Timestamp,
2105
2550
  decided_at: Timestamp.nullable()
2106
2551
  });
2107
- var ReferralStatusSchema = z23.enum(["pending", "active", "expired"]);
2108
- var ReferralSchema = z23.object({
2552
+ var ReferralStatusSchema = z26.enum(["pending", "active", "expired"]);
2553
+ var ReferralSchema = z26.object({
2109
2554
  id: idOf("crf"),
2110
- object: z23.literal("referral"),
2555
+ object: z26.literal("referral"),
2111
2556
  creator_id: idOf("crt"),
2112
2557
  organization_id: idOf("org"),
2113
2558
  status: ReferralStatusSchema,
@@ -2115,16 +2560,16 @@ var ReferralSchema = z23.object({
2115
2560
  first_paid_at: Timestamp.nullable(),
2116
2561
  commission_until: Timestamp.nullable()
2117
2562
  });
2118
- var CommissionKindSchema = z23.enum(["referral", "template"]);
2119
- var CommissionStatusSchema = z23.enum([
2563
+ var CommissionKindSchema = z26.enum(["referral", "template"]);
2564
+ var CommissionStatusSchema = z26.enum([
2120
2565
  "pending",
2121
2566
  "available",
2122
2567
  "claimed",
2123
2568
  "paid"
2124
2569
  ]);
2125
- var CommissionSchema = z23.object({
2570
+ var CommissionSchema = z26.object({
2126
2571
  id: idOf("crc"),
2127
- object: z23.literal("commission"),
2572
+ object: z26.literal("commission"),
2128
2573
  creator_id: idOf("crt"),
2129
2574
  kind: CommissionKindSchema,
2130
2575
  referral_id: idOf("crf").nullable(),
@@ -2137,18 +2582,18 @@ var CommissionSchema = z23.object({
2137
2582
  available_at: Timestamp,
2138
2583
  payout_id: idOf("crp").nullable()
2139
2584
  });
2140
- var PayoutStatusSchema = z23.enum(["requested", "paid", "rejected"]);
2141
- var PayoutSchema = z23.object({
2585
+ var PayoutStatusSchema = z26.enum(["requested", "paid", "rejected"]);
2586
+ var PayoutSchema = z26.object({
2142
2587
  id: idOf("crp"),
2143
- object: z23.literal("payout"),
2588
+ object: z26.literal("payout"),
2144
2589
  creator_id: idOf("crt"),
2145
2590
  amount_micro_usd: MicroUsdField.positive(),
2146
- currency: z23.literal("USD"),
2591
+ currency: z26.literal("USD"),
2147
2592
  method: PayoutMethodSchema,
2148
- account: z23.string().min(1),
2593
+ account: z26.string().min(1),
2149
2594
  status: PayoutStatusSchema,
2150
- reference: z23.string().nullable(),
2151
- note: z23.string().nullable(),
2595
+ reference: z26.string().nullable(),
2596
+ note: z26.string().nullable(),
2152
2597
  requested_at: Timestamp,
2153
2598
  decided_at: Timestamp.nullable()
2154
2599
  });
@@ -2160,100 +2605,100 @@ var CREATOR_PROGRAM = {
2160
2605
  attribution_days: 30,
2161
2606
  minimum_payout_micro_usd: 2e7
2162
2607
  };
2163
- var CreatorTemplateSlugSchema = z23.string().max(32).regex(
2608
+ var CreatorTemplateSlugSchema = z26.string().max(32).regex(
2164
2609
  /^[a-z0-9]+(-[a-z0-9]+)*$/,
2165
2610
  "lowercase letters, digits and single dashes"
2166
2611
  );
2167
- var CreatorSkillSchema = z23.object({
2168
- slug: z23.string().regex(/^[a-z0-9][a-z0-9-]*$/, "lowercase letters, digits and dashes"),
2169
- body: z23.string().min(1).max(64 * 1024)
2612
+ var CreatorSkillSchema = z26.object({
2613
+ slug: z26.string().regex(/^[a-z0-9][a-z0-9-]*$/, "lowercase letters, digits and dashes"),
2614
+ body: z26.string().min(1).max(64 * 1024)
2170
2615
  });
2171
- var CreatorDeclarationSchema = z23.object({
2172
- agents: z23.array(z23.unknown()),
2173
- questions: z23.array(z23.unknown()),
2174
- skills: z23.array(CreatorSkillSchema).max(16)
2616
+ var CreatorDeclarationSchema = z26.object({
2617
+ agents: z26.array(z26.unknown()),
2618
+ questions: z26.array(z26.unknown()),
2619
+ skills: z26.array(CreatorSkillSchema).max(16)
2175
2620
  });
2176
- var CreatorTemplateVersionStatusSchema = z23.enum([
2621
+ var CreatorTemplateVersionStatusSchema = z26.enum([
2177
2622
  "in_review",
2178
2623
  "approved",
2179
2624
  "changes_requested"
2180
2625
  ]);
2181
- var VersionNumber = z23.number().int().positive();
2182
- var CreatorTemplateSchema = z23.object({
2626
+ var VersionNumber = z26.number().int().positive();
2627
+ var CreatorTemplateSchema = z26.object({
2183
2628
  id: idOf("ctp"),
2184
- object: z23.literal("creator_template"),
2629
+ object: z26.literal("creator_template"),
2185
2630
  creator_id: idOf("crt"),
2186
- blueprint: z23.string().min(1),
2187
- base_template: z23.string().min(1),
2631
+ blueprint: z26.string().min(1),
2632
+ base_template: z26.string().min(1),
2188
2633
  slug: CreatorTemplateSlugSchema,
2189
- template: z23.string().min(1).max(64),
2190
- name: z23.string().min(1).max(80),
2191
- description: z23.string().max(2e3),
2634
+ template: z26.string().min(1).max(64),
2635
+ name: z26.string().min(1).max(80),
2636
+ description: z26.string().max(2e3),
2192
2637
  declaration: CreatorDeclarationSchema,
2193
2638
  published_version: VersionNumber.nullable(),
2194
- latest_version: z23.object({
2639
+ latest_version: z26.object({
2195
2640
  version: VersionNumber,
2196
2641
  status: CreatorTemplateVersionStatusSchema
2197
2642
  }).nullable(),
2198
2643
  created_at: Timestamp,
2199
2644
  updated_at: Timestamp
2200
2645
  });
2201
- var CreatorTemplateVersionSchema = z23.object({
2202
- object: z23.literal("creator_template_version"),
2646
+ var CreatorTemplateVersionSchema = z26.object({
2647
+ object: z26.literal("creator_template_version"),
2203
2648
  template_id: idOf("ctp"),
2204
2649
  version: VersionNumber,
2205
2650
  declaration: CreatorDeclarationSchema,
2206
2651
  status: CreatorTemplateVersionStatusSchema,
2207
- note: z23.string().nullable(),
2652
+ note: z26.string().nullable(),
2208
2653
  artifact_id: idOf("bpa").nullable(),
2209
2654
  submitted_at: Timestamp,
2210
2655
  decided_at: Timestamp.nullable()
2211
2656
  });
2212
- var CreatorBalanceSchema = z23.object({
2213
- object: z23.literal("creator_balance"),
2657
+ var CreatorBalanceSchema = z26.object({
2658
+ object: z26.literal("creator_balance"),
2214
2659
  pending_micro_usd: MicroUsdField.nonnegative(),
2215
2660
  available_micro_usd: MicroUsdField.nonnegative(),
2216
2661
  claimed_micro_usd: MicroUsdField.nonnegative(),
2217
2662
  paid_micro_usd: MicroUsdField.nonnegative(),
2218
- minimum_payout_micro_usd: z23.literal(CREATOR_PROGRAM.minimum_payout_micro_usd)
2663
+ minimum_payout_micro_usd: z26.literal(CREATOR_PROGRAM.minimum_payout_micro_usd)
2219
2664
  });
2220
- var ReferralClickSchema = z23.object({
2221
- object: z23.literal("referral_click"),
2665
+ var ReferralClickSchema = z26.object({
2666
+ object: z26.literal("referral_click"),
2222
2667
  code: CreatorCodeSchema,
2223
- creator: z23.object({ display_name: z23.string().min(1) }),
2668
+ creator: z26.object({ display_name: z26.string().min(1) }),
2224
2669
  expires_at: Timestamp
2225
2670
  });
2226
- var Day = z23.iso.date();
2227
- var CreatorAnalyticsSchema = z23.object({
2228
- object: z23.literal("creator_analytics"),
2229
- days: z23.number().int().min(1).max(90),
2230
- from: Day,
2231
- to: Day,
2232
- clicks: z23.number().int().nonnegative(),
2233
- referrals: z23.number().int().nonnegative(),
2234
- installs: z23.number().int().nonnegative(),
2235
- active_installs: z23.number().int().nonnegative(),
2236
- usage_by_day: z23.array(
2237
- z23.object({ day: Day, debit_micro_usd: MicroUsdField.nonnegative() })
2671
+ var Day2 = z26.iso.date();
2672
+ var CreatorAnalyticsSchema = z26.object({
2673
+ object: z26.literal("creator_analytics"),
2674
+ days: z26.number().int().min(1).max(90),
2675
+ from: Day2,
2676
+ to: Day2,
2677
+ clicks: z26.number().int().nonnegative(),
2678
+ referrals: z26.number().int().nonnegative(),
2679
+ installs: z26.number().int().nonnegative(),
2680
+ active_installs: z26.number().int().nonnegative(),
2681
+ usage_by_day: z26.array(
2682
+ z26.object({ day: Day2, debit_micro_usd: MicroUsdField.nonnegative() })
2238
2683
  ),
2239
- commission_micro_usd: z23.object({
2684
+ commission_micro_usd: z26.object({
2240
2685
  pending: MicroUsdField.nonnegative(),
2241
2686
  available: MicroUsdField.nonnegative(),
2242
2687
  claimed: MicroUsdField.nonnegative(),
2243
2688
  paid: MicroUsdField.nonnegative()
2244
2689
  }),
2245
- commissions_by_template: z23.array(
2246
- z23.object({
2690
+ commissions_by_template: z26.array(
2691
+ z26.object({
2247
2692
  creator_template_id: idOf("ctp"),
2248
2693
  amount_micro_usd: MicroUsdField.nonnegative()
2249
2694
  })
2250
2695
  ),
2251
2696
  /** Every install covered, newest first: the day it was created and the day its twelve months end. */
2252
- install_windows: z23.array(z23.object({ install_id: idOf("bpi"), from: Day, until: Day }))
2697
+ install_windows: z26.array(z26.object({ install_id: idOf("bpi"), from: Day2, until: Day2 }))
2253
2698
  });
2254
2699
 
2255
2700
  // ../core/src/schema/legal.ts
2256
- import { z as z24 } from "zod";
2701
+ import { z as z27 } from "zod";
2257
2702
  var LEGAL_MEMBER_STATUSES = [
2258
2703
  "pending",
2259
2704
  "link_ready",
@@ -2263,16 +2708,16 @@ var LEGAL_MEMBER_STATUSES = [
2263
2708
  "verified",
2264
2709
  "failed"
2265
2710
  ];
2266
- var LegalMemberStatusSchema = z24.enum(LEGAL_MEMBER_STATUSES);
2711
+ var LegalMemberStatusSchema = z27.enum(LEGAL_MEMBER_STATUSES);
2267
2712
  var LEGAL_VERIFICATION_STATUSES = ["in_progress", "pending_review", "verified", "failed"];
2268
- var LegalVerificationStatusSchema = z24.enum(LEGAL_VERIFICATION_STATUSES);
2713
+ var LegalVerificationStatusSchema = z27.enum(LEGAL_VERIFICATION_STATUSES);
2269
2714
  var LEGAL_COMPANY_STATUSES = ["awaiting_payment", "paid", "submitted", "formed", "failed"];
2270
- var LegalCompanyStatusSchema = z24.enum(LEGAL_COMPANY_STATUSES);
2715
+ var LegalCompanyStatusSchema = z27.enum(LEGAL_COMPANY_STATUSES);
2271
2716
  var LEGAL_DOCUMENT_KINDS = ["articles", "ein_letter", "operating_agreement", "other"];
2272
- var LegalDocumentKindSchema = z24.enum(LEGAL_DOCUMENT_KINDS);
2273
- var LegalMemberRoleSchema = z24.enum(["primary", "secondary"]);
2274
- var LegalEinStatusSchema = z24.enum(["none", "pending", "issued"]);
2275
- var LegalRequiredActionKindSchema = z24.enum(["signature", "information", "payment", "other"]);
2717
+ var LegalDocumentKindSchema = z27.enum(LEGAL_DOCUMENT_KINDS);
2718
+ var LegalMemberRoleSchema = z27.enum(["primary", "secondary"]);
2719
+ var LegalEinStatusSchema = z27.enum(["none", "pending", "issued"]);
2720
+ var LegalRequiredActionKindSchema = z27.enum(["signature", "information", "payment", "other"]);
2276
2721
  var US_STATES = [
2277
2722
  "AL",
2278
2723
  "AK",
@@ -2326,105 +2771,105 @@ var US_STATES = [
2326
2771
  "WI",
2327
2772
  "WY"
2328
2773
  ];
2329
- var UsStateSchema = z24.enum(US_STATES);
2330
- var LegalMemberInputSchema = z24.object({
2331
- first_name: z24.string().min(1).max(128),
2332
- last_name: z24.string().min(1).max(128),
2333
- email: z24.string().min(1).max(320),
2774
+ var UsStateSchema = z27.enum(US_STATES);
2775
+ var LegalMemberInputSchema = z27.object({
2776
+ first_name: z27.string().min(1).max(128),
2777
+ last_name: z27.string().min(1).max(128),
2778
+ email: z27.string().min(1).max(320),
2334
2779
  role: LegalMemberRoleSchema,
2335
- is_responsible_party: z24.boolean(),
2336
- ownership_percent: z24.number().int()
2780
+ is_responsible_party: z27.boolean(),
2781
+ ownership_percent: z27.number().int()
2337
2782
  });
2338
2783
  var LegalMemberSchema = LegalMemberInputSchema.extend({
2339
2784
  id: idOf("lgm"),
2340
- object: z24.literal("legal_member"),
2785
+ object: z27.literal("legal_member"),
2341
2786
  verification_id: idOf("lgv"),
2342
2787
  status: LegalMemberStatusSchema,
2343
- link_url: z24.url().nullable(),
2788
+ link_url: z27.url().nullable(),
2344
2789
  link_expires_at: Timestamp.nullable(),
2345
2790
  completed_at: Timestamp.nullable()
2346
2791
  });
2347
- var LegalVerificationSchema = z24.object({
2792
+ var LegalVerificationSchema = z27.object({
2348
2793
  id: idOf("lgv"),
2349
- object: z24.literal("legal_verification"),
2794
+ object: z27.literal("legal_verification"),
2350
2795
  identity_id: idOf("idn"),
2351
2796
  status: LegalVerificationStatusSchema,
2352
- members: z24.array(LegalMemberSchema),
2353
- ready_for_formation: z24.boolean(),
2797
+ members: z27.array(LegalMemberSchema),
2798
+ ready_for_formation: z27.boolean(),
2354
2799
  started_at: Timestamp,
2355
2800
  completed_at: Timestamp.nullable(),
2356
2801
  created_at: Timestamp,
2357
2802
  updated_at: Timestamp
2358
2803
  });
2359
- var StartLegalVerificationSchema = z24.object({ members: z24.array(LegalMemberInputSchema) });
2360
- var CompleteLegalMemberSchema = z24.object({ token: z24.string().min(1) });
2361
- var LegalNameOptionSchema = z24.object({ name: z24.string().min(1).max(200), ending: z24.literal("LLC") });
2362
- var LegalMailingAddressSchema = z24.object({
2363
- line1: z24.string().min(1).max(200),
2364
- line2: z24.string().max(200).nullable(),
2365
- city: z24.string().min(1).max(100),
2804
+ var StartLegalVerificationSchema = z27.object({ members: z27.array(LegalMemberInputSchema) });
2805
+ var CompleteLegalMemberSchema = z27.object({ token: z27.string().min(1) });
2806
+ var LegalNameOptionSchema = z27.object({ name: z27.string().min(1).max(200), ending: z27.literal("LLC") });
2807
+ var LegalMailingAddressSchema = z27.object({
2808
+ line1: z27.string().min(1).max(200),
2809
+ line2: z27.string().max(200).nullable(),
2810
+ city: z27.string().min(1).max(100),
2366
2811
  state: UsStateSchema,
2367
- postal_code: z24.string().min(1).max(16),
2368
- country: z24.literal("US")
2812
+ postal_code: z27.string().min(1).max(16),
2813
+ country: z27.literal("US")
2369
2814
  });
2370
- var LegalRequiredActionSchema = z24.object({
2815
+ var LegalRequiredActionSchema = z27.object({
2371
2816
  kind: LegalRequiredActionKindSchema,
2372
- description: z24.string(),
2373
- url: z24.url().nullable()
2817
+ description: z27.string(),
2818
+ url: z27.url().nullable()
2374
2819
  });
2375
2820
  var LEGAL_DESCRIPTION_MAX = 50;
2376
- var CreateLegalCompanySchema = z24.object({
2821
+ var CreateLegalCompanySchema = z27.object({
2377
2822
  verification_id: idOf("lgv"),
2378
2823
  state: UsStateSchema,
2379
- name_options: z24.array(z24.string().min(1).max(200)).min(1).max(3),
2380
- naics_code: z24.string().regex(/^\d{2,6}$/),
2381
- description: z24.string().min(1).max(LEGAL_DESCRIPTION_MAX),
2824
+ name_options: z27.array(z27.string().min(1).max(200)).min(1).max(3),
2825
+ naics_code: z27.string().regex(/^\d{2,6}$/),
2826
+ description: z27.string().min(1).max(LEGAL_DESCRIPTION_MAX),
2382
2827
  mailing_address: LegalMailingAddressSchema
2383
2828
  });
2384
2829
  var LegalCompanySchema = CreateLegalCompanySchema.omit({ name_options: true }).extend({
2385
2830
  id: idOf("lgc"),
2386
- object: z24.literal("legal_company"),
2831
+ object: z27.literal("legal_company"),
2387
2832
  identity_id: idOf("idn"),
2388
2833
  status: LegalCompanyStatusSchema,
2389
- entity_type: z24.literal("llc"),
2390
- name_options: z24.array(LegalNameOptionSchema),
2391
- legal_name: z24.string().nullable(),
2834
+ entity_type: z27.literal("llc"),
2835
+ name_options: z27.array(LegalNameOptionSchema),
2836
+ legal_name: z27.string().nullable(),
2392
2837
  ein_status: LegalEinStatusSchema,
2393
2838
  price_micro_usd: MicroUsdField,
2394
- required_actions: z24.array(LegalRequiredActionSchema),
2395
- failure_reason: z24.string().max(256).nullable(),
2839
+ required_actions: z27.array(LegalRequiredActionSchema),
2840
+ failure_reason: z27.string().max(256).nullable(),
2396
2841
  submitted_at: Timestamp.nullable(),
2397
2842
  formed_at: Timestamp.nullable(),
2398
2843
  created_at: Timestamp,
2399
2844
  updated_at: Timestamp
2400
2845
  });
2401
- var LegalDocumentSchema = z24.object({
2846
+ var LegalDocumentSchema = z27.object({
2402
2847
  id: idOf("lgd"),
2403
- object: z24.literal("legal_document"),
2848
+ object: z27.literal("legal_document"),
2404
2849
  company_id: idOf("lgc"),
2405
2850
  kind: LegalDocumentKindSchema,
2406
- name: z24.string(),
2851
+ name: z27.string(),
2407
2852
  created_at: Timestamp
2408
2853
  });
2409
- var LegalDocumentLinkSchema = z24.object({
2410
- object: z24.literal("legal_document_link"),
2411
- url: z24.url(),
2854
+ var LegalDocumentLinkSchema = z27.object({
2855
+ object: z27.literal("legal_document_link"),
2856
+ url: z27.url(),
2412
2857
  expires_at: Timestamp
2413
2858
  });
2414
- var NaicsCodeSchema = z24.object({
2415
- object: z24.literal("naics_code"),
2416
- code: z24.string().regex(/^\d{2,6}$/),
2417
- title: z24.string()
2859
+ var NaicsCodeSchema = z27.object({
2860
+ object: z27.literal("naics_code"),
2861
+ code: z27.string().regex(/^\d{2,6}$/),
2862
+ title: z27.string()
2418
2863
  });
2419
- var LegalStateSchema = z24.object({
2420
- object: z24.literal("legal_state"),
2864
+ var LegalStateSchema = z27.object({
2865
+ object: z27.literal("legal_state"),
2421
2866
  code: UsStateSchema,
2422
- name: z24.string(),
2867
+ name: z27.string(),
2423
2868
  formation_fee_micro_usd: MicroUsdField
2424
2869
  });
2425
- var LegalWebhookEventSchema = z24.object({
2426
- provider_session_ref: z24.string().min(1),
2427
- status: z24.enum(["verified", "failed", "pending_review"]),
2870
+ var LegalWebhookEventSchema = z27.object({
2871
+ provider_session_ref: z27.string().min(1),
2872
+ status: z27.enum(["verified", "failed", "pending_review"]),
2428
2873
  metadata: Metadata
2429
2874
  });
2430
2875
  var LLC_ENDING = /\s*(?:,\s*)?(?:l\.?l\.?c\.?|limited\s+liability\s+company)\s*$/i;
@@ -2435,237 +2880,441 @@ function canonicalName(raw) {
2435
2880
  }
2436
2881
 
2437
2882
  // ../core/src/schema/wallet.ts
2438
- import { z as z25 } from "zod";
2883
+ import { z as z28 } from "zod";
2439
2884
  var WALLET_NETWORKS = ["eip155:84532", "eip155:8453"];
2440
- var WalletNetworkSchema = z25.enum(WALLET_NETWORKS);
2885
+ var WalletNetworkSchema = z28.enum(WALLET_NETWORKS);
2441
2886
  var DEFAULT_WALLET_NETWORK = "eip155:84532";
2442
- var WalletSelectSchema = z25.object({ network: WalletNetworkSchema.optional() });
2887
+ var WalletSelectSchema = z28.object({ network: WalletNetworkSchema.optional() });
2443
2888
  var WALLET_STATUSES = ["active", "frozen", "swept"];
2444
- var WalletStatusSchema = z25.enum(WALLET_STATUSES);
2889
+ var WalletStatusSchema = z28.enum(WALLET_STATUSES);
2445
2890
  var WALLET_TRANSACTION_KINDS = ["fund", "transfer", "pay", "sweep"];
2446
- var WalletTransactionKindSchema = z25.enum(WALLET_TRANSACTION_KINDS);
2891
+ var WalletTransactionKindSchema = z28.enum(WALLET_TRANSACTION_KINDS);
2447
2892
  var WALLET_TRANSACTION_STATUSES = ["pending", "confirmed", "failed"];
2448
- var WalletTransactionStatusSchema = z25.enum(WALLET_TRANSACTION_STATUSES);
2449
- var WalletDirectionSchema = z25.enum(["in", "out"]);
2450
- var WalletFundSourceSchema = z25.enum(["faucet", "treasury"]);
2451
- var EvmAddressSchema = z25.string().regex(/^0x[0-9a-fA-F]{40}$/, "expected a 0x address");
2452
- var TxHashSchema = z25.string().regex(/^0x[0-9a-fA-F]{64}$/, "expected a 0x transaction hash");
2453
- var WalletPolicySchema = z25.object({
2893
+ var WalletTransactionStatusSchema = z28.enum(WALLET_TRANSACTION_STATUSES);
2894
+ var WalletDirectionSchema = z28.enum(["in", "out"]);
2895
+ var WalletFundSourceSchema = z28.enum(["faucet", "treasury"]);
2896
+ var EvmAddressSchema = z28.string().regex(/^0x[0-9a-fA-F]{40}$/, "expected a 0x address");
2897
+ var TxHashSchema = z28.string().regex(/^0x[0-9a-fA-F]{64}$/, "expected a 0x transaction hash");
2898
+ var WalletPolicySchema = z28.object({
2454
2899
  per_tx_cap_micro_usd: MicroUsdField.nonnegative(),
2455
2900
  daily_cap_micro_usd: MicroUsdField.positive().nullable(),
2456
2901
  low_balance_micro_usd: MicroUsdField.nonnegative().nullable()
2457
2902
  });
2458
- var WalletSchema = z25.object({
2903
+ var WalletSchema = z28.object({
2459
2904
  id: idOf("wlt"),
2460
- object: z25.literal("wallet"),
2905
+ object: z28.literal("wallet"),
2461
2906
  identity_id: idOf("idn"),
2462
2907
  status: WalletStatusSchema,
2463
2908
  network: WalletNetworkSchema,
2464
2909
  address: EvmAddressSchema,
2465
- asset: z25.literal("usdc"),
2910
+ asset: z28.literal("usdc"),
2466
2911
  balance_micro_usd: MicroUsdField,
2467
2912
  policy: WalletPolicySchema,
2468
2913
  spent_today_micro_usd: MicroUsdField,
2469
2914
  created_at: Timestamp,
2470
2915
  updated_at: Timestamp
2471
2916
  });
2472
- var CreateWalletSchema = z25.object({
2917
+ var CreateWalletSchema = z28.object({
2473
2918
  network: WalletNetworkSchema.optional(),
2474
2919
  policy: WalletPolicySchema.partial().optional()
2475
2920
  });
2476
2921
  var UpdateWalletPolicySchema = WalletPolicySchema.partial();
2477
- var FundWalletSchema = z25.object({
2922
+ var FundWalletSchema = z28.object({
2478
2923
  amount_micro_usd: MicroUsdField.positive(),
2479
2924
  source: WalletFundSourceSchema
2480
2925
  });
2481
- var TransferWalletSchema = z25.object({
2482
- to: z25.union([EvmAddressSchema, idOf("idn")]),
2926
+ var TransferWalletSchema = z28.object({
2927
+ to: z28.union([EvmAddressSchema, idOf("idn")]),
2483
2928
  amount_micro_usd: MicroUsdField.positive(),
2484
- purpose: z25.string().min(1).max(256)
2929
+ purpose: z28.string().min(1).max(256)
2485
2930
  });
2486
- var SweepWalletSchema = z25.object({ to: EvmAddressSchema.optional() });
2487
- var WalletTransactionSchema = z25.object({
2931
+ var SweepWalletSchema = z28.object({ to: EvmAddressSchema.optional() });
2932
+ var WalletTransactionSchema = z28.object({
2488
2933
  id: idOf("wtx"),
2489
- object: z25.literal("wallet_transaction"),
2934
+ object: z28.literal("wallet_transaction"),
2490
2935
  wallet_id: idOf("wlt"),
2491
2936
  kind: WalletTransactionKindSchema,
2492
2937
  direction: WalletDirectionSchema,
2493
2938
  amount_micro_usd: MicroUsdField,
2494
- counterparty: z25.string().nullable(),
2495
- origin: z25.string().nullable(),
2496
- purpose: z25.string().nullable(),
2939
+ counterparty: z28.string().nullable(),
2940
+ origin: z28.string().nullable(),
2941
+ purpose: z28.string().nullable(),
2497
2942
  tx_hash: TxHashSchema.nullable(),
2498
2943
  session_id: idOf("ses").nullable(),
2499
2944
  status: WalletTransactionStatusSchema,
2500
2945
  created_at: Timestamp
2501
2946
  });
2502
- var ListWalletTransactionsSchema = z25.object({
2947
+ var ListWalletTransactionsSchema = z28.object({
2503
2948
  kind: WalletTransactionKindSchema.optional(),
2504
2949
  direction: WalletDirectionSchema.optional(),
2505
- origin: z25.string().optional(),
2950
+ origin: z28.string().optional(),
2506
2951
  since: Timestamp.optional()
2507
2952
  });
2508
- var HttpMethodSchema = z25.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]);
2509
- var WalletQuoteRequestSchema = z25.object({ url: z25.url(), method: HttpMethodSchema.optional() });
2510
- var WalletQuoteSchema = z25.object({
2511
- object: z25.literal("wallet_quote"),
2512
- url: z25.url(),
2513
- payable: z25.boolean(),
2953
+ var HttpMethodSchema = z28.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]);
2954
+ var WalletQuoteRequestSchema = z28.object({ url: z28.url(), method: HttpMethodSchema.optional() });
2955
+ var WalletQuoteSchema = z28.object({
2956
+ object: z28.literal("wallet_quote"),
2957
+ url: z28.url(),
2958
+ payable: z28.boolean(),
2514
2959
  network: WalletNetworkSchema.nullable(),
2515
- asset: z25.literal("usdc").nullable(),
2960
+ asset: z28.literal("usdc").nullable(),
2516
2961
  amount_micro_usd: MicroUsdField.nullable(),
2517
2962
  pay_to: EvmAddressSchema.nullable(),
2518
- description: z25.string().nullable(),
2519
- max_timeout_seconds: z25.number().int().nullable()
2963
+ description: z28.string().nullable(),
2964
+ max_timeout_seconds: z28.number().int().nullable()
2520
2965
  });
2521
2966
  var WalletPayRequestSchema = WalletQuoteRequestSchema.extend({
2522
2967
  max_amount_micro_usd: MicroUsdField.positive().optional()
2523
2968
  });
2524
2969
  var WALLET_RESPONSE_BODY_MAX = 64 * 1024;
2525
- var WalletPaymentSchema = z25.object({
2526
- object: z25.literal("wallet_payment"),
2527
- paid: z25.boolean(),
2970
+ var WalletPaymentSchema = z28.object({
2971
+ object: z28.literal("wallet_payment"),
2972
+ paid: z28.boolean(),
2528
2973
  transaction_id: idOf("wtx").nullable(),
2529
2974
  amount_micro_usd: MicroUsdField.nullable(),
2530
- response_status: z25.number().int(),
2531
- response_body: z25.string().max(WALLET_RESPONSE_BODY_MAX)
2975
+ response_status: z28.number().int(),
2976
+ response_body: z28.string().max(WALLET_RESPONSE_BODY_MAX)
2532
2977
  });
2533
2978
 
2534
2979
  // ../core/src/schema/cards.ts
2535
- import { z as z26 } from "zod";
2980
+ import { z as z29 } from "zod";
2536
2981
  var CARD_STATUSES = ["pending_payment", "issuing", "active", "failed", "cancelled", "refunded"];
2537
- var CardStatusSchema = z26.enum(CARD_STATUSES);
2982
+ var CardStatusSchema = z29.enum(CARD_STATUSES);
2538
2983
  var CARD_MIN_LOAD_MICRO_USD = 1e6;
2539
2984
  var CARD_MAX_LOAD_MICRO_USD = 15e7;
2540
2985
  var CARD_LOAD_GRANULARITY_MICRO_USD = 1e4;
2541
- var CardSchema = z26.object({
2986
+ var CardSchema = z29.object({
2542
2987
  id: idOf("vcd"),
2543
- object: z26.literal("card"),
2988
+ object: z29.literal("card"),
2544
2989
  identity_id: idOf("idn"),
2545
- kind: z26.literal("prepaid"),
2990
+ kind: z29.literal("prepaid"),
2546
2991
  status: CardStatusSchema,
2547
- label: z26.string().min(1).max(128),
2548
- brand: z26.string().nullable(),
2549
- last4: z26.string().regex(/^\d{4}$/).nullable(),
2992
+ label: z29.string().min(1).max(128),
2993
+ brand: z29.string().nullable(),
2994
+ last4: z29.string().regex(/^\d{4}$/).nullable(),
2550
2995
  load_micro_usd: MicroUsdField,
2551
2996
  spent_micro_usd: MicroUsdField,
2552
- currency: z26.literal("usd"),
2997
+ currency: z29.literal("usd"),
2553
2998
  expires_at: Timestamp.nullable(),
2554
- failure_reason: z26.string().max(256).nullable(),
2999
+ failure_reason: z29.string().max(256).nullable(),
2555
3000
  created_at: Timestamp,
2556
3001
  updated_at: Timestamp
2557
3002
  });
2558
- var IssueCardSchema = z26.object({
3003
+ var IssueCardSchema = z29.object({
2559
3004
  label: CardSchema.shape.label,
2560
3005
  load_micro_usd: MicroUsdField.min(CARD_MIN_LOAD_MICRO_USD).max(CARD_MAX_LOAD_MICRO_USD).multipleOf(CARD_LOAD_GRANULARITY_MICRO_USD)
2561
3006
  });
2562
3007
  var CardQuoteRequestSchema = IssueCardSchema.pick({ load_micro_usd: true });
2563
- var CardQuoteSchema = z26.object({
2564
- object: z26.literal("card_quote"),
3008
+ var CardQuoteSchema = z29.object({
3009
+ object: z29.literal("card_quote"),
2565
3010
  load_micro_usd: MicroUsdField,
2566
3011
  price_micro_usd: MicroUsdField,
2567
- brand: z26.string().nullable(),
3012
+ brand: z29.string().nullable(),
2568
3013
  min_load_micro_usd: MicroUsdField,
2569
3014
  max_load_micro_usd: MicroUsdField
2570
3015
  });
2571
- var CardCredentialsSchema = z26.object({
2572
- object: z26.literal("card_credentials"),
3016
+ var CardCredentialsSchema = z29.object({
3017
+ object: z29.literal("card_credentials"),
2573
3018
  card_id: idOf("vcd"),
2574
- number: z26.string().min(1),
2575
- pin: z26.string().nullable(),
2576
- cvv: z26.string().nullable(),
2577
- expiry: z26.string().nullable(),
2578
- url: z26.url().nullable(),
2579
- instructions: z26.string().nullable(),
3019
+ number: z29.string().min(1),
3020
+ pin: z29.string().nullable(),
3021
+ cvv: z29.string().nullable(),
3022
+ expiry: z29.string().nullable(),
3023
+ url: z29.url().nullable(),
3024
+ instructions: z29.string().nullable(),
2580
3025
  revealed_at: Timestamp
2581
3026
  });
2582
- var CardTransactionSchema = z26.object({
3027
+ var CardTransactionSchema = z29.object({
2583
3028
  id: idOf("vct"),
2584
- object: z26.literal("card_transaction"),
3029
+ object: z29.literal("card_transaction"),
2585
3030
  card_id: idOf("vcd"),
2586
3031
  amount_micro_usd: MicroUsdField,
2587
- merchant: z26.string().nullable(),
2588
- description: z26.string().nullable(),
3032
+ merchant: z29.string().nullable(),
3033
+ description: z29.string().nullable(),
2589
3034
  session_id: idOf("ses").nullable(),
2590
3035
  metadata: Metadata,
2591
3036
  created_at: Timestamp
2592
3037
  });
2593
- var LogCardTransactionSchema = z26.object({
3038
+ var LogCardTransactionSchema = z29.object({
2594
3039
  amount_micro_usd: MicroUsdField.positive(),
2595
- merchant: z26.string().max(256).optional(),
2596
- description: z26.string().max(1024).optional(),
3040
+ merchant: z29.string().max(256).optional(),
3041
+ description: z29.string().max(1024).optional(),
2597
3042
  metadata: Metadata.optional()
2598
3043
  });
2599
- var ListCardsSchema = z26.object({ status: CardStatusSchema.optional() });
3044
+ var ListCardsSchema = z29.object({ status: CardStatusSchema.optional() });
2600
3045
 
2601
3046
  // ../core/src/schema/proxy-trace.ts
2602
- import { z as z27 } from "zod";
2603
- var ProxyDialectSchema = z27.enum(["anthropic", "openai"]);
2604
- var ProxyTraceContentScopeSchema = z27.enum(["full", "metadata"]);
2605
- var ProxyTraceRequestSchema = z27.object({
2606
- system: z27.string(),
2607
- messages: z27.array(z27.object({ role: z27.string(), content: z27.string() })),
2608
- tool_names: z27.array(z27.string())
2609
- });
2610
- var ProxyTraceResponseSchema = z27.object({
2611
- text: z27.string(),
2612
- tool_calls: z27.array(z27.object({ name: z27.string(), arguments: z27.string() }))
2613
- });
2614
- var Sha256 = z27.string().regex(/^[0-9a-f]{64}$/);
2615
- var ProxyCallTraceSchema = z27.object({
3047
+ import { z as z30 } from "zod";
3048
+ var ProxyDialectSchema = z30.enum(["anthropic", "openai", "native"]);
3049
+ var ProxyTraceContentScopeSchema = z30.enum(["full", "metadata", "object"]);
3050
+ var TraceToolCall = z30.object({ id: z30.string().optional(), name: z30.string(), arguments: z30.string() });
3051
+ var ProxyTraceRequestSchema = z30.object({
3052
+ model: z30.string().optional(),
3053
+ window: WindowSchema.optional(),
3054
+ system: z30.string(),
3055
+ messages: z30.array(
3056
+ z30.looseObject({
3057
+ role: z30.string(),
3058
+ content: z30.string(),
3059
+ tool_calls: z30.array(z30.looseObject({ id: z30.string(), name: z30.string() })).optional(),
3060
+ tool_call_id: z30.string().optional()
3061
+ })
3062
+ ),
3063
+ tools: z30.array(z30.object({ name: z30.string(), description: z30.string(), parameters: z30.record(z30.string(), z30.unknown()) })).optional(),
3064
+ tool_schema_hash: z30.string().optional(),
3065
+ max_output_tokens: z30.number().int().optional(),
3066
+ tool_names: z30.array(z30.string()).optional()
3067
+ });
3068
+ var ProxyTraceResponseSchema = z30.object({
3069
+ text: z30.string(),
3070
+ reasoning: z30.string().optional(),
3071
+ reasoning_details: z30.array(z30.unknown()).optional(),
3072
+ tool_calls: z30.array(TraceToolCall),
3073
+ /** A call that threw, was abandoned or never completed (ADR-0794): the reply is what streamed before. */
3074
+ is_error: z30.literal(true).optional(),
3075
+ /** The error's class name — never its message — or `incomplete` for a stream that just stopped. */
3076
+ error_class: z30.string().optional(),
3077
+ partial: z30.literal(true).optional()
3078
+ });
3079
+ var Sha256 = z30.string().regex(/^[0-9a-f]{64}$/);
3080
+ var ProxyCallTraceSchema = z30.object({
2616
3081
  /** The request id: also `x-request-id`, the reply's `id`, and the ledger entry's idempotency key. */
2617
3082
  id: idOf("req"),
2618
- object: z27.literal("proxy_call_trace"),
3083
+ object: z30.literal("proxy_call_trace"),
2619
3084
  dialect: ProxyDialectSchema,
2620
3085
  /** The principal that made the call (§17). An API key here is the answer to "who sent this". */
2621
3086
  actor: PrincipalSchema,
2622
3087
  /** The public model id the caller asked for. */
2623
- model: z27.string(),
3088
+ model: z30.string(),
2624
3089
  window: WindowSchema,
2625
3090
  /** The model the reply said served it — where `vetta/auto` resolves — or null if it named none. */
2626
- resolved_model: z27.string().nullable(),
3091
+ resolved_model: z30.string().nullable(),
2627
3092
  /**
2628
3093
  * The serving provider and the gateway's own generation id. Null on every row written before the
2629
3094
  * adapter stops dropping them (Track A); together they are what lets an upstream invoice line be
2630
3095
  * matched back to an organization, a key and a ledger entry.
2631
3096
  */
2632
- provider: z27.string().nullable(),
2633
- generation_id: z27.string().nullable(),
2634
- stop: z27.enum(["end_turn", "tool_use", "length"]).nullable(),
3097
+ provider: z30.string().nullable(),
3098
+ generation_id: z30.string().nullable(),
3099
+ stop: z30.enum(["end_turn", "tool_use", "length"]).nullable(),
2635
3100
  usage: TokenUsageSchema,
2636
3101
  /** What the customer was charged, µUSD. The ledger entry is the authority; this is its copy. */
2637
3102
  billed_micro_usd: MicroUsdField.nullable(),
2638
3103
  /** What the vendor said it cost, µUSD. A CROSS-CHECK, NEVER A DEBIT. */
2639
3104
  vendor_cost_micro_usd: MicroUsdField.nullable(),
2640
- duration_ms: z27.number().int().nonnegative().nullable(),
3105
+ duration_ms: z30.number().int().nonnegative().nullable(),
2641
3106
  content_scope: ProxyTraceContentScopeSchema,
3107
+ /** `proxy` — a `/v1/proxy/*` call; `harness` — a hosted harness's own model call (ADR-0762). */
3108
+ source: z30.enum(["proxy", "harness"]),
3109
+ /** The session the call belongs to: a harness call's, or a sandbox token's `sub` on the proxy. */
3110
+ session_id: z30.string().nullable(),
3111
+ /**
3112
+ * The `seq` of the call's `span.model_request.end` event — or of its `.start` when the call failed
3113
+ * or its `.end` was withheld (ADR-0794). Null on the proxy, which writes no event.
3114
+ */
3115
+ seq: z30.number().int().nullable(),
3116
+ /** The board card the session was woken for (`session.metadata.board.card_id`), or null. */
3117
+ board_card_id: z30.string().nullable(),
3118
+ /** The ids of the tool calls this reply made — the join to the `tool.*` events they caused. */
3119
+ tool_call_ids: z30.array(z30.string()),
3120
+ /** sha-256 of the canonical JSON of the tool schema array the model was offered, or null. */
3121
+ tool_schema_hash: Sha256.nullable(),
2642
3122
  request_sha256: Sha256,
2643
3123
  response_sha256: Sha256,
2644
- /** The size of each body BEFORE any cap, so a truncated row still reports what was really sent. */
2645
- request_bytes: z27.number().int().nonnegative(),
2646
- response_bytes: z27.number().int().nonnegative(),
2647
- /** Null whenever `content_scope` is `metadata`. */
3124
+ /** The UTF-8 size of each stored body. */
3125
+ request_bytes: z30.number().int().nonnegative(),
3126
+ response_bytes: z30.number().int().nonnegative(),
3127
+ /** Inline in `full` scope — every new row. Null on a legacy `metadata` or `object` row. */
2648
3128
  request: ProxyTraceRequestSchema.nullable(),
2649
3129
  response: ProxyTraceResponseSchema.nullable(),
2650
- truncated: z27.boolean(),
3130
+ /** Always false since ADR-0762 (nothing is cut); true only on rows from before it. */
3131
+ truncated: z30.boolean(),
2651
3132
  created_at: Timestamp,
2652
- /** When the reaper deletes this row. Never null: there is no row that is kept forever. */
2653
- expires_at: Timestamp
3133
+ /** When the reaper deletes this row. Null since ADR-0762: model I/O is kept, not expired. */
3134
+ expires_at: Timestamp.nullable()
3135
+ });
3136
+
3137
+ // ../core/src/schema/review.ts
3138
+ import { z as z31 } from "zod";
3139
+ var ReviewDecisionSchema = z31.enum(["approve", "reject", "edit"]);
3140
+ var Fields = z31.record(z31.string().max(100), z31.unknown()).nullable().optional();
3141
+ var CreateReviewSchema = z31.object({
3142
+ decision: ReviewDecisionSchema,
3143
+ reason: z31.string().max(4e3).nullable().optional(),
3144
+ file_ids: z31.array(idOf("fil")).max(50).optional(),
3145
+ session_id: idOf("ses").optional(),
3146
+ subject: z31.record(z31.string().max(100), z31.unknown()).optional(),
3147
+ before: Fields,
3148
+ after: Fields
3149
+ });
3150
+
3151
+ // ../core/src/schema/mini-app.ts
3152
+ import { z as z32 } from "zod";
3153
+ var PAGE_BLOCKS = [
3154
+ "Page",
3155
+ "Section",
3156
+ "Stack",
3157
+ "Grid",
3158
+ "Metric",
3159
+ "LineChart",
3160
+ "BarList",
3161
+ "Progress",
3162
+ "Roadmap",
3163
+ "Schedule",
3164
+ "Media",
3165
+ "Text",
3166
+ "Needs",
3167
+ "Activity",
3168
+ "Accounts",
3169
+ "Posts",
3170
+ "Answers",
3171
+ "MediaLibrary"
3172
+ ];
3173
+ var MAX_PAGE_ELEMENTS = 48;
3174
+ var MINI_APP_ICONS = ["grid", "list", "chart", "calendar", "play"];
3175
+ var MiniAppIconSchema = z32.enum(MINI_APP_ICONS);
3176
+ var SLUG = "[a-z][a-z0-9-]{0,39}";
3177
+ var MiniAppSlugSchema = z32.string().regex(new RegExp(`^${SLUG}$`), "a slug is lowercase letters, digits and -");
3178
+ var Place = z32.string().regex(new RegExp(`^/(board|connections|apps/${SLUG}(\\?page=${SLUG})?)$`), "a section links to /board, /connections or /apps/<slug>[?page=<slug>]");
3179
+ var POSTS = ["waiting", "scheduled", "posted"];
3180
+ var PostStatus = z32.enum(POSTS);
3181
+ var PostLayout = z32.enum(["list", "row", "grid"]);
3182
+ var PostStatuses = z32.union([PostStatus, z32.array(PostStatus).min(1).max(3).refine((all) => new Set(all).size === all.length, "each status once")]);
3183
+ var PageBound = {
3184
+ ...Bound,
3185
+ board: bound(["roadmap"], { per_group: z32.number().int().min(1).max(5).default(5) }),
3186
+ media: bound(["latest_media", "newest_media"], { count: z32.number().int().min(1).max(6).default(4) })
3187
+ };
3188
+ var PageResolved = {
3189
+ ...Resolved,
3190
+ board: z32.strictObject({ $source: z32.literal("roadmap"), per_group: z32.number().int(), groups: RoadmapViewSchema.shape.groups }),
3191
+ media: z32.array(z32.strictObject({ id: z32.string(), kind: z32.enum(["image", "video"]) })).max(6)
3192
+ };
3193
+ function pageBlocks(slot) {
3194
+ return {
3195
+ Page: element("Page", {}, box, "The page itself, the root and only the root."),
3196
+ Section: element("Section", { title: words(40), to: Place.optional(), hide_empty: z32.boolean().optional() }, box, "A titled part of the page; hidden when every block in it is empty, if asked."),
3197
+ Needs: element("Needs", { label, needs: slot.needs }, leaf, "What waits on a person: approvals, questions, spent caps."),
3198
+ Activity: element("Activity", { label, agents: slot.agents }, leaf, "The agents working or waiting, and on what."),
3199
+ Accounts: element("Accounts", { accounts: slot.accounts }, leaf, "The template's networks: connected with a handle, or not."),
3200
+ Posts: element(
3201
+ "Posts",
3202
+ { label, layout: PostLayout.optional(), posts: slot.posts },
3203
+ leaf,
3204
+ "Posts waiting on a person, scheduled, or posted; several statuses make one list. Drawn as rows (list, the default), one sideways row of cards (row), or a picture grid (grid)."
3205
+ ),
3206
+ Answers: element("Answers", { answers: slot.answers }, leaf, "The setup's answers in one line, linking to the setup."),
3207
+ // No binding: the studio's gallery reads and pages the company's files itself (ADR-0987).
3208
+ MediaLibrary: element("MediaLibrary", {}, leaf, "Every picture and clip the company's agents made, with filters, sort and a viewer.")
3209
+ };
3210
+ }
3211
+ var OwnBound = pageBlocks({
3212
+ needs: bound(["needs"], {}),
3213
+ agents: bound(["agents_activity"], {}),
3214
+ accounts: bound(["accounts"], {}),
3215
+ posts: bound(["posts"], { status: PostStatuses, limit: z32.number().int().min(1).max(50).default(10) }),
3216
+ answers: bound(["answers"], { keys: z32.array(Key).min(1).max(TEMPLATE_QUESTIONS_MAX) })
3217
+ });
3218
+ var Need = z32.object({
3219
+ session_id: z32.string(),
3220
+ agent_id: z32.string(),
3221
+ agent: z32.string(),
3222
+ since: Timestamp,
3223
+ /** The chat's stored title, or `null`: the studio names it by when it began. */
3224
+ title: z32.string().nullable(),
3225
+ kind: z32.enum(["tool", "question", "budget"]),
3226
+ /** The call or question it is held on; `null` for a spent cap. */
3227
+ action: PendingActionSchema.nullable()
3228
+ });
3229
+ var Working = z32.object({
3230
+ agent_id: z32.string(),
3231
+ agent: z32.string(),
3232
+ state: z32.enum(["working", "waiting"]),
3233
+ session_id: z32.string().nullable(),
3234
+ title: z32.string().nullable(),
3235
+ at: Timestamp
3236
+ });
3237
+ var OwnResolved = pageBlocks({
3238
+ needs: z32.strictObject({ $source: z32.literal("needs"), items: z32.array(Need) }),
3239
+ agents: z32.strictObject({ $source: z32.literal("agents_activity"), agents: z32.array(Working) }),
3240
+ accounts: z32.strictObject({
3241
+ $source: z32.literal("accounts"),
3242
+ accounts: z32.array(z32.object({ platform: SocialPlatformSchema, connected: z32.boolean(), handle: z32.string().nullable() }))
3243
+ }),
3244
+ posts: z32.strictObject({ $source: z32.literal("posts"), status: z32.union([PostStatus, z32.array(PostStatus)]), limit: z32.number().int(), posts: z32.array(PostSchema), more: z32.boolean() }),
3245
+ answers: z32.strictObject({
3246
+ $source: z32.literal("answers"),
3247
+ keys: z32.array(z32.string()),
3248
+ values: z32.array(z32.string()),
3249
+ template: z32.object({ blueprint: z32.string(), template: z32.string() }).nullable()
3250
+ })
3251
+ });
3252
+ var BoundBlocks = { ...catalog(PageBound), ...OwnBound };
3253
+ var ResolvedBlocks = { ...catalog(PageResolved), ...OwnResolved };
3254
+ var Unread = element("Unread", { of: z32.string(), label: z32.string().nullable(), reason: z32.string() }, leaf, "A block that could not be read.");
3255
+ var B = BoundBlocks;
3256
+ var PageSpecSchema = spec(
3257
+ z32.discriminatedUnion(
3258
+ "type",
3259
+ [B.Page, B.Section, B.Stack, B.Grid, B.Metric, B.LineChart, B.BarList, B.Progress, B.Roadmap, B.Schedule, B.Media, B.Text, B.Needs, B.Activity, B.Accounts, B.Posts, B.Answers, B.MediaLibrary],
3260
+ unknownComponent(PAGE_BLOCKS)
3261
+ ),
3262
+ "Page",
3263
+ MAX_PAGE_ELEMENTS
3264
+ );
3265
+ var R = ResolvedBlocks;
3266
+ var ResolvedPageElementSchema = z32.discriminatedUnion(
3267
+ "type",
3268
+ [R.Page, R.Section, R.Stack, R.Grid, R.Metric, R.LineChart, R.BarList, R.Progress, R.Roadmap, R.Schedule, R.Media, R.Text, R.Needs, R.Activity, R.Accounts, R.Posts, R.Answers, R.MediaLibrary, Unread],
3269
+ unknownComponent(PAGE_BLOCKS)
3270
+ );
3271
+ var ResolvedPageSpecSchema = spec(ResolvedPageElementSchema, "Page", MAX_PAGE_ELEMENTS);
3272
+ var unique = (items) => new Set(items.map((item) => item.slug)).size === items.length;
3273
+ var MiniAppPageSchema = z32.strictObject({ slug: MiniAppSlugSchema, title: words(24), spec: PageSpecSchema });
3274
+ var MiniAppDeclSchema = z32.strictObject({
3275
+ slug: MiniAppSlugSchema,
3276
+ name: words(40),
3277
+ icon: MiniAppIconSchema,
3278
+ pages: z32.array(MiniAppPageSchema).min(1).max(6).refine(unique, "each page's slug is its own")
3279
+ });
3280
+ var MiniAppDeclsSchema = z32.array(MiniAppDeclSchema).max(8).refine(unique, "each mini app's slug is its own");
3281
+ var MiniAppSummarySchema = z32.object({
3282
+ object: z32.literal("mini_app"),
3283
+ slug: MiniAppSlugSchema,
3284
+ name: z32.string(),
3285
+ icon: MiniAppIconSchema,
3286
+ pages: z32.array(z32.object({ slug: MiniAppSlugSchema, title: z32.string() })).min(1),
3287
+ /** What it reads (`miniAppReads`). Absent from an older API: the Studio then claims nothing it cannot see. */
3288
+ reads: z32.array(z32.string()).optional()
3289
+ });
3290
+ var MiniAppSchema = MiniAppSummarySchema.extend({
3291
+ networks: z32.array(z32.object({ platform: SocialPlatformSchema, connected: z32.boolean().nullable() })),
3292
+ page: MiniAppSlugSchema,
3293
+ as_of: Timestamp,
3294
+ timezone: z32.string().min(1),
3295
+ spec: ResolvedPageSpecSchema
2654
3296
  });
2655
3297
 
3298
+ // ../core/src/session-token.ts
3299
+ var SESSION_TTL_SECONDS = 30 * 24 * 60 * 60;
3300
+ var encoder = new TextEncoder();
3301
+
3302
+ // ../core/src/logo-svg.ts
3303
+ var MAX_BYTES = 16 * 1024;
3304
+
2656
3305
  // ../core/src/file-url.ts
2657
3306
  var encoder2 = new TextEncoder();
2658
3307
  var SESSION_FILE_URL_TTL_MS = 15 * 6e4;
2659
3308
 
2660
3309
  // src/define.ts
2661
- import { z as z30 } from "zod";
3310
+ import { z as z35 } from "zod";
2662
3311
 
2663
3312
  // src/roster.ts
2664
- import { z as z29 } from "zod";
3313
+ import { z as z34 } from "zod";
2665
3314
 
2666
3315
  // src/report.ts
2667
3316
  import { ApiError, send } from "@usenaive-sdk/vetta";
2668
- import { z as z28 } from "zod";
3317
+ import { z as z33 } from "zod";
2669
3318
  function message(error) {
2670
3319
  if (error instanceof ApiError && error.requestId !== "") return `${error.message} (request ${error.requestId})`;
2671
3320
  return error instanceof Error ? error.message : String(error);
@@ -2707,15 +3356,15 @@ async function absent(work) {
2707
3356
  throw error;
2708
3357
  }
2709
3358
  }
2710
- var PageShape = z28.object({
2711
- data: z28.array(z28.unknown()),
2712
- has_more: z28.boolean(),
2713
- next_cursor: z28.string().nullable()
3359
+ var PageShape = z33.object({
3360
+ data: z33.array(z33.unknown()),
3361
+ has_more: z33.boolean(),
3362
+ next_cursor: z33.string().nullable()
2714
3363
  });
2715
3364
  function rowLabel(row) {
2716
3365
  const { object, id } = row ?? {};
2717
- const words = [object, id].filter((one) => typeof one === "string");
2718
- return words.length > 0 ? words.join(" ") : "a row";
3366
+ const words2 = [object, id].filter((one) => typeof one === "string");
3367
+ return words2.length > 0 ? words2.join(" ") : "a row";
2719
3368
  }
2720
3369
  var why = (error) => error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`).join("; ");
2721
3370
  async function listAll(config, path, item, skipped, query = {}) {
@@ -2742,17 +3391,17 @@ async function tombstone(name, current, remove, dryRun) {
2742
3391
  }
2743
3392
 
2744
3393
  // src/roster.ts
2745
- var NAME = z29.string().min(1);
2746
- var RosterNameSchema = z29.union([
3394
+ var NAME = z34.string().min(1);
3395
+ var RosterNameSchema = z34.union([
2747
3396
  NAME.transform((name) => ({ type: "agent", name })),
2748
- z29.object({ type: z29.literal("agent"), name: NAME, version: z29.number().int().positive().optional() }),
2749
- z29.object({ type: z29.literal("self") }),
2750
- z29.object({ type: z29.literal("advisor"), model: z29.string().min(1) })
3397
+ z34.object({ type: z34.literal("agent"), name: NAME, version: z34.number().int().positive().optional() }),
3398
+ z34.object({ type: z34.literal("self") }),
3399
+ z34.object({ type: z34.literal("advisor"), model: z34.string().min(1) })
2751
3400
  ]);
2752
- var DeclMultiagentField = z29.union([
2753
- z29.boolean(),
2754
- z29.object({ ...MultiagentSchema.shape, agents: z29.array(RosterNameSchema).min(1).max(20) }),
2755
- z29.null()
3401
+ var DeclMultiagentField = z34.union([
3402
+ z34.boolean(),
3403
+ z34.object({ ...MultiagentSchema.shape, agents: z34.array(RosterNameSchema).min(1).max(20) }),
3404
+ z34.null()
2756
3405
  ]);
2757
3406
  var hasRoster = (value) => typeof value === "object" && value !== null;
2758
3407
  var rosterNames = (roster) => roster.agents.flatMap((entry) => entry.type === "agent" ? [entry.name] : []);
@@ -2809,8 +3458,14 @@ var BLUEPRINTS = {
2809
3458
  * Post queue, accounts, calendar, analytics. The wire ids are frozen: `install.template` is a
2810
3459
  * stored string on every provisioned org, so the display names moved ("Naive Short Form v1",
2811
3460
  * "Naive Long Form v1", "Naive Clipping v1") and these did not.
3461
+ *
3462
+ * The first three are the base crews. The six after them are NICHE CHANNEL TEMPLATES (ADR-1115,
3463
+ * ADR-1119): each is a thin template that reuses a base crew (`gaming-clips`/`news`/`sports` on
3464
+ * `clipping`; `ufc`/`history`/`animal-feast` on `faceless`) and pins `naive/channel-template-<niche>`
3465
+ * in every seat's `skills[]`. They are ordinary templates of this blueprint, so they publish, install
3466
+ * and switch through the exact paths the base three do — the whole point of a template being data.
2812
3467
  */
2813
- media: { templates: ["faceless", "longform", "clipping"] },
3468
+ media: { templates: ["faceless", "longform", "clipping", "gaming-clips", "news", "sports", "ufc", "history", "animal-feast"] },
2814
3469
  /** Pages, posts, forms, analytics — a published site with a crew behind it (`usenaive/web-blueprint`). */
2815
3470
  web: { templates: ["publisher"], default: "publisher" }
2816
3471
  };
@@ -2844,65 +3499,65 @@ function chooseTemplate(blueprint, template) {
2844
3499
  var BlueprintRefusal = class extends Error {
2845
3500
  name = "BlueprintRefusal";
2846
3501
  };
2847
- var EnvValueSchema = z30.union([
2848
- z30.string(),
2849
- z30.object({ from_env: z30.string().min(1) }),
2850
- z30.object({ generate: z30.literal(true) })
3502
+ var EnvValueSchema = z35.union([
3503
+ z35.string(),
3504
+ z35.object({ from_env: z35.string().min(1) }),
3505
+ z35.object({ generate: z35.literal(true) })
2851
3506
  ]);
2852
- var AppDeclSchema = z30.object({
3507
+ var AppDeclSchema = z35.object({
2853
3508
  /** Becomes a hostname, so the grammar is the platform's `APP_NAME` (a DNS label). */
2854
- name: z30.string().regex(APP_NAME, "a lowercase DNS label, 63 characters or fewer"),
3509
+ name: z35.string().regex(APP_NAME, "a lowercase DNS label, 63 characters or fewer"),
2855
3510
  type: AppTypeSchema,
2856
- description: z30.string().optional(),
3511
+ description: z35.string().optional(),
2857
3512
  /** A directory whose files are collected and shipped as the app's file-map deployment. */
2858
- deploy_dir: z30.string().min(1).optional(),
3513
+ deploy_dir: z35.string().min(1).optional(),
2859
3514
  /** The path the app itself serves MCP on (§29.5); `fullstack` only. Absent means none. */
2860
3515
  mcp: AppMcpPathSchema.optional(),
2861
3516
  /** Written as the app's write-only secrets (§29.2) on every apply; names follow the platform's `ENV_NAME`. */
2862
- env: z30.record(z30.string().regex(ENV_NAME), EnvValueSchema, { error: "keyed by environment variable name (A-Z, 0-9, _)" }).optional(),
3517
+ env: z35.record(z35.string().regex(ENV_NAME), EnvValueSchema, { error: "keyed by environment variable name (A-Z, 0-9, _)" }).optional(),
2863
3518
  /** An install may not leave this app out of its `selection` (§31.2). Absent means it may. */
2864
- required: z30.boolean().optional(),
3519
+ required: z35.boolean().optional(),
2865
3520
  // core-gaps: U8-database
2866
3521
  /** SQL files applied in order to the app's database after it is provisioned (§37); `fullstack` only. */
2867
- migrations: z30.array(z30.string().min(1)).optional(),
3522
+ migrations: z35.array(z35.string().min(1)).optional(),
2868
3523
  // core-gaps: storage-stock
2869
3524
  /** Buckets the app's object store must hold (§38.2); `fullstack` only. `public` defaults to false. */
2870
- buckets: z30.array(CreateBucketSchema).optional()
3525
+ buckets: z35.array(CreateBucketSchema).optional()
2871
3526
  });
2872
- var ScheduleDeclSchema = z30.object({
2873
- cron: z30.string().min(1),
2874
- timezone: z30.string().min(1).optional(),
3527
+ var ScheduleDeclSchema = z35.object({
3528
+ cron: z35.string().min(1),
3529
+ timezone: z35.string().min(1).optional(),
2875
3530
  /** The message every fire opens its session with (`input_template` on the wire). */
2876
- input: z30.string().min(1),
3531
+ input: z35.string().min(1),
2877
3532
  budget_micro_usd: MicroUsdField.nonnegative(),
2878
- identity: z30.string().min(1).optional(),
2879
- enabled: z30.boolean().optional()
3533
+ identity: z35.string().min(1).optional(),
3534
+ enabled: z35.boolean().optional()
2880
3535
  });
2881
3536
  var ToolsDeclSchema = ToolsetSchema;
2882
- var AgentDeclSchema = z30.object({
2883
- name: z30.string().min(1),
2884
- model: z30.string().min(1),
3537
+ var AgentDeclSchema = z35.object({
3538
+ name: z35.string().min(1),
3539
+ model: z35.string().min(1),
2885
3540
  budget: BudgetSchema,
2886
- description: z30.string().optional(),
3541
+ description: z35.string().optional(),
2887
3542
  /** Two or three words the studio prints beside the name (§31.5) — "Head of content", not a sentence. */
2888
- role: z30.string().min(1).optional(),
3543
+ role: z35.string().min(1).optional(),
2889
3544
  /** An install may not leave this agent out of its `selection` (§31.2). Absent means it may. */
2890
- required: z30.boolean().optional(),
2891
- system: z30.string().optional(),
3545
+ required: z35.boolean().optional(),
3546
+ system: z35.string().optional(),
2892
3547
  tools: ToolsDeclSchema.optional(),
2893
- skills: z30.array(SkillRefSchema).optional(),
2894
- mcp_servers: z30.array(McpServerSchema).optional(),
3548
+ skills: z35.array(SkillRefSchema).optional(),
3549
+ mcp_servers: z35.array(McpServerSchema).optional(),
2895
3550
  /** The rest of the runtime's agent config (§31.6), each the core schema; absent means the route's default and never drift. */
2896
3551
  window: WindowSchema.optional(),
2897
3552
  /** A roster names crew members by declared *name*; `up` resolves them to `agt_` ids in a second pass (`roster.ts`). */
2898
3553
  multiagent: DeclMultiagentField.optional(),
2899
3554
  output_schema: JsonSchemaDocument.nullable().optional(),
2900
- structured_output_required: z30.boolean().optional(),
3555
+ structured_output_required: z35.boolean().optional(),
2901
3556
  metadata: Metadata.optional(),
2902
3557
  /** Declared app *names*; `up` resolves them to `app_` ids in `tools.configs.apps` (§29.3). */
2903
- allowed_apps: z30.array(z30.string()).optional(),
3558
+ allowed_apps: z35.array(z35.string()).optional(),
2904
3559
  /** A declared identity *name*; `up` attaches it after the agent upsert (§22). */
2905
- identity: z30.string().min(1).optional(),
3560
+ identity: z35.string().min(1).optional(),
2906
3561
  /**
2907
3562
  * Who this agent may `send_to_agent` (§31.7, §28.12): `true` (anyone in the organization),
2908
3563
  * `false` (nobody), `"team"` (its `multiagent` roster), or declared agent *names*, checked
@@ -2910,7 +3565,7 @@ var AgentDeclSchema = z30.object({
2910
3565
  */
2911
3566
  handoffs: HandoffsField.optional(),
2912
3567
  /** The agent's deployments as a complete set: declared → owned, and the rest are pruned (ADR-0355). */
2913
- schedules: z30.array(ScheduleDeclSchema).optional(),
3568
+ schedules: z35.array(ScheduleDeclSchema).optional(),
2914
3569
  /**
2915
3570
  * The first thing this agent reads, once, on the apply that **creates** it (`canonical-spec
2916
3571
  * §31.4`). It is what turns a provisioned crew into a crew that has started working.
@@ -2923,66 +3578,79 @@ var AgentDeclSchema = z30.object({
2923
3578
  * repeatedly and unattended while an intake spends once, at an apply a person is watching. Absent
2924
3579
  * means the agent's own `budget` governs.
2925
3580
  */
2926
- intake: z30.object({ message: z30.string().min(1), budget_micro_usd: MicroUsdField.nonnegative().optional() }).optional()
3581
+ intake: z35.object({ message: z35.string().min(1), budget_micro_usd: MicroUsdField.nonnegative().optional() }).optional()
2927
3582
  });
2928
- var CredentialDeclSchema = z30.object({
3583
+ var CredentialDeclSchema = z35.object({
2929
3584
  kind: VaultCredentialKindSchema,
2930
- key: z30.string().min(1).max(128),
3585
+ key: z35.string().min(1).max(128),
2931
3586
  /** The one exact destination host an `env_var` is bound to. */
2932
- host: z30.string().min(1).optional(),
3587
+ host: z35.string().min(1).optional(),
2933
3588
  /** The MCP server URL a `static_bearer` / `mcp_oauth` token is matched to. */
2934
- mcp_server_url: z30.url().optional(),
2935
- value: z30.object({ from_env: z30.string().min(1) })
3589
+ mcp_server_url: z35.url().optional(),
3590
+ value: z35.object({ from_env: z35.string().min(1) })
2936
3591
  });
2937
- var VaultDeclSchema = z30.object({
3592
+ var VaultDeclSchema = z35.object({
2938
3593
  name: VaultSchema.shape.display_name,
2939
- identity: z30.string().min(1).optional(),
2940
- credentials: z30.array(CredentialDeclSchema)
3594
+ identity: z35.string().min(1).optional(),
3595
+ credentials: z35.array(CredentialDeclSchema)
2941
3596
  });
2942
- var SkillDeclSchema = z30.object({
2943
- slug: z30.string().regex(/^[a-z0-9][a-z0-9-]*$/, "lowercase letters, digits and dashes"),
2944
- file: z30.string().min(1)
3597
+ var SkillDeclSchema = z35.object({
3598
+ slug: z35.string().regex(/^[a-z0-9][a-z0-9-]*$/, "lowercase letters, digits and dashes"),
3599
+ file: z35.string().min(1)
2945
3600
  });
2946
3601
  var LegalDeclSchema = CreateLegalCompanySchema.pick({
2947
3602
  state: true,
2948
3603
  name_options: true,
2949
3604
  naics_code: true,
2950
3605
  description: true
2951
- }).extend({ label: z30.string().min(1).max(128) });
3606
+ }).extend({ label: z35.string().min(1).max(128) });
2952
3607
  var WalletDeclSchema = CreateWalletSchema.or(
2953
- z30.array(CreateWalletSchema).refine(
3608
+ z35.array(CreateWalletSchema).refine(
2954
3609
  (list2) => new Set(list2.map((w) => w.network ?? DEFAULT_WALLET_NETWORK)).size === list2.length,
2955
3610
  { message: "one wallet per network" }
2956
3611
  )
2957
3612
  );
2958
3613
  var CardDeclSchema = IssueCardSchema;
2959
3614
  var IdentityDeclSchema = IdentitySchema.pick({ name: true, description: true }).partial({ description: true }).extend({
2960
- connections: BlueprintIdentityConnectionsSchema.optional(),
2961
- legal: z30.array(LegalDeclSchema).optional(),
3615
+ legal: z35.array(LegalDeclSchema).optional(),
2962
3616
  wallet: WalletDeclSchema.optional(),
2963
- cards: z30.array(CardDeclSchema).optional()
2964
- });
2965
- var RemovedSchema = z30.object({
2966
- apps: z30.array(z30.string().min(1)).default([]),
2967
- agents: z30.array(z30.string().min(1)).default([]),
2968
- skills: z30.array(z30.string().min(1)).default([]),
2969
- identities: z30.array(z30.string().min(1)).default([]),
2970
- vaults: z30.array(z30.string().min(1)).default([])
2971
- });
2972
- var KeptSchema = z30.object({ agents: z30.array(z30.string().min(1)).default([]) });
2973
- var TaskDeclSchema = z30.object({
2974
- key: z30.string().min(1),
2975
- title: z30.string().min(1).max(200),
2976
- body: z30.string().max(8192).optional(),
2977
- assignee: z30.string().min(1).optional(),
2978
- blocked_by: z30.array(z30.string().min(1)).optional()
2979
- });
2980
- var ProjectSchema = z30.object({
2981
- name: z30.string().min(1),
3617
+ cards: z35.array(CardDeclSchema).optional()
3618
+ });
3619
+ var RemovedSchema = z35.object({
3620
+ apps: z35.array(z35.string().min(1)).default([]),
3621
+ agents: z35.array(z35.string().min(1)).default([]),
3622
+ skills: z35.array(z35.string().min(1)).default([]),
3623
+ identities: z35.array(z35.string().min(1)).default([]),
3624
+ vaults: z35.array(z35.string().min(1)).default([])
3625
+ });
3626
+ var KeptSchema = z35.object({ agents: z35.array(z35.string().min(1)).default([]) });
3627
+ var TaskDeclSchema = z35.object({
3628
+ key: z35.string().min(1),
3629
+ title: z35.string().min(1).max(200),
3630
+ body: z35.string().max(8192).optional(),
3631
+ assignee: z35.string().min(1).optional(),
3632
+ blocked_by: z35.array(z35.string().min(1)).optional()
3633
+ });
3634
+ var ProjectSchema = z35.object({
3635
+ name: z35.string().min(1),
2982
3636
  /** The machine this project runs: its repo, its screens, its `/api/*` (`template.ts`). */
2983
- blueprint: z30.string().min(1).optional(),
3637
+ blueprint: z35.string().min(1).optional(),
2984
3638
  /** Which of that blueprint's templates provides the crew; a blueprint with a default may omit it. */
2985
- template: z30.string().min(1).optional(),
3639
+ template: z35.string().min(1).optional(),
3640
+ /**
3641
+ * What a person calls this template, one line on what its crew does, and the networks it
3642
+ * publishes to (`canonical-spec §31.5`). Printed on the artifact and never provisioned: where the
3643
+ * crew posts is the accounts connected to its persona, not this list.
3644
+ */
3645
+ title: z35.string().min(1).max(80).optional(),
3646
+ description: z35.string().min(1).max(280).optional(),
3647
+ platforms: z35.array(SocialPlatformSchema).optional(),
3648
+ /**
3649
+ * The company's mini apps (`canonical-spec §50`): each a name, an icon and pages of the platform's
3650
+ * blocks — data only, checked with the platform's catalog here and again when a page is read. The
3651
+ * studio draws every one with one general UI, under Apps.
3652
+ */
3653
+ mini_apps: MiniAppDeclsSchema.optional(),
2986
3654
  /**
2987
3655
  * What a person is asked BEFORE the crew is provisioned (`canonical-spec §31.2`).
2988
3656
  *
@@ -2994,21 +3662,21 @@ var ProjectSchema = z30.object({
2994
3662
  *
2995
3663
  * **Configuration only.** A secret is a vault credential or an app secret; neither is an answer.
2996
3664
  */
2997
- questions: z30.array(QuestionFieldSchema).default([]),
2998
- skills: z30.array(SkillDeclSchema).default([]),
2999
- identities: z30.array(IdentityDeclSchema).default([]),
3000
- vaults: z30.array(VaultDeclSchema).default([]),
3001
- apps: z30.array(AppDeclSchema).default([]),
3002
- agents: z30.array(AgentDeclSchema).default([]),
3665
+ questions: z35.array(QuestionFieldSchema).default([]),
3666
+ skills: z35.array(SkillDeclSchema).default([]),
3667
+ identities: z35.array(IdentityDeclSchema).default([]),
3668
+ vaults: z35.array(VaultDeclSchema).default([]),
3669
+ apps: z35.array(AppDeclSchema).default([]),
3670
+ agents: z35.array(AgentDeclSchema).default([]),
3003
3671
  /**
3004
3672
  * The agents this template creates PER CLIENT the operator signs (`canonical-spec §31.1`) —
3005
3673
  * printed on the artifact so a person sees the whole company, never provisioned by an apply,
3006
3674
  * because the apply does not know the clients yet. Names only: a model and a budget are the
3007
3675
  * crew's business at the moment a client is signed, not the declaration's.
3008
3676
  */
3009
- crew_per_client: z30.array(z30.object({ name: z30.string().min(1), role: z30.string().min(1).optional(), description: z30.string().optional() })).optional(),
3677
+ crew_per_client: z35.array(z35.object({ name: z35.string().min(1), role: z35.string().min(1).optional(), description: z35.string().optional() })).optional(),
3010
3678
  /** The crew's first work, as cards on the organization's board rather than N private intakes (§31.11). */
3011
- tasks: z30.array(TaskDeclSchema).default([]),
3679
+ tasks: z35.array(TaskDeclSchema).default([]),
3012
3680
  removed: RemovedSchema.default({ apps: [], agents: [], skills: [], identities: [], vaults: [] }),
3013
3681
  kept: KeptSchema.default({ agents: [] })
3014
3682
  });
@@ -3063,8 +3731,8 @@ function parseProject(input) {
3063
3731
  }
3064
3732
  const config = parsed.data;
3065
3733
  applyChoice(config);
3066
- if (config.template !== void 0 && config.questions.length > 4) {
3067
- refuse(`template "${config.template}" asks ${config.questions.length} questions, but a template asks at most 4 before anything is provisioned \u2014 a fifth belongs to the crew's first conversation`);
3734
+ if (config.template !== void 0 && config.questions.length > TEMPLATE_QUESTIONS_MAX) {
3735
+ refuse(`template "${config.template}" asks ${config.questions.length} questions, but a template asks at most ${TEMPLATE_QUESTIONS_MAX} before anything is provisioned \u2014 a fifth belongs to the crew's first conversation`);
3068
3736
  }
3069
3737
  assertUniqueNames("app", [...config.apps.map((a) => a.name), ...config.removed.apps]);
3070
3738
  assertUniqueNames("agent", [...config.agents.map((a) => a.name), ...config.removed.agents, ...config.kept.agents]);
@@ -3085,20 +3753,6 @@ function parseProject(input) {
3085
3753
  assertUniqueNames("bucket", (app.buckets ?? []).map((bucket) => bucket.name));
3086
3754
  }
3087
3755
  const identityNames = new Set(config.identities.map((i) => i.name));
3088
- const connectable = config.identities.filter((i) => i.connections !== void 0).map((i) => i.name);
3089
- if (connectable.length > 1) {
3090
- refuse(`identities ${connectable.map((n) => `"${n}"`).join(", ")} each declare connections, but the studio's Add connections step connects one persona \u2014 declare connections on the one the crew publishes through`);
3091
- }
3092
- for (const identity of config.identities) {
3093
- const social = identity.connections?.social;
3094
- if (social === void 0) continue;
3095
- const question = config.questions.find((q) => q.key === social.from);
3096
- if (question === void 0) refuse(`identity "${identity.name}": connections.social.from names "${social.from}", but no question with that key is declared in this project`);
3097
- if (question.type !== "choice") refuse(`identity "${identity.name}": connections.social.from names "${social.from}", which is a ${question.type} question \u2014 the map is keyed by a choice question's options`);
3098
- for (const label of Object.keys(social.map)) {
3099
- if (!question.options.includes(label)) refuse(`identity "${identity.name}": connections.social.map names "${label}", which is not one of question "${social.from}"'s options \u2014 a key no answer can equal is a row nobody can reach`);
3100
- }
3101
- }
3102
3756
  for (const vault of config.vaults) {
3103
3757
  if (vault.identity !== void 0 && !identityNames.has(vault.identity)) {
3104
3758
  refuse(`vault "${vault.name}": identity names "${vault.identity}", but no identity with that name is declared in this project`);
@@ -3309,167 +3963,6 @@ import { createHash as createHash3 } from "node:crypto";
3309
3963
  import { readFileSync as readFileSync4 } from "node:fs";
3310
3964
  import { resolve as resolve4 } from "node:path";
3311
3965
 
3312
- // src/agents.ts
3313
- var PROJECT_CONTEXT_PREAMBLE = "Before anything else, read the project context with the `project_context` tool. The answers in it are the client's own \u2014 never invent, assume or restate them from memory; what the context does not say, you ask. Use the context's own words for the company, its offer and its audience.";
3314
- function desiredMetadata(decl, of, current) {
3315
- if (of.template === void 0) return decl.metadata;
3316
- return {
3317
- ...current?.metadata,
3318
- ...decl.metadata,
3319
- project: of.project,
3320
- ...of.blueprint !== void 0 ? { blueprint: of.blueprint } : {},
3321
- template: of.template,
3322
- group: of.template
3323
- };
3324
- }
3325
- function desiredSystem(decl, of) {
3326
- if (of.template === void 0) return decl.system;
3327
- return decl.system === void 0 ? PROJECT_CONTEXT_PREAMBLE : `${PROJECT_CONTEXT_PREAMBLE}
3328
-
3329
- ${decl.system}`;
3330
- }
3331
- function desiredTools(decl, current, ids) {
3332
- const handoff = decl.handoffs !== void 0 && handoffsEnabled(decl.handoffs);
3333
- if (ids === void 0 && !handoff) return decl.tools;
3334
- const base = decl.tools ?? current?.tools ?? { default_config: { permission: "allow" }, configs: {} };
3335
- const appsTool = base.configs["apps"] ?? { enabled: true, permission: base.default_config.permission };
3336
- const allowed = { enabled: true, permission: "allow" };
3337
- return {
3338
- default_config: base.default_config,
3339
- configs: {
3340
- ...base.configs,
3341
- ...ids !== void 0 ? { apps: { ...appsTool, config: { ...appsTool.config, allowed_apps: ids } } } : {},
3342
- ...handoff ? { send_to_agent: allowed, list_agents: allowed } : {}
3343
- }
3344
- };
3345
- }
3346
- async function createAgent(client, decl, tools, team, identityId, system, metadata) {
3347
- const created = await client.agents.create({
3348
- name: decl.name,
3349
- model: decl.model,
3350
- budget: decl.budget,
3351
- ...decl.description !== void 0 ? { description: decl.description } : {},
3352
- ...system !== void 0 ? { system } : {},
3353
- ...decl.skills !== void 0 ? { skills: decl.skills } : {},
3354
- ...decl.mcp_servers !== void 0 ? { mcp_servers: decl.mcp_servers } : {},
3355
- ...tools !== void 0 ? { tools } : {},
3356
- ...decl.window !== void 0 ? { window: decl.window } : {},
3357
- ...team !== void 0 ? { multiagent: team } : {},
3358
- ...decl.handoffs !== void 0 ? { handoffs: decl.handoffs } : {},
3359
- ...decl.output_schema !== void 0 ? { output_schema: decl.output_schema } : {},
3360
- ...decl.structured_output_required !== void 0 ? { structured_output_required: decl.structured_output_required } : {},
3361
- ...metadata !== void 0 ? { metadata } : {}
3362
- });
3363
- if (identityId !== void 0) await client.identities.attach(created.id, identityId);
3364
- return { name: decl.name, action: "created", id: created.id };
3365
- }
3366
- async function upsertAgent(client, decl, existing, ids, dryRun, scoped, of) {
3367
- const unresolved = (decl.allowed_apps ?? []).filter((name) => !ids.apps.has(name));
3368
- const identityId = decl.identity === void 0 ? void 0 : ids.identities.get(decl.identity);
3369
- const missing = unresolved.length > 0 ? `allowed_apps needs app "${unresolved[0]}"` : decl.identity !== void 0 && identityId === void 0 ? `identity needs "${decl.identity}"` : null;
3370
- if (missing !== null && !dryRun) {
3371
- return { name: decl.name, action: "refused", reason: `${missing}, which was not provisioned in this run` };
3372
- }
3373
- const appIds = decl.allowed_apps !== void 0 ? decl.allowed_apps.flatMap((name) => ids.apps.get(name) ?? []) : scoped;
3374
- const current = existing.find((agent) => agent.name === decl.name) ?? null;
3375
- const tools = desiredTools(decl, current, appIds);
3376
- const team = teamWithoutRoster(decl.multiagent);
3377
- const system = desiredSystem(decl, of);
3378
- const metadata = desiredMetadata(decl, of, current);
3379
- if (!current) {
3380
- return dryRun ? { name: decl.name, action: "created" } : createAgent(client, decl, tools, team, identityId, system, metadata);
3381
- }
3382
- const patch = drift(decl, current, tools, team, system, metadata);
3383
- const held = identityId === void 0 ? [] : (await client.identities.held(current.id)).data;
3384
- const grant = identityId === void 0 || held.some((one) => one.id === identityId) ? null : identityId;
3385
- const drifted = Object.keys(patch).length > 0 || missing !== null || grant !== null;
3386
- if (!drifted) return { name: decl.name, action: "unchanged", id: current.id };
3387
- if (!dryRun) {
3388
- if (Object.keys(patch).length > 0) await client.agents.update(current.id, patch);
3389
- if (grant !== null) await client.identities.attach(current.id, grant);
3390
- }
3391
- return { name: decl.name, action: "updated", id: current.id };
3392
- }
3393
- function drift(decl, current, tools, team, system, metadata) {
3394
- const patch = {};
3395
- if (changed(decl.model, current.model)) patch.model = decl.model;
3396
- if (changed(decl.budget, current.budget)) patch.budget = decl.budget;
3397
- if (changed(decl.description, current.description)) patch.description = decl.description;
3398
- if (changed(system, current.system)) patch.system = system;
3399
- if (changed(decl.skills, current.skills)) patch.skills = decl.skills;
3400
- if (changed(decl.mcp_servers, current.mcp_servers)) patch.mcp_servers = decl.mcp_servers;
3401
- if (changed(tools, current.tools)) patch.tools = tools;
3402
- if (changed(decl.window, current.window)) patch.window = decl.window;
3403
- if (team !== void 0 && changed(normaliseMultiagent(team), normaliseMultiagent(current.multiagent))) patch.multiagent = team;
3404
- if (changed(decl.handoffs, handoffsOf(current))) patch.handoffs = decl.handoffs;
3405
- if (changed(decl.output_schema, current.output_schema)) patch.output_schema = decl.output_schema;
3406
- if (changed(decl.structured_output_required, current.structured_output_required)) patch.structured_output_required = decl.structured_output_required;
3407
- if (changed(metadata, current.metadata)) patch.metadata = metadata;
3408
- return patch;
3409
- }
3410
- async function openIntake(client, agent, decl, dryRun) {
3411
- if (dryRun || agent.id === void 0) return { name: agent.name, action: "created" };
3412
- const started = await client.sessions.create({
3413
- agent_id: agent.id,
3414
- message: decl.message,
3415
- ...decl.budget_micro_usd !== void 0 ? { budget_micro_usd: decl.budget_micro_usd } : {}
3416
- });
3417
- return { name: agent.name, action: "created", id: started.id };
3418
- }
3419
- function brief(input) {
3420
- const first = input.trim().split(/(?<=[.!?])\s|\n/)[0]?.trim() ?? "";
3421
- const text = first.replace(/[.\s]+$/, "");
3422
- return text.length > 72 ? `${text.slice(0, 71).trimEnd()}\u2026` : text;
3423
- }
3424
- async function upsertSchedule(client, agent, decl, current, identityIds, dryRun) {
3425
- const name = `${agent.name} @ ${decl.cron}`;
3426
- if (agent.action === "refused") throw new Error(`agent "${agent.name}" was not provisioned in this run`);
3427
- const identity = decl.identity === void 0 ? void 0 : identityIds.get(decl.identity);
3428
- const unresolved = decl.identity !== void 0 && identity === void 0;
3429
- if (unresolved && !dryRun) throw new Error(`identity needs "${decl.identity}", which was not provisioned in this run`);
3430
- if (!current) {
3431
- if (dryRun || agent.id === void 0) return { name, action: "created" };
3432
- const created = await client.deployments.create({
3433
- agent_id: agent.id,
3434
- cron: decl.cron,
3435
- input_template: decl.input,
3436
- budget_micro_usd: decl.budget_micro_usd,
3437
- ...decl.timezone !== void 0 ? { timezone: decl.timezone } : {},
3438
- ...identity !== void 0 ? { identity } : {},
3439
- ...decl.enabled !== void 0 ? { enabled: decl.enabled } : {}
3440
- });
3441
- return { name, action: "created", id: created.id };
3442
- }
3443
- const patch = {};
3444
- if (changed(decl.timezone, current.timezone)) patch.timezone = decl.timezone;
3445
- if (changed(decl.input, current.input_template)) patch.input_template = decl.input;
3446
- if (changed(decl.budget_micro_usd, current.budget_micro_usd)) patch.budget_micro_usd = decl.budget_micro_usd;
3447
- if (changed(identity, current.identity)) patch.identity = identity;
3448
- if (changed(decl.enabled, current.enabled)) patch.enabled = decl.enabled;
3449
- if (Object.keys(patch).length === 0 && !unresolved) return { name, action: "unchanged", id: current.id };
3450
- if (!dryRun) await client.deployments.update(current.id, patch);
3451
- return { name, action: "updated", id: current.id };
3452
- }
3453
- async function reconcileSchedules(client, agent, declared, live, identityIds, dryRun, into) {
3454
- const rows = live.filter((row) => row.agent_id === agent.id);
3455
- into.push(
3456
- ...await eachInFlight(declared, async (decl) => ({
3457
- ...await line(
3458
- `${agent.name} @ ${decl.cron}`,
3459
- () => upsertSchedule(client, agent, decl, rows.find((row) => row.cron === decl.cron), identityIds, dryRun)
3460
- ),
3461
- // `<agent> @ <cron>` says WHEN a timer runs and nothing about what it does, so the dashboard's
3462
- // opening message could only ever draw a timetable from these lines. The brief's first
3463
- // sentence is what turns that timetable into a roadmap (§29.6).
3464
- summary: brief(decl.input)
3465
- }))
3466
- );
3467
- for (const row of rows.filter((row2) => !declared.some((decl) => decl.cron === row2.cron))) {
3468
- const name = `${agent.name} @ ${row.cron}`;
3469
- await attempt(into, name, () => tombstone(name, row, (id) => client.deployments.delete(id), dryRun));
3470
- }
3471
- }
3472
-
3473
3966
  // src/apps.ts
3474
3967
  import { createHash as createHash2, randomBytes } from "node:crypto";
3475
3968
  import { resolve as resolve3 } from "node:path";
@@ -3529,10 +4022,10 @@ async function findApp(client, name, skipped) {
3529
4022
  const rows = await listAll(client.config, "/v1/apps", AppSchema, skipped, { name });
3530
4023
  return rows.find((app) => app.name === name) ?? null;
3531
4024
  }
3532
- function ownershipRefusal(name, project, owner) {
4025
+ function ownershipRefusal(name, project, owner, kind = "app") {
3533
4026
  const held = owner === null ? "no project (it was created outside a blueprint)" : `project "${owner}"`;
3534
4027
  const verb = owner === null ? "take" : "transfer";
3535
- return `app "${name}" is owned by ${held}; this project is "${project}". Rename the app in your config, or re-run \`naive up --adopt\` to ${verb} it.`;
4028
+ return `${kind} "${name}" is owned by ${held}; this project is "${project}". Rename the ${kind} in your config, or re-run \`naive up --adopt\` to ${verb} it.`;
3536
4029
  }
3537
4030
  var ensureApp = (client, body) => client.apps.create(body);
3538
4031
  var PLATFORM_ENV = {
@@ -3636,13 +4129,13 @@ function builtTree(decl, opts) {
3636
4129
  const files = collectFiles(hosted?.[decl.name] ?? resolve3(opts.dir, decl.deploy_dir));
3637
4130
  return { files, hash: contentHash(files) };
3638
4131
  }
3639
- async function writeApp(client, id, env, tree) {
4132
+ async function writeApp(client, id, env, tree2) {
3640
4133
  await eachInFlight(
3641
4134
  Object.entries(env),
3642
4135
  ([name, value]) => client.apps.setSecret(id, { name, value, value_hash: secretHash(name, value) })
3643
4136
  );
3644
- if (!tree) return;
3645
- await client.apps.deploy(id, tree.files, tree.hash);
4137
+ if (!tree2) return;
4138
+ await client.apps.deploy(id, tree2.files, tree2.hash);
3646
4139
  await settleDeploy(client, id);
3647
4140
  }
3648
4141
  var SETTLE_TRIES = 30;
@@ -3654,7 +4147,7 @@ async function settleDeploy(client, id) {
3654
4147
  await new Promise((resolve5) => setTimeout(resolve5, SETTLE_MS));
3655
4148
  }
3656
4149
  }
3657
- async function createApp(client, decl, env, tree, migrations, opts, appIds) {
4150
+ async function createApp(client, decl, env, tree2, migrations, opts, appIds) {
3658
4151
  const created = await ensureApp(client, {
3659
4152
  name: decl.name,
3660
4153
  type: decl.type,
@@ -3663,7 +4156,7 @@ async function createApp(client, decl, env, tree, migrations, opts, appIds) {
3663
4156
  ...decl.mcp !== void 0 ? { mcp: decl.mcp } : {}
3664
4157
  });
3665
4158
  appIds.set(decl.name, created.id);
3666
- await writeApp(client, created.id, withAppId(env, decl, opts, created.id), tree);
4159
+ await writeApp(client, created.id, withAppId(env, decl, opts, created.id), tree2);
3667
4160
  const notes = [];
3668
4161
  if (migrations.length > 0) notes.push((await applyMigrations(client, created.id, migrations)).note);
3669
4162
  if (decl.buckets !== void 0) notes.push((await applyBuckets(client, created.id, decl.buckets)).note);
@@ -3734,9 +4227,9 @@ async function upsertApp(client, decl, opts, appIds) {
3734
4227
  ...(decl.mcp ?? null) !== current.mcp ? { mcp: decl.mcp ?? null } : {}
3735
4228
  };
3736
4229
  const drifted = Object.keys(patch).length > 0;
3737
- const tree = builtTree(decl, opts);
3738
- const newest = tree ? (await client.apps.deployments(current.id, { limit: 1 })).data[0] : void 0;
3739
- const stale = tree !== null && newest?.content_hash !== tree.hash;
4230
+ const tree2 = builtTree(decl, opts);
4231
+ const newest = tree2 ? (await client.apps.deployments(current.id, { limit: 1 })).data[0] : void 0;
4232
+ const stale = tree2 !== null && newest?.content_hash !== tree2.hash;
3740
4233
  let action = !owned || drifted || stale || staleNames.length > 0 ? "updated" : "unchanged";
3741
4234
  const plan = opts.dryRun ? [
3742
4235
  ...staleNames.length > 0 ? [`will set ${staleNames.join(", ")}`] : [],
@@ -3747,7 +4240,7 @@ async function upsertApp(client, decl, opts, appIds) {
3747
4240
  ] : [];
3748
4241
  if (!opts.dryRun) {
3749
4242
  if (drifted) await client.apps.update(current.id, { ...patch, project: opts.project });
3750
- await writeApp(client, current.id, staleEnv, stale ? tree : null);
4243
+ await writeApp(client, current.id, staleEnv, stale ? tree2 : null);
3751
4244
  const migrations = declaredMigrations(decl, opts);
3752
4245
  if (migrations.length > 0) {
3753
4246
  const { fresh, note: note2 } = await applyMigrations(client, current.id, migrations);
@@ -3770,6 +4263,172 @@ async function upsertApp(client, decl, opts, appIds) {
3770
4263
  };
3771
4264
  }
3772
4265
 
4266
+ // src/agents.ts
4267
+ var PROJECT_CONTEXT_PREAMBLE = "Before anything else, read the project context with the `project_context` tool. The answers in it are the client's own \u2014 never invent, assume or restate them from memory; what the context does not say, you ask. Use the context's own words for the company, its offer and its audience.";
4268
+ function desiredMetadata(decl, of, current) {
4269
+ if (of.template === void 0) return decl.metadata;
4270
+ return {
4271
+ ...current?.metadata,
4272
+ ...decl.metadata,
4273
+ project: of.project,
4274
+ ...of.blueprint !== void 0 ? { blueprint: of.blueprint } : {},
4275
+ template: of.template,
4276
+ group: of.group ?? of.template
4277
+ };
4278
+ }
4279
+ function desiredSystem(decl, of) {
4280
+ if (of.template === void 0) return decl.system;
4281
+ return decl.system === void 0 ? PROJECT_CONTEXT_PREAMBLE : `${PROJECT_CONTEXT_PREAMBLE}
4282
+
4283
+ ${decl.system}`;
4284
+ }
4285
+ function desiredTools(decl, current, ids) {
4286
+ const handoff = decl.handoffs !== void 0 && handoffsEnabled(decl.handoffs);
4287
+ if (ids === void 0 && !handoff) return decl.tools;
4288
+ const base = decl.tools ?? current?.tools ?? { default_config: { permission: "allow" }, configs: {} };
4289
+ const appsTool = base.configs["apps"] ?? { enabled: true, permission: base.default_config.permission };
4290
+ const allowed = { enabled: true, permission: "allow" };
4291
+ return {
4292
+ default_config: base.default_config,
4293
+ configs: {
4294
+ ...base.configs,
4295
+ ...ids !== void 0 ? { apps: { ...appsTool, config: { ...appsTool.config, allowed_apps: ids } } } : {},
4296
+ ...handoff ? { send_to_agent: allowed, list_agents: allowed } : {}
4297
+ }
4298
+ };
4299
+ }
4300
+ async function createAgent(client, decl, tools, team, identityId, system, metadata) {
4301
+ const created = await client.agents.create({
4302
+ name: decl.name,
4303
+ model: decl.model,
4304
+ budget: decl.budget,
4305
+ ...decl.description !== void 0 ? { description: decl.description } : {},
4306
+ ...system !== void 0 ? { system } : {},
4307
+ ...decl.skills !== void 0 ? { skills: decl.skills } : {},
4308
+ ...decl.mcp_servers !== void 0 ? { mcp_servers: decl.mcp_servers } : {},
4309
+ ...tools !== void 0 ? { tools } : {},
4310
+ ...decl.window !== void 0 ? { window: decl.window } : {},
4311
+ ...team !== void 0 ? { multiagent: team } : {},
4312
+ ...decl.handoffs !== void 0 ? { handoffs: decl.handoffs } : {},
4313
+ ...decl.output_schema !== void 0 ? { output_schema: decl.output_schema } : {},
4314
+ ...decl.structured_output_required !== void 0 ? { structured_output_required: decl.structured_output_required } : {},
4315
+ ...metadata !== void 0 ? { metadata } : {}
4316
+ });
4317
+ if (identityId !== void 0) await client.identities.attach(created.id, identityId);
4318
+ return { name: decl.name, action: "created", id: created.id };
4319
+ }
4320
+ async function upsertAgent(client, decl, existing, ids, dryRun, scoped2, of) {
4321
+ const unresolved = (decl.allowed_apps ?? []).filter((name) => !ids.apps.has(name));
4322
+ const identityId = decl.identity === void 0 ? void 0 : ids.identities.get(decl.identity);
4323
+ const missing = unresolved.length > 0 ? `allowed_apps needs app "${unresolved[0]}"` : decl.identity !== void 0 && identityId === void 0 ? `identity needs "${decl.identity}"` : null;
4324
+ if (missing !== null && !dryRun) {
4325
+ return { name: decl.name, action: "refused", reason: `${missing}, which was not provisioned in this run` };
4326
+ }
4327
+ const appIds = decl.allowed_apps !== void 0 ? decl.allowed_apps.flatMap((name) => ids.apps.get(name) ?? []) : scoped2;
4328
+ const current = existing.find((agent) => agent.name === decl.name) ?? null;
4329
+ const owner = typeof current?.metadata?.["project"] === "string" ? current.metadata["project"] : null;
4330
+ if (current && of.template !== void 0 && owner !== null && owner !== of.project && !of.adopt) {
4331
+ return { name: decl.name, action: "refused", id: current.id, reason: ownershipRefusal(decl.name, of.project, owner, "agent") };
4332
+ }
4333
+ const tools = desiredTools(decl, current, appIds);
4334
+ const team = teamWithoutRoster(decl.multiagent);
4335
+ const system = desiredSystem(decl, of);
4336
+ const metadata = desiredMetadata(decl, of, current);
4337
+ if (!current) {
4338
+ return dryRun ? { name: decl.name, action: "created" } : createAgent(client, decl, tools, team, identityId, system, metadata);
4339
+ }
4340
+ const patch = drift(decl, current, tools, team, system, metadata);
4341
+ const held = identityId === void 0 ? [] : (await client.identities.held(current.id)).data;
4342
+ const grant = identityId === void 0 || held.some((one) => one.id === identityId) ? null : identityId;
4343
+ const drifted = Object.keys(patch).length > 0 || missing !== null || grant !== null;
4344
+ if (!drifted) return { name: decl.name, action: "unchanged", id: current.id };
4345
+ if (!dryRun) {
4346
+ if (Object.keys(patch).length > 0) await client.agents.update(current.id, patch);
4347
+ if (grant !== null) await client.identities.attach(current.id, grant);
4348
+ }
4349
+ return { name: decl.name, action: "updated", id: current.id };
4350
+ }
4351
+ function drift(decl, current, tools, team, system, metadata) {
4352
+ const patch = {};
4353
+ if (changed(decl.model, current.model)) patch.model = decl.model;
4354
+ if (changed(decl.budget, current.budget)) patch.budget = decl.budget;
4355
+ if (changed(decl.description, current.description)) patch.description = decl.description;
4356
+ if (changed(system, current.system)) patch.system = system;
4357
+ if (changed(decl.skills, current.skills)) patch.skills = decl.skills;
4358
+ if (changed(decl.mcp_servers, current.mcp_servers)) patch.mcp_servers = decl.mcp_servers;
4359
+ if (changed(tools, current.tools)) patch.tools = tools;
4360
+ if (changed(decl.window, current.window)) patch.window = decl.window;
4361
+ if (team !== void 0 && changed(normaliseMultiagent(team), normaliseMultiagent(current.multiagent))) patch.multiagent = team;
4362
+ if (changed(decl.handoffs, handoffsOf(current))) patch.handoffs = decl.handoffs;
4363
+ if (changed(decl.output_schema, current.output_schema)) patch.output_schema = decl.output_schema;
4364
+ if (changed(decl.structured_output_required, current.structured_output_required)) patch.structured_output_required = decl.structured_output_required;
4365
+ if (changed(metadata, current.metadata)) patch.metadata = metadata;
4366
+ return patch;
4367
+ }
4368
+ async function openIntake(client, agent, decl, dryRun) {
4369
+ if (dryRun || agent.id === void 0) return { name: agent.name, action: "created" };
4370
+ const started = await client.sessions.create({
4371
+ agent_id: agent.id,
4372
+ message: decl.message,
4373
+ ...decl.budget_micro_usd !== void 0 ? { budget_micro_usd: decl.budget_micro_usd } : {}
4374
+ });
4375
+ return { name: agent.name, action: "created", id: started.id };
4376
+ }
4377
+ function brief(input) {
4378
+ const first = input.trim().split(/(?<=[.!?])\s|\n/)[0]?.trim() ?? "";
4379
+ const text = first.replace(/[.\s]+$/, "");
4380
+ return text.length > 72 ? `${text.slice(0, 71).trimEnd()}\u2026` : text;
4381
+ }
4382
+ async function upsertSchedule(client, agent, decl, current, identityIds, dryRun) {
4383
+ const name = `${agent.name} @ ${decl.cron}`;
4384
+ if (agent.action === "refused") throw new Error(`agent "${agent.name}" was not provisioned in this run`);
4385
+ const identity = decl.identity === void 0 ? void 0 : identityIds.get(decl.identity);
4386
+ const unresolved = decl.identity !== void 0 && identity === void 0;
4387
+ if (unresolved && !dryRun) throw new Error(`identity needs "${decl.identity}", which was not provisioned in this run`);
4388
+ if (!current) {
4389
+ if (dryRun || agent.id === void 0) return { name, action: "created" };
4390
+ const created = await client.deployments.create({
4391
+ agent_id: agent.id,
4392
+ cron: decl.cron,
4393
+ input_template: decl.input,
4394
+ budget_micro_usd: decl.budget_micro_usd,
4395
+ ...decl.timezone !== void 0 ? { timezone: decl.timezone } : {},
4396
+ ...identity !== void 0 ? { identity } : {},
4397
+ ...decl.enabled !== void 0 ? { enabled: decl.enabled } : {}
4398
+ });
4399
+ return { name, action: "created", id: created.id };
4400
+ }
4401
+ const patch = {};
4402
+ if (changed(decl.timezone, current.timezone)) patch.timezone = decl.timezone;
4403
+ if (changed(decl.input, current.input_template)) patch.input_template = decl.input;
4404
+ if (changed(decl.budget_micro_usd, current.budget_micro_usd)) patch.budget_micro_usd = decl.budget_micro_usd;
4405
+ if (changed(identity, current.identity)) patch.identity = identity;
4406
+ if (changed(decl.enabled, current.enabled)) patch.enabled = decl.enabled;
4407
+ if (Object.keys(patch).length === 0 && !unresolved) return { name, action: "unchanged", id: current.id };
4408
+ if (!dryRun) await client.deployments.update(current.id, patch);
4409
+ return { name, action: "updated", id: current.id };
4410
+ }
4411
+ async function reconcileSchedules(client, agent, declared, live, identityIds, dryRun, into) {
4412
+ const rows = live.filter((row) => row.agent_id === agent.id);
4413
+ into.push(
4414
+ ...await eachInFlight(declared, async (decl) => ({
4415
+ ...await line(
4416
+ `${agent.name} @ ${decl.cron}`,
4417
+ () => upsertSchedule(client, agent, decl, rows.find((row) => row.cron === decl.cron), identityIds, dryRun)
4418
+ ),
4419
+ // `<agent> @ <cron>` says WHEN a timer runs and nothing about what it does, so the dashboard's
4420
+ // opening message could only ever draw a timetable from these lines. The brief's first
4421
+ // sentence is what turns that timetable into a roadmap (§29.6).
4422
+ summary: brief(decl.input)
4423
+ }))
4424
+ );
4425
+ if (agent.action === "refused") return;
4426
+ for (const row of rows.filter((row2) => !declared.some((decl) => decl.cron === row2.cron))) {
4427
+ const name = `${agent.name} @ ${row.cron}`;
4428
+ await attempt(into, name, () => tombstone(name, row, (id) => client.deployments.delete(id), dryRun));
4429
+ }
4430
+ }
4431
+
3773
4432
  // src/reconcile-cards.ts
3774
4433
  var LIVE = /* @__PURE__ */ new Set(["pending_payment", "issuing", "active"]);
3775
4434
  var nameOf = (identity, decl) => `${identity} / card ${decl.label}`;
@@ -4084,17 +4743,22 @@ async function upsertSkill(client, decl, opts) {
4084
4743
  const pushed = await client.skills.push({ slug: decl.slug, content, sha256 });
4085
4744
  return { name: decl.slug, action, id: pushed.id };
4086
4745
  }
4087
- async function upsertIdentity(client, decl, dryRun, identityIds) {
4746
+ async function upsertIdentity(client, decl, dryRun, identityIds, owner) {
4088
4747
  const current = await absent(client.identities.get(decl.name));
4089
4748
  if (!current) {
4090
4749
  if (dryRun) return { name: decl.name, action: "created" };
4091
4750
  const created = await client.identities.create({
4092
4751
  name: decl.name,
4093
- ...decl.description !== void 0 ? { description: decl.description } : {}
4752
+ ...decl.description !== void 0 ? { description: decl.description } : {},
4753
+ ...owner !== void 0 ? { metadata: { project: owner } } : {}
4094
4754
  });
4095
4755
  identityIds.set(decl.name, created.id);
4096
4756
  return { name: decl.name, action: "created", id: created.id };
4097
4757
  }
4758
+ const held = typeof current.metadata["project"] === "string" ? current.metadata["project"] : null;
4759
+ if (owner !== void 0 && held !== owner) {
4760
+ return { name: decl.name, action: "refused", id: current.id, reason: ownershipRefusal(decl.name, owner, held, "identity") };
4761
+ }
4098
4762
  identityIds.set(decl.name, current.id);
4099
4763
  const drifted = decl.description !== void 0 && decl.description !== current.description;
4100
4764
  if (drifted && !dryRun) await client.identities.update(current.id, { description: decl.description ?? null });
@@ -4157,12 +4821,14 @@ async function up(config, client, opts = {}) {
4157
4821
  const taken = selectCrew(config, opts.select);
4158
4822
  const report2 = { dry_run: dryRun, ...applied(config), skills: [], identities: [], vaults: [], apps: [], agents: [], schedules: [], intake: [], tasks: [], skipped: [], deselected: taken.deselected };
4159
4823
  const owner = { project: config.name, adopt: opts.adopt ?? false, skipped: report2.skipped };
4824
+ const project = opts.project ?? config.name;
4825
+ const isolated = opts.isolated === true ? project : void 0;
4160
4826
  const hosted = opts.trees !== void 0;
4161
4827
  for (const decl of config.skills) {
4162
4828
  await attempt(report2.skills, decl.slug, () => upsertSkill(client, decl, { dryRun, dir, hosted, skills: opts.skills ?? {} }));
4163
4829
  }
4164
4830
  for (const decl of config.identities) {
4165
- await attempt(report2.identities, decl.name, () => upsertIdentity(client, decl, dryRun, ids.identities));
4831
+ await attempt(report2.identities, decl.name, () => upsertIdentity(client, decl, dryRun, ids.identities, isolated));
4166
4832
  const identityId = ids.identities.get(decl.name);
4167
4833
  report2.identities.push(...await reportLegal(client, decl.legal ?? [], identityId, report2.skipped));
4168
4834
  for (const wallet of decl.wallet === void 0 ? [] : Array.isArray(decl.wallet) ? decl.wallet : [decl.wallet]) {
@@ -4191,7 +4857,7 @@ async function up(config, client, opts = {}) {
4191
4857
  ...opts.platform,
4192
4858
  known: {
4193
4859
  ...opts.platform.known,
4194
- [PLATFORM_ENV.project]: opts.project ?? config.name,
4860
+ [PLATFORM_ENV.project]: project,
4195
4861
  ...identityEnv(config, ids.identities)
4196
4862
  }
4197
4863
  };
@@ -4224,9 +4890,10 @@ async function up(config, client, opts = {}) {
4224
4890
  );
4225
4891
  const existing = taken.agents.length > 0 || config.removed.agents.length > 0 || config.kept.agents.length > 0 || config.tasks.length > 0 ? await listAll(client.config, "/v1/agents", AgentSchema, report2.skipped) : [];
4226
4892
  const deployments = taken.agents.some((decl) => decl.schedules !== void 0) ? await listAll(client.config, "/v1/deployments", DeploymentSchema, report2.skipped) : [];
4227
- const scoped = config.apps.length > 0 ? [...ids.apps.values()] : void 0;
4893
+ const scoped2 = config.apps.length > 0 ? [...ids.apps.values()] : void 0;
4228
4894
  const crew = await eachInFlight(taken.agents, async (decl) => {
4229
- const agent = await line(decl.name, () => upsertAgent(client, decl, existing, ids, dryRun, scoped, { project: opts.project ?? config.name, ...applied(config) }));
4895
+ const of = { project, ...applied(config), adopt: opts.adopt ?? false, ...isolated === void 0 ? {} : { group: project } };
4896
+ const agent = await line(decl.name, () => upsertAgent(client, decl, existing, ids, dryRun, scoped2, of));
4230
4897
  const schedules = [];
4231
4898
  if (decl.schedules !== void 0) {
4232
4899
  await reconcileSchedules(client, agent, decl.schedules, deployments, ids.identities, dryRun, schedules);
@@ -4263,6 +4930,56 @@ async function up(config, client, opts = {}) {
4263
4930
  );
4264
4931
  return report2;
4265
4932
  }
4933
+
4934
+ // src/scoped.ts
4935
+ function scoped(config, prefix, project) {
4936
+ const removed = { ...config.removed, skills: [] };
4937
+ if (prefix === "") return { ...config, name: project, removed };
4938
+ const as = (name) => prefix + name;
4939
+ const apps = new Set(config.apps.map((app) => app.name));
4940
+ const tool = (key) => {
4941
+ const app = key.split(".")[0] ?? "";
4942
+ return key.includes(".") && apps.has(app) ? as(key) : key;
4943
+ };
4944
+ const team = teamLine(config, as);
4945
+ const agent = (decl) => ({
4946
+ ...decl,
4947
+ name: as(decl.name),
4948
+ system: decl.system === void 0 ? team : `${decl.system}
4949
+
4950
+ ${team}`,
4951
+ ...decl.tools === void 0 ? {} : { tools: { ...decl.tools, configs: Object.fromEntries(Object.entries(decl.tools.configs).map(([key, one]) => [tool(key), one])) } },
4952
+ ...decl.allowed_apps === void 0 ? {} : { allowed_apps: decl.allowed_apps.map(as) },
4953
+ ...decl.identity === void 0 ? {} : { identity: as(decl.identity) },
4954
+ ...Array.isArray(decl.handoffs) ? { handoffs: decl.handoffs.map(as) } : {},
4955
+ ...hasRoster(decl.multiagent) ? { multiagent: { ...decl.multiagent, agents: decl.multiagent.agents.map((one) => one.type === "agent" ? { ...one, name: as(one.name) } : one) } } : {},
4956
+ ...decl.schedules === void 0 ? {} : { schedules: decl.schedules.map((one) => one.identity === void 0 ? one : { ...one, identity: as(one.identity) }) }
4957
+ });
4958
+ return {
4959
+ ...config,
4960
+ name: project,
4961
+ identities: config.identities.map((one) => ({ ...one, name: as(one.name) })),
4962
+ vaults: config.vaults.map((one) => ({ ...one, name: as(one.name), ...one.identity === void 0 ? {} : { identity: as(one.identity) } })),
4963
+ apps: config.apps.map((one) => ({ ...one, name: as(one.name) })),
4964
+ agents: config.agents.map(agent),
4965
+ tasks: config.tasks.map((one) => one.assignee === void 0 ? one : { ...one, assignee: as(one.assignee) }),
4966
+ removed: {
4967
+ ...removed,
4968
+ apps: config.removed.apps.map(as),
4969
+ agents: config.removed.agents.map(as),
4970
+ identities: config.removed.identities.map(as),
4971
+ vaults: config.removed.vaults.map(as)
4972
+ },
4973
+ kept: { agents: config.kept.agents.map(as) }
4974
+ };
4975
+ }
4976
+ function teamLine(config, as) {
4977
+ const names = [
4978
+ ...config.agents.map((one) => `${one.name} is ${as(one.name)}`),
4979
+ ...config.apps.map((one) => `the app ${one.name} is ${as(one.name)} (its tools are ${as(one.name)}.*)`)
4980
+ ];
4981
+ return `Your team's names here: ${names.join("; ")}.`;
4982
+ }
4266
4983
  export {
4267
4984
  BLUEPRINTS,
4268
4985
  BlueprintRefusal,
@@ -4279,6 +4996,7 @@ export {
4279
4996
  loadConfig,
4280
4997
  migrationFiles,
4281
4998
  parseProject,
4999
+ scoped,
4282
5000
  selectCrew,
4283
5001
  up
4284
5002
  };