@bradygaster/squad-sdk 0.8.24 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/dist/adapter/client.d.ts +17 -0
  2. package/dist/adapter/client.d.ts.map +1 -1
  3. package/dist/adapter/client.js +101 -1
  4. package/dist/adapter/client.js.map +1 -1
  5. package/dist/agents/history-shadow.d.ts.map +1 -1
  6. package/dist/agents/history-shadow.js +99 -32
  7. package/dist/agents/history-shadow.js.map +1 -1
  8. package/dist/agents/index.d.ts +1 -0
  9. package/dist/agents/index.d.ts.map +1 -1
  10. package/dist/agents/index.js +2 -0
  11. package/dist/agents/index.js.map +1 -1
  12. package/dist/agents/model-selector.d.ts +2 -0
  13. package/dist/agents/model-selector.d.ts.map +1 -1
  14. package/dist/agents/model-selector.js +41 -35
  15. package/dist/agents/model-selector.js.map +1 -1
  16. package/dist/agents/personal.d.ts +35 -0
  17. package/dist/agents/personal.d.ts.map +1 -0
  18. package/dist/agents/personal.js +67 -0
  19. package/dist/agents/personal.js.map +1 -0
  20. package/dist/builders/index.d.ts +3 -2
  21. package/dist/builders/index.d.ts.map +1 -1
  22. package/dist/builders/index.js +28 -0
  23. package/dist/builders/index.js.map +1 -1
  24. package/dist/builders/types.d.ts +13 -0
  25. package/dist/builders/types.d.ts.map +1 -1
  26. package/dist/config/init.d.ts +8 -0
  27. package/dist/config/init.d.ts.map +1 -1
  28. package/dist/config/init.js +131 -20
  29. package/dist/config/init.js.map +1 -1
  30. package/dist/config/models.d.ts +112 -0
  31. package/dist/config/models.d.ts.map +1 -1
  32. package/dist/config/models.js +329 -18
  33. package/dist/config/models.js.map +1 -1
  34. package/dist/coordinator/index.js +2 -2
  35. package/dist/coordinator/index.js.map +1 -1
  36. package/dist/index.d.ts +8 -3
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +7 -2
  39. package/dist/index.js.map +1 -1
  40. package/dist/platform/azure-devops.d.ts +42 -0
  41. package/dist/platform/azure-devops.d.ts.map +1 -1
  42. package/dist/platform/azure-devops.js +75 -0
  43. package/dist/platform/azure-devops.js.map +1 -1
  44. package/dist/platform/comms-file-log.d.ts.map +1 -1
  45. package/dist/platform/comms-file-log.js +2 -1
  46. package/dist/platform/comms-file-log.js.map +1 -1
  47. package/dist/platform/index.d.ts +2 -1
  48. package/dist/platform/index.d.ts.map +1 -1
  49. package/dist/platform/index.js +1 -0
  50. package/dist/platform/index.js.map +1 -1
  51. package/dist/ralph/capabilities.d.ts +67 -0
  52. package/dist/ralph/capabilities.d.ts.map +1 -0
  53. package/dist/ralph/capabilities.js +111 -0
  54. package/dist/ralph/capabilities.js.map +1 -0
  55. package/dist/ralph/index.d.ts +2 -0
  56. package/dist/ralph/index.d.ts.map +1 -1
  57. package/dist/ralph/index.js +6 -5
  58. package/dist/ralph/index.js.map +1 -1
  59. package/dist/ralph/rate-limiting.d.ts +99 -0
  60. package/dist/ralph/rate-limiting.d.ts.map +1 -0
  61. package/dist/ralph/rate-limiting.js +170 -0
  62. package/dist/ralph/rate-limiting.js.map +1 -0
  63. package/dist/resolution.d.ts +24 -2
  64. package/dist/resolution.d.ts.map +1 -1
  65. package/dist/resolution.js +106 -6
  66. package/dist/resolution.js.map +1 -1
  67. package/dist/roles/catalog-categories.d.ts +146 -0
  68. package/dist/roles/catalog-categories.d.ts.map +1 -0
  69. package/dist/roles/catalog-categories.js +374 -0
  70. package/dist/roles/catalog-categories.js.map +1 -0
  71. package/dist/roles/catalog-engineering.d.ts +212 -0
  72. package/dist/roles/catalog-engineering.d.ts.map +1 -0
  73. package/dist/roles/catalog-engineering.js +549 -0
  74. package/dist/roles/catalog-engineering.js.map +1 -0
  75. package/dist/roles/catalog.d.ts +24 -0
  76. package/dist/roles/catalog.d.ts.map +1 -0
  77. package/dist/roles/catalog.js +28 -0
  78. package/dist/roles/catalog.js.map +1 -0
  79. package/dist/roles/index.d.ts +69 -0
  80. package/dist/roles/index.d.ts.map +1 -0
  81. package/dist/roles/index.js +197 -0
  82. package/dist/roles/index.js.map +1 -0
  83. package/dist/roles/types.d.ts +87 -0
  84. package/dist/roles/types.d.ts.map +1 -0
  85. package/dist/roles/types.js +14 -0
  86. package/dist/roles/types.js.map +1 -0
  87. package/dist/runtime/benchmarks.js +5 -5
  88. package/dist/runtime/benchmarks.js.map +1 -1
  89. package/dist/runtime/constants.d.ts +2 -2
  90. package/dist/runtime/constants.d.ts.map +1 -1
  91. package/dist/runtime/constants.js +5 -3
  92. package/dist/runtime/constants.js.map +1 -1
  93. package/dist/runtime/cross-squad.d.ts +118 -0
  94. package/dist/runtime/cross-squad.d.ts.map +1 -0
  95. package/dist/runtime/cross-squad.js +234 -0
  96. package/dist/runtime/cross-squad.js.map +1 -0
  97. package/dist/runtime/otel-init.d.ts +24 -17
  98. package/dist/runtime/otel-init.d.ts.map +1 -1
  99. package/dist/runtime/otel-init.js +29 -20
  100. package/dist/runtime/otel-init.js.map +1 -1
  101. package/dist/runtime/otel-metrics.d.ts +5 -0
  102. package/dist/runtime/otel-metrics.d.ts.map +1 -1
  103. package/dist/runtime/otel-metrics.js +54 -0
  104. package/dist/runtime/otel-metrics.js.map +1 -1
  105. package/dist/runtime/rework.d.ts +71 -0
  106. package/dist/runtime/rework.d.ts.map +1 -0
  107. package/dist/runtime/rework.js +107 -0
  108. package/dist/runtime/rework.js.map +1 -0
  109. package/dist/runtime/scheduler.d.ts +128 -0
  110. package/dist/runtime/scheduler.d.ts.map +1 -0
  111. package/dist/runtime/scheduler.js +427 -0
  112. package/dist/runtime/scheduler.js.map +1 -0
  113. package/dist/runtime/squad-observer.d.ts.map +1 -1
  114. package/dist/runtime/squad-observer.js +4 -0
  115. package/dist/runtime/squad-observer.js.map +1 -1
  116. package/dist/runtime/streaming.d.ts +2 -0
  117. package/dist/runtime/streaming.d.ts.map +1 -1
  118. package/dist/runtime/streaming.js +6 -0
  119. package/dist/runtime/streaming.js.map +1 -1
  120. package/dist/runtime/telemetry.d.ts +2 -0
  121. package/dist/runtime/telemetry.d.ts.map +1 -1
  122. package/dist/runtime/telemetry.js +6 -0
  123. package/dist/runtime/telemetry.js.map +1 -1
  124. package/dist/sharing/consult.d.ts +2 -2
  125. package/dist/sharing/consult.js +6 -6
  126. package/dist/sharing/consult.js.map +1 -1
  127. package/dist/sharing/export.d.ts.map +1 -1
  128. package/dist/sharing/export.js +17 -4
  129. package/dist/sharing/export.js.map +1 -1
  130. package/dist/skills/handler-types.d.ts +271 -0
  131. package/dist/skills/handler-types.d.ts.map +1 -0
  132. package/dist/skills/handler-types.js +31 -0
  133. package/dist/skills/handler-types.js.map +1 -0
  134. package/dist/skills/index.d.ts +3 -0
  135. package/dist/skills/index.d.ts.map +1 -1
  136. package/dist/skills/index.js +3 -0
  137. package/dist/skills/index.js.map +1 -1
  138. package/dist/skills/skill-script-loader.d.ts +65 -0
  139. package/dist/skills/skill-script-loader.d.ts.map +1 -0
  140. package/dist/skills/skill-script-loader.js +227 -0
  141. package/dist/skills/skill-script-loader.js.map +1 -0
  142. package/dist/skills/skill-source.d.ts.map +1 -1
  143. package/dist/skills/skill-source.js +5 -1
  144. package/dist/skills/skill-source.js.map +1 -1
  145. package/dist/tools/index.d.ts +10 -1
  146. package/dist/tools/index.d.ts.map +1 -1
  147. package/dist/tools/index.js +49 -8
  148. package/dist/tools/index.js.map +1 -1
  149. package/dist/upstream/resolver.d.ts.map +1 -1
  150. package/dist/upstream/resolver.js +14 -5
  151. package/dist/upstream/resolver.js.map +1 -1
  152. package/package.json +34 -3
  153. package/templates/casting/Futurama.json +10 -0
  154. package/templates/casting-policy.json +4 -2
  155. package/templates/casting-reference.md +104 -0
  156. package/templates/cooperative-rate-limiting.md +229 -0
  157. package/templates/issue-lifecycle.md +412 -0
  158. package/templates/keda-scaler.md +164 -0
  159. package/templates/machine-capabilities.md +75 -0
  160. package/templates/mcp-config.md +0 -8
  161. package/templates/orchestration-log.md +27 -27
  162. package/templates/package.json +3 -0
  163. package/templates/ralph-circuit-breaker.md +313 -0
  164. package/templates/ralph-triage.js +543 -0
  165. package/templates/routing.md +5 -20
  166. package/templates/schedule.json +19 -0
  167. package/templates/scribe-charter.md +1 -1
  168. package/templates/skills/agent-collaboration/SKILL.md +42 -0
  169. package/templates/skills/agent-conduct/SKILL.md +24 -0
  170. package/templates/skills/architectural-proposals/SKILL.md +151 -0
  171. package/templates/skills/ci-validation-gates/SKILL.md +84 -0
  172. package/templates/skills/cli-wiring/SKILL.md +47 -0
  173. package/templates/skills/client-compatibility/SKILL.md +89 -0
  174. package/templates/skills/cross-squad/SKILL.md +114 -0
  175. package/templates/skills/distributed-mesh/SKILL.md +287 -0
  176. package/templates/skills/distributed-mesh/mesh.json.example +30 -0
  177. package/templates/skills/distributed-mesh/sync-mesh.ps1 +111 -0
  178. package/templates/skills/distributed-mesh/sync-mesh.sh +104 -0
  179. package/templates/skills/docs-standards/SKILL.md +71 -0
  180. package/templates/skills/economy-mode/SKILL.md +114 -0
  181. package/templates/skills/external-comms/SKILL.md +329 -0
  182. package/templates/skills/gh-auth-isolation/SKILL.md +183 -0
  183. package/templates/skills/git-workflow/SKILL.md +204 -0
  184. package/templates/skills/github-multi-account/SKILL.md +95 -0
  185. package/templates/skills/history-hygiene/SKILL.md +36 -0
  186. package/templates/skills/humanizer/SKILL.md +105 -0
  187. package/templates/skills/init-mode/SKILL.md +102 -0
  188. package/templates/skills/model-selection/SKILL.md +117 -0
  189. package/templates/skills/nap/SKILL.md +24 -0
  190. package/templates/skills/personal-squad/SKILL.md +57 -0
  191. package/templates/skills/release-process/SKILL.md +423 -0
  192. package/templates/skills/reskill/SKILL.md +92 -0
  193. package/templates/skills/reviewer-protocol/SKILL.md +79 -0
  194. package/templates/skills/secret-handling/SKILL.md +200 -0
  195. package/templates/skills/session-recovery/SKILL.md +155 -0
  196. package/templates/skills/squad-conventions/SKILL.md +69 -0
  197. package/templates/skills/test-discipline/SKILL.md +37 -0
  198. package/templates/skills/windows-compatibility/SKILL.md +74 -0
  199. package/templates/squad.agent.md +1287 -1146
  200. package/templates/workflows/squad-docs.yml +8 -4
  201. package/templates/workflows/squad-heartbeat.yml +55 -200
  202. package/templates/workflows/squad-insider-release.yml +1 -1
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Predictive Circuit Breaker — Rate Limit Protection
3
+ *
4
+ * Opens the circuit BEFORE getting a 429 by predicting when
5
+ * API quota will be exhausted. Prediction uses the observed
6
+ * consumption rate between the oldest and newest samples
7
+ * (first-to-last delta), not a full least-squares regression.
8
+ *
9
+ * @see https://github.com/bradygaster/squad/issues/515
10
+ */
11
+ /** A rate limit sample from API response headers */
12
+ export interface RateSample {
13
+ timestamp: number;
14
+ remaining: number;
15
+ limit: number;
16
+ }
17
+ /** Traffic light state for rate-aware scheduling */
18
+ export type TrafficLight = 'green' | 'amber' | 'red';
19
+ /** Agent priority for quota allocation */
20
+ export type AgentPriority = 0 | 1 | 2;
21
+ /**
22
+ * Determine traffic light from rate limit headers.
23
+ */
24
+ export declare function getTrafficLight(remaining: number, limit: number): TrafficLight;
25
+ /**
26
+ * Check if an agent should proceed based on traffic light and priority.
27
+ * - GREEN: all agents proceed
28
+ * - AMBER: only P0 agents proceed
29
+ * - RED: no agents proceed
30
+ */
31
+ export declare function shouldProceed(light: TrafficLight, priority: AgentPriority): boolean;
32
+ /**
33
+ * Get retry delay with priority-based jitter windows.
34
+ * Higher priority agents retry sooner with smaller windows.
35
+ */
36
+ export declare function getRetryDelay(priority: AgentPriority, attempt: number): number;
37
+ /**
38
+ * Predictive circuit breaker that opens BEFORE rate limit errors.
39
+ *
40
+ * Tracks the last N rate limit samples and uses linear regression
41
+ * to predict when quota will be exhausted. If predicted ETA is
42
+ * below the warning threshold, the circuit opens preemptively.
43
+ */
44
+ export declare class PredictiveCircuitBreaker {
45
+ private samples;
46
+ private readonly maxSamples;
47
+ private readonly warningThresholdSeconds;
48
+ constructor(options?: {
49
+ maxSamples?: number;
50
+ warningThresholdSeconds?: number;
51
+ });
52
+ /** Record a rate limit sample from API response headers */
53
+ addSample(remaining: number, limit: number): void;
54
+ /** Get all recorded samples (for testing/debugging) */
55
+ getSamples(): readonly RateSample[];
56
+ /**
57
+ * Predict seconds until quota exhaustion using the observed
58
+ * consumption rate between the first and last recorded samples.
59
+ * Returns null if insufficient data or quota is not being consumed.
60
+ */
61
+ predictExhaustion(): number | null;
62
+ /**
63
+ * Should the circuit open preemptively?
64
+ * Returns true when predicted ETA to exhaustion is below threshold.
65
+ */
66
+ shouldOpen(): boolean;
67
+ /** Reset all samples (e.g., after rate limit window resets) */
68
+ reset(): void;
69
+ }
70
+ /** Rate pool allocation for cooperative multi-agent quota management */
71
+ export interface RatePoolAllocation {
72
+ priority: AgentPriority;
73
+ allocated: number;
74
+ used: number;
75
+ leaseExpiry: string;
76
+ }
77
+ /** Shared rate pool state */
78
+ export interface RatePool {
79
+ totalLimit: number;
80
+ resetAt: string;
81
+ allocations: Record<string, RatePoolAllocation>;
82
+ }
83
+ /**
84
+ * Check if an agent has remaining quota in the cooperative pool.
85
+ * Pure read — no side effects.
86
+ */
87
+ export declare function canUseQuota(pool: RatePool, agentName: string): boolean;
88
+ /**
89
+ * Consume one unit of quota for an agent.
90
+ * Also reclaims stale leases from other crashed agents so their
91
+ * unused allocation is freed for the pool.
92
+ * Call this after canUseQuota() confirms there is quota available.
93
+ */
94
+ export declare function consumeQuota(pool: RatePool, agentName: string): void;
95
+ /**
96
+ * Load rate pool state from the shared file.
97
+ */
98
+ export declare function loadRatePool(teamRoot?: string): Promise<RatePool | null>;
99
+ //# sourceMappingURL=rate-limiting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiting.d.ts","sourceRoot":"","sources":["../../src/ralph/rate-limiting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oDAAoD;AACpD,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAErD,0CAA0C;AAC1C,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAStC;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAM9E;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAInF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAK9E;AAED;;;;;;GAMG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;gBAErC,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;KAAE;IAK/E,2DAA2D;IAC3D,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAOjD,uDAAuD;IACvD,UAAU,IAAI,SAAS,UAAU,EAAE;IAInC;;;;OAIG;IACH,iBAAiB,IAAI,MAAM,GAAG,IAAI;IAkBlC;;;OAGG;IACH,UAAU,IAAI,OAAO;IAMrB,+DAA+D;IAC/D,KAAK,IAAI,IAAI;CAGd;AAED,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,aAAa,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,6BAA6B;AAC7B,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CACjD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAKtE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAapE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAmB9E"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Predictive Circuit Breaker — Rate Limit Protection
3
+ *
4
+ * Opens the circuit BEFORE getting a 429 by predicting when
5
+ * API quota will be exhausted. Prediction uses the observed
6
+ * consumption rate between the oldest and newest samples
7
+ * (first-to-last delta), not a full least-squares regression.
8
+ *
9
+ * @see https://github.com/bradygaster/squad/issues/515
10
+ */
11
+ import { readFile } from 'node:fs/promises';
12
+ import { existsSync } from 'node:fs';
13
+ import path from 'node:path';
14
+ import os from 'node:os';
15
+ /** Priority-based retry windows (ms) */
16
+ const RETRY_WINDOWS = {
17
+ 0: [500, 5_000], // P0 (Lead): 500ms–5s
18
+ 1: [2_000, 30_000], // P1 (Specialists): 2s–30s
19
+ 2: [5_000, 60_000], // P2 (Ralph/Scribe): 5s–60s
20
+ };
21
+ /**
22
+ * Determine traffic light from rate limit headers.
23
+ */
24
+ export function getTrafficLight(remaining, limit) {
25
+ if (limit === 0)
26
+ return 'red';
27
+ const pct = remaining / limit;
28
+ if (pct > 0.20)
29
+ return 'green';
30
+ if (pct > 0.05)
31
+ return 'amber';
32
+ return 'red';
33
+ }
34
+ /**
35
+ * Check if an agent should proceed based on traffic light and priority.
36
+ * - GREEN: all agents proceed
37
+ * - AMBER: only P0 agents proceed
38
+ * - RED: no agents proceed
39
+ */
40
+ export function shouldProceed(light, priority) {
41
+ if (light === 'green')
42
+ return true;
43
+ if (light === 'amber')
44
+ return priority === 0;
45
+ return false;
46
+ }
47
+ /**
48
+ * Get retry delay with priority-based jitter windows.
49
+ * Higher priority agents retry sooner with smaller windows.
50
+ */
51
+ export function getRetryDelay(priority, attempt) {
52
+ const [min, max] = RETRY_WINDOWS[priority] ?? RETRY_WINDOWS[2];
53
+ const base = Math.min(min * Math.pow(2, attempt), max);
54
+ const jitter = Math.random() * base * 0.5;
55
+ return Math.round(base + jitter);
56
+ }
57
+ /**
58
+ * Predictive circuit breaker that opens BEFORE rate limit errors.
59
+ *
60
+ * Tracks the last N rate limit samples and uses linear regression
61
+ * to predict when quota will be exhausted. If predicted ETA is
62
+ * below the warning threshold, the circuit opens preemptively.
63
+ */
64
+ export class PredictiveCircuitBreaker {
65
+ samples = [];
66
+ maxSamples;
67
+ warningThresholdSeconds;
68
+ constructor(options) {
69
+ this.maxSamples = options?.maxSamples ?? 10;
70
+ this.warningThresholdSeconds = options?.warningThresholdSeconds ?? 120;
71
+ }
72
+ /** Record a rate limit sample from API response headers */
73
+ addSample(remaining, limit) {
74
+ this.samples.push({ timestamp: Date.now(), remaining, limit });
75
+ if (this.samples.length > this.maxSamples) {
76
+ this.samples.shift();
77
+ }
78
+ }
79
+ /** Get all recorded samples (for testing/debugging) */
80
+ getSamples() {
81
+ return this.samples;
82
+ }
83
+ /**
84
+ * Predict seconds until quota exhaustion using the observed
85
+ * consumption rate between the first and last recorded samples.
86
+ * Returns null if insufficient data or quota is not being consumed.
87
+ */
88
+ predictExhaustion() {
89
+ if (this.samples.length < 3)
90
+ return null;
91
+ const n = this.samples.length;
92
+ const first = this.samples[0];
93
+ const last = this.samples[n - 1];
94
+ const elapsedMs = last.timestamp - first.timestamp;
95
+ if (elapsedMs === 0)
96
+ return null;
97
+ const consumed = first.remaining - last.remaining;
98
+ if (consumed <= 0)
99
+ return null; // Not consuming or recovering
100
+ const consumedPerMs = consumed / elapsedMs;
101
+ const msUntilExhausted = last.remaining / consumedPerMs;
102
+ return msUntilExhausted / 1000;
103
+ }
104
+ /**
105
+ * Should the circuit open preemptively?
106
+ * Returns true when predicted ETA to exhaustion is below threshold.
107
+ */
108
+ shouldOpen() {
109
+ const eta = this.predictExhaustion();
110
+ if (eta === null)
111
+ return false;
112
+ return eta < this.warningThresholdSeconds;
113
+ }
114
+ /** Reset all samples (e.g., after rate limit window resets) */
115
+ reset() {
116
+ this.samples = [];
117
+ }
118
+ }
119
+ /**
120
+ * Check if an agent has remaining quota in the cooperative pool.
121
+ * Pure read — no side effects.
122
+ */
123
+ export function canUseQuota(pool, agentName) {
124
+ const alloc = pool.allocations[agentName];
125
+ if (!alloc)
126
+ return true; // Unknown agent — allow gracefully
127
+ return alloc.used < alloc.allocated;
128
+ }
129
+ /**
130
+ * Consume one unit of quota for an agent.
131
+ * Also reclaims stale leases from other crashed agents so their
132
+ * unused allocation is freed for the pool.
133
+ * Call this after canUseQuota() confirms there is quota available.
134
+ */
135
+ export function consumeQuota(pool, agentName) {
136
+ const alloc = pool.allocations[agentName];
137
+ if (!alloc)
138
+ return; // Unknown agent — nothing to consume
139
+ // Reclaim stale leases from other agents
140
+ const now = new Date();
141
+ for (const [name, a] of Object.entries(pool.allocations)) {
142
+ if (new Date(a.leaseExpiry) < now && name !== agentName) {
143
+ a.allocated = 0;
144
+ }
145
+ }
146
+ alloc.used++;
147
+ }
148
+ /**
149
+ * Load rate pool state from the shared file.
150
+ */
151
+ export async function loadRatePool(teamRoot) {
152
+ const candidates = [];
153
+ if (teamRoot) {
154
+ candidates.push(path.join(teamRoot, '.squad', 'rate-pool.json'));
155
+ }
156
+ candidates.push(path.join(os.homedir(), '.squad', 'rate-pool.json'));
157
+ for (const candidate of candidates) {
158
+ if (existsSync(candidate)) {
159
+ try {
160
+ const raw = await readFile(candidate, 'utf8');
161
+ return JSON.parse(raw);
162
+ }
163
+ catch {
164
+ // Malformed — skip
165
+ }
166
+ }
167
+ }
168
+ return null;
169
+ }
170
+ //# sourceMappingURL=rate-limiting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiting.js","sourceRoot":"","sources":["../../src/ralph/rate-limiting.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,8 @@ export interface ResolvedSquadPaths {
37
37
  projectDir: string;
38
38
  /** Team identity root (agents, casting, skills) */
39
39
  teamDir: string;
40
+ /** User's personal squad dir, null if not found or disabled */
41
+ personalDir: string | null;
40
42
  config: SquadDirConfig | null;
41
43
  name: '.squad' | '.ai-team';
42
44
  isLegacy: boolean;
@@ -44,10 +46,14 @@ export interface ResolvedSquadPaths {
44
46
  /**
45
47
  * Walk up the directory tree from `startDir` looking for a `.squad/` directory.
46
48
  *
47
- * Stops at the repository root (the directory containing `.git`).
49
+ * Stops at the repository root (the directory containing `.git` as a directory).
50
+ * When `.git` is a **file** (git worktree), falls back to the main checkout strategy:
51
+ * reads the `gitdir:` pointer, resolves the main checkout path, and checks there.
48
52
  * Returns the **absolute path** to the `.squad/` directory, or `null` if none is found.
49
53
  *
50
- * Handles nested repos, worktrees (`.git` file pointing elsewhere), and symlinks.
54
+ * Resolution order (worktree-local strategy first, main-checkout strategy second):
55
+ * 1. Walk up from `startDir` checking for `.squad/` — stops at `.git` directory boundary
56
+ * 2. If `.git` is a file (worktree), check the main checkout for `.squad/`
51
57
  *
52
58
  * @param startDir - Directory to start searching from. Defaults to `process.cwd()`.
53
59
  * @returns Absolute path to `.squad/` or `null`.
@@ -88,6 +94,16 @@ export declare function resolveSquadPaths(startDir?: string): ResolvedSquadPaths
88
94
  * @returns Absolute path to the global squad config directory.
89
95
  */
90
96
  export declare function resolveGlobalSquadPath(): string;
97
+ /**
98
+ * Resolves the user's personal squad directory.
99
+ * Returns null if SQUAD_NO_PERSONAL is set or directory doesn't exist.
100
+ *
101
+ * Platform paths:
102
+ * - Windows: %APPDATA%/squad/personal-squad
103
+ * - macOS: ~/Library/Application Support/squad/personal-squad
104
+ * - Linux: $XDG_CONFIG_HOME/squad/personal-squad or ~/.config/squad/personal-squad
105
+ */
106
+ export declare function resolvePersonalSquadDir(): string | null;
91
107
  /**
92
108
  * Validate that a file path is within `.squad/` or the system temp directory.
93
109
  *
@@ -111,6 +127,12 @@ export declare function ensureSquadPath(filePath: string, squadRoot: string): st
111
127
  * @throws If filePath is outside both roots and not in the system temp directory.
112
128
  */
113
129
  export declare function ensureSquadPathDual(filePath: string, projectDir: string, teamDir: string): string;
130
+ /**
131
+ * Validates a file path is inside one of three allowed directories:
132
+ * projectDir, teamDir, personalDir, or system temp.
133
+ * Extends ensureSquadPathDual() for triple-root (project + team + personal).
134
+ */
135
+ export declare function ensureSquadPathTriple(filePath: string, projectDir: string, teamDir: string, personalDir: string | null): string;
114
136
  /**
115
137
  * ensureSquadPath that works with resolved dual-root paths.
116
138
  * Convenience wrapper around ensureSquadPathDual.
@@ -1 +1 @@
1
- {"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA2B7D;AAyCD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CA0BrE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAEpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAiC9E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAuB/C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmB3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAyBjG;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAE3F"}
1
+ {"version":3,"file":"resolution.d.ts","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAkCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsC7D;AAyDD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CA0BrE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAEpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,IAAI,CAmC9E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAuB/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAQvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmB3E;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAyBjG;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,MAAM,CAeR;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAE3F"}
@@ -14,13 +14,50 @@
14
14
  import fs from 'node:fs';
15
15
  import path from 'node:path';
16
16
  import os from 'node:os';
17
+ /**
18
+ * Given a directory containing a `.git` worktree pointer file, parse the file
19
+ * to derive the absolute path of the main checkout.
20
+ *
21
+ * The `.git` file format is: `gitdir: <relative-or-absolute-path-to-.git/worktrees/name>`
22
+ * The main checkout is: dirname(dirname(dirname(resolvedGitdir))) — i.e. two levels up
23
+ * from the gitdir path puts us at the shared `.git/` dir, and one more dirname gives
24
+ * us the main working tree root.
25
+ *
26
+ * @returns Absolute path to the main working tree, or `null` if resolution fails.
27
+ */
28
+ function getMainWorktreePath(worktreeDir, gitFilePath) {
29
+ try {
30
+ const content = fs.readFileSync(gitFilePath, 'utf-8').trim();
31
+ const match = content.match(/^gitdir:\s*(.+)$/m);
32
+ if (!match || !match[1])
33
+ return null;
34
+ // worktreeGitDir = /main/.git/worktrees/name
35
+ const worktreeGitDir = path.resolve(worktreeDir, match[1].trim());
36
+ // mainGitDir = /main/.git (up 2 from worktreeGitDir)
37
+ const mainGitDir = path.resolve(worktreeGitDir, '..', '..');
38
+ // mainCheckout = /main (dirname of mainGitDir)
39
+ const mainCheckout = path.dirname(mainGitDir);
40
+ // Verify the derived main checkout is a real git repo
41
+ if (!fs.existsSync(mainGitDir) || !fs.statSync(mainGitDir).isDirectory()) {
42
+ return null;
43
+ }
44
+ return mainCheckout;
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
17
50
  /**
18
51
  * Walk up the directory tree from `startDir` looking for a `.squad/` directory.
19
52
  *
20
- * Stops at the repository root (the directory containing `.git`).
53
+ * Stops at the repository root (the directory containing `.git` as a directory).
54
+ * When `.git` is a **file** (git worktree), falls back to the main checkout strategy:
55
+ * reads the `gitdir:` pointer, resolves the main checkout path, and checks there.
21
56
  * Returns the **absolute path** to the `.squad/` directory, or `null` if none is found.
22
57
  *
23
- * Handles nested repos, worktrees (`.git` file pointing elsewhere), and symlinks.
58
+ * Resolution order (worktree-local strategy first, main-checkout strategy second):
59
+ * 1. Walk up from `startDir` checking for `.squad/` — stops at `.git` directory boundary
60
+ * 2. If `.git` is a file (worktree), check the main checkout for `.squad/`
24
61
  *
25
62
  * @param startDir - Directory to start searching from. Defaults to `process.cwd()`.
26
63
  * @returns Absolute path to `.squad/` or `null`.
@@ -33,10 +70,21 @@ export function resolveSquad(startDir) {
33
70
  if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
34
71
  return candidate;
35
72
  }
36
- // Stop if we hit a .git boundary (directory or worktree file)
37
73
  const gitMarker = path.join(current, '.git');
38
74
  if (fs.existsSync(gitMarker)) {
39
- // We've reached the repo root — don't walk higher
75
+ if (fs.statSync(gitMarker).isDirectory()) {
76
+ // Real repo root — stop walking, no .squad/ found in this checkout
77
+ return null;
78
+ }
79
+ // .git is a file — this is a git worktree
80
+ // Worktree-local .squad/ was already checked above; fall back to main checkout
81
+ const mainCheckout = getMainWorktreePath(current, gitMarker);
82
+ if (mainCheckout) {
83
+ const mainCandidate = path.join(mainCheckout, '.squad');
84
+ if (fs.existsSync(mainCandidate) && fs.statSync(mainCandidate).isDirectory()) {
85
+ return mainCandidate;
86
+ }
87
+ }
40
88
  return null;
41
89
  }
42
90
  const parent = path.dirname(current);
@@ -56,7 +104,10 @@ const SQUAD_DIR_NAMES = ['.squad', '.ai-team'];
56
104
  * Find the squad directory by walking up from `startDir`, checking both
57
105
  * `.squad/` and `.ai-team/` (legacy fallback).
58
106
  *
59
- * Returns the absolute path, the directory name used, and whether it's legacy.
107
+ * Worktree-aware: when `.git` is a file (worktree pointer), falls back to
108
+ * checking the main checkout for either squad directory name.
109
+ *
110
+ * Returns the absolute path and the directory name used.
60
111
  */
61
112
  function findSquadDir(startDir) {
62
113
  let current = path.resolve(startDir);
@@ -68,9 +119,22 @@ function findSquadDir(startDir) {
68
119
  return { dir: candidate, name };
69
120
  }
70
121
  }
71
- // Stop if we hit a .git boundary
72
122
  const gitMarker = path.join(current, '.git');
73
123
  if (fs.existsSync(gitMarker)) {
124
+ if (fs.statSync(gitMarker).isDirectory()) {
125
+ // Real repo root — stop, no squad dir found in this checkout
126
+ return null;
127
+ }
128
+ // .git is a file — this is a git worktree; fall back to main checkout
129
+ const mainCheckout = getMainWorktreePath(current, gitMarker);
130
+ if (mainCheckout) {
131
+ for (const name of SQUAD_DIR_NAMES) {
132
+ const candidate = path.join(mainCheckout, name);
133
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
134
+ return { dir: candidate, name };
135
+ }
136
+ }
137
+ }
74
138
  return null;
75
139
  }
76
140
  const parent = path.dirname(current);
@@ -143,6 +207,7 @@ export function resolveSquadPaths(startDir) {
143
207
  mode: 'remote',
144
208
  projectDir,
145
209
  teamDir,
210
+ personalDir: resolvePersonalSquadDir(),
146
211
  config,
147
212
  name,
148
213
  isLegacy,
@@ -153,6 +218,7 @@ export function resolveSquadPaths(startDir) {
153
218
  mode: 'local',
154
219
  projectDir,
155
220
  teamDir: projectDir,
221
+ personalDir: resolvePersonalSquadDir(),
156
222
  config,
157
223
  name,
158
224
  isLegacy,
@@ -193,6 +259,24 @@ export function resolveGlobalSquadPath() {
193
259
  }
194
260
  return globalDir;
195
261
  }
262
+ /**
263
+ * Resolves the user's personal squad directory.
264
+ * Returns null if SQUAD_NO_PERSONAL is set or directory doesn't exist.
265
+ *
266
+ * Platform paths:
267
+ * - Windows: %APPDATA%/squad/personal-squad
268
+ * - macOS: ~/Library/Application Support/squad/personal-squad
269
+ * - Linux: $XDG_CONFIG_HOME/squad/personal-squad or ~/.config/squad/personal-squad
270
+ */
271
+ export function resolvePersonalSquadDir() {
272
+ if (process.env['SQUAD_NO_PERSONAL'])
273
+ return null;
274
+ const globalDir = resolveGlobalSquadPath();
275
+ const personalDir = path.join(globalDir, 'personal-squad');
276
+ if (!fs.existsSync(personalDir))
277
+ return null;
278
+ return personalDir;
279
+ }
196
280
  /**
197
281
  * Validate that a file path is within `.squad/` or the system temp directory.
198
282
  *
@@ -249,6 +333,22 @@ export function ensureSquadPathDual(filePath, projectDir, teamDir) {
249
333
  throw new Error(`Path "${resolved}" is outside both squad roots ("${resolvedProject}", "${resolvedTeam}"). ` +
250
334
  'All squad scratch/temp/state files must be written inside a squad directory or the system temp directory.');
251
335
  }
336
+ /**
337
+ * Validates a file path is inside one of three allowed directories:
338
+ * projectDir, teamDir, personalDir, or system temp.
339
+ * Extends ensureSquadPathDual() for triple-root (project + team + personal).
340
+ */
341
+ export function ensureSquadPathTriple(filePath, projectDir, teamDir, personalDir) {
342
+ const resolved = path.resolve(filePath);
343
+ const tmpDir = os.tmpdir();
344
+ const allowed = [projectDir, teamDir, personalDir, tmpDir].filter(Boolean);
345
+ for (const dir of allowed) {
346
+ if (resolved.startsWith(path.resolve(dir) + path.sep) || resolved === path.resolve(dir)) {
347
+ return resolved;
348
+ }
349
+ }
350
+ throw new Error(`Path "${resolved}" is outside all allowed directories: ${allowed.join(', ')}`);
351
+ }
252
352
  /**
253
353
  * ensureSquadPath that works with resolved dual-root paths.
254
354
  * Convenience wrapper around ensureSquadPathDual.
@@ -1 +1 @@
1
- {"version":3,"file":"resolution.js","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resolution.js","sourceRoot":"","sources":["../src/resolution.ts"],"names":[],"mappings":"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"}