@skillcdn/console 0.1.16 → 0.1.18

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 (143) hide show
  1. package/README.md +4 -3
  2. package/dist/api.d.ts +4 -3
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +3 -2
  5. package/dist/api.js.map +1 -1
  6. package/dist/cli/cli.d.ts +12 -0
  7. package/dist/cli/cli.d.ts.map +1 -1
  8. package/dist/cli/cli.js +226 -21
  9. package/dist/cli/cli.js.map +1 -1
  10. package/dist/cli/format.d.ts +8 -3
  11. package/dist/cli/format.d.ts.map +1 -1
  12. package/dist/cli/format.js +31 -5
  13. package/dist/cli/format.js.map +1 -1
  14. package/dist/cli/help.d.ts.map +1 -1
  15. package/dist/cli/help.js +34 -8
  16. package/dist/cli/help.js.map +1 -1
  17. package/dist/cli/install.d.ts +21 -0
  18. package/dist/cli/install.d.ts.map +1 -0
  19. package/dist/cli/install.js +87 -0
  20. package/dist/cli/install.js.map +1 -0
  21. package/dist/cli/main.js +24 -4
  22. package/dist/cli/main.js.map +1 -1
  23. package/dist/cli/notices.d.ts +13 -0
  24. package/dist/cli/notices.d.ts.map +1 -0
  25. package/dist/cli/notices.js +31 -0
  26. package/dist/cli/notices.js.map +1 -0
  27. package/dist/cli/terminal.d.ts +5 -0
  28. package/dist/cli/terminal.d.ts.map +1 -1
  29. package/dist/cli/terminal.js +11 -1
  30. package/dist/cli/terminal.js.map +1 -1
  31. package/dist/client.d.ts +43 -5
  32. package/dist/client.d.ts.map +1 -1
  33. package/dist/client.js +69 -4
  34. package/dist/client.js.map +1 -1
  35. package/dist/compat.d.ts +66 -0
  36. package/dist/compat.d.ts.map +1 -0
  37. package/dist/compat.js +115 -0
  38. package/dist/compat.js.map +1 -0
  39. package/dist/components/calendar.d.ts +3 -1
  40. package/dist/components/calendar.d.ts.map +1 -1
  41. package/dist/components/calendar.js +21 -2
  42. package/dist/components/calendar.js.map +1 -1
  43. package/dist/components/comments.d.ts +59 -0
  44. package/dist/components/comments.d.ts.map +1 -0
  45. package/dist/components/comments.js +138 -0
  46. package/dist/components/comments.js.map +1 -0
  47. package/dist/components/event-feed.d.ts.map +1 -1
  48. package/dist/components/event-feed.js +2 -0
  49. package/dist/components/event-feed.js.map +1 -1
  50. package/dist/components/goals.d.ts +3 -1
  51. package/dist/components/goals.d.ts.map +1 -1
  52. package/dist/components/goals.js +23 -11
  53. package/dist/components/goals.js.map +1 -1
  54. package/dist/components/markdown.d.ts +6 -0
  55. package/dist/components/markdown.d.ts.map +1 -1
  56. package/dist/components/markdown.js +2 -1
  57. package/dist/components/markdown.js.map +1 -1
  58. package/dist/components/projects.d.ts.map +1 -1
  59. package/dist/components/projects.js +6 -1
  60. package/dist/components/projects.js.map +1 -1
  61. package/dist/components/roadmap.d.ts +37 -0
  62. package/dist/components/roadmap.d.ts.map +1 -0
  63. package/dist/components/roadmap.js +76 -0
  64. package/dist/components/roadmap.js.map +1 -0
  65. package/dist/components/task-view.d.ts +8 -3
  66. package/dist/components/task-view.d.ts.map +1 -1
  67. package/dist/components/task-view.js +6 -4
  68. package/dist/components/task-view.js.map +1 -1
  69. package/dist/components/tokens.d.ts +2 -0
  70. package/dist/components/tokens.d.ts.map +1 -1
  71. package/dist/components/tokens.js +13 -3
  72. package/dist/components/tokens.js.map +1 -1
  73. package/dist/console.css +314 -2
  74. package/dist/console.d.ts.map +1 -1
  75. package/dist/console.js +30 -11
  76. package/dist/console.js.map +1 -1
  77. package/dist/data.d.ts +5 -1
  78. package/dist/data.d.ts.map +1 -1
  79. package/dist/data.js +3 -1
  80. package/dist/data.js.map +1 -1
  81. package/dist/i18n/en.d.ts +38 -2
  82. package/dist/i18n/en.d.ts.map +1 -1
  83. package/dist/i18n/en.js +38 -2
  84. package/dist/i18n/en.js.map +1 -1
  85. package/dist/i18n/ko.d.ts.map +1 -1
  86. package/dist/i18n/ko.js +38 -2
  87. package/dist/i18n/ko.js.map +1 -1
  88. package/dist/index.d.ts +3 -1
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +3 -1
  91. package/dist/index.js.map +1 -1
  92. package/dist/limits.d.ts +3 -0
  93. package/dist/limits.d.ts.map +1 -1
  94. package/dist/limits.js +3 -0
  95. package/dist/limits.js.map +1 -1
  96. package/dist/router.d.ts +6 -1
  97. package/dist/router.d.ts.map +1 -1
  98. package/dist/router.js +10 -1
  99. package/dist/router.js.map +1 -1
  100. package/dist/rules.js +2 -2
  101. package/dist/rules.js.map +1 -1
  102. package/dist/schemas.d.ts +147 -0
  103. package/dist/schemas.d.ts.map +1 -1
  104. package/dist/schemas.js +50 -1
  105. package/dist/schemas.js.map +1 -1
  106. package/dist/vocabulary.d.ts +1 -1
  107. package/dist/vocabulary.d.ts.map +1 -1
  108. package/dist/vocabulary.js +1 -0
  109. package/dist/vocabulary.js.map +1 -1
  110. package/docs/specs/cli.md +17 -10
  111. package/docs/specs/rest.md +17 -6
  112. package/package.json +3 -2
  113. package/skills/working-the-board/SKILL.md +8 -5
  114. package/src/api.ts +35 -0
  115. package/src/cli/cli.ts +273 -22
  116. package/src/cli/format.ts +36 -4
  117. package/src/cli/help.ts +38 -7
  118. package/src/cli/install.ts +111 -0
  119. package/src/cli/main.ts +25 -4
  120. package/src/cli/notices.ts +48 -0
  121. package/src/cli/terminal.ts +12 -1
  122. package/src/client.ts +142 -8
  123. package/src/compat.ts +173 -0
  124. package/src/components/calendar.tsx +41 -1
  125. package/src/components/comments.tsx +342 -0
  126. package/src/components/event-feed.tsx +2 -0
  127. package/src/components/goals.tsx +86 -7
  128. package/src/components/markdown.tsx +9 -1
  129. package/src/components/projects.tsx +16 -3
  130. package/src/components/roadmap.tsx +242 -0
  131. package/src/components/task-view.tsx +32 -33
  132. package/src/components/tokens.tsx +38 -1
  133. package/src/console.tsx +45 -3
  134. package/src/data.ts +9 -1
  135. package/src/i18n/en.ts +40 -2
  136. package/src/i18n/ko.ts +40 -2
  137. package/src/index.ts +20 -0
  138. package/src/limits.ts +3 -0
  139. package/src/router.ts +13 -2
  140. package/src/rules.ts +2 -2
  141. package/src/schemas.ts +60 -1
  142. package/src/styles/console.css +314 -2
  143. package/src/vocabulary.ts +1 -0
package/dist/console.css CHANGED
@@ -295,6 +295,7 @@ table {
295
295
  .sc-answer-form > *,
296
296
  .sc-run > *,
297
297
  .sc-report > *,
298
+ .sc-comment > *,
298
299
  .sc-feed > *,
299
300
  .sc-card > *,
300
301
  .sc-form > *,
@@ -468,12 +469,15 @@ table {
468
469
 
469
470
  /* The tabs: the pages of the level the person is on, under the header's first row. */
470
471
 
472
+ /* The bar lies one pixel over the header's line, so that the current tab's underline sits on it;
473
+ the tabs scroll sideways where they do not fit, and nothing in the bar ever scrolls down. */
471
474
  .sc-tabs {
472
475
  width: 100%;
473
476
  max-width: var(--sc-width-page);
474
477
  margin-inline: auto;
478
+ margin-bottom: -1px;
475
479
  padding-inline: var(--sc-space-5);
476
- overflow-x: auto;
480
+ overflow: auto hidden;
477
481
  scrollbar-width: none;
478
482
  }
479
483
 
@@ -487,7 +491,6 @@ table {
487
491
  align-items: center;
488
492
  gap: var(--sc-space-2);
489
493
  padding: var(--sc-space-2) 0 var(--sc-space-3);
490
- margin-bottom: -1px;
491
494
  border-bottom: 2px solid transparent;
492
495
  color: var(--sc-color-text-muted);
493
496
  font-size: var(--sc-text-sm);
@@ -743,6 +746,7 @@ table {
743
746
  .sc-project,
744
747
  .sc-decision,
745
748
  .sc-run,
749
+ .sc-comment,
746
750
  .sc-sign-in,
747
751
  .sc-facts {
748
752
  position: relative;
@@ -758,6 +762,7 @@ table {
758
762
  .sc-project::before,
759
763
  .sc-decision::before,
760
764
  .sc-run::before,
765
+ .sc-comment::before,
761
766
  .sc-sign-in::before,
762
767
  .sc-facts::before {
763
768
  content: "";
@@ -2135,6 +2140,109 @@ table {
2135
2140
  border-top: var(--sc-border);
2136
2141
  }
2137
2142
 
2143
+ /* The discussion on a task (ADR-0024): what was said, the runs and the decisions, one thread in
2144
+ the order they came, with the way to say something at its end. */
2145
+ .sc-thread {
2146
+ display: grid;
2147
+ gap: var(--sc-space-3);
2148
+ }
2149
+
2150
+ .sc-comment {
2151
+ display: grid;
2152
+ gap: var(--sc-space-3);
2153
+ padding: var(--sc-space-4) var(--sc-space-5);
2154
+ border-radius: var(--sc-radius-lg);
2155
+ }
2156
+
2157
+ .sc-comment-header {
2158
+ display: flex;
2159
+ flex-wrap: wrap;
2160
+ align-items: center;
2161
+ gap: var(--sc-space-2);
2162
+ }
2163
+
2164
+ .sc-comment-meta {
2165
+ color: var(--sc-color-text-muted);
2166
+ font-size: var(--sc-text-sm);
2167
+ }
2168
+
2169
+ /* A picture in a comment is seen where it is, no taller than a screen's worth. */
2170
+ .sc-comment-picture img,
2171
+ .sc-comment .sc-prose img {
2172
+ display: block;
2173
+ max-width: 100%;
2174
+ max-height: 24rem;
2175
+ border: var(--sc-border);
2176
+ border-radius: var(--sc-radius-md);
2177
+ }
2178
+
2179
+ .sc-comment-files {
2180
+ display: grid;
2181
+ gap: var(--sc-space-2);
2182
+ margin: 0;
2183
+ padding: 0;
2184
+ list-style: none;
2185
+ font-size: var(--sc-text-sm);
2186
+ }
2187
+
2188
+ .sc-comment-picture {
2189
+ display: grid;
2190
+ gap: var(--sc-space-1);
2191
+ justify-items: start;
2192
+ }
2193
+
2194
+ .sc-comment-form {
2195
+ display: grid;
2196
+ gap: var(--sc-space-2);
2197
+ }
2198
+
2199
+ .sc-comment-chosen {
2200
+ display: flex;
2201
+ flex-wrap: wrap;
2202
+ gap: var(--sc-space-2);
2203
+ margin: 0;
2204
+ padding: 0;
2205
+ list-style: none;
2206
+ font-size: var(--sc-text-sm);
2207
+ }
2208
+
2209
+ .sc-comment-chosen-file {
2210
+ display: inline-flex;
2211
+ align-items: center;
2212
+ gap: var(--sc-space-1);
2213
+ padding: var(--sc-space-1) var(--sc-space-2);
2214
+ border: var(--sc-border);
2215
+ border-radius: var(--sc-radius-md);
2216
+ background: var(--sc-color-sheet);
2217
+ }
2218
+
2219
+ .sc-comment-form-actions {
2220
+ display: flex;
2221
+ flex-wrap: wrap;
2222
+ align-items: center;
2223
+ justify-content: flex-end;
2224
+ gap: var(--sc-space-2);
2225
+ }
2226
+
2227
+ .sc-comment-form-actions label {
2228
+ position: relative;
2229
+ cursor: pointer;
2230
+ }
2231
+
2232
+ /* The file input is the label's: there for the keyboard and the screen reader, not seen. */
2233
+ .sc-comment-file-input {
2234
+ position: absolute;
2235
+ width: 1px;
2236
+ height: 1px;
2237
+ overflow: hidden;
2238
+ clip-path: inset(50%);
2239
+ opacity: 0;
2240
+ }
2241
+
2242
+ .sc-comment-form .sc-field-hint {
2243
+ margin-top: 0;
2244
+ }
2245
+
2138
2246
  .sc-connect {
2139
2247
  display: grid;
2140
2248
  gap: var(--sc-space-3);
@@ -3368,3 +3476,207 @@ table {
3368
3476
  .sc-rules-fold[open] > summary {
3369
3477
  margin-bottom: var(--sc-space-3);
3370
3478
  }
3479
+
3480
+ /* The roadmap as months (ADR-0026): the months as columns, each goal a bar from its start to its target. */
3481
+ .sc-timeline {
3482
+ display: grid;
3483
+ gap: var(--sc-space-3);
3484
+ margin-bottom: var(--sc-space-6);
3485
+ }
3486
+
3487
+ .sc-timeline-head {
3488
+ display: flex;
3489
+ flex-wrap: wrap;
3490
+ align-items: center;
3491
+ justify-content: space-between;
3492
+ gap: var(--sc-space-2);
3493
+ }
3494
+
3495
+ .sc-timeline-title {
3496
+ margin: 0;
3497
+ font-size: var(--sc-text-base);
3498
+ font-weight: var(--sc-weight-medium);
3499
+ }
3500
+
3501
+ .sc-timeline-grid {
3502
+ display: grid;
3503
+ gap: 2px;
3504
+ overflow-x: auto;
3505
+ }
3506
+
3507
+ .sc-timeline-row {
3508
+ display: grid;
3509
+ grid-template-columns: minmax(8rem, 14rem) minmax(20rem, 1fr);
3510
+ align-items: center;
3511
+ gap: var(--sc-space-2);
3512
+ }
3513
+
3514
+ .sc-timeline-label {
3515
+ display: flex;
3516
+ flex-wrap: wrap;
3517
+ align-items: center;
3518
+ gap: var(--sc-space-2);
3519
+ min-width: 0;
3520
+ }
3521
+
3522
+ .sc-timeline-goal {
3523
+ color: var(--sc-color-text);
3524
+ font-size: var(--sc-text-sm);
3525
+ text-decoration: none;
3526
+ overflow-wrap: anywhere;
3527
+ }
3528
+
3529
+ .sc-timeline-goal:hover {
3530
+ color: var(--sc-color-accent);
3531
+ }
3532
+
3533
+ .sc-timeline-track {
3534
+ position: relative;
3535
+ display: flex;
3536
+ height: 1.75rem;
3537
+ }
3538
+
3539
+ .sc-timeline-months .sc-timeline-track {
3540
+ height: auto;
3541
+ }
3542
+
3543
+ .sc-timeline-month {
3544
+ flex: none;
3545
+ padding: var(--sc-space-1) var(--sc-space-2);
3546
+ border-left: var(--sc-border);
3547
+ color: var(--sc-color-text-muted);
3548
+ font-size: var(--sc-text-xs);
3549
+ white-space: nowrap;
3550
+ overflow: hidden;
3551
+ text-overflow: ellipsis;
3552
+ }
3553
+
3554
+ .sc-timeline-column {
3555
+ flex: none;
3556
+ height: 100%;
3557
+ border-left: var(--sc-border);
3558
+ background: var(--sc-color-sheet);
3559
+ }
3560
+
3561
+ .sc-timeline-today {
3562
+ position: absolute;
3563
+ top: 0;
3564
+ bottom: 0;
3565
+ width: 2px;
3566
+ margin-left: -1px;
3567
+ background: var(--sc-color-accent);
3568
+ opacity: 0.7;
3569
+ }
3570
+
3571
+ .sc-timeline-today-mark {
3572
+ top: auto;
3573
+ bottom: 0;
3574
+ height: var(--sc-space-2);
3575
+ }
3576
+
3577
+ .sc-timeline-bar {
3578
+ position: absolute;
3579
+ top: 0.25rem;
3580
+ bottom: 0.25rem;
3581
+ display: flex;
3582
+ align-items: center;
3583
+ overflow: hidden;
3584
+ border-block: 1px solid color-mix(in srgb, var(--sc-category-line) 45%, transparent);
3585
+ background: var(--sc-category-fill);
3586
+ color: var(--sc-category-line);
3587
+ font-size: var(--sc-text-xs);
3588
+ text-decoration: none;
3589
+ white-space: nowrap;
3590
+ }
3591
+
3592
+ .sc-timeline-bar:hover {
3593
+ background: color-mix(in srgb, var(--sc-category-fill), white 12%);
3594
+ }
3595
+
3596
+ .sc-timeline-bar.sc-timeline-bar-begins {
3597
+ border-left: 1px solid color-mix(in srgb, var(--sc-category-line) 45%, transparent);
3598
+ border-start-start-radius: var(--sc-radius-full);
3599
+ border-end-start-radius: var(--sc-radius-full);
3600
+ }
3601
+
3602
+ .sc-timeline-bar.sc-timeline-bar-ends {
3603
+ border-right: 1px solid color-mix(in srgb, var(--sc-category-line) 45%, transparent);
3604
+ border-start-end-radius: var(--sc-radius-full);
3605
+ border-end-end-radius: var(--sc-radius-full);
3606
+ }
3607
+
3608
+ .sc-timeline-fill {
3609
+ position: absolute;
3610
+ top: 0;
3611
+ bottom: 0;
3612
+ left: 0;
3613
+ background: color-mix(in srgb, var(--sc-category-line) 35%, transparent);
3614
+ }
3615
+
3616
+ .sc-timeline-words {
3617
+ position: relative;
3618
+ padding-inline: var(--sc-space-2);
3619
+ }
3620
+
3621
+ .sc-timeline-point {
3622
+ position: absolute;
3623
+ top: 50%;
3624
+ width: 0.75rem;
3625
+ height: 0.75rem;
3626
+ margin-left: -0.375rem;
3627
+ transform: translateY(-50%) rotate(45deg);
3628
+ border: 1px solid color-mix(in srgb, var(--sc-category-line) 60%, transparent);
3629
+ background: var(--sc-category-fill);
3630
+ }
3631
+
3632
+ .sc-goal-done .sc-timeline-bar,
3633
+ .sc-goal-done .sc-timeline-point {
3634
+ opacity: 0.6;
3635
+ }
3636
+
3637
+ .sc-goal-dropped .sc-timeline-bar,
3638
+ .sc-goal-dropped .sc-timeline-point {
3639
+ opacity: 0.4;
3640
+ }
3641
+
3642
+ .sc-timeline-undated {
3643
+ margin: 0;
3644
+ font-size: var(--sc-text-sm);
3645
+ }
3646
+
3647
+ .sc-goal-days {
3648
+ color: var(--sc-color-text-muted);
3649
+ font-size: var(--sc-text-xs);
3650
+ }
3651
+
3652
+ /* A goal marks its target day on the month: a flag before its title, in the colour of its category. */
3653
+ .sc-calendar-goal {
3654
+ display: flex;
3655
+ align-items: center;
3656
+ gap: var(--sc-space-1);
3657
+ margin-top: 2px;
3658
+ color: var(--sc-category-line, var(--sc-color-text));
3659
+ font-size: var(--sc-text-xs);
3660
+ font-weight: var(--sc-weight-medium);
3661
+ line-height: 1.2;
3662
+ text-decoration: none;
3663
+ }
3664
+
3665
+ .sc-calendar-goal:hover {
3666
+ color: var(--sc-color-accent);
3667
+ }
3668
+
3669
+ .sc-calendar-flag {
3670
+ display: inline-block;
3671
+ flex: none;
3672
+ width: 0.5rem;
3673
+ height: 0.5rem;
3674
+ transform: rotate(45deg);
3675
+ background: var(--sc-category-line, var(--sc-color-text-faint));
3676
+ }
3677
+
3678
+ @media (max-width: 40rem) {
3679
+ .sc-timeline-row {
3680
+ grid-template-columns: minmax(6rem, 8rem) minmax(16rem, 1fr);
3681
+ }
3682
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../src/console.tsx"],"names":[],"mappings":"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"}
package/dist/console.js CHANGED
@@ -12,6 +12,7 @@ import { EventFeed } from "./components/event-feed.js";
12
12
  import { GoalForm, GoalList, GoalView } from "./components/goals.js";
13
13
  import { ListingForm, PeopleList } from "./components/people.js";
14
14
  import { MemberList, ProjectForm, ProjectList, ProjectMark, } from "./components/projects.js";
15
+ import { GoalTimeline } from "./components/roadmap.js";
15
16
  import { RulesForm, RulesView } from "./components/rules.js";
16
17
  import { isPlainClick, Shell, } from "./components/shell.js";
17
18
  import { SignIn } from "./components/sign-in.js";
@@ -27,7 +28,7 @@ import { useConsoleData } from "./data.js";
27
28
  import { monthOf, today } from "./dates.js";
28
29
  import { DocsPage } from "./docs-page.js";
29
30
  import { chooseLanguage, DEFAULT_LANGUAGES, LanguageContext, useWords, } from "./i18n/index.js";
30
- import { boardHref, calendarHref, customPageHref, decisionHref, docHref, goalHref, matchRoute, newDecisionHref, newGoalHref, newTaskHref, PATHS, personAgentsHref, personWorkHref, projectHref, projectSettingsHref, settingsHref, signInFailureOf, taskHref, withoutSignInParam, workHref, } from "./router.js";
31
+ import { boardHref, calendarHref, customPageHref, decisionHref, docHref, goalHref, matchRoute, newDecisionHref, newGoalHref, newTaskHref, PATHS, personAgentsHref, personWorkHref, projectHref, projectSettingsHref, roadmapHref, settingsHref, signInFailureOf, taskHref, withoutSignInParam, workHref, } from "./router.js";
31
32
  import { projectPath } from "./routes.js";
32
33
  import { errorWords, useAction } from "./use-action.js";
33
34
  export const DEFAULT_COMPONENTS = {
@@ -206,7 +207,8 @@ function TaskPage(props) {
206
207
  ? data.tasks.find((candidate) => candidate.id === route.id)
207
208
  : data.tasks.find((candidate) => candidate.number === route.number);
208
209
  const [history, setHistory] = useState(undefined);
209
- const { taskHistory } = data.actions;
210
+ const [comments, setComments] = useState(undefined);
211
+ const { taskHistory, taskComments } = data.actions;
210
212
  const taskId = task?.id;
211
213
  const number = task?.number;
212
214
  // A task named by its id is shown at its number's address.
@@ -230,19 +232,36 @@ function TaskPage(props) {
230
232
  }
231
233
  })
232
234
  .catch(() => undefined);
235
+ taskComments(taskId, controller.signal)
236
+ .then((items) => {
237
+ if (!controller.signal.aborted) {
238
+ setComments(items);
239
+ }
240
+ })
241
+ .catch(() => undefined);
233
242
  return () => controller.abort();
234
- }, [taskId, taskHistory, feedLength]);
243
+ }, [taskId, taskHistory, taskComments, feedLength]);
235
244
  if (task === undefined) {
236
245
  return (_jsx(EmptyState, { title: words.task.noSuch.title, body: words.task.noSuch.body, action: _jsx(LinkButton, { href: projectHref(key), children: words.nav.board }) }));
237
246
  }
238
247
  const here = taskHref(key, task.number);
239
- return (_jsx(components.TaskView, { task: task, people: data.people.filter(inWorkspace), tasks: data.tasks, decisions: data.decisions, runs: data.runs, history: history, categories: data.categories, goals: data.goals, taskHref: (candidate) => taskHref(key, candidate.number), decisionHref: (decisionId) => decisionHref(key, decisionId), goalHref: (goalId) => goalHref(key, goalId), fileHref: (artifact) => projectPath(key, "files", artifact.id), docHref: (path) => docHref(key, path), form: route.form, formHref: (form) => taskHref(key, task.number, form), onCancel: () => navigation.back(here), busy: busy, error: error, onChange: (target, patch) => void act(async () => {
248
+ return (_jsx(components.TaskView, { task: task, people: data.people.filter(inWorkspace), tasks: data.tasks, decisions: data.decisions, runs: data.runs, comments: comments, history: history, categories: data.categories, goals: data.goals, taskHref: (candidate) => taskHref(key, candidate.number), decisionHref: (decisionId) => decisionHref(key, decisionId), goalHref: (goalId) => goalHref(key, goalId), fileHref: (fileId) => projectPath(key, "files", fileId), docHref: (path) => docHref(key, path), form: route.form, formHref: (form) => taskHref(key, task.number, form), onCancel: () => navigation.back(here), busy: busy, error: error, onChange: (target, patch) => void act(async () => {
240
249
  await data.actions.updateTask(target.id, patch);
241
250
  navigation.replace(here);
242
251
  }), onMove: (target, state) => void act(() => data.actions.updateTask(target.id, { state })), onRaiseDecision: (input) => void act(async () => {
243
252
  await data.actions.raiseDecision(input);
244
253
  navigation.replace(here);
245
- }), onAnswer: (decision, input) => void act(() => data.actions.answerDecision(decision.id, input)), onUpdateDecision: (decision, patch) => void act(() => data.actions.updateDecision(decision.id, patch)), onAbandonRun: (run) => void act(() => data.actions.abandonRun(run.id)) }));
254
+ }), onAnswer: (decision, input) => void act(() => data.actions.answerDecision(decision.id, input)), onUpdateDecision: (decision, patch) => void act(() => data.actions.updateDecision(decision.id, patch)), onAbandonRun: (run) => void act(() => data.actions.abandonRun(run.id)), onComment: (draft) => void act(async () => {
255
+ await data.actions.comment(task.id, {
256
+ body: draft.body,
257
+ files: draft.files.map((file) => ({
258
+ name: file.name,
259
+ bytes: file,
260
+ ...(file.type === "" ? {} : { contentType: file.type }),
261
+ })),
262
+ });
263
+ setComments(await taskComments(task.id));
264
+ }) }));
246
265
  }
247
266
  function ProjectPage(props) {
248
267
  const words = useWords();
@@ -279,7 +298,7 @@ function ProjectPage(props) {
279
298
  const overdue = open.filter((task) => task.dueOn !== null && task.dueOn < now).sort(byDue);
280
299
  const unscheduled = open.filter((task) => task.dueOn === null).sort(byDue);
281
300
  const calendar = words.calendar;
282
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: calendar.title }), _jsx(LinkButton, { href: newTaskHref(key), variant: "primary", children: words.board.writeTask })] }), data.tasks.length > 0 && (_jsx(BoardFilters, { filter: route.filter, categories: data.categories, goals: data.goals, people: data.people.filter(inWorkspace), me: me, shown: shown.length, total: data.tasks.length, onChange: (filter) => navigation.replace(calendarHref(key, route.month, filter)) })), _jsx(components.Calendar, { tasks: shown, month: month, today: now, categories: data.categories, goals: data.goals, taskHref: href, monthHref: (wanted) => calendarHref(key, wanted, route.filter) }), _jsxs("div", { className: "sc-calendar-below", children: [_jsxs("section", { className: "sc-task-section", "aria-label": calendar.overdue, children: [_jsxs("h2", { className: "sc-section-title", children: [calendar.overdue, " ", _jsx("span", { className: "sc-column-count", children: overdue.length })] }), _jsx(TaskList, { tasks: overdue, taskHref: href, today: now, showState: true, empty: _jsx("p", { className: "sc-muted", children: calendar.nothingOverdue }) })] }), _jsxs("section", { className: "sc-task-section", "aria-label": calendar.unscheduled, children: [_jsxs("h2", { className: "sc-section-title", children: [calendar.unscheduled, " ", _jsx("span", { className: "sc-column-count", children: unscheduled.length })] }), _jsx(TaskList, { tasks: unscheduled, taskHref: href, today: now, showState: true, empty: _jsx("p", { className: "sc-muted", children: calendar.allScheduled }) })] })] }), open.length > 0 && (_jsxs("section", { className: "sc-task-section", "aria-label": calendar.workload.title, children: [_jsx("h2", { className: "sc-section-title", children: calendar.workload.title }), _jsx(Workload, { tasks: shown, today: now, personHref: (person) => boardHref(key, person === undefined ? {} : { person: person.id }) })] }))] }));
301
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: calendar.title }), _jsx(LinkButton, { href: newTaskHref(key), variant: "primary", children: words.board.writeTask })] }), data.tasks.length > 0 && (_jsx(BoardFilters, { filter: route.filter, categories: data.categories, goals: data.goals, people: data.people.filter(inWorkspace), me: me, shown: shown.length, total: data.tasks.length, onChange: (filter) => navigation.replace(calendarHref(key, route.month, filter)) })), _jsx(components.Calendar, { tasks: shown, month: month, today: now, categories: data.categories, goals: data.goals, taskHref: href, goalHref: (goal) => goalHref(key, goal.id), monthHref: (wanted) => calendarHref(key, wanted, route.filter) }), _jsxs("div", { className: "sc-calendar-below", children: [_jsxs("section", { className: "sc-task-section", "aria-label": calendar.overdue, children: [_jsxs("h2", { className: "sc-section-title", children: [calendar.overdue, " ", _jsx("span", { className: "sc-column-count", children: overdue.length })] }), _jsx(TaskList, { tasks: overdue, taskHref: href, today: now, showState: true, empty: _jsx("p", { className: "sc-muted", children: calendar.nothingOverdue }) })] }), _jsxs("section", { className: "sc-task-section", "aria-label": calendar.unscheduled, children: [_jsxs("h2", { className: "sc-section-title", children: [calendar.unscheduled, " ", _jsx("span", { className: "sc-column-count", children: unscheduled.length })] }), _jsx(TaskList, { tasks: unscheduled, taskHref: href, today: now, showState: true, empty: _jsx("p", { className: "sc-muted", children: calendar.allScheduled }) })] })] }), open.length > 0 && (_jsxs("section", { className: "sc-task-section", "aria-label": calendar.workload.title, children: [_jsx("h2", { className: "sc-section-title", children: calendar.workload.title }), _jsx(Workload, { tasks: shown, today: now, personHref: (person) => boardHref(key, person === undefined ? {} : { person: person.id }) })] }))] }));
283
302
  }
284
303
  if (route.name === "roadmap" || route.name === "new-goal") {
285
304
  const roadmap = words.roadmap;
@@ -287,10 +306,10 @@ function ProjectPage(props) {
287
306
  if (making && !owner) {
288
307
  return _jsx(EmptyState, { title: roadmap.onlyOwner.title, body: roadmap.onlyOwner.body });
289
308
  }
290
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: roadmap.title }), !making && owner && (_jsx(LinkButton, { href: newGoalHref(key), variant: "primary", children: roadmap.setGoal }))] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), making && (_jsx("section", { className: "sc-panel sc-panel-form", "aria-label": roadmap.setGoalAria, children: _jsx(GoalForm, { busy: busy, onSubmit: (input) => void act(async () => {
309
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: roadmap.title }), !making && owner && (_jsx(LinkButton, { href: newGoalHref(key), variant: "primary", children: roadmap.setGoal }))] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), making && (_jsx("section", { className: "sc-panel sc-panel-form", "aria-label": roadmap.setGoalAria, children: _jsx(GoalForm, { categories: data.categories, busy: busy, onSubmit: (input) => void act(async () => {
291
310
  const made = await data.actions.createGoal(input);
292
311
  navigation.replace(goalHref(key, made.id));
293
- }), onCancel: () => navigation.back(projectHref(key, "roadmap")) }) })), _jsx(components.GoalList, { goals: data.goals, goalHref: (goal) => goalHref(key, goal.id), empty: _jsx(EmptyState, { title: roadmap.empty.title, body: roadmap.empty.body, action: owner ? (_jsx(LinkButton, { href: newGoalHref(key), children: roadmap.setGoal })) : undefined }) })] }));
312
+ }), onCancel: () => navigation.back(projectHref(key, "roadmap")) }) })), data.goals.length > 0 && (_jsx(GoalTimeline, { goals: data.goals, from: route.name === "roadmap" && route.from !== undefined ? route.from : monthOf(today()), today: today(), categories: data.categories, goalHref: (goal) => goalHref(key, goal.id), fromHref: (month) => roadmapHref(key, month) })), _jsx(components.GoalList, { goals: data.goals, goalHref: (goal) => goalHref(key, goal.id), empty: _jsx(EmptyState, { title: roadmap.empty.title, body: roadmap.empty.body, action: owner ? (_jsx(LinkButton, { href: newGoalHref(key), children: roadmap.setGoal })) : undefined }) })] }));
294
313
  }
295
314
  if (route.name === "goal") {
296
315
  const roadmap = words.roadmap;
@@ -303,7 +322,7 @@ function ProjectPage(props) {
303
322
  if (!owner) {
304
323
  return _jsx(EmptyState, { title: roadmap.onlyOwner.title, body: roadmap.onlyOwner.body });
305
324
  }
306
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: goal.title }) }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx("section", { className: "sc-panel sc-panel-form", "aria-label": roadmap.editAria, children: _jsx(GoalForm, { goal: goal, busy: busy, onSubmit: (input) => void act(async () => {
325
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "sc-page-head", children: _jsx("h1", { className: "sc-page-title", children: goal.title }) }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), _jsx("section", { className: "sc-panel sc-panel-form", "aria-label": roadmap.editAria, children: _jsx(GoalForm, { goal: goal, categories: data.categories, busy: busy, onSubmit: (input) => void act(async () => {
307
326
  await data.actions.updateGoal(goal.id, input);
308
327
  navigation.replace(here);
309
328
  }), onCancel: () => navigation.back(here) }) })] }));
@@ -520,7 +539,7 @@ function PersonAgentsPage(props) {
520
539
  if (!administrator) {
521
540
  return (_jsx(EmptyState, { title: words.people.onlyAdmin.title, body: words.people.onlyAdmin.body, action: _jsx(LinkButton, { href: PATHS.agents, children: words.nav.agents }) }));
522
541
  }
523
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.people.agentsOf(person === undefined ? "?" : personName(person)) }), _jsx(LinkButton, { href: PATHS.people, children: words.nav.people })] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), tokens === undefined ? (_jsx("div", { className: "sc-loading", children: _jsx(Spinner, { label: words.people.loadingAgents }) })) : (_jsx(components.TokenList, { tokens: tokens, busy: busy, onRevoke: (token) => void act(async () => {
542
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: words.people.agentsOf(person === undefined ? "?" : personName(person)) }), _jsx(LinkButton, { href: PATHS.people, children: words.nav.people })] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), tokens === undefined ? (_jsx("div", { className: "sc-loading", children: _jsx(Spinner, { label: words.people.loadingAgents }) })) : (_jsx(components.TokenList, { tokens: tokens, busy: busy, consoleVersion: data.me?.console?.version, onRevoke: (token) => void act(async () => {
524
543
  await data.actions.revokePersonToken(id, token.id);
525
544
  setGeneration((current) => current + 1);
526
545
  }), empty: _jsx(EmptyState, { title: words.people.noAgent }) }))] }));
@@ -635,7 +654,7 @@ function WorkspacePage(props) {
635
654
  return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "sc-page-head", children: [_jsx("h1", { className: "sc-page-title", children: agents.title }), !making && (_jsx(LinkButton, { href: PATHS.newToken, variant: "primary", children: agents.makeByHand }))] }), error !== undefined && _jsx(Callout, { tone: "danger", children: error }), fresh !== undefined && (_jsx(NewToken, { token: fresh.token, secret: fresh.secret, onDone: () => setFresh(undefined) })), making && (_jsx("section", { className: "sc-panel sc-panel-form", "aria-label": agents.makeAria, children: _jsx(TokenForm, { daysAtMost: data.me?.workspace.tokenDaysAtMost, busy: busy, onSubmit: (input) => void act(async () => {
636
655
  setFresh(await data.actions.createToken(input));
637
656
  navigation.replace(PATHS.agents);
638
- }), onCancel: () => navigation.back(PATHS.agents) }) })), _jsx(components.TokenList, { tokens: data.tokens, busy: busy, onRevoke: (token) => void act(() => data.actions.revokeToken(token.id)), empty: _jsx(EmptyState, { title: agents.empty.title, body: agents.empty.body }) }), _jsx(ConnectWords, { origin: origin })] }));
657
+ }), onCancel: () => navigation.back(PATHS.agents) }) })), _jsx(components.TokenList, { tokens: data.tokens, busy: busy, consoleVersion: data.me?.console?.version, onRevoke: (token) => void act(() => data.actions.revokeToken(token.id)), empty: _jsx(EmptyState, { title: agents.empty.title, body: agents.empty.body }) }), _jsx(ConnectWords, { origin: origin })] }));
639
658
  }
640
659
  return _jsx(NothingHere, {});
641
660
  }