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,312 @@
1
+ /**
2
+ * Pushes the owner board to Crewly Cloud (crewly#1247).
3
+ *
4
+ * - a full snapshot every 60 s (Cloud may ask for another cadence);
5
+ * - a delta (only the agent rows that changed, plus new timeline events)
6
+ * within {@link BOARD_CONSTANTS.DELTA_DELAY_MS} of an activity change;
7
+ * - gzip bodies, exponential backoff on failure, an hour's pause when Cloud
8
+ * does not take board pushes (not deployed / refusing);
9
+ * - nothing is sent when the machine is not signed in to Cloud, or when
10
+ * `CREWLY_BOARD_PUSH=0`.
11
+ *
12
+ * Event-driven: a change only marks a session dirty and arms one timer; the
13
+ * delta is built from the builder's cache and the live tracker, never from a
14
+ * disk scan.
15
+ *
16
+ * @module services/board/board-push.service
17
+ */
18
+ import { gzipSync } from 'zlib';
19
+ import { BOARD_CONSTANTS } from '../../constants.js';
20
+ import { LoggerService } from '../core/logger.service.js';
21
+ const C = BOARD_CONSTANTS;
22
+ /**
23
+ * Whether the board push is switched off.
24
+ *
25
+ * @param env - Environment
26
+ * @returns True for `CREWLY_BOARD_PUSH=0` (also `false` / `off`)
27
+ */
28
+ export function isBoardPushDisabled(env = process.env) {
29
+ const v = (env[C.ENV_SWITCH] ?? '').trim().toLowerCase();
30
+ return v === '0' || v === 'false' || v === 'off' || v === 'no';
31
+ }
32
+ /**
33
+ * Shrink a snapshot until its JSON fits the body limit: the longest list
34
+ * loses its tail first.
35
+ *
36
+ * @param snapshot - Snapshot (mutated)
37
+ * @returns The same snapshot
38
+ */
39
+ export function fitSnapshot(snapshot) {
40
+ const size = () => Buffer.byteLength(JSON.stringify(snapshot));
41
+ const lists = [snapshot.outcomes.doneToday, snapshot.outcomes.stuck, snapshot.outcomes.waitingOnOwner];
42
+ let guard = 0;
43
+ while (size() > C.MAX_BODY_BYTES && guard < 500) {
44
+ guard += 1;
45
+ const longest = lists.reduce((a, b) => (b.length > a.length ? b : a), lists[0]);
46
+ if (longest.length > 0) {
47
+ longest.length = Math.floor(longest.length / 2);
48
+ continue;
49
+ }
50
+ // Only agents are left: drop the last agent of the biggest team
51
+ const team = [...snapshot.teams].sort((a, b) => b.agents.length - a.agents.length)[0];
52
+ if (!team || team.agents.length === 0)
53
+ break;
54
+ team.agents.pop();
55
+ }
56
+ return snapshot;
57
+ }
58
+ /** Pushes snapshots and deltas. */
59
+ export class BoardPushService {
60
+ deps;
61
+ logger;
62
+ fetchImpl;
63
+ now;
64
+ setTimer;
65
+ clearTimer;
66
+ started = false;
67
+ fullTimer = null;
68
+ deltaTimer = null;
69
+ unsubscribe = null;
70
+ dirty = new Set();
71
+ /** Rows Cloud has, as JSON, by session */
72
+ lastSent = new Map();
73
+ lastToken = null;
74
+ fullOk = false;
75
+ fullAfterMs = C.FULL_INTERVAL_MS;
76
+ failures = 0;
77
+ pausedUntil = 0;
78
+ pauseLogged = false;
79
+ inFlight = Promise.resolve();
80
+ constructor(deps) {
81
+ this.deps = deps;
82
+ this.logger = deps.logger ?? LoggerService.getInstance().createComponentLogger('BoardPush');
83
+ this.fetchImpl = deps.fetchImpl ?? ((input, init) => fetch(input, init));
84
+ this.now = deps.now ?? Date.now;
85
+ this.setTimer =
86
+ deps.setTimeout ??
87
+ ((fn, ms) => {
88
+ const t = setTimeout(fn, ms);
89
+ t.unref?.();
90
+ return t;
91
+ });
92
+ this.clearTimer = deps.clearTimeout ?? ((h) => clearTimeout(h));
93
+ }
94
+ /** Whether the push is switched off in the environment. */
95
+ get disabled() {
96
+ return isBoardPushDisabled(this.deps.env ?? process.env);
97
+ }
98
+ /** Start pushing. Idempotent; a no-op when switched off. Never throws. */
99
+ start() {
100
+ if (this.started || this.disabled)
101
+ return;
102
+ this.started = true;
103
+ this.unsubscribe = this.deps.tracker.onChange((session) => this.markDirty(session));
104
+ this.scheduleFull(0);
105
+ }
106
+ /** Stop timers and the subscription. */
107
+ stop() {
108
+ this.started = false;
109
+ if (this.fullTimer)
110
+ this.clearTimer(this.fullTimer);
111
+ if (this.deltaTimer)
112
+ this.clearTimer(this.deltaTimer);
113
+ this.fullTimer = null;
114
+ this.deltaTimer = null;
115
+ this.unsubscribe?.();
116
+ this.unsubscribe = null;
117
+ this.dirty.clear();
118
+ }
119
+ /**
120
+ * A session's row may have changed: send a delta soon.
121
+ *
122
+ * @param session - Agent session
123
+ */
124
+ markDirty(session) {
125
+ if (!this.started)
126
+ return;
127
+ this.dirty.add(session);
128
+ if (this.deltaTimer)
129
+ return;
130
+ this.deltaTimer = this.setTimer(() => {
131
+ this.deltaTimer = null;
132
+ void this.flushDelta();
133
+ }, C.DELTA_DELAY_MS);
134
+ }
135
+ scheduleFull(delayMs) {
136
+ if (!this.started)
137
+ return;
138
+ if (this.fullTimer)
139
+ this.clearTimer(this.fullTimer);
140
+ this.fullTimer = this.setTimer(() => {
141
+ this.fullTimer = null;
142
+ void this.pushFull().finally(() => this.scheduleFull(this.nextFullDelay()));
143
+ }, delayMs);
144
+ }
145
+ nextFullDelay() {
146
+ // A failure retries by its own backoff (or pause), not by the 60 s cadence
147
+ const remaining = this.pausedUntil - this.now();
148
+ return remaining > 0 ? remaining : this.fullAfterMs;
149
+ }
150
+ /** The Cloud endpoint and token, or null when the machine is not signed in or a pause is on. */
151
+ target() {
152
+ if (this.disabled)
153
+ return null;
154
+ const token = this.deps.cloud.getToken();
155
+ const base = this.deps.cloud.getCloudUrl();
156
+ if (!token || !base)
157
+ return null;
158
+ if (token !== this.lastToken) {
159
+ // New sign-in / refreshed token: Cloud's copy may be another account's; resend everything
160
+ if (this.lastToken !== null)
161
+ this.fullOk = false;
162
+ this.lastToken = token;
163
+ }
164
+ if (this.now() < this.pausedUntil)
165
+ return 'paused';
166
+ return { base: base.replace(/\/$/, ''), token };
167
+ }
168
+ /**
169
+ * Build and send the full snapshot, then any timeline events that are
170
+ * waiting. Serialised with deltas. Never throws.
171
+ *
172
+ * @returns What happened
173
+ */
174
+ pushFull() {
175
+ const run = this.inFlight.then(() => this.doFull()).catch(() => 'failed');
176
+ this.inFlight = run;
177
+ return run;
178
+ }
179
+ async doFull() {
180
+ const target = this.target();
181
+ if (target === null)
182
+ return 'skipped';
183
+ if (target === 'paused')
184
+ return 'paused';
185
+ const snapshot = fitSnapshot(await this.deps.builder.build());
186
+ const outcome = await this.post(target, C.SNAPSHOT_PATH, snapshot, snapshot.instanceId);
187
+ if (outcome !== 'sent')
188
+ return outcome;
189
+ this.fullOk = true;
190
+ this.lastSent.clear();
191
+ for (const team of snapshot.teams)
192
+ for (const a of team.agents)
193
+ this.lastSent.set(a.session, JSON.stringify(a));
194
+ this.dirty.clear();
195
+ // Timeline events ride in deltas
196
+ const pending = this.deps.tracker.sessionsWithUnsent();
197
+ if (pending.length > 0)
198
+ await this.doDelta(new Set(pending));
199
+ return 'sent';
200
+ }
201
+ /**
202
+ * Send a delta for the sessions marked dirty. Serialised with full pushes.
203
+ * Never throws.
204
+ *
205
+ * @returns What happened
206
+ */
207
+ flushDelta() {
208
+ const sessions = new Set(this.dirty);
209
+ this.dirty.clear();
210
+ const run = this.inFlight.then(() => this.doDelta(sessions)).catch(() => 'failed');
211
+ this.inFlight = run;
212
+ return run;
213
+ }
214
+ async doDelta(sessions) {
215
+ if (sessions.size === 0)
216
+ return 'nothing';
217
+ const target = this.target();
218
+ // The next full snapshot carries the rows; a delta before the first one is pointless
219
+ if (target === null || target === 'paused' || !this.fullOk || !this.deps.builder.primed)
220
+ return target === 'paused' ? 'paused' : 'skipped';
221
+ const rows = this.deps.builder.rows(sessions);
222
+ const changed = rows.filter((r) => this.lastSent.get(r.session) !== JSON.stringify(stripTeam(r)));
223
+ const timeline = this.deps.tracker.peekUnsent(sessions);
224
+ if (changed.length === 0 && timeline.length === 0)
225
+ return 'nothing';
226
+ const instanceId = (await this.deps.builder.identity()).instanceId;
227
+ const body = {
228
+ v: 1,
229
+ instanceId,
230
+ generatedAt: new Date(this.now()).toISOString(),
231
+ agents: changed,
232
+ ...(timeline.length > 0 ? { timeline } : {}),
233
+ };
234
+ const outcome = await this.post(target, C.DELTA_PATH, body, instanceId);
235
+ if (outcome === 'sent') {
236
+ for (const r of changed)
237
+ this.lastSent.set(r.session, JSON.stringify(stripTeam(r)));
238
+ this.deps.tracker.ackUnsent(timeline);
239
+ }
240
+ else if (outcome === 'failed') {
241
+ // keep them dirty for the next try (the full push also repairs everything)
242
+ for (const s of sessions)
243
+ this.dirty.add(s);
244
+ }
245
+ return outcome;
246
+ }
247
+ async post(target, path, body, instanceId) {
248
+ const json = JSON.stringify(body);
249
+ const gz = gzipSync(Buffer.from(json));
250
+ let status = 0;
251
+ let code = null;
252
+ try {
253
+ const response = await this.fetchImpl(`${target.base}${path}`, {
254
+ method: 'POST',
255
+ headers: {
256
+ Authorization: `Bearer ${target.token}`,
257
+ 'Content-Type': 'application/json',
258
+ 'Content-Encoding': 'gzip',
259
+ [C.INSTANCE_HEADER]: instanceId,
260
+ },
261
+ body: gz,
262
+ signal: AbortSignal.timeout(C.REQUEST_TIMEOUT_MS),
263
+ });
264
+ status = response.status;
265
+ if (response.ok) {
266
+ const parsed = (await response.json().catch(() => null));
267
+ const sec = parsed?.data?.next?.fullAfterSec;
268
+ if (typeof sec === 'number' && Number.isFinite(sec))
269
+ this.fullAfterMs = Math.min(600, Math.max(15, sec)) * 1000;
270
+ this.failures = 0;
271
+ if (this.pauseLogged) {
272
+ this.pauseLogged = false;
273
+ this.logger.info('Crewly Cloud is taking board updates again');
274
+ }
275
+ return 'sent';
276
+ }
277
+ const parsed = (await response.json().catch(() => null));
278
+ code = typeof parsed?.code === 'string' ? parsed.code : null;
279
+ }
280
+ catch (error) {
281
+ code = error instanceof Error ? error.message : String(error);
282
+ }
283
+ if (status === 404 || status === 400 || status === 503 || status === 403 || status === 413) {
284
+ this.pausedUntil = this.now() + C.UNAVAILABLE_RETRY_MS;
285
+ this.fullOk = false;
286
+ if (!this.pauseLogged) {
287
+ this.pauseLogged = true;
288
+ this.logger.info('Crewly Cloud is not taking board updates right now; checking again later', { status, code });
289
+ }
290
+ return 'paused';
291
+ }
292
+ if (status === 401)
293
+ void this.deps.cloud.tryRefreshToken?.().catch(() => false);
294
+ this.failures += 1;
295
+ this.fullOk = false;
296
+ const delay = Math.min(C.BACKOFF_INITIAL_MS * 2 ** (this.failures - 1), C.BACKOFF_MAX_MS);
297
+ this.pausedUntil = this.now() + delay;
298
+ // A failed delta: the next full snapshot repairs every row, so bring it forward to the end of the backoff
299
+ if (path === C.DELTA_PATH)
300
+ this.scheduleFull(delay);
301
+ if (this.failures === 1)
302
+ this.logger.warn('Board push failed; will retry', { status, code, retryInMs: delay });
303
+ return 'failed';
304
+ }
305
+ }
306
+ /** A row without the delta-only `teamId`, as the full snapshot has it. */
307
+ function stripTeam(row) {
308
+ const { teamId: _teamId, ...rest } = row;
309
+ void _teamId;
310
+ return rest;
311
+ }
312
+ //# sourceMappingURL=board-push.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-push.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/board/board-push.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
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
+ /** Placeholder for removed secrets. */
14
+ export declare const REDACTED = "[redacted]";
15
+ /**
16
+ * Whether a path segment or word looks like an identifier or a token, not a
17
+ * human name: long with digits and letters, long hex, or a long number.
18
+ *
19
+ * @param s - Segment
20
+ * @returns True when it should not be shown
21
+ */
22
+ export declare function looksLikeToken(s: string): boolean;
23
+ /**
24
+ * Cut a text to the board limit.
25
+ *
26
+ * @param s - Text
27
+ * @param max - Limit (default 140)
28
+ * @returns The text, ending with an ellipsis when cut
29
+ */
30
+ export declare function clip(s: string, max?: number): string;
31
+ /**
32
+ * A URL as host + path: no scheme, credentials, port, query or fragment;
33
+ * path segments that look like ids or tokens become `:id`.
34
+ *
35
+ * @param raw - URL or `host/path`
36
+ * @returns `host/path` (at most 100 characters), or `[redacted]` when unparseable
37
+ */
38
+ export declare function redactUrl(raw: string): string;
39
+ /**
40
+ * A free text made safe: one line, URLs reduced, secrets / emails / phone
41
+ * numbers removed, at most 140 characters.
42
+ *
43
+ * @param input - Any text
44
+ * @param max - Limit (default 140)
45
+ * @returns Safe text (possibly empty)
46
+ */
47
+ export declare function scrubText(input: unknown, max?: number): string;
48
+ /**
49
+ * A file path relative to the project it is in, so no absolute path, user
50
+ * name or machine layout leaves the machine.
51
+ *
52
+ * @param file - Absolute or relative path
53
+ * @param roots - Project roots to make it relative to (longest match wins)
54
+ * @returns `repo/relative/path`, `~/…`, or `…/last/segments`; at most 100 characters
55
+ */
56
+ export declare function relativePath(file: string, roots?: readonly string[]): string;
57
+ /**
58
+ * Split a shell command into segments of words (quotes removed). Separators
59
+ * `&&`, `||`, `;`, `|`, `&` and newlines end a segment. Not a full parser; it
60
+ * only needs to find the first words of each segment safely.
61
+ *
62
+ * @param command - Shell command
63
+ * @returns Segments
64
+ */
65
+ export declare function splitCommand(command: string): string[][];
66
+ /** The result of reducing a command. */
67
+ export interface ReducedCommand {
68
+ /** `git push`, `npm run build`, `python build.py`, `ffmpeg` */
69
+ label: string;
70
+ /** Executable name alone */
71
+ executable: string;
72
+ /** Skill name when the command runs a Crewly skill script */
73
+ skill?: string;
74
+ /** Words of the segment after the executable (not shown; for the normalizer's own parsing) */
75
+ args: string[];
76
+ }
77
+ /**
78
+ * Reduce a shell command to the executable and subcommand. Arguments are
79
+ * never part of the label, so tokens, URLs and prompts in them cannot leak.
80
+ *
81
+ * @param command - Shell command
82
+ * @returns The reduced command, or null when nothing recognisable is in it
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * reduceCommand('cd app && GIT_TOKEN=abc git -C x push origin main'); // label: 'git push'
87
+ * ```
88
+ */
89
+ export declare function reduceCommand(command: string): ReducedCommand | null;
90
+ //# sourceMappingURL=board-redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board-redact.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/board/board-redact.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,uCAAuC;AACvC,eAAO,MAAM,QAAQ,eAAe,CAAC;AAgBrC;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAMjD;AAED;;;;;;GAMG;AACH,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,MAAY,GAAG,MAAM,CAGzD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA0B7C;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,GAAE,MAAY,GAAG,MAAM,CAgBnE;AAKD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,SAAS,MAAM,EAAO,GAAG,MAAM,CAmChF;AAuBD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAiDxD;AAED,wCAAwC;AACxC,MAAM,WAAW,cAAc;IAC9B,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8FAA8F;IAC9F,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAsEpE"}