@skillcdn/console 0.1.9 → 0.1.11

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 (162) hide show
  1. package/README.md +6 -6
  2. package/dist/api.d.ts +6 -5
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +5 -4
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli/cli.d.ts.map +1 -1
  7. package/dist/cli/cli.js +303 -18
  8. package/dist/cli/cli.js.map +1 -1
  9. package/dist/cli/format.d.ts +11 -1
  10. package/dist/cli/format.d.ts.map +1 -1
  11. package/dist/cli/format.js +87 -6
  12. package/dist/cli/format.js.map +1 -1
  13. package/dist/cli/help.d.ts.map +1 -1
  14. package/dist/cli/help.js +70 -14
  15. package/dist/cli/help.js.map +1 -1
  16. package/dist/client.d.ts +44 -8
  17. package/dist/client.d.ts.map +1 -1
  18. package/dist/client.js +32 -4
  19. package/dist/client.js.map +1 -1
  20. package/dist/components/board.d.ts +24 -1
  21. package/dist/components/board.d.ts.map +1 -1
  22. package/dist/components/board.js +66 -5
  23. package/dist/components/board.js.map +1 -1
  24. package/dist/components/calendar.d.ts +54 -0
  25. package/dist/components/calendar.d.ts.map +1 -0
  26. package/dist/components/calendar.js +156 -0
  27. package/dist/components/calendar.js.map +1 -0
  28. package/dist/components/categories.d.ts +13 -0
  29. package/dist/components/categories.d.ts.map +1 -0
  30. package/dist/components/categories.js +52 -0
  31. package/dist/components/categories.js.map +1 -0
  32. package/dist/components/decision-list.d.ts +10 -0
  33. package/dist/components/decision-list.d.ts.map +1 -1
  34. package/dist/components/decision-list.js +16 -1
  35. package/dist/components/decision-list.js.map +1 -1
  36. package/dist/components/event-feed.d.ts.map +1 -1
  37. package/dist/components/event-feed.js +23 -7
  38. package/dist/components/event-feed.js.map +1 -1
  39. package/dist/components/goals.d.ts +35 -0
  40. package/dist/components/goals.d.ts.map +1 -0
  41. package/dist/components/goals.js +45 -0
  42. package/dist/components/goals.js.map +1 -0
  43. package/dist/components/paged.d.ts +14 -0
  44. package/dist/components/paged.d.ts.map +1 -0
  45. package/dist/components/paged.js +28 -0
  46. package/dist/components/paged.js.map +1 -0
  47. package/dist/components/projects.d.ts +22 -2
  48. package/dist/components/projects.d.ts.map +1 -1
  49. package/dist/components/projects.js +35 -7
  50. package/dist/components/projects.js.map +1 -1
  51. package/dist/components/runs.d.ts.map +1 -1
  52. package/dist/components/runs.js +2 -2
  53. package/dist/components/runs.js.map +1 -1
  54. package/dist/components/shell.d.ts +2 -1
  55. package/dist/components/shell.d.ts.map +1 -1
  56. package/dist/components/shell.js +1 -1
  57. package/dist/components/shell.js.map +1 -1
  58. package/dist/components/task-form.d.ts +5 -1
  59. package/dist/components/task-form.d.ts.map +1 -1
  60. package/dist/components/task-form.js +13 -1
  61. package/dist/components/task-form.js.map +1 -1
  62. package/dist/components/task-list.d.ts +16 -0
  63. package/dist/components/task-list.d.ts.map +1 -0
  64. package/dist/components/task-list.js +16 -0
  65. package/dist/components/task-list.js.map +1 -0
  66. package/dist/components/task-view.d.ts +9 -1
  67. package/dist/components/task-view.d.ts.map +1 -1
  68. package/dist/components/task-view.js +10 -4
  69. package/dist/components/task-view.js.map +1 -1
  70. package/dist/components/ui.d.ts +30 -1
  71. package/dist/components/ui.d.ts.map +1 -1
  72. package/dist/components/ui.js +60 -0
  73. package/dist/components/ui.js.map +1 -1
  74. package/dist/components/work.d.ts +10 -0
  75. package/dist/components/work.d.ts.map +1 -0
  76. package/dist/components/work.js +33 -0
  77. package/dist/components/work.js.map +1 -0
  78. package/dist/console.css +658 -0
  79. package/dist/console.d.ts +8 -0
  80. package/dist/console.d.ts.map +1 -1
  81. package/dist/console.js +145 -13
  82. package/dist/console.js.map +1 -1
  83. package/dist/data.d.ts +19 -3
  84. package/dist/data.d.ts.map +1 -1
  85. package/dist/data.js +51 -4
  86. package/dist/data.js.map +1 -1
  87. package/dist/dates.d.ts +39 -0
  88. package/dist/dates.d.ts.map +1 -0
  89. package/dist/dates.js +120 -0
  90. package/dist/dates.js.map +1 -0
  91. package/dist/i18n/en.d.ts +172 -5
  92. package/dist/i18n/en.d.ts.map +1 -1
  93. package/dist/i18n/en.js +183 -6
  94. package/dist/i18n/en.js.map +1 -1
  95. package/dist/i18n/ko.d.ts.map +1 -1
  96. package/dist/i18n/ko.js +178 -6
  97. package/dist/i18n/ko.js.map +1 -1
  98. package/dist/index.d.ts +12 -5
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +12 -5
  101. package/dist/index.js.map +1 -1
  102. package/dist/limits.d.ts +11 -0
  103. package/dist/limits.d.ts.map +1 -1
  104. package/dist/limits.js +11 -0
  105. package/dist/limits.js.map +1 -1
  106. package/dist/marks.d.ts +12 -0
  107. package/dist/marks.d.ts.map +1 -0
  108. package/dist/marks.js +31 -0
  109. package/dist/marks.js.map +1 -0
  110. package/dist/router.d.ts +51 -1
  111. package/dist/router.d.ts.map +1 -1
  112. package/dist/router.js +80 -1
  113. package/dist/router.js.map +1 -1
  114. package/dist/routes.d.ts +14 -1
  115. package/dist/routes.d.ts.map +1 -1
  116. package/dist/routes.js +17 -0
  117. package/dist/routes.js.map +1 -1
  118. package/dist/schemas.d.ts +489 -3
  119. package/dist/schemas.d.ts.map +1 -1
  120. package/dist/schemas.js +150 -9
  121. package/dist/schemas.js.map +1 -1
  122. package/dist/vocabulary.d.ts +21 -1
  123. package/dist/vocabulary.d.ts.map +1 -1
  124. package/dist/vocabulary.js +31 -0
  125. package/dist/vocabulary.js.map +1 -1
  126. package/docs/specs/cli.md +17 -8
  127. package/docs/specs/rest.md +48 -17
  128. package/package.json +1 -1
  129. package/skills/working-the-board/SKILL.md +7 -6
  130. package/src/api.ts +42 -0
  131. package/src/cli/cli.ts +362 -18
  132. package/src/cli/format.ts +96 -6
  133. package/src/cli/help.ts +77 -15
  134. package/src/client.ts +98 -7
  135. package/src/components/board.tsx +173 -13
  136. package/src/components/calendar.tsx +367 -0
  137. package/src/components/categories.tsx +209 -0
  138. package/src/components/decision-list.tsx +67 -5
  139. package/src/components/event-feed.tsx +46 -27
  140. package/src/components/goals.tsx +264 -0
  141. package/src/components/paged.tsx +39 -0
  142. package/src/components/projects.tsx +128 -10
  143. package/src/components/runs.tsx +7 -1
  144. package/src/components/shell.tsx +5 -2
  145. package/src/components/task-form.tsx +78 -1
  146. package/src/components/task-list.tsx +64 -0
  147. package/src/components/task-view.tsx +75 -4
  148. package/src/components/ui.tsx +116 -1
  149. package/src/components/work.tsx +93 -0
  150. package/src/console.tsx +376 -9
  151. package/src/data.ts +83 -12
  152. package/src/dates.ts +143 -0
  153. package/src/i18n/en.ts +193 -6
  154. package/src/i18n/ko.ts +184 -6
  155. package/src/index.ts +62 -1
  156. package/src/limits.ts +11 -0
  157. package/src/marks.ts +40 -0
  158. package/src/router.ts +131 -6
  159. package/src/routes.ts +19 -0
  160. package/src/schemas.ts +187 -7
  161. package/src/styles/console.css +658 -0
  162. package/src/vocabulary.ts +43 -0
package/src/i18n/ko.ts CHANGED
@@ -21,12 +21,23 @@ export const ko: Messages = {
21
21
  projectRole: { owner: "소유자", member: "멤버" },
22
22
  visibility: { workspace: "워크스페이스의 모두", private: "목록에 있는 사람만" },
23
23
  runStatus: {
24
- running: "작업 중",
24
+ running: "열림",
25
25
  waiting: "결정 대기 중",
26
26
  finished: "완료",
27
27
  failed: "실패",
28
28
  abandoned: "중단됨",
29
29
  },
30
+ goalState: { planned: "계획됨", active: "진행 중", done: "달성", dropped: "중단" },
31
+ categoryColor: {
32
+ gray: "회색",
33
+ blue: "파랑",
34
+ green: "초록",
35
+ orange: "주황",
36
+ pink: "분홍",
37
+ purple: "보라",
38
+ teal: "청록",
39
+ yellow: "노랑",
40
+ },
30
41
  },
31
42
 
32
43
  common: {
@@ -57,13 +68,18 @@ export const ko: Messages = {
57
68
  nobody: "없음",
58
69
  nothing: "없음",
59
70
  language: "언어",
71
+ showMore: (n, of) => `${of}개 중 ${n}개 더 보기`,
60
72
  },
61
73
 
62
74
  nav: {
63
75
  projects: "프로젝트",
76
+ work: "내 작업",
64
77
  people: "사람들",
65
78
  agents: "에이전트",
79
+ categories: "카테고리",
66
80
  board: "보드",
81
+ roadmap: "로드맵",
82
+ calendar: "캘린더",
67
83
  docs: "문서",
68
84
  decisions: "결정",
69
85
  feed: "피드",
@@ -108,7 +124,6 @@ export const ko: Messages = {
108
124
  list: "프로젝트",
109
125
  private: "비공개",
110
126
  decisionsWaiting: (n) => `결정 ${n}건 대기 중`,
111
- agentsAtWork: (n) => `에이전트 ${n}개 작업 중`,
112
127
  form: {
113
128
  aria: "새 프로젝트",
114
129
  name: "이름",
@@ -119,6 +134,11 @@ export const ko: Messages = {
119
134
  whoIsMember: "멤버 범위",
120
135
  skillsAddress: "스킬 주소",
121
136
  skillsAddressPlaceholder: "/gh/<owner>/<repo>, 비우면 조직의 스킬",
137
+ symbol: "마크",
138
+ image: "이미지",
139
+ imageRemove: "이미지 지우기",
140
+ color: "색",
141
+ colorAuto: "키에서 정해진 색",
122
142
  make: "프로젝트 만들기",
123
143
  },
124
144
  members: {
@@ -164,9 +184,24 @@ export const ko: Messages = {
164
184
  moveTo: "이동",
165
185
  decisions: (n) => `결정 ${n}건`,
166
186
  decisionsTitle: "사람을 기다리는 결정",
167
- agentAtWork: "에이전트 작업 중",
168
- agentAtWorkTitle: "에이전트가 이 작업을 하고 있습니다",
169
- links: (n) => `링크 ${n}개`,
187
+ filters: {
188
+ aria: "보드 좁혀 보기",
189
+ everyone: "모두",
190
+ mine: "내 작업",
191
+ anyCategory: "모든 카테고리",
192
+ noCategory: "카테고리 없음",
193
+ anyGoal: "모든 목표",
194
+ noGoal: "목표 없음",
195
+ clear: "전체 보기",
196
+ showing: (n, of) => `작업 ${of}개 중 ${n}개`,
197
+ },
198
+ due: {
199
+ overdue: (days) => `${days}일 지남`,
200
+ today: "오늘 마감",
201
+ tomorrow: "내일 마감",
202
+ inDays: (days) => `${days}일 남음`,
203
+ on: (day) => `${day} 마감`,
204
+ },
170
205
  },
171
206
 
172
207
  task: {
@@ -186,12 +221,24 @@ export const ko: Messages = {
186
221
  raiseDecision: "결정 요청",
187
222
  nothingMore: "더 적힌 내용이 없습니다.",
188
223
  links: "링크",
189
- agentsAtWork: "작업 중인 에이전트",
190
224
  runs: "실행",
191
225
  decisions: "결정",
192
226
  history: "일어난 일",
193
227
  subtasks: "하위 작업",
194
228
  partOfIt: "하위 작업",
229
+ category: "카테고리",
230
+ goal: "목표",
231
+ plan: "일정",
232
+ planned: (from, to) =>
233
+ from !== undefined && to !== undefined
234
+ ? `${from}부터 ${to}까지`
235
+ : from !== undefined
236
+ ? `${from}부터`
237
+ : to !== undefined
238
+ ? `${to}까지`
239
+ : "",
240
+ started: "시작",
241
+ done: "완료",
195
242
  form: {
196
243
  title: "제목",
197
244
  body: "본문",
@@ -200,6 +247,12 @@ export const ko: Messages = {
200
247
  priority: "우선순위",
201
248
  assignee: "배정",
202
249
  partOf: "상위 작업",
250
+ category: "카테고리",
251
+ noCategory: "카테고리 없음",
252
+ goal: "목표",
253
+ noGoal: "목표 없음",
254
+ startsOn: "시작일",
255
+ dueOn: "기한",
203
256
  links: "링크",
204
257
  label: "이름",
205
258
  addLink: "링크 추가",
@@ -223,6 +276,10 @@ export const ko: Messages = {
223
276
  },
224
277
  waiting: "대기 중",
225
278
  answered: "답변됨",
279
+ record: "기록",
280
+ recordLead:
281
+ "답변된 모든 결정, 최신순. 무엇을 물었고, 무엇을 골랐고, 누가 골랐는지. 맥락과 근거, 그 뒤에 일어난 일은 각 결정을 열어 봅니다.",
282
+ openRecord: "열기",
226
283
  waitingForPerson: "사람을 기다리는 중입니다.",
227
284
  options: "선택지",
228
285
  notePlaceholder: "덧붙일 말이 있다면",
@@ -250,6 +307,112 @@ export const ko: Messages = {
250
307
  },
251
308
  },
252
309
 
310
+ calendar: {
311
+ title: "캘린더",
312
+ lead: "작업을 날짜 위에 놓고 봅니다. 시작일과 기한이 있는 작업은 그 기간에 걸쳐 놓이고, 기한만 있는 작업은 그날에 놓입니다. 날짜가 없는 작업은 아래에서 날짜를 기다립니다.",
313
+ grid: "이 달",
314
+ legend: { title: "카테고리 색" },
315
+ startsOnly: "그날 시작, 기한은 아직 없음",
316
+ previous: "이전 달",
317
+ next: "다음 달",
318
+ thisMonth: "이번 달",
319
+ nothingDue: "이 달에 마감인 작업이 없습니다.",
320
+ overdue: "기한 지남",
321
+ nothingOverdue: "기한이 지난 작업이 없습니다.",
322
+ unscheduled: "날짜 없음",
323
+ allScheduled: "열린 작업마다 날짜가 있습니다.",
324
+ workload: {
325
+ title: "누가 무엇을",
326
+ lead: "사람마다 열린 작업과, 그중 늦은 것과 일주일 안에 마감인 것.",
327
+ person: "사람",
328
+ open: "열림",
329
+ inProgress: "진행 중",
330
+ dueSoon: "7일 내 마감",
331
+ overdue: "기한 지남",
332
+ unassigned: "아직 배정 없음",
333
+ },
334
+ },
335
+
336
+ roadmap: {
337
+ title: "로드맵",
338
+ lead: "프로젝트가 향하는 것. 목표마다 달성 목표일과, 그 아래 작업들이 어디까지 왔는지. 진행은 보드의 현재 상태에서 그대로 읽습니다.",
339
+ setGoal: "목표 세우기",
340
+ setGoalAria: "목표 세우기",
341
+ editAria: "목표 바꾸기",
342
+ one: "목표",
343
+ all: "모든 목표",
344
+ empty: {
345
+ title: "아직 세운 목표가 없습니다",
346
+ body: "소유자가 첫 목표를 세웁니다. 무엇을, 언제까지. 그 뒤 작업을 그 목표를 향해 씁니다.",
347
+ },
348
+ noSuch: {
349
+ title: "그런 목표가 없습니다",
350
+ body: "다른 프로젝트의 것이거나, 링크가 잘못됐습니다.",
351
+ },
352
+ onlyOwner: {
353
+ title: "로드맵은 소유자만 세웁니다",
354
+ body: "프로젝트 소유자나 워크스페이스 관리자에게 요청하세요.",
355
+ },
356
+ progress: (done, of) => `작업 ${of}개 중 ${done}개 완료`,
357
+ inProgress: (n) => `${n}개 진행 중`,
358
+ noTasks: "아직 이 목표를 향한 작업이 없습니다.",
359
+ tasks: "작업",
360
+ target: "목표일",
361
+ noTarget: "목표일 없음",
362
+ setBy: "세운 사람",
363
+ state: "상태",
364
+ nothingMore: "더 적힌 내용이 없습니다.",
365
+ form: {
366
+ title: "제목",
367
+ body: "달성의 의미",
368
+ bodyPlaceholder: "목표를 이루면 무엇이 참이 되는지, Markdown으로.",
369
+ state: "상태",
370
+ dueOn: "목표일",
371
+ set: "목표 세우기",
372
+ },
373
+ },
374
+
375
+ work: {
376
+ title: "내 작업",
377
+ lead: "내 프로젝트들에 걸쳐 내게 놓인 일. 내게 배정된 열린 작업을 기한순으로, 그리고 사람을 기다리는 결정.",
378
+ loading: "내 작업을 불러오는 중",
379
+ couldNotLoad: "내 작업을 불러올 수 없습니다.",
380
+ empty: {
381
+ title: "내게 배정된 작업이 없습니다",
382
+ body: "볼 수 있는 어느 프로젝트에서든 내게 배정된 작업이 여기에 나타납니다.",
383
+ },
384
+ overdue: "기한 지남",
385
+ thisWeek: "이번 주 마감",
386
+ later: "그 뒤",
387
+ noDay: "날짜 없음",
388
+ decisions: "사람을 기다리는 결정",
389
+ noDecisions: "기다리는 결정이 없습니다.",
390
+ inProject: (project) => `${project}에서`,
391
+ },
392
+
393
+ categories: {
394
+ title: "카테고리",
395
+ lead: "작업을 나누는 일의 종류이며, 모든 프로젝트에서 같습니다. 작업은 하나를 가지고, 보드는 하나로 좁혀 보며, 관리자가 목록을 관리합니다.",
396
+ onlyAdmin: "관리자가 추가하고 바꾸고 제거합니다. 다른 사람은 여기서 읽습니다.",
397
+ list: "카테고리",
398
+ add: "카테고리 추가",
399
+ addAria: "카테고리 추가",
400
+ empty: {
401
+ title: "카테고리가 없습니다",
402
+ body: "관리자가 여기서 첫 카테고리를 추가합니다.",
403
+ },
404
+ inUse: "작업이 속해 있는 카테고리는 그 작업들을 옮기기 전에는 제거할 수 없습니다.",
405
+ form: {
406
+ name: "이름",
407
+ key: "키",
408
+ keyHint: "소문자, 숫자, 하이픈. 명령과 필터가 부르는 이름이며 바뀌지 않습니다.",
409
+ color: "색",
410
+ add: "추가",
411
+ },
412
+ nameOf: (key) => `${key}의 이름`,
413
+ colorOf: (key) => `${key}의 색`,
414
+ },
415
+
253
416
  feed: {
254
417
  title: "일어난 일",
255
418
  list: "일어난 일",
@@ -263,6 +426,8 @@ export const ko: Messages = {
263
426
  something: "무언가",
264
427
  aQuestion: "질문",
265
428
  aFile: "파일",
429
+ aGoal: "목표",
430
+ aCategory: "카테고리",
266
431
  thePage: (name) => `페이지 ${name}`.trimEnd(),
267
432
  role: {
268
433
  admin: "관리자",
@@ -282,6 +447,12 @@ export const ko: Messages = {
282
447
  visibility: "멤버 범위",
283
448
  skillsAddress: "스킬 주소",
284
449
  outcome: "그 뒤에 일어난 일",
450
+ category: "카테고리",
451
+ goalId: "목표",
452
+ startsOn: "시작일",
453
+ dueOn: "기한",
454
+ state: "상태",
455
+ color: "색",
285
456
  },
286
457
  event: {
287
458
  personJoined: () => "보드에 들어왔습니다",
@@ -293,6 +464,11 @@ export const ko: Messages = {
293
464
  memberChanged: (login, role, project) =>
294
465
  `${login}을(를) ${project}의 ${role}(으)로 지정했습니다`,
295
466
  memberRemoved: (login, project) => `${login}을(를) ${project}에서 제외했습니다`,
467
+ categoryCreated: (category) => `카테고리 ${category}을(를) 만들었습니다`,
468
+ categoryUpdated: (fields, category) => `카테고리 ${category}의 ${fields}을(를) 바꿨습니다`,
469
+ categoryRemoved: (category) => `카테고리 ${category}을(를) 제거했습니다`,
470
+ goalCreated: (goal) => `목표 ${goal}을(를) 세웠습니다`,
471
+ goalUpdated: (fields, goal) => `목표 ${goal}의 ${fields}을(를) 바꿨습니다`,
296
472
  taskCreated: (task) => `${task}을(를) 썼습니다`,
297
473
  taskMoved: (task, from, to) => `${task}을(를) ${from}에서 ${to}(으)로 옮겼습니다`,
298
474
  taskUpdated: (fields, task) => `${task}의 ${fields}을(를) 바꿨습니다`,
@@ -303,6 +479,7 @@ export const ko: Messages = {
303
479
  runReported: (task, excerpt) =>
304
480
  `${task}에 보고했습니다${excerpt === undefined ? "" : `: ${excerpt}`}`,
305
481
  runHandedIn: (label, task) => `${task}에 ${label}을(를) 제출했습니다`,
482
+ runTakenOver: (task, agent) => `${agent}에게서 ${task}을(를) 넘겨받았습니다`,
306
483
  runFinished: (task) => `${task}을(를) 끝냈습니다`,
307
484
  runFailed: (task) => `${task}에 실패했습니다`,
308
485
  runAbandoned: (task) => `${task}을(를) 포기했습니다`,
@@ -318,6 +495,7 @@ export const ko: Messages = {
318
495
  for: "대신:",
319
496
  since: "시작",
320
497
  until: "종료",
498
+ lastHeard: "마지막 소식",
321
499
  markAbandoned: "중단됨으로 표시",
322
500
  waitingForDecision: "결정을 기다리는 중",
323
501
  answerIt: "답변하기",
package/src/index.ts CHANGED
@@ -4,7 +4,26 @@
4
4
  // a script that wants none of the pages. The styles are `@skillcdn/console/console.css`.
5
5
 
6
6
  export * from "./api.js";
7
- export { Board, type BoardProps, TaskCard } from "./components/board.js";
7
+ export {
8
+ Board,
9
+ BoardFilters,
10
+ type BoardFiltersProps,
11
+ type BoardProps,
12
+ byDue,
13
+ filterTasks,
14
+ TaskCard,
15
+ } from "./components/board.js";
16
+ export {
17
+ Calendar,
18
+ type CalendarProps,
19
+ type WeekSegment,
20
+ Workload,
21
+ type WorkloadProps,
22
+ type WorkloadRow,
23
+ weekSegments,
24
+ workloadOf,
25
+ } from "./components/calendar.js";
26
+ export { CategoryList, type CategoryListProps } from "./components/categories.js";
8
27
  export {
9
28
  ConnectApproval,
10
29
  type ConnectApprovalProps,
@@ -19,6 +38,8 @@ export {
19
38
  type DecisionCardProps,
20
39
  DecisionList,
21
40
  type DecisionListProps,
41
+ DecisionLog,
42
+ type DecisionLogProps,
22
43
  } from "./components/decision-list.js";
23
44
  export {
24
45
  DocumentCrumbs,
@@ -36,7 +57,16 @@ export {
36
57
  type FolderViewProps,
37
58
  } from "./components/documents.js";
38
59
  export { describeEvent, EventFeed, type EventFeedProps } from "./components/event-feed.js";
60
+ export {
61
+ GoalForm,
62
+ type GoalFormProps,
63
+ GoalList,
64
+ type GoalListProps,
65
+ GoalView,
66
+ type GoalViewProps,
67
+ } from "./components/goals.js";
39
68
  export { Markdown, type MarkdownProps } from "./components/markdown.js";
69
+ export { PAGE_SIZE, ShowMore, usePaged } from "./components/paged.js";
40
70
  export { PeopleList, type PeopleListProps } from "./components/people.js";
41
71
  export {
42
72
  keyOf,
@@ -47,6 +77,7 @@ export {
47
77
  type ProjectFormProps,
48
78
  ProjectList,
49
79
  type ProjectListProps,
80
+ ProjectMark,
50
81
  ProjectRoleBadge,
51
82
  VISIBILITY_LABELS,
52
83
  } from "./components/projects.js";
@@ -69,6 +100,7 @@ export {
69
100
  export { SignIn, type SignInProps } from "./components/sign-in.js";
70
101
  export { SkillList, type SkillListProps } from "./components/skills.js";
71
102
  export { TaskForm, type TaskFormProps } from "./components/task-form.js";
103
+ export { TaskList, type TaskListProps } from "./components/task-list.js";
72
104
  export { TaskView, type TaskViewProps } from "./components/task-view.js";
73
105
  export {
74
106
  NewToken,
@@ -83,13 +115,18 @@ export {
83
115
  Badge,
84
116
  Button,
85
117
  Callout,
118
+ CategoryBadge,
86
119
  cx,
120
+ Day,
121
+ DueBadge,
87
122
  EmptyState,
88
123
  formatBytes,
89
124
  formatInstant,
125
+ GoalStateBadge,
90
126
  PersonChip,
91
127
  PRIORITY_LABELS,
92
128
  PriorityBadge,
129
+ ProgressBar,
93
130
  ROLE_LABELS,
94
131
  RoleBadge,
95
132
  Spinner,
@@ -97,6 +134,7 @@ export {
97
134
  StateBadge,
98
135
  Time,
99
136
  } from "./components/ui.js";
137
+ export { WorkList, type WorkListProps } from "./components/work.js";
100
138
  export { ConnectPage, type ConnectPageProps } from "./connect-page.js";
101
139
  export {
102
140
  type ConsoleApp,
@@ -106,6 +144,24 @@ export {
106
144
  DEFAULT_COMPONENTS,
107
145
  } from "./console.js";
108
146
  export { type ConsoleActions, type ConsoleData, useConsoleData } from "./data.js";
147
+ export {
148
+ addDays,
149
+ addMonths,
150
+ dateOf,
151
+ dayOf,
152
+ daysBetween,
153
+ firstDayOfWeek,
154
+ formatDay,
155
+ formatMonth,
156
+ formatWeekday,
157
+ type GridDay,
158
+ isDay,
159
+ isMonth,
160
+ monthGrid,
161
+ monthOf,
162
+ today,
163
+ weekdays,
164
+ } from "./dates.js";
109
165
  export { DocsPage, type DocsPageProps } from "./docs-page.js";
110
166
  export {
111
167
  chooseLanguage,
@@ -120,14 +176,19 @@ export {
120
176
  useWords,
121
177
  } from "./i18n/index.js";
122
178
  export {
179
+ type BoardFilter,
180
+ boardHref,
181
+ calendarHref,
123
182
  connectHref,
124
183
  type DocsView,
125
184
  decisionHref,
126
185
  docHref,
186
+ goalHref,
127
187
  matchRoute,
128
188
  movedFrom,
129
189
  type Navigation,
130
190
  newDecisionHref,
191
+ newGoalHref,
131
192
  newTaskHref,
132
193
  PATHS,
133
194
  type ProjectPage,
package/src/limits.ts CHANGED
@@ -59,3 +59,14 @@ export const MAX_VERSIONS_PER_DOCUMENT = 500;
59
59
  export const MAX_FILES_PER_DOCUMENT = 50;
60
60
  /** The words a search of the documents takes. */
61
61
  export const MAX_SEARCH_LENGTH = 200;
62
+ /** A category of tasks (ADR-0019): its key, what the command and filters say, and its name. */
63
+ export const MAX_CATEGORY_KEY_LENGTH = 40;
64
+ export const MAX_CATEGORY_NAME_LENGTH = 60;
65
+ /** How many categories one workspace may have: a vocabulary, not a tag cloud. */
66
+ export const MAX_CATEGORIES = 50;
67
+ /** A project's mark: a letter or two, or a symbol, shown on its colour; counted in code units. */
68
+ export const MAX_PROJECT_SYMBOL_LENGTH = 8;
69
+ /** How large a project's own image for its mark may be, in bytes. */
70
+ export const MAX_PROJECT_ICON_BYTES = 512 * 1024;
71
+ /** How many items a listing answers with when none is asked for, and the most one may ask for. */
72
+ export const DEFAULT_PAGE_LIMIT = 50;
package/src/marks.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { COLOR_NAMES, type ColorName } from "./vocabulary.js";
2
+
3
+ // A project's mark: a symbol on a colour, so that projects tell apart at a glance. A project
4
+ // that names neither gets a colour from its key, the same everywhere and every time, and the
5
+ // first letter of its name.
6
+
7
+ /** A small, well-spread hash of a string: enough to pick a colour, nothing more. */
8
+ function hashOf(value: string): number {
9
+ let hash = 2166136261;
10
+ for (const char of value) {
11
+ hash ^= char.codePointAt(0) ?? 0;
12
+ hash = Math.imul(hash, 16777619) >>> 0;
13
+ }
14
+ return hash;
15
+ }
16
+
17
+ /** The colour of a project's mark: the one it names, else one chosen from its key. */
18
+ export function projectColorOf(project: {
19
+ readonly key: string;
20
+ readonly color: ColorName | null;
21
+ }): ColorName {
22
+ if (project.color !== null) {
23
+ return project.color;
24
+ }
25
+ // Gray is for what has no colour; a project chosen one gets one of the rest.
26
+ const choices = COLOR_NAMES.filter((name) => name !== "gray");
27
+ return choices[hashOf(project.key) % choices.length] ?? "gray";
28
+ }
29
+
30
+ /** The symbol of a project's mark: the one it names, else the first letter of its name. */
31
+ export function projectSymbolOf(project: {
32
+ readonly name: string;
33
+ readonly symbol: string | null;
34
+ }): string {
35
+ if (project.symbol !== null && project.symbol.length > 0) {
36
+ return project.symbol;
37
+ }
38
+ const first = [...project.name.trim()][0];
39
+ return first === undefined ? "?" : first.toUpperCase();
40
+ }