@bradygaster/squad-cli 0.9.2-insider.6 → 0.9.4-insider.1
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/README.md +33 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +27 -5
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/externalize.d.ts +27 -0
- package/dist/cli/commands/externalize.d.ts.map +1 -0
- package/dist/cli/commands/externalize.js +207 -0
- package/dist/cli/commands/externalize.js.map +1 -0
- package/dist/cli/commands/loop.d.ts +56 -0
- package/dist/cli/commands/loop.d.ts.map +1 -0
- package/dist/cli/commands/loop.js +352 -0
- package/dist/cli/commands/loop.js.map +1 -0
- package/dist/cli/commands/migrate.js +2 -2
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands/rc.js +2 -2
- package/dist/cli/commands/rc.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/cleanup.d.ts +18 -0
- package/dist/cli/commands/watch/capabilities/cleanup.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/cleanup.js +135 -0
- package/dist/cli/commands/watch/capabilities/cleanup.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/execute.d.ts +15 -3
- package/dist/cli/commands/watch/capabilities/execute.d.ts.map +1 -1
- package/dist/cli/commands/watch/capabilities/execute.js +106 -86
- package/dist/cli/commands/watch/capabilities/execute.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/fleet-dispatch.d.ts +20 -0
- package/dist/cli/commands/watch/capabilities/fleet-dispatch.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/fleet-dispatch.js +144 -0
- package/dist/cli/commands/watch/capabilities/fleet-dispatch.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/index.d.ts +0 -2
- package/dist/cli/commands/watch/capabilities/index.d.ts.map +1 -1
- package/dist/cli/commands/watch/capabilities/index.js +4 -12
- package/dist/cli/commands/watch/capabilities/index.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/self-pull.d.ts +4 -1
- package/dist/cli/commands/watch/capabilities/self-pull.d.ts.map +1 -1
- package/dist/cli/commands/watch/capabilities/self-pull.js +53 -5
- package/dist/cli/commands/watch/capabilities/self-pull.js.map +1 -1
- package/dist/cli/commands/watch/config.d.ts +10 -15
- package/dist/cli/commands/watch/config.d.ts.map +1 -1
- package/dist/cli/commands/watch/config.js +14 -47
- package/dist/cli/commands/watch/config.js.map +1 -1
- package/dist/cli/commands/watch/health.d.ts +41 -0
- package/dist/cli/commands/watch/health.d.ts.map +1 -0
- package/dist/cli/commands/watch/health.js +141 -0
- package/dist/cli/commands/watch/health.js.map +1 -0
- package/dist/cli/commands/watch/index.d.ts +9 -16
- package/dist/cli/commands/watch/index.d.ts.map +1 -1
- package/dist/cli/commands/watch/index.js +117 -63
- package/dist/cli/commands/watch/index.js.map +1 -1
- package/dist/cli/commands/watch/types.d.ts +2 -0
- package/dist/cli/commands/watch/types.d.ts.map +1 -1
- package/dist/cli/commands/watch/verbose.d.ts +12 -0
- package/dist/cli/commands/watch/verbose.d.ts.map +1 -0
- package/dist/cli/commands/watch/verbose.js +28 -0
- package/dist/cli/commands/watch/verbose.js.map +1 -0
- package/dist/cli/core/detect-squad-dir.d.ts.map +1 -1
- package/dist/cli/core/detect-squad-dir.js +9 -12
- package/dist/cli/core/detect-squad-dir.js.map +1 -1
- package/dist/cli/core/email-scrub.js +2 -2
- package/dist/cli/core/email-scrub.js.map +1 -1
- package/dist/cli/core/init.d.ts.map +1 -1
- package/dist/cli/core/init.js +4 -1
- package/dist/cli/core/init.js.map +1 -1
- package/dist/cli/core/migrations.js +1 -1
- package/dist/cli/core/migrations.js.map +1 -1
- package/dist/cli/core/nap.js +2 -2
- package/dist/cli/core/nap.js.map +1 -1
- package/dist/cli/core/project-type.js +1 -1
- package/dist/cli/core/project-type.js.map +1 -1
- package/dist/cli/core/templates.d.ts.map +1 -1
- package/dist/cli/core/templates.js +48 -0
- package/dist/cli/core/templates.js.map +1 -1
- package/dist/cli/core/upgrade.d.ts +20 -0
- package/dist/cli/core/upgrade.d.ts.map +1 -1
- package/dist/cli/core/upgrade.js +141 -15
- package/dist/cli/core/upgrade.js.map +1 -1
- package/dist/cli/shell/session-store.js +2 -2
- package/dist/cli/shell/session-store.js.map +1 -1
- package/dist/cli-entry.js +201 -89
- package/dist/cli-entry.js.map +1 -1
- package/package.json +6 -2
- package/templates/casting-reference.md +104 -104
- package/templates/ceremonies.md +28 -0
- package/templates/fact-checker-charter.md +83 -0
- package/templates/issue-lifecycle.md +2 -1
- package/templates/loop.md +46 -0
- package/templates/ralph-triage.js +3 -1
- package/templates/scribe-charter.md +20 -1
- package/templates/skills/external-comms/SKILL.md +329 -329
- package/templates/skills/gh-auth-isolation/SKILL.md +183 -183
- package/templates/skills/humanizer/SKILL.md +105 -105
- package/templates/skills/pr-review-response/SKILL.md +268 -0
- package/templates/skills/pr-screenshots/SKILL.md +149 -149
- package/templates/skills/versioning-policy/SKILL.md +119 -0
- package/templates/squad.agent.md.template +9 -7
- package/templates/workflows/squad-triage.yml +4 -2
- package/templates/workflows/sync-squad-labels.yml +3 -1
- package/dist/cli/commands/watch/capabilities/budget-check.d.ts +0 -29
- package/dist/cli/commands/watch/capabilities/budget-check.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/budget-check.js +0 -38
- package/dist/cli/commands/watch/capabilities/budget-check.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/circuit-breaker.d.ts +0 -52
- package/dist/cli/commands/watch/capabilities/circuit-breaker.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/circuit-breaker.js +0 -152
- package/dist/cli/commands/watch/capabilities/circuit-breaker.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/health-check.d.ts +0 -29
- package/dist/cli/commands/watch/capabilities/health-check.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/health-check.js +0 -139
- package/dist/cli/commands/watch/capabilities/health-check.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/heartbeat.d.ts +0 -48
- package/dist/cli/commands/watch/capabilities/heartbeat.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/heartbeat.js +0 -115
- package/dist/cli/commands/watch/capabilities/heartbeat.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/lockfile.d.ts +0 -30
- package/dist/cli/commands/watch/capabilities/lockfile.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/lockfile.js +0 -100
- package/dist/cli/commands/watch/capabilities/lockfile.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/machine-capabilities.d.ts +0 -30
- package/dist/cli/commands/watch/capabilities/machine-capabilities.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/machine-capabilities.js +0 -103
- package/dist/cli/commands/watch/capabilities/machine-capabilities.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/post-failure.d.ts +0 -19
- package/dist/cli/commands/watch/capabilities/post-failure.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/post-failure.js +0 -58
- package/dist/cli/commands/watch/capabilities/post-failure.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/priority.d.ts +0 -59
- package/dist/cli/commands/watch/capabilities/priority.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/priority.js +0 -101
- package/dist/cli/commands/watch/capabilities/priority.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/rate-pool.d.ts +0 -67
- package/dist/cli/commands/watch/capabilities/rate-pool.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/rate-pool.js +0 -187
- package/dist/cli/commands/watch/capabilities/rate-pool.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/stale-reclaim.d.ts +0 -23
- package/dist/cli/commands/watch/capabilities/stale-reclaim.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/stale-reclaim.js +0 -87
- package/dist/cli/commands/watch/capabilities/stale-reclaim.js.map +0 -1
- package/dist/cli/commands/watch/capabilities/webhook-alerts.d.ts +0 -29
- package/dist/cli/commands/watch/capabilities/webhook-alerts.d.ts.map +0 -1
- package/dist/cli/commands/watch/capabilities/webhook-alerts.js +0 -114
- package/dist/cli/commands/watch/capabilities/webhook-alerts.js.map +0 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup capability — housekeeping for stale temp and log files.
|
|
3
|
+
*
|
|
4
|
+
* Runs in the 'housekeeping' phase. Clears the scratch directory, prunes
|
|
5
|
+
* old orchestration-log and session-log entries, and warns about stale
|
|
6
|
+
* decision inbox files.
|
|
7
|
+
*/
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { rmSync } from 'node:fs';
|
|
10
|
+
import { FSStorageProvider } from '@bradygaster/squad-sdk';
|
|
11
|
+
const storage = new FSStorageProvider();
|
|
12
|
+
/** Default: files older than this many days are pruned. */
|
|
13
|
+
const DEFAULT_MAX_AGE_DAYS = 30;
|
|
14
|
+
/** Default: run cleanup every N rounds (not every round). */
|
|
15
|
+
const DEFAULT_EVERY_N_ROUNDS = 10;
|
|
16
|
+
/** Stale inbox warning threshold (days). */
|
|
17
|
+
const STALE_INBOX_DAYS = 7;
|
|
18
|
+
function parseConfig(raw) {
|
|
19
|
+
return {
|
|
20
|
+
everyNRounds: typeof raw.everyNRounds === 'number' && Number.isFinite(raw.everyNRounds) && raw.everyNRounds > 0
|
|
21
|
+
? raw.everyNRounds
|
|
22
|
+
: DEFAULT_EVERY_N_ROUNDS,
|
|
23
|
+
maxAgeDays: typeof raw.maxAgeDays === 'number' && Number.isFinite(raw.maxAgeDays) && raw.maxAgeDays > 0
|
|
24
|
+
? raw.maxAgeDays
|
|
25
|
+
: DEFAULT_MAX_AGE_DAYS,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function isOlderThan(filename, days) {
|
|
29
|
+
// Filenames may start with ISO timestamp: 2026-04-01T12-00-00Z-agent.md
|
|
30
|
+
const match = filename.match(/^(\d{4}-\d{2}-\d{2})/);
|
|
31
|
+
if (!match)
|
|
32
|
+
return false;
|
|
33
|
+
const fileDate = new Date(match[1]);
|
|
34
|
+
if (isNaN(fileDate.getTime()))
|
|
35
|
+
return false;
|
|
36
|
+
const cutoffMs = Date.now() - (days * 86400000);
|
|
37
|
+
return fileDate.getTime() < cutoffMs;
|
|
38
|
+
}
|
|
39
|
+
function safeList(dir) {
|
|
40
|
+
try {
|
|
41
|
+
if (!storage.existsSync(dir))
|
|
42
|
+
return [];
|
|
43
|
+
return storage.listSync?.(dir) ?? [];
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function safeDelete(filePath) {
|
|
50
|
+
try {
|
|
51
|
+
rmSync(filePath, { recursive: true, force: true });
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export class CleanupCapability {
|
|
59
|
+
name = 'cleanup';
|
|
60
|
+
description = 'Remove stale scratch files, prune old logs, warn about stale inbox';
|
|
61
|
+
configShape = 'object';
|
|
62
|
+
requires = [];
|
|
63
|
+
phase = 'housekeeping';
|
|
64
|
+
async preflight(context) {
|
|
65
|
+
const squadDir = path.join(context.teamRoot, '.squad');
|
|
66
|
+
if (!storage.existsSync(squadDir)) {
|
|
67
|
+
return { ok: false, reason: '.squad/ directory not found' };
|
|
68
|
+
}
|
|
69
|
+
return { ok: true };
|
|
70
|
+
}
|
|
71
|
+
async execute(context) {
|
|
72
|
+
const config = parseConfig(context.config);
|
|
73
|
+
const everyN = config.everyNRounds ?? DEFAULT_EVERY_N_ROUNDS;
|
|
74
|
+
// Only run on every Nth round (or round 1 for immediate feedback)
|
|
75
|
+
if (context.round > 1 && context.round % everyN !== 0) {
|
|
76
|
+
return { success: true, summary: `cleanup: skipped (runs every ${everyN} rounds)` };
|
|
77
|
+
}
|
|
78
|
+
const squadDir = path.join(context.teamRoot, '.squad');
|
|
79
|
+
const maxAge = config.maxAgeDays ?? DEFAULT_MAX_AGE_DAYS;
|
|
80
|
+
const actions = [];
|
|
81
|
+
// 1. Clear .squad/.scratch/ — everything in here is ephemeral
|
|
82
|
+
const scratchDir = path.join(squadDir, '.scratch');
|
|
83
|
+
const scratchFiles = safeList(scratchDir);
|
|
84
|
+
let scratchDeleted = 0;
|
|
85
|
+
for (const f of scratchFiles) {
|
|
86
|
+
if (safeDelete(path.join(scratchDir, f)))
|
|
87
|
+
scratchDeleted++;
|
|
88
|
+
}
|
|
89
|
+
if (scratchDeleted > 0) {
|
|
90
|
+
actions.push(`scratch: ${scratchDeleted} files cleared`);
|
|
91
|
+
}
|
|
92
|
+
// 2. Prune old orchestration-log entries (older than maxAge days)
|
|
93
|
+
const orchDir = path.join(squadDir, 'orchestration-log');
|
|
94
|
+
const orchFiles = safeList(orchDir);
|
|
95
|
+
let orchPruned = 0;
|
|
96
|
+
for (const f of orchFiles) {
|
|
97
|
+
if (isOlderThan(f, maxAge)) {
|
|
98
|
+
if (safeDelete(path.join(orchDir, f)))
|
|
99
|
+
orchPruned++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (orchPruned > 0) {
|
|
103
|
+
actions.push(`orchestration-log: ${orchPruned} entries pruned (>${maxAge}d)`);
|
|
104
|
+
}
|
|
105
|
+
// 3. Prune old session logs
|
|
106
|
+
const logDir = path.join(squadDir, 'log');
|
|
107
|
+
const logFiles = safeList(logDir);
|
|
108
|
+
let logPruned = 0;
|
|
109
|
+
for (const f of logFiles) {
|
|
110
|
+
if (isOlderThan(f, maxAge)) {
|
|
111
|
+
if (safeDelete(path.join(logDir, f)))
|
|
112
|
+
logPruned++;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (logPruned > 0) {
|
|
116
|
+
actions.push(`log: ${logPruned} entries pruned (>${maxAge}d)`);
|
|
117
|
+
}
|
|
118
|
+
// 4. Warn about stale decision inbox files
|
|
119
|
+
const inboxDir = path.join(squadDir, 'decisions', 'inbox');
|
|
120
|
+
const inboxFiles = safeList(inboxDir).filter(f => f.endsWith('.md'));
|
|
121
|
+
const staleInbox = inboxFiles.filter(f => isOlderThan(f, STALE_INBOX_DAYS));
|
|
122
|
+
if (staleInbox.length > 0) {
|
|
123
|
+
actions.push(`⚠ ${staleInbox.length} stale inbox files (>${STALE_INBOX_DAYS}d)`);
|
|
124
|
+
}
|
|
125
|
+
if (actions.length === 0) {
|
|
126
|
+
return { success: true, summary: 'cleanup: nothing to do' };
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
success: true,
|
|
130
|
+
summary: `cleanup: ${actions.join('; ')}`,
|
|
131
|
+
data: { scratchDeleted, orchPruned, logPruned, staleInboxCount: staleInbox.length },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,12 +15,24 @@ export interface ExecutableWorkItem {
|
|
|
15
15
|
login: string;
|
|
16
16
|
}>;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
export declare function
|
|
18
|
+
/** Classify an issue as read-heavy or write-heavy by title keywords. */
|
|
19
|
+
export declare function classifyIssue(title: string): 'read' | 'write';
|
|
20
|
+
/** Find issues eligible for autonomous execution.
|
|
21
|
+
*
|
|
22
|
+
* Pre-filters to keep only clearly actionable items:
|
|
23
|
+
* - must have a squad/squad:* label
|
|
24
|
+
* - must not be assigned to a human (agent decides once it reads ralph-instructions.md)
|
|
25
|
+
* - must not carry a blocking status label
|
|
26
|
+
*
|
|
27
|
+
* Matches the PS1 ralph-watch pre-filter design.
|
|
28
|
+
*/
|
|
29
|
+
export declare function findExecutableIssues(_roster: Array<{
|
|
20
30
|
name: string;
|
|
21
31
|
label: string;
|
|
22
32
|
expertise: string[];
|
|
23
|
-
}>,
|
|
33
|
+
}>, _capabilities: MachineCapabilities | null, issues: ExecutableWorkItem[]): ExecutableWorkItem[];
|
|
34
|
+
/** Build the rich agent prompt matching PS1 ralph-watch design. */
|
|
35
|
+
export declare function buildAgentPrompt(issues: ExecutableWorkItem[], teamRoot: string): string;
|
|
24
36
|
export declare class ExecuteCapability implements WatchCapability {
|
|
25
37
|
readonly name = "execute";
|
|
26
38
|
readonly description = "Spawn Copilot sessions to work on eligible issues";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/execute.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/execute.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAGrF,0CAA0C;AAC1C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChC,SAAS,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrC;AAoBD,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAM7D;AAiCD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,EACpE,aAAa,EAAE,mBAAmB,GAAG,IAAI,EACzC,MAAM,EAAE,kBAAkB,EAAE,GAC3B,kBAAkB,EAAE,CAItB;AAaD,mEAAmE;AACnE,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,kBAAkB,EAAE,EAC5B,QAAQ,EAAE,MAAM,GACf,MAAM,CA8BR;AA6BD,qBAAa,iBAAkB,YAAW,eAAe;IACvD,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,WAAW,uDAAuD;IAC3E,QAAQ,CAAC,WAAW,EAAG,SAAS,CAAU;IAC1C,QAAQ,CAAC,QAAQ,WAAU;IAC3B,QAAQ,CAAC,KAAK,EAAG,cAAc,CAAU;IAEnC,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAQ3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA4ChE"}
|
|
@@ -2,20 +2,33 @@
|
|
|
2
2
|
* Execute capability — spawns Copilot sessions for eligible issues.
|
|
3
3
|
*/
|
|
4
4
|
import { execFile } from 'node:child_process';
|
|
5
|
+
import { existsSync } from 'node:fs';
|
|
5
6
|
import path from 'node:path';
|
|
6
|
-
import {
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
'
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
'
|
|
14
|
-
'
|
|
15
|
-
'
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
import { createVerboseLogger } from '../verbose.js';
|
|
8
|
+
/** Check whether an issue carries a squad or squad:* label. */
|
|
9
|
+
function hasSquadLabel(issue) {
|
|
10
|
+
return issue.labels.some(l => l.name === 'squad' || l.name.startsWith('squad:'));
|
|
11
|
+
}
|
|
12
|
+
/** Keywords that indicate read-heavy / analysis work. */
|
|
13
|
+
const READ_KEYWORDS = [
|
|
14
|
+
'research', 'review', 'analyze', 'investigate', 'audit',
|
|
15
|
+
'check', 'scan', 'assess', 'evaluate', 'fact-check',
|
|
16
|
+
'document', 'report',
|
|
17
|
+
];
|
|
18
|
+
/** Keywords that indicate write-heavy / implementation work. */
|
|
19
|
+
const WRITE_KEYWORDS = [
|
|
20
|
+
'fix', 'implement', 'create', 'build', 'refactor',
|
|
21
|
+
'add', 'update', 'migrate', 'deploy', 'feature',
|
|
22
|
+
];
|
|
23
|
+
/** Classify an issue as read-heavy or write-heavy by title keywords. */
|
|
24
|
+
export function classifyIssue(title) {
|
|
25
|
+
const lower = title.toLowerCase();
|
|
26
|
+
const isRead = READ_KEYWORDS.some(k => lower.includes(k));
|
|
27
|
+
const isWrite = WRITE_KEYWORDS.some(k => lower.includes(k));
|
|
28
|
+
if (isRead && !isWrite)
|
|
29
|
+
return 'read';
|
|
30
|
+
return 'write'; // default to write (safer — gets full agent session)
|
|
31
|
+
}
|
|
19
32
|
/** Build agent command for a prompt. */
|
|
20
33
|
function buildAgentCommand(prompt, context) {
|
|
21
34
|
if (context.agentCmd) {
|
|
@@ -30,32 +43,71 @@ function buildAgentCommand(prompt, context) {
|
|
|
30
43
|
}
|
|
31
44
|
return { cmd: 'gh', args };
|
|
32
45
|
}
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (!labels.some(l => memberLabels.has(l)))
|
|
39
|
-
return false;
|
|
40
|
-
if (issue.assignees && issue.assignees.length > 0)
|
|
41
|
-
return false;
|
|
42
|
-
if (labels.some(l => BLOCKED_LABELS.has(l)))
|
|
43
|
-
return false;
|
|
44
|
-
return true;
|
|
45
|
-
});
|
|
46
|
+
/** Labels that indicate an issue should not be auto-executed. */
|
|
47
|
+
const BLOCKING_LABELS = ['status:blocked', 'status:wontfix', 'status:on-hold', 'blocked'];
|
|
48
|
+
/** Check whether an issue has a blocking status label. */
|
|
49
|
+
function hasBlockingLabel(issue) {
|
|
50
|
+
return issue.labels.some(l => BLOCKING_LABELS.includes(l.name));
|
|
46
51
|
}
|
|
47
|
-
/**
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
/** Check whether an issue is already assigned to a human. */
|
|
53
|
+
function isAssigned(issue) {
|
|
54
|
+
return issue.assignees.length > 0;
|
|
55
|
+
}
|
|
56
|
+
/** Find issues eligible for autonomous execution.
|
|
57
|
+
*
|
|
58
|
+
* Pre-filters to keep only clearly actionable items:
|
|
59
|
+
* - must have a squad/squad:* label
|
|
60
|
+
* - must not be assigned to a human (agent decides once it reads ralph-instructions.md)
|
|
61
|
+
* - must not carry a blocking status label
|
|
62
|
+
*
|
|
63
|
+
* Matches the PS1 ralph-watch pre-filter design.
|
|
64
|
+
*/
|
|
65
|
+
export function findExecutableIssues(_roster, _capabilities, issues) {
|
|
66
|
+
return issues.filter(issue => hasSquadLabel(issue) && !isAssigned(issue) && !hasBlockingLabel(issue));
|
|
67
|
+
}
|
|
68
|
+
/** Format issue list for the agent prompt. */
|
|
69
|
+
function formatIssueList(issues) {
|
|
70
|
+
return issues.map(i => {
|
|
71
|
+
const labels = i.labels.map(l => l.name).join(', ');
|
|
72
|
+
const assigned = i.assignees?.length
|
|
73
|
+
? `assigned: ${i.assignees.map(a => a.login).join(',')}`
|
|
74
|
+
: 'unassigned';
|
|
75
|
+
return `- #${i.number}: ${i.title} [${labels}] ${assigned}`;
|
|
76
|
+
}).join('\n');
|
|
77
|
+
}
|
|
78
|
+
/** Build the rich agent prompt matching PS1 ralph-watch design. */
|
|
79
|
+
export function buildAgentPrompt(issues, teamRoot) {
|
|
80
|
+
const issueList = formatIssueList(issues);
|
|
81
|
+
const hasInstructions = existsSync(path.join(teamRoot, '.squad', 'ralph-instructions.md'));
|
|
82
|
+
if (hasInstructions) {
|
|
83
|
+
return [
|
|
84
|
+
'Ralph, Go! Read .squad/ralph-instructions.md for your full instructions. Follow ALL sections there. MAXIMIZE PARALLELISM — spawn agents for ALL actionable issues simultaneously.',
|
|
85
|
+
'',
|
|
86
|
+
'Here are the current open squad issues:',
|
|
87
|
+
issueList,
|
|
88
|
+
'',
|
|
89
|
+
'Task: Read the issues, follow your instructions in .squad/ralph-instructions.md, and work on what\'s actionable.',
|
|
90
|
+
'WHY: Keep the squad pipeline moving — no idle work.',
|
|
91
|
+
'Success: Issues get branches, PRs, and progress.',
|
|
92
|
+
'Escalation: If blocked, comment on the issue and move to next.',
|
|
93
|
+
].join('\n');
|
|
56
94
|
}
|
|
57
|
-
|
|
58
|
-
|
|
95
|
+
// Fallback when ralph-instructions.md does not exist
|
|
96
|
+
return [
|
|
97
|
+
'You are Ralph, the autonomous work monitor. Review the open squad issues below and work on every actionable one. Skip issues that are blocked, waiting on external input, or already assigned.',
|
|
98
|
+
'',
|
|
99
|
+
'Here are the current open squad issues:',
|
|
100
|
+
issueList,
|
|
101
|
+
'',
|
|
102
|
+
'Task: Triage the list, pick up unblocked/unassigned issues, create branches and PRs.',
|
|
103
|
+
'WHY: Keep the squad pipeline moving — no idle work.',
|
|
104
|
+
'Success: Issues get branches, PRs, and progress.',
|
|
105
|
+
'Escalation: If blocked, comment on the issue and move to next.',
|
|
106
|
+
].join('\n');
|
|
107
|
+
}
|
|
108
|
+
/** Spawn a single agent session for all eligible issues. */
|
|
109
|
+
async function executeAll(issues, context, timeoutMs) {
|
|
110
|
+
const prompt = buildAgentPrompt(issues, context.teamRoot);
|
|
59
111
|
const { cmd, args } = buildAgentCommand(prompt, context);
|
|
60
112
|
return new Promise((resolve) => {
|
|
61
113
|
const _cp = execFile(cmd, args, { cwd: context.teamRoot, timeout: timeoutMs, maxBuffer: 50 * 1024 * 1024 }, (err) => {
|
|
@@ -84,9 +136,10 @@ export class ExecuteCapability {
|
|
|
84
136
|
});
|
|
85
137
|
}
|
|
86
138
|
async execute(context) {
|
|
139
|
+
const vlog = createVerboseLogger(context.verbose ?? false);
|
|
87
140
|
try {
|
|
88
|
-
const maxConcurrent = context.config['maxConcurrent'] ?? 1;
|
|
89
141
|
const timeout = (context.config['timeout'] ?? 30) * 60_000;
|
|
142
|
+
vlog.log(`Execute: agentCmd=${context.agentCmd ?? 'gh copilot'}, timeout=${timeout / 60_000}m`);
|
|
90
143
|
// Fetch open issues with squad label
|
|
91
144
|
const sdkItems = await context.adapter.listWorkItems({ tags: ['squad'], state: 'open', limit: 50 });
|
|
92
145
|
const issues = sdkItems.map(wi => ({
|
|
@@ -95,57 +148,24 @@ export class ExecuteCapability {
|
|
|
95
148
|
labels: wi.tags.map(t => ({ name: t })),
|
|
96
149
|
assignees: wi.assignedTo ? [{ login: wi.assignedTo }] : [],
|
|
97
150
|
}));
|
|
98
|
-
//
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (batch.length === 0) {
|
|
105
|
-
return { success: true, summary: 'no executable issues' };
|
|
106
|
-
}
|
|
107
|
-
// Rate pool gate — respect shared API budget across instances
|
|
108
|
-
const poolCfg = context.config['ratePool'];
|
|
109
|
-
const squadDir = path.join(context.teamRoot, '.squad');
|
|
110
|
-
const ratePool = new RatePool(squadDir, {
|
|
111
|
-
maxCallsPerInterval: poolCfg?.['maxCallsPerInterval'] ?? undefined,
|
|
112
|
-
intervalSeconds: poolCfg?.['intervalSeconds'] ?? undefined,
|
|
113
|
-
poolFile: poolCfg?.['poolFile'] ?? undefined,
|
|
114
|
-
});
|
|
115
|
-
const admitted = [];
|
|
116
|
-
const skipped = [];
|
|
117
|
-
for (const issue of batch) {
|
|
118
|
-
if (ratePool.acquireSlot()) {
|
|
119
|
-
admitted.push(issue);
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
skipped.push(issue.number);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (admitted.length === 0) {
|
|
126
|
-
const status = ratePool.getPoolStatus();
|
|
127
|
-
return {
|
|
128
|
-
success: true,
|
|
129
|
-
summary: `rate pool exhausted (${status.slotsUsed}/${status.maxSlots}), ${skipped.length} skipped`,
|
|
130
|
-
};
|
|
151
|
+
// Minimal filter: must have squad or squad:* label (agent decides the rest)
|
|
152
|
+
const eligible = findExecutableIssues(context.roster, null, issues);
|
|
153
|
+
vlog.log(`Execute: ${issues.length} total issues, ${eligible.length} eligible`);
|
|
154
|
+
for (const issue of eligible.slice(0, 5)) {
|
|
155
|
+
const labels = issue.labels.map(l => l.name).join(', ');
|
|
156
|
+
vlog.log(` → #${issue.number}: "${issue.title}" [${labels}]`);
|
|
131
157
|
}
|
|
132
|
-
if (
|
|
133
|
-
|
|
158
|
+
if (eligible.length === 0) {
|
|
159
|
+
return { success: true, summary: 'no squad-labeled issues found' };
|
|
134
160
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return await executeOne(issue, context, timeout);
|
|
138
|
-
}
|
|
139
|
-
finally {
|
|
140
|
-
ratePool.releaseSlot();
|
|
141
|
-
}
|
|
142
|
-
}));
|
|
143
|
-
const succeeded = results.filter(r => r.success).length;
|
|
144
|
-
const failed = results.length - succeeded;
|
|
161
|
+
// Single agent invocation with all issues — agent reads ralph-instructions.md
|
|
162
|
+
const result = await executeAll(eligible, context, timeout);
|
|
145
163
|
return {
|
|
146
|
-
success:
|
|
147
|
-
summary:
|
|
148
|
-
|
|
164
|
+
success: result.success,
|
|
165
|
+
summary: result.success
|
|
166
|
+
? `agent dispatched with ${eligible.length} issues`
|
|
167
|
+
: `agent failed: ${result.error}`,
|
|
168
|
+
data: { dispatched: eligible.length, success: result.success },
|
|
149
169
|
};
|
|
150
170
|
}
|
|
151
171
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/execute.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAqB,MAAM,oBAAoB,CAAC;AACjE,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/execute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FleetDispatch capability — batches read-heavy issues into a single
|
|
3
|
+
* `/fleet`-style parallel Copilot session for efficient triage.
|
|
4
|
+
*
|
|
5
|
+
* Runs in the `post-execute` phase. When `dispatchMode` is `'fleet'` or
|
|
6
|
+
* `'hybrid'`, this capability picks up issues classified as read-heavy
|
|
7
|
+
* (research, review, audit, etc.) and dispatches them as parallel
|
|
8
|
+
* analysis tracks inside one Copilot invocation.
|
|
9
|
+
*/
|
|
10
|
+
import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
|
|
11
|
+
export declare class FleetDispatchCapability implements WatchCapability {
|
|
12
|
+
readonly name = "fleet-dispatch";
|
|
13
|
+
readonly description = "Batch read-heavy issues into a parallel /fleet Copilot session";
|
|
14
|
+
readonly configShape: "boolean";
|
|
15
|
+
readonly requires: string[];
|
|
16
|
+
readonly phase: "post-execute";
|
|
17
|
+
preflight(_context: WatchContext): Promise<PreflightResult>;
|
|
18
|
+
execute(context: WatchContext): Promise<CapabilityResult>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=fleet-dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-dispatch.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/fleet-dispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAoFpG,qBAAa,uBAAwB,YAAW,eAAe;IAC7D,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,WAAW,oEAAoE;IACxF,QAAQ,CAAC,WAAW,EAAG,SAAS,CAAU;IAC1C,QAAQ,CAAC,QAAQ,WAAqB;IACtC,QAAQ,CAAC,KAAK,EAAG,cAAc,CAAU;IAEnC,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAU3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAyDhE"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FleetDispatch capability — batches read-heavy issues into a single
|
|
3
|
+
* `/fleet`-style parallel Copilot session for efficient triage.
|
|
4
|
+
*
|
|
5
|
+
* Runs in the `post-execute` phase. When `dispatchMode` is `'fleet'` or
|
|
6
|
+
* `'hybrid'`, this capability picks up issues classified as read-heavy
|
|
7
|
+
* (research, review, audit, etc.) and dispatches them as parallel
|
|
8
|
+
* analysis tracks inside one Copilot invocation.
|
|
9
|
+
*/
|
|
10
|
+
import { execSync, execFileSync } from 'node:child_process';
|
|
11
|
+
import { writeFileSync, readFileSync, unlinkSync } from 'node:fs';
|
|
12
|
+
import { join } from 'node:path';
|
|
13
|
+
import { tmpdir } from 'node:os';
|
|
14
|
+
import { findExecutableIssues, classifyIssue, } from './execute.js';
|
|
15
|
+
/** Map a roster member label to a display-friendly agent name. */
|
|
16
|
+
function agentForIssue(issue, roster) {
|
|
17
|
+
const memberLabels = new Map(roster.map(m => [m.label, m.name]));
|
|
18
|
+
for (const label of issue.labels) {
|
|
19
|
+
const name = memberLabels.get(label.name);
|
|
20
|
+
if (name)
|
|
21
|
+
return name;
|
|
22
|
+
}
|
|
23
|
+
return 'Copilot';
|
|
24
|
+
}
|
|
25
|
+
/** Build the multi-track fleet prompt for a set of read-heavy issues. */
|
|
26
|
+
function buildFleetPrompt(issues, roster) {
|
|
27
|
+
const tracks = issues.map((issue, idx) => {
|
|
28
|
+
const agent = agentForIssue(issue, roster);
|
|
29
|
+
return [
|
|
30
|
+
`Track ${idx + 1} (${agent}): Issue #${issue.number}: ${issue.title}`,
|
|
31
|
+
` Read the issue body. Analyze, assess urgency (P0/P1/P2), recommend next step.`,
|
|
32
|
+
` Write findings as an issue comment.`,
|
|
33
|
+
` Do NOT create branches or modify files.`,
|
|
34
|
+
].join('\n');
|
|
35
|
+
});
|
|
36
|
+
return [
|
|
37
|
+
`/fleet Execute these ${issues.length} read-only analysis tracks in parallel:`,
|
|
38
|
+
'',
|
|
39
|
+
...tracks,
|
|
40
|
+
'',
|
|
41
|
+
'Rules: All tracks READ-ONLY. Write findings as issue comments. Run in parallel.',
|
|
42
|
+
].join('\n');
|
|
43
|
+
}
|
|
44
|
+
/** Invoke a fleet prompt via the Copilot CLI. */
|
|
45
|
+
function invokeFleet(prompt, cwd, timeoutMs) {
|
|
46
|
+
const promptFile = join(tmpdir(), `fleet-prompt-${Date.now()}.txt`);
|
|
47
|
+
writeFileSync(promptFile, prompt, 'utf-8');
|
|
48
|
+
try {
|
|
49
|
+
// Read the prompt from file
|
|
50
|
+
const promptContent = readFileSync(promptFile, 'utf-8');
|
|
51
|
+
// Use execFileSync with args array — no shell, no injection risk
|
|
52
|
+
const copilotBin = process.platform === 'win32' ? 'copilot.cmd' : 'copilot';
|
|
53
|
+
const result = execFileSync(copilotBin, [
|
|
54
|
+
'-p', promptContent,
|
|
55
|
+
'--allow-all',
|
|
56
|
+
'--no-ask-user',
|
|
57
|
+
'--autopilot',
|
|
58
|
+
], {
|
|
59
|
+
cwd,
|
|
60
|
+
timeout: timeoutMs,
|
|
61
|
+
encoding: 'utf-8',
|
|
62
|
+
});
|
|
63
|
+
return { success: true, output: String(result) };
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
const err = e;
|
|
67
|
+
const msg = err.killed
|
|
68
|
+
? `Fleet dispatch timed out after ${Math.round(timeoutMs / 60_000)}m`
|
|
69
|
+
: err.stderr || err.message;
|
|
70
|
+
return { success: false, error: msg };
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
try {
|
|
74
|
+
unlinkSync(promptFile);
|
|
75
|
+
}
|
|
76
|
+
catch { /* best-effort cleanup */ }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export class FleetDispatchCapability {
|
|
80
|
+
name = 'fleet-dispatch';
|
|
81
|
+
description = 'Batch read-heavy issues into a parallel /fleet Copilot session';
|
|
82
|
+
configShape = 'boolean';
|
|
83
|
+
requires = ['gh', 'copilot'];
|
|
84
|
+
phase = 'post-execute';
|
|
85
|
+
async preflight(_context) {
|
|
86
|
+
// Fleet dispatch requires the copilot CLI — quick sanity check
|
|
87
|
+
try {
|
|
88
|
+
execSync('copilot --version', { encoding: 'utf-8', stdio: 'pipe' });
|
|
89
|
+
return { ok: true };
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return { ok: false, reason: 'copilot CLI not found — required for fleet dispatch' };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async execute(context) {
|
|
96
|
+
try {
|
|
97
|
+
const dispatchMode = context.config['dispatchMode'] ?? 'task';
|
|
98
|
+
// Only run when fleet or hybrid dispatch is active
|
|
99
|
+
if (dispatchMode !== 'fleet' && dispatchMode !== 'hybrid') {
|
|
100
|
+
return { success: true, summary: 'fleet-dispatch: skipped (dispatch mode is task)' };
|
|
101
|
+
}
|
|
102
|
+
const timeoutMs = (context.config['timeout'] ?? 30) * 60_000;
|
|
103
|
+
// Fetch the same issue set as the execute capability
|
|
104
|
+
const sdkItems = await context.adapter.listWorkItems({ tags: ['squad'], state: 'open', limit: 50 });
|
|
105
|
+
const issues = sdkItems.map(wi => ({
|
|
106
|
+
number: wi.id,
|
|
107
|
+
title: wi.title,
|
|
108
|
+
labels: wi.tags.map(t => ({ name: t })),
|
|
109
|
+
assignees: wi.assignedTo ? [{ login: wi.assignedTo }] : [],
|
|
110
|
+
}));
|
|
111
|
+
const { filterByCapabilities, loadCapabilities } = await import('@bradygaster/squad-sdk/ralph/capabilities');
|
|
112
|
+
const capabilities = await loadCapabilities(context.teamRoot);
|
|
113
|
+
const { handled } = filterByCapabilities(issues, capabilities);
|
|
114
|
+
const executable = findExecutableIssues(context.roster, capabilities, handled);
|
|
115
|
+
// Pick only read-heavy issues (or all in pure fleet mode)
|
|
116
|
+
const readIssues = dispatchMode === 'fleet'
|
|
117
|
+
? executable
|
|
118
|
+
: executable.filter(i => classifyIssue(i.title) === 'read');
|
|
119
|
+
if (readIssues.length === 0) {
|
|
120
|
+
return { success: true, summary: 'fleet-dispatch: no read-heavy issues to batch' };
|
|
121
|
+
}
|
|
122
|
+
// Build and invoke fleet prompt
|
|
123
|
+
const prompt = buildFleetPrompt(readIssues, context.roster);
|
|
124
|
+
const fleetTimeout = Math.max(timeoutMs, 300_000); // at least 5 min for fleet
|
|
125
|
+
const result = invokeFleet(prompt, context.teamRoot, fleetTimeout);
|
|
126
|
+
if (result.success) {
|
|
127
|
+
return {
|
|
128
|
+
success: true,
|
|
129
|
+
summary: `fleet-dispatch: ${readIssues.length} issues analyzed in parallel`,
|
|
130
|
+
data: { dispatched: readIssues.length, issues: readIssues.map(i => i.number) },
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
success: false,
|
|
135
|
+
summary: `fleet-dispatch: failed — ${result.error}`,
|
|
136
|
+
data: { dispatched: 0, error: result.error },
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
return { success: false, summary: `fleet-dispatch error: ${e.message}` };
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=fleet-dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-dispatch.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/fleet-dispatch.ts"],"names":[],"mappings":"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"}
|