@bradygaster/squad-cli 0.9.0 → 0.9.2-insider.5
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 +1 -1
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +10 -10
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/config.d.ts +12 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +157 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/consult.d.ts.map +1 -1
- package/dist/cli/commands/consult.js +9 -4
- package/dist/cli/commands/consult.js.map +1 -1
- package/dist/cli/commands/copilot.d.ts.map +1 -1
- package/dist/cli/commands/copilot.js +8 -7
- package/dist/cli/commands/copilot.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +50 -17
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/economy.d.ts.map +1 -1
- package/dist/cli/commands/economy.js +3 -2
- package/dist/cli/commands/economy.js.map +1 -1
- package/dist/cli/commands/export.d.ts.map +1 -1
- package/dist/cli/commands/export.js +22 -16
- package/dist/cli/commands/export.js.map +1 -1
- package/dist/cli/commands/extract.d.ts.map +1 -1
- package/dist/cli/commands/extract.js +14 -10
- package/dist/cli/commands/extract.js.map +1 -1
- package/dist/cli/commands/import.d.ts.map +1 -1
- package/dist/cli/commands/import.js +21 -18
- package/dist/cli/commands/import.js.map +1 -1
- package/dist/cli/commands/init-remote.d.ts.map +1 -1
- package/dist/cli/commands/init-remote.js +7 -6
- package/dist/cli/commands/init-remote.js.map +1 -1
- package/dist/cli/commands/link.d.ts.map +1 -1
- package/dist/cli/commands/link.js +11 -10
- package/dist/cli/commands/link.js.map +1 -1
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +19 -18
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands/personal.d.ts.map +1 -1
- package/dist/cli/commands/personal.js +12 -20
- package/dist/cli/commands/personal.js.map +1 -1
- package/dist/cli/commands/plugin.d.ts.map +1 -1
- package/dist/cli/commands/plugin.js +8 -7
- package/dist/cli/commands/plugin.js.map +1 -1
- package/dist/cli/commands/rc.d.ts.map +1 -1
- package/dist/cli/commands/rc.js +19 -12
- package/dist/cli/commands/rc.js.map +1 -1
- package/dist/cli/commands/schedule.d.ts.map +1 -1
- package/dist/cli/commands/schedule.js +6 -5
- package/dist/cli/commands/schedule.js.map +1 -1
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +18 -11
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/streams.d.ts.map +1 -1
- package/dist/cli/commands/streams.js +3 -2
- package/dist/cli/commands/streams.js.map +1 -1
- package/dist/cli/commands/upstream.d.ts.map +1 -1
- package/dist/cli/commands/upstream.js +23 -19
- package/dist/cli/commands/upstream.js.map +1 -1
- package/dist/cli/commands/watch/capabilities/board.d.ts +22 -0
- package/dist/cli/commands/watch/capabilities/board.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/board.js +121 -0
- package/dist/cli/commands/watch/capabilities/board.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/decision-hygiene.d.ts +14 -0
- package/dist/cli/commands/watch/capabilities/decision-hygiene.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/decision-hygiene.js +72 -0
- package/dist/cli/commands/watch/capabilities/decision-hygiene.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/execute.d.ts +33 -0
- package/dist/cli/commands/watch/capabilities/execute.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/execute.js +119 -0
- package/dist/cli/commands/watch/capabilities/execute.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/index.d.ts +7 -0
- package/dist/cli/commands/watch/capabilities/index.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/index.js +28 -0
- package/dist/cli/commands/watch/capabilities/index.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/monitor-email.d.ts +14 -0
- package/dist/cli/commands/watch/capabilities/monitor-email.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/monitor-email.js +54 -0
- package/dist/cli/commands/watch/capabilities/monitor-email.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/monitor-teams.d.ts +14 -0
- package/dist/cli/commands/watch/capabilities/monitor-teams.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/monitor-teams.js +55 -0
- package/dist/cli/commands/watch/capabilities/monitor-teams.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/retro.d.ts +14 -0
- package/dist/cli/commands/watch/capabilities/retro.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/retro.js +81 -0
- package/dist/cli/commands/watch/capabilities/retro.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/self-pull.d.ts +14 -0
- package/dist/cli/commands/watch/capabilities/self-pull.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/self-pull.js +33 -0
- package/dist/cli/commands/watch/capabilities/self-pull.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/two-pass.d.ts +14 -0
- package/dist/cli/commands/watch/capabilities/two-pass.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/two-pass.js +66 -0
- package/dist/cli/commands/watch/capabilities/two-pass.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/wave-dispatch.d.ts +14 -0
- package/dist/cli/commands/watch/capabilities/wave-dispatch.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/wave-dispatch.js +117 -0
- package/dist/cli/commands/watch/capabilities/wave-dispatch.js.map +1 -0
- package/dist/cli/commands/watch/config.d.ts +25 -0
- package/dist/cli/commands/watch/config.d.ts.map +1 -0
- package/dist/cli/commands/watch/config.js +82 -0
- package/dist/cli/commands/watch/config.js.map +1 -0
- package/dist/cli/commands/watch/index.d.ts +95 -0
- package/dist/cli/commands/watch/index.d.ts.map +1 -0
- package/dist/cli/commands/watch/index.js +704 -0
- package/dist/cli/commands/watch/index.js.map +1 -0
- package/dist/cli/commands/watch/registry.d.ts +19 -0
- package/dist/cli/commands/watch/registry.d.ts.map +1 -0
- package/dist/cli/commands/watch/registry.js +28 -0
- package/dist/cli/commands/watch/registry.js.map +1 -0
- package/dist/cli/commands/watch/types.d.ts +57 -0
- package/dist/cli/commands/watch/types.d.ts.map +1 -0
- package/dist/cli/commands/watch/types.js +8 -0
- package/dist/cli/commands/watch/types.js.map +1 -0
- package/dist/cli/core/cast.d.ts.map +1 -1
- package/dist/cli/core/cast.js +15 -19
- package/dist/cli/core/cast.js.map +1 -1
- package/dist/cli/core/detect-squad-dir.d.ts.map +1 -1
- package/dist/cli/core/detect-squad-dir.js +12 -10
- package/dist/cli/core/detect-squad-dir.js.map +1 -1
- package/dist/cli/core/email-scrub.d.ts.map +1 -1
- package/dist/cli/core/email-scrub.js +12 -11
- package/dist/cli/core/email-scrub.js.map +1 -1
- package/dist/cli/core/gh-cli.d.ts +13 -0
- package/dist/cli/core/gh-cli.d.ts.map +1 -1
- package/dist/cli/core/gh-cli.js +24 -0
- package/dist/cli/core/gh-cli.js.map +1 -1
- package/dist/cli/core/init.d.ts +2 -0
- package/dist/cli/core/init.d.ts.map +1 -1
- package/dist/cli/core/init.js +22 -5
- package/dist/cli/core/init.js.map +1 -1
- package/dist/cli/core/migrate-directory.d.ts.map +1 -1
- package/dist/cli/core/migrate-directory.js +14 -13
- package/dist/cli/core/migrate-directory.js.map +1 -1
- package/dist/cli/core/migrations.d.ts.map +1 -1
- package/dist/cli/core/migrations.js +22 -8
- package/dist/cli/core/migrations.js.map +1 -1
- package/dist/cli/core/nap.d.ts.map +1 -1
- package/dist/cli/core/nap.js +111 -49
- package/dist/cli/core/nap.js.map +1 -1
- package/dist/cli/core/project-type.d.ts.map +1 -1
- package/dist/cli/core/project-type.js +11 -10
- package/dist/cli/core/project-type.js.map +1 -1
- package/dist/cli/core/team-md.d.ts.map +1 -1
- package/dist/cli/core/team-md.js +9 -4
- package/dist/cli/core/team-md.js.map +1 -1
- package/dist/cli/core/templates.d.ts.map +1 -1
- package/dist/cli/core/templates.js +4 -3
- package/dist/cli/core/templates.js.map +1 -1
- package/dist/cli/core/upgrade.d.ts.map +1 -1
- package/dist/cli/core/upgrade.js +68 -55
- package/dist/cli/core/upgrade.js.map +1 -1
- package/dist/cli/core/version.d.ts.map +1 -1
- package/dist/cli/core/version.js +8 -7
- package/dist/cli/core/version.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/self-update.d.ts.map +1 -1
- package/dist/cli/self-update.js +7 -4
- package/dist/cli/self-update.js.map +1 -1
- package/dist/cli/shell/agent-name-parser.d.ts +16 -0
- package/dist/cli/shell/agent-name-parser.d.ts.map +1 -0
- package/dist/cli/shell/agent-name-parser.js +54 -0
- package/dist/cli/shell/agent-name-parser.js.map +1 -0
- package/dist/cli/shell/commands.d.ts.map +1 -1
- package/dist/cli/shell/commands.js +4 -3
- package/dist/cli/shell/commands.js.map +1 -1
- package/dist/cli/shell/coordinator.d.ts +4 -1
- package/dist/cli/shell/coordinator.d.ts.map +1 -1
- package/dist/cli/shell/coordinator.js +29 -26
- package/dist/cli/shell/coordinator.js.map +1 -1
- package/dist/cli/shell/index.d.ts.map +1 -1
- package/dist/cli/shell/index.js +33 -35
- package/dist/cli/shell/index.js.map +1 -1
- package/dist/cli/shell/lifecycle.d.ts +13 -2
- package/dist/cli/shell/lifecycle.d.ts.map +1 -1
- package/dist/cli/shell/lifecycle.js +26 -13
- package/dist/cli/shell/lifecycle.js.map +1 -1
- package/dist/cli/shell/session-store.d.ts.map +1 -1
- package/dist/cli/shell/session-store.js +16 -12
- package/dist/cli/shell/session-store.js.map +1 -1
- package/dist/cli/shell/spawn.d.ts +4 -1
- package/dist/cli/shell/spawn.d.ts.map +1 -1
- package/dist/cli/shell/spawn.js +28 -10
- package/dist/cli/shell/spawn.js.map +1 -1
- package/dist/cli-entry.js +83 -12
- package/dist/cli-entry.js.map +1 -1
- package/package.json +8 -4
- package/templates/scribe-charter.md +4 -0
- package/templates/skills/cross-machine-coordination/SKILL.md +434 -0
- package/templates/skills/error-recovery/SKILL.md +99 -0
- package/templates/skills/iterative-retrieval/SKILL.md +165 -0
- package/templates/skills/notification-routing/SKILL.md +105 -0
- package/templates/skills/pr-screenshots/SKILL.md +149 -0
- package/templates/skills/ralph-two-pass-scan/SKILL.md +35 -0
- package/templates/skills/reflect/SKILL.md +229 -0
- package/templates/skills/release-process/SKILL.md +84 -376
- package/templates/skills/retro-enforcement/SKILL.md +148 -0
- package/templates/skills/tiered-memory/SKILL.md +234 -0
- package/templates/skills/windows-compatibility/SKILL.md +24 -0
- package/templates/{squad.agent.md → squad.agent.md.template} +1316 -1287
- package/templates/workflows/squad-ci.yml +1 -1
- package/templates/workflows/squad-heartbeat.yml +0 -4
- package/templates/workflows/squad-insider-release.yml +1 -1
- package/templates/workflows/squad-preview.yml +1 -1
- package/templates/workflows/squad-release.yml +1 -1
- package/dist/cli/commands/watch.d.ts +0 -18
- package/dist/cli/commands/watch.d.ts.map +0 -1
- package/dist/cli/commands/watch.js +0 -306
- package/dist/cli/commands/watch.js.map +0 -1
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DecisionHygiene capability — merge decision inbox when >5 files.
|
|
3
|
+
*/
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { execFile } from 'node:child_process';
|
|
6
|
+
import { FSStorageProvider } from '@bradygaster/squad-sdk';
|
|
7
|
+
const storage = new FSStorageProvider();
|
|
8
|
+
function buildAgentCommand(prompt, context) {
|
|
9
|
+
if (context.agentCmd) {
|
|
10
|
+
const parts = context.agentCmd.trim().split(/\s+/);
|
|
11
|
+
return { cmd: parts[0], args: [...parts.slice(1), '--message', prompt] };
|
|
12
|
+
}
|
|
13
|
+
const args = ['copilot', '--message', prompt];
|
|
14
|
+
if (context.copilotFlags)
|
|
15
|
+
args.push(...context.copilotFlags.trim().split(/\s+/));
|
|
16
|
+
return { cmd: 'gh', args };
|
|
17
|
+
}
|
|
18
|
+
function spawnWithTimeout(cmd, args, cwd, timeoutMs) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
execFile(cmd, args, { cwd, timeout: timeoutMs, maxBuffer: 50 * 1024 * 1024 }, (err) => {
|
|
21
|
+
if (err) {
|
|
22
|
+
const execErr = err;
|
|
23
|
+
reject(new Error(execErr.killed ? `Timed out after ${Math.round(timeoutMs / 1000)}s` : execErr.message));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
resolve();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export class DecisionHygieneCapability {
|
|
32
|
+
name = 'decision-hygiene';
|
|
33
|
+
description = 'Auto-merge decision inbox when >5 files accumulate';
|
|
34
|
+
configShape = 'boolean';
|
|
35
|
+
requires = ['gh'];
|
|
36
|
+
phase = 'housekeeping';
|
|
37
|
+
async preflight(context) {
|
|
38
|
+
const inboxDir = path.join(context.teamRoot, '.squad', 'decisions', 'inbox');
|
|
39
|
+
if (!storage.existsSync(inboxDir)) {
|
|
40
|
+
return { ok: false, reason: 'no decision inbox directory found' };
|
|
41
|
+
}
|
|
42
|
+
return { ok: true };
|
|
43
|
+
}
|
|
44
|
+
async execute(context) {
|
|
45
|
+
try {
|
|
46
|
+
const inboxDir = path.join(context.teamRoot, '.squad', 'decisions', 'inbox');
|
|
47
|
+
if (!storage.existsSync(inboxDir)) {
|
|
48
|
+
return { success: true, summary: 'no decision inbox' };
|
|
49
|
+
}
|
|
50
|
+
let fileCount = 0;
|
|
51
|
+
try {
|
|
52
|
+
const files = storage.listSync?.(inboxDir) ?? [];
|
|
53
|
+
fileCount = Array.isArray(files) ? files.filter((f) => f.endsWith('.md')).length : 0;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return { success: true, summary: 'decision inbox empty' };
|
|
57
|
+
}
|
|
58
|
+
if (fileCount <= 5) {
|
|
59
|
+
return { success: true, summary: `decision inbox: ${fileCount} files (threshold: >5)` };
|
|
60
|
+
}
|
|
61
|
+
const prompt = 'Merge the decision inbox files in .squad/decisions/inbox/ into .squad/decisions.md. ' +
|
|
62
|
+
'Append each decision as a new section. After merging, delete the inbox files.';
|
|
63
|
+
const { cmd, args } = buildAgentCommand(prompt, context);
|
|
64
|
+
await spawnWithTimeout(cmd, args, context.teamRoot, 60_000);
|
|
65
|
+
return { success: true, summary: `decision inbox merged (${fileCount} files)` };
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
return { success: false, summary: `decision hygiene: ${e.message}` };
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=decision-hygiene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-hygiene.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/decision-hygiene.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execute capability — spawns Copilot sessions for eligible issues.
|
|
3
|
+
*/
|
|
4
|
+
import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
|
|
5
|
+
import type { MachineCapabilities } from '@bradygaster/squad-sdk/ralph/capabilities';
|
|
6
|
+
/** Normalized work item for execution. */
|
|
7
|
+
export interface ExecutableWorkItem {
|
|
8
|
+
number: number;
|
|
9
|
+
title: string;
|
|
10
|
+
body?: string;
|
|
11
|
+
labels: Array<{
|
|
12
|
+
name: string;
|
|
13
|
+
}>;
|
|
14
|
+
assignees: Array<{
|
|
15
|
+
login: string;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
18
|
+
/** Find issues eligible for autonomous execution. */
|
|
19
|
+
export declare function findExecutableIssues(roster: Array<{
|
|
20
|
+
name: string;
|
|
21
|
+
label: string;
|
|
22
|
+
expertise: string[];
|
|
23
|
+
}>, capabilities: MachineCapabilities | null, issues: ExecutableWorkItem[]): ExecutableWorkItem[];
|
|
24
|
+
export declare class ExecuteCapability implements WatchCapability {
|
|
25
|
+
readonly name = "execute";
|
|
26
|
+
readonly description = "Spawn Copilot sessions to work on eligible issues";
|
|
27
|
+
readonly configShape: "boolean";
|
|
28
|
+
readonly requires: string[];
|
|
29
|
+
readonly phase: "post-execute";
|
|
30
|
+
preflight(_context: WatchContext): Promise<PreflightResult>;
|
|
31
|
+
execute(context: WatchContext): Promise<CapabilityResult>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=execute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/execute.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAErF,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;AAiCD,qDAAqD;AACrD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,EACnE,YAAY,EAAE,mBAAmB,GAAG,IAAI,EACxC,MAAM,EAAE,kBAAkB,EAAE,GAC3B,kBAAkB,EAAE,CAStB;AAsCD,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;CAyChE"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execute capability — spawns Copilot sessions for eligible issues.
|
|
3
|
+
*/
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
/** Labels that block autonomous execution. */
|
|
6
|
+
const BLOCKED_LABELS = new Set([
|
|
7
|
+
'status:blocked',
|
|
8
|
+
'status:waiting-external',
|
|
9
|
+
'status:postponed',
|
|
10
|
+
'status:scheduled',
|
|
11
|
+
'status:needs-action',
|
|
12
|
+
'status:needs-decision',
|
|
13
|
+
'status:needs-review',
|
|
14
|
+
'pending-user',
|
|
15
|
+
'do-not-merge',
|
|
16
|
+
]);
|
|
17
|
+
/** Build agent command for a prompt. */
|
|
18
|
+
function buildAgentCommand(prompt, context) {
|
|
19
|
+
if (context.agentCmd) {
|
|
20
|
+
const parts = context.agentCmd.trim().split(/\s+/);
|
|
21
|
+
const cmd = parts[0];
|
|
22
|
+
const args = [...parts.slice(1), '--message', prompt];
|
|
23
|
+
return { cmd, args };
|
|
24
|
+
}
|
|
25
|
+
const args = ['copilot', '--message', prompt];
|
|
26
|
+
if (context.copilotFlags) {
|
|
27
|
+
args.push(...context.copilotFlags.trim().split(/\s+/));
|
|
28
|
+
}
|
|
29
|
+
return { cmd: 'gh', args };
|
|
30
|
+
}
|
|
31
|
+
/** Find issues eligible for autonomous execution. */
|
|
32
|
+
export function findExecutableIssues(roster, capabilities, issues) {
|
|
33
|
+
const memberLabels = new Set(roster.map(m => m.label));
|
|
34
|
+
return issues.filter(issue => {
|
|
35
|
+
const labels = issue.labels.map(l => l.name);
|
|
36
|
+
if (!labels.some(l => memberLabels.has(l)))
|
|
37
|
+
return false;
|
|
38
|
+
if (issue.assignees && issue.assignees.length > 0)
|
|
39
|
+
return false;
|
|
40
|
+
if (labels.some(l => BLOCKED_LABELS.has(l)))
|
|
41
|
+
return false;
|
|
42
|
+
return true;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/** Spawn agent for a single issue. */
|
|
46
|
+
async function executeOne(issue, context, timeoutMs) {
|
|
47
|
+
// Claim the issue
|
|
48
|
+
try {
|
|
49
|
+
await context.adapter.addTag(issue.number, 'status:in-progress');
|
|
50
|
+
}
|
|
51
|
+
catch { /* best-effort */ }
|
|
52
|
+
try {
|
|
53
|
+
await context.adapter.addComment(issue.number, '🤖 Ralph: starting autonomous work on this issue.');
|
|
54
|
+
}
|
|
55
|
+
catch { /* best-effort */ }
|
|
56
|
+
const prompt = `Work on issue #${issue.number}: ${issue.title}. Read the issue body for full details.`;
|
|
57
|
+
const { cmd, args } = buildAgentCommand(prompt, context);
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
const _cp = execFile(cmd, args, { cwd: context.teamRoot, timeout: timeoutMs, maxBuffer: 50 * 1024 * 1024 }, (err) => {
|
|
60
|
+
if (err) {
|
|
61
|
+
const execErr = err;
|
|
62
|
+
const msg = execErr.killed ? `Timed out` : execErr.message;
|
|
63
|
+
resolve({ success: false, error: msg });
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
resolve({ success: true });
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export class ExecuteCapability {
|
|
72
|
+
name = 'execute';
|
|
73
|
+
description = 'Spawn Copilot sessions to work on eligible issues';
|
|
74
|
+
configShape = 'boolean';
|
|
75
|
+
requires = ['gh'];
|
|
76
|
+
phase = 'post-execute';
|
|
77
|
+
async preflight(_context) {
|
|
78
|
+
return new Promise((resolve) => {
|
|
79
|
+
execFile('gh', ['--version'], (err) => {
|
|
80
|
+
resolve(err ? { ok: false, reason: 'gh CLI not found' } : { ok: true });
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async execute(context) {
|
|
85
|
+
try {
|
|
86
|
+
const maxConcurrent = context.config['maxConcurrent'] ?? 1;
|
|
87
|
+
const timeout = (context.config['timeout'] ?? 30) * 60_000;
|
|
88
|
+
// Fetch open issues with squad label
|
|
89
|
+
const sdkItems = await context.adapter.listWorkItems({ tags: ['squad'], state: 'open', limit: 50 });
|
|
90
|
+
const issues = sdkItems.map(wi => ({
|
|
91
|
+
number: wi.id,
|
|
92
|
+
title: wi.title,
|
|
93
|
+
labels: wi.tags.map(t => ({ name: t })),
|
|
94
|
+
assignees: wi.assignedTo ? [{ login: wi.assignedTo }] : [],
|
|
95
|
+
}));
|
|
96
|
+
// Filter by capabilities
|
|
97
|
+
const { filterByCapabilities, loadCapabilities } = await import('@bradygaster/squad-sdk/ralph/capabilities');
|
|
98
|
+
const capabilities = await loadCapabilities(context.teamRoot);
|
|
99
|
+
const { handled } = filterByCapabilities(issues, capabilities);
|
|
100
|
+
const executable = findExecutableIssues(context.roster, capabilities, handled);
|
|
101
|
+
const batch = executable.slice(0, maxConcurrent);
|
|
102
|
+
if (batch.length === 0) {
|
|
103
|
+
return { success: true, summary: 'no executable issues' };
|
|
104
|
+
}
|
|
105
|
+
const results = await Promise.all(batch.map(issue => executeOne(issue, context, timeout)));
|
|
106
|
+
const succeeded = results.filter(r => r.success).length;
|
|
107
|
+
const failed = results.length - succeeded;
|
|
108
|
+
return {
|
|
109
|
+
success: true,
|
|
110
|
+
summary: `${succeeded} executed, ${failed} failed`,
|
|
111
|
+
data: { executed: succeeded, failed },
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
return { success: false, summary: `execute error: ${e.message}` };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/execute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability barrel — registers all built-in capabilities.
|
|
3
|
+
*/
|
|
4
|
+
import { CapabilityRegistry } from '../registry.js';
|
|
5
|
+
/** Create a registry pre-loaded with all built-in capabilities. */
|
|
6
|
+
export declare function createDefaultRegistry(): CapabilityRegistry;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAWpD,mEAAmE;AACnE,wBAAgB,qBAAqB,IAAI,kBAAkB,CAY1D"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability barrel — registers all built-in capabilities.
|
|
3
|
+
*/
|
|
4
|
+
import { CapabilityRegistry } from '../registry.js';
|
|
5
|
+
import { SelfPullCapability } from './self-pull.js';
|
|
6
|
+
import { ExecuteCapability } from './execute.js';
|
|
7
|
+
import { BoardCapability } from './board.js';
|
|
8
|
+
import { MonitorTeamsCapability } from './monitor-teams.js';
|
|
9
|
+
import { MonitorEmailCapability } from './monitor-email.js';
|
|
10
|
+
import { TwoPassCapability } from './two-pass.js';
|
|
11
|
+
import { WaveDispatchCapability } from './wave-dispatch.js';
|
|
12
|
+
import { RetroCapability } from './retro.js';
|
|
13
|
+
import { DecisionHygieneCapability } from './decision-hygiene.js';
|
|
14
|
+
/** Create a registry pre-loaded with all built-in capabilities. */
|
|
15
|
+
export function createDefaultRegistry() {
|
|
16
|
+
const registry = new CapabilityRegistry();
|
|
17
|
+
registry.register(new SelfPullCapability());
|
|
18
|
+
registry.register(new ExecuteCapability());
|
|
19
|
+
registry.register(new BoardCapability());
|
|
20
|
+
registry.register(new MonitorTeamsCapability());
|
|
21
|
+
registry.register(new MonitorEmailCapability());
|
|
22
|
+
registry.register(new TwoPassCapability());
|
|
23
|
+
registry.register(new WaveDispatchCapability());
|
|
24
|
+
registry.register(new RetroCapability());
|
|
25
|
+
registry.register(new DecisionHygieneCapability());
|
|
26
|
+
return registry;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE,mEAAmE;AACnE,MAAM,UAAU,qBAAqB;IACnC,MAAM,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAC5C,QAAQ,CAAC,QAAQ,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,QAAQ,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,IAAI,iBAAiB,EAAE,CAAC,CAAC;IAC3C,QAAQ,CAAC,QAAQ,CAAC,IAAI,sBAAsB,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,QAAQ,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,IAAI,yBAAyB,EAAE,CAAC,CAAC;IACnD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MonitorEmail capability — scan email for actionable items + GitHub alerts.
|
|
3
|
+
*/
|
|
4
|
+
import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
|
|
5
|
+
export declare class MonitorEmailCapability implements WatchCapability {
|
|
6
|
+
readonly name = "monitor-email";
|
|
7
|
+
readonly description = "Scan email for actionable items each round (requires WorkIQ MCP)";
|
|
8
|
+
readonly configShape: "boolean";
|
|
9
|
+
readonly requires: string[];
|
|
10
|
+
readonly phase: "housekeeping";
|
|
11
|
+
preflight(_context: WatchContext): Promise<PreflightResult>;
|
|
12
|
+
execute(context: WatchContext): Promise<CapabilityResult>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=monitor-email.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor-email.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/monitor-email.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAyBpG,qBAAa,sBAAuB,YAAW,eAAe;IAC5D,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,WAAW,sEAAsE;IAC1F,QAAQ,CAAC,WAAW,EAAG,SAAS,CAAU;IAC1C,QAAQ,CAAC,QAAQ,WAAwB;IACzC,QAAQ,CAAC,KAAK,EAAG,cAAc,CAAU;IAEnC,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAI3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAiBhE"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MonitorEmail capability — scan email for actionable items + GitHub alerts.
|
|
3
|
+
*/
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
function buildAgentCommand(prompt, context) {
|
|
6
|
+
if (context.agentCmd) {
|
|
7
|
+
const parts = context.agentCmd.trim().split(/\s+/);
|
|
8
|
+
return { cmd: parts[0], args: [...parts.slice(1), '--message', prompt] };
|
|
9
|
+
}
|
|
10
|
+
const args = ['copilot', '--message', prompt];
|
|
11
|
+
if (context.copilotFlags)
|
|
12
|
+
args.push(...context.copilotFlags.trim().split(/\s+/));
|
|
13
|
+
return { cmd: 'gh', args };
|
|
14
|
+
}
|
|
15
|
+
function spawnWithTimeout(cmd, args, cwd, timeoutMs) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
execFile(cmd, args, { cwd, timeout: timeoutMs, maxBuffer: 50 * 1024 * 1024 }, (err) => {
|
|
18
|
+
if (err) {
|
|
19
|
+
const execErr = err;
|
|
20
|
+
reject(new Error(execErr.killed ? `Timed out after ${Math.round(timeoutMs / 1000)}s` : execErr.message));
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
resolve();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export class MonitorEmailCapability {
|
|
29
|
+
name = 'monitor-email';
|
|
30
|
+
description = 'Scan email for actionable items each round (requires WorkIQ MCP)';
|
|
31
|
+
configShape = 'boolean';
|
|
32
|
+
requires = ['gh', 'WorkIQ MCP'];
|
|
33
|
+
phase = 'housekeeping';
|
|
34
|
+
async preflight(_context) {
|
|
35
|
+
return { ok: true };
|
|
36
|
+
}
|
|
37
|
+
async execute(context) {
|
|
38
|
+
try {
|
|
39
|
+
const prompt = 'Check email for actionable items. Use workiq-ask_work_iq to query: ' +
|
|
40
|
+
'"Recent emails about CI failures, Dependabot alerts, security vulnerabilities, or review requests". ' +
|
|
41
|
+
'For CI failures: check if a GitHub issue with label "ci-alert" already exists for the same workflow in the last 24 hours — if so, skip. ' +
|
|
42
|
+
'For new alerts: create a GitHub issue with label "email-bridge". ' +
|
|
43
|
+
'If a failed workflow can be re-run, attempt: gh run rerun <run-id> --failed. ' +
|
|
44
|
+
'If WorkIQ is not available, just report that and exit.';
|
|
45
|
+
const { cmd, args } = buildAgentCommand(prompt, context);
|
|
46
|
+
await spawnWithTimeout(cmd, args, context.teamRoot, 60_000);
|
|
47
|
+
return { success: true, summary: 'Email scan complete' };
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
return { success: false, summary: `Email monitor: ${e.message}` };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=monitor-email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor-email.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/monitor-email.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,SAAS,iBAAiB,CAAC,MAAc,EAAE,OAAqB;IAC9D,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAC9C,IAAI,OAAO,CAAC,YAAY;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACjF,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,IAAc,EAAE,GAAW,EAAE,SAAiB;IACnF,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;YACpF,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,OAAO,GAAG,GAAmC,CAAC;gBACpD,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3G,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,sBAAsB;IACxB,IAAI,GAAG,eAAe,CAAC;IACvB,WAAW,GAAG,kEAAkE,CAAC;IACjF,WAAW,GAAG,SAAkB,CAAC;IACjC,QAAQ,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAChC,KAAK,GAAG,cAAuB,CAAC;IAEzC,KAAK,CAAC,SAAS,CAAC,QAAsB;QACpC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAqB;QACjC,IAAI,CAAC;YACH,MAAM,MAAM,GACV,qEAAqE;gBACrE,sGAAsG;gBACtG,0IAA0I;gBAC1I,mEAAmE;gBACnE,+EAA+E;gBAC/E,wDAAwD,CAAC;YAE3D,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC5D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAC;QAC3D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAmB,CAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/E,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MonitorTeams capability — scan Teams for actionable messages via WorkIQ.
|
|
3
|
+
*/
|
|
4
|
+
import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
|
|
5
|
+
export declare class MonitorTeamsCapability implements WatchCapability {
|
|
6
|
+
readonly name = "monitor-teams";
|
|
7
|
+
readonly description = "Scan Teams for actionable messages each round (requires WorkIQ MCP)";
|
|
8
|
+
readonly configShape: "boolean";
|
|
9
|
+
readonly requires: string[];
|
|
10
|
+
readonly phase: "housekeeping";
|
|
11
|
+
preflight(_context: WatchContext): Promise<PreflightResult>;
|
|
12
|
+
execute(context: WatchContext): Promise<CapabilityResult>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=monitor-teams.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor-teams.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/monitor-teams.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA0BpG,qBAAa,sBAAuB,YAAW,eAAe;IAC5D,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,WAAW,yEAAyE;IAC7F,QAAQ,CAAC,WAAW,EAAG,SAAS,CAAU;IAC1C,QAAQ,CAAC,QAAQ,WAAwB;IACzC,QAAQ,CAAC,KAAK,EAAG,cAAc,CAAU;IAEnC,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAK3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAgBhE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MonitorTeams capability — scan Teams for actionable messages via WorkIQ.
|
|
3
|
+
*/
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
/** Build agent command from prompt, respecting --agent-cmd. */
|
|
6
|
+
function buildAgentCommand(prompt, context) {
|
|
7
|
+
if (context.agentCmd) {
|
|
8
|
+
const parts = context.agentCmd.trim().split(/\s+/);
|
|
9
|
+
return { cmd: parts[0], args: [...parts.slice(1), '--message', prompt] };
|
|
10
|
+
}
|
|
11
|
+
const args = ['copilot', '--message', prompt];
|
|
12
|
+
if (context.copilotFlags)
|
|
13
|
+
args.push(...context.copilotFlags.trim().split(/\s+/));
|
|
14
|
+
return { cmd: 'gh', args };
|
|
15
|
+
}
|
|
16
|
+
function spawnWithTimeout(cmd, args, cwd, timeoutMs) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
execFile(cmd, args, { cwd, timeout: timeoutMs, maxBuffer: 50 * 1024 * 1024 }, (err) => {
|
|
19
|
+
if (err) {
|
|
20
|
+
const execErr = err;
|
|
21
|
+
reject(new Error(execErr.killed ? `Timed out after ${Math.round(timeoutMs / 1000)}s` : execErr.message));
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
resolve();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export class MonitorTeamsCapability {
|
|
30
|
+
name = 'monitor-teams';
|
|
31
|
+
description = 'Scan Teams for actionable messages each round (requires WorkIQ MCP)';
|
|
32
|
+
configShape = 'boolean';
|
|
33
|
+
requires = ['gh', 'WorkIQ MCP'];
|
|
34
|
+
phase = 'housekeeping';
|
|
35
|
+
async preflight(_context) {
|
|
36
|
+
// WorkIQ availability can only be checked at runtime; preflight is optimistic
|
|
37
|
+
return { ok: true };
|
|
38
|
+
}
|
|
39
|
+
async execute(context) {
|
|
40
|
+
try {
|
|
41
|
+
const prompt = 'Check Teams for actionable messages from the last 30 minutes. ' +
|
|
42
|
+
'Use workiq-ask_work_iq to query: "Teams messages in last 30 min mentioning action items, reviews, urgent requests". ' +
|
|
43
|
+
'For each actionable item found, create a GitHub issue with the label "teams-bridge". ' +
|
|
44
|
+
'First check existing open issues with label "teams-bridge" to avoid duplicates. ' +
|
|
45
|
+
'If WorkIQ is not available, just report that and exit.';
|
|
46
|
+
const { cmd, args } = buildAgentCommand(prompt, context);
|
|
47
|
+
await spawnWithTimeout(cmd, args, context.teamRoot, 60_000);
|
|
48
|
+
return { success: true, summary: 'Teams scan complete' };
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
return { success: false, summary: `Teams monitor: ${e.message}` };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=monitor-teams.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monitor-teams.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/monitor-teams.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,+DAA+D;AAC/D,SAAS,iBAAiB,CAAC,MAAc,EAAE,OAAqB;IAC9D,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACnD,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5E,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAC9C,IAAI,OAAO,CAAC,YAAY;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IACjF,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW,EAAE,IAAc,EAAE,GAAW,EAAE,SAAiB;IACnF,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;YACpF,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,OAAO,GAAG,GAAmC,CAAC;gBACpD,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3G,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,OAAO,sBAAsB;IACxB,IAAI,GAAG,eAAe,CAAC;IACvB,WAAW,GAAG,qEAAqE,CAAC;IACpF,WAAW,GAAG,SAAkB,CAAC;IACjC,QAAQ,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAChC,KAAK,GAAG,cAAuB,CAAC;IAEzC,KAAK,CAAC,SAAS,CAAC,QAAsB;QACpC,8EAA8E;QAC9E,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAqB;QACjC,IAAI,CAAC;YACH,MAAM,MAAM,GACV,gEAAgE;gBAChE,sHAAsH;gBACtH,uFAAuF;gBACvF,kFAAkF;gBAClF,wDAAwD,CAAC;YAE3D,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,gBAAgB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC5D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,qBAAqB,EAAE,CAAC;QAC3D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,kBAAmB,CAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/E,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retro capability — enforce retrospective checks (Fridays or when missed).
|
|
3
|
+
*/
|
|
4
|
+
import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
|
|
5
|
+
export declare class RetroCapability implements WatchCapability {
|
|
6
|
+
readonly name = "retro";
|
|
7
|
+
readonly description = "Enforce retrospective checks (Fridays or when missed >7 days)";
|
|
8
|
+
readonly configShape: "boolean";
|
|
9
|
+
readonly requires: string[];
|
|
10
|
+
readonly phase: "housekeeping";
|
|
11
|
+
preflight(_context: WatchContext): Promise<PreflightResult>;
|
|
12
|
+
execute(context: WatchContext): Promise<CapabilityResult>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=retro.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retro.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/retro.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA2BpG,qBAAa,eAAgB,YAAW,eAAe;IACrD,QAAQ,CAAC,IAAI,WAAW;IACxB,QAAQ,CAAC,WAAW,mEAAmE;IACvF,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;IAI3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CA4ChE"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retro capability — enforce retrospective checks (Fridays or when missed).
|
|
3
|
+
*/
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { execFile } from 'node:child_process';
|
|
6
|
+
import { FSStorageProvider } from '@bradygaster/squad-sdk';
|
|
7
|
+
const storage = new FSStorageProvider();
|
|
8
|
+
function buildAgentCommand(prompt, context) {
|
|
9
|
+
if (context.agentCmd) {
|
|
10
|
+
const parts = context.agentCmd.trim().split(/\s+/);
|
|
11
|
+
return { cmd: parts[0], args: [...parts.slice(1), '--message', prompt] };
|
|
12
|
+
}
|
|
13
|
+
const args = ['copilot', '--message', prompt];
|
|
14
|
+
if (context.copilotFlags)
|
|
15
|
+
args.push(...context.copilotFlags.trim().split(/\s+/));
|
|
16
|
+
return { cmd: 'gh', args };
|
|
17
|
+
}
|
|
18
|
+
function spawnWithTimeout(cmd, args, cwd, timeoutMs) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
execFile(cmd, args, { cwd, timeout: timeoutMs, maxBuffer: 50 * 1024 * 1024 }, (err) => {
|
|
21
|
+
if (err) {
|
|
22
|
+
const execErr = err;
|
|
23
|
+
reject(new Error(execErr.killed ? `Timed out after ${Math.round(timeoutMs / 1000)}s` : execErr.message));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
resolve();
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
export class RetroCapability {
|
|
32
|
+
name = 'retro';
|
|
33
|
+
description = 'Enforce retrospective checks (Fridays or when missed >7 days)';
|
|
34
|
+
configShape = 'boolean';
|
|
35
|
+
requires = ['gh'];
|
|
36
|
+
phase = 'housekeeping';
|
|
37
|
+
async preflight(_context) {
|
|
38
|
+
return { ok: true };
|
|
39
|
+
}
|
|
40
|
+
async execute(context) {
|
|
41
|
+
try {
|
|
42
|
+
const now = new Date();
|
|
43
|
+
const isFriday = now.getUTCDay() === 5;
|
|
44
|
+
const isAfternoon = now.getUTCHours() >= 14;
|
|
45
|
+
const logDir = path.join(context.teamRoot, '.squad', 'log');
|
|
46
|
+
let lastRetroAge = Infinity;
|
|
47
|
+
try {
|
|
48
|
+
const files = storage.listSync?.(logDir) ?? [];
|
|
49
|
+
const retroFiles = (Array.isArray(files) ? files : [])
|
|
50
|
+
.filter((f) => f.includes('retrospective'));
|
|
51
|
+
if (retroFiles.length > 0) {
|
|
52
|
+
retroFiles.sort().reverse();
|
|
53
|
+
const newest = retroFiles[0];
|
|
54
|
+
const dateMatch = newest.match(/(\d{4}-\d{2}-\d{2})/);
|
|
55
|
+
if (dateMatch) {
|
|
56
|
+
const retroDate = new Date(dateMatch[1]);
|
|
57
|
+
lastRetroAge = now.getTime() - retroDate.getTime();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch { /* no log dir */ }
|
|
62
|
+
const sevenDaysMs = 7 * 24 * 60 * 60 * 1000;
|
|
63
|
+
const isDue = (isFriday && isAfternoon) || lastRetroAge > sevenDaysMs;
|
|
64
|
+
if (!isDue) {
|
|
65
|
+
return { success: true, summary: 'retro not due' };
|
|
66
|
+
}
|
|
67
|
+
const dateSlug = now.toISOString().slice(0, 10);
|
|
68
|
+
const prompt = `Run a sprint retrospective for the squad. ` +
|
|
69
|
+
`Review recent GitHub activity (issues closed, PRs merged, CI status). ` +
|
|
70
|
+
`Summarize: what went well, what didn't, action items. ` +
|
|
71
|
+
`Write the output to .squad/log/${dateSlug}-retrospective.md`;
|
|
72
|
+
const { cmd, args } = buildAgentCommand(prompt, context);
|
|
73
|
+
await spawnWithTimeout(cmd, args, context.teamRoot, 120_000);
|
|
74
|
+
return { success: true, summary: 'retrospective completed' };
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
return { success: false, summary: `retro: ${e.message}` };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=retro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retro.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/retro.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SelfPull capability — git fetch + pull --ff-only at round start.
|
|
3
|
+
*/
|
|
4
|
+
import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
|
|
5
|
+
export declare class SelfPullCapability implements WatchCapability {
|
|
6
|
+
readonly name = "self-pull";
|
|
7
|
+
readonly description = "Git fetch/pull at round start to keep work-tree current";
|
|
8
|
+
readonly configShape: "boolean";
|
|
9
|
+
readonly requires: string[];
|
|
10
|
+
readonly phase: "pre-scan";
|
|
11
|
+
preflight(_context: WatchContext): Promise<PreflightResult>;
|
|
12
|
+
execute(context: WatchContext): Promise<CapabilityResult>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=self-pull.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-pull.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/self-pull.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpG,qBAAa,kBAAmB,YAAW,eAAe;IACxD,QAAQ,CAAC,IAAI,eAAe;IAC5B,QAAQ,CAAC,WAAW,6DAA6D;IACjF,QAAQ,CAAC,WAAW,EAAG,SAAS,CAAU;IAC1C,QAAQ,CAAC,QAAQ,WAAW;IAC5B,QAAQ,CAAC,KAAK,EAAG,UAAU,CAAU;IAE/B,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAQ3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAiBhE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SelfPull capability — git fetch + pull --ff-only at round start.
|
|
3
|
+
*/
|
|
4
|
+
import { execFile } from 'node:child_process';
|
|
5
|
+
export class SelfPullCapability {
|
|
6
|
+
name = 'self-pull';
|
|
7
|
+
description = 'Git fetch/pull at round start to keep work-tree current';
|
|
8
|
+
configShape = 'boolean';
|
|
9
|
+
requires = ['git'];
|
|
10
|
+
phase = 'pre-scan';
|
|
11
|
+
async preflight(_context) {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
execFile('git', ['--version'], (err) => {
|
|
14
|
+
resolve(err ? { ok: false, reason: 'git not found' } : { ok: true });
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
async execute(context) {
|
|
19
|
+
try {
|
|
20
|
+
await new Promise((resolve, reject) => {
|
|
21
|
+
execFile('git', ['fetch', '--quiet'], { cwd: context.teamRoot }, (err) => err ? reject(err) : resolve());
|
|
22
|
+
});
|
|
23
|
+
await new Promise((resolve, reject) => {
|
|
24
|
+
execFile('git', ['pull', '--ff-only', '--quiet'], { cwd: context.teamRoot }, (err) => err ? reject(err) : resolve());
|
|
25
|
+
});
|
|
26
|
+
return { success: true, summary: 'git pull ok' };
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return { success: true, summary: 'git pull skipped (not on tracking branch or conflicts)' };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=self-pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-pull.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/self-pull.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,OAAO,kBAAkB;IACpB,IAAI,GAAG,WAAW,CAAC;IACnB,WAAW,GAAG,yDAAyD,CAAC;IACxE,WAAW,GAAG,SAAkB,CAAC;IACjC,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,KAAK,GAAG,UAAmB,CAAC;IAErC,KAAK,CAAC,SAAS,CAAC,QAAsB;QACpC,OAAO,IAAI,OAAO,CAAkB,CAAC,OAAO,EAAE,EAAE;YAC9C,QAAQ,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;gBACrC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YACvE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,OAAqB;QACjC,IAAI,CAAC;YACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CACvE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAC9B,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC1C,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CACnF,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAC9B,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,wDAAwD,EAAE,CAAC;QAC9F,CAAC;IACH,CAAC;CACF"}
|