@yeaft/webchat-agent 0.1.982 → 0.1.983

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yeaft/webchat-agent",
3
- "version": "0.1.982",
3
+ "version": "0.1.983",
4
4
  "description": "Remote agent for Yeaft WebChat — connects worker machines to the central server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -1,7 +1,7 @@
1
1
  import { spawn } from 'child_process';
2
2
  import { randomUUID } from 'crypto';
3
3
  import { existsSync } from 'fs';
4
- import { homedir } from 'os';
4
+ import { homedir, platform as osPlatform } from 'os';
5
5
  import { join } from 'path';
6
6
  import { DatabaseSync } from 'node:sqlite';
7
7
  import ctx from '../context.js';
@@ -26,6 +26,19 @@ const COPILOT_BIN = process.env.COPILOT_BIN || 'copilot';
26
26
  const YOLO = process.env.COPILOT_YOLO === '1';
27
27
  const ACP_PROTOCOL_VERSION = 1;
28
28
 
29
+ export function resolveCopilotLaunchOptions({ cwd, env = process.env, platform = osPlatform(), bin = COPILOT_BIN } = {}) {
30
+ const isWindows = platform === 'win32';
31
+ return {
32
+ command: bin || 'copilot',
33
+ options: {
34
+ cwd,
35
+ env,
36
+ stdio: ['pipe', 'pipe', 'pipe'],
37
+ ...(isWindows ? { shell: true, windowsHide: true } : {}),
38
+ },
39
+ };
40
+ }
41
+
29
42
  /**
30
43
  * Start (or resume) a Copilot ACP session.
31
44
  *
@@ -92,22 +105,24 @@ async function _bootAcp(state, resumeSessionId) {
92
105
  for (const d of state.providerOptions.addDirs) args.push('--add-dir', String(d));
93
106
  }
94
107
 
95
- const child = spawn(COPILOT_BIN, args, {
96
- cwd: state.workDir,
97
- env: process.env,
98
- stdio: ['pipe', 'pipe', 'pipe'],
99
- });
108
+ const launch = resolveCopilotLaunchOptions({ cwd: state.workDir });
109
+ const child = spawn(launch.command, args, launch.options);
100
110
  state.copilotChild = child;
101
111
 
102
112
  let stderrBuf = '';
103
113
  const STDERR_CAP = 64 * 1024;
114
+ let client = null;
115
+ let childError = null;
104
116
  child.stderr.on('data', (chunk) => {
105
117
  if (stderrBuf.length < STDERR_CAP) {
106
118
  stderrBuf += chunk.toString('utf8').slice(0, STDERR_CAP - stderrBuf.length);
107
119
  }
108
120
  });
109
121
  child.on('error', (err) => {
110
- _sendTurnError(state, `copilot process error: ${err?.message || err}`);
122
+ const message = `copilot process error: ${err?.message || err}`;
123
+ childError = new Error(message);
124
+ if (state.turnActive) _sendTurnError(state, message);
125
+ if (client) client.close(message);
111
126
  });
112
127
  child.on('close', (code) => {
113
128
  if (state.turnActive) {
@@ -126,7 +141,7 @@ async function _bootAcp(state, resumeSessionId) {
126
141
  state.initialized = false;
127
142
  });
128
143
 
129
- const client = new AcpClient({
144
+ client = new AcpClient({
130
145
  stdin: child.stdin,
131
146
  stdout: child.stdout,
132
147
  onNotification: (method, params) => _handleAcpNotification(state, method, params),
@@ -136,6 +151,10 @@ async function _bootAcp(state, resumeSessionId) {
136
151
  },
137
152
  });
138
153
  state.acpClient = client;
154
+ if (childError) {
155
+ client.close(childError.message);
156
+ throw childError;
157
+ }
139
158
 
140
159
  // 1) initialize
141
160
  const initResp = await client.request('initialize', {