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.
- package/LICENSE +21 -0
- package/README.md +602 -0
- package/build/config/timeouts.d.ts +9 -0
- package/build/config/timeouts.d.ts.map +1 -0
- package/build/config/timeouts.js +18 -0
- package/build/config/timeouts.js.map +1 -0
- package/build/helpers.d.ts +6 -0
- package/build/helpers.d.ts.map +1 -0
- package/build/helpers.js +47 -0
- package/build/helpers.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +245 -0
- package/build/index.js.map +1 -0
- package/build/models.d.ts +32 -0
- package/build/models.d.ts.map +1 -0
- package/build/models.js +58 -0
- package/build/models.js.map +1 -0
- package/build/server/register-notifications.d.ts +3 -0
- package/build/server/register-notifications.d.ts.map +1 -0
- package/build/server/register-notifications.js +77 -0
- package/build/server/register-notifications.js.map +1 -0
- package/build/server/register-resources.d.ts +3 -0
- package/build/server/register-resources.d.ts.map +1 -0
- package/build/server/register-resources.js +210 -0
- package/build/server/register-resources.js.map +1 -0
- package/build/server/register-retry-execution.d.ts +2 -0
- package/build/server/register-retry-execution.d.ts.map +1 -0
- package/build/server/register-retry-execution.js +28 -0
- package/build/server/register-retry-execution.js.map +1 -0
- package/build/server/register-tasks.d.ts +3 -0
- package/build/server/register-tasks.d.ts.map +1 -0
- package/build/server/register-tasks.js +52 -0
- package/build/server/register-tasks.js.map +1 -0
- package/build/server/register-tools.d.ts +3 -0
- package/build/server/register-tools.d.ts.map +1 -0
- package/build/server/register-tools.js +32 -0
- package/build/server/register-tools.js.map +1 -0
- package/build/server/resource-helpers.d.ts +21 -0
- package/build/server/resource-helpers.d.ts.map +1 -0
- package/build/server/resource-helpers.js +84 -0
- package/build/server/resource-helpers.js.map +1 -0
- package/build/services/account-manager.d.ts +88 -0
- package/build/services/account-manager.d.ts.map +1 -0
- package/build/services/account-manager.js +239 -0
- package/build/services/account-manager.js.map +1 -0
- package/build/services/claude-code-runner.d.ts +15 -0
- package/build/services/claude-code-runner.d.ts.map +1 -0
- package/build/services/claude-code-runner.js +475 -0
- package/build/services/claude-code-runner.js.map +1 -0
- package/build/services/client-context.d.ts +31 -0
- package/build/services/client-context.d.ts.map +1 -0
- package/build/services/client-context.js +44 -0
- package/build/services/client-context.js.map +1 -0
- package/build/services/exhaustion-fallback.d.ts +27 -0
- package/build/services/exhaustion-fallback.d.ts.map +1 -0
- package/build/services/exhaustion-fallback.js +30 -0
- package/build/services/exhaustion-fallback.js.map +1 -0
- package/build/services/fallback-orchestrator.d.ts +16 -0
- package/build/services/fallback-orchestrator.d.ts.map +1 -0
- package/build/services/fallback-orchestrator.js +48 -0
- package/build/services/fallback-orchestrator.js.map +1 -0
- package/build/services/opencode-client.d.ts +40 -0
- package/build/services/opencode-client.d.ts.map +1 -0
- package/build/services/opencode-client.js +147 -0
- package/build/services/opencode-client.js.map +1 -0
- package/build/services/opencode-spawner.d.ts +56 -0
- package/build/services/opencode-spawner.d.ts.map +1 -0
- package/build/services/opencode-spawner.js +426 -0
- package/build/services/opencode-spawner.js.map +1 -0
- package/build/services/output-file.d.ts +24 -0
- package/build/services/output-file.d.ts.map +1 -0
- package/build/services/output-file.js +90 -0
- package/build/services/output-file.js.map +1 -0
- package/build/services/progress-registry.d.ts +12 -0
- package/build/services/progress-registry.d.ts.map +1 -0
- package/build/services/progress-registry.js +97 -0
- package/build/services/progress-registry.js.map +1 -0
- package/build/services/question-registry.d.ts +79 -0
- package/build/services/question-registry.d.ts.map +1 -0
- package/build/services/question-registry.js +249 -0
- package/build/services/question-registry.js.map +1 -0
- package/build/services/retry-queue.d.ts +41 -0
- package/build/services/retry-queue.d.ts.map +1 -0
- package/build/services/retry-queue.js +195 -0
- package/build/services/retry-queue.js.map +1 -0
- package/build/services/sdk-client-manager.d.ts +149 -0
- package/build/services/sdk-client-manager.d.ts.map +1 -0
- package/build/services/sdk-client-manager.js +632 -0
- package/build/services/sdk-client-manager.js.map +1 -0
- package/build/services/sdk-session-adapter.d.ts +203 -0
- package/build/services/sdk-session-adapter.d.ts.map +1 -0
- package/build/services/sdk-session-adapter.js +1088 -0
- package/build/services/sdk-session-adapter.js.map +1 -0
- package/build/services/sdk-spawner.d.ts +42 -0
- package/build/services/sdk-spawner.d.ts.map +1 -0
- package/build/services/sdk-spawner.js +488 -0
- package/build/services/sdk-spawner.js.map +1 -0
- package/build/services/session-hooks.d.ts +24 -0
- package/build/services/session-hooks.d.ts.map +1 -0
- package/build/services/session-hooks.js +130 -0
- package/build/services/session-hooks.js.map +1 -0
- package/build/services/session-snapshot.d.ts +19 -0
- package/build/services/session-snapshot.d.ts.map +1 -0
- package/build/services/session-snapshot.js +203 -0
- package/build/services/session-snapshot.js.map +1 -0
- package/build/services/subscription-registry.d.ts +12 -0
- package/build/services/subscription-registry.d.ts.map +1 -0
- package/build/services/subscription-registry.js +27 -0
- package/build/services/subscription-registry.js.map +1 -0
- package/build/services/task-manager.d.ts +150 -0
- package/build/services/task-manager.d.ts.map +1 -0
- package/build/services/task-manager.js +765 -0
- package/build/services/task-manager.js.map +1 -0
- package/build/services/task-persistence.d.ts +29 -0
- package/build/services/task-persistence.d.ts.map +1 -0
- package/build/services/task-persistence.js +159 -0
- package/build/services/task-persistence.js.map +1 -0
- package/build/services/task-status-mapper.d.ts +21 -0
- package/build/services/task-status-mapper.d.ts.map +1 -0
- package/build/services/task-status-mapper.js +171 -0
- package/build/services/task-status-mapper.js.map +1 -0
- package/build/templates/index.d.ts +22 -0
- package/build/templates/index.d.ts.map +1 -0
- package/build/templates/index.js +147 -0
- package/build/templates/index.js.map +1 -0
- package/build/templates/overlays/coder-csharp.mdx +58 -0
- package/build/templates/overlays/coder-go.mdx +53 -0
- package/build/templates/overlays/coder-java.mdx +54 -0
- package/build/templates/overlays/coder-kotlin.mdx +56 -0
- package/build/templates/overlays/coder-nextjs.mdx +65 -0
- package/build/templates/overlays/coder-python.mdx +53 -0
- package/build/templates/overlays/coder-react.mdx +55 -0
- package/build/templates/overlays/coder-ruby.mdx +59 -0
- package/build/templates/overlays/coder-rust.mdx +48 -0
- package/build/templates/overlays/coder-supabase.mdx +268 -0
- package/build/templates/overlays/coder-supastarter.mdx +313 -0
- package/build/templates/overlays/coder-swift.mdx +56 -0
- package/build/templates/overlays/coder-tauri.mdx +566 -0
- package/build/templates/overlays/coder-triggerdev.mdx +296 -0
- package/build/templates/overlays/coder-typescript.mdx +45 -0
- package/build/templates/overlays/coder-vue.mdx +62 -0
- package/build/templates/overlays/planner-architecture.mdx +78 -0
- package/build/templates/overlays/planner-bugfix.mdx +36 -0
- package/build/templates/overlays/planner-feature.mdx +38 -0
- package/build/templates/overlays/planner-migration.mdx +50 -0
- package/build/templates/overlays/planner-refactor.mdx +57 -0
- package/build/templates/overlays/researcher-library.mdx +59 -0
- package/build/templates/overlays/researcher-performance.mdx +68 -0
- package/build/templates/overlays/researcher-security.mdx +86 -0
- package/build/templates/overlays/tester-graphql.mdx +191 -0
- package/build/templates/overlays/tester-playwright.mdx +621 -0
- package/build/templates/overlays/tester-rest.mdx +101 -0
- package/build/templates/overlays/tester-suite.mdx +177 -0
- package/build/templates/super-coder.mdx +529 -0
- package/build/templates/super-planner.mdx +568 -0
- package/build/templates/super-researcher.mdx +406 -0
- package/build/templates/super-tester.mdx +243 -0
- package/build/tools/answer-question.d.ts +30 -0
- package/build/tools/answer-question.d.ts.map +1 -0
- package/build/tools/answer-question.js +108 -0
- package/build/tools/answer-question.js.map +1 -0
- package/build/tools/cancel-task.d.ts +44 -0
- package/build/tools/cancel-task.d.ts.map +1 -0
- package/build/tools/cancel-task.js +144 -0
- package/build/tools/cancel-task.js.map +1 -0
- package/build/tools/send-message.d.ts +39 -0
- package/build/tools/send-message.d.ts.map +1 -0
- package/build/tools/send-message.js +124 -0
- package/build/tools/send-message.js.map +1 -0
- package/build/tools/shared-spawn.d.ts +56 -0
- package/build/tools/shared-spawn.d.ts.map +1 -0
- package/build/tools/shared-spawn.js +114 -0
- package/build/tools/shared-spawn.js.map +1 -0
- package/build/tools/spawn-agent.d.ts +85 -0
- package/build/tools/spawn-agent.d.ts.map +1 -0
- package/build/tools/spawn-agent.js +133 -0
- package/build/tools/spawn-agent.js.map +1 -0
- package/build/tools/spawn-coder.d.ts +70 -0
- package/build/tools/spawn-coder.d.ts.map +1 -0
- package/build/tools/spawn-coder.js +71 -0
- package/build/tools/spawn-coder.js.map +1 -0
- package/build/tools/spawn-planner.d.ts +70 -0
- package/build/tools/spawn-planner.d.ts.map +1 -0
- package/build/tools/spawn-planner.js +71 -0
- package/build/tools/spawn-planner.js.map +1 -0
- package/build/tools/spawn-researcher.d.ts +70 -0
- package/build/tools/spawn-researcher.d.ts.map +1 -0
- package/build/tools/spawn-researcher.js +70 -0
- package/build/tools/spawn-researcher.js.map +1 -0
- package/build/tools/spawn-task.d.ts +74 -0
- package/build/tools/spawn-task.d.ts.map +1 -0
- package/build/tools/spawn-task.js +107 -0
- package/build/tools/spawn-task.js.map +1 -0
- package/build/tools/spawn-tester.d.ts +70 -0
- package/build/tools/spawn-tester.d.ts.map +1 -0
- package/build/tools/spawn-tester.js +69 -0
- package/build/tools/spawn-tester.js.map +1 -0
- package/build/types.d.ts +101 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +28 -0
- package/build/types.js.map +1 -0
- package/build/utils/brief-validator.d.ts +30 -0
- package/build/utils/brief-validator.d.ts.map +1 -0
- package/build/utils/brief-validator.js +254 -0
- package/build/utils/brief-validator.js.map +1 -0
- package/build/utils/format.d.ts +34 -0
- package/build/utils/format.d.ts.map +1 -0
- package/build/utils/format.js +55 -0
- package/build/utils/format.js.map +1 -0
- package/build/utils/sanitize.d.ts +240 -0
- package/build/utils/sanitize.d.ts.map +1 -0
- package/build/utils/sanitize.js +89 -0
- package/build/utils/sanitize.js.map +1 -0
- package/build/utils/task-id-generator.d.ts +10 -0
- package/build/utils/task-id-generator.d.ts.map +1 -0
- package/build/utils/task-id-generator.js +22 -0
- package/build/utils/task-id-generator.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,632 @@
|
|
|
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 } from '@github/copilot-sdk';
|
|
17
|
+
import { execSync } from 'node:child_process';
|
|
18
|
+
import { accountManager } from './account-manager.js';
|
|
19
|
+
import { questionRegistry } from './question-registry.js';
|
|
20
|
+
import { createSessionHooks } from './session-hooks.js';
|
|
21
|
+
import { taskManager, TERMINAL_STATUSES } from './task-manager.js';
|
|
22
|
+
const DEFAULT_COPILOT_PATH = 'copilot';
|
|
23
|
+
const COPILOT_PATH = resolveCopilotPath();
|
|
24
|
+
const PERMISSION_MODE = process.env.COPILOT_PERMISSION_MODE || 'allow_all';
|
|
25
|
+
const STRICT_PERMISSION_MODE = PERMISSION_MODE === 'safe';
|
|
26
|
+
const PTY_RECYCLE_THRESHOLD = 80;
|
|
27
|
+
const DESTROY_SESSION_TIMEOUT_MS = 10_000;
|
|
28
|
+
const CLIENT_START_TIMEOUT_MS = 30_000;
|
|
29
|
+
const CLIENT_HEALTH_CHECK_TIMEOUT_MS = 5_000;
|
|
30
|
+
const RECYCLE_STOP_TIMEOUT_MS = 10_000;
|
|
31
|
+
const SHUTDOWN_STOP_TIMEOUT_MS = 15_000;
|
|
32
|
+
const STALE_SESSION_CLEANUP_INTERVAL_MS = 60_000;
|
|
33
|
+
function resolveCopilotPath() {
|
|
34
|
+
if (process.env.COPILOT_PATH?.trim()) {
|
|
35
|
+
return process.env.COPILOT_PATH.trim();
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const resolved = execSync('command -v copilot', {
|
|
39
|
+
encoding: 'utf8',
|
|
40
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
41
|
+
timeout: 1_000,
|
|
42
|
+
}).trim();
|
|
43
|
+
if (resolved) {
|
|
44
|
+
return resolved;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Fallback below.
|
|
49
|
+
}
|
|
50
|
+
// Keep macOS Homebrew path as best-effort fallback when PATH is missing.
|
|
51
|
+
if (process.platform === 'darwin') {
|
|
52
|
+
return '/opt/homebrew/bin/copilot';
|
|
53
|
+
}
|
|
54
|
+
return DEFAULT_COPILOT_PATH;
|
|
55
|
+
}
|
|
56
|
+
function extractShellCommand(request) {
|
|
57
|
+
const candidates = ['command', 'cmd', 'shellCommand', 'input', 'value'];
|
|
58
|
+
for (const key of candidates) {
|
|
59
|
+
const value = request[key];
|
|
60
|
+
if (typeof value === 'string' && value.trim()) {
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return '';
|
|
65
|
+
}
|
|
66
|
+
function createPermissionHandler(taskId) {
|
|
67
|
+
return async (request) => {
|
|
68
|
+
if (STRICT_PERMISSION_MODE && request.kind === 'shell') {
|
|
69
|
+
const cmd = extractShellCommand(request).toLowerCase();
|
|
70
|
+
const dangerousPatterns = [
|
|
71
|
+
/\brm\s+-rf\s+\//,
|
|
72
|
+
/\bmkfs\b/,
|
|
73
|
+
/\bdd\s+if=/,
|
|
74
|
+
/\bshutdown\b/,
|
|
75
|
+
/\breboot\b/,
|
|
76
|
+
/\bchown\s+-r\s+root\b/,
|
|
77
|
+
];
|
|
78
|
+
if (dangerousPatterns.some((re) => re.test(cmd))) {
|
|
79
|
+
console.error(`[sdk-client-manager] Denied dangerous shell permission${taskId ? ` for task ${taskId}` : ''}: ${cmd}`);
|
|
80
|
+
return { kind: 'denied-by-rules' };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { kind: 'approved' };
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Generic timeout wrapper for SDK operations that can hang.
|
|
88
|
+
*/
|
|
89
|
+
function withTimeout(promise, ms, label) {
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
|
|
92
|
+
promise.then((v) => { clearTimeout(timer); resolve(v); }, (e) => { clearTimeout(timer); reject(e); });
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Retry-with-backoff wrapper for session.destroy(), matching the SDK's own
|
|
97
|
+
* 3-attempt exponential backoff pattern used in stop().
|
|
98
|
+
*/
|
|
99
|
+
async function destroySessionWithRetry(session, sessionId, totalTimeoutMs) {
|
|
100
|
+
return withTimeout((async () => {
|
|
101
|
+
const MAX_ATTEMPTS = 3;
|
|
102
|
+
let lastError = null;
|
|
103
|
+
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
104
|
+
try {
|
|
105
|
+
await session.destroy();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
lastError = err instanceof Error ? err : new Error(String(err));
|
|
110
|
+
if (attempt < MAX_ATTEMPTS) {
|
|
111
|
+
await new Promise(r => setTimeout(r, 100 * Math.pow(2, attempt - 1)));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
throw lastError;
|
|
116
|
+
})(), totalTimeoutMs, `destroy session ${sessionId} (with retries)`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Create a user input handler that forwards questions to the QuestionRegistry.
|
|
120
|
+
* This enables SDK's ask_user tool to pause and wait for MCP client response.
|
|
121
|
+
*/
|
|
122
|
+
function createUserInputHandler(taskId) {
|
|
123
|
+
return async (request, invocation) => {
|
|
124
|
+
console.error(`[sdk-client-manager] User input requested for task ${taskId}, session ${invocation.sessionId}: "${request.question}"`);
|
|
125
|
+
// Register question and wait for answer via QuestionRegistry
|
|
126
|
+
const response = await questionRegistry.register(taskId, invocation.sessionId, request.question, request.choices, request.allowFreeform ?? true);
|
|
127
|
+
return response;
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
class SDKClientManager {
|
|
131
|
+
clients = new Map();
|
|
132
|
+
pendingClients = new Map(); // RC-3: Dedup concurrent getClient calls
|
|
133
|
+
isShuttingDown = false;
|
|
134
|
+
staleSessionTimer = null;
|
|
135
|
+
sweepCycle = 0;
|
|
136
|
+
/**
|
|
137
|
+
* Initialize the client manager (call on MCP connect).
|
|
138
|
+
* Initializes the account manager and resets to first token.
|
|
139
|
+
*/
|
|
140
|
+
initialize() {
|
|
141
|
+
accountManager.initialize();
|
|
142
|
+
this.startStaleSessionSweeper();
|
|
143
|
+
console.error(`[sdk-client-manager] Initialized with ${accountManager.getTokenCount()} account(s)`);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Reset the client manager (call on MCP reconnect).
|
|
147
|
+
* Clears all clients and resets account rotation to first token.
|
|
148
|
+
*/
|
|
149
|
+
async reset() {
|
|
150
|
+
this.pendingClients.clear();
|
|
151
|
+
// Clear our tracking first — let SDK stop() handle session cleanup
|
|
152
|
+
for (const entry of this.clients.values()) {
|
|
153
|
+
entry.sessions.clear();
|
|
154
|
+
}
|
|
155
|
+
for (const [key, entry] of this.clients) {
|
|
156
|
+
try {
|
|
157
|
+
await withTimeout(entry.client.stop(), SHUTDOWN_STOP_TIMEOUT_MS, `stop client ${key}`);
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
try {
|
|
161
|
+
await entry.client.forceStop();
|
|
162
|
+
}
|
|
163
|
+
catch { /* ignore */ }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
this.clients.clear();
|
|
167
|
+
accountManager.reset();
|
|
168
|
+
console.error('[sdk-client-manager] Reset complete - all clients cleared, starting from first account');
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get or create a CopilotClient for the given workspace.
|
|
172
|
+
* Uses the current token from account manager.
|
|
173
|
+
*/
|
|
174
|
+
async getClient(cwd) {
|
|
175
|
+
if (this.isShuttingDown) {
|
|
176
|
+
throw new Error('SDK client manager is shutting down');
|
|
177
|
+
}
|
|
178
|
+
const currentToken = accountManager.getCurrentToken();
|
|
179
|
+
const tokenIndex = accountManager.getCurrentIndex();
|
|
180
|
+
const clientKey = `${cwd}:${tokenIndex}`;
|
|
181
|
+
// Fast path: client already exists
|
|
182
|
+
const entry = this.clients.get(clientKey);
|
|
183
|
+
if (entry) {
|
|
184
|
+
entry.lastUsedAt = new Date();
|
|
185
|
+
return entry.client;
|
|
186
|
+
}
|
|
187
|
+
// RC-3: Check if creation is already in progress for this key
|
|
188
|
+
const pending = this.pendingClients.get(clientKey);
|
|
189
|
+
if (pending) {
|
|
190
|
+
return pending;
|
|
191
|
+
}
|
|
192
|
+
// Create with dedup — store the promise so concurrent callers reuse it
|
|
193
|
+
const promise = this.createClient(cwd, currentToken).then(client => {
|
|
194
|
+
// Guard: if reset/shutdown invalidated this creation, stop the orphaned client
|
|
195
|
+
if (this.isShuttingDown || this.pendingClients.get(clientKey) !== promise) {
|
|
196
|
+
client.stop?.().catch(() => { });
|
|
197
|
+
throw new Error('Client creation invalidated by reset/shutdown');
|
|
198
|
+
}
|
|
199
|
+
this.clients.set(clientKey, {
|
|
200
|
+
client,
|
|
201
|
+
cwd,
|
|
202
|
+
tokenIndex,
|
|
203
|
+
createdAt: new Date(),
|
|
204
|
+
lastUsedAt: new Date(),
|
|
205
|
+
sessions: new Map(),
|
|
206
|
+
});
|
|
207
|
+
this.pendingClients.delete(clientKey);
|
|
208
|
+
console.error(`[sdk-client-manager] Created client for cwd=${cwd} with token #${tokenIndex + 1}/${accountManager.getTokenCount()}`);
|
|
209
|
+
return client;
|
|
210
|
+
}).catch(err => {
|
|
211
|
+
this.pendingClients.delete(clientKey);
|
|
212
|
+
throw err;
|
|
213
|
+
});
|
|
214
|
+
this.pendingClients.set(clientKey, promise);
|
|
215
|
+
return promise;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Create a new CopilotClient with the specified configuration.
|
|
219
|
+
*/
|
|
220
|
+
async createClient(cwd, githubToken) {
|
|
221
|
+
const options = {
|
|
222
|
+
cliPath: COPILOT_PATH,
|
|
223
|
+
cwd,
|
|
224
|
+
logLevel: 'error',
|
|
225
|
+
autoStart: true,
|
|
226
|
+
autoRestart: false,
|
|
227
|
+
useStdio: false, // TCP mode: avoids macOS stdio pipe destruction race
|
|
228
|
+
};
|
|
229
|
+
if (githubToken) {
|
|
230
|
+
options.githubToken = githubToken;
|
|
231
|
+
options.useLoggedInUser = false;
|
|
232
|
+
}
|
|
233
|
+
const client = new CopilotClient(options);
|
|
234
|
+
await withTimeout(client.start(), CLIENT_START_TIMEOUT_MS, 'client.start()');
|
|
235
|
+
return client;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Create a session using the SDK client for the given workspace.
|
|
239
|
+
* Includes user input handler for SDK ask_user tool support.
|
|
240
|
+
*/
|
|
241
|
+
async createSession(cwd, sessionId, config, taskId) {
|
|
242
|
+
const client = await this.getClient(cwd);
|
|
243
|
+
const tokenIndex = accountManager.getCurrentIndex();
|
|
244
|
+
const clientKey = `${cwd}:${tokenIndex}`;
|
|
245
|
+
// Build session config with user input handler and hooks if taskId provided
|
|
246
|
+
const sessionConfig = {
|
|
247
|
+
sessionId,
|
|
248
|
+
...config,
|
|
249
|
+
};
|
|
250
|
+
// Always attach explicit permission policy to avoid SDK default-deny.
|
|
251
|
+
sessionConfig.onPermissionRequest = config.onPermissionRequest ?? createPermissionHandler(taskId);
|
|
252
|
+
// Add user input handler and session hooks when taskId is provided
|
|
253
|
+
if (taskId) {
|
|
254
|
+
sessionConfig.onUserInputRequest = createUserInputHandler(taskId);
|
|
255
|
+
// Wire SDK session hooks for lifecycle events, error handling, and tool telemetry
|
|
256
|
+
sessionConfig.hooks = createSessionHooks(taskId);
|
|
257
|
+
}
|
|
258
|
+
const session = await client.createSession(sessionConfig);
|
|
259
|
+
// Track the session in the client entry
|
|
260
|
+
const entry = this.clients.get(clientKey);
|
|
261
|
+
if (entry) {
|
|
262
|
+
entry.sessions.set(sessionId, session);
|
|
263
|
+
}
|
|
264
|
+
return session;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Resume an existing session.
|
|
268
|
+
* Includes user input handler for SDK ask_user tool support.
|
|
269
|
+
*/
|
|
270
|
+
async resumeSession(cwd, sessionId, config, taskId) {
|
|
271
|
+
const client = await this.getClient(cwd);
|
|
272
|
+
// Capture token index BEFORE the async resumeSession call to prevent
|
|
273
|
+
// tracking drift if token rotation happens during the await
|
|
274
|
+
const tokenIndex = accountManager.getCurrentIndex();
|
|
275
|
+
const clientKey = `${cwd}:${tokenIndex}`;
|
|
276
|
+
// Build resume config with user input handler and hooks if taskId provided
|
|
277
|
+
const resumeConfig = { ...config };
|
|
278
|
+
// Re-register explicit permission policy on resume as required by SDK.
|
|
279
|
+
resumeConfig.onPermissionRequest = config?.onPermissionRequest ?? createPermissionHandler(taskId);
|
|
280
|
+
if (taskId) {
|
|
281
|
+
resumeConfig.onUserInputRequest = createUserInputHandler(taskId);
|
|
282
|
+
// Wire SDK session hooks for lifecycle events, error handling, and tool telemetry
|
|
283
|
+
resumeConfig.hooks = createSessionHooks(taskId);
|
|
284
|
+
}
|
|
285
|
+
const session = await client.resumeSession(sessionId, resumeConfig);
|
|
286
|
+
// Track the resumed session in the client entry
|
|
287
|
+
const entry = this.clients.get(clientKey);
|
|
288
|
+
if (entry) {
|
|
289
|
+
entry.sessions.set(sessionId, session);
|
|
290
|
+
}
|
|
291
|
+
return session;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Get an active session by ID.
|
|
295
|
+
*/
|
|
296
|
+
getSession(sessionId) {
|
|
297
|
+
for (const entry of this.clients.values()) {
|
|
298
|
+
const session = entry.sessions.get(sessionId);
|
|
299
|
+
if (session) {
|
|
300
|
+
return session;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return undefined;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Destroy a session and remove it from tracking.
|
|
307
|
+
*/
|
|
308
|
+
async destroySession(sessionId) {
|
|
309
|
+
for (const entry of this.clients.values()) {
|
|
310
|
+
const session = entry.sessions.get(sessionId);
|
|
311
|
+
if (session) {
|
|
312
|
+
// Delete from tracking first to prevent double-destroy race with sweeper
|
|
313
|
+
entry.sessions.delete(sessionId);
|
|
314
|
+
try {
|
|
315
|
+
await destroySessionWithRetry(session, sessionId, DESTROY_SESSION_TIMEOUT_MS);
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
console.error(`[sdk-client-manager] Failed to destroy session ${sessionId}:`, err);
|
|
319
|
+
}
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Abort a running session.
|
|
327
|
+
*/
|
|
328
|
+
async abortSession(sessionId) {
|
|
329
|
+
const session = this.getSession(sessionId);
|
|
330
|
+
if (session) {
|
|
331
|
+
try {
|
|
332
|
+
await session.abort();
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
catch (err) {
|
|
336
|
+
console.error(`[sdk-client-manager] Failed to abort session ${sessionId}:`, err);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return false;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Rotate to the next account on error.
|
|
343
|
+
* Returns the new client if rotation was successful.
|
|
344
|
+
*
|
|
345
|
+
* @param cwd - Workspace directory
|
|
346
|
+
* @param reason - Reason for rotation (e.g., 'rate_limit_429', 'server_error_500')
|
|
347
|
+
*/
|
|
348
|
+
async rotateOnError(cwd, reason) {
|
|
349
|
+
const result = accountManager.rotateToNext(reason);
|
|
350
|
+
if (!result.success) {
|
|
351
|
+
if (result.allExhausted) {
|
|
352
|
+
return {
|
|
353
|
+
success: false,
|
|
354
|
+
allExhausted: true,
|
|
355
|
+
error: `All ${accountManager.getTokenCount()} accounts exhausted: ${result.error}`
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
return { success: false, error: result.error };
|
|
359
|
+
}
|
|
360
|
+
// Get client with new token
|
|
361
|
+
try {
|
|
362
|
+
const client = await this.getClient(cwd);
|
|
363
|
+
console.error(`[sdk-client-manager] Rotated to token #${result.tokenIndex + 1} due to: ${reason}`);
|
|
364
|
+
// RC-7: Clean up stale clients from previous tokens
|
|
365
|
+
this.cleanupStaleClients();
|
|
366
|
+
return { success: true, client };
|
|
367
|
+
}
|
|
368
|
+
catch (err) {
|
|
369
|
+
return {
|
|
370
|
+
success: false,
|
|
371
|
+
error: `Failed to create client with new token: ${err}`
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* RC-7: Remove client entries with no active sessions that belong to non-current tokens.
|
|
377
|
+
* Prevents gradual resource leak from accumulated stale clients after rotation.
|
|
378
|
+
*/
|
|
379
|
+
cleanupStaleClients() {
|
|
380
|
+
const currentIndex = accountManager.getCurrentIndex();
|
|
381
|
+
for (const [key, entry] of this.clients.entries()) {
|
|
382
|
+
if (entry.tokenIndex !== currentIndex && entry.sessions.size === 0) {
|
|
383
|
+
entry.client.stop?.().catch(() => { });
|
|
384
|
+
this.clients.delete(key);
|
|
385
|
+
console.error(`[sdk-client-manager] Cleaned up stale client: ${key}`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Start the periodic stale-session sweeper. Timer is unref()'d so it
|
|
391
|
+
* doesn't prevent the process from exiting.
|
|
392
|
+
*/
|
|
393
|
+
startStaleSessionSweeper() {
|
|
394
|
+
if (this.staleSessionTimer)
|
|
395
|
+
return;
|
|
396
|
+
this.staleSessionTimer = setInterval(() => {
|
|
397
|
+
this.sweepStaleSessions().catch((err) => {
|
|
398
|
+
console.error('[sdk-client-manager] Sweeper error:', err);
|
|
399
|
+
});
|
|
400
|
+
}, STALE_SESSION_CLEANUP_INTERVAL_MS);
|
|
401
|
+
this.staleSessionTimer.unref();
|
|
402
|
+
console.error('[sdk-client-manager] Stale-session sweeper started');
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Ping each client to detect dead/crashed CLI processes. Removes dead
|
|
406
|
+
* clients from the pool and force-stops them.
|
|
407
|
+
*/
|
|
408
|
+
async checkClientHealth() {
|
|
409
|
+
for (const [key, entry] of this.clients.entries()) {
|
|
410
|
+
try {
|
|
411
|
+
await withTimeout(entry.client.ping('health'), CLIENT_HEALTH_CHECK_TIMEOUT_MS, `ping client ${key}`);
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
console.error(`[sdk-client-manager] Health check failed for client ${key}, removing dead client`);
|
|
415
|
+
entry.sessions.clear();
|
|
416
|
+
this.clients.delete(key);
|
|
417
|
+
try {
|
|
418
|
+
await entry.client.forceStop();
|
|
419
|
+
}
|
|
420
|
+
catch { /* already dead */ }
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Sweep all tracked sessions. If the corresponding task (looked up by
|
|
426
|
+
* sessionId which equals taskId by convention) is terminal or missing,
|
|
427
|
+
* destroy the session with a timeout. Then recycle PTY leakers.
|
|
428
|
+
*/
|
|
429
|
+
async sweepStaleSessions() {
|
|
430
|
+
// Remove dead clients first so we don't try to destroy sessions on them
|
|
431
|
+
await this.checkClientHealth();
|
|
432
|
+
let destroyed = 0;
|
|
433
|
+
for (const entry of this.clients.values()) {
|
|
434
|
+
for (const [sessionId, session] of entry.sessions) {
|
|
435
|
+
const task = taskManager.getTask(sessionId);
|
|
436
|
+
if (!task || TERMINAL_STATUSES.has(task.status)) {
|
|
437
|
+
entry.sessions.delete(sessionId);
|
|
438
|
+
try {
|
|
439
|
+
await withTimeout(entry.client.deleteSession(sessionId), DESTROY_SESSION_TIMEOUT_MS, `delete session ${sessionId}`);
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
// Fall back to local destroy if deleteSession fails
|
|
443
|
+
try {
|
|
444
|
+
await destroySessionWithRetry(session, sessionId, DESTROY_SESSION_TIMEOUT_MS);
|
|
445
|
+
}
|
|
446
|
+
catch (err) {
|
|
447
|
+
console.error(`[sdk-client-manager] Sweeper: destroy failed for ${sessionId}: ${err}`);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
destroyed++;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
if (destroyed > 0) {
|
|
455
|
+
console.error(`[sdk-client-manager] Sweeper: destroyed ${destroyed} stale session(s)`);
|
|
456
|
+
}
|
|
457
|
+
// Every 5th sweep cycle, detect and clean up orphaned server-side sessions
|
|
458
|
+
this.sweepCycle++;
|
|
459
|
+
if (this.sweepCycle % 5 === 0) {
|
|
460
|
+
await this.detectOrphanedSessions();
|
|
461
|
+
}
|
|
462
|
+
await this.recyclePtyLeakers();
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Detect server-side sessions that we're not tracking locally (orphaned from
|
|
466
|
+
* crashes). Uses listSessions() and deletes any not in our tracking map.
|
|
467
|
+
*/
|
|
468
|
+
async detectOrphanedSessions() {
|
|
469
|
+
for (const [key, entry] of this.clients.entries()) {
|
|
470
|
+
try {
|
|
471
|
+
const serverSessions = await withTimeout(entry.client.listSessions(), CLIENT_HEALTH_CHECK_TIMEOUT_MS, `listSessions ${key}`);
|
|
472
|
+
const trackedIds = new Set(entry.sessions.keys());
|
|
473
|
+
for (const meta of serverSessions) {
|
|
474
|
+
if (!trackedIds.has(meta.sessionId)) {
|
|
475
|
+
console.error(`[sdk-client-manager] Sweeper: deleting orphaned session ${meta.sessionId}`);
|
|
476
|
+
try {
|
|
477
|
+
await entry.client.deleteSession(meta.sessionId);
|
|
478
|
+
}
|
|
479
|
+
catch { /* best effort */ }
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
catch { /* listSessions failure is non-fatal */ }
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* For each client entry, check PTY FD count via lsof. If count exceeds
|
|
488
|
+
* threshold and no active sessions remain, recycle the client (stop it
|
|
489
|
+
* and remove from map so the next getClient() creates a fresh one).
|
|
490
|
+
*/
|
|
491
|
+
async recyclePtyLeakers() {
|
|
492
|
+
for (const [key, entry] of this.clients.entries()) {
|
|
493
|
+
// Skip dead clients — health check will handle cleanup
|
|
494
|
+
try {
|
|
495
|
+
await withTimeout(entry.client.ping('recycle-check'), 3_000, `ping ${key}`);
|
|
496
|
+
}
|
|
497
|
+
catch {
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
// SDK has no public API for process PID or FD count.
|
|
501
|
+
// cliProcess is private (client.ts:121). This cast is the only way
|
|
502
|
+
// to count ptmx FDs until the SDK adds a resource health endpoint.
|
|
503
|
+
const pid = entry.client.cliProcess?.pid;
|
|
504
|
+
if (!pid)
|
|
505
|
+
continue;
|
|
506
|
+
let ptmxCount = 0;
|
|
507
|
+
try {
|
|
508
|
+
const output = execSync(`lsof -p ${pid} 2>/dev/null | grep -c ptmx`, {
|
|
509
|
+
encoding: 'utf8',
|
|
510
|
+
timeout: 5_000,
|
|
511
|
+
});
|
|
512
|
+
ptmxCount = parseInt(output.trim(), 10) || 0;
|
|
513
|
+
}
|
|
514
|
+
catch {
|
|
515
|
+
// grep returns exit code 1 when no matches → ptmxCount stays 0
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
if (ptmxCount > PTY_RECYCLE_THRESHOLD && entry.sessions.size === 0) {
|
|
519
|
+
console.error(`[sdk-client-manager] Sweeper: recycling client ${key} (${ptmxCount} ptmx FDs, 0 active sessions)`);
|
|
520
|
+
// Escalating shutdown: graceful → force
|
|
521
|
+
try {
|
|
522
|
+
await withTimeout(entry.client.stop(), RECYCLE_STOP_TIMEOUT_MS, `stop client ${key}`);
|
|
523
|
+
}
|
|
524
|
+
catch (stopErr) {
|
|
525
|
+
console.error(`[sdk-client-manager] Sweeper: graceful stop failed for ${key}, forcing: ${stopErr}`);
|
|
526
|
+
try {
|
|
527
|
+
await entry.client.forceStop();
|
|
528
|
+
}
|
|
529
|
+
catch { /* ignore */ }
|
|
530
|
+
}
|
|
531
|
+
this.clients.delete(key);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Check if rotation should happen based on error.
|
|
537
|
+
*/
|
|
538
|
+
shouldRotateOnError(statusCode, errorMessage) {
|
|
539
|
+
return accountManager.shouldRotate(statusCode, errorMessage);
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Check authentication status for current token.
|
|
543
|
+
*/
|
|
544
|
+
async checkAuthStatus(cwd) {
|
|
545
|
+
try {
|
|
546
|
+
const client = await this.getClient(cwd);
|
|
547
|
+
const status = await client.getAuthStatus();
|
|
548
|
+
return {
|
|
549
|
+
isAuthenticated: status.isAuthenticated,
|
|
550
|
+
login: status.login,
|
|
551
|
+
tokenIndex: accountManager.getCurrentIndex(),
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
catch (err) {
|
|
555
|
+
console.error('[sdk-client-manager] Auth status check failed:', err);
|
|
556
|
+
return { isAuthenticated: false, tokenIndex: accountManager.getCurrentIndex() };
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* List available models.
|
|
561
|
+
*/
|
|
562
|
+
async listModels(cwd) {
|
|
563
|
+
try {
|
|
564
|
+
const client = await this.getClient(cwd);
|
|
565
|
+
const models = await client.listModels();
|
|
566
|
+
return models.map((m) => ({ id: m.id, name: m.name }));
|
|
567
|
+
}
|
|
568
|
+
catch (err) {
|
|
569
|
+
console.error('[sdk-client-manager] Failed to list models:', err);
|
|
570
|
+
return [];
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Shutdown all clients gracefully.
|
|
575
|
+
*/
|
|
576
|
+
async shutdown() {
|
|
577
|
+
this.isShuttingDown = true;
|
|
578
|
+
this.pendingClients.clear();
|
|
579
|
+
if (this.staleSessionTimer) {
|
|
580
|
+
clearInterval(this.staleSessionTimer);
|
|
581
|
+
this.staleSessionTimer = null;
|
|
582
|
+
}
|
|
583
|
+
const errors = [];
|
|
584
|
+
// Clear our tracking first (prevents sweeper interference)
|
|
585
|
+
for (const entry of this.clients.values()) {
|
|
586
|
+
entry.sessions.clear();
|
|
587
|
+
}
|
|
588
|
+
// Let SDK stop() handle cleanup with its own retry+backoff, with forceStop fallback
|
|
589
|
+
for (const [key, entry] of this.clients) {
|
|
590
|
+
try {
|
|
591
|
+
const clientErrors = await withTimeout(entry.client.stop(), SHUTDOWN_STOP_TIMEOUT_MS, `stop client ${key}`);
|
|
592
|
+
errors.push(...clientErrors);
|
|
593
|
+
}
|
|
594
|
+
catch (err) {
|
|
595
|
+
console.error(`[sdk-client-manager] Shutdown: stop timed out for ${key}, forcing`);
|
|
596
|
+
try {
|
|
597
|
+
await entry.client.forceStop();
|
|
598
|
+
}
|
|
599
|
+
catch (e) {
|
|
600
|
+
errors.push(new Error(`Failed to force-stop client ${key}: ${e}`));
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
this.clients.clear();
|
|
605
|
+
if (errors.length > 0) {
|
|
606
|
+
console.error('[sdk-client-manager] Shutdown errors:', errors);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Get statistics about active clients, sessions, and account rotation.
|
|
611
|
+
*/
|
|
612
|
+
getStats() {
|
|
613
|
+
let sessions = 0;
|
|
614
|
+
for (const entry of this.clients.values()) {
|
|
615
|
+
sessions += entry.sessions.size;
|
|
616
|
+
}
|
|
617
|
+
const accountStats = accountManager.getStats();
|
|
618
|
+
return {
|
|
619
|
+
pools: 1,
|
|
620
|
+
clients: this.clients.size,
|
|
621
|
+
sessions,
|
|
622
|
+
accounts: {
|
|
623
|
+
total: accountStats.totalTokens,
|
|
624
|
+
current: accountStats.currentIndex + 1,
|
|
625
|
+
rotations: accountStats.rotationCount,
|
|
626
|
+
available: accountStats.availableTokens,
|
|
627
|
+
},
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
export const sdkClientManager = new SDKClientManager();
|
|
632
|
+
//# sourceMappingURL=sdk-client-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-client-manager.js","sourceRoot":"","sources":["../../src/services/sdk-client-manager.ts"],"names":[],"mappings":"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"}
|