crewly 1.20.306 → 1.20.308
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.
- package/config/hooks/agent-status/report.sh +39 -1
- package/dist/backend/backend/src/constants.d.ts +120 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +120 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts +2 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js +18 -1
- package/dist/backend/backend/src/controllers/agent-hooks/agent-hooks.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/board/board.controller.d.ts +23 -0
- package/dist/backend/backend/src/controllers/board/board.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/board/board.controller.js +48 -0
- package/dist/backend/backend/src/controllers/board/board.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/board/board.routes.d.ts +15 -0
- package/dist/backend/backend/src/controllers/board/board.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/board/board.routes.js +21 -0
- package/dist/backend/backend/src/controllers/board/board.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/browser/browser.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/browser/browser.controller.js +2 -0
- package/dist/backend/backend/src/controllers/browser/browser.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/chat/chat.controller.js +5 -0
- package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/slack/slack.controller.js +3 -0
- package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +18 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +172 -2
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +3 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/services/board/board-activity.normalizer.d.ts +102 -0
- package/dist/backend/backend/src/services/board/board-activity.normalizer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-activity.normalizer.js +244 -0
- package/dist/backend/backend/src/services/board/board-activity.normalizer.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-activity.tracker.d.ts +159 -0
- package/dist/backend/backend/src/services/board/board-activity.tracker.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-activity.tracker.js +346 -0
- package/dist/backend/backend/src/services/board/board-activity.tracker.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-outcome-phrases.d.ts +43 -0
- package/dist/backend/backend/src/services/board/board-outcome-phrases.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-outcome-phrases.js +76 -0
- package/dist/backend/backend/src/services/board/board-outcome-phrases.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-push.service.d.ts +132 -0
- package/dist/backend/backend/src/services/board/board-push.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-push.service.js +374 -0
- package/dist/backend/backend/src/services/board/board-push.service.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-redact.d.ts +90 -0
- package/dist/backend/backend/src/services/board/board-redact.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-redact.js +359 -0
- package/dist/backend/backend/src/services/board/board-redact.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-snapshot.builder.d.ts +183 -0
- package/dist/backend/backend/src/services/board/board-snapshot.builder.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-snapshot.builder.js +344 -0
- package/dist/backend/backend/src/services/board/board-snapshot.builder.js.map +1 -0
- package/dist/backend/backend/src/services/board/board-usage.d.ts +20 -0
- package/dist/backend/backend/src/services/board/board-usage.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board-usage.js +82 -0
- package/dist/backend/backend/src/services/board/board-usage.js.map +1 -0
- package/dist/backend/backend/src/services/board/board.service.d.ts +60 -0
- package/dist/backend/backend/src/services/board/board.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board.service.js +82 -0
- package/dist/backend/backend/src/services/board/board.service.js.map +1 -0
- package/dist/backend/backend/src/services/board/board.sources.d.ts +25 -0
- package/dist/backend/backend/src/services/board/board.sources.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board.sources.js +300 -0
- package/dist/backend/backend/src/services/board/board.sources.js.map +1 -0
- package/dist/backend/backend/src/services/board/board.types.d.ts +122 -0
- package/dist/backend/backend/src/services/board/board.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/board.types.js +8 -0
- package/dist/backend/backend/src/services/board/board.types.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-inbound.service.d.ts +122 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-inbound.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-inbound.service.js +339 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-inbound.service.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-redact.d.ts +44 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-redact.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-redact.js +161 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-redact.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.normalizer.d.ts +57 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.normalizer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.normalizer.js +164 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.normalizer.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.stream.d.ts +140 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.stream.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.stream.js +300 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-step.stream.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-terminal.service.d.ts +99 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-terminal.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-terminal.service.js +223 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-terminal.service.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-transcript.tail.d.ts +126 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-transcript.tail.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-transcript.tail.js +385 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-transcript.tail.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-wiring.d.ts +103 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-wiring.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-wiring.js +124 -0
- package/dist/backend/backend/src/services/board/canvas/canvas-wiring.js.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas.types.d.ts +88 -0
- package/dist/backend/backend/src/services/board/canvas/canvas.types.d.ts.map +1 -0
- package/dist/backend/backend/src/services/board/canvas/canvas.types.js +8 -0
- package/dist/backend/backend/src/services/board/canvas/canvas.types.js.map +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/backend/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- package/dist/backend/backend/src/services/google/google-reauth-notifier.service.d.ts +13 -0
- package/dist/backend/backend/src/services/google/google-reauth-notifier.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/google/google-reauth-notifier.service.js +15 -0
- package/dist/backend/backend/src/services/google/google-reauth-notifier.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js +2 -1
- package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +120 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +120 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.d.ts.map +1 -1
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js +1 -0
- package/dist/cli/backend/src/services/cloud/cloud-sync.types.js.map +1 -1
- 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":"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"}
|
|
@@ -0,0 +1,183 @@
|
|
|
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
|
+
import type { AgentCapabilities } from './canvas/canvas.types.js';
|
|
20
|
+
/** One agent as the team config knows it. */
|
|
21
|
+
export interface BoardMember {
|
|
22
|
+
session: string;
|
|
23
|
+
name: string;
|
|
24
|
+
role: string;
|
|
25
|
+
runtime: string;
|
|
26
|
+
model?: string;
|
|
27
|
+
agentStatus: string;
|
|
28
|
+
workingStatus: string;
|
|
29
|
+
}
|
|
30
|
+
/** One team as the team config knows it. */
|
|
31
|
+
export interface BoardTeamInfo {
|
|
32
|
+
teamId: string;
|
|
33
|
+
name: string;
|
|
34
|
+
paused?: boolean;
|
|
35
|
+
members: BoardMember[];
|
|
36
|
+
}
|
|
37
|
+
/** The WorkItem fields the board reads. */
|
|
38
|
+
export interface BoardWorkItem {
|
|
39
|
+
id: string;
|
|
40
|
+
title: string;
|
|
41
|
+
type: string;
|
|
42
|
+
status: string;
|
|
43
|
+
target?: string;
|
|
44
|
+
requestId?: string;
|
|
45
|
+
/** Project ticket this item works on */
|
|
46
|
+
projectTaskId?: string;
|
|
47
|
+
createdAt: string;
|
|
48
|
+
startedAt?: string;
|
|
49
|
+
completedAt?: string;
|
|
50
|
+
statusChangedAt?: string;
|
|
51
|
+
scheduledAt?: string;
|
|
52
|
+
blockedReason?: string;
|
|
53
|
+
blockSource?: string;
|
|
54
|
+
error?: string;
|
|
55
|
+
}
|
|
56
|
+
/** The ticket fields the board reads (harness tickets and project tickets alike). */
|
|
57
|
+
export interface BoardTicket {
|
|
58
|
+
id: string;
|
|
59
|
+
/** `TKT-12` / `CE-7` */
|
|
60
|
+
label?: string;
|
|
61
|
+
title: string;
|
|
62
|
+
kind?: string;
|
|
63
|
+
/** `done`, `to_review`, `blocked`, `in_progress`, ... */
|
|
64
|
+
column: string;
|
|
65
|
+
assignee?: string;
|
|
66
|
+
teamId?: string;
|
|
67
|
+
submittedAt?: string;
|
|
68
|
+
completedAt?: string;
|
|
69
|
+
updatedAt: string;
|
|
70
|
+
}
|
|
71
|
+
/** An open decision card. */
|
|
72
|
+
export interface BoardDecision {
|
|
73
|
+
id: string;
|
|
74
|
+
kind: 'decision' | 'approval' | 'question';
|
|
75
|
+
title: string;
|
|
76
|
+
/** Session that asked (the agent that waits for the answer) */
|
|
77
|
+
asker?: string;
|
|
78
|
+
teamId?: string;
|
|
79
|
+
createdAt: string;
|
|
80
|
+
}
|
|
81
|
+
/** What the usage ledger says. */
|
|
82
|
+
export interface BoardUsage {
|
|
83
|
+
perAgent: Map<string, {
|
|
84
|
+
todayUsd: number;
|
|
85
|
+
todayTokens: number;
|
|
86
|
+
}>;
|
|
87
|
+
spend: BoardSpend;
|
|
88
|
+
/** Open ledger unit each agent worked on most recently */
|
|
89
|
+
taskOf: Map<string, {
|
|
90
|
+
id?: string;
|
|
91
|
+
title: string;
|
|
92
|
+
since: string;
|
|
93
|
+
}>;
|
|
94
|
+
}
|
|
95
|
+
/** Everything the builder reads. All reads are best-effort; a failing source is an empty one. */
|
|
96
|
+
export interface BoardSources {
|
|
97
|
+
identity(): Promise<{
|
|
98
|
+
instanceId: string;
|
|
99
|
+
machineName: string;
|
|
100
|
+
}>;
|
|
101
|
+
version(): Promise<string>;
|
|
102
|
+
teams(): Promise<BoardTeamInfo[]>;
|
|
103
|
+
/** Runtime turn state for a session */
|
|
104
|
+
turnState(session: string, now: number): 'working' | 'idle' | 'unknown';
|
|
105
|
+
/** A permission prompt / question is open in the agent's terminal */
|
|
106
|
+
waitingOnHuman(session: string): boolean;
|
|
107
|
+
/** Messages queued or deferred for the agent */
|
|
108
|
+
queuedFor(session: string): number;
|
|
109
|
+
/** The agent crashed / is stuck in an error the runtime reports, if any */
|
|
110
|
+
errorOf?(session: string): string | null;
|
|
111
|
+
/** Background work that stopped making progress (#1251) */
|
|
112
|
+
stalledBackground(session: string, now: number): {
|
|
113
|
+
since: number;
|
|
114
|
+
description?: string;
|
|
115
|
+
} | null;
|
|
116
|
+
workItems(): Promise<BoardWorkItem[]>;
|
|
117
|
+
tickets(): Promise<BoardTicket[]>;
|
|
118
|
+
decisions(): Promise<BoardDecision[]>;
|
|
119
|
+
/** Other things that wait on the owner (doc-comment batches, held mail, reconnect cards), already shaped */
|
|
120
|
+
holds(): Promise<BoardWaitingItem[]>;
|
|
121
|
+
usage(now: number): Promise<BoardUsage>;
|
|
122
|
+
/** What each agent is on now: its running WorkItem or the ticket of its turn */
|
|
123
|
+
activeWork(): Promise<Map<string, {
|
|
124
|
+
id?: string;
|
|
125
|
+
title: string;
|
|
126
|
+
since: string;
|
|
127
|
+
}>>;
|
|
128
|
+
/** What the owner can do with an agent from the canvas (crewly#1247 v2); omitted = no capabilities in the rows */
|
|
129
|
+
capabilities?(session: string, info: {
|
|
130
|
+
runtime: string;
|
|
131
|
+
stopped: boolean;
|
|
132
|
+
now: number;
|
|
133
|
+
}): AgentCapabilities;
|
|
134
|
+
}
|
|
135
|
+
/** Local midnight of `now`. */
|
|
136
|
+
export declare function startOfLocalDay(now: number): number;
|
|
137
|
+
/**
|
|
138
|
+
* Builds board snapshots and per-agent rows.
|
|
139
|
+
*/
|
|
140
|
+
export declare class BoardSnapshotBuilder {
|
|
141
|
+
private readonly sources;
|
|
142
|
+
private readonly tracker;
|
|
143
|
+
private readonly clock;
|
|
144
|
+
private cache;
|
|
145
|
+
/**
|
|
146
|
+
* @param sources - Everything the board reads
|
|
147
|
+
* @param tracker - Live activity
|
|
148
|
+
* @param clock - Clock (tests)
|
|
149
|
+
*/
|
|
150
|
+
constructor(sources: BoardSources, tracker: BoardActivityTracker, clock?: () => number);
|
|
151
|
+
/** Whether a full build has filled the cache. */
|
|
152
|
+
get primed(): boolean;
|
|
153
|
+
/** This machine's identity. */
|
|
154
|
+
identity(): Promise<{
|
|
155
|
+
instanceId: string;
|
|
156
|
+
machineName: string;
|
|
157
|
+
}>;
|
|
158
|
+
/** Sessions known from the last full build. */
|
|
159
|
+
knownSessions(): string[];
|
|
160
|
+
private safe;
|
|
161
|
+
/**
|
|
162
|
+
* Build the full snapshot and refresh the cache.
|
|
163
|
+
*
|
|
164
|
+
* @returns The snapshot
|
|
165
|
+
*/
|
|
166
|
+
build(): Promise<BoardSnapshot>;
|
|
167
|
+
/**
|
|
168
|
+
* Rows for some agents, from the cache and the live activity. No disk or
|
|
169
|
+
* network reads.
|
|
170
|
+
*
|
|
171
|
+
* @param sessions - Sessions to build
|
|
172
|
+
* @returns Rows of the known sessions
|
|
173
|
+
*/
|
|
174
|
+
rows(sessions: Iterable<string>): Array<BoardAgent & {
|
|
175
|
+
teamId: string;
|
|
176
|
+
}>;
|
|
177
|
+
private row;
|
|
178
|
+
private safeSync;
|
|
179
|
+
private doneToday;
|
|
180
|
+
private waiting;
|
|
181
|
+
private stuck;
|
|
182
|
+
}
|
|
183
|
+
//# 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":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EACX,UAAU,EAGV,aAAa,EACb,UAAU,EAGV,gBAAgB,EAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,4CAA4C;AAC5C,MAAM,WAAW,aAAa;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,WAAW,EAAE,CAAC;CACvB;AAED,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,wBAAwB;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,6BAA6B;AAC7B,MAAM,WAAW,aAAa;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,kCAAkC;AAClC,MAAM,WAAW,UAAU;IAC1B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,KAAK,EAAE,UAAU,CAAC;IAClB,0DAA0D;IAC1D,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACnE;AAED,iGAAiG;AACjG,MAAM,WAAW,YAAY;IAC5B,QAAQ,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjE,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3B,KAAK,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAClC,uCAAuC;IACvC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IACxE,qEAAqE;IACrE,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IACzC,gDAAgD;IAChD,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IACnC,2EAA2E;IAC3E,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACzC,2DAA2D;IAC3D,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChG,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACtC,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAClC,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACtC,4GAA4G;IAC5G,KAAK,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACrC,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,gFAAgF;IAChF,UAAU,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAClF,kHAAkH;IAClH,YAAY,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,iBAAiB,CAAC;CAC5G;AAWD,+BAA+B;AAC/B,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAInD;AAaD;;GAEG;AACH,qBAAa,oBAAoB;IAS/B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAVvB,OAAO,CAAC,KAAK,CAAiF;IAE9F;;;;OAIG;gBAEe,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,oBAAoB,EAC7B,KAAK,GAAE,MAAM,MAAiB;IAGhD,iDAAiD;IACjD,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,+BAA+B;IAC/B,QAAQ,IAAI,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAIhE,+CAA+C;IAC/C,aAAa,IAAI,MAAM,EAAE;YAIX,IAAI;IAQlB;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC;IAkDrC;;;;;;OAMG;IACH,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,UAAU,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAexE,OAAO,CAAC,GAAG;IA+CX,OAAO,CAAC,QAAQ;IAYhB,OAAO,CAAC,SAAS;IA8CjB,OAAO,CAAC,OAAO;IAmCf,OAAO,CAAC,KAAK;CAoDb"}
|