@songsid/agend 2.3.0-beta.19 → 2.3.0-beta.20

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 (81) hide show
  1. package/dist/agent-cli-instructions.md +4 -0
  2. package/dist/agent-cli.js +25 -0
  3. package/dist/agent-cli.js.map +1 -1
  4. package/dist/channel/mcp-tools.js +2 -1
  5. package/dist/channel/mcp-tools.js.map +1 -1
  6. package/dist/config-validator.js +19 -1
  7. package/dist/config-validator.js.map +1 -1
  8. package/dist/cross-instance-notice.d.ts +7 -0
  9. package/dist/cross-instance-notice.js +10 -0
  10. package/dist/cross-instance-notice.js.map +1 -1
  11. package/dist/daemon.js +4 -0
  12. package/dist/daemon.js.map +1 -1
  13. package/dist/delivery-outbox.js +5 -0
  14. package/dist/delivery-outbox.js.map +1 -1
  15. package/dist/fleet-manager.d.ts +26 -0
  16. package/dist/fleet-manager.js +115 -14
  17. package/dist/fleet-manager.js.map +1 -1
  18. package/dist/general-knowledge/skills/scheduling/SKILL.md +4 -0
  19. package/dist/general-knowledge/skills/web-dashboard/SKILL.md +25 -1
  20. package/dist/instance-config-impact.js +4 -0
  21. package/dist/instance-config-impact.js.map +1 -1
  22. package/dist/log-steps.d.ts +1 -0
  23. package/dist/log-steps.js +15 -0
  24. package/dist/log-steps.js.map +1 -1
  25. package/dist/outbound-handlers.d.ts +3 -0
  26. package/dist/outbound-handlers.js +20 -4
  27. package/dist/outbound-handlers.js.map +1 -1
  28. package/dist/outbound-schemas.d.ts +33 -0
  29. package/dist/outbound-schemas.js +25 -8
  30. package/dist/outbound-schemas.js.map +1 -1
  31. package/dist/public-web-gateway.js +5 -2
  32. package/dist/public-web-gateway.js.map +1 -1
  33. package/dist/scheduler/db.d.ts +40 -13
  34. package/dist/scheduler/db.js +123 -89
  35. package/dist/scheduler/db.js.map +1 -1
  36. package/dist/scheduler/task-board-text.d.ts +26 -0
  37. package/dist/scheduler/task-board-text.js +135 -0
  38. package/dist/scheduler/task-board-text.js.map +1 -0
  39. package/dist/scheduler/task-board.d.ts +650 -0
  40. package/dist/scheduler/task-board.js +1938 -0
  41. package/dist/scheduler/task-board.js.map +1 -0
  42. package/dist/scheduler/types.d.ts +6 -1
  43. package/dist/search/search-docs.d.ts +58 -0
  44. package/dist/search/search-docs.js +63 -0
  45. package/dist/search/search-docs.js.map +1 -0
  46. package/dist/search/search-index.d.ts +141 -0
  47. package/dist/search/search-index.js +440 -0
  48. package/dist/search/search-index.js.map +1 -0
  49. package/dist/search/search-store.d.ts +122 -0
  50. package/dist/search/search-store.js +236 -0
  51. package/dist/search/search-store.js.map +1 -0
  52. package/dist/search/search-worker.d.ts +1 -0
  53. package/dist/search/search-worker.js +163 -0
  54. package/dist/search/search-worker.js.map +1 -0
  55. package/dist/task-board-tool.d.ts +25 -0
  56. package/dist/task-board-tool.js +154 -0
  57. package/dist/task-board-tool.js.map +1 -0
  58. package/dist/task-board-waker.d.ts +44 -0
  59. package/dist/task-board-waker.js +128 -0
  60. package/dist/task-board-waker.js.map +1 -0
  61. package/dist/types.d.ts +15 -0
  62. package/dist/ui/fleet-task-card.js +436 -0
  63. package/dist/ui/fleet-task-common.js +448 -0
  64. package/dist/ui/fleet-tasks.js +535 -0
  65. package/dist/ui/panel-chat.js +8 -0
  66. package/dist/ui/panel-fleet.js +21 -65
  67. package/dist/ui/search-dialog.js +349 -0
  68. package/dist/ui/shared/app-i18n.js +3 -0
  69. package/dist/ui/shared/app-shell.js +43 -1
  70. package/dist/ui/shared/app-stream.js +2 -1
  71. package/dist/ui/shared/app.css +270 -2
  72. package/dist/ui/shared/app.js +3 -1
  73. package/dist/ui/shared/ui-toast.js +16 -3
  74. package/dist/web-api.d.ts +14 -4
  75. package/dist/web-api.js +408 -10
  76. package/dist/web-api.js.map +1 -1
  77. package/dist/web-chat-history.d.ts +2 -0
  78. package/dist/web-chat-history.js +2 -0
  79. package/dist/web-chat-history.js.map +1 -1
  80. package/dist/workflow-templates/default.md +3 -0
  81. package/package.json +1 -1
@@ -0,0 +1,236 @@
1
+ /**
2
+ * #2293: the global search's index — `search.db`, a derived store of its own (SQLite FTS5, trigram tokenizer).
3
+ *
4
+ * Synchronous (better-sqlite3); it runs in the search worker (search-worker.ts), never on the fleet's loop. Tests use it
5
+ * directly. What is indexed is masked first (maskSecrets, the Log tab's), and only the fields the docs below carry.
6
+ *
7
+ * Queries: every term of 3+ characters is an FTS5 trigram MATCH (a substring, any script — no word breaking needed for
8
+ * Chinese or Japanese); a term of 1–2 characters cannot use a trigram index, so it is an `instr()` filter on rows the
9
+ * other terms or the filters already narrowed. A query of short terms only scans the newest SHORT_SCAN_ROWS rows that
10
+ * match the filters (newest first) and says so (`limited`).
11
+ */
12
+ import Database from "better-sqlite3";
13
+ import { maskOpenSecretTail, maskSecrets } from "../log-steps.js";
14
+ export const SEARCH_SOURCES = ["chat", "xmsg", "task"];
15
+ export const QUERY_MAX_CHARS = 200;
16
+ export const QUERY_MAX_TERMS = 8;
17
+ export const RESULT_MAX = 200;
18
+ export const SHORT_SCAN_ROWS = 5000;
19
+ export const ROW_CAP = 300_000;
20
+ export const TEXT_MAX = 16_000;
21
+ /**
22
+ * Masking reads this much past TEXT_MAX before the text is cut (#2295 review): a secret cut at the edge loses what makes
23
+ * it recognisable (a closing quote), so the cut comes after the mask. One starting in the kept text and shorter than
24
+ * this is masked whole — a private key block is a few KB. A text cut before it got here (the web chat's history keeps
25
+ * 16000 characters) can end inside a quoted secret: its open tail is masked too (maskOpenSecretTail).
26
+ */
27
+ export const MASK_MARGIN = 16_000;
28
+ const SCHEMA_VERSION = "1";
29
+ const SNIPPET_BEFORE = 60, SNIPPET_AFTER = 120;
30
+ /** The terms of a query: whitespace-split, lower-cased, deduplicated; long (3+ characters) and short ones apart. */
31
+ export function parseQuery(q) {
32
+ const terms = [...new Set(String(q ?? "").slice(0, QUERY_MAX_CHARS).toLowerCase().split(/\s+/).filter(Boolean))].slice(0, QUERY_MAX_TERMS);
33
+ const len = (t) => [...t].length;
34
+ return { long: terms.filter(t => len(t) >= 3), short: terms.filter(t => len(t) < 3) };
35
+ }
36
+ /** An FTS5 query that matches `term` as a literal substring (a phrase; its quotes doubled). */
37
+ const phrase = (term) => `"${term.replace(/"/g, '""')}"`;
38
+ /** The sentence around the first hit of any term, and every hit's place in it. */
39
+ export function snippetOf(text, terms) {
40
+ const lower = text.toLowerCase();
41
+ let first = -1;
42
+ for (const t of terms) {
43
+ const i = lower.indexOf(t);
44
+ if (i >= 0 && (first < 0 || i < first))
45
+ first = i;
46
+ }
47
+ const from = first < 0 ? 0 : Math.max(0, first - SNIPPET_BEFORE);
48
+ const to = Math.min(text.length, (first < 0 ? 0 : first) + SNIPPET_AFTER + SNIPPET_BEFORE);
49
+ const lead = from > 0 ? "…" : "", tail = to < text.length ? "…" : "";
50
+ const body = text.slice(from, to).replace(/\s+/g, " ");
51
+ const snippet = lead + body + tail;
52
+ const marks = [];
53
+ const lb = snippet.toLowerCase();
54
+ for (const t of terms)
55
+ for (let i = lb.indexOf(t); i >= 0; i = lb.indexOf(t, i + t.length))
56
+ marks.push([i, i + t.length]);
57
+ marks.sort((a, b) => a[0] - b[0]);
58
+ const merged = [];
59
+ for (const m of marks) {
60
+ const last = merged.at(-1);
61
+ if (last && m[0] <= last[1])
62
+ last[1] = Math.max(last[1], m[1]);
63
+ else
64
+ merged.push([...m]);
65
+ }
66
+ return { snippet, marks: merged };
67
+ }
68
+ export class SearchStore {
69
+ db;
70
+ constructor(path) {
71
+ this.db = new Database(path);
72
+ this.db.pragma("journal_mode = WAL");
73
+ this.db.pragma("synchronous = NORMAL");
74
+ this.db.pragma("busy_timeout = 1000");
75
+ this.db.exec(`
76
+ CREATE TABLE IF NOT EXISTS meta(k TEXT PRIMARY KEY, v TEXT NOT NULL);
77
+ CREATE TABLE IF NOT EXISTS docs(
78
+ rowid INTEGER PRIMARY KEY, key TEXT NOT NULL UNIQUE, source TEXT NOT NULL, instance TEXT NOT NULL, peer TEXT,
79
+ sender TEXT NOT NULL, role TEXT, mine TEXT, ts INTEGER NOT NULL, ref TEXT NOT NULL, text TEXT NOT NULL);
80
+ CREATE INDEX IF NOT EXISTS docs_ts ON docs(ts);
81
+ CREATE INDEX IF NOT EXISTS docs_instance_ts ON docs(instance, ts);
82
+ CREATE VIRTUAL TABLE IF NOT EXISTS docs_fts USING fts5(text, sender, content='docs', content_rowid='rowid', tokenize='trigram');
83
+ CREATE TRIGGER IF NOT EXISTS docs_ai AFTER INSERT ON docs BEGIN
84
+ INSERT INTO docs_fts(rowid, text, sender) VALUES (new.rowid, new.text, new.sender); END;
85
+ CREATE TRIGGER IF NOT EXISTS docs_ad AFTER DELETE ON docs BEGIN
86
+ INSERT INTO docs_fts(docs_fts, rowid, text, sender) VALUES ('delete', old.rowid, old.text, old.sender); END;
87
+ CREATE TRIGGER IF NOT EXISTS docs_au AFTER UPDATE ON docs BEGIN
88
+ INSERT INTO docs_fts(docs_fts, rowid, text, sender) VALUES ('delete', old.rowid, old.text, old.sender);
89
+ INSERT INTO docs_fts(rowid, text, sender) VALUES (new.rowid, new.text, new.sender); END;`);
90
+ }
91
+ /** Whether this index was built (backfilled) under the current schema; false on a new or older one. */
92
+ built() {
93
+ const row = this.db.prepare("SELECT v FROM meta WHERE k = 'schema'").get();
94
+ return row?.v === SCHEMA_VERSION && !!this.db.prepare("SELECT v FROM meta WHERE k = 'built_at'").get();
95
+ }
96
+ /** Marks a finished backfill (a rebuild starts over: everything is replaced or added by key). */
97
+ markBuilt(now) {
98
+ const set = this.db.prepare("INSERT INTO meta(k, v) VALUES (?, ?) ON CONFLICT(k) DO UPDATE SET v = excluded.v");
99
+ this.db.transaction(() => { set.run("schema", SCHEMA_VERSION); set.run("built_at", String(now)); })();
100
+ }
101
+ /** Add or replace docs (by key), in one transaction. Text is masked, one-spaced at its edges and bounded. */
102
+ add(docs) {
103
+ const put = this.db.prepare(`INSERT INTO docs(key, source, instance, peer, sender, role, mine, ts, ref, text)
104
+ VALUES (@key, @source, @instance, @peer, @sender, @role, @mine, @ts, @ref, @text)
105
+ ON CONFLICT(key) DO UPDATE SET source = excluded.source, instance = excluded.instance, peer = excluded.peer,
106
+ sender = excluded.sender, role = excluded.role, mine = excluded.mine, ts = excluded.ts, ref = excluded.ref, text = excluded.text`);
107
+ let n = 0;
108
+ this.db.transaction(() => {
109
+ for (const d of docs) {
110
+ if (!valid(d))
111
+ continue;
112
+ put.run({ key: d.key, source: d.source, instance: d.instance, peer: d.peer ?? null, sender: d.sender.slice(0, 256), role: d.role ?? null,
113
+ mine: d.mine ?? null, ts: Math.trunc(d.ts), ref: JSON.stringify(d.ref ?? {}), text: indexedText(d.text) });
114
+ n++;
115
+ }
116
+ })();
117
+ return n;
118
+ }
119
+ /** An instance's docs go (the instance was deleted). */
120
+ /**
121
+ * An instance removed from the fleet: its chat goes, as the fleet forgets it. Its cross-instance messages and tasks
122
+ * stay — the outbox and the Task Board still hold them, and the other side's view of them is not this instance's.
123
+ */
124
+ removeInstance(instance) {
125
+ return this.db.prepare("DELETE FROM docs WHERE source = 'chat' AND instance = ?").run(instance).changes;
126
+ }
127
+ /** Docs older than `cutoff` go, then the oldest beyond `cap`; in chunks (the caller yields between calls). */
128
+ prune(cutoff, cap = ROW_CAP, chunk = 1000) {
129
+ let removed = this.db.prepare("DELETE FROM docs WHERE rowid IN (SELECT rowid FROM docs WHERE ts < ? ORDER BY ts LIMIT ?)").run(cutoff, chunk).changes;
130
+ if (removed < chunk) {
131
+ const count = this.db.prepare("SELECT count(*) AS n FROM docs").get().n;
132
+ if (count > cap)
133
+ removed += this.db.prepare("DELETE FROM docs WHERE rowid IN (SELECT rowid FROM docs ORDER BY ts LIMIT ?)").run(Math.min(chunk, count - cap)).changes;
134
+ }
135
+ return { removed, more: removed >= chunk };
136
+ }
137
+ count() { return this.db.prepare("SELECT count(*) AS n FROM docs").get().n; }
138
+ /** The newest matches, newest first. */
139
+ search(f) {
140
+ const { long, short } = parseQuery(f.q);
141
+ if (!long.length && !short.length)
142
+ return { hits: [], limited: false };
143
+ const limit = Math.max(1, Math.min(RESULT_MAX, Math.trunc(f.limit ?? 50)));
144
+ const where = [], args = [];
145
+ if (f.instances?.length) {
146
+ const marks = f.instances.map(() => "?").join(",");
147
+ where.push(`(d.instance IN (${marks}) OR (d.source = 'xmsg' AND d.peer IN (${marks})))`);
148
+ args.push(...f.instances, ...f.instances);
149
+ }
150
+ if (f.sources?.length) {
151
+ where.push(`d.source IN (${f.sources.map(() => "?").join(",")})`);
152
+ args.push(...f.sources);
153
+ }
154
+ if (typeof f.since === "number") {
155
+ where.push("d.ts >= ?");
156
+ args.push(f.since);
157
+ }
158
+ if (typeof f.until === "number") {
159
+ where.push("d.ts < ?");
160
+ args.push(f.until);
161
+ }
162
+ if (f.mine?.length) {
163
+ where.push(`d.mine IN (${f.mine.map(() => "?").join(",")})`);
164
+ args.push(...f.mine);
165
+ }
166
+ if (f.hidden?.length) {
167
+ const marks = f.hidden.map(() => "?").join(",");
168
+ where.push(`NOT (d.source = 'xmsg' AND (d.instance IN (${marks}) OR d.peer IN (${marks})))`);
169
+ args.push(...f.hidden, ...f.hidden);
170
+ }
171
+ if (f.xmsgAmong) {
172
+ const marks = f.xmsgAmong.map(() => "?").join(",");
173
+ where.push(f.xmsgAmong.length ? `(d.source <> 'xmsg' OR (d.instance IN (${marks}) AND d.peer IN (${marks})))` : "d.source <> 'xmsg'");
174
+ args.push(...f.xmsgAmong, ...f.xmsgAmong);
175
+ }
176
+ const shortWhere = short.map(() => "instr(lower(d.text || ' ' || d.sender), ?) > 0");
177
+ let rows, limited = false;
178
+ if (long.length) {
179
+ const sql = `SELECT d.* FROM docs_fts JOIN docs d ON d.rowid = docs_fts.rowid WHERE docs_fts MATCH ?
180
+ ${[...where, ...shortWhere].map(w => `AND ${w}`).join(" ")} ORDER BY d.ts DESC, d.rowid DESC LIMIT ?`;
181
+ rows = this.db.prepare(sql).all(long.map(phrase).join(" "), ...args, ...short, limit);
182
+ }
183
+ else {
184
+ // Short terms only: the newest SHORT_SCAN_ROWS rows the filters allow, scanned.
185
+ const scan = `SELECT * FROM docs d ${where.length ? `WHERE ${where.join(" AND ")}` : ""} ORDER BY d.ts DESC, d.rowid DESC LIMIT ?`;
186
+ const sql = `SELECT * FROM (${scan}) AS d WHERE ${shortWhere.join(" AND ")} ORDER BY d.ts DESC, d.rowid DESC LIMIT ?`;
187
+ rows = this.db.prepare(sql).all(...args, SHORT_SCAN_ROWS, ...short, limit);
188
+ const scanned = this.db.prepare(`SELECT count(*) AS n FROM (${scan}) AS d`).get(...args, SHORT_SCAN_ROWS).n;
189
+ limited = scanned >= SHORT_SCAN_ROWS;
190
+ }
191
+ const terms = [...long, ...short];
192
+ return { hits: rows.map(r => ({ ...hitOf(r), ...snippetOf(r.text, terms) })), limited };
193
+ }
194
+ /** One doc by key, with (for a chat message) up to `around` messages of its chat before and after it. */
195
+ context(key, around = 8) {
196
+ const row = this.db.prepare("SELECT * FROM docs WHERE key = ?").get(key);
197
+ if (!row)
198
+ return null;
199
+ const full = (r) => ({ ...hitOf(r), snippet: "", marks: [], text: r.text });
200
+ if (row.source !== "chat")
201
+ return { doc: full(row), before: [], after: [] };
202
+ const before = this.db.prepare(`SELECT * FROM docs WHERE source = 'chat' AND instance = ? AND (ts < ? OR (ts = ? AND rowid < ?))
203
+ ORDER BY ts DESC, rowid DESC LIMIT ?`).all(row.instance, row.ts, row.ts, row.rowid, around).reverse();
204
+ const after = this.db.prepare(`SELECT * FROM docs WHERE source = 'chat' AND instance = ? AND (ts > ? OR (ts = ? AND rowid > ?))
205
+ ORDER BY ts, rowid LIMIT ?`).all(row.instance, row.ts, row.ts, row.rowid, around);
206
+ return { doc: full(row), before: before.map(full), after: after.map(full) };
207
+ }
208
+ close() { try {
209
+ this.db.close();
210
+ }
211
+ catch { /* already */ } }
212
+ }
213
+ /**
214
+ * What the index stores of a text: masked, then cut. An open tail is masked first too — the end of what arrived may
215
+ * already be a cut (the history's), and the rules for closed values would otherwise take part of its opener (a lone
216
+ * backslash of \" read as a bare value) — and again after the cut to TEXT_MAX.
217
+ */
218
+ function indexedText(text) {
219
+ return maskOpenSecretTail(maskSecrets(maskOpenSecretTail(text.slice(0, TEXT_MAX + MASK_MARGIN))).slice(0, TEXT_MAX)).trim();
220
+ }
221
+ function hitOf(r) {
222
+ let ref = {};
223
+ try {
224
+ const v = JSON.parse(r.ref);
225
+ if (v && typeof v === "object" && !Array.isArray(v))
226
+ ref = v;
227
+ }
228
+ catch { /* {} */ }
229
+ return { key: r.key, source: r.source, instance: r.instance, peer: r.peer, sender: r.sender, role: r.role, ts: r.ts, ref };
230
+ }
231
+ function valid(d) {
232
+ return !!d && typeof d.key === "string" && d.key.length > 0 && d.key.length <= 300 && SEARCH_SOURCES.includes(d.source)
233
+ && typeof d.instance === "string" && d.instance.length > 0 && typeof d.sender === "string" && typeof d.text === "string"
234
+ && typeof d.ts === "number" && Number.isFinite(d.ts) && (d.peer === undefined || typeof d.peer === "string");
235
+ }
236
+ //# sourceMappingURL=search-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-store.js","sourceRoot":"","sources":["../../src/search/search-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGlE,MAAM,CAAC,MAAM,cAAc,GAA4B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAwDhF,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC;AACnC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AACjC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAC9B,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AACpC,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC;AAC/B;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC;AAClC,MAAM,cAAc,GAAG,GAAG,CAAC;AAC3B,MAAM,cAAc,GAAG,EAAE,EAAE,aAAa,GAAG,GAAG,CAAC;AAE/C,oHAAoH;AACpH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;IAC3I,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;AACxF,CAAC;AAED,+FAA+F;AAC/F,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AAEjE,kFAAkF;AAClF,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAwB;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;IACf,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QAAC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;YAAE,KAAK,GAAG,CAAC,CAAC;IAAC,CAAC;IACzG,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,cAAc,CAAC,CAAC;IACjE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,aAAa,GAAG,cAAc,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IACnC,MAAM,KAAK,GAA4B,EAAE,CAAC;IAC1C,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1H,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QAAC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;YAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;;YAAM,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAAC,CAAC;IAChJ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,OAAO,WAAW;IACd,EAAE,CAAoB;IAC9B,YAAY,IAAY;QACtB,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;iGAcgF,CAAC,CAAC;IACjG,CAAC;IAED,uGAAuG;IACvG,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC,GAAG,EAA+B,CAAC;QACxG,OAAO,GAAG,EAAE,CAAC,KAAK,cAAc,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,EAAE,CAAC;IACzG,CAAC;IACD,iGAAiG;IACjG,SAAS,CAAC,GAAW;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,kFAAkF,CAAC,CAAC;QAChH,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxG,CAAC;IAED,6GAA6G;IAC7G,GAAG,CAAC,IAA0B;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;yIAGyG,CAAC,CAAC;QACvI,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YACvB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;oBAAE,SAAS;gBACxB,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI;oBACtI,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC7G,CAAC,EAAE,CAAC;YACN,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QACL,OAAO,CAAC,CAAC;IACX,CAAC;IAED,wDAAwD;IACxD;;;OAGG;IACH,cAAc,CAAC,QAAgB;QAC7B,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,yDAAyD,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;IAC1G,CAAC;IAED,8GAA8G;IAC9G,KAAK,CAAC,MAAc,EAAE,GAAG,GAAG,OAAO,EAAE,KAAK,GAAG,IAAI;QAC/C,IAAI,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,2FAA2F,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC;QACtJ,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;YACpB,MAAM,KAAK,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC;YAC3F,IAAI,KAAK,GAAG,GAAG;gBAAE,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,8EAA8E,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;QACxK,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,IAAI,KAAK,EAAE,CAAC;IAC7C,CAAC;IAED,KAAK,KAAa,OAAQ,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,GAAG,EAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;IAExG,wCAAwC;IACxC,MAAM,CAAC,CAAgB;QACrB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACvE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3E,MAAM,KAAK,GAAa,EAAE,EAAE,IAAI,GAAc,EAAE,CAAC;QACjD,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,mBAAmB,KAAK,0CAA0C,KAAK,KAAK,CAAC,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;QACtI,CAAC;QACD,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;QAAC,CAAC;QACtH,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QACjF,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QAChF,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;YAAC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAC3G,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChD,KAAK,CAAC,IAAI,CAAC,8CAA8C,KAAK,mBAAmB,KAAK,KAAK,CAAC,CAAC;YAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;QACpI,CAAC;QACD,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,0CAA0C,KAAK,oBAAoB,KAAK,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;YACtI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,UAAU,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,gDAAgD,CAAC,CAAC;QACrF,IAAI,IAAW,EAAE,OAAO,GAAG,KAAK,CAAC;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG;UACR,CAAC,GAAG,KAAK,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,2CAA2C,CAAC;YACxG,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,EAAE,KAAK,CAAU,CAAC;QACjG,CAAC;aAAM,CAAC;YACN,gFAAgF;YAChF,MAAM,IAAI,GAAG,wBAAwB,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,2CAA2C,CAAC;YACnI,MAAM,GAAG,GAAG,kBAAkB,IAAI,gBAAgB,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,2CAA2C,CAAC;YACtH,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,eAAe,EAAE,GAAG,KAAK,EAAE,KAAK,CAAU,CAAC;YACpF,MAAM,OAAO,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,8BAA8B,IAAI,QAAQ,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,eAAe,CAAmB,CAAC,CAAC,CAAC;YAC/H,OAAO,GAAG,OAAO,IAAI,eAAe,CAAC;QACvC,CAAC;QACD,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;QAClC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1F,CAAC;IAED,yGAAyG;IACzG,OAAO,CAAC,GAAW,EAAE,MAAM,GAAG,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,kCAAkC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAoB,CAAC;QAC5F,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QACtB,MAAM,IAAI,GAAG,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAA6B,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5G,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC5E,MAAM,MAAM,GAAI,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;2CACO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,CAAW,CAAC,OAAO,EAAE,CAAC;QAClH,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;iCACD,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,CAAU,CAAC;QAC7F,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9E,CAAC;IAED,KAAK,KAAW,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;CACnE;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,kBAAkB,CAAC,WAAW,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9H,CAAC;AAED,SAAS,KAAK,CAAC,CAAM;IACnB,IAAI,GAAG,GAA4B,EAAE,CAAC;IACtC,IAAI,CAAC;QAAC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAAC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAAE,GAAG,GAAG,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;IACrH,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC;AAC7H,CAAC;AACD,SAAS,KAAK,CAAC,CAAY;IACzB,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;WAClH,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;WACrH,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;AACjH,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,163 @@
1
+ /**
2
+ * #2293: the search index's worker — it alone opens search.db, so no SQLite work of the index runs on the fleet's loop.
3
+ * The fleet posts batches of docs and queries (search-index.ts); this answers queries and says when it is ready and
4
+ * whether the index still needs its backfill. A corrupt file is moved aside (`search.db.corrupt-<stamp>`, with its -wal
5
+ * and -shm) and a fresh one opened — the fleet backfills it; any other failure to open ends the worker (search is then
6
+ * unavailable, the fleet runs on).
7
+ *
8
+ * The backfill of the two sources that live in SQLite is read here too, read-only: the outbox's cross-instance messages
9
+ * (its own retention: 30 days) and the Task Board. A page at a time, yielding between pages, so a query is answered
10
+ * while it runs.
11
+ */
12
+ import { parentPort, workerData } from "node:worker_threads";
13
+ import { existsSync, renameSync } from "node:fs";
14
+ import Database from "better-sqlite3";
15
+ import { classifySqliteOpenError } from "../sqlite-open-errors.js";
16
+ import { SearchStore } from "./search-store.js";
17
+ import { taskDoc, xmsgDoc, xmsgFromOutbox } from "./search-docs.js";
18
+ const path = String(workerData?.path ?? "");
19
+ const port = parentPort;
20
+ let store = null;
21
+ function moveAside() {
22
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
23
+ for (const suffix of ["", "-wal", "-shm"])
24
+ if (existsSync(path + suffix))
25
+ renameSync(path + suffix, `${path}.corrupt-${stamp}${suffix}`);
26
+ }
27
+ function open() {
28
+ try {
29
+ store = new SearchStore(path);
30
+ }
31
+ catch (err) {
32
+ if (classifySqliteOpenError(err) !== "corrupt") {
33
+ port.postMessage({ op: "failed", reason: String(err?.message ?? err) });
34
+ process.exit(0);
35
+ }
36
+ moveAside();
37
+ store = new SearchStore(path);
38
+ }
39
+ port.postMessage({ op: "ready", built: store.built() });
40
+ }
41
+ /** A corrupt file found while working: the same as at open — moved aside, a fresh index, a new backfill. */
42
+ function recover(err) {
43
+ if (classifySqliteOpenError(err) !== "corrupt")
44
+ return false;
45
+ store?.close();
46
+ store = null;
47
+ moveAside();
48
+ open();
49
+ return true;
50
+ }
51
+ const BACKFILL_PAGE = 500;
52
+ const MESSAGE_KINDS = ["fleet_inbound", "steer", "broadcast"];
53
+ const pause = () => new Promise(resolve => setImmediate(resolve));
54
+ function readOnly(file) {
55
+ if (!file || !existsSync(file))
56
+ return null;
57
+ try {
58
+ const db = new Database(file, { readonly: true, fileMustExist: true });
59
+ db.pragma("busy_timeout = 1000");
60
+ return db;
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }
66
+ /** The outbox's cross-instance messages since `cutoff`, then every task: what the fleet recorded before the index. */
67
+ async function backfill(outboxPath, schedulerPath, cutoff) {
68
+ let xmsg = 0, tasks = 0;
69
+ const outbox = readOnly(outboxPath);
70
+ if (outbox)
71
+ try {
72
+ const page = outbox.prepare(`SELECT created_seq AS seq, COALESCE(target_session, target_instance) AS target, created_at AS createdAt, payload_json AS payload, kind
73
+ FROM deliveries WHERE created_seq > ? AND kind IN (${MESSAGE_KINDS.map(() => "?").join(",")}) ORDER BY created_seq LIMIT ?`);
74
+ for (let after = -1;;) {
75
+ const rows = page.all(after, ...MESSAGE_KINDS, BACKFILL_PAGE);
76
+ if (!rows.length || !store)
77
+ break;
78
+ after = rows[rows.length - 1].seq;
79
+ const docs = rows.map(r => xmsgFromOutbox(r.target, r.createdAt, r.payload, r.kind)).map(r => (r ? xmsgDoc(r) : null)).filter(d => d !== null && d.ts >= cutoff);
80
+ xmsg += store.add(docs);
81
+ await pause();
82
+ }
83
+ }
84
+ catch { /* an outbox this can't read: its messages are not found, the rest is */ }
85
+ finally {
86
+ outbox.close();
87
+ }
88
+ const scheduler = readOnly(schedulerPath);
89
+ if (scheduler)
90
+ try {
91
+ const page = scheduler.prepare("SELECT rowid AS rid, id, title, description, result, status, assignee, created_by, created_at, updated_at FROM tasks WHERE rowid > ? ORDER BY rowid LIMIT ?");
92
+ for (let after = -1;;) {
93
+ const rows = page.all(after, BACKFILL_PAGE);
94
+ if (!rows.length || !store)
95
+ break;
96
+ after = rows[rows.length - 1].rid;
97
+ tasks += store.add(rows.map(taskDoc).filter(d => d !== null && d.ts >= cutoff));
98
+ await pause();
99
+ }
100
+ }
101
+ catch { /* the same for the Task Board */ }
102
+ finally {
103
+ scheduler.close();
104
+ }
105
+ return { xmsg, tasks };
106
+ }
107
+ port.on("message", (m) => {
108
+ if (!store)
109
+ return;
110
+ const reply = (value) => { if (m.id !== undefined)
111
+ port.postMessage({ op: "reply", id: m.id, ok: true, value }); };
112
+ try {
113
+ switch (m.op) {
114
+ // Acked once written: the fleet keeps a batch until then, and sends it again to a worker that replaces this one.
115
+ case "add":
116
+ store.add((m.docs ?? []));
117
+ if (m.batch !== undefined)
118
+ port.postMessage({ op: "added", batch: m.batch });
119
+ break;
120
+ case "markBuilt":
121
+ store.markBuilt(Number(m.now) || Date.now());
122
+ break;
123
+ case "removeInstance":
124
+ if (typeof m.instance === "string") {
125
+ store.removeInstance(m.instance);
126
+ port.postMessage({ op: "removed", instance: m.instance, gen: m.gen });
127
+ }
128
+ break;
129
+ case "query":
130
+ reply(store.search(m.filters));
131
+ break;
132
+ case "context":
133
+ reply(store.context(String(m.key ?? "")));
134
+ break;
135
+ case "prune":
136
+ reply(store.prune(Number(m.cutoff) || 0));
137
+ break;
138
+ case "count":
139
+ reply(store.count());
140
+ break;
141
+ case "backfill":
142
+ void backfill(m.outboxPath, m.schedulerPath, Number(m.cutoff) || 0).then(reply, err => {
143
+ if (m.id !== undefined)
144
+ port.postMessage({ op: "reply", id: m.id, ok: false, error: String(err?.message ?? err) });
145
+ });
146
+ break;
147
+ case "close":
148
+ store.close();
149
+ store = null;
150
+ process.exit(0);
151
+ }
152
+ }
153
+ catch (err) {
154
+ if (m.id !== undefined)
155
+ port.postMessage({ op: "reply", id: m.id, ok: false, error: String(err?.message ?? err) });
156
+ // A corrupt file: a fresh one, announced as not built (the fleet sends its uncommitted batches again and backfills).
157
+ // Any other failed write is let go (acked): sent again it would fail again.
158
+ if (!recover(err) && m.op === "add" && m.batch !== undefined)
159
+ port.postMessage({ op: "added", batch: m.batch });
160
+ }
161
+ });
162
+ open();
163
+ //# sourceMappingURL=search-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-worker.js","sourceRoot":"","sources":["../../src/search/search-worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAmB,MAAM,kBAAkB,CAAC;AAErF,MAAM,IAAI,GAAG,MAAM,CAAE,UAA6C,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;AAChF,MAAM,IAAI,GAAG,UAAW,CAAC;AACzB,IAAI,KAAK,GAAuB,IAAI,CAAC;AAErC,SAAS,SAAS;IAChB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7D,KAAK,MAAM,MAAM,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC;QAAE,IAAI,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC;YAAE,UAAU,CAAC,IAAI,GAAG,MAAM,EAAE,GAAG,IAAI,YAAY,KAAK,GAAG,MAAM,EAAE,CAAC,CAAC;AAC3I,CAAC;AACD,SAAS,IAAI;IACX,IAAI,CAAC;QAAC,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IACtC,OAAO,GAAG,EAAE,CAAC;QACX,IAAI,uBAAuB,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,CAAC;QACxJ,SAAS,EAAE,CAAC;QACZ,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AACD,4GAA4G;AAC5G,SAAS,OAAO,CAAC,GAAY;IAC3B,IAAI,uBAAuB,CAAC,GAAG,CAAC,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7D,KAAK,EAAE,KAAK,EAAE,CAAC;IAAC,KAAK,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,CAAC;IACZ,IAAI,EAAE,CAAC;IACP,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,MAAM,aAAa,GAAG,CAAC,eAAe,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AAC9D,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;AACxE,SAAS,QAAQ,CAAC,IAAwB;IACxC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,CAAC;QAAC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAAC,OAAO,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;AACrJ,CAAC;AACD,sHAAsH;AACtH,KAAK,UAAU,QAAQ,CAAC,UAA8B,EAAE,aAAiC,EAAE,MAAc;IACvG,IAAI,IAAI,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,MAAM;QAAE,IAAI,CAAC;YACf,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;2DAC2B,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAC/H,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,IAAK,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,aAAa,EAAE,aAAa,CAA6F,CAAC;gBAC1J,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;oBAAE,MAAM;gBAClC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC;gBACnC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,CAAC;gBACjK,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,IAAa,CAAC,CAAC;gBACjC,MAAM,KAAK,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,wEAAwE,CAAC,CAAC;gBAAS,CAAC;YAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;IAChH,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAC;IAC1C,IAAI,SAAS;QAAE,IAAI,CAAC;YAClB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,6JAA6J,CAAC,CAAC;YAC9L,KAAK,IAAI,KAAK,GAAG,CAAC,CAAC,IAAK,CAAC;gBACvB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAwC,CAAC;gBACnF,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK;oBAAE,MAAM;gBAClC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC;gBACnC,KAAK,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,IAAI,MAAM,CAAU,CAAC,CAAC;gBACzF,MAAM,KAAK,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,iCAAiC,CAAC,CAAC;gBAAS,CAAC;YAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;IAC5E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAA8M,EAAE,EAAE;IACpO,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,KAAK,GAAG,CAAC,KAAc,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5H,IAAI,CAAC;QACH,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC;YACb,iHAAiH;YACjH,KAAK,KAAK;gBAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAU,CAAC,CAAC;gBAAC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;oBAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;gBAAC,MAAM;YACpI,KAAK,WAAW;gBAAE,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAAC,MAAM;YACtE,KAAK,gBAAgB;gBAAE,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;oBAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM;YAC9K,KAAK,OAAO;gBAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAgB,CAAC,CAAC,CAAC;gBAAC,MAAM;YAC7D,KAAK,SAAS;gBAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBAAC,MAAM;YACjE,KAAK,OAAO;gBAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAAC,MAAM;YAC/D,KAAK,OAAO;gBAAE,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;gBAAC,MAAM;YAC1C,KAAK,UAAU;gBAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;oBACrG,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;wBAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;gBAChI,CAAC,CAAC,CAAC;gBAAC,MAAM;YACV,KAAK,OAAO;gBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;gBAAC,KAAK,GAAG,IAAI,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,CAAC,EAAE,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9H,qHAAqH;QACrH,4EAA4E;QAC5E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAClH,CAAC;AACH,CAAC,CAAC,CAAC;AACH,IAAI,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The `task` tool's board actions (step 2, docs/design/task-board.md), for both of the tool's doors — the MCP tool
3
+ * over IPC (FleetManager.handleTaskCrud) and `agend-agent task` over HTTP (handleTaskCrudHttp):
4
+ *
5
+ * - `mine` — the caller's work; `projects` — the board's projects;
6
+ * - `move` — a card to another status, with the reason, result or comment the move needs;
7
+ * - `create` or `update` naming a board field (a project, a parent, a checklist, state, a log line, a comment…);
8
+ * - `get` of a card on the board — the card as text, with the comments new to its assignee.
9
+ *
10
+ * Everything else is the tool's own and is answered as before (undefined here). The caller is the instance the tool
11
+ * belongs to; the board's rules (scheduler/task-board.ts) decide what it may do. Answers are plain text.
12
+ */
13
+ import type { SchedulerDb } from "./scheduler/db.js";
14
+ export declare function boardToolAction(db: SchedulerDb, instance: string, args: Record<string, unknown>): string | undefined;
15
+ /** The activity log's line for a board action that changed work (as `created task:` / `claimed:` / `completed:` for plain tasks). */
16
+ export declare function boardActivity(args: Record<string, unknown>): string | null;
17
+ /**
18
+ * #2303: how many handed-out board cards an instance may have in progress at once — its `board_cards_at_once`, else
19
+ * 1 (the validator holds it to a whole number of at least 1; anything else here counts as 1).
20
+ */
21
+ export declare function boardCardLimit(fleet: {
22
+ instances?: Record<string, {
23
+ board_cards_at_once?: unknown;
24
+ } | undefined>;
25
+ } | null | undefined, name: string): number;
@@ -0,0 +1,154 @@
1
+ import { CARD_PRIORITIES, CARD_SIZES, CARD_STATUSES, TaskBoardError } from "./scheduler/task-board.js";
2
+ import { cardLine, cardText, myWorkText, projectsText, writeText } from "./scheduler/task-board-text.js";
3
+ /** A `create` naming one of these opens a board card; without them it is the tool's plain task. */
4
+ const BOARD_CREATE = ["project", "parent", "scope", "acceptance", "context", "needs_review", "size", "dispatcher"];
5
+ /** An `update` naming one of these edits the card on the board's terms; without them it is the tool's plain update. */
6
+ const BOARD_UPDATE = ["title", "description", "scope", "context", "state", "acceptance", "check", "uncheck", "log", "comment", "needs_review", "size", "depends_on", "version", "dispatcher"];
7
+ /** Words agents bring from other boards. */
8
+ const STATUS_ALIAS = { todo: "open", "to do": "open", doing: "claimed", in_progress: "claimed", "in progress": "claimed", waiting: "review" };
9
+ const str = (v) => (typeof v === "string" ? v : undefined);
10
+ const strs = (v) => (Array.isArray(v) && v.every((x) => typeof x === "string") ? v : undefined);
11
+ const nums = (v) => (Array.isArray(v) && v.every((x) => typeof x === "number") ? v : undefined);
12
+ const int = (v) => (typeof v === "number" && Number.isInteger(v) ? v : undefined);
13
+ const bool = (v) => (typeof v === "boolean" ? v : undefined);
14
+ // A dispatcher of null is a value (nobody), not an absent field.
15
+ const has = (args, keys) => keys.some((k) => args[k] !== undefined && (args[k] !== null || k === "dispatcher"));
16
+ function status(v, param = "to") {
17
+ const s = typeof v === "string" ? v.trim().toLowerCase() : "";
18
+ const known = CARD_STATUSES.includes(s) ? s : STATUS_ALIAS[s];
19
+ if (!known)
20
+ throw new TaskBoardError("invalid", `"${param}" is one of ${CARD_STATUSES.join(", ")}`);
21
+ return known;
22
+ }
23
+ const priority = (v) => (CARD_PRIORITIES.includes(v) ? v : undefined);
24
+ /** An instance's name; null, "" or "none": nobody. */
25
+ const dispatcher = (v) => {
26
+ if (v === undefined)
27
+ return undefined;
28
+ const name = typeof v === "string" ? v.trim() : "";
29
+ return !name || name.toLowerCase() === "none" ? null : { kind: "instance", name };
30
+ };
31
+ const size = (v) => (v === null || v === "" ? null : CARD_SIZES.includes(v) ? v : undefined);
32
+ function need(v, what) {
33
+ const s = str(v)?.trim();
34
+ if (!s)
35
+ throw new TaskBoardError("invalid", `${what} is required`);
36
+ return s;
37
+ }
38
+ export function boardToolAction(db, instance, args) {
39
+ const board = db.board;
40
+ const actor = { kind: "instance", name: instance };
41
+ switch (args.action) {
42
+ case "mine":
43
+ return myWorkText(board, instance, board.myWork(instance));
44
+ case "projects":
45
+ return projectsText(board.listProjects(true), board.projectStats());
46
+ case "move": {
47
+ const id = need(args.id, "id");
48
+ let to = status(args.to ?? args.status);
49
+ // As the tool's `done`: finishing a card that waits for the person's confirmation hands it to them (review).
50
+ if (to === "done") {
51
+ const held = board.findCard(id);
52
+ if (held?.needsReview && held.status !== "review")
53
+ to = "review";
54
+ }
55
+ const { card, from, notes } = board.moveCard(actor, id, to, {
56
+ reason: str(args.reason), result: str(args.result), comment: str(args.comment), version: int(args.version),
57
+ });
58
+ return writeText(card, notes, from);
59
+ }
60
+ case "create": {
61
+ if (!has(args, BOARD_CREATE))
62
+ return undefined;
63
+ const spec = {
64
+ title: need(args.title, "title"),
65
+ goal: str(args.description),
66
+ scope: str(args.scope),
67
+ context: str(args.context),
68
+ acceptance: strs(args.acceptance),
69
+ priority: priority(args.priority),
70
+ size: size(args.size) ?? undefined,
71
+ dependsOn: strs(args.depends_on),
72
+ needsReview: bool(args.needs_review),
73
+ dispatcher: dispatcher(args.dispatcher),
74
+ ...(str(args.parent) ? { parent: str(args.parent) } : { project: str(args.project) ?? (typeof args.project === "number" ? args.project : undefined) }),
75
+ ...(args.assignee !== undefined ? { assignee: str(args.assignee) ?? null } : {}),
76
+ };
77
+ const { cards, notes } = board.createCards(actor, { cards: [spec] });
78
+ return writeText(cards[0], notes);
79
+ }
80
+ case "update": {
81
+ if (!has(args, BOARD_UPDATE))
82
+ return undefined;
83
+ const patch = {
84
+ version: int(args.version),
85
+ title: str(args.title),
86
+ goal: str(args.description),
87
+ scope: str(args.scope),
88
+ context: str(args.context),
89
+ state: str(args.state),
90
+ result: str(args.result),
91
+ acceptance: strs(args.acceptance),
92
+ check: nums(args.check),
93
+ uncheck: nums(args.uncheck),
94
+ log: str(args.log),
95
+ comment: str(args.comment),
96
+ needsReview: bool(args.needs_review),
97
+ dispatcher: dispatcher(args.dispatcher),
98
+ size: size(args.size),
99
+ priority: priority(args.priority),
100
+ dependsOn: strs(args.depends_on),
101
+ ...(args.assignee !== undefined ? { assignee: str(args.assignee) ?? null } : {}),
102
+ };
103
+ if (args.status === undefined) {
104
+ const { card, notes } = board.updateCard(actor, need(args.id, "id"), patch);
105
+ return writeText(card, notes);
106
+ }
107
+ // A status given with the fields: the fields, then the move as the tool's plain update makes it (the board's
108
+ // rules, the gate) — one write, so a refused move keeps the fields unchanged too.
109
+ const to = status(args.status, "status");
110
+ const { card, from } = board.atomically(() => {
111
+ const { card: edited } = board.updateCard(actor, need(args.id, "id"), patch);
112
+ if (to !== edited.status)
113
+ db.updateTask(edited.uuid, { status: to }, actor);
114
+ return { card: board.getCard(edited.uuid), from: edited.status };
115
+ });
116
+ return writeText(card, board.takeNotes(), from);
117
+ }
118
+ case "list": {
119
+ if (!has(args, ["project", "parent"]))
120
+ return undefined;
121
+ const filterStatus = args.filter_status === undefined ? undefined : (Array.isArray(args.filter_status) ? args.filter_status : [args.filter_status]).map((v) => status(v, "filter_status"));
122
+ const project = args.project === "" || args.project === "none" ? null : (str(args.project) ?? (typeof args.project === "number" ? args.project : undefined));
123
+ const { cards, total } = board.listCards({ project, parent: str(args.parent), assignee: str(args.filter_assignee) || undefined, status: filterStatus });
124
+ if (!cards.length)
125
+ return "No cards match.";
126
+ return [...cards.map((c) => cardLine(c)), ...(total > cards.length ? [`… ${total - cards.length} more: narrow with filter_status or filter_assignee`] : [])].join("\n");
127
+ }
128
+ case "get": {
129
+ const card = board.findCard(need(args.id, "id"));
130
+ return card && board.isOnBoard(card) ? cardText(board, card) : undefined;
131
+ }
132
+ default:
133
+ return undefined;
134
+ }
135
+ }
136
+ /** The activity log's line for a board action that changed work (as `created task:` / `claimed:` / `completed:` for plain tasks). */
137
+ export function boardActivity(args) {
138
+ const id = typeof args.id === "string" ? args.id : "";
139
+ if (args.action === "create" && has(args, BOARD_CREATE) && typeof args.title === "string")
140
+ return `created task: ${args.title}`;
141
+ if (args.action !== "move")
142
+ return null;
143
+ const to = typeof args.to === "string" ? args.to : typeof args.status === "string" ? args.status : "";
144
+ return { claimed: `claimed: ${id}`, done: `completed: ${id}`, review: `submitted for review: ${id}`, blocked: `blocked: ${id}`, cancelled: `cancelled: ${id}`, open: `put back: ${id}` }[STATUS_ALIAS[to] ?? to] ?? null;
145
+ }
146
+ /**
147
+ * #2303: how many handed-out board cards an instance may have in progress at once — its `board_cards_at_once`, else
148
+ * 1 (the validator holds it to a whole number of at least 1; anything else here counts as 1).
149
+ */
150
+ export function boardCardLimit(fleet, name) {
151
+ const own = fleet?.instances && Object.prototype.hasOwnProperty.call(fleet.instances, name) ? fleet.instances[name]?.board_cards_at_once : undefined;
152
+ return typeof own === "number" && Number.isInteger(own) && own >= 1 ? own : 1;
153
+ }
154
+ //# sourceMappingURL=task-board-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-board-tool.js","sourceRoot":"","sources":["../src/task-board-tool.ts"],"names":[],"mappings":"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"}