@skillcdn/console 0.4.3 → 0.4.5

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 (268) hide show
  1. package/README.md +6 -6
  2. package/dist/api.d.ts +4 -4
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +4 -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 +255 -33
  8. package/dist/cli/cli.js.map +1 -1
  9. package/dist/cli/format.d.ts +20 -5
  10. package/dist/cli/format.d.ts.map +1 -1
  11. package/dist/cli/format.js +98 -26
  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 +39 -15
  15. package/dist/cli/help.js.map +1 -1
  16. package/dist/cli/plugin-check.d.ts +5 -1
  17. package/dist/cli/plugin-check.d.ts.map +1 -1
  18. package/dist/cli/plugin-check.js +23 -4
  19. package/dist/cli/plugin-check.js.map +1 -1
  20. package/dist/cli/plugin-cli.d.ts.map +1 -1
  21. package/dist/cli/plugin-cli.js +10 -1
  22. package/dist/cli/plugin-cli.js.map +1 -1
  23. package/dist/cli/plugin-init.d.ts +2 -0
  24. package/dist/cli/plugin-init.d.ts.map +1 -1
  25. package/dist/cli/plugin-init.js +6 -0
  26. package/dist/cli/plugin-init.js.map +1 -1
  27. package/dist/client.d.ts +32 -1
  28. package/dist/client.d.ts.map +1 -1
  29. package/dist/client.js +14 -2
  30. package/dist/client.js.map +1 -1
  31. package/dist/compat.js +1 -1
  32. package/dist/components/board.d.ts +8 -0
  33. package/dist/components/board.d.ts.map +1 -1
  34. package/dist/components/board.js +49 -18
  35. package/dist/components/board.js.map +1 -1
  36. package/dist/components/decision-form.d.ts +6 -3
  37. package/dist/components/decision-form.d.ts.map +1 -1
  38. package/dist/components/decision-form.js +24 -18
  39. package/dist/components/decision-form.js.map +1 -1
  40. package/dist/components/decision-list.d.ts +5 -1
  41. package/dist/components/decision-list.d.ts.map +1 -1
  42. package/dist/components/decision-list.js +25 -5
  43. package/dist/components/decision-list.js.map +1 -1
  44. package/dist/components/event-feed.d.ts.map +1 -1
  45. package/dist/components/event-feed.js +34 -8
  46. package/dist/components/event-feed.js.map +1 -1
  47. package/dist/components/goals.d.ts.map +1 -1
  48. package/dist/components/goals.js +2 -2
  49. package/dist/components/goals.js.map +1 -1
  50. package/dist/components/home.d.ts +35 -0
  51. package/dist/components/home.d.ts.map +1 -0
  52. package/dist/components/home.js +326 -0
  53. package/dist/components/home.js.map +1 -0
  54. package/dist/components/my-decisions.d.ts +20 -3
  55. package/dist/components/my-decisions.d.ts.map +1 -1
  56. package/dist/components/my-decisions.js +14 -1
  57. package/dist/components/my-decisions.js.map +1 -1
  58. package/dist/components/pack-connect.d.ts.map +1 -1
  59. package/dist/components/pack-connect.js +5 -4
  60. package/dist/components/pack-connect.js.map +1 -1
  61. package/dist/components/people.d.ts +45 -1
  62. package/dist/components/people.d.ts.map +1 -1
  63. package/dist/components/people.js +125 -4
  64. package/dist/components/people.js.map +1 -1
  65. package/dist/components/picker.d.ts +8 -0
  66. package/dist/components/picker.d.ts.map +1 -1
  67. package/dist/components/picker.js +2 -2
  68. package/dist/components/picker.js.map +1 -1
  69. package/dist/components/plugin-frame.d.ts +3 -13
  70. package/dist/components/plugin-frame.d.ts.map +1 -1
  71. package/dist/components/plugin-frame.js +75 -21
  72. package/dist/components/plugin-frame.js.map +1 -1
  73. package/dist/components/plugin-settings.d.ts +5 -1
  74. package/dist/components/plugin-settings.d.ts.map +1 -1
  75. package/dist/components/plugin-settings.js +283 -45
  76. package/dist/components/plugin-settings.js.map +1 -1
  77. package/dist/components/projects.d.ts +0 -8
  78. package/dist/components/projects.d.ts.map +1 -1
  79. package/dist/components/projects.js +4 -14
  80. package/dist/components/projects.js.map +1 -1
  81. package/dist/components/searches.d.ts +11 -0
  82. package/dist/components/searches.d.ts.map +1 -0
  83. package/dist/components/searches.js +30 -0
  84. package/dist/components/searches.js.map +1 -0
  85. package/dist/components/task-form.d.ts.map +1 -1
  86. package/dist/components/task-form.js +6 -5
  87. package/dist/components/task-form.js.map +1 -1
  88. package/dist/components/task-view.d.ts.map +1 -1
  89. package/dist/components/task-view.js +2 -1
  90. package/dist/components/task-view.js.map +1 -1
  91. package/dist/components/ui.d.ts +16 -0
  92. package/dist/components/ui.d.ts.map +1 -1
  93. package/dist/components/ui.js +15 -2
  94. package/dist/components/ui.js.map +1 -1
  95. package/dist/connect-page.d.ts.map +1 -1
  96. package/dist/connect-page.js +5 -6
  97. package/dist/connect-page.js.map +1 -1
  98. package/dist/console.css +1123 -258
  99. package/dist/console.d.ts +12 -4
  100. package/dist/console.d.ts.map +1 -1
  101. package/dist/console.js +123 -27
  102. package/dist/console.js.map +1 -1
  103. package/dist/data.d.ts +18 -3
  104. package/dist/data.d.ts.map +1 -1
  105. package/dist/data.js +41 -1
  106. package/dist/data.js.map +1 -1
  107. package/dist/docs-page.d.ts.map +1 -1
  108. package/dist/docs-page.js +6 -5
  109. package/dist/docs-page.js.map +1 -1
  110. package/dist/home-tiles.d.ts +92 -0
  111. package/dist/home-tiles.d.ts.map +1 -0
  112. package/dist/home-tiles.js +294 -0
  113. package/dist/home-tiles.js.map +1 -0
  114. package/dist/i18n/en.d.ts +264 -1
  115. package/dist/i18n/en.d.ts.map +1 -1
  116. package/dist/i18n/en.js +260 -1
  117. package/dist/i18n/en.js.map +1 -1
  118. package/dist/i18n/index.d.ts +4 -2
  119. package/dist/i18n/index.d.ts.map +1 -1
  120. package/dist/i18n/index.js +10 -11
  121. package/dist/i18n/index.js.map +1 -1
  122. package/dist/i18n/ko.d.ts.map +1 -1
  123. package/dist/i18n/ko.js +255 -4
  124. package/dist/i18n/ko.js.map +1 -1
  125. package/dist/index.d.ts +7 -5
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +7 -5
  128. package/dist/index.js.map +1 -1
  129. package/dist/limits.d.ts +12 -0
  130. package/dist/limits.d.ts.map +1 -1
  131. package/dist/limits.js +12 -0
  132. package/dist/limits.js.map +1 -1
  133. package/dist/plugin/args.d.ts +6 -1
  134. package/dist/plugin/args.d.ts.map +1 -1
  135. package/dist/plugin/args.js +16 -11
  136. package/dist/plugin/args.js.map +1 -1
  137. package/dist/plugin/bridge.d.ts +63 -3
  138. package/dist/plugin/bridge.d.ts.map +1 -1
  139. package/dist/plugin/bridge.js +54 -0
  140. package/dist/plugin/bridge.js.map +1 -1
  141. package/dist/plugin/capabilities.d.ts +7 -1
  142. package/dist/plugin/capabilities.d.ts.map +1 -1
  143. package/dist/plugin/capabilities.js +24 -1
  144. package/dist/plugin/capabilities.js.map +1 -1
  145. package/dist/plugin/context.d.ts +174 -12
  146. package/dist/plugin/context.d.ts.map +1 -1
  147. package/dist/plugin/define.d.ts +14 -1
  148. package/dist/plugin/define.d.ts.map +1 -1
  149. package/dist/plugin/define.js +18 -2
  150. package/dist/plugin/define.js.map +1 -1
  151. package/dist/plugin/limits.d.ts +9 -2
  152. package/dist/plugin/limits.d.ts.map +1 -1
  153. package/dist/plugin/limits.js +9 -2
  154. package/dist/plugin/limits.js.map +1 -1
  155. package/dist/plugin/manifest.d.ts +98 -6
  156. package/dist/plugin/manifest.d.ts.map +1 -1
  157. package/dist/plugin/manifest.js +171 -10
  158. package/dist/plugin/manifest.js.map +1 -1
  159. package/dist/plugin/rest-schemas.d.ts +120 -0
  160. package/dist/plugin/rest-schemas.d.ts.map +1 -1
  161. package/dist/plugin/rest-schemas.js +78 -5
  162. package/dist/plugin/rest-schemas.js.map +1 -1
  163. package/dist/plugin/sandbox.d.ts +4 -3
  164. package/dist/plugin/sandbox.d.ts.map +1 -1
  165. package/dist/plugin/sandbox.js +33 -6
  166. package/dist/plugin/sandbox.js.map +1 -1
  167. package/dist/plugin/semver.d.ts +26 -0
  168. package/dist/plugin/semver.d.ts.map +1 -0
  169. package/dist/plugin/semver.js +76 -0
  170. package/dist/plugin/semver.js.map +1 -0
  171. package/dist/plugin/testing.d.ts +15 -1
  172. package/dist/plugin/testing.d.ts.map +1 -1
  173. package/dist/plugin/testing.js +42 -5
  174. package/dist/plugin/testing.js.map +1 -1
  175. package/dist/plugin/web.d.ts +16 -1
  176. package/dist/plugin/web.d.ts.map +1 -1
  177. package/dist/plugin/web.js +44 -1
  178. package/dist/plugin/web.js.map +1 -1
  179. package/dist/plugin.d.ts +3 -2
  180. package/dist/plugin.d.ts.map +1 -1
  181. package/dist/plugin.js +3 -2
  182. package/dist/plugin.js.map +1 -1
  183. package/dist/router.d.ts +19 -0
  184. package/dist/router.d.ts.map +1 -1
  185. package/dist/router.js +18 -0
  186. package/dist/router.js.map +1 -1
  187. package/dist/routes.d.ts +11 -2
  188. package/dist/routes.d.ts.map +1 -1
  189. package/dist/routes.js +14 -1
  190. package/dist/routes.js.map +1 -1
  191. package/dist/rules.d.ts +2 -2
  192. package/dist/rules.js +3 -3
  193. package/dist/schemas.d.ts +864 -2
  194. package/dist/schemas.d.ts.map +1 -1
  195. package/dist/schemas.js +156 -9
  196. package/dist/schemas.js.map +1 -1
  197. package/dist/use-action.d.ts +8 -2
  198. package/dist/use-action.d.ts.map +1 -1
  199. package/dist/use-action.js +13 -6
  200. package/dist/use-action.js.map +1 -1
  201. package/dist/vocabulary.d.ts +3 -1
  202. package/dist/vocabulary.d.ts.map +1 -1
  203. package/dist/vocabulary.js +9 -0
  204. package/dist/vocabulary.js.map +1 -1
  205. package/docs/specs/cli.md +10 -6
  206. package/docs/specs/plugins.md +83 -62
  207. package/docs/specs/rest.md +34 -16
  208. package/package.json +1 -1
  209. package/skills/building-a-plugin/SKILL.md +15 -12
  210. package/skills/planning-the-board/references/setting-up.md +2 -1
  211. package/skills/working-the-board/SKILL.md +3 -3
  212. package/src/api.ts +23 -0
  213. package/src/cli/cli.ts +323 -30
  214. package/src/cli/format.ts +122 -26
  215. package/src/cli/help.ts +43 -14
  216. package/src/cli/plugin-check.ts +41 -2
  217. package/src/cli/plugin-cli.ts +10 -1
  218. package/src/cli/plugin-init.ts +8 -0
  219. package/src/client.ts +78 -0
  220. package/src/compat.ts +1 -1
  221. package/src/components/board.tsx +86 -45
  222. package/src/components/decision-form.tsx +73 -36
  223. package/src/components/decision-list.tsx +45 -13
  224. package/src/components/event-feed.tsx +40 -7
  225. package/src/components/goals.tsx +4 -1
  226. package/src/components/home.tsx +615 -0
  227. package/src/components/my-decisions.tsx +50 -5
  228. package/src/components/pack-connect.tsx +5 -4
  229. package/src/components/people.tsx +500 -61
  230. package/src/components/picker.tsx +11 -2
  231. package/src/components/plugin-frame.tsx +85 -63
  232. package/src/components/plugin-settings.tsx +735 -185
  233. package/src/components/projects.tsx +14 -69
  234. package/src/components/searches.ts +47 -0
  235. package/src/components/task-form.tsx +23 -28
  236. package/src/components/task-view.tsx +7 -0
  237. package/src/components/ui.tsx +42 -2
  238. package/src/connect-page.tsx +5 -6
  239. package/src/console.tsx +303 -64
  240. package/src/data.ts +62 -3
  241. package/src/docs-page.tsx +6 -5
  242. package/src/home-tiles.ts +438 -0
  243. package/src/i18n/en.ts +274 -0
  244. package/src/i18n/index.ts +17 -14
  245. package/src/i18n/ko.ts +267 -4
  246. package/src/index.ts +18 -5
  247. package/src/limits.ts +12 -0
  248. package/src/plugin/args.ts +16 -11
  249. package/src/plugin/bridge.ts +122 -1
  250. package/src/plugin/capabilities.ts +28 -1
  251. package/src/plugin/context.ts +186 -9
  252. package/src/plugin/define.ts +38 -1
  253. package/src/plugin/limits.ts +9 -2
  254. package/src/plugin/manifest.ts +228 -13
  255. package/src/plugin/rest-schemas.ts +89 -6
  256. package/src/plugin/sandbox.ts +36 -8
  257. package/src/plugin/semver.ts +89 -0
  258. package/src/plugin/testing.ts +63 -6
  259. package/src/plugin/web.ts +66 -0
  260. package/src/plugin.ts +19 -0
  261. package/src/router.ts +25 -0
  262. package/src/routes.ts +17 -2
  263. package/src/rules.ts +3 -3
  264. package/src/schemas.ts +197 -10
  265. package/src/styles/console.css +1123 -258
  266. package/src/use-action.ts +16 -7
  267. package/src/vocabulary.ts +10 -0
  268. package/template/plugin/console-plugin.json +3 -1
package/src/i18n/ko.ts CHANGED
@@ -98,6 +98,136 @@ export const ko: Messages = {
98
98
  },
99
99
  },
100
100
 
101
+ errors: {
102
+ internal: "콘솔에 문제가 생겼습니다. 잠시 후 다시 시도하세요.",
103
+ invalid_response: "콘솔의 응답을 읽을 수 없습니다.",
104
+ network: "콘솔에 연결할 수 없습니다.",
105
+ no_project: "이 페이지는 프로젝트에 속해 있지 않습니다.",
106
+ not_found: "이 주소에는 아무것도 없습니다.",
107
+ "auth.deactivated": "비활성화된 계정입니다.",
108
+ "auth.forbidden": "이 작업을 할 권한이 없습니다.",
109
+ "auth.forbidden_origin": "콘솔 화면에서 보낸 요청이 아닙니다.",
110
+ "auth.invalid_token": "토큰이 유효하지 않습니다. 만료되었거나 삭제되었을 수 있습니다.",
111
+ "auth.not_admitted": "콘솔에 추가되지 않은 계정입니다. 관리자에게 문의하세요.",
112
+ "auth.required": "로그인해 주세요.",
113
+ "auth.session_required": "콘솔 화면에 직접 로그인해야 할 수 있는 작업입니다.",
114
+ "category.in_use":
115
+ "이 카테고리를 쓰는 작업이나 목표가 있습니다. 먼저 다른 카테고리로 옮기세요.",
116
+ "category.key_taken": "같은 키의 카테고리가 이미 있습니다.",
117
+ "category.not_found": "카테고리를 찾을 수 없습니다.",
118
+ "category.too_many": "워크스페이스에 만들 수 있는 카테고리 수를 다 채웠습니다.",
119
+ "client.outdated": "명령어가 콘솔보다 오래되었습니다. 업데이트하세요.",
120
+ "client.too_new": "명령어가 콘솔보다 새 버전입니다.",
121
+ "comment.empty": "내용을 쓰거나 파일을 첨부하세요.",
122
+ "comment.too_many": "이 작업에 달 수 있는 댓글 수를 다 채웠습니다.",
123
+ "comment.too_many_files": "댓글에 파일이 너무 많습니다.",
124
+ "connect.approved": "이미 승인된 연결입니다.",
125
+ "connect.not_found": "이 코드로 기다리는 연결이 없습니다.",
126
+ "connect.too_many": "연결을 요청하는 에이전트가 너무 많습니다. 잠시 후 다시 시도하세요.",
127
+ "credentials.unavailable": "콘솔의 인증 정보를 읽을 수 없습니다. 잠시 후 다시 시도하세요.",
128
+ "decision.answered": "이미 답한 결정입니다.",
129
+ "decision.invalid_decider": "결정할 사람으로 지정한 사람이 이 프로젝트에서 일할 수 없습니다.",
130
+ "decision.invalid_run": "요청한 사람의 실행이 아니거나 이미 끝난 실행입니다.",
131
+ "decision.invalid_task": "이 프로젝트의 작업이 아닙니다.",
132
+ "decision.no_such_option": "이 결정에 없는 선택지입니다.",
133
+ "decision.not_found": "결정을 찾을 수 없습니다.",
134
+ "decision.too_many": "프로젝트에 올릴 수 있는 결정 수를 다 채웠습니다.",
135
+ "decision.too_many_deciders": "결정할 사람을 너무 많이 지정했습니다.",
136
+ "decision.too_many_files": "결정에 파일이 너무 많습니다.",
137
+ "document.archived": "보관된 문서입니다.",
138
+ "document.conflict": "작성하는 사이 문서가 바뀌었습니다. 다시 불러온 뒤 수정하세요.",
139
+ "document.invalid_path": "문서에 쓸 수 없는 경로입니다.",
140
+ "document.not_found": "문서를 찾을 수 없습니다.",
141
+ "document.too_many": "프로젝트에 만들 수 있는 문서 수를 다 채웠습니다.",
142
+ "document.too_many_files": "문서에 첨부할 수 있는 파일 수를 다 채웠습니다.",
143
+ "document.too_many_versions": "문서에 남길 수 있는 버전 수를 다 채웠습니다.",
144
+ "document.version_not_found": "문서에 그런 버전이 없습니다.",
145
+ "feed.too_many": "실시간 화면이 너무 많이 열려 있습니다. 탭을 닫고 다시 시도하세요.",
146
+ "file.not_found": "파일을 찾을 수 없습니다.",
147
+ "file.not_served": "제공되지 않는 파일입니다.",
148
+ "file.not_text": "글로 읽을 수 없는 파일입니다.",
149
+ "file.store_unavailable": "지금은 파일을 불러올 수 없습니다. 잠시 후 다시 시도하세요.",
150
+ "file.too_large": "파일이 너무 큽니다.",
151
+ "goal.invalid_category": "워크스페이스에 없는 카테고리입니다.",
152
+ "goal.invalid_dates": "목표일이 시작일보다 빠릅니다.",
153
+ "goal.not_found": "목표를 찾을 수 없습니다.",
154
+ "goal.too_many": "프로젝트에 세울 수 있는 목표 수를 다 채웠습니다.",
155
+ "index.failed": "팩을 읽지 못했습니다.",
156
+ "index.indexing": "팩을 읽는 중입니다. 잠시 후 다시 시도하세요.",
157
+ "listing.exists": "이미 추가된 로그인이거나 이미 멤버인 사람입니다.",
158
+ "listing.not_found": "목록에 없는 로그인입니다.",
159
+ "listing.unknown_host": "이 콘솔에서는 그 제공자로 로그인할 수 없습니다.",
160
+ "member.exists": "이미 프로젝트에 있는 사람입니다.",
161
+ "member.invalid_person": "워크스페이스에 없는 사람입니다.",
162
+ "member.not_found": "프로젝트에 없는 사람입니다.",
163
+ "member.open_project": "공개 프로젝트라서 워크스페이스의 모든 사람이 이미 멤버입니다.",
164
+ "mount.ref_not_found": "팩의 그 버전을 찾을 수 없습니다.",
165
+ "mount.repo_not_found": "팩을 찾을 수 없습니다.",
166
+ "person.email_taken": "이 워크스페이스의 다른 사람이 쓰는 주소입니다.",
167
+ "team.not_found": "팀을 찾을 수 없습니다.",
168
+ "team.name_taken": "같은 이름의 팀이 이미 있습니다.",
169
+ "team.key_taken": "같은 키의 팀이나 프로젝트가 이미 있습니다.",
170
+ "team.invalid_name": "팀 이름은 한 줄의 글자여야 합니다.",
171
+ "team.too_many": "워크스페이스가 가질 수 있는 만큼의 팀이 이미 있습니다.",
172
+ "team.invalid_member": "활성 상태인 워크스페이스의 사람만 팀에 넣을 수 있습니다.",
173
+ "team.not_a_member": "그 사람은 이 팀에 없습니다.",
174
+ "person.invalid_manager": "본인, 본인의 팀원, 비활성화된 사람은 매니저로 지정할 수 없습니다.",
175
+ "person.last_admin": "관리자가 한 명은 있어야 합니다.",
176
+ "person.not_found": "사람을 찾을 수 없습니다.",
177
+ "person.of_organization": "조직 설정으로 정해지는 사람이라 여기서 바꿀 수 없습니다.",
178
+ "picture.refused": "표시할 수 없는 이미지입니다.",
179
+ "picture.unavailable": "이미지를 불러오지 못했습니다. 잠시 후 다시 시도하세요.",
180
+ "plugin.conflict": "이미 처리되었거나 그사이에 바뀌었습니다.",
181
+ "plugin.disabled": "꺼져 있는 플러그인입니다.",
182
+ "plugin.failed": "플러그인에 문제가 생겼습니다.",
183
+ "plugin.forbidden": "플러그인이 할 수 없는 작업입니다.",
184
+ "plugin.invalid_args": "입력한 내용을 확인한 뒤 다시 시도하세요.",
185
+ "plugin.needs_consent": "플러그인이 요청한 권한에 관리자가 먼저 동의해야 합니다.",
186
+ "plugin.not_found": "플러그인을 찾을 수 없습니다.",
187
+ "plugin.rate_limited": "플러그인의 요청이 너무 많습니다. 잠시 후 다시 시도하세요.",
188
+ "plugin.required_by":
189
+ "이 플러그인이 필요한 다른 플러그인이 있습니다. 그 플러그인을 먼저 끄세요.",
190
+ "plugin.requires": "이 플러그인에 필요한 다른 플러그인이 켜져 있지 않습니다.",
191
+ "plugin.timeout": "플러그인의 응답이 너무 늦습니다.",
192
+ "plugin.too_many": "플러그인이 한도에 도달했습니다.",
193
+ "plugin.unavailable": "지금은 플러그인을 쓸 수 없습니다.",
194
+ "project.invalid_address": "팩 주소가 아닙니다.",
195
+ "project.invalid_icon": "프로젝트 이미지로 쓸 수 없는 파일입니다.",
196
+ "project.key_taken": "같은 키의 프로젝트나 팀이 이미 있습니다.",
197
+ "project.no_icon": "프로젝트에 이미지가 없습니다.",
198
+ "project.not_found": "프로젝트를 찾을 수 없습니다.",
199
+ "project.pack_connect_refused": "SkillCDN이 연결을 거부했습니다.",
200
+ "project.pack_connect_unsupported": "이 콘솔에서는 팩을 연결할 수 없습니다.",
201
+ "project.pack_token_refused": "SkillCDN이 이 토큰으로는 팩을 제공하지 않습니다.",
202
+ "project.pack_token_unsupported": "이 콘솔에서는 팩 토큰을 보관할 수 없습니다.",
203
+ "project.too_many": "워크스페이스에 만들 수 있는 프로젝트 수를 다 채웠습니다.",
204
+ "project.too_many_bytes": "프로젝트의 파일 용량을 다 썼습니다.",
205
+ "request.invalid": "입력한 내용을 확인한 뒤 다시 시도하세요.",
206
+ "request.too_large": "보내기에 너무 큽니다.",
207
+ "run.not_found": "실행을 찾을 수 없습니다.",
208
+ "run.not_yours": "다른 사람의 실행입니다.",
209
+ "run.over": "이미 끝난 실행입니다.",
210
+ "run.task_closed": "완료되었거나 중단된 작업입니다.",
211
+ "run.task_not_found": "이 프로젝트의 작업이 아닙니다.",
212
+ "run.too_many": "이 작업을 맡을 수 있는 횟수를 다 채웠습니다.",
213
+ "run.too_many_artifacts": "실행에 남길 수 있는 결과물 수를 다 채웠습니다.",
214
+ "run.too_many_reports": "실행에 남길 수 있는 보고 수를 다 채웠습니다.",
215
+ "skills.unavailable": "SkillCDN에 연결할 수 없습니다. 잠시 후 다시 시도하세요.",
216
+ "task.invalid_category": "워크스페이스에 없는 카테고리입니다.",
217
+ "task.invalid_dates": "마감일이 시작일보다 빠릅니다.",
218
+ "task.invalid_goal": "이 프로젝트의 목표가 아닙니다.",
219
+ "task.invalid_parent": "이 프로젝트의 작업이 아니거나, 상위 작업으로 두면 순환이 생깁니다.",
220
+ "task.invalid_worker": "이 프로젝트에서 일할 수 있는 사람만 담당자로 지정할 수 있습니다.",
221
+ "task.not_found": "작업을 찾을 수 없습니다.",
222
+ "task.too_many": "프로젝트에 만들 수 있는 작업 수를 다 채웠습니다.",
223
+ "token.expiry_at_most": "이 콘솔에서는 토큰을 그렇게 오래 쓰도록 만들 수 없습니다.",
224
+ "token.not_found": "토큰을 찾을 수 없습니다.",
225
+ "token.too_many": "만들 수 있는 토큰 수를 다 채웠습니다. 먼저 하나를 삭제하세요.",
226
+ "workspace.pack_connect_refused": "SkillCDN이 연결을 거부했습니다.",
227
+ "workspace.pack_connect_unsupported": "이 콘솔에서는 팩을 연결할 수 없습니다.",
228
+ "workspace.pack_token_refused": "SkillCDN이 이 토큰으로는 팩을 제공하지 않습니다.",
229
+ "workspace.pack_token_unsupported": "이 콘솔에서는 팩 토큰을 보관할 수 없습니다.",
230
+ },
101
231
  nav: {
102
232
  projects: "프로젝트",
103
233
  work: "내 작업",
@@ -139,6 +269,11 @@ export const ko: Messages = {
139
269
  problems: "실행할 수 없는 이유",
140
270
  nothing: "없음",
141
271
  capabilities: "권한",
272
+ required: "필수",
273
+ requiredHint: "플러그인이 동작하려면 꼭 필요해서 끌 수 없습니다.",
274
+ optional: "선택",
275
+ optionalHint: "쓰려는 것만 켜세요. 나중에 바꿀 수 있습니다.",
276
+ newCapability: "새 권한",
142
277
  board: "보드 프로젝트",
143
278
  boardHint: "플러그인의 결정, 태스크, 문서가 가는 곳입니다.",
144
279
  boardNone: "없음",
@@ -152,6 +287,10 @@ export const ko: Messages = {
152
287
  projectsSome: "일부 프로젝트",
153
288
  settingsForm: "설정",
154
289
  secretSet: (when) => `${when} 설정됨`,
290
+ secretSealedFrom: (host, when) => `${when} ${host}에서 받아 저장됨`,
291
+ secretExpires: (when) => `${when} 만료 예정`,
292
+ secretExpired: (when) => `${when} 만료됨`,
293
+ secretHosts: (hosts) => `${hosts}에만 보냅니다.`,
155
294
  secretUnset: "설정 안 됨",
156
295
  secretNew: "새 값",
157
296
  enable: "활성화",
@@ -160,11 +299,24 @@ export const ko: Messages = {
160
299
  rolesNone: "역할이 없어 모든 멤버가 쓸 수 있습니다.",
161
300
  roleDefault: "기본",
162
301
  everyMember: "모든 멤버",
302
+ roleManagers: "보고 라인",
303
+ whoeverManages: "누군가의 매니저인 사람",
163
304
  grantEveryone: "모두",
164
305
  grantMembersOf: (project) => `${project}의 멤버`,
165
306
  grantPeople: "사람",
166
307
  grantProjects: "프로젝트의 멤버",
167
308
  grantWhom: "부여할 대상…",
309
+ grantPlugins: "플러그인",
310
+ grantTeams: "팀",
311
+ grantTeam: (team) => `팀 ${team}`,
312
+ grantPlugin: (plugin) => `플러그인 ${plugin}`,
313
+ asks: "다른 플러그인에 요청한 역할",
314
+ asksHint:
315
+ "이 플러그인이 다른 플러그인에서 자기 이름으로 쓰려고 요청한 역할입니다. 관리자가 여기서, 또는 켤 때 부여합니다.",
316
+ askGranted: "부여됨",
317
+ askUngranted: "부여되지 않음",
318
+ askUnavailable: (plugin) => `${plugin}이(가) 꺼져 있습니다. 켜진 뒤 여기서 부여하세요.`,
319
+ askGrantNow: "지금 부여",
168
320
  grant: "부여",
169
321
  revoke: "회수",
170
322
  events: "일어난 일",
@@ -180,7 +332,20 @@ export const ko: Messages = {
180
332
  purged: "삭제했습니다.",
181
333
  agentNote: "에이전트에게",
182
334
  operations: "명령과 조회",
183
- },
335
+ console: "콘솔 버전",
336
+ consoleRange: (range) => `콘솔 ${range}`,
337
+ timeZoneHint: "워크스페이스 시간대 기준입니다.",
338
+ keeps: "보관 기간",
339
+ keepsFor: (collection, days) => `${collection}: ${days}일이 지나면 삭제`,
340
+ needsTimeZone:
341
+ "워크스페이스에 시간대가 없어서, 시간대를 정하기 전까지 이 플러그인의 시각은 UTC 기준으로 실행됩니다.",
342
+ setTimeZone: "시간대 정하기",
343
+ addItem: "추가",
344
+ itemPlaceholder: "입력한 뒤 추가",
345
+ choose: "선택…",
346
+ addOne: "추가…",
347
+ },
348
+ frameUnavailable: "지금은 표시할 수 없습니다.",
184
349
  capability: {
185
350
  files: { name: "파일", opens: "레코드에 파일을 붙입니다. 배포가 허용한 용량까지." },
186
351
  "people:read": { name: "사람 읽기", opens: "보는 사람이 볼 수 있는 사람들을 읽습니다." },
@@ -188,6 +353,15 @@ export const ko: Messages = {
188
353
  name: "모든 사람 읽기",
189
354
  opens: "워크스페이스의 모든 사람을 읽습니다. 예약 실행과 훅에서도.",
190
355
  },
356
+ "people:read:email": {
357
+ name: "업무 이메일",
358
+ opens: "읽을 수 있는 사람의 업무 이메일을 읽습니다. 다른 서비스의 계정과 맞추는 데 씁니다.",
359
+ },
360
+ "people:act": {
361
+ name: "사람 대신 실행",
362
+ opens:
363
+ "다른 곳에서 한 일을 그 사람 대신 실행하고 결정에 답합니다. 그 사람이 할 수 있는 범위 안에서, 플러그인을 거친 것으로 기록됩니다.",
364
+ },
191
365
  "projects:read": {
192
366
  name: "프로젝트 읽기",
193
367
  opens: "보는 사람이 볼 수 있는 프로젝트와 멤버를 읽습니다.",
@@ -223,6 +397,11 @@ export const ko: Messages = {
223
397
  name: "전용 데이터베이스 스키마",
224
398
  opens: "콘솔 데이터베이스에 전용 스키마와 로그인 역할을 갖습니다.",
225
399
  },
400
+ "outbound:webrtc": {
401
+ name: "페이지의 WebRTC 연결",
402
+ opens:
403
+ "페이지가 콘솔을 거치지 않고 각 사람의 브라우저에서 어떤 주소로든 연결합니다. 화면에 보여 주는 내용과 그 사람의 네트워크 주소가 어디로든 나갈 수 있습니다.",
404
+ },
226
405
  outbound: (host) => ({ name: `${host}로 요청`, opens: `${host}에 https 요청을 보냅니다.` }),
227
406
  plugins: (key) => ({
228
407
  name: `플러그인 ${key} 호출`,
@@ -377,7 +556,7 @@ export const ko: Messages = {
377
556
  filters: {
378
557
  aria: "보드 좁혀 보기",
379
558
  words: "제목, 번호, 사람",
380
- everyone: "모두",
559
+ everyone: "모든 사람",
381
560
  mine: "내 작업",
382
561
  anyCategory: "모든 카테고리",
383
562
  noCategory: "카테고리 없음",
@@ -405,6 +584,7 @@ export const ko: Messages = {
405
584
  },
406
585
  partOf: "상위 작업:",
407
586
  owner: "담당자",
587
+ writtenThrough: "작성한 에이전트",
408
588
  workers: "작업자",
409
589
  written: "작성",
410
590
  changed: "변경",
@@ -488,11 +668,14 @@ export const ko: Messages = {
488
668
  askedThrough: (agent) => `${agent}을(를) 통해 질문`,
489
669
  about: "관련 작업:",
490
670
  answeredBy: "답변",
671
+ answeredThrough: (agent) => `${agent}을(를) 통해 답변`,
491
672
  context: "맥락",
492
673
  files: "파일",
493
674
  picture: (name) => `그림 ${name}`,
494
675
  whatFollowed: "그 뒤에 일어난 일",
495
676
  nothingWritten: "아직 적힌 것이 없습니다.",
677
+ wroteWhatFollowed: "그 뒤에 일어난 일을 적음",
678
+ wroteWhatFollowedThrough: (agent) => `${agent}을(를) 통해 그 뒤에 일어난 일을 적음`,
496
679
  outcomePlaceholder: "답변으로 무엇을 했고 무엇이 됐는지, Markdown으로.",
497
680
  writeWhatFollowed: "그 뒤에 일어난 일 쓰기",
498
681
  changeIt: "고치기",
@@ -509,6 +692,8 @@ export const ko: Messages = {
509
692
  noTask: "특정 작업 없음",
510
693
  decider: "결정할 사람",
511
694
  deciderPlaceholder: "지정하지 않으면 본인",
695
+ addDecider: "사람 추가",
696
+ decidersHint: "누구든 답할 수 있고, 첫 답으로 끝납니다.",
512
697
  me: "(나)",
513
698
  options: "선택지",
514
699
  option: (n) => `선택지 ${n}`,
@@ -599,6 +784,7 @@ export const ko: Messages = {
599
784
  target: "목표일",
600
785
  noTarget: "목표일 없음",
601
786
  setBy: "세운 사람",
787
+ setThrough: (agent) => `${agent}을(를) 통해`,
602
788
  state: "상태",
603
789
  nothingMore: "더 적힌 내용이 없습니다.",
604
790
  about: "이루면 무엇이 달라지나",
@@ -728,8 +914,13 @@ export const ko: Messages = {
728
914
  console: "콘솔",
729
915
  as: (agent) => `${agent}(으)로`,
730
916
  asTitle: "그 사람이 사용한 에이전트",
917
+ via: (plugin) => `${plugin} 플러그인을 통해`,
918
+ viaTitle: "그 사람 대신 실행한 플러그인",
919
+ thePlugin: (plugin) => `플러그인 ${plugin}`,
731
920
  aTask: "작업",
732
921
  aPlugin: "플러그인",
922
+ aTeam: "팀",
923
+ theTeam: (team) => `팀 ${team}`,
733
924
  throughPlugin: (plugin) => `플러그인 ${plugin}을(를) 통해`,
734
925
  everyone: "모든 구성원",
735
926
  membersOf: (project) => `${project}의 구성원`,
@@ -784,6 +975,15 @@ export const ko: Messages = {
784
975
  personUnlisted: (login) => `${login}을(를) 목록에서 뺐습니다`,
785
976
  personDeactivated: (login) => `${login}을(를) 비활성화했습니다`,
786
977
  personReactivated: (login) => `${login}을(를) 다시 활성화했습니다`,
978
+ managerChanged: (login, manager) => `${login}의 매니저를 ${manager}(으)로 지정했습니다`,
979
+ managerCleared: (login) => `${login}의 매니저 지정을 해제했습니다`,
980
+ emailChanged: (login) => `${login}의 업무 이메일을 바꿨습니다`,
981
+ emailCleared: (login) => `${login}의 업무 이메일을 지웠습니다`,
982
+ teamCreated: (team) => `팀 ${team}을(를) 만들었습니다`,
983
+ teamRenamed: (from, team) => `팀 ${from}의 이름을 ${team}(으)로 바꿨습니다`,
984
+ teamRemoved: (team) => `팀 ${team}을(를) 삭제했습니다`,
985
+ teamMemberAdded: (login, team) => `${login}을(를) 팀 ${team}에 추가했습니다`,
986
+ teamMemberRemoved: (login, team) => `${login}을(를) 팀 ${team}에서 뺐습니다`,
787
987
  projectCreated: (project) => `프로젝트 ${project}을(를) 만들었습니다`,
788
988
  projectUpdated: (fields, project) => `프로젝트 ${project}의 ${fields}을(를) 바꿨습니다`,
789
989
  memberAdded: (login, project, role) =>
@@ -823,11 +1023,14 @@ export const ko: Messages = {
823
1023
  fileAttached: (label, page) => `${page}에 ${label}을(를) 첨부했습니다`,
824
1024
  pluginEnabled: (plugin) => `플러그인 ${plugin}을(를) 활성화했습니다`,
825
1025
  pluginDisabled: (plugin) => `플러그인 ${plugin}을(를) 비활성화했습니다`,
1026
+ pluginConsented: (plugin) => `플러그인 ${plugin}의 권한을 바꿨습니다`,
826
1027
  pluginConfigured: (fields, plugin) => `플러그인 ${plugin}의 ${fields}을(를) 바꿨습니다`,
1028
+ pluginSealed: (fields, plugin, host) =>
1029
+ `플러그인 ${plugin}의 ${fields}을(를) ${host}에서 받아 저장했습니다`,
827
1030
  pluginGranted: (role, who, plugin) =>
828
- `${who}에게 플러그인 ${plugin}의 ${role} 역할을 주었습니다`,
1031
+ `${who}에게 플러그인 ${plugin}의 ${role} 역할을 부여했습니다`,
829
1032
  pluginRevoked: (role, who, plugin) =>
830
- `${who}에게서 플러그인 ${plugin}의 ${role} 역할을 거두었습니다`,
1033
+ `${who}에게서 플러그인 ${plugin}의 ${role} 역할을 제거했습니다`,
831
1034
  pluginUpgraded: (plugin, version) => `플러그인 ${plugin}을(를) ${version}으로 올렸습니다`,
832
1035
  pluginCommand: (command, plugin, outcome) =>
833
1036
  `플러그인 ${plugin}의 ${command}을(를) 실행했습니다: ${outcome}`,
@@ -990,11 +1193,43 @@ export const ko: Messages = {
990
1193
  },
991
1194
  },
992
1195
 
1196
+ home: {
1197
+ edit: "화면 편집",
1198
+ hint: "끌어서 옮기세요. 크기는 오른쪽 위에서 고르고, ×로 화면에서 뺍니다.",
1199
+ done: "완료",
1200
+ add: "추가",
1201
+ remove: "화면에서 제거",
1202
+ size: "크기",
1203
+ sizes: {
1204
+ icon: "아이콘",
1205
+ small: "소형",
1206
+ medium: "중형",
1207
+ large: "대형",
1208
+ wide: "와이드",
1209
+ full: "전체",
1210
+ },
1211
+ },
1212
+
993
1213
  people: {
994
1214
  title: "사람들",
995
1215
  list: "사람들",
996
1216
  narrowed: "같은 프로젝트에 속한 사람들과 관리자입니다.",
997
1217
  roleOf: (name) => `${name}의 역할`,
1218
+ role: "역할",
1219
+ manager: "매니저",
1220
+ managerOf: (name) => `${name}의 매니저`,
1221
+ email: "업무 이메일",
1222
+ emailOf: (name) => `${name}의 업무 이메일`,
1223
+ emailHint:
1224
+ "Google 로그인은 로그인 주소가 들어오고, 그 밖은 여기서 적습니다. 관리자, 본인, 권한 있는 플러그인만 읽습니다.",
1225
+ team: "직속 구성원",
1226
+ teams: "팀",
1227
+ joinTeam: "팀 추가…",
1228
+ joinTeamOf: (name) => `${name}을(를) 추가할 팀`,
1229
+ leaveTeam: (name, team) => `${team}에서 ${name} 빼기`,
1230
+ howMany: (count) => `${count}명`,
1231
+ views: { aria: "사람과 팀", people: "사람", teams: "팀" },
1232
+ nobody: "없음",
998
1233
  letIn: "사람 추가",
999
1234
  letInAria: "사람 추가",
1000
1235
  notSignedIn: "추가됨, 아직 로그인하지 않음",
@@ -1042,6 +1277,34 @@ export const ko: Messages = {
1042
1277
  },
1043
1278
  },
1044
1279
 
1280
+ teams: {
1281
+ list: "팀",
1282
+ none: {
1283
+ title: "아직 팀이 없습니다",
1284
+ body: "팀은 사람들을 한 이름으로 묶습니다. 플러그인은 팀 이름으로 사람을 찾고, 팀에 준 플러그인 역할은 그 팀의 모든 사람이 갖습니다.",
1285
+ },
1286
+ members: (count) => `${count}명`,
1287
+ nobody: "아직 아무도 없습니다.",
1288
+ nameOf: (team) => `팀 ${team}의 이름`,
1289
+ keyTitle: "팀의 키: 부여, 플러그인, 명령이 팀을 부르는 이름이며 바뀌지 않습니다.",
1290
+ addMember: "사람 추가…",
1291
+ addMemberTo: (team) => `${team}에 추가할 사람`,
1292
+ removeMember: (name, team) => `${team}에서 ${name} 빼기`,
1293
+ remove: "팀 삭제",
1294
+ removeAsk: (team) =>
1295
+ `팀 ${team}을(를) 삭제할까요? 이 팀에 준 플러그인 역할도 함께 사라지고, 사람들은 그대로 남습니다.`,
1296
+ newTeam: "새 팀",
1297
+ newAria: "새 팀",
1298
+ form: {
1299
+ name: "팀 이름",
1300
+ key: "키",
1301
+ keyHint:
1302
+ "소문자, 숫자, 하이픈. 부여, 플러그인, 명령이 팀을 부르는 이름입니다. 다른 팀이나 프로젝트와 겹칠 수 없고 바뀌지 않습니다.",
1303
+ hint: "이름은 사람이 읽는 것이라 바꿀 수 있고, 키는 바뀌지 않습니다. 사람은 팀을 만든 뒤 팀 카드에서 추가합니다.",
1304
+ submit: "팀 만들기",
1305
+ },
1306
+ },
1307
+
1045
1308
  agents: {
1046
1309
  title: "에이전트",
1047
1310
  makeByHand: "토큰 직접 만들기",
package/src/index.ts CHANGED
@@ -82,6 +82,12 @@ export {
82
82
  type GoalViewProps,
83
83
  goalMonth,
84
84
  } from "./components/goals.js";
85
+ export {
86
+ HomeGrid,
87
+ type HomeGridProps,
88
+ ProjectTile,
89
+ type ProjectTileProps,
90
+ } from "./components/home.js";
85
91
  export { Markdown, type MarkdownProps } from "./components/markdown.js";
86
92
  export { MyDecisions, type MyDecisionsProps } from "./components/my-decisions.js";
87
93
  export {
@@ -103,6 +109,10 @@ export {
103
109
  type ListingFormProps,
104
110
  PeopleList,
105
111
  type PeopleListProps,
112
+ TeamForm,
113
+ type TeamFormProps,
114
+ TeamList,
115
+ type TeamListProps,
106
116
  } from "./components/people.js";
107
117
  export {
108
118
  PICKER_PAGE_LIMIT,
@@ -135,8 +145,6 @@ export {
135
145
  BridgeRefusal,
136
146
  PluginFrame,
137
147
  type PluginFrameProps,
138
- PluginWidgets,
139
- type PluginWidgetsProps,
140
148
  performBridgeCall,
141
149
  readTheme,
142
150
  } from "./components/plugin-frame.js";
@@ -149,8 +157,6 @@ export {
149
157
  PROJECT_ROLE_LABELS,
150
158
  ProjectForm,
151
159
  type ProjectFormProps,
152
- ProjectList,
153
- type ProjectListProps,
154
160
  ProjectMark,
155
161
  ProjectRoleBadge,
156
162
  VISIBILITY_LABELS,
@@ -176,6 +182,12 @@ export {
176
182
  type RunListProps,
177
183
  RunStatusBadge,
178
184
  } from "./components/runs.js";
185
+ export {
186
+ goalsSearch,
187
+ listSearch,
188
+ peopleSearch,
189
+ projectsSearch,
190
+ } from "./components/searches.js";
179
191
  export {
180
192
  type Brand,
181
193
  isPlainClick,
@@ -210,6 +222,7 @@ export {
210
222
  Button,
211
223
  Callout,
212
224
  CategoryBadge,
225
+ Chip,
213
226
  CopyButton,
214
227
  cx,
215
228
  Day,
@@ -326,4 +339,4 @@ export {
326
339
  workHref,
327
340
  } from "./router.js";
328
341
  export { CONSOLE_TOKENS } from "./tokens.js";
329
- export { errorWords, useAction } from "./use-action.js";
342
+ export { errorWords, useAction, wordsForFailure } from "./use-action.js";
package/src/limits.ts CHANGED
@@ -11,6 +11,12 @@ export const MAX_BODY_LENGTH = 20_000;
11
11
  export const MAX_LINKS = 20;
12
12
  /** How many people may be at work on one task at a time (ADR-0037): a crew, not a mailing list. */
13
13
  export const MAX_WORKERS = 20;
14
+ /** How many people one decision may be addressed to (ADR-0057): the approvers of a team, any of whom may answer. */
15
+ export const MAX_DECIDERS = 10;
16
+ /** How many tiles a person keeps at a width of their front page, and how many they took off it (ADR-0061). */
17
+ export const MAX_HOME_TILES = 200;
18
+ /** How far down the front page a tile may stand, in rows. */
19
+ export const MAX_HOME_ROW = 1000;
14
20
  export const MAX_LINK_LABEL_LENGTH = 120;
15
21
  export const MAX_URL_LENGTH = 2048;
16
22
  /** The options of a decision, and how a person words each. */
@@ -42,6 +48,12 @@ export const MAX_FILE_NAME_LENGTH = 200;
42
48
  export const MAX_TOKEN_NAME_LENGTH = 80;
43
49
  /** A login at a git host, or an address at a Workspace, as an administrator lists one. */
44
50
  export const MAX_LOGIN_LENGTH = 254;
51
+ /** A team's name (ADR-0073). */
52
+ export const MAX_TEAM_NAME_LENGTH = 60;
53
+ /** A team's key (ADR-0074), as long as a project's may be: the two are one set of names. */
54
+ export const MAX_TEAM_KEY_LENGTH = 40;
55
+ /** How many teams one workspace may hold. */
56
+ export const MAX_TEAMS = 200;
45
57
  /** How long a token may be good for, in days, and how long one is when nothing is said. */
46
58
  export const MAX_TOKEN_DAYS = 365;
47
59
  export const DEFAULT_TOKEN_DAYS = 90;
@@ -4,7 +4,7 @@
4
4
  // crosses from the plugin's thread to the console is exactly that object.
5
5
  import { PluginDefinitionError } from "./definition-error.js";
6
6
  import { MAX_PLUGIN_ABOUT_LENGTH, MAX_PLUGIN_OPTIONS } from "./limits.js";
7
- import { PLUGIN_KEY_PATTERN } from "./manifest.js";
7
+ import { isCalendarDay, PLUGIN_KEY_PATTERN } from "./manifest.js";
8
8
 
9
9
  export const ARG_TYPES = [
10
10
  "text",
@@ -269,7 +269,6 @@ export const arg = {
269
269
  },
270
270
  };
271
271
 
272
- const DAY = /^\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$/;
273
272
  const DEFAULT_TEXT_MAX = 2000;
274
273
  const DEFAULT_MARKDOWN_MAX = 20_000;
275
274
  const DEFAULT_LIST_MAX = 100;
@@ -304,9 +303,8 @@ export function argProblem(
304
303
  return undefined;
305
304
  }
306
305
  case "day":
307
- return typeof value === "string" && DAY.test(value)
308
- ? undefined
309
- : `${name} is not a day as YYYY-MM-DD`;
306
+ // The shape, and the calendar: February 30 fits the shape and is no day.
307
+ return isCalendarDay(value) ? undefined : `${name} is not a day as YYYY-MM-DD`;
310
308
  case "number": {
311
309
  if (typeof value !== "number" || !Number.isFinite(value)) {
312
310
  return `${name} is not a number`;
@@ -512,15 +510,22 @@ export function parseArgv(
512
510
  return { values };
513
511
  }
514
512
 
515
- /** The usage of an argument, as help prints it: `<from>` for a positional, `--to <day>` for a flag, in brackets where optional. */
513
+ /**
514
+ * The usage of an argument, as help prints it: `<from>` for a positional, `--to <day>` for a
515
+ * flag, in brackets where optional; a file as `--file <path>`, the flag the command itself takes,
516
+ * since the command uploads the file first and hands the plugin a handle, never a flag of the
517
+ * argument's name.
518
+ */
516
519
  export function argUsage(name: string, description: ArgDescription): string {
517
520
  const placeholder =
518
521
  description.type === "list" ? `${description.of?.type ?? "item"},...` : description.type;
519
522
  const form =
520
- description.type === "boolean" && !description.positional
521
- ? `--${name}`
522
- : description.positional
523
- ? `<${name}>`
524
- : `--${name} <${placeholder}>`;
523
+ description.type === "file"
524
+ ? "--file <path>"
525
+ : description.type === "boolean" && !description.positional
526
+ ? `--${name}`
527
+ : description.positional
528
+ ? `<${name}>`
529
+ : `--${name} <${placeholder}>`;
525
530
  return description.optional ? `[${form}]` : form;
526
531
  }