@skillcdn/console 0.1.14 → 0.1.16

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 (165) hide show
  1. package/README.md +5 -4
  2. package/SKILLCDN.md +2 -0
  3. package/dist/agent-name.d.ts +3 -0
  4. package/dist/agent-name.d.ts.map +1 -0
  5. package/dist/agent-name.js +9 -0
  6. package/dist/agent-name.js.map +1 -0
  7. package/dist/api.d.ts +6 -4
  8. package/dist/api.d.ts.map +1 -1
  9. package/dist/api.js +6 -4
  10. package/dist/api.js.map +1 -1
  11. package/dist/cli/cli.d.ts +2 -0
  12. package/dist/cli/cli.d.ts.map +1 -1
  13. package/dist/cli/cli.js +225 -24
  14. package/dist/cli/cli.js.map +1 -1
  15. package/dist/cli/format.d.ts +14 -4
  16. package/dist/cli/format.d.ts.map +1 -1
  17. package/dist/cli/format.js +59 -10
  18. package/dist/cli/format.js.map +1 -1
  19. package/dist/cli/help.d.ts.map +1 -1
  20. package/dist/cli/help.js +28 -12
  21. package/dist/cli/help.js.map +1 -1
  22. package/dist/cli/main.js +5 -0
  23. package/dist/cli/main.js.map +1 -1
  24. package/dist/client.d.ts +20 -2
  25. package/dist/client.d.ts.map +1 -1
  26. package/dist/client.js +11 -2
  27. package/dist/client.js.map +1 -1
  28. package/dist/components/calendar.d.ts +35 -2
  29. package/dist/components/calendar.d.ts.map +1 -1
  30. package/dist/components/calendar.js +80 -31
  31. package/dist/components/calendar.js.map +1 -1
  32. package/dist/components/connect.d.ts +4 -1
  33. package/dist/components/connect.d.ts.map +1 -1
  34. package/dist/components/connect.js +7 -3
  35. package/dist/components/connect.js.map +1 -1
  36. package/dist/components/decision-list.d.ts.map +1 -1
  37. package/dist/components/decision-list.js +2 -2
  38. package/dist/components/decision-list.js.map +1 -1
  39. package/dist/components/documents.d.ts +5 -0
  40. package/dist/components/documents.d.ts.map +1 -1
  41. package/dist/components/documents.js +3 -2
  42. package/dist/components/documents.js.map +1 -1
  43. package/dist/components/event-feed.d.ts +1 -1
  44. package/dist/components/event-feed.d.ts.map +1 -1
  45. package/dist/components/event-feed.js +10 -1
  46. package/dist/components/event-feed.js.map +1 -1
  47. package/dist/components/people.d.ts +24 -1
  48. package/dist/components/people.d.ts.map +1 -1
  49. package/dist/components/people.js +35 -3
  50. package/dist/components/people.js.map +1 -1
  51. package/dist/components/projects.d.ts +10 -1
  52. package/dist/components/projects.d.ts.map +1 -1
  53. package/dist/components/projects.js +8 -5
  54. package/dist/components/projects.js.map +1 -1
  55. package/dist/components/rules.d.ts +40 -0
  56. package/dist/components/rules.d.ts.map +1 -0
  57. package/dist/components/rules.js +46 -0
  58. package/dist/components/rules.js.map +1 -0
  59. package/dist/components/runs.d.ts +1 -1
  60. package/dist/components/runs.d.ts.map +1 -1
  61. package/dist/components/runs.js +2 -1
  62. package/dist/components/runs.js.map +1 -1
  63. package/dist/components/skills.d.ts.map +1 -1
  64. package/dist/components/skills.js +5 -1
  65. package/dist/components/skills.js.map +1 -1
  66. package/dist/components/task-form.d.ts.map +1 -1
  67. package/dist/components/task-form.js +1 -1
  68. package/dist/components/task-form.js.map +1 -1
  69. package/dist/components/tokens.d.ts.map +1 -1
  70. package/dist/components/tokens.js +2 -9
  71. package/dist/components/tokens.js.map +1 -1
  72. package/dist/components/ui.d.ts +7 -2
  73. package/dist/components/ui.d.ts.map +1 -1
  74. package/dist/components/ui.js +13 -0
  75. package/dist/components/ui.js.map +1 -1
  76. package/dist/components/work.d.ts +5 -1
  77. package/dist/components/work.d.ts.map +1 -1
  78. package/dist/components/work.js +1 -1
  79. package/dist/components/work.js.map +1 -1
  80. package/dist/console.css +263 -17
  81. package/dist/console.d.ts.map +1 -1
  82. package/dist/console.js +197 -43
  83. package/dist/console.js.map +1 -1
  84. package/dist/data.d.ts +19 -2
  85. package/dist/data.d.ts.map +1 -1
  86. package/dist/data.js +27 -1
  87. package/dist/data.js.map +1 -1
  88. package/dist/i18n/en.d.ts +84 -9
  89. package/dist/i18n/en.d.ts.map +1 -1
  90. package/dist/i18n/en.js +84 -13
  91. package/dist/i18n/en.js.map +1 -1
  92. package/dist/i18n/ko.d.ts.map +1 -1
  93. package/dist/i18n/ko.js +84 -13
  94. package/dist/i18n/ko.js.map +1 -1
  95. package/dist/index.d.ts +4 -3
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +4 -3
  98. package/dist/index.js.map +1 -1
  99. package/dist/limits.d.ts +4 -0
  100. package/dist/limits.d.ts.map +1 -1
  101. package/dist/limits.js +4 -0
  102. package/dist/limits.js.map +1 -1
  103. package/dist/router.d.ts +30 -2
  104. package/dist/router.d.ts.map +1 -1
  105. package/dist/router.js +50 -10
  106. package/dist/router.js.map +1 -1
  107. package/dist/routes.d.ts +14 -4
  108. package/dist/routes.d.ts.map +1 -1
  109. package/dist/routes.js +17 -2
  110. package/dist/routes.js.map +1 -1
  111. package/dist/rules.d.ts +28 -0
  112. package/dist/rules.d.ts.map +1 -0
  113. package/dist/rules.js +102 -0
  114. package/dist/rules.js.map +1 -0
  115. package/dist/schemas.d.ts +652 -4
  116. package/dist/schemas.d.ts.map +1 -1
  117. package/dist/schemas.js +96 -6
  118. package/dist/schemas.js.map +1 -1
  119. package/dist/vocabulary.d.ts +21 -1
  120. package/dist/vocabulary.d.ts.map +1 -1
  121. package/dist/vocabulary.js +21 -0
  122. package/dist/vocabulary.js.map +1 -1
  123. package/docs/specs/cli.md +13 -9
  124. package/docs/specs/rest.md +33 -9
  125. package/package.json +1 -1
  126. package/skills/building-a-console/SKILL.md +1 -1
  127. package/skills/deploying-a-console/SKILL.md +5 -5
  128. package/skills/deploying-a-console/assets/secrets.example.json +2 -1
  129. package/skills/deploying-a-console/references/access.md +10 -6
  130. package/skills/deploying-a-console/references/resources.md +10 -7
  131. package/skills/working-the-board/SKILL.md +10 -9
  132. package/skills/working-the-board/references/project-rules.md +36 -0
  133. package/src/agent-name.ts +9 -0
  134. package/src/api.ts +37 -0
  135. package/src/cli/cli.ts +264 -26
  136. package/src/cli/format.ts +74 -10
  137. package/src/cli/help.ts +31 -11
  138. package/src/cli/main.ts +5 -0
  139. package/src/client.ts +47 -1
  140. package/src/components/calendar.tsx +252 -51
  141. package/src/components/connect.tsx +12 -6
  142. package/src/components/decision-list.tsx +2 -1
  143. package/src/components/documents.tsx +7 -3
  144. package/src/components/event-feed.tsx +16 -3
  145. package/src/components/people.tsx +244 -35
  146. package/src/components/projects.tsx +37 -14
  147. package/src/components/rules.tsx +167 -0
  148. package/src/components/runs.tsx +4 -2
  149. package/src/components/skills.tsx +22 -10
  150. package/src/components/task-form.tsx +1 -0
  151. package/src/components/tokens.tsx +2 -14
  152. package/src/components/ui.tsx +25 -2
  153. package/src/components/work.tsx +34 -28
  154. package/src/console.tsx +524 -45
  155. package/src/data.ts +52 -2
  156. package/src/i18n/en.ts +94 -14
  157. package/src/i18n/ko.ts +90 -14
  158. package/src/index.ts +16 -1
  159. package/src/limits.ts +4 -0
  160. package/src/router.ts +67 -12
  161. package/src/routes.ts +23 -3
  162. package/src/rules.ts +109 -0
  163. package/src/schemas.ts +121 -4
  164. package/src/styles/console.css +263 -17
  165. package/src/vocabulary.ts +30 -0
package/src/cli/help.ts CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  MAX_PROJECT_SYMBOL_LENGTH,
21
21
  MAX_QUESTION_LENGTH,
22
22
  MAX_REPORTS_PER_RUN,
23
+ MAX_RULES_LENGTH,
23
24
  MAX_SUMMARY_LENGTH,
24
25
  MAX_TITLE_LENGTH,
25
26
  MAX_VERSIONS_PER_DOCUMENT,
@@ -83,7 +84,7 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
83
84
  login: {
84
85
  usage: "login --url <origin> [--agent <name>] [--token-stdin]",
85
86
  about:
86
- "Connects this agent to the console: shows an address and a code, which a person opens signed in, names the agent and approves; the command then receives a token of its own and keeps it, with the console's address, in your home directory, never showing it. An agent running the command relays the address and the code to its person and waits. --agent says what the agent calls itself. --token-stdin reads a token made by hand from standard input instead, for a script or a job.",
87
+ "Connects this agent to the console: shows an address and a code, which a person opens signed in, names the agent and approves; the command then receives a token of its own and keeps it, with the console's address, in your home directory, never showing it. An agent running the command relays the address and the code to its person and waits. --agent says what the agent calls itself; left out, the command names the agent it runs under where its environment says so (Claude Code, Codex), else An agent; the machine's name follows, and the pages show the name before 'on' with the whole on hover. --token-stdin reads a token made by hand from standard input instead, for a script or a job.",
87
88
  refusals: [
88
89
  "connect.not_found: the code was not approved in time, or the person said it was not theirs; run login again",
89
90
  "the console does not know the token given: make one on the Agents page and try again",
@@ -92,7 +93,7 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
92
93
  logout: {
93
94
  usage: "logout",
94
95
  about:
95
- "Forgets the address and the token kept here. The token itself is removed on the Agents page.",
96
+ "Signs this agent out: gives the token up at the console, so that it is good for nothing from now on, and forgets it with the address kept here. A console out of reach leaves the token to the Agents page.",
96
97
  },
97
98
  whoami: {
98
99
  usage: "whoami",
@@ -111,9 +112,9 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
111
112
  refusals: ["project.not_found: no project has the key, or it is not yours to see"],
112
113
  },
113
114
  work: {
114
- usage: "work",
115
+ usage: "work [--person <login>]",
115
116
  about:
116
- "What is on your plate across the projects you may see: the open tasks assigned to you, the sooner due first, each with its project; and the decisions waiting for a person. Needs no project.",
117
+ "What is on your plate across the projects you may see: the open tasks assigned to you, the sooner due first, each with its project; and the decisions waiting for a person. Needs no project. --person <login> shows another person's plate, for an administrator or for an owner of a project they are in: their open tasks within the projects you may see, without the decisions, which wait for anyone.",
117
118
  },
118
119
  tasks: {
119
120
  usage:
@@ -125,7 +126,7 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
125
126
  about:
126
127
  "One task in full, with its plan (category, goal, start and due days), what happened to it (when it was started and done, which the board keeps itself), the decisions about it and the runs on it; or a new task written down; or a task changed, only in what the flags say, where none clears a field (priorities: low, normal, high, urgent).",
127
128
  limits: [
128
- `title: one line, up to ${MAX_TITLE_LENGTH} characters`,
129
+ `title: one line, up to ${MAX_TITLE_LENGTH} characters, saying what is to be done on its own; what it refers to goes in the body`,
129
130
  `body: ${MARKDOWN}`,
130
131
  ...TASK_FIELD_LIMITS,
131
132
  ],
@@ -159,15 +160,19 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
159
160
  people: {
160
161
  usage: "people",
161
162
  about:
162
- "Everyone of the workspace, by login, with their name where the host gives one and what they are in it: admin, who configures the workspace, or member, who works in the projects they are in. The logins are what --assignee, member and person role take.",
163
+ "Everyone of the workspace, by login, with their name where the host gives one and what they are in it: admin, who configures the workspace, or member, who works in the projects they are in; a person taken out is marked deactivated. Then the logins an administrator let in that nobody has signed in with yet. The logins are what --assignee, member and person take.",
163
164
  },
164
165
  person: {
165
- usage: "person role <login> <admin|member>",
166
+ usage:
167
+ "person role <login> <admin|member> | person add <login> [--host gh|google] | person remove <login> | person deactivate <login> | person reactivate <login>",
166
168
  about:
167
- "Says what a person is in the workspace, for an administrator: the person themselves on the People page, or their agent here, named on it. The board keeps at least one administrator.",
169
+ "For an administrator: the person themselves on the People page, or their agent here, named on it. role says what a person is in the workspace; the board keeps at least one administrator in. add lets a login in: whoever signs in with that account at that host is a person from then on; the host is read off the login (an address is Google's, anything else GitHub's) unless --host says. remove takes a login away that nobody has signed in with yet. deactivate takes a person out: refused on every request at once, their agents with them, kept with everything they did, and listed nowhere; reactivate takes them back in. A person the organization let in comes and goes with it, and is neither.",
168
170
  refusals: [
169
- "auth.forbidden: only an administrator says what a person is",
170
- "person.last_admin: the board keeps at least one administrator; make another one first",
171
+ "auth.forbidden: only an administrator says who is in and what they are",
172
+ "person.last_admin: the board keeps at least one administrator in; make another one first",
173
+ "person.of_organization: the organization says whether that person is in",
174
+ "listing.exists: the login is let in already, or is a person's who is in",
175
+ "listing.unknown_host: nobody signs in through that provider here",
171
176
  ],
172
177
  },
173
178
  project: {
@@ -228,7 +233,20 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
228
233
  skills: {
229
234
  usage: "skills",
230
235
  about:
231
- "The organization's skills, as SkillCDN serves them at the console's address: each with its description and the URI you load it by through your own SkillCDN connection. --json adds the page of each, for a person.",
236
+ "The organization's skills, as SkillCDN serves them at the project's address: each with its description and the URI you load it by through your own SkillCDN connection, which a person makes at the address's page when you have none; and where the console's own skills are on this machine. --json adds the page of each, for a person.",
237
+ },
238
+ rules: {
239
+ usage:
240
+ "rules | rules write --body <markdown>|--file <path>|-|none [--workspace] [--base <version>]",
241
+ about:
242
+ "What this organization asks of agents (ADR-0023): the workspace's rules, the console's own until an administrator writes the organization's, and this project's own when it has them. Read them before taking a task; take prints them again. rules write writes this project's rules, for an owner, or with --workspace the workspace's, for an administrator; none puts the written rules away, so that the console's own hold again, or the project adds none. Without a project named, rules shows the workspace's alone.",
243
+ limits: [
244
+ `body: Markdown, up to ${MAX_RULES_LENGTH} characters; the console's own rules, written as they are, write nothing`,
245
+ ],
246
+ refusals: [
247
+ "auth.forbidden: an owner writes a project's rules, an administrator the workspace's",
248
+ "document.conflict: the rules have moved on since --base; read them again",
249
+ ],
232
250
  },
233
251
  take: {
234
252
  usage: "take <number|id> [--agent <name>]",
@@ -384,6 +402,7 @@ export const COMMAND_HELP: Readonly<Record<string, CommandHelp>> = {
384
402
  const preamble = (version: string | undefined): string =>
385
403
  `console${version === undefined ? "" : ` ${version}`}: the board of your organization's work with AI agents, from the command line.
386
404
  You act as the person whose token you hold; everything you send is shown to people as text.
405
+ The rules of this organization come with the task: console take prints them; console rules reads them any time.
387
406
 
388
407
  Usage: console <command> [arguments] [--json] [--url <origin>] [--project <key>]
389
408
  `;
@@ -425,6 +444,7 @@ const SECTIONS: readonly { readonly title: string; readonly commands: readonly s
425
444
  "runs",
426
445
  "run",
427
446
  "skills",
447
+ "rules",
428
448
  ],
429
449
  },
430
450
  { title: "Working", commands: ["take", "report", "hand-in", "ask", "finish", "fail", "abandon"] },
package/src/cli/main.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
2
3
  import { createRequire } from "node:module";
3
4
  import { hostname } from "node:os";
4
5
  import process from "node:process";
6
+ import { fileURLToPath } from "node:url";
5
7
  import * as z from "zod/mini";
6
8
  import { runCli } from "./cli.js";
7
9
  import { createFileStore, defaultConfigDir } from "./credentials.js";
@@ -16,6 +18,8 @@ import { readBytesAt, readFileAt, readStdin } from "./terminal.js";
16
18
  const manifest = z
17
19
  .object({ version: z.string() })
18
20
  .safeParse(createRequire(import.meta.url)("../../package.json"));
21
+ /** The console's own skills, shipped with the package beside dist/ (ADR-0015); not there in a checkout before packing. */
22
+ const skillsDir = fileURLToPath(new URL("../../skills/", import.meta.url));
19
23
 
20
24
  process.exitCode = await runCli(process.argv.slice(2), {
21
25
  env: process.env,
@@ -35,5 +39,6 @@ process.exitCode = await runCli(process.argv.slice(2), {
35
39
  sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
36
40
  now: () => Date.now(),
37
41
  version: manifest.success ? manifest.data.version : undefined,
42
+ skillsDir: existsSync(skillsDir) ? skillsDir : undefined,
38
43
  listen: listenOn,
39
44
  });
package/src/client.ts CHANGED
@@ -4,9 +4,11 @@ import {
4
4
  categoryPath,
5
5
  connectPath,
6
6
  personTokensPath,
7
+ personWorkPath,
7
8
  projectPath,
8
9
  REST_ROUTES,
9
10
  restPath,
11
+ rulesPath,
10
12
  } from "./routes.js";
11
13
  import {
12
14
  type RestAnswerInput,
@@ -31,6 +33,8 @@ import {
31
33
  type RestGoalInput,
32
34
  type RestGoalPatch,
33
35
  type RestGoals,
36
+ type RestListing,
37
+ type RestListingInput,
34
38
  type RestMe,
35
39
  type RestMember,
36
40
  type RestMemberInput,
@@ -40,11 +44,15 @@ import {
40
44
  type RestPeople,
41
45
  type RestPerson,
42
46
  type RestPersonPatch,
47
+ type RestPersonWork,
43
48
  type RestProject,
44
49
  type RestProjectInput,
45
50
  type RestProjectPatch,
51
+ type RestProjectRules,
46
52
  type RestProjects,
47
53
  type RestReportInput,
54
+ type RestRules,
55
+ type RestRulesInput,
48
56
  type RestRun,
49
57
  type RestRunEndInput,
50
58
  type RestRunInput,
@@ -73,13 +81,17 @@ import {
73
81
  restEventsSchema,
74
82
  restGoalSchema,
75
83
  restGoalsSchema,
84
+ restListingSchema,
76
85
  restMemberSchema,
77
86
  restMembersSchema,
78
87
  restMeSchema,
79
88
  restPeopleSchema,
80
89
  restPersonSchema,
90
+ restPersonWorkSchema,
91
+ restProjectRulesSchema,
81
92
  restProjectSchema,
82
93
  restProjectsSchema,
94
+ restRulesSchema,
83
95
  restRunSchema,
84
96
  restRunsSchema,
85
97
  restSkillsSchema,
@@ -243,6 +255,8 @@ export interface ProjectClient {
243
255
  eventStreamUrl(after: number): string;
244
256
  /** The project's skills, as SkillCDN serves them at its address, or the organization's. */
245
257
  skills(signal?: AbortSignal): Promise<RestSkills>;
258
+ /** The rules that hold in the project (ADR-0023): the workspace's, and what the project adds. */
259
+ rules(signal?: AbortSignal): Promise<RestProjectRules>;
246
260
  /** A folder's pages and folders, or the pages a search finds. */
247
261
  documents(filter?: DocumentFilter, signal?: AbortSignal): Promise<RestDocuments>;
248
262
  /** One document, by its path: its latest version, its links both ways, its files. */
@@ -271,11 +285,17 @@ export interface ProjectClient {
271
285
 
272
286
  export interface ConsoleClient {
273
287
  me(signal?: AbortSignal): Promise<RestMe>;
288
+ /** Gives up the token this client acts with, so that it is good for nothing from now on: what `console logout` does. For a token; a session has none. */
289
+ giveUpToken(): Promise<void>;
274
290
  /** Keeps the person's choice of language, or none; for a person signed in. */
275
291
  updateMe(patch: RestMePatch): Promise<RestMe>;
276
292
  people(signal?: AbortSignal): Promise<RestPeople>;
277
- /** Changes what a person is; for an administrator. */
293
+ /** Changes what a person is, or whether they are in; for an administrator. */
278
294
  updatePerson(id: string, patch: RestPersonPatch): Promise<RestPerson>;
295
+ /** Lets a login in (ADR-0022): whoever signs in with that account becomes a person; for an administrator. */
296
+ createListing(input: RestListingInput): Promise<RestListing>;
297
+ /** Takes a listing away before anyone signed in with it; for an administrator. */
298
+ removeListing(id: string): Promise<void>;
279
299
  /** The projects the asker may see, with what they are in each. */
280
300
  projects(signal?: AbortSignal): Promise<RestProjects>;
281
301
  /** Makes a project, whose owner the asker becomes. */
@@ -286,6 +306,14 @@ export interface ConsoleClient {
286
306
  events(after: number, signal?: AbortSignal): Promise<RestEvents>;
287
307
  /** The categories tasks are sorted into (ADR-0019), by name. */
288
308
  categories(signal?: AbortSignal): Promise<RestCategories>;
309
+ /** The workspace's rules (ADR-0023): the console's own until an administrator writes the organization's. */
310
+ rules(signal?: AbortSignal): Promise<RestRules>;
311
+ /** Writes the organization's rules; for an administrator. The console's own, sent as they are, write nothing. */
312
+ writeRules(input: RestRulesInput): Promise<RestRules>;
313
+ /** Puts the organization's rules away, so that the console's own hold again; for an administrator. */
314
+ archiveRules(): Promise<RestRules>;
315
+ /** The versions of the organization's rules, newest first; none while the console's own hold. */
316
+ rulesVersions(signal?: AbortSignal): Promise<RestVersions>;
289
317
  /** Makes a category; for an administrator signed in. */
290
318
  createCategory(input: RestCategoryInput): Promise<RestCategory>;
291
319
  updateCategory(key: string, patch: RestCategoryPatch): Promise<RestCategory>;
@@ -293,6 +321,8 @@ export interface ConsoleClient {
293
321
  removeCategory(key: string): Promise<void>;
294
322
  /** What is on the asker's plate across the projects they may see: their open tasks, and the decisions waiting. */
295
323
  work(signal?: AbortSignal): Promise<RestWork>;
324
+ /** Another person's plate, within what the asker may see: for an administrator, or an owner of a project they are in. */
325
+ personWork(personId: string, signal?: AbortSignal): Promise<RestPersonWork>;
296
326
  /** The tokens of whoever asks. */
297
327
  tokens(signal?: AbortSignal): Promise<RestTokens>;
298
328
  /** The tokens of another person: for an administrator. */
@@ -520,6 +550,8 @@ export function createClient(options: ClientOptions = {}): ConsoleClient {
520
550
  eventStreamUrl: (after) => withQuery(`${at("events")}/stream`, { after: String(after) }),
521
551
  skills: (signal) =>
522
552
  request("GET", `${base}${at("skills")}`, undefined, restSkillsSchema, signal),
553
+ rules: (signal) =>
554
+ request("GET", `${base}${at("rules")}`, undefined, restProjectRulesSchema, signal),
523
555
  documents: (filter = {}, signal) =>
524
556
  request(
525
557
  "GET",
@@ -572,10 +604,15 @@ export function createClient(options: ClientOptions = {}): ConsoleClient {
572
604
 
573
605
  return {
574
606
  me: (signal) => request("GET", `${base}${REST_ROUTES.me}`, undefined, restMeSchema, signal),
607
+ giveUpToken: () => request("DELETE", `${base}${REST_ROUTES.meToken}`, undefined, undefined),
575
608
  people: (signal) =>
576
609
  request("GET", `${base}${REST_ROUTES.people}`, undefined, restPeopleSchema, signal),
577
610
  updatePerson: (id, patch) =>
578
611
  request("PATCH", `${base}${restPath("people", id)}`, patch, restPersonSchema),
612
+ createListing: (input) =>
613
+ request("POST", `${base}${REST_ROUTES.listings}`, input, restListingSchema),
614
+ removeListing: (id) =>
615
+ request("DELETE", `${base}${restPath("listings", id)}`, undefined, undefined),
579
616
  projects: (signal) =>
580
617
  request("GET", `${base}${REST_ROUTES.projects}`, undefined, restProjectsSchema, signal),
581
618
  createProject: (input) =>
@@ -591,6 +628,13 @@ export function createClient(options: ClientOptions = {}): ConsoleClient {
591
628
  ),
592
629
  categories: (signal) =>
593
630
  request("GET", `${base}${REST_ROUTES.categories}`, undefined, restCategoriesSchema, signal),
631
+ rules: (signal) =>
632
+ request("GET", `${base}${REST_ROUTES.rules}`, undefined, restRulesSchema, signal),
633
+ writeRules: (input) => request("PUT", `${base}${REST_ROUTES.rules}`, input, restRulesSchema),
634
+ archiveRules: () =>
635
+ request("POST", `${base}${rulesPath("archive")}`, undefined, restRulesSchema),
636
+ rulesVersions: (signal) =>
637
+ request("GET", `${base}${rulesPath("versions")}`, undefined, restVersionsSchema, signal),
594
638
  createCategory: (input) =>
595
639
  request("POST", `${base}${REST_ROUTES.categories}`, input, restCategorySchema),
596
640
  updateCategory: (key, patch) =>
@@ -598,6 +642,8 @@ export function createClient(options: ClientOptions = {}): ConsoleClient {
598
642
  removeCategory: (key) => request("DELETE", `${base}${categoryPath(key)}`, undefined, undefined),
599
643
  work: (signal) =>
600
644
  request("GET", `${base}${REST_ROUTES.work}`, undefined, restWorkSchema, signal),
645
+ personWork: (personId, signal) =>
646
+ request("GET", `${base}${personWorkPath(personId)}`, undefined, restPersonWorkSchema, signal),
601
647
  tokens: (signal) =>
602
648
  request("GET", `${base}${REST_ROUTES.tokens}`, undefined, restTokensSchema, signal),
603
649
  createToken: (input) =>