@bradygaster/squad-cli 0.9.1 → 0.9.2-insider.6
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 +329 -329
- 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 +57 -65
- 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/budget-check.d.ts +29 -0
- package/dist/cli/commands/watch/capabilities/budget-check.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/budget-check.js +38 -0
- package/dist/cli/commands/watch/capabilities/budget-check.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/circuit-breaker.d.ts +52 -0
- package/dist/cli/commands/watch/capabilities/circuit-breaker.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/circuit-breaker.js +152 -0
- package/dist/cli/commands/watch/capabilities/circuit-breaker.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 +156 -0
- package/dist/cli/commands/watch/capabilities/execute.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/health-check.d.ts +29 -0
- package/dist/cli/commands/watch/capabilities/health-check.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/health-check.js +139 -0
- package/dist/cli/commands/watch/capabilities/health-check.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/heartbeat.d.ts +48 -0
- package/dist/cli/commands/watch/capabilities/heartbeat.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/heartbeat.js +115 -0
- package/dist/cli/commands/watch/capabilities/heartbeat.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/index.d.ts +9 -0
- package/dist/cli/commands/watch/capabilities/index.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/index.js +40 -0
- package/dist/cli/commands/watch/capabilities/index.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/lockfile.d.ts +30 -0
- package/dist/cli/commands/watch/capabilities/lockfile.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/lockfile.js +100 -0
- package/dist/cli/commands/watch/capabilities/lockfile.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/machine-capabilities.d.ts +30 -0
- package/dist/cli/commands/watch/capabilities/machine-capabilities.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/machine-capabilities.js +103 -0
- package/dist/cli/commands/watch/capabilities/machine-capabilities.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/post-failure.d.ts +19 -0
- package/dist/cli/commands/watch/capabilities/post-failure.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/post-failure.js +58 -0
- package/dist/cli/commands/watch/capabilities/post-failure.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/priority.d.ts +59 -0
- package/dist/cli/commands/watch/capabilities/priority.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/priority.js +101 -0
- package/dist/cli/commands/watch/capabilities/priority.js.map +1 -0
- package/dist/cli/commands/watch/capabilities/rate-pool.d.ts +67 -0
- package/dist/cli/commands/watch/capabilities/rate-pool.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/rate-pool.js +187 -0
- package/dist/cli/commands/watch/capabilities/rate-pool.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/stale-reclaim.d.ts +23 -0
- package/dist/cli/commands/watch/capabilities/stale-reclaim.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/stale-reclaim.js +87 -0
- package/dist/cli/commands/watch/capabilities/stale-reclaim.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/capabilities/webhook-alerts.d.ts +29 -0
- package/dist/cli/commands/watch/capabilities/webhook-alerts.d.ts.map +1 -0
- package/dist/cli/commands/watch/capabilities/webhook-alerts.js +114 -0
- package/dist/cli/commands/watch/capabilities/webhook-alerts.js.map +1 -0
- package/dist/cli/commands/watch/config.d.ts +40 -0
- package/dist/cli/commands/watch/config.d.ts.map +1 -0
- package/dist/cli/commands/watch/config.js +129 -0
- package/dist/cli/commands/watch/config.js.map +1 -0
- package/dist/cli/commands/watch/index.d.ts +109 -0
- package/dist/cli/commands/watch/index.d.ts.map +1 -0
- package/dist/cli/commands/watch/index.js +757 -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 +116 -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 +43 -38
- 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 +136 -12
- package/dist/cli-entry.js.map +1 -1
- package/package.json +8 -4
- package/scripts/patch-esm-imports.mjs +105 -105
- package/scripts/patch-ink-rendering.mjs +115 -115
- package/templates/casting/Futurama.json +9 -9
- package/templates/casting-history.json +4 -4
- package/templates/casting-policy.json +37 -37
- package/templates/casting-reference.md +104 -104
- package/templates/casting-registry.json +3 -3
- package/templates/ceremonies.md +41 -41
- package/templates/charter.md +53 -53
- package/templates/constraint-tracking.md +38 -38
- package/templates/cooperative-rate-limiting.md +229 -229
- package/templates/copilot-instructions.md +46 -46
- package/templates/history.md +10 -10
- package/templates/identity/now.md +9 -9
- package/templates/identity/wisdom.md +15 -15
- package/templates/issue-lifecycle.md +412 -412
- package/templates/keda-scaler.md +164 -164
- package/templates/machine-capabilities.md +74 -74
- package/templates/mcp-config.md +90 -90
- package/templates/multi-agent-format.md +28 -28
- package/templates/orchestration-log.md +27 -27
- package/templates/plugin-marketplace.md +49 -49
- package/templates/ralph-circuit-breaker.md +313 -313
- package/templates/raw-agent-output.md +37 -37
- package/templates/roster.md +60 -60
- package/templates/routing.md +39 -39
- package/templates/run-output.md +50 -50
- package/templates/scribe-charter.md +123 -119
- package/templates/skill.md +24 -24
- package/templates/skills/agent-collaboration/SKILL.md +42 -42
- package/templates/skills/agent-conduct/SKILL.md +24 -24
- package/templates/skills/architectural-proposals/SKILL.md +151 -151
- package/templates/skills/ci-validation-gates/SKILL.md +84 -84
- package/templates/skills/cli-wiring/SKILL.md +47 -47
- package/templates/skills/client-compatibility/SKILL.md +89 -89
- package/templates/skills/cross-machine-coordination/SKILL.md +434 -0
- package/templates/skills/cross-squad/SKILL.md +114 -114
- package/templates/skills/distributed-mesh/SKILL.md +287 -287
- package/templates/skills/distributed-mesh/mesh.json.example +30 -30
- package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -111
- package/templates/skills/distributed-mesh/sync-mesh.sh +104 -104
- package/templates/skills/docs-standards/SKILL.md +71 -71
- package/templates/skills/economy-mode/SKILL.md +114 -114
- package/templates/skills/error-recovery/SKILL.md +99 -0
- package/templates/skills/external-comms/SKILL.md +329 -329
- package/templates/skills/gh-auth-isolation/SKILL.md +183 -183
- package/templates/skills/git-workflow/SKILL.md +204 -204
- package/templates/skills/github-multi-account/SKILL.md +95 -95
- package/templates/skills/history-hygiene/SKILL.md +36 -36
- package/templates/skills/humanizer/SKILL.md +105 -105
- package/templates/skills/init-mode/SKILL.md +102 -102
- package/templates/skills/iterative-retrieval/SKILL.md +165 -0
- package/templates/skills/model-selection/SKILL.md +117 -117
- package/templates/skills/nap/SKILL.md +24 -24
- package/templates/skills/notification-routing/SKILL.md +105 -0
- package/templates/skills/personal-squad/SKILL.md +57 -57
- 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 +131 -423
- package/templates/skills/reskill/SKILL.md +92 -92
- package/templates/skills/retro-enforcement/SKILL.md +148 -0
- package/templates/skills/reviewer-protocol/SKILL.md +79 -79
- package/templates/skills/secret-handling/SKILL.md +200 -200
- package/templates/skills/session-recovery/SKILL.md +155 -155
- package/templates/skills/squad-conventions/SKILL.md +69 -69
- package/templates/skills/test-discipline/SKILL.md +37 -37
- package/templates/skills/tiered-memory/SKILL.md +234 -0
- package/templates/skills/windows-compatibility/SKILL.md +98 -74
- package/templates/{squad.agent.md → squad.agent.md.template} +1316 -1287
- package/templates/workflows/squad-ci.yml +24 -24
- package/templates/workflows/squad-docs.yml +54 -54
- package/templates/workflows/squad-heartbeat.yml +0 -4
- package/templates/workflows/squad-insider-release.yml +61 -61
- package/templates/workflows/squad-issue-assign.yml +161 -161
- package/templates/workflows/squad-label-enforce.yml +181 -181
- package/templates/workflows/squad-preview.yml +55 -55
- package/templates/workflows/squad-promote.yml +120 -120
- package/templates/workflows/squad-release.yml +77 -77
- package/templates/workflows/squad-triage.yml +260 -260
- package/templates/workflows/sync-squad-labels.yml +169 -169
- 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,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue priority scoring — weigh issues for execution order.
|
|
3
|
+
*
|
|
4
|
+
* Ported from ralph-watch.ps1 issue scoring logic.
|
|
5
|
+
* Factors:
|
|
6
|
+
* - Priority labels: P0 (100), P1 (60), P2 (30), P3 (10)
|
|
7
|
+
* - Age bonus: +1 per day open (max +30)
|
|
8
|
+
* - Staleness: +20 if no activity in 7+ days
|
|
9
|
+
* - Bug label: +15
|
|
10
|
+
* - Size labels: size:S +10, size:M 0, size:L -5
|
|
11
|
+
*
|
|
12
|
+
* This is a utility module — not a WatchCapability.
|
|
13
|
+
* Used by the execute capability to sort issues before picking work.
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_WEIGHTS = {
|
|
16
|
+
p0: 100,
|
|
17
|
+
p1: 60,
|
|
18
|
+
p2: 30,
|
|
19
|
+
p3: 10,
|
|
20
|
+
agePerDay: 1,
|
|
21
|
+
ageMax: 30,
|
|
22
|
+
staleThresholdDays: 7,
|
|
23
|
+
staleBonus: 20,
|
|
24
|
+
bugBonus: 15,
|
|
25
|
+
sizeSBonus: 10,
|
|
26
|
+
sizeLPenalty: -5,
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Score a single issue for execution priority.
|
|
30
|
+
* Higher score = should be picked first.
|
|
31
|
+
*/
|
|
32
|
+
export function scoreIssue(issue, config) {
|
|
33
|
+
const w = { ...DEFAULT_WEIGHTS, ...(config?.weights ?? {}) };
|
|
34
|
+
const breakdown = {};
|
|
35
|
+
let score = 0;
|
|
36
|
+
const labels = new Set(issue.labels.map(l => l.name.toLowerCase()));
|
|
37
|
+
// Priority label scoring
|
|
38
|
+
if (labels.has('p0') || labels.has('priority:p0') || labels.has('priority:critical')) {
|
|
39
|
+
breakdown['priority'] = w.p0;
|
|
40
|
+
}
|
|
41
|
+
else if (labels.has('p1') || labels.has('priority:p1') || labels.has('priority:high')) {
|
|
42
|
+
breakdown['priority'] = w.p1;
|
|
43
|
+
}
|
|
44
|
+
else if (labels.has('p2') || labels.has('priority:p2') || labels.has('priority:medium')) {
|
|
45
|
+
breakdown['priority'] = w.p2;
|
|
46
|
+
}
|
|
47
|
+
else if (labels.has('p3') || labels.has('priority:p3') || labels.has('priority:low')) {
|
|
48
|
+
breakdown['priority'] = w.p3;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
breakdown['priority'] = w.p2; // Default to P2 if unlabeled
|
|
52
|
+
}
|
|
53
|
+
score += breakdown['priority'];
|
|
54
|
+
// Age bonus
|
|
55
|
+
if (issue.createdAt) {
|
|
56
|
+
const created = new Date(issue.createdAt);
|
|
57
|
+
const ageDays = Math.floor((Date.now() - created.getTime()) / (1000 * 60 * 60 * 24));
|
|
58
|
+
const ageScore = Math.min(ageDays * w.agePerDay, w.ageMax);
|
|
59
|
+
breakdown['age'] = ageScore;
|
|
60
|
+
score += ageScore;
|
|
61
|
+
}
|
|
62
|
+
// Staleness bonus
|
|
63
|
+
if (issue.updatedAt) {
|
|
64
|
+
const updated = new Date(issue.updatedAt);
|
|
65
|
+
const staleDays = Math.floor((Date.now() - updated.getTime()) / (1000 * 60 * 60 * 24));
|
|
66
|
+
if (staleDays >= w.staleThresholdDays) {
|
|
67
|
+
breakdown['stale'] = w.staleBonus;
|
|
68
|
+
score += w.staleBonus;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Bug label bonus
|
|
72
|
+
if (labels.has('bug') || labels.has('type:bug')) {
|
|
73
|
+
breakdown['bug'] = w.bugBonus;
|
|
74
|
+
score += w.bugBonus;
|
|
75
|
+
}
|
|
76
|
+
// Size label adjustment
|
|
77
|
+
if (labels.has('size:s') || labels.has('size:small')) {
|
|
78
|
+
breakdown['size'] = w.sizeSBonus;
|
|
79
|
+
score += w.sizeSBonus;
|
|
80
|
+
}
|
|
81
|
+
else if (labels.has('size:l') || labels.has('size:large') || labels.has('size:xl')) {
|
|
82
|
+
breakdown['size'] = w.sizeLPenalty;
|
|
83
|
+
score += w.sizeLPenalty;
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
number: issue.number,
|
|
87
|
+
title: issue.title,
|
|
88
|
+
labels: issue.labels,
|
|
89
|
+
score,
|
|
90
|
+
breakdown,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Score and sort a batch of issues, highest score first.
|
|
95
|
+
*/
|
|
96
|
+
export function rankIssues(issues, config) {
|
|
97
|
+
return issues
|
|
98
|
+
.map(i => scoreIssue(i, config))
|
|
99
|
+
.sort((a, b) => b.score - a.score);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=priority.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"priority.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/priority.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cooperative Rate Pool — shared API call budget across Ralph instances.
|
|
3
|
+
*
|
|
4
|
+
* Ported from ralph-watch.ps1 `New-RatePool` / `Read-RatePool` /
|
|
5
|
+
* `Write-RatePool` / `Update-RatePool` budget coordination logic.
|
|
6
|
+
*
|
|
7
|
+
* Multiple Ralph instances on different machines (or in different
|
|
8
|
+
* terminals) share a single `.squad/ralph-rate-pool.json` file.
|
|
9
|
+
* Advisory file-based locking (read-modify-write with PID stamps)
|
|
10
|
+
* keeps the pool consistent without an external lock manager.
|
|
11
|
+
*
|
|
12
|
+
* Config (via squad.config.ts → watch.ratePool):
|
|
13
|
+
* maxCallsPerInterval – max API calls in the window (default: 50)
|
|
14
|
+
* intervalSeconds – window length in seconds (default: 600)
|
|
15
|
+
* poolFile – override path (default: .squad/ralph-rate-pool.json)
|
|
16
|
+
*/
|
|
17
|
+
export interface RatePoolConfig {
|
|
18
|
+
maxCallsPerInterval?: number;
|
|
19
|
+
intervalSeconds?: number;
|
|
20
|
+
poolFile?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface RatePoolMachineEntry {
|
|
23
|
+
lastActive: string;
|
|
24
|
+
pid: number;
|
|
25
|
+
slotsHeld: number;
|
|
26
|
+
}
|
|
27
|
+
export interface RatePoolState {
|
|
28
|
+
windowStart: string;
|
|
29
|
+
slotsUsed: number;
|
|
30
|
+
maxSlots: number;
|
|
31
|
+
intervalSeconds: number;
|
|
32
|
+
machines: Record<string, RatePoolMachineEntry>;
|
|
33
|
+
}
|
|
34
|
+
export interface PoolStatus {
|
|
35
|
+
available: boolean;
|
|
36
|
+
slotsUsed: number;
|
|
37
|
+
maxSlots: number;
|
|
38
|
+
remaining: number;
|
|
39
|
+
windowSecondsLeft: number;
|
|
40
|
+
activeMachines: number;
|
|
41
|
+
}
|
|
42
|
+
export declare class RatePool {
|
|
43
|
+
private readonly poolPath;
|
|
44
|
+
private readonly maxSlots;
|
|
45
|
+
private readonly intervalSeconds;
|
|
46
|
+
constructor(squadDir: string, config?: RatePoolConfig);
|
|
47
|
+
/**
|
|
48
|
+
* Try to acquire a slot from the shared pool.
|
|
49
|
+
* Returns `true` if a slot was reserved, `false` if budget is exhausted.
|
|
50
|
+
*/
|
|
51
|
+
acquireSlot(): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Release a slot back to the pool.
|
|
54
|
+
* Safe to call even if no slot is held (clamps to zero).
|
|
55
|
+
*/
|
|
56
|
+
releaseSlot(): void;
|
|
57
|
+
/** Return a snapshot of the current pool status. */
|
|
58
|
+
getPoolStatus(): PoolStatus;
|
|
59
|
+
private newPool;
|
|
60
|
+
/** Read with retry + window-expiry reset (mirrors Read-RatePool). */
|
|
61
|
+
private read;
|
|
62
|
+
/** Atomic write: temp file → rename (mirrors Write-RatePool). */
|
|
63
|
+
private write;
|
|
64
|
+
private touchMachine;
|
|
65
|
+
private pruneStale;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=rate-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-pool.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/rate-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAQH,MAAM,WAAW,cAAc;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAsBD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc;IASrD;;;OAGG;IACH,WAAW,IAAI,OAAO;IAatB;;;OAGG;IACH,WAAW,IAAI,IAAI;IAOnB,oDAAoD;IACpD,aAAa,IAAI,UAAU;IAoB3B,OAAO,CAAC,OAAO;IAUf,qEAAqE;IACrE,OAAO,CAAC,IAAI;IA8CZ,iEAAiE;IACjE,OAAO,CAAC,KAAK;IAgCb,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,UAAU;CAQnB"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cooperative Rate Pool — shared API call budget across Ralph instances.
|
|
3
|
+
*
|
|
4
|
+
* Ported from ralph-watch.ps1 `New-RatePool` / `Read-RatePool` /
|
|
5
|
+
* `Write-RatePool` / `Update-RatePool` budget coordination logic.
|
|
6
|
+
*
|
|
7
|
+
* Multiple Ralph instances on different machines (or in different
|
|
8
|
+
* terminals) share a single `.squad/ralph-rate-pool.json` file.
|
|
9
|
+
* Advisory file-based locking (read-modify-write with PID stamps)
|
|
10
|
+
* keeps the pool consistent without an external lock manager.
|
|
11
|
+
*
|
|
12
|
+
* Config (via squad.config.ts → watch.ratePool):
|
|
13
|
+
* maxCallsPerInterval – max API calls in the window (default: 50)
|
|
14
|
+
* intervalSeconds – window length in seconds (default: 600)
|
|
15
|
+
* poolFile – override path (default: .squad/ralph-rate-pool.json)
|
|
16
|
+
*/
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
import fs from 'node:fs';
|
|
19
|
+
import os from 'node:os';
|
|
20
|
+
// ── Defaults ─────────────────────────────────────────────────────────
|
|
21
|
+
const DEFAULT_MAX_CALLS = 50;
|
|
22
|
+
const DEFAULT_INTERVAL_SECONDS = 600; // 10 minutes
|
|
23
|
+
const MAX_RETRIES = 3;
|
|
24
|
+
const RETRY_BASE_MS = 200;
|
|
25
|
+
const STALE_MACHINE_MS = 30 * 60 * 1000; // 30 minutes
|
|
26
|
+
// ── Helpers ──────────────────────────────────────────────────────────
|
|
27
|
+
function machineId() {
|
|
28
|
+
return `${os.hostname()}-${process.pid}`;
|
|
29
|
+
}
|
|
30
|
+
function nowISO() {
|
|
31
|
+
return new Date().toISOString();
|
|
32
|
+
}
|
|
33
|
+
// ── Rate Pool Class ──────────────────────────────────────────────────
|
|
34
|
+
export class RatePool {
|
|
35
|
+
poolPath;
|
|
36
|
+
maxSlots;
|
|
37
|
+
intervalSeconds;
|
|
38
|
+
constructor(squadDir, config) {
|
|
39
|
+
this.poolPath =
|
|
40
|
+
config?.poolFile ?? path.join(squadDir, 'ralph-rate-pool.json');
|
|
41
|
+
this.maxSlots = config?.maxCallsPerInterval ?? DEFAULT_MAX_CALLS;
|
|
42
|
+
this.intervalSeconds = config?.intervalSeconds ?? DEFAULT_INTERVAL_SECONDS;
|
|
43
|
+
}
|
|
44
|
+
// ── Public API ───────────────────────────────────────────────────
|
|
45
|
+
/**
|
|
46
|
+
* Try to acquire a slot from the shared pool.
|
|
47
|
+
* Returns `true` if a slot was reserved, `false` if budget is exhausted.
|
|
48
|
+
*/
|
|
49
|
+
acquireSlot() {
|
|
50
|
+
const pool = this.read();
|
|
51
|
+
if (pool.slotsUsed >= pool.maxSlots) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
pool.slotsUsed++;
|
|
55
|
+
this.touchMachine(pool, 1);
|
|
56
|
+
this.write(pool);
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Release a slot back to the pool.
|
|
61
|
+
* Safe to call even if no slot is held (clamps to zero).
|
|
62
|
+
*/
|
|
63
|
+
releaseSlot() {
|
|
64
|
+
const pool = this.read();
|
|
65
|
+
pool.slotsUsed = Math.max(0, pool.slotsUsed - 1);
|
|
66
|
+
this.touchMachine(pool, -1);
|
|
67
|
+
this.write(pool);
|
|
68
|
+
}
|
|
69
|
+
/** Return a snapshot of the current pool status. */
|
|
70
|
+
getPoolStatus() {
|
|
71
|
+
const pool = this.read();
|
|
72
|
+
const elapsed = (Date.now() - new Date(pool.windowStart).getTime()) / 1000;
|
|
73
|
+
const windowLeft = Math.max(0, pool.intervalSeconds - elapsed);
|
|
74
|
+
const activeMachines = Object.values(pool.machines).filter((m) => Date.now() - new Date(m.lastActive).getTime() < STALE_MACHINE_MS).length;
|
|
75
|
+
return {
|
|
76
|
+
available: pool.slotsUsed < pool.maxSlots,
|
|
77
|
+
slotsUsed: pool.slotsUsed,
|
|
78
|
+
maxSlots: pool.maxSlots,
|
|
79
|
+
remaining: Math.max(0, pool.maxSlots - pool.slotsUsed),
|
|
80
|
+
windowSecondsLeft: Math.round(windowLeft),
|
|
81
|
+
activeMachines,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
// ── Persistence ──────────────────────────────────────────────────
|
|
85
|
+
newPool() {
|
|
86
|
+
return {
|
|
87
|
+
windowStart: nowISO(),
|
|
88
|
+
slotsUsed: 0,
|
|
89
|
+
maxSlots: this.maxSlots,
|
|
90
|
+
intervalSeconds: this.intervalSeconds,
|
|
91
|
+
machines: {},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/** Read with retry + window-expiry reset (mirrors Read-RatePool). */
|
|
95
|
+
read() {
|
|
96
|
+
if (!fs.existsSync(this.poolPath)) {
|
|
97
|
+
const pool = this.newPool();
|
|
98
|
+
this.write(pool);
|
|
99
|
+
return pool;
|
|
100
|
+
}
|
|
101
|
+
for (let i = 0; i < MAX_RETRIES; i++) {
|
|
102
|
+
try {
|
|
103
|
+
const raw = fs.readFileSync(this.poolPath, 'utf-8');
|
|
104
|
+
const pool = JSON.parse(raw);
|
|
105
|
+
// Apply authoritative config (pool file may have been created by
|
|
106
|
+
// another instance with different settings — this instance's config wins)
|
|
107
|
+
pool.maxSlots = this.maxSlots;
|
|
108
|
+
pool.intervalSeconds = this.intervalSeconds;
|
|
109
|
+
// Window expiry check
|
|
110
|
+
const elapsed = (Date.now() - new Date(pool.windowStart).getTime()) / 1000;
|
|
111
|
+
if (elapsed >= pool.intervalSeconds) {
|
|
112
|
+
pool.windowStart = nowISO();
|
|
113
|
+
pool.slotsUsed = 0;
|
|
114
|
+
this.pruneStale(pool);
|
|
115
|
+
this.write(pool);
|
|
116
|
+
}
|
|
117
|
+
return pool;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
if (i < MAX_RETRIES - 1) {
|
|
121
|
+
// Busy-wait with escalating backoff (matches PS1 pattern)
|
|
122
|
+
const waitMs = RETRY_BASE_MS * (i + 1);
|
|
123
|
+
const end = Date.now() + waitMs;
|
|
124
|
+
while (Date.now() < end) {
|
|
125
|
+
/* spin */
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// All retries exhausted — create fresh pool
|
|
131
|
+
const pool = this.newPool();
|
|
132
|
+
this.write(pool);
|
|
133
|
+
return pool;
|
|
134
|
+
}
|
|
135
|
+
/** Atomic write: temp file → rename (mirrors Write-RatePool). */
|
|
136
|
+
write(pool) {
|
|
137
|
+
const dir = path.dirname(this.poolPath);
|
|
138
|
+
if (!fs.existsSync(dir)) {
|
|
139
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
140
|
+
}
|
|
141
|
+
const tmpFile = `${this.poolPath}.tmp.${process.pid}`;
|
|
142
|
+
for (let i = 0; i < MAX_RETRIES; i++) {
|
|
143
|
+
try {
|
|
144
|
+
fs.writeFileSync(tmpFile, JSON.stringify(pool, null, 2), 'utf-8');
|
|
145
|
+
fs.renameSync(tmpFile, this.poolPath);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
if (i >= MAX_RETRIES - 1) {
|
|
150
|
+
try {
|
|
151
|
+
fs.unlinkSync(tmpFile);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
/* ignore */
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
const waitMs = RETRY_BASE_MS * (i + 1);
|
|
159
|
+
const end = Date.now() + waitMs;
|
|
160
|
+
while (Date.now() < end) {
|
|
161
|
+
/* spin */
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// ── Machine tracking ─────────────────────────────────────────────
|
|
168
|
+
touchMachine(pool, slotDelta) {
|
|
169
|
+
const id = machineId();
|
|
170
|
+
const existing = pool.machines[id];
|
|
171
|
+
const held = Math.max(0, (existing?.slotsHeld ?? 0) + slotDelta);
|
|
172
|
+
pool.machines[id] = {
|
|
173
|
+
lastActive: nowISO(),
|
|
174
|
+
pid: process.pid,
|
|
175
|
+
slotsHeld: held,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
pruneStale(pool) {
|
|
179
|
+
const now = Date.now();
|
|
180
|
+
for (const [id, entry] of Object.entries(pool.machines)) {
|
|
181
|
+
if (now - new Date(entry.lastActive).getTime() > STALE_MACHINE_MS) {
|
|
182
|
+
delete pool.machines[id];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=rate-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-pool.js","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/rate-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stale work reclaim capability — find assigned issues with no activity
|
|
3
|
+
* and unassign them so they can be re-queued.
|
|
4
|
+
*
|
|
5
|
+
* Ported from ralph-watch.ps1 `Get-StaleIssues`.
|
|
6
|
+
*
|
|
7
|
+
* Runs in the `pre-scan` phase.
|
|
8
|
+
*
|
|
9
|
+
* Config (via squad.config.ts → watch.capabilities["stale-reclaim"]):
|
|
10
|
+
* staleHours – hours since last update to consider stale (default: 24)
|
|
11
|
+
* dryRun – log but don't actually unassign (default: false)
|
|
12
|
+
*/
|
|
13
|
+
import type { WatchCapability, WatchContext, PreflightResult, CapabilityResult } from '../types.js';
|
|
14
|
+
export declare class StaleReclaimCapability implements WatchCapability {
|
|
15
|
+
readonly name = "stale-reclaim";
|
|
16
|
+
readonly description = "Reclaim issues assigned >24h with no activity";
|
|
17
|
+
readonly configShape: "object";
|
|
18
|
+
readonly requires: string[];
|
|
19
|
+
readonly phase: "pre-scan";
|
|
20
|
+
preflight(_context: WatchContext): Promise<PreflightResult>;
|
|
21
|
+
execute(context: WatchContext): Promise<CapabilityResult>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=stale-reclaim.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-reclaim.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/watch/capabilities/stale-reclaim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpG,qBAAa,sBAAuB,YAAW,eAAe;IAC5D,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,WAAW,mDAAmD;IACvE,QAAQ,CAAC,WAAW,EAAG,QAAQ,CAAU;IACzC,QAAQ,CAAC,QAAQ,WAAU;IAC3B,QAAQ,CAAC,KAAK,EAAG,UAAU,CAAU;IAE/B,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAI3D,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAoEhE"}
|