@heyramzi/ui 2.1.0 → 2.2.0

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 (312) hide show
  1. package/package.json +7 -8
  2. package/scripts/sync-shadcn.mjs +3 -4
  3. package/src/agents/agent-avatar.svelte +604 -575
  4. package/src/agents/agent-cast.svelte +179 -183
  5. package/src/agents/demo.svelte +125 -113
  6. package/src/agents/helpers.ts +23 -17
  7. package/src/agents/index.ts +4 -4
  8. package/src/agents/page-state.ts +6 -6
  9. package/src/agents/types.ts +6 -6
  10. package/src/ai/ai-button/AiButton.svelte +4 -12
  11. package/src/ai/generation-progress/GenerationProgress.svelte +10 -3
  12. package/src/ai/prompt-input/PromptInputTextarea.svelte +1 -2
  13. package/src/ai/response/Response.css +2 -3
  14. package/src/animations/avatar-group-hover.css +2 -16
  15. package/src/animations/card-tilt.css +3 -6
  16. package/src/animations/digit-pop-in.css +2 -15
  17. package/src/animations/dropdown.css +4 -17
  18. package/src/animations/input-clear-dissolve.css +5 -18
  19. package/src/animations/input-shake.css +9 -41
  20. package/src/animations/learn-more-hover.css +17 -9
  21. package/src/animations/like-button.css +2 -4
  22. package/src/animations/page-side-by-side.css +2 -10
  23. package/src/animations/plus-menu-morph.css +2 -5
  24. package/src/animations/shimmer-text.css +5 -18
  25. package/src/animations/spinning-counter.css +2 -6
  26. package/src/animations/success-check.css +2 -15
  27. package/src/animations/thinking-states.css +2 -7
  28. package/src/brand/brand.test.ts +21 -5
  29. package/src/brand/index.ts +4 -10
  30. package/src/canvas/card/card-frame.svelte +43 -39
  31. package/src/canvas/card/resize-handles.svelte +89 -80
  32. package/src/canvas/chrome/chrome-zoom.svelte +101 -100
  33. package/src/canvas/chrome/lock-badge.svelte +8 -8
  34. package/src/canvas/chrome/side-handles.svelte +24 -19
  35. package/src/canvas/chrome/size-chip.svelte +30 -30
  36. package/src/canvas/chrome/snap-guides.svelte +20 -20
  37. package/src/canvas/components/icons/ToolIcon.svelte +8 -8
  38. package/src/canvas/components/shared/svg/PreviewSvg.svelte +19 -19
  39. package/src/canvas/components/shared/svg/ShapeOutline.svelte +71 -48
  40. package/src/canvas/components/shared/svg/StrokeNode.svelte +21 -27
  41. package/src/canvas/components/shared/svg/TextRule.svelte +25 -17
  42. package/src/canvas/edges/bend-handle.svelte +46 -46
  43. package/src/canvas/edges/edge-gradient.svelte +10 -10
  44. package/src/canvas/edges/gradient-edge.svelte +45 -29
  45. package/src/canvas/editor/lock.test.ts +6 -1
  46. package/src/canvas/editor/style.ts +7 -1
  47. package/src/canvas/headless/svg-figure.test.ts +5 -1
  48. package/src/canvas/lod/lod-switch.svelte +111 -106
  49. package/src/canvas/pen/PenField.svelte +87 -81
  50. package/src/canvas/pen/PenOverlay.svelte +127 -127
  51. package/src/canvas/pen/ShapeNode.svelte +31 -32
  52. package/src/canvas/pen/TextNode.svelte +54 -53
  53. package/src/canvas/pen/host-field.test.svelte +7 -7
  54. package/src/canvas/pen/shapes.ts +7 -1
  55. package/src/canvas/screen/GlyphIcon.svelte +22 -17
  56. package/src/canvas/screen/PartView.svelte +138 -72
  57. package/src/canvas/screen/ScreenBody.svelte +81 -60
  58. package/src/canvas/screen/ScreenCard.svelte +20 -20
  59. package/src/canvas/ui/CanvasToolbar.svelte +173 -85
  60. package/src/canvas/ui/FrameLayer.svelte +59 -59
  61. package/src/canvas/ui/PenLayer.svelte +39 -30
  62. package/src/canvas/ui/StylePanel.svelte +119 -102
  63. package/src/canvas/ui/canvas-grid.svelte +137 -129
  64. package/src/charts/animated-value.svelte +1 -1
  65. package/src/charts/area-chart.css +2 -5
  66. package/src/charts/area-chart.svelte +1 -1
  67. package/src/charts/bar-chart.css +2 -3
  68. package/src/charts/bar-chart.svelte +1 -1
  69. package/src/charts/charts.css +5 -17
  70. package/src/charts/crosshair.svelte +1 -1
  71. package/src/charts/dashboard/dashboard-empty.svelte +25 -25
  72. package/src/charts/dashboard/dashboard-section.svelte +24 -24
  73. package/src/charts/dashboard/data-panel.svelte +50 -50
  74. package/src/charts/dashboard/data-sort-head.svelte +56 -56
  75. package/src/charts/dashboard/data-table.svelte +138 -138
  76. package/src/charts/dashboard/panel-grid.svelte +30 -30
  77. package/src/charts/dashboard/period-filter.svelte +25 -25
  78. package/src/charts/dashboard/rating-chip.svelte +19 -19
  79. package/src/charts/dashboard/stat-band.svelte +32 -32
  80. package/src/charts/dashboard/stat-tile.svelte +106 -99
  81. package/src/charts/donut-chart.svelte +1 -1
  82. package/src/charts/edge-fade.svelte +1 -1
  83. package/src/charts/figure.svelte +1 -1
  84. package/src/charts/gauge-chart.css +4 -7
  85. package/src/charts/gauge-chart.svelte +1 -1
  86. package/src/charts/hover-focus.svelte +1 -1
  87. package/src/charts/legend.css +1 -3
  88. package/src/charts/legend.svelte +1 -1
  89. package/src/charts/line-chart.svelte +1 -1
  90. package/src/charts/number-chart.css +6 -9
  91. package/src/charts/number-chart.svelte +1 -1
  92. package/src/charts/reference-line.svelte +19 -19
  93. package/src/charts/reveal.svelte +1 -1
  94. package/src/charts/ring-chart.css +2 -4
  95. package/src/charts/ring-chart.svelte +1 -1
  96. package/src/charts/sparkline.svelte +5 -2
  97. package/src/charts/stat-card.svelte +1 -1
  98. package/src/charts/time-series-chart.css +2 -5
  99. package/src/charts/trend-pill.css +2 -4
  100. package/src/charts/trend-pill.svelte +1 -1
  101. package/src/components/copy/copy-button.svelte +93 -98
  102. package/src/components/copy/copy-button.test.ts +10 -2
  103. package/src/components/data-table/infinite-scroll.svelte +42 -42
  104. package/src/components/data-table/pagination.svelte +34 -22
  105. package/src/components/data-table/row-arrow.svelte +19 -16
  106. package/src/components/data-table/row-context-menu.svelte +52 -52
  107. package/src/components/data-table/sortable-head.svelte +25 -25
  108. package/src/components/data-table/table-skeleton.svelte +41 -36
  109. package/src/components/docs/doc-page.svelte +18 -9
  110. package/src/components/docs/on-this-page.svelte +16 -3
  111. package/src/components/docs/scroll-spy.svelte.ts +2 -3
  112. package/src/components/field-row/field-row.svelte +10 -8
  113. package/src/components/hold-to-confirm/hold-to-confirm.svelte +5 -1
  114. package/src/components/icon/icon.svelte +14 -14
  115. package/src/components/language-flag/language-flag.svelte +3 -1
  116. package/src/components/list-page/detail-empty.svelte +34 -34
  117. package/src/components/list-page/detail-header.svelte +55 -47
  118. package/src/components/list-page/detail-panel.svelte +51 -59
  119. package/src/components/list-page/detail-row.svelte +19 -19
  120. package/src/components/list-page/detail-stack.svelte +21 -21
  121. package/src/components/list-page/empty-state.svelte +30 -30
  122. package/src/components/list-page/filter-item.svelte +20 -20
  123. package/src/components/list-page/filter-popover.svelte +60 -55
  124. package/src/components/list-page/grouped-list.svelte +4 -2
  125. package/src/components/list-page/index.ts +5 -1
  126. package/src/components/list-page/list-page-shell.svelte +2 -5
  127. package/src/components/list-page/master-detail.svelte +87 -88
  128. package/src/components/list-page/notice-bar.svelte +38 -38
  129. package/src/components/list-page/prev-next.svelte +63 -63
  130. package/src/components/list-page/rail-body.svelte +18 -18
  131. package/src/components/list-page/rail-empty.svelte +23 -30
  132. package/src/components/list-page/rail-head.svelte +24 -24
  133. package/src/components/list-page/rail-row.svelte +77 -73
  134. package/src/components/list-page/section-host.ts +2 -3
  135. package/src/components/locale-switch/locale-switch.svelte +41 -41
  136. package/src/components/mark/mark.svelte +34 -38
  137. package/src/components/open-in/index.ts +1 -5
  138. package/src/components/open-in/open-in.svelte +40 -40
  139. package/src/components/picker/mark-picker.svelte +49 -49
  140. package/src/components/picker/picker.svelte +5 -3
  141. package/src/components/section-header/section-header.test.ts +7 -1
  142. package/src/components/section-header/section-label.svelte +20 -20
  143. package/src/components/segmented/animated-tabs.svelte +31 -2
  144. package/src/components/segmented/collapse.test.ts +2 -1
  145. package/src/components/segmented/index.ts +2 -0
  146. package/src/components/segmented/segment.svelte +52 -49
  147. package/src/components/segmented/segmented-filter.svelte +79 -80
  148. package/src/components/segmented/segmented-nav.svelte +34 -40
  149. package/src/components/segmented/segmented-overflow.svelte +53 -50
  150. package/src/components/segmented/segmented-track.svelte +62 -46
  151. package/src/components/segmented/segmented.ts +2 -3
  152. package/src/components/star-rating-input/star-rating-input.svelte +103 -103
  153. package/src/components/svg/svg.svelte +4 -4
  154. package/src/components/table-view/table-view.svelte +17 -2
  155. package/src/components/table-view/table-view.test.ts +7 -1
  156. package/src/components/table-view/types.ts +11 -11
  157. package/src/components/tags-input/index.ts +13 -0
  158. package/src/components/tags-input/tags-input.svelte +305 -0
  159. package/src/components/tags-input/tags.test.ts +64 -0
  160. package/src/components/tags-input/tags.ts +142 -0
  161. package/src/components/theme/index.ts +2 -4
  162. package/src/components/theme/theme-provider.svelte +1 -3
  163. package/src/components/toolbar/toolbar-search.svelte +25 -25
  164. package/src/components/toolbar/toolbar.svelte +11 -7
  165. package/src/components/toolbar/toolbar.test.ts +10 -1
  166. package/src/design/index.css +21 -78
  167. package/src/design/polish.css +26 -35
  168. package/src/editor/editor-toolbar.svelte +104 -99
  169. package/src/editor/editor.svelte +296 -266
  170. package/src/editor/image-toolbar.svelte +20 -22
  171. package/src/editor/index.ts +1 -4
  172. package/src/editor/inline-editor.svelte +280 -238
  173. package/src/editor/markdown.ts +15 -15
  174. package/src/editor/renderer.svelte +71 -71
  175. package/src/editor/slash-menu.svelte +24 -27
  176. package/src/effects/animated-beam/diagrams/BeamSvg.svelte +1 -1
  177. package/src/effects/image-comparison/ImageComparison.svelte +11 -1
  178. package/src/effects/interactive-hover-button/InteractiveHoverButton.svelte +59 -46
  179. package/src/effects/magic-card/MagicCard.css +14 -7
  180. package/src/effects/marquee/Marquee.svelte +3 -5
  181. package/src/effects/reveal/observe.ts +0 -3
  182. package/src/effects/spotlight/Spotlight.svelte +1 -1
  183. package/src/effects/theme-toggle/ThemeToggle.css +25 -22
  184. package/src/effects/theme-toggle/ThemeToggle.svelte +6 -7
  185. package/src/gallery.test.ts +14 -4
  186. package/src/inbox/README.md +1 -3
  187. package/src/inbox/inbox.test.ts +181 -138
  188. package/src/inbox/index.ts +20 -20
  189. package/src/inbox/logic.ts +114 -111
  190. package/src/inbox/thread-inbox.svelte +227 -151
  191. package/src/inbox/types.ts +130 -108
  192. package/src/lib/theme-transition.ts +2 -4
  193. package/src/lib/tone.ts +2 -4
  194. package/src/lib/utils.ts +2 -2
  195. package/src/modules.test.ts +79 -69
  196. package/src/onboarding/define-tours.test.ts +55 -40
  197. package/src/onboarding/define-tours.ts +23 -23
  198. package/src/onboarding/demo.svelte +24 -5
  199. package/src/onboarding/index.ts +1 -8
  200. package/src/onboarding/onboarding-provider.svelte +19 -7
  201. package/src/onboarding/onboarding.svelte.ts +16 -16
  202. package/src/onboarding/pick.test.ts +61 -52
  203. package/src/onboarding/pick.ts +16 -13
  204. package/src/onboarding/stores.test.ts +80 -80
  205. package/src/onboarding/stores.ts +41 -39
  206. package/src/onboarding/tour-card.svelte +30 -5
  207. package/src/onboarding/tour-runner.svelte +12 -3
  208. package/src/onboarding/types.ts +20 -12
  209. package/src/onboarding/wait.ts +22 -22
  210. package/src/panel/side-panel.svelte +94 -93
  211. package/src/record/demo-data.ts +291 -225
  212. package/src/record/field-section.svelte +38 -34
  213. package/src/record/fields.ts +148 -96
  214. package/src/record/format.ts +63 -56
  215. package/src/record/index.ts +49 -35
  216. package/src/record/info-list.svelte +145 -114
  217. package/src/record/kinds.ts +31 -31
  218. package/src/record/logic.ts +216 -214
  219. package/src/record/next-up.svelte +45 -34
  220. package/src/record/project-list.svelte +56 -50
  221. package/src/record/record-demo.svelte +130 -110
  222. package/src/record/record-header.svelte +37 -28
  223. package/src/record/record-shell.svelte +54 -54
  224. package/src/record/record-stats.svelte +25 -25
  225. package/src/record/record-timeline.svelte +134 -114
  226. package/src/record/record.test.ts +430 -309
  227. package/src/record/steps-rail.svelte +225 -216
  228. package/src/record/types.ts +234 -215
  229. package/src/record/where-we-are.svelte +62 -58
  230. package/src/shadcn/button/button.svelte +1 -1
  231. package/src/shadcn/card/card-title.svelte +1 -5
  232. package/src/shadcn/hooks/use-highlighted-code.svelte.ts +2 -13
  233. package/src/shadcn/sheet/sheet-content.svelte +2 -4
  234. package/src/shadcn/table/table-cell.svelte +2 -3
  235. package/src/shadcn/utilities.css +3 -8
  236. package/src/slides/Controls.svelte +150 -124
  237. package/src/slides/Deck.svelte +243 -238
  238. package/src/slides/Fragment.svelte +64 -57
  239. package/src/slides/Overview.svelte +106 -101
  240. package/src/slides/Presenter.svelte +300 -266
  241. package/src/slides/Slide.svelte +185 -170
  242. package/src/slides/SlideList.svelte +16 -12
  243. package/src/slides/ambient.d.ts +1 -1
  244. package/src/slides/bridges.ts +42 -23
  245. package/src/slides/deck-controller.svelte.ts +47 -35
  246. package/src/slides/demo-slides.svelte +330 -306
  247. package/src/slides/demo.svelte +164 -160
  248. package/src/slides/export/capture.ts +20 -16
  249. package/src/slides/export/ffmpeg.ts +43 -38
  250. package/src/slides/export/index.ts +5 -5
  251. package/src/slides/export/launch.ts +3 -1
  252. package/src/slides/export/pdf.ts +30 -27
  253. package/src/slides/export/types.ts +10 -8
  254. package/src/slides/index.ts +11 -11
  255. package/src/slides/labels.ts +22 -19
  256. package/src/slides/layout.ts +9 -2
  257. package/src/slides/model.ts +4 -4
  258. package/src/slides/navigation.ts +43 -31
  259. package/src/slides/theme.css +5 -7
  260. package/src/slides/types.ts +9 -10
  261. package/src/status/define-statuses.ts +17 -24
  262. package/src/status/index.ts +5 -5
  263. package/src/status/status-badge.svelte +3 -1
  264. package/src/status/status-dot.svelte +1 -3
  265. package/src/status/status-icon.svelte +1 -1
  266. package/src/status/status-types.ts +21 -21
  267. package/src/tasks/board-order.ts +2 -4
  268. package/src/tasks/demo.svelte +189 -31
  269. package/src/tasks/detail/detail-demo.svelte +73 -13
  270. package/src/tasks/detail/detail-types.ts +45 -45
  271. package/src/tasks/detail/task-detail.svelte +40 -10
  272. package/src/tasks/detail/task-property.svelte +8 -2
  273. package/src/tasks/detail/task-thread.svelte +53 -12
  274. package/src/tasks/gantt/gantt-bar.svelte +17 -6
  275. package/src/tasks/gantt/gantt-grid.svelte +40 -9
  276. package/src/tasks/gantt/gantt-group-row.svelte +8 -2
  277. package/src/tasks/gantt/gantt-header.svelte +9 -3
  278. package/src/tasks/gantt/gantt-task-row.svelte +26 -6
  279. package/src/tasks/gantt/gantt.css +2 -1
  280. package/src/tasks/gantt/gantt.test.ts +3 -1
  281. package/src/tasks/gantt/logic.test.ts +110 -20
  282. package/src/tasks/gantt/logic.ts +42 -6
  283. package/src/tasks/inbox/inbox-card.svelte +13 -5
  284. package/src/tasks/inbox/inbox-draft.svelte +1 -1
  285. package/src/tasks/inbox/inbox-logic.ts +6 -40
  286. package/src/tasks/inbox/inbox-statuses.ts +23 -23
  287. package/src/tasks/inbox/inbox-trace.svelte +9 -3
  288. package/src/tasks/inbox/inbox-types.ts +54 -58
  289. package/src/tasks/inbox/index.ts +22 -21
  290. package/src/tasks/index.ts +49 -52
  291. package/src/tasks/kanban-board.svelte +16 -12
  292. package/src/tasks/kanban-types.ts +2 -3
  293. package/src/tasks/presets/sales.ts +6 -6
  294. package/src/tasks/task-gantt.svelte +28 -8
  295. package/src/tasks/task-list.svelte +41 -17
  296. package/src/tasks/time/duration.ts +40 -40
  297. package/src/tasks/time/time-chip.svelte +9 -2
  298. package/src/tasks/time/time-dot.svelte +1 -1
  299. package/src/tasks/time/time-ring.svelte +11 -3
  300. package/src/tasks/time/time-tracker.svelte +57 -15
  301. package/src/tasks/time/time-types.ts +57 -57
  302. package/src/tasks/use-kanban-dnd.svelte.ts +2 -3
  303. package/src/thread/index.ts +7 -7
  304. package/src/thread/logic.ts +36 -33
  305. package/src/thread/thread.svelte +82 -16
  306. package/src/thread/thread.test.ts +58 -47
  307. package/src/thread/types.ts +68 -68
  308. package/src/tokens/craft.css +17 -53
  309. package/src/tokens/index.css +3 -13
  310. package/src/tokens/palette.css +13 -11
  311. package/src/tokens/primitives.css +10 -23
  312. package/src/tasks/inbox/inbox.svelte +0 -203
@@ -68,7 +68,8 @@ export function spanOf<T>(item: T, { getStart, getEnd }: Dates<T>): Span | null
68
68
  export function liveSpan(span: Span | null, drag: Drag | null, id: string): Span | null {
69
69
  if (!span || drag?.id !== id || drag.dx === 0) return span;
70
70
  if (drag.mode === "move") return { start: span.start + drag.dx, end: span.end + drag.dx };
71
- if (drag.mode === "start") return { start: Math.min(span.start + drag.dx, span.end), end: span.end };
71
+ if (drag.mode === "start")
72
+ return { start: Math.min(span.start + drag.dx, span.end), end: span.end };
72
73
  return { start: span.start, end: Math.max(span.end + drag.dx, span.start) };
73
74
  }
74
75
 
@@ -103,7 +104,13 @@ export function buildDays(first: number, count: number) {
103
104
  return Array.from({ length: count }, (_, i) => {
104
105
  const day = first + i;
105
106
  const wd = weekday(day);
106
- return { day, i, date: Number(isoFromDay(day).slice(8, 10)), wd, weekend: wd === 0 || wd === 6 };
107
+ return {
108
+ day,
109
+ i,
110
+ date: Number(isoFromDay(day).slice(8, 10)),
111
+ wd,
112
+ weekend: wd === 0 || wd === 6,
113
+ };
107
114
  });
108
115
  }
109
116
  export type GanttDay = ReturnType<typeof buildDays>[number];
@@ -133,7 +140,17 @@ export function buildRows<T>(items: T[], source: RowSource<T>): Row<T>[] {
133
140
  for (const item of members) {
134
141
  const id = getId(item);
135
142
  const own = live(item, id);
136
- out.push({ kind: "task", item, id, order: order++, depth: 0, hasChildren: false, open: true, own, span: own });
143
+ out.push({
144
+ kind: "task",
145
+ item,
146
+ id,
147
+ order: order++,
148
+ depth: 0,
149
+ hasChildren: false,
150
+ open: true,
151
+ own,
152
+ span: own,
153
+ });
137
154
  }
138
155
  return;
139
156
  }
@@ -149,7 +166,17 @@ export function buildRows<T>(items: T[], source: RowSource<T>): Row<T>[] {
149
166
  const children = kids.get(id) ?? [];
150
167
  const open = !folded.has(id);
151
168
  const own = live(item, id);
152
- const row: TaskRow<T> = { kind: "task", item, id, order: 0, depth, hasChildren: children.length > 0, open, own, span: own };
169
+ const row: TaskRow<T> = {
170
+ kind: "task",
171
+ item,
172
+ id,
173
+ order: 0,
174
+ depth,
175
+ hasChildren: children.length > 0,
176
+ open,
177
+ own,
178
+ span: own,
179
+ };
153
180
  if (visible) {
154
181
  row.order = order++;
155
182
  out.push(row);
@@ -195,7 +222,11 @@ export function roundedPath(points: [number, number][], radius: number): string
195
222
  }
196
223
 
197
224
  /** Each arrow runs from the end of the task waited on to the start of the one waiting. */
198
- export function buildArrows<T>(rows: Row<T>[], layout: Layout, getDependsOn: (item: T) => string[] | undefined): Arrow[] {
225
+ export function buildArrows<T>(
226
+ rows: Row<T>[],
227
+ layout: Layout,
228
+ getDependsOn: (item: T) => string[] | undefined,
229
+ ): Arrow[] {
199
230
  const { rowHeight, inset } = layout;
200
231
  const at = new Map<string, { row: number; span: Span }>();
201
232
  rows.forEach((row, index) => {
@@ -216,7 +247,12 @@ export function buildArrows<T>(rows: Row<T>[], layout: Layout, getDependsOn: (it
216
247
  // Room between the bars: one bend in the gap. No room: out, round the row gap, and back in.
217
248
  const points: [number, number][] =
218
249
  x2 - x1 >= 24
219
- ? [[x1, y1], [x1 + 12, y1], [x1 + 12, y2], [x2, y2]]
250
+ ? [
251
+ [x1, y1],
252
+ [x1 + 12, y1],
253
+ [x1 + 12, y2],
254
+ [x2, y2],
255
+ ]
220
256
  : [
221
257
  [x1, y1],
222
258
  [x1 + 10, y1],
@@ -29,7 +29,7 @@
29
29
  onverdict: (verdict: InboxVerdict) => void;
30
30
  /** Replaces the summary lines, for a host that renders its own proposal. */
31
31
  renderProposal?: Snippet<[InboxItem]>;
32
- };
32
+ }
33
33
 
34
34
  let { item, selected = false, onselect, onverdict, renderProposal }: Props = $props();
35
35
 
@@ -158,7 +158,9 @@
158
158
  class={cn(
159
159
  "flex flex-col gap-3 rounded-xl p-3 outline-none transition-[background-color,border-color,box-shadow] duration-[var(--duration-quick,120ms)] ease-[var(--ease-smooth-out,ease-out)]",
160
160
  "focus-visible:ring-ring/50 focus-visible:ring-3",
161
- open ? "border-border bg-card border shadow-[var(--elev-card,none)]" : "bg-muted/30 border border-transparent",
161
+ open
162
+ ? "border-border bg-card border shadow-[var(--elev-card,none)]"
163
+ : "bg-muted/30 border border-transparent",
162
164
  selected && open && "border-ring",
163
165
  )}
164
166
  >
@@ -228,7 +230,9 @@
228
230
  <div class="flex flex-col gap-1.5 pl-6">
229
231
  <PixelLoader label="Agent is re-running with your note" />
230
232
  {#if item.steer}
231
- <p class="text-muted-foreground border-border border-l-2 pl-3 text-sm">&ldquo;{item.steer}&rdquo;</p>
233
+ <p class="text-muted-foreground border-border border-l-2 pl-3 text-sm">
234
+ &ldquo;{item.steer}&rdquo;
235
+ </p>
232
236
  {/if}
233
237
  </div>
234
238
  {/if}
@@ -259,14 +263,18 @@
259
263
  <div class="flex flex-wrap items-center gap-2">
260
264
  <Button size="sm" onclick={submitSteer} disabled={!note.trim()}>Send to agent</Button>
261
265
  <Button size="sm" variant="ghost" onclick={() => (steering = false)}>Cancel</Button>
262
- <span class="text-muted-foreground text-xs max-sm:hidden">The agent retries with your note.</span>
266
+ <span class="text-muted-foreground text-xs max-sm:hidden"
267
+ >The agent retries with your note.</span
268
+ >
263
269
  </div>
264
270
  </div>
265
271
  {:else if open}
266
272
  <div class="flex flex-wrap items-center gap-2 pl-6">
267
273
  <Button size="sm" onclick={approve} aria-keyshortcuts="a">{sendLabel}</Button>
268
274
  {#if !drafts.some((d) => d.outcome === "decline")}
269
- <Button size="sm" variant="destructive" onclick={decline} aria-keyshortcuts="d">Decline</Button>
275
+ <Button size="sm" variant="destructive" onclick={decline} aria-keyshortcuts="d"
276
+ >Decline</Button
277
+ >
270
278
  {/if}
271
279
  <Button size="sm" variant="outline" onclick={steer} aria-keyshortcuts="s">Steer</Button>
272
280
  {#if drafts.length}
@@ -19,7 +19,7 @@
19
19
  bodyEl?: HTMLTextAreaElement | null;
20
20
  disabled?: boolean;
21
21
  class?: string;
22
- };
22
+ }
23
23
 
24
24
  let {
25
25
  drafts,
@@ -1,55 +1,21 @@
1
- import type {
2
- InboxDraft,
3
- InboxItem,
4
- InboxKindFilter,
5
- InboxLane,
6
- InboxProject,
7
- } from "./inbox-types.js";
8
-
9
- /** Which lane an item sits in. The agent's own work and the person's decisions never share one. */
10
- export function laneOf(item: InboxItem): InboxLane {
11
- if (item.tier === "auto") return "auto";
12
- return item.state === "proposed" || item.state === "working" ? "needs" : "decided";
13
- }
14
-
15
- export function inLane(items: InboxItem[], lane: InboxLane, kind: InboxKindFilter): InboxItem[] {
16
- return items.filter((item) => laneOf(item) === lane && (kind === "all" || item.kind === kind));
17
- }
18
-
19
- export type InboxGroup = { project: InboxProject; items: InboxItem[] };
20
-
21
- /** Group by project in order of first appearance, so the oldest waiting item keeps its place. */
22
- export function groupByProject(items: InboxItem[]): InboxGroup[] {
23
- const groups = new Map<string, InboxGroup>();
24
- for (const item of items) {
25
- const group = groups.get(item.project.id);
26
- if (group) group.items.push(item);
27
- else groups.set(item.project.id, { project: item.project, items: [item] });
28
- }
29
- return [...groups.values()];
30
- }
31
-
32
- /** Items in the order the screen shows them, so j and k walk what the eye sees. */
33
- export function flatten(groups: InboxGroup[]): InboxItem[] {
34
- return groups.flatMap((group) => group.items);
35
- }
1
+ import type { InboxDraft, InboxItem } from "./inbox-types.js";
36
2
 
37
3
  /** The draft to open on: the agent's pick, else the first. */
38
4
  export function startDraft(drafts: InboxDraft[], recommended?: string): InboxDraft | undefined {
39
- return drafts.find((draft) => draft.templateId === recommended) ?? drafts[0];
5
+ return drafts.find((draft) => draft.templateId === recommended) ?? drafts[0];
40
6
  }
41
7
 
42
8
  /** A person can act on an item only while it waits for them. */
43
9
  export function isOpen(item: InboxItem): boolean {
44
- return item.tier === "ask" && item.state === "proposed";
10
+ return item.tier === "ask" && item.state === "proposed";
45
11
  }
46
12
 
47
13
  export function canUndo(item: InboxItem): boolean {
48
- return item.tier === "auto" && item.state === "done";
14
+ return item.tier === "auto" && item.state === "done";
49
15
  }
50
16
 
51
17
  /** True when a key press belongs to a text field and so isn't a shortcut. */
52
18
  export function isTyping(target: EventTarget | null): boolean {
53
- if (!(target instanceof HTMLElement)) return false;
54
- return target.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(target.tagName);
19
+ if (!(target instanceof HTMLElement)) return false;
20
+ return target.isContentEditable || /^(INPUT|TEXTAREA|SELECT)$/.test(target.tagName);
55
21
  }
@@ -5,44 +5,44 @@ import type { InboxSourceType } from "./inbox-types.js";
5
5
 
6
6
  /** The lifecycle of an item. The dot and the badge both read this one map. */
7
7
  export const inboxStates = defineStatuses({
8
- proposed: { label: "Needs you", tone: "warning", variant: "open" },
9
- working: { label: "Agent working", tone: "accent", variant: "progress", progress: 0.6 },
10
- approved: { label: "Approved", tone: "success", variant: "completed" },
11
- declined: { label: "Declined", tone: "neutral", variant: "lost" },
12
- done: { label: "Done by agent", tone: "success", variant: "completed" },
13
- undone: { label: "Undone", tone: "neutral", variant: "lost" },
8
+ proposed: { label: "Needs you", tone: "warning", variant: "open" },
9
+ working: { label: "Agent working", tone: "accent", variant: "progress", progress: 0.6 },
10
+ approved: { label: "Approved", tone: "success", variant: "completed" },
11
+ declined: { label: "Declined", tone: "neutral", variant: "lost" },
12
+ done: { label: "Done by agent", tone: "success", variant: "completed" },
13
+ undone: { label: "Undone", tone: "neutral", variant: "lost" },
14
14
  });
15
15
 
16
16
  /** What the agent made of the touchpoint. */
17
17
  export const inboxKinds = defineStatuses({
18
- information: { label: "Information", tone: "info", variant: "filled" },
19
- action: { label: "Action", tone: "accent", variant: "filled" },
20
- decision: { label: "Decision", tone: "warning", variant: "filled" },
18
+ information: { label: "Information", tone: "info", variant: "filled" },
19
+ action: { label: "Action", tone: "accent", variant: "filled" },
20
+ decision: { label: "Decision", tone: "warning", variant: "filled" },
21
21
  });
22
22
 
23
23
  /** How sure the agent is, bucketed. The dot's fill carries the exact score. */
24
24
  export const inboxConfidence = defineStatuses({
25
- high: { label: "Confident", tone: "success", variant: "progress" },
26
- medium: { label: "Unsure", tone: "warning", variant: "progress" },
27
- low: { label: "Guessing", tone: "destructive", variant: "progress" },
25
+ high: { label: "Confident", tone: "success", variant: "progress" },
26
+ medium: { label: "Unsure", tone: "warning", variant: "progress" },
27
+ low: { label: "Guessing", tone: "destructive", variant: "progress" },
28
28
  });
29
29
 
30
30
  export function confidenceLevel(score: number): "high" | "medium" | "low" {
31
- if (score >= 0.8) return "high";
32
- if (score >= 0.5) return "medium";
33
- return "low";
31
+ if (score >= 0.8) return "high";
32
+ if (score >= 0.5) return "medium";
33
+ return "low";
34
34
  }
35
35
 
36
36
  export const SOURCE_ICON: Record<InboxSourceType, PhosphorIcon> = {
37
- call: Phone,
38
- email: EnvelopeSimple,
39
- slack: Hash,
40
- form: ClipboardText,
37
+ call: Phone,
38
+ email: EnvelopeSimple,
39
+ slack: Hash,
40
+ form: ClipboardText,
41
41
  };
42
42
 
43
43
  export const SOURCE_LABEL: Record<InboxSourceType, string> = {
44
- call: "Call",
45
- email: "Email",
46
- slack: "Slack",
47
- form: "Form",
44
+ call: "Call",
45
+ email: "Email",
46
+ slack: "Slack",
47
+ form: "Form",
48
48
  };
@@ -3,7 +3,9 @@
3
3
  import { SOURCE_ICON, SOURCE_LABEL } from "./inbox-statuses.js";
4
4
  import type { InboxTrace } from "./inbox-types.js";
5
5
 
6
- interface Props { trace: InboxTrace };
6
+ interface Props {
7
+ trace: InboxTrace;
8
+ }
7
9
 
8
10
  let { trace }: Props = $props();
9
11
 
@@ -26,7 +28,9 @@
26
28
  <p class="text-foreground">
27
29
  {trace.source.label}
28
30
  {#if trace.source.href}
29
- <a href={trace.source.href} class="text-foreground ml-1 underline underline-offset-2">Open source</a>
31
+ <a href={trace.source.href} class="text-foreground ml-1 underline underline-offset-2"
32
+ >Open source</a
33
+ >
30
34
  {/if}
31
35
  </p>
32
36
  <ul class="flex flex-col gap-2">
@@ -34,7 +38,9 @@
34
38
  <li>
35
39
  <blockquote class="text-foreground">&ldquo;{evidence.quote}&rdquo;</blockquote>
36
40
  {#if evidence.by || evidence.at}
37
- <span class="text-xs tabular-nums">{[evidence.by, evidence.at].filter(Boolean).join(", ")}</span>
41
+ <span class="text-xs tabular-nums"
42
+ >{[evidence.by, evidence.at].filter(Boolean).join(", ")}</span
43
+ >
38
44
  {/if}
39
45
  </li>
40
46
  {/each}
@@ -15,94 +15,90 @@ export type InboxOutcome = "approve" | "decline" | "clarify";
15
15
 
16
16
  /** An editable email, filled in from a template by the agent. */
17
17
  export type InboxDraft = {
18
- /** The template it came from. Comes back in the verdict so the host knows which one was sent. */
19
- templateId: string;
20
- /** The button's word: "Pre-qualify", "Decline", "Clarify". */
21
- label: string;
22
- subject: string;
23
- body: string;
24
- outcome?: InboxOutcome;
18
+ /** The template it came from. Comes back in the verdict so the host knows which one was sent. */
19
+ templateId: string;
20
+ /** The button's word: "Pre-qualify", "Decline", "Clarify". */
21
+ label: string;
22
+ subject: string;
23
+ body: string;
24
+ outcome?: InboxOutcome;
25
25
  };
26
26
 
27
27
  /** What the agent wants to do, in one line, with the drafts it prepared. */
28
28
  export type InboxProposal = {
29
- summary: string;
30
- detail?: string;
31
- drafts?: InboxDraft[];
32
- /** The draft to open on. Defaults to the first. */
33
- recommended?: string;
29
+ summary: string;
30
+ detail?: string;
31
+ drafts?: InboxDraft[];
32
+ /** The draft to open on. Defaults to the first. */
33
+ recommended?: string;
34
34
  };
35
35
 
36
36
  /** A short quote the agent read. */
37
37
  export type InboxEvidence = {
38
- quote: string;
39
- /** Who said it, or where it sat: "Priya", "line 14". */
40
- by?: string;
41
- /** A position in the source, such as "12:41" in a call. */
42
- at?: string;
38
+ quote: string;
39
+ /** Who said it, or where it sat: "Priya", "line 14". */
40
+ by?: string;
41
+ /** A position in the source, such as "12:41" in a call. */
42
+ at?: string;
43
43
  };
44
44
 
45
45
  /** Where an item came from and what the agent made of it. Every verdict is traceable to this. */
46
46
  export type InboxTrace = {
47
- source: {
48
- type: InboxSourceType;
49
- label: string;
50
- /** Display time, formatted by the host so server and browser agree. */
51
- at: string;
52
- href?: string;
53
- };
54
- evidence: InboxEvidence[];
55
- reasoning: string;
47
+ source: {
48
+ type: InboxSourceType;
49
+ label: string;
50
+ /** Display time, formatted by the host so server and browser agree. */
51
+ at: string;
52
+ href?: string;
53
+ };
54
+ evidence: InboxEvidence[];
55
+ reasoning: string;
56
56
  };
57
57
 
58
58
  export type InboxConfidence = {
59
- /** 0 to 1. */
60
- score: number;
61
- /** What the agent couldn't tell. Shown when the agent is unsure. */
62
- missing?: string;
59
+ /** 0 to 1. */
60
+ score: number;
61
+ /** What the agent couldn't tell. Shown when the agent is unsure. */
62
+ missing?: string;
63
63
  };
64
64
 
65
65
  export type InboxProject = {
66
- id: string;
67
- name: string;
68
- client?: string;
69
- /** The project timeline. Decided items link here. */
70
- href?: string;
66
+ id: string;
67
+ name: string;
68
+ client?: string;
69
+ /** The project timeline. Decided items link here. */
70
+ href?: string;
71
71
  };
72
72
 
73
73
  export type InboxAgent = {
74
- name: string;
75
- shape?: AgentShape;
76
- color?: string;
74
+ name: string;
75
+ shape?: AgentShape;
76
+ color?: string;
77
77
  };
78
78
 
79
79
  export type InboxItem = {
80
- id: string;
81
- kind: InboxKind;
82
- tier: InboxTier;
83
- state: InboxState;
84
- title: string;
85
- project: InboxProject;
86
- proposal: InboxProposal;
87
- confidence: InboxConfidence;
88
- trace: InboxTrace;
89
- agent?: InboxAgent;
90
- /** The last steer note, shown while the agent re-runs. */
91
- steer?: string;
80
+ id: string;
81
+ kind: InboxKind;
82
+ tier: InboxTier;
83
+ state: InboxState;
84
+ title: string;
85
+ project: InboxProject;
86
+ proposal: InboxProposal;
87
+ confidence: InboxConfidence;
88
+ trace: InboxTrace;
89
+ agent?: InboxAgent;
90
+ /** The last steer note, shown while the agent re-runs. */
91
+ steer?: string;
92
92
  };
93
93
 
94
94
  /** The draft as the person left it, after editing. */
95
95
  export type InboxDraftEdit = Pick<InboxDraft, "templateId" | "subject" | "body">;
96
96
 
97
97
  export type InboxVerdict =
98
- | { type: "approve"; id: string; draft?: InboxDraftEdit }
99
- | { type: "decline"; id: string; draft?: InboxDraftEdit }
100
- | { type: "steer"; id: string; note: string }
101
- | { type: "undo"; id: string };
102
-
103
- export type InboxLane = "needs" | "auto" | "decided";
104
-
105
- export type InboxKindFilter = "all" | InboxKind;
98
+ | { type: "approve"; id: string; draft?: InboxDraftEdit }
99
+ | { type: "decline"; id: string; draft?: InboxDraftEdit }
100
+ | { type: "steer"; id: string; note: string }
101
+ | { type: "undo"; id: string };
106
102
 
107
103
  /** What the person typed into the drafts, by template id. */
108
104
  export type InboxDraftEdits = Record<string, { subject: string; body: string }>;
@@ -1,23 +1,24 @@
1
- export { default as Inbox } from "./inbox.svelte";
2
- export { confidenceLevel, inboxConfidence, inboxKinds, inboxStates } from "./inbox-statuses.js";
3
- export { flatten, groupByProject, inLane, laneOf } from "./inbox-logic.js";
1
+ export {
2
+ confidenceLevel,
3
+ inboxConfidence,
4
+ inboxKinds,
5
+ inboxStates,
6
+ } from "./inbox-statuses.js";
4
7
  export type {
5
- InboxAgent,
6
- InboxConfidence,
7
- InboxDraft,
8
- InboxDraftEdit,
9
- InboxDraftEdits,
10
- InboxEvidence,
11
- InboxItem,
12
- InboxKind,
13
- InboxKindFilter,
14
- InboxLane,
15
- InboxOutcome,
16
- InboxProject,
17
- InboxProposal,
18
- InboxSourceType,
19
- InboxState,
20
- InboxTier,
21
- InboxTrace,
22
- InboxVerdict,
8
+ InboxAgent,
9
+ InboxConfidence,
10
+ InboxDraft,
11
+ InboxDraftEdit,
12
+ InboxDraftEdits,
13
+ InboxEvidence,
14
+ InboxItem,
15
+ InboxKind,
16
+ InboxOutcome,
17
+ InboxProject,
18
+ InboxProposal,
19
+ InboxSourceType,
20
+ InboxState,
21
+ InboxTier,
22
+ InboxTrace,
23
+ InboxVerdict,
23
24
  } from "./inbox-types.js";
@@ -6,25 +6,20 @@ export { boardOrderAt, keyBetween } from "./board-order.js";
6
6
  export { reorderByIds } from "./reorder.js";
7
7
  export type { KanbanDndConfig, KanbanDragOver } from "./use-kanban-dnd.svelte.js";
8
8
  export type {
9
- KanbanCardContext,
10
- KanbanCardSnippet,
11
- KanbanColumn as KanbanColumnDef,
12
- KanbanColumnContext,
13
- KanbanMove,
14
- KanbanSortKey,
9
+ KanbanCardContext,
10
+ KanbanCardSnippet,
11
+ KanbanColumn as KanbanColumnDef,
12
+ KanbanColumnContext,
13
+ KanbanMove,
14
+ KanbanSortKey,
15
15
  } from "./kanban-types.js";
16
- export {
17
- StatusBadge,
18
- StatusDot,
19
- StatusIcon,
20
- defineStatuses,
21
- } from "../status/index.js";
16
+ export { StatusBadge, StatusDot, StatusIcon, defineStatuses } from "../status/index.js";
22
17
  export type {
23
- StatusDef,
24
- StatusDotVariant,
25
- StatusId,
26
- StatusMap,
27
- Statuses,
18
+ StatusDef,
19
+ StatusDotVariant,
20
+ StatusId,
21
+ StatusMap,
22
+ Statuses,
28
23
  } from "../status/index.js";
29
24
  export { SidePanel } from "../panel/index.js";
30
25
  export type { PanelStat, SidePanelWidth } from "../panel/index.js";
@@ -32,10 +27,10 @@ export { default as TaskList } from "./task-list.svelte";
32
27
  export { default as TaskGantt } from "./task-gantt.svelte";
33
28
  export { addDays, dayNumber, isoFromDay, todayIso } from "./dates.js";
34
29
  export type {
35
- GanttChange,
36
- GanttLabelContext,
37
- TaskListGroupContext,
38
- TaskListRowContext,
30
+ GanttChange,
31
+ GanttLabelContext,
32
+ TaskListGroupContext,
33
+ TaskListRowContext,
39
34
  } from "./task-types.js";
40
35
  export { default as TaskDetail } from "./detail/task-detail.svelte";
41
36
  export { default as TaskThread } from "./detail/task-thread.svelte";
@@ -48,40 +43,42 @@ export { default as TimeChip } from "./time/time-chip.svelte";
48
43
  export { default as TimeRing } from "./time/time-ring.svelte";
49
44
  export { default as TimeDot } from "./time/time-dot.svelte";
50
45
  export {
51
- budgetTone,
52
- dayLabel,
53
- formatClock,
54
- formatMinutes,
55
- localDay,
56
- parseMinutes,
57
- personColor,
46
+ budgetTone,
47
+ dayLabel,
48
+ formatClock,
49
+ formatMinutes,
50
+ localDay,
51
+ parseMinutes,
52
+ personColor,
58
53
  } from "./time/duration.js";
59
54
  export {
60
- Inbox,
61
- confidenceLevel,
62
- inboxConfidence,
63
- inboxKinds,
64
- inboxStates,
55
+ confidenceLevel,
56
+ inboxConfidence,
57
+ inboxKinds,
58
+ inboxStates,
65
59
  } from "./inbox/index.js";
66
60
  export type {
67
- InboxAgent,
68
- InboxConfidence,
69
- InboxDraft,
70
- InboxDraftEdit,
71
- InboxDraftEdits,
72
- InboxEvidence,
73
- InboxItem,
74
- InboxKind,
75
- InboxKindFilter,
76
- InboxLane,
77
- InboxOutcome,
78
- InboxProject,
79
- InboxProposal,
80
- InboxSourceType,
81
- InboxState,
82
- InboxTier,
83
- InboxTrace,
84
- InboxVerdict,
61
+ InboxAgent,
62
+ InboxConfidence,
63
+ InboxDraft,
64
+ InboxDraftEdit,
65
+ InboxDraftEdits,
66
+ InboxEvidence,
67
+ InboxItem,
68
+ InboxKind,
69
+ InboxOutcome,
70
+ InboxProject,
71
+ InboxProposal,
72
+ InboxSourceType,
73
+ InboxState,
74
+ InboxTier,
75
+ InboxTrace,
76
+ InboxVerdict,
85
77
  } from "./inbox/index.js";
86
78
  export { DEFAULT_TIME_LABELS } from "./time/time-types.js";
87
- export type { TimeLabels, TimeLogInput, TimeRunning, TimeStopInfo } from "./time/time-types.js";
79
+ export type {
80
+ TimeLabels,
81
+ TimeLogInput,
82
+ TimeRunning,
83
+ TimeStopInfo,
84
+ } from "./time/time-types.js";