@skillcdn/console 0.1.24 → 0.3.1

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.
Files changed (156) hide show
  1. package/README.md +8 -7
  2. package/dist/api.d.ts +2 -2
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +2 -2
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli/cli.d.ts +1 -1
  7. package/dist/cli/cli.d.ts.map +1 -1
  8. package/dist/cli/cli.js +248 -92
  9. package/dist/cli/cli.js.map +1 -1
  10. package/dist/cli/credentials.d.ts +5 -0
  11. package/dist/cli/credentials.d.ts.map +1 -1
  12. package/dist/cli/credentials.js +2 -0
  13. package/dist/cli/credentials.js.map +1 -1
  14. package/dist/cli/directory.d.ts +7 -0
  15. package/dist/cli/directory.d.ts.map +1 -1
  16. package/dist/cli/directory.js +7 -0
  17. package/dist/cli/directory.js.map +1 -1
  18. package/dist/cli/format.d.ts +13 -28
  19. package/dist/cli/format.d.ts.map +1 -1
  20. package/dist/cli/format.js +74 -274
  21. package/dist/cli/format.js.map +1 -1
  22. package/dist/cli/help.d.ts.map +1 -1
  23. package/dist/cli/help.js +36 -19
  24. package/dist/cli/help.js.map +1 -1
  25. package/dist/cli/pack.d.ts +46 -0
  26. package/dist/cli/pack.d.ts.map +1 -0
  27. package/dist/cli/pack.js +250 -0
  28. package/dist/cli/pack.js.map +1 -0
  29. package/dist/client.d.ts +26 -1
  30. package/dist/client.d.ts.map +1 -1
  31. package/dist/client.js +14 -1
  32. package/dist/client.js.map +1 -1
  33. package/dist/compat.d.ts +1 -1
  34. package/dist/compat.js +1 -1
  35. package/dist/components/calendar.d.ts +5 -1
  36. package/dist/components/calendar.d.ts.map +1 -1
  37. package/dist/components/calendar.js +3 -3
  38. package/dist/components/calendar.js.map +1 -1
  39. package/dist/components/decision-list.d.ts +13 -1
  40. package/dist/components/decision-list.d.ts.map +1 -1
  41. package/dist/components/decision-list.js +74 -29
  42. package/dist/components/decision-list.js.map +1 -1
  43. package/dist/components/event-feed.d.ts.map +1 -1
  44. package/dist/components/event-feed.js +2 -0
  45. package/dist/components/event-feed.js.map +1 -1
  46. package/dist/components/pack-connect.d.ts +23 -0
  47. package/dist/components/pack-connect.d.ts.map +1 -0
  48. package/dist/components/pack-connect.js +86 -0
  49. package/dist/components/pack-connect.js.map +1 -0
  50. package/dist/components/pack-token.d.ts +27 -0
  51. package/dist/components/pack-token.d.ts.map +1 -0
  52. package/dist/components/pack-token.js +11 -0
  53. package/dist/components/pack-token.js.map +1 -0
  54. package/dist/components/paged.d.ts +24 -0
  55. package/dist/components/paged.d.ts.map +1 -1
  56. package/dist/components/paged.js +40 -4
  57. package/dist/components/paged.js.map +1 -1
  58. package/dist/components/projects.d.ts +13 -0
  59. package/dist/components/projects.d.ts.map +1 -1
  60. package/dist/components/projects.js +37 -5
  61. package/dist/components/projects.js.map +1 -1
  62. package/dist/components/skills.d.ts.map +1 -1
  63. package/dist/components/skills.js +8 -4
  64. package/dist/components/skills.js.map +1 -1
  65. package/dist/components/ui.d.ts +2 -0
  66. package/dist/components/ui.d.ts.map +1 -1
  67. package/dist/components/ui.js +7 -2
  68. package/dist/components/ui.js.map +1 -1
  69. package/dist/components/work.d.ts +3 -1
  70. package/dist/components/work.d.ts.map +1 -1
  71. package/dist/components/work.js +1 -1
  72. package/dist/components/work.js.map +1 -1
  73. package/dist/components/workspace.d.ts +46 -0
  74. package/dist/components/workspace.d.ts.map +1 -0
  75. package/dist/components/workspace.js +124 -0
  76. package/dist/components/workspace.js.map +1 -0
  77. package/dist/console.css +268 -5
  78. package/dist/console.d.ts.map +1 -1
  79. package/dist/console.js +62 -23
  80. package/dist/console.js.map +1 -1
  81. package/dist/data.d.ts +16 -1
  82. package/dist/data.d.ts.map +1 -1
  83. package/dist/data.js +64 -2
  84. package/dist/data.js.map +1 -1
  85. package/dist/dates.d.ts +12 -2
  86. package/dist/dates.d.ts.map +1 -1
  87. package/dist/dates.js +20 -2
  88. package/dist/dates.js.map +1 -1
  89. package/dist/i18n/en.d.ts +66 -0
  90. package/dist/i18n/en.d.ts.map +1 -1
  91. package/dist/i18n/en.js +80 -8
  92. package/dist/i18n/en.js.map +1 -1
  93. package/dist/i18n/ko.d.ts.map +1 -1
  94. package/dist/i18n/ko.js +75 -7
  95. package/dist/i18n/ko.js.map +1 -1
  96. package/dist/index.d.ts +5 -2
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +5 -2
  99. package/dist/index.js.map +1 -1
  100. package/dist/router.d.ts +10 -5
  101. package/dist/router.d.ts.map +1 -1
  102. package/dist/router.js +24 -9
  103. package/dist/router.js.map +1 -1
  104. package/dist/routes.d.ts +4 -0
  105. package/dist/routes.d.ts.map +1 -1
  106. package/dist/routes.js +4 -0
  107. package/dist/routes.js.map +1 -1
  108. package/dist/schemas.d.ts +500 -158
  109. package/dist/schemas.d.ts.map +1 -1
  110. package/dist/schemas.js +169 -165
  111. package/dist/schemas.js.map +1 -1
  112. package/dist/vocabulary.d.ts +19 -1
  113. package/dist/vocabulary.d.ts.map +1 -1
  114. package/dist/vocabulary.js +16 -0
  115. package/dist/vocabulary.js.map +1 -1
  116. package/docs/specs/cli.md +19 -14
  117. package/docs/specs/rest.md +34 -19
  118. package/package.json +2 -1
  119. package/skills/building-a-console/SKILL.md +5 -5
  120. package/skills/building-a-console/references/the-look-from-a-website.md +39 -0
  121. package/skills/deploying-a-console/SKILL.md +9 -8
  122. package/skills/working-the-board/SKILL.md +5 -5
  123. package/skills/working-the-board/references/setting-up.md +1 -1
  124. package/skills/working-the-board/references/terms.md +2 -0
  125. package/skills/working-the-board/references/the-sentence.md +1 -1
  126. package/src/api.ts +18 -7
  127. package/src/cli/cli.ts +345 -109
  128. package/src/cli/credentials.ts +7 -0
  129. package/src/cli/directory.ts +9 -0
  130. package/src/cli/format.ts +82 -341
  131. package/src/cli/help.ts +43 -19
  132. package/src/cli/pack.ts +356 -0
  133. package/src/client.ts +84 -0
  134. package/src/compat.ts +1 -1
  135. package/src/components/calendar.tsx +8 -2
  136. package/src/components/decision-list.tsx +227 -94
  137. package/src/components/event-feed.tsx +2 -0
  138. package/src/components/pack-connect.tsx +179 -0
  139. package/src/components/pack-token.tsx +74 -0
  140. package/src/components/paged.tsx +72 -3
  141. package/src/components/projects.tsx +108 -9
  142. package/src/components/skills.tsx +51 -33
  143. package/src/components/ui.tsx +16 -3
  144. package/src/components/work.tsx +4 -1
  145. package/src/components/workspace.tsx +298 -0
  146. package/src/console.tsx +176 -29
  147. package/src/data.ts +89 -2
  148. package/src/dates.ts +23 -2
  149. package/src/i18n/en.ts +94 -8
  150. package/src/i18n/ko.ts +84 -7
  151. package/src/index.ts +25 -1
  152. package/src/router.ts +37 -14
  153. package/src/routes.ts +4 -0
  154. package/src/schemas.ts +202 -189
  155. package/src/styles/console.css +268 -5
  156. package/src/vocabulary.ts +25 -0
package/src/schemas.ts CHANGED
@@ -2,6 +2,13 @@
2
2
  // most of what a page downloads. The server validates what it is sent with the input schemas
3
3
  // and builds the output shapes; the pages and a custom console parse answers with the rest.
4
4
  // Absent values are `null` on the wire, never missing keys. Changes within a version are additive.
5
+ import {
6
+ restBrowseSchema as packBrowseSchema,
7
+ restFileSchema as packFileSchema,
8
+ restFindSchema as packFindSchema,
9
+ restMountSchema as packMountSchema,
10
+ restSkillSchema as packSkillSchema,
11
+ } from "@skillcdn/core";
5
12
  import * as z from "zod/mini";
6
13
  import { isDocumentPath } from "./documents.js";
7
14
  import {
@@ -43,6 +50,8 @@ import {
43
50
  GOAL_STATES,
44
51
  LINK_SOURCES,
45
52
  MEMBERSHIP_SOURCES,
53
+ PACK_CONNECT_ENDINGS,
54
+ PEOPLE_VISIBILITIES,
46
55
  PERSON_ROLES,
47
56
  PERSON_STATUSES,
48
57
  PROJECT_ICON_TYPES,
@@ -56,6 +65,7 @@ import {
56
65
  SKILLS_STATUSES,
57
66
  TASK_PRIORITIES,
58
67
  TASK_STATES,
68
+ WEEK_STARTS,
59
69
  } from "./vocabulary.js";
60
70
 
61
71
  /** A line of text a person wrote: trimmed, bounded, and free of characters that hide. */
@@ -159,6 +169,18 @@ export const restProviderSchema = z.object({
159
169
  });
160
170
  export type RestProvider = z.infer<typeof restProviderSchema>;
161
171
 
172
+ /**
173
+ * A time zone's name as the IANA database spells one (`Asia/Seoul`, `UTC`): its shape here; the
174
+ * server knows which names are zones.
175
+ */
176
+ export const timeZoneName = z
177
+ .string()
178
+ .check(
179
+ z.minLength(1),
180
+ z.maxLength(64),
181
+ z.regex(/^[A-Za-z0-9_+-]+(?:\/[A-Za-z0-9_+-]+)*$/, "must be a time zone name"),
182
+ );
183
+
162
184
  /** A language tag as a browser sends one (`en`, `ko-KR`): what the pages speak, by the person's choice. */
163
185
  const languageTag = z
164
186
  .string()
@@ -171,22 +193,67 @@ const languageTag = z
171
193
  export const restMePatchSchema = z.object({ language: z.nullable(languageTag) });
172
194
  export type RestMePatch = z.infer<typeof restMePatchSchema>;
173
195
 
196
+ /**
197
+ * The workspace as `GET /api/v1/me` describes it, and as `PATCH /api/v1/workspace` answers: what
198
+ * the board is called, what the deployment's configuration says of it, and the settings an
199
+ * administrator keeps on the Settings page (ADR-0035).
200
+ */
201
+ export const restWorkspaceSchema = z.object({
202
+ name: z.string(),
203
+ /** The most days a token may be good for here, or `null` when a person chooses. */
204
+ tokenDaysAtMost: z.nullable(z.int().check(z.positive())),
205
+ /**
206
+ * The organization's skills: the origin of the SkillCDN deployment they are read through,
207
+ * and the address a project without one of its own reads, canonical, or `null` for none.
208
+ */
209
+ skills: z.object({
210
+ source: z.string(),
211
+ address: z.nullable(z.string()),
212
+ /**
213
+ * The SkillCDN token the organization's pack is read with, by a project that names no
214
+ * address and holds no token of its own (ADR-0036): when it was set, never the token; `null`
215
+ * for none. Optional, so that a console older than it still answers.
216
+ */
217
+ packToken: z.optional(z.nullable(z.object({ setAt: instant }))),
218
+ }),
219
+ /**
220
+ * Who sees whom on the People page (ADR-0035): everyone, or the people one shares a project
221
+ * with. Read as optional, so that a console older than this setting still answers; `everyone`
222
+ * then, which is what it does.
223
+ */
224
+ peopleVisibility: z.optional(z.enum(PEOPLE_VISIBILITIES)),
225
+ /** The day the calendars begin a week on: the language's, Monday or Sunday. Optional as above; `auto` then. */
226
+ weekStart: z.optional(z.enum(WEEK_STARTS)),
227
+ /**
228
+ * The workspace's time zone, an IANA name, in which the command prints moments; `null` for
229
+ * none, when they stay as the API gives them, in UTC. Optional as above; none then.
230
+ */
231
+ timeZone: z.optional(z.nullable(timeZoneName)),
232
+ });
233
+ export type RestWorkspace = z.infer<typeof restWorkspaceSchema>;
234
+
235
+ /** What `PATCH /api/v1/workspace` is sent, by an administrator: the settings to change, at least one. */
236
+ export const restWorkspacePatchSchema = z
237
+ .object({
238
+ peopleVisibility: z.optional(z.enum(PEOPLE_VISIBILITIES)),
239
+ weekStart: z.optional(z.enum(WEEK_STARTS)),
240
+ /** A zone's name, or `null` for none. */
241
+ timeZone: z.optional(z.nullable(timeZoneName)),
242
+ })
243
+ .check(
244
+ z.refine((patch) => Object.values(patch).some((value) => value !== undefined), {
245
+ message: "names nothing to change",
246
+ }),
247
+ );
248
+ export type RestWorkspacePatch = z.infer<typeof restWorkspacePatchSchema>;
249
+
174
250
  /**
175
251
  * `GET /api/v1/me`: the workspace, who the session cookie says is signed in (or `null`), the
176
252
  * language they chose (or `null`), and the identity providers people sign in through, none
177
253
  * where nobody can.
178
254
  */
179
255
  export const restMeSchema = z.object({
180
- workspace: z.object({
181
- name: z.string(),
182
- /** The most days a token may be good for here, or `null` when a person chooses. */
183
- tokenDaysAtMost: z.nullable(z.int().check(z.positive())),
184
- /**
185
- * The organization's skills: the origin of the SkillCDN deployment they are read through,
186
- * and the address a project without one of its own reads, canonical, or `null` for none.
187
- */
188
- skills: z.object({ source: z.string(), address: z.nullable(z.string()) }),
189
- }),
256
+ workspace: restWorkspaceSchema,
190
257
  person: z.nullable(restPersonSchema),
191
258
  /**
192
259
  * What the token asking is called by its person, when a token asks: how a console of a
@@ -322,15 +389,25 @@ export const restProjectPatchSchema = z.object({
322
389
  });
323
390
  export type RestProjectPatch = z.infer<typeof restProjectPatchSchema>;
324
391
 
325
- /** A person listed in a project, with what they are in it. */
392
+ /**
393
+ * A member of a project, with what they are in it: a person listed in it, or, in a project open
394
+ * to the workspace, anyone of the workspace, who is a member of it without a listing (ADR-0035).
395
+ */
326
396
  export const restMemberSchema = z.object({
327
397
  person: restPersonSchema,
398
+ /** What they are in it: an owner as listed or as an administrator, else a member. */
328
399
  role: z.enum(PROJECT_ROLES),
400
+ /** Since when: the listing's day, or, for a member without one, the later of the project's making and their joining. */
329
401
  addedAt: instant,
402
+ /**
403
+ * Whether a listing holds them in the project. Read as optional, so that a console older than
404
+ * this field still answers; everyone it lists is listed.
405
+ */
406
+ listed: z.optional(z.boolean()),
330
407
  });
331
408
  export type RestMember = z.infer<typeof restMemberSchema>;
332
409
 
333
- /** `GET /api/v1/projects/<key>/members`: those listed, by login. */
410
+ /** `GET /api/v1/projects/<key>/members`: the members, by login; everyone of the workspace in a project open to it. */
334
411
  export const restMembersSchema = z.object({ items: z.array(restMemberSchema) });
335
412
  export type RestMembers = z.infer<typeof restMembersSchema>;
336
413
 
@@ -548,9 +625,15 @@ export const restGoalPatchSchema = z.object({
548
625
  export type RestGoalPatch = z.infer<typeof restGoalPatchSchema>;
549
626
 
550
627
  export const restDecisionOptionSchema = z.object({
551
- /** What an answer names: stable for the life of the decision. */
628
+ /** What an answer names: stable once given. */
552
629
  id: z.string(),
553
630
  label: z.string(),
631
+ /**
632
+ * On the one option a person's own answer became, when they answered in their own words
633
+ * instead of choosing (`POST .../answer` with `own`): added then, after the options given,
634
+ * which carry no `own`.
635
+ */
636
+ own: z.optional(z.literal(true)),
554
637
  });
555
638
  export type RestDecisionOption = z.infer<typeof restDecisionOptionSchema>;
556
639
 
@@ -646,11 +729,24 @@ export const restDecisionPatchSchema = z.object({
646
729
  });
647
730
  export type RestDecisionPatch = z.infer<typeof restDecisionPatchSchema>;
648
731
 
649
- /** What `POST .../decisions/<id>/answer` is sent: an option, and a word about it. */
650
- export const restAnswerInputSchema = z.object({
651
- option: z.string().check(z.minLength(1), z.maxLength(64)),
652
- note: z.optional(paragraphs(MAX_NOTE_LENGTH)),
653
- });
732
+ /**
733
+ * What `POST .../decisions/<id>/answer` is sent: one of the options by its id, or the person's
734
+ * own answer in a line, one of the two; and a word about either.
735
+ */
736
+ export const restAnswerInputSchema = z
737
+ .object({
738
+ /** The id of the chosen option. */
739
+ option: z.optional(z.string().check(z.minLength(1), z.maxLength(64))),
740
+ /** The person's own answer, when none of the options is it: one line, worded as an option is. */
741
+ own: z.optional(line(MAX_OPTION_LABEL_LENGTH)),
742
+ note: z.optional(paragraphs(MAX_NOTE_LENGTH)),
743
+ })
744
+ .check(
745
+ z.refine(
746
+ (input) => (input.option === undefined) !== (input.own === undefined),
747
+ "must name an option or give an answer of its own, one of the two",
748
+ ),
749
+ );
654
750
  export type RestAnswerInput = z.infer<typeof restAnswerInputSchema>;
655
751
 
656
752
  /**
@@ -894,15 +990,39 @@ export const restClaimSchema = z.union([
894
990
  ]);
895
991
  export type RestClaim = z.infer<typeof restClaimSchema>;
896
992
 
897
- /** One of the project's skills, as the SkillCDN deployment lists it at the project's address. */
993
+ /** Why a pack did not answer a read: the code and the words the deployment, or the console reading a directory, gave, as the main repository's API spells them. */
994
+ export const restPackRefusalSchema = z.object({
995
+ code: z.string(),
996
+ message: z.string(),
997
+ /** With a file the pack will not carry: where it is at its source, or `null`. */
998
+ sourceUrl: z.nullable(z.string()),
999
+ /** With `skill.ambiguous`: the directories to choose from. */
1000
+ directories: z.array(z.string()),
1001
+ });
1002
+ export type RestPackRefusal = z.infer<typeof restPackRefusalSchema>;
1003
+
1004
+ /** What every answer about a pack says first: its address, where it is read, and how the read went. */
1005
+ const packEnvelope = {
1006
+ /** The address, canonical, or `null` when neither the project nor the console names one. */
1007
+ address: z.nullable(z.string()),
1008
+ /** The origin of the SkillCDN deployment the pack is read at; `null` for a pack read from a directory on the console's machine (ADR-0031). */
1009
+ source: z.nullable(z.string()),
1010
+ /** Where a person browses the address at the deployment, or `null` without one. */
1011
+ page: z.nullable(z.string()),
1012
+ status: z.enum(SKILLS_STATUSES),
1013
+ /** Why the read did not happen, in the pack's own words, when `status` says it did not; `null` otherwise. */
1014
+ refusal: z.nullable(restPackRefusalSchema),
1015
+ };
1016
+
1017
+ /** One of the project's skills, as the pack lists it: what the repository says of it, where a person reads it, what an agent loads it by. */
898
1018
  export const restSkillSchema = z.object({
899
1019
  name: z.string(),
900
1020
  description: z.string(),
901
1021
  /** The skill's folder in the repository (`""` for the root), and the path of its `SKILL.md`. */
902
1022
  directory: z.string(),
903
1023
  path: z.string(),
904
- /** Where a person reads the skill: its page at the deployment. */
905
- page: z.string(),
1024
+ /** Where a person reads the skill: its page at the deployment, or `null` for a pack read from a directory. */
1025
+ page: z.nullable(z.string()),
906
1026
  /** What an agent loads the skill by, through its own SkillCDN connection; `null` when the path is not one. */
907
1027
  uri: z.nullable(z.string()),
908
1028
  /** The title and the description in other languages, by language tag, as the repository gives them. */
@@ -913,15 +1033,9 @@ export const restSkillSchema = z.object({
913
1033
  });
914
1034
  export type RestSkill = z.infer<typeof restSkillSchema>;
915
1035
 
916
- /** `GET /api/v1/projects/<key>/skills`: the project's skills, read by address through SkillCDN. */
1036
+ /** `GET /api/v1/projects/<key>/skills`: the project's pack, read by address (ADR-0028, ADR-0031). */
917
1037
  export const restSkillsSchema = z.object({
918
- /** The address, canonical, or `null` when neither the project nor the deployment names one. */
919
- address: z.nullable(z.string()),
920
- /** The origin of the SkillCDN deployment the skills are read through. */
921
- source: z.string(),
922
- /** Where a person browses the address, or `null` without one. */
923
- page: z.nullable(z.string()),
924
- status: z.enum(SKILLS_STATUSES),
1038
+ ...packEnvelope,
925
1039
  /** The pack as its manifest or its README names it, when `ready`: what it is called, what it is for, the language it is written in. */
926
1040
  pack: z.optional(
927
1041
  z.object({
@@ -930,10 +1044,12 @@ export const restSkillsSchema = z.object({
930
1044
  language: z.nullable(z.string()),
931
1045
  }),
932
1046
  ),
933
- /** How many skills and documents the deployment indexed at the address, when `ready`. */
1047
+ /** How many skills and documents the index found at the address, when `ready`. */
934
1048
  counts: z.optional(z.object({ skills: count, documents: count })),
935
1049
  /** The skills, when `ready`; empty otherwise. */
936
1050
  items: z.array(restSkillSchema),
1051
+ /** What the address serves, as the main repository's REST API answers it (`RestMount` of `@skillcdn/core`), for a program that renders what a model is given; `null` when nothing was answered. */
1052
+ mount: z.nullable(packMountSchema),
937
1053
  });
938
1054
  export type RestSkills = z.infer<typeof restSkillsSchema>;
939
1055
 
@@ -945,181 +1061,78 @@ export const restPackTokenInputSchema = z.object({
945
1061
  });
946
1062
  export type RestPackTokenInput = z.infer<typeof restPackTokenInputSchema>;
947
1063
 
948
- /** A rule, the body or an included file of a skill: its path from the repository's root and its text, cut where a page ends. */
949
- export const restSkillTextSchema = z.object({
950
- path: z.string(),
951
- body: z.string(),
952
- truncated: z.boolean(),
1064
+ /**
1065
+ * `POST .../pack-token/connect` (ADR-0036): what the person is shown, as the deployment said it,
1066
+ * the code and the page to approve it on, until when, and how often the console asks again. The
1067
+ * secret the console claims the token with stays with the console.
1068
+ */
1069
+ export const restPackConnectStartedSchema = z.object({
1070
+ code: z.string(),
1071
+ url: z.string(),
1072
+ expiresAt: instant,
1073
+ intervalSeconds: z.int().check(z.positive()),
953
1074
  });
954
- /** A skill as the deployment serves it, on one page of its context: what `load_skill` gives a model, in the console's shape. */
955
- export const restSkillPageSchema = z.object({
956
- path: z.string(),
957
- directory: z.string(),
958
- name: z.string(),
959
- description: z.string(),
960
- /** The rules that hold for the skill, from the repository's root to the nearest manifest. */
961
- rules: z.array(restSkillTextSchema),
962
- body: z.string(),
963
- /** The files the skill includes with its body. */
964
- included: z.array(restSkillTextSchema),
965
- /** The paths of the skill's own files, read with the file route. */
966
- files: z.array(z.string()),
967
- references: z.array(
968
- z.object({
969
- path: z.string(),
970
- status: z.enum(["available", "blocked", "missing", "outside_mount"]),
971
- }),
972
- ),
973
- /** Whether this page completes the skill; else the cursor of the next. */
974
- complete: z.boolean(),
975
- nextCursor: z.nullable(z.string()),
976
- /** How the skill is served: whole, or described only, with its license and where it is read at its host. */
977
- serving: z.object({
978
- full: z.boolean(),
979
- license: z.nullable(z.string()),
980
- sourceUrl: z.nullable(z.string()),
981
- }),
982
- warnings: z.array(z.string()),
1075
+ export type RestPackConnectStarted = z.infer<typeof restPackConnectStartedSchema>;
1076
+
1077
+ /**
1078
+ * `GET .../pack-token/connect`: how the connection stands. Nothing asked; waiting for the
1079
+ * person, with what they were shown; connected, the token kept and the project as it stands; or
1080
+ * ended short of a token, and why.
1081
+ */
1082
+ const packConnectNone = z.object({ status: z.literal("none") });
1083
+ const packConnectPending = z.object({
1084
+ status: z.literal("pending"),
1085
+ code: z.string(),
1086
+ url: z.string(),
1087
+ expiresAt: instant,
1088
+ intervalSeconds: z.int().check(z.positive()),
1089
+ });
1090
+ const packConnectEnded = z.object({
1091
+ status: z.literal("ended"),
1092
+ reason: z.enum(PACK_CONNECT_ENDINGS),
983
1093
  });
984
- export type RestSkillPage = z.infer<typeof restSkillPageSchema>;
1094
+ export const restPackConnectSchema = z.union([
1095
+ packConnectNone,
1096
+ packConnectPending,
1097
+ z.object({ status: z.literal("connected"), project: restProjectSchema }),
1098
+ packConnectEnded,
1099
+ ]);
1100
+ export type RestPackConnect = z.infer<typeof restPackConnectSchema>;
1101
+
1102
+ /** `GET /api/v1/workspace/pack-token/connect`: the same, for the workspace's token, with the workspace as it stands once connected. */
1103
+ export const restWorkspacePackConnectSchema = z.union([
1104
+ packConnectNone,
1105
+ packConnectPending,
1106
+ z.object({ status: z.literal("connected"), workspace: restWorkspaceSchema }),
1107
+ packConnectEnded,
1108
+ ]);
1109
+ export type RestWorkspacePackConnect = z.infer<typeof restWorkspacePackConnectSchema>;
985
1110
 
986
- /** `GET .../skills/one?path=&cursor=`: one skill of the pack, a page of it; `skill` is `null` unless `ready`. */
1111
+ /** `GET .../skills/one?path=&cursor=`: a page of a skill's context, as the pack answers `load_skill` (`RestSkill` of `@skillcdn/core`); `read` is `null` unless `ready`. */
987
1112
  export const restSkillLoadSchema = z.object({
988
- address: z.nullable(z.string()),
989
- source: z.string(),
990
- page: z.nullable(z.string()),
991
- status: z.enum(SKILLS_STATUSES),
992
- skill: z.nullable(restSkillPageSchema),
1113
+ ...packEnvelope,
1114
+ read: z.nullable(packSkillSchema),
993
1115
  });
994
1116
  export type RestSkillLoad = z.infer<typeof restSkillLoadSchema>;
995
1117
 
996
- /** `GET .../skills/file?path=&offset=&limit=`: a page of a file of the pack, or what a folder holds; both `null` unless `ready`. */
1118
+ /** `GET .../skills/file?path=&offset=&limit=`: a page of a file, or what a folder holds, as the pack answers `read_repo_file` (`RestFile` of `@skillcdn/core`); `read` is `null` unless `ready`. */
997
1119
  export const restSkillFileSchema = z.object({
998
- address: z.nullable(z.string()),
999
- source: z.string(),
1000
- status: z.enum(SKILLS_STATUSES),
1001
- file: z.nullable(
1002
- z.object({
1003
- path: z.string(),
1004
- content: z.string(),
1005
- offset: count,
1006
- nextOffset: z.nullable(count),
1007
- totalLength: count,
1008
- }),
1009
- ),
1010
- folder: z.nullable(
1011
- z.object({
1012
- path: z.string(),
1013
- entries: z.array(
1014
- z.object({
1015
- path: z.string(),
1016
- kind: z.enum(["directory", "file"]),
1017
- size: z.nullable(count),
1018
- }),
1019
- ),
1020
- truncated: z.boolean(),
1021
- }),
1022
- ),
1120
+ ...packEnvelope,
1121
+ read: z.nullable(packFileSchema),
1023
1122
  });
1024
1123
  export type RestSkillFile = z.infer<typeof restSkillFileSchema>;
1025
1124
 
1026
- /** An entry of a folder of the pack, as the deployment browses it: a skill, a folder with what it holds, or a file. */
1027
- export const restSkillBrowseEntrySchema = z.object({
1028
- kind: z.enum(["skill", "directory", "file"]),
1029
- /** The path from the repository's root: of the `SKILL.md` for a skill, of the folder, of the file. */
1030
- path: z.string(),
1031
- name: z.nullable(z.string()),
1032
- description: z.nullable(z.string()),
1033
- /** For a folder: the skills and the documents under it. */
1034
- skillCount: count,
1035
- documentCount: count,
1036
- /** For a file: its size in bytes. */
1037
- size: z.nullable(count),
1038
- /** For a folder: the README that introduces it, read with the file route. */
1039
- overviewPath: z.nullable(z.string()),
1040
- /** For a skill: its license, and whether the address only describes it. */
1041
- license: z.nullable(z.string()),
1042
- describedOnly: z.boolean(),
1043
- });
1044
- export type RestSkillBrowseEntry = z.infer<typeof restSkillBrowseEntrySchema>;
1045
-
1046
- /** `GET .../skills/browse?path=&cursor=&limit=`: what a folder of the pack holds, a page of it (`browse_repo`); `folder` is `null` unless `ready`. */
1125
+ /** `GET .../skills/browse?path=&cursor=&limit=`: what a folder holds, a page of it, as the pack answers `browse_repo` (`RestBrowse` of `@skillcdn/core`); `read` is `null` unless `ready`. */
1047
1126
  export const restSkillBrowseSchema = z.object({
1048
- address: z.nullable(z.string()),
1049
- source: z.string(),
1050
- page: z.nullable(z.string()),
1051
- status: z.enum(SKILLS_STATUSES),
1052
- folder: z.nullable(
1053
- z.object({
1054
- path: z.string(),
1055
- /** The README that introduces the folder, or `null`. */
1056
- overview: z.nullable(
1057
- z.object({
1058
- path: z.string(),
1059
- title: z.nullable(z.string()),
1060
- description: z.nullable(z.string()),
1061
- }),
1062
- ),
1063
- entries: z.array(restSkillBrowseEntrySchema),
1064
- /** Where the listing goes on, or `null` at its end. */
1065
- nextCursor: z.nullable(z.string()),
1066
- }),
1067
- ),
1127
+ ...packEnvelope,
1128
+ read: z.nullable(packBrowseSchema),
1068
1129
  });
1069
1130
  export type RestSkillBrowse = z.infer<typeof restSkillBrowseSchema>;
1070
1131
 
1071
- /** What a search of the pack found: a skill, as the listing has it, with the files of it that matched; or a document on its own. */
1072
- export const restSkillFindItemSchema = z.discriminatedUnion("kind", [
1073
- z.object({
1074
- kind: z.literal("skill"),
1075
- name: z.string(),
1076
- description: z.string(),
1077
- directory: z.string(),
1078
- path: z.string(),
1079
- page: z.string(),
1080
- uri: z.nullable(z.string()),
1081
- translations: z.record(
1082
- z.string(),
1083
- z.object({ title: z.nullable(z.string()), description: z.nullable(z.string()) }),
1084
- ),
1085
- /** The files of the skill that matched, a few, and how many more did. */
1086
- files: z.array(
1087
- z.object({
1088
- path: z.string(),
1089
- title: z.nullable(z.string()),
1090
- summary: z.nullable(z.string()),
1091
- }),
1092
- ),
1093
- moreFiles: count,
1094
- license: z.nullable(z.string()),
1095
- describedOnly: z.boolean(),
1096
- }),
1097
- z.object({
1098
- kind: z.literal("document"),
1099
- path: z.string(),
1100
- title: z.nullable(z.string()),
1101
- summary: z.nullable(z.string()),
1102
- /** The folder of the skill the document belongs to, or `null` for one on its own. */
1103
- skillDirectory: z.nullable(z.string()),
1104
- }),
1105
- ]);
1106
- export type RestSkillFindItem = z.infer<typeof restSkillFindItemSchema>;
1107
-
1108
- /** `GET .../skills/find?query=&path=&cursor=&limit=`: what words find in the pack, a page of it in relevance order (`search_repo`); `found` is `null` unless `ready`. */
1132
+ /** `GET .../skills/find?query=&path=&cursor=&limit=`: what words find, a page of it in relevance order, as the pack answers `search_repo` (`RestFind` of `@skillcdn/core`); `read` is `null` unless `ready`. */
1109
1133
  export const restSkillFindSchema = z.object({
1110
- address: z.nullable(z.string()),
1111
- source: z.string(),
1112
- page: z.nullable(z.string()),
1113
- status: z.enum(SKILLS_STATUSES),
1114
- found: z.nullable(
1115
- z.object({
1116
- query: z.string(),
1117
- /** The folder the search was kept to, or `null` for the whole pack. */
1118
- path: z.nullable(z.string()),
1119
- items: z.array(restSkillFindItemSchema),
1120
- nextCursor: z.nullable(z.string()),
1121
- }),
1122
- ),
1134
+ ...packEnvelope,
1135
+ read: z.nullable(packFindSchema),
1123
1136
  });
1124
1137
  export type RestSkillFind = z.infer<typeof restSkillFindSchema>;
1125
1138