mcp-subagents-opencode 1.0.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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +602 -0
  3. package/build/config/timeouts.d.ts +9 -0
  4. package/build/config/timeouts.d.ts.map +1 -0
  5. package/build/config/timeouts.js +18 -0
  6. package/build/config/timeouts.js.map +1 -0
  7. package/build/helpers.d.ts +6 -0
  8. package/build/helpers.d.ts.map +1 -0
  9. package/build/helpers.js +47 -0
  10. package/build/helpers.js.map +1 -0
  11. package/build/index.d.ts +3 -0
  12. package/build/index.d.ts.map +1 -0
  13. package/build/index.js +245 -0
  14. package/build/index.js.map +1 -0
  15. package/build/models.d.ts +32 -0
  16. package/build/models.d.ts.map +1 -0
  17. package/build/models.js +58 -0
  18. package/build/models.js.map +1 -0
  19. package/build/server/register-notifications.d.ts +3 -0
  20. package/build/server/register-notifications.d.ts.map +1 -0
  21. package/build/server/register-notifications.js +77 -0
  22. package/build/server/register-notifications.js.map +1 -0
  23. package/build/server/register-resources.d.ts +3 -0
  24. package/build/server/register-resources.d.ts.map +1 -0
  25. package/build/server/register-resources.js +210 -0
  26. package/build/server/register-resources.js.map +1 -0
  27. package/build/server/register-retry-execution.d.ts +2 -0
  28. package/build/server/register-retry-execution.d.ts.map +1 -0
  29. package/build/server/register-retry-execution.js +28 -0
  30. package/build/server/register-retry-execution.js.map +1 -0
  31. package/build/server/register-tasks.d.ts +3 -0
  32. package/build/server/register-tasks.d.ts.map +1 -0
  33. package/build/server/register-tasks.js +52 -0
  34. package/build/server/register-tasks.js.map +1 -0
  35. package/build/server/register-tools.d.ts +3 -0
  36. package/build/server/register-tools.d.ts.map +1 -0
  37. package/build/server/register-tools.js +32 -0
  38. package/build/server/register-tools.js.map +1 -0
  39. package/build/server/resource-helpers.d.ts +21 -0
  40. package/build/server/resource-helpers.d.ts.map +1 -0
  41. package/build/server/resource-helpers.js +84 -0
  42. package/build/server/resource-helpers.js.map +1 -0
  43. package/build/services/account-manager.d.ts +88 -0
  44. package/build/services/account-manager.d.ts.map +1 -0
  45. package/build/services/account-manager.js +239 -0
  46. package/build/services/account-manager.js.map +1 -0
  47. package/build/services/claude-code-runner.d.ts +15 -0
  48. package/build/services/claude-code-runner.d.ts.map +1 -0
  49. package/build/services/claude-code-runner.js +475 -0
  50. package/build/services/claude-code-runner.js.map +1 -0
  51. package/build/services/client-context.d.ts +31 -0
  52. package/build/services/client-context.d.ts.map +1 -0
  53. package/build/services/client-context.js +44 -0
  54. package/build/services/client-context.js.map +1 -0
  55. package/build/services/exhaustion-fallback.d.ts +27 -0
  56. package/build/services/exhaustion-fallback.d.ts.map +1 -0
  57. package/build/services/exhaustion-fallback.js +30 -0
  58. package/build/services/exhaustion-fallback.js.map +1 -0
  59. package/build/services/fallback-orchestrator.d.ts +16 -0
  60. package/build/services/fallback-orchestrator.d.ts.map +1 -0
  61. package/build/services/fallback-orchestrator.js +48 -0
  62. package/build/services/fallback-orchestrator.js.map +1 -0
  63. package/build/services/opencode-client.d.ts +40 -0
  64. package/build/services/opencode-client.d.ts.map +1 -0
  65. package/build/services/opencode-client.js +147 -0
  66. package/build/services/opencode-client.js.map +1 -0
  67. package/build/services/opencode-spawner.d.ts +56 -0
  68. package/build/services/opencode-spawner.d.ts.map +1 -0
  69. package/build/services/opencode-spawner.js +426 -0
  70. package/build/services/opencode-spawner.js.map +1 -0
  71. package/build/services/output-file.d.ts +24 -0
  72. package/build/services/output-file.d.ts.map +1 -0
  73. package/build/services/output-file.js +90 -0
  74. package/build/services/output-file.js.map +1 -0
  75. package/build/services/progress-registry.d.ts +12 -0
  76. package/build/services/progress-registry.d.ts.map +1 -0
  77. package/build/services/progress-registry.js +97 -0
  78. package/build/services/progress-registry.js.map +1 -0
  79. package/build/services/question-registry.d.ts +79 -0
  80. package/build/services/question-registry.d.ts.map +1 -0
  81. package/build/services/question-registry.js +249 -0
  82. package/build/services/question-registry.js.map +1 -0
  83. package/build/services/retry-queue.d.ts +41 -0
  84. package/build/services/retry-queue.d.ts.map +1 -0
  85. package/build/services/retry-queue.js +195 -0
  86. package/build/services/retry-queue.js.map +1 -0
  87. package/build/services/sdk-client-manager.d.ts +149 -0
  88. package/build/services/sdk-client-manager.d.ts.map +1 -0
  89. package/build/services/sdk-client-manager.js +632 -0
  90. package/build/services/sdk-client-manager.js.map +1 -0
  91. package/build/services/sdk-session-adapter.d.ts +203 -0
  92. package/build/services/sdk-session-adapter.d.ts.map +1 -0
  93. package/build/services/sdk-session-adapter.js +1088 -0
  94. package/build/services/sdk-session-adapter.js.map +1 -0
  95. package/build/services/sdk-spawner.d.ts +42 -0
  96. package/build/services/sdk-spawner.d.ts.map +1 -0
  97. package/build/services/sdk-spawner.js +488 -0
  98. package/build/services/sdk-spawner.js.map +1 -0
  99. package/build/services/session-hooks.d.ts +24 -0
  100. package/build/services/session-hooks.d.ts.map +1 -0
  101. package/build/services/session-hooks.js +130 -0
  102. package/build/services/session-hooks.js.map +1 -0
  103. package/build/services/session-snapshot.d.ts +19 -0
  104. package/build/services/session-snapshot.d.ts.map +1 -0
  105. package/build/services/session-snapshot.js +203 -0
  106. package/build/services/session-snapshot.js.map +1 -0
  107. package/build/services/subscription-registry.d.ts +12 -0
  108. package/build/services/subscription-registry.d.ts.map +1 -0
  109. package/build/services/subscription-registry.js +27 -0
  110. package/build/services/subscription-registry.js.map +1 -0
  111. package/build/services/task-manager.d.ts +150 -0
  112. package/build/services/task-manager.d.ts.map +1 -0
  113. package/build/services/task-manager.js +765 -0
  114. package/build/services/task-manager.js.map +1 -0
  115. package/build/services/task-persistence.d.ts +29 -0
  116. package/build/services/task-persistence.d.ts.map +1 -0
  117. package/build/services/task-persistence.js +159 -0
  118. package/build/services/task-persistence.js.map +1 -0
  119. package/build/services/task-status-mapper.d.ts +21 -0
  120. package/build/services/task-status-mapper.d.ts.map +1 -0
  121. package/build/services/task-status-mapper.js +171 -0
  122. package/build/services/task-status-mapper.js.map +1 -0
  123. package/build/templates/index.d.ts +22 -0
  124. package/build/templates/index.d.ts.map +1 -0
  125. package/build/templates/index.js +147 -0
  126. package/build/templates/index.js.map +1 -0
  127. package/build/templates/overlays/coder-csharp.mdx +58 -0
  128. package/build/templates/overlays/coder-go.mdx +53 -0
  129. package/build/templates/overlays/coder-java.mdx +54 -0
  130. package/build/templates/overlays/coder-kotlin.mdx +56 -0
  131. package/build/templates/overlays/coder-nextjs.mdx +65 -0
  132. package/build/templates/overlays/coder-python.mdx +53 -0
  133. package/build/templates/overlays/coder-react.mdx +55 -0
  134. package/build/templates/overlays/coder-ruby.mdx +59 -0
  135. package/build/templates/overlays/coder-rust.mdx +48 -0
  136. package/build/templates/overlays/coder-supabase.mdx +268 -0
  137. package/build/templates/overlays/coder-supastarter.mdx +313 -0
  138. package/build/templates/overlays/coder-swift.mdx +56 -0
  139. package/build/templates/overlays/coder-tauri.mdx +566 -0
  140. package/build/templates/overlays/coder-triggerdev.mdx +296 -0
  141. package/build/templates/overlays/coder-typescript.mdx +45 -0
  142. package/build/templates/overlays/coder-vue.mdx +62 -0
  143. package/build/templates/overlays/planner-architecture.mdx +78 -0
  144. package/build/templates/overlays/planner-bugfix.mdx +36 -0
  145. package/build/templates/overlays/planner-feature.mdx +38 -0
  146. package/build/templates/overlays/planner-migration.mdx +50 -0
  147. package/build/templates/overlays/planner-refactor.mdx +57 -0
  148. package/build/templates/overlays/researcher-library.mdx +59 -0
  149. package/build/templates/overlays/researcher-performance.mdx +68 -0
  150. package/build/templates/overlays/researcher-security.mdx +86 -0
  151. package/build/templates/overlays/tester-graphql.mdx +191 -0
  152. package/build/templates/overlays/tester-playwright.mdx +621 -0
  153. package/build/templates/overlays/tester-rest.mdx +101 -0
  154. package/build/templates/overlays/tester-suite.mdx +177 -0
  155. package/build/templates/super-coder.mdx +529 -0
  156. package/build/templates/super-planner.mdx +568 -0
  157. package/build/templates/super-researcher.mdx +406 -0
  158. package/build/templates/super-tester.mdx +243 -0
  159. package/build/tools/answer-question.d.ts +30 -0
  160. package/build/tools/answer-question.d.ts.map +1 -0
  161. package/build/tools/answer-question.js +108 -0
  162. package/build/tools/answer-question.js.map +1 -0
  163. package/build/tools/cancel-task.d.ts +44 -0
  164. package/build/tools/cancel-task.d.ts.map +1 -0
  165. package/build/tools/cancel-task.js +144 -0
  166. package/build/tools/cancel-task.js.map +1 -0
  167. package/build/tools/send-message.d.ts +39 -0
  168. package/build/tools/send-message.d.ts.map +1 -0
  169. package/build/tools/send-message.js +124 -0
  170. package/build/tools/send-message.js.map +1 -0
  171. package/build/tools/shared-spawn.d.ts +56 -0
  172. package/build/tools/shared-spawn.d.ts.map +1 -0
  173. package/build/tools/shared-spawn.js +114 -0
  174. package/build/tools/shared-spawn.js.map +1 -0
  175. package/build/tools/spawn-agent.d.ts +85 -0
  176. package/build/tools/spawn-agent.d.ts.map +1 -0
  177. package/build/tools/spawn-agent.js +133 -0
  178. package/build/tools/spawn-agent.js.map +1 -0
  179. package/build/tools/spawn-coder.d.ts +70 -0
  180. package/build/tools/spawn-coder.d.ts.map +1 -0
  181. package/build/tools/spawn-coder.js +71 -0
  182. package/build/tools/spawn-coder.js.map +1 -0
  183. package/build/tools/spawn-planner.d.ts +70 -0
  184. package/build/tools/spawn-planner.d.ts.map +1 -0
  185. package/build/tools/spawn-planner.js +71 -0
  186. package/build/tools/spawn-planner.js.map +1 -0
  187. package/build/tools/spawn-researcher.d.ts +70 -0
  188. package/build/tools/spawn-researcher.d.ts.map +1 -0
  189. package/build/tools/spawn-researcher.js +70 -0
  190. package/build/tools/spawn-researcher.js.map +1 -0
  191. package/build/tools/spawn-task.d.ts +74 -0
  192. package/build/tools/spawn-task.d.ts.map +1 -0
  193. package/build/tools/spawn-task.js +107 -0
  194. package/build/tools/spawn-task.js.map +1 -0
  195. package/build/tools/spawn-tester.d.ts +70 -0
  196. package/build/tools/spawn-tester.d.ts.map +1 -0
  197. package/build/tools/spawn-tester.js +69 -0
  198. package/build/tools/spawn-tester.js.map +1 -0
  199. package/build/types.d.ts +101 -0
  200. package/build/types.d.ts.map +1 -0
  201. package/build/types.js +28 -0
  202. package/build/types.js.map +1 -0
  203. package/build/utils/brief-validator.d.ts +30 -0
  204. package/build/utils/brief-validator.d.ts.map +1 -0
  205. package/build/utils/brief-validator.js +254 -0
  206. package/build/utils/brief-validator.js.map +1 -0
  207. package/build/utils/format.d.ts +34 -0
  208. package/build/utils/format.d.ts.map +1 -0
  209. package/build/utils/format.js +55 -0
  210. package/build/utils/format.js.map +1 -0
  211. package/build/utils/sanitize.d.ts +240 -0
  212. package/build/utils/sanitize.d.ts.map +1 -0
  213. package/build/utils/sanitize.js +89 -0
  214. package/build/utils/sanitize.js.map +1 -0
  215. package/build/utils/task-id-generator.d.ts +10 -0
  216. package/build/utils/task-id-generator.d.ts.map +1 -0
  217. package/build/utils/task-id-generator.js +22 -0
  218. package/build/utils/task-id-generator.js.map +1 -0
  219. package/package.json +62 -0
@@ -0,0 +1,195 @@
1
+ import { TaskStatus } from '../types.js';
2
+ // Rate-limit detection patterns for HTTP error messages
3
+ const RATE_LIMIT_PATTERNS = [
4
+ /rate limit/i,
5
+ /too many requests/i,
6
+ /try again in \d+ (hour|minute|second)/i,
7
+ /exceeded.*quota/i,
8
+ /throttl/i,
9
+ ];
10
+ const DEFAULT_RETRY_DELAYS_MS = [
11
+ 5 * 60 * 1000, // 5 minutes
12
+ 10 * 60 * 1000, // 10 minutes
13
+ 20 * 60 * 1000, // 20 minutes
14
+ 40 * 60 * 1000, // 40 minutes
15
+ 60 * 60 * 1000, // 1 hour
16
+ 120 * 60 * 1000, // 2 hours (max)
17
+ ];
18
+ const MAX_RETRIES = DEFAULT_RETRY_DELAYS_MS.length;
19
+ /**
20
+ * Check if an error/output indicates rate limiting.
21
+ * Prefers structured failureContext over string parsing when available.
22
+ */
23
+ export function isRateLimitError(output, error, task) {
24
+ // Prefer structured failure context
25
+ if (task?.failureContext?.statusCode === 429) {
26
+ return true;
27
+ }
28
+ // Check quota info for exhausted quota
29
+ if (task?.quotaInfo?.remainingPercentage !== undefined && task.quotaInfo.remainingPercentage < 1) {
30
+ return true;
31
+ }
32
+ // Fallback to string pattern matching
33
+ const allText = [...output, error || ''].join('\n');
34
+ return RATE_LIMIT_PATTERNS.some(pattern => pattern.test(allText));
35
+ }
36
+ /**
37
+ * Extract rate limit wait time from error message if present.
38
+ * Returns milliseconds or null if not found.
39
+ * Prefers quotaInfo.resetDate for precise timing when available.
40
+ */
41
+ export function extractWaitTime(output, error, task) {
42
+ // Prefer quota reset date for precise timing
43
+ if (task?.quotaInfo?.resetDate) {
44
+ const resetTime = new Date(task.quotaInfo.resetDate).getTime();
45
+ const now = Date.now();
46
+ if (resetTime > now) {
47
+ return resetTime - now;
48
+ }
49
+ }
50
+ // Fallback to string parsing
51
+ const allText = [...output, error || ''].join('\n');
52
+ // Match patterns like "try again in 2 hours" or "wait 30 minutes"
53
+ const hourMatch = allText.match(/(?:try again|wait).*?(\d+)\s*hour/i);
54
+ if (hourMatch) {
55
+ return parseInt(hourMatch[1], 10) * 60 * 60 * 1000;
56
+ }
57
+ const minuteMatch = allText.match(/(?:try again|wait).*?(\d+)\s*minute/i);
58
+ if (minuteMatch) {
59
+ return parseInt(minuteMatch[1], 10) * 60 * 1000;
60
+ }
61
+ const secondMatch = allText.match(/(?:try again|wait).*?(\d+)\s*second/i);
62
+ if (secondMatch) {
63
+ return parseInt(secondMatch[1], 10) * 1000;
64
+ }
65
+ return null;
66
+ }
67
+ /**
68
+ * Calculate next retry time based on retry count and task data.
69
+ * Uses quotaInfo.resetDate when available for precise timing.
70
+ */
71
+ export function calculateNextRetryTime(retryCount, suggestedWaitMs, task) {
72
+ let delayMs;
73
+ // Priority 1: Use quota reset date if available and in the future
74
+ if (task?.quotaInfo?.resetDate) {
75
+ const resetTime = new Date(task.quotaInfo.resetDate).getTime();
76
+ const now = Date.now();
77
+ if (resetTime > now) {
78
+ // Add a small buffer (30s) after reset
79
+ return new Date(resetTime + 30000).toISOString();
80
+ }
81
+ }
82
+ // Priority 2: Use suggested wait time from error message
83
+ if (suggestedWaitMs && suggestedWaitMs > 0) {
84
+ // Add some jitter to avoid thundering herd
85
+ delayMs = suggestedWaitMs + Math.random() * 60000; // +0-60s jitter
86
+ }
87
+ else {
88
+ // Priority 3: Use exponential backoff
89
+ const index = Math.min(retryCount, DEFAULT_RETRY_DELAYS_MS.length - 1);
90
+ delayMs = DEFAULT_RETRY_DELAYS_MS[index];
91
+ }
92
+ const nextRetryTime = new Date(Date.now() + delayMs);
93
+ return nextRetryTime.toISOString();
94
+ }
95
+ /**
96
+ * Create retry info for a rate-limited task.
97
+ * Uses structured task data for better timing when available.
98
+ */
99
+ export function createRetryInfo(task, reason, existingRetryInfo) {
100
+ const retryCount = (existingRetryInfo?.retryCount ?? 0) + 1;
101
+ const suggestedWait = extractWaitTime(task.output, task.error, task);
102
+ // Use failure context for better reason if available
103
+ let enhancedReason = reason;
104
+ if (task.failureContext) {
105
+ const { errorType, statusCode, errorContext } = task.failureContext;
106
+ const parts = [];
107
+ if (statusCode)
108
+ parts.push(`status: ${statusCode}`);
109
+ if (errorType)
110
+ parts.push(`type: ${errorType}`);
111
+ if (errorContext)
112
+ parts.push(`context: ${errorContext}`);
113
+ if (parts.length > 0) {
114
+ enhancedReason = `${reason} (${parts.join(', ')})`;
115
+ }
116
+ }
117
+ return {
118
+ reason: enhancedReason,
119
+ retryCount,
120
+ nextRetryTime: calculateNextRetryTime(retryCount - 1, suggestedWait, task),
121
+ maxRetries: MAX_RETRIES,
122
+ originalTaskId: existingRetryInfo?.originalTaskId || task.id,
123
+ };
124
+ }
125
+ /**
126
+ * Check if a task should be retried now.
127
+ * Considers quota info when deciding whether to retry.
128
+ */
129
+ export function shouldRetryNow(task) {
130
+ if (task.status !== TaskStatus.RATE_LIMITED) {
131
+ return false;
132
+ }
133
+ if (!task.retryInfo) {
134
+ return true; // No retry info, retry immediately
135
+ }
136
+ if (task.retryInfo.retryCount >= task.retryInfo.maxRetries) {
137
+ return false; // Max retries exceeded
138
+ }
139
+ // Check quota reset date if available
140
+ if (task.quotaInfo?.resetDate) {
141
+ const resetTime = new Date(task.quotaInfo.resetDate).getTime();
142
+ if (Date.now() < resetTime) {
143
+ return false; // Quota hasn't reset yet
144
+ }
145
+ }
146
+ const nextRetryTime = new Date(task.retryInfo.nextRetryTime).getTime();
147
+ return Date.now() >= nextRetryTime;
148
+ }
149
+ /**
150
+ * Check if a task has exceeded max retries.
151
+ */
152
+ export function hasExceededMaxRetries(task) {
153
+ if (!task.retryInfo) {
154
+ return false;
155
+ }
156
+ return task.retryInfo.retryCount >= task.retryInfo.maxRetries;
157
+ }
158
+ /**
159
+ * Check if handoff is recommended instead of retry.
160
+ * Uses task data to make intelligent recommendations.
161
+ */
162
+ export function shouldRecommendHandoff(task) {
163
+ // If max retries exceeded and we have multiple accounts, recommend handoff
164
+ if (hasExceededMaxRetries(task)) {
165
+ return true;
166
+ }
167
+ // If quota is critically low (<1%), recommend handoff
168
+ if (task.quotaInfo?.remainingPercentage !== undefined && task.quotaInfo.remainingPercentage < 1) {
169
+ return true;
170
+ }
171
+ // If failure context indicates unrecoverable rate limit, recommend handoff
172
+ if (task.failureContext?.statusCode === 429 && task.failureContext.recoverable === false) {
173
+ return true;
174
+ }
175
+ return false;
176
+ }
177
+ /**
178
+ * Get recommended action for a rate-limited task.
179
+ */
180
+ export function getRecommendedAction(task) {
181
+ if (task.status !== TaskStatus.RATE_LIMITED) {
182
+ return 'give_up';
183
+ }
184
+ if (hasExceededMaxRetries(task)) {
185
+ return shouldRecommendHandoff(task) ? 'handoff' : 'give_up';
186
+ }
187
+ if (shouldRetryNow(task)) {
188
+ return 'retry';
189
+ }
190
+ if (shouldRecommendHandoff(task)) {
191
+ return 'handoff';
192
+ }
193
+ return 'wait';
194
+ }
195
+ //# sourceMappingURL=retry-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry-queue.js","sourceRoot":"","sources":["../../src/services/retry-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * SDK Client Manager - Manages CopilotClient instances for the MCP server.
3
+ *
4
+ * Provides a singleton pattern for managing Copilot SDK clients per workspace,
5
+ * handling authentication, lifecycle, and multi-account PAT token rotation.
6
+ *
7
+ * Multi-Account Support:
8
+ * - Integrates with AccountManager for round-robin PAT token rotation
9
+ * - Automatically switches tokens on rate limit (429) or server errors (5xx)
10
+ * - Resets to first token on MCP reconnect
11
+ *
12
+ * User Input (ask_user) Support:
13
+ * - Registers onUserInputRequest handler for SDK questions
14
+ * - Forwards questions to QuestionRegistry for MCP client handling
15
+ */
16
+ import { CopilotClient, type CopilotSession, type SessionConfig } from '@github/copilot-sdk';
17
+ declare class SDKClientManager {
18
+ private clients;
19
+ private pendingClients;
20
+ private isShuttingDown;
21
+ private staleSessionTimer;
22
+ private sweepCycle;
23
+ /**
24
+ * Initialize the client manager (call on MCP connect).
25
+ * Initializes the account manager and resets to first token.
26
+ */
27
+ initialize(): void;
28
+ /**
29
+ * Reset the client manager (call on MCP reconnect).
30
+ * Clears all clients and resets account rotation to first token.
31
+ */
32
+ reset(): Promise<void>;
33
+ /**
34
+ * Get or create a CopilotClient for the given workspace.
35
+ * Uses the current token from account manager.
36
+ */
37
+ getClient(cwd: string): Promise<CopilotClient>;
38
+ /**
39
+ * Create a new CopilotClient with the specified configuration.
40
+ */
41
+ private createClient;
42
+ /**
43
+ * Create a session using the SDK client for the given workspace.
44
+ * Includes user input handler for SDK ask_user tool support.
45
+ */
46
+ createSession(cwd: string, sessionId: string, config: Omit<SessionConfig, 'sessionId'>, taskId?: string): Promise<CopilotSession>;
47
+ /**
48
+ * Resume an existing session.
49
+ * Includes user input handler for SDK ask_user tool support.
50
+ */
51
+ resumeSession(cwd: string, sessionId: string, config?: Partial<SessionConfig>, taskId?: string): Promise<CopilotSession>;
52
+ /**
53
+ * Get an active session by ID.
54
+ */
55
+ getSession(sessionId: string): CopilotSession | undefined;
56
+ /**
57
+ * Destroy a session and remove it from tracking.
58
+ */
59
+ destroySession(sessionId: string): Promise<boolean>;
60
+ /**
61
+ * Abort a running session.
62
+ */
63
+ abortSession(sessionId: string): Promise<boolean>;
64
+ /**
65
+ * Rotate to the next account on error.
66
+ * Returns the new client if rotation was successful.
67
+ *
68
+ * @param cwd - Workspace directory
69
+ * @param reason - Reason for rotation (e.g., 'rate_limit_429', 'server_error_500')
70
+ */
71
+ rotateOnError(cwd: string, reason: string): Promise<{
72
+ success: boolean;
73
+ client?: CopilotClient;
74
+ error?: string;
75
+ allExhausted?: boolean;
76
+ }>;
77
+ /**
78
+ * RC-7: Remove client entries with no active sessions that belong to non-current tokens.
79
+ * Prevents gradual resource leak from accumulated stale clients after rotation.
80
+ */
81
+ private cleanupStaleClients;
82
+ /**
83
+ * Start the periodic stale-session sweeper. Timer is unref()'d so it
84
+ * doesn't prevent the process from exiting.
85
+ */
86
+ private startStaleSessionSweeper;
87
+ /**
88
+ * Ping each client to detect dead/crashed CLI processes. Removes dead
89
+ * clients from the pool and force-stops them.
90
+ */
91
+ private checkClientHealth;
92
+ /**
93
+ * Sweep all tracked sessions. If the corresponding task (looked up by
94
+ * sessionId which equals taskId by convention) is terminal or missing,
95
+ * destroy the session with a timeout. Then recycle PTY leakers.
96
+ */
97
+ private sweepStaleSessions;
98
+ /**
99
+ * Detect server-side sessions that we're not tracking locally (orphaned from
100
+ * crashes). Uses listSessions() and deletes any not in our tracking map.
101
+ */
102
+ private detectOrphanedSessions;
103
+ /**
104
+ * For each client entry, check PTY FD count via lsof. If count exceeds
105
+ * threshold and no active sessions remain, recycle the client (stop it
106
+ * and remove from map so the next getClient() creates a fresh one).
107
+ */
108
+ private recyclePtyLeakers;
109
+ /**
110
+ * Check if rotation should happen based on error.
111
+ */
112
+ shouldRotateOnError(statusCode?: number, errorMessage?: string): boolean;
113
+ /**
114
+ * Check authentication status for current token.
115
+ */
116
+ checkAuthStatus(cwd: string): Promise<{
117
+ isAuthenticated: boolean;
118
+ login?: string;
119
+ tokenIndex: number;
120
+ }>;
121
+ /**
122
+ * List available models.
123
+ */
124
+ listModels(cwd: string): Promise<Array<{
125
+ id: string;
126
+ name: string;
127
+ }>>;
128
+ /**
129
+ * Shutdown all clients gracefully.
130
+ */
131
+ shutdown(): Promise<void>;
132
+ /**
133
+ * Get statistics about active clients, sessions, and account rotation.
134
+ */
135
+ getStats(): {
136
+ pools: number;
137
+ clients: number;
138
+ sessions: number;
139
+ accounts: {
140
+ total: number;
141
+ current: number;
142
+ rotations: number;
143
+ available: number;
144
+ };
145
+ };
146
+ }
147
+ export declare const sdkClientManager: SDKClientManager;
148
+ export {};
149
+ //# sourceMappingURL=sdk-client-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-client-manager.d.ts","sourceRoot":"","sources":["../../src/services/sdk-client-manager.ts"],"names":[],"mappings":"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"}