@skillcdn/console 0.1.8 → 0.1.10

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 (147) hide show
  1. package/README.md +5 -5
  2. package/dist/api.d.ts +5 -5
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +4 -4
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli/cli.d.ts.map +1 -1
  7. package/dist/cli/cli.js +255 -10
  8. package/dist/cli/cli.js.map +1 -1
  9. package/dist/cli/format.d.ts +9 -1
  10. package/dist/cli/format.d.ts.map +1 -1
  11. package/dist/cli/format.js +80 -0
  12. package/dist/cli/format.js.map +1 -1
  13. package/dist/cli/help.d.ts.map +1 -1
  14. package/dist/cli/help.js +62 -7
  15. package/dist/cli/help.js.map +1 -1
  16. package/dist/client.d.ts +31 -4
  17. package/dist/client.d.ts.map +1 -1
  18. package/dist/client.js +19 -3
  19. package/dist/client.js.map +1 -1
  20. package/dist/components/board.d.ts +27 -1
  21. package/dist/components/board.d.ts.map +1 -1
  22. package/dist/components/board.js +75 -7
  23. package/dist/components/board.js.map +1 -1
  24. package/dist/components/calendar.d.ts +34 -0
  25. package/dist/components/calendar.d.ts.map +1 -0
  26. package/dist/components/calendar.js +96 -0
  27. package/dist/components/calendar.js.map +1 -0
  28. package/dist/components/categories.d.ts +13 -0
  29. package/dist/components/categories.d.ts.map +1 -0
  30. package/dist/components/categories.js +52 -0
  31. package/dist/components/categories.js.map +1 -0
  32. package/dist/components/decision-list.d.ts +10 -0
  33. package/dist/components/decision-list.d.ts.map +1 -1
  34. package/dist/components/decision-list.js +14 -1
  35. package/dist/components/decision-list.js.map +1 -1
  36. package/dist/components/event-feed.d.ts.map +1 -1
  37. package/dist/components/event-feed.js +12 -0
  38. package/dist/components/event-feed.js.map +1 -1
  39. package/dist/components/goals.d.ts +35 -0
  40. package/dist/components/goals.d.ts.map +1 -0
  41. package/dist/components/goals.js +45 -0
  42. package/dist/components/goals.js.map +1 -0
  43. package/dist/components/task-form.d.ts +5 -1
  44. package/dist/components/task-form.d.ts.map +1 -1
  45. package/dist/components/task-form.js +13 -1
  46. package/dist/components/task-form.js.map +1 -1
  47. package/dist/components/task-list.d.ts +16 -0
  48. package/dist/components/task-list.d.ts.map +1 -0
  49. package/dist/components/task-list.js +14 -0
  50. package/dist/components/task-list.js.map +1 -0
  51. package/dist/components/task-view.d.ts +9 -1
  52. package/dist/components/task-view.d.ts.map +1 -1
  53. package/dist/components/task-view.js +10 -4
  54. package/dist/components/task-view.js.map +1 -1
  55. package/dist/components/ui.d.ts +30 -1
  56. package/dist/components/ui.d.ts.map +1 -1
  57. package/dist/components/ui.js +60 -0
  58. package/dist/components/ui.js.map +1 -1
  59. package/dist/components/work.d.ts +10 -0
  60. package/dist/components/work.d.ts.map +1 -0
  61. package/dist/components/work.js +29 -0
  62. package/dist/components/work.js.map +1 -0
  63. package/dist/console.css +511 -0
  64. package/dist/console.d.ts +8 -0
  65. package/dist/console.d.ts.map +1 -1
  66. package/dist/console.js +124 -8
  67. package/dist/console.js.map +1 -1
  68. package/dist/data.d.ts +14 -1
  69. package/dist/data.d.ts.map +1 -1
  70. package/dist/data.js +36 -2
  71. package/dist/data.js.map +1 -1
  72. package/dist/dates.d.ts +39 -0
  73. package/dist/dates.d.ts.map +1 -0
  74. package/dist/dates.js +120 -0
  75. package/dist/dates.js.map +1 -0
  76. package/dist/i18n/en.d.ts +162 -1
  77. package/dist/i18n/en.d.ts.map +1 -1
  78. package/dist/i18n/en.js +174 -1
  79. package/dist/i18n/en.js.map +1 -1
  80. package/dist/i18n/ko.d.ts.map +1 -1
  81. package/dist/i18n/ko.js +169 -1
  82. package/dist/i18n/ko.js.map +1 -1
  83. package/dist/index.d.ts +10 -4
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +10 -4
  86. package/dist/index.js.map +1 -1
  87. package/dist/limits.d.ts +5 -0
  88. package/dist/limits.d.ts.map +1 -1
  89. package/dist/limits.js +5 -0
  90. package/dist/limits.js.map +1 -1
  91. package/dist/router.d.ts +50 -1
  92. package/dist/router.d.ts.map +1 -1
  93. package/dist/router.js +74 -1
  94. package/dist/router.js.map +1 -1
  95. package/dist/routes.d.ts +7 -1
  96. package/dist/routes.d.ts.map +1 -1
  97. package/dist/routes.js +9 -0
  98. package/dist/routes.js.map +1 -1
  99. package/dist/schemas.d.ts +366 -0
  100. package/dist/schemas.d.ts.map +1 -1
  101. package/dist/schemas.js +112 -3
  102. package/dist/schemas.js.map +1 -1
  103. package/dist/vocabulary.d.ts +15 -1
  104. package/dist/vocabulary.d.ts.map +1 -1
  105. package/dist/vocabulary.js +26 -0
  106. package/dist/vocabulary.js.map +1 -1
  107. package/docs/specs/cli.md +11 -4
  108. package/docs/specs/rest.md +33 -8
  109. package/package.json +1 -1
  110. package/skills/building-a-console/SKILL.md +4 -4
  111. package/skills/building-a-console/references/the-default-console.md +1 -1
  112. package/skills/deploying-a-console/SKILL.md +11 -10
  113. package/skills/deploying-a-console/assets/deployer-policy.json +13 -12
  114. package/skills/deploying-a-console/assets/secrets.example.json +4 -4
  115. package/skills/deploying-a-console/references/access.md +10 -9
  116. package/skills/deploying-a-console/references/resources.md +107 -50
  117. package/skills/deploying-a-console/references/sizing.md +1 -1
  118. package/skills/deploying-a-console/scripts/store-secrets.mjs +1 -15
  119. package/skills/working-the-board/SKILL.md +7 -6
  120. package/src/api.ts +30 -0
  121. package/src/cli/cli.ts +311 -10
  122. package/src/cli/format.ts +88 -0
  123. package/src/cli/help.ts +69 -7
  124. package/src/client.ts +70 -2
  125. package/src/components/board.tsx +205 -12
  126. package/src/components/calendar.tsx +255 -0
  127. package/src/components/categories.tsx +209 -0
  128. package/src/components/decision-list.tsx +62 -5
  129. package/src/components/event-feed.tsx +12 -0
  130. package/src/components/goals.tsx +264 -0
  131. package/src/components/task-form.tsx +78 -1
  132. package/src/components/task-list.tsx +61 -0
  133. package/src/components/task-view.tsx +74 -3
  134. package/src/components/ui.tsx +116 -1
  135. package/src/components/work.tsx +83 -0
  136. package/src/console.tsx +337 -4
  137. package/src/data.ts +63 -8
  138. package/src/dates.ts +143 -0
  139. package/src/i18n/en.ts +184 -1
  140. package/src/i18n/ko.ts +175 -1
  141. package/src/index.ts +58 -1
  142. package/src/limits.ts +5 -0
  143. package/src/router.ts +119 -6
  144. package/src/routes.ts +10 -0
  145. package/src/schemas.ts +141 -1
  146. package/src/styles/console.css +511 -0
  147. package/src/vocabulary.ts +33 -0
package/src/schemas.ts CHANGED
@@ -7,6 +7,8 @@ import { isDocumentPath } from "./documents.js";
7
7
  import {
8
8
  MAX_AGENT_LENGTH,
9
9
  MAX_BODY_LENGTH,
10
+ MAX_CATEGORY_KEY_LENGTH,
11
+ MAX_CATEGORY_NAME_LENGTH,
10
12
  MAX_DOCUMENT_LENGTH,
11
13
  MAX_DOCUMENT_PATH_LENGTH,
12
14
  MAX_FILE_NAME_LENGTH,
@@ -32,7 +34,9 @@ import {
32
34
  import { hasForbiddenCodePoint } from "./text.js";
33
35
  import {
34
36
  ARTIFACT_KINDS,
37
+ CATEGORY_COLORS,
35
38
  EVENT_KINDS,
39
+ GOAL_STATES,
36
40
  LINK_SOURCES,
37
41
  PERSON_ROLES,
38
42
  PROJECT_ROLES,
@@ -70,6 +74,8 @@ const url = z.string().check(z.trim(), z.maxLength(MAX_URL_LENGTH), z.url({ prot
70
74
  const uuid = z.uuid();
71
75
  /** An ISO 8601 instant, as the server writes it. */
72
76
  const instant = z.iso.datetime();
77
+ /** A calendar day (`2026-10-20`): a plan is made in days, wherever the people are (ADR-0019). */
78
+ const day = z.iso.date();
73
79
  const count = z.int().check(z.nonnegative());
74
80
 
75
81
  /** A person of the workspace, as the pages show them. Nothing here is a secret. */
@@ -230,6 +236,48 @@ export const restTaskLinkSchema = z.object({
230
236
  });
231
237
  export type RestTaskLink = z.infer<typeof restTaskLinkSchema>;
232
238
 
239
+ /**
240
+ * A category's key: what the command and the filters say, as a project's key is. Lowercase
241
+ * letters, digits and hyphens; immutable once the category is made.
242
+ */
243
+ const categoryKey = z
244
+ .string()
245
+ .check(
246
+ z.maxLength(MAX_CATEGORY_KEY_LENGTH),
247
+ z.regex(/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/, "must be lowercase letters, digits and hyphens"),
248
+ );
249
+
250
+ /** A category tasks are sorted into (ADR-0019): the workspace's own word for a kind of work. */
251
+ export const restCategorySchema = z.object({
252
+ key: categoryKey,
253
+ name: z.string(),
254
+ /** One of the names the pages paint a category in. */
255
+ color: z.enum(CATEGORY_COLORS),
256
+ createdAt: instant,
257
+ updatedAt: instant,
258
+ });
259
+ export type RestCategory = z.infer<typeof restCategorySchema>;
260
+
261
+ /** `GET /api/v1/categories`: the workspace's categories, by name. */
262
+ export const restCategoriesSchema = z.object({ items: z.array(restCategorySchema) });
263
+ export type RestCategories = z.infer<typeof restCategoriesSchema>;
264
+
265
+ /** What `POST /api/v1/categories` is sent, by an administrator: the key, the name, and a colour or the plain one. */
266
+ export const restCategoryInputSchema = z.object({
267
+ key: categoryKey,
268
+ name: line(MAX_CATEGORY_NAME_LENGTH),
269
+ /** Left out: `gray`. */
270
+ color: z.optional(z.enum(CATEGORY_COLORS)),
271
+ });
272
+ export type RestCategoryInput = z.infer<typeof restCategoryInputSchema>;
273
+
274
+ /** What `PATCH /api/v1/categories/<key>` is sent: only what changes; the key does not. */
275
+ export const restCategoryPatchSchema = z.object({
276
+ name: z.optional(line(MAX_CATEGORY_NAME_LENGTH)),
277
+ color: z.optional(z.enum(CATEGORY_COLORS)),
278
+ });
279
+ export type RestCategoryPatch = z.infer<typeof restCategoryPatchSchema>;
280
+
233
281
  export const restTaskSchema = z.object({
234
282
  id: uuid,
235
283
  /** The task's number in its project, the one people say out loud. */
@@ -243,6 +291,18 @@ export const restTaskSchema = z.object({
243
291
  assignee: z.nullable(restPersonSchema),
244
292
  /** The task this one is part of, or `null`. */
245
293
  parentId: z.nullable(uuid),
294
+ /** The category the task is sorted into, as the workspace keeps it, or `null`. */
295
+ category: z.nullable(
296
+ z.object({ key: z.string(), name: z.string(), color: z.enum(CATEGORY_COLORS) }),
297
+ ),
298
+ /** The goal of the project's roadmap the task works towards, or `null`. */
299
+ goalId: z.nullable(uuid),
300
+ /** The plan (ADR-0019): the day the work is meant to begin, and the day it is due, each or `null`. */
301
+ startsOn: z.nullable(day),
302
+ dueOn: z.nullable(day),
303
+ /** What happened: when the task was first moved past ready, and when it was moved to done; each or `null`. The board keeps both. */
304
+ startedAt: z.nullable(instant),
305
+ doneAt: z.nullable(instant),
246
306
  links: z.array(restTaskLinkSchema),
247
307
  /** How many decisions about this task wait for a person. */
248
308
  openDecisions: count,
@@ -270,6 +330,13 @@ export const restTaskInputSchema = z.object({
270
330
  priority: z.optional(z.enum(TASK_PRIORITIES)),
271
331
  assigneeId: z.optional(z.nullable(uuid)),
272
332
  parentId: z.optional(z.nullable(uuid)),
333
+ /** The key of a category of the workspace, or `null` for none. */
334
+ category: z.optional(z.nullable(categoryKey)),
335
+ /** A goal of the project, or `null` for none. */
336
+ goalId: z.optional(z.nullable(uuid)),
337
+ /** The plan, in days; the due day is not before the start. */
338
+ startsOn: z.optional(z.nullable(day)),
339
+ dueOn: z.optional(z.nullable(day)),
273
340
  links: z.optional(z.array(taskLinkInput).check(z.maxLength(MAX_LINKS))),
274
341
  });
275
342
  export type RestTaskInput = z.infer<typeof restTaskInputSchema>;
@@ -282,10 +349,68 @@ export const restTaskPatchSchema = z.object({
282
349
  priority: z.optional(z.enum(TASK_PRIORITIES)),
283
350
  assigneeId: z.optional(z.nullable(uuid)),
284
351
  parentId: z.optional(z.nullable(uuid)),
352
+ category: z.optional(z.nullable(categoryKey)),
353
+ goalId: z.optional(z.nullable(uuid)),
354
+ startsOn: z.optional(z.nullable(day)),
355
+ dueOn: z.optional(z.nullable(day)),
285
356
  links: z.optional(z.array(taskLinkInput).check(z.maxLength(MAX_LINKS))),
286
357
  });
287
358
  export type RestTaskPatch = z.infer<typeof restTaskPatchSchema>;
288
359
 
360
+ /** How many tasks a goal has in each state: what its progress is read from, live. */
361
+ export const restTaskCountsSchema = z.object({
362
+ idea: count,
363
+ ready: count,
364
+ in_progress: count,
365
+ in_review: count,
366
+ done: count,
367
+ dropped: count,
368
+ });
369
+ export type RestTaskCounts = z.infer<typeof restTaskCountsSchema>;
370
+
371
+ /**
372
+ * A goal of a project's roadmap (ADR-0019): what the project works towards, with the day it is
373
+ * meant to be reached by, and how far the tasks under it are.
374
+ */
375
+ export const restGoalSchema = z.object({
376
+ id: uuid,
377
+ title: z.string(),
378
+ /** Markdown: what reaching the goal means. Shown as text or rendered to elements, never as HTML. */
379
+ body: z.string(),
380
+ state: z.enum(GOAL_STATES),
381
+ /** The day the goal is meant to be reached by, or `null`. */
382
+ dueOn: z.nullable(day),
383
+ createdBy: restPersonSchema,
384
+ /** The tasks that work towards it, counted by state. */
385
+ taskCounts: restTaskCountsSchema,
386
+ createdAt: instant,
387
+ updatedAt: instant,
388
+ });
389
+ export type RestGoal = z.infer<typeof restGoalSchema>;
390
+
391
+ /** `GET /api/v1/projects/<key>/goals`: the roadmap, the active goals first. */
392
+ export const restGoalsSchema = z.object({ items: z.array(restGoalSchema) });
393
+ export type RestGoals = z.infer<typeof restGoalsSchema>;
394
+
395
+ /** What `POST /api/v1/projects/<key>/goals` is sent: the title, and the rest with defaults. */
396
+ export const restGoalInputSchema = z.object({
397
+ title: line(MAX_TITLE_LENGTH),
398
+ body: z.optional(body),
399
+ /** Left out: `planned`. */
400
+ state: z.optional(z.enum(GOAL_STATES)),
401
+ dueOn: z.optional(z.nullable(day)),
402
+ });
403
+ export type RestGoalInput = z.infer<typeof restGoalInputSchema>;
404
+
405
+ /** What `PATCH /api/v1/projects/<key>/goals/<id>` is sent: only what changes. */
406
+ export const restGoalPatchSchema = z.object({
407
+ title: z.optional(line(MAX_TITLE_LENGTH)),
408
+ body: z.optional(body),
409
+ state: z.optional(z.enum(GOAL_STATES)),
410
+ dueOn: z.optional(z.nullable(day)),
411
+ });
412
+ export type RestGoalPatch = z.infer<typeof restGoalPatchSchema>;
413
+
289
414
  export const restDecisionOptionSchema = z.object({
290
415
  /** What an answer names: stable for the life of the decision. */
291
416
  id: z.string(),
@@ -328,6 +453,19 @@ export type RestDecision = z.infer<typeof restDecisionSchema>;
328
453
  export const restDecisionsSchema = z.object({ items: z.array(restDecisionSchema) });
329
454
  export type RestDecisions = z.infer<typeof restDecisionsSchema>;
330
455
 
456
+ /** The project a thing on a person's plate belongs to, named for the page to say and link it. */
457
+ const projectRef = z.object({ key: projectKey, name: z.string() });
458
+
459
+ /**
460
+ * `GET /api/v1/work`: what is on the asker's plate across the projects they may see (ADR-0019):
461
+ * the open tasks assigned to them, and the decisions that wait for a person, each with its project.
462
+ */
463
+ export const restWorkSchema = z.object({
464
+ tasks: z.array(z.object({ project: projectRef, task: restTaskSchema })),
465
+ decisions: z.array(z.object({ project: projectRef, decision: restDecisionSchema })),
466
+ });
467
+ export type RestWork = z.infer<typeof restWorkSchema>;
468
+
331
469
  /** What `POST /api/v1/projects/<key>/decisions` is sent: the question, its context, and the options. */
332
470
  export const restDecisionInputSchema = z.object({
333
471
  question: line(MAX_QUESTION_LENGTH),
@@ -363,7 +501,7 @@ export type RestAnswerInput = z.infer<typeof restAnswerInputSchema>;
363
501
  export const restEventDataSchema = z.object({
364
502
  number: z.optional(z.int()),
365
503
  title: z.optional(z.string()),
366
- /** For `task.updated`, `project.updated` and `decision.updated`: which fields changed. */
504
+ /** For `task.updated`, `project.updated`, `goal.updated` and `decision.updated`: which fields changed. */
367
505
  fields: z.optional(z.array(z.string())),
368
506
  /** For the events about a document: its path, and the version written. */
369
507
  path: z.optional(z.string()),
@@ -406,6 +544,8 @@ export const restEventSchema = z.object({
406
544
  runId: z.nullable(uuid),
407
545
  /** The document it is about, or `null`. */
408
546
  documentId: z.nullable(uuid),
547
+ /** The goal it is about, or `null`. */
548
+ goalId: z.nullable(uuid),
409
549
  data: restEventDataSchema,
410
550
  createdAt: instant,
411
551
  });