@gobing-ai/knowledge-kit 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/dist/board/collect/index.css +447 -0
  3. package/dist/board/collect/index.js +2505 -453
  4. package/dist/board/daily-voice/index.css +447 -0
  5. package/dist/board/daily-voice/index.js +415 -8
  6. package/dist/board/itc/index.css +447 -0
  7. package/dist/board/itc/index.js +415 -8
  8. package/dist/index.js +475 -136
  9. package/package.json +6 -5
  10. package/plugins/generations/content-gen/dist/index.js +9 -9
  11. package/plugins/generations/core-facts-gen/dist/index.js +12 -12
  12. package/plugins/generations/daily-article-gen/dist/index.js +12 -12
  13. package/plugins/generations/dailynews-gen/dist/index.js +9 -9
  14. package/plugins/generations/episode-plan-gen/dist/index.js +12 -12
  15. package/plugins/generations/gemini-tts/dist/index.js +9 -9
  16. package/plugins/generations/image-gen/dist/index.js +28 -12
  17. package/plugins/generations/image-gen/src/compose/card.ts +19 -3
  18. package/plugins/generations/news-report-gen/dist/index.js +12 -12
  19. package/plugins/generations/voice-gen/dist/index.js +9 -9
  20. package/plugins/generations/voxcpm-tts/dist/index.js +9 -9
  21. package/plugins/ingestions/aihot-ingest/dist/index.js +12 -12
  22. package/plugins/ingestions/horizon-ingest/dist/index.js +12 -12
  23. package/plugins/ingestions/karakeep-local/dist/index.js +13 -13
  24. package/plugins/ingestions/last30days-ingest/dist/index.js +12 -12
  25. package/plugins/ingestions/web-search/dist/index.js +10 -10
  26. package/plugins/kk/decisions/kk-podcast.yaml +44 -0
  27. package/plugins/kk/decisions/kk-safety.yaml +46 -0
  28. package/plugins/kk/plugin.json +1 -1
  29. package/plugins/kk/scripts/daily-stages.ts +117 -0
  30. package/plugins/kk/scripts/kk-workflow-stages.ts +10 -0
  31. package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +6 -3
  32. package/plugins/kk/workflows/kk-daily-safety.yaml +37 -10
  33. package/plugins/kk/workflows/kk-solo-podcast.yaml +65 -1
  34. package/plugins/publishings/bilibili-pub/dist/index.js +22 -22
  35. package/plugins/publishings/bilibili-pub/dist/profile-check.js +22 -22
  36. package/plugins/publishings/cnblogs-pub/dist/index.js +22 -22
  37. package/plugins/publishings/cnblogs-pub/dist/profile-check.js +22 -22
  38. package/plugins/publishings/csdn-pub/dist/index.js +22 -22
  39. package/plugins/publishings/csdn-pub/dist/profile-check.js +22 -22
  40. package/plugins/publishings/emdash-pub/dist/index.js +9 -9
  41. package/plugins/publishings/infoq-pub/dist/index.js +22 -22
  42. package/plugins/publishings/infoq-pub/dist/profile-check.js +22 -22
  43. package/plugins/publishings/jike-pub/dist/index.js +22 -22
  44. package/plugins/publishings/jike-pub/dist/profile-check.js +22 -22
  45. package/plugins/publishings/juejin-pub/dist/index.js +22 -22
  46. package/plugins/publishings/juejin-pub/dist/profile-check.js +22 -22
  47. package/plugins/publishings/medium-pub/dist/index.js +9 -9
  48. package/plugins/publishings/podcast-pub/dist/index.js +9 -9
  49. package/plugins/publishings/qiita-pub/dist/index.js +9 -9
  50. package/plugins/publishings/shipinhao-pub/dist/index.js +22 -22
  51. package/plugins/publishings/shipinhao-pub/dist/profile-check.js +22 -22
  52. package/plugins/publishings/sspai-pub/dist/index.js +22 -22
  53. package/plugins/publishings/sspai-pub/dist/profile-check.js +22 -22
  54. package/plugins/publishings/substack-pub/dist/index.js +22 -22
  55. package/plugins/publishings/substack-pub/dist/profile-check.js +22 -22
  56. package/plugins/publishings/surfdash-pub/dist/index.js +9 -9
  57. package/plugins/publishings/threads-pub/dist/index.js +9 -9
  58. package/plugins/publishings/wechatmp-pub/dist/index.js +22 -22
  59. package/plugins/publishings/wechatmp-pub/dist/profile-check.js +22 -22
  60. package/plugins/publishings/weibo-pub/dist/index.js +22 -22
  61. package/plugins/publishings/weibo-pub/dist/profile-check.js +22 -22
  62. package/plugins/publishings/x-pub/dist/index.js +22 -22
  63. package/plugins/publishings/x-pub/dist/profile-check.js +22 -22
  64. package/plugins/publishings/xhs-pub/dist/index.js +22 -22
  65. package/plugins/publishings/xhs-pub/dist/profile-check.js +22 -22
  66. package/plugins/publishings/xiaoyuzhou-pub/dist/index.js +22 -22
  67. package/plugins/publishings/xiaoyuzhou-pub/dist/profile-check.js +22 -22
  68. package/plugins/publishings/zenn-pub/dist/index.js +9 -9
@@ -17,17 +17,35 @@ function storeItemsQueryString(query) {
17
17
  }
18
18
  if (query.selection !== undefined)
19
19
  params.set("selection", query.selection);
20
+ if (query.search !== undefined && query.search.trim() !== "") {
21
+ params.set("search", query.search.trim());
22
+ }
23
+ return params.toString();
24
+ }
25
+ function storeSelectionsQueryString(query) {
26
+ const params = new URLSearchParams;
27
+ if (query.page !== undefined)
28
+ params.set("page", String(query.page));
29
+ if (query.topic !== undefined && query.topic !== "")
30
+ params.set("topic", query.topic);
31
+ if (query.status !== undefined)
32
+ params.set("status", query.status);
33
+ if (query.runId !== undefined && query.runId !== "")
34
+ params.set("runId", query.runId);
35
+ if (query.search !== undefined && query.search.trim() !== "") {
36
+ params.set("search", query.search.trim());
37
+ }
20
38
  return params.toString();
21
39
  }
22
40
  var DEFAULT_READER_ORIGIN = "http://127.0.0.1:4340";
23
- function readerOriginFrom(search) {
41
+ function readerOriginFrom(search, defaultOrigin = DEFAULT_READER_ORIGIN) {
24
42
  const override = new URLSearchParams(search).get("kkApi");
25
43
  if (override === null)
26
- return { origin: DEFAULT_READER_ORIGIN, diagnostic: null };
44
+ return { origin: defaultOrigin, diagnostic: null };
27
45
  if (isLoopbackHttpOrigin(override))
28
46
  return { origin: override, diagnostic: null };
29
47
  return {
30
- origin: DEFAULT_READER_ORIGIN,
48
+ origin: defaultOrigin,
31
49
  diagnostic: {
32
50
  code: "board.reader.origin-invalid",
33
51
  message: "Ignored a non-loopback kkApi origin; using the default reader."
@@ -52,6 +70,25 @@ function isLoopbackHttpOrigin(origin) {
52
70
  function origin(base) {
53
71
  return base.replace(/\/+$/, "");
54
72
  }
73
+ function parseSpurDbRows(pageData) {
74
+ const { columns, rows } = pageData;
75
+ if (!columns || !rows)
76
+ return [];
77
+ return rows.map((rowCells) => {
78
+ const rowObj = {};
79
+ columns.forEach((col, idx) => {
80
+ const cell = rowCells[idx];
81
+ if (!cell || cell.t === "null") {
82
+ rowObj[col] = null;
83
+ } else if (cell.t === "num" || cell.t === "text") {
84
+ rowObj[col] = cell.v;
85
+ } else {
86
+ rowObj[col] = null;
87
+ }
88
+ });
89
+ return rowObj;
90
+ });
91
+ }
55
92
  function createBoardClient(options) {
56
93
  if (!isLoopbackHttpOrigin(options.readerOrigin)) {
57
94
  throw new Error(`reader origin must be loopback http, got '${options.readerOrigin}'`);
@@ -62,6 +99,7 @@ function createBoardClient(options) {
62
99
  const reader = origin(options.readerOrigin);
63
100
  const board = origin(options.boardOrigin);
64
101
  const doFetch = options.fetchImpl ?? fetch;
102
+ const isNativeSpur = reader === board;
65
103
  async function getJson(url) {
66
104
  const response = await doFetch(url, { headers: { accept: "application/json" } });
67
105
  if (!response.ok) {
@@ -69,10 +107,370 @@ function createBoardClient(options) {
69
107
  }
70
108
  return await response.json();
71
109
  }
110
+ async function nativeStoreOverview(runIds) {
111
+ try {
112
+ const pageData = await getJson(`${board}/api/project/database/tables/collect_runs/rows?pageSize=100&sort=started_at&dir=desc`);
113
+ const dbRows = parseSpurDbRows(pageData);
114
+ const byId = new Map;
115
+ let maxFinishedAt = 0;
116
+ for (const row of dbRows) {
117
+ let sourceCounts = {};
118
+ try {
119
+ if (row.source_counts_json) {
120
+ const parsed = JSON.parse(row.source_counts_json);
121
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
122
+ sourceCounts = parsed;
123
+ }
124
+ }
125
+ } catch {
126
+ sourceCounts = {};
127
+ }
128
+ if (row.finished_at && typeof row.finished_at === "number" && row.finished_at > maxFinishedAt) {
129
+ maxFinishedAt = row.finished_at;
130
+ }
131
+ byId.set(row.run_id, {
132
+ runId: row.run_id,
133
+ sourceCounts,
134
+ inserted: row.inserted ?? 0,
135
+ updated: row.updated ?? 0,
136
+ labelRows: 0,
137
+ labeledItems: 0,
138
+ labelRowsBySource: {},
139
+ yield: { selected: 0, published: 0, dropped: 0 }
140
+ });
141
+ }
142
+ const rowsMap = {};
143
+ for (const id of runIds) {
144
+ rowsMap[id] = byId.get(id) ?? null;
145
+ }
146
+ return {
147
+ schemaVersion: 1,
148
+ availability: "available",
149
+ lastStoredAt: maxFinishedAt > 0 ? new Date(maxFinishedAt).toISOString() : null,
150
+ rows: rowsMap,
151
+ diagnostics: []
152
+ };
153
+ } catch {
154
+ return {
155
+ schemaVersion: 1,
156
+ availability: "available",
157
+ lastStoredAt: null,
158
+ rows: Object.fromEntries(runIds.map((id) => [id, null])),
159
+ diagnostics: []
160
+ };
161
+ }
162
+ }
163
+ async function nativeStoreRun(runId) {
164
+ try {
165
+ const runRes = await getJson(`${board}/api/project/database/tables/collect_runs/rows?filterColumn=run_id&filter=${encodeURIComponent(runId)}`);
166
+ const runRows = parseSpurDbRows(runRes);
167
+ const rowData = runRows[0];
168
+ let runStoreRow = null;
169
+ if (rowData) {
170
+ let sourceCounts = {};
171
+ try {
172
+ if (rowData.source_counts_json) {
173
+ const parsed = JSON.parse(rowData.source_counts_json);
174
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
175
+ sourceCounts = parsed;
176
+ }
177
+ }
178
+ } catch {
179
+ sourceCounts = {};
180
+ }
181
+ runStoreRow = {
182
+ runId: rowData.run_id,
183
+ sourceCounts,
184
+ inserted: rowData.inserted ?? 0,
185
+ updated: rowData.updated ?? 0,
186
+ labelRows: 0,
187
+ labeledItems: 0,
188
+ labelRowsBySource: {},
189
+ yield: { selected: 0, published: 0, dropped: 0 }
190
+ };
191
+ }
192
+ let labelQuality = [];
193
+ try {
194
+ const labelsRes = await getJson(`${board}/api/project/database/tables/labels/rows?filterColumn=run_id&filter=${encodeURIComponent(runId)}&pageSize=200`);
195
+ const labelRows = parseSpurDbRows(labelsRes);
196
+ const decisionMap = new Map;
197
+ for (const l of labelRows) {
198
+ const dec = l.decision_id || "unknown";
199
+ const val = String(l.value ?? "none");
200
+ const conf = l.confidence || "none";
201
+ let valMap = decisionMap.get(dec);
202
+ if (!valMap) {
203
+ valMap = new Map;
204
+ decisionMap.set(dec, valMap);
205
+ }
206
+ let counts = valMap.get(val);
207
+ if (!counts) {
208
+ counts = { HIGH: 0, MEDIUM: 0, LOW: 0, none: 0 };
209
+ valMap.set(val, counts);
210
+ }
211
+ if (conf === "HIGH" || conf === "MEDIUM" || conf === "LOW") {
212
+ counts[conf] = (counts[conf] ?? 0) + 1;
213
+ } else {
214
+ counts.none = (counts.none ?? 0) + 1;
215
+ }
216
+ }
217
+ labelQuality = Array.from(decisionMap.entries()).map(([decisionId, valMap]) => ({
218
+ decisionId,
219
+ run: Array.from(valMap.entries()).map(([value, counts]) => ({
220
+ value,
221
+ ...counts
222
+ })),
223
+ effective: Array.from(valMap.entries()).map(([value, counts]) => ({
224
+ value,
225
+ count: counts.HIGH + counts.MEDIUM + counts.LOW + counts.none
226
+ }))
227
+ }));
228
+ } catch {
229
+ labelQuality = [];
230
+ }
231
+ return {
232
+ schemaVersion: 1,
233
+ availability: "available",
234
+ runId,
235
+ row: runStoreRow,
236
+ labelQuality,
237
+ diagnostics: []
238
+ };
239
+ } catch {
240
+ return {
241
+ schemaVersion: 1,
242
+ availability: "available",
243
+ runId,
244
+ row: null,
245
+ labelQuality: [],
246
+ diagnostics: []
247
+ };
248
+ }
249
+ }
250
+ async function nativeStoreItems(runId, query = {}) {
251
+ const pageNum = query.page ?? 1;
252
+ const params = new URLSearchParams({
253
+ page: String(pageNum),
254
+ pageSize: "25",
255
+ sort: "first_seen_at",
256
+ dir: "desc"
257
+ });
258
+ if (query.search?.trim()) {
259
+ params.set("filterColumn", "title");
260
+ params.set("filter", query.search.trim());
261
+ } else if (query.source) {
262
+ params.set("filterColumn", "source");
263
+ params.set("filter", query.source);
264
+ } else if (runId?.trim()) {
265
+ params.set("filterColumn", "first_seen_run");
266
+ params.set("filter", runId.trim());
267
+ }
268
+ try {
269
+ const pageData = await getJson(`${board}/api/project/database/tables/items/rows?${params.toString()}`);
270
+ const rows = parseSpurDbRows(pageData);
271
+ const itemsWithLabels = await Promise.all(rows.map(async (row) => {
272
+ const labels = {};
273
+ const labelDetails = {};
274
+ try {
275
+ const labRes = await getJson(`${board}/api/project/database/tables/labels/rows?filterColumn=item_id&filter=${encodeURIComponent(row.id)}&pageSize=50`);
276
+ const labRows = parseSpurDbRows(labRes);
277
+ for (const l of labRows) {
278
+ if (l.decision_id) {
279
+ labels[l.decision_id] = String(l.value ?? "");
280
+ labelDetails[l.decision_id] = {
281
+ value: String(l.value ?? ""),
282
+ confidence: l.confidence ?? null,
283
+ maker: l.maker ?? null,
284
+ score: typeof l.score === "number" ? l.score : null
285
+ };
286
+ }
287
+ }
288
+ } catch {}
289
+ const url = row.canonical_url && /^https?:\/\//i.test(row.canonical_url) ? row.canonical_url : null;
290
+ const seen = row.first_seen_run && row.last_seen_run && row.first_seen_run !== row.last_seen_run ? "reseen" : "new";
291
+ return {
292
+ id: row.id,
293
+ title: (row.title || "").slice(0, 300),
294
+ url,
295
+ source: row.source || "unknown",
296
+ storyId: row.story_id ?? null,
297
+ seen,
298
+ labels,
299
+ labelDetails,
300
+ selection: "none",
301
+ domain: row.domain ?? null,
302
+ lang: row.lang ?? null,
303
+ bodyChars: row.body_chars ?? null,
304
+ engagement: row.engagement ?? null,
305
+ firstSeenAt: row.first_seen_at ?? null,
306
+ publishedAt: row.published_at ?? null
307
+ };
308
+ }));
309
+ return {
310
+ schemaVersion: 1,
311
+ availability: "available",
312
+ runId: runId ?? "",
313
+ page: pageNum,
314
+ pageSize: 25,
315
+ total: pageData.total ?? itemsWithLabels.length,
316
+ items: itemsWithLabels,
317
+ sources: ["aihot", "hackernews", "youtube", "reddit", "polymarket", "github", "grounding", "rss"],
318
+ diagnostics: []
319
+ };
320
+ } catch {
321
+ return {
322
+ schemaVersion: 1,
323
+ availability: "available",
324
+ runId: runId ?? "",
325
+ page: pageNum,
326
+ pageSize: 25,
327
+ total: 0,
328
+ items: [],
329
+ sources: [],
330
+ diagnostics: []
331
+ };
332
+ }
333
+ }
334
+ async function nativeStoreSelections(query = {}) {
335
+ const pageNum = query.page ?? 1;
336
+ const params = new URLSearchParams({
337
+ page: String(pageNum),
338
+ pageSize: "25",
339
+ sort: "selected_at",
340
+ dir: "desc"
341
+ });
342
+ if (query.topic) {
343
+ params.set("filterColumn", "topic");
344
+ params.set("filter", query.topic);
345
+ } else if (query.status) {
346
+ params.set("filterColumn", "status");
347
+ params.set("filter", query.status);
348
+ } else if (query.runId) {
349
+ params.set("filterColumn", "run_id");
350
+ params.set("filter", query.runId);
351
+ }
352
+ try {
353
+ const pageData = await getJson(`${board}/api/project/database/tables/selections/rows?${params.toString()}`);
354
+ const rows = parseSpurDbRows(pageData);
355
+ const selectionsWithItems = await Promise.all(rows.map(async (row) => {
356
+ let title = null;
357
+ let source = row.workflow ?? null;
358
+ let url = null;
359
+ try {
360
+ const itRes = await getJson(`${board}/api/project/database/tables/items/rows?filterColumn=id&filter=${encodeURIComponent(row.item_id)}&pageSize=1`);
361
+ const itRows = parseSpurDbRows(itRes);
362
+ if (itRows[0]) {
363
+ title = itRows[0].title ?? null;
364
+ source = itRows[0].source ?? source;
365
+ url = itRows[0].canonical_url && /^https?:\/\//i.test(itRows[0].canonical_url) ? itRows[0].canonical_url : null;
366
+ }
367
+ } catch {}
368
+ return {
369
+ topic: row.topic,
370
+ itemId: row.item_id,
371
+ runId: row.run_id,
372
+ storyId: row.story_id,
373
+ workflow: row.workflow ?? null,
374
+ rank: typeof row.rank === "number" ? row.rank : null,
375
+ reason: row.reason ?? null,
376
+ status: row.status ?? "selected",
377
+ selectedAt: row.selected_at,
378
+ publishedAt: row.published_at ?? null,
379
+ title: title || row.item_id,
380
+ source: source || "unknown",
381
+ url
382
+ };
383
+ }));
384
+ return {
385
+ schemaVersion: 1,
386
+ availability: "available",
387
+ page: pageNum,
388
+ pageSize: 25,
389
+ total: pageData.total ?? selectionsWithItems.length,
390
+ selections: selectionsWithItems,
391
+ topics: ["ai-news"],
392
+ diagnostics: []
393
+ };
394
+ } catch {
395
+ return {
396
+ schemaVersion: 1,
397
+ availability: "available",
398
+ page: pageNum,
399
+ pageSize: 25,
400
+ total: 0,
401
+ selections: [],
402
+ topics: ["ai-news"],
403
+ diagnostics: []
404
+ };
405
+ }
406
+ }
407
+ async function nativeResults(workflow, runId) {
408
+ try {
409
+ const runData = await getJson(`${board}/api/runs/${encodeURIComponent(runId)}`);
410
+ const totalDuration = runData.actions?.reduce((acc, a) => acc + (a.durationMs || 0), 0) ?? 0;
411
+ return {
412
+ schemaVersion: 1,
413
+ workflow,
414
+ runId,
415
+ availability: "available",
416
+ summary: {
417
+ status: runData.run?.status ?? "done",
418
+ startedAt: runData.run?.startedAt,
419
+ completedAt: runData.run?.completedAt,
420
+ durationMs: totalDuration,
421
+ actions: runData.actions?.length ?? 0,
422
+ phases: runData.phases?.length ?? 0
423
+ },
424
+ artifacts: [],
425
+ diagnostics: []
426
+ };
427
+ } catch {
428
+ return {
429
+ schemaVersion: 1,
430
+ workflow,
431
+ runId,
432
+ availability: "missing",
433
+ summary: {},
434
+ artifacts: [],
435
+ diagnostics: []
436
+ };
437
+ }
438
+ }
439
+ async function nativeConfig(workflow, runId) {
440
+ try {
441
+ const runData = await getJson(`${board}/api/runs/${encodeURIComponent(runId)}`);
442
+ return {
443
+ schemaVersion: 1,
444
+ workflow,
445
+ runId,
446
+ capturedAt: runData.run?.startedAt ?? null,
447
+ settings: {
448
+ workflowName: runData.run?.workflowName ?? workflow,
449
+ status: runData.run?.status ?? "done",
450
+ mode: runData.run?.mode ?? "state-machine"
451
+ },
452
+ unavailableKeys: [],
453
+ diagnostics: []
454
+ };
455
+ } catch {
456
+ return {
457
+ schemaVersion: 1,
458
+ workflow,
459
+ runId,
460
+ capturedAt: null,
461
+ settings: {},
462
+ unavailableKeys: [],
463
+ diagnostics: []
464
+ };
465
+ }
466
+ }
72
467
  return {
73
- health: () => getJson(`${reader}/api/health`),
74
- results: (workflow, runId) => getJson(`${reader}/api/workflows/${encodeURIComponent(workflow)}/runs/${encodeURIComponent(runId)}/results`),
75
- config: (workflow, runId) => getJson(`${reader}/api/workflows/${encodeURIComponent(workflow)}/runs/${encodeURIComponent(runId)}/config`),
468
+ health: () => isNativeSpur ? getJson(`${board}/api/health`).then(() => ({
469
+ schemaVersion: 1,
470
+ projectPath: "knowledge-kit"
471
+ })) : getJson(`${reader}/api/health`),
472
+ results: (workflow, runId) => isNativeSpur ? nativeResults(workflow, runId) : getJson(`${reader}/api/workflows/${encodeURIComponent(workflow)}/runs/${encodeURIComponent(runId)}/results`),
473
+ config: (workflow, runId) => isNativeSpur ? nativeConfig(workflow, runId) : getJson(`${reader}/api/workflows/${encodeURIComponent(workflow)}/runs/${encodeURIComponent(runId)}/config`),
76
474
  artifactUrl: (workflow, runId, artifactId) => `${reader}/api/workflows/${encodeURIComponent(workflow)}/runs/${encodeURIComponent(runId)}/artifacts/${encodeURIComponent(artifactId)}`,
77
475
  runs: (workflow, cursor) => {
78
476
  const params = new URLSearchParams({ workflow, limit: "25" });
@@ -81,11 +479,20 @@ function createBoardClient(options) {
81
479
  return getJson(`${board}/api/runs?${params.toString()}`);
82
480
  },
83
481
  storeOverview: (runIds) => {
482
+ if (isNativeSpur)
483
+ return nativeStoreOverview(runIds);
84
484
  const params = new URLSearchParams({ runs: runIds.slice(0, MAX_OVERVIEW_RUNS).join(",") });
85
485
  return getJson(`${reader}/api/workflows/kk-collect/store/overview?${params.toString()}`);
86
486
  },
87
- storeRun: (runId) => getJson(`${reader}/api/workflows/kk-collect/runs/${encodeURIComponent(runId)}/store`),
88
- storeItems: (runId, query = {}) => getJson(`${reader}/api/workflows/kk-collect/runs/${encodeURIComponent(runId)}/store/items?${storeItemsQueryString(query)}`),
487
+ storeRun: (runId) => isNativeSpur ? nativeStoreRun(runId) : getJson(`${reader}/api/workflows/kk-collect/runs/${encodeURIComponent(runId)}/store`),
488
+ storeItems: (runId, query = {}) => {
489
+ if (isNativeSpur)
490
+ return nativeStoreItems(runId, query);
491
+ const qs = storeItemsQueryString(query);
492
+ const path = runId !== undefined && runId.trim() !== "" ? `${reader}/api/workflows/kk-collect/runs/${encodeURIComponent(runId)}/store/items?${qs}` : `${reader}/api/workflows/kk-collect/store/items?${qs}`;
493
+ return getJson(path);
494
+ },
495
+ storeSelections: (query = {}) => isNativeSpur ? nativeStoreSelections(query) : getJson(`${reader}/api/workflows/kk-collect/store/selections?${storeSelectionsQueryString(query)}`),
89
496
  runDetail: (runId) => getJson(`${board}/api/runs/${encodeURIComponent(runId)}`),
90
497
  progress: (runId) => getJson(`${board}/api/runs/${encodeURIComponent(runId)}/progress`)
91
498
  };