@skillcdn/console 0.1.13 → 0.1.15

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 (170) 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 +215 -22
  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 +27 -11
  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 +15 -0
  29. package/dist/components/calendar.d.ts.map +1 -1
  30. package/dist/components/calendar.js +78 -41
  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 +3 -3
  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 +6 -0
  52. package/dist/components/projects.d.ts.map +1 -1
  53. package/dist/components/projects.js +3 -3
  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/tokens.d.ts.map +1 -1
  67. package/dist/components/tokens.js +2 -9
  68. package/dist/components/tokens.js.map +1 -1
  69. package/dist/components/ui.d.ts +7 -2
  70. package/dist/components/ui.d.ts.map +1 -1
  71. package/dist/components/ui.js +13 -0
  72. package/dist/components/ui.js.map +1 -1
  73. package/dist/components/work.d.ts +9 -1
  74. package/dist/components/work.d.ts.map +1 -1
  75. package/dist/components/work.js +8 -3
  76. package/dist/components/work.js.map +1 -1
  77. package/dist/connect-page.d.ts.map +1 -1
  78. package/dist/connect-page.js +1 -1
  79. package/dist/connect-page.js.map +1 -1
  80. package/dist/console.css +253 -13
  81. package/dist/console.d.ts.map +1 -1
  82. package/dist/console.js +203 -49
  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/dates.d.ts +4 -0
  89. package/dist/dates.d.ts.map +1 -1
  90. package/dist/dates.js +26 -0
  91. package/dist/dates.js.map +1 -1
  92. package/dist/i18n/en.d.ts +90 -28
  93. package/dist/i18n/en.d.ts.map +1 -1
  94. package/dist/i18n/en.js +89 -31
  95. package/dist/i18n/en.js.map +1 -1
  96. package/dist/i18n/ko.d.ts.map +1 -1
  97. package/dist/i18n/ko.js +89 -31
  98. package/dist/i18n/ko.js.map +1 -1
  99. package/dist/index.d.ts +6 -5
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +6 -5
  102. package/dist/index.js.map +1 -1
  103. package/dist/limits.d.ts +4 -0
  104. package/dist/limits.d.ts.map +1 -1
  105. package/dist/limits.js +4 -0
  106. package/dist/limits.js.map +1 -1
  107. package/dist/router.d.ts +34 -2
  108. package/dist/router.d.ts.map +1 -1
  109. package/dist/router.js +55 -7
  110. package/dist/router.js.map +1 -1
  111. package/dist/routes.d.ts +14 -4
  112. package/dist/routes.d.ts.map +1 -1
  113. package/dist/routes.js +17 -2
  114. package/dist/routes.js.map +1 -1
  115. package/dist/rules.d.ts +28 -0
  116. package/dist/rules.d.ts.map +1 -0
  117. package/dist/rules.js +102 -0
  118. package/dist/rules.js.map +1 -0
  119. package/dist/schemas.d.ts +652 -4
  120. package/dist/schemas.d.ts.map +1 -1
  121. package/dist/schemas.js +96 -6
  122. package/dist/schemas.js.map +1 -1
  123. package/dist/vocabulary.d.ts +21 -1
  124. package/dist/vocabulary.d.ts.map +1 -1
  125. package/dist/vocabulary.js +21 -0
  126. package/dist/vocabulary.js.map +1 -1
  127. package/docs/specs/cli.md +13 -9
  128. package/docs/specs/rest.md +32 -8
  129. package/package.json +1 -1
  130. package/skills/building-a-console/SKILL.md +1 -1
  131. package/skills/deploying-a-console/SKILL.md +5 -5
  132. package/skills/deploying-a-console/assets/secrets.example.json +2 -1
  133. package/skills/deploying-a-console/references/access.md +10 -6
  134. package/skills/deploying-a-console/references/resources.md +10 -7
  135. package/skills/working-the-board/SKILL.md +10 -9
  136. package/skills/working-the-board/references/project-rules.md +36 -0
  137. package/src/agent-name.ts +9 -0
  138. package/src/api.ts +37 -0
  139. package/src/cli/cli.ts +253 -24
  140. package/src/cli/format.ts +74 -10
  141. package/src/cli/help.ts +30 -10
  142. package/src/cli/main.ts +5 -0
  143. package/src/client.ts +47 -1
  144. package/src/components/calendar.tsx +242 -101
  145. package/src/components/connect.tsx +12 -6
  146. package/src/components/decision-list.tsx +2 -2
  147. package/src/components/documents.tsx +7 -3
  148. package/src/components/event-feed.tsx +16 -3
  149. package/src/components/people.tsx +244 -35
  150. package/src/components/projects.tsx +31 -8
  151. package/src/components/rules.tsx +167 -0
  152. package/src/components/runs.tsx +4 -2
  153. package/src/components/skills.tsx +22 -11
  154. package/src/components/tokens.tsx +2 -14
  155. package/src/components/ui.tsx +25 -2
  156. package/src/components/work.tsx +69 -43
  157. package/src/connect-page.tsx +0 -1
  158. package/src/console.tsx +531 -67
  159. package/src/data.ts +52 -2
  160. package/src/dates.ts +28 -0
  161. package/src/i18n/en.ts +99 -38
  162. package/src/i18n/ko.ts +95 -38
  163. package/src/index.ts +21 -1
  164. package/src/limits.ts +4 -0
  165. package/src/router.ts +77 -12
  166. package/src/routes.ts +23 -3
  167. package/src/rules.ts +109 -0
  168. package/src/schemas.ts +121 -4
  169. package/src/styles/console.css +253 -13
  170. package/src/vocabulary.ts +30 -0
package/src/data.ts CHANGED
@@ -20,16 +20,23 @@ import {
20
20
  type RestGoal,
21
21
  type RestGoalInput,
22
22
  type RestGoalPatch,
23
+ type RestListing,
24
+ type RestListingInput,
23
25
  type RestMe,
24
26
  type RestMember,
25
27
  type RestMemberInput,
26
28
  type RestMemberPatch,
27
29
  type RestMePatch,
30
+ type RestOrganization,
28
31
  type RestPerson,
29
32
  type RestPersonPatch,
33
+ type RestPersonWork,
30
34
  type RestProject,
31
35
  type RestProjectInput,
32
36
  type RestProjectPatch,
37
+ type RestProjectRules,
38
+ type RestRules,
39
+ type RestRulesInput,
33
40
  type RestRun,
34
41
  type RestSkills,
35
42
  type RestTask,
@@ -83,6 +90,12 @@ export interface ConsoleActions {
83
90
  createCategory(input: RestCategoryInput): Promise<RestCategory>;
84
91
  updateCategory(key: string, patch: RestCategoryPatch): Promise<RestCategory>;
85
92
  removeCategory(key: string): Promise<void>;
93
+ /** The workspace's rules (ADR-0023), read when the page asks; written and put away by an administrator. */
94
+ rules(signal?: AbortSignal): Promise<RestRules>;
95
+ writeRules(input: RestRulesInput): Promise<RestRules>;
96
+ archiveRules(): Promise<RestRules>;
97
+ /** The rules that hold in the project the page is on: the workspace's, and what the project adds. */
98
+ projectRules(signal?: AbortSignal): Promise<RestProjectRules>;
86
99
  /** A folder's pages and folders, or the pages a search finds, in the project the page is on. */
87
100
  documents(filter?: DocumentFilter, signal?: AbortSignal): Promise<RestDocuments>;
88
101
  document(path: string, signal?: AbortSignal): Promise<RestDocument>;
@@ -92,8 +105,12 @@ export interface ConsoleActions {
92
105
  documentVersions(path: string, signal?: AbortSignal): Promise<RestVersions>;
93
106
  documentVersion(path: string, number: number, signal?: AbortSignal): Promise<RestVersion>;
94
107
  attachDocumentFile(path: string, input: FileUpload): Promise<RestDocument>;
95
- /** Changes what a person is; for an administrator. */
108
+ /** Changes what a person is, or whether they are in; for an administrator. */
96
109
  updatePerson(id: string, patch: RestPersonPatch): Promise<RestPerson>;
110
+ /** Lets a login in (ADR-0022); for an administrator. */
111
+ createListing(input: RestListingInput): Promise<RestListing>;
112
+ /** Takes a listing away that nobody signed in with; for an administrator. */
113
+ removeListing(id: string): Promise<void>;
97
114
  /** Keeps the person's own choice of language (ADR-0012). */
98
115
  updateMe(patch: RestMePatch): Promise<RestMe>;
99
116
  /** Marks a run that will not come back as abandoned. */
@@ -107,6 +124,8 @@ export interface ConsoleActions {
107
124
  connectRequest(code: string, signal?: AbortSignal): Promise<RestConnectRequest>;
108
125
  approveConnection(code: string, input: RestTokenInput): Promise<RestConnectRequest>;
109
126
  denyConnection(code: string): Promise<void>;
127
+ /** Another person's plate: for an administrator, or an owner of a project they are in. */
128
+ personWork(personId: string, signal?: AbortSignal): Promise<RestPersonWork>;
110
129
  /** The tokens of another person, and the way to take one away: for an administrator. */
111
130
  personTokens(personId: string, signal?: AbortSignal): Promise<RestTokens>;
112
131
  revokePersonToken(personId: string, tokenId: string): Promise<void>;
@@ -122,7 +141,12 @@ export interface ConsoleData {
122
141
  readonly loaded: boolean;
123
142
  /** The projects the person may see, by name. */
124
143
  readonly projects: readonly RestProject[];
144
+ /** Everyone of the workspace, those in first, the deactivated last (ADR-0022). */
125
145
  readonly people: readonly RestPerson[];
146
+ /** The logins let in that nobody has signed in with yet. */
147
+ readonly listed: readonly RestListing[];
148
+ /** The organization at the git host that says who is in, where the deployment names one. */
149
+ readonly organization: RestOrganization | null;
126
150
  /** The categories tasks are sorted into, by name. */
127
151
  readonly categories: readonly RestCategory[];
128
152
  /** The tokens of whoever is signed in, newest first. */
@@ -184,6 +208,8 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
184
208
  const [loaded, setLoaded] = useState(false);
185
209
  const [projects, setProjects] = useState<readonly RestProject[]>([]);
186
210
  const [people, setPeople] = useState<readonly RestPerson[]>([]);
211
+ const [listed, setListed] = useState<readonly RestListing[]>([]);
212
+ const [organization, setOrganization] = useState<RestOrganization | null>(null);
187
213
  const [categories, setCategories] = useState<readonly RestCategory[]>([]);
188
214
  const [tokens, setTokens] = useState<readonly RestToken[]>([]);
189
215
  const [project, setProject] = useState<RestProject | undefined>(undefined);
@@ -216,6 +242,8 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
216
242
  }
217
243
  setProjects(nextProjects.items);
218
244
  setPeople(nextPeople.items);
245
+ setListed(nextPeople.listed);
246
+ setOrganization(nextPeople.organization);
219
247
  setCategories(nextCategories.items);
220
248
  },
221
249
  [client],
@@ -345,7 +373,13 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
345
373
  setSkills(answer);
346
374
  }
347
375
  })
348
- .catch(() => undefined);
376
+ .catch(() => {
377
+ // No answer at all is said on the page as the deployment being out of reach,
378
+ // rather than waited for.
379
+ if (!signal.aborted) {
380
+ setSkills({ address: null, source: "", page: null, status: "unavailable", items: [] });
381
+ }
382
+ });
349
383
  if (typeof EventSource === "undefined") {
350
384
  return;
351
385
  }
@@ -494,6 +528,15 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
494
528
  await refreshWorkspace();
495
529
  return person;
496
530
  },
531
+ async createListing(input) {
532
+ const listing = await client.createListing(input);
533
+ await refreshWorkspace();
534
+ return listing;
535
+ },
536
+ async removeListing(id) {
537
+ await client.removeListing(id);
538
+ await refreshWorkspace();
539
+ },
497
540
  async updateMe(patch) {
498
541
  const answer = await client.updateMe(patch);
499
542
  setMe(answer);
@@ -526,9 +569,14 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
526
569
  await client.revokeToken(id);
527
570
  setTokens((current) => current.filter((token) => token.id !== id));
528
571
  },
572
+ rules: (signal) => client.rules(signal),
573
+ writeRules: (input) => client.writeRules(input),
574
+ archiveRules: () => client.archiveRules(),
575
+ projectRules: (signal) => scope().rules(signal),
529
576
  connectRequest: (code, signal) => client.connectRequest(code, signal),
530
577
  approveConnection: (code, input) => client.approveConnection(code, input),
531
578
  denyConnection: (code) => client.denyConnection(code),
579
+ personWork: (personId, signal) => client.personWork(personId, signal),
532
580
  personTokens: (personId, signal) => client.personTokens(personId, signal),
533
581
  revokePersonToken: (personId, tokenId) => client.revokePersonToken(personId, tokenId),
534
582
  async signOut() {
@@ -545,6 +593,8 @@ export function useConsoleData(client: ConsoleClient, projectKey: string | undef
545
593
  loaded,
546
594
  projects,
547
595
  people,
596
+ listed,
597
+ organization,
548
598
  categories,
549
599
  tokens,
550
600
  project,
package/src/dates.ts CHANGED
@@ -113,6 +113,17 @@ export function weekdays(firstDay = 1): number[] {
113
113
  return Array.from({ length: 7 }, (_, index) => ((firstDay - 1 + index) % 7) + 1);
114
114
  }
115
115
 
116
+ /** The seven days of the week `day` is in, from the day the week begins on (1 for Monday, 7 for Sunday). */
117
+ export function weekOf(day: string, firstDay = 1): string[] {
118
+ const date = dateOf(day);
119
+ if (Number.isNaN(date.getTime())) {
120
+ return [];
121
+ }
122
+ const weekday = date.getDay() === 0 ? 7 : date.getDay();
123
+ const first = addDays(day, -((weekday - firstDay + 7) % 7));
124
+ return Array.from({ length: 7 }, (_, index) => addDays(first, index));
125
+ }
126
+
116
127
  /** A day as people read one in a language: the month and the day, with the year when it is not this year's. */
117
128
  export function formatDay(day: string, language?: string, now: Date = new Date()): string {
118
129
  const date = dateOf(day);
@@ -126,6 +137,23 @@ export function formatDay(day: string, language?: string, now: Date = new Date()
126
137
  });
127
138
  }
128
139
 
140
+ /** A stretch of days as people read one: from a day to a day, with the year. */
141
+ export function formatDays(from: string, to: string, language?: string): string {
142
+ const start = dateOf(from);
143
+ const end = dateOf(to);
144
+ if (Number.isNaN(start.getTime()) || Number.isNaN(end.getTime())) {
145
+ return `${from} - ${to}`;
146
+ }
147
+ const format = new Intl.DateTimeFormat(language, {
148
+ month: "short",
149
+ day: "numeric",
150
+ year: "numeric",
151
+ });
152
+ return typeof format.formatRange === "function"
153
+ ? format.formatRange(start, end)
154
+ : `${format.format(start)} - ${format.format(end)}`;
155
+ }
156
+
129
157
  /** A month as people read one: the month and the year. */
130
158
  export function formatMonth(month: string, language?: string): string {
131
159
  const date = dateOf(`${month}-01`);
package/src/i18n/en.ts CHANGED
@@ -2,9 +2,12 @@ import type { SignInFailure } from "../routes.js";
2
2
  import type {
3
3
  CategoryColor,
4
4
  GoalState,
5
+ MembershipSource,
5
6
  PersonRole,
7
+ PersonStatus,
6
8
  ProjectRole,
7
9
  ProjectVisibility,
10
+ ProviderKey,
8
11
  RunStatus,
9
12
  TaskPriority,
10
13
  TaskState,
@@ -37,6 +40,7 @@ export const en = {
37
40
  urgent: "Urgent",
38
41
  } satisfies Record<TaskPriority, string>,
39
42
  role: { admin: "Administrator", member: "Member" } satisfies Record<PersonRole, string>,
43
+ status: { active: "Active", deactivated: "Deactivated" } satisfies Record<PersonStatus, string>,
40
44
  projectRole: { owner: "Owner", member: "Member" } satisfies Record<ProjectRole, string>,
41
45
  visibility: {
42
46
  workspace: "Everyone of the workspace",
@@ -95,6 +99,8 @@ export const en = {
95
99
  nobody: "Nobody",
96
100
  nothing: "Nothing",
97
101
  language: "Language",
102
+ copy: "Copy",
103
+ copied: "Copied",
98
104
  showMore: (n: number, of: number) => `Show ${n} more of ${of}`,
99
105
  },
100
106
 
@@ -103,7 +109,6 @@ export const en = {
103
109
  work: "My work",
104
110
  people: "People",
105
111
  agents: "Agents",
106
- categories: "Categories",
107
112
  board: "Board",
108
113
  roadmap: "Roadmap",
109
114
  calendar: "Calendar",
@@ -143,13 +148,13 @@ export const en = {
143
148
  projects: {
144
149
  title: "Projects",
145
150
  newProject: "New project",
146
- lead: "A project holds its board, its documents, its skills and its people. What you may see and change is decided per project: an owner configures it, a member works on it.",
147
151
  empty: {
148
152
  title: "No projects yet",
149
153
  body: "Make the first one: what it is for, and who is in it. Or ask an owner to add you to theirs.",
150
154
  },
151
155
  list: "Projects",
152
156
  private: "Private",
157
+ public: "Open to everyone",
153
158
  decisionsWaiting: (n: number) => `${count(n, "decision", "decisions")} waiting`,
154
159
  form: {
155
160
  aria: "New project",
@@ -161,7 +166,11 @@ export const en = {
161
166
  descriptionPlaceholder: "What the project is for, in a sentence or two.",
162
167
  whoIsMember: "Who is a member",
163
168
  skillsAddress: "Skills address",
164
- skillsAddressPlaceholder: "/gh/<owner>/<repo>, or empty for the organization's",
169
+ skillsAddressPlaceholder: "/gh/<owner>/<repo>",
170
+ skillsAddressHint: (address: string | null) =>
171
+ address === null
172
+ ? "Left empty, the project has no skills: the console names no address for the organization's."
173
+ : `Left empty, the organization's: ${address}`,
165
174
  symbol: "Mark",
166
175
  image: "Image",
167
176
  imageRemove: "Remove the image",
@@ -172,11 +181,6 @@ export const en = {
172
181
  members: {
173
182
  title: "Members",
174
183
  list: "Members",
175
- leadWorkspace:
176
- "Everyone of the workspace is a member of this project; those listed here are its owners and the people named besides.",
177
- leadPrivate: "Only those listed here are in this project.",
178
- leadRoles:
179
- "An owner configures the project; a member works on it. A workspace administrator is an owner of every project.",
180
184
  since: "since",
181
185
  roleOf: (name: string) => `Role of ${name}`,
182
186
  addAria: "Add a member",
@@ -193,13 +197,9 @@ export const en = {
193
197
  settings: {
194
198
  title: "Settings",
195
199
  aria: "Project settings",
196
- leadBefore: "The key, ",
197
- leadAfter:
198
- ", is what addresses and the command say, and does not change. The skills address names a repository served by SkillCDN; empty, the organization's skills are shown.",
199
- onlyOwner: {
200
- title: "Only an owner may change the project",
201
- body: "Ask one of its owners, or a workspace administrator.",
202
- },
200
+ edit: "Edit the project",
201
+ organizationsSkills: (address: string) => `The organization's: ${address}`,
202
+ noSkills: "None: the console names no address for the organization's.",
203
203
  },
204
204
  },
205
205
 
@@ -305,8 +305,6 @@ export const en = {
305
305
  waiting: "Waiting",
306
306
  answered: "Answered",
307
307
  record: "The record",
308
- recordLead:
309
- "Every decision answered, newest first: what was asked, what was chosen, by whom. Open one for its context, its rationale and what followed.",
310
308
  openRecord: "Open",
311
309
  waitingForPerson: "Waiting for a person.",
312
310
  options: "Options",
@@ -337,10 +335,8 @@ export const en = {
337
335
 
338
336
  calendar: {
339
337
  title: "Calendar",
340
- lead: "The tasks on their days: planned from a start to a due day, a task lies across them; due on a day alone, it sits on it. One with no day waits at the bottom to be given one.",
341
338
  grid: "The month",
342
339
  legend: { title: "Category colours" },
343
- startsOnly: "Starts that day, with no due day yet",
344
340
  previous: "The month before",
345
341
  next: "The month after",
346
342
  thisMonth: "This month",
@@ -349,9 +345,15 @@ export const en = {
349
345
  nothingOverdue: "Nothing is overdue.",
350
346
  unscheduled: "No day set",
351
347
  allScheduled: "Every open task has a day.",
348
+ week: {
349
+ title: "The week",
350
+ previous: "The week before",
351
+ next: "The week after",
352
+ thisWeek: "This week",
353
+ nothing: "Nothing is planned this week.",
354
+ },
352
355
  workload: {
353
356
  title: "Who has what",
354
- lead: "The open tasks of each person, and what of them is late or due within the week.",
355
357
  person: "Person",
356
358
  open: "Open",
357
359
  inProgress: "In progress",
@@ -363,7 +365,6 @@ export const en = {
363
365
 
364
366
  roadmap: {
365
367
  title: "Roadmap",
366
- lead: "What the project works towards: each goal with the day it is meant to be reached by, and how far its tasks are. Progress is read from the board as it stands.",
367
368
  setGoal: "Set a goal",
368
369
  setGoalAria: "Set a goal",
369
370
  editAria: "Change the goal",
@@ -402,7 +403,6 @@ export const en = {
402
403
 
403
404
  work: {
404
405
  title: "My work",
405
- lead: "What is on your plate across your projects: the open tasks assigned to you, by the day they are due, and the decisions that wait for a person.",
406
406
  loading: "Loading your work",
407
407
  couldNotLoad: "Your work could not be loaded.",
408
408
  empty: {
@@ -420,8 +420,6 @@ export const en = {
420
420
 
421
421
  categories: {
422
422
  title: "Categories",
423
- lead: "The kinds of work tasks are sorted into, the same in every project. A task carries one, the board is narrowed by one, and an administrator keeps the list.",
424
- onlyAdmin: "An administrator adds, changes and removes them; everyone else reads them here.",
425
423
  list: "Categories",
426
424
  add: "Add a category",
427
425
  addAria: "Add a category",
@@ -429,7 +427,6 @@ export const en = {
429
427
  title: "No categories",
430
428
  body: "An administrator adds the first one here.",
431
429
  },
432
- inUse: "A category tasks are sorted into cannot be removed until they are moved out of it.",
433
430
  form: {
434
431
  name: "Name",
435
432
  key: "Key",
@@ -442,6 +439,39 @@ export const en = {
442
439
  colorOf: (key: string) => `Colour of ${key}`,
443
440
  },
444
441
 
442
+ settings: {
443
+ title: "Settings",
444
+ categories: "Categories",
445
+ manageCategories: "Manage the categories",
446
+ skills: "Skills",
447
+ skillsSource: "Served by SkillCDN at",
448
+ skillsAddress: "The organization's skills",
449
+ noSkillsAddress: "No address: each project names its own, or has none.",
450
+ skillsFromConfiguration:
451
+ "Set by whoever runs the console, in its configuration: the deployment the skills are read through, and the organization's address.",
452
+ },
453
+
454
+ rules: {
455
+ title: "Rules",
456
+ loading: "Loading the rules",
457
+ reference:
458
+ "The console's own rules hold here until an administrator writes the organization's. They change with the console's version.",
459
+ writeOrganizations: "Write the organization's rules",
460
+ useReference: "Reset to the console's rules",
461
+ read: "Read the rules",
462
+ none: "This project adds no rules of its own; the workspace's hold.",
463
+ write: "Write this project's rules",
464
+ projectRules: "This project's rules",
465
+ workspaceRules: "The workspace's rules",
466
+ onWorkspaceSettings: "Changed on the workspace's Settings page.",
467
+ form: {
468
+ body: "Rules",
469
+ hint: (max: number) =>
470
+ `Markdown, up to ${max} characters, read by every agent before it works here: which skills to load first, where the work lives, the pages, what may be decided alone, how to report. {language} stands for the language of the person the agent works for. Nothing secret, such as a token or a password.`,
471
+ save: "Save the rules",
472
+ },
473
+ },
474
+
445
475
  feed: {
446
476
  title: "What happened",
447
477
  list: "What happened",
@@ -486,6 +516,10 @@ export const en = {
486
516
  event: {
487
517
  personJoined: () => "joined the board",
488
518
  roleChanged: (login: string, role: string) => `made ${login} ${role}`,
519
+ personListed: (login: string) => `added ${login}`,
520
+ personUnlisted: (login: string) => `took ${login} off the list`,
521
+ personDeactivated: (login: string) => `deactivated ${login}`,
522
+ personReactivated: (login: string) => `reactivated ${login}`,
489
523
  projectCreated: (project: string) => `made the project ${project}`,
490
524
  projectUpdated: (fields: string, project: string) =>
491
525
  `changed ${fields} of the project ${project}`,
@@ -543,10 +577,11 @@ export const en = {
543
577
  title: "No skills address yet",
544
578
  body: "This console has no address for the organization's skills. Whoever runs it names a repository served by SkillCDN in its configuration.",
545
579
  },
546
- servedBy: "The organization's skills, served by",
580
+ servedBy: "Served by",
547
581
  at: "at",
548
- howLoaded:
549
- ". An agent loads one through its SkillCDN connection; a person reads it at its page.",
582
+ connect:
583
+ "An agent reads these through its own MCP connection to this address, which a person makes once:",
584
+ connectLink: "how, on the address's page at SkillCDN",
550
585
  status: {
551
586
  indexing: "SkillCDN is still indexing the repository. Look again in a moment.",
552
587
  failed: "SkillCDN could not index the repository. What it found is on the address's page.",
@@ -624,12 +659,44 @@ export const en = {
624
659
  people: {
625
660
  title: "People",
626
661
  list: "People",
627
- lead: "Everyone who has signed in. An administrator configures the workspace and says what each person is; a member works in the projects they are in. What a person may do, their agents may do.",
628
662
  roleOf: (name: string) => `Role of ${name}`,
663
+ letIn: "Add a person",
664
+ letInAria: "Add a person",
665
+ notSignedIn: "Added, not signed in yet",
666
+ deactivated: "Deactivated",
667
+ deactivate: "Deactivate",
668
+ reactivate: "Reactivate",
669
+ leftOrganization: "Left the organization",
670
+ source: {
671
+ organization: "Of the organization",
672
+ domain: "Of the domain",
673
+ listed: "Added by an administrator",
674
+ } satisfies Record<MembershipSource, string>,
675
+ at: { gh: "at GitHub", google: "at Google" } satisfies Record<ProviderKey, string>,
676
+ organization: (name: string) => `The organization ${name} at GitHub says who is in.`,
677
+ organizationRead: "Last read",
678
+ organizationNotRead: "Not read yet.",
679
+ form: {
680
+ login: "Login, or address",
681
+ provider: "Signs in with",
682
+ byShape: "As the login reads",
683
+ hint: "A login at GitHub, or an address at Google. Whoever signs in with that account is in.",
684
+ submit: "Add",
685
+ },
686
+ work: "Work",
687
+ workOf: (name: string) => `Work of ${name}`,
688
+ loadingWork: "Loading the work",
689
+ couldNotLoadWork: "The work could not be loaded.",
690
+ noWork: {
691
+ title: (name: string) => `Nothing is assigned to ${name}`,
692
+ body: "An open task assigned to them, in a project you may see, shows up here.",
693
+ },
694
+ notOverseen: {
695
+ title: "Not yours to see",
696
+ body: "An administrator sees everyone's work; an owner sees the work of the people in their projects.",
697
+ },
629
698
  agents: "Agents",
630
699
  agentsOf: (name: string) => `Agents of ${name}`,
631
- agentsLead: (name: string) =>
632
- `What works here as ${name}, each with a token of its own. Disconnecting one takes its token away at once.`,
633
700
  loadingAgents: "Loading the agents",
634
701
  noAgent: "No agent is connected",
635
702
  onlyAdmin: {
@@ -642,7 +709,6 @@ export const en = {
642
709
  title: "Agents",
643
710
  makeByHand: "Make a token by hand",
644
711
  makeAria: "Make a token",
645
- lead: "What works here as you: each agent you connected, with a token of its own that nobody sees. What you may do, it may do; disconnect it here when that is over. A script or a console of your own holds a token the same way, made by hand.",
646
712
  empty: {
647
713
  title: "No agent is connected yet",
648
714
  body: "Tell your agent to connect to this console, as below, and it shows up here.",
@@ -664,8 +730,6 @@ export const en = {
664
730
  fresh: {
665
731
  ready: (name: string) => `The token "${name}" is ready`,
666
732
  copyNow: "Copy it now: it is shown this once, and the console keeps only its hash.",
667
- copy: "Copy",
668
- copied: "Copied",
669
733
  useIt:
670
734
  "Sign the console command in with it, present it as a bearer token to the REST API, or give it to a console or a script of your own.",
671
735
  removeWhenDone: "It does not expire, so remove it here once it is no longer needed.",
@@ -677,7 +741,6 @@ export const en = {
677
741
  connect: {
678
742
  title: "Connect an agent",
679
743
  aria: "Connect",
680
- lead: "Your agent showed you a code when it was told to connect to this console. Type it here, and say whether the agent may work as you.",
681
744
  codeAria: "The code",
682
745
  codeLabel: "The code your agent showed",
683
746
  continue: "Continue",
@@ -712,11 +775,9 @@ export const en = {
712
775
  title: "Connecting an agent",
713
776
  tellYourAgent: "Tell your agent, in its own chat:",
714
777
  quote: (origin: string) =>
715
- `Install @skillcdn/console from npm, run console login --url ${origin}, and tell me the address and the code it shows.`,
778
+ `Run these two commands, and tell me the address and the code the second shows:\nnpm install -g @skillcdn/console\nconsole login --url ${origin}`,
716
779
  doesTheRest:
717
780
  "An agent that can run commands does the rest: it installs the command, connects, and shows you an address with a code.",
718
- thenApprove:
719
- "Open the address, signed in here, check that the page shows the same code, give the agent a name, and approve. From then on the agent works here as you, within what you may do; disconnect it on this page when that is over. The token it holds is never shown to anyone, you included.",
720
781
  byHand: "By hand, where no agent runs the command for you:",
721
782
  },
722
783
  },