@happyvertical/smrt-ingestion 0.57.20 → 0.57.22

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 (115) hide show
  1. package/FEEDBACK.md +137 -0
  2. package/PROPOSALS.md +146 -5
  3. package/README.md +168 -2
  4. package/REVIEW.md +611 -7
  5. package/agents/execution.md +87 -0
  6. package/dist/chunks/{execution-NoDh3pjs.js → execution-BzVQax0n.js} +528 -42
  7. package/dist/chunks/execution-BzVQax0n.js.map +1 -0
  8. package/dist/chunks/{feedback-CJB900iG.js → feedback-D3UTF8fm.js} +175 -36
  9. package/dist/chunks/feedback-D3UTF8fm.js.map +1 -0
  10. package/dist/chunks/{proposal-errors-VxcTU6Db.js → proposal-contracts-77Uo1B1j.js} +38 -44
  11. package/dist/chunks/proposal-contracts-77Uo1B1j.js.map +1 -0
  12. package/dist/chunks/reviewer-instruction-CEc3AOuU.js +33 -0
  13. package/dist/chunks/reviewer-instruction-CEc3AOuU.js.map +1 -0
  14. package/dist/dto.d.ts +75 -0
  15. package/dist/dto.d.ts.map +1 -1
  16. package/dist/execution-contracts.d.ts +4 -1
  17. package/dist/execution-contracts.d.ts.map +1 -1
  18. package/dist/execution-dto.d.ts +16 -0
  19. package/dist/execution-dto.d.ts.map +1 -1
  20. package/dist/execution-internal.d.ts +2 -0
  21. package/dist/execution-internal.d.ts.map +1 -1
  22. package/dist/execution.d.ts +101 -4
  23. package/dist/execution.d.ts.map +1 -1
  24. package/dist/execution.js +2 -2
  25. package/dist/feedback-dto.d.ts +18 -4
  26. package/dist/feedback-dto.d.ts.map +1 -1
  27. package/dist/feedback-internal.d.ts +9 -0
  28. package/dist/feedback-internal.d.ts.map +1 -1
  29. package/dist/feedback.d.ts +10 -0
  30. package/dist/feedback.d.ts.map +1 -1
  31. package/dist/index.js +2 -2
  32. package/dist/manifest.json +339 -3
  33. package/dist/models.d.ts +15 -0
  34. package/dist/models.d.ts.map +1 -1
  35. package/dist/models.js +82 -2
  36. package/dist/models.js.map +1 -1
  37. package/dist/policy.d.ts +3 -0
  38. package/dist/policy.d.ts.map +1 -1
  39. package/dist/presented-filename.d.ts +11 -0
  40. package/dist/presented-filename.d.ts.map +1 -0
  41. package/dist/proposal-contracts.d.ts +31 -6
  42. package/dist/proposal-contracts.d.ts.map +1 -1
  43. package/dist/proposal-dto.d.ts +17 -0
  44. package/dist/proposal-dto.d.ts.map +1 -1
  45. package/dist/proposal-errors.d.ts +20 -0
  46. package/dist/proposal-errors.d.ts.map +1 -1
  47. package/dist/proposal-validation.d.ts +26 -0
  48. package/dist/proposal-validation.d.ts.map +1 -1
  49. package/dist/proposals.d.ts +6 -1
  50. package/dist/proposals.d.ts.map +1 -1
  51. package/dist/proposals.js +268 -71
  52. package/dist/proposals.js.map +1 -1
  53. package/dist/redaction.d.ts +9 -0
  54. package/dist/redaction.d.ts.map +1 -0
  55. package/dist/review-dto.d.ts +108 -5
  56. package/dist/review-dto.d.ts.map +1 -1
  57. package/dist/review-host.d.ts +52 -3
  58. package/dist/review-host.d.ts.map +1 -1
  59. package/dist/review-instruction-view.d.ts +12 -0
  60. package/dist/review-instruction-view.d.ts.map +1 -0
  61. package/dist/review-summary.d.ts.map +1 -1
  62. package/dist/reviewer-instruction.d.ts +20 -0
  63. package/dist/reviewer-instruction.d.ts.map +1 -0
  64. package/dist/server.d.ts +252 -13
  65. package/dist/server.d.ts.map +1 -1
  66. package/dist/server.js +1190 -85
  67. package/dist/server.js.map +1 -1
  68. package/dist/smrt-knowledge.json +137 -23
  69. package/dist/sources/common.d.ts +11 -0
  70. package/dist/sources/common.d.ts.map +1 -1
  71. package/dist/sources/email.d.ts.map +1 -1
  72. package/dist/sources/http.d.ts.map +1 -1
  73. package/dist/sources/watch-folder.d.ts.map +1 -1
  74. package/dist/svelte/components/ActionReview.svelte +54 -55
  75. package/dist/svelte/components/ActionReview.svelte.d.ts +8 -1
  76. package/dist/svelte/components/ActionReview.svelte.d.ts.map +1 -1
  77. package/dist/svelte/components/CandidatePicker.svelte +72 -0
  78. package/dist/svelte/components/CandidatePicker.svelte.d.ts +15 -0
  79. package/dist/svelte/components/CandidatePicker.svelte.d.ts.map +1 -0
  80. package/dist/svelte/components/EvidenceViewer.svelte +60 -4
  81. package/dist/svelte/components/EvidenceViewer.svelte.d.ts +12 -1
  82. package/dist/svelte/components/EvidenceViewer.svelte.d.ts.map +1 -1
  83. package/dist/svelte/components/InboxView.svelte +172 -19
  84. package/dist/svelte/components/InboxView.svelte.d.ts +36 -2
  85. package/dist/svelte/components/InboxView.svelte.d.ts.map +1 -1
  86. package/dist/svelte/components/IntakeInbox.svelte +6 -3
  87. package/dist/svelte/components/IntakeInbox.svelte.d.ts +4 -1
  88. package/dist/svelte/components/IntakeInbox.svelte.d.ts.map +1 -1
  89. package/dist/svelte/components/IntakeReview.svelte +4 -2
  90. package/dist/svelte/components/IntakeReview.svelte.d.ts +2 -0
  91. package/dist/svelte/components/IntakeReview.svelte.d.ts.map +1 -1
  92. package/dist/svelte/components/IntakeWorkspace.svelte +27 -0
  93. package/dist/svelte/components/IntakeWorkspace.svelte.d.ts +19 -0
  94. package/dist/svelte/components/IntakeWorkspace.svelte.d.ts.map +1 -0
  95. package/dist/svelte/components/ReviewView.svelte +653 -71
  96. package/dist/svelte/components/ReviewView.svelte.d.ts +20 -1
  97. package/dist/svelte/components/ReviewView.svelte.d.ts.map +1 -1
  98. package/dist/svelte/components/TriageView.svelte +669 -0
  99. package/dist/svelte/components/TriageView.svelte.d.ts +16 -0
  100. package/dist/svelte/components/TriageView.svelte.d.ts.map +1 -0
  101. package/dist/svelte/i18n.d.ts +56 -0
  102. package/dist/svelte/i18n.d.ts.map +1 -1
  103. package/dist/svelte/i18n.js +56 -0
  104. package/dist/svelte/index.d.ts +2 -1
  105. package/dist/svelte/index.d.ts.map +1 -1
  106. package/dist/svelte/index.js +1 -0
  107. package/dist/svelte/view-utils.d.ts +67 -0
  108. package/dist/svelte/view-utils.d.ts.map +1 -1
  109. package/dist/svelte/view-utils.js +157 -0
  110. package/package.json +13 -13
  111. package/dist/chunks/execution-NoDh3pjs.js.map +0 -1
  112. package/dist/chunks/execution-internal-DWteDHM2.js +0 -7
  113. package/dist/chunks/execution-internal-DWteDHM2.js.map +0 -1
  114. package/dist/chunks/feedback-CJB900iG.js.map +0 -1
  115. package/dist/chunks/proposal-errors-VxcTU6Db.js.map +0 -1
@@ -2,18 +2,56 @@
2
2
  import { FilePicker, Input, Select } from '@happyvertical/smrt-ui/forms';
3
3
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
4
4
  import { Button } from '@happyvertical/smrt-ui/ui';
5
- import { onDestroy, onMount } from 'svelte';
5
+ import { onDestroy, onMount, type Snippet } from 'svelte';
6
6
  import type {
7
7
  InboxEntry,
8
8
  InboxState,
9
9
  IntakeReviewHost,
10
10
  } from '../../review-dto.js';
11
11
  import { M } from '../i18n.js';
12
+ import { evidenceUrl } from '../view-utils.js';
12
13
  export interface Props {
13
14
  host: IntakeReviewHost;
14
15
  onselect?: (itemId: string) => void;
16
+ /**
17
+ * Optional per-row aside; without it a row shows the host's original
18
+ * link/preview. Rendered in a plain `div`, not an `aside` landmark, so a
19
+ * page of rows does not add one complementary landmark per row.
20
+ */
21
+ rowAside?: Snippet<[InboxEntry]>;
22
+ /** The row a workspace has open; marked `aria-current`. */
23
+ selectedId?: string;
24
+ /**
25
+ * The displayed rows after every settled load or page append (not after
26
+ * `patch`, which returns them), whether more pages exist, and the entries
27
+ * exactly as the page read returned them (`appended` for Load more), absent
28
+ * when the read failed.
29
+ */
30
+ onitems?: (
31
+ items: InboxEntry[],
32
+ more: boolean,
33
+ page?: { entries: InboxEntry[]; appended: boolean; issued?: number },
34
+ ) => void;
35
+ /** Called before a page request so a workspace can order concurrent follow reads. */
36
+ onreadstart?: () => void;
37
+ /** A row's status text; the listed inbox state is shown when omitted or undefined. */
38
+ status?: (entry: InboxEntry) => string | undefined;
39
+ /** Show the per-row "Handled, no action" control (a workspace resolves in its item pane). */
40
+ resolveInRow?: boolean;
41
+ /** Numbers each page read when its request starts (`issued` on the page). */
42
+ stamp?: () => number;
15
43
  }
16
- let { host, onselect }: Props = $props();
44
+ let {
45
+ host,
46
+ onselect,
47
+ rowAside,
48
+ selectedId,
49
+ onitems,
50
+ onreadstart,
51
+ status,
52
+ resolveInRow = true,
53
+ stamp,
54
+ }: Props = $props();
17
55
  const { t } = useI18n();
18
56
  const states: InboxState[] = [
19
57
  'processing',
@@ -23,11 +61,13 @@ const states: InboxState[] = [
23
61
  'deferred',
24
62
  'partially_completed',
25
63
  'completed',
64
+ 'resolved',
26
65
  ];
27
66
  let items = $state<InboxEntry[]>([]),
28
67
  selectedState = $state(''),
29
68
  assignee = $state(''),
30
69
  assignments = $state<Record<string, string>>({}),
70
+ reasons = $state<Record<string, string>>({}),
31
71
  files = $state<File[]>([]),
32
72
  cursor = $state<string>(),
33
73
  pending = $state(false),
@@ -35,41 +75,145 @@ let items = $state<InboxEntry[]>([]),
35
75
  let alive = true,
36
76
  epoch = 0;
37
77
  let uploadRequestId: string | undefined;
78
+ // The filter the displayed rows were listed under (the inputs may have been
79
+ // edited since); `patch` keeps a row only while it still matches it.
80
+ let listed: { state?: InboxState; assigneeId?: string } = {};
81
+ function publish(page?: {
82
+ entries: InboxEntry[];
83
+ appended: boolean;
84
+ issued?: number;
85
+ }) {
86
+ onitems?.($state.snapshot(items) as InboxEntry[], !!cursor, page);
87
+ }
88
+ /**
89
+ * Replace one displayed row with a fresher entry for the same item (item and
90
+ * state; the assignment only when its version is newer), keeping its listed
91
+ * label and preview: `load` entries
92
+ * carry no preview and a host may label them differently. Unless `keep` is
93
+ * set, a row that no longer matches the listed filter leaves the list. Rows
94
+ * that are not displayed are never added. Returns the displayed rows.
95
+ */
96
+ export function patch(entry: InboxEntry, keep = false): InboxEntry[] {
97
+ const index = items.findIndex((row) => row.item.id === entry.item.id);
98
+ if (index < 0) return $state.snapshot(items) as InboxEntry[];
99
+ const previous = items[index];
100
+ // Assignment is versioned (the host's compare-and-set): an entry carrying
101
+ // an older or equal version never replaces the row's, so a view loaded
102
+ // before an assignment cannot roll the row (and the next expected version)
103
+ // back.
104
+ const newer = entry.assignment.version > previous.assignment.version;
105
+ const assignment = newer ? entry.assignment : previous.assignment;
106
+ const matches =
107
+ (!listed.state || entry.state === listed.state) &&
108
+ (!listed.assigneeId || assignment.assigneeId === listed.assigneeId);
109
+ if (keep || matches) {
110
+ const evidence = previous.evidence;
111
+ items[index] = {
112
+ item: entry.item,
113
+ label: previous.label,
114
+ state: entry.state,
115
+ assignment: $state.snapshot(assignment),
116
+ ...(evidence ? { evidence } : {}),
117
+ };
118
+ // An unsaved assignee the reviewer typed survives unless the durable
119
+ // assignment itself changed.
120
+ if (newer) assignments[entry.item.id] = assignment.assigneeId ?? '';
121
+ } else items = items.filter((row) => row.item.id !== entry.item.id);
122
+ return $state.snapshot(items) as InboxEntry[];
123
+ }
124
+ /**
125
+ * Append the next page, if any. Resolves with the displayed rows and what
126
+ * happened: `appended` (or `none` when there is no further page), `pending`
127
+ * when another read was in flight or superseded this one (nothing was
128
+ * appended), or `failed` when the page read failed (the list failed closed
129
+ * and its rows were cleared).
130
+ */
131
+ export async function more(): Promise<{
132
+ items: InboxEntry[];
133
+ result: 'appended' | 'none' | 'pending' | 'failed';
134
+ }> {
135
+ let result: 'appended' | 'none' | 'pending' | 'failed';
136
+ if (pending) result = 'pending';
137
+ else if (!cursor) result = 'none';
138
+ else {
139
+ const read = await load(true);
140
+ result =
141
+ read === 'shown' ? 'appended' : read === 'failed' ? 'failed' : 'pending';
142
+ }
143
+ return { items: $state.snapshot(items) as InboxEntry[], result };
144
+ }
38
145
  onDestroy(() => {
39
146
  alive = false;
40
147
  epoch++;
41
148
  files = [];
42
149
  uploadRequestId = undefined;
43
150
  });
44
- async function load(more = false) {
151
+ /**
152
+ * Resolves `shown` when this read's page was displayed, `failed` when it
153
+ * failed (the rows were cleared), `superseded` when a newer read or the
154
+ * component's end fenced it.
155
+ */
156
+ async function load(more = false): Promise<'shown' | 'failed' | 'superseded'> {
45
157
  const ticket = ++epoch;
158
+ onreadstart?.();
46
159
  pending = true;
47
160
  error = false;
48
- const prior = more ? items : [];
161
+ let page:
162
+ | { entries: InboxEntry[]; appended: boolean; issued?: number }
163
+ | undefined;
49
164
  const next = more ? cursor : undefined;
50
- items = [];
51
- assignments = {};
165
+ // The displayed rows stay (controls disabled while pending) until the new
166
+ // page arrives, so a workspace can keep patching and navigating them; a
167
+ // failed read still clears them.
168
+ const filter = more
169
+ ? listed
170
+ : {
171
+ state: selectedState ? (selectedState as InboxState) : undefined,
172
+ assigneeId: assignee || undefined,
173
+ };
52
174
  try {
53
- const page = await host.list({
54
- state: selectedState ? (selectedState as InboxState) : undefined,
55
- assigneeId: assignee || undefined,
56
- cursor: next,
57
- });
58
- if (!alive || ticket !== epoch) return;
59
- items = [...prior, ...page.items];
60
- cursor = page.nextCursor;
175
+ const issued = stamp?.();
176
+ const read = await host.list({ ...filter, cursor: next });
177
+ if (!alive || ticket !== epoch) return 'superseded';
178
+ listed = filter;
179
+ // An appended page builds on the rows as displayed now (patches made
180
+ // while it loaded included); a row already shown is not repeated.
181
+ const shown = new Set(more ? items.map((entry) => entry.item.id) : []);
182
+ const added = read.items.filter((entry) => !shown.has(entry.item.id));
183
+ page = {
184
+ entries: $state.snapshot(more ? added : read.items) as InboxEntry[],
185
+ appended: more,
186
+ ...(issued !== undefined ? { issued } : {}),
187
+ };
188
+ const kept = more ? { assignments, reasons } : undefined;
189
+ items = more ? [...items, ...added] : read.items;
190
+ cursor = read.nextCursor;
61
191
  assignments = Object.fromEntries(
62
- items.map((entry) => [entry.item.id, entry.assignment.assigneeId ?? '']),
192
+ items.map((entry) => [
193
+ entry.item.id,
194
+ kept?.assignments[entry.item.id] ?? entry.assignment.assigneeId ?? '',
195
+ ]),
196
+ );
197
+ reasons = Object.fromEntries(
198
+ items.map((entry) => [entry.item.id, kept?.reasons[entry.item.id] ?? '']),
63
199
  );
64
200
  } catch {
201
+ // Any failed read, Load more included, fails closed: the host cannot say
202
+ // whether it was transient or a revoked grant.
65
203
  if (alive && ticket === epoch) {
66
204
  items = [];
205
+ assignments = {};
206
+ reasons = {};
67
207
  cursor = undefined;
68
208
  error = true;
69
209
  }
70
210
  } finally {
71
- if (alive && ticket === epoch) pending = false;
211
+ if (alive && ticket === epoch) {
212
+ pending = false;
213
+ publish(page);
214
+ }
72
215
  }
216
+ return page ? 'shown' : alive && ticket === epoch ? 'failed' : 'superseded';
73
217
  }
74
218
  async function mutate(operation: () => Promise<unknown>, selected = false) {
75
219
  if (pending) return;
@@ -92,6 +236,7 @@ async function mutate(operation: () => Promise<unknown>, selected = false) {
92
236
  assignments = {};
93
237
  error = true;
94
238
  pending = false;
239
+ publish();
95
240
  }
96
241
  }
97
242
  }
@@ -119,17 +264,25 @@ onMount(() => {
119
264
  {#if error}<p role="alert">{t(M['ingestion.error'])}</p>{/if}
120
265
  {#if pending}<p role="status">{t(M['ingestion.loading'])}</p>{/if}
121
266
  {#if !pending && !error && !items.length}<p>{t(M['ingestion.empty'])}</p>{/if}
122
- <ul>{#each items as entry (entry.item.id)}<li>
123
- <h2>{entry.label}</h2><p>{t(M[`ingestion.${entry.state}`])}</p>
267
+ <ul>{#each items as entry (entry.item.id)}<li data-item-id={entry.item.id} aria-current={entry.item.id === selectedId ? 'true' : undefined} class:selected={entry.item.id === selectedId}>
268
+ <h2>{entry.label}</h2><p data-testid="row-status">{status?.(entry) ?? t(M[`ingestion.${entry.state}`])}</p>
269
+ {#if rowAside}<div class="row-aside">{@render rowAside(entry)}</div>{:else if entry.evidence}{@const original = evidenceUrl(entry.evidence.viewUrl)}{@const thumbnail = evidenceUrl(entry.evidence.thumbnailUrl)}{#if thumbnail || original}<div class="row-aside">
270
+ {#if thumbnail}<img src={thumbnail} alt={entry.evidence.label} loading="lazy" />{/if}
271
+ {#if original}<a href={original} target="_blank" rel="noopener noreferrer" aria-label={`${t(M['ingestion.original'])}: ${entry.label}`}>{t(M['ingestion.original'])}</a>{/if}
272
+ </div>{/if}{/if}
124
273
  <Button onclick={() => onselect?.(entry.item.id)} disabled={pending}>{t(M['ingestion.open'])}</Button>
125
274
  <Input aria-label={`${t(M['ingestion.assignee'])}: ${entry.label}`} bind:value={assignments[entry.item.id]} disabled={pending} />
126
275
  <Button disabled={pending} onclick={() => mutate(() => host.assign({itemId:entry.item.id,expectedVersion:entry.assignment.version,assigneeId:assignments[entry.item.id] || null,requestId:crypto.randomUUID()}))}>{t(M['ingestion.assign'])}</Button>
276
+ {#if resolveInRow && host.resolve && !entry.item.disposition}
277
+ <Input aria-label={`${t(M['ingestion.resolveReason'])}: ${entry.label}`} bind:value={reasons[entry.item.id]} disabled={pending} />
278
+ <Button disabled={pending} onclick={() => { const close = host.resolve; const reason = reasons[entry.item.id]; if (close) void mutate(() => close({itemId:entry.item.id,disposition:'resolve_no_action',requestId:crypto.randomUUID(),...(reason ? { reason } : {})})); }}>{t(M['ingestion.resolveNoAction'])}</Button>
279
+ {/if}
127
280
  </li>{/each}</ul>
128
281
  {#if cursor}<Button disabled={pending} onclick={() => load(true)}>{t(M['ingestion.more'])}</Button>{/if}
129
282
  </section>
130
283
  <style>
131
284
  @layer smrt.reset, smrt.structure, smrt.theme;
132
285
  @layer smrt.theme {
133
- section{max-width:72rem;margin-inline:auto;padding:1rem;color:var(--smrt-color-on-surface)}.toolbar{display:flex;flex-wrap:wrap;gap:.75rem;margin-block:1rem}ul{list-style:none;padding:0}li{padding:1rem;border-block-end:var(--smrt-hairline);display:grid;gap:.75rem}h2{font-size:1.1rem}
286
+ section{max-width:72rem;margin-inline:auto;padding:1rem;color:var(--smrt-color-on-surface)}.toolbar{display:flex;flex-wrap:wrap;gap:.75rem;margin-block:1rem}ul{list-style:none;padding:0}li{padding:1rem;border-block-end:var(--smrt-hairline);display:grid;gap:.75rem}li.selected{border-inline-start:.25rem solid var(--smrt-color-primary)}h2{font-size:1.1rem}.row-aside{display:flex;flex-wrap:wrap;align-items:center;gap:.75rem}.row-aside img{max-block-size:6rem;max-inline-size:100%;object-fit:contain}
134
287
  }
135
288
  </style>
@@ -1,9 +1,43 @@
1
- import type { IntakeReviewHost } from '../../review-dto.js';
1
+ import { type Snippet } from 'svelte';
2
+ import type { InboxEntry, IntakeReviewHost } from '../../review-dto.js';
2
3
  export interface Props {
3
4
  host: IntakeReviewHost;
4
5
  onselect?: (itemId: string) => void;
6
+ /**
7
+ * Optional per-row aside; without it a row shows the host's original
8
+ * link/preview. Rendered in a plain `div`, not an `aside` landmark, so a
9
+ * page of rows does not add one complementary landmark per row.
10
+ */
11
+ rowAside?: Snippet<[InboxEntry]>;
12
+ /** The row a workspace has open; marked `aria-current`. */
13
+ selectedId?: string;
14
+ /**
15
+ * The displayed rows after every settled load or page append (not after
16
+ * `patch`, which returns them), whether more pages exist, and the entries
17
+ * exactly as the page read returned them (`appended` for Load more), absent
18
+ * when the read failed.
19
+ */
20
+ onitems?: (items: InboxEntry[], more: boolean, page?: {
21
+ entries: InboxEntry[];
22
+ appended: boolean;
23
+ issued?: number;
24
+ }) => void;
25
+ /** Called before a page request so a workspace can order concurrent follow reads. */
26
+ onreadstart?: () => void;
27
+ /** A row's status text; the listed inbox state is shown when omitted or undefined. */
28
+ status?: (entry: InboxEntry) => string | undefined;
29
+ /** Show the per-row "Handled, no action" control (a workspace resolves in its item pane). */
30
+ resolveInRow?: boolean;
31
+ /** Numbers each page read when its request starts (`issued` on the page). */
32
+ stamp?: () => number;
5
33
  }
6
- declare const InboxView: import("svelte").Component<Props, {}, "">;
34
+ declare const InboxView: import("svelte").Component<Props, {
35
+ patch: (entry: InboxEntry, keep?: boolean) => InboxEntry[];
36
+ more: () => Promise<{
37
+ items: InboxEntry[];
38
+ result: "appended" | "none" | "pending" | "failed";
39
+ }>;
40
+ }, "">;
7
41
  type InboxView = ReturnType<typeof InboxView>;
8
42
  export default InboxView;
9
43
  //# sourceMappingURL=InboxView.svelte.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InboxView.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/InboxView.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AA+HD,QAAA,MAAM,SAAS,2CAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"InboxView.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/InboxView.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,EAAsB,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,KAAK,EACV,UAAU,EAEV,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAI7B,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IACjC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,UAAU,EAAE,EACnB,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,UAAU,EAAE,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KACjE,IAAI,CAAC;IACV,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,sFAAsF;IACtF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,MAAM,GAAG,SAAS,CAAC;IACnD,6FAA6F;IAC7F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AA6PD,QAAA,MAAM,SAAS;mBA/LQ,UAAU,qBAAiB,UAAU,EAAE;gBAmCtC,OAAO,CAAC;QAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;QACpB,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;KACpD,CAAC;MAyJqD,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
@@ -1,11 +1,14 @@
1
1
  <script lang="ts">
2
- import type { IntakeReviewHost } from '../../review-dto.js';
2
+ import type { Snippet } from 'svelte';
3
+ import type { InboxEntry, IntakeReviewHost } from '../../review-dto.js';
3
4
  import InboxView from './InboxView.svelte';
4
5
  export interface Props {
5
6
  host: IntakeReviewHost;
6
7
  contextKey?: string;
7
8
  onselect?: (itemId: string) => void;
9
+ /** Optional per-row aside (preview, original link); receives the page entry. */
10
+ rowAside?: Snippet<[InboxEntry]>;
8
11
  }
9
- let { host, contextKey = '', onselect }: Props = $props();
12
+ let { host, contextKey = '', onselect, rowAside }: Props = $props();
10
13
  </script>
11
- {#key host}{#key contextKey}<InboxView {host} {onselect} />{/key}{/key}
14
+ {#key host}{#key contextKey}<InboxView {host} {onselect} {rowAside} />{/key}{/key}
@@ -1,8 +1,11 @@
1
- import type { IntakeReviewHost } from '../../review-dto.js';
1
+ import type { Snippet } from 'svelte';
2
+ import type { InboxEntry, IntakeReviewHost } from '../../review-dto.js';
2
3
  export interface Props {
3
4
  host: IntakeReviewHost;
4
5
  contextKey?: string;
5
6
  onselect?: (itemId: string) => void;
7
+ /** Optional per-row aside (preview, original link); receives the page entry. */
8
+ rowAside?: Snippet<[InboxEntry]>;
6
9
  }
7
10
  declare const IntakeInbox: import("svelte").Component<Props, {}, "">;
8
11
  type IntakeInbox = ReturnType<typeof IntakeInbox>;
@@ -1 +1 @@
1
- {"version":3,"file":"IntakeInbox.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/IntakeInbox.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAWD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"IntakeInbox.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/IntakeInbox.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGxE,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CAClC;AAYD,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
@@ -5,7 +5,9 @@ export interface Props {
5
5
  host: IntakeReviewHost;
6
6
  itemId: string;
7
7
  contextKey?: string;
8
+ /** Reload interval while the host reports the item as processing. */
9
+ pollMs?: number;
8
10
  }
9
- let { host, itemId, contextKey = '' }: Props = $props();
11
+ let { host, itemId, contextKey = '', pollMs = 2000 }: Props = $props();
10
12
  </script>
11
- {#key host}{#key contextKey}{#key itemId}<ReviewView {host} {itemId} />{/key}{/key}{/key}
13
+ {#key host}{#key contextKey}{#key itemId}<ReviewView {host} {itemId} {pollMs} />{/key}{/key}{/key}
@@ -3,6 +3,8 @@ export interface Props {
3
3
  host: IntakeReviewHost;
4
4
  itemId: string;
5
5
  contextKey?: string;
6
+ /** Reload interval while the host reports the item as processing. */
7
+ pollMs?: number;
6
8
  }
7
9
  declare const IntakeReview: import("svelte").Component<Props, {}, "">;
8
10
  type IntakeReview = ReturnType<typeof IntakeReview>;
@@ -1 +1 @@
1
- {"version":3,"file":"IntakeReview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/IntakeReview.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAWD,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"IntakeReview.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/IntakeReview.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAWD,QAAA,MAAM,YAAY,2CAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { InboxEntry, IntakeReviewHost } from '../../review-dto.js';
4
+ import TriageView from './TriageView.svelte';
5
+ export interface Props {
6
+ host: IntakeReviewHost;
7
+ /** Replace whenever the authenticated tenant/session context changes. */
8
+ contextKey?: string;
9
+ /** Item to open first; afterwards the workspace owns the selection. */
10
+ itemId?: string;
11
+ /** Reload interval while an item's background stage is in flight. */
12
+ pollMs?: number;
13
+ /** Told about every selection change (e.g. to keep a URL in step); never navigates. */
14
+ onselect?: (itemId: string | undefined) => void;
15
+ /** Optional per-row aside (preview, original link); receives the page entry. */
16
+ rowAside?: Snippet<[InboxEntry]>;
17
+ }
18
+ let {
19
+ host,
20
+ contextKey = '',
21
+ itemId,
22
+ pollMs = 2000,
23
+ onselect,
24
+ rowAside,
25
+ }: Props = $props();
26
+ </script>
27
+ {#key host}{#key contextKey}<TriageView {host} {itemId} {pollMs} {onselect} {rowAside} />{/key}{/key}
@@ -0,0 +1,19 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { InboxEntry, IntakeReviewHost } from '../../review-dto.js';
3
+ export interface Props {
4
+ host: IntakeReviewHost;
5
+ /** Replace whenever the authenticated tenant/session context changes. */
6
+ contextKey?: string;
7
+ /** Item to open first; afterwards the workspace owns the selection. */
8
+ itemId?: string;
9
+ /** Reload interval while an item's background stage is in flight. */
10
+ pollMs?: number;
11
+ /** Told about every selection change (e.g. to keep a URL in step); never navigates. */
12
+ onselect?: (itemId: string | undefined) => void;
13
+ /** Optional per-row aside (preview, original link); receives the page entry. */
14
+ rowAside?: Snippet<[InboxEntry]>;
15
+ }
16
+ declare const IntakeWorkspace: import("svelte").Component<Props, {}, "">;
17
+ type IntakeWorkspace = ReturnType<typeof IntakeWorkspace>;
18
+ export default IntakeWorkspace;
19
+ //# sourceMappingURL=IntakeWorkspace.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IntakeWorkspace.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/IntakeWorkspace.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGxE,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,gBAAgB,CAAC;IACvB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAChD,gFAAgF;IAChF,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;CAClC;AAmBD,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}