crewly 1.20.306 → 1.20.307

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 (83) hide show
  1. package/config/hooks/agent-status/report.sh +39 -1
  2. package/dist/backend/backend/src/constants.d.ts +54 -0
  3. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  4. package/dist/backend/backend/src/constants.js +54 -0
  5. package/dist/backend/backend/src/constants.js.map +1 -1
  6. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts +2 -1
  7. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
  8. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +18 -1
  9. package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
  10. package/dist/backend/backend/src/controllers/board/board.controller.d.ts +23 -0
  11. package/dist/backend/backend/src/controllers/board/board.controller.d.ts.map +1 -0
  12. package/dist/backend/backend/src/controllers/board/board.controller.js +48 -0
  13. package/dist/backend/backend/src/controllers/board/board.controller.js.map +1 -0
  14. package/dist/backend/backend/src/controllers/board/board.routes.d.ts +15 -0
  15. package/dist/backend/backend/src/controllers/board/board.routes.d.ts.map +1 -0
  16. package/dist/backend/backend/src/controllers/board/board.routes.js +21 -0
  17. package/dist/backend/backend/src/controllers/board/board.routes.js.map +1 -0
  18. package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
  19. package/dist/backend/backend/src/controllers/browser/browser.controller.js +2 -0
  20. package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
  21. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  22. package/dist/backend/backend/src/controllers/chat/chat.controller.js +5 -0
  23. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  24. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  25. package/dist/backend/backend/src/controllers/slack/slack.controller.js +3 -0
  26. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  27. package/dist/backend/backend/src/index.d.ts +9 -0
  28. package/dist/backend/backend/src/index.d.ts.map +1 -1
  29. package/dist/backend/backend/src/index.js +46 -0
  30. package/dist/backend/backend/src/index.js.map +1 -1
  31. package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
  32. package/dist/backend/backend/src/routes/api.routes.js +3 -0
  33. package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
  34. package/dist/backend/backend/src/services/board/board-activity.normalizer.d.ts +85 -0
  35. package/dist/backend/backend/src/services/board/board-activity.normalizer.d.ts.map +1 -0
  36. package/dist/backend/backend/src/services/board/board-activity.normalizer.js +241 -0
  37. package/dist/backend/backend/src/services/board/board-activity.normalizer.js.map +1 -0
  38. package/dist/backend/backend/src/services/board/board-activity.tracker.d.ts +154 -0
  39. package/dist/backend/backend/src/services/board/board-activity.tracker.d.ts.map +1 -0
  40. package/dist/backend/backend/src/services/board/board-activity.tracker.js +322 -0
  41. package/dist/backend/backend/src/services/board/board-activity.tracker.js.map +1 -0
  42. package/dist/backend/backend/src/services/board/board-outcome-phrases.d.ts +43 -0
  43. package/dist/backend/backend/src/services/board/board-outcome-phrases.d.ts.map +1 -0
  44. package/dist/backend/backend/src/services/board/board-outcome-phrases.js +76 -0
  45. package/dist/backend/backend/src/services/board/board-outcome-phrases.js.map +1 -0
  46. package/dist/backend/backend/src/services/board/board-push.service.d.ts +114 -0
  47. package/dist/backend/backend/src/services/board/board-push.service.d.ts.map +1 -0
  48. package/dist/backend/backend/src/services/board/board-push.service.js +312 -0
  49. package/dist/backend/backend/src/services/board/board-push.service.js.map +1 -0
  50. package/dist/backend/backend/src/services/board/board-redact.d.ts +90 -0
  51. package/dist/backend/backend/src/services/board/board-redact.d.ts.map +1 -0
  52. package/dist/backend/backend/src/services/board/board-redact.js +359 -0
  53. package/dist/backend/backend/src/services/board/board-redact.js.map +1 -0
  54. package/dist/backend/backend/src/services/board/board-snapshot.builder.d.ts +176 -0
  55. package/dist/backend/backend/src/services/board/board-snapshot.builder.d.ts.map +1 -0
  56. package/dist/backend/backend/src/services/board/board-snapshot.builder.js +342 -0
  57. package/dist/backend/backend/src/services/board/board-snapshot.builder.js.map +1 -0
  58. package/dist/backend/backend/src/services/board/board-usage.d.ts +20 -0
  59. package/dist/backend/backend/src/services/board/board-usage.d.ts.map +1 -0
  60. package/dist/backend/backend/src/services/board/board-usage.js +82 -0
  61. package/dist/backend/backend/src/services/board/board-usage.js.map +1 -0
  62. package/dist/backend/backend/src/services/board/board.service.d.ts +60 -0
  63. package/dist/backend/backend/src/services/board/board.service.d.ts.map +1 -0
  64. package/dist/backend/backend/src/services/board/board.service.js +82 -0
  65. package/dist/backend/backend/src/services/board/board.service.js.map +1 -0
  66. package/dist/backend/backend/src/services/board/board.sources.d.ts +25 -0
  67. package/dist/backend/backend/src/services/board/board.sources.d.ts.map +1 -0
  68. package/dist/backend/backend/src/services/board/board.sources.js +293 -0
  69. package/dist/backend/backend/src/services/board/board.sources.js.map +1 -0
  70. package/dist/backend/backend/src/services/board/board.types.d.ts +117 -0
  71. package/dist/backend/backend/src/services/board/board.types.d.ts.map +1 -0
  72. package/dist/backend/backend/src/services/board/board.types.js +8 -0
  73. package/dist/backend/backend/src/services/board/board.types.js.map +1 -0
  74. package/dist/backend/backend/src/services/google/google-reauth-notifier.service.d.ts +13 -0
  75. package/dist/backend/backend/src/services/google/google-reauth-notifier.service.d.ts.map +1 -1
  76. package/dist/backend/backend/src/services/google/google-reauth-notifier.service.js +15 -0
  77. package/dist/backend/backend/src/services/google/google-reauth-notifier.service.js.map +1 -1
  78. package/dist/backend/build-info.json +2 -2
  79. package/dist/cli/backend/src/constants.d.ts +54 -0
  80. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  81. package/dist/cli/backend/src/constants.js +54 -0
  82. package/dist/cli/backend/src/constants.js.map +1 -1
  83. package/package.json +1 -1
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Redaction for the Owner Board (crewly#1247). Everything that leaves the
3
+ * machine as board text goes through here first: query strings, tokens,
4
+ * emails and phone numbers are removed, URLs are cut to host + path, commands
5
+ * to executable + subcommand, file paths to project-relative, and every text
6
+ * to at most {@link BOARD_CONSTANTS.MAX_TEXT} characters.
7
+ *
8
+ * Pure (no I/O). The functions never throw and never return their input
9
+ * unchanged when it looks like a secret.
10
+ *
11
+ * @module services/board/board-redact
12
+ */
13
+ import * as os from 'os';
14
+ import * as path from 'path';
15
+ import { BOARD_CONSTANTS } from '../../constants.js';
16
+ const MAX = BOARD_CONSTANTS.MAX_TEXT;
17
+ /** Placeholder for removed secrets. */
18
+ export const REDACTED = '[redacted]';
19
+ const URL_IN_TEXT = /\b(?:https?|ftp|wss?):\/\/[^\s<>"'`)\]]+/gi;
20
+ const EMAIL = /[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}/g;
21
+ const EMAIL_ONE = /[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*\.[A-Za-z]{2,}/;
22
+ const BEARER = /\b(?:bearer|basic)\s+[A-Za-z0-9._~+/=-]{6,}/gi;
23
+ /** `token=abc`, `password: abc`, `--api-key abc`, `"secret":"abc"` */
24
+ const SECRET_ASSIGNMENT = /((?:api[_-]?key|access[_-]?key|secret|token|passw(?:or)?d|pwd|auth(?:orization)?|credential|private[_-]?key|session)[\w-]*["']?\s*[=:]\s*["']?)[^\s"',;&]+/gi;
25
+ const SECRET_FLAG = /(--?(?:api[_-]?key|token|secret|passw(?:or)?d|pwd|auth|key|authorization)(?:=|\s+))[^\s]+/gi;
26
+ const KNOWN_PREFIX = /\b(?:sk|pk|rk)-[A-Za-z0-9_-]{8,}|\bgh[pousr]_[A-Za-z0-9]{16,}|\bgithub_pat_[A-Za-z0-9_]{16,}|\bxox[abprso]-[A-Za-z0-9-]{8,}|\bAKIA[0-9A-Z]{12,}|\bAIza[0-9A-Za-z_-]{20,}|\bya29\.[\w-]{10,}|\beyJ[\w-]{6,}\.[\w-]{6,}\.[\w-]*|\bnpm_[A-Za-z0-9]{20,}|\bglpat-[\w-]{12,}/g;
27
+ /** Digits with separators, at least 9 digits in all (dates have 8). */
28
+ const PHONE = /(?<![\w.])\+?\d[\d\s().-]{7,}\d(?![\w])/g;
29
+ const LONG_TOKEN = /(?<![\w/.:-])[A-Za-z0-9_+=-]{24,}(?![\w])/g;
30
+ const HEX_LONG = /\b[0-9a-fA-F]{32,}\b/g;
31
+ /**
32
+ * Whether a path segment or word looks like an identifier or a token, not a
33
+ * human name: long with digits and letters, long hex, or a long number.
34
+ *
35
+ * @param s - Segment
36
+ * @returns True when it should not be shown
37
+ */
38
+ export function looksLikeToken(s) {
39
+ if (s.length >= 32 && /^[0-9a-fA-F-]+$/.test(s))
40
+ return true;
41
+ if (/^\d{9,}$/.test(s))
42
+ return true;
43
+ if (s.length >= 20 && /\d/.test(s) && /[A-Za-z]/.test(s) && /^[A-Za-z0-9_+=-]+$/.test(s))
44
+ return true;
45
+ if (s.length >= 28 && /^[A-Za-z0-9_+=-]+$/.test(s) && /[A-Z]/.test(s) && /[a-z]/.test(s))
46
+ return true;
47
+ return false;
48
+ }
49
+ /**
50
+ * Cut a text to the board limit.
51
+ *
52
+ * @param s - Text
53
+ * @param max - Limit (default 140)
54
+ * @returns The text, ending with an ellipsis when cut
55
+ */
56
+ export function clip(s, max = MAX) {
57
+ if (s.length <= max)
58
+ return s;
59
+ return `${s.slice(0, Math.max(0, max - 1)).trimEnd()}…`;
60
+ }
61
+ /**
62
+ * A URL as host + path: no scheme, credentials, port, query or fragment;
63
+ * path segments that look like ids or tokens become `:id`.
64
+ *
65
+ * @param raw - URL or `host/path`
66
+ * @returns `host/path` (at most 100 characters), or `[redacted]` when unparseable
67
+ */
68
+ export function redactUrl(raw) {
69
+ const trimmed = raw.trim().replace(/[.,;:!?)\]]+$/, '');
70
+ if (!trimmed)
71
+ return REDACTED;
72
+ let url;
73
+ try {
74
+ url = new URL(/^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`);
75
+ }
76
+ catch {
77
+ return REDACTED;
78
+ }
79
+ const host = url.hostname.toLowerCase();
80
+ if (!host || /[^a-z0-9.-]/.test(host))
81
+ return REDACTED;
82
+ const segments = url.pathname
83
+ .split('/')
84
+ .filter(Boolean)
85
+ .map((seg) => {
86
+ let s = seg;
87
+ try {
88
+ s = decodeURIComponent(seg);
89
+ }
90
+ catch {
91
+ // keep raw
92
+ }
93
+ if (looksLikeToken(s) || EMAIL_ONE.test(s) || s.length > 40)
94
+ return ':id';
95
+ return s.replace(/[^\w.~:@!$&'()*+,=-]/g, '');
96
+ });
97
+ const out = segments.length > 0 ? `${host}/${segments.join('/')}` : host;
98
+ return clip(out, 100);
99
+ }
100
+ /**
101
+ * A free text made safe: one line, URLs reduced, secrets / emails / phone
102
+ * numbers removed, at most 140 characters.
103
+ *
104
+ * @param input - Any text
105
+ * @param max - Limit (default 140)
106
+ * @returns Safe text (possibly empty)
107
+ */
108
+ export function scrubText(input, max = MAX) {
109
+ if (typeof input !== 'string' || input.length === 0)
110
+ return '';
111
+ let s = input.length > 4000 ? input.slice(0, 4000) : input;
112
+ // eslint-disable-next-line no-control-regex
113
+ s = s.replace(/[\u0000-\u001f\u007f]+/g, ' ');
114
+ s = s.replace(URL_IN_TEXT, (u) => redactUrl(u));
115
+ s = s.replace(EMAIL, '[email]');
116
+ s = s.replace(BEARER, REDACTED);
117
+ s = s.replace(SECRET_ASSIGNMENT, `$1${REDACTED}`);
118
+ s = s.replace(SECRET_FLAG, `$1${REDACTED}`);
119
+ s = s.replace(KNOWN_PREFIX, REDACTED);
120
+ s = s.replace(HEX_LONG, REDACTED);
121
+ s = s.replace(PHONE, (m) => (m.replace(/\D/g, '').length >= 9 ? '[number]' : m));
122
+ s = s.replace(LONG_TOKEN, (m) => (looksLikeToken(m) ? REDACTED : m));
123
+ s = s.replace(/\s+/g, ' ').trim();
124
+ return clip(s, max);
125
+ }
126
+ /** Home directory prefixes shown as `~`. */
127
+ const HOME_PATTERN = /^(?:\/Users|\/home)\/[^/]+(?=\/|$)/;
128
+ /**
129
+ * A file path relative to the project it is in, so no absolute path, user
130
+ * name or machine layout leaves the machine.
131
+ *
132
+ * @param file - Absolute or relative path
133
+ * @param roots - Project roots to make it relative to (longest match wins)
134
+ * @returns `repo/relative/path`, `~/…`, or `…/last/segments`; at most 100 characters
135
+ */
136
+ export function relativePath(file, roots = []) {
137
+ let p = file.trim().replace(/\\/g, '/');
138
+ if (!p)
139
+ return '';
140
+ const ordered = [...roots].map((r) => r.replace(/\\/g, '/').replace(/\/+$/, '')).filter(Boolean).sort((a, b) => b.length - a.length);
141
+ let out = null;
142
+ for (const root of ordered) {
143
+ if (p === root) {
144
+ out = path.posix.basename(root);
145
+ break;
146
+ }
147
+ if (p.startsWith(`${root}/`)) {
148
+ out = `${path.posix.basename(root)}/${p.slice(root.length + 1)}`;
149
+ break;
150
+ }
151
+ }
152
+ if (out === null) {
153
+ const home = os.homedir().replace(/\\/g, '/');
154
+ if (home && home !== '/' && (p === home || p.startsWith(`${home}/`)))
155
+ p = `~${p.slice(home.length)}`;
156
+ else if (HOME_PATTERN.test(p))
157
+ p = p.replace(HOME_PATTERN, '~');
158
+ if (p.startsWith('/')) {
159
+ const parts = p.split('/').filter(Boolean);
160
+ p = parts.length > 3 ? `…/${parts.slice(-3).join('/')}` : parts.join('/');
161
+ }
162
+ else if (p.startsWith('~/')) {
163
+ const parts = p.split('/');
164
+ if (parts.length > 5)
165
+ p = `~/…/${parts.slice(-3).join('/')}`;
166
+ }
167
+ out = p;
168
+ }
169
+ const cleaned = out
170
+ .split('/')
171
+ .map((seg) => (looksLikeToken(seg) ? ':id' : seg))
172
+ .join('/');
173
+ const scrubbed = scrubText(cleaned, 400);
174
+ if (scrubbed.length <= 100)
175
+ return scrubbed;
176
+ return `…${scrubbed.slice(scrubbed.length - 99)}`;
177
+ }
178
+ // ---------------------------------------------------------------------------
179
+ // Commands
180
+ // ---------------------------------------------------------------------------
181
+ /** Tools whose first plain word is a subcommand worth showing (`git push`). */
182
+ const SUBCOMMAND_TOOLS = new Set([
183
+ 'git', 'npm', 'pnpm', 'yarn', 'bun', 'npx', 'docker', 'docker-compose', 'gh', 'kubectl', 'cargo', 'brew', 'pip', 'pip3', 'go', 'make',
184
+ 'systemctl', 'pm2', 'aws', 'gcloud', 'vercel', 'wrangler', 'terraform', 'tmux', 'apt', 'apt-get', 'jest', 'tsc', 'crewly',
185
+ ]);
186
+ /** Interpreters: the script name is shown. */
187
+ const INTERPRETERS = new Set(['python', 'python3', 'node', 'tsx', 'ts-node', 'ruby', 'bash', 'sh', 'zsh', 'deno', 'perl', 'php']);
188
+ /** Leading words that run something else. */
189
+ const WRAPPERS = new Set(['sudo', 'env', 'time', 'nohup', 'nice', 'command', 'exec', 'builtin', 'stdbuf', 'caffeinate', 'xargs']);
190
+ /** Segments that only set the scene. */
191
+ const SCENE_SETTERS = new Set(['cd', 'export', 'set', 'unset', 'source', '.', 'pushd', 'popd', 'true', 'false', ':', 'shopt', 'umask', 'trap', 'ulimit', 'alias']);
192
+ const SUB_WORD = /^[a-z][a-z0-9:_-]{0,30}$/;
193
+ const SCRIPT_FILE = /\.(?:py|js|mjs|cjs|ts|tsx|sh|rb|pl|php)$/i;
194
+ const EXECUTABLE = /^[A-Za-z0-9._+-]{1,40}$/;
195
+ const SKILL_SCRIPT = /\/skills\/(?:[\w.-]+\/)*([\w-]+)\/execute\.sh$/;
196
+ /**
197
+ * Split a shell command into segments of words (quotes removed). Separators
198
+ * `&&`, `||`, `;`, `|`, `&` and newlines end a segment. Not a full parser; it
199
+ * only needs to find the first words of each segment safely.
200
+ *
201
+ * @param command - Shell command
202
+ * @returns Segments
203
+ */
204
+ export function splitCommand(command) {
205
+ const segments = [];
206
+ let words = [];
207
+ let cur = '';
208
+ let has = false;
209
+ let quote = null;
210
+ const endWord = () => {
211
+ if (has)
212
+ words.push(cur);
213
+ cur = '';
214
+ has = false;
215
+ };
216
+ const endSegment = () => {
217
+ endWord();
218
+ if (words.length > 0)
219
+ segments.push(words);
220
+ words = [];
221
+ };
222
+ const s = command.length > 4000 ? command.slice(0, 4000) : command;
223
+ for (let i = 0; i < s.length; i += 1) {
224
+ const c = s[i];
225
+ if (quote) {
226
+ if (c === quote)
227
+ quote = null;
228
+ else if (c === '\\' && quote === '"' && i + 1 < s.length)
229
+ cur += s[(i += 1)];
230
+ else
231
+ cur += c;
232
+ continue;
233
+ }
234
+ if (c === '"' || c === "'") {
235
+ quote = c;
236
+ has = true;
237
+ }
238
+ else if (c === '\\' && i + 1 < s.length) {
239
+ cur += s[(i += 1)];
240
+ has = true;
241
+ }
242
+ else if (c === '\n' || c === ';' || c === '|' || c === '&') {
243
+ // `2>&1` and `&>` are redirections, not separators
244
+ if (c === '&' && (s[i - 1] === '>' || s[i + 1] === '>' || /\d/.test(s[i - 1] ?? ''))) {
245
+ cur += c;
246
+ has = true;
247
+ continue;
248
+ }
249
+ endSegment();
250
+ if ((c === '&' || c === '|') && s[i + 1] === c)
251
+ i += 1;
252
+ }
253
+ else if (c === ' ' || c === '\t') {
254
+ endWord();
255
+ }
256
+ else {
257
+ cur += c;
258
+ has = true;
259
+ }
260
+ }
261
+ endSegment();
262
+ return segments;
263
+ }
264
+ /**
265
+ * Reduce a shell command to the executable and subcommand. Arguments are
266
+ * never part of the label, so tokens, URLs and prompts in them cannot leak.
267
+ *
268
+ * @param command - Shell command
269
+ * @returns The reduced command, or null when nothing recognisable is in it
270
+ *
271
+ * @example
272
+ * ```typescript
273
+ * reduceCommand('cd app && GIT_TOKEN=abc git -C x push origin main'); // label: 'git push'
274
+ * ```
275
+ */
276
+ export function reduceCommand(command) {
277
+ for (const original of splitCommand(command)) {
278
+ const words = [...original];
279
+ // Leading assignments and wrappers
280
+ for (;;) {
281
+ const w = words[0];
282
+ if (w === undefined)
283
+ break;
284
+ if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(w)) {
285
+ words.shift();
286
+ continue;
287
+ }
288
+ const base = path.posix.basename(w);
289
+ if (WRAPPERS.has(base)) {
290
+ words.shift();
291
+ // `timeout 30 cmd`, `nice -n 5 cmd`, `env -i cmd`
292
+ while (words[0] !== undefined && (words[0].startsWith('-') || /^\d+$/.test(words[0]) || /^[A-Za-z_][A-Za-z0-9_]*=/.test(words[0])))
293
+ words.shift();
294
+ continue;
295
+ }
296
+ if (base === 'timeout') {
297
+ words.shift();
298
+ while (words[0] !== undefined && (words[0].startsWith('-') || /^\d+[smhd]?$/.test(words[0])))
299
+ words.shift();
300
+ continue;
301
+ }
302
+ break;
303
+ }
304
+ const head = words[0];
305
+ if (head === undefined)
306
+ continue;
307
+ const exe = path.posix.basename(head);
308
+ if (SCENE_SETTERS.has(exe) || exe.startsWith('#'))
309
+ continue;
310
+ const skillMatch = SKILL_SCRIPT.exec(head.replace(/\\/g, '/')) ?? (INTERPRETERS.has(exe) && words[1] ? SKILL_SCRIPT.exec(words[1].replace(/\\/g, '/')) : null);
311
+ if (skillMatch) {
312
+ return { label: `skill ${skillMatch[1]}`, executable: 'bash', skill: skillMatch[1], args: words.slice(INTERPRETERS.has(exe) ? 2 : 1) };
313
+ }
314
+ if (!EXECUTABLE.test(exe) || looksLikeToken(exe))
315
+ return { label: 'shell command', executable: 'shell', args: [] };
316
+ const args = words.slice(1);
317
+ if (SUBCOMMAND_TOOLS.has(exe)) {
318
+ const rest = [...args];
319
+ let sub;
320
+ while (rest.length > 0) {
321
+ const w = rest.shift();
322
+ if (exe === 'git' && (w === '-C' || w === '-c' || w === '--git-dir' || w === '--work-tree')) {
323
+ rest.shift();
324
+ continue;
325
+ }
326
+ if (w.startsWith('-'))
327
+ continue;
328
+ if (SUB_WORD.test(w))
329
+ sub = w;
330
+ break;
331
+ }
332
+ let label = sub ? `${exe} ${sub}` : exe;
333
+ if (sub && (sub === 'run' || sub === 'run-script') && (exe === 'npm' || exe === 'pnpm' || exe === 'yarn' || exe === 'bun')) {
334
+ const script = rest.find((w) => !w.startsWith('-'));
335
+ if (script && SUB_WORD.test(script))
336
+ label = `${exe} run ${script}`;
337
+ }
338
+ return { label, executable: exe, args };
339
+ }
340
+ if (INTERPRETERS.has(exe)) {
341
+ const first = args.find((w) => !w.startsWith('-'));
342
+ const inline = args.some((w) => w === '-c' || w === '-e' || w === '--eval' || w === '-p');
343
+ const module = args[0] === '-m' && args[1] && /^[A-Za-z_][\w.]{0,40}$/.test(args[1]) ? args[1] : null;
344
+ if (module)
345
+ return { label: `${exe} -m ${module}`, executable: exe, args };
346
+ if (inline)
347
+ return { label: `${exe} (inline script)`, executable: exe, args };
348
+ if (first && SCRIPT_FILE.test(first)) {
349
+ const file = path.posix.basename(first);
350
+ if (/^[\w.-]{1,50}$/.test(file) && !looksLikeToken(file.replace(/\.[^.]+$/, '')))
351
+ return { label: `${exe} ${file}`, executable: exe, args };
352
+ }
353
+ return { label: exe, executable: exe, args };
354
+ }
355
+ return { label: exe, executable: exe, args };
356
+ }
357
+ return null;
358
+ }
359
+ //# sourceMappingURL=board-redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-redact.js","sourceRoot":"","sources":["../../../../../../backend/src/services/board/board-redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,GAAG,GAAG,eAAe,CAAC,QAAQ,CAAC;AAErC,uCAAuC;AACvC,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAY,CAAC;AAErC,MAAM,WAAW,GAAG,4CAA4C,CAAC;AACjE,MAAM,KAAK,GAAG,oEAAoE,CAAC;AACnF,MAAM,SAAS,GAAG,mEAAmE,CAAC;AACtF,MAAM,MAAM,GAAG,+CAA+C,CAAC;AAC/D,sEAAsE;AACtE,MAAM,iBAAiB,GAAG,8JAA8J,CAAC;AACzL,MAAM,WAAW,GAAG,6FAA6F,CAAC;AAClH,MAAM,YAAY,GACjB,0QAA0Q,CAAC;AAC5Q,uEAAuE;AACvE,MAAM,KAAK,GAAG,0CAA0C,CAAC;AACzD,MAAM,UAAU,GAAG,4CAA4C,CAAC;AAChE,MAAM,QAAQ,GAAG,uBAAuB,CAAC;AAEzC;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,CAAS;IACvC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7D,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACtG,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACtG,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,IAAI,CAAC,CAAS,EAAE,MAAc,GAAG;IAChD,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC;AACzD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACpC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACJ,GAAG,GAAG,IAAI,GAAG,CAAC,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC;IAC1F,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,IAAI,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IACvD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ;SAC3B,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACZ,IAAI,CAAC,GAAG,GAAG,CAAC;QACZ,IAAI,CAAC;YACJ,CAAC,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACR,WAAW;QACZ,CAAC;QACD,IAAI,cAAc,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,EAAE;YAAE,OAAO,KAAK,CAAC;QAC1E,OAAO,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IACJ,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACzE,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,MAAc,GAAG;IAC1D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC/D,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3D,4CAA4C;IAC5C,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAC9C,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAChC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,KAAK,QAAQ,EAAE,CAAC,CAAC;IAClD,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC,CAAC;IAC5C,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACtC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAClC,OAAO,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,4CAA4C;AAC5C,MAAM,YAAY,GAAG,oCAAoC,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,QAA2B,EAAE;IACvE,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IACrI,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAChB,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM;QACP,CAAC;QACD,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;YAC9B,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YACjE,MAAM;QACP,CAAC;IACF,CAAC;IACD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9C,IAAI,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;YAAE,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;aAChG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAChE,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC3C,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,CAAC,GAAG,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9D,CAAC;QACD,GAAG,GAAG,CAAC,CAAC;IACT,CAAC;IACD,MAAM,OAAO,GAAG,GAAG;SACjB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SACjD,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACzC,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC5C,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,+EAA+E;AAC/E,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAChC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IACrI,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ;CACzH,CAAC,CAAC;AACH,8CAA8C;AAC9C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAClI,6CAA6C;AAC7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;AAClI,wCAAwC;AACxC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAEnK,MAAM,QAAQ,GAAG,0BAA0B,CAAC;AAC5C,MAAM,WAAW,GAAG,2CAA2C,CAAC;AAChE,MAAM,UAAU,GAAG,yBAAyB,CAAC;AAC7C,MAAM,YAAY,GAAG,gDAAgD,CAAC;AAEtE;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC3C,MAAM,QAAQ,GAAe,EAAE,CAAC;IAChC,IAAI,KAAK,GAAa,EAAE,CAAC;IACzB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,IAAI,KAAK,GAAqB,IAAI,CAAC;IACnC,MAAM,OAAO,GAAG,GAAS,EAAE;QAC1B,IAAI,GAAG;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,GAAG,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,KAAK,CAAC;IACb,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,GAAS,EAAE;QAC7B,OAAO,EAAE,CAAC;QACV,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,KAAK,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC;IACF,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACnE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACf,IAAI,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,KAAK,KAAK;gBAAE,KAAK,GAAG,IAAI,CAAC;iBACzB,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM;gBAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;;gBACxE,GAAG,IAAI,CAAC,CAAC;YACd,SAAS;QACV,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAC5B,KAAK,GAAG,CAAC,CAAC;YACV,GAAG,GAAG,IAAI,CAAC;QACZ,CAAC;aAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YAC3C,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,GAAG,GAAG,IAAI,CAAC;QACZ,CAAC;aAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9D,mDAAmD;YACnD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;gBACtF,GAAG,IAAI,CAAC,CAAC;gBACT,GAAG,GAAG,IAAI,CAAC;gBACX,SAAS;YACV,CAAC;YACD,UAAU,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;gBAAE,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO,EAAE,CAAC;QACX,CAAC;aAAM,CAAC;YACP,GAAG,IAAI,CAAC,CAAC;YACT,GAAG,GAAG,IAAI,CAAC;QACZ,CAAC;IACF,CAAC;IACD,UAAU,EAAE,CAAC;IACb,OAAO,QAAQ,CAAC;AACjB,CAAC;AAcD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC5C,KAAK,MAAM,QAAQ,IAAI,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC5B,mCAAmC;QACnC,SAAS,CAAC;YACT,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,KAAK,SAAS;gBAAE,MAAM;YAC3B,IAAI,0BAA0B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,SAAS;YACV,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACpC,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,kDAAkD;gBAClD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;oBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;gBAClJ,SAAS;YACV,CAAC;YACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACxB,KAAK,CAAC,KAAK,EAAE,CAAC;gBACd,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;oBAAE,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC5G,SAAS;YACV,CAAC;YACD,MAAM;QACP,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5D,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/J,IAAI,UAAU,EAAE,CAAC;YAChB,OAAO,EAAE,KAAK,EAAE,SAAS,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxI,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACnH,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YACvB,IAAI,GAAuB,CAAC;YAC5B,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,EAAY,CAAC;gBACjC,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,KAAK,aAAa,CAAC,EAAE,CAAC;oBAC7F,IAAI,CAAC,KAAK,EAAE,CAAC;oBACb,SAAS;gBACV,CAAC;gBACD,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAChC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;oBAAE,GAAG,GAAG,CAAC,CAAC;gBAC9B,MAAM;YACP,CAAC;YACD,IAAI,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YACxC,IAAI,GAAG,IAAI,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,YAAY,CAAC,IAAI,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,EAAE,CAAC;gBAC5H,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;gBACpD,IAAI,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;oBAAE,KAAK,GAAG,GAAG,GAAG,QAAQ,MAAM,EAAE,CAAC;YACrE,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QACzC,CAAC;QACD,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;YAC1F,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACtG,IAAI,MAAM;gBAAE,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,MAAM,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YAC3E,IAAI,MAAM;gBAAE,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,kBAAkB,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YAC9E,IAAI,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACxC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;oBAAE,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;YAC7I,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QAC9C,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Board snapshot builder (crewly#1247): turns what the machine knows (teams,
3
+ * runtime turn state, WorkItems, tickets, decisions, the usage ledger and the
4
+ * live activity tracker) into the {@link BoardSnapshot} Cloud and the local
5
+ * dashboard show.
6
+ *
7
+ * Everything is read through {@link BoardSources}, so the builder is a pure
8
+ * function of its inputs and is tested with fixtures. A full build refreshes
9
+ * a cache (roster, usage, tasks, owner waits); the per-agent delta rows are
10
+ * built from that cache plus the live activity, so a delta never rescans the
11
+ * disk.
12
+ *
13
+ * Every text in the result went through {@link scrubText}.
14
+ *
15
+ * @module services/board/board-snapshot.builder
16
+ */
17
+ import type { BoardActivityTracker } from './board-activity.tracker.js';
18
+ import type { BoardAgent, BoardSnapshot, BoardSpend, BoardWaitingItem } from './board.types.js';
19
+ /** One agent as the team config knows it. */
20
+ export interface BoardMember {
21
+ session: string;
22
+ name: string;
23
+ role: string;
24
+ runtime: string;
25
+ model?: string;
26
+ agentStatus: string;
27
+ workingStatus: string;
28
+ }
29
+ /** One team as the team config knows it. */
30
+ export interface BoardTeamInfo {
31
+ teamId: string;
32
+ name: string;
33
+ paused?: boolean;
34
+ members: BoardMember[];
35
+ }
36
+ /** The WorkItem fields the board reads. */
37
+ export interface BoardWorkItem {
38
+ id: string;
39
+ title: string;
40
+ type: string;
41
+ status: string;
42
+ target?: string;
43
+ requestId?: string;
44
+ /** Project ticket this item works on */
45
+ projectTaskId?: string;
46
+ createdAt: string;
47
+ startedAt?: string;
48
+ completedAt?: string;
49
+ statusChangedAt?: string;
50
+ scheduledAt?: string;
51
+ blockedReason?: string;
52
+ blockSource?: string;
53
+ error?: string;
54
+ }
55
+ /** The ticket fields the board reads (harness tickets and project tickets alike). */
56
+ export interface BoardTicket {
57
+ id: string;
58
+ /** `TKT-12` / `CE-7` */
59
+ label?: string;
60
+ title: string;
61
+ kind?: string;
62
+ /** `done`, `to_review`, `blocked`, `in_progress`, ... */
63
+ column: string;
64
+ assignee?: string;
65
+ teamId?: string;
66
+ submittedAt?: string;
67
+ completedAt?: string;
68
+ updatedAt: string;
69
+ }
70
+ /** An open decision card. */
71
+ export interface BoardDecision {
72
+ id: string;
73
+ kind: 'decision' | 'approval' | 'question';
74
+ title: string;
75
+ /** Session that asked (the agent that waits for the answer) */
76
+ asker?: string;
77
+ teamId?: string;
78
+ createdAt: string;
79
+ }
80
+ /** What the usage ledger says. */
81
+ export interface BoardUsage {
82
+ perAgent: Map<string, {
83
+ todayUsd: number;
84
+ todayTokens: number;
85
+ }>;
86
+ spend: BoardSpend;
87
+ /** Open ledger unit each agent worked on most recently */
88
+ taskOf: Map<string, {
89
+ id?: string;
90
+ title: string;
91
+ since: string;
92
+ }>;
93
+ }
94
+ /** Everything the builder reads. All reads are best-effort; a failing source is an empty one. */
95
+ export interface BoardSources {
96
+ identity(): Promise<{
97
+ instanceId: string;
98
+ machineName: string;
99
+ }>;
100
+ version(): Promise<string>;
101
+ teams(): Promise<BoardTeamInfo[]>;
102
+ /** Runtime turn state for a session */
103
+ turnState(session: string, now: number): 'working' | 'idle' | 'unknown';
104
+ /** A permission prompt / question is open in the agent's terminal */
105
+ waitingOnHuman(session: string): boolean;
106
+ /** Messages queued or deferred for the agent */
107
+ queuedFor(session: string): number;
108
+ /** The agent crashed / is stuck in an error the runtime reports, if any */
109
+ errorOf?(session: string): string | null;
110
+ /** Background work that stopped making progress (#1251) */
111
+ stalledBackground(session: string, now: number): {
112
+ since: number;
113
+ description?: string;
114
+ } | null;
115
+ workItems(): Promise<BoardWorkItem[]>;
116
+ tickets(): Promise<BoardTicket[]>;
117
+ decisions(): Promise<BoardDecision[]>;
118
+ /** Other things that wait on the owner (doc-comment batches, held mail, reconnect cards), already shaped */
119
+ holds(): Promise<BoardWaitingItem[]>;
120
+ usage(now: number): Promise<BoardUsage>;
121
+ /** What each agent is on now: its running WorkItem or the ticket of its turn */
122
+ activeWork(): Promise<Map<string, {
123
+ id?: string;
124
+ title: string;
125
+ since: string;
126
+ }>>;
127
+ }
128
+ /** Local midnight of `now`. */
129
+ export declare function startOfLocalDay(now: number): number;
130
+ /**
131
+ * Builds board snapshots and per-agent rows.
132
+ */
133
+ export declare class BoardSnapshotBuilder {
134
+ private readonly sources;
135
+ private readonly tracker;
136
+ private readonly clock;
137
+ private cache;
138
+ /**
139
+ * @param sources - Everything the board reads
140
+ * @param tracker - Live activity
141
+ * @param clock - Clock (tests)
142
+ */
143
+ constructor(sources: BoardSources, tracker: BoardActivityTracker, clock?: () => number);
144
+ /** Whether a full build has filled the cache. */
145
+ get primed(): boolean;
146
+ /** This machine's identity. */
147
+ identity(): Promise<{
148
+ instanceId: string;
149
+ machineName: string;
150
+ }>;
151
+ /** Sessions known from the last full build. */
152
+ knownSessions(): string[];
153
+ private safe;
154
+ /**
155
+ * Build the full snapshot and refresh the cache.
156
+ *
157
+ * @returns The snapshot
158
+ */
159
+ build(): Promise<BoardSnapshot>;
160
+ /**
161
+ * Rows for some agents, from the cache and the live activity. No disk or
162
+ * network reads.
163
+ *
164
+ * @param sessions - Sessions to build
165
+ * @returns Rows of the known sessions
166
+ */
167
+ rows(sessions: Iterable<string>): Array<BoardAgent & {
168
+ teamId: string;
169
+ }>;
170
+ private row;
171
+ private safeSync;
172
+ private doneToday;
173
+ private waiting;
174
+ private stuck;
175
+ }
176
+ //# sourceMappingURL=board-snapshot.builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-snapshot.builder.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/board/board-snapshot.builder.ts"],"names":[],"mappings":"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"}