@wirecat/cli-template 0.13.1 → 0.14.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 (112) hide show
  1. package/.github/workflows/changelog-guard.yml +1 -1
  2. package/.github/workflows/ci.yml +1 -1
  3. package/.github/workflows/monthly.yml +1 -1
  4. package/.github/workflows/release.yml +44 -10
  5. package/CHANGELOG.md +36 -0
  6. package/config/parity-groups.json +32 -1
  7. package/contracts/mcp-tools.json +100 -0
  8. package/dist/bin/clidev.js +6 -2
  9. package/dist/bundle/{all-profiles-MJ6XSFOO.js → all-profiles-NVB2HT2S.js} +6 -6
  10. package/dist/bundle/{anthropic-W5UKBZUB.js → anthropic-ICTW7CNQ.js} +4 -4
  11. package/dist/bundle/{app-server-EZ46JAHB.js → app-server-B6BCKXR7.js} +40 -38
  12. package/dist/bundle/{bun-HB6O2TTT.js → bun-ILPS6AYA.js} +2 -2
  13. package/dist/bundle/{bun-sqlite-KBXOW2ES.js → bun-sqlite-JE6FJFQT.js} +3 -3
  14. package/dist/bundle/{chunk-KJTNT4SW.js → chunk-2DAXUNTS.js} +2 -2
  15. package/dist/bundle/chunk-3MDNAYQA.js +34 -0
  16. package/dist/bundle/chunk-3WDYHOAF.js +91 -0
  17. package/dist/bundle/{chunk-EGRB55FF.js → chunk-45244QQ6.js} +14 -12
  18. package/dist/bundle/{chunk-JHO2LL2J.js → chunk-4PA6DJ7F.js} +7 -7
  19. package/dist/bundle/{chunk-FZZIU4B7.js → chunk-5SAF3XOL.js} +8196 -5601
  20. package/dist/bundle/chunk-62JRF2JA.js +35 -0
  21. package/dist/bundle/{chunk-TGB5F7NC.js → chunk-66VMJGV6.js} +4 -4
  22. package/dist/bundle/{chunk-V3ZTQ24B.js → chunk-6AW4DDK4.js} +4 -4
  23. package/dist/bundle/{chunk-PJOVK7PG.js → chunk-7F5VMLVK.js} +49 -24
  24. package/dist/bundle/{chunk-MFS52LTZ.js → chunk-7Z4HR6GO.js} +1 -1
  25. package/dist/bundle/{chunk-E42W72PQ.js → chunk-AS2PJNQ2.js} +7 -5
  26. package/dist/bundle/{chunk-SVDF6NJF.js → chunk-ASHVHS52.js} +14 -14
  27. package/dist/bundle/{chunk-N2Z3MCOF.js → chunk-BEBD27QT.js} +37 -35
  28. package/dist/bundle/{chunk-IGHEW777.js → chunk-BM5ZCDPQ.js} +5 -40
  29. package/dist/bundle/{chunk-AK257OMS.js → chunk-BVLPNNEL.js} +209 -78
  30. package/dist/bundle/{chunk-ERKR3VJ5.js → chunk-BWBZCYUN.js} +141 -46
  31. package/dist/bundle/{chunk-Z7MSIRSQ.js → chunk-CGFQT3LQ.js} +1 -1
  32. package/dist/bundle/{chunk-QKWRL4OD.js → chunk-DQIBGCF3.js} +6 -6
  33. package/dist/bundle/{chunk-RUKDZEID.js → chunk-DZLHY4IA.js} +3 -3
  34. package/dist/bundle/{chunk-TAYOKLGF.js → chunk-EMHCXXNJ.js} +7 -6
  35. package/dist/bundle/{chunk-IBBN7Z3A.js → chunk-F34HGYWF.js} +12 -3
  36. package/dist/bundle/{chunk-ERGB4NJA.js → chunk-G45R7M42.js} +1 -1
  37. package/dist/bundle/{chunk-ZLY6GUAS.js → chunk-G7W53MQP.js} +3 -3
  38. package/dist/bundle/{chunk-JAOGZMKQ.js → chunk-GUFPQZUA.js} +2 -2
  39. package/dist/bundle/{chunk-4LURWBVV.js → chunk-HYTHTSJP.js} +188 -22
  40. package/dist/bundle/{chunk-EFHLQXG6.js → chunk-IOJ2DTCY.js} +162 -55
  41. package/dist/bundle/{chunk-L5WWMP5M.js → chunk-IZKXJJ7V.js} +121 -31
  42. package/dist/bundle/{chunk-NOVLCHDV.js → chunk-LATYBJ4T.js} +2 -2
  43. package/dist/bundle/{chunk-QBP7OMN5.js → chunk-LFLSV353.js} +2 -2
  44. package/dist/bundle/{chunk-HDY5X3WQ.js → chunk-LU4A2T7Y.js} +4 -4
  45. package/dist/bundle/{chunk-JRK73FOW.js → chunk-NENYWEXF.js} +1 -1
  46. package/dist/bundle/{chunk-2B5U4Z5H.js → chunk-NH6LZ3H3.js} +8 -13
  47. package/dist/bundle/{chunk-OV6PHTAY.js → chunk-NVNUUHT5.js} +17130 -2232
  48. package/dist/bundle/chunk-PIJUGF5F.js +392 -0
  49. package/dist/bundle/{chunk-7IXL4UFK.js → chunk-PX2KP4QE.js} +8 -8
  50. package/dist/bundle/{chunk-N5GXKDBC.js → chunk-QXOSPYM3.js} +1 -1
  51. package/dist/bundle/{chunk-PBN4RBHS.js → chunk-R2JKPHH5.js} +8 -8
  52. package/dist/bundle/{chunk-PDGXMKJS.js → chunk-R5RYPD23.js} +2 -2
  53. package/dist/bundle/{chunk-QJ6XW4DM.js → chunk-RJ7AS7UB.js} +6210 -1207
  54. package/dist/bundle/{chunk-35KYY65W.js → chunk-SOYOOU2D.js} +3 -3
  55. package/dist/bundle/{chunk-FDBINRWA.js → chunk-TJJ2XSJP.js} +5 -5
  56. package/dist/bundle/{chunk-O3UXNU3S.js → chunk-U6QD3J3F.js} +3 -3
  57. package/dist/bundle/{chunk-YJNUDHJD.js → chunk-UT5TQ6MD.js} +139 -35
  58. package/dist/bundle/{chunk-VYSUKHKL.js → chunk-VOTEB3AN.js} +1 -1
  59. package/dist/bundle/{chunk-IN3FVRPK.js → chunk-VS5LGSTM.js} +1 -1
  60. package/dist/bundle/{chunk-MJRSEUKG.js → chunk-VXOR76ZL.js} +13 -89
  61. package/dist/bundle/{chunk-CXQXVKUY.js → chunk-YIVY2WI3.js} +1 -1
  62. package/dist/bundle/{chunk-VLNKTMV7.js → chunk-YOJLIVGO.js} +959 -350
  63. package/dist/bundle/clidev.js +3 -3
  64. package/dist/bundle/command-contract-JMVMT5HT.js +28 -0
  65. package/dist/bundle/{decode-AMXUVKNY.js → decode-NXB5UKMO.js} +18 -16
  66. package/dist/bundle/{echarts-GJDMQ2AQ.js → echarts-DRDGGHJT.js} +2 -2
  67. package/dist/bundle/{embed-L4CRZ2XQ.js → embed-IKZ24BMC.js} +4 -4
  68. package/dist/bundle/{embedder-IBGV4M2K.js → embedder-GMQ24DOQ.js} +7 -7
  69. package/dist/bundle/{first-run-VTKC2IBV.js → first-run-MDD4SIUK.js} +8 -8
  70. package/dist/bundle/first-screen-376CXGXJ.js +26 -0
  71. package/dist/bundle/{instructions-YJECS4KN.js → instructions-EOQOXY6V.js} +1 -1
  72. package/dist/bundle/{mcp-OQBZXELQ.js → mcp-7HBLFGCW.js} +2 -2
  73. package/dist/bundle/mcp-KHUZOJO6.js +82 -0
  74. package/dist/bundle/{mcp-7XPOACO4.js → mcp-MZHWJXAE.js} +38 -37
  75. package/dist/bundle/{node-NQG4EVZR.js → node-52WF2326.js} +2 -2
  76. package/dist/bundle/{node-sqlite-BR7F3BLB.js → node-sqlite-73Z4SFOA.js} +9 -3
  77. package/dist/bundle/{oauth-J7UAWNIK.js → oauth-EVTPAMZP.js} +5 -5
  78. package/dist/bundle/{open-BR47R5UE.js → open-46WZAPJ3.js} +3 -2
  79. package/dist/bundle/openai-GWRDAHDU.js +248 -0
  80. package/dist/bundle/{process-66I7RDPJ.js → process-YIQPKLZI.js} +1 -1
  81. package/dist/bundle/{program-ZNXLJ3D2.js → program-B3CY3FP7.js} +11346 -9559
  82. package/dist/bundle/{prompt-NE5JJ7UP.js → prompt-IVEYRLS5.js} +3 -3
  83. package/dist/bundle/{recognize-GC3YFVIA.js → recognize-WVEKHODM.js} +4 -2
  84. package/dist/bundle/{remote-QELOMKQM.js → remote-4K5VPMC7.js} +5 -5
  85. package/dist/bundle/{rerank-BH6TZ2SP.js → rerank-V24UJZYJ.js} +5 -5
  86. package/dist/bundle/{serve-WWLRNDT2.js → serve-PJWSOV7F.js} +7 -7
  87. package/dist/bundle/server-2ZN7KZHZ.js +40 -0
  88. package/dist/bundle/server-5VYM7CCF.js +53 -0
  89. package/dist/bundle/{state-2BEGXAMO.js → state-ZPYGECVP.js} +4 -4
  90. package/dist/bundle/{store-AH6WZMCF.js → store-6JQCLPQF.js} +14 -9
  91. package/dist/bundle/store-maintenance-command-7XICIYHW.js +42 -0
  92. package/dist/version.d.ts +1 -1
  93. package/dist/version.js +1 -1
  94. package/docs/commands.md +37 -11
  95. package/docs/dev/reference-clis.md +1 -1
  96. package/docs/dev/skills/design-interview/SKILL.md +2 -2
  97. package/docs/dev/test-matrix.md +5 -1
  98. package/kit/dist/interview.js +1 -0
  99. package/kit/dist/new.js +8 -3
  100. package/package.json +3 -3
  101. package/src/program.test.ts +56 -0
  102. package/src/version.ts +1 -1
  103. package/dist/bundle/chunk-IDWW4TU2.js +0 -18
  104. package/dist/bundle/chunk-MUSYGFCY.js +0 -3556
  105. package/dist/bundle/chunk-O5EHUB2V.js +0 -2
  106. package/dist/bundle/command-contract-75VJ36U4.js +0 -29
  107. package/dist/bundle/first-screen-X5IJKBSU.js +0 -27
  108. package/dist/bundle/mcp-RDZGYPSY.js +0 -78
  109. package/dist/bundle/server-DE6NLNUF.js +0 -52
  110. package/dist/bundle/server-ZPSQKOAH.js +0 -39
  111. package/dist/bundle/store-maintenance-command-PBXX3IEV.js +0 -40
  112. /package/dist/bundle/{chunk-GOO67PDU.js → chunk-NL2DQPT7.js} +0 -0
@@ -13,6 +13,7 @@ import {
13
13
  integer,
14
14
  isCliError,
15
15
  isoTime,
16
+ isoTimestamp,
16
17
  lazy,
17
18
  literal,
18
19
  maxValue,
@@ -25,6 +26,7 @@ import {
25
26
  pageSchema,
26
27
  picklist,
27
28
  pipe,
29
+ record,
28
30
  reference,
29
31
  safeParse,
30
32
  singleLine,
@@ -32,14 +34,15 @@ import {
32
34
  strictObject,
33
35
  string,
34
36
  union,
37
+ unknown,
35
38
  variant,
36
39
  visibleControls
37
- } from "./chunk-EFHLQXG6.js";
40
+ } from "./chunk-IOJ2DTCY.js";
38
41
  import {
39
42
  __name
40
43
  } from "./chunk-ZVVMGPBJ.js";
41
44
 
42
- // node_modules/.pnpm/@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/types.js
45
+ // node_modules/.pnpm/@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/types.js
43
46
  var QUERY_LIMITS = {
44
47
  bytes: 8192,
45
48
  depth: 32,
@@ -83,7 +86,7 @@ function queryError(reason, span, alternative, context3 = {}, details = {}) {
83
86
  __name(queryError, "queryError");
84
87
  var walkQuery = /* @__PURE__ */ __name((node) => node.kind === "predicate" ? [node] : node.clauses.flatMap(({ node: node2 }) => walkQuery(node2)), "walkQuery");
85
88
 
86
- // node_modules/.pnpm/@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/dates.js
89
+ // node_modules/.pnpm/@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/dates.js
87
90
  var timezoneOf = /* @__PURE__ */ __name((given) => {
88
91
  const zone = given ?? Intl.DateTimeFormat().resolvedOptions().timeZone ?? "UTC";
89
92
  try {
@@ -116,8 +119,8 @@ var dayBoundary = /* @__PURE__ */ __name((value, zone, next, span) => {
116
119
  day: "2-digit",
117
120
  era: "short"
118
121
  });
119
- const dayAt = /* @__PURE__ */ __name((time) => {
120
- const parts = formatter.formatToParts(time);
122
+ const dayAt = /* @__PURE__ */ __name((time2) => {
123
+ const parts = formatter.formatToParts(time2);
121
124
  const value2 = /* @__PURE__ */ __name((name) => Number(parts.find((p) => p.type === name)?.value), "value");
122
125
  const year = parts.find((p) => p.type === "era")?.value === "BC" ? 1 - value2("year") : value2("year");
123
126
  return year * 1e4 + value2("month") * 100 + value2("day");
@@ -173,11 +176,11 @@ var zonedMoment = /* @__PURE__ */ __name((value, zone, span, { end = false } = {
173
176
  return dayBoundary(value, zone, end, span) - (end ? 1 : 0);
174
177
  if (!ZONED.test(value))
175
178
  return wallTime(value, zone, span);
176
- const time = Date.parse(value);
177
- if (!/^\d{4}-\d{2}-\d{2}T/u.test(value) || !Number.isFinite(time))
179
+ const time2 = Date.parse(value);
180
+ if (!/^\d{4}-\d{2}-\d{2}T/u.test(value) || !Number.isFinite(time2))
178
181
  queryError("query.invalid-date", span);
179
182
  calendar(value.slice(0, 10), span);
180
- return time;
183
+ return time2;
181
184
  }, "zonedMoment");
182
185
  var AGO = /^(\d+)(m|h|d)$/u;
183
186
  var AGO_MS = { m: 6e4, h: 36e5, d: 864e5 };
@@ -211,10 +214,10 @@ var dateEndpoint = /* @__PURE__ */ __name((value, zone, side, inclusive, span, n
211
214
  if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})$/u.test(value))
212
215
  queryError("query.invalid-date", span, "use an ISO date, today, yesterday, 30m/2h/7d ago, or a quoted timestamp with offset");
213
216
  calendar(value.slice(0, 10), span);
214
- const time = Date.parse(value);
215
- if (!Number.isFinite(time) || Number(value.slice(11, 13)) > 23 || Number(value.slice(14, 16)) > 59 || Number(value.slice(17, 19)) > 59)
217
+ const time2 = Date.parse(value);
218
+ if (!Number.isFinite(time2) || Number(value.slice(11, 13)) > 23 || Number(value.slice(14, 16)) > 59 || Number(value.slice(17, 19)) > 59)
216
219
  queryError("query.invalid-date", span);
217
- return { time, inclusive };
220
+ return { time: time2, inclusive };
218
221
  }, "dateEndpoint");
219
222
  var dateRange = /* @__PURE__ */ __name((lower, upper, lowerInclusive, upperInclusive, zone, span, now = Date.now()) => {
220
223
  const since = lower === upper && AGO.test(lower.toLowerCase());
@@ -228,7 +231,7 @@ var dateRange = /* @__PURE__ */ __name((lower, upper, lowerInclusive, upperInclu
228
231
  };
229
232
  }, "dateRange");
230
233
 
231
- // node_modules/.pnpm/@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/fields.js
234
+ // node_modules/.pnpm/@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/fields.js
232
235
  var FIELD_TYPES = ["kw", "txt", "enum", "num", "time", "bool", "ref"];
233
236
  var OPERATORS_BY_TYPE = {
234
237
  kw: ["term", "phrase", "wildcard"],
@@ -278,11 +281,13 @@ var queryFieldsOf = /* @__PURE__ */ __name((schema, annotations = {}) => {
278
281
  const excluded = new Set(annotations.exclude ?? []);
279
282
  const words2 = new Set(annotations.text ?? []);
280
283
  const native = new Set(annotations.native ?? []);
284
+ const negatable = new Set(annotations.negatable ?? []);
281
285
  const finish = /* @__PURE__ */ __name((field) => ({
282
286
  ...field,
283
287
  operators: OPERATORS_BY_TYPE[field.type],
284
288
  example: annotations.examples?.[field.name] ?? field.example ?? exampleOf(field.name, field.type, field.values),
285
289
  ...native.has(field.name) ? { native: true } : {},
290
+ ...negatable.has(field.name) ? { negatable: true } : {},
286
291
  ...annotations.validate?.[field.name] ? { validate: annotations.validate[field.name] } : {}
287
292
  }), "finish");
288
293
  const own = Object.entries(entries).flatMap(([name, entry]) => {
@@ -305,7 +310,44 @@ var queryFieldsOf = /* @__PURE__ */ __name((schema, annotations = {}) => {
305
310
  return [...own, ...relations, ...states];
306
311
  }, "queryFieldsOf");
307
312
 
308
- // node_modules/.pnpm/@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/validate.js
313
+ // node_modules/.pnpm/@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/help.js
314
+ var shownOf = /* @__PURE__ */ __name((registry) => registry.backend === "native" ? registry.fields.filter((field) => field.native) : registry.fields, "shownOf");
315
+ var leftOut = /* @__PURE__ */ __name((fields) => fields.filter((field) => field.negatable).map((field) => field.name), "leftOut");
316
+ var has = /* @__PURE__ */ __name((fields, operator) => fields.some((field) => field.operators.includes(operator)), "has");
317
+ var syntaxOf = /* @__PURE__ */ __name((shown, backend) => [
318
+ "field:value",
319
+ ...has(shown, "phrase") ? ['"a phrase"'] : [],
320
+ ...has(shown, "wildcard") ? ["word*"] : [],
321
+ ...backend === "native" ? ["terms joined by AND"] : ["AND OR NOT", "( )"],
322
+ ...has(shown, "range") ? ["[a TO b] \xB7 > >= < <="] : []
323
+ ].join(" \xB7 "), "syntaxOf");
324
+ var kindOf = /* @__PURE__ */ __name((field) => field.values ? `${field.type}: ${field.values.join("|")}` : `${field.type}: ${field.operators.join(", ")}`, "kindOf");
325
+ var fieldsHelp = /* @__PURE__ */ __name((registry, guide) => {
326
+ const shown = shownOf(registry);
327
+ const negatable = leftOut(shown);
328
+ const rows = shown.map((field) => [field.name, kindOf(field), field.example]);
329
+ const widths = [0, 1].map((at) => Math.max(...rows.map((row) => (row[at] ?? "").length)));
330
+ return [
331
+ "Fields:",
332
+ ...rows.map(([name = "", kind = "", example = ""]) => ` ${name.padEnd(widths[0] ?? 0)} ${kind.padEnd(widths[1] ?? 0)} ${example}`.trimEnd()),
333
+ ...registry.defaults && registry.defaults.length > 0 ? [`Defaults: ${registry.defaults.join(" ")} \u2014 name the field to change it`] : [],
334
+ ...negatable.length > 0 ? [`Leave out: -${negatable[0]}:value or NOT ${negatable[0]}:value, for ${negatable.join(", ")}`] : [],
335
+ `Syntax: ${syntaxOf(shown, registry.backend)}`,
336
+ ...guide ? [`Guide: ${guide}`] : []
337
+ ].join("\n");
338
+ }, "fieldsHelp");
339
+ var queryDescription = /* @__PURE__ */ __name((registry) => {
340
+ const shown = shownOf(registry);
341
+ if (shown.length === 0)
342
+ return "field:value terms; this list filters by none yet, so any term is refused";
343
+ const negatable = leftOut(shown);
344
+ const terms = registry.backend === "native" ? `field:value terms joined by AND that narrow the list${negatable.length > 0 ? `; -field:value or NOT field:value leaves out what matches, for ${negatable.join(", ")} only` : ""}` : `field:value terms that narrow the list (Lucene: AND OR NOT, -field:value${has(shown, "range") ? ", [a TO b], > <" : ""})`;
345
+ const fields = shown.map((field) => field.values ? `${field.name} (${field.values.join("|")})` : field.name);
346
+ const defaults = registry.defaults?.length ? `; unless named: ${registry.defaults.join(" ")}` : "";
347
+ return `${terms}; fields: ${fields.join(", ")}; e.g. ${shown[0]?.example ?? ""}${defaults}`;
348
+ }, "queryDescription");
349
+
350
+ // node_modules/.pnpm/@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/validate.js
309
351
  var inContext = /* @__PURE__ */ __name((context3, run2) => {
310
352
  try {
311
353
  run2();
@@ -380,7 +422,7 @@ var validateQuery = /* @__PURE__ */ __name((ast, registry, options = {}) => {
380
422
  }, "validateQuery");
381
423
  var fieldsNamed = /* @__PURE__ */ __name((ast) => new Set(walkQuery(ast.root).map((node) => node.field)), "fieldsNamed");
382
424
 
383
- // node_modules/.pnpm/@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/parser.js
425
+ // node_modules/.pnpm/@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/parser.js
384
426
  var whitespace = /* @__PURE__ */ __name((c) => /[ \t\n\r\u3000]/u.test(c), "whitespace");
385
427
  var reserved = /* @__PURE__ */ new Set([
386
428
  "+",
@@ -487,6 +529,10 @@ var tokensOf = /* @__PURE__ */ __name((text6, fail = queryError) => {
487
529
  break;
488
530
  at++;
489
531
  }
532
+ const [field, colon] = tokens.slice(-2);
533
+ if (field?.kind === "term" && colon?.kind === ":" && colon.span.end === start && text6[at] === ":" && /^[a-z][a-z_-]*$/u.test(text6.slice(start, at)) && /^:[^\s()"]/u.test(text6.slice(at)))
534
+ while (at < text6.length && !whitespace(text6[at] ?? "") && !["(", ")", '"'].includes(text6[at] ?? ""))
535
+ at++;
490
536
  const raw = text6.slice(start, at);
491
537
  kind = { AND: "AND", OR: "OR", NOT: "NOT", "&&": "AND", "||": "OR" }[raw] ?? (/^\d+(?:\.\d+)?$/u.test(raw) ? "number" : "term");
492
538
  }
@@ -514,7 +560,7 @@ var parseLucene = /* @__PURE__ */ __name((text6, { defaultField = "text", proxim
514
560
  fail("query.too-large", { start: 0, end: text6.length });
515
561
  const tokens = tokensOf(text6, fail);
516
562
  let at = 0;
517
- let count6 = 0;
563
+ let count7 = 0;
518
564
  let depth = 0;
519
565
  const peek = /* @__PURE__ */ __name(() => tokens[at], "peek");
520
566
  const take = /* @__PURE__ */ __name(() => tokens[at++], "take");
@@ -524,7 +570,7 @@ var parseLucene = /* @__PURE__ */ __name((text6, { defaultField = "text", proxim
524
570
  return take();
525
571
  }, "expect");
526
572
  const built = /* @__PURE__ */ __name((node) => {
527
- if (++count6 > QUERY_LIMITS.nodes)
573
+ if (++count7 > QUERY_LIMITS.nodes)
528
574
  fail("query.too-large", node.span);
529
575
  return node;
530
576
  }, "built");
@@ -682,10 +728,10 @@ var implicitTextTerms = /* @__PURE__ */ __name((text6) => {
682
728
  const tokens = tokensOf(text6);
683
729
  if (tokens.some(({ kind }) => ["AND", "OR", "NOT", "+", "-", "!", "(", ")"].includes(kind)))
684
730
  return /* @__PURE__ */ new Set();
685
- return new Set(tokens.flatMap((token, index) => token.kind === "term" && ![":", "=", "<", ">", "<=", ">="].includes(tokens[index - 1]?.kind ?? "") && ![":", "=", "<", ">", "<=", ">="].includes(tokens[index + 1]?.kind ?? "") ? [token.span.start] : []));
731
+ return new Set(tokens.flatMap((token, index) => (token.kind === "term" || token.kind === "number") && ![":", "=", "<", ">", "<=", ">="].includes(tokens[index - 1]?.kind ?? "") && ![":", "=", "<", ">", "<=", ">="].includes(tokens[index + 1]?.kind ?? "") ? [token.span.start] : []));
686
732
  }, "implicitTextTerms");
687
733
 
688
- // node_modules/.pnpm/@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/registry.js
734
+ // node_modules/.pnpm/@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/registry.js
689
735
  var describeQuery = /* @__PURE__ */ __name((registry) => ({
690
736
  entity: registry.entity,
691
737
  backend: registry.backend,
@@ -713,7 +759,10 @@ var exampleProblems = /* @__PURE__ */ __name((registry) => {
713
759
  ...defaults
714
760
  ].filter((entry) => entry.problem !== void 0);
715
761
  }, "exampleProblems");
762
+ var checked = /* @__PURE__ */ new WeakSet();
716
763
  var defineQuery = /* @__PURE__ */ __name((registry) => {
764
+ if (checked.has(registry))
765
+ return registry;
717
766
  const names = registry.fields.map((field) => field.name);
718
767
  const problems = [
719
768
  ...duplicates(names).map((name) => `"${name}" is listed twice`),
@@ -722,6 +771,7 @@ var defineQuery = /* @__PURE__ */ __name((registry) => {
722
771
  ];
723
772
  if (problems.length > 0)
724
773
  throw new RegistryError(`${registry.entity} query`, problems);
774
+ checked.add(registry);
725
775
  return registry;
726
776
  }, "defineQuery");
727
777
  var SPAN = ["span", "alternative", "guide"];
@@ -752,7 +802,7 @@ var QUERY_REASONS = defineReasons([
752
802
  details: [...SPAN, ...details]
753
803
  })));
754
804
 
755
- // node_modules/.pnpm/@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/evaluate.js
805
+ // node_modules/.pnpm/@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/evaluate.js
756
806
  var wordsOf = /* @__PURE__ */ __name((text6) => text6.toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [], "wordsOf");
757
807
  var pattern = /* @__PURE__ */ __name((value) => new RegExp(`^${[...value].map((char) => char === "*" ? ".*" : char === "?" ? "." : char.replace(/[.+^${}()|[\]\\]/, "\\$&")).join("")}$`, "iu"), "pattern");
758
808
  var present = /* @__PURE__ */ __name((value) => value !== void 0 && value !== null && value !== "", "present");
@@ -778,10 +828,10 @@ var matchOne = /* @__PURE__ */ __name((field, node, value, options) => {
778
828
  return (lower === "*" || (lowerInclusive ? number2 >= Number(lower) : number2 > Number(lower))) && (upper === "*" || (upperInclusive ? number2 <= Number(upper) : number2 < Number(upper)));
779
829
  }
780
830
  case "time": {
781
- const time = Date.parse(text6);
831
+ const time2 = Date.parse(text6);
782
832
  const [lower, upper, lowerInclusive, upperInclusive] = node.operator === "range" ? [node.value, node.upper ?? "*", node.lower_inclusive ?? true, node.upper_inclusive ?? true] : [node.value, node.value, true, true];
783
833
  const range = dateRange(lower, upper, lowerInclusive, upperInclusive, options.zone ?? "UTC", node.span, options.now);
784
- return (range.lower === void 0 || (range.lower_inclusive ? time >= range.lower : time > range.lower)) && (range.upper === void 0 || (range.upper_inclusive ? time <= range.upper : time < range.upper));
834
+ return (range.lower === void 0 || (range.lower_inclusive ? time2 >= range.lower : time2 > range.lower)) && (range.upper === void 0 || (range.upper_inclusive ? time2 <= range.upper : time2 < range.upper));
785
835
  }
786
836
  default:
787
837
  return node.operator === "wildcard" ? pattern(node.value).test(text6) : text6.toLowerCase() === node.value.toLowerCase();
@@ -805,25 +855,9 @@ var matches = /* @__PURE__ */ __name((node, item, byName, options) => {
805
855
  const value = item[node.field];
806
856
  return Array.isArray(value) ? value.some((one) => matchOne(field, node, one, options)) : matchOne(field, node, value, options);
807
857
  }, "matches");
808
- var evaluate = /* @__PURE__ */ __name((ast, fields2, item, options = {}) => matches(ast.root, item, new Map(fields2.map((field) => [field.name, field])), options), "evaluate");
858
+ var evaluate = /* @__PURE__ */ __name((ast, fields, item, options = {}) => matches(ast.root, item, new Map(fields.map((field) => [field.name, field])), options), "evaluate");
809
859
 
810
- // node_modules/.pnpm/@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_typescript@7.0.2_vitest@5.0.5/node_modules/@wirecat/cli-base/dist/query/help.js
811
- var QUERY_SYNTAX = 'field:value \xB7 "a phrase" \xB7 word* \xB7 AND OR NOT \xB7 ( ) \xB7 [a TO b] \xB7 > >= < <=';
812
- var kindOf = /* @__PURE__ */ __name((field) => field.values ? `${field.type}: ${field.values.join("|")}` : `${field.type}: ${field.operators.join(", ")}`, "kindOf");
813
- var fieldsHelp = /* @__PURE__ */ __name((registry, guide) => {
814
- const shown = registry.backend === "native" ? registry.fields.filter((field) => field.native) : registry.fields;
815
- const rows = shown.map((field) => [field.name, kindOf(field), field.example]);
816
- const widths = [0, 1].map((at) => Math.max(...rows.map((row) => (row[at] ?? "").length)));
817
- return [
818
- "Fields:",
819
- ...rows.map(([name = "", kind = "", example = ""]) => ` ${name.padEnd(widths[0] ?? 0)} ${kind.padEnd(widths[1] ?? 0)} ${example}`.trimEnd()),
820
- ...registry.defaults && registry.defaults.length > 0 ? [`Defaults: ${registry.defaults.join(" ")} \u2014 name the field to change it`] : [],
821
- `Syntax: ${QUERY_SYNTAX}`,
822
- ...guide ? [`Guide: ${guide}`] : []
823
- ].join("\n");
824
- }, "fieldsHelp");
825
-
826
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/reference.js
860
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/reference.js
827
861
  var invalid = /* @__PURE__ */ __name(() => new CliError("validation_error", "expected meeting:<accountId>/<meetingId>[/<transcriptId>[/<cuePosition>]] with safe integer IDs"), "invalid");
828
862
  var integer2 = /* @__PURE__ */ __name((value, minimum = 1) => {
829
863
  if (!Number.isSafeInteger(value) || value < minimum)
@@ -860,7 +894,7 @@ var parseMeetingReference = /* @__PURE__ */ __name((text6) => {
860
894
  }, "parseMeetingReference");
861
895
  var canonicalMeetingReference = /* @__PURE__ */ __name((text6) => formatMeetingReference(parseMeetingReference(text6)), "canonicalMeetingReference");
862
896
 
863
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/item.js
897
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/item.js
864
898
  var text = string();
865
899
  var count = pipe(number(), integer(), minValue(0));
866
900
  var MEETING_ISSUES = ["time_without_zone"];
@@ -925,7 +959,7 @@ var MEETING_QUERY = {
925
959
  })
926
960
  };
927
961
 
928
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/join-key.js
962
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/join-key.js
929
963
  var joinKeyOf = /* @__PURE__ */ __name((url) => {
930
964
  const parsed = urlOf(url);
931
965
  if (!parsed)
@@ -959,7 +993,7 @@ var urlOf = /* @__PURE__ */ __name((url) => {
959
993
  }
960
994
  }, "urlOf");
961
995
 
962
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/calendar-text.js
996
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/calendar-text.js
963
997
  var ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', "#39": "'", apos: "'", nbsp: " " };
964
998
  var SECRET_LINE = /(?<![\p{L}\p{N}])(pass ?codes?|passwords?|pwd|pins?|access ?codes?|meeting ?codes?|kennwort|пароль|пин-?код|код доступа)(?![\p{L}\p{N}])|pwd=/iu;
965
999
  var htmlToText = /* @__PURE__ */ __name((html) => html.replace(/<\s*br\s*\/?>/giu, "\n").replace(/<\/\s*(p|div|li|tr|h[1-6])\s*>/giu, "\n").replace(/<a\s[^>]*href\s*=\s*"([^"]*)"[^>]*>/giu, " $1 ").replace(/<[^>]+>/gu, "").replace(/&(amp|lt|gt|quot|#39|apos|nbsp);/gu, (_, name) => ENTITIES[name] ?? ""), "htmlToText");
@@ -992,7 +1026,7 @@ var entryMetadata = /* @__PURE__ */ __name((metadata) => {
992
1026
  return kept;
993
1027
  }, "entryMetadata");
994
1028
 
995
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/cue-fingerprint.js
1029
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/cue-fingerprint.js
996
1030
  import { createHash } from "node:crypto";
997
1031
  var meetingCueFingerprint = /* @__PURE__ */ __name((cue2) => createHash("sha256").update(JSON.stringify({
998
1032
  reference: cue2.reference,
@@ -1006,7 +1040,7 @@ var meetingCueFingerprint = /* @__PURE__ */ __name((cue2) => createHash("sha256"
1006
1040
  text: cue2.text
1007
1041
  })).digest("hex"), "meetingCueFingerprint");
1008
1042
 
1009
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/event-store.js
1043
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/event-store.js
1010
1044
  var UNTIL = /(?:^|;)UNTIL=(\d{4})(\d{2})(\d{2})(?:T(\d{2})(\d{2})(\d{2})Z?)?(?:;|$)/iu;
1011
1045
  var seriesEnd = /* @__PURE__ */ __name((entry) => {
1012
1046
  if (entry.recurrenceEndsAt !== null)
@@ -1029,7 +1063,7 @@ var entryInWindow = /* @__PURE__ */ __name((entry, window) => {
1029
1063
  return Math.max(entry.endsAt ?? start, start + 1) > window.from;
1030
1064
  }, "entryInWindow");
1031
1065
 
1032
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/answers.js
1066
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/answers.js
1033
1067
  var text2 = string();
1034
1068
  var count2 = pipe(number(), integer(), minValue(0));
1035
1069
  var iso2 = /* @__PURE__ */ __name((ms) => ms === null ? null : new Date(ms).toISOString(), "iso");
@@ -1043,6 +1077,11 @@ var meetingHit = strictObject({
1043
1077
  excerpt: text2,
1044
1078
  /** How far into the meeting the passage is. */
1045
1079
  offset_ms: nullable(count2),
1080
+ /** A transcript passage's transcript language (`ru`, `en`…), `null` when unknown. */
1081
+ language: optional(nullable(text2)),
1082
+ /** A transcript passage's line, from 1, of `lines_total`. */
1083
+ line: optional(pipe(count2, minValue(1))),
1084
+ lines_total: optional(count2),
1046
1085
  /** `corrected`: a query word matched only a garbled form of itself, listed in `corrections`. */
1047
1086
  match: optional(picklist(["words", "corrected"])),
1048
1087
  corrections: optional(array(strictObject({ from: text2, to: array(text2) }))),
@@ -1209,6 +1248,9 @@ var meetingHitItem = /* @__PURE__ */ __name((hit) => ({
1209
1248
  id: String(hit.id),
1210
1249
  excerpt: hit.text,
1211
1250
  offset_ms: hit.startMs,
1251
+ ...hit.language === void 0 ? {} : { language: hit.language },
1252
+ ...hit.line === void 0 ? {} : { line: hit.line },
1253
+ ...hit.linesTotal === void 0 ? {} : { lines_total: hit.linesTotal },
1212
1254
  untrusted: hit.source === void 0 ? ["excerpt"] : ["excerpt", "source.title"],
1213
1255
  ...hit.match === void 0 ? {} : { match: hit.match },
1214
1256
  ...hit.corrections === void 0 ? {} : { corrections: hit.corrections },
@@ -1256,7 +1298,7 @@ var meetingHitsList = /* @__PURE__ */ __name((found, limit, command = "search me
1256
1298
  };
1257
1299
  }, "meetingHitsList");
1258
1300
 
1259
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/participant-search.js
1301
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/participant-search.js
1260
1302
  var normalizeMeetingParticipantQuery = /* @__PURE__ */ __name((text6) => text6.normalize("NFKC").toLowerCase(), "normalizeMeetingParticipantQuery");
1261
1303
  var validateMeetingParticipantQuery = /* @__PURE__ */ __name((query) => {
1262
1304
  if (typeof query !== "string" || !query.trim() || query.length > 500 || query.includes("\0"))
@@ -1280,7 +1322,7 @@ var validateMeetingParticipantSearch = /* @__PURE__ */ __name((query, input) =>
1280
1322
  };
1281
1323
  }, "validateMeetingParticipantSearch");
1282
1324
 
1283
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/reads.js
1325
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/reads.js
1284
1326
  var MeetingError = class extends CliError {
1285
1327
  static {
1286
1328
  __name(this, "MeetingError");
@@ -1307,8 +1349,8 @@ var validateFilter = /* @__PURE__ */ __name((filter) => {
1307
1349
  if (value !== void 0 && (!Number.isSafeInteger(value) || value < 0))
1308
1350
  throw new MeetingError("validation_error", "expected a nonnegative integer");
1309
1351
  }, "validateFilter");
1310
- var meetingShow = /* @__PURE__ */ __name(async (store, id3, accountId) => {
1311
- const details = await store.meeting(positiveInteger(id3));
1352
+ var meetingShow = /* @__PURE__ */ __name(async (store, id4, accountId) => {
1353
+ const details = await store.meeting(positiveInteger(id4));
1312
1354
  if (!details || accountId !== void 0 && details.meeting.accountId !== accountId)
1313
1355
  throw new MeetingError("not_found", "meeting not found");
1314
1356
  return details;
@@ -1399,20 +1441,20 @@ var ownerOf = /* @__PURE__ */ __name(async (store, accountId) => {
1399
1441
  throw new MeetingError("not_found", `meeting account ${accountId} is not in the store`);
1400
1442
  return owner;
1401
1443
  }, "ownerOf");
1402
- var meetingDetailsAnswer = /* @__PURE__ */ __name(async (store, id3, accountId) => {
1403
- const details = await meetingShow(store, id3, accountId);
1444
+ var meetingDetailsAnswer = /* @__PURE__ */ __name(async (store, id4, accountId) => {
1445
+ const details = await meetingShow(store, id4, accountId);
1404
1446
  return { item: meetingDetailsItem(details, await ownerOf(store, details.meeting.accountId)) };
1405
1447
  }, "meetingDetailsAnswer");
1406
- var meetingTranscriptAnswer = /* @__PURE__ */ __name(async (store, id3, accountId, options = {}) => {
1407
- const details = await meetingShow(store, id3, accountId);
1448
+ var meetingTranscriptAnswer = /* @__PURE__ */ __name(async (store, id4, accountId, options = {}) => {
1449
+ const details = await meetingShow(store, id4, accountId);
1408
1450
  return wholeList(details.transcripts.filter((t) => (options.history || t.transcript.supersededAt === null) && t.transcript.deletedAt === null).map((t) => meetingTranscriptItem(details.meeting.accountId, t.transcript, t.rows)));
1409
1451
  }, "meetingTranscriptAnswer");
1410
- var meetingSummaryAnswer = /* @__PURE__ */ __name(async (store, id3, accountId) => {
1411
- const details = await meetingShow(store, id3, accountId);
1452
+ var meetingSummaryAnswer = /* @__PURE__ */ __name(async (store, id4, accountId) => {
1453
+ const details = await meetingShow(store, id4, accountId);
1412
1454
  return wholeList(details.summaries.map((one) => meetingSummaryItem(details.meeting.accountId, one)));
1413
1455
  }, "meetingSummaryAnswer");
1414
1456
 
1415
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/export.js
1457
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/export.js
1416
1458
  var timestamp = /* @__PURE__ */ __name((milliseconds) => {
1417
1459
  if (!Number.isSafeInteger(milliseconds) || milliseconds < 0)
1418
1460
  throw new MeetingError("validation_error", "transcript times must be nonnegative integer milliseconds");
@@ -1455,10 +1497,10 @@ var transcriptsOf = /* @__PURE__ */ __name((details, transcriptId) => {
1455
1497
  }
1456
1498
  return details.transcripts.filter((part) => part.transcript.supersededAt === null && part.transcript.deletedAt === null);
1457
1499
  }, "transcriptsOf");
1458
- var exportMeeting = /* @__PURE__ */ __name(async (store, id3, options) => {
1500
+ var exportMeeting = /* @__PURE__ */ __name(async (store, id4, options) => {
1459
1501
  if (options.format !== "markdown" && options.format !== "vtt")
1460
1502
  throw new MeetingError("validation_error", "export format must be markdown or vtt");
1461
- const details = await meetingShow(store, id3, options.accountId);
1503
+ const details = await meetingShow(store, id4, options.accountId);
1462
1504
  const transcripts = transcriptsOf(details, options.transcriptId);
1463
1505
  let content;
1464
1506
  if (options.format === "vtt") {
@@ -1508,13 +1550,107 @@ var exportMeeting = /* @__PURE__ */ __name(async (store, id3, options) => {
1508
1550
  };
1509
1551
  }, "exportMeeting");
1510
1552
 
1511
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/findings-rules.js
1553
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/payment.js
1554
+ var FACT_TYPES = ["fact", "statement", "question", "decision", "promise"];
1555
+ var PAYMENT_DIRECTIONS = ["to_us", "from_us"];
1556
+ var PAYMENT_STATES = ["expected", "paid", "cancelled"];
1557
+ var invalid2 = /* @__PURE__ */ __name((message) => {
1558
+ throw new CliError("validation_error", message);
1559
+ }, "invalid");
1560
+ var CURRENCIES = new Set(Intl.supportedValuesOf("currency"));
1561
+ var AMOUNT = /^(\d{1,15})(?:\.(\d{1,2}))?$/;
1562
+ var COUNTERPARTY = /^(person|organization|project):[1-9]\d*$/;
1563
+ var amountOf = /* @__PURE__ */ __name((value) => {
1564
+ const match = AMOUNT.exec(typeof value === "number" ? String(value) : typeof value === "string" ? value.trim() : "");
1565
+ if (!match)
1566
+ return invalid2("a payment's amount is a positive number with at most 2 decimals, such as 1200.50");
1567
+ const amount = `${BigInt(match[1] ?? "0")}.${(match[2] ?? "").padEnd(2, "0")}`;
1568
+ if (amount === "0.00")
1569
+ return invalid2("a payment's amount is more than 0");
1570
+ return amount;
1571
+ }, "amountOf");
1572
+ var dateOf = /* @__PURE__ */ __name((value) => {
1573
+ const date = typeof value === "string" ? value.trim() : "";
1574
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(date) || (/* @__PURE__ */ new Date(`${date}T00:00:00Z`)).toISOString().slice(0, 10) !== date)
1575
+ return invalid2("a payment's dates are ISO dates, such as 2026-10-31");
1576
+ return date;
1577
+ }, "dateOf");
1578
+ var optionalText = /* @__PURE__ */ __name((value, what, limit) => {
1579
+ if (value === void 0 || value === null)
1580
+ return null;
1581
+ if (typeof value !== "string" || !value.trim() || value.length > limit || value.includes("\0"))
1582
+ return invalid2(`a payment's ${what} takes 1\u2013${limit} characters`);
1583
+ return value.trim();
1584
+ }, "optionalText");
1585
+ var oneOf = /* @__PURE__ */ __name((value, allowed, what) => {
1586
+ if (typeof value !== "string" || !allowed.includes(value))
1587
+ return invalid2(`a payment's ${what} is one of ${allowed.join(", ")}`);
1588
+ return value;
1589
+ }, "oneOf");
1590
+ var FIELDS = [
1591
+ "amount",
1592
+ "currency",
1593
+ "direction",
1594
+ "counterparty",
1595
+ "counterparty_name",
1596
+ "due_at",
1597
+ "state",
1598
+ "item",
1599
+ "paid_at"
1600
+ ];
1601
+ var validatePayment = /* @__PURE__ */ __name((input) => {
1602
+ if (!input || typeof input !== "object" || Array.isArray(input))
1603
+ return invalid2("a payment is an object");
1604
+ const raw = input;
1605
+ const unknown2 = Object.keys(raw).filter((key) => !FIELDS.includes(key));
1606
+ if (unknown2.length)
1607
+ return invalid2(`a payment has no field ${unknown2.join(", ")}; its fields are ${FIELDS.join(", ")}`);
1608
+ const currency = typeof raw.currency === "string" ? raw.currency.trim().toUpperCase() : "";
1609
+ if (!/^[A-Z]{3}$/.test(currency) || !CURRENCIES.has(currency))
1610
+ return invalid2("a payment's currency is an ISO 4217 code, such as EUR or RUB");
1611
+ const counterparty = optionalText(raw.counterparty, "counterparty", 80);
1612
+ if (counterparty !== null && !COUNTERPARTY.test(counterparty))
1613
+ return invalid2("a payment's counterparty is a person:, organization: or project: reference");
1614
+ const state = oneOf(raw.state, PAYMENT_STATES, "state");
1615
+ if (raw.paid_at != null && state !== "paid")
1616
+ return invalid2("only a paid payment has paid_at");
1617
+ return {
1618
+ amount: amountOf(raw.amount),
1619
+ currency,
1620
+ direction: oneOf(raw.direction, PAYMENT_DIRECTIONS, "direction"),
1621
+ counterparty,
1622
+ counterparty_name: optionalText(raw.counterparty_name, "counterparty name", 200),
1623
+ due_at: raw.due_at === void 0 || raw.due_at === null ? null : dateOf(raw.due_at),
1624
+ state,
1625
+ item: optionalText(raw.item, "item", 200),
1626
+ // Left out when absent, so a finding staged before the field keeps its fingerprint.
1627
+ ...raw.paid_at == null ? {} : { paid_at: dateOf(raw.paid_at) }
1628
+ };
1629
+ }, "validatePayment");
1630
+ var grouped = /* @__PURE__ */ __name((amount) => {
1631
+ const [whole = "0", cents = "00"] = amount.split(".");
1632
+ const digits = whole.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
1633
+ return cents === "00" ? digits : `${digits}.${cents}`;
1634
+ }, "grouped");
1635
+ var paymentTitle = /* @__PURE__ */ __name((fact) => {
1636
+ const payment = fact.payment;
1637
+ if (!payment)
1638
+ return "";
1639
+ const who = payment.counterparty_name ?? payment.counterparty;
1640
+ const way = payment.direction === "to_us" ? "to us" : "from us";
1641
+ const party = who === null ? "" : payment.direction === "to_us" ? ` from ${who}` : ` to ${who}`;
1642
+ const due = payment.due_at === null ? "" : `, due ${payment.due_at.slice(8, 10)}.${payment.due_at.slice(5, 7)}`;
1643
+ const item = payment.item === null ? "" : ` for ${payment.item}`;
1644
+ return `${grouped(payment.amount)} ${payment.currency} ${way}${party}${item}${due} (${payment.state})`;
1645
+ }, "paymentTitle");
1646
+
1647
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/findings-rules.js
1512
1648
  import { createHash as createHash2 } from "node:crypto";
1513
1649
 
1514
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/timestamp.js
1650
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/timestamp.js
1515
1651
  var meetingTimestamp = /* @__PURE__ */ __name((value, name) => {
1516
1652
  if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T.+(?:Z|[+-]\d{2}:\d{2})$/i.test(value) || !Number.isFinite(Date.parse(value)))
1517
- throw new CliError("validation_error", `${name} must be an ISO timestamp with a timezone`);
1653
+ throw new CliError("validation_error", `${name} must be an ISO timestamp with a timezone, such as 2026-11-09T09:00:00Z`);
1518
1654
  const date = value.slice(0, 10);
1519
1655
  const instant = Date.parse(`${date}T00:00:00Z`);
1520
1656
  if (!Number.isFinite(instant) || new Date(instant).toISOString().slice(0, 10) !== date)
@@ -1522,162 +1658,180 @@ var meetingTimestamp = /* @__PURE__ */ __name((value, name) => {
1522
1658
  return new Date(value).toISOString();
1523
1659
  }, "meetingTimestamp");
1524
1660
 
1525
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/meeting-management.js
1526
- var nonempty = /* @__PURE__ */ __name((value, name) => {
1527
- if (typeof value !== "string" || !value.trim())
1528
- throw new CliError("validation_error", `${name} must be nonempty`);
1529
- return value;
1530
- }, "nonempty");
1531
- var validateMeetingChange = /* @__PURE__ */ __name((change, create) => {
1532
- if (!change || typeof change !== "object" || Array.isArray(change) || Object.keys(change).some((key) => !["title", "kind", "startTime", "durationMinutes", "timezone", "agenda"].includes(key)))
1533
- throw new CliError("validation_error", "unsupported meeting change field");
1534
- const result = {};
1535
- if (change.title !== void 0)
1536
- result.title = nonempty(change.title, "meeting title");
1537
- if (create && result.title === void 0)
1538
- throw new CliError("validation_error", "meeting title is required");
1539
- if (change.kind !== void 0) {
1540
- if (change.kind !== "instant" && change.kind !== "scheduled")
1541
- throw new CliError("validation_error", "only instant or scheduled meeting kinds are supported");
1542
- result.kind = change.kind;
1543
- }
1544
- if (change.startTime !== void 0) {
1545
- result.startTime = meetingTimestamp(change.startTime, "meeting start");
1546
- }
1547
- if (change.durationMinutes !== void 0) {
1548
- if (!Number.isSafeInteger(change.durationMinutes) || change.durationMinutes <= 0 || change.durationMinutes > 1440)
1549
- throw new CliError("validation_error", "meeting duration must be an integer from 1 to 1440 minutes");
1550
- result.durationMinutes = change.durationMinutes;
1551
- }
1552
- if (change.timezone !== void 0) {
1553
- if (typeof change.timezone !== "string" || !change.timezone.trim())
1554
- throw new CliError("validation_error", "meeting timezone must be a valid IANA timezone");
1555
- try {
1556
- new Intl.DateTimeFormat("en", { timeZone: change.timezone }).format();
1557
- } catch {
1558
- throw new CliError("validation_error", "meeting timezone must be a valid IANA timezone");
1559
- }
1560
- result.timezone = change.timezone;
1561
- }
1562
- if (change.agenda !== void 0) {
1563
- if (typeof change.agenda !== "string")
1564
- throw new CliError("validation_error", "meeting agenda must be text");
1565
- result.agenda = change.agenda;
1566
- }
1567
- if (create) {
1568
- result.kind ??= "scheduled";
1569
- if (result.kind === "scheduled" && result.startTime === void 0)
1570
- throw new CliError("validation_error", "scheduled meeting start is required");
1571
- } else if (!Object.keys(result).length)
1572
- throw new CliError("validation_error", "at least one meeting change is required");
1573
- return Object.freeze(result);
1574
- }, "validateMeetingChange");
1575
-
1576
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/meeting-context.js
1577
- var MEETING_FACT_TYPES = ["fact", "statement", "question", "decision", "promise"];
1578
-
1579
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/findings-rules.js
1661
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/findings-rules.js
1580
1662
  var TASK_TYPES = ["bug", "feature", "chore"];
1581
- var invalid2 = /* @__PURE__ */ __name((message) => {
1663
+ var invalid3 = /* @__PURE__ */ __name((message) => {
1582
1664
  throw new CliError("validation_error", message);
1583
1665
  }, "invalid");
1584
- var text3 = /* @__PURE__ */ __name((value, limit) => {
1666
+ var findingText = /* @__PURE__ */ __name((value, limit) => {
1585
1667
  if (typeof value !== "string" || !value.trim() || value.includes("\0") || value.length > limit)
1586
- return invalid2(`finding text must contain 1\u2013${limit} characters without NUL`);
1668
+ return invalid3(`finding text must contain 1\u2013${limit} characters without NUL`);
1587
1669
  return value.trim();
1588
- }, "text");
1670
+ }, "findingText");
1589
1671
  var findingHash = /* @__PURE__ */ __name((value) => createHash2("sha256").update(JSON.stringify(value)).digest("hex"), "findingHash");
1590
- var fields = /* @__PURE__ */ __name((value, allowed, noun) => {
1591
- if (Object.keys(value).some((key) => !allowed.includes(key)))
1592
- invalid2(`unknown ${noun} field`);
1593
- }, "fields");
1594
- var validateFindings = /* @__PURE__ */ __name((input, rules) => {
1595
- if (!input || typeof input !== "object" || Buffer.byteLength(JSON.stringify(input), "utf8") > 65536)
1596
- return invalid2(`${rules.plural} take at most 65536 UTF-8 bytes`);
1597
- fields(input, ["schemaVersion", "key", "extractor", "findings"], rules.singular);
1598
- if (input.schemaVersion !== 1 || !Array.isArray(input.findings) || input.findings.length < 1 || input.findings.length > 16)
1599
- return invalid2(`schemaVersion 1 takes 1\u201316 ${rules.plural}`);
1600
- const key = text3(input.key, 64);
1601
- if (!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/.test(key))
1602
- return invalid2("a findings key uses letters, digits, dot, colon, underscore or hyphen");
1603
- const ids2 = /* @__PURE__ */ new Set();
1604
- const findings = input.findings.map((finding) => {
1605
- if (!finding || typeof finding !== "object")
1606
- return invalid2("a finding is an object");
1607
- const id3 = text3(finding.id, 64);
1608
- if (!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/.test(id3) || ids2.has(id3))
1609
- return invalid2("finding IDs must be unique simple keys");
1610
- ids2.add(id3);
1611
- const project = text3(finding.project, 64);
1612
- if (!/^project:[1-9]\d*$/.test(project))
1613
- return invalid2("a finding names a project reference");
1614
- if (!Array.isArray(finding.evidence) || finding.evidence.length < 1 || finding.evidence.length > 8)
1615
- return invalid2(`a finding requires 1\u20138 cited ${rules.cited}s`);
1616
- const evidence = finding.evidence.map((item) => {
1617
- if (!item || typeof item !== "object")
1618
- return invalid2("finding evidence is a reference and fingerprint");
1619
- fields(item, ["reference", "fingerprint"], rules.singular);
1620
- if (typeof item.reference !== "string" || typeof item.fingerprint !== "string")
1621
- return invalid2("evidence requires a reference and fingerprint");
1622
- const reference2 = rules.reference(item.reference);
1623
- if (!/^[a-f0-9]{64}$/.test(item.fingerprint))
1624
- return invalid2(`finding evidence requires exact ${rules.cited} references and fingerprints`);
1625
- return { reference: reference2, fingerprint: item.fingerprint };
1626
- }).sort((a, b) => a.reference.localeCompare(b.reference));
1627
- if (new Set(evidence.map((item) => item.reference)).size !== evidence.length)
1628
- return invalid2(`duplicate evidence ${rules.cited}`);
1629
- const base = { id: id3, project, evidence };
1630
- if (finding.kind === "fact") {
1631
- fields(finding, ["id", "project", "evidence", "kind", "type", "statement"], rules.singular);
1632
- if (!MEETING_FACT_TYPES.includes(finding.type))
1633
- return invalid2("unknown fact finding type");
1634
- return { ...base, kind: "fact", type: finding.type, statement: text3(finding.statement, 2e3) };
1635
- }
1636
- if (finding.kind !== "task")
1637
- return invalid2("a finding is a fact or task");
1638
- fields(finding, [
1639
- "id",
1640
- "project",
1641
- "evidence",
1642
- "kind",
1643
- "type",
1644
- "title",
1645
- "reason",
1646
- "commitment",
1647
- "dueAt",
1648
- "dueEvidence",
1649
- "assignee",
1650
- "assigneeEvidence"
1651
- ], rules.singular);
1652
- if (!TASK_TYPES.includes(finding.type))
1653
- return invalid2("a task finding type is bug, chore or feature");
1654
- if (!["explicit", "inferred"].includes(finding.commitment))
1655
- return invalid2("task commitment must be explicit or inferred");
1656
- const support = /* @__PURE__ */ __name((value) => {
1657
- if (!Array.isArray(value) || value.length < 1 || value.length > 8 || value.some((ref) => typeof ref !== "string" || !evidence.some((item) => item.reference === ref)))
1658
- return invalid2("date and assignee support must cite the finding's evidence");
1659
- return [...new Set(value)].sort();
1660
- }, "support");
1661
- if (finding.dueAt === void 0 !== (finding.dueEvidence === void 0) || finding.assignee === void 0 !== (finding.assigneeEvidence === void 0))
1662
- return invalid2("optional dates and assignees require their supporting evidence");
1663
- if (finding.assignee !== void 0 && (typeof finding.assignee !== "string" || !/^person:[1-9]\d*$/.test(finding.assignee)))
1664
- return invalid2("an assignee must be a person reference");
1672
+ var snakeCase = /* @__PURE__ */ __name((key) => key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`), "snakeCase");
1673
+ var findingWhere = /* @__PURE__ */ __name((of) => {
1674
+ const id4 = typeof of.id === "string" ? of.id : null;
1675
+ const kind = typeof of.kind === "string" ? of.kind : null;
1676
+ return {
1677
+ where: id4 || kind ? ` in ${[id4, kind && `(${kind})`].filter(Boolean).join(" ")}` : "",
1678
+ named: { ...id4 ? { finding: id4 } : {}, ...kind ? { kind } : {} }
1679
+ };
1680
+ }, "findingWhere");
1681
+ var findingFields = /* @__PURE__ */ __name((value, allowed, noun, of = value) => {
1682
+ const unknown2 = Object.keys(value).filter((key) => !allowed.includes(key));
1683
+ if (!unknown2.length)
1684
+ return;
1685
+ const fields = unknown2.map(snakeCase);
1686
+ const takes = allowed.map(snakeCase);
1687
+ const { where, named } = findingWhere(of);
1688
+ throw new CliError("validation_error", `unknown ${noun} field${fields.length > 1 ? "s" : ""} ${fields.join(", ")}${where}; it takes ${takes.join(", ")}`, { reason: "finding.unknown-field", fields, allowed: takes, ...named });
1689
+ }, "findingFields");
1690
+ var findingNeeds = /* @__PURE__ */ __name((value, needed, noun) => {
1691
+ const missing = needed.filter((key) => value[key] === void 0);
1692
+ if (!missing.length)
1693
+ return;
1694
+ const fields = missing.map(snakeCase);
1695
+ const needs = needed.map(snakeCase);
1696
+ const { where, named } = findingWhere(value);
1697
+ throw new CliError("validation_error", `missing ${noun} field${fields.length > 1 ? "s" : ""} ${fields.join(", ")}${where}; it needs ${needs.join(", ")}`, { reason: "finding.missing-field", fields, needs, ...named });
1698
+ }, "findingNeeds");
1699
+ var SUBJECT = /^(person|organization|project):[1-9]\d*$|^task:[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/;
1700
+ var validEvidence = /* @__PURE__ */ __name((raw, rules) => {
1701
+ if (!Array.isArray(raw) || raw.length < 1 || raw.length > 8)
1702
+ return invalid3(`a finding requires 1\u20138 cited ${rules.cited}s`);
1703
+ const evidence = raw.map((item) => {
1704
+ if (!item || typeof item !== "object")
1705
+ return invalid3("finding evidence is a reference and fingerprint");
1706
+ findingFields(item, ["reference", "fingerprint"], rules.singular);
1707
+ if (typeof item.reference !== "string" || typeof item.fingerprint !== "string")
1708
+ return invalid3("evidence requires a reference and fingerprint");
1709
+ const reference2 = rules.reference(item.reference);
1710
+ if (!/^[a-f0-9]{64}$/.test(item.fingerprint))
1711
+ return invalid3(`finding evidence requires exact ${rules.cited} references and fingerprints`);
1712
+ return { reference: reference2, fingerprint: item.fingerprint };
1713
+ }).sort((a, b) => a.reference.localeCompare(b.reference));
1714
+ if (new Set(evidence.map((item) => item.reference)).size !== evidence.length)
1715
+ return invalid3(`duplicate evidence ${rules.cited}`);
1716
+ return evidence;
1717
+ }, "validEvidence");
1718
+ var findingId = /* @__PURE__ */ __name((raw, ids2) => {
1719
+ const id4 = findingText(raw, 64);
1720
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/.test(id4) || ids2.has(id4))
1721
+ return invalid3("finding IDs must be unique simple keys");
1722
+ ids2.add(id4);
1723
+ return id4;
1724
+ }, "findingId");
1725
+ var validateFinding = /* @__PURE__ */ __name((finding, rules, ids2) => {
1726
+ if (!finding || typeof finding !== "object")
1727
+ return invalid3("a finding is an object");
1728
+ const id4 = findingId(finding.id, ids2);
1729
+ const project2 = finding.project === void 0 && rules.anySubject ? void 0 : findingText(finding.project, 64);
1730
+ if (project2 !== void 0 && !/^project:[1-9]\d*$/.test(project2))
1731
+ return invalid3("a finding names a project reference");
1732
+ if (finding.subject !== void 0 && (!rules.anySubject || !SUBJECT.test(findingText(finding.subject, 80))))
1733
+ return invalid3("a finding's subject is a person:, organization:, task: or project: reference");
1734
+ if (finding.kind === "task" && project2 === void 0 && !rules.inboxTasks)
1735
+ return invalid3("a task finding names the project the task goes in");
1736
+ const evidence = validEvidence(finding.evidence, rules);
1737
+ const base = {
1738
+ id: id4,
1739
+ ...project2 === void 0 ? {} : { project: project2 },
1740
+ ...finding.subject === void 0 ? {} : { subject: finding.subject },
1741
+ evidence
1742
+ };
1743
+ if (finding.kind === "fact") {
1744
+ findingFields(finding, ["id", "project", "subject", "evidence", "kind", "type", "statement"], rules.singular);
1745
+ if (finding.type === "payment")
1746
+ return invalid3("a payment is a finding of kind payment; money is a payments row, not a fact");
1747
+ if (!FACT_TYPES.includes(finding.type))
1748
+ return invalid3("unknown fact finding type");
1749
+ return { ...base, kind: "fact", type: finding.type, statement: findingText(finding.statement, 2e3) };
1750
+ }
1751
+ if (finding.kind === "payment" && rules.payments) {
1752
+ findingFields(finding, ["id", "project", "subject", "evidence", "kind", "statement", "payment", "supersedes"], rules.singular);
1753
+ if (finding.supersedes !== void 0 && !/^invoice:[1-9]\d*$/.test(String(finding.supersedes)))
1754
+ return invalid3("a payment finding supersedes an invoice: reference, the expected payment it settles or voids");
1755
+ const payment = validatePayment(finding.payment);
1756
+ if (payment.state === "expected" && finding.supersedes !== void 0)
1757
+ return invalid3("an expected payment supersedes nothing; a paid or cancelled one supersedes its invoice");
1758
+ if (payment.state === "cancelled" && finding.supersedes === void 0)
1759
+ return invalid3("a cancelled payment names the invoice: it cancels in supersedes");
1760
+ if (payment.state === "expected" && !/^(person|organization):/.test(payment.counterparty ?? ""))
1761
+ return invalid3("an expected payment becomes an invoice, which names its counterparty as a person: or organization:");
1665
1762
  return {
1666
1763
  ...base,
1667
- kind: "task",
1668
- type: finding.type,
1669
- title: text3(finding.title, 300),
1670
- reason: text3(finding.reason, 2e3),
1671
- commitment: finding.commitment,
1672
- ...finding.dueAt === void 0 ? {} : { dueAt: meetingTimestamp(finding.dueAt, "finding due date"), dueEvidence: support(finding.dueEvidence) },
1673
- ...finding.assignee === void 0 ? {} : { assignee: finding.assignee, assigneeEvidence: support(finding.assigneeEvidence) }
1764
+ kind: "payment",
1765
+ ...finding.statement === void 0 ? {} : { statement: findingText(finding.statement, 2e3) },
1766
+ payment,
1767
+ ...finding.supersedes === void 0 ? {} : { supersedes: finding.supersedes }
1674
1768
  };
1675
- });
1676
- return { schemaVersion: 1, key, extractor: text3(input.extractor, 200), findings };
1677
- }, "validateFindings");
1769
+ }
1770
+ if (finding.kind !== "task")
1771
+ return invalid3(`a finding is a fact${rules.payments ? ", payment" : ""} or task`);
1772
+ findingFields(finding, [
1773
+ "id",
1774
+ "project",
1775
+ "evidence",
1776
+ "kind",
1777
+ "type",
1778
+ "title",
1779
+ "reason",
1780
+ "commitment",
1781
+ "dueAt",
1782
+ "dueEvidence",
1783
+ "assignee",
1784
+ "assigneeEvidence"
1785
+ ], rules.singular);
1786
+ if (!TASK_TYPES.includes(finding.type))
1787
+ return invalid3("a task finding type is bug, chore or feature");
1788
+ if (!["explicit", "inferred"].includes(finding.commitment))
1789
+ return invalid3("task commitment must be explicit or inferred");
1790
+ if (finding.dueAt === void 0 !== (finding.dueEvidence === void 0))
1791
+ return invalid3(`due_at comes with due_evidence: the ${rules.cited} references of this finding's evidence that give the date, as a list of strings such as ["<reference>"]`);
1792
+ if (finding.assignee === void 0 !== (finding.assigneeEvidence === void 0))
1793
+ return invalid3(`assignee comes with assignee_evidence: the ${rules.cited} references of this finding's evidence that name them, as a list of strings such as ["<reference>"]`);
1794
+ if (finding.assignee !== void 0 && (typeof finding.assignee !== "string" || !/^person:[1-9]\d*$/.test(finding.assignee)))
1795
+ return invalid3("an assignee must be a person reference");
1796
+ return {
1797
+ ...base,
1798
+ kind: "task",
1799
+ type: finding.type,
1800
+ title: findingText(finding.title, 300),
1801
+ reason: findingText(finding.reason, 2e3),
1802
+ commitment: finding.commitment,
1803
+ ...finding.dueAt === void 0 ? {} : {
1804
+ dueAt: meetingTimestamp(finding.dueAt, "a task's due_at"),
1805
+ dueEvidence: support(finding.dueEvidence, evidence, "due_evidence")
1806
+ },
1807
+ ...finding.assignee === void 0 ? {} : {
1808
+ assignee: finding.assignee,
1809
+ assigneeEvidence: support(finding.assigneeEvidence, evidence, "assignee_evidence")
1810
+ }
1811
+ };
1812
+ }, "validateFinding");
1813
+ var support = /* @__PURE__ */ __name((value, evidence, field) => {
1814
+ if (!Array.isArray(value) || value.length < 1 || value.length > 8 || value.some((ref) => typeof ref !== "string" || !evidence.some((item) => item.reference === ref)))
1815
+ return invalid3(`${field} lists 1\u20138 references this finding's evidence cites, as plain strings such as ["<reference>"], not evidence objects`);
1816
+ return [...new Set(value)].sort();
1817
+ }, "support");
1818
+ var validateBatch = /* @__PURE__ */ __name((input, rules, most, one) => {
1819
+ if (!input || typeof input !== "object" || Buffer.byteLength(JSON.stringify(input), "utf8") > 65536)
1820
+ return invalid3(`${rules.plural} take at most 65536 UTF-8 bytes`);
1821
+ findingFields(input, ["schemaVersion", "key", "extractor", "findings"], rules.singular);
1822
+ if (input.schemaVersion !== 1 || !Array.isArray(input.findings) || input.findings.length < 1 || input.findings.length > most)
1823
+ return invalid3(`schemaVersion 1 takes 1\u2013${most} ${rules.plural}`);
1824
+ const key = findingText(input.key, 64);
1825
+ if (!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]*$/.test(key))
1826
+ return invalid3("a findings key uses letters, digits, dot, colon, underscore or hyphen");
1827
+ const ids2 = /* @__PURE__ */ new Set();
1828
+ const findings = input.findings.map((finding) => one(finding, ids2));
1829
+ return { schemaVersion: 1, key, extractor: findingText(input.extractor, 200), findings };
1830
+ }, "validateBatch");
1831
+ var validateFindings = /* @__PURE__ */ __name((input, rules) => validateBatch(input, rules, 16, (finding, ids2) => validateFinding(finding, rules, ids2)), "validateFindings");
1678
1832
  var findingFingerprint = /* @__PURE__ */ __name(({ id: _id, ...finding }) => findingHash(finding), "findingFingerprint");
1679
1833
 
1680
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/findings.js
1834
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/findings.js
1681
1835
  var MEETING_FINDINGS_KIND = "meeting_findings";
1682
1836
  var cue = /* @__PURE__ */ __name((raw) => {
1683
1837
  const reference2 = canonicalMeetingReference(raw);
@@ -1688,24 +1842,24 @@ var cue = /* @__PURE__ */ __name((raw) => {
1688
1842
  var validateMeetingFindings = /* @__PURE__ */ __name((input) => validateFindings(input, { plural: "meeting findings", singular: "meeting finding", cited: "cue", reference: cue }), "validateMeetingFindings");
1689
1843
  var meetingFindingFingerprint = findingFingerprint;
1690
1844
 
1691
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/result-items.js
1692
- var text4 = string();
1693
- var identifier = pipe(text4, minLength(1));
1694
- var nullableText = nullable(text4);
1845
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/result-items.js
1846
+ var text3 = string();
1847
+ var identifier = pipe(text3, minLength(1));
1848
+ var nullableText = nullable(text3);
1695
1849
  var count3 = pipe(number(), integer(), minValue(0));
1696
1850
  var flag = boolean();
1697
- var scope = strictObject({ provider: text4, account: text4 });
1851
+ var scope = strictObject({ provider: text3, account: text3 });
1698
1852
  var run = strictObject({
1699
1853
  meetings: count3,
1700
1854
  participants: count3,
1701
1855
  transcript_rows: count3,
1702
1856
  summaries: count3,
1703
- warnings: array(strictObject({ external_id: text4, message: text4 })),
1704
- timezone: optional(text4)
1857
+ warnings: array(strictObject({ external_id: text3, message: text3 })),
1858
+ timezone: optional(text3)
1705
1859
  });
1706
1860
  var exported = union([
1707
- strictObject({ meeting_id: identifier, format: picklist(["markdown", "vtt"]), filename: text4, content: text4 }),
1708
- strictObject({ meeting_id: identifier, format: picklist(["markdown", "vtt"]), output: text4 })
1861
+ strictObject({ meeting_id: identifier, format: picklist(["markdown", "vtt"]), filename: text3, content: text3 }),
1862
+ strictObject({ meeting_id: identifier, format: picklist(["markdown", "vtt"]), output: text3 })
1709
1863
  ]);
1710
1864
  var eventChange = strictObject({
1711
1865
  action: literal("event.link"),
@@ -1715,7 +1869,7 @@ var eventChange = strictObject({
1715
1869
  var personChange = strictObject({
1716
1870
  action: literal("person.link"),
1717
1871
  participant_id: identifier,
1718
- person_uid: text4,
1872
+ person_uid: text3,
1719
1873
  expected_person_uid: optional(nullableText),
1720
1874
  target_account_ids: optional(array(identifier))
1721
1875
  });
@@ -1728,7 +1882,7 @@ var eventResult = strictObject({
1728
1882
  var personResult = strictObject({
1729
1883
  meeting_id: identifier,
1730
1884
  participant_id: identifier,
1731
- person_uid: text4,
1885
+ person_uid: text3,
1732
1886
  previous_person_uid: nullableText,
1733
1887
  changed: flag
1734
1888
  });
@@ -1741,23 +1895,23 @@ var meetingChange = strictObject({
1741
1895
  result: optional(union([eventResult, personResult]))
1742
1896
  });
1743
1897
  var recognition = strictObject({
1744
- engine: text4,
1745
- model: text4,
1746
- version: optional(text4),
1898
+ engine: text3,
1899
+ model: text3,
1900
+ version: optional(text3),
1747
1901
  timing: optional(picklist(["fixed-windows", "recognition-segments"]))
1748
1902
  });
1749
1903
  var transcription = union([
1750
1904
  strictObject({
1751
1905
  applied: literal(false),
1752
1906
  account_id: identifier,
1753
- external_id: text4,
1907
+ external_id: text3,
1754
1908
  segments: count3,
1755
1909
  media: strictObject({
1756
- id: text4,
1757
- content_hash: text4,
1910
+ id: text3,
1911
+ content_hash: text3,
1758
1912
  size: count3,
1759
1913
  duration_ms: count3,
1760
- format: text4,
1914
+ format: text3,
1761
1915
  sample_rate: count3,
1762
1916
  channels: count3,
1763
1917
  recognition
@@ -1766,21 +1920,21 @@ var transcription = union([
1766
1920
  strictObject({
1767
1921
  applied: literal(true),
1768
1922
  account_id: identifier,
1769
- external_id: text4,
1923
+ external_id: text3,
1770
1924
  meeting_id: identifier,
1771
1925
  created: flag,
1772
1926
  inserted_transcripts: count3,
1773
1927
  replayed_transcripts: count3,
1774
1928
  superseded_transcripts: count3,
1775
1929
  segments: count3,
1776
- media_sha256: text4,
1777
- engine: text4,
1778
- model: text4,
1930
+ media_sha256: text3,
1931
+ engine: text3,
1932
+ model: text3,
1779
1933
  model_version: nullableText,
1780
1934
  timing: picklist(["fixed-windows", "recognition-segments"])
1781
1935
  })
1782
1936
  ]);
1783
- var embeddingModel = strictObject({ key: text4, dims: count3, kind: picklist(["local", "remote"]), model: text4 });
1937
+ var embeddingModel = strictObject({ key: text3, dims: count3, kind: picklist(["local", "remote"]), model: text3 });
1784
1938
  var embedding = union([
1785
1939
  strictObject({
1786
1940
  account_id: identifier,
@@ -1796,7 +1950,7 @@ var embedding = union([
1796
1950
  saved: count3,
1797
1951
  skipped: count3,
1798
1952
  has_more: flag,
1799
- next_hash: optional(text4),
1953
+ next_hash: optional(text3),
1800
1954
  applied: literal(true),
1801
1955
  rebuild: strictObject({
1802
1956
  transcripts: count3,
@@ -1806,15 +1960,22 @@ var embedding = union([
1806
1960
  })
1807
1961
  })
1808
1962
  ]);
1963
+ var repair = strictObject({
1964
+ account_id: identifier,
1965
+ applied: flag,
1966
+ transcripts: count3,
1967
+ languages: array(strictObject({ language: nullableText, transcripts: count3 }))
1968
+ });
1809
1969
  var MEETING_RESULT_ENTITIES = {
1810
1970
  meeting_ingestion: run,
1811
1971
  meeting_export: exported,
1812
1972
  meeting_association: meetingChange,
1813
1973
  meeting_transcription: transcription,
1814
- meeting_embedding: embedding
1974
+ meeting_embedding: embedding,
1975
+ meeting_repair: repair
1815
1976
  };
1816
1977
 
1817
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/event-query.js
1978
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/event-query.js
1818
1979
  var EVENT_QUERY = defineQuery({
1819
1980
  entity: "event",
1820
1981
  backend: "sql",
@@ -1830,7 +1991,7 @@ var EVENT_QUERY = defineQuery({
1830
1991
  ]
1831
1992
  });
1832
1993
 
1833
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/events.js
1994
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/events.js
1834
1995
  var linkEvent = /* @__PURE__ */ __name(async (store, details, now = Date.now()) => {
1835
1996
  const current = await store.meeting(details.meeting.id);
1836
1997
  if (!current)
@@ -1845,7 +2006,7 @@ var linkEvent = /* @__PURE__ */ __name(async (store, details, now = Date.now())
1845
2006
  endsAt: meeting2.endedAt ?? meeting2.startedAt
1846
2007
  });
1847
2008
  if (candidates.length > 1) {
1848
- await store.reviewMeetingLink?.(meeting2.id, candidates.map(({ id: id3 }) => id3), now);
2009
+ await store.reviewMeetingLink?.(meeting2.id, candidates.map(({ id: id4 }) => id4), now);
1849
2010
  return null;
1850
2011
  }
1851
2012
  let event2 = candidates[0];
@@ -1873,7 +2034,7 @@ var linkEvent = /* @__PURE__ */ __name(async (store, details, now = Date.now())
1873
2034
  return (await store.events()).find((e) => e.id === linked?.meeting.eventId) ?? null;
1874
2035
  }, "linkEvent");
1875
2036
 
1876
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/hit-query.js
2037
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/hit-query.js
1877
2038
  var context = {
1878
2039
  command: "search meetings",
1879
2040
  guide: "https://github.com/WireCatLabs/cli-core/blob/main/docs/search/query-language.md#\u0432\u0441\u0442\u0440\u0435\u0447\u0438"
@@ -1936,7 +2097,56 @@ var MEETING_FIELDS = defineQuery({
1936
2097
  });
1937
2098
  var parseMeetingQuery = /* @__PURE__ */ __name((query) => validateQuery(parseLucene(query, { defaultField: "text", proximity: true, ...context }), MEETING_HIT_QUERY, context), "parseMeetingQuery");
1938
2099
 
1939
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/ingest.js
2100
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/language.js
2101
+ var LATIN_WORDS = {
2102
+ en: ["the", "and", "is", "that", "you", "this", "what", "have", "with", "are"],
2103
+ es: ["el", "los", "las", "por", "pero", "para", "est\xE1", "muy", "tambi\xE9n", "hay"],
2104
+ de: ["der", "und", "ist", "nicht", "das", "ich", "wir", "mit", "auch", "ein"],
2105
+ fr: ["le", "les", "est", "une", "pas", "je", "vous", "nous", "avec", "mais"],
2106
+ it: ["gli", "della", "sono", "perch\xE9", "anche", "questo", "molto", "che", "di", "\xE8"],
2107
+ pt: ["n\xE3o", "voc\xEA", "isso", "muito", "ent\xE3o", "com", "uma", "tamb\xE9m", "mas", "eu"]
2108
+ };
2109
+ var LATIN_LANGUAGE = new Map(Object.entries(LATIN_WORDS).flatMap(([language, words2]) => words2.map((word) => [word, language])));
2110
+ var UKRAINIAN = /[іїєґ]/giu;
2111
+ var CYRILLIC = new RegExp("\\p{Script=Cyrillic}", "gu");
2112
+ var LATIN = new RegExp("\\p{Script=Latin}", "gu");
2113
+ var MIN_LETTERS = 20;
2114
+ var DOMINANT = 0.75;
2115
+ var countOf = /* @__PURE__ */ __name((text6, pattern2) => text6.match(pattern2)?.length ?? 0, "countOf");
2116
+ var latinLanguage = /* @__PURE__ */ __name((texts) => {
2117
+ const votes = /* @__PURE__ */ new Map();
2118
+ for (const text6 of texts)
2119
+ for (const word of text6.toLowerCase().split(/[^\p{L}]+/u)) {
2120
+ const language = LATIN_LANGUAGE.get(word);
2121
+ if (language)
2122
+ votes.set(language, (votes.get(language) ?? 0) + 1);
2123
+ }
2124
+ const [first, second] = [...votes].sort((a, b) => b[1] - a[1]);
2125
+ if (!first || first[1] < 3 || second && first[1] < 2 * second[1])
2126
+ return null;
2127
+ return first[0];
2128
+ }, "latinLanguage");
2129
+ var transcriptLanguage = /* @__PURE__ */ __name((texts) => {
2130
+ const all = [...texts];
2131
+ let cyrillic = 0;
2132
+ let latin = 0;
2133
+ let ukrainian = 0;
2134
+ for (const text6 of all) {
2135
+ cyrillic += countOf(text6, CYRILLIC);
2136
+ latin += countOf(text6, LATIN);
2137
+ ukrainian += countOf(text6, UKRAINIAN);
2138
+ }
2139
+ const letters = cyrillic + latin;
2140
+ if (letters < MIN_LETTERS)
2141
+ return null;
2142
+ if (cyrillic / letters >= DOMINANT)
2143
+ return ukrainian / cyrillic >= 0.01 ? "uk" : "ru";
2144
+ if (latin / letters >= DOMINANT)
2145
+ return latinLanguage(all);
2146
+ return null;
2147
+ }, "transcriptLanguage");
2148
+
2149
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/ingest.js
1940
2150
  var contentHash = /* @__PURE__ */ __name(async (text6) => {
1941
2151
  const bytes = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(text6));
1942
2152
  return Array.from(new Uint8Array(bytes), (byte) => byte.toString(16).padStart(2, "0")).join("");
@@ -1950,7 +2160,7 @@ var speakerPosition = /* @__PURE__ */ __name((name, participants) => {
1950
2160
  var transcriptInput = /* @__PURE__ */ __name(async (lines, participants, source, hashText = JSON.stringify(lines), format = null) => ({
1951
2161
  source,
1952
2162
  format,
1953
- language: null,
2163
+ language: transcriptLanguage(lines.map((line2) => line2.text)),
1954
2164
  contentHash: await contentHash(hashText),
1955
2165
  externalCreatedAt: null,
1956
2166
  metadata: null,
@@ -1967,13 +2177,13 @@ var transcriptInput = /* @__PURE__ */ __name(async (lines, participants, source,
1967
2177
  }))
1968
2178
  }), "transcriptInput");
1969
2179
  var timestamp2 = /* @__PURE__ */ __name((value) => {
1970
- const time = Date.parse(value);
1971
- if (!Number.isFinite(time))
2180
+ const time2 = Date.parse(value);
2181
+ if (!Number.isFinite(time2))
1972
2182
  throw new Error("Invalid meeting timestamp");
1973
- return time;
2183
+ return time2;
1974
2184
  }, "timestamp");
1975
2185
 
1976
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/transcript-text.js
2186
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/transcript-text.js
1977
2187
  var TranscriptTextError = class extends Error {
1978
2188
  static {
1979
2189
  __name(this, "TranscriptTextError");
@@ -2028,7 +2238,7 @@ var parseTranscriptText = /* @__PURE__ */ __name((input) => {
2028
2238
  return { header, lines };
2029
2239
  }, "parseTranscriptText");
2030
2240
 
2031
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/vtt.js
2241
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/vtt.js
2032
2242
  var VttError = class extends Error {
2033
2243
  static {
2034
2244
  __name(this, "VttError");
@@ -2080,7 +2290,7 @@ var parseVtt = /* @__PURE__ */ __name((input) => {
2080
2290
  return cues;
2081
2291
  }, "parseVtt");
2082
2292
 
2083
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/import.js
2293
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/import.js
2084
2294
  var importFiles = /* @__PURE__ */ __name(async (files, store, now = Date.now()) => {
2085
2295
  const report = { meetings: 0, participants: 0, transcriptRows: 0, summaries: 0, warnings: [] };
2086
2296
  for (const file of files) {
@@ -2113,10 +2323,61 @@ var importFiles = /* @__PURE__ */ __name(async (files, store, now = Date.now())
2113
2323
  return report;
2114
2324
  }, "importFiles");
2115
2325
 
2116
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/links.js
2326
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/links.js
2117
2327
  var CHAT_MESSAGES_READ = 1e5;
2118
2328
 
2119
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/passage.js
2329
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/meeting-management.js
2330
+ var nonempty = /* @__PURE__ */ __name((value, name) => {
2331
+ if (typeof value !== "string" || !value.trim())
2332
+ throw new CliError("validation_error", `${name} must be nonempty`);
2333
+ return value;
2334
+ }, "nonempty");
2335
+ var validateMeetingChange = /* @__PURE__ */ __name((change, create) => {
2336
+ if (!change || typeof change !== "object" || Array.isArray(change) || Object.keys(change).some((key) => !["title", "kind", "startTime", "durationMinutes", "timezone", "agenda"].includes(key)))
2337
+ throw new CliError("validation_error", "unsupported meeting change field");
2338
+ const result = {};
2339
+ if (change.title !== void 0)
2340
+ result.title = nonempty(change.title, "meeting title");
2341
+ if (create && result.title === void 0)
2342
+ throw new CliError("validation_error", "meeting title is required");
2343
+ if (change.kind !== void 0) {
2344
+ if (change.kind !== "instant" && change.kind !== "scheduled")
2345
+ throw new CliError("validation_error", "only instant or scheduled meeting kinds are supported");
2346
+ result.kind = change.kind;
2347
+ }
2348
+ if (change.startTime !== void 0) {
2349
+ result.startTime = meetingTimestamp(change.startTime, "meeting start");
2350
+ }
2351
+ if (change.durationMinutes !== void 0) {
2352
+ if (!Number.isSafeInteger(change.durationMinutes) || change.durationMinutes <= 0 || change.durationMinutes > 1440)
2353
+ throw new CliError("validation_error", "meeting duration must be an integer from 1 to 1440 minutes");
2354
+ result.durationMinutes = change.durationMinutes;
2355
+ }
2356
+ if (change.timezone !== void 0) {
2357
+ if (typeof change.timezone !== "string" || !change.timezone.trim())
2358
+ throw new CliError("validation_error", "meeting timezone must be a valid IANA timezone");
2359
+ try {
2360
+ new Intl.DateTimeFormat("en", { timeZone: change.timezone }).format();
2361
+ } catch {
2362
+ throw new CliError("validation_error", "meeting timezone must be a valid IANA timezone");
2363
+ }
2364
+ result.timezone = change.timezone;
2365
+ }
2366
+ if (change.agenda !== void 0) {
2367
+ if (typeof change.agenda !== "string")
2368
+ throw new CliError("validation_error", "meeting agenda must be text");
2369
+ result.agenda = change.agenda;
2370
+ }
2371
+ if (create) {
2372
+ result.kind ??= "scheduled";
2373
+ if (result.kind === "scheduled" && result.startTime === void 0)
2374
+ throw new CliError("validation_error", "scheduled meeting start is required");
2375
+ } else if (!Object.keys(result).length)
2376
+ throw new CliError("validation_error", "at least one meeting change is required");
2377
+ return Object.freeze(result);
2378
+ }, "validateMeetingChange");
2379
+
2380
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/passage.js
2120
2381
  var meetingHitContextLimits = /* @__PURE__ */ __name((options = {}) => {
2121
2382
  const { before = 3, after = 3, bytes = 65536, max_read_bytes = 4194304, expected_fingerprint } = options;
2122
2383
  if (![before, after].every((value) => Number.isSafeInteger(value) && value >= 0) || before + after > 999 || !Number.isSafeInteger(bytes) || bytes < 2 || bytes > 4194304 || !Number.isSafeInteger(max_read_bytes) || max_read_bytes < 1 || max_read_bytes > 67108864 || expected_fingerprint !== void 0 && (typeof expected_fingerprint !== "string" || !/^[a-f0-9]{64}$/.test(expected_fingerprint)))
@@ -2129,7 +2390,7 @@ var validateMeetingPassage = /* @__PURE__ */ __name((reference2, options) => {
2129
2390
  throw new CliError("validation_error", "choose a cue reference and json, text or markdown output");
2130
2391
  }, "validateMeetingPassage");
2131
2392
 
2132
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/preparation-context.js
2393
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/preparation-context.js
2133
2394
  var validateMeetingPreparationContext = /* @__PURE__ */ __name((original) => {
2134
2395
  if (!original || typeof original !== "object" || Array.isArray(original))
2135
2396
  throw new CliError("validation_error", "meeting preparation context is required");
@@ -2154,7 +2415,7 @@ var validateMeetingPreparationContext = /* @__PURE__ */ __name((original) => {
2154
2415
  return { ...input, limit, maxReadBytes };
2155
2416
  }, "validateMeetingPreparationContext");
2156
2417
 
2157
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/project-evidence-answer.js
2418
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/project-evidence-answer.js
2158
2419
  var count4 = pipe(number(), integer(), minValue(0));
2159
2420
  var id = pipe(string(), minLength(1));
2160
2421
  var meetingProjectEvidence = strictObject({
@@ -2275,7 +2536,7 @@ var meetingProjectEvidenceAnswer = /* @__PURE__ */ __name((page, prepared, comma
2275
2536
  };
2276
2537
  }, "meetingProjectEvidenceAnswer");
2277
2538
 
2278
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/search-validation.js
2539
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/search-validation.js
2279
2540
  var validateMeetingHitSearch = /* @__PURE__ */ __name((query, options = {}) => {
2280
2541
  const integer3 = /* @__PURE__ */ __name((value, low, high) => Number.isSafeInteger(value) && value >= low && value <= high, "integer");
2281
2542
  if (typeof query !== "string" || !query.trim() || query.includes("\0") || new TextEncoder().encode(query).byteLength > 65536 || !integer3(options.limit ?? 100, 1, 1e3) || !integer3(options.maxReadBytes ?? 4194304, 1, 67108864) || [
@@ -2295,7 +2556,7 @@ var validateMeetingHitSearch = /* @__PURE__ */ __name((query, options = {}) => {
2295
2556
  throw new CliError("validation_error", "choose one project selector and one tag or topic selector");
2296
2557
  }, "validateMeetingHitSearch");
2297
2558
 
2298
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/project-evidence-query.js
2559
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/project-evidence-query.js
2299
2560
  var ids = {
2300
2561
  meeting_id: "meetingId",
2301
2562
  identity_id: "participantIdentityId",
@@ -2331,8 +2592,8 @@ var MEETING_PROJECT_EVIDENCE_QUERY = defineQuery({
2331
2592
  ]
2332
2593
  });
2333
2594
  var requestKeys = /* @__PURE__ */ new Set(["query", "limit", "cursor", "maxReadBytes", "signal"]);
2334
- var prepareMeetingProjectEvidence = /* @__PURE__ */ __name((project, request = {}, now = Date.now()) => {
2335
- if (!request || typeof request !== "object" || Array.isArray(request) || Object.keys(request).some((key) => !requestKeys.has(key)) || typeof project !== "string" || !project.trim() || project.length > 200 || /[\p{Cc}\p{Cf}]/u.test(project) || request.query !== void 0 && typeof request.query !== "string")
2595
+ var prepareMeetingProjectEvidence = /* @__PURE__ */ __name((project2, request = {}, now = Date.now()) => {
2596
+ if (!request || typeof request !== "object" || Array.isArray(request) || Object.keys(request).some((key) => !requestKeys.has(key)) || typeof project2 !== "string" || !project2.trim() || project2.length > 200 || /[\p{Cc}\p{Cf}]/u.test(project2) || request.query !== void 0 && typeof request.query !== "string")
2336
2597
  throw new CliError("validation_error", "expected an existing project and bounded evidence arguments");
2337
2598
  if (request.query !== void 0 && new TextEncoder().encode(request.query).byteLength > 8192 || [request.limit, request.maxReadBytes].some((value) => value !== void 0 && typeof value !== "number"))
2338
2599
  throw new CliError("validation_error", "invalid project evidence query or budget");
@@ -2380,26 +2641,26 @@ var prepareMeetingProjectEvidence = /* @__PURE__ */ __name((project, request = {
2380
2641
  options.until = range.upper - (range.upper_inclusive ? 0 : 1);
2381
2642
  frozen.push(`started_at:[${options.since === void 0 ? "*" : `"${new Date(options.since).toISOString()}"`} TO ${options.until === void 0 ? "*" : `"${new Date(options.until).toISOString()}"`}]`);
2382
2643
  }
2383
- validateMeetingHitSearch(project, options);
2644
+ validateMeetingHitSearch(project2, options);
2384
2645
  if (options.cursor !== void 0 && (typeof options.cursor !== "string" || !/^[A-Za-z0-9_-]{1,4096}$/.test(options.cursor)))
2385
2646
  throw new CliError("validation_error", "invalid project evidence cursor");
2386
- return { project: project.trim(), options, query: frozen.join(" AND ") };
2647
+ return { project: project2.trim(), options, query: frozen.join(" AND ") };
2387
2648
  }, "prepareMeetingProjectEvidence");
2388
2649
 
2389
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/project-evidence.js
2390
- var readMeetingProjectEvidence = /* @__PURE__ */ __name(async (read, project, request = {}, now = Date.now()) => {
2391
- const prepared = prepareMeetingProjectEvidence(project, request, now);
2650
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/project-evidence.js
2651
+ var readMeetingProjectEvidence = /* @__PURE__ */ __name(async (read, project2, request = {}, now = Date.now()) => {
2652
+ const prepared = prepareMeetingProjectEvidence(project2, request, now);
2392
2653
  const page = await read(prepared.project, prepared.options);
2393
2654
  prepared.options.signal?.throwIfAborted();
2394
2655
  return meetingProjectEvidenceAnswer(page, prepared);
2395
2656
  }, "readMeetingProjectEvidence");
2396
2657
 
2397
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/pull.js
2658
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/pull.js
2398
2659
  var participantInput = /* @__PURE__ */ __name((p, provider, occurrenceId2, position, accountId) => {
2399
- const { identityExternalId, ...fields2 } = p;
2660
+ const { identityExternalId, ...fields } = p;
2400
2661
  const externalId = identityExternalId ?? (p.email ? `email:${p.email.toLowerCase()}` : p.externalId) ?? `name:${p.displayName ?? "unknown"}@${accountId}/${occurrenceId2}:${position}`;
2401
2662
  return {
2402
- ...fields2,
2663
+ ...fields,
2403
2664
  identity: {
2404
2665
  provider,
2405
2666
  externalId,
@@ -2421,20 +2682,20 @@ var pull = /* @__PURE__ */ __name(async (source, store, options) => {
2421
2682
  const from = timestamp2(since) - lookbackMs;
2422
2683
  const meetings = await source.meetings(lookbackMs === 0 ? since : new Date(from).toISOString());
2423
2684
  for (const m of meetings) {
2424
- const id3 = m.occurrence.id;
2685
+ const id4 = m.occurrence.id;
2425
2686
  const read = /* @__PURE__ */ __name(async (part, call) => {
2426
2687
  try {
2427
2688
  return await call();
2428
2689
  } catch (error) {
2429
2690
  failed = true;
2430
2691
  const message = error instanceof Error ? error.message : "could not be read";
2431
- report.warnings.push({ externalId: id3, message: `${part}: ${message}` });
2692
+ report.warnings.push({ externalId: id4, message: `${part}: ${message}` });
2432
2693
  return void 0;
2433
2694
  }
2434
2695
  }, "read");
2435
2696
  try {
2436
- const sourceParticipants = await read("participants", () => source.participants(id3));
2437
- const participants = (sourceParticipants ?? []).map((p, i) => participantInput(p, source.provider, id3, i, options.accountId));
2697
+ const sourceParticipants = await read("participants", () => source.participants(id4));
2698
+ const participants = (sourceParticipants ?? []).map((p, i) => participantInput(p, source.provider, id4, i, options.accountId));
2438
2699
  const names = /* @__PURE__ */ new Map();
2439
2700
  for (const p of participants)
2440
2701
  if (p.displayName !== null) {
@@ -2443,18 +2704,18 @@ var pull = /* @__PURE__ */ __name(async (source, store, options) => {
2443
2704
  names.set(p.displayName, identities);
2444
2705
  }
2445
2706
  if ([...names.values()].some((ids2) => ids2.size > 1))
2446
- report.warnings.push({ externalId: id3, message: "Participant names are ambiguous" });
2447
- const lines = await read("transcript", () => source.transcript(id3));
2448
- const chat = await read("chat", () => source.chat(id3));
2449
- const summary = await read("summary", () => source.summary(id3));
2450
- const attachments = await read("files", () => source.files(id3));
2707
+ report.warnings.push({ externalId: id4, message: "Participant names are ambiguous" });
2708
+ const lines = await read("transcript", () => source.transcript(id4));
2709
+ const chat = await read("chat", () => source.chat(id4));
2710
+ const summary = await read("summary", () => source.summary(id4));
2711
+ const attachments = await read("files", () => source.files(id4));
2451
2712
  const startedAt = timestamp2(m.occurrence.startedAt);
2452
2713
  const endedAt = m.occurrence.endedAt === null ? null : timestamp2(m.occurrence.endedAt);
2453
2714
  if (endedAt !== null && endedAt < startedAt)
2454
2715
  throw new Error("Meeting ends before it starts");
2455
2716
  const meeting2 = {
2456
2717
  accountId: options.accountId,
2457
- externalId: id3,
2718
+ externalId: id4,
2458
2719
  title: m.occurrence.title,
2459
2720
  description: m.description ?? null,
2460
2721
  location: m.location ?? null,
@@ -2525,7 +2786,7 @@ unlinked`, format)],
2525
2786
  report.summaries += summary ? 1 : 0;
2526
2787
  } catch (error) {
2527
2788
  failed = true;
2528
- report.warnings.push({ externalId: id3, message: error instanceof Error ? error.message : "Meeting pull failed" });
2789
+ report.warnings.push({ externalId: id4, message: error instanceof Error ? error.message : "Meeting pull failed" });
2529
2790
  }
2530
2791
  }
2531
2792
  if (!failed)
@@ -2533,47 +2794,47 @@ unlinked`, format)],
2533
2794
  return report;
2534
2795
  }, "pull");
2535
2796
 
2536
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/read-answers.js
2537
- var text5 = string();
2797
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/read-answers.js
2798
+ var text4 = string();
2538
2799
  var count5 = pipe(number(), integer(), minValue(0));
2539
2800
  var id2 = pipe(number(), integer(), minValue(1));
2540
2801
  var iso3 = /* @__PURE__ */ __name((ms) => ms === null ? null : new Date(ms).toISOString(), "iso");
2541
2802
  var meetingReview = strictObject({
2542
2803
  ref: reference,
2543
2804
  id: pipe(string(), minLength(1)),
2544
- title: nullable(text5),
2805
+ title: nullable(text4),
2545
2806
  started_at: nullable(isoTime),
2546
2807
  duration_ms: nullable(count5),
2547
2808
  participants_count: nullable(count5),
2548
- projects: array(text5),
2809
+ projects: array(text4),
2549
2810
  /** Null when the meeting has no current transcript. */
2550
2811
  transcript: nullable(strictObject({ lines: count5, words: count5 })),
2551
2812
  /** The three who talked longest. */
2552
- speakers: array(strictObject({ name: nullable(text5), talk_ms: count5 })),
2813
+ speakers: array(strictObject({ name: nullable(text4), talk_ms: count5 })),
2553
2814
  /** The newest stored summary; null when there is none. */
2554
2815
  summary: nullable(strictObject({
2555
- source: text5,
2556
- title: nullable(text5),
2557
- overview: nullable(text5),
2558
- next_steps: array(text5),
2559
- url: nullable(text5)
2816
+ source: text4,
2817
+ title: nullable(text4),
2818
+ overview: nullable(text4),
2819
+ next_steps: array(text4),
2820
+ url: nullable(text4)
2560
2821
  }))
2561
2822
  });
2562
2823
  var meetingLink = strictObject({
2563
- url: text5,
2564
- domain: nullable(text5),
2824
+ url: text4,
2825
+ domain: nullable(text4),
2565
2826
  /** The Google Docs, Sheets, Slides, Forms or Drive file it names. */
2566
- document_id: nullable(text5),
2827
+ document_id: nullable(text4),
2567
2828
  count: count5,
2568
2829
  first_at: isoTime,
2569
2830
  last_at: isoTime,
2570
- senders: array(text5),
2571
- meetings: array(strictObject({ ref: reference, title: nullable(text5) }))
2831
+ senders: array(text4),
2832
+ meetings: array(strictObject({ ref: reference, title: nullable(text4) }))
2572
2833
  });
2573
2834
  var meetingSpeaker = strictObject({
2574
2835
  /** `person:<id>`, `identity:<id>`, `name:<lowercased name>` or `unknown`. */
2575
- key: text5,
2576
- name: nullable(text5),
2836
+ key: text4,
2837
+ name: nullable(text4),
2577
2838
  person_id: nullable(id2),
2578
2839
  identity_id: nullable(id2),
2579
2840
  meetings: count5,
@@ -2584,27 +2845,44 @@ var meetingSpeaker = strictObject({
2584
2845
  share: pipe(number(), minValue(0), maxValue(1))
2585
2846
  });
2586
2847
  var meetingStats = strictObject({
2587
- time_zone: text5,
2848
+ time_zone: text4,
2588
2849
  meetings: count5,
2589
2850
  lines: count5,
2590
2851
  words: count5,
2591
2852
  talk_ms: count5,
2592
2853
  /** `week_start` is the Monday, as a date in `time_zone`. */
2593
- weeks: array(strictObject({ week_start: text5, meetings: count5, talk_ms: count5 })),
2854
+ weeks: array(strictObject({ week_start: text4, meetings: count5, talk_ms: count5 })),
2594
2855
  top_speakers: array(meetingSpeaker)
2595
2856
  });
2857
+ var meetingCountsRow = strictObject({
2858
+ key: text4,
2859
+ name: nullable(text4),
2860
+ meetings: count5,
2861
+ minutes: count5,
2862
+ mean_minutes: nullable(number()),
2863
+ transcripts: count5
2864
+ });
2865
+ var meetingCounts = strictObject({
2866
+ by: picklist(["day", "week", "series"]),
2867
+ meetings: count5,
2868
+ minutes: count5,
2869
+ mean_minutes: nullable(number()),
2870
+ transcripts: count5,
2871
+ rows: array(meetingCountsRow),
2872
+ has_more: boolean()
2873
+ });
2596
2874
  var truncated = /* @__PURE__ */ __name((...why) => nullable(picklist(why)), "truncated");
2597
2875
  var meetingParticipants = strictObject({
2598
2876
  schema_version: literal(1),
2599
2877
  kind: literal("meeting_participants"),
2600
2878
  account_id: id2,
2601
- query: text5,
2879
+ query: text4,
2602
2880
  items: array(strictObject({
2603
2881
  participant_id: id2,
2604
2882
  meeting_id: id2,
2605
2883
  identity_id: id2,
2606
- display_name: nullable(text5),
2607
- email: nullable(text5)
2884
+ display_name: nullable(text4),
2885
+ email: nullable(text4)
2608
2886
  })),
2609
2887
  /** Several identities on one page are observations, never speaker attribution or person links. */
2610
2888
  ambiguity: strictObject({ scope: literal("page"), multiple_identities: boolean(), identity_ids: array(id2) }),
@@ -2618,7 +2896,7 @@ var meetingParticipants = strictObject({
2618
2896
  mode: literal("cursor"),
2619
2897
  limit: count5,
2620
2898
  has_more: boolean(),
2621
- next_cursor: optional(text5)
2899
+ next_cursor: optional(text4)
2622
2900
  })
2623
2901
  });
2624
2902
  var revision = picklist(["current", "superseded"]);
@@ -2627,8 +2905,8 @@ var meetingPassage = strictObject({
2627
2905
  kind: literal("meeting_context"),
2628
2906
  source: reference,
2629
2907
  target_ref: reference,
2630
- target_fingerprint: text5,
2631
- fingerprint: text5,
2908
+ target_fingerprint: text4,
2909
+ fingerprint: text4,
2632
2910
  revision,
2633
2911
  limits: strictObject({ before: count5, after: count5, bytes: count5, max_read_bytes: count5 }),
2634
2912
  content_bytes: count5,
@@ -2647,30 +2925,30 @@ var meetingPassage = strictObject({
2647
2925
  }),
2648
2926
  items: array(strictObject({
2649
2927
  ref: reference,
2650
- fingerprint: text5,
2928
+ fingerprint: text4,
2651
2929
  transcript_id: id2,
2652
- content_hash: nullable(text5),
2930
+ content_hash: nullable(text4),
2653
2931
  position: count5,
2654
2932
  start_ms: count5,
2655
2933
  end_ms: count5,
2656
2934
  speaker_participant_id: nullable(id2),
2657
- speaker_name: nullable(text5),
2658
- text: text5,
2935
+ speaker_name: nullable(text4),
2936
+ text: text4,
2659
2937
  revision
2660
2938
  }))
2661
2939
  });
2662
2940
  var event = strictObject({
2663
2941
  id: pipe(string(), minLength(1)),
2664
- event_series_id: nullable(text5),
2665
- title: nullable(text5),
2666
- description: nullable(text5),
2667
- location: nullable(text5),
2942
+ event_series_id: nullable(text4),
2943
+ title: nullable(text4),
2944
+ description: nullable(text4),
2945
+ location: nullable(text4),
2668
2946
  starts_at: nullable(isoTime),
2669
2947
  ends_at: nullable(isoTime),
2670
- timezone: nullable(text5),
2948
+ timezone: nullable(text4),
2671
2949
  /** `auto`: made from a meeting; `owner`: made by hand; `calendar`: from a calendar's entries. */
2672
2950
  origin: picklist(["auto", "owner", "calendar"]),
2673
- status: nullable(text5),
2951
+ status: nullable(text4),
2674
2952
  all_day: boolean(),
2675
2953
  /** When its calendar deleted it: shown as "deleted in Google", kept as history. */
2676
2954
  source_deleted_at: nullable(isoTime),
@@ -2678,7 +2956,19 @@ var event = strictObject({
2678
2956
  created_at: isoTime,
2679
2957
  updated_at: isoTime,
2680
2958
  /** The fields whoever sent the invitation wrote, on a calendar CLI's `events list`: an agent reads them as data. */
2681
- untrusted: optional(array(text5))
2959
+ untrusted: optional(array(text4)),
2960
+ /** On a calendar CLI's `events list changed:<date>`: what changed since then, and when the store saw it. */
2961
+ change: optional(picklist(["new", "moved", "cancelled"])),
2962
+ changed_at: optional(nullable(isoTime)),
2963
+ /** The times a moved event had at that date. */
2964
+ was: optional(strictObject({ starts_at: nullable(isoTime), ends_at: nullable(isoTime) })),
2965
+ /**
2966
+ * Whether its time overlaps another event's, in the accounts read: a timed event, not cancelled, not declined, not
2967
+ * free and no working-location block. On a calendar CLI's `events list` when the query names it.
2968
+ */
2969
+ overlapping: optional(boolean()),
2970
+ /** With `overlapping:true`: the events it overlaps, as `event:<id>`. */
2971
+ overlaps: optional(array(text4))
2682
2972
  });
2683
2973
  var eventItem = /* @__PURE__ */ __name((one) => ({
2684
2974
  id: String(one.id),
@@ -2698,10 +2988,10 @@ var eventItem = /* @__PURE__ */ __name((one) => ({
2698
2988
  updated_at: new Date(one.updatedAt).toISOString()
2699
2989
  }), "eventItem");
2700
2990
 
2701
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/recording-transfer.js
2991
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/recording-transfer.js
2702
2992
  var strongRecordingValidator = /* @__PURE__ */ __name((value) => typeof value === "string" && value.length <= 1024 && /^"[\x21\x23-\x7e\x80-\xff]*"$/.test(value), "strongRecordingValidator");
2703
2993
 
2704
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/related-history.js
2994
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/related-history.js
2705
2995
  var validateMeetingRelatedHistory = /* @__PURE__ */ __name((original) => {
2706
2996
  if (!original || typeof original !== "object" || Array.isArray(original))
2707
2997
  throw new CliError("validation_error", "related history request is required");
@@ -2712,7 +3002,7 @@ var validateMeetingRelatedHistory = /* @__PURE__ */ __name((original) => {
2712
3002
  const positive = /* @__PURE__ */ __name((value) => Number.isSafeInteger(value) && value > 0, "positive");
2713
3003
  if (!positive(input.accountId) || !positive(input.seriesId))
2714
3004
  throw new CliError("validation_error", "accountId and seriesId must be positive safe integers");
2715
- if (!Array.isArray(input.anchorIds) || input.anchorIds.length > 20 || input.anchorIds.some((id3) => !positive(id3)))
3005
+ if (!Array.isArray(input.anchorIds) || input.anchorIds.length > 20 || input.anchorIds.some((id4) => !positive(id4)))
2716
3006
  throw new CliError("validation_error", "anchorIds must contain at most 20 positive safe integers");
2717
3007
  for (const key of ["after", "before"])
2718
3008
  if (!Number.isSafeInteger(input[key]) || Math.abs(input[key]) > 864e13)
@@ -2731,14 +3021,14 @@ var validateMeetingRelatedHistory = /* @__PURE__ */ __name((original) => {
2731
3021
  return { ...input, anchorIds: [...new Set(input.anchorIds)], limit, maxReadBytes };
2732
3022
  }, "validateMeetingRelatedHistory");
2733
3023
 
2734
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/review.js
3024
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/review.js
2735
3025
  var REVIEW_LIMIT = { default: 50, most: 200 };
2736
3026
 
2737
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/save-hints.js
3027
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/save-hints.js
2738
3028
  var SAVE_HELP = `Worth keeping \u2014 a decision, a promise, a preference? Record it with \`memo facts add\` or
2739
3029
  \`memo memories add\`, citing the msg: locator or meeting: reference as --evidence.`;
2740
3030
 
2741
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/series-history.js
3031
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/series-history.js
2742
3032
  var validateMeetingSeriesHistory = /* @__PURE__ */ __name((input) => {
2743
3033
  input.signal?.throwIfAborted();
2744
3034
  if (!Number.isSafeInteger(input.accountId) || input.accountId <= 0)
@@ -2759,39 +3049,40 @@ var validateMeetingSeriesHistory = /* @__PURE__ */ __name((input) => {
2759
3049
  return { ...input, limit, maxReadBytes };
2760
3050
  }, "validateMeetingSeriesHistory");
2761
3051
 
2762
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/upcoming-validation.js
3052
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/upcoming-validation.js
2763
3053
  var occurrenceId = /* @__PURE__ */ __name((value) => typeof value === "string" && value.trim().length > 0 && value.length <= 1e3 && !/[\0\r\n]/.test(value), "occurrenceId");
2764
3054
 
2765
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/series-inventory-validation.js
2766
- function invalid3(field, response = false) {
3055
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/series-inventory-validation.js
3056
+ function invalid4(field, response = false) {
2767
3057
  throw new CliError(response ? "invalid_response" : "validation_error", `invalid meeting inventory ${field}`);
2768
3058
  }
2769
- __name(invalid3, "invalid");
2770
- var object2 = /* @__PURE__ */ __name((value, fields2, field, response = false) => {
3059
+ __name(invalid4, "invalid");
3060
+ var object2 = /* @__PURE__ */ __name((value, fields, field, response = false) => {
2771
3061
  if (!value || typeof value !== "object" || Array.isArray(value))
2772
- invalid3(field, response);
3062
+ invalid4(field, response);
2773
3063
  for (const key of Object.keys(value))
2774
- if (!fields2.includes(key))
2775
- invalid3(`${field}.${key}`, response);
3064
+ if (!fields.includes(key))
3065
+ invalid4(`${field}.${key}`, response);
2776
3066
  }, "object");
2777
3067
  var cursorDetails = /* @__PURE__ */ __name((value) => {
2778
3068
  if (typeof value !== "string" || value.length > 4096 || !/^[A-Za-z0-9_-]+$/.test(value))
2779
- invalid3("cursor");
3069
+ invalid4("cursor");
2780
3070
  try {
2781
3071
  const decoded = JSON.parse(new TextDecoder("utf8", { fatal: true }).decode(Buffer.from(value, "base64url")));
2782
3072
  object2(decoded, ["version", "selection", "cursor"], "cursor");
2783
3073
  if (decoded.version !== 1 || typeof decoded.selection !== "string" || !/^[a-f0-9]{64}$/.test(decoded.selection) || !occurrenceId(decoded.cursor))
2784
- invalid3("cursor");
3074
+ invalid4("cursor");
2785
3075
  return decoded;
2786
3076
  } catch {
2787
- return invalid3("cursor");
3077
+ return invalid4("cursor");
2788
3078
  }
2789
3079
  }, "cursorDetails");
2790
3080
  var validateMeetingSeriesInventoryCursor = /* @__PURE__ */ __name((value) => {
2791
3081
  cursorDetails(value);
2792
3082
  }, "validateMeetingSeriesInventoryCursor");
2793
3083
 
2794
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/meetings/stats.js
3084
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/meetings/stats.js
3085
+ var MEETING_COUNTS_GROUPINGS = ["day", "week", "series"];
2795
3086
  var zoneOf = /* @__PURE__ */ __name((timeZone) => {
2796
3087
  const zone = timeZone ?? "UTC";
2797
3088
  try {
@@ -2807,17 +3098,72 @@ var weekStart = /* @__PURE__ */ __name((at, format) => {
2807
3098
  const day = Date.UTC(Number(parts.year), Number(parts.month) - 1, Number(parts.day));
2808
3099
  return new Date(day - DAYS.indexOf(parts.weekday ?? "Mon") * 864e5).toISOString().slice(0, 10);
2809
3100
  }, "weekStart");
3101
+ var dayKey = /* @__PURE__ */ __name((at, format) => {
3102
+ const parts = Object.fromEntries(format.formatToParts(new Date(at)).map((part) => [part.type, part.value]));
3103
+ return `${parts.year}-${parts.month}-${parts.day}`;
3104
+ }, "dayKey");
3105
+ var zoneFormat = /* @__PURE__ */ __name((zone) => new Intl.DateTimeFormat("en-US", {
3106
+ timeZone: zone,
3107
+ year: "numeric",
3108
+ month: "2-digit",
3109
+ day: "2-digit",
3110
+ weekday: "short"
3111
+ }), "zoneFormat");
3112
+ var NO_SERIES = "no-series";
3113
+ var MOST_COUNT_ROWS = 100;
3114
+ var minutesOf = /* @__PURE__ */ __name((ms) => Math.round(ms / 6e4), "minutesOf");
3115
+ var meanOf = /* @__PURE__ */ __name((ms, timed) => timed === 0 ? null : Math.round(ms / timed / 6e3) / 10, "meanOf");
3116
+ var aggregateMeetingCounts = /* @__PURE__ */ __name((meetings, by, timeZone, limit = MOST_COUNT_ROWS) => {
3117
+ if (!MEETING_COUNTS_GROUPINGS.includes(by))
3118
+ throw new CliError("validation_error", `--by takes ${MEETING_COUNTS_GROUPINGS.join(", ")}`);
3119
+ if (!Number.isSafeInteger(limit) || limit < 1)
3120
+ throw new CliError("validation_error", "--limit is a positive number");
3121
+ const zone = zoneOf(timeZone);
3122
+ const format = zoneFormat(zone);
3123
+ const sum = /* @__PURE__ */ __name(() => ({ meetings: 0, ms: 0, timed: 0, transcripts: 0 }), "sum");
3124
+ const add = /* @__PURE__ */ __name((into, meeting2) => {
3125
+ into.meetings += 1;
3126
+ if (meeting2.durationMs !== null) {
3127
+ into.ms += Math.max(0, meeting2.durationMs);
3128
+ into.timed += 1;
3129
+ }
3130
+ if (meeting2.transcribed)
3131
+ into.transcripts += 1;
3132
+ }, "add");
3133
+ const total = { ...sum(), name: null };
3134
+ const groups = /* @__PURE__ */ new Map();
3135
+ for (const meeting2 of meetings) {
3136
+ add(total, meeting2);
3137
+ const key = by === "series" ? meeting2.seriesKey === null ? NO_SERIES : `series:${meeting2.seriesKey}` : meeting2.startedAt === null ? null : by === "day" ? dayKey(meeting2.startedAt, format) : weekStart(meeting2.startedAt, format);
3138
+ if (key === null)
3139
+ continue;
3140
+ const group = groups.get(key) ?? { ...sum(), name: by === "series" ? meeting2.seriesTitle : null };
3141
+ add(group, meeting2);
3142
+ groups.set(key, group);
3143
+ }
3144
+ const ordered = [...groups.entries()].sort(([a, one], [b, other]) => by === "series" ? other.ms - one.ms || other.meetings - one.meetings || a.localeCompare(b) : b.localeCompare(a));
3145
+ const kept = ordered.slice(0, limit);
3146
+ if (by !== "series")
3147
+ kept.reverse();
3148
+ const counted = /* @__PURE__ */ __name(({ meetings: count7, ms, timed, transcripts }) => ({
3149
+ meetings: count7,
3150
+ minutes: minutesOf(ms),
3151
+ meanMinutes: meanOf(ms, timed),
3152
+ transcripts
3153
+ }), "counted");
3154
+ return {
3155
+ by,
3156
+ timeZone: zone,
3157
+ ...counted(total),
3158
+ rows: kept.map(([key, group]) => ({ key, name: group.name, ...counted(group) })),
3159
+ hasMore: ordered.length > limit
3160
+ };
3161
+ }, "aggregateMeetingCounts");
2810
3162
  var UNKNOWN_SPEAKER = "unknown";
2811
3163
  var speakerOf = /* @__PURE__ */ __name((row) => row.personId !== null ? { key: `person:${row.personId}`, name: row.personName ?? row.identityName ?? row.speakerName } : row.identityId !== null ? { key: `identity:${row.identityId}`, name: row.identityName ?? row.speakerName } : row.speakerName?.trim() ? { key: `name:${row.speakerName.trim().toLowerCase()}`, name: row.speakerName.trim() } : { key: UNKNOWN_SPEAKER, name: null }, "speakerOf");
2812
3164
  var aggregateMeetingStats = /* @__PURE__ */ __name((rows, timeZone) => {
2813
3165
  const zone = zoneOf(timeZone);
2814
- const format = new Intl.DateTimeFormat("en-US", {
2815
- timeZone: zone,
2816
- year: "numeric",
2817
- month: "2-digit",
2818
- day: "2-digit",
2819
- weekday: "short"
2820
- });
3166
+ const format = zoneFormat(zone);
2821
3167
  const speakers = /* @__PURE__ */ new Map();
2822
3168
  const weeks = /* @__PURE__ */ new Map();
2823
3169
  const meetings = /* @__PURE__ */ new Set();
@@ -2870,31 +3216,176 @@ var aggregateMeetingStats = /* @__PURE__ */ __name((rows, timeZone) => {
2870
3216
  };
2871
3217
  }, "aggregateMeetingStats");
2872
3218
 
2873
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/tasks/model.js
3219
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/domain/money.js
3220
+ var CURRENCY_SCALES = {
3221
+ AED: 2,
3222
+ AMD: 2,
3223
+ AUD: 2,
3224
+ BHD: 3,
3225
+ BYN: 2,
3226
+ CAD: 2,
3227
+ CHF: 2,
3228
+ CLP: 0,
3229
+ CNY: 2,
3230
+ CZK: 2,
3231
+ DKK: 2,
3232
+ EUR: 2,
3233
+ GBP: 2,
3234
+ GEL: 2,
3235
+ HUF: 2,
3236
+ ILS: 2,
3237
+ INR: 2,
3238
+ ISK: 0,
3239
+ JPY: 0,
3240
+ KGS: 2,
3241
+ KRW: 0,
3242
+ KWD: 3,
3243
+ KZT: 2,
3244
+ NOK: 2,
3245
+ PLN: 2,
3246
+ RSD: 2,
3247
+ RUB: 2,
3248
+ SEK: 2,
3249
+ THB: 2,
3250
+ TRY: 2,
3251
+ UAH: 2,
3252
+ USD: 2,
3253
+ UZS: 2,
3254
+ VND: 0
3255
+ };
3256
+ var refuse = /* @__PURE__ */ __name((message, reason) => {
3257
+ throw new CliError("validation_error", message, { reason });
3258
+ }, "refuse");
3259
+ var DECIMAL = /^(\d{1,15})(?:\.(\d+))?$/;
3260
+ var parseDecimal = /* @__PURE__ */ __name((text6, scale) => {
3261
+ const match = DECIMAL.exec(text6.trim());
3262
+ if (!match || (match[2] ?? "").length > scale)
3263
+ return void 0;
3264
+ return BigInt(`${match[1]}${(match[2] ?? "").padEnd(scale, "0")}`);
3265
+ }, "parseDecimal");
3266
+ var formatDecimal = /* @__PURE__ */ __name((units, scale) => {
3267
+ const digits = BigInt(units).toString().padStart(scale + 1, "0");
3268
+ return scale === 0 ? digits : `${digits.slice(0, -scale)}.${digits.slice(-scale)}`;
3269
+ }, "formatDecimal");
3270
+ var groupDigits = /* @__PURE__ */ __name((decimal) => {
3271
+ const [whole = "0", fraction] = decimal.split(".");
3272
+ const grouped2 = whole.replace(/\B(?=(\d{3})+(?!\d))/g, " ");
3273
+ return fraction === void 0 ? grouped2 : `${grouped2}.${fraction}`;
3274
+ }, "groupDigits");
3275
+ var currencyOf = /* @__PURE__ */ __name((text6) => {
3276
+ const code = typeof text6 === "string" ? text6.trim().toUpperCase() : "";
3277
+ if (CURRENCY_SCALES[code] === void 0)
3278
+ return refuse(`${typeof text6 === "string" && text6.trim() ? text6.trim() : "an empty currency"} is not a currency the store keeps; use one of ${Object.keys(CURRENCY_SCALES).join(", ")}`, "money.currency");
3279
+ return code;
3280
+ }, "currencyOf");
3281
+ var scaleOf = /* @__PURE__ */ __name((currency) => CURRENCY_SCALES[currencyOf(currency)], "scaleOf");
3282
+ var minorUnits = /* @__PURE__ */ __name((amount, currency, what = "an amount") => {
3283
+ const scale = scaleOf(currency);
3284
+ const units = typeof amount === "string" ? parseDecimal(amount, scale) : void 0;
3285
+ if (units === void 0 || units > BigInt(Number.MAX_SAFE_INTEGER))
3286
+ return refuse(`${what} is a decimal string with at most ${scale} decimal${scale === 1 ? "" : "s"} for ${currency}, such as "${formatDecimal(5e3 * 10 ** scale, scale)}"`, "money.amount");
3287
+ return Number(units);
3288
+ }, "minorUnits");
3289
+ var moneyOf = /* @__PURE__ */ __name((units, currency) => ({
3290
+ amount: formatDecimal(units, scaleOf(currency)),
3291
+ currency
3292
+ }), "moneyOf");
3293
+ var moneyLabel = /* @__PURE__ */ __name((units, currency) => `${groupDigits(formatDecimal(units, scaleOf(currency)))} ${currency}`, "moneyLabel");
3294
+ var QUANTITY_SCALE = 3;
3295
+ var quantityOf = /* @__PURE__ */ __name((text6) => {
3296
+ const thousandths = typeof text6 === "string" ? parseDecimal(text6, QUANTITY_SCALE) : void 0;
3297
+ if (thousandths === void 0 || thousandths === 0n)
3298
+ return refuse('a quantity is a decimal string above 0 with at most 3 decimals, such as "1.5"', "money.quantity");
3299
+ const plain = formatDecimal(thousandths, QUANTITY_SCALE).replace(/\.?0+$/, "");
3300
+ return { text: plain, thousandths };
3301
+ }, "quantityOf");
3302
+ var lineUnits = /* @__PURE__ */ __name((thousandths, unitPrice) => Number((thousandths * BigInt(unitPrice) + 500n) / 1000n), "lineUnits");
3303
+
3304
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/domain/finance.js
3305
+ var INVOICE_DIRECTIONS = ["receivable", "payable"];
3306
+ var INVOICE_STATUSES = ["draft", "issued", "partly_paid", "paid", "void"];
3307
+ var MONEY_DIRECTIONS = ["in", "out"];
3308
+ var FINANCE_REVIEWS = ["proposed", "confirmed", "rejected"];
3309
+ var settledStatus = /* @__PURE__ */ __name((current, total, paid) => {
3310
+ if (current === "draft" || current === "void")
3311
+ return current;
3312
+ if (paid <= 0)
3313
+ return "issued";
3314
+ return paid < total ? "partly_paid" : "paid";
3315
+ }, "settledStatus");
3316
+ var dayMonth = /* @__PURE__ */ __name((date) => date === null ? null : `${date.slice(8, 10)}.${date.slice(5, 7)}`, "dayMonth");
3317
+ var notes = /* @__PURE__ */ __name((...words2) => {
3318
+ const kept = words2.filter((word) => word !== null);
3319
+ return kept.length === 0 ? "" : ` (${kept.join(", ")})`;
3320
+ }, "notes");
3321
+ var invoiceLine = /* @__PURE__ */ __name((invoice) => {
3322
+ const party = invoice.counterpartyName === null ? "" : `${invoice.direction === "receivable" ? " to" : " from"} ${invoice.counterpartyName}`;
3323
+ const due = invoice.dueDate === null ? "" : `, due ${dayMonth(invoice.dueDate)}`;
3324
+ return `${invoice.number ?? `#${invoice.id}`} \xB7 ${moneyLabel(invoice.total, invoice.currency)}${party}${due}` + notes(invoice.status.replace("_", " "), invoice.review === "confirmed" ? null : invoice.review);
3325
+ }, "invoiceLine");
3326
+ var paymentLine = /* @__PURE__ */ __name((payment) => {
3327
+ const party = payment.partyName === null ? "" : `${payment.direction === "in" ? " from" : " to"} ${payment.partyName}`;
3328
+ return `${moneyLabel(payment.amount, payment.currency)}${party}, ${dayMonth(payment.date)}` + notes(payment.review === "confirmed" ? null : payment.review);
3329
+ }, "paymentLine");
3330
+ var invoiceTitle = /* @__PURE__ */ __name((invoice) => `Invoice ${invoiceLine(invoice)}`, "invoiceTitle");
3331
+ var paymentEntryTitle = /* @__PURE__ */ __name((payment) => `Payment \xB7 ${paymentLine(payment)}`, "paymentEntryTitle");
3332
+
3333
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/tasks/model.js
2874
3334
  var TASK_KINDS = ["question", "request", "mention", "promise"];
2875
- var TASK_STATES = ["open", "done", "dismissed"];
3335
+ var TASK_STATES = ["open", "todo", "in_progress", "done", "dismissed"];
3336
+ var CLOSED_STATES = ["done", "dismissed"];
2876
3337
  var TASK_ORIGINS = ["rule", "agent", "owner"];
2877
3338
  var TASK_VERDICTS = ["useful", "not_useful"];
3339
+ var isClosedState = /* @__PURE__ */ __name((state) => CLOSED_STATES.includes(state), "isClosedState");
2878
3340
  function closeTask(task, state, by, at, reason) {
2879
- if (task.state !== "open")
3341
+ if (isClosedState(task.state))
2880
3342
  throw new CliError("validation_error", `task ${task.id} is already ${task.state}`, { reason: "task.closed" });
2881
3343
  const { claimedBy: _by, claimedUntil: _until, ...unclaimed } = task;
2882
3344
  return { ...unclaimed, state, closedAt: at, closedBy: by, ...reason === void 0 ? {} : { reason } };
2883
3345
  }
2884
3346
  __name(closeTask, "closeTask");
2885
3347
 
2886
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/tasks/store.js
3348
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/tasks/store.js
2887
3349
  function matches2(task, filter) {
2888
3350
  return (filter.account === void 0 || task.account === filter.account) && (filter.state === void 0 || task.state === filter.state) && (filter.group === void 0 || task.group === filter.group) && (filter.kind === void 0 || task.kind === filter.kind) && (filter.createdBefore === void 0 || task.createdAt < filter.createdBefore);
2889
3351
  }
2890
3352
  __name(matches2, "matches");
2891
3353
 
2892
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/tasks/service.js
3354
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/tasks/priority.js
3355
+ var PRIORITY_LABELS = ["low", "medium", "high", "critical"];
3356
+ var MIDDLE = { low: 0.125, medium: 0.375, high: 0.625, critical: 0.875 };
3357
+ var LEGACY_PRIORITY_SCORES = [0.875, 0.625, 0.375, 0.1875, 0.0625];
3358
+ var priorityLabel = /* @__PURE__ */ __name((score) => score === null ? null : PRIORITY_LABELS[Math.min(3, Math.max(0, Math.floor(score * 4)))], "priorityLabel");
3359
+ var priorityBand = /* @__PURE__ */ __name((label) => {
3360
+ const at = PRIORITY_LABELS.indexOf(label);
3361
+ return { from: at / 4, to: (at + 1) / 4 };
3362
+ }, "priorityBand");
3363
+ var legacyPriority = /* @__PURE__ */ __name((score) => score === null ? null : score < 0.125 ? 4 : 3 - PRIORITY_LABELS.indexOf(priorityLabel(score)), "legacyPriority");
3364
+ var checkedScore = /* @__PURE__ */ __name((score) => {
3365
+ if (!Number.isFinite(score) || score < 0 || score > 1)
3366
+ throw new CliError("validation_error", "a priority score is 0 to 1");
3367
+ return score;
3368
+ }, "checkedScore");
3369
+ var priorityOf = /* @__PURE__ */ __name((value) => {
3370
+ const word = value.trim().toLowerCase();
3371
+ if (word === "none")
3372
+ return null;
3373
+ if (PRIORITY_LABELS.includes(word))
3374
+ return MIDDLE[word];
3375
+ if (/^[0-4]$/.test(word))
3376
+ return LEGACY_PRIORITY_SCORES[Number(word)];
3377
+ if (/^(0?\.\d+|[01]\.\d*)$/.test(word) && Number(word) <= 1)
3378
+ return Number(word);
3379
+ throw new CliError("validation_error", `a priority is ${PRIORITY_LABELS.join(", ")}, none, or a score from 0.0 to 1.0 with its decimal point; 0 (urgent) \u2026 4 (low) still work as critical, high, medium, low, low`);
3380
+ }, "priorityOf");
3381
+ var priorityOption = /* @__PURE__ */ __name((value) => priorityOf(value) ?? "none", "priorityOption");
3382
+
3383
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/tasks/service.js
2893
3384
  function createTaskService({ store, now = /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "now"), newId = /* @__PURE__ */ __name(() => crypto.randomUUID(), "newId") }) {
2894
- async function find(id3) {
2895
- const task = await store.get(id3);
3385
+ async function find(id4) {
3386
+ const task = await store.get(id4);
2896
3387
  if (!task)
2897
- throw new CliError("not_found", `no task ${id3}`);
3388
+ throw new CliError("not_found", `no task ${id4}`);
2898
3389
  return task;
2899
3390
  }
2900
3391
  __name(find, "find");
@@ -2916,8 +3407,8 @@ function createTaskService({ store, now = /* @__PURE__ */ __name(() => /* @__PUR
2916
3407
  return { task, created: true };
2917
3408
  return { task, created: true, review: await store.reviewDuplicates(task.id) };
2918
3409
  },
2919
- async close(id3, { as, by, reason }) {
2920
- const task = closeTask(await find(id3), as, by, now(), reason);
3410
+ async close(id4, { as, by, reason }) {
3411
+ const task = closeTask(await find(id4), as, by, now(), reason);
2921
3412
  await store.update(task);
2922
3413
  return task;
2923
3414
  },
@@ -2927,7 +3418,7 @@ function createTaskService({ store, now = /* @__PURE__ */ __name(() => /* @__PUR
2927
3418
  for (const task of await store.list(filter))
2928
3419
  byGroup.set(task.group, [...byGroup.get(task.group) ?? [], task]);
2929
3420
  return [...byGroup].map(([group, tasks]) => {
2930
- const open = tasks.filter((task) => task.state === "open");
3421
+ const open = tasks.filter((task) => !isClosedState(task.state));
2931
3422
  const closeMs = tasks.flatMap((task) => task.closedAt ? [task.closedAt.getTime() - task.createdAt.getTime()] : []);
2932
3423
  const oldestOpenAt = open.map((task) => task.createdAt).sort((a, b) => a.getTime() - b.getTime())[0];
2933
3424
  return {
@@ -2949,16 +3440,25 @@ function median(values) {
2949
3440
  }
2950
3441
  __name(median, "median");
2951
3442
 
2952
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/domain/knowledge.js
2953
- var FACT_TYPES = ["fact", "statement", "question", "decision", "promise"];
2954
- var FACT_STATUSES = ["proposed", "accepted", "superseded", "reversed"];
3443
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/domain/knowledge.js
3444
+ var FACT_STATUSES = ["proposed", "accepted", "superseded", "reversed", "rejected"];
2955
3445
  var MEMORY_KINDS = ["summary", "digest", "preference"];
2956
3446
  var MEMORY_STATUSES = ["proposed", "confirmed", "stale", "superseded"];
2957
3447
  var MEMORY_SCOPES = ["personal", "work"];
2958
3448
  var WORK_TASK_TYPES = ["bug", "feature", "chore"];
2959
3449
  var TASK_TYPES2 = [...WORK_TASK_TYPES, ...TASK_KINDS];
2960
3450
 
2961
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/store/sqlite/link-kinds.js
3451
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/domain/orders.js
3452
+ var ORDER_STATUSES = ["placed", "shipped", "delivered", "cancelled", "returned"];
3453
+ var ORDER_PURPOSES = ["personal", "business", "client", "other"];
3454
+ var orderLine = /* @__PURE__ */ __name((order) => {
3455
+ const money = order.total === null || order.currency === null ? "" : `, ${moneyLabel(order.total, order.currency)}`;
3456
+ const notes2 = [order.status, order.review === "confirmed" ? null : order.review].filter(Boolean).join(", ");
3457
+ return `${order.number ?? `#${order.id}`} \xB7 ${order.supplierName}${money} (${notes2})`;
3458
+ }, "orderLine");
3459
+ var orderTitle = /* @__PURE__ */ __name((order) => `Order ${orderLine(order)}`, "orderTitle");
3460
+
3461
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/store/sqlite/link-kinds.js
2962
3462
  var LINK_KINDS = [
2963
3463
  "links-to",
2964
3464
  "blocked-by",
@@ -2979,7 +3479,7 @@ var LINK_SOURCES = [...LINK_ORIGINS, "calendar"];
2979
3479
  var RELATION_KINDS = ["member-of", "related-to"];
2980
3480
  var linkKind = /* @__PURE__ */ __name((kind) => `'${kind}'`, "linkKind");
2981
3481
 
2982
- // node_modules/.pnpm/@wirecat+cli-core@0.495.0_@wirecat+cli-base@0.65.0_commander@15.0.0_esbuild@0.28.2_type_24cca5e5c8b0984f2f26e7d1ba6b6d47/node_modules/@wirecat/cli-core/dist/domain/tags.js
3482
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/domain/tags.js
2983
3483
  var TAG_TYPES = ["chat", "contact", "message", "task"];
2984
3484
  var TAG = /^[a-z0-9-]{1,32}$/;
2985
3485
  var tagOf = /* @__PURE__ */ __name((value) => {
@@ -2993,14 +3493,68 @@ var normalizeTag = /* @__PURE__ */ __name((value) => {
2993
3493
  return tag;
2994
3494
  }, "normalizeTag");
2995
3495
 
3496
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/entities/fields.js
3497
+ var text5 = string();
3498
+ var id3 = pipe(string(), minLength(1));
3499
+ var time = isoTime;
3500
+ var zonedTime = pipe(string(), isoTimestamp("an ISO 8601 time with a zone"));
3501
+ var count6 = pipe(number(), integer(), minValue(0));
3502
+ var untrusted = optional(array(text5));
3503
+ var providerMetadata = optional(record(string(), unknown()));
3504
+ var evidenceSource = strictObject({
3505
+ ref: nullable(reference),
3506
+ kind: text5,
3507
+ title: nullable(text5),
3508
+ sender: nullable(text5),
3509
+ at: nullable(time),
3510
+ excerpt: nullable(text5),
3511
+ tool: nullable(text5),
3512
+ missing: boolean()
3513
+ });
3514
+ var author = strictObject({
3515
+ type: picklist(["person", "bot"]),
3516
+ id: id3,
3517
+ name: nullable(text5)
3518
+ });
3519
+
3520
+ // node_modules/.pnpm/@wirecat+cli-core@0.584.0_@wirecat+cli-base@0.77.1_commander@15.0.0_esbuild@0.28.2_type_ab8c0b68b8b4768d5b87d6e249ef10da/node_modules/@wirecat/cli-core/dist/entities/knowledge-lists.js
3521
+ var organization = strictObject({
3522
+ id: id3,
3523
+ ref: reference,
3524
+ kind: picklist(["company", "team", "family", "community"]),
3525
+ name: text5,
3526
+ scope: picklist(["personal", "work"]),
3527
+ created_at: time
3528
+ });
3529
+ var project = strictObject({
3530
+ id: id3,
3531
+ ref: reference,
3532
+ key: text5,
3533
+ name: text5,
3534
+ kind: picklist(["project", "inbox"]),
3535
+ type: picklist(["work", "client", "personal", "oss", "other"]),
3536
+ organization_id: nullable(id3),
3537
+ scope: picklist(["personal", "work"]),
3538
+ created_at: time
3539
+ });
3540
+ var reminder = strictObject({
3541
+ id: id3,
3542
+ task: text5,
3543
+ due_at: time,
3544
+ timezone: text5,
3545
+ state: picklist(["pending", "leased", "delivered", "cancelled"]),
3546
+ revision: number(),
3547
+ receipt: nullable(text5)
3548
+ });
3549
+
2996
3550
  export {
2997
3551
  QUERY_LIMITS,
2998
3552
  queryAstSchema,
2999
3553
  queryError,
3000
3554
  walkQuery,
3001
3555
  timezoneOf,
3556
+ dayBoundary,
3002
3557
  zonedMoment,
3003
- dateEndpoint,
3004
3558
  dateRange,
3005
3559
  evaluate,
3006
3560
  FIELD_TYPES,
@@ -3008,6 +3562,7 @@ export {
3008
3562
  QUERY_BACKENDS,
3009
3563
  queryFieldsOf,
3010
3564
  fieldsHelp,
3565
+ queryDescription,
3011
3566
  parseLucene,
3012
3567
  implicitTextTerms,
3013
3568
  validateQuery,
@@ -3044,16 +3599,28 @@ export {
3044
3599
  meetingTranscriptAnswer,
3045
3600
  meetingSummaryAnswer,
3046
3601
  exportMeeting,
3047
- validateMeetingChange,
3602
+ FACT_TYPES,
3603
+ validatePayment,
3604
+ paymentTitle,
3605
+ meetingTimestamp,
3606
+ findingText,
3048
3607
  findingHash,
3608
+ findingFields,
3609
+ findingNeeds,
3610
+ validEvidence,
3611
+ findingId,
3612
+ validateFinding,
3613
+ validateBatch,
3049
3614
  validateFindings,
3050
3615
  findingFingerprint,
3051
3616
  MEETING_FINDINGS_KIND,
3052
3617
  validateMeetingFindings,
3053
3618
  meetingFindingFingerprint,
3054
3619
  parseMeetingQuery,
3620
+ transcriptLanguage,
3055
3621
  importFiles,
3056
3622
  CHAT_MESSAGES_READ,
3623
+ validateMeetingChange,
3057
3624
  validateMeetingPassage,
3058
3625
  validateMeetingPreparationContext,
3059
3626
  meetingProjectEvidence,
@@ -3067,6 +3634,7 @@ export {
3067
3634
  meetingLink,
3068
3635
  meetingSpeaker,
3069
3636
  meetingStats,
3637
+ meetingCounts,
3070
3638
  meetingParticipants,
3071
3639
  meetingPassage,
3072
3640
  event,
@@ -3078,20 +3646,61 @@ export {
3078
3646
  SAVE_HELP,
3079
3647
  validateMeetingSeriesHistory,
3080
3648
  validateMeetingSeriesInventoryCursor,
3649
+ aggregateMeetingCounts,
3081
3650
  aggregateMeetingStats,
3651
+ text5 as text,
3652
+ id3 as id,
3653
+ time,
3654
+ zonedTime,
3655
+ count6 as count,
3656
+ untrusted,
3657
+ providerMetadata,
3658
+ evidenceSource,
3659
+ author,
3660
+ parseDecimal,
3661
+ formatDecimal,
3662
+ currencyOf,
3663
+ scaleOf,
3664
+ minorUnits,
3665
+ moneyOf,
3666
+ moneyLabel,
3667
+ quantityOf,
3668
+ lineUnits,
3669
+ INVOICE_DIRECTIONS,
3670
+ INVOICE_STATUSES,
3671
+ MONEY_DIRECTIONS,
3672
+ FINANCE_REVIEWS,
3673
+ settledStatus,
3674
+ invoiceLine,
3675
+ paymentLine,
3676
+ invoiceTitle,
3677
+ paymentEntryTitle,
3082
3678
  TASK_KINDS,
3083
3679
  TASK_STATES,
3084
3680
  TASK_ORIGINS,
3085
3681
  TASK_VERDICTS,
3682
+ isClosedState,
3683
+ PRIORITY_LABELS,
3684
+ priorityLabel,
3685
+ priorityBand,
3686
+ legacyPriority,
3687
+ checkedScore,
3688
+ priorityOption,
3086
3689
  createTaskService,
3087
3690
  matches2 as matches,
3088
- FACT_TYPES,
3089
3691
  FACT_STATUSES,
3090
3692
  MEMORY_KINDS,
3091
3693
  MEMORY_STATUSES,
3092
3694
  MEMORY_SCOPES,
3093
3695
  WORK_TASK_TYPES,
3094
3696
  TASK_TYPES2 as TASK_TYPES,
3697
+ ORDER_STATUSES,
3698
+ ORDER_PURPOSES,
3699
+ orderLine,
3700
+ orderTitle,
3701
+ organization,
3702
+ project,
3703
+ reminder,
3095
3704
  LINK_KINDS,
3096
3705
  LINK_ORIGINS,
3097
3706
  LINK_SOURCES,