@skillcdn/console 0.4.2 → 0.4.4
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/README.md +4 -4
- package/dist/api.d.ts +3 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +3 -3
- package/dist/api.js.map +1 -1
- package/dist/cli/cli.d.ts.map +1 -1
- package/dist/cli/cli.js +120 -33
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/format.d.ts +4 -2
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.js +38 -10
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +22 -15
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/plugin-check.d.ts +10 -1
- package/dist/cli/plugin-check.d.ts.map +1 -1
- package/dist/cli/plugin-check.js +45 -4
- package/dist/cli/plugin-check.js.map +1 -1
- package/dist/cli/plugin-cli.d.ts +1 -1
- package/dist/cli/plugin-cli.d.ts.map +1 -1
- package/dist/cli/plugin-cli.js +80 -5
- package/dist/cli/plugin-cli.js.map +1 -1
- package/dist/cli/plugin-init.d.ts +19 -0
- package/dist/cli/plugin-init.d.ts.map +1 -1
- package/dist/cli/plugin-init.js +141 -3
- package/dist/cli/plugin-init.js.map +1 -1
- package/dist/client.d.ts +7 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +18 -5
- package/dist/client.js.map +1 -1
- package/dist/compat.js +1 -1
- package/dist/components/board.d.ts +8 -0
- package/dist/components/board.d.ts.map +1 -1
- package/dist/components/board.js +3 -3
- package/dist/components/board.js.map +1 -1
- package/dist/components/comments.d.ts.map +1 -1
- package/dist/components/comments.js +1 -1
- package/dist/components/comments.js.map +1 -1
- package/dist/components/decision-form.d.ts +8 -1
- package/dist/components/decision-form.d.ts.map +1 -1
- package/dist/components/decision-form.js +57 -7
- package/dist/components/decision-form.js.map +1 -1
- package/dist/components/decision-list.d.ts +9 -1
- package/dist/components/decision-list.d.ts.map +1 -1
- package/dist/components/decision-list.js +53 -7
- package/dist/components/decision-list.js.map +1 -1
- package/dist/components/event-feed.d.ts.map +1 -1
- package/dist/components/event-feed.js +7 -1
- package/dist/components/event-feed.js.map +1 -1
- package/dist/components/goals.d.ts.map +1 -1
- package/dist/components/goals.js +2 -2
- package/dist/components/goals.js.map +1 -1
- package/dist/components/home.d.ts +35 -0
- package/dist/components/home.d.ts.map +1 -0
- package/dist/components/home.js +326 -0
- package/dist/components/home.js.map +1 -0
- package/dist/components/my-decisions.d.ts +2 -0
- package/dist/components/my-decisions.d.ts.map +1 -1
- package/dist/components/my-decisions.js +2 -2
- package/dist/components/my-decisions.js.map +1 -1
- package/dist/components/pack-connect.d.ts.map +1 -1
- package/dist/components/pack-connect.js +5 -4
- package/dist/components/pack-connect.js.map +1 -1
- package/dist/components/people.d.ts +2 -0
- package/dist/components/people.d.ts.map +1 -1
- package/dist/components/people.js +15 -2
- package/dist/components/people.js.map +1 -1
- package/dist/components/plugin-frame.d.ts +3 -12
- package/dist/components/plugin-frame.d.ts.map +1 -1
- package/dist/components/plugin-frame.js +53 -20
- package/dist/components/plugin-frame.js.map +1 -1
- package/dist/components/plugin-settings.d.ts.map +1 -1
- package/dist/components/plugin-settings.js +151 -26
- package/dist/components/plugin-settings.js.map +1 -1
- package/dist/components/projects.d.ts +0 -8
- package/dist/components/projects.d.ts.map +1 -1
- package/dist/components/projects.js +1 -13
- package/dist/components/projects.js.map +1 -1
- package/dist/components/task-view.d.ts +2 -1
- package/dist/components/task-view.d.ts.map +1 -1
- package/dist/components/task-view.js +2 -1
- package/dist/components/task-view.js.map +1 -1
- package/dist/components/ui.d.ts.map +1 -1
- package/dist/components/ui.js +5 -2
- package/dist/components/ui.js.map +1 -1
- package/dist/connect-page.d.ts.map +1 -1
- package/dist/connect-page.js +5 -6
- package/dist/connect-page.js.map +1 -1
- package/dist/console.css +764 -192
- package/dist/console.d.ts +10 -3
- package/dist/console.d.ts.map +1 -1
- package/dist/console.js +49 -28
- package/dist/console.js.map +1 -1
- package/dist/data.d.ts +6 -3
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +31 -7
- package/dist/data.js.map +1 -1
- package/dist/docs-page.d.ts.map +1 -1
- package/dist/docs-page.js +6 -5
- package/dist/docs-page.js.map +1 -1
- package/dist/home-tiles.d.ts +92 -0
- package/dist/home-tiles.d.ts.map +1 -0
- package/dist/home-tiles.js +294 -0
- package/dist/home-tiles.js.map +1 -0
- package/dist/i18n/en.d.ts +180 -0
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +181 -1
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/index.d.ts +4 -2
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +10 -11
- package/dist/i18n/index.js.map +1 -1
- package/dist/i18n/ko.d.ts.map +1 -1
- package/dist/i18n/ko.js +176 -3
- package/dist/i18n/ko.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +8 -0
- package/dist/limits.d.ts.map +1 -1
- package/dist/limits.js +8 -0
- package/dist/limits.js.map +1 -1
- package/dist/plugin/bridge.d.ts +44 -3
- package/dist/plugin/bridge.d.ts.map +1 -1
- package/dist/plugin/bridge.js +26 -0
- package/dist/plugin/bridge.js.map +1 -1
- package/dist/plugin/capabilities.d.ts +7 -1
- package/dist/plugin/capabilities.d.ts.map +1 -1
- package/dist/plugin/capabilities.js +14 -1
- package/dist/plugin/capabilities.js.map +1 -1
- package/dist/plugin/context.d.ts +24 -1
- package/dist/plugin/context.d.ts.map +1 -1
- package/dist/plugin/define.d.ts +1 -0
- package/dist/plugin/define.d.ts.map +1 -1
- package/dist/plugin/define.js +1 -1
- package/dist/plugin/define.js.map +1 -1
- package/dist/plugin/limits.d.ts +5 -2
- package/dist/plugin/limits.d.ts.map +1 -1
- package/dist/plugin/limits.js +5 -2
- package/dist/plugin/limits.js.map +1 -1
- package/dist/plugin/manifest.d.ts +83 -6
- package/dist/plugin/manifest.d.ts.map +1 -1
- package/dist/plugin/manifest.js +111 -7
- package/dist/plugin/manifest.js.map +1 -1
- package/dist/plugin/rest-schemas.d.ts +76 -0
- package/dist/plugin/rest-schemas.d.ts.map +1 -1
- package/dist/plugin/rest-schemas.js +23 -2
- package/dist/plugin/rest-schemas.js.map +1 -1
- package/dist/plugin/sandbox.d.ts +4 -3
- package/dist/plugin/sandbox.d.ts.map +1 -1
- package/dist/plugin/sandbox.js +33 -6
- package/dist/plugin/sandbox.js.map +1 -1
- package/dist/plugin/semver.d.ts +26 -0
- package/dist/plugin/semver.d.ts.map +1 -0
- package/dist/plugin/semver.js +76 -0
- package/dist/plugin/semver.js.map +1 -0
- package/dist/plugin/testing.d.ts.map +1 -1
- package/dist/plugin/testing.js +2 -1
- package/dist/plugin/testing.js.map +1 -1
- package/dist/plugin/web.d.ts +10 -1
- package/dist/plugin/web.d.ts.map +1 -1
- package/dist/plugin/web.js +34 -0
- package/dist/plugin/web.js.map +1 -1
- package/dist/plugin.d.ts +3 -2
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +3 -2
- package/dist/plugin.js.map +1 -1
- package/dist/rules.d.ts +2 -2
- package/dist/rules.js +3 -3
- package/dist/schemas.d.ts +574 -11
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +154 -25
- package/dist/schemas.js.map +1 -1
- package/dist/use-action.d.ts +8 -2
- package/dist/use-action.d.ts.map +1 -1
- package/dist/use-action.js +13 -6
- package/dist/use-action.js.map +1 -1
- package/dist/vocabulary.d.ts +3 -1
- package/dist/vocabulary.d.ts.map +1 -1
- package/dist/vocabulary.js +3 -0
- package/dist/vocabulary.js.map +1 -1
- package/docs/specs/cli.md +4 -3
- package/docs/specs/plugins.md +49 -35
- package/docs/specs/rest.md +20 -18
- package/package.json +7 -7
- package/skills/building-a-plugin/SKILL.md +10 -9
- package/skills/planning-the-board/references/setting-up.md +2 -1
- package/skills/working-the-board/SKILL.md +3 -3
- package/src/api.ts +10 -0
- package/src/cli/cli.ts +162 -39
- package/src/cli/format.ts +54 -10
- package/src/cli/help.ts +23 -14
- package/src/cli/plugin-check.ts +68 -2
- package/src/cli/plugin-cli.ts +104 -6
- package/src/cli/plugin-init.ts +178 -3
- package/src/client.ts +36 -9
- package/src/compat.ts +1 -1
- package/src/components/board.tsx +3 -3
- package/src/components/comments.tsx +1 -0
- package/src/components/decision-form.tsx +166 -29
- package/src/components/decision-list.tsx +116 -15
- package/src/components/event-feed.tsx +7 -1
- package/src/components/goals.tsx +4 -1
- package/src/components/home.tsx +615 -0
- package/src/components/my-decisions.tsx +4 -1
- package/src/components/pack-connect.tsx +5 -4
- package/src/components/people.tsx +136 -54
- package/src/components/plugin-frame.tsx +62 -63
- package/src/components/plugin-settings.tsx +428 -87
- package/src/components/projects.tsx +0 -55
- package/src/components/task-view.tsx +9 -1
- package/src/components/ui.tsx +6 -2
- package/src/connect-page.tsx +5 -6
- package/src/console.tsx +98 -42
- package/src/data.ts +41 -11
- package/src/docs-page.tsx +6 -5
- package/src/home-tiles.ts +438 -0
- package/src/i18n/en.ts +185 -0
- package/src/i18n/index.ts +17 -14
- package/src/i18n/ko.ts +181 -3
- package/src/index.ts +7 -5
- package/src/limits.ts +8 -0
- package/src/plugin/bridge.ts +77 -1
- package/src/plugin/capabilities.ts +17 -1
- package/src/plugin/context.ts +24 -2
- package/src/plugin/define.ts +4 -1
- package/src/plugin/limits.ts +5 -2
- package/src/plugin/manifest.ts +154 -10
- package/src/plugin/rest-schemas.ts +27 -1
- package/src/plugin/sandbox.ts +36 -8
- package/src/plugin/semver.ts +89 -0
- package/src/plugin/testing.ts +2 -1
- package/src/plugin/web.ts +49 -0
- package/src/plugin.ts +18 -0
- package/src/rules.ts +3 -3
- package/src/schemas.ts +190 -28
- package/src/styles/console.css +764 -192
- package/src/use-action.ts +16 -7
- package/src/vocabulary.ts +4 -0
- package/template/plugin/console-plugin.json +3 -1
- package/template/plugin/package.json +3 -3
package/src/schemas.ts
CHANGED
|
@@ -16,9 +16,12 @@ import {
|
|
|
16
16
|
MAX_BODY_LENGTH,
|
|
17
17
|
MAX_CATEGORY_KEY_LENGTH,
|
|
18
18
|
MAX_CATEGORY_NAME_LENGTH,
|
|
19
|
+
MAX_DECIDERS,
|
|
19
20
|
MAX_DOCUMENT_LENGTH,
|
|
20
21
|
MAX_DOCUMENT_PATH_LENGTH,
|
|
21
22
|
MAX_FILE_NAME_LENGTH,
|
|
23
|
+
MAX_HOME_ROW,
|
|
24
|
+
MAX_HOME_TILES,
|
|
22
25
|
MAX_LANGUAGE_TAG_LENGTH,
|
|
23
26
|
MAX_LINK_LABEL_LENGTH,
|
|
24
27
|
MAX_LINKS,
|
|
@@ -42,6 +45,7 @@ import {
|
|
|
42
45
|
MAX_WORKERS,
|
|
43
46
|
MIN_OPTIONS,
|
|
44
47
|
} from "./limits.js";
|
|
48
|
+
import { PLUGIN_WIDGET_SIZE_NAMES } from "./plugin/manifest.js";
|
|
45
49
|
import { hasForbiddenCodePoint } from "./text.js";
|
|
46
50
|
import {
|
|
47
51
|
ARTIFACT_KINDS,
|
|
@@ -100,6 +104,14 @@ const day = z.iso.date();
|
|
|
100
104
|
const count = z.int().check(z.nonnegative());
|
|
101
105
|
|
|
102
106
|
/** A person of the workspace, as the pages show them. Nothing here is a secret. */
|
|
107
|
+
/** A language tag as a browser sends one (`en`, `ko-KR`). */
|
|
108
|
+
const languageTag = z
|
|
109
|
+
.string()
|
|
110
|
+
.check(
|
|
111
|
+
z.maxLength(MAX_LANGUAGE_TAG_LENGTH),
|
|
112
|
+
z.regex(/^[A-Za-z]{2,8}(?:-[A-Za-z0-9]{1,8})*$/, "must be a language tag"),
|
|
113
|
+
);
|
|
114
|
+
|
|
103
115
|
export const restPersonSchema = z.object({
|
|
104
116
|
id: uuid,
|
|
105
117
|
/** What the account is called at its provider: a login at the git host, an address at Google. */
|
|
@@ -116,6 +128,19 @@ export const restPersonSchema = z.object({
|
|
|
116
128
|
source: z.enum(MEMBERSHIP_SOURCES),
|
|
117
129
|
/** When they were deactivated, or `null`. */
|
|
118
130
|
deactivatedAt: z.nullable(instant),
|
|
131
|
+
/**
|
|
132
|
+
* The id of the person they report to, the reporting line of the directory an administrator
|
|
133
|
+
* keeps, or `null` for nobody; what a plugin reads as the default approver, the default
|
|
134
|
+
* assignee, in place of a line of its own. Answered from 0.4.4 and read as optional, so that
|
|
135
|
+
* a console built on this package still reads an older console's people.
|
|
136
|
+
*/
|
|
137
|
+
managerId: z.optional(z.nullable(uuid)),
|
|
138
|
+
/**
|
|
139
|
+
* The language the person reads in (ADR-0065), a tag: the one they chose, else the one the pages
|
|
140
|
+
* first saw them in; `null` until they have opened the pages. What a plugin or an agent writes
|
|
141
|
+
* for them in. Answered from 0.4.4 and read as optional, as `managerId` is.
|
|
142
|
+
*/
|
|
143
|
+
language: z.optional(z.nullable(languageTag)),
|
|
119
144
|
});
|
|
120
145
|
export type RestPerson = z.infer<typeof restPersonSchema>;
|
|
121
146
|
|
|
@@ -195,16 +220,59 @@ export const timeZoneName = z
|
|
|
195
220
|
z.regex(/^[A-Za-z0-9_+-]+(?:\/[A-Za-z0-9_+-]+)*$/, "must be a time zone name"),
|
|
196
221
|
);
|
|
197
222
|
|
|
198
|
-
/**
|
|
199
|
-
|
|
223
|
+
/** What `PATCH /api/v1/me` is sent: the language the person chose, or `null` to choose none. */
|
|
224
|
+
/** The sizes of a tile on the front page (ADR-0061): a project's icon, and the widgets' family. */
|
|
225
|
+
export const HOME_TILE_SIZES = ["icon", ...PLUGIN_WIDGET_SIZE_NAMES] as const;
|
|
226
|
+
|
|
227
|
+
/** A tile by what it is: a project by its id, a widget by its plugin's key and its own. */
|
|
228
|
+
const homeTileId = z
|
|
200
229
|
.string()
|
|
201
230
|
.check(
|
|
202
|
-
z.
|
|
203
|
-
|
|
231
|
+
z.regex(
|
|
232
|
+
/^(?:project:[0-9a-f-]{36}|widget:[a-z][a-z0-9-]{0,31}:[a-z][a-z0-9-]{0,31})$/,
|
|
233
|
+
"must name a project or a widget",
|
|
234
|
+
),
|
|
204
235
|
);
|
|
205
236
|
|
|
206
|
-
/**
|
|
207
|
-
export const
|
|
237
|
+
/** One tile of a person's own front page, at a place of the grid and at a size. */
|
|
238
|
+
export const restHomeTileSchema = z.object({
|
|
239
|
+
tile: homeTileId,
|
|
240
|
+
x: z.int().check(z.gte(0), z.lte(11)),
|
|
241
|
+
y: z.int().check(z.gte(0), z.lte(MAX_HOME_ROW)),
|
|
242
|
+
size: z.enum(HOME_TILE_SIZES),
|
|
243
|
+
});
|
|
244
|
+
export type RestHomeTile = z.infer<typeof restHomeTileSchema>;
|
|
245
|
+
|
|
246
|
+
const homeLayoutSchema = z.array(restHomeTileSchema).check(z.maxLength(MAX_HOME_TILES));
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* A person's own front page (ADR-0061): the tiles they took off it, which stay off, and what
|
|
250
|
+
* they arranged at each width of the grid, by its columns; what they have not seen yet takes
|
|
251
|
+
* the first room.
|
|
252
|
+
*/
|
|
253
|
+
export const restHomeSchema = z.object({
|
|
254
|
+
hidden: z.array(homeTileId).check(z.maxLength(MAX_HOME_TILES)),
|
|
255
|
+
layouts: z.object({
|
|
256
|
+
12: z.optional(homeLayoutSchema),
|
|
257
|
+
8: z.optional(homeLayoutSchema),
|
|
258
|
+
6: z.optional(homeLayoutSchema),
|
|
259
|
+
4: z.optional(homeLayoutSchema),
|
|
260
|
+
}),
|
|
261
|
+
});
|
|
262
|
+
export type RestHome = z.infer<typeof restHomeSchema>;
|
|
263
|
+
|
|
264
|
+
/** What `PATCH /api/v1/me` is sent: the language, the front page, either or both; `null` lets the console choose. */
|
|
265
|
+
export const restMePatchSchema = z
|
|
266
|
+
.object({
|
|
267
|
+
language: z.optional(z.nullable(languageTag)),
|
|
268
|
+
home: z.optional(z.nullable(restHomeSchema)),
|
|
269
|
+
})
|
|
270
|
+
.check(
|
|
271
|
+
z.refine(
|
|
272
|
+
(patch) => patch.language !== undefined || patch.home !== undefined,
|
|
273
|
+
"must name a language or the front page",
|
|
274
|
+
),
|
|
275
|
+
);
|
|
208
276
|
export type RestMePatch = z.infer<typeof restMePatchSchema>;
|
|
209
277
|
|
|
210
278
|
/**
|
|
@@ -274,8 +342,13 @@ export const restMeSchema = z.object({
|
|
|
274
342
|
* person's own knows it holds one. `null` on a session, and for nobody.
|
|
275
343
|
*/
|
|
276
344
|
agent: z.nullable(z.string()),
|
|
277
|
-
/** The language the person
|
|
345
|
+
/** The language the person reads in (ADR-0065): the one they chose, else the one the pages first saw them in; `null` until then. */
|
|
278
346
|
language: z.nullable(languageTag),
|
|
347
|
+
/**
|
|
348
|
+
* The person's own front page (ADR-0061), or `null` while they have arranged nothing; answered
|
|
349
|
+
* from 0.4.4 and read as optional.
|
|
350
|
+
*/
|
|
351
|
+
home: z.optional(z.nullable(restHomeSchema)),
|
|
279
352
|
signIn: z.array(restProviderSchema),
|
|
280
353
|
/**
|
|
281
354
|
* The console's version and the range of command versions it takes, as npm spells one
|
|
@@ -284,6 +357,13 @@ export const restMeSchema = z.object({
|
|
|
284
357
|
* built on this package still reads an older console's answer, and says it is older.
|
|
285
358
|
*/
|
|
286
359
|
console: z.optional(z.object({ version: z.string(), clientRange: z.string() })),
|
|
360
|
+
/**
|
|
361
|
+
* How many decisions wait for the person's answer across the projects they may see
|
|
362
|
+
* (ADR-0042), for the pages to say beside My decisions; `null` for nobody. Answered from
|
|
363
|
+
* 0.4.3 and read as optional, so that a console built on this package still reads an older
|
|
364
|
+
* console's answer.
|
|
365
|
+
*/
|
|
366
|
+
decisions: z.optional(z.nullable(z.object({ waiting: count }))),
|
|
287
367
|
});
|
|
288
368
|
export type RestMe = z.infer<typeof restMeSchema>;
|
|
289
369
|
|
|
@@ -306,11 +386,14 @@ export const restPersonPatchSchema = z
|
|
|
306
386
|
.object({
|
|
307
387
|
role: z.optional(z.enum(PERSON_ROLES)),
|
|
308
388
|
status: z.optional(z.enum(PERSON_STATUSES)),
|
|
389
|
+
/** Whom the person reports to: another active person of the workspace, or `null` for nobody. */
|
|
390
|
+
managerId: z.optional(z.nullable(uuid)),
|
|
309
391
|
})
|
|
310
392
|
.check(
|
|
311
393
|
z.refine(
|
|
312
|
-
(patch) =>
|
|
313
|
-
|
|
394
|
+
(patch) =>
|
|
395
|
+
patch.role !== undefined || patch.status !== undefined || patch.managerId !== undefined,
|
|
396
|
+
"must name a role, a status or a manager",
|
|
314
397
|
),
|
|
315
398
|
);
|
|
316
399
|
export type RestPersonPatch = z.infer<typeof restPersonPatchSchema>;
|
|
@@ -498,6 +581,8 @@ export const restTaskSchema = z.object({
|
|
|
498
581
|
owner: restPersonSchema,
|
|
499
582
|
/** The plugin that made it, by key (ADR-0052), or `null`; left out by a console older than the plugins. */
|
|
500
583
|
plugin: z.optional(z.nullable(z.string())),
|
|
584
|
+
/** The agent the task was written through, or `null` when a person wrote it themselves (ADR-0056); the owner may have changed since. Left out by an older console. */
|
|
585
|
+
agent: z.optional(z.nullable(z.string())),
|
|
501
586
|
/** The people at work on it (ADR-0037), in the order they came to it; `[]` while nobody is. */
|
|
502
587
|
workers: z.array(restPersonSchema),
|
|
503
588
|
/** The task this one is part of, or `null`. */
|
|
@@ -608,6 +693,8 @@ export const restGoalSchema = z.object({
|
|
|
608
693
|
/** The day the goal is meant to be reached by, or `null`. */
|
|
609
694
|
dueOn: z.nullable(day),
|
|
610
695
|
createdBy: restPersonSchema,
|
|
696
|
+
/** The agent the goal was set through, or `null` when a person set it themselves (ADR-0056); left out by an older console. */
|
|
697
|
+
agent: z.optional(z.nullable(z.string())),
|
|
611
698
|
/** The tasks that work towards it, counted by state. */
|
|
612
699
|
taskCounts: restTaskCountsSchema,
|
|
613
700
|
createdAt: instant,
|
|
@@ -643,10 +730,50 @@ export const restGoalPatchSchema = z.object({
|
|
|
643
730
|
});
|
|
644
731
|
export type RestGoalPatch = z.infer<typeof restGoalPatchSchema>;
|
|
645
732
|
|
|
733
|
+
/** A file a run handed in, as the console keeps it; its bytes are at `projectPath(key, "files", <artifact id>)`. */
|
|
734
|
+
export const restFileSchema = z.object({
|
|
735
|
+
/** What the agent called it: one line, without a path. */
|
|
736
|
+
name: z.string(),
|
|
737
|
+
/** In bytes. */
|
|
738
|
+
size: count,
|
|
739
|
+
/** The media type the agent said, or `application/octet-stream`. */
|
|
740
|
+
contentType: z.string(),
|
|
741
|
+
/** The SHA-256 of the bytes, in hex: what the console keeps them under. */
|
|
742
|
+
sha256: z.string(),
|
|
743
|
+
});
|
|
744
|
+
export type RestFile = z.infer<typeof restFileSchema>;
|
|
745
|
+
|
|
746
|
+
/** A file put on a decision when it was raised (ADR-0055), kept as a run's file is; its bytes are at `projectPath(key, "files", <id>)`. */
|
|
747
|
+
export const restDecisionFileSchema = z.object({
|
|
748
|
+
id: uuid,
|
|
749
|
+
file: restFileSchema,
|
|
750
|
+
});
|
|
751
|
+
export type RestDecisionFile = z.infer<typeof restDecisionFileSchema>;
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* The key a raiser may give an option, for a program to read the answer by instead of
|
|
755
|
+
* comparing labels: spelled as a plugin's key is.
|
|
756
|
+
*/
|
|
757
|
+
export const OPTION_KEY_PATTERN = /^[a-z][a-z0-9-]{1,31}$/;
|
|
758
|
+
const optionKey = z
|
|
759
|
+
.string()
|
|
760
|
+
.check(
|
|
761
|
+
z.regex(
|
|
762
|
+
OPTION_KEY_PATTERN,
|
|
763
|
+
"must be a key: a lowercase letter, then lowercase letters, digits and hyphens, 2 to 32 long",
|
|
764
|
+
),
|
|
765
|
+
);
|
|
766
|
+
|
|
646
767
|
export const restDecisionOptionSchema = z.object({
|
|
647
768
|
/** What an answer names: stable once given. */
|
|
648
769
|
id: z.string(),
|
|
649
770
|
label: z.string(),
|
|
771
|
+
/**
|
|
772
|
+
* The key the raiser gave the option, for a program to read the answer by (`optionKey` on the
|
|
773
|
+
* `decision.answered` event) without comparing labels; none on an option given without one,
|
|
774
|
+
* and none on the person's own answer.
|
|
775
|
+
*/
|
|
776
|
+
key: z.optional(z.string()),
|
|
650
777
|
/**
|
|
651
778
|
* On the one option a person's own answer became, when they answered in their own words
|
|
652
779
|
* instead of choosing (`POST .../answer` with `own`): added then, after the options given,
|
|
@@ -667,8 +794,15 @@ export const restDecisionSchema = z.object({
|
|
|
667
794
|
/** The task's number, when there is a task, or `null`. */
|
|
668
795
|
taskNumber: z.nullable(z.int()),
|
|
669
796
|
raisedBy: restPersonSchema,
|
|
670
|
-
/**
|
|
797
|
+
/** The first of those to answer (ADR-0042): the raiser, unless others of the project were named. */
|
|
671
798
|
decider: restPersonSchema,
|
|
799
|
+
/**
|
|
800
|
+
* Everyone the decision is addressed to (ADR-0057), `decider` first: each finds it among their
|
|
801
|
+
* decisions, any of them may answer, and the first answer ends it. Answered from 0.4.4 and read
|
|
802
|
+
* as optional, so that a console built on this package still reads an older console's
|
|
803
|
+
* decisions, where it is `[decider]`.
|
|
804
|
+
*/
|
|
805
|
+
deciders: z.optional(z.array(restPersonSchema)),
|
|
672
806
|
/** The run that raised it, as the agent asked, or `null` when a person did. */
|
|
673
807
|
run: z.nullable(z.object({ id: uuid, agent: z.string() })),
|
|
674
808
|
/** The plugin that raised it, by key (ADR-0052), or `null`; left out by a console older than the plugins. */
|
|
@@ -682,10 +816,31 @@ export const restDecisionSchema = z.object({
|
|
|
682
816
|
note: z.nullable(z.string()),
|
|
683
817
|
by: restPersonSchema,
|
|
684
818
|
at: instant,
|
|
819
|
+
/**
|
|
820
|
+
* The agent the answer came through, when the person's agent wrote it in their name
|
|
821
|
+
* (`console answer`, ADR-0021), or `null` when they answered themselves (ADR-0056).
|
|
822
|
+
* Answered from 0.4.4 and read as optional, so that a console built on this package still
|
|
823
|
+
* reads an older console's decisions.
|
|
824
|
+
*/
|
|
825
|
+
agent: z.optional(z.nullable(z.string())),
|
|
685
826
|
}),
|
|
686
827
|
),
|
|
687
828
|
/** What followed the decision, in Markdown, written afterwards; `null` until someone does. */
|
|
688
829
|
outcome: z.nullable(z.string()),
|
|
830
|
+
/**
|
|
831
|
+
* Who wrote what followed, the agent they wrote it through (`null` when themselves) and when
|
|
832
|
+
* (ADR-0056); each `null` until someone does. Answered from 0.4.4 and read as optional.
|
|
833
|
+
*/
|
|
834
|
+
outcomeBy: z.optional(z.nullable(restPersonSchema)),
|
|
835
|
+
outcomeAgent: z.optional(z.nullable(z.string())),
|
|
836
|
+
outcomeAt: z.optional(z.nullable(instant)),
|
|
837
|
+
/**
|
|
838
|
+
* The files put on it when it was raised (ADR-0055), in the order they came; a picture among
|
|
839
|
+
* them is shown where the context names it as ``, else after it. Answered
|
|
840
|
+
* from 0.4.3 and read as optional, so that a console built on this package still reads an
|
|
841
|
+
* older console's decisions.
|
|
842
|
+
*/
|
|
843
|
+
files: z.optional(z.array(restDecisionFileSchema)),
|
|
689
844
|
createdAt: instant,
|
|
690
845
|
updatedAt: instant,
|
|
691
846
|
});
|
|
@@ -742,18 +897,35 @@ export const restPersonWorkSchema = z.object({
|
|
|
742
897
|
});
|
|
743
898
|
export type RestPersonWork = z.infer<typeof restPersonWorkSchema>;
|
|
744
899
|
|
|
745
|
-
/**
|
|
900
|
+
/**
|
|
901
|
+
* What `POST /api/v1/projects/<key>/decisions` is sent: the question, its context, and the
|
|
902
|
+
* options. As JSON; or, with files put on the decision (ADR-0055), as the part `decision` of a
|
|
903
|
+
* form, with a part `file` for each file.
|
|
904
|
+
*/
|
|
746
905
|
export const restDecisionInputSchema = z.object({
|
|
747
906
|
question: line(MAX_QUESTION_LENGTH),
|
|
748
907
|
body: z.optional(body),
|
|
908
|
+
/** Each a label, and optionally a key a program reads the answer by, each key once. */
|
|
749
909
|
options: z
|
|
750
|
-
.array(z.object({ label: line(MAX_OPTION_LABEL_LENGTH) }))
|
|
751
|
-
.check(
|
|
910
|
+
.array(z.object({ label: line(MAX_OPTION_LABEL_LENGTH), key: z.optional(optionKey) }))
|
|
911
|
+
.check(
|
|
912
|
+
z.minLength(MIN_OPTIONS),
|
|
913
|
+
z.maxLength(MAX_OPTIONS),
|
|
914
|
+
z.refine((options) => {
|
|
915
|
+
const keys = options.flatMap((option) => (option.key === undefined ? [] : [option.key]));
|
|
916
|
+
return new Set(keys).size === keys.length;
|
|
917
|
+
}, "each key once"),
|
|
918
|
+
),
|
|
752
919
|
taskId: z.optional(z.nullable(uuid)),
|
|
753
920
|
/** The run that asks, when an agent does: the decision is about its task, and it waits for the answer. */
|
|
754
921
|
runId: z.optional(z.nullable(uuid)),
|
|
755
922
|
/** Who is to answer (ADR-0042): a person who may work in the project; the asker when left out. */
|
|
756
923
|
deciderId: z.optional(uuid),
|
|
924
|
+
/**
|
|
925
|
+
* Several to answer (ADR-0057), in place of `deciderId`: each a person who may work in the
|
|
926
|
+
* project, up to `MAX_DECIDERS`; any of them may answer, and the first answer ends the decision.
|
|
927
|
+
*/
|
|
928
|
+
deciderIds: z.optional(z.array(uuid).check(z.minLength(1), z.maxLength(MAX_DECIDERS))),
|
|
757
929
|
});
|
|
758
930
|
export type RestDecisionInput = z.infer<typeof restDecisionInputSchema>;
|
|
759
931
|
|
|
@@ -801,11 +973,14 @@ export const restEventDataSchema = z.object({
|
|
|
801
973
|
from: z.optional(z.enum(TASK_STATES)),
|
|
802
974
|
to: z.optional(z.enum(TASK_STATES)),
|
|
803
975
|
question: z.optional(z.string()),
|
|
804
|
-
/** For `decision.answered`: the label of the chosen option. */
|
|
976
|
+
/** For `decision.answered`: the label of the chosen option, and its key where the raiser gave one. */
|
|
805
977
|
option: z.optional(z.string()),
|
|
978
|
+
optionKey: z.optional(z.string()),
|
|
806
979
|
/** For `person.role_changed` and the events about a project's members: whose role, and what it became. */
|
|
807
980
|
login: z.optional(z.string()),
|
|
808
981
|
role: z.optional(z.string()),
|
|
982
|
+
/** For `person.manager_changed`: the login of whom the person reports to now, or `null` for nobody. */
|
|
983
|
+
manager: z.optional(z.nullable(z.string())),
|
|
809
984
|
/** For the events about a project: its key and its name. */
|
|
810
985
|
key: z.optional(z.string()),
|
|
811
986
|
name: z.optional(z.string()),
|
|
@@ -818,7 +993,7 @@ export const restEventDataSchema = z.object({
|
|
|
818
993
|
label: z.optional(z.string()),
|
|
819
994
|
/** For `run.reported` and `task.commented`: the first words of what was written. */
|
|
820
995
|
excerpt: z.optional(z.string()),
|
|
821
|
-
/** For `task.commented
|
|
996
|
+
/** For `task.commented`, and for `decision.raised` when any came: how many files came with it. */
|
|
822
997
|
files: z.optional(z.int()),
|
|
823
998
|
/** For `plugin.command`: the command, how it ended, the refusal's code where it was refused, how long it ran, and the arguments, a secret one as `[hidden]`. */
|
|
824
999
|
command: z.optional(z.string()),
|
|
@@ -867,19 +1042,6 @@ export const restReportSchema = z.object({
|
|
|
867
1042
|
});
|
|
868
1043
|
export type RestReport = z.infer<typeof restReportSchema>;
|
|
869
1044
|
|
|
870
|
-
/** A file a run handed in, as the console keeps it; its bytes are at `projectPath(key, "files", <artifact id>)`. */
|
|
871
|
-
export const restFileSchema = z.object({
|
|
872
|
-
/** What the agent called it: one line, without a path. */
|
|
873
|
-
name: z.string(),
|
|
874
|
-
/** In bytes. */
|
|
875
|
-
size: count,
|
|
876
|
-
/** The media type the agent said, or `application/octet-stream`. */
|
|
877
|
-
contentType: z.string(),
|
|
878
|
-
/** The SHA-256 of the bytes, in hex: what the console keeps them under. */
|
|
879
|
-
sha256: z.string(),
|
|
880
|
-
});
|
|
881
|
-
export type RestFile = z.infer<typeof restFileSchema>;
|
|
882
|
-
|
|
883
1045
|
/** What a run handed in: a link to a branch, a pull request, a page; or a file the console keeps. */
|
|
884
1046
|
export const restArtifactSchema = z.object({
|
|
885
1047
|
id: uuid,
|