aisnitch 0.2.20 → 0.2.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/cli/index.cjs +1835 -119
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +1812 -91
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +7219 -6428
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +165 -4
- package/dist/index.d.ts +165 -4
- package/dist/index.js +7243 -6459
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/cli/index.cjs
CHANGED
|
@@ -6,6 +6,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __esm = (fn, res) => function __init() {
|
|
10
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
11
|
+
};
|
|
9
12
|
var __export = (target, all) => {
|
|
10
13
|
for (var name in all)
|
|
11
14
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -28,6 +31,733 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
31
|
));
|
|
29
32
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
33
|
|
|
34
|
+
// node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
|
|
35
|
+
function hasDockerEnv() {
|
|
36
|
+
try {
|
|
37
|
+
import_node_fs4.default.statSync("/.dockerenv");
|
|
38
|
+
return true;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function hasDockerCGroup() {
|
|
44
|
+
try {
|
|
45
|
+
return import_node_fs4.default.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function isDocker() {
|
|
51
|
+
if (isDockerCached === void 0) {
|
|
52
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
53
|
+
}
|
|
54
|
+
return isDockerCached;
|
|
55
|
+
}
|
|
56
|
+
var import_node_fs4, isDockerCached;
|
|
57
|
+
var init_is_docker = __esm({
|
|
58
|
+
"node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js"() {
|
|
59
|
+
"use strict";
|
|
60
|
+
import_node_fs4 = __toESM(require("fs"), 1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
65
|
+
function isInsideContainer() {
|
|
66
|
+
if (cachedResult === void 0) {
|
|
67
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
68
|
+
}
|
|
69
|
+
return cachedResult;
|
|
70
|
+
}
|
|
71
|
+
var import_node_fs5, cachedResult, hasContainerEnv;
|
|
72
|
+
var init_is_inside_container = __esm({
|
|
73
|
+
"node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js"() {
|
|
74
|
+
"use strict";
|
|
75
|
+
import_node_fs5 = __toESM(require("fs"), 1);
|
|
76
|
+
init_is_docker();
|
|
77
|
+
hasContainerEnv = () => {
|
|
78
|
+
try {
|
|
79
|
+
import_node_fs5.default.statSync("/run/.containerenv");
|
|
80
|
+
return true;
|
|
81
|
+
} catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
|
|
89
|
+
var import_node_process, import_node_os5, import_node_fs6, isWsl, is_wsl_default;
|
|
90
|
+
var init_is_wsl = __esm({
|
|
91
|
+
"node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js"() {
|
|
92
|
+
"use strict";
|
|
93
|
+
import_node_process = __toESM(require("process"), 1);
|
|
94
|
+
import_node_os5 = __toESM(require("os"), 1);
|
|
95
|
+
import_node_fs6 = __toESM(require("fs"), 1);
|
|
96
|
+
init_is_inside_container();
|
|
97
|
+
isWsl = () => {
|
|
98
|
+
if (import_node_process.default.platform !== "linux") {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (import_node_os5.default.release().toLowerCase().includes("microsoft")) {
|
|
102
|
+
if (isInsideContainer()) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
if (import_node_fs6.default.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
|
|
109
|
+
return !isInsideContainer();
|
|
110
|
+
}
|
|
111
|
+
} catch {
|
|
112
|
+
}
|
|
113
|
+
if (import_node_fs6.default.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || import_node_fs6.default.existsSync("/run/WSL")) {
|
|
114
|
+
return !isInsideContainer();
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
};
|
|
118
|
+
is_wsl_default = import_node_process.default.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// node_modules/.pnpm/powershell-utils@0.1.0/node_modules/powershell-utils/index.js
|
|
123
|
+
var import_node_process2, import_node_buffer, import_node_util15, import_node_child_process16, import_promises19, execFile15, powerShellPath, executePowerShell;
|
|
124
|
+
var init_powershell_utils = __esm({
|
|
125
|
+
"node_modules/.pnpm/powershell-utils@0.1.0/node_modules/powershell-utils/index.js"() {
|
|
126
|
+
"use strict";
|
|
127
|
+
import_node_process2 = __toESM(require("process"), 1);
|
|
128
|
+
import_node_buffer = require("buffer");
|
|
129
|
+
import_node_util15 = require("util");
|
|
130
|
+
import_node_child_process16 = __toESM(require("child_process"), 1);
|
|
131
|
+
import_promises19 = __toESM(require("fs/promises"), 1);
|
|
132
|
+
execFile15 = (0, import_node_util15.promisify)(import_node_child_process16.default.execFile);
|
|
133
|
+
powerShellPath = () => `${import_node_process2.default.env.SYSTEMROOT || import_node_process2.default.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
134
|
+
executePowerShell = async (command, options = {}) => {
|
|
135
|
+
const {
|
|
136
|
+
powerShellPath: psPath,
|
|
137
|
+
...execFileOptions
|
|
138
|
+
} = options;
|
|
139
|
+
const encodedCommand = executePowerShell.encodeCommand(command);
|
|
140
|
+
return execFile15(
|
|
141
|
+
psPath ?? powerShellPath(),
|
|
142
|
+
[
|
|
143
|
+
...executePowerShell.argumentsPrefix,
|
|
144
|
+
encodedCommand
|
|
145
|
+
],
|
|
146
|
+
{
|
|
147
|
+
encoding: "utf8",
|
|
148
|
+
...execFileOptions
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
};
|
|
152
|
+
executePowerShell.argumentsPrefix = [
|
|
153
|
+
"-NoProfile",
|
|
154
|
+
"-NonInteractive",
|
|
155
|
+
"-ExecutionPolicy",
|
|
156
|
+
"Bypass",
|
|
157
|
+
"-EncodedCommand"
|
|
158
|
+
];
|
|
159
|
+
executePowerShell.encodeCommand = (command) => import_node_buffer.Buffer.from(command, "utf16le").toString("base64");
|
|
160
|
+
executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// node_modules/.pnpm/wsl-utils@0.3.1/node_modules/wsl-utils/utilities.js
|
|
165
|
+
function parseMountPointFromConfig(content) {
|
|
166
|
+
for (const line of content.split("\n")) {
|
|
167
|
+
if (/^\s*#/.test(line)) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
|
|
171
|
+
if (!match) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
var init_utilities = __esm({
|
|
178
|
+
"node_modules/.pnpm/wsl-utils@0.3.1/node_modules/wsl-utils/utilities.js"() {
|
|
179
|
+
"use strict";
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// node_modules/.pnpm/wsl-utils@0.3.1/node_modules/wsl-utils/index.js
|
|
184
|
+
var import_node_util16, import_node_child_process17, import_promises20, execFile16, wslDrivesMountPoint, powerShellPathFromWsl, powerShellPath2, canAccessPowerShellPromise, canAccessPowerShell, wslDefaultBrowser, convertWslPathToWindows;
|
|
185
|
+
var init_wsl_utils = __esm({
|
|
186
|
+
"node_modules/.pnpm/wsl-utils@0.3.1/node_modules/wsl-utils/index.js"() {
|
|
187
|
+
"use strict";
|
|
188
|
+
import_node_util16 = require("util");
|
|
189
|
+
import_node_child_process17 = __toESM(require("child_process"), 1);
|
|
190
|
+
import_promises20 = __toESM(require("fs/promises"), 1);
|
|
191
|
+
init_is_wsl();
|
|
192
|
+
init_powershell_utils();
|
|
193
|
+
init_utilities();
|
|
194
|
+
init_is_wsl();
|
|
195
|
+
execFile16 = (0, import_node_util16.promisify)(import_node_child_process17.default.execFile);
|
|
196
|
+
wslDrivesMountPoint = /* @__PURE__ */ (() => {
|
|
197
|
+
const defaultMountPoint = "/mnt/";
|
|
198
|
+
let mountPoint;
|
|
199
|
+
return async function() {
|
|
200
|
+
if (mountPoint) {
|
|
201
|
+
return mountPoint;
|
|
202
|
+
}
|
|
203
|
+
const configFilePath = "/etc/wsl.conf";
|
|
204
|
+
let isConfigFileExists = false;
|
|
205
|
+
try {
|
|
206
|
+
await import_promises20.default.access(configFilePath, import_promises20.constants.F_OK);
|
|
207
|
+
isConfigFileExists = true;
|
|
208
|
+
} catch {
|
|
209
|
+
}
|
|
210
|
+
if (!isConfigFileExists) {
|
|
211
|
+
return defaultMountPoint;
|
|
212
|
+
}
|
|
213
|
+
const configContent = await import_promises20.default.readFile(configFilePath, { encoding: "utf8" });
|
|
214
|
+
const parsedMountPoint = parseMountPointFromConfig(configContent);
|
|
215
|
+
if (parsedMountPoint === void 0) {
|
|
216
|
+
return defaultMountPoint;
|
|
217
|
+
}
|
|
218
|
+
mountPoint = parsedMountPoint;
|
|
219
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
220
|
+
return mountPoint;
|
|
221
|
+
};
|
|
222
|
+
})();
|
|
223
|
+
powerShellPathFromWsl = async () => {
|
|
224
|
+
const mountPoint = await wslDrivesMountPoint();
|
|
225
|
+
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
226
|
+
};
|
|
227
|
+
powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
|
|
228
|
+
canAccessPowerShell = async () => {
|
|
229
|
+
canAccessPowerShellPromise ??= (async () => {
|
|
230
|
+
try {
|
|
231
|
+
const psPath = await powerShellPath2();
|
|
232
|
+
await import_promises20.default.access(psPath, import_promises20.constants.X_OK);
|
|
233
|
+
return true;
|
|
234
|
+
} catch {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
})();
|
|
238
|
+
return canAccessPowerShellPromise;
|
|
239
|
+
};
|
|
240
|
+
wslDefaultBrowser = async () => {
|
|
241
|
+
const psPath = await powerShellPath2();
|
|
242
|
+
const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
243
|
+
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
244
|
+
return stdout.trim();
|
|
245
|
+
};
|
|
246
|
+
convertWslPathToWindows = async (path2) => {
|
|
247
|
+
if (/^[a-z]+:\/\//i.test(path2)) {
|
|
248
|
+
return path2;
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
const { stdout } = await execFile16("wslpath", ["-aw", path2], { encoding: "utf8" });
|
|
252
|
+
return stdout.trim();
|
|
253
|
+
} catch {
|
|
254
|
+
return path2;
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
|
|
261
|
+
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
262
|
+
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
263
|
+
Object.defineProperty(object, propertyName, {
|
|
264
|
+
configurable: true,
|
|
265
|
+
enumerable: true,
|
|
266
|
+
get() {
|
|
267
|
+
const result = valueGetter();
|
|
268
|
+
define(result);
|
|
269
|
+
return result;
|
|
270
|
+
},
|
|
271
|
+
set(value) {
|
|
272
|
+
define(value);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
return object;
|
|
276
|
+
}
|
|
277
|
+
var init_define_lazy_prop = __esm({
|
|
278
|
+
"node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js"() {
|
|
279
|
+
"use strict";
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
// node_modules/.pnpm/default-browser-id@5.0.1/node_modules/default-browser-id/index.js
|
|
284
|
+
async function defaultBrowserId() {
|
|
285
|
+
if (import_node_process3.default.platform !== "darwin") {
|
|
286
|
+
throw new Error("macOS only");
|
|
287
|
+
}
|
|
288
|
+
const { stdout } = await execFileAsync2("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
289
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
290
|
+
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
291
|
+
if (browserId === "com.apple.safari") {
|
|
292
|
+
return "com.apple.Safari";
|
|
293
|
+
}
|
|
294
|
+
return browserId;
|
|
295
|
+
}
|
|
296
|
+
var import_node_util17, import_node_process3, import_node_child_process18, execFileAsync2;
|
|
297
|
+
var init_default_browser_id = __esm({
|
|
298
|
+
"node_modules/.pnpm/default-browser-id@5.0.1/node_modules/default-browser-id/index.js"() {
|
|
299
|
+
"use strict";
|
|
300
|
+
import_node_util17 = require("util");
|
|
301
|
+
import_node_process3 = __toESM(require("process"), 1);
|
|
302
|
+
import_node_child_process18 = require("child_process");
|
|
303
|
+
execFileAsync2 = (0, import_node_util17.promisify)(import_node_child_process18.execFile);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js
|
|
308
|
+
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
309
|
+
if (import_node_process4.default.platform !== "darwin") {
|
|
310
|
+
throw new Error("macOS only");
|
|
311
|
+
}
|
|
312
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
313
|
+
const execOptions = {};
|
|
314
|
+
if (signal) {
|
|
315
|
+
execOptions.signal = signal;
|
|
316
|
+
}
|
|
317
|
+
const { stdout } = await execFileAsync3("osascript", ["-e", script, outputArguments], execOptions);
|
|
318
|
+
return stdout.trim();
|
|
319
|
+
}
|
|
320
|
+
var import_node_process4, import_node_util18, import_node_child_process19, execFileAsync3;
|
|
321
|
+
var init_run_applescript = __esm({
|
|
322
|
+
"node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js"() {
|
|
323
|
+
"use strict";
|
|
324
|
+
import_node_process4 = __toESM(require("process"), 1);
|
|
325
|
+
import_node_util18 = require("util");
|
|
326
|
+
import_node_child_process19 = require("child_process");
|
|
327
|
+
execFileAsync3 = (0, import_node_util18.promisify)(import_node_child_process19.execFile);
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
// node_modules/.pnpm/bundle-name@4.1.0/node_modules/bundle-name/index.js
|
|
332
|
+
async function bundleName(bundleId) {
|
|
333
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
334
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
335
|
+
}
|
|
336
|
+
var init_bundle_name = __esm({
|
|
337
|
+
"node_modules/.pnpm/bundle-name@4.1.0/node_modules/bundle-name/index.js"() {
|
|
338
|
+
"use strict";
|
|
339
|
+
init_run_applescript();
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/windows.js
|
|
344
|
+
async function defaultBrowser(_execFileAsync = execFileAsync4) {
|
|
345
|
+
const { stdout } = await _execFileAsync("reg", [
|
|
346
|
+
"QUERY",
|
|
347
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
348
|
+
"/v",
|
|
349
|
+
"ProgId"
|
|
350
|
+
]);
|
|
351
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
352
|
+
if (!match) {
|
|
353
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
354
|
+
}
|
|
355
|
+
const { id } = match.groups;
|
|
356
|
+
const dotIndex = id.lastIndexOf(".");
|
|
357
|
+
const hyphenIndex = id.lastIndexOf("-");
|
|
358
|
+
const baseIdByDot = dotIndex === -1 ? void 0 : id.slice(0, dotIndex);
|
|
359
|
+
const baseIdByHyphen = hyphenIndex === -1 ? void 0 : id.slice(0, hyphenIndex);
|
|
360
|
+
return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
|
|
361
|
+
}
|
|
362
|
+
var import_node_util19, import_node_child_process20, execFileAsync4, windowsBrowserProgIds, _windowsBrowserProgIdMap, UnknownBrowserError;
|
|
363
|
+
var init_windows = __esm({
|
|
364
|
+
"node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/windows.js"() {
|
|
365
|
+
"use strict";
|
|
366
|
+
import_node_util19 = require("util");
|
|
367
|
+
import_node_child_process20 = require("child_process");
|
|
368
|
+
execFileAsync4 = (0, import_node_util19.promisify)(import_node_child_process20.execFile);
|
|
369
|
+
windowsBrowserProgIds = {
|
|
370
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
371
|
+
// The missing `L` is correct.
|
|
372
|
+
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
373
|
+
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
374
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
375
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
376
|
+
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
377
|
+
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
378
|
+
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
379
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
380
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
381
|
+
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
382
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
383
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
384
|
+
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
385
|
+
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
386
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
387
|
+
};
|
|
388
|
+
_windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
389
|
+
UnknownBrowserError = class extends Error {
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/index.js
|
|
395
|
+
async function defaultBrowser2() {
|
|
396
|
+
if (import_node_process5.default.platform === "darwin") {
|
|
397
|
+
const id = await defaultBrowserId();
|
|
398
|
+
const name = await bundleName(id);
|
|
399
|
+
return { name, id };
|
|
400
|
+
}
|
|
401
|
+
if (import_node_process5.default.platform === "linux") {
|
|
402
|
+
const { stdout } = await execFileAsync5("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
403
|
+
const id = stdout.trim();
|
|
404
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
405
|
+
return { name, id };
|
|
406
|
+
}
|
|
407
|
+
if (import_node_process5.default.platform === "win32") {
|
|
408
|
+
return defaultBrowser();
|
|
409
|
+
}
|
|
410
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
411
|
+
}
|
|
412
|
+
var import_node_util20, import_node_process5, import_node_child_process21, execFileAsync5, titleize;
|
|
413
|
+
var init_default_browser = __esm({
|
|
414
|
+
"node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/index.js"() {
|
|
415
|
+
"use strict";
|
|
416
|
+
import_node_util20 = require("util");
|
|
417
|
+
import_node_process5 = __toESM(require("process"), 1);
|
|
418
|
+
import_node_child_process21 = require("child_process");
|
|
419
|
+
init_default_browser_id();
|
|
420
|
+
init_bundle_name();
|
|
421
|
+
init_windows();
|
|
422
|
+
init_windows();
|
|
423
|
+
execFileAsync5 = (0, import_node_util20.promisify)(import_node_child_process21.execFile);
|
|
424
|
+
titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
// node_modules/.pnpm/is-in-ssh@1.0.0/node_modules/is-in-ssh/index.js
|
|
429
|
+
var import_node_process6, isInSsh, is_in_ssh_default;
|
|
430
|
+
var init_is_in_ssh = __esm({
|
|
431
|
+
"node_modules/.pnpm/is-in-ssh@1.0.0/node_modules/is-in-ssh/index.js"() {
|
|
432
|
+
"use strict";
|
|
433
|
+
import_node_process6 = __toESM(require("process"), 1);
|
|
434
|
+
isInSsh = Boolean(import_node_process6.default.env.SSH_CONNECTION || import_node_process6.default.env.SSH_CLIENT || import_node_process6.default.env.SSH_TTY);
|
|
435
|
+
is_in_ssh_default = isInSsh;
|
|
436
|
+
}
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// node_modules/.pnpm/open@11.0.0/node_modules/open/index.js
|
|
440
|
+
var open_exports = {};
|
|
441
|
+
__export(open_exports, {
|
|
442
|
+
apps: () => apps,
|
|
443
|
+
default: () => open_default,
|
|
444
|
+
openApp: () => openApp
|
|
445
|
+
});
|
|
446
|
+
function detectArchBinary(binary) {
|
|
447
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
448
|
+
return binary;
|
|
449
|
+
}
|
|
450
|
+
const { [arch]: archBinary } = binary;
|
|
451
|
+
if (!archBinary) {
|
|
452
|
+
throw new Error(`${arch} is not supported`);
|
|
453
|
+
}
|
|
454
|
+
return archBinary;
|
|
455
|
+
}
|
|
456
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl } = {}) {
|
|
457
|
+
if (wsl && is_wsl_default) {
|
|
458
|
+
return detectArchBinary(wsl);
|
|
459
|
+
}
|
|
460
|
+
if (!platformBinary) {
|
|
461
|
+
throw new Error(`${platform} is not supported`);
|
|
462
|
+
}
|
|
463
|
+
return detectArchBinary(platformBinary);
|
|
464
|
+
}
|
|
465
|
+
var import_node_process7, import_node_path21, import_node_url, import_node_child_process22, import_promises21, import_meta, fallbackAttemptSymbol, __dirname, localXdgOpenPath, platform, arch, tryEachApp, baseOpen, open, openApp, apps, open_default;
|
|
466
|
+
var init_open = __esm({
|
|
467
|
+
"node_modules/.pnpm/open@11.0.0/node_modules/open/index.js"() {
|
|
468
|
+
"use strict";
|
|
469
|
+
import_node_process7 = __toESM(require("process"), 1);
|
|
470
|
+
import_node_path21 = __toESM(require("path"), 1);
|
|
471
|
+
import_node_url = require("url");
|
|
472
|
+
import_node_child_process22 = __toESM(require("child_process"), 1);
|
|
473
|
+
import_promises21 = __toESM(require("fs/promises"), 1);
|
|
474
|
+
init_wsl_utils();
|
|
475
|
+
init_powershell_utils();
|
|
476
|
+
init_define_lazy_prop();
|
|
477
|
+
init_default_browser();
|
|
478
|
+
init_is_inside_container();
|
|
479
|
+
init_is_in_ssh();
|
|
480
|
+
import_meta = {};
|
|
481
|
+
fallbackAttemptSymbol = /* @__PURE__ */ Symbol("fallbackAttempt");
|
|
482
|
+
__dirname = import_meta.url ? import_node_path21.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url)) : "";
|
|
483
|
+
localXdgOpenPath = import_node_path21.default.join(__dirname, "xdg-open");
|
|
484
|
+
({ platform, arch } = import_node_process7.default);
|
|
485
|
+
tryEachApp = async (apps2, opener) => {
|
|
486
|
+
if (apps2.length === 0) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
const errors = [];
|
|
490
|
+
for (const app of apps2) {
|
|
491
|
+
try {
|
|
492
|
+
return await opener(app);
|
|
493
|
+
} catch (error) {
|
|
494
|
+
errors.push(error);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
throw new AggregateError(errors, "Failed to open in all supported apps");
|
|
498
|
+
};
|
|
499
|
+
baseOpen = async (options) => {
|
|
500
|
+
options = {
|
|
501
|
+
wait: false,
|
|
502
|
+
background: false,
|
|
503
|
+
newInstance: false,
|
|
504
|
+
allowNonzeroExitCode: false,
|
|
505
|
+
...options
|
|
506
|
+
};
|
|
507
|
+
const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
|
|
508
|
+
delete options[fallbackAttemptSymbol];
|
|
509
|
+
if (Array.isArray(options.app)) {
|
|
510
|
+
return tryEachApp(options.app, (singleApp) => baseOpen({
|
|
511
|
+
...options,
|
|
512
|
+
app: singleApp,
|
|
513
|
+
[fallbackAttemptSymbol]: true
|
|
514
|
+
}));
|
|
515
|
+
}
|
|
516
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
517
|
+
appArguments = [...appArguments];
|
|
518
|
+
if (Array.isArray(app)) {
|
|
519
|
+
return tryEachApp(app, (appName) => baseOpen({
|
|
520
|
+
...options,
|
|
521
|
+
app: {
|
|
522
|
+
name: appName,
|
|
523
|
+
arguments: appArguments
|
|
524
|
+
},
|
|
525
|
+
[fallbackAttemptSymbol]: true
|
|
526
|
+
}));
|
|
527
|
+
}
|
|
528
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
529
|
+
const ids = {
|
|
530
|
+
"com.google.chrome": "chrome",
|
|
531
|
+
"google-chrome.desktop": "chrome",
|
|
532
|
+
"com.brave.browser": "brave",
|
|
533
|
+
"org.mozilla.firefox": "firefox",
|
|
534
|
+
"firefox.desktop": "firefox",
|
|
535
|
+
"com.microsoft.msedge": "edge",
|
|
536
|
+
"com.microsoft.edge": "edge",
|
|
537
|
+
"com.microsoft.edgemac": "edge",
|
|
538
|
+
"microsoft-edge.desktop": "edge",
|
|
539
|
+
"com.apple.safari": "safari"
|
|
540
|
+
};
|
|
541
|
+
const flags = {
|
|
542
|
+
chrome: "--incognito",
|
|
543
|
+
brave: "--incognito",
|
|
544
|
+
firefox: "--private-window",
|
|
545
|
+
edge: "--inPrivate"
|
|
546
|
+
// Safari doesn't support private mode via command line
|
|
547
|
+
};
|
|
548
|
+
let browser;
|
|
549
|
+
if (is_wsl_default) {
|
|
550
|
+
const progId = await wslDefaultBrowser();
|
|
551
|
+
const browserInfo = _windowsBrowserProgIdMap.get(progId);
|
|
552
|
+
browser = browserInfo ?? {};
|
|
553
|
+
} else {
|
|
554
|
+
browser = await defaultBrowser2();
|
|
555
|
+
}
|
|
556
|
+
if (browser.id in ids) {
|
|
557
|
+
const browserName = ids[browser.id.toLowerCase()];
|
|
558
|
+
if (app === "browserPrivate") {
|
|
559
|
+
if (browserName === "safari") {
|
|
560
|
+
throw new Error("Safari doesn't support opening in private mode via command line");
|
|
561
|
+
}
|
|
562
|
+
appArguments.push(flags[browserName]);
|
|
563
|
+
}
|
|
564
|
+
return baseOpen({
|
|
565
|
+
...options,
|
|
566
|
+
app: {
|
|
567
|
+
name: apps[browserName],
|
|
568
|
+
arguments: appArguments
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
573
|
+
}
|
|
574
|
+
let command;
|
|
575
|
+
const cliArguments = [];
|
|
576
|
+
const childProcessOptions = {};
|
|
577
|
+
let shouldUseWindowsInWsl = false;
|
|
578
|
+
if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
|
|
579
|
+
shouldUseWindowsInWsl = await canAccessPowerShell();
|
|
580
|
+
}
|
|
581
|
+
if (platform === "darwin") {
|
|
582
|
+
command = "open";
|
|
583
|
+
if (options.wait) {
|
|
584
|
+
cliArguments.push("--wait-apps");
|
|
585
|
+
}
|
|
586
|
+
if (options.background) {
|
|
587
|
+
cliArguments.push("--background");
|
|
588
|
+
}
|
|
589
|
+
if (options.newInstance) {
|
|
590
|
+
cliArguments.push("--new");
|
|
591
|
+
}
|
|
592
|
+
if (app) {
|
|
593
|
+
cliArguments.push("-a", app);
|
|
594
|
+
}
|
|
595
|
+
} else if (platform === "win32" || shouldUseWindowsInWsl) {
|
|
596
|
+
command = await powerShellPath2();
|
|
597
|
+
cliArguments.push(...executePowerShell.argumentsPrefix);
|
|
598
|
+
if (!is_wsl_default) {
|
|
599
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
600
|
+
}
|
|
601
|
+
if (is_wsl_default && options.target) {
|
|
602
|
+
options.target = await convertWslPathToWindows(options.target);
|
|
603
|
+
}
|
|
604
|
+
const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
|
|
605
|
+
if (options.wait) {
|
|
606
|
+
encodedArguments.push("-Wait");
|
|
607
|
+
}
|
|
608
|
+
if (app) {
|
|
609
|
+
encodedArguments.push(executePowerShell.escapeArgument(app));
|
|
610
|
+
if (options.target) {
|
|
611
|
+
appArguments.push(options.target);
|
|
612
|
+
}
|
|
613
|
+
} else if (options.target) {
|
|
614
|
+
encodedArguments.push(executePowerShell.escapeArgument(options.target));
|
|
615
|
+
}
|
|
616
|
+
if (appArguments.length > 0) {
|
|
617
|
+
appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
|
|
618
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
619
|
+
}
|
|
620
|
+
options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
|
|
621
|
+
if (!options.wait) {
|
|
622
|
+
childProcessOptions.stdio = "ignore";
|
|
623
|
+
}
|
|
624
|
+
} else {
|
|
625
|
+
if (app) {
|
|
626
|
+
command = app;
|
|
627
|
+
} else {
|
|
628
|
+
const isBundled = !__dirname || __dirname === "/";
|
|
629
|
+
let exeLocalXdgOpen = false;
|
|
630
|
+
try {
|
|
631
|
+
await import_promises21.default.access(localXdgOpenPath, import_promises21.constants.X_OK);
|
|
632
|
+
exeLocalXdgOpen = true;
|
|
633
|
+
} catch {
|
|
634
|
+
}
|
|
635
|
+
const useSystemXdgOpen = import_node_process7.default.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
636
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
637
|
+
}
|
|
638
|
+
if (appArguments.length > 0) {
|
|
639
|
+
cliArguments.push(...appArguments);
|
|
640
|
+
}
|
|
641
|
+
if (!options.wait) {
|
|
642
|
+
childProcessOptions.stdio = "ignore";
|
|
643
|
+
childProcessOptions.detached = true;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
647
|
+
cliArguments.push("--args", ...appArguments);
|
|
648
|
+
}
|
|
649
|
+
if (options.target) {
|
|
650
|
+
cliArguments.push(options.target);
|
|
651
|
+
}
|
|
652
|
+
const subprocess = import_node_child_process22.default.spawn(command, cliArguments, childProcessOptions);
|
|
653
|
+
if (options.wait) {
|
|
654
|
+
return new Promise((resolve2, reject) => {
|
|
655
|
+
subprocess.once("error", reject);
|
|
656
|
+
subprocess.once("close", (exitCode) => {
|
|
657
|
+
if (!options.allowNonzeroExitCode && exitCode !== 0) {
|
|
658
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
resolve2(subprocess);
|
|
662
|
+
});
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
if (isFallbackAttempt) {
|
|
666
|
+
return new Promise((resolve2, reject) => {
|
|
667
|
+
subprocess.once("error", reject);
|
|
668
|
+
subprocess.once("spawn", () => {
|
|
669
|
+
subprocess.once("close", (exitCode) => {
|
|
670
|
+
subprocess.off("error", reject);
|
|
671
|
+
if (exitCode !== 0) {
|
|
672
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
subprocess.unref();
|
|
676
|
+
resolve2(subprocess);
|
|
677
|
+
});
|
|
678
|
+
});
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
subprocess.unref();
|
|
682
|
+
return new Promise((resolve2, reject) => {
|
|
683
|
+
subprocess.once("error", reject);
|
|
684
|
+
subprocess.once("spawn", () => {
|
|
685
|
+
subprocess.off("error", reject);
|
|
686
|
+
resolve2(subprocess);
|
|
687
|
+
});
|
|
688
|
+
});
|
|
689
|
+
};
|
|
690
|
+
open = (target, options) => {
|
|
691
|
+
if (typeof target !== "string") {
|
|
692
|
+
throw new TypeError("Expected a `target`");
|
|
693
|
+
}
|
|
694
|
+
return baseOpen({
|
|
695
|
+
...options,
|
|
696
|
+
target
|
|
697
|
+
});
|
|
698
|
+
};
|
|
699
|
+
openApp = (name, options) => {
|
|
700
|
+
if (typeof name !== "string" && !Array.isArray(name)) {
|
|
701
|
+
throw new TypeError("Expected a valid `name`");
|
|
702
|
+
}
|
|
703
|
+
const { arguments: appArguments = [] } = options ?? {};
|
|
704
|
+
if (appArguments !== void 0 && appArguments !== null && !Array.isArray(appArguments)) {
|
|
705
|
+
throw new TypeError("Expected `appArguments` as Array type");
|
|
706
|
+
}
|
|
707
|
+
return baseOpen({
|
|
708
|
+
...options,
|
|
709
|
+
app: {
|
|
710
|
+
name,
|
|
711
|
+
arguments: appArguments
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
};
|
|
715
|
+
apps = {
|
|
716
|
+
browser: "browser",
|
|
717
|
+
browserPrivate: "browserPrivate"
|
|
718
|
+
};
|
|
719
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
720
|
+
darwin: "google chrome",
|
|
721
|
+
win32: "chrome",
|
|
722
|
+
// `chromium-browser` is the older deb package name used by Ubuntu/Debian before snap.
|
|
723
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
|
|
724
|
+
}, {
|
|
725
|
+
wsl: {
|
|
726
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
727
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
728
|
+
}
|
|
729
|
+
}));
|
|
730
|
+
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
731
|
+
darwin: "brave browser",
|
|
732
|
+
win32: "brave",
|
|
733
|
+
linux: ["brave-browser", "brave"]
|
|
734
|
+
}, {
|
|
735
|
+
wsl: {
|
|
736
|
+
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
737
|
+
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
738
|
+
}
|
|
739
|
+
}));
|
|
740
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
741
|
+
darwin: "firefox",
|
|
742
|
+
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
743
|
+
linux: "firefox"
|
|
744
|
+
}, {
|
|
745
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
746
|
+
}));
|
|
747
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
748
|
+
darwin: "microsoft edge",
|
|
749
|
+
win32: "msedge",
|
|
750
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
751
|
+
}, {
|
|
752
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
753
|
+
}));
|
|
754
|
+
defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
755
|
+
darwin: "Safari"
|
|
756
|
+
}));
|
|
757
|
+
open_default = open;
|
|
758
|
+
}
|
|
759
|
+
});
|
|
760
|
+
|
|
31
761
|
// src/cli/index.ts
|
|
32
762
|
var cli_exports = {};
|
|
33
763
|
__export(cli_exports, {
|
|
@@ -41,7 +771,7 @@ var import_commander = require("commander");
|
|
|
41
771
|
|
|
42
772
|
// src/package-info.ts
|
|
43
773
|
var AISNITCH_PACKAGE_NAME = "aisnitch";
|
|
44
|
-
var AISNITCH_VERSION = "0.2.
|
|
774
|
+
var AISNITCH_VERSION = "0.2.22";
|
|
45
775
|
var AISNITCH_DESCRIPTION = "Universal bridge for AI coding tool activity \u2014 capture, normalize, stream.";
|
|
46
776
|
|
|
47
777
|
// src/core/events/schema.ts
|
|
@@ -82,6 +812,8 @@ var TOOL_NAMES = [
|
|
|
82
812
|
"kiro",
|
|
83
813
|
"augment-code",
|
|
84
814
|
"mistral",
|
|
815
|
+
"zed",
|
|
816
|
+
"pi",
|
|
85
817
|
"unknown"
|
|
86
818
|
];
|
|
87
819
|
var ERROR_TYPES = [
|
|
@@ -129,6 +861,11 @@ var ToolInputSchema = import_zod.z.strictObject({
|
|
|
129
861
|
(value) => value.filePath !== void 0 || value.command !== void 0,
|
|
130
862
|
"toolInput must include filePath or command"
|
|
131
863
|
);
|
|
864
|
+
var ThinkingContentSchema = import_zod.z.string().max(1e5).describe("Raw thinking/reasoning content from the AI model");
|
|
865
|
+
var ToolCallNameSchema = import_zod.z.string().min(1).max(100).describe("Name of the tool being invoked (e.g., Edit, Bash, Grep)");
|
|
866
|
+
var FinalMessageSchema = import_zod.z.string().max(5e4).describe("End-of-run summary or completion message");
|
|
867
|
+
var ToolResultSchema = import_zod.z.string().max(1e4).describe("Tool execution result or output");
|
|
868
|
+
var MessageContentSchema = import_zod.z.string().max(1e5).describe("Raw text content from AI messages");
|
|
132
869
|
var ToolNameSchema = import_zod.z.enum(TOOL_NAMES);
|
|
133
870
|
var AISnitchEventTypeSchema = import_zod.z.enum(AISNITCH_EVENT_TYPES);
|
|
134
871
|
var ErrorTypeSchema = import_zod.z.enum(ERROR_TYPES);
|
|
@@ -143,6 +880,9 @@ var EventDataSchema = import_zod.z.strictObject({
|
|
|
143
880
|
activeFile: import_zod.z.string().min(1).max(4096).optional(),
|
|
144
881
|
model: import_zod.z.string().min(1).max(200).optional(),
|
|
145
882
|
tokensUsed: import_zod.z.number().int().min(0).optional(),
|
|
883
|
+
inputTokens: import_zod.z.number().int().min(0).optional(),
|
|
884
|
+
outputTokens: import_zod.z.number().int().min(0).optional(),
|
|
885
|
+
cachedTokens: import_zod.z.number().int().min(0).optional(),
|
|
146
886
|
errorMessage: import_zod.z.string().min(1).max(1e4).optional(),
|
|
147
887
|
errorType: ErrorTypeSchema.optional(),
|
|
148
888
|
raw: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
|
|
@@ -151,7 +891,13 @@ var EventDataSchema = import_zod.z.strictObject({
|
|
|
151
891
|
pid: import_zod.z.number().int().positive().optional(),
|
|
152
892
|
instanceId: import_zod.z.string().min(1).max(255).optional(),
|
|
153
893
|
instanceIndex: import_zod.z.number().int().min(1).optional(),
|
|
154
|
-
instanceTotal: import_zod.z.number().int().min(1).optional()
|
|
894
|
+
instanceTotal: import_zod.z.number().int().min(1).optional(),
|
|
895
|
+
// New fields for enhanced content capture
|
|
896
|
+
thinkingContent: ThinkingContentSchema.optional(),
|
|
897
|
+
toolCallName: ToolCallNameSchema.optional(),
|
|
898
|
+
finalMessage: FinalMessageSchema.optional(),
|
|
899
|
+
toolResult: ToolResultSchema.optional(),
|
|
900
|
+
messageContent: MessageContentSchema.optional()
|
|
155
901
|
});
|
|
156
902
|
var AISnitchEventSchema = import_zod.z.strictObject({
|
|
157
903
|
specversion: import_zod.z.literal("1.0"),
|
|
@@ -956,8 +1702,8 @@ var ClaudeCodeSetup = class extends FileToolSetupBase {
|
|
|
956
1702
|
return `${JSON.stringify(nextSettings, null, 2)}
|
|
957
1703
|
`;
|
|
958
1704
|
}
|
|
959
|
-
getFileBackupPath(
|
|
960
|
-
return `${
|
|
1705
|
+
getFileBackupPath(path2) {
|
|
1706
|
+
return `${path2}.bak`;
|
|
961
1707
|
}
|
|
962
1708
|
};
|
|
963
1709
|
var OpenCodeSetup = class extends FileToolSetupBase {
|
|
@@ -1197,8 +1943,8 @@ var CopilotCLISetup = class {
|
|
|
1197
1943
|
return `${JSON.stringify(nextConfig, null, 2)}
|
|
1198
1944
|
`;
|
|
1199
1945
|
}
|
|
1200
|
-
getBackupPath(
|
|
1201
|
-
return `${
|
|
1946
|
+
getBackupPath(path2) {
|
|
1947
|
+
return `${path2}.bak`;
|
|
1202
1948
|
}
|
|
1203
1949
|
};
|
|
1204
1950
|
var OpenClawSetup = class {
|
|
@@ -1323,8 +2069,8 @@ var OpenClawSetup = class {
|
|
|
1323
2069
|
return `${JSON.stringify(nextConfig, null, 2)}
|
|
1324
2070
|
`;
|
|
1325
2071
|
}
|
|
1326
|
-
getBackupPath(
|
|
1327
|
-
return `${
|
|
2072
|
+
getBackupPath(path2) {
|
|
2073
|
+
return `${path2}.bak`;
|
|
1328
2074
|
}
|
|
1329
2075
|
};
|
|
1330
2076
|
async function createToolSetup(toolName, options = {}, dependencies = {}) {
|
|
@@ -2367,17 +3113,17 @@ async function isBinaryAvailable(binaryName) {
|
|
|
2367
3113
|
return false;
|
|
2368
3114
|
}
|
|
2369
3115
|
}
|
|
2370
|
-
async function fileExists(
|
|
3116
|
+
async function fileExists(path2) {
|
|
2371
3117
|
try {
|
|
2372
|
-
await (0, import_promises2.access)(
|
|
3118
|
+
await (0, import_promises2.access)(path2, import_node_fs.constants.F_OK);
|
|
2373
3119
|
return true;
|
|
2374
3120
|
} catch {
|
|
2375
3121
|
return false;
|
|
2376
3122
|
}
|
|
2377
3123
|
}
|
|
2378
|
-
async function readOptionalFile(
|
|
3124
|
+
async function readOptionalFile(path2) {
|
|
2379
3125
|
try {
|
|
2380
|
-
return await (0, import_promises2.readFile)(
|
|
3126
|
+
return await (0, import_promises2.readFile)(path2, "utf8");
|
|
2381
3127
|
} catch (error) {
|
|
2382
3128
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
2383
3129
|
return null;
|
|
@@ -2388,14 +3134,14 @@ async function readOptionalFile(path) {
|
|
|
2388
3134
|
function shellEscapeSingle(value) {
|
|
2389
3135
|
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
2390
3136
|
}
|
|
2391
|
-
async function restoreBackupOrRemove(
|
|
2392
|
-
const backupPath = `${
|
|
3137
|
+
async function restoreBackupOrRemove(path2) {
|
|
3138
|
+
const backupPath = `${path2}.bak`;
|
|
2393
3139
|
if (await fileExists(backupPath)) {
|
|
2394
|
-
await (0, import_promises2.copyFile)(backupPath,
|
|
3140
|
+
await (0, import_promises2.copyFile)(backupPath, path2);
|
|
2395
3141
|
await (0, import_promises2.rm)(backupPath, { force: true });
|
|
2396
3142
|
return;
|
|
2397
3143
|
}
|
|
2398
|
-
await (0, import_promises2.rm)(
|
|
3144
|
+
await (0, import_promises2.rm)(path2, { force: true });
|
|
2399
3145
|
}
|
|
2400
3146
|
function buildAiderNotificationCommand(options) {
|
|
2401
3147
|
const cliArgs = [process.execPath, resolveCurrentCliEntryPath(), "aider-notify"];
|
|
@@ -2463,13 +3209,13 @@ function toConfigPathOptions(options) {
|
|
|
2463
3209
|
}
|
|
2464
3210
|
|
|
2465
3211
|
// src/cli/runtime.ts
|
|
2466
|
-
var
|
|
2467
|
-
var
|
|
2468
|
-
var
|
|
3212
|
+
var import_node_child_process23 = require("child_process");
|
|
3213
|
+
var import_node_fs7 = require("fs");
|
|
3214
|
+
var import_promises22 = require("fs/promises");
|
|
2469
3215
|
var import_node_net4 = require("net");
|
|
2470
|
-
var
|
|
2471
|
-
var
|
|
2472
|
-
var
|
|
3216
|
+
var import_node_os6 = require("os");
|
|
3217
|
+
var import_node_path22 = require("path");
|
|
3218
|
+
var import_node_util21 = require("util");
|
|
2473
3219
|
|
|
2474
3220
|
// src/adapters/generic-pty.ts
|
|
2475
3221
|
var import_node_path5 = require("path");
|
|
@@ -2540,9 +3286,11 @@ var TOOL_BINARY_MAP = {
|
|
|
2540
3286
|
"openhands": "openhands",
|
|
2541
3287
|
"openclaw": "openclaw",
|
|
2542
3288
|
"opencode": "opencode",
|
|
3289
|
+
"pi": "pi",
|
|
2543
3290
|
"qwen-code": "qwen",
|
|
2544
3291
|
"unknown": "unknown",
|
|
2545
|
-
"windsurf": "windsurf"
|
|
3292
|
+
"windsurf": "windsurf",
|
|
3293
|
+
"zed": "zed"
|
|
2546
3294
|
};
|
|
2547
3295
|
var ContextDetector = class {
|
|
2548
3296
|
cache = /* @__PURE__ */ new Map();
|
|
@@ -4401,7 +5149,7 @@ var UDSServer = class {
|
|
|
4401
5149
|
};
|
|
4402
5150
|
|
|
4403
5151
|
// src/core/engine/pipeline.ts
|
|
4404
|
-
var
|
|
5152
|
+
var import_node_path18 = require("path");
|
|
4405
5153
|
var import_zod4 = require("zod");
|
|
4406
5154
|
|
|
4407
5155
|
// src/adapters/aider.ts
|
|
@@ -4508,20 +5256,29 @@ var BaseAdapter = class {
|
|
|
4508
5256
|
});
|
|
4509
5257
|
let published;
|
|
4510
5258
|
try {
|
|
4511
|
-
published = await
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
5259
|
+
published = await SHARED_BREAKERS.adapterEmit.execute(async () => {
|
|
5260
|
+
return await this.publishEventImplementation(event, {
|
|
5261
|
+
cwd: context.cwd,
|
|
5262
|
+
env: context.env,
|
|
5263
|
+
hookPayload: context.hookPayload,
|
|
5264
|
+
pid: context.pid,
|
|
5265
|
+
sessionId,
|
|
5266
|
+
source: context.source,
|
|
5267
|
+
transcriptPath: context.transcriptPath
|
|
5268
|
+
});
|
|
4519
5269
|
});
|
|
4520
5270
|
} catch (error) {
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
5271
|
+
if (error instanceof Error && error.name === "CircuitOpenError") {
|
|
5272
|
+
logger.warn(
|
|
5273
|
+
{ error, eventType: type, adapter: this.name },
|
|
5274
|
+
"\u{1F4D6} Adapter emit blocked by open circuit \u2014 event dropped"
|
|
5275
|
+
);
|
|
5276
|
+
} else {
|
|
5277
|
+
logger.error(
|
|
5278
|
+
{ error, eventType: type, adapter: this.name, sessionId },
|
|
5279
|
+
"\u{1F4D6} Failed to publish event \u2014 swallowing to prevent daemon crash"
|
|
5280
|
+
);
|
|
5281
|
+
}
|
|
4525
5282
|
published = false;
|
|
4526
5283
|
}
|
|
4527
5284
|
if (published) {
|
|
@@ -5535,7 +6292,11 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
5535
6292
|
return;
|
|
5536
6293
|
}
|
|
5537
6294
|
case "SessionEnd": {
|
|
5538
|
-
|
|
6295
|
+
const finalMessage = extractFinalMessageFromPayload(payload);
|
|
6296
|
+
await this.emitStateChange("session.end", {
|
|
6297
|
+
...sharedData,
|
|
6298
|
+
finalMessage
|
|
6299
|
+
}, context);
|
|
5539
6300
|
return;
|
|
5540
6301
|
}
|
|
5541
6302
|
case "UserPromptSubmit":
|
|
@@ -5552,12 +6313,22 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
5552
6313
|
return;
|
|
5553
6314
|
}
|
|
5554
6315
|
case "PreToolUse": {
|
|
5555
|
-
|
|
6316
|
+
const toolCallName = extractToolNameFromPayload(payload);
|
|
6317
|
+
await this.emitStateChange("agent.tool_call", {
|
|
6318
|
+
...sharedData,
|
|
6319
|
+
toolCallName
|
|
6320
|
+
}, context);
|
|
5556
6321
|
return;
|
|
5557
6322
|
}
|
|
5558
6323
|
case "PostToolUse": {
|
|
6324
|
+
const toolCallName = extractToolNameFromPayload(payload);
|
|
6325
|
+
const toolResult = extractToolResultFromPayload(payload);
|
|
5559
6326
|
const emittedType = isClaudeCodingTool(sharedData.toolName) ? "agent.coding" : "agent.tool_call";
|
|
5560
|
-
await this.emitStateChange(emittedType,
|
|
6327
|
+
await this.emitStateChange(emittedType, {
|
|
6328
|
+
...sharedData,
|
|
6329
|
+
toolCallName,
|
|
6330
|
+
toolResult
|
|
6331
|
+
}, context);
|
|
5561
6332
|
return;
|
|
5562
6333
|
}
|
|
5563
6334
|
case "PostToolUseFailure":
|
|
@@ -5742,7 +6513,7 @@ function extractClaudeTranscriptObservations(payload, transcriptPath) {
|
|
|
5742
6513
|
});
|
|
5743
6514
|
const contentParts = extractClaudeContentParts(payload);
|
|
5744
6515
|
const model = getString(payload, "model") ?? getString(getRecord(payload.message), "model");
|
|
5745
|
-
const
|
|
6516
|
+
const tokens = extractTokenUsageDetailed(payload);
|
|
5746
6517
|
const rawPayload = payload;
|
|
5747
6518
|
const sharedContext = {
|
|
5748
6519
|
// 📖 Pass process.env so terminal detection works from transcript path too
|
|
@@ -5755,25 +6526,57 @@ function extractClaudeTranscriptObservations(payload, transcriptPath) {
|
|
|
5755
6526
|
const sharedData = {
|
|
5756
6527
|
model,
|
|
5757
6528
|
raw: rawPayload,
|
|
5758
|
-
tokensUsed
|
|
6529
|
+
tokensUsed: tokens.total,
|
|
6530
|
+
inputTokens: tokens.input,
|
|
6531
|
+
outputTokens: tokens.output,
|
|
6532
|
+
cachedTokens: tokens.cached
|
|
5759
6533
|
};
|
|
5760
6534
|
const observations = [];
|
|
5761
6535
|
if (contentParts.some((part) => part.type === "thinking")) {
|
|
6536
|
+
const thinkingParts = contentParts.filter((part) => part.type === "thinking");
|
|
6537
|
+
const thinkingText = thinkingParts.map((part) => {
|
|
6538
|
+
const text = part.text;
|
|
6539
|
+
return typeof text === "string" ? text : void 0;
|
|
6540
|
+
}).filter((text) => text !== void 0).join("\n");
|
|
5762
6541
|
observations.push({
|
|
5763
6542
|
context: sharedContext,
|
|
5764
|
-
data:
|
|
6543
|
+
data: {
|
|
6544
|
+
...sharedData,
|
|
6545
|
+
thinkingContent: thinkingText.length > 0 ? thinkingText : void 0
|
|
6546
|
+
},
|
|
5765
6547
|
type: "agent.thinking"
|
|
5766
6548
|
});
|
|
5767
6549
|
}
|
|
5768
6550
|
if (contentParts.some(
|
|
5769
6551
|
(part) => part.type === "text" && typeof part.text === "string" && part.text.trim().length > 0
|
|
5770
6552
|
)) {
|
|
6553
|
+
const messageTexts = contentParts.filter((part) => part.type === "text").map((part) => part.text).filter((text) => text.trim().length > 0);
|
|
6554
|
+
const messageContent = messageTexts.join("\n");
|
|
5771
6555
|
observations.push({
|
|
5772
6556
|
context: sharedContext,
|
|
5773
|
-
data:
|
|
6557
|
+
data: {
|
|
6558
|
+
...sharedData,
|
|
6559
|
+
messageContent: messageContent.length > 0 ? messageContent : void 0
|
|
6560
|
+
},
|
|
5774
6561
|
type: "agent.streaming"
|
|
5775
6562
|
});
|
|
5776
6563
|
}
|
|
6564
|
+
const toolUseParts = contentParts.filter(
|
|
6565
|
+
(part) => part.type === "tool_use" || part.type === "toolUse"
|
|
6566
|
+
);
|
|
6567
|
+
if (toolUseParts.length > 0) {
|
|
6568
|
+
const toolName = getString(toolUseParts[0], "name") ?? getString(toolUseParts[0], "tool");
|
|
6569
|
+
if (toolName) {
|
|
6570
|
+
observations.push({
|
|
6571
|
+
context: sharedContext,
|
|
6572
|
+
data: {
|
|
6573
|
+
...sharedData,
|
|
6574
|
+
toolCallName: toolName
|
|
6575
|
+
},
|
|
6576
|
+
type: "agent.tool_call"
|
|
6577
|
+
});
|
|
6578
|
+
}
|
|
6579
|
+
}
|
|
5777
6580
|
return observations;
|
|
5778
6581
|
}
|
|
5779
6582
|
function extractClaudeContentParts(payload) {
|
|
@@ -5784,23 +6587,28 @@ function extractClaudeContentParts(payload) {
|
|
|
5784
6587
|
}
|
|
5785
6588
|
return content.filter(isRecord2);
|
|
5786
6589
|
}
|
|
5787
|
-
function
|
|
6590
|
+
function extractTokenUsageDetailed(payload) {
|
|
5788
6591
|
const tokens = getNumber(payload, "tokens");
|
|
5789
6592
|
if (tokens !== void 0) {
|
|
5790
|
-
return tokens;
|
|
6593
|
+
return { total: tokens };
|
|
5791
6594
|
}
|
|
5792
6595
|
const usage = getRecord(payload.usage);
|
|
5793
6596
|
if (!usage) {
|
|
5794
|
-
return
|
|
6597
|
+
return {};
|
|
5795
6598
|
}
|
|
5796
6599
|
const totalTokens = getNumber(usage, "total_tokens");
|
|
5797
6600
|
if (totalTokens !== void 0) {
|
|
5798
|
-
return
|
|
6601
|
+
return {
|
|
6602
|
+
total: totalTokens,
|
|
6603
|
+
input: getNumber(usage, "input_tokens"),
|
|
6604
|
+
output: getNumber(usage, "output_tokens"),
|
|
6605
|
+
cached: getNumber(usage, "cached_tokens")
|
|
6606
|
+
};
|
|
5799
6607
|
}
|
|
5800
6608
|
const inputTokens = getNumber(usage, "input_tokens") ?? 0;
|
|
5801
6609
|
const outputTokens = getNumber(usage, "output_tokens") ?? 0;
|
|
5802
6610
|
const usageSum = inputTokens + outputTokens;
|
|
5803
|
-
return usageSum > 0 ? usageSum :
|
|
6611
|
+
return usageSum > 0 ? { total: usageSum, input: inputTokens, output: outputTokens } : {};
|
|
5804
6612
|
}
|
|
5805
6613
|
function extractClaudeToolInput(payload) {
|
|
5806
6614
|
const toolInput = getRecord(payload.tool_input) ?? getRecord(payload.toolInput);
|
|
@@ -5896,6 +6704,51 @@ function getString(payload, key) {
|
|
|
5896
6704
|
const value = payload[key];
|
|
5897
6705
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
5898
6706
|
}
|
|
6707
|
+
function extractToolNameFromPayload(payload) {
|
|
6708
|
+
const directToolName = getString(payload, "tool_name") ?? getString(payload, "toolName");
|
|
6709
|
+
if (directToolName) {
|
|
6710
|
+
return directToolName;
|
|
6711
|
+
}
|
|
6712
|
+
const toolUse = getRecord(payload.tool_use) ?? getRecord(payload.toolUse);
|
|
6713
|
+
if (toolUse) {
|
|
6714
|
+
return getString(toolUse, "name") ?? getString(toolUse, "tool");
|
|
6715
|
+
}
|
|
6716
|
+
const toolInput = getRecord(payload.tool_input) ?? getRecord(payload.toolInput);
|
|
6717
|
+
if (toolInput) {
|
|
6718
|
+
return getString(toolInput, "tool_name") ?? getString(toolInput, "type");
|
|
6719
|
+
}
|
|
6720
|
+
return void 0;
|
|
6721
|
+
}
|
|
6722
|
+
function extractToolResultFromPayload(payload) {
|
|
6723
|
+
const directResult = getString(payload, "result") ?? getString(payload, "output");
|
|
6724
|
+
if (directResult) {
|
|
6725
|
+
return directResult;
|
|
6726
|
+
}
|
|
6727
|
+
const toolResult = getRecord(payload.tool_result) ?? getRecord(payload.toolResult);
|
|
6728
|
+
if (toolResult) {
|
|
6729
|
+
return getString(toolResult, "content") ?? getString(toolResult, "output");
|
|
6730
|
+
}
|
|
6731
|
+
const errorField = getString(payload, "error") ?? getString(payload, "error_message");
|
|
6732
|
+
if (errorField) {
|
|
6733
|
+
return errorField;
|
|
6734
|
+
}
|
|
6735
|
+
return void 0;
|
|
6736
|
+
}
|
|
6737
|
+
function extractFinalMessageFromPayload(payload) {
|
|
6738
|
+
const directMessage = getString(payload, "final_message") ?? getString(payload, "finalMessage") ?? getString(payload, "summary") ?? getString(payload, "completion_message");
|
|
6739
|
+
if (directMessage) {
|
|
6740
|
+
return directMessage;
|
|
6741
|
+
}
|
|
6742
|
+
const result = getString(payload, "result") ?? getString(payload, "output") ?? getString(payload, "message");
|
|
6743
|
+
if (result) {
|
|
6744
|
+
return result;
|
|
6745
|
+
}
|
|
6746
|
+
const stats = getRecord(payload.stats);
|
|
6747
|
+
if (stats) {
|
|
6748
|
+
return getString(stats, "summary") ?? getString(stats, "completion_summary");
|
|
6749
|
+
}
|
|
6750
|
+
return void 0;
|
|
6751
|
+
}
|
|
5899
6752
|
|
|
5900
6753
|
// src/adapters/copilot-cli.ts
|
|
5901
6754
|
var import_node_child_process5 = require("child_process");
|
|
@@ -10859,7 +11712,17 @@ var OpenCodeAdapter = class extends BaseAdapter {
|
|
|
10859
11712
|
project: extractOpenCodeProject(payload),
|
|
10860
11713
|
raw: payload,
|
|
10861
11714
|
toolInput: extractOpenCodeToolInput(payload),
|
|
10862
|
-
toolName: extractOpenCodeToolName(payload)
|
|
11715
|
+
toolName: extractOpenCodeToolName(payload),
|
|
11716
|
+
// 📖 Extract token usage from payload (with input/output/cached breakdown)
|
|
11717
|
+
...(() => {
|
|
11718
|
+
const tokens = extractOpenCodeTokens(payload);
|
|
11719
|
+
return {
|
|
11720
|
+
tokensUsed: tokens.total,
|
|
11721
|
+
inputTokens: tokens.inputTokens,
|
|
11722
|
+
outputTokens: tokens.outputTokens,
|
|
11723
|
+
cachedTokens: tokens.cachedTokens
|
|
11724
|
+
};
|
|
11725
|
+
})()
|
|
10863
11726
|
};
|
|
10864
11727
|
switch (eventType) {
|
|
10865
11728
|
case "session.created": {
|
|
@@ -10869,7 +11732,11 @@ var OpenCodeAdapter = class extends BaseAdapter {
|
|
|
10869
11732
|
return;
|
|
10870
11733
|
}
|
|
10871
11734
|
case "session.deleted": {
|
|
10872
|
-
|
|
11735
|
+
const finalMessage = extractOpenCodeFinalMessage(payload);
|
|
11736
|
+
await this.emitStateChange("session.end", {
|
|
11737
|
+
...sharedData,
|
|
11738
|
+
finalMessage
|
|
11739
|
+
}, context);
|
|
10873
11740
|
return;
|
|
10874
11741
|
}
|
|
10875
11742
|
case "session.error": {
|
|
@@ -10884,9 +11751,21 @@ var OpenCodeAdapter = class extends BaseAdapter {
|
|
|
10884
11751
|
await this.emitStateChange("agent.compact", sharedData, context);
|
|
10885
11752
|
return;
|
|
10886
11753
|
}
|
|
11754
|
+
case "thinking": {
|
|
11755
|
+
const thinkingContent = extractOpenCodeThinkingContent(payload);
|
|
11756
|
+
await this.emitStateChange("agent.thinking", {
|
|
11757
|
+
...sharedData,
|
|
11758
|
+
thinkingContent
|
|
11759
|
+
}, context);
|
|
11760
|
+
return;
|
|
11761
|
+
}
|
|
10887
11762
|
case "message.updated":
|
|
10888
11763
|
case "message.part.updated": {
|
|
10889
|
-
|
|
11764
|
+
const messageContent = extractOpenCodeMessageContent(payload);
|
|
11765
|
+
await this.emitStateChange("agent.streaming", {
|
|
11766
|
+
...sharedData,
|
|
11767
|
+
messageContent
|
|
11768
|
+
}, context);
|
|
10890
11769
|
return;
|
|
10891
11770
|
}
|
|
10892
11771
|
case "permission.asked": {
|
|
@@ -10894,12 +11773,22 @@ var OpenCodeAdapter = class extends BaseAdapter {
|
|
|
10894
11773
|
return;
|
|
10895
11774
|
}
|
|
10896
11775
|
case "tool.execute.before": {
|
|
10897
|
-
|
|
11776
|
+
const toolCallName = extractOpenCodeToolName(payload);
|
|
11777
|
+
await this.emitStateChange("agent.tool_call", {
|
|
11778
|
+
...sharedData,
|
|
11779
|
+
toolCallName
|
|
11780
|
+
}, context);
|
|
10898
11781
|
return;
|
|
10899
11782
|
}
|
|
10900
11783
|
case "tool.execute.after": {
|
|
11784
|
+
const toolCallName = extractOpenCodeToolName(payload);
|
|
11785
|
+
const toolResult = extractOpenCodeToolResult(payload);
|
|
10901
11786
|
const emittedType = isOpenCodeCodingTool(sharedData.toolName) ? "agent.coding" : "agent.tool_call";
|
|
10902
|
-
await this.emitStateChange(emittedType,
|
|
11787
|
+
await this.emitStateChange(emittedType, {
|
|
11788
|
+
...sharedData,
|
|
11789
|
+
toolCallName,
|
|
11790
|
+
toolResult
|
|
11791
|
+
}, context);
|
|
10903
11792
|
return;
|
|
10904
11793
|
}
|
|
10905
11794
|
default: {
|
|
@@ -11066,7 +11955,597 @@ function getString10(payload, key) {
|
|
|
11066
11955
|
const value = payload[key];
|
|
11067
11956
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
11068
11957
|
}
|
|
11069
|
-
|
|
11958
|
+
function extractOpenCodeFinalMessage(payload) {
|
|
11959
|
+
const directMessage = getString10(payload, "final_message") ?? getString10(payload, "finalMessage") ?? getString10(payload, "summary") ?? getString10(payload, "completion_message");
|
|
11960
|
+
if (directMessage) {
|
|
11961
|
+
return directMessage;
|
|
11962
|
+
}
|
|
11963
|
+
const result = getString10(payload, "result") ?? getString10(payload, "output") ?? getString10(getRecord9(payload.properties), "result");
|
|
11964
|
+
if (result) {
|
|
11965
|
+
return result;
|
|
11966
|
+
}
|
|
11967
|
+
return void 0;
|
|
11968
|
+
}
|
|
11969
|
+
function extractOpenCodeToolResult(payload) {
|
|
11970
|
+
const directResult = getString10(payload, "result") ?? getString10(payload, "output") ?? getString10(payload, "toolResult");
|
|
11971
|
+
if (directResult) {
|
|
11972
|
+
return directResult;
|
|
11973
|
+
}
|
|
11974
|
+
const toolResult = getRecord9(payload.tool_result) ?? getRecord9(payload.toolResult);
|
|
11975
|
+
if (toolResult) {
|
|
11976
|
+
return getString10(toolResult, "content") ?? getString10(toolResult, "output");
|
|
11977
|
+
}
|
|
11978
|
+
const props = getRecord9(payload.properties);
|
|
11979
|
+
if (props) {
|
|
11980
|
+
const nestedResult = getRecord9(props.tool_result) ?? getRecord9(props.toolResult);
|
|
11981
|
+
if (nestedResult) {
|
|
11982
|
+
return getString10(nestedResult, "content") ?? getString10(nestedResult, "output");
|
|
11983
|
+
}
|
|
11984
|
+
}
|
|
11985
|
+
return void 0;
|
|
11986
|
+
}
|
|
11987
|
+
function extractOpenCodeMessageContent(payload) {
|
|
11988
|
+
const directMessage = getString10(payload, "text") ?? getString10(payload, "message") ?? getString10(payload, "content") ?? getString10(payload, "output");
|
|
11989
|
+
if (directMessage) {
|
|
11990
|
+
return directMessage;
|
|
11991
|
+
}
|
|
11992
|
+
const part = getRecord9(payload.part) ?? getRecord9(getRecord9(payload.properties)?.part);
|
|
11993
|
+
if (part) {
|
|
11994
|
+
return getString10(part, "text") ?? getString10(part, "content");
|
|
11995
|
+
}
|
|
11996
|
+
const props = getRecord9(payload.properties);
|
|
11997
|
+
if (props) {
|
|
11998
|
+
const message = getRecord9(props.message) ?? getRecord9(props.info);
|
|
11999
|
+
if (message) {
|
|
12000
|
+
return getString10(message, "text") ?? getString10(message, "content");
|
|
12001
|
+
}
|
|
12002
|
+
return getString10(props, "text") ?? getString10(props, "message");
|
|
12003
|
+
}
|
|
12004
|
+
return void 0;
|
|
12005
|
+
}
|
|
12006
|
+
function extractOpenCodeThinkingContent(payload) {
|
|
12007
|
+
const directThinking = getString10(payload, "thinking") ?? getString10(payload, "thinkingContent") ?? getString10(payload, "reasoning") ?? getString10(payload, "thought");
|
|
12008
|
+
if (directThinking) {
|
|
12009
|
+
return directThinking;
|
|
12010
|
+
}
|
|
12011
|
+
const props = getRecord9(payload.properties);
|
|
12012
|
+
if (props) {
|
|
12013
|
+
return getString10(props, "thinking") ?? getString10(props, "reasoning") ?? getString10(props, "thought");
|
|
12014
|
+
}
|
|
12015
|
+
return void 0;
|
|
12016
|
+
}
|
|
12017
|
+
function extractOpenCodeTokens(payload) {
|
|
12018
|
+
const directTokens = getNumber8(payload, "tokensUsed") ?? getNumber8(payload, "tokens");
|
|
12019
|
+
if (directTokens !== void 0) {
|
|
12020
|
+
return { total: directTokens };
|
|
12021
|
+
}
|
|
12022
|
+
const props = getRecord9(payload.properties);
|
|
12023
|
+
if (props) {
|
|
12024
|
+
const info = getRecord9(props.info);
|
|
12025
|
+
if (info) {
|
|
12026
|
+
const tokens = getRecord9(info.tokens);
|
|
12027
|
+
if (tokens) {
|
|
12028
|
+
const inputTokens = getNumber8(tokens, "input") ?? 0;
|
|
12029
|
+
const outputTokens = getNumber8(tokens, "output") ?? 0;
|
|
12030
|
+
const reasoningTokens = getNumber8(tokens, "reasoning") ?? 0;
|
|
12031
|
+
const total = inputTokens + outputTokens + reasoningTokens;
|
|
12032
|
+
return total > 0 ? {
|
|
12033
|
+
total,
|
|
12034
|
+
inputTokens,
|
|
12035
|
+
outputTokens,
|
|
12036
|
+
// reasoning tokens are often billed as cached on some providers
|
|
12037
|
+
cachedTokens: reasoningTokens
|
|
12038
|
+
} : {};
|
|
12039
|
+
}
|
|
12040
|
+
}
|
|
12041
|
+
const fallbackTokens = getNumber8(props, "tokensUsed") ?? getNumber8(props, "tokens");
|
|
12042
|
+
if (fallbackTokens !== void 0) {
|
|
12043
|
+
return { total: fallbackTokens };
|
|
12044
|
+
}
|
|
12045
|
+
}
|
|
12046
|
+
return {};
|
|
12047
|
+
}
|
|
12048
|
+
|
|
12049
|
+
// src/adapters/pi.ts
|
|
12050
|
+
var import_node_child_process14 = require("child_process");
|
|
12051
|
+
var import_node_path16 = require("path");
|
|
12052
|
+
var import_node_util14 = require("util");
|
|
12053
|
+
var execFileAsync = (0, import_node_util14.promisify)(import_node_child_process14.execFile);
|
|
12054
|
+
var PiAdapter = class extends BaseAdapter {
|
|
12055
|
+
displayName = "Pi (MiniMax)";
|
|
12056
|
+
name = "pi";
|
|
12057
|
+
strategies = [
|
|
12058
|
+
"process-detect",
|
|
12059
|
+
"api-client",
|
|
12060
|
+
"log-watch"
|
|
12061
|
+
];
|
|
12062
|
+
apiPort = 7890;
|
|
12063
|
+
logPath;
|
|
12064
|
+
poller = null;
|
|
12065
|
+
activePiSessions = /* @__PURE__ */ new Map();
|
|
12066
|
+
lastCheckedTime = 0;
|
|
12067
|
+
constructor(options) {
|
|
12068
|
+
super(options);
|
|
12069
|
+
this.logPath = (0, import_node_path16.join)(
|
|
12070
|
+
options.homeDirectory ?? process.env.HOME ?? "",
|
|
12071
|
+
".pi",
|
|
12072
|
+
"agent.log"
|
|
12073
|
+
);
|
|
12074
|
+
}
|
|
12075
|
+
start() {
|
|
12076
|
+
if (this.getStatus().running) {
|
|
12077
|
+
return Promise.resolve();
|
|
12078
|
+
}
|
|
12079
|
+
this.setRunning(true);
|
|
12080
|
+
this.startPolling();
|
|
12081
|
+
logger.info({ adapter: this.name }, "Pi adapter started");
|
|
12082
|
+
return Promise.resolve();
|
|
12083
|
+
}
|
|
12084
|
+
stop() {
|
|
12085
|
+
if (this.poller !== null) {
|
|
12086
|
+
clearInterval(this.poller);
|
|
12087
|
+
this.poller = null;
|
|
12088
|
+
}
|
|
12089
|
+
this.setRunning(false);
|
|
12090
|
+
logger.info({ adapter: this.name }, "Pi adapter stopped");
|
|
12091
|
+
return Promise.resolve();
|
|
12092
|
+
}
|
|
12093
|
+
async handleHook(payload) {
|
|
12094
|
+
const normalized = this.parseNormalizedHookPayload(payload);
|
|
12095
|
+
if (normalized === null) {
|
|
12096
|
+
return;
|
|
12097
|
+
}
|
|
12098
|
+
const context = {
|
|
12099
|
+
cwd: normalized.cwd,
|
|
12100
|
+
pid: normalized.pid,
|
|
12101
|
+
sessionId: normalized.sessionId,
|
|
12102
|
+
source: "pi-hook"
|
|
12103
|
+
};
|
|
12104
|
+
const eventType = this.mapEventType(normalized.type ?? "");
|
|
12105
|
+
const eventData = this.buildEventData(eventType, normalized);
|
|
12106
|
+
await this.emit(eventType, eventData, context);
|
|
12107
|
+
}
|
|
12108
|
+
startPolling() {
|
|
12109
|
+
this.poller = setInterval(() => {
|
|
12110
|
+
void this.pollPiActivity();
|
|
12111
|
+
}, 2e3);
|
|
12112
|
+
}
|
|
12113
|
+
async pollPiActivity() {
|
|
12114
|
+
const running = await this.detectPiInstance();
|
|
12115
|
+
if (!running) {
|
|
12116
|
+
for (const [sessionId, activity] of this.activePiSessions) {
|
|
12117
|
+
if (activity.state !== "idle") {
|
|
12118
|
+
activity.state = "idle";
|
|
12119
|
+
await this.emitIdle(sessionId);
|
|
12120
|
+
}
|
|
12121
|
+
}
|
|
12122
|
+
return;
|
|
12123
|
+
}
|
|
12124
|
+
try {
|
|
12125
|
+
const response = await fetch(
|
|
12126
|
+
`http://127.0.0.1:${this.apiPort}/api/status`,
|
|
12127
|
+
{
|
|
12128
|
+
signal: AbortSignal.timeout(500)
|
|
12129
|
+
}
|
|
12130
|
+
);
|
|
12131
|
+
if (response.ok) {
|
|
12132
|
+
const data = await response.json();
|
|
12133
|
+
await this.processPiApiResponse(data);
|
|
12134
|
+
}
|
|
12135
|
+
} catch {
|
|
12136
|
+
await this.checkMiniMaxApi();
|
|
12137
|
+
}
|
|
12138
|
+
}
|
|
12139
|
+
async detectPiInstance() {
|
|
12140
|
+
try {
|
|
12141
|
+
const result = await execFileAsync("pgrep", ["-l", "pi|minimax"]);
|
|
12142
|
+
if (result.stdout.includes("pi") || result.stdout.includes("minimax")) {
|
|
12143
|
+
return true;
|
|
12144
|
+
}
|
|
12145
|
+
} catch {
|
|
12146
|
+
}
|
|
12147
|
+
try {
|
|
12148
|
+
const response = await fetch(
|
|
12149
|
+
`http://127.0.0.1:${this.apiPort}/health`,
|
|
12150
|
+
{
|
|
12151
|
+
signal: AbortSignal.timeout(200)
|
|
12152
|
+
}
|
|
12153
|
+
);
|
|
12154
|
+
if (response.ok) {
|
|
12155
|
+
return true;
|
|
12156
|
+
}
|
|
12157
|
+
} catch {
|
|
12158
|
+
}
|
|
12159
|
+
return false;
|
|
12160
|
+
}
|
|
12161
|
+
async checkMiniMaxApi() {
|
|
12162
|
+
try {
|
|
12163
|
+
const response = await fetch("http://127.0.0.1:3000/api/agent/status", {
|
|
12164
|
+
signal: AbortSignal.timeout(500)
|
|
12165
|
+
});
|
|
12166
|
+
if (response.ok) {
|
|
12167
|
+
const data = await response.json();
|
|
12168
|
+
await this.processPiApiResponse(data);
|
|
12169
|
+
}
|
|
12170
|
+
} catch {
|
|
12171
|
+
}
|
|
12172
|
+
}
|
|
12173
|
+
async processPiApiResponse(data) {
|
|
12174
|
+
const rawSession = data.sessionId ?? data.project ?? "default";
|
|
12175
|
+
const sessionId = `pi:${rawSession.replace(/[^a-zA-Z0-9-_]/g, "-")}`;
|
|
12176
|
+
let activity = this.activePiSessions.get(sessionId);
|
|
12177
|
+
if (!activity) {
|
|
12178
|
+
activity = { sessionId, state: "idle" };
|
|
12179
|
+
this.activePiSessions.set(sessionId, activity);
|
|
12180
|
+
await this.emitSessionStart(sessionId, data);
|
|
12181
|
+
}
|
|
12182
|
+
const rawState = data.state ?? "idle";
|
|
12183
|
+
const state = rawState;
|
|
12184
|
+
if (state !== activity.state) {
|
|
12185
|
+
switch (state) {
|
|
12186
|
+
case "thinking": {
|
|
12187
|
+
const rawThinking = data.thinking;
|
|
12188
|
+
if (rawThinking) {
|
|
12189
|
+
await this.emitThinking(sessionId, rawThinking);
|
|
12190
|
+
}
|
|
12191
|
+
break;
|
|
12192
|
+
}
|
|
12193
|
+
case "tool": {
|
|
12194
|
+
const rawFilePath = data.filePath;
|
|
12195
|
+
const rawCommand = data.command;
|
|
12196
|
+
const rawToolName = data.toolName ?? "unknown";
|
|
12197
|
+
await this.emitToolCall(
|
|
12198
|
+
sessionId,
|
|
12199
|
+
{
|
|
12200
|
+
filePath: rawFilePath ?? "",
|
|
12201
|
+
command: rawCommand ?? ""
|
|
12202
|
+
},
|
|
12203
|
+
rawToolName
|
|
12204
|
+
);
|
|
12205
|
+
break;
|
|
12206
|
+
}
|
|
12207
|
+
case "output": {
|
|
12208
|
+
const rawOutput = data.output;
|
|
12209
|
+
if (rawOutput) {
|
|
12210
|
+
await this.emitOutput(sessionId, rawOutput);
|
|
12211
|
+
}
|
|
12212
|
+
break;
|
|
12213
|
+
}
|
|
12214
|
+
case "error": {
|
|
12215
|
+
const rawError = data.error ?? "Unknown error";
|
|
12216
|
+
await this.emitError(sessionId, rawError);
|
|
12217
|
+
break;
|
|
12218
|
+
}
|
|
12219
|
+
case "idle":
|
|
12220
|
+
await this.emitIdle(sessionId);
|
|
12221
|
+
break;
|
|
12222
|
+
}
|
|
12223
|
+
activity.state = state;
|
|
12224
|
+
}
|
|
12225
|
+
}
|
|
12226
|
+
async emitSessionStart(sessionId, data) {
|
|
12227
|
+
const rawProject = data.project ?? "pi-project";
|
|
12228
|
+
const rawModel = data.model ?? "minimax/moonshot";
|
|
12229
|
+
const eventData = {
|
|
12230
|
+
state: "session.start",
|
|
12231
|
+
project: rawProject,
|
|
12232
|
+
model: rawModel,
|
|
12233
|
+
raw: data
|
|
12234
|
+
};
|
|
12235
|
+
await this.emit("session.start", eventData, { sessionId });
|
|
12236
|
+
}
|
|
12237
|
+
async emitThinking(sessionId, content) {
|
|
12238
|
+
if (!content) return;
|
|
12239
|
+
const eventData = {
|
|
12240
|
+
state: "agent.thinking",
|
|
12241
|
+
thinkingContent: content
|
|
12242
|
+
};
|
|
12243
|
+
await this.emit("agent.thinking", eventData, { sessionId });
|
|
12244
|
+
}
|
|
12245
|
+
async emitToolCall(sessionId, toolInput, toolName) {
|
|
12246
|
+
const eventData = {
|
|
12247
|
+
state: "agent.tool_call",
|
|
12248
|
+
toolCallName: toolName,
|
|
12249
|
+
toolInput,
|
|
12250
|
+
activeFile: toolInput.filePath
|
|
12251
|
+
};
|
|
12252
|
+
await this.emit("agent.tool_call", eventData, { sessionId });
|
|
12253
|
+
}
|
|
12254
|
+
async emitOutput(sessionId, content) {
|
|
12255
|
+
if (!content) return;
|
|
12256
|
+
const eventData = {
|
|
12257
|
+
state: "agent.streaming",
|
|
12258
|
+
messageContent: content
|
|
12259
|
+
};
|
|
12260
|
+
await this.emit("agent.streaming", eventData, { sessionId });
|
|
12261
|
+
}
|
|
12262
|
+
async emitError(sessionId, errorMessage) {
|
|
12263
|
+
const eventData = {
|
|
12264
|
+
state: "agent.error",
|
|
12265
|
+
errorMessage,
|
|
12266
|
+
errorType: "api_error"
|
|
12267
|
+
};
|
|
12268
|
+
await this.emit("agent.error", eventData, { sessionId });
|
|
12269
|
+
}
|
|
12270
|
+
async emitIdle(sessionId) {
|
|
12271
|
+
const eventData = {
|
|
12272
|
+
state: "agent.idle"
|
|
12273
|
+
};
|
|
12274
|
+
await this.emit("agent.idle", eventData, { sessionId });
|
|
12275
|
+
}
|
|
12276
|
+
mapEventType(type) {
|
|
12277
|
+
const mapping = {
|
|
12278
|
+
"session.start": "session.start",
|
|
12279
|
+
"session.end": "session.end",
|
|
12280
|
+
"task.start": "task.start",
|
|
12281
|
+
"task.complete": "task.complete",
|
|
12282
|
+
thinking: "agent.thinking",
|
|
12283
|
+
tool: "agent.tool_call",
|
|
12284
|
+
coding: "agent.coding",
|
|
12285
|
+
output: "agent.streaming",
|
|
12286
|
+
message: "agent.streaming",
|
|
12287
|
+
ask: "agent.asking_user",
|
|
12288
|
+
error: "agent.error",
|
|
12289
|
+
idle: "agent.idle",
|
|
12290
|
+
compact: "agent.compact"
|
|
12291
|
+
};
|
|
12292
|
+
return mapping[type] ?? "agent.streaming";
|
|
12293
|
+
}
|
|
12294
|
+
buildEventData(eventType, payload) {
|
|
12295
|
+
const data = payload.data ?? {};
|
|
12296
|
+
return {
|
|
12297
|
+
state: eventType,
|
|
12298
|
+
project: data.project,
|
|
12299
|
+
activeFile: data.activeFile,
|
|
12300
|
+
model: data.model,
|
|
12301
|
+
toolInput: data.toolInput,
|
|
12302
|
+
toolCallName: data.toolCallName,
|
|
12303
|
+
thinkingContent: data.thinkingContent,
|
|
12304
|
+
messageContent: data.messageContent,
|
|
12305
|
+
finalMessage: data.finalMessage,
|
|
12306
|
+
toolResult: data.toolResult,
|
|
12307
|
+
errorMessage: data.errorMessage,
|
|
12308
|
+
errorType: data.errorType,
|
|
12309
|
+
raw: data.raw
|
|
12310
|
+
};
|
|
12311
|
+
}
|
|
12312
|
+
};
|
|
12313
|
+
|
|
12314
|
+
// src/adapters/zed.ts
|
|
12315
|
+
var import_promises15 = require("fs/promises");
|
|
12316
|
+
var import_node_path17 = require("path");
|
|
12317
|
+
var ZedAdapter = class extends BaseAdapter {
|
|
12318
|
+
displayName = "Zed AI";
|
|
12319
|
+
name = "zed";
|
|
12320
|
+
strategies = [
|
|
12321
|
+
"process-detect",
|
|
12322
|
+
"api-client"
|
|
12323
|
+
];
|
|
12324
|
+
logPaths;
|
|
12325
|
+
apiPort = 9876;
|
|
12326
|
+
pollIntervalMs;
|
|
12327
|
+
poller = null;
|
|
12328
|
+
lastEventTime = 0;
|
|
12329
|
+
activeZedSessions = /* @__PURE__ */ new Map();
|
|
12330
|
+
constructor(options) {
|
|
12331
|
+
super(options);
|
|
12332
|
+
this.pollIntervalMs = 2e3;
|
|
12333
|
+
this.logPaths = [
|
|
12334
|
+
(0, import_node_path17.join)(options.homeDirectory ?? process.env.HOME ?? "", ".config", "zed", "logs", "agent.log"),
|
|
12335
|
+
"/tmp/zed-agent.log"
|
|
12336
|
+
];
|
|
12337
|
+
}
|
|
12338
|
+
start() {
|
|
12339
|
+
if (this.getStatus().running) {
|
|
12340
|
+
return Promise.resolve();
|
|
12341
|
+
}
|
|
12342
|
+
this.setRunning(true);
|
|
12343
|
+
this.startPolling();
|
|
12344
|
+
logger.info({ adapter: this.name }, "Zed adapter started");
|
|
12345
|
+
return Promise.resolve();
|
|
12346
|
+
}
|
|
12347
|
+
stop() {
|
|
12348
|
+
if (this.poller !== null) {
|
|
12349
|
+
clearInterval(this.poller);
|
|
12350
|
+
this.poller = null;
|
|
12351
|
+
}
|
|
12352
|
+
this.setRunning(false);
|
|
12353
|
+
logger.info({ adapter: this.name }, "Zed adapter stopped");
|
|
12354
|
+
return Promise.resolve();
|
|
12355
|
+
}
|
|
12356
|
+
async handleHook(payload) {
|
|
12357
|
+
const normalized = this.parseNormalizedHookPayload(payload);
|
|
12358
|
+
if (normalized === null) {
|
|
12359
|
+
return;
|
|
12360
|
+
}
|
|
12361
|
+
const context = {
|
|
12362
|
+
cwd: normalized.cwd,
|
|
12363
|
+
pid: normalized.pid,
|
|
12364
|
+
sessionId: normalized.sessionId,
|
|
12365
|
+
source: "zed-hook"
|
|
12366
|
+
};
|
|
12367
|
+
const eventType = this.mapEventType(normalized.type ?? "");
|
|
12368
|
+
const eventData = this.buildEventData(eventType, normalized);
|
|
12369
|
+
await this.emit(eventType, eventData, context);
|
|
12370
|
+
}
|
|
12371
|
+
startPolling() {
|
|
12372
|
+
this.poller = setInterval(() => {
|
|
12373
|
+
void this.pollZedStatus();
|
|
12374
|
+
}, this.pollIntervalMs);
|
|
12375
|
+
}
|
|
12376
|
+
async pollZedStatus() {
|
|
12377
|
+
try {
|
|
12378
|
+
const response = await fetch(`http://127.0.0.1:${this.apiPort}/api/agent/status`, {
|
|
12379
|
+
signal: AbortSignal.timeout(1e3)
|
|
12380
|
+
});
|
|
12381
|
+
if (response.ok) {
|
|
12382
|
+
const data = await response.json();
|
|
12383
|
+
if (data.sessionId && typeof data.sessionId === "string") {
|
|
12384
|
+
const sessionId = `zed:${data.sessionId}`;
|
|
12385
|
+
if (!this.activeZedSessions.has(sessionId)) {
|
|
12386
|
+
this.activeZedSessions.set(sessionId, sessionId);
|
|
12387
|
+
await this.emitSessionStart(sessionId, data);
|
|
12388
|
+
}
|
|
12389
|
+
if (data.state === "thinking" && this.lastEventTime < Date.now() - 5e3) {
|
|
12390
|
+
const rawThinking = data.thinking;
|
|
12391
|
+
if (rawThinking) {
|
|
12392
|
+
await this.emitThinking(sessionId, rawThinking);
|
|
12393
|
+
}
|
|
12394
|
+
} else if (data.state === "tool" && data.toolName) {
|
|
12395
|
+
const rawFilePath = data.filePath;
|
|
12396
|
+
const rawCommand = data.command;
|
|
12397
|
+
const rawToolName = data.toolName ?? "unknown";
|
|
12398
|
+
await this.emitToolCall(
|
|
12399
|
+
sessionId,
|
|
12400
|
+
{
|
|
12401
|
+
filePath: rawFilePath ?? "",
|
|
12402
|
+
command: rawCommand ?? ""
|
|
12403
|
+
},
|
|
12404
|
+
rawToolName
|
|
12405
|
+
);
|
|
12406
|
+
} else if (data.state === "idle") {
|
|
12407
|
+
await this.emitIdle(sessionId);
|
|
12408
|
+
}
|
|
12409
|
+
}
|
|
12410
|
+
}
|
|
12411
|
+
} catch {
|
|
12412
|
+
await this.checkLogFiles();
|
|
12413
|
+
}
|
|
12414
|
+
}
|
|
12415
|
+
async checkLogFiles() {
|
|
12416
|
+
for (const logPath of this.logPaths) {
|
|
12417
|
+
try {
|
|
12418
|
+
const content = await (0, import_promises15.readFile)(logPath, "utf8");
|
|
12419
|
+
await this.parseLogContent(content);
|
|
12420
|
+
} catch {
|
|
12421
|
+
}
|
|
12422
|
+
}
|
|
12423
|
+
}
|
|
12424
|
+
async parseLogContent(content) {
|
|
12425
|
+
const lines = content.split("\n").filter((line) => line.trim());
|
|
12426
|
+
for (const line of lines) {
|
|
12427
|
+
if (this.lastEventTime > 0 && this.lastEventTime >= Date.now() - 2e3) {
|
|
12428
|
+
continue;
|
|
12429
|
+
}
|
|
12430
|
+
const event = this.extractZedEventFromLog(line);
|
|
12431
|
+
if (event) {
|
|
12432
|
+
await this.handleHook(event);
|
|
12433
|
+
this.lastEventTime = Date.now();
|
|
12434
|
+
}
|
|
12435
|
+
}
|
|
12436
|
+
}
|
|
12437
|
+
extractZedEventFromLog(line) {
|
|
12438
|
+
try {
|
|
12439
|
+
const parsed = JSON.parse(line);
|
|
12440
|
+
if (!parsed.type || typeof parsed.type !== "string") {
|
|
12441
|
+
return null;
|
|
12442
|
+
}
|
|
12443
|
+
const rawSessionId = parsed.sessionId;
|
|
12444
|
+
const rawWorkspace = parsed.workspace;
|
|
12445
|
+
const sessionId = rawSessionId ? rawSessionId : rawWorkspace ? `zed:${(0, import_node_path17.basename)(rawWorkspace)}` : `zed:${Date.now()}`;
|
|
12446
|
+
const rawCwd = parsed.cwd ?? rawWorkspace;
|
|
12447
|
+
return {
|
|
12448
|
+
type: parsed.type,
|
|
12449
|
+
sessionId,
|
|
12450
|
+
cwd: rawCwd,
|
|
12451
|
+
data: {
|
|
12452
|
+
project: parsed.project ?? rawWorkspace ? (0, import_node_path17.basename)(String(rawWorkspace)) : void 0,
|
|
12453
|
+
model: parsed.model,
|
|
12454
|
+
state: parsed.type,
|
|
12455
|
+
thinkingContent: parsed.thinking,
|
|
12456
|
+
toolCallName: parsed.toolName,
|
|
12457
|
+
toolInput: parsed.toolInput,
|
|
12458
|
+
messageContent: parsed.message ?? parsed.output,
|
|
12459
|
+
errorMessage: parsed.error,
|
|
12460
|
+
raw: parsed
|
|
12461
|
+
}
|
|
12462
|
+
};
|
|
12463
|
+
} catch {
|
|
12464
|
+
if (line.includes("[zed:agent]")) {
|
|
12465
|
+
const cleaned = line.replace(/^\[.*?\] \[.*?\] /, "");
|
|
12466
|
+
if (cleaned.includes("Thinking:")) {
|
|
12467
|
+
return { type: "thinking", thinkingContent: cleaned.replace("Thinking:", "").trim() };
|
|
12468
|
+
}
|
|
12469
|
+
if (cleaned.includes("Executing tool:")) {
|
|
12470
|
+
return { type: "tool", toolCallName: cleaned.replace("Executing tool:", "").trim() };
|
|
12471
|
+
}
|
|
12472
|
+
if (cleaned.includes("Error:")) {
|
|
12473
|
+
return { type: "error", errorMessage: cleaned.replace("Error:", "").trim() };
|
|
12474
|
+
}
|
|
12475
|
+
}
|
|
12476
|
+
return null;
|
|
12477
|
+
}
|
|
12478
|
+
}
|
|
12479
|
+
async emitSessionStart(sessionId, _data) {
|
|
12480
|
+
const eventData = {
|
|
12481
|
+
state: "session.start",
|
|
12482
|
+
project: sessionId.split(":")[1] ?? "unknown"
|
|
12483
|
+
};
|
|
12484
|
+
await this.emit("session.start", eventData, { sessionId });
|
|
12485
|
+
}
|
|
12486
|
+
async emitThinking(sessionId, content) {
|
|
12487
|
+
if (!content) return;
|
|
12488
|
+
const eventData = {
|
|
12489
|
+
state: "agent.thinking",
|
|
12490
|
+
thinkingContent: content
|
|
12491
|
+
};
|
|
12492
|
+
await this.emit("agent.thinking", eventData, { sessionId });
|
|
12493
|
+
this.lastEventTime = Date.now();
|
|
12494
|
+
}
|
|
12495
|
+
async emitToolCall(sessionId, toolInput, toolName) {
|
|
12496
|
+
const eventData = {
|
|
12497
|
+
state: "agent.tool_call",
|
|
12498
|
+
toolCallName: toolName,
|
|
12499
|
+
toolInput,
|
|
12500
|
+
activeFile: toolInput.filePath
|
|
12501
|
+
};
|
|
12502
|
+
await this.emit("agent.tool_call", eventData, { sessionId });
|
|
12503
|
+
this.lastEventTime = Date.now();
|
|
12504
|
+
}
|
|
12505
|
+
async emitIdle(sessionId) {
|
|
12506
|
+
const eventData = {
|
|
12507
|
+
state: "agent.idle"
|
|
12508
|
+
};
|
|
12509
|
+
await this.emit("agent.idle", eventData, { sessionId });
|
|
12510
|
+
}
|
|
12511
|
+
mapEventType(type) {
|
|
12512
|
+
const mapping = {
|
|
12513
|
+
"session.start": "session.start",
|
|
12514
|
+
"session.end": "session.end",
|
|
12515
|
+
"task.start": "task.start",
|
|
12516
|
+
"task.complete": "task.complete",
|
|
12517
|
+
thinking: "agent.thinking",
|
|
12518
|
+
tool: "agent.tool_call",
|
|
12519
|
+
coding: "agent.coding",
|
|
12520
|
+
output: "agent.streaming",
|
|
12521
|
+
message: "agent.streaming",
|
|
12522
|
+
ask: "agent.asking_user",
|
|
12523
|
+
error: "agent.error",
|
|
12524
|
+
idle: "agent.idle",
|
|
12525
|
+
compact: "agent.compact"
|
|
12526
|
+
};
|
|
12527
|
+
return mapping[type] ?? "agent.streaming";
|
|
12528
|
+
}
|
|
12529
|
+
buildEventData(eventType, payload) {
|
|
12530
|
+
const data = payload.data ?? {};
|
|
12531
|
+
return {
|
|
12532
|
+
state: eventType,
|
|
12533
|
+
project: data.project,
|
|
12534
|
+
activeFile: data.activeFile,
|
|
12535
|
+
model: data.model,
|
|
12536
|
+
toolInput: data.toolInput,
|
|
12537
|
+
toolCallName: data.toolCallName,
|
|
12538
|
+
thinkingContent: data.thinkingContent,
|
|
12539
|
+
messageContent: data.messageContent,
|
|
12540
|
+
finalMessage: data.finalMessage,
|
|
12541
|
+
toolResult: data.toolResult,
|
|
12542
|
+
errorMessage: data.errorMessage,
|
|
12543
|
+
errorType: data.errorType,
|
|
12544
|
+
raw: data.raw
|
|
12545
|
+
};
|
|
12546
|
+
}
|
|
12547
|
+
};
|
|
12548
|
+
|
|
11070
12549
|
// src/adapters/registry.ts
|
|
11071
12550
|
var AdapterRegistry = class {
|
|
11072
12551
|
adapters = /* @__PURE__ */ new Map();
|
|
@@ -11150,7 +12629,9 @@ function createDefaultAdapters(options) {
|
|
|
11150
12629
|
new KiloAdapter(options),
|
|
11151
12630
|
new CodexAdapter(options),
|
|
11152
12631
|
new OpenClawAdapter(options),
|
|
11153
|
-
new OpenCodeAdapter(options)
|
|
12632
|
+
new OpenCodeAdapter(options),
|
|
12633
|
+
new PiAdapter(options),
|
|
12634
|
+
new ZedAdapter(options)
|
|
11154
12635
|
];
|
|
11155
12636
|
}
|
|
11156
12637
|
|
|
@@ -11171,7 +12652,7 @@ function getSocketPath(aisnitchHomePath) {
|
|
|
11171
12652
|
if (process.platform === "win32") {
|
|
11172
12653
|
return "\\\\.\\pipe\\aisnitch.sock";
|
|
11173
12654
|
}
|
|
11174
|
-
return (0,
|
|
12655
|
+
return (0, import_node_path18.join)(aisnitchHomePath, "aisnitch.sock");
|
|
11175
12656
|
}
|
|
11176
12657
|
var Pipeline = class {
|
|
11177
12658
|
eventBus = new EventBus();
|
|
@@ -11376,6 +12857,30 @@ var Pipeline = class {
|
|
|
11376
12857
|
getEventBus() {
|
|
11377
12858
|
return this.eventBus;
|
|
11378
12859
|
}
|
|
12860
|
+
/**
|
|
12861
|
+
* Returns the adapter registry for graceful shutdown coordination.
|
|
12862
|
+
*/
|
|
12863
|
+
getAdapterRegistry() {
|
|
12864
|
+
return this.adapterRegistry ?? void 0;
|
|
12865
|
+
}
|
|
12866
|
+
/**
|
|
12867
|
+
* Returns the HTTP receiver for graceful shutdown coordination.
|
|
12868
|
+
*/
|
|
12869
|
+
getHttpReceiver() {
|
|
12870
|
+
return this.httpReceiver;
|
|
12871
|
+
}
|
|
12872
|
+
/**
|
|
12873
|
+
* Returns the UDS server for graceful shutdown coordination.
|
|
12874
|
+
*/
|
|
12875
|
+
getUdsServer() {
|
|
12876
|
+
return this.udsServer;
|
|
12877
|
+
}
|
|
12878
|
+
/**
|
|
12879
|
+
* Returns the WebSocket server for graceful shutdown coordination.
|
|
12880
|
+
*/
|
|
12881
|
+
getWsServer() {
|
|
12882
|
+
return this.wsServer;
|
|
12883
|
+
}
|
|
11379
12884
|
getHealthSnapshot() {
|
|
11380
12885
|
const status = this.getStatus();
|
|
11381
12886
|
return {
|
|
@@ -11500,6 +13005,72 @@ var DEFAULT_TIMEOUTS = Object.freeze({
|
|
|
11500
13005
|
pipelineStartup: 15e3
|
|
11501
13006
|
});
|
|
11502
13007
|
|
|
13008
|
+
// src/core/graceful-shutdown.ts
|
|
13009
|
+
async function withShutdownTimeout(fn, timeoutMs, component) {
|
|
13010
|
+
if (timeoutMs <= 0) {
|
|
13011
|
+
await fn();
|
|
13012
|
+
return;
|
|
13013
|
+
}
|
|
13014
|
+
const timeoutPromise = new Promise((resolve2) => {
|
|
13015
|
+
setTimeout(() => {
|
|
13016
|
+
resolve2("timed_out");
|
|
13017
|
+
}, timeoutMs).unref();
|
|
13018
|
+
});
|
|
13019
|
+
const result = await Promise.race([
|
|
13020
|
+
fn().then(() => "completed"),
|
|
13021
|
+
timeoutPromise
|
|
13022
|
+
]);
|
|
13023
|
+
if (result === "timed_out") {
|
|
13024
|
+
logger.warn(
|
|
13025
|
+
{ component, timeoutMs },
|
|
13026
|
+
`Graceful shutdown exceeded ${timeoutMs}ms timeout \u2014 forcing through`
|
|
13027
|
+
);
|
|
13028
|
+
}
|
|
13029
|
+
}
|
|
13030
|
+
async function shutdownInOrder(components, timeouts, label) {
|
|
13031
|
+
const getTimeout = (key) => {
|
|
13032
|
+
return timeouts[key] ?? DEFAULT_TIMEOUTS.daemonShutdown;
|
|
13033
|
+
};
|
|
13034
|
+
const stopSafely = async (key, fn) => {
|
|
13035
|
+
const timeoutMs = getTimeout(key);
|
|
13036
|
+
try {
|
|
13037
|
+
await withShutdownTimeout(fn, timeoutMs, `${label}.${key}`);
|
|
13038
|
+
} catch (error) {
|
|
13039
|
+
logger.warn(
|
|
13040
|
+
{ error, key, label },
|
|
13041
|
+
`Error during shutdown of ${key} \u2014 continuing with remaining components`
|
|
13042
|
+
);
|
|
13043
|
+
}
|
|
13044
|
+
};
|
|
13045
|
+
if (components.cleanupFns) {
|
|
13046
|
+
for (const cleanupFn of components.cleanupFns) {
|
|
13047
|
+
try {
|
|
13048
|
+
await withShutdownTimeout(
|
|
13049
|
+
async () => {
|
|
13050
|
+
const result = cleanupFn();
|
|
13051
|
+
if (result instanceof Promise) {
|
|
13052
|
+
await result;
|
|
13053
|
+
}
|
|
13054
|
+
},
|
|
13055
|
+
1e3,
|
|
13056
|
+
`${label}.cleanup`
|
|
13057
|
+
);
|
|
13058
|
+
} catch (error) {
|
|
13059
|
+
logger.warn({ error, label }, "Cleanup function failed");
|
|
13060
|
+
}
|
|
13061
|
+
}
|
|
13062
|
+
}
|
|
13063
|
+
if (components.eventBus) {
|
|
13064
|
+
components.eventBus.unsubscribeAll();
|
|
13065
|
+
}
|
|
13066
|
+
await stopSafely("wsServer", () => components.wsServer.stop());
|
|
13067
|
+
await stopSafely("udsServer", () => components.udsServer.stop());
|
|
13068
|
+
await stopSafely("httpReceiver", () => components.httpReceiver.stop());
|
|
13069
|
+
if (components.adapterRegistry) {
|
|
13070
|
+
await stopSafely("adapterRegistry", () => components.adapterRegistry.stopAll());
|
|
13071
|
+
}
|
|
13072
|
+
}
|
|
13073
|
+
|
|
11503
13074
|
// src/tui/index.tsx
|
|
11504
13075
|
var import_ink13 = require("ink");
|
|
11505
13076
|
var import_fullscreen_ink = require("fullscreen-ink");
|
|
@@ -11703,9 +13274,11 @@ var TOOL_COLORS = {
|
|
|
11703
13274
|
"openhands": "#facc15",
|
|
11704
13275
|
"openclaw": "#ef4444",
|
|
11705
13276
|
"opencode": "#10b981",
|
|
13277
|
+
"pi": "#1db954",
|
|
11706
13278
|
"qwen-code": "#22c55e",
|
|
11707
13279
|
"unknown": "#94a3b8",
|
|
11708
|
-
"windsurf": "#a855f7"
|
|
13280
|
+
"windsurf": "#a855f7",
|
|
13281
|
+
"zed": "#e85d04"
|
|
11709
13282
|
};
|
|
11710
13283
|
var EVENT_COLORS = {
|
|
11711
13284
|
"agent.asking_user": "#ef4444",
|
|
@@ -13459,10 +15032,10 @@ async function renderManagedTui(options) {
|
|
|
13459
15032
|
|
|
13460
15033
|
// src/cli/pid.ts
|
|
13461
15034
|
var import_node_fs3 = require("fs");
|
|
13462
|
-
var
|
|
15035
|
+
var import_promises16 = require("fs/promises");
|
|
13463
15036
|
var import_node_net3 = require("net");
|
|
13464
15037
|
var import_node_os4 = require("os");
|
|
13465
|
-
var
|
|
15038
|
+
var import_node_path19 = require("path");
|
|
13466
15039
|
var import_zod5 = require("zod");
|
|
13467
15040
|
var DaemonStateSchema = import_zod5.z.strictObject({
|
|
13468
15041
|
pid: import_zod5.z.number().int().positive(),
|
|
@@ -13477,14 +15050,14 @@ function getDefaultSocketPath(options) {
|
|
|
13477
15050
|
if (process.platform === "win32") {
|
|
13478
15051
|
return "\\\\.\\pipe\\aisnitch.sock";
|
|
13479
15052
|
}
|
|
13480
|
-
return (0,
|
|
15053
|
+
return (0, import_node_path19.join)(getAISnitchHomePath(options), "aisnitch.sock");
|
|
13481
15054
|
}
|
|
13482
15055
|
async function cleanupSocketPathIfStale(socketPath) {
|
|
13483
15056
|
if (process.platform === "win32") {
|
|
13484
15057
|
return false;
|
|
13485
15058
|
}
|
|
13486
15059
|
try {
|
|
13487
|
-
await (0,
|
|
15060
|
+
await (0, import_promises16.access)(socketPath, import_node_fs3.constants.F_OK);
|
|
13488
15061
|
} catch (error) {
|
|
13489
15062
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
13490
15063
|
return false;
|
|
@@ -13508,20 +15081,20 @@ async function cleanupSocketPathIfStale(socketPath) {
|
|
|
13508
15081
|
if (!staleSocket) {
|
|
13509
15082
|
return false;
|
|
13510
15083
|
}
|
|
13511
|
-
await (0,
|
|
15084
|
+
await (0, import_promises16.rm)(socketPath, { force: true });
|
|
13512
15085
|
return true;
|
|
13513
15086
|
}
|
|
13514
15087
|
function getPidFilePath(options = {}) {
|
|
13515
|
-
return (0,
|
|
15088
|
+
return (0, import_node_path19.join)(getAISnitchHomePath(options), "aisnitch.pid");
|
|
13516
15089
|
}
|
|
13517
15090
|
function getDaemonStatePath(options = {}) {
|
|
13518
|
-
return (0,
|
|
15091
|
+
return (0, import_node_path19.join)(getAISnitchHomePath(options), "daemon-state.json");
|
|
13519
15092
|
}
|
|
13520
15093
|
function getDaemonLogPath(options = {}) {
|
|
13521
|
-
return (0,
|
|
15094
|
+
return (0, import_node_path19.join)(getAISnitchHomePath(options), "daemon.log");
|
|
13522
15095
|
}
|
|
13523
15096
|
function getLaunchAgentPath(options = {}) {
|
|
13524
|
-
return (0,
|
|
15097
|
+
return (0, import_node_path19.join)(
|
|
13525
15098
|
options.launchAgentHomeDirectory ?? (0, import_node_os4.homedir)(),
|
|
13526
15099
|
"Library",
|
|
13527
15100
|
"LaunchAgents",
|
|
@@ -13531,13 +15104,13 @@ function getLaunchAgentPath(options = {}) {
|
|
|
13531
15104
|
async function writePid(pid, options = {}) {
|
|
13532
15105
|
await ensureConfigDir(options);
|
|
13533
15106
|
const pidFilePath = getPidFilePath(options);
|
|
13534
|
-
await (0,
|
|
15107
|
+
await (0, import_promises16.writeFile)(pidFilePath, `${pid}
|
|
13535
15108
|
`, "utf8");
|
|
13536
15109
|
return pidFilePath;
|
|
13537
15110
|
}
|
|
13538
15111
|
async function readPid(options = {}) {
|
|
13539
15112
|
try {
|
|
13540
|
-
const rawPid = await (0,
|
|
15113
|
+
const rawPid = await (0, import_promises16.readFile)(getPidFilePath(options), "utf8");
|
|
13541
15114
|
const parsedPid = Number.parseInt(rawPid.trim(), 10);
|
|
13542
15115
|
if (!Number.isInteger(parsedPid) || parsedPid <= 0) {
|
|
13543
15116
|
throw new Error("Invalid PID file contents.");
|
|
@@ -13551,13 +15124,13 @@ async function readPid(options = {}) {
|
|
|
13551
15124
|
}
|
|
13552
15125
|
}
|
|
13553
15126
|
async function removePid(options = {}) {
|
|
13554
|
-
await (0,
|
|
15127
|
+
await (0, import_promises16.rm)(getPidFilePath(options), { force: true });
|
|
13555
15128
|
}
|
|
13556
15129
|
async function writeDaemonState(state, options = {}) {
|
|
13557
15130
|
await ensureConfigDir(options);
|
|
13558
15131
|
const daemonStatePath = getDaemonStatePath(options);
|
|
13559
15132
|
const validatedState = DaemonStateSchema.parse(state);
|
|
13560
|
-
await (0,
|
|
15133
|
+
await (0, import_promises16.writeFile)(
|
|
13561
15134
|
daemonStatePath,
|
|
13562
15135
|
`${JSON.stringify(validatedState, null, 2)}
|
|
13563
15136
|
`,
|
|
@@ -13567,7 +15140,7 @@ async function writeDaemonState(state, options = {}) {
|
|
|
13567
15140
|
}
|
|
13568
15141
|
async function readDaemonState(options = {}) {
|
|
13569
15142
|
try {
|
|
13570
|
-
const rawJson = await (0,
|
|
15143
|
+
const rawJson = await (0, import_promises16.readFile)(getDaemonStatePath(options), "utf8");
|
|
13571
15144
|
const parsedJson = JSON.parse(rawJson);
|
|
13572
15145
|
return DaemonStateSchema.parse(parsedJson);
|
|
13573
15146
|
} catch (error) {
|
|
@@ -13578,7 +15151,7 @@ async function readDaemonState(options = {}) {
|
|
|
13578
15151
|
}
|
|
13579
15152
|
}
|
|
13580
15153
|
async function removeDaemonState(options = {}) {
|
|
13581
|
-
await (0,
|
|
15154
|
+
await (0, import_promises16.rm)(getDaemonStatePath(options), { force: true });
|
|
13582
15155
|
}
|
|
13583
15156
|
function isProcessRunning(pid) {
|
|
13584
15157
|
try {
|
|
@@ -13614,13 +15187,13 @@ async function cleanupStaleDaemonFiles(options = {}) {
|
|
|
13614
15187
|
}
|
|
13615
15188
|
async function ensureLaunchAgentDir(options = {}) {
|
|
13616
15189
|
const launchAgentPath = getLaunchAgentPath(options);
|
|
13617
|
-
const directoryPath = (0,
|
|
13618
|
-
await (0,
|
|
15190
|
+
const directoryPath = (0, import_node_path19.dirname)(launchAgentPath);
|
|
15191
|
+
await (0, import_promises16.mkdir)(directoryPath, { recursive: true });
|
|
13619
15192
|
return directoryPath;
|
|
13620
15193
|
}
|
|
13621
15194
|
async function getDaemonLogSize(options = {}) {
|
|
13622
15195
|
try {
|
|
13623
|
-
const logStats = await (0,
|
|
15196
|
+
const logStats = await (0, import_promises16.stat)(getDaemonLogPath(options));
|
|
13624
15197
|
return logStats.size;
|
|
13625
15198
|
} catch (error) {
|
|
13626
15199
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -13634,16 +15207,16 @@ function getEffectiveCliConfigPath(options = {}) {
|
|
|
13634
15207
|
}
|
|
13635
15208
|
|
|
13636
15209
|
// src/cli/auto-update.ts
|
|
13637
|
-
var
|
|
13638
|
-
var import_promises16 = require("fs/promises");
|
|
15210
|
+
var import_node_child_process15 = require("child_process");
|
|
13639
15211
|
var import_promises17 = require("fs/promises");
|
|
13640
|
-
var
|
|
15212
|
+
var import_promises18 = require("fs/promises");
|
|
15213
|
+
var import_node_path20 = require("path");
|
|
13641
15214
|
var AUTO_UPDATE_STATE_FILE = "auto-update.json";
|
|
13642
15215
|
var AUTO_UPDATE_LOG_FILE = "auto-update.log";
|
|
13643
15216
|
function createAutoUpdateController(dependencies = {}) {
|
|
13644
15217
|
const fetchImplementation = dependencies.fetch ?? globalThis.fetch;
|
|
13645
15218
|
const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
|
|
13646
|
-
const spawnImplementation = dependencies.spawn ??
|
|
15219
|
+
const spawnImplementation = dependencies.spawn ?? import_node_child_process15.spawn;
|
|
13647
15220
|
return {
|
|
13648
15221
|
runDetachedUpdate: async (options) => {
|
|
13649
15222
|
const pathOptions = toPathOptions(options);
|
|
@@ -13651,8 +15224,8 @@ function createAutoUpdateController(dependencies = {}) {
|
|
|
13651
15224
|
const command = resolveUpdateCommand(options.manager);
|
|
13652
15225
|
const args = resolveUpdateArgs(options.manager);
|
|
13653
15226
|
const aisnitchHomePath = getAISnitchHomePath(pathOptions);
|
|
13654
|
-
await (0,
|
|
13655
|
-
const logFilePath = (0,
|
|
15227
|
+
await (0, import_promises17.mkdir)(aisnitchHomePath, { recursive: true });
|
|
15228
|
+
const logFilePath = (0, import_node_path20.join)(aisnitchHomePath, AUTO_UPDATE_LOG_FILE);
|
|
13656
15229
|
const startedAt = now().toISOString();
|
|
13657
15230
|
await writeAutoUpdateState(
|
|
13658
15231
|
{
|
|
@@ -13685,7 +15258,7 @@ function createAutoUpdateController(dependencies = {}) {
|
|
|
13685
15258
|
});
|
|
13686
15259
|
combinedLog += `[${now().toISOString()}] finished with code ${exitCode}
|
|
13687
15260
|
`;
|
|
13688
|
-
await (0,
|
|
15261
|
+
await (0, import_promises17.writeFile)(logFilePath, combinedLog, "utf8");
|
|
13689
15262
|
await writeAutoUpdateState(
|
|
13690
15263
|
{
|
|
13691
15264
|
attemptedVersion: options.latestVersion,
|
|
@@ -13776,7 +15349,7 @@ async function detectInstallManager(options) {
|
|
|
13776
15349
|
}
|
|
13777
15350
|
let resolvedCliPath = options.cliEntryPath;
|
|
13778
15351
|
try {
|
|
13779
|
-
resolvedCliPath = await (0,
|
|
15352
|
+
resolvedCliPath = await (0, import_promises18.realpath)(options.cliEntryPath);
|
|
13780
15353
|
} catch {
|
|
13781
15354
|
}
|
|
13782
15355
|
if (resolvedCliPath.includes("/Cellar/aisnitch/")) {
|
|
@@ -13840,7 +15413,7 @@ function resolveUpdateArgs(manager) {
|
|
|
13840
15413
|
async function readAutoUpdateState(options) {
|
|
13841
15414
|
const statePath = getAutoUpdateStatePath(options);
|
|
13842
15415
|
try {
|
|
13843
|
-
const rawJson = await (0,
|
|
15416
|
+
const rawJson = await (0, import_promises17.readFile)(statePath, "utf8");
|
|
13844
15417
|
return JSON.parse(rawJson);
|
|
13845
15418
|
} catch (error) {
|
|
13846
15419
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -13851,8 +15424,8 @@ async function readAutoUpdateState(options) {
|
|
|
13851
15424
|
}
|
|
13852
15425
|
async function writeAutoUpdateState(state, options) {
|
|
13853
15426
|
const aisnitchHomePath = getAISnitchHomePath(options);
|
|
13854
|
-
await (0,
|
|
13855
|
-
await (0,
|
|
15427
|
+
await (0, import_promises17.mkdir)(aisnitchHomePath, { recursive: true });
|
|
15428
|
+
await (0, import_promises17.writeFile)(
|
|
13856
15429
|
getAutoUpdateStatePath(options),
|
|
13857
15430
|
`${JSON.stringify(state, null, 2)}
|
|
13858
15431
|
`,
|
|
@@ -13860,7 +15433,7 @@ async function writeAutoUpdateState(state, options) {
|
|
|
13860
15433
|
);
|
|
13861
15434
|
}
|
|
13862
15435
|
function getAutoUpdateStatePath(options) {
|
|
13863
|
-
return (0,
|
|
15436
|
+
return (0, import_node_path20.join)(getAISnitchHomePath(options), AUTO_UPDATE_STATE_FILE);
|
|
13864
15437
|
}
|
|
13865
15438
|
function toPathOptions(options) {
|
|
13866
15439
|
return {
|
|
@@ -13974,9 +15547,9 @@ function flattenValue(lines, currentPath, value) {
|
|
|
13974
15547
|
}
|
|
13975
15548
|
lines.push(formatLoggerField(currentPath, value, inferValueKind(value)));
|
|
13976
15549
|
}
|
|
13977
|
-
function formatLoggerField(
|
|
15550
|
+
function formatLoggerField(path2, value, kind) {
|
|
13978
15551
|
const renderedValue = typeof value === "string" ? JSON.stringify(value) : value === null ? "null" : typeof value === "undefined" ? "undefined" : JSON.stringify(value);
|
|
13979
|
-
return `${colorize(
|
|
15552
|
+
return `${colorize(path2, TUI_THEME.warning)} ${colorize("=", TUI_THEME.muted)} ${colorize(
|
|
13980
15553
|
renderedValue,
|
|
13981
15554
|
getValueColor(kind)
|
|
13982
15555
|
)}`;
|
|
@@ -14051,7 +15624,8 @@ function isRecord13(value) {
|
|
|
14051
15624
|
}
|
|
14052
15625
|
|
|
14053
15626
|
// src/cli/runtime.ts
|
|
14054
|
-
var
|
|
15627
|
+
var openPromise = Promise.resolve().then(() => (init_open(), open_exports));
|
|
15628
|
+
var execFile21 = (0, import_node_util21.promisify)(import_node_child_process23.execFile);
|
|
14055
15629
|
var DAEMON_READY_TIMEOUT_MS = 4e3;
|
|
14056
15630
|
var DAEMON_READY_POLL_INTERVAL_MS = 100;
|
|
14057
15631
|
var DAEMON_STOP_TIMEOUT_MS = 4e3;
|
|
@@ -14061,13 +15635,13 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14061
15635
|
const output = dependencies.output ?? createProcessOutput();
|
|
14062
15636
|
const fetchImplementation = dependencies.fetch ?? globalThis.fetch;
|
|
14063
15637
|
const renderManagedTuiImplementation = dependencies.renderManagedTui ?? renderManagedTui;
|
|
14064
|
-
const spawnImplementation = dependencies.spawn ??
|
|
15638
|
+
const spawnImplementation = dependencies.spawn ?? import_node_child_process23.spawn;
|
|
14065
15639
|
const autoUpdateController = createAutoUpdateController({
|
|
14066
15640
|
fetch: fetchImplementation,
|
|
14067
15641
|
spawn: spawnImplementation
|
|
14068
15642
|
});
|
|
14069
15643
|
const execFileImplementation = dependencies.execFile ?? (async (file, args) => {
|
|
14070
|
-
return await
|
|
15644
|
+
return await execFile21(file, [...args], {
|
|
14071
15645
|
encoding: "utf8"
|
|
14072
15646
|
});
|
|
14073
15647
|
});
|
|
@@ -14120,8 +15694,8 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14120
15694
|
await ensureConfigDir(daemonPathOptions);
|
|
14121
15695
|
await rotateDaemonLogIfNeeded(daemonPathOptions);
|
|
14122
15696
|
const daemonLogPath = getDaemonLogPath(daemonPathOptions);
|
|
14123
|
-
const stdoutFd = (0,
|
|
14124
|
-
const stderrFd = (0,
|
|
15697
|
+
const stdoutFd = (0, import_node_fs7.openSync)(daemonLogPath, "w");
|
|
15698
|
+
const stderrFd = (0, import_node_fs7.openSync)(daemonLogPath, "a");
|
|
14125
15699
|
const cliEntryPath = resolveCliEntryPath();
|
|
14126
15700
|
const daemonArgs = [cliEntryPath, "daemon-run", ...toDaemonArgv(options)];
|
|
14127
15701
|
const child = spawnImplementation(process.execPath, daemonArgs, {
|
|
@@ -14133,8 +15707,8 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14133
15707
|
stdio: ["ignore", stdoutFd, stderrFd]
|
|
14134
15708
|
});
|
|
14135
15709
|
child.unref();
|
|
14136
|
-
(0,
|
|
14137
|
-
(0,
|
|
15710
|
+
(0, import_node_fs7.closeSync)(stdoutFd);
|
|
15711
|
+
(0, import_node_fs7.closeSync)(stderrFd);
|
|
14138
15712
|
if (child.pid === void 0) {
|
|
14139
15713
|
throw new Error("Failed to obtain the AISnitch daemon PID.");
|
|
14140
15714
|
}
|
|
@@ -14206,8 +15780,8 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14206
15780
|
if (logSize < DAEMON_LOG_MAX_BYTES) {
|
|
14207
15781
|
return;
|
|
14208
15782
|
}
|
|
14209
|
-
await (0,
|
|
14210
|
-
await (0,
|
|
15783
|
+
await (0, import_promises22.rm)(backupPath, { force: true });
|
|
15784
|
+
await (0, import_promises22.rename)(logFilePath, backupPath);
|
|
14211
15785
|
}
|
|
14212
15786
|
async function waitForDaemonReady(pathOptions) {
|
|
14213
15787
|
const deadline = Date.now() + DAEMON_READY_TIMEOUT_MS;
|
|
@@ -14242,7 +15816,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14242
15816
|
}
|
|
14243
15817
|
async function readDaemonStartupFailure(pathOptions) {
|
|
14244
15818
|
try {
|
|
14245
|
-
const daemonLog = await (0,
|
|
15819
|
+
const daemonLog = await (0, import_promises22.readFile)(getDaemonLogPath(pathOptions), "utf8");
|
|
14246
15820
|
const logLines = daemonLog.split(/\r?\n/u).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
14247
15821
|
const lastLine = logLines.at(-1);
|
|
14248
15822
|
if (!lastLine) {
|
|
@@ -14340,22 +15914,35 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14340
15914
|
return;
|
|
14341
15915
|
}
|
|
14342
15916
|
shuttingDown = true;
|
|
14343
|
-
|
|
14344
|
-
|
|
14345
|
-
|
|
14346
|
-
|
|
14347
|
-
|
|
15917
|
+
const shutdownTimeouts = {
|
|
15918
|
+
adapterRegistry: DEFAULT_TIMEOUTS.adapterShutdown,
|
|
15919
|
+
httpReceiver: DEFAULT_TIMEOUTS.httpRequest,
|
|
15920
|
+
udsServer: DEFAULT_TIMEOUTS.fileOperation,
|
|
15921
|
+
wsServer: DEFAULT_TIMEOUTS.wsConnection,
|
|
15922
|
+
cleanupFns: 1e3
|
|
15923
|
+
};
|
|
15924
|
+
const components = {
|
|
15925
|
+
adapterRegistry: pipeline.getAdapterRegistry(),
|
|
15926
|
+
httpReceiver: pipeline.getHttpReceiver(),
|
|
15927
|
+
udsServer: pipeline.getUdsServer(),
|
|
15928
|
+
wsServer: pipeline.getWsServer(),
|
|
15929
|
+
eventBus: pipeline.getEventBus(),
|
|
15930
|
+
cleanupFns: daemonMode ? [async () => {
|
|
14348
15931
|
await Promise.all([
|
|
14349
|
-
removePid(
|
|
14350
|
-
removeDaemonState(
|
|
15932
|
+
removePid(toPathOptions2(options)),
|
|
15933
|
+
removeDaemonState(toPathOptions2(options))
|
|
14351
15934
|
]);
|
|
14352
|
-
}
|
|
14353
|
-
}
|
|
14354
|
-
|
|
14355
|
-
|
|
15935
|
+
}] : []
|
|
15936
|
+
};
|
|
15937
|
+
try {
|
|
15938
|
+
await shutdownInOrder(components, shutdownTimeouts, "pipeline");
|
|
15939
|
+
} finally {
|
|
15940
|
+
if (!daemonMode) {
|
|
15941
|
+
output.stdout(`AISnitch stopped after ${signal}.
|
|
14356
15942
|
`);
|
|
15943
|
+
}
|
|
15944
|
+
process.exit(exitCode);
|
|
14357
15945
|
}
|
|
14358
|
-
process.exit(exitCode);
|
|
14359
15946
|
};
|
|
14360
15947
|
if (daemonMode) {
|
|
14361
15948
|
process.once("SIGTERM", () => {
|
|
@@ -14541,6 +16128,113 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14541
16128
|
}
|
|
14542
16129
|
});
|
|
14543
16130
|
}
|
|
16131
|
+
async function fullscreen(options) {
|
|
16132
|
+
const snapshot = await getStatusSnapshot(options);
|
|
16133
|
+
if (!snapshot.running && options.daemonMode) {
|
|
16134
|
+
output.stdout("Starting daemon...\n");
|
|
16135
|
+
await startDetachedDaemon(options);
|
|
16136
|
+
}
|
|
16137
|
+
if (!snapshot.running && !options.daemonMode) {
|
|
16138
|
+
throw new Error(
|
|
16139
|
+
"AISnitch daemon is not running. Start one with `aisnitch start --daemon` or use `aisnitch fs --daemon` to start and open the dashboard."
|
|
16140
|
+
);
|
|
16141
|
+
}
|
|
16142
|
+
for (let i = 0; i < 20; i++) {
|
|
16143
|
+
const health = await fetchHealth(snapshot.httpPort);
|
|
16144
|
+
if (health) break;
|
|
16145
|
+
await new Promise((resolve2) => setTimeout(resolve2, 200).unref());
|
|
16146
|
+
}
|
|
16147
|
+
const dashboardPort = options.dashboardPort ?? 5174;
|
|
16148
|
+
const dashboardUrl = `http://127.0.0.1:${dashboardPort}`;
|
|
16149
|
+
const distPath = (0, import_node_path22.join)(process.cwd(), "examples", "fullscreen-dashboard", "dist");
|
|
16150
|
+
output.stdout(`Starting dashboard server on port ${dashboardPort}...
|
|
16151
|
+
`);
|
|
16152
|
+
const viteProcess = spawnImplementation(process.execPath, [
|
|
16153
|
+
"-e",
|
|
16154
|
+
`
|
|
16155
|
+
import { createServer } from 'vite';
|
|
16156
|
+
import path from 'path';
|
|
16157
|
+
|
|
16158
|
+
const distPath = '${distPath}';
|
|
16159
|
+
const port = ${dashboardPort};
|
|
16160
|
+
|
|
16161
|
+
const server = await createServer({
|
|
16162
|
+
root: distPath,
|
|
16163
|
+
server: {
|
|
16164
|
+
port,
|
|
16165
|
+
strictPort: true,
|
|
16166
|
+
allowedHosts: true,
|
|
16167
|
+
},
|
|
16168
|
+
preview: {
|
|
16169
|
+
port,
|
|
16170
|
+
strictPort: true,
|
|
16171
|
+
},
|
|
16172
|
+
});
|
|
16173
|
+
|
|
16174
|
+
await server.listen();
|
|
16175
|
+
console.log('READY');
|
|
16176
|
+
|
|
16177
|
+
process.stdin.resume();
|
|
16178
|
+
`
|
|
16179
|
+
], {
|
|
16180
|
+
cwd: distPath,
|
|
16181
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
16182
|
+
});
|
|
16183
|
+
let serverOutput = "";
|
|
16184
|
+
viteProcess.stdout?.on("data", (data) => {
|
|
16185
|
+
serverOutput += data.toString();
|
|
16186
|
+
});
|
|
16187
|
+
viteProcess.stderr?.on("data", (data) => {
|
|
16188
|
+
serverOutput += data.toString();
|
|
16189
|
+
});
|
|
16190
|
+
let serverReady = false;
|
|
16191
|
+
for (let i = 0; i < 100; i++) {
|
|
16192
|
+
await new Promise((resolve2) => setTimeout(resolve2, 100).unref());
|
|
16193
|
+
try {
|
|
16194
|
+
const response = await fetchImplementation(dashboardUrl);
|
|
16195
|
+
if (response.ok) {
|
|
16196
|
+
serverReady = true;
|
|
16197
|
+
break;
|
|
16198
|
+
}
|
|
16199
|
+
} catch {
|
|
16200
|
+
}
|
|
16201
|
+
if (!viteProcess.pid) break;
|
|
16202
|
+
}
|
|
16203
|
+
if (!serverReady) {
|
|
16204
|
+
output.stdout(`Server output: ${serverOutput}
|
|
16205
|
+
`);
|
|
16206
|
+
throw new Error("Failed to start dashboard server");
|
|
16207
|
+
}
|
|
16208
|
+
output.stdout(`Dashboard ready at ${dashboardUrl}
|
|
16209
|
+
`);
|
|
16210
|
+
if (!options.noBrowser) {
|
|
16211
|
+
output.stdout("Opening browser...\n");
|
|
16212
|
+
const openModule = await openPromise;
|
|
16213
|
+
await openModule.default(dashboardUrl);
|
|
16214
|
+
}
|
|
16215
|
+
output.stdout("Press Ctrl+C to stop\n");
|
|
16216
|
+
await new Promise((resolve2) => {
|
|
16217
|
+
const shutdown = () => {
|
|
16218
|
+
process.off("SIGINT", handleSigint);
|
|
16219
|
+
process.off("SIGTERM", handleSigterm);
|
|
16220
|
+
if (viteProcess.pid !== void 0) {
|
|
16221
|
+
try {
|
|
16222
|
+
process.kill(viteProcess.pid, "SIGTERM");
|
|
16223
|
+
} catch {
|
|
16224
|
+
}
|
|
16225
|
+
}
|
|
16226
|
+
resolve2();
|
|
16227
|
+
};
|
|
16228
|
+
const handleSigint = () => {
|
|
16229
|
+
shutdown();
|
|
16230
|
+
};
|
|
16231
|
+
const handleSigterm = () => {
|
|
16232
|
+
shutdown();
|
|
16233
|
+
};
|
|
16234
|
+
process.once("SIGINT", handleSigint);
|
|
16235
|
+
process.once("SIGTERM", handleSigterm);
|
|
16236
|
+
});
|
|
16237
|
+
}
|
|
14544
16238
|
async function logger2(options) {
|
|
14545
16239
|
const snapshot = await getStatusSnapshot(options);
|
|
14546
16240
|
if (!snapshot.running) {
|
|
@@ -14612,7 +16306,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14612
16306
|
}
|
|
14613
16307
|
const { config } = await loadEffectiveConfig(options);
|
|
14614
16308
|
setLoggerLevel(getForegroundSafeLogLevel(config.logLevel, false));
|
|
14615
|
-
const ephemeralHomeDirectory = await (0,
|
|
16309
|
+
const ephemeralHomeDirectory = await (0, import_promises22.mkdtemp)((0, import_node_path22.join)((0, import_node_os6.tmpdir)(), "aisnitch-mock-"));
|
|
14616
16310
|
const ephemeralPipeline = new Pipeline();
|
|
14617
16311
|
const status2 = await ephemeralPipeline.start({
|
|
14618
16312
|
config: {
|
|
@@ -14651,7 +16345,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14651
16345
|
} finally {
|
|
14652
16346
|
await Promise.resolve(monitorClose());
|
|
14653
16347
|
await ephemeralPipeline.stop();
|
|
14654
|
-
await (0,
|
|
16348
|
+
await (0, import_promises22.rm)(ephemeralHomeDirectory, { force: true, recursive: true });
|
|
14655
16349
|
}
|
|
14656
16350
|
}
|
|
14657
16351
|
async function install(options) {
|
|
@@ -14673,7 +16367,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14673
16367
|
await execFileImplementation("launchctl", ["bootout", domainTarget, launchAgentPath]);
|
|
14674
16368
|
} catch {
|
|
14675
16369
|
}
|
|
14676
|
-
await (0,
|
|
16370
|
+
await (0, import_promises22.writeFile)(launchAgentPath, plistContents, "utf8");
|
|
14677
16371
|
await execFileImplementation("launchctl", ["bootstrap", domainTarget, launchAgentPath]);
|
|
14678
16372
|
output.stdout(`AISnitch LaunchAgent installed at ${launchAgentPath}
|
|
14679
16373
|
`);
|
|
@@ -14696,7 +16390,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14696
16390
|
} else {
|
|
14697
16391
|
const { config } = await loadEffectiveConfig(options);
|
|
14698
16392
|
setLoggerLevel(getForegroundSafeLogLevel(config.logLevel, false));
|
|
14699
|
-
ephemeralHomeDirectory = await (0,
|
|
16393
|
+
ephemeralHomeDirectory = await (0, import_promises22.mkdtemp)((0, import_node_path22.join)((0, import_node_os6.tmpdir)(), "aisnitch-wrap-"));
|
|
14700
16394
|
ephemeralPipeline = new Pipeline();
|
|
14701
16395
|
await ephemeralPipeline.start({
|
|
14702
16396
|
config: {
|
|
@@ -14751,7 +16445,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14751
16445
|
await ephemeralPipeline.stop();
|
|
14752
16446
|
}
|
|
14753
16447
|
if (ephemeralHomeDirectory !== null) {
|
|
14754
|
-
await (0,
|
|
16448
|
+
await (0, import_promises22.rm)(ephemeralHomeDirectory, { force: true, recursive: true });
|
|
14755
16449
|
}
|
|
14756
16450
|
}
|
|
14757
16451
|
process.exit(wrappedExitCode);
|
|
@@ -14771,7 +16465,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14771
16465
|
},
|
|
14772
16466
|
pid: process.ppid > 1 ? process.ppid : void 0,
|
|
14773
16467
|
source: "aisnitch://adapters/aider/notifications-command",
|
|
14774
|
-
transcriptPath: (0,
|
|
16468
|
+
transcriptPath: (0, import_node_path22.join)(process.cwd(), ".aider.chat.history.md"),
|
|
14775
16469
|
type: "agent.idle"
|
|
14776
16470
|
}),
|
|
14777
16471
|
headers: {
|
|
@@ -14793,7 +16487,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14793
16487
|
await execFileImplementation("launchctl", ["bootout", domainTarget, launchAgentPath]);
|
|
14794
16488
|
} catch {
|
|
14795
16489
|
}
|
|
14796
|
-
await (0,
|
|
16490
|
+
await (0, import_promises22.rm)(launchAgentPath, { force: true });
|
|
14797
16491
|
output.stdout(`AISnitch LaunchAgent removed from ${launchAgentPath}
|
|
14798
16492
|
`);
|
|
14799
16493
|
}
|
|
@@ -14832,6 +16526,7 @@ function createCliRuntime(dependencies = {}) {
|
|
|
14832
16526
|
adapters,
|
|
14833
16527
|
aiderNotify,
|
|
14834
16528
|
attach,
|
|
16529
|
+
fullscreen,
|
|
14835
16530
|
install,
|
|
14836
16531
|
logger: logger2,
|
|
14837
16532
|
mock,
|
|
@@ -14972,7 +16667,7 @@ function joinSocketPath(pathOptions) {
|
|
|
14972
16667
|
}
|
|
14973
16668
|
function resolveCliEntryPath() {
|
|
14974
16669
|
const cliEntryPath = process.argv[1];
|
|
14975
|
-
if (!cliEntryPath || (0,
|
|
16670
|
+
if (!cliEntryPath || (0, import_node_path22.basename)(cliEntryPath).length === 0) {
|
|
14976
16671
|
throw new Error("Unable to resolve the AISnitch CLI entry path.");
|
|
14977
16672
|
}
|
|
14978
16673
|
return cliEntryPath;
|
|
@@ -15043,6 +16738,9 @@ Examples:
|
|
|
15043
16738
|
aisnitch start --daemon
|
|
15044
16739
|
aisnitch start --view full-data
|
|
15045
16740
|
aisnitch start --mock
|
|
16741
|
+
aisnitch fs
|
|
16742
|
+
aisnitch fs --daemon
|
|
16743
|
+
aisnitch fs --dashboard-port 8080
|
|
15046
16744
|
aisnitch status
|
|
15047
16745
|
aisnitch attach
|
|
15048
16746
|
aisnitch attach --view full-data
|
|
@@ -15066,6 +16764,7 @@ Examples:
|
|
|
15066
16764
|
addAdaptersCommand(program, runtime);
|
|
15067
16765
|
addSetupCommand(program, runtime);
|
|
15068
16766
|
addAttachCommand(program, runtime);
|
|
16767
|
+
addFullscreenCommand(program, runtime);
|
|
15069
16768
|
addLoggerCommand(program, runtime);
|
|
15070
16769
|
addMockCommand(program, runtime);
|
|
15071
16770
|
addWrapCommand(program, runtime);
|
|
@@ -15198,6 +16897,23 @@ function addAttachCommand(program, runtime) {
|
|
|
15198
16897
|
await runtime.attach(options);
|
|
15199
16898
|
});
|
|
15200
16899
|
}
|
|
16900
|
+
function addFullscreenCommand(program, runtime) {
|
|
16901
|
+
addCommonOptions(
|
|
16902
|
+
program.command("fs").description("Open the fullscreen web dashboard in browser (starts daemon if needed with --daemon)").alias("fullscreen").option(
|
|
16903
|
+
"--daemon",
|
|
16904
|
+
"Start the daemon automatically if not running"
|
|
16905
|
+
).option(
|
|
16906
|
+
"--dashboard-port <port>",
|
|
16907
|
+
"Port for the dashboard server (default: 5174)",
|
|
16908
|
+
wrapOptionParser(parsePortOption)
|
|
16909
|
+
).option(
|
|
16910
|
+
"--no-browser",
|
|
16911
|
+
"Start server without opening browser"
|
|
16912
|
+
)
|
|
16913
|
+
).action(async (options) => {
|
|
16914
|
+
await runtime.fullscreen(options);
|
|
16915
|
+
});
|
|
16916
|
+
}
|
|
15201
16917
|
function addWrapCommand(program, runtime) {
|
|
15202
16918
|
addCommonOptions(
|
|
15203
16919
|
program.command("wrap").description("Run a command inside a PTY while AISnitch observes its terminal activity").allowUnknownOption(true).argument("<command>", "Command to wrap").argument("[args...]", "Arguments forwarded to the wrapped command").option("--cwd <path>", "Run the wrapped command from a specific working directory")
|