@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/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/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",
@@ -126,7 +131,7 @@ export const en = {
126
131
  },
127
132
 
128
133
  signIn: {
129
- lead: "The board of the work, the agents at it, what they did, and the decisions that wait for a person.",
134
+ lead: "Join an organization made of AI agents.",
130
135
  continueWith: (provider: string) => `Continue with ${provider}`,
131
136
  nobody: {
132
137
  title: "Nobody can sign in here yet",
@@ -149,6 +154,7 @@ export const en = {
149
154
  },
150
155
  list: "Projects",
151
156
  private: "Private",
157
+ public: "Open to everyone",
152
158
  decisionsWaiting: (n: number) => `${count(n, "decision", "decisions")} waiting`,
153
159
  form: {
154
160
  aria: "New project",
@@ -160,7 +166,11 @@ export const en = {
160
166
  descriptionPlaceholder: "What the project is for, in a sentence or two.",
161
167
  whoIsMember: "Who is a member",
162
168
  skillsAddress: "Skills address",
163
- 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}`,
164
174
  symbol: "Mark",
165
175
  image: "Image",
166
176
  imageRemove: "Remove the image",
@@ -187,10 +197,9 @@ export const en = {
187
197
  settings: {
188
198
  title: "Settings",
189
199
  aria: "Project settings",
190
- onlyOwner: {
191
- title: "Only an owner may change the project",
192
- body: "Ask one of its owners, or a workspace administrator.",
193
- },
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.",
194
203
  },
195
204
  },
196
205
 
@@ -260,6 +269,7 @@ export const en = {
260
269
  done: "Done",
261
270
  form: {
262
271
  title: "Title",
272
+ titlePlaceholder: "What is to be done, in plain words that stand on their own.",
263
273
  body: "Body",
264
274
  bodyPlaceholder: "What is to be done, in Markdown.",
265
275
  state: "State",
@@ -290,7 +300,7 @@ export const en = {
290
300
  body: "It may belong to another project, or the link is wrong.",
291
301
  },
292
302
  empty: {
293
- title: "Nothing waits for a person",
303
+ title: "No decision waits for a person",
294
304
  body: "A decision raised from a task, or from here, shows up on this page.",
295
305
  },
296
306
  waiting: "Waiting",
@@ -328,7 +338,6 @@ export const en = {
328
338
  title: "Calendar",
329
339
  grid: "The month",
330
340
  legend: { title: "Category colours" },
331
- startsOnly: "Starts that day, with no due day yet",
332
341
  previous: "The month before",
333
342
  next: "The month after",
334
343
  thisMonth: "This month",
@@ -431,6 +440,39 @@ export const en = {
431
440
  colorOf: (key: string) => `Colour of ${key}`,
432
441
  },
433
442
 
443
+ settings: {
444
+ title: "Settings",
445
+ categories: "Categories",
446
+ manageCategories: "Manage the categories",
447
+ skills: "Skills",
448
+ skillsSource: "Served by SkillCDN at",
449
+ skillsAddress: "The organization's skills",
450
+ noSkillsAddress: "No address: each project names its own, or has none.",
451
+ skillsFromConfiguration:
452
+ "Set by whoever runs the console, in its configuration: the deployment the skills are read through, and the organization's address.",
453
+ },
454
+
455
+ rules: {
456
+ title: "Rules",
457
+ loading: "Loading the rules",
458
+ reference:
459
+ "The console's own rules hold here until an administrator writes the organization's. They change with the console's version.",
460
+ writeOrganizations: "Write the organization's rules",
461
+ useReference: "Reset to the console's rules",
462
+ read: "Read the rules",
463
+ none: "This project adds no rules of its own; the workspace's hold.",
464
+ write: "Write this project's rules",
465
+ projectRules: "This project's rules",
466
+ workspaceRules: "The workspace's rules",
467
+ onWorkspaceSettings: "Changed on the workspace's Settings page.",
468
+ form: {
469
+ body: "Rules",
470
+ hint: (max: number) =>
471
+ `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.`,
472
+ save: "Save the rules",
473
+ },
474
+ },
475
+
434
476
  feed: {
435
477
  title: "What happened",
436
478
  list: "What happened",
@@ -475,6 +517,10 @@ export const en = {
475
517
  event: {
476
518
  personJoined: () => "joined the board",
477
519
  roleChanged: (login: string, role: string) => `made ${login} ${role}`,
520
+ personListed: (login: string) => `added ${login}`,
521
+ personUnlisted: (login: string) => `took ${login} off the list`,
522
+ personDeactivated: (login: string) => `deactivated ${login}`,
523
+ personReactivated: (login: string) => `reactivated ${login}`,
478
524
  projectCreated: (project: string) => `made the project ${project}`,
479
525
  projectUpdated: (fields: string, project: string) =>
480
526
  `changed ${fields} of the project ${project}`,
@@ -534,6 +580,9 @@ export const en = {
534
580
  },
535
581
  servedBy: "Served by",
536
582
  at: "at",
583
+ connect:
584
+ "An agent reads these through its own MCP connection to this address, which a person makes once:",
585
+ connectLink: "how, on the address's page at SkillCDN",
537
586
  status: {
538
587
  indexing: "SkillCDN is still indexing the repository. Look again in a moment.",
539
588
  failed: "SkillCDN could not index the repository. What it found is on the address's page.",
@@ -612,6 +661,41 @@ export const en = {
612
661
  title: "People",
613
662
  list: "People",
614
663
  roleOf: (name: string) => `Role of ${name}`,
664
+ letIn: "Add a person",
665
+ letInAria: "Add a person",
666
+ notSignedIn: "Added, not signed in yet",
667
+ deactivated: "Deactivated",
668
+ deactivate: "Deactivate",
669
+ reactivate: "Reactivate",
670
+ leftOrganization: "Left the organization",
671
+ source: {
672
+ organization: "Of the organization",
673
+ domain: "Of the domain",
674
+ listed: "Added by an administrator",
675
+ } satisfies Record<MembershipSource, string>,
676
+ at: { gh: "at GitHub", google: "at Google" } satisfies Record<ProviderKey, string>,
677
+ organization: (name: string) => `The organization ${name} at GitHub says who is in.`,
678
+ organizationRead: "Last read",
679
+ organizationNotRead: "Not read yet.",
680
+ form: {
681
+ login: "Login, or address",
682
+ provider: "Signs in with",
683
+ byShape: "As the login reads",
684
+ hint: "A login at GitHub, or an address at Google. Whoever signs in with that account is in.",
685
+ submit: "Add",
686
+ },
687
+ work: "Work",
688
+ workOf: (name: string) => `Work of ${name}`,
689
+ loadingWork: "Loading the work",
690
+ couldNotLoadWork: "The work could not be loaded.",
691
+ noWork: {
692
+ title: (name: string) => `Nothing is assigned to ${name}`,
693
+ body: "An open task assigned to them, in a project you may see, shows up here.",
694
+ },
695
+ notOverseen: {
696
+ title: "Not yours to see",
697
+ body: "An administrator sees everyone's work; an owner sees the work of the people in their projects.",
698
+ },
615
699
  agents: "Agents",
616
700
  agentsOf: (name: string) => `Agents of ${name}`,
617
701
  loadingAgents: "Loading the agents",
@@ -647,8 +731,6 @@ export const en = {
647
731
  fresh: {
648
732
  ready: (name: string) => `The token "${name}" is ready`,
649
733
  copyNow: "Copy it now: it is shown this once, and the console keeps only its hash.",
650
- copy: "Copy",
651
- copied: "Copied",
652
734
  useIt:
653
735
  "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.",
654
736
  removeWhenDone: "It does not expire, so remove it here once it is no longer needed.",
@@ -694,11 +776,9 @@ export const en = {
694
776
  title: "Connecting an agent",
695
777
  tellYourAgent: "Tell your agent, in its own chat:",
696
778
  quote: (origin: string) =>
697
- `Install @skillcdn/console from npm, run console login --url ${origin}, and tell me the address and the code it shows.`,
779
+ `Run these two commands, and tell me the address and the code the second shows:\nnpm install -g @skillcdn/console\nconsole login --url ${origin}`,
698
780
  doesTheRest:
699
781
  "An agent that can run commands does the rest: it installs the command, connects, and shows you an address with a code.",
700
- thenApprove:
701
- "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.",
702
782
  byHand: "By hand, where no agent runs the command for you:",
703
783
  },
704
784
  },
package/src/i18n/ko.ts CHANGED
@@ -18,6 +18,7 @@ export const ko: Messages = {
18
18
  },
19
19
  priority: { low: "낮음", normal: "보통", high: "높음", urgent: "긴급" },
20
20
  role: { admin: "관리자", member: "멤버" },
21
+ status: { active: "활성", deactivated: "비활성화" },
21
22
  projectRole: { owner: "소유자", member: "멤버" },
22
23
  visibility: { workspace: "워크스페이스의 모두", private: "목록에 있는 사람만" },
23
24
  runStatus: {
@@ -68,6 +69,8 @@ export const ko: Messages = {
68
69
  nobody: "없음",
69
70
  nothing: "없음",
70
71
  language: "언어",
72
+ copy: "복사",
73
+ copied: "복사됨",
71
74
  showMore: (n, of) => `${of}개 중 ${n}개 더 보기`,
72
75
  },
73
76
 
@@ -76,7 +79,6 @@ export const ko: Messages = {
76
79
  work: "내 작업",
77
80
  people: "사람들",
78
81
  agents: "에이전트",
79
- categories: "카테고리",
80
82
  board: "보드",
81
83
  roadmap: "로드맵",
82
84
  calendar: "캘린더",
@@ -99,7 +101,7 @@ export const ko: Messages = {
99
101
  },
100
102
 
101
103
  signIn: {
102
- lead: "할 일의 보드, 일하는 에이전트, 그들이 한 일, 그리고 사람을 기다리는 결정.",
104
+ lead: "AI 에이전트로 이뤄진 조직에 합류하세요.",
103
105
  continueWith: (provider) => `${provider}로 계속`,
104
106
  nobody: {
105
107
  title: "아직 아무도 로그인할 수 없습니다",
@@ -122,6 +124,7 @@ export const ko: Messages = {
122
124
  },
123
125
  list: "프로젝트",
124
126
  private: "비공개",
127
+ public: "공개",
125
128
  decisionsWaiting: (n) => `결정 ${n}건 대기 중`,
126
129
  form: {
127
130
  aria: "새 프로젝트",
@@ -132,7 +135,11 @@ export const ko: Messages = {
132
135
  descriptionPlaceholder: "이 프로젝트가 무엇을 위한 것인지, 한두 문장으로.",
133
136
  whoIsMember: "멤버 범위",
134
137
  skillsAddress: "스킬 주소",
135
- skillsAddressPlaceholder: "/gh/<owner>/<repo>, 비우면 조직의 스킬",
138
+ skillsAddressPlaceholder: "/gh/<owner>/<repo>",
139
+ skillsAddressHint: (address) =>
140
+ address === null
141
+ ? "비우면 이 프로젝트에 스킬이 없습니다. 콘솔에 조직의 주소가 없습니다."
142
+ : `비우면 조직의 스킬: ${address}`,
136
143
  symbol: "마크",
137
144
  image: "이미지",
138
145
  imageRemove: "이미지 지우기",
@@ -159,10 +166,9 @@ export const ko: Messages = {
159
166
  settings: {
160
167
  title: "설정",
161
168
  aria: "프로젝트 설정",
162
- onlyOwner: {
163
- title: "소유자만 프로젝트를 바꿀 수 있습니다",
164
- body: "소유자나 워크스페이스 관리자에게 요청하세요.",
165
- },
169
+ edit: "프로젝트 편집",
170
+ organizationsSkills: (address) => `조직의 스킬: ${address}`,
171
+ noSkills: "없음: 콘솔에 조직의 주소가 없습니다.",
166
172
  },
167
173
  },
168
174
 
@@ -232,6 +238,7 @@ export const ko: Messages = {
232
238
  done: "완료",
233
239
  form: {
234
240
  title: "제목",
241
+ titlePlaceholder: "무엇을 할지, 제목만 보고도 알 수 있게.",
235
242
  body: "본문",
236
243
  bodyPlaceholder: "무엇을 할지, Markdown으로.",
237
244
  state: "상태",
@@ -262,7 +269,7 @@ export const ko: Messages = {
262
269
  body: "다른 프로젝트의 것이거나, 링크가 잘못됐습니다.",
263
270
  },
264
271
  empty: {
265
- title: "사람을 기다리는 것이 없습니다",
272
+ title: "사람을 기다리는 결정이 없습니다",
266
273
  body: "작업에서, 또는 여기서 요청한 결정이 이 페이지에 나타납니다.",
267
274
  },
268
275
  waiting: "대기 중",
@@ -300,7 +307,6 @@ export const ko: Messages = {
300
307
  title: "캘린더",
301
308
  grid: "이 달",
302
309
  legend: { title: "카테고리 색" },
303
- startsOnly: "그날 시작, 기한은 아직 없음",
304
310
  previous: "이전 달",
305
311
  next: "다음 달",
306
312
  thisMonth: "이번 달",
@@ -402,6 +408,39 @@ export const ko: Messages = {
402
408
  colorOf: (key) => `${key}의 색`,
403
409
  },
404
410
 
411
+ settings: {
412
+ title: "설정",
413
+ categories: "카테고리",
414
+ manageCategories: "카테고리 관리",
415
+ skills: "스킬",
416
+ skillsSource: "SkillCDN 제공 주소",
417
+ skillsAddress: "조직의 스킬",
418
+ noSkillsAddress: "주소 없음: 프로젝트마다 자기 주소를 두거나, 두지 않습니다.",
419
+ skillsFromConfiguration:
420
+ "콘솔을 운영하는 쪽이 설정으로 정합니다. 스킬을 읽어 오는 배포와 조직의 주소.",
421
+ },
422
+
423
+ rules: {
424
+ title: "규칙",
425
+ loading: "규칙을 불러오는 중",
426
+ reference:
427
+ "관리자가 조직의 규칙을 쓰기 전까지 콘솔의 기본 규칙이 적용됩니다. 콘솔 버전과 함께 바뀝니다.",
428
+ writeOrganizations: "조직의 규칙 쓰기",
429
+ useReference: "콘솔의 기본 규칙으로 초기화",
430
+ read: "규칙 읽기",
431
+ none: "이 프로젝트에 더하는 규칙이 없습니다. 워크스페이스의 규칙이 적용됩니다.",
432
+ write: "이 프로젝트의 규칙 쓰기",
433
+ projectRules: "이 프로젝트의 규칙",
434
+ workspaceRules: "워크스페이스의 규칙",
435
+ onWorkspaceSettings: "워크스페이스 설정에서 바꿉니다.",
436
+ form: {
437
+ body: "규칙",
438
+ hint: (max) =>
439
+ `Markdown, 최대 ${max}자. 여기서 일하는 모든 에이전트가 먼저 읽습니다. 먼저 불러올 스킬, 일이 있는 곳, 페이지, 혼자 정할 것, 보고 방식. {language}는 에이전트가 대신 일하는 사람의 언어로 바뀝니다. 토큰이나 비밀번호 같은 민감한 정보는 넣지 않습니다.`,
440
+ save: "규칙 저장",
441
+ },
442
+ },
443
+
405
444
  feed: {
406
445
  title: "일어난 일",
407
446
  list: "일어난 일",
@@ -446,6 +485,10 @@ export const ko: Messages = {
446
485
  event: {
447
486
  personJoined: () => "보드에 들어왔습니다",
448
487
  roleChanged: (login, role) => `${login}을(를) ${role}(으)로 지정했습니다`,
488
+ personListed: (login) => `${login}을(를) 추가했습니다`,
489
+ personUnlisted: (login) => `${login}을(를) 목록에서 뺐습니다`,
490
+ personDeactivated: (login) => `${login}을(를) 비활성화했습니다`,
491
+ personReactivated: (login) => `${login}을(를) 다시 활성화했습니다`,
449
492
  projectCreated: (project) => `프로젝트 ${project}을(를) 만들었습니다`,
450
493
  projectUpdated: (fields, project) => `프로젝트 ${project}의 ${fields}을(를) 바꿨습니다`,
451
494
  memberAdded: (login, project, role) =>
@@ -502,6 +545,8 @@ export const ko: Messages = {
502
545
  },
503
546
  servedBy: "제공:",
504
547
  at: "주소:",
548
+ connect: "에이전트는 이 주소에 자기 MCP 연결로 스킬을 받습니다. 사람이 한 번 연결해 줍니다:",
549
+ connectLink: "SkillCDN 페이지의 연결 안내",
505
550
  status: {
506
551
  indexing: "SkillCDN이 아직 저장소를 색인하고 있습니다. 잠시 후 다시 보세요.",
507
552
  failed: "SkillCDN이 저장소를 색인하지 못했습니다. 찾은 내용은 주소의 페이지에 있습니다.",
@@ -580,6 +625,41 @@ export const ko: Messages = {
580
625
  title: "사람들",
581
626
  list: "사람들",
582
627
  roleOf: (name) => `${name}의 역할`,
628
+ letIn: "사람 추가",
629
+ letInAria: "사람 추가",
630
+ notSignedIn: "추가됨, 아직 로그인하지 않음",
631
+ deactivated: "비활성화됨",
632
+ deactivate: "비활성화",
633
+ reactivate: "다시 활성화",
634
+ leftOrganization: "조직에서 나감",
635
+ source: {
636
+ organization: "조직의 구성원",
637
+ domain: "도메인의 계정",
638
+ listed: "관리자가 추가함",
639
+ },
640
+ at: { gh: "GitHub", google: "Google" },
641
+ organization: (name) => `GitHub 조직 ${name}이(가) 구성원을 정합니다.`,
642
+ organizationRead: "마지막으로 읽음",
643
+ organizationNotRead: "아직 읽지 않았습니다.",
644
+ form: {
645
+ login: "로그인 아이디 또는 주소",
646
+ provider: "로그인 방식",
647
+ byShape: "아이디 모양대로",
648
+ hint: "GitHub 아이디나 Google 주소. 그 계정으로 로그인하는 사람이 들어옵니다.",
649
+ submit: "추가",
650
+ },
651
+ work: "작업",
652
+ workOf: (name) => `${name}의 작업`,
653
+ loadingWork: "작업을 불러오는 중",
654
+ couldNotLoadWork: "작업을 불러올 수 없습니다.",
655
+ noWork: {
656
+ title: (name) => `${name}에게 배정된 작업이 없습니다`,
657
+ body: "내가 볼 수 있는 프로젝트에서 그 사람에게 배정된 열린 작업이 여기에 나타납니다.",
658
+ },
659
+ notOverseen: {
660
+ title: "볼 수 없는 작업입니다",
661
+ body: "관리자는 모든 사람의 작업을, 소유자는 자기 프로젝트에 속한 사람의 작업을 봅니다.",
662
+ },
583
663
  agents: "에이전트",
584
664
  agentsOf: (name) => `${name}의 에이전트`,
585
665
  loadingAgents: "에이전트를 불러오는 중",
@@ -615,8 +695,6 @@ export const ko: Messages = {
615
695
  fresh: {
616
696
  ready: (name) => `토큰 "${name}"이(가) 준비됐습니다`,
617
697
  copyNow: "지금 복사하세요. 이번 한 번만 보이며, 콘솔은 해시만 보관합니다.",
618
- copy: "복사",
619
- copied: "복사됨",
620
698
  useIt:
621
699
  "이 토큰으로 console 명령을 로그인시키거나, REST API에 bearer 토큰으로 제시하거나, 내 콘솔이나 스크립트에 주세요.",
622
700
  removeWhenDone: "만료되지 않으니, 더 쓰지 않게 되면 여기서 제거하세요.",
@@ -661,11 +739,9 @@ export const ko: Messages = {
661
739
  title: "에이전트 연결하기",
662
740
  tellYourAgent: "에이전트의 대화창에서 이렇게 말하세요:",
663
741
  quote: (origin) =>
664
- `npm으로 @skillcdn/console을 설치하고, console login --url ${origin} 을 실행한 뒤 나오는 주소와 코드를 알려줘.`,
742
+ `이 두 명령을 실행하고, 두 번째 명령이 보여 주는 주소와 코드를 알려 줘:\nnpm install -g @skillcdn/console\nconsole login --url ${origin}`,
665
743
  doesTheRest:
666
744
  "명령을 실행할 수 있는 에이전트는 나머지를 알아서 합니다. 명령을 설치하고, 연결하고, 코드가 있는 주소를 보여 줍니다.",
667
- thenApprove:
668
- "여기에 로그인한 채 그 주소를 열고, 페이지에 같은 코드가 보이는지 확인하고, 에이전트에게 이름을 붙이고, 승인하세요. 그때부터 에이전트는 내가 할 수 있는 범위 안에서 나로서 여기서 일합니다. 더 쓰지 않으면 이 페이지에서 연결을 끊으세요. 에이전트가 가진 토큰은 나를 포함해 아무에게도 보이지 않습니다.",
669
745
  byHand: "에이전트가 명령을 대신 실행하지 않는다면, 직접:",
670
746
  },
671
747
  },
package/src/index.ts CHANGED
@@ -69,7 +69,12 @@ export {
69
69
  } from "./components/goals.js";
70
70
  export { Markdown, type MarkdownProps } from "./components/markdown.js";
71
71
  export { PAGE_SIZE, ShowMore, usePaged } from "./components/paged.js";
72
- export { PeopleList, type PeopleListProps } from "./components/people.js";
72
+ export {
73
+ ListingForm,
74
+ type ListingFormProps,
75
+ PeopleList,
76
+ type PeopleListProps,
77
+ } from "./components/people.js";
73
78
  export {
74
79
  keyOf,
75
80
  MemberList,
@@ -83,6 +88,12 @@ export {
83
88
  ProjectRoleBadge,
84
89
  VISIBILITY_LABELS,
85
90
  } from "./components/projects.js";
91
+ export {
92
+ RulesForm,
93
+ type RulesFormProps,
94
+ RulesView,
95
+ type RulesViewProps,
96
+ } from "./components/rules.js";
86
97
  export {
87
98
  RUN_STATUS_LABELS,
88
99
  RunCard,
@@ -118,6 +129,7 @@ export {
118
129
  Button,
119
130
  Callout,
120
131
  CategoryBadge,
132
+ CopyButton,
121
133
  cx,
122
134
  Day,
123
135
  DueBadge,
@@ -202,8 +214,11 @@ export {
202
214
  PATHS,
203
215
  type ProjectPage,
204
216
  personAgentsHref,
217
+ personWorkHref,
205
218
  projectHref,
219
+ projectSettingsHref,
206
220
  type Route,
221
+ settingsHref,
207
222
  signInFailureOf,
208
223
  type TaskFormKind,
209
224
  taskHref,
package/src/limits.ts CHANGED
@@ -33,6 +33,8 @@ export const MAX_FILE_BYTES = 10 * 1024 * 1024;
33
33
  export const MAX_FILE_NAME_LENGTH = 200;
34
34
  /** What a person calls a token: the agent it is for, where it runs. One line. */
35
35
  export const MAX_TOKEN_NAME_LENGTH = 80;
36
+ /** A login at a git host, or an address at a Workspace, as an administrator lists one. */
37
+ export const MAX_LOGIN_LENGTH = 254;
36
38
  /** How long a token may be good for, in days, and how long one is when nothing is said. */
37
39
  export const MAX_TOKEN_DAYS = 365;
38
40
  export const DEFAULT_TOKEN_DAYS = 90;
@@ -54,6 +56,8 @@ export const MAX_DOCUMENT_PATH_LENGTH = 200;
54
56
  export const MAX_DOCUMENT_SEGMENT_LENGTH = 64;
55
57
  /** A document's body: a page of Markdown. */
56
58
  export const MAX_DOCUMENT_LENGTH = 64_000;
59
+ /** The rules of a board, the workspace's or a project's (ADR-0023): kept short, since every agent reads them. */
60
+ export const MAX_RULES_LENGTH = 12_000;
57
61
  /** How many versions one document keeps, and how many files attach to one. */
58
62
  export const MAX_VERSIONS_PER_DOCUMENT = 500;
59
63
  export const MAX_FILES_PER_DOCUMENT = 50;