@dhf-claude/grix 0.1.8 → 0.1.9
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 +133 -86
- package/cli/prod-runner.js +163 -0
- package/cli/prod-runner.test.js +195 -0
- package/cli/runtime-targets.js +66 -0
- package/dist/daemon.js +2010 -904
- package/dist/index.js +1364 -2033
- package/hooks/hooks.json +34 -1
- package/package.json +5 -3
- package/scripts/dev-start.js +14 -0
- package/scripts/elicitation-hook.js +34 -27
- package/scripts/lifecycle-hook.js +3 -0
- package/scripts/notification-hook.js +0 -8
- package/scripts/prod-start.js +7 -0
- package/scripts/user-prompt-submit-hook.js +2 -1
- package/skills/grix/SKILL.md +121 -0
- package/skills/access/SKILL.md +0 -129
- package/skills/status/SKILL.md +0 -11
package/dist/daemon.js
CHANGED
|
@@ -1049,11 +1049,11 @@ var hasColors, format, reset, bold, dim, italic, underline, overline, inverse, h
|
|
|
1049
1049
|
var init_base = __esm({
|
|
1050
1050
|
"node_modules/yoctocolors/base.js"() {
|
|
1051
1051
|
hasColors = tty?.WriteStream?.prototype?.hasColors?.() ?? false;
|
|
1052
|
-
format = (
|
|
1052
|
+
format = (open4, close) => {
|
|
1053
1053
|
if (!hasColors) {
|
|
1054
1054
|
return (input) => input;
|
|
1055
1055
|
}
|
|
1056
|
-
const openCode = `\x1B[${
|
|
1056
|
+
const openCode = `\x1B[${open4}m`;
|
|
1057
1057
|
const closeCode = `\x1B[${close}m`;
|
|
1058
1058
|
return (input) => {
|
|
1059
1059
|
const string = input + "";
|
|
@@ -1332,7 +1332,7 @@ var require_windows = __commonJS({
|
|
|
1332
1332
|
module.exports = isexe;
|
|
1333
1333
|
isexe.sync = sync;
|
|
1334
1334
|
var fs = __require("fs");
|
|
1335
|
-
function checkPathExt(
|
|
1335
|
+
function checkPathExt(path25, options) {
|
|
1336
1336
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
1337
1337
|
if (!pathext) {
|
|
1338
1338
|
return true;
|
|
@@ -1343,25 +1343,25 @@ var require_windows = __commonJS({
|
|
|
1343
1343
|
}
|
|
1344
1344
|
for (var i2 = 0; i2 < pathext.length; i2++) {
|
|
1345
1345
|
var p = pathext[i2].toLowerCase();
|
|
1346
|
-
if (p &&
|
|
1346
|
+
if (p && path25.substr(-p.length).toLowerCase() === p) {
|
|
1347
1347
|
return true;
|
|
1348
1348
|
}
|
|
1349
1349
|
}
|
|
1350
1350
|
return false;
|
|
1351
1351
|
}
|
|
1352
|
-
function checkStat(
|
|
1353
|
-
if (!
|
|
1352
|
+
function checkStat(stat4, path25, options) {
|
|
1353
|
+
if (!stat4.isSymbolicLink() && !stat4.isFile()) {
|
|
1354
1354
|
return false;
|
|
1355
1355
|
}
|
|
1356
|
-
return checkPathExt(
|
|
1356
|
+
return checkPathExt(path25, options);
|
|
1357
1357
|
}
|
|
1358
|
-
function isexe(
|
|
1359
|
-
fs.stat(
|
|
1360
|
-
cb(er, er ? false : checkStat(
|
|
1358
|
+
function isexe(path25, options, cb) {
|
|
1359
|
+
fs.stat(path25, function(er, stat4) {
|
|
1360
|
+
cb(er, er ? false : checkStat(stat4, path25, options));
|
|
1361
1361
|
});
|
|
1362
1362
|
}
|
|
1363
|
-
function sync(
|
|
1364
|
-
return checkStat(fs.statSync(
|
|
1363
|
+
function sync(path25, options) {
|
|
1364
|
+
return checkStat(fs.statSync(path25), path25, options);
|
|
1365
1365
|
}
|
|
1366
1366
|
}
|
|
1367
1367
|
});
|
|
@@ -1372,21 +1372,21 @@ var require_mode = __commonJS({
|
|
|
1372
1372
|
module.exports = isexe;
|
|
1373
1373
|
isexe.sync = sync;
|
|
1374
1374
|
var fs = __require("fs");
|
|
1375
|
-
function isexe(
|
|
1376
|
-
fs.stat(
|
|
1377
|
-
cb(er, er ? false : checkStat(
|
|
1375
|
+
function isexe(path25, options, cb) {
|
|
1376
|
+
fs.stat(path25, function(er, stat4) {
|
|
1377
|
+
cb(er, er ? false : checkStat(stat4, options));
|
|
1378
1378
|
});
|
|
1379
1379
|
}
|
|
1380
|
-
function sync(
|
|
1381
|
-
return checkStat(fs.statSync(
|
|
1380
|
+
function sync(path25, options) {
|
|
1381
|
+
return checkStat(fs.statSync(path25), options);
|
|
1382
1382
|
}
|
|
1383
|
-
function checkStat(
|
|
1384
|
-
return
|
|
1383
|
+
function checkStat(stat4, options) {
|
|
1384
|
+
return stat4.isFile() && checkMode(stat4, options);
|
|
1385
1385
|
}
|
|
1386
|
-
function checkMode(
|
|
1387
|
-
var mod =
|
|
1388
|
-
var uid =
|
|
1389
|
-
var gid =
|
|
1386
|
+
function checkMode(stat4, options) {
|
|
1387
|
+
var mod = stat4.mode;
|
|
1388
|
+
var uid = stat4.uid;
|
|
1389
|
+
var gid = stat4.gid;
|
|
1390
1390
|
var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
|
|
1391
1391
|
var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
|
|
1392
1392
|
var u2 = parseInt("100", 8);
|
|
@@ -1411,7 +1411,7 @@ var require_isexe = __commonJS({
|
|
|
1411
1411
|
}
|
|
1412
1412
|
module.exports = isexe;
|
|
1413
1413
|
isexe.sync = sync;
|
|
1414
|
-
function isexe(
|
|
1414
|
+
function isexe(path25, options, cb) {
|
|
1415
1415
|
if (typeof options === "function") {
|
|
1416
1416
|
cb = options;
|
|
1417
1417
|
options = {};
|
|
@@ -1421,7 +1421,7 @@ var require_isexe = __commonJS({
|
|
|
1421
1421
|
throw new TypeError("callback not provided");
|
|
1422
1422
|
}
|
|
1423
1423
|
return new Promise(function(resolve, reject) {
|
|
1424
|
-
isexe(
|
|
1424
|
+
isexe(path25, options || {}, function(er, is) {
|
|
1425
1425
|
if (er) {
|
|
1426
1426
|
reject(er);
|
|
1427
1427
|
} else {
|
|
@@ -1430,7 +1430,7 @@ var require_isexe = __commonJS({
|
|
|
1430
1430
|
});
|
|
1431
1431
|
});
|
|
1432
1432
|
}
|
|
1433
|
-
core(
|
|
1433
|
+
core(path25, options || {}, function(er, is) {
|
|
1434
1434
|
if (er) {
|
|
1435
1435
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
1436
1436
|
er = null;
|
|
@@ -1440,9 +1440,9 @@ var require_isexe = __commonJS({
|
|
|
1440
1440
|
cb(er, is);
|
|
1441
1441
|
});
|
|
1442
1442
|
}
|
|
1443
|
-
function sync(
|
|
1443
|
+
function sync(path25, options) {
|
|
1444
1444
|
try {
|
|
1445
|
-
return core.sync(
|
|
1445
|
+
return core.sync(path25, options || {});
|
|
1446
1446
|
} catch (er) {
|
|
1447
1447
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
1448
1448
|
return false;
|
|
@@ -1458,7 +1458,7 @@ var require_isexe = __commonJS({
|
|
|
1458
1458
|
var require_which = __commonJS({
|
|
1459
1459
|
"node_modules/which/which.js"(exports, module) {
|
|
1460
1460
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
1461
|
-
var
|
|
1461
|
+
var path25 = __require("path");
|
|
1462
1462
|
var COLON = isWindows ? ";" : ":";
|
|
1463
1463
|
var isexe = require_isexe();
|
|
1464
1464
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -1496,7 +1496,7 @@ var require_which = __commonJS({
|
|
|
1496
1496
|
return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
1497
1497
|
const ppRaw = pathEnv[i2];
|
|
1498
1498
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
1499
|
-
const pCmd =
|
|
1499
|
+
const pCmd = path25.join(pathPart, cmd);
|
|
1500
1500
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
1501
1501
|
resolve(subStep(p, i2, 0));
|
|
1502
1502
|
});
|
|
@@ -1523,7 +1523,7 @@ var require_which = __commonJS({
|
|
|
1523
1523
|
for (let i2 = 0; i2 < pathEnv.length; i2++) {
|
|
1524
1524
|
const ppRaw = pathEnv[i2];
|
|
1525
1525
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
1526
|
-
const pCmd =
|
|
1526
|
+
const pCmd = path25.join(pathPart, cmd);
|
|
1527
1527
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
1528
1528
|
for (let j = 0; j < pathExt.length; j++) {
|
|
1529
1529
|
const cur = p + pathExt[j];
|
|
@@ -1571,7 +1571,7 @@ var require_path_key = __commonJS({
|
|
|
1571
1571
|
var require_resolveCommand = __commonJS({
|
|
1572
1572
|
"node_modules/cross-spawn/lib/util/resolveCommand.js"(exports, module) {
|
|
1573
1573
|
"use strict";
|
|
1574
|
-
var
|
|
1574
|
+
var path25 = __require("path");
|
|
1575
1575
|
var which = require_which();
|
|
1576
1576
|
var getPathKey = require_path_key();
|
|
1577
1577
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -1589,7 +1589,7 @@ var require_resolveCommand = __commonJS({
|
|
|
1589
1589
|
try {
|
|
1590
1590
|
resolved = which.sync(parsed.command, {
|
|
1591
1591
|
path: env[getPathKey({ env })],
|
|
1592
|
-
pathExt: withoutPathExt ?
|
|
1592
|
+
pathExt: withoutPathExt ? path25.delimiter : void 0
|
|
1593
1593
|
});
|
|
1594
1594
|
} catch (e) {
|
|
1595
1595
|
} finally {
|
|
@@ -1598,7 +1598,7 @@ var require_resolveCommand = __commonJS({
|
|
|
1598
1598
|
}
|
|
1599
1599
|
}
|
|
1600
1600
|
if (resolved) {
|
|
1601
|
-
resolved =
|
|
1601
|
+
resolved = path25.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
1602
1602
|
}
|
|
1603
1603
|
return resolved;
|
|
1604
1604
|
}
|
|
@@ -1652,8 +1652,8 @@ var require_shebang_command = __commonJS({
|
|
|
1652
1652
|
if (!match) {
|
|
1653
1653
|
return null;
|
|
1654
1654
|
}
|
|
1655
|
-
const [
|
|
1656
|
-
const binary =
|
|
1655
|
+
const [path25, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
1656
|
+
const binary = path25.split("/").pop();
|
|
1657
1657
|
if (binary === "env") {
|
|
1658
1658
|
return argument;
|
|
1659
1659
|
}
|
|
@@ -1688,7 +1688,7 @@ var require_readShebang = __commonJS({
|
|
|
1688
1688
|
var require_parse = __commonJS({
|
|
1689
1689
|
"node_modules/cross-spawn/lib/parse.js"(exports, module) {
|
|
1690
1690
|
"use strict";
|
|
1691
|
-
var
|
|
1691
|
+
var path25 = __require("path");
|
|
1692
1692
|
var resolveCommand = require_resolveCommand();
|
|
1693
1693
|
var escape = require_escape();
|
|
1694
1694
|
var readShebang = require_readShebang();
|
|
@@ -1713,7 +1713,7 @@ var require_parse = __commonJS({
|
|
|
1713
1713
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
1714
1714
|
if (parsed.options.forceShell || needsShell) {
|
|
1715
1715
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
1716
|
-
parsed.command =
|
|
1716
|
+
parsed.command = path25.normalize(parsed.command);
|
|
1717
1717
|
parsed.command = escape.command(parsed.command);
|
|
1718
1718
|
parsed.args = parsed.args.map((arg) => escape.argument(arg, needsDoubleEscapeMetaChars));
|
|
1719
1719
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
@@ -1809,7 +1809,7 @@ var require_cross_spawn = __commonJS({
|
|
|
1809
1809
|
enoent.hookChildProcess(spawned, parsed);
|
|
1810
1810
|
return spawned;
|
|
1811
1811
|
}
|
|
1812
|
-
function
|
|
1812
|
+
function spawnSync4(command, args, options) {
|
|
1813
1813
|
const parsed = parse(command, args, options);
|
|
1814
1814
|
const result = cp.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
1815
1815
|
result.error = result.error || enoent.verifyENOENTSync(result.status, parsed);
|
|
@@ -1817,7 +1817,7 @@ var require_cross_spawn = __commonJS({
|
|
|
1817
1817
|
}
|
|
1818
1818
|
module.exports = spawn4;
|
|
1819
1819
|
module.exports.spawn = spawn4;
|
|
1820
|
-
module.exports.sync =
|
|
1820
|
+
module.exports.sync = spawnSync4;
|
|
1821
1821
|
module.exports._parse = parse;
|
|
1822
1822
|
module.exports._enoent = enoent;
|
|
1823
1823
|
}
|
|
@@ -5843,13 +5843,13 @@ var init_output_sync = __esm({
|
|
|
5843
5843
|
}
|
|
5844
5844
|
};
|
|
5845
5845
|
writeToFiles = (serializedResult, stdioItems, outputFiles) => {
|
|
5846
|
-
for (const { path:
|
|
5847
|
-
const pathString = typeof
|
|
5846
|
+
for (const { path: path25, append } of stdioItems.filter(({ type }) => FILE_TYPES.has(type))) {
|
|
5847
|
+
const pathString = typeof path25 === "string" ? path25 : path25.toString();
|
|
5848
5848
|
if (append || outputFiles.has(pathString)) {
|
|
5849
|
-
appendFileSync(
|
|
5849
|
+
appendFileSync(path25, serializedResult);
|
|
5850
5850
|
} else {
|
|
5851
5851
|
outputFiles.add(pathString);
|
|
5852
|
-
writeFileSync(
|
|
5852
|
+
writeFileSync(path25, serializedResult);
|
|
5853
5853
|
}
|
|
5854
5854
|
}
|
|
5855
5855
|
};
|
|
@@ -6780,7 +6780,7 @@ var processOk, kExitEmitter, global2, ObjectDefineProperty, Emitter, SignalExitB
|
|
|
6780
6780
|
var init_mjs = __esm({
|
|
6781
6781
|
"node_modules/signal-exit/dist/mjs/index.js"() {
|
|
6782
6782
|
init_signals2();
|
|
6783
|
-
processOk = (
|
|
6783
|
+
processOk = (process18) => !!process18 && typeof process18 === "object" && typeof process18.removeListener === "function" && typeof process18.emit === "function" && typeof process18.reallyExit === "function" && typeof process18.listeners === "function" && typeof process18.kill === "function" && typeof process18.pid === "number" && typeof process18.on === "function";
|
|
6784
6784
|
kExitEmitter = /* @__PURE__ */ Symbol.for("signal-exit emitter");
|
|
6785
6785
|
global2 = globalThis;
|
|
6786
6786
|
ObjectDefineProperty = Object.defineProperty.bind(Object);
|
|
@@ -6873,15 +6873,15 @@ var init_mjs = __esm({
|
|
|
6873
6873
|
#originalProcessReallyExit;
|
|
6874
6874
|
#sigListeners = {};
|
|
6875
6875
|
#loaded = false;
|
|
6876
|
-
constructor(
|
|
6876
|
+
constructor(process18) {
|
|
6877
6877
|
super();
|
|
6878
|
-
this.#process =
|
|
6878
|
+
this.#process = process18;
|
|
6879
6879
|
this.#sigListeners = {};
|
|
6880
6880
|
for (const sig of signals) {
|
|
6881
6881
|
this.#sigListeners[sig] = () => {
|
|
6882
6882
|
const listeners = this.#process.listeners(sig);
|
|
6883
6883
|
let { count: count2 } = this.#emitter;
|
|
6884
|
-
const p =
|
|
6884
|
+
const p = process18;
|
|
6885
6885
|
if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
|
|
6886
6886
|
count2 += p.__signal_exit_emitter__.count;
|
|
6887
6887
|
}
|
|
@@ -6890,12 +6890,12 @@ var init_mjs = __esm({
|
|
|
6890
6890
|
const ret = this.#emitter.emit("exit", null, sig);
|
|
6891
6891
|
const s = sig === "SIGHUP" ? this.#hupSig : sig;
|
|
6892
6892
|
if (!ret)
|
|
6893
|
-
|
|
6893
|
+
process18.kill(process18.pid, s);
|
|
6894
6894
|
}
|
|
6895
6895
|
};
|
|
6896
6896
|
}
|
|
6897
|
-
this.#originalProcessReallyExit =
|
|
6898
|
-
this.#originalProcessEmit =
|
|
6897
|
+
this.#originalProcessReallyExit = process18.reallyExit;
|
|
6898
|
+
this.#originalProcessEmit = process18.emit;
|
|
6899
6899
|
}
|
|
6900
6900
|
onExit(cb, opts) {
|
|
6901
6901
|
if (!processOk(this.#process)) {
|
|
@@ -8649,7 +8649,7 @@ var require_bin = __commonJS({
|
|
|
8649
8649
|
var require_ps = __commonJS({
|
|
8650
8650
|
"node_modules/pidtree/lib/ps.js"(exports, module) {
|
|
8651
8651
|
"use strict";
|
|
8652
|
-
var
|
|
8652
|
+
var os8 = __require("os");
|
|
8653
8653
|
var bin = require_bin();
|
|
8654
8654
|
function ps(callback) {
|
|
8655
8655
|
var args = ["-A", "-o", "ppid,pid"];
|
|
@@ -8659,7 +8659,7 @@ var require_ps = __commonJS({
|
|
|
8659
8659
|
return callback(new Error("pidtree ps command exited with code " + code));
|
|
8660
8660
|
}
|
|
8661
8661
|
try {
|
|
8662
|
-
stdout = stdout.split(
|
|
8662
|
+
stdout = stdout.split(os8.EOL);
|
|
8663
8663
|
var list = [];
|
|
8664
8664
|
for (var i2 = 1; i2 < stdout.length; i2++) {
|
|
8665
8665
|
stdout[i2] = stdout[i2].trim();
|
|
@@ -8683,7 +8683,7 @@ var require_ps = __commonJS({
|
|
|
8683
8683
|
var require_wmic = __commonJS({
|
|
8684
8684
|
"node_modules/pidtree/lib/wmic.js"(exports, module) {
|
|
8685
8685
|
"use strict";
|
|
8686
|
-
var
|
|
8686
|
+
var os8 = __require("os");
|
|
8687
8687
|
var bin = require_bin();
|
|
8688
8688
|
function wmic(callback) {
|
|
8689
8689
|
var args = ["PROCESS", "get", "ParentProcessId,ProcessId"];
|
|
@@ -8698,7 +8698,7 @@ var require_wmic = __commonJS({
|
|
|
8698
8698
|
return;
|
|
8699
8699
|
}
|
|
8700
8700
|
try {
|
|
8701
|
-
stdout = stdout.split(
|
|
8701
|
+
stdout = stdout.split(os8.EOL);
|
|
8702
8702
|
var list = [];
|
|
8703
8703
|
for (var i2 = 1; i2 < stdout.length; i2++) {
|
|
8704
8704
|
stdout[i2] = stdout[i2].trim();
|
|
@@ -8722,7 +8722,7 @@ var require_wmic = __commonJS({
|
|
|
8722
8722
|
var require_get = __commonJS({
|
|
8723
8723
|
"node_modules/pidtree/lib/get.js"(exports, module) {
|
|
8724
8724
|
"use strict";
|
|
8725
|
-
var
|
|
8725
|
+
var os8 = __require("os");
|
|
8726
8726
|
var platformToMethod = {
|
|
8727
8727
|
darwin: "ps",
|
|
8728
8728
|
sunos: "ps",
|
|
@@ -8736,7 +8736,7 @@ var require_get = __commonJS({
|
|
|
8736
8736
|
ps: () => require_ps(),
|
|
8737
8737
|
wmic: () => require_wmic()
|
|
8738
8738
|
};
|
|
8739
|
-
var platform2 =
|
|
8739
|
+
var platform2 = os8.platform();
|
|
8740
8740
|
if (platform2.startsWith("win")) {
|
|
8741
8741
|
platform2 = "win";
|
|
8742
8742
|
}
|
|
@@ -8745,7 +8745,7 @@ var require_get = __commonJS({
|
|
|
8745
8745
|
if (method === void 0) {
|
|
8746
8746
|
callback(
|
|
8747
8747
|
new Error(
|
|
8748
|
-
|
|
8748
|
+
os8.platform() + " is not supported yet, please open an issue (https://github.com/simonepri/pidtree)"
|
|
8749
8749
|
)
|
|
8750
8750
|
);
|
|
8751
8751
|
}
|
|
@@ -9429,32 +9429,6 @@ function canDeliverToWorker(binding) {
|
|
|
9429
9429
|
const responseState = normalizeWorkerResponseState(binding?.worker_response_state);
|
|
9430
9430
|
return hasReadyWorkerBridge(binding) && responseState === "healthy";
|
|
9431
9431
|
}
|
|
9432
|
-
function formatWorkerResponseAssessment(binding) {
|
|
9433
|
-
const workerStatus = normalizeString10(binding?.worker_status);
|
|
9434
|
-
const responseState = normalizeWorkerResponseState(binding?.worker_response_state);
|
|
9435
|
-
if (workerStatus === "ready") {
|
|
9436
|
-
if (responseState === "healthy") {
|
|
9437
|
-
return "\u53EF\u7528\uFF08\u6700\u8FD1\u4E00\u6B21\u771F\u5B9E\u4EA4\u4E92\u5DF2\u9A8C\u8BC1\uFF09";
|
|
9438
|
-
}
|
|
9439
|
-
if (responseState === "probing") {
|
|
9440
|
-
return "\u63A2\u6D4B\u4E2D\uFF08\u6B63\u5728\u7B49\u5F85 ping/pong\uFF09";
|
|
9441
|
-
}
|
|
9442
|
-
if (responseState === "failed") {
|
|
9443
|
-
return "\u5F02\u5E38\uFF08\u6700\u8FD1\u4E00\u6B21\u771F\u5B9E\u4EA4\u4E92\u5931\u8D25\uFF09";
|
|
9444
|
-
}
|
|
9445
|
-
return "\u5F85\u9A8C\u8BC1\uFF08\u5DF2\u5C31\u7EEA\uFF0C\u4F46\u8FD8\u6CA1\u6709\u771F\u5B9E\u4EA4\u4E92\u8BC1\u660E\uFF09";
|
|
9446
|
-
}
|
|
9447
|
-
if (workerStatus === "starting" || workerStatus === "connected") {
|
|
9448
|
-
return "\u542F\u52A8\u4E2D";
|
|
9449
|
-
}
|
|
9450
|
-
if (workerStatus === "stopped") {
|
|
9451
|
-
return "\u5DF2\u505C\u6B62";
|
|
9452
|
-
}
|
|
9453
|
-
if (workerStatus === "failed") {
|
|
9454
|
-
return "\u5DF2\u5931\u8D25";
|
|
9455
|
-
}
|
|
9456
|
-
return "\u672A\u77E5";
|
|
9457
|
-
}
|
|
9458
9432
|
var init_worker_state = __esm({
|
|
9459
9433
|
"server/daemon/worker-state.js"() {
|
|
9460
9434
|
}
|
|
@@ -10380,7 +10354,9 @@ var init_worker_bridge_server = __esm({
|
|
|
10380
10354
|
onSendEventResult = null,
|
|
10381
10355
|
onSendEventStopAck = null,
|
|
10382
10356
|
onSendEventStopResult = null,
|
|
10383
|
-
onSetSessionComposing = null
|
|
10357
|
+
onSetSessionComposing = null,
|
|
10358
|
+
onAgentInvoke = null,
|
|
10359
|
+
onLocalActionResult = null
|
|
10384
10360
|
} = {}) {
|
|
10385
10361
|
this.host = host;
|
|
10386
10362
|
this.port = port;
|
|
@@ -10396,6 +10372,8 @@ var init_worker_bridge_server = __esm({
|
|
|
10396
10372
|
this.onSendEventStopAck = typeof onSendEventStopAck === "function" ? onSendEventStopAck : null;
|
|
10397
10373
|
this.onSendEventStopResult = typeof onSendEventStopResult === "function" ? onSendEventStopResult : null;
|
|
10398
10374
|
this.onSetSessionComposing = typeof onSetSessionComposing === "function" ? onSetSessionComposing : null;
|
|
10375
|
+
this.onAgentInvoke = typeof onAgentInvoke === "function" ? onAgentInvoke : null;
|
|
10376
|
+
this.onLocalActionResult = typeof onLocalActionResult === "function" ? onLocalActionResult : null;
|
|
10399
10377
|
this.server = null;
|
|
10400
10378
|
this.address = null;
|
|
10401
10379
|
}
|
|
@@ -10438,6 +10416,8 @@ var init_worker_bridge_server = __esm({
|
|
|
10438
10416
|
const server = this.server;
|
|
10439
10417
|
this.server = null;
|
|
10440
10418
|
this.address = null;
|
|
10419
|
+
server.closeIdleConnections?.();
|
|
10420
|
+
server.closeAllConnections?.();
|
|
10441
10421
|
await new Promise((resolve, reject) => {
|
|
10442
10422
|
server.close((error) => {
|
|
10443
10423
|
if (error) {
|
|
@@ -10576,6 +10556,30 @@ var init_worker_bridge_server = __esm({
|
|
|
10576
10556
|
ok(response, result ?? { ok: true });
|
|
10577
10557
|
return;
|
|
10578
10558
|
}
|
|
10559
|
+
if (pathname === "/v1/worker/agent-invoke") {
|
|
10560
|
+
this.trace({
|
|
10561
|
+
stage: "worker_agent_invoke_received",
|
|
10562
|
+
worker_id: payload?.worker_id,
|
|
10563
|
+
aibot_session_id: payload?.aibot_session_id,
|
|
10564
|
+
invoke_id: payload?.invoke_id,
|
|
10565
|
+
action: payload?.action
|
|
10566
|
+
});
|
|
10567
|
+
const result = this.onAgentInvoke ? await this.onAgentInvoke(payload) : { code: 4004, msg: "agent invoke handler is not configured" };
|
|
10568
|
+
ok(response, result ?? { code: 4004, msg: "agent invoke handler is not configured" });
|
|
10569
|
+
return;
|
|
10570
|
+
}
|
|
10571
|
+
if (pathname === "/v1/worker/local-action-result") {
|
|
10572
|
+
this.trace({
|
|
10573
|
+
stage: "worker_local_action_result_received",
|
|
10574
|
+
worker_id: payload?.worker_id,
|
|
10575
|
+
aibot_session_id: payload?.aibot_session_id,
|
|
10576
|
+
action_id: payload?.action_id,
|
|
10577
|
+
status: payload?.status
|
|
10578
|
+
});
|
|
10579
|
+
const result = this.onLocalActionResult ? await this.onLocalActionResult(payload) : { ok: true };
|
|
10580
|
+
ok(response, result ?? { ok: true });
|
|
10581
|
+
return;
|
|
10582
|
+
}
|
|
10579
10583
|
notFound(response);
|
|
10580
10584
|
}
|
|
10581
10585
|
};
|
|
@@ -10788,7 +10792,7 @@ var init_paths = __esm({
|
|
|
10788
10792
|
});
|
|
10789
10793
|
|
|
10790
10794
|
// server/hook-signal-store.js
|
|
10791
|
-
import { appendFile, mkdir as mkdir9 } from "node:fs/promises";
|
|
10795
|
+
import { appendFile, mkdir as mkdir9, open as open2, rm as rm5, stat } from "node:fs/promises";
|
|
10792
10796
|
import path19 from "node:path";
|
|
10793
10797
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
10794
10798
|
function normalizeString17(value) {
|
|
@@ -10805,12 +10809,21 @@ function pickHookEventDetail(input = {}, hookEventName) {
|
|
|
10805
10809
|
if (hookEventName === "SessionStart") {
|
|
10806
10810
|
return normalizeString17(input.source);
|
|
10807
10811
|
}
|
|
10812
|
+
if (hookEventName === "PermissionRequest") {
|
|
10813
|
+
return normalizeString17(input.tool_name);
|
|
10814
|
+
}
|
|
10808
10815
|
if (hookEventName === "PostToolUse" || hookEventName === "PostToolUseFailure") {
|
|
10809
10816
|
return normalizeString17(input.tool_name);
|
|
10810
10817
|
}
|
|
10818
|
+
if (hookEventName === "PermissionDenied") {
|
|
10819
|
+
return normalizeString17(input.tool_name) || normalizeString17(input.reason);
|
|
10820
|
+
}
|
|
10811
10821
|
if (hookEventName === "Elicitation") {
|
|
10812
10822
|
return normalizeString17(input.mode);
|
|
10813
10823
|
}
|
|
10824
|
+
if (hookEventName === "ElicitationResult") {
|
|
10825
|
+
return normalizeString17(input.action) || normalizeString17(input.mode);
|
|
10826
|
+
}
|
|
10814
10827
|
if (hookEventName === "Notification") {
|
|
10815
10828
|
return normalizeString17(input.matcher) || normalizeString17(input.notification_type) || normalizeString17(input.type);
|
|
10816
10829
|
}
|
|
@@ -10829,11 +10842,7 @@ function normalizeHookSignalEvent(input) {
|
|
|
10829
10842
|
event_id: eventID,
|
|
10830
10843
|
hook_event_name: hookEventName,
|
|
10831
10844
|
event_at: normalizeOptionalTimestamp3(input.event_at),
|
|
10832
|
-
detail: normalizeString17(input.detail)
|
|
10833
|
-
tool_name: normalizeString17(input.tool_name),
|
|
10834
|
-
session_id: normalizeString17(input.session_id),
|
|
10835
|
-
cwd: normalizeString17(input.cwd),
|
|
10836
|
-
transcript_path: normalizeString17(input.transcript_path)
|
|
10845
|
+
detail: normalizeString17(input.detail)
|
|
10837
10846
|
};
|
|
10838
10847
|
}
|
|
10839
10848
|
function normalizeState4(input) {
|
|
@@ -10856,6 +10865,26 @@ function normalizeState4(input) {
|
|
|
10856
10865
|
function resolveHookSignalsPath(pluginID) {
|
|
10857
10866
|
return path19.join(resolvePluginDataDir(pluginID), "hook-signals.json");
|
|
10858
10867
|
}
|
|
10868
|
+
function resolveHookSignalsLockPathFromDataDir(pluginDataDir, pluginID) {
|
|
10869
|
+
const normalizedDir = normalizeString17(pluginDataDir);
|
|
10870
|
+
if (normalizedDir) {
|
|
10871
|
+
return path19.join(normalizedDir, "hook-signals.lock");
|
|
10872
|
+
}
|
|
10873
|
+
return path19.join(resolvePluginDataDir(pluginID), "hook-signals.lock");
|
|
10874
|
+
}
|
|
10875
|
+
function sleep(delayMs) {
|
|
10876
|
+
return new Promise((resolve) => {
|
|
10877
|
+
setTimeout(resolve, delayMs);
|
|
10878
|
+
});
|
|
10879
|
+
}
|
|
10880
|
+
async function readLockAgeMs(filePath) {
|
|
10881
|
+
try {
|
|
10882
|
+
const details = await stat(filePath);
|
|
10883
|
+
return Date.now() - Number(details.mtimeMs ?? 0);
|
|
10884
|
+
} catch {
|
|
10885
|
+
return 0;
|
|
10886
|
+
}
|
|
10887
|
+
}
|
|
10859
10888
|
function buildHookSignalEvent(input, { recordedAt = Date.now() } = {}) {
|
|
10860
10889
|
const hookEventName = normalizeString17(input?.hook_event_name);
|
|
10861
10890
|
if (!hookEventName) {
|
|
@@ -10865,24 +10894,10 @@ function buildHookSignalEvent(input, { recordedAt = Date.now() } = {}) {
|
|
|
10865
10894
|
event_id: randomUUID3(),
|
|
10866
10895
|
hook_event_name: hookEventName,
|
|
10867
10896
|
event_at: normalizeOptionalTimestamp3(recordedAt) || Date.now(),
|
|
10868
|
-
detail: pickHookEventDetail(input, hookEventName)
|
|
10869
|
-
tool_name: normalizeString17(input?.tool_name),
|
|
10870
|
-
session_id: normalizeString17(input?.session_id),
|
|
10871
|
-
cwd: normalizeString17(input?.cwd),
|
|
10872
|
-
transcript_path: normalizeString17(input?.transcript_path)
|
|
10897
|
+
detail: pickHookEventDetail(input, hookEventName)
|
|
10873
10898
|
};
|
|
10874
10899
|
}
|
|
10875
|
-
|
|
10876
|
-
const normalized = normalizeHookSignalEvent(event);
|
|
10877
|
-
if (!normalized) {
|
|
10878
|
-
return "";
|
|
10879
|
-
}
|
|
10880
|
-
if (normalized.detail) {
|
|
10881
|
-
return `${normalized.hook_event_name}:${normalized.detail}`;
|
|
10882
|
-
}
|
|
10883
|
-
return normalized.hook_event_name;
|
|
10884
|
-
}
|
|
10885
|
-
var schemaVersion4, defaultRecentEventLimit, HookSignalStore;
|
|
10900
|
+
var schemaVersion4, defaultRecentEventLimit, defaultLockTimeoutMs, defaultLockPollMs, defaultLockStaleMs, HookSignalStore;
|
|
10886
10901
|
var init_hook_signal_store = __esm({
|
|
10887
10902
|
"server/hook-signal-store.js"() {
|
|
10888
10903
|
init_json_file();
|
|
@@ -10890,10 +10905,17 @@ var init_hook_signal_store = __esm({
|
|
|
10890
10905
|
init_paths();
|
|
10891
10906
|
schemaVersion4 = 1;
|
|
10892
10907
|
defaultRecentEventLimit = 20;
|
|
10908
|
+
defaultLockTimeoutMs = 5e3;
|
|
10909
|
+
defaultLockPollMs = 25;
|
|
10910
|
+
defaultLockStaleMs = 3e4;
|
|
10893
10911
|
HookSignalStore = class {
|
|
10894
|
-
constructor(filePath = resolveHookSignalsPath(), {
|
|
10912
|
+
constructor(filePath = resolveHookSignalsPath(), {
|
|
10913
|
+
logPath = path19.join(path19.dirname(filePath), "hook-signals.log"),
|
|
10914
|
+
lockPath = resolveHookSignalsLockPathFromDataDir(path19.dirname(filePath))
|
|
10915
|
+
} = {}) {
|
|
10895
10916
|
this.filePath = filePath;
|
|
10896
10917
|
this.logPath = logPath;
|
|
10918
|
+
this.lockPath = lockPath;
|
|
10897
10919
|
}
|
|
10898
10920
|
async readState() {
|
|
10899
10921
|
const stored = await readJSONFile(this.filePath, null);
|
|
@@ -10903,9 +10925,54 @@ var init_hook_signal_store = __esm({
|
|
|
10903
10925
|
await mkdir9(path19.dirname(this.filePath), { recursive: true });
|
|
10904
10926
|
await writeJSONFileAtomic(this.filePath, normalizeState4(state));
|
|
10905
10927
|
}
|
|
10928
|
+
async withStateLock(callback, {
|
|
10929
|
+
timeoutMs = defaultLockTimeoutMs,
|
|
10930
|
+
pollMs = defaultLockPollMs,
|
|
10931
|
+
staleMs = defaultLockStaleMs
|
|
10932
|
+
} = {}) {
|
|
10933
|
+
await mkdir9(path19.dirname(this.lockPath), { recursive: true });
|
|
10934
|
+
const deadlineAt = Date.now() + Math.max(1, Number(timeoutMs) || defaultLockTimeoutMs);
|
|
10935
|
+
while (Date.now() < deadlineAt) {
|
|
10936
|
+
let handle = null;
|
|
10937
|
+
try {
|
|
10938
|
+
handle = await open2(this.lockPath, "wx", 384);
|
|
10939
|
+
await handle.writeFile(JSON.stringify({
|
|
10940
|
+
schema_version: schemaVersion4,
|
|
10941
|
+
pid: process.pid,
|
|
10942
|
+
acquired_at: Date.now()
|
|
10943
|
+
}), "utf8");
|
|
10944
|
+
try {
|
|
10945
|
+
return await callback();
|
|
10946
|
+
} finally {
|
|
10947
|
+
await handle.close().catch(() => {
|
|
10948
|
+
});
|
|
10949
|
+
await rm5(this.lockPath, { force: true }).catch(() => {
|
|
10950
|
+
});
|
|
10951
|
+
}
|
|
10952
|
+
} catch (error) {
|
|
10953
|
+
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") {
|
|
10954
|
+
if (handle) {
|
|
10955
|
+
await handle.close().catch(() => {
|
|
10956
|
+
});
|
|
10957
|
+
}
|
|
10958
|
+
throw error;
|
|
10959
|
+
}
|
|
10960
|
+
const lockAgeMs = await readLockAgeMs(this.lockPath);
|
|
10961
|
+
if (lockAgeMs > staleMs) {
|
|
10962
|
+
await rm5(this.lockPath, { force: true }).catch(() => {
|
|
10963
|
+
});
|
|
10964
|
+
continue;
|
|
10965
|
+
}
|
|
10966
|
+
await sleep(Math.min(pollMs, Math.max(1, deadlineAt - Date.now())));
|
|
10967
|
+
}
|
|
10968
|
+
}
|
|
10969
|
+
throw new Error("hook signal store lock timeout");
|
|
10970
|
+
}
|
|
10906
10971
|
async reset() {
|
|
10907
|
-
|
|
10908
|
-
|
|
10972
|
+
return this.withStateLock(async () => {
|
|
10973
|
+
await this.writeState(normalizeState4(null));
|
|
10974
|
+
return this.readState();
|
|
10975
|
+
});
|
|
10909
10976
|
}
|
|
10910
10977
|
async appendEventLog(event) {
|
|
10911
10978
|
const normalized = normalizeHookSignalEvent(event);
|
|
@@ -10918,11 +10985,7 @@ var init_hook_signal_store = __esm({
|
|
|
10918
10985
|
event_id: normalized.event_id,
|
|
10919
10986
|
hook_event_name: normalized.hook_event_name,
|
|
10920
10987
|
hook_detail: normalized.detail,
|
|
10921
|
-
event_at: normalized.event_at
|
|
10922
|
-
tool_name: normalized.tool_name,
|
|
10923
|
-
session_id: normalized.session_id,
|
|
10924
|
-
cwd: normalized.cwd,
|
|
10925
|
-
transcript_path: normalized.transcript_path
|
|
10988
|
+
event_at: normalized.event_at
|
|
10926
10989
|
})}
|
|
10927
10990
|
`, "utf8");
|
|
10928
10991
|
return true;
|
|
@@ -10935,29 +10998,100 @@ var init_hook_signal_store = __esm({
|
|
|
10935
10998
|
if (!nextEvent) {
|
|
10936
10999
|
return this.readState();
|
|
10937
11000
|
}
|
|
10938
|
-
|
|
10939
|
-
|
|
10940
|
-
|
|
10941
|
-
updated_at: nextEvent.event_at,
|
|
10942
|
-
latest_event: nextEvent,
|
|
10943
|
-
recent_events: [
|
|
11001
|
+
return this.withStateLock(async () => {
|
|
11002
|
+
const current = await this.readState();
|
|
11003
|
+
const recentEvents = [
|
|
10944
11004
|
...current.recent_events,
|
|
10945
11005
|
nextEvent
|
|
10946
|
-
].slice(-Math.max(1, Number(recentEventLimit) || defaultRecentEventLimit))
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
|
|
10950
|
-
|
|
11006
|
+
].sort((left, right) => left.event_at - right.event_at).slice(-Math.max(1, Number(recentEventLimit) || defaultRecentEventLimit));
|
|
11007
|
+
const latestEvent = !current.latest_event || nextEvent.event_at >= current.updated_at ? nextEvent : current.latest_event;
|
|
11008
|
+
const nextState = {
|
|
11009
|
+
schema_version: schemaVersion4,
|
|
11010
|
+
updated_at: Math.max(current.updated_at, nextEvent.event_at),
|
|
11011
|
+
latest_event: latestEvent,
|
|
11012
|
+
recent_events: recentEvents
|
|
11013
|
+
};
|
|
11014
|
+
await this.writeState(nextState);
|
|
11015
|
+
await this.appendEventLog(nextEvent);
|
|
11016
|
+
return normalizeState4(nextState);
|
|
11017
|
+
});
|
|
10951
11018
|
}
|
|
10952
11019
|
};
|
|
10953
11020
|
}
|
|
10954
11021
|
});
|
|
10955
11022
|
|
|
10956
|
-
// server/
|
|
10957
|
-
import {
|
|
10958
|
-
import {
|
|
11023
|
+
// server/claude-command.js
|
|
11024
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
11025
|
+
import { accessSync, constants as fsConstants } from "node:fs";
|
|
11026
|
+
import os7 from "node:os";
|
|
10959
11027
|
import path20 from "node:path";
|
|
10960
11028
|
import process13 from "node:process";
|
|
11029
|
+
function normalizeString18(value) {
|
|
11030
|
+
return String(value ?? "").trim();
|
|
11031
|
+
}
|
|
11032
|
+
function defaultClaudeCommandName(platform2 = process13.platform) {
|
|
11033
|
+
return platform2 === "win32" ? "claude.cmd" : "claude";
|
|
11034
|
+
}
|
|
11035
|
+
function buildClaudeCommandCandidates(env = process13.env) {
|
|
11036
|
+
const candidates = [];
|
|
11037
|
+
const explicit = normalizeString18(env.CLAUDE_BIN);
|
|
11038
|
+
if (explicit) {
|
|
11039
|
+
candidates.push(explicit);
|
|
11040
|
+
}
|
|
11041
|
+
const commandName = defaultClaudeCommandName();
|
|
11042
|
+
candidates.push(commandName);
|
|
11043
|
+
if (process13.platform !== "win32") {
|
|
11044
|
+
const homeDir = normalizeString18(env.HOME || env.USERPROFILE) || os7.homedir();
|
|
11045
|
+
if (homeDir) {
|
|
11046
|
+
candidates.push(path20.join(homeDir, ".local", "bin", "claude"));
|
|
11047
|
+
}
|
|
11048
|
+
candidates.push("/opt/homebrew/bin/claude");
|
|
11049
|
+
candidates.push("/usr/local/bin/claude");
|
|
11050
|
+
}
|
|
11051
|
+
return Array.from(new Set(candidates.filter((value) => normalizeString18(value))));
|
|
11052
|
+
}
|
|
11053
|
+
function claudeCommandExists(command, env = process13.env) {
|
|
11054
|
+
const normalized = normalizeString18(command);
|
|
11055
|
+
if (!normalized) {
|
|
11056
|
+
return false;
|
|
11057
|
+
}
|
|
11058
|
+
if (path20.isAbsolute(normalized) || normalized.includes(path20.sep)) {
|
|
11059
|
+
try {
|
|
11060
|
+
accessSync(normalized, fsConstants.X_OK);
|
|
11061
|
+
return true;
|
|
11062
|
+
} catch {
|
|
11063
|
+
return false;
|
|
11064
|
+
}
|
|
11065
|
+
}
|
|
11066
|
+
const locator = process13.platform === "win32" ? "where" : "which";
|
|
11067
|
+
const located = spawnSync3(locator, [normalized], {
|
|
11068
|
+
stdio: "ignore",
|
|
11069
|
+
env
|
|
11070
|
+
});
|
|
11071
|
+
return located.status === 0;
|
|
11072
|
+
}
|
|
11073
|
+
function resolveClaudeCommand(env = process13.env) {
|
|
11074
|
+
const explicit = normalizeString18(env.CLAUDE_BIN);
|
|
11075
|
+
if (explicit) {
|
|
11076
|
+
return explicit;
|
|
11077
|
+
}
|
|
11078
|
+
for (const candidate of buildClaudeCommandCandidates(env)) {
|
|
11079
|
+
if (claudeCommandExists(candidate, env)) {
|
|
11080
|
+
return candidate;
|
|
11081
|
+
}
|
|
11082
|
+
}
|
|
11083
|
+
return defaultClaudeCommandName();
|
|
11084
|
+
}
|
|
11085
|
+
var init_claude_command = __esm({
|
|
11086
|
+
"server/claude-command.js"() {
|
|
11087
|
+
}
|
|
11088
|
+
});
|
|
11089
|
+
|
|
11090
|
+
// server/daemon/worker-process.js
|
|
11091
|
+
import { chmod as chmod2, mkdir as mkdir10, open as open3, readdir, readFile as readFile4, stat as stat2, writeFile as writeFile3 } from "node:fs/promises";
|
|
11092
|
+
import { execSync, spawn as spawn3 } from "node:child_process";
|
|
11093
|
+
import path21 from "node:path";
|
|
11094
|
+
import process14 from "node:process";
|
|
10961
11095
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
10962
11096
|
function stripTerminalControlSequences(content) {
|
|
10963
11097
|
return String(content ?? "").replace(/\u001B\][^\u0007]*(?:\u0007|\u001B\\)/gu, " ").replace(/\u001B\[[0-?]*[ -/]*[@-~]/gu, " ").replace(/\r/g, "\n");
|
|
@@ -10969,7 +11103,7 @@ function patternMatches(pattern, content) {
|
|
|
10969
11103
|
pattern.lastIndex = 0;
|
|
10970
11104
|
return pattern.test(content);
|
|
10971
11105
|
}
|
|
10972
|
-
function
|
|
11106
|
+
function normalizeString19(value) {
|
|
10973
11107
|
return String(value ?? "").trim();
|
|
10974
11108
|
}
|
|
10975
11109
|
function normalizeNonNegativeOffset(value) {
|
|
@@ -10990,13 +11124,13 @@ async function readLogSlice(filePath, {
|
|
|
10990
11124
|
startOffset = 0,
|
|
10991
11125
|
maxBytes = 0
|
|
10992
11126
|
} = {}) {
|
|
10993
|
-
const normalizedPath =
|
|
11127
|
+
const normalizedPath = normalizeString19(filePath);
|
|
10994
11128
|
if (!normalizedPath) {
|
|
10995
11129
|
return "";
|
|
10996
11130
|
}
|
|
10997
11131
|
let fileSize = 0;
|
|
10998
11132
|
try {
|
|
10999
|
-
const info = await
|
|
11133
|
+
const info = await stat2(normalizedPath);
|
|
11000
11134
|
fileSize = normalizeNonNegativeOffset(info?.size);
|
|
11001
11135
|
} catch {
|
|
11002
11136
|
return "";
|
|
@@ -11013,7 +11147,7 @@ async function readLogSlice(filePath, {
|
|
|
11013
11147
|
if (bytesToRead <= 0) {
|
|
11014
11148
|
return "";
|
|
11015
11149
|
}
|
|
11016
|
-
const handle = await
|
|
11150
|
+
const handle = await open3(normalizedPath, "r");
|
|
11017
11151
|
try {
|
|
11018
11152
|
const buffer = Buffer.alloc(bytesToRead);
|
|
11019
11153
|
const { bytesRead = 0 } = await handle.read(buffer, 0, bytesToRead, start);
|
|
@@ -11023,12 +11157,6 @@ async function readLogSlice(filePath, {
|
|
|
11023
11157
|
});
|
|
11024
11158
|
}
|
|
11025
11159
|
}
|
|
11026
|
-
function resolveClaudeCommand(env = process13.env) {
|
|
11027
|
-
if (process13.platform === "win32") {
|
|
11028
|
-
return env.CLAUDE_BIN || "claude.cmd";
|
|
11029
|
-
}
|
|
11030
|
-
return env.CLAUDE_BIN || "claude";
|
|
11031
|
-
}
|
|
11032
11160
|
function shellEscape(value) {
|
|
11033
11161
|
return `'${String(value ?? "").replace(/'/g, `'\\''`)}'`;
|
|
11034
11162
|
}
|
|
@@ -11063,24 +11191,24 @@ function buildVisibleTerminalCleanupLines() {
|
|
|
11063
11191
|
];
|
|
11064
11192
|
}
|
|
11065
11193
|
function buildShellEnvArgs(env) {
|
|
11066
|
-
return Object.entries(env).filter(([key, value]) =>
|
|
11194
|
+
return Object.entries(env).filter(([key, value]) => normalizeString19(key) && !String(key).includes("=") && value !== void 0).map(([key, value]) => shellEscape(`${String(key)}=${String(value ?? "")}`));
|
|
11067
11195
|
}
|
|
11068
|
-
function shouldShowClaudeWindow(env =
|
|
11196
|
+
function shouldShowClaudeWindow(env = process14.env) {
|
|
11069
11197
|
return env.GRIX_CLAUDE_SHOW_CLAUDE_WINDOW === "1";
|
|
11070
11198
|
}
|
|
11071
11199
|
function buildWorkerSessionName(aibotSessionID) {
|
|
11072
|
-
const normalized =
|
|
11200
|
+
const normalized = normalizeString19(aibotSessionID).replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
11073
11201
|
return normalized ? `grix-${normalized}` : "grix-worker";
|
|
11074
11202
|
}
|
|
11075
11203
|
function resolveWorkerLogPaths({ logsDir, workerID }) {
|
|
11076
|
-
const normalizedWorkerID =
|
|
11204
|
+
const normalizedWorkerID = normalizeString19(workerID) || randomUUID4();
|
|
11077
11205
|
return {
|
|
11078
|
-
stdoutLogPath:
|
|
11079
|
-
stderrLogPath:
|
|
11206
|
+
stdoutLogPath: path21.join(logsDir, `${normalizedWorkerID}.out.log`),
|
|
11207
|
+
stderrLogPath: path21.join(logsDir, `${normalizedWorkerID}.err.log`)
|
|
11080
11208
|
};
|
|
11081
11209
|
}
|
|
11082
11210
|
function buildWorkerEnvironment({
|
|
11083
|
-
baseEnv =
|
|
11211
|
+
baseEnv = process14.env,
|
|
11084
11212
|
pluginDataDir,
|
|
11085
11213
|
aibotSessionID,
|
|
11086
11214
|
claudeSessionID,
|
|
@@ -11091,18 +11219,18 @@ function buildWorkerEnvironment({
|
|
|
11091
11219
|
}) {
|
|
11092
11220
|
const env = {
|
|
11093
11221
|
...baseEnv,
|
|
11094
|
-
CLAUDE_PLUGIN_DATA:
|
|
11095
|
-
GRIX_CLAUDE_AIBOT_SESSION_ID:
|
|
11096
|
-
GRIX_CLAUDE_SESSION_ID:
|
|
11222
|
+
CLAUDE_PLUGIN_DATA: normalizeString19(pluginDataDir),
|
|
11223
|
+
GRIX_CLAUDE_AIBOT_SESSION_ID: normalizeString19(aibotSessionID),
|
|
11224
|
+
GRIX_CLAUDE_SESSION_ID: normalizeString19(claudeSessionID),
|
|
11097
11225
|
GRIX_CLAUDE_DAEMON_MODE: "1",
|
|
11098
|
-
GRIX_CLAUDE_WORKER_ID:
|
|
11099
|
-
GRIX_CLAUDE_DAEMON_BRIDGE_URL:
|
|
11100
|
-
GRIX_CLAUDE_DAEMON_BRIDGE_TOKEN:
|
|
11226
|
+
GRIX_CLAUDE_WORKER_ID: normalizeString19(workerID),
|
|
11227
|
+
GRIX_CLAUDE_DAEMON_BRIDGE_URL: normalizeString19(bridgeURL),
|
|
11228
|
+
GRIX_CLAUDE_DAEMON_BRIDGE_TOKEN: normalizeString19(bridgeToken)
|
|
11101
11229
|
};
|
|
11102
11230
|
if (connectionConfig) {
|
|
11103
|
-
env.GRIX_CLAUDE_WS_URL =
|
|
11104
|
-
env.GRIX_CLAUDE_AGENT_ID =
|
|
11105
|
-
env.GRIX_CLAUDE_API_KEY =
|
|
11231
|
+
env.GRIX_CLAUDE_WS_URL = normalizeString19(connectionConfig.wsURL);
|
|
11232
|
+
env.GRIX_CLAUDE_AGENT_ID = normalizeString19(connectionConfig.agentID);
|
|
11233
|
+
env.GRIX_CLAUDE_API_KEY = normalizeString19(connectionConfig.apiKey);
|
|
11106
11234
|
if (Number.isFinite(Number(connectionConfig.outboundTextChunkLimit))) {
|
|
11107
11235
|
env.GRIX_CLAUDE_OUTBOUND_TEXT_CHUNK_LIMIT = String(
|
|
11108
11236
|
Math.floor(Number(connectionConfig.outboundTextChunkLimit))
|
|
@@ -11117,8 +11245,8 @@ function buildWorkerClaudeArgs({
|
|
|
11117
11245
|
claudeSessionID,
|
|
11118
11246
|
resumeSession = false
|
|
11119
11247
|
}) {
|
|
11120
|
-
const normalizedPackageRoot =
|
|
11121
|
-
const normalizedClaudeSessionID =
|
|
11248
|
+
const normalizedPackageRoot = normalizeString19(packageRoot);
|
|
11249
|
+
const normalizedClaudeSessionID = normalizeString19(claudeSessionID);
|
|
11122
11250
|
if (!normalizedPackageRoot) {
|
|
11123
11251
|
throw new Error("packageRoot is required");
|
|
11124
11252
|
}
|
|
@@ -11153,10 +11281,10 @@ async function createVisibleClaudeLaunchScript({
|
|
|
11153
11281
|
captureOutputInExpectLog = true
|
|
11154
11282
|
}) {
|
|
11155
11283
|
await mkdir10(logsDir, { recursive: true });
|
|
11156
|
-
const normalizedWorkerID =
|
|
11157
|
-
const scriptPath =
|
|
11158
|
-
const expectPath =
|
|
11159
|
-
const pidPath =
|
|
11284
|
+
const normalizedWorkerID = normalizeString19(workerID) || randomUUID4();
|
|
11285
|
+
const scriptPath = path21.join(logsDir, `${normalizedWorkerID}.launch.command`);
|
|
11286
|
+
const expectPath = path21.join(logsDir, `${normalizedWorkerID}.launch.expect`);
|
|
11287
|
+
const pidPath = path21.join(logsDir, `${normalizedWorkerID}.pid`);
|
|
11160
11288
|
const { stdoutLogPath } = resolveWorkerLogPaths({
|
|
11161
11289
|
logsDir,
|
|
11162
11290
|
workerID: normalizedWorkerID
|
|
@@ -11256,7 +11384,7 @@ async function launchClaudeInVisibleTerminal({
|
|
|
11256
11384
|
env,
|
|
11257
11385
|
spawnImpl
|
|
11258
11386
|
}) {
|
|
11259
|
-
if (
|
|
11387
|
+
if (process14.platform !== "darwin") {
|
|
11260
11388
|
throw new Error("show-claude currently only supports macOS Terminal");
|
|
11261
11389
|
}
|
|
11262
11390
|
const { scriptPath, pidPath } = await createVisibleClaudeLaunchScript({
|
|
@@ -11350,17 +11478,17 @@ async function launchClaudeInHiddenPty({
|
|
|
11350
11478
|
};
|
|
11351
11479
|
}
|
|
11352
11480
|
function resolveWorkerPIDPath(logsDir, workerID) {
|
|
11353
|
-
const normalizedWorkerID =
|
|
11354
|
-
return
|
|
11481
|
+
const normalizedWorkerID = normalizeString19(workerID) || randomUUID4();
|
|
11482
|
+
return path21.join(logsDir, `${normalizedWorkerID}.pid`);
|
|
11355
11483
|
}
|
|
11356
11484
|
async function listManagedPIDFiles(logsDir) {
|
|
11357
|
-
const normalizedLogsDir =
|
|
11485
|
+
const normalizedLogsDir = normalizeString19(logsDir);
|
|
11358
11486
|
if (!normalizedLogsDir) {
|
|
11359
11487
|
return [];
|
|
11360
11488
|
}
|
|
11361
11489
|
try {
|
|
11362
11490
|
const entries = await readdir(normalizedLogsDir, { withFileTypes: true });
|
|
11363
|
-
return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".pid")).map((entry) =>
|
|
11491
|
+
return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".pid")).map((entry) => path21.join(normalizedLogsDir, entry.name));
|
|
11364
11492
|
} catch {
|
|
11365
11493
|
return [];
|
|
11366
11494
|
}
|
|
@@ -11383,6 +11511,7 @@ var init_worker_process = __esm({
|
|
|
11383
11511
|
init_mcp();
|
|
11384
11512
|
init_daemon_paths();
|
|
11385
11513
|
init_hook_signal_store();
|
|
11514
|
+
init_claude_command();
|
|
11386
11515
|
init_process_control();
|
|
11387
11516
|
missingResumeSessionPattern = /No conversation found with session ID:/u;
|
|
11388
11517
|
authLoginRequiredPatterns = [
|
|
@@ -11410,7 +11539,7 @@ var init_worker_process = __esm({
|
|
|
11410
11539
|
startupMcpServerFailedMarkerPattern = /\[grix\]\s+startup_mcp_server_failed/u;
|
|
11411
11540
|
WorkerProcessManager = class {
|
|
11412
11541
|
constructor({
|
|
11413
|
-
env =
|
|
11542
|
+
env = process14.env,
|
|
11414
11543
|
packageRoot = resolvePackageRoot(),
|
|
11415
11544
|
connectionConfig = null,
|
|
11416
11545
|
spawnImpl = spawn3,
|
|
@@ -11430,14 +11559,14 @@ var init_worker_process = __esm({
|
|
|
11430
11559
|
this.spawnQueues = /* @__PURE__ */ new Map();
|
|
11431
11560
|
}
|
|
11432
11561
|
getWorkerRuntime(workerID) {
|
|
11433
|
-
const runtime = this.runtimes.get(
|
|
11562
|
+
const runtime = this.runtimes.get(normalizeString19(workerID));
|
|
11434
11563
|
return runtime ? { ...runtime } : null;
|
|
11435
11564
|
}
|
|
11436
11565
|
markWorkerRuntimeStopped(workerID, {
|
|
11437
11566
|
exitCode = 0,
|
|
11438
11567
|
exitSignal = ""
|
|
11439
11568
|
} = {}) {
|
|
11440
|
-
const normalizedWorkerID =
|
|
11569
|
+
const normalizedWorkerID = normalizeString19(workerID);
|
|
11441
11570
|
if (!normalizedWorkerID) {
|
|
11442
11571
|
return null;
|
|
11443
11572
|
}
|
|
@@ -11449,7 +11578,7 @@ var init_worker_process = __esm({
|
|
|
11449
11578
|
...current,
|
|
11450
11579
|
status: "stopped",
|
|
11451
11580
|
exit_code: Number(exitCode ?? 0),
|
|
11452
|
-
exit_signal:
|
|
11581
|
+
exit_signal: normalizeString19(exitSignal),
|
|
11453
11582
|
stopped_at: Date.now()
|
|
11454
11583
|
};
|
|
11455
11584
|
this.runtimes.set(normalizedWorkerID, next);
|
|
@@ -11460,7 +11589,7 @@ var init_worker_process = __esm({
|
|
|
11460
11589
|
const serverEntryPath = resolveServerEntryPath(this.packageRoot);
|
|
11461
11590
|
await this.ensureUserMcpServer({
|
|
11462
11591
|
claudeCommand,
|
|
11463
|
-
serverCommand:
|
|
11592
|
+
serverCommand: process14.execPath,
|
|
11464
11593
|
serverArgs: [serverEntryPath],
|
|
11465
11594
|
env
|
|
11466
11595
|
});
|
|
@@ -11471,7 +11600,7 @@ var init_worker_process = __esm({
|
|
|
11471
11600
|
}
|
|
11472
11601
|
async cleanupStaleManagedProcesses(aibotSessionIDs = []) {
|
|
11473
11602
|
const normalizedSessionIDs = Array.from(new Set(
|
|
11474
|
-
(Array.isArray(aibotSessionIDs) ? aibotSessionIDs : []).map((value) =>
|
|
11603
|
+
(Array.isArray(aibotSessionIDs) ? aibotSessionIDs : []).map((value) => normalizeString19(value)).filter((value) => value)
|
|
11475
11604
|
));
|
|
11476
11605
|
if (normalizedSessionIDs.length === 0) {
|
|
11477
11606
|
return [];
|
|
@@ -11496,7 +11625,7 @@ var init_worker_process = __esm({
|
|
|
11496
11625
|
if (!entry?.pid) {
|
|
11497
11626
|
continue;
|
|
11498
11627
|
}
|
|
11499
|
-
await this.terminateProcessTree(entry.pid, { platform:
|
|
11628
|
+
await this.terminateProcessTree(entry.pid, { platform: process14.platform });
|
|
11500
11629
|
terminatedPIDs.push(entry.pid);
|
|
11501
11630
|
if (entry.pidPath) {
|
|
11502
11631
|
await writeFile3(entry.pidPath, "", "utf8").catch(() => {
|
|
@@ -11511,7 +11640,7 @@ var init_worker_process = __esm({
|
|
|
11511
11640
|
);
|
|
11512
11641
|
const orphanPIDs = output.trim().split("\n").map(Number).filter((n2) => n2 > 0);
|
|
11513
11642
|
for (const pid of orphanPIDs) {
|
|
11514
|
-
await this.terminateProcessTree(pid, { platform:
|
|
11643
|
+
await this.terminateProcessTree(pid, { platform: process14.platform });
|
|
11515
11644
|
terminatedPIDs.push(pid);
|
|
11516
11645
|
}
|
|
11517
11646
|
} catch {
|
|
@@ -11520,7 +11649,7 @@ var init_worker_process = __esm({
|
|
|
11520
11649
|
return terminatedPIDs;
|
|
11521
11650
|
}
|
|
11522
11651
|
enqueueSpawnForSession(aibotSessionID, task) {
|
|
11523
|
-
const normalizedSessionID =
|
|
11652
|
+
const normalizedSessionID = normalizeString19(aibotSessionID);
|
|
11524
11653
|
if (!normalizedSessionID || typeof task !== "function") {
|
|
11525
11654
|
return Promise.resolve().then(task);
|
|
11526
11655
|
}
|
|
@@ -11546,18 +11675,18 @@ var init_worker_process = __esm({
|
|
|
11546
11675
|
bridgeToken = "",
|
|
11547
11676
|
resumeSession = false
|
|
11548
11677
|
}) {
|
|
11549
|
-
const normalizedWorkerID =
|
|
11550
|
-
const normalizedSessionID =
|
|
11551
|
-
const normalizedCwd =
|
|
11552
|
-
const normalizedPluginDataDir =
|
|
11553
|
-
const normalizedClaudeSessionID =
|
|
11678
|
+
const normalizedWorkerID = normalizeString19(workerID) || randomUUID4();
|
|
11679
|
+
const normalizedSessionID = normalizeString19(aibotSessionID);
|
|
11680
|
+
const normalizedCwd = normalizeString19(cwd);
|
|
11681
|
+
const normalizedPluginDataDir = normalizeString19(pluginDataDir);
|
|
11682
|
+
const normalizedClaudeSessionID = normalizeString19(claudeSessionID) || randomUUID4();
|
|
11554
11683
|
if (!normalizedSessionID || !normalizedCwd || !normalizedPluginDataDir) {
|
|
11555
11684
|
throw new Error("aibotSessionID, cwd, and pluginDataDir are required");
|
|
11556
11685
|
}
|
|
11557
11686
|
return this.enqueueSpawnForSession(normalizedSessionID, async () => {
|
|
11558
11687
|
const logsDir = resolveWorkerLogsDir(normalizedSessionID, this.env);
|
|
11559
11688
|
await mkdir10(logsDir, { recursive: true });
|
|
11560
|
-
await new HookSignalStore(
|
|
11689
|
+
await new HookSignalStore(path21.join(normalizedPluginDataDir, "hook-signals.json")).reset();
|
|
11561
11690
|
const workerEnv = buildWorkerEnvironment({
|
|
11562
11691
|
baseEnv: this.env,
|
|
11563
11692
|
pluginDataDir: normalizedPluginDataDir,
|
|
@@ -11584,8 +11713,8 @@ var init_worker_process = __esm({
|
|
|
11584
11713
|
logsDir,
|
|
11585
11714
|
workerID: normalizedWorkerID
|
|
11586
11715
|
});
|
|
11587
|
-
const stdoutHandle = await
|
|
11588
|
-
const stderrHandle = await
|
|
11716
|
+
const stdoutHandle = await open3(stdoutLogPath, "w");
|
|
11717
|
+
const stderrHandle = await open3(stderrLogPath, "w");
|
|
11589
11718
|
let deferFDClose = false;
|
|
11590
11719
|
try {
|
|
11591
11720
|
await this.cleanupStaleManagedProcesses([normalizedSessionID]);
|
|
@@ -11604,8 +11733,8 @@ var init_worker_process = __esm({
|
|
|
11604
11733
|
spawnImpl: this.spawnImpl
|
|
11605
11734
|
});
|
|
11606
11735
|
pid = Number(visibleTerminal.pid ?? 0);
|
|
11607
|
-
pidPath =
|
|
11608
|
-
} else if (
|
|
11736
|
+
pidPath = normalizeString19(visibleTerminal.pidPath);
|
|
11737
|
+
} else if (process14.platform === "darwin") {
|
|
11609
11738
|
const hiddenPty = await launchClaudeInHiddenPty({
|
|
11610
11739
|
logsDir,
|
|
11611
11740
|
workerID: normalizedWorkerID,
|
|
@@ -11618,7 +11747,7 @@ var init_worker_process = __esm({
|
|
|
11618
11747
|
stderrFD: stderrHandle.fd
|
|
11619
11748
|
});
|
|
11620
11749
|
pid = hiddenPty.pid;
|
|
11621
|
-
pidPath =
|
|
11750
|
+
pidPath = normalizeString19(hiddenPty.pidPath);
|
|
11622
11751
|
if (hiddenPty.child) {
|
|
11623
11752
|
child = hiddenPty.child;
|
|
11624
11753
|
const exitWorkerID = normalizedWorkerID;
|
|
@@ -11674,7 +11803,7 @@ var init_worker_process = __esm({
|
|
|
11674
11803
|
if (!Number.isFinite(pid) || pid <= 0) {
|
|
11675
11804
|
throw new Error("failed to determine spawned Claude pid");
|
|
11676
11805
|
}
|
|
11677
|
-
const isHiddenPty = !visibleTerminal &&
|
|
11806
|
+
const isHiddenPty = !visibleTerminal && process14.platform === "darwin";
|
|
11678
11807
|
deferFDClose = isHiddenPty;
|
|
11679
11808
|
const runtime = {
|
|
11680
11809
|
worker_id: normalizedWorkerID,
|
|
@@ -11710,7 +11839,7 @@ var init_worker_process = __esm({
|
|
|
11710
11839
|
});
|
|
11711
11840
|
}
|
|
11712
11841
|
async stopWorker(workerID) {
|
|
11713
|
-
const normalizedWorkerID =
|
|
11842
|
+
const normalizedWorkerID = normalizeString19(workerID);
|
|
11714
11843
|
const runtime = this.runtimes.get(normalizedWorkerID);
|
|
11715
11844
|
if (!runtime) {
|
|
11716
11845
|
return false;
|
|
@@ -11719,7 +11848,7 @@ var init_worker_process = __esm({
|
|
|
11719
11848
|
let exitSignal = "SIGTERM";
|
|
11720
11849
|
if (pid > 0) {
|
|
11721
11850
|
const terminated = await this.terminateProcessTree(pid, {
|
|
11722
|
-
platform:
|
|
11851
|
+
platform: process14.platform,
|
|
11723
11852
|
signal: exitSignal
|
|
11724
11853
|
});
|
|
11725
11854
|
if (!terminated) {
|
|
@@ -11731,7 +11860,7 @@ var init_worker_process = __esm({
|
|
|
11731
11860
|
if (!exited) {
|
|
11732
11861
|
exitSignal = "SIGKILL";
|
|
11733
11862
|
await this.terminateProcessTree(pid, {
|
|
11734
|
-
platform:
|
|
11863
|
+
platform: process14.platform,
|
|
11735
11864
|
signal: exitSignal
|
|
11736
11865
|
});
|
|
11737
11866
|
const forceExited = await this.waitForProcessExit(pid, {
|
|
@@ -11762,7 +11891,7 @@ var init_worker_process = __esm({
|
|
|
11762
11891
|
logCursor = null,
|
|
11763
11892
|
maxBytes = 0
|
|
11764
11893
|
} = {}) {
|
|
11765
|
-
const runtime = this.runtimes.get(
|
|
11894
|
+
const runtime = this.runtimes.get(normalizeString19(workerID));
|
|
11766
11895
|
if (!runtime) {
|
|
11767
11896
|
return false;
|
|
11768
11897
|
}
|
|
@@ -11782,7 +11911,7 @@ var init_worker_process = __esm({
|
|
|
11782
11911
|
}
|
|
11783
11912
|
];
|
|
11784
11913
|
for (const target of logTargets) {
|
|
11785
|
-
const normalizedFilePath =
|
|
11914
|
+
const normalizedFilePath = normalizeString19(target.filePath);
|
|
11786
11915
|
if (!normalizedFilePath) {
|
|
11787
11916
|
continue;
|
|
11788
11917
|
}
|
|
@@ -11819,19 +11948,19 @@ var init_worker_process = __esm({
|
|
|
11819
11948
|
});
|
|
11820
11949
|
}
|
|
11821
11950
|
async captureLogCursor(workerID) {
|
|
11822
|
-
const runtime = this.runtimes.get(
|
|
11951
|
+
const runtime = this.runtimes.get(normalizeString19(workerID));
|
|
11823
11952
|
if (!runtime) {
|
|
11824
11953
|
return null;
|
|
11825
11954
|
}
|
|
11826
11955
|
let stdoutOffset = 0;
|
|
11827
11956
|
let stderrOffset = 0;
|
|
11828
11957
|
try {
|
|
11829
|
-
stdoutOffset = normalizeNonNegativeOffset((await
|
|
11958
|
+
stdoutOffset = normalizeNonNegativeOffset((await stat2(runtime.stdout_log_path)).size);
|
|
11830
11959
|
} catch {
|
|
11831
11960
|
stdoutOffset = 0;
|
|
11832
11961
|
}
|
|
11833
11962
|
try {
|
|
11834
|
-
stderrOffset = normalizeNonNegativeOffset((await
|
|
11963
|
+
stderrOffset = normalizeNonNegativeOffset((await stat2(runtime.stderr_log_path)).size);
|
|
11835
11964
|
} catch {
|
|
11836
11965
|
stderrOffset = 0;
|
|
11837
11966
|
}
|
|
@@ -15052,7 +15181,7 @@ var require_stream = __commonJS({
|
|
|
15052
15181
|
};
|
|
15053
15182
|
duplex2._final = function(callback) {
|
|
15054
15183
|
if (ws.readyState === ws.CONNECTING) {
|
|
15055
|
-
ws.once("open", function
|
|
15184
|
+
ws.once("open", function open4() {
|
|
15056
15185
|
duplex2._final(callback);
|
|
15057
15186
|
});
|
|
15058
15187
|
return;
|
|
@@ -15073,7 +15202,7 @@ var require_stream = __commonJS({
|
|
|
15073
15202
|
};
|
|
15074
15203
|
duplex2._write = function(chunk, encoding, callback) {
|
|
15075
15204
|
if (ws.readyState === ws.CONNECTING) {
|
|
15076
|
-
ws.once("open", function
|
|
15205
|
+
ws.once("open", function open4() {
|
|
15077
15206
|
duplex2._write(chunk, encoding, callback);
|
|
15078
15207
|
});
|
|
15079
15208
|
return;
|
|
@@ -15539,10 +15668,258 @@ var init_wrapper = __esm({
|
|
|
15539
15668
|
}
|
|
15540
15669
|
});
|
|
15541
15670
|
|
|
15671
|
+
// package.json
|
|
15672
|
+
var package_default;
|
|
15673
|
+
var init_package = __esm({
|
|
15674
|
+
"package.json"() {
|
|
15675
|
+
package_default = {
|
|
15676
|
+
name: "@dhf-claude/grix",
|
|
15677
|
+
version: "0.1.9",
|
|
15678
|
+
description: "Claude Code channel plugin for Aibot Grix",
|
|
15679
|
+
type: "module",
|
|
15680
|
+
repository: {
|
|
15681
|
+
type: "git",
|
|
15682
|
+
url: "git+https://github.com/askie/clawpool-claude.git"
|
|
15683
|
+
},
|
|
15684
|
+
bugs: {
|
|
15685
|
+
url: "https://github.com/askie/clawpool-claude/issues"
|
|
15686
|
+
},
|
|
15687
|
+
homepage: "https://github.com/askie/clawpool-claude#readme",
|
|
15688
|
+
publishConfig: {
|
|
15689
|
+
access: "public"
|
|
15690
|
+
},
|
|
15691
|
+
bin: {
|
|
15692
|
+
"grix-claude": "bin/grix-claude.js"
|
|
15693
|
+
},
|
|
15694
|
+
files: [
|
|
15695
|
+
"bin",
|
|
15696
|
+
"cli",
|
|
15697
|
+
"dist",
|
|
15698
|
+
"hooks",
|
|
15699
|
+
"scripts",
|
|
15700
|
+
"skills",
|
|
15701
|
+
".claude-plugin",
|
|
15702
|
+
"start.sh"
|
|
15703
|
+
],
|
|
15704
|
+
scripts: {
|
|
15705
|
+
prepublishOnly: "npm run build",
|
|
15706
|
+
clean: `node -e "const fs=require('node:fs'); fs.rmSync('dist', { recursive: true, force: true });"`,
|
|
15707
|
+
"build:worker": "esbuild server/main.js --bundle --platform=node --format=esm --target=node20 --outfile=dist/index.js",
|
|
15708
|
+
"build:daemon": `esbuild bin/grix-claude.js --bundle --platform=node --format=esm --target=node20 --banner:js="import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);" --outfile=dist/daemon.js`,
|
|
15709
|
+
build: "npm run clean && npm run build:worker && npm run build:daemon",
|
|
15710
|
+
dev: "node ./scripts/dev-start.js",
|
|
15711
|
+
"dev:build": "node ./scripts/dev-build.js",
|
|
15712
|
+
daemon: "node ./dist/daemon.js --show-claude",
|
|
15713
|
+
prod: "node ./scripts/prod-start.js",
|
|
15714
|
+
test: "node --test server/*.test.js cli/*.test.js",
|
|
15715
|
+
"test:daemon-sim": "node --test server/daemon-simulated-e2e.scenario.js"
|
|
15716
|
+
},
|
|
15717
|
+
dependencies: {
|
|
15718
|
+
"@modelcontextprotocol/sdk": "^1.18.0",
|
|
15719
|
+
execa: "^9.6.0",
|
|
15720
|
+
pidtree: "^0.6.0",
|
|
15721
|
+
ws: "^8.18.3",
|
|
15722
|
+
zod: "^4.3.6"
|
|
15723
|
+
},
|
|
15724
|
+
devDependencies: {
|
|
15725
|
+
esbuild: "^0.27.0"
|
|
15726
|
+
}
|
|
15727
|
+
};
|
|
15728
|
+
}
|
|
15729
|
+
});
|
|
15730
|
+
|
|
15731
|
+
// server/protocol-contract.js
|
|
15732
|
+
var contractVersion, protocolVersion, adapterHint, declaredCapabilities, localActionTypes, declaredLocalActions, agentInvokeActions, sessionControlVerbs, interactionKinds, interactionResolutionTypes, accessControlVerbs, resultDomains, bindingWorkerStatuses, sessionControlOutcomes, localActionResultStatuses, localActionErrorCodes, sessionControlErrorCodes, interactionReplyOutcomes, interactionReplyErrorCodes, eventResultStatuses, publicProtocolContract;
|
|
15733
|
+
var init_protocol_contract = __esm({
|
|
15734
|
+
"server/protocol-contract.js"() {
|
|
15735
|
+
contractVersion = 1;
|
|
15736
|
+
protocolVersion = "aibot-agent-api-v1";
|
|
15737
|
+
adapterHint = "claude/base";
|
|
15738
|
+
declaredCapabilities = Object.freeze([
|
|
15739
|
+
"session_route",
|
|
15740
|
+
"local_action_v1",
|
|
15741
|
+
"agent_invoke"
|
|
15742
|
+
]);
|
|
15743
|
+
localActionTypes = Object.freeze({
|
|
15744
|
+
sessionControl: "claude_session_control",
|
|
15745
|
+
interactionReply: "claude_interaction_reply"
|
|
15746
|
+
});
|
|
15747
|
+
declaredLocalActions = Object.freeze([
|
|
15748
|
+
localActionTypes.sessionControl,
|
|
15749
|
+
localActionTypes.interactionReply
|
|
15750
|
+
]);
|
|
15751
|
+
agentInvokeActions = Object.freeze({
|
|
15752
|
+
interactionRequestCreate: "claude_interaction_request_create",
|
|
15753
|
+
accessControl: "claude_access_control"
|
|
15754
|
+
});
|
|
15755
|
+
sessionControlVerbs = Object.freeze({
|
|
15756
|
+
open: "open",
|
|
15757
|
+
status: "status",
|
|
15758
|
+
where: "where",
|
|
15759
|
+
stop: "stop"
|
|
15760
|
+
});
|
|
15761
|
+
interactionKinds = Object.freeze({
|
|
15762
|
+
permission: "permission",
|
|
15763
|
+
elicitation: "elicitation"
|
|
15764
|
+
});
|
|
15765
|
+
interactionResolutionTypes = Object.freeze({
|
|
15766
|
+
decision: "decision",
|
|
15767
|
+
action: "action",
|
|
15768
|
+
text: "text",
|
|
15769
|
+
map: "map"
|
|
15770
|
+
});
|
|
15771
|
+
accessControlVerbs = Object.freeze({
|
|
15772
|
+
statusRead: "status_read",
|
|
15773
|
+
pairApprove: "pair_approve",
|
|
15774
|
+
pairDeny: "pair_deny",
|
|
15775
|
+
senderAllow: "sender_allow",
|
|
15776
|
+
senderRemove: "sender_remove",
|
|
15777
|
+
policySet: "policy_set"
|
|
15778
|
+
});
|
|
15779
|
+
resultDomains = Object.freeze({
|
|
15780
|
+
sessionControl: "session_control",
|
|
15781
|
+
interactionReply: "interaction_reply"
|
|
15782
|
+
});
|
|
15783
|
+
bindingWorkerStatuses = Object.freeze({
|
|
15784
|
+
starting: "starting",
|
|
15785
|
+
connected: "connected",
|
|
15786
|
+
ready: "ready",
|
|
15787
|
+
stopped: "stopped",
|
|
15788
|
+
failed: "failed"
|
|
15789
|
+
});
|
|
15790
|
+
sessionControlOutcomes = Object.freeze({
|
|
15791
|
+
opened: "opened",
|
|
15792
|
+
alreadyBound: "already_bound",
|
|
15793
|
+
status: "status",
|
|
15794
|
+
where: "where",
|
|
15795
|
+
stopped: "stopped"
|
|
15796
|
+
});
|
|
15797
|
+
localActionResultStatuses = Object.freeze({
|
|
15798
|
+
ok: "ok",
|
|
15799
|
+
failed: "failed"
|
|
15800
|
+
});
|
|
15801
|
+
localActionErrorCodes = Object.freeze({
|
|
15802
|
+
unsupportedLocalAction: "unsupported_local_action",
|
|
15803
|
+
localActionRouteMissing: "local_action_route_missing"
|
|
15804
|
+
});
|
|
15805
|
+
sessionControlErrorCodes = Object.freeze({
|
|
15806
|
+
cwdRequired: "session_cwd_required",
|
|
15807
|
+
invalidCwd: "session_invalid_cwd",
|
|
15808
|
+
bindingMissing: "session_binding_missing",
|
|
15809
|
+
rebindForbidden: "session_rebind_forbidden",
|
|
15810
|
+
verbInvalid: "session_verb_invalid",
|
|
15811
|
+
runtimeError: "session_runtime_error"
|
|
15812
|
+
});
|
|
15813
|
+
interactionReplyOutcomes = Object.freeze({
|
|
15814
|
+
resolved: "resolved"
|
|
15815
|
+
});
|
|
15816
|
+
interactionReplyErrorCodes = Object.freeze({
|
|
15817
|
+
requestIDRequired: "interaction_request_id_required",
|
|
15818
|
+
requestNotFound: "interaction_request_not_found",
|
|
15819
|
+
requestNotPending: "interaction_request_not_pending",
|
|
15820
|
+
resolutionInvalid: "interaction_resolution_invalid",
|
|
15821
|
+
forwardFailed: "interaction_forward_failed"
|
|
15822
|
+
});
|
|
15823
|
+
eventResultStatuses = Object.freeze({
|
|
15824
|
+
responded: "responded",
|
|
15825
|
+
failed: "failed",
|
|
15826
|
+
canceled: "canceled"
|
|
15827
|
+
});
|
|
15828
|
+
publicProtocolContract = Object.freeze({
|
|
15829
|
+
contract_version: contractVersion,
|
|
15830
|
+
protocol_version: protocolVersion,
|
|
15831
|
+
adapter_hint: adapterHint,
|
|
15832
|
+
capabilities: [...declaredCapabilities],
|
|
15833
|
+
local_actions: [...declaredLocalActions],
|
|
15834
|
+
agent_invoke_actions: [
|
|
15835
|
+
agentInvokeActions.interactionRequestCreate,
|
|
15836
|
+
agentInvokeActions.accessControl
|
|
15837
|
+
],
|
|
15838
|
+
local_action_types: [
|
|
15839
|
+
localActionTypes.sessionControl,
|
|
15840
|
+
localActionTypes.interactionReply
|
|
15841
|
+
],
|
|
15842
|
+
session_control_verbs: [
|
|
15843
|
+
sessionControlVerbs.open,
|
|
15844
|
+
sessionControlVerbs.status,
|
|
15845
|
+
sessionControlVerbs.where,
|
|
15846
|
+
sessionControlVerbs.stop
|
|
15847
|
+
],
|
|
15848
|
+
interaction_kinds: [
|
|
15849
|
+
interactionKinds.permission,
|
|
15850
|
+
interactionKinds.elicitation
|
|
15851
|
+
],
|
|
15852
|
+
interaction_resolution_types: [
|
|
15853
|
+
interactionResolutionTypes.decision,
|
|
15854
|
+
interactionResolutionTypes.action,
|
|
15855
|
+
interactionResolutionTypes.text,
|
|
15856
|
+
interactionResolutionTypes.map
|
|
15857
|
+
],
|
|
15858
|
+
access_control_verbs: [
|
|
15859
|
+
accessControlVerbs.statusRead,
|
|
15860
|
+
accessControlVerbs.pairApprove,
|
|
15861
|
+
accessControlVerbs.pairDeny,
|
|
15862
|
+
accessControlVerbs.senderAllow,
|
|
15863
|
+
accessControlVerbs.senderRemove,
|
|
15864
|
+
accessControlVerbs.policySet
|
|
15865
|
+
],
|
|
15866
|
+
result_domains: [
|
|
15867
|
+
resultDomains.sessionControl,
|
|
15868
|
+
resultDomains.interactionReply
|
|
15869
|
+
],
|
|
15870
|
+
binding_worker_statuses: [
|
|
15871
|
+
bindingWorkerStatuses.starting,
|
|
15872
|
+
bindingWorkerStatuses.connected,
|
|
15873
|
+
bindingWorkerStatuses.ready,
|
|
15874
|
+
bindingWorkerStatuses.stopped,
|
|
15875
|
+
bindingWorkerStatuses.failed
|
|
15876
|
+
],
|
|
15877
|
+
session_control_outcomes: [
|
|
15878
|
+
sessionControlOutcomes.opened,
|
|
15879
|
+
sessionControlOutcomes.alreadyBound,
|
|
15880
|
+
sessionControlOutcomes.status,
|
|
15881
|
+
sessionControlOutcomes.where,
|
|
15882
|
+
sessionControlOutcomes.stopped
|
|
15883
|
+
],
|
|
15884
|
+
local_action_result_statuses: [
|
|
15885
|
+
localActionResultStatuses.ok,
|
|
15886
|
+
localActionResultStatuses.failed
|
|
15887
|
+
],
|
|
15888
|
+
local_action_error_codes: [
|
|
15889
|
+
localActionErrorCodes.unsupportedLocalAction,
|
|
15890
|
+
localActionErrorCodes.localActionRouteMissing
|
|
15891
|
+
],
|
|
15892
|
+
session_control_error_codes: [
|
|
15893
|
+
sessionControlErrorCodes.cwdRequired,
|
|
15894
|
+
sessionControlErrorCodes.invalidCwd,
|
|
15895
|
+
sessionControlErrorCodes.bindingMissing,
|
|
15896
|
+
sessionControlErrorCodes.rebindForbidden,
|
|
15897
|
+
sessionControlErrorCodes.verbInvalid,
|
|
15898
|
+
sessionControlErrorCodes.runtimeError
|
|
15899
|
+
],
|
|
15900
|
+
interaction_reply_outcomes: [
|
|
15901
|
+
interactionReplyOutcomes.resolved
|
|
15902
|
+
],
|
|
15903
|
+
interaction_reply_error_codes: [
|
|
15904
|
+
interactionReplyErrorCodes.requestIDRequired,
|
|
15905
|
+
interactionReplyErrorCodes.requestNotFound,
|
|
15906
|
+
interactionReplyErrorCodes.requestNotPending,
|
|
15907
|
+
interactionReplyErrorCodes.resolutionInvalid,
|
|
15908
|
+
interactionReplyErrorCodes.forwardFailed
|
|
15909
|
+
],
|
|
15910
|
+
event_result_statuses: [
|
|
15911
|
+
eventResultStatuses.responded,
|
|
15912
|
+
eventResultStatuses.failed,
|
|
15913
|
+
eventResultStatuses.canceled
|
|
15914
|
+
]
|
|
15915
|
+
});
|
|
15916
|
+
}
|
|
15917
|
+
});
|
|
15918
|
+
|
|
15542
15919
|
// server/aibot-client.js
|
|
15543
15920
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
15544
15921
|
import { appendFileSync as appendFileSync3 } from "node:fs";
|
|
15545
|
-
function
|
|
15922
|
+
function normalizeString20(value) {
|
|
15546
15923
|
return String(value ?? "").trim();
|
|
15547
15924
|
}
|
|
15548
15925
|
function logDebug(message) {
|
|
@@ -15557,23 +15934,33 @@ function logDebug(message) {
|
|
|
15557
15934
|
function buildSendNackError(packet) {
|
|
15558
15935
|
const payload = packet?.payload ?? {};
|
|
15559
15936
|
const code = Number(payload.code ?? 5001);
|
|
15560
|
-
const msg =
|
|
15937
|
+
const msg = normalizeString20(payload.msg) || packet?.cmd || "unknown error";
|
|
15561
15938
|
const error = new Error(`aibot ${packet?.cmd ?? "packet"} error ${code}: ${msg}`);
|
|
15562
15939
|
error.code = code;
|
|
15563
15940
|
return error;
|
|
15564
15941
|
}
|
|
15565
15942
|
function withOptionalString(target, key, value) {
|
|
15566
|
-
const normalized =
|
|
15943
|
+
const normalized = normalizeString20(value);
|
|
15567
15944
|
if (normalized) {
|
|
15568
15945
|
target[key] = normalized;
|
|
15569
15946
|
}
|
|
15570
15947
|
}
|
|
15571
15948
|
function buildAuthPayload(config) {
|
|
15949
|
+
const clientVersion = normalizeString20(config?.clientVersion) || pluginVersion;
|
|
15950
|
+
const hostVersion = normalizeString20(config?.hostVersion) || clientVersion;
|
|
15572
15951
|
return {
|
|
15573
15952
|
agent_id: config.agentID,
|
|
15574
15953
|
api_key: config.apiKey,
|
|
15575
15954
|
client: "claude-grix-claude-channel",
|
|
15576
|
-
client_type: "claude"
|
|
15955
|
+
client_type: "claude",
|
|
15956
|
+
contract_version: contractVersion,
|
|
15957
|
+
client_version: clientVersion,
|
|
15958
|
+
host_type: "claude",
|
|
15959
|
+
host_version: hostVersion,
|
|
15960
|
+
protocol_version: protocolVersion,
|
|
15961
|
+
capabilities: [...declaredCapabilities],
|
|
15962
|
+
local_actions: [...declaredLocalActions],
|
|
15963
|
+
adapter_hint: adapterHint
|
|
15577
15964
|
};
|
|
15578
15965
|
}
|
|
15579
15966
|
function buildSessionActivityPayload({
|
|
@@ -15585,8 +15972,8 @@ function buildSessionActivityPayload({
|
|
|
15585
15972
|
refEventID = ""
|
|
15586
15973
|
}) {
|
|
15587
15974
|
const payload = {
|
|
15588
|
-
session_id:
|
|
15589
|
-
kind:
|
|
15975
|
+
session_id: normalizeString20(sessionID),
|
|
15976
|
+
kind: normalizeString20(kind),
|
|
15590
15977
|
active: active === true
|
|
15591
15978
|
};
|
|
15592
15979
|
if (Number.isFinite(Number(ttlMs)) && Number(ttlMs) > 0) {
|
|
@@ -15596,17 +15983,21 @@ function buildSessionActivityPayload({
|
|
|
15596
15983
|
withOptionalString(payload, "ref_event_id", refEventID);
|
|
15597
15984
|
return payload;
|
|
15598
15985
|
}
|
|
15599
|
-
var verboseDebugEnabled, verboseDebugLogPath, AibotClient;
|
|
15986
|
+
var verboseDebugEnabled, verboseDebugLogPath, pluginVersion, AibotClient;
|
|
15600
15987
|
var init_aibot_client = __esm({
|
|
15601
15988
|
"server/aibot-client.js"() {
|
|
15602
15989
|
init_wrapper();
|
|
15990
|
+
init_package();
|
|
15991
|
+
init_protocol_contract();
|
|
15603
15992
|
verboseDebugEnabled = process.env.GRIX_CLAUDE_E2E_DEBUG === "1";
|
|
15604
|
-
verboseDebugLogPath =
|
|
15993
|
+
verboseDebugLogPath = normalizeString20(process.env.GRIX_CLAUDE_E2E_DEBUG_LOG);
|
|
15994
|
+
pluginVersion = normalizeString20(package_default?.version) || "0.1.0";
|
|
15605
15995
|
AibotClient = class {
|
|
15606
|
-
constructor({ onEventMessage, onEventStop, onEventRevoke, onStatus } = {}) {
|
|
15996
|
+
constructor({ onEventMessage, onEventStop, onEventRevoke, onLocalAction, onStatus } = {}) {
|
|
15607
15997
|
this.onEventMessage = onEventMessage;
|
|
15608
15998
|
this.onEventStop = onEventStop;
|
|
15609
15999
|
this.onEventRevoke = onEventRevoke;
|
|
16000
|
+
this.onLocalAction = onLocalAction;
|
|
15610
16001
|
this.onStatus = onStatus;
|
|
15611
16002
|
this.desired = false;
|
|
15612
16003
|
this.config = null;
|
|
@@ -15736,10 +16127,10 @@ var init_aibot_client = __esm({
|
|
|
15736
16127
|
expected: ["auth_ack"],
|
|
15737
16128
|
timeoutMs: 1e4
|
|
15738
16129
|
});
|
|
15739
|
-
logDebug(`auth response code=${Number(auth?.payload?.code ?? 0)} msg=${
|
|
16130
|
+
logDebug(`auth response code=${Number(auth?.payload?.code ?? 0)} msg=${normalizeString20(auth?.payload?.msg)}`);
|
|
15740
16131
|
const code = Number(auth?.payload?.code ?? 0);
|
|
15741
16132
|
if (code !== 0) {
|
|
15742
|
-
throw new Error(
|
|
16133
|
+
throw new Error(normalizeString20(auth?.payload?.msg) || `auth failed code=${code}`);
|
|
15743
16134
|
}
|
|
15744
16135
|
this.setStatus({
|
|
15745
16136
|
connecting: false,
|
|
@@ -15847,7 +16238,7 @@ var init_aibot_client = __esm({
|
|
|
15847
16238
|
}
|
|
15848
16239
|
async handleMessage(text) {
|
|
15849
16240
|
const packet = JSON.parse(text);
|
|
15850
|
-
const cmd =
|
|
16241
|
+
const cmd = normalizeString20(packet.cmd);
|
|
15851
16242
|
const seq = Number(packet.seq ?? 0);
|
|
15852
16243
|
logDebug(`recv cmd=${cmd} seq=${seq}`);
|
|
15853
16244
|
if (cmd === "ping") {
|
|
@@ -15871,6 +16262,10 @@ var init_aibot_client = __esm({
|
|
|
15871
16262
|
}
|
|
15872
16263
|
if (cmd === "event_revoke" && this.onEventRevoke) {
|
|
15873
16264
|
await this.onEventRevoke(packet.payload ?? {});
|
|
16265
|
+
return;
|
|
16266
|
+
}
|
|
16267
|
+
if (cmd === "local_action" && this.onLocalAction) {
|
|
16268
|
+
await this.onLocalAction(packet.payload ?? {});
|
|
15874
16269
|
}
|
|
15875
16270
|
}
|
|
15876
16271
|
setStatus(patch) {
|
|
@@ -15940,7 +16335,7 @@ var init_aibot_client = __esm({
|
|
|
15940
16335
|
}
|
|
15941
16336
|
ackEvent(eventID, { sessionID, msgID, receivedAt = Date.now() } = {}) {
|
|
15942
16337
|
const payload = {
|
|
15943
|
-
event_id:
|
|
16338
|
+
event_id: normalizeString20(eventID),
|
|
15944
16339
|
received_at: Math.floor(receivedAt)
|
|
15945
16340
|
};
|
|
15946
16341
|
withOptionalString(payload, "session_id", sessionID);
|
|
@@ -15949,8 +16344,8 @@ var init_aibot_client = __esm({
|
|
|
15949
16344
|
}
|
|
15950
16345
|
sendEventResult({ event_id, status, code = "", msg = "", updated_at = Date.now() }) {
|
|
15951
16346
|
const payload = {
|
|
15952
|
-
event_id:
|
|
15953
|
-
status:
|
|
16347
|
+
event_id: normalizeString20(event_id),
|
|
16348
|
+
status: normalizeString20(status),
|
|
15954
16349
|
updated_at: Math.floor(updated_at)
|
|
15955
16350
|
};
|
|
15956
16351
|
withOptionalString(payload, "code", code);
|
|
@@ -15959,7 +16354,7 @@ var init_aibot_client = __esm({
|
|
|
15959
16354
|
}
|
|
15960
16355
|
sendEventStopAck({ event_id, stop_id = "", accepted, updated_at = Date.now() }) {
|
|
15961
16356
|
const payload = {
|
|
15962
|
-
event_id:
|
|
16357
|
+
event_id: normalizeString20(event_id),
|
|
15963
16358
|
accepted: accepted === true,
|
|
15964
16359
|
updated_at: Math.floor(updated_at)
|
|
15965
16360
|
};
|
|
@@ -15975,8 +16370,8 @@ var init_aibot_client = __esm({
|
|
|
15975
16370
|
updated_at = Date.now()
|
|
15976
16371
|
}) {
|
|
15977
16372
|
const payload = {
|
|
15978
|
-
event_id:
|
|
15979
|
-
status:
|
|
16373
|
+
event_id: normalizeString20(event_id),
|
|
16374
|
+
status: normalizeString20(status),
|
|
15980
16375
|
updated_at: Math.floor(updated_at)
|
|
15981
16376
|
};
|
|
15982
16377
|
withOptionalString(payload, "stop_id", stop_id);
|
|
@@ -16013,8 +16408,8 @@ var init_aibot_client = __esm({
|
|
|
16013
16408
|
extra = {}
|
|
16014
16409
|
}) {
|
|
16015
16410
|
const payload = {
|
|
16016
|
-
session_id:
|
|
16017
|
-
client_msg_id:
|
|
16411
|
+
session_id: normalizeString20(sessionID),
|
|
16412
|
+
client_msg_id: normalizeString20(clientMsgID),
|
|
16018
16413
|
msg_type: 1,
|
|
16019
16414
|
content: String(text ?? ""),
|
|
16020
16415
|
extra
|
|
@@ -16040,11 +16435,11 @@ var init_aibot_client = __esm({
|
|
|
16040
16435
|
extra = {}
|
|
16041
16436
|
}) {
|
|
16042
16437
|
const payload = {
|
|
16043
|
-
session_id:
|
|
16044
|
-
client_msg_id:
|
|
16438
|
+
session_id: normalizeString20(sessionID),
|
|
16439
|
+
client_msg_id: normalizeString20(clientMsgID),
|
|
16045
16440
|
msg_type: 2,
|
|
16046
|
-
content:
|
|
16047
|
-
media_url:
|
|
16441
|
+
content: normalizeString20(caption) || "[attachment]",
|
|
16442
|
+
media_url: normalizeString20(mediaURL),
|
|
16048
16443
|
extra
|
|
16049
16444
|
};
|
|
16050
16445
|
withOptionalString(payload, "event_id", eventID);
|
|
@@ -16058,9 +16453,69 @@ var init_aibot_client = __esm({
|
|
|
16058
16453
|
}
|
|
16059
16454
|
return packet.payload ?? {};
|
|
16060
16455
|
}
|
|
16456
|
+
async sendAgentInvoke({
|
|
16457
|
+
invokeID = randomUUID5(),
|
|
16458
|
+
action,
|
|
16459
|
+
params = {},
|
|
16460
|
+
timeoutMs = 15e3
|
|
16461
|
+
} = {}) {
|
|
16462
|
+
const normalizedAction = normalizeString20(action);
|
|
16463
|
+
if (!normalizedAction) {
|
|
16464
|
+
throw new Error("sendAgentInvoke requires action");
|
|
16465
|
+
}
|
|
16466
|
+
const normalizedTimeoutMs = Number.isFinite(Number(timeoutMs)) && Number(timeoutMs) > 0 ? Math.floor(Number(timeoutMs)) : 15e3;
|
|
16467
|
+
const packet = await this.request("agent_invoke", {
|
|
16468
|
+
invoke_id: normalizeString20(invokeID) || randomUUID5(),
|
|
16469
|
+
action: normalizedAction,
|
|
16470
|
+
params: params && typeof params === "object" && !Array.isArray(params) ? params : {},
|
|
16471
|
+
timeout_ms: normalizedTimeoutMs
|
|
16472
|
+
}, {
|
|
16473
|
+
expected: ["agent_invoke_result", "error"],
|
|
16474
|
+
timeoutMs: normalizedTimeoutMs + 1e3
|
|
16475
|
+
});
|
|
16476
|
+
if (packet.cmd !== "agent_invoke_result") {
|
|
16477
|
+
throw buildSendNackError(packet);
|
|
16478
|
+
}
|
|
16479
|
+
return packet.payload ?? {};
|
|
16480
|
+
}
|
|
16481
|
+
async sendLocalActionResult({
|
|
16482
|
+
actionID,
|
|
16483
|
+
status,
|
|
16484
|
+
result = void 0,
|
|
16485
|
+
errorCode = "",
|
|
16486
|
+
errorMsg = "",
|
|
16487
|
+
timeoutMs = 15e3
|
|
16488
|
+
} = {}) {
|
|
16489
|
+
const normalizedActionID = normalizeString20(actionID);
|
|
16490
|
+
if (!normalizedActionID) {
|
|
16491
|
+
throw new Error("sendLocalActionResult requires actionID");
|
|
16492
|
+
}
|
|
16493
|
+
const normalizedStatus = normalizeString20(status);
|
|
16494
|
+
if (!normalizedStatus) {
|
|
16495
|
+
throw new Error("sendLocalActionResult requires status");
|
|
16496
|
+
}
|
|
16497
|
+
const normalizedTimeoutMs = Number.isFinite(Number(timeoutMs)) && Number(timeoutMs) > 0 ? Math.floor(Number(timeoutMs)) : 15e3;
|
|
16498
|
+
const payload = {
|
|
16499
|
+
action_id: normalizedActionID,
|
|
16500
|
+
status: normalizedStatus
|
|
16501
|
+
};
|
|
16502
|
+
if (arguments[0] && Object.prototype.hasOwnProperty.call(arguments[0], "result")) {
|
|
16503
|
+
payload.result = result;
|
|
16504
|
+
}
|
|
16505
|
+
withOptionalString(payload, "error_code", errorCode);
|
|
16506
|
+
withOptionalString(payload, "error_msg", errorMsg);
|
|
16507
|
+
const packet = await this.request("local_action_result", payload, {
|
|
16508
|
+
expected: ["local_action_ack", "error"],
|
|
16509
|
+
timeoutMs: normalizedTimeoutMs
|
|
16510
|
+
});
|
|
16511
|
+
if (packet.cmd !== "local_action_ack") {
|
|
16512
|
+
throw buildSendNackError(packet);
|
|
16513
|
+
}
|
|
16514
|
+
return packet.payload ?? {};
|
|
16515
|
+
}
|
|
16061
16516
|
async deleteMessage(sessionID, messageID, { timeoutMs = 2e4 } = {}) {
|
|
16062
|
-
const normalizedSessionID =
|
|
16063
|
-
const normalizedMessageID =
|
|
16517
|
+
const normalizedSessionID = normalizeString20(sessionID);
|
|
16518
|
+
const normalizedMessageID = normalizeString20(messageID);
|
|
16064
16519
|
if (!normalizedSessionID) {
|
|
16065
16520
|
throw new Error("deleteMessage requires sessionID");
|
|
16066
16521
|
}
|
|
@@ -16083,74 +16538,113 @@ var init_aibot_client = __esm({
|
|
|
16083
16538
|
}
|
|
16084
16539
|
});
|
|
16085
16540
|
|
|
16086
|
-
// server/
|
|
16087
|
-
|
|
16088
|
-
function normalizeString20(value) {
|
|
16541
|
+
// server/grix-card-link.js
|
|
16542
|
+
function normalizeString21(value) {
|
|
16089
16543
|
return String(value ?? "").trim();
|
|
16090
16544
|
}
|
|
16091
|
-
function
|
|
16092
|
-
return
|
|
16545
|
+
function hasComplexPayload(payload) {
|
|
16546
|
+
return Object.values(payload ?? {}).some((value) => Array.isArray(value) || value && typeof value === "object");
|
|
16093
16547
|
}
|
|
16094
|
-
function
|
|
16095
|
-
const
|
|
16096
|
-
|
|
16097
|
-
|
|
16098
|
-
|
|
16099
|
-
|
|
16100
|
-
|
|
16101
|
-
|
|
16548
|
+
function appendFlatPayload(params, payload) {
|
|
16549
|
+
for (const [rawKey, value] of Object.entries(payload ?? {})) {
|
|
16550
|
+
const key = normalizeString21(rawKey);
|
|
16551
|
+
if (!key || value == null) {
|
|
16552
|
+
continue;
|
|
16553
|
+
}
|
|
16554
|
+
if (typeof value === "string") {
|
|
16555
|
+
if (!value) {
|
|
16556
|
+
continue;
|
|
16557
|
+
}
|
|
16558
|
+
params.set(key, value);
|
|
16559
|
+
continue;
|
|
16560
|
+
}
|
|
16561
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
16562
|
+
params.set(key, String(value));
|
|
16563
|
+
}
|
|
16102
16564
|
}
|
|
16103
|
-
|
|
16104
|
-
|
|
16105
|
-
|
|
16565
|
+
}
|
|
16566
|
+
function buildGrixCardURI(cardType, payload = {}) {
|
|
16567
|
+
const normalizedType = normalizeString21(cardType);
|
|
16568
|
+
if (!normalizedType) {
|
|
16569
|
+
throw new Error("cardType is required");
|
|
16106
16570
|
}
|
|
16107
|
-
const
|
|
16108
|
-
if (
|
|
16109
|
-
|
|
16571
|
+
const params = new URLSearchParams();
|
|
16572
|
+
if (hasComplexPayload(payload)) {
|
|
16573
|
+
params.set("d", JSON.stringify(payload));
|
|
16574
|
+
} else {
|
|
16575
|
+
appendFlatPayload(params, payload);
|
|
16110
16576
|
}
|
|
16111
|
-
|
|
16112
|
-
|
|
16113
|
-
|
|
16114
|
-
|
|
16115
|
-
|
|
16116
|
-
|
|
16117
|
-
|
|
16118
|
-
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
},
|
|
16123
|
-
error: ""
|
|
16124
|
-
};
|
|
16577
|
+
const query = params.toString();
|
|
16578
|
+
return `grix://card/${encodeURIComponent(normalizedType)}${query ? `?${query}` : ""}`;
|
|
16579
|
+
}
|
|
16580
|
+
function buildGrixCardLink({
|
|
16581
|
+
fallbackText,
|
|
16582
|
+
cardType,
|
|
16583
|
+
payload = {}
|
|
16584
|
+
}) {
|
|
16585
|
+
const normalizedFallbackText = normalizeString21(fallbackText);
|
|
16586
|
+
if (!normalizedFallbackText) {
|
|
16587
|
+
throw new Error("fallbackText is required");
|
|
16125
16588
|
}
|
|
16126
|
-
|
|
16127
|
-
|
|
16128
|
-
|
|
16129
|
-
|
|
16130
|
-
command,
|
|
16131
|
-
args: {},
|
|
16132
|
-
error: ""
|
|
16133
|
-
};
|
|
16589
|
+
return `[${normalizedFallbackText}](${buildGrixCardURI(cardType, payload)})`;
|
|
16590
|
+
}
|
|
16591
|
+
var init_grix_card_link = __esm({
|
|
16592
|
+
"server/grix-card-link.js"() {
|
|
16134
16593
|
}
|
|
16135
|
-
|
|
16594
|
+
});
|
|
16595
|
+
|
|
16596
|
+
// server/agent-open-session-card.js
|
|
16597
|
+
function normalizeString22(value) {
|
|
16598
|
+
return String(value ?? "").trim();
|
|
16599
|
+
}
|
|
16600
|
+
function buildAgentOpenSessionCardLink({
|
|
16601
|
+
fallbackText = "\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55",
|
|
16602
|
+
summaryText = "",
|
|
16603
|
+
detailText = "",
|
|
16604
|
+
initialCwd = "",
|
|
16605
|
+
submittedPath = ""
|
|
16606
|
+
} = {}) {
|
|
16607
|
+
const payload = {};
|
|
16608
|
+
const normalizedSummaryText = normalizeString22(summaryText);
|
|
16609
|
+
const normalizedDetailText = normalizeString22(detailText);
|
|
16610
|
+
const normalizedInitialCwd = normalizeString22(initialCwd);
|
|
16611
|
+
const normalizedSubmittedPath = normalizeString22(submittedPath);
|
|
16612
|
+
if (normalizedSummaryText) {
|
|
16613
|
+
payload.summary_text = normalizedSummaryText;
|
|
16614
|
+
}
|
|
16615
|
+
if (normalizedDetailText) {
|
|
16616
|
+
payload.detail_text = normalizedDetailText;
|
|
16617
|
+
}
|
|
16618
|
+
if (normalizedInitialCwd) {
|
|
16619
|
+
payload.initial_cwd = normalizedInitialCwd;
|
|
16620
|
+
}
|
|
16621
|
+
if (normalizedSubmittedPath) {
|
|
16622
|
+
payload.submitted_path = normalizedSubmittedPath;
|
|
16623
|
+
}
|
|
16624
|
+
return buildGrixCardLink({
|
|
16625
|
+
fallbackText: normalizeString22(fallbackText) || "\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55",
|
|
16626
|
+
cardType: "agent_open_session",
|
|
16627
|
+
payload
|
|
16628
|
+
});
|
|
16136
16629
|
}
|
|
16137
|
-
var
|
|
16138
|
-
"server/
|
|
16630
|
+
var init_agent_open_session_card = __esm({
|
|
16631
|
+
"server/agent-open-session-card.js"() {
|
|
16632
|
+
init_grix_card_link();
|
|
16139
16633
|
}
|
|
16140
16634
|
});
|
|
16141
16635
|
|
|
16142
16636
|
// server/inbound-event-meta.js
|
|
16143
|
-
function
|
|
16637
|
+
function normalizeString23(value) {
|
|
16144
16638
|
return String(value ?? "").trim();
|
|
16145
16639
|
}
|
|
16146
16640
|
function normalizeOptionalString(value) {
|
|
16147
|
-
return
|
|
16641
|
+
return normalizeString23(value) || "";
|
|
16148
16642
|
}
|
|
16149
16643
|
function normalizeStringArray(value) {
|
|
16150
16644
|
if (!Array.isArray(value)) {
|
|
16151
16645
|
return [];
|
|
16152
16646
|
}
|
|
16153
|
-
return value.map((item) =>
|
|
16647
|
+
return value.map((item) => normalizeString23(item)).filter((item) => item);
|
|
16154
16648
|
}
|
|
16155
16649
|
function normalizeJSONObject(value) {
|
|
16156
16650
|
if (!value) {
|
|
@@ -16206,6 +16700,43 @@ function normalizeAttachmentRecord(value) {
|
|
|
16206
16700
|
}
|
|
16207
16701
|
return attachment;
|
|
16208
16702
|
}
|
|
16703
|
+
function normalizeContextMessageRecord(value) {
|
|
16704
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
16705
|
+
return null;
|
|
16706
|
+
}
|
|
16707
|
+
const normalized = {
|
|
16708
|
+
msg_id: normalizeOptionalString(value.msg_id),
|
|
16709
|
+
sender_id: normalizeOptionalString(value.sender_id),
|
|
16710
|
+
sender_type: Number(value.sender_type ?? 0),
|
|
16711
|
+
msg_type: Number(value.msg_type ?? 0),
|
|
16712
|
+
content: String(value.content ?? ""),
|
|
16713
|
+
quoted_message_id: normalizeOptionalString(value.quoted_message_id),
|
|
16714
|
+
mention_user_ids: normalizeStringArray(value.mention_user_ids),
|
|
16715
|
+
created_at: Number(value.created_at ?? 0)
|
|
16716
|
+
};
|
|
16717
|
+
if (!normalized.msg_id) {
|
|
16718
|
+
return null;
|
|
16719
|
+
}
|
|
16720
|
+
return normalized;
|
|
16721
|
+
}
|
|
16722
|
+
function normalizeContextMessageArray(value) {
|
|
16723
|
+
if (Array.isArray(value)) {
|
|
16724
|
+
return value.map((item) => normalizeContextMessageRecord(item)).filter(Boolean);
|
|
16725
|
+
}
|
|
16726
|
+
if (typeof value === "string") {
|
|
16727
|
+
const trimmed = value.trim();
|
|
16728
|
+
if (!trimmed) {
|
|
16729
|
+
return [];
|
|
16730
|
+
}
|
|
16731
|
+
try {
|
|
16732
|
+
const parsed = JSON.parse(trimmed);
|
|
16733
|
+
return normalizeContextMessageArray(parsed);
|
|
16734
|
+
} catch {
|
|
16735
|
+
return [];
|
|
16736
|
+
}
|
|
16737
|
+
}
|
|
16738
|
+
return [];
|
|
16739
|
+
}
|
|
16209
16740
|
function deriveAttachments(payload, extra) {
|
|
16210
16741
|
const explicit = normalizeJSONArray(payload.attachments).map((item) => normalizeAttachmentRecord(item)).filter(Boolean);
|
|
16211
16742
|
if (explicit.length > 0) {
|
|
@@ -16235,19 +16766,25 @@ function stringifyJSON(value) {
|
|
|
16235
16766
|
}
|
|
16236
16767
|
return JSON.stringify(value);
|
|
16237
16768
|
}
|
|
16769
|
+
function deriveContextMessages(payload) {
|
|
16770
|
+
const currentMsgID = normalizeString23(payload.msg_id);
|
|
16771
|
+
return normalizeContextMessageArray(payload.context_messages).filter((entry) => entry.msg_id !== currentMsgID);
|
|
16772
|
+
}
|
|
16238
16773
|
function normalizeInboundEventPayload(rawPayload) {
|
|
16239
16774
|
const extra = normalizeJSONObject(rawPayload.extra);
|
|
16240
16775
|
const attachments = deriveAttachments(rawPayload, extra);
|
|
16241
16776
|
const bizCard = normalizeJSONObject(rawPayload.biz_card) ?? normalizeJSONObject(extra?.biz_card);
|
|
16242
16777
|
const channelData = normalizeJSONObject(rawPayload.channel_data) ?? normalizeJSONObject(extra?.channel_data);
|
|
16778
|
+
const contextMessages = deriveContextMessages(rawPayload);
|
|
16243
16779
|
return {
|
|
16244
|
-
event_id:
|
|
16245
|
-
event_type:
|
|
16246
|
-
|
|
16780
|
+
event_id: normalizeString23(rawPayload.event_id),
|
|
16781
|
+
event_type: normalizeString23(rawPayload.event_type),
|
|
16782
|
+
mirror_mode: normalizeString23(rawPayload.mirror_mode),
|
|
16783
|
+
session_id: normalizeString23(rawPayload.session_id),
|
|
16247
16784
|
session_type: normalizeOptionalString(rawPayload.session_type),
|
|
16248
|
-
msg_id:
|
|
16785
|
+
msg_id: normalizeString23(rawPayload.msg_id),
|
|
16249
16786
|
quoted_message_id: normalizeOptionalString(rawPayload.quoted_message_id),
|
|
16250
|
-
sender_id:
|
|
16787
|
+
sender_id: normalizeString23(rawPayload.sender_id),
|
|
16251
16788
|
owner_id: normalizeOptionalString(rawPayload.owner_id),
|
|
16252
16789
|
agent_id: normalizeOptionalString(rawPayload.agent_id),
|
|
16253
16790
|
msg_type: normalizeOptionalString(rawPayload.msg_type),
|
|
@@ -16258,7 +16795,8 @@ function normalizeInboundEventPayload(rawPayload) {
|
|
|
16258
16795
|
attachments_json: stringifyJSON(attachments),
|
|
16259
16796
|
attachment_count: attachments.length > 0 ? String(attachments.length) : "",
|
|
16260
16797
|
biz_card_json: stringifyJSON(bizCard),
|
|
16261
|
-
channel_data_json: stringifyJSON(channelData)
|
|
16798
|
+
channel_data_json: stringifyJSON(channelData),
|
|
16799
|
+
context_messages_json: stringifyJSON(contextMessages)
|
|
16262
16800
|
};
|
|
16263
16801
|
}
|
|
16264
16802
|
var init_inbound_event_meta = __esm({
|
|
@@ -16267,7 +16805,7 @@ var init_inbound_event_meta = __esm({
|
|
|
16267
16805
|
});
|
|
16268
16806
|
|
|
16269
16807
|
// server/daemon/worker-control-client.js
|
|
16270
|
-
function
|
|
16808
|
+
function normalizeString24(value) {
|
|
16271
16809
|
return String(value ?? "").trim();
|
|
16272
16810
|
}
|
|
16273
16811
|
async function parseJSONResponse(response) {
|
|
@@ -16282,8 +16820,8 @@ var init_worker_control_client = __esm({
|
|
|
16282
16820
|
"server/daemon/worker-control-client.js"() {
|
|
16283
16821
|
WorkerControlClient = class {
|
|
16284
16822
|
constructor({ controlURL, token, fetchImpl = globalThis.fetch, pingTimeoutMs = 5e3, deliverTimeoutMs = 1e4 } = {}) {
|
|
16285
|
-
this.controlURL =
|
|
16286
|
-
this.token =
|
|
16823
|
+
this.controlURL = normalizeString24(controlURL).replace(/\/+$/u, "");
|
|
16824
|
+
this.token = normalizeString24(token);
|
|
16287
16825
|
this.fetchImpl = fetchImpl;
|
|
16288
16826
|
this.pingTimeoutMs = pingTimeoutMs;
|
|
16289
16827
|
this.deliverTimeoutMs = deliverTimeoutMs;
|
|
@@ -16291,135 +16829,52 @@ var init_worker_control_client = __esm({
|
|
|
16291
16829
|
isConfigured() {
|
|
16292
16830
|
return Boolean(this.controlURL && this.token && typeof this.fetchImpl === "function");
|
|
16293
16831
|
}
|
|
16294
|
-
async
|
|
16832
|
+
async post(pathname, payload, timeoutMs) {
|
|
16295
16833
|
if (!this.isConfigured()) {
|
|
16296
16834
|
throw new Error("worker control is not configured");
|
|
16297
16835
|
}
|
|
16298
|
-
const response = await this.fetchImpl(`${this.controlURL}
|
|
16836
|
+
const response = await this.fetchImpl(`${this.controlURL}${pathname}`, {
|
|
16299
16837
|
method: "POST",
|
|
16300
16838
|
headers: {
|
|
16301
16839
|
"content-type": "application/json",
|
|
16302
16840
|
authorization: `Bearer ${this.token}`
|
|
16303
16841
|
},
|
|
16304
|
-
body: JSON.stringify(
|
|
16305
|
-
signal: AbortSignal.timeout(
|
|
16842
|
+
body: JSON.stringify(payload),
|
|
16843
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
16306
16844
|
});
|
|
16307
16845
|
const json = await parseJSONResponse(response);
|
|
16308
16846
|
if (!response.ok) {
|
|
16309
|
-
throw new Error(
|
|
16847
|
+
throw new Error(normalizeString24(json.error) || `worker control failed ${response.status}`);
|
|
16310
16848
|
}
|
|
16311
16849
|
return json;
|
|
16312
16850
|
}
|
|
16851
|
+
async deliverEvent(rawPayload) {
|
|
16852
|
+
return this.post("/v1/worker/deliver-event", { payload: rawPayload }, this.deliverTimeoutMs);
|
|
16853
|
+
}
|
|
16313
16854
|
async deliverStop(rawPayload) {
|
|
16314
|
-
|
|
16315
|
-
throw new Error("worker control is not configured");
|
|
16316
|
-
}
|
|
16317
|
-
const response = await this.fetchImpl(`${this.controlURL}/v1/worker/deliver-stop`, {
|
|
16318
|
-
method: "POST",
|
|
16319
|
-
headers: {
|
|
16320
|
-
"content-type": "application/json",
|
|
16321
|
-
authorization: `Bearer ${this.token}`
|
|
16322
|
-
},
|
|
16323
|
-
body: JSON.stringify({ payload: rawPayload }),
|
|
16324
|
-
signal: AbortSignal.timeout(this.deliverTimeoutMs)
|
|
16325
|
-
});
|
|
16326
|
-
const json = await parseJSONResponse(response);
|
|
16327
|
-
if (!response.ok) {
|
|
16328
|
-
throw new Error(normalizeString22(json.error) || `worker control failed ${response.status}`);
|
|
16329
|
-
}
|
|
16330
|
-
return json;
|
|
16855
|
+
return this.post("/v1/worker/deliver-stop", { payload: rawPayload }, this.deliverTimeoutMs);
|
|
16331
16856
|
}
|
|
16332
16857
|
async deliverRevoke(rawPayload) {
|
|
16333
|
-
|
|
16334
|
-
|
|
16335
|
-
|
|
16336
|
-
|
|
16337
|
-
method: "POST",
|
|
16338
|
-
headers: {
|
|
16339
|
-
"content-type": "application/json",
|
|
16340
|
-
authorization: `Bearer ${this.token}`
|
|
16341
|
-
},
|
|
16342
|
-
body: JSON.stringify({ payload: rawPayload }),
|
|
16343
|
-
signal: AbortSignal.timeout(this.deliverTimeoutMs)
|
|
16344
|
-
});
|
|
16345
|
-
const json = await parseJSONResponse(response);
|
|
16346
|
-
if (!response.ok) {
|
|
16347
|
-
throw new Error(normalizeString22(json.error) || `worker control failed ${response.status}`);
|
|
16348
|
-
}
|
|
16349
|
-
return json;
|
|
16858
|
+
return this.post("/v1/worker/deliver-revoke", { payload: rawPayload }, this.deliverTimeoutMs);
|
|
16859
|
+
}
|
|
16860
|
+
async deliverLocalAction(rawPayload) {
|
|
16861
|
+
return this.post("/v1/worker/deliver-local-action", { payload: rawPayload }, this.deliverTimeoutMs);
|
|
16350
16862
|
}
|
|
16351
16863
|
async ping() {
|
|
16352
|
-
|
|
16353
|
-
throw new Error("worker control is not configured");
|
|
16354
|
-
}
|
|
16355
|
-
const response = await this.fetchImpl(`${this.controlURL}/v1/worker/ping`, {
|
|
16356
|
-
method: "POST",
|
|
16357
|
-
headers: {
|
|
16358
|
-
"content-type": "application/json",
|
|
16359
|
-
authorization: `Bearer ${this.token}`
|
|
16360
|
-
},
|
|
16361
|
-
body: JSON.stringify({}),
|
|
16362
|
-
signal: AbortSignal.timeout(this.pingTimeoutMs)
|
|
16363
|
-
});
|
|
16364
|
-
const json = await parseJSONResponse(response);
|
|
16365
|
-
if (!response.ok) {
|
|
16366
|
-
throw new Error(normalizeString22(json.error) || `worker control failed ${response.status}`);
|
|
16367
|
-
}
|
|
16368
|
-
return json;
|
|
16864
|
+
return this.post("/v1/worker/ping", {}, this.pingTimeoutMs);
|
|
16369
16865
|
}
|
|
16370
16866
|
};
|
|
16371
16867
|
}
|
|
16372
16868
|
});
|
|
16373
16869
|
|
|
16374
|
-
// server/message-card-envelope.js
|
|
16375
|
-
function buildMessageCardEnvelope(type, payload) {
|
|
16376
|
-
return {
|
|
16377
|
-
version: currentVersion,
|
|
16378
|
-
type,
|
|
16379
|
-
payload
|
|
16380
|
-
};
|
|
16381
|
-
}
|
|
16382
|
-
var currentVersion;
|
|
16383
|
-
var init_message_card_envelope = __esm({
|
|
16384
|
-
"server/message-card-envelope.js"() {
|
|
16385
|
-
currentVersion = 1;
|
|
16386
|
-
}
|
|
16387
|
-
});
|
|
16388
|
-
|
|
16389
|
-
// server/daemon/control-card.js
|
|
16390
|
-
function normalizeString23(value) {
|
|
16391
|
-
return String(value ?? "").trim();
|
|
16392
|
-
}
|
|
16393
|
-
function buildOpenWorkspaceCard({
|
|
16394
|
-
summaryText = "open \u7F3A\u5C11\u76EE\u5F55\u8DEF\u5F84\u3002",
|
|
16395
|
-
detailText = "\u8BF7\u8F93\u5165\u5DE5\u4F5C\u76EE\u5F55\u6765\u542F\u52A8\u6216\u6062\u590D Claude \u4F1A\u8BDD\u3002",
|
|
16396
|
-
initialCwd = ""
|
|
16397
|
-
} = {}) {
|
|
16398
|
-
return buildMessageCardEnvelope("claude_open_session", {
|
|
16399
|
-
summary_text: normalizeString23(summaryText),
|
|
16400
|
-
detail_text: normalizeString23(detailText),
|
|
16401
|
-
command_prefix: openCommandPrefix,
|
|
16402
|
-
command_hint: openCommandHint,
|
|
16403
|
-
initial_cwd: normalizeString23(initialCwd)
|
|
16404
|
-
});
|
|
16405
|
-
}
|
|
16406
|
-
var openCommandPrefix, openCommandHint;
|
|
16407
|
-
var init_control_card = __esm({
|
|
16408
|
-
"server/daemon/control-card.js"() {
|
|
16409
|
-
init_message_card_envelope();
|
|
16410
|
-
openCommandPrefix = "/grix open";
|
|
16411
|
-
openCommandHint = "/grix open <working-directory>";
|
|
16412
|
-
}
|
|
16413
|
-
});
|
|
16414
|
-
|
|
16415
16870
|
// server/daemon/claude-session-store.js
|
|
16416
16871
|
import path22 from "node:path";
|
|
16417
16872
|
import { access } from "node:fs/promises";
|
|
16418
|
-
function
|
|
16873
|
+
function normalizeString25(value) {
|
|
16419
16874
|
return String(value ?? "").trim();
|
|
16420
16875
|
}
|
|
16421
16876
|
function encodeClaudeProjectPath(cwd) {
|
|
16422
|
-
const normalized =
|
|
16877
|
+
const normalized = normalizeString25(cwd);
|
|
16423
16878
|
if (!normalized) {
|
|
16424
16879
|
return "";
|
|
16425
16880
|
}
|
|
@@ -16427,8 +16882,8 @@ function encodeClaudeProjectPath(cwd) {
|
|
|
16427
16882
|
}
|
|
16428
16883
|
function resolveClaudeSessionPath({ cwd, claudeSessionID, env = process.env } = {}) {
|
|
16429
16884
|
const projectKey = encodeClaudeProjectPath(cwd);
|
|
16430
|
-
const sessionID =
|
|
16431
|
-
const homeDir =
|
|
16885
|
+
const sessionID = normalizeString25(claudeSessionID);
|
|
16886
|
+
const homeDir = normalizeString25(env?.HOME);
|
|
16432
16887
|
if (!projectKey || !sessionID || !homeDir) {
|
|
16433
16888
|
return "";
|
|
16434
16889
|
}
|
|
@@ -16451,228 +16906,6 @@ var init_claude_session_store = __esm({
|
|
|
16451
16906
|
}
|
|
16452
16907
|
});
|
|
16453
16908
|
|
|
16454
|
-
// server/daemon/control-command-handler.js
|
|
16455
|
-
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
16456
|
-
function normalizeString25(value) {
|
|
16457
|
-
return String(value ?? "").trim();
|
|
16458
|
-
}
|
|
16459
|
-
function defaultFormatBindingSummary(binding) {
|
|
16460
|
-
if (!binding) {
|
|
16461
|
-
return "\u5F53\u524D\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u7ED1\u5B9A\u76EE\u5F55\u3002";
|
|
16462
|
-
}
|
|
16463
|
-
const lines = [
|
|
16464
|
-
`Aibot \u4F1A\u8BDD: ${binding.aibot_session_id}`,
|
|
16465
|
-
`Claude \u4F1A\u8BDD: ${binding.claude_session_id}`,
|
|
16466
|
-
`\u76EE\u5F55: ${binding.cwd}`,
|
|
16467
|
-
`Worker \u72B6\u6001: ${binding.worker_status}`,
|
|
16468
|
-
`\u53EF\u7528\u6027\u8BC4\u4F30: ${formatWorkerResponseAssessment(binding)}`
|
|
16469
|
-
];
|
|
16470
|
-
if (normalizeString25(binding.worker_response_reason)) {
|
|
16471
|
-
lines.push(`\u8BC4\u4F30\u539F\u56E0: ${normalizeString25(binding.worker_response_reason)}`);
|
|
16472
|
-
}
|
|
16473
|
-
return lines.join("\n");
|
|
16474
|
-
}
|
|
16475
|
-
function defaultBuildMissingBindingCardOptions() {
|
|
16476
|
-
return {
|
|
16477
|
-
summaryText: "\u5F53\u524D\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u7ED1\u5B9A\u76EE\u5F55\u3002",
|
|
16478
|
-
detailText: "\u53D1\u9001 open <\u76EE\u5F55> \u6765\u521B\u5EFA\u4F1A\u8BDD\u3002"
|
|
16479
|
-
};
|
|
16480
|
-
}
|
|
16481
|
-
function defaultFormatRuntimeError(error, fallback = "\u5904\u7406\u5931\u8D25\u3002") {
|
|
16482
|
-
const message = normalizeString25(error?.message || error);
|
|
16483
|
-
return message || fallback;
|
|
16484
|
-
}
|
|
16485
|
-
var DaemonControlCommandHandler;
|
|
16486
|
-
var init_control_command_handler = __esm({
|
|
16487
|
-
"server/daemon/control-command-handler.js"() {
|
|
16488
|
-
init_daemon_paths();
|
|
16489
|
-
init_worker_state();
|
|
16490
|
-
DaemonControlCommandHandler = class {
|
|
16491
|
-
constructor({
|
|
16492
|
-
env = process.env,
|
|
16493
|
-
bindingRegistry,
|
|
16494
|
-
workerProcessManager,
|
|
16495
|
-
bridgeServer,
|
|
16496
|
-
ensureWorker,
|
|
16497
|
-
respond,
|
|
16498
|
-
respondWithOpenWorkspaceCard,
|
|
16499
|
-
ensureDirectoryExists: ensureDirectoryExists2,
|
|
16500
|
-
formatBindingSummary: formatBindingSummary2 = defaultFormatBindingSummary,
|
|
16501
|
-
buildMissingBindingCardOptions: buildMissingBindingCardOptions2 = defaultBuildMissingBindingCardOptions,
|
|
16502
|
-
formatRuntimeError: formatRuntimeError2 = defaultFormatRuntimeError
|
|
16503
|
-
} = {}) {
|
|
16504
|
-
this.env = env;
|
|
16505
|
-
this.bindingRegistry = bindingRegistry;
|
|
16506
|
-
this.workerProcessManager = workerProcessManager;
|
|
16507
|
-
this.bridgeServer = bridgeServer;
|
|
16508
|
-
this.ensureWorker = ensureWorker;
|
|
16509
|
-
this.respond = respond;
|
|
16510
|
-
this.respondWithOpenWorkspaceCard = respondWithOpenWorkspaceCard;
|
|
16511
|
-
this.ensureDirectoryExists = ensureDirectoryExists2;
|
|
16512
|
-
this.formatBindingSummary = formatBindingSummary2;
|
|
16513
|
-
this.buildMissingBindingCardOptions = buildMissingBindingCardOptions2;
|
|
16514
|
-
this.formatRuntimeError = formatRuntimeError2;
|
|
16515
|
-
}
|
|
16516
|
-
async handleOpenCommand(event, parsed) {
|
|
16517
|
-
const cwd = normalizeString25(parsed.args.cwd);
|
|
16518
|
-
await this.ensureDirectoryExists(cwd);
|
|
16519
|
-
const existing = this.bindingRegistry.getByAibotSessionID(event.session_id);
|
|
16520
|
-
if (existing) {
|
|
16521
|
-
if (existing.cwd !== cwd) {
|
|
16522
|
-
await this.respond(
|
|
16523
|
-
event,
|
|
16524
|
-
`\u5F53\u524D\u4F1A\u8BDD\u5DF2\u7ECF\u56FA\u5B9A\u7ED1\u5B9A\u76EE\u5F55\uFF0C\u4E0D\u80FD\u6539\u6210\u65B0\u76EE\u5F55\u3002
|
|
16525
|
-
|
|
16526
|
-
${this.formatBindingSummary(existing)}`,
|
|
16527
|
-
{ reply_source: "daemon_control_open_reject" }
|
|
16528
|
-
);
|
|
16529
|
-
return;
|
|
16530
|
-
}
|
|
16531
|
-
await this.ensureWorker(existing, { ignoreAuthCooldown: true });
|
|
16532
|
-
await this.respond(
|
|
16533
|
-
event,
|
|
16534
|
-
`\u5F53\u524D\u4F1A\u8BDD\u5DF2\u7ECF\u7ED1\u5B9A\uFF0C\u5DF2\u6309\u539F\u76EE\u5F55\u6062\u590D\u6216\u4FDD\u6301\u539F\u4F1A\u8BDD\u3002
|
|
16535
|
-
|
|
16536
|
-
${this.formatBindingSummary(existing)}`,
|
|
16537
|
-
{ reply_source: "daemon_control_open_existing" }
|
|
16538
|
-
);
|
|
16539
|
-
return;
|
|
16540
|
-
}
|
|
16541
|
-
const workerID = randomUUID6();
|
|
16542
|
-
const claudeSessionID = randomUUID6();
|
|
16543
|
-
const pluginDataDir = resolveWorkerPluginDataDir(event.session_id, this.env);
|
|
16544
|
-
const created = await this.bindingRegistry.createBinding({
|
|
16545
|
-
aibot_session_id: event.session_id,
|
|
16546
|
-
claude_session_id: claudeSessionID,
|
|
16547
|
-
cwd,
|
|
16548
|
-
worker_id: workerID,
|
|
16549
|
-
worker_status: "starting",
|
|
16550
|
-
plugin_data_dir: pluginDataDir,
|
|
16551
|
-
created_at: Date.now(),
|
|
16552
|
-
updated_at: Date.now(),
|
|
16553
|
-
last_started_at: Date.now(),
|
|
16554
|
-
last_stopped_at: 0
|
|
16555
|
-
});
|
|
16556
|
-
await this.workerProcessManager.spawnWorker({
|
|
16557
|
-
aibotSessionID: created.aibot_session_id,
|
|
16558
|
-
cwd: created.cwd,
|
|
16559
|
-
pluginDataDir: created.plugin_data_dir,
|
|
16560
|
-
claudeSessionID: created.claude_session_id,
|
|
16561
|
-
workerID: created.worker_id,
|
|
16562
|
-
bridgeURL: this.bridgeServer.getURL(),
|
|
16563
|
-
bridgeToken: this.bridgeServer.token
|
|
16564
|
-
});
|
|
16565
|
-
await this.respond(
|
|
16566
|
-
event,
|
|
16567
|
-
`\u5DF2\u65B0\u5EFA\u76EE\u5F55\u4F1A\u8BDD\u3002
|
|
16568
|
-
|
|
16569
|
-
${this.formatBindingSummary(created)}`,
|
|
16570
|
-
{ reply_source: "daemon_control_open_created" }
|
|
16571
|
-
);
|
|
16572
|
-
}
|
|
16573
|
-
async handleStatusCommand(event) {
|
|
16574
|
-
const binding = this.bindingRegistry.getByAibotSessionID(event.session_id);
|
|
16575
|
-
if (!binding) {
|
|
16576
|
-
await this.respondWithOpenWorkspaceCard(event, {
|
|
16577
|
-
...this.buildMissingBindingCardOptions(),
|
|
16578
|
-
replySource: "daemon_control_status_missing"
|
|
16579
|
-
});
|
|
16580
|
-
return;
|
|
16581
|
-
}
|
|
16582
|
-
await this.respond(event, this.formatBindingSummary(binding), {
|
|
16583
|
-
reply_source: "daemon_control_status"
|
|
16584
|
-
});
|
|
16585
|
-
}
|
|
16586
|
-
async handleWhereCommand(event) {
|
|
16587
|
-
const binding = this.bindingRegistry.getByAibotSessionID(event.session_id);
|
|
16588
|
-
if (!binding) {
|
|
16589
|
-
await this.respondWithOpenWorkspaceCard(event, {
|
|
16590
|
-
...this.buildMissingBindingCardOptions(),
|
|
16591
|
-
replySource: "daemon_control_where_missing"
|
|
16592
|
-
});
|
|
16593
|
-
return;
|
|
16594
|
-
}
|
|
16595
|
-
const text = `\u5F53\u524D\u76EE\u5F55: ${binding.cwd}`;
|
|
16596
|
-
await this.respond(event, text, {
|
|
16597
|
-
reply_source: "daemon_control_where"
|
|
16598
|
-
});
|
|
16599
|
-
}
|
|
16600
|
-
async handleStopCommand(event) {
|
|
16601
|
-
const binding = this.bindingRegistry.getByAibotSessionID(event.session_id);
|
|
16602
|
-
if (!binding) {
|
|
16603
|
-
await this.respondWithOpenWorkspaceCard(event, {
|
|
16604
|
-
...this.buildMissingBindingCardOptions(),
|
|
16605
|
-
replySource: "daemon_control_stop_missing"
|
|
16606
|
-
});
|
|
16607
|
-
return;
|
|
16608
|
-
}
|
|
16609
|
-
if (binding.worker_id) {
|
|
16610
|
-
await this.workerProcessManager.stopWorker(binding.worker_id);
|
|
16611
|
-
}
|
|
16612
|
-
await this.bindingRegistry.markWorkerStopped(event.session_id, {
|
|
16613
|
-
updatedAt: Date.now(),
|
|
16614
|
-
lastStoppedAt: Date.now()
|
|
16615
|
-
});
|
|
16616
|
-
await this.respond(event, `\u5DF2\u505C\u6B62\u5F53\u524D\u4F1A\u8BDD\u5BF9\u5E94\u7684 Claude\u3002
|
|
16617
|
-
|
|
16618
|
-
${this.formatBindingSummary({
|
|
16619
|
-
...binding,
|
|
16620
|
-
worker_status: "stopped"
|
|
16621
|
-
})}`, {
|
|
16622
|
-
reply_source: "daemon_control_stop"
|
|
16623
|
-
});
|
|
16624
|
-
}
|
|
16625
|
-
async handleControlCommand(event, parsed) {
|
|
16626
|
-
if (!parsed.ok) {
|
|
16627
|
-
if (parsed.command === "open") {
|
|
16628
|
-
await this.respondWithOpenWorkspaceCard(event, {
|
|
16629
|
-
summaryText: parsed.error,
|
|
16630
|
-
replySource: "daemon_control_invalid"
|
|
16631
|
-
});
|
|
16632
|
-
return true;
|
|
16633
|
-
}
|
|
16634
|
-
await this.respond(event, parsed.error, {
|
|
16635
|
-
reply_source: "daemon_control_invalid"
|
|
16636
|
-
});
|
|
16637
|
-
return true;
|
|
16638
|
-
}
|
|
16639
|
-
try {
|
|
16640
|
-
switch (parsed.command) {
|
|
16641
|
-
case "open":
|
|
16642
|
-
await this.handleOpenCommand(event, parsed);
|
|
16643
|
-
return true;
|
|
16644
|
-
case "status":
|
|
16645
|
-
await this.handleStatusCommand(event);
|
|
16646
|
-
return true;
|
|
16647
|
-
case "where":
|
|
16648
|
-
await this.handleWhereCommand(event);
|
|
16649
|
-
return true;
|
|
16650
|
-
case "stop":
|
|
16651
|
-
await this.handleStopCommand(event);
|
|
16652
|
-
return true;
|
|
16653
|
-
default:
|
|
16654
|
-
return false;
|
|
16655
|
-
}
|
|
16656
|
-
} catch (error) {
|
|
16657
|
-
const message = this.formatRuntimeError(error, "\u547D\u4EE4\u6267\u884C\u5931\u8D25\u3002");
|
|
16658
|
-
if (parsed.command === "open") {
|
|
16659
|
-
await this.respondWithOpenWorkspaceCard(event, {
|
|
16660
|
-
summaryText: message,
|
|
16661
|
-
detailText: "\u53D1\u9001 open <\u76EE\u5F55> \u6765\u521B\u5EFA\u4F1A\u8BDD\u3002",
|
|
16662
|
-
replySource: "daemon_control_open_error"
|
|
16663
|
-
});
|
|
16664
|
-
return true;
|
|
16665
|
-
}
|
|
16666
|
-
await this.respond(event, message, {
|
|
16667
|
-
reply_source: "daemon_control_error"
|
|
16668
|
-
});
|
|
16669
|
-
return true;
|
|
16670
|
-
}
|
|
16671
|
-
}
|
|
16672
|
-
};
|
|
16673
|
-
}
|
|
16674
|
-
});
|
|
16675
|
-
|
|
16676
16909
|
// server/daemon/worker-health-inspector.js
|
|
16677
16910
|
function normalizeString26(value) {
|
|
16678
16911
|
return String(value ?? "").trim();
|
|
@@ -16930,7 +17163,7 @@ function resolveRecordInFlightActivityAt(record) {
|
|
|
16930
17163
|
const normalizedComposingAt = Number.isFinite(composingAt) && composingAt > 0 ? composingAt : 0;
|
|
16931
17164
|
return Math.max(normalizedUpdatedAt, normalizedComposingAt);
|
|
16932
17165
|
}
|
|
16933
|
-
function
|
|
17166
|
+
function sleep2(ms) {
|
|
16934
17167
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
16935
17168
|
}
|
|
16936
17169
|
var PendingEventOrchestrator;
|
|
@@ -17077,7 +17310,7 @@ var init_pending_event_orchestrator = __esm({
|
|
|
17077
17310
|
error: error instanceof Error ? error.message : String(error)
|
|
17078
17311
|
}, "error");
|
|
17079
17312
|
}
|
|
17080
|
-
await
|
|
17313
|
+
await sleep2(this.retryDelayMs);
|
|
17081
17314
|
const latestBinding = this.bindingRegistry.getByAibotSessionID(normalizedSessionID);
|
|
17082
17315
|
if (!canDeliverToWorker(latestBinding)) {
|
|
17083
17316
|
this.trace({
|
|
@@ -17185,8 +17418,473 @@ var init_session_queue = __esm({
|
|
|
17185
17418
|
delete(sessionID) {
|
|
17186
17419
|
this._queues.delete(String(sessionID ?? "").trim());
|
|
17187
17420
|
}
|
|
17188
|
-
clear() {
|
|
17189
|
-
this._queues.clear();
|
|
17421
|
+
clear() {
|
|
17422
|
+
this._queues.clear();
|
|
17423
|
+
}
|
|
17424
|
+
};
|
|
17425
|
+
}
|
|
17426
|
+
});
|
|
17427
|
+
|
|
17428
|
+
// server/inbound-interaction-action.js
|
|
17429
|
+
import path23 from "node:path";
|
|
17430
|
+
function normalizeString29(value) {
|
|
17431
|
+
return String(value ?? "").trim();
|
|
17432
|
+
}
|
|
17433
|
+
function buildUnmatchedResult() {
|
|
17434
|
+
return {
|
|
17435
|
+
matched: false,
|
|
17436
|
+
ok: false,
|
|
17437
|
+
source: "",
|
|
17438
|
+
action: null,
|
|
17439
|
+
errorCode: "",
|
|
17440
|
+
errorMsg: ""
|
|
17441
|
+
};
|
|
17442
|
+
}
|
|
17443
|
+
function buildErrorResult({
|
|
17444
|
+
source,
|
|
17445
|
+
errorCode,
|
|
17446
|
+
errorMsg
|
|
17447
|
+
} = {}) {
|
|
17448
|
+
return {
|
|
17449
|
+
matched: true,
|
|
17450
|
+
ok: false,
|
|
17451
|
+
source: normalizeString29(source),
|
|
17452
|
+
action: null,
|
|
17453
|
+
errorCode: normalizeString29(errorCode),
|
|
17454
|
+
errorMsg: normalizeString29(errorMsg)
|
|
17455
|
+
};
|
|
17456
|
+
}
|
|
17457
|
+
function buildSuccessResult({
|
|
17458
|
+
source,
|
|
17459
|
+
actionType,
|
|
17460
|
+
params,
|
|
17461
|
+
timeoutMs = 0
|
|
17462
|
+
} = {}) {
|
|
17463
|
+
return {
|
|
17464
|
+
matched: true,
|
|
17465
|
+
ok: true,
|
|
17466
|
+
source: normalizeString29(source),
|
|
17467
|
+
action: {
|
|
17468
|
+
action_type: normalizeString29(actionType),
|
|
17469
|
+
params: params && typeof params === "object" && !Array.isArray(params) ? params : {},
|
|
17470
|
+
timeout_ms: Number.isFinite(Number(timeoutMs)) && Number(timeoutMs) > 0 ? Math.floor(Number(timeoutMs)) : 0
|
|
17471
|
+
},
|
|
17472
|
+
errorCode: "",
|
|
17473
|
+
errorMsg: ""
|
|
17474
|
+
};
|
|
17475
|
+
}
|
|
17476
|
+
function decodeUrlComponentRepeatedly(value) {
|
|
17477
|
+
let current = normalizeString29(value);
|
|
17478
|
+
if (!current) {
|
|
17479
|
+
return "";
|
|
17480
|
+
}
|
|
17481
|
+
for (let index = 0; index < 3; index += 1) {
|
|
17482
|
+
try {
|
|
17483
|
+
const decoded = decodeURIComponent(current);
|
|
17484
|
+
if (decoded === current) {
|
|
17485
|
+
break;
|
|
17486
|
+
}
|
|
17487
|
+
current = decoded;
|
|
17488
|
+
} catch {
|
|
17489
|
+
break;
|
|
17490
|
+
}
|
|
17491
|
+
}
|
|
17492
|
+
return normalizeString29(current);
|
|
17493
|
+
}
|
|
17494
|
+
function extractGrixCardURI(text) {
|
|
17495
|
+
const normalizedText = normalizeString29(text).replace(/&/giu, "&");
|
|
17496
|
+
if (!normalizedText) {
|
|
17497
|
+
return "";
|
|
17498
|
+
}
|
|
17499
|
+
const match = normalizedText.match(/grix:\/\/card\/[^\s)]+/u);
|
|
17500
|
+
return normalizeString29(match?.[0] ?? normalizedText);
|
|
17501
|
+
}
|
|
17502
|
+
function parseGrixCardURI(text) {
|
|
17503
|
+
const rawURI = extractGrixCardURI(text);
|
|
17504
|
+
if (!rawURI) {
|
|
17505
|
+
return null;
|
|
17506
|
+
}
|
|
17507
|
+
let parsed;
|
|
17508
|
+
try {
|
|
17509
|
+
parsed = new URL(rawURI);
|
|
17510
|
+
} catch {
|
|
17511
|
+
return null;
|
|
17512
|
+
}
|
|
17513
|
+
if (parsed.protocol !== "grix:" || normalizeString29(parsed.hostname) !== "card") {
|
|
17514
|
+
return null;
|
|
17515
|
+
}
|
|
17516
|
+
return parsed;
|
|
17517
|
+
}
|
|
17518
|
+
function normalizeResolutionMapEntries(entries) {
|
|
17519
|
+
if (!Array.isArray(entries)) {
|
|
17520
|
+
return [];
|
|
17521
|
+
}
|
|
17522
|
+
return entries.map((entry) => {
|
|
17523
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
17524
|
+
return null;
|
|
17525
|
+
}
|
|
17526
|
+
const key = normalizeString29(entry.key);
|
|
17527
|
+
const value = normalizeString29(entry.value);
|
|
17528
|
+
if (!key || !value) {
|
|
17529
|
+
return null;
|
|
17530
|
+
}
|
|
17531
|
+
return { key, value };
|
|
17532
|
+
}).filter(Boolean);
|
|
17533
|
+
}
|
|
17534
|
+
function parseQuestionReplyPayload(rawPayload) {
|
|
17535
|
+
const decoded = decodeUrlComponentRepeatedly(rawPayload);
|
|
17536
|
+
if (!decoded) {
|
|
17537
|
+
return null;
|
|
17538
|
+
}
|
|
17539
|
+
try {
|
|
17540
|
+
const parsed = JSON.parse(decoded);
|
|
17541
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
17542
|
+
} catch {
|
|
17543
|
+
return null;
|
|
17544
|
+
}
|
|
17545
|
+
}
|
|
17546
|
+
function parseQuestionReplyAction(parsedURI) {
|
|
17547
|
+
const payload = parseQuestionReplyPayload(parsedURI?.searchParams?.get("d"));
|
|
17548
|
+
if (!payload) {
|
|
17549
|
+
return buildErrorResult({
|
|
17550
|
+
source: "grix_card_question_reply",
|
|
17551
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17552
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u5185\u5BB9\u683C\u5F0F\u4E0D\u6B63\u786E\u3002"
|
|
17553
|
+
});
|
|
17554
|
+
}
|
|
17555
|
+
const requestID = normalizeString29(payload.request_id);
|
|
17556
|
+
if (!requestID) {
|
|
17557
|
+
return buildErrorResult({
|
|
17558
|
+
source: "grix_card_question_reply",
|
|
17559
|
+
errorCode: interactionReplyErrorCodes.requestIDRequired,
|
|
17560
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7F3A\u5C11 request_id\u3002"
|
|
17561
|
+
});
|
|
17562
|
+
}
|
|
17563
|
+
const action = normalizeString29(payload.action).toLowerCase();
|
|
17564
|
+
if (action) {
|
|
17565
|
+
if (!["accept", "cancel", "decline"].includes(action)) {
|
|
17566
|
+
return buildErrorResult({
|
|
17567
|
+
source: "grix_card_question_reply",
|
|
17568
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17569
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u52A8\u4F5C\u65E0\u6548\u3002"
|
|
17570
|
+
});
|
|
17571
|
+
}
|
|
17572
|
+
return buildSuccessResult({
|
|
17573
|
+
source: "grix_card_question_reply",
|
|
17574
|
+
actionType: localActionTypes.interactionReply,
|
|
17575
|
+
timeoutMs: 15e3,
|
|
17576
|
+
params: {
|
|
17577
|
+
kind: interactionKinds.elicitation,
|
|
17578
|
+
request_id: requestID,
|
|
17579
|
+
resolution: {
|
|
17580
|
+
type: interactionResolutionTypes.action,
|
|
17581
|
+
value: action
|
|
17582
|
+
}
|
|
17583
|
+
}
|
|
17584
|
+
});
|
|
17585
|
+
}
|
|
17586
|
+
const response = payload.response;
|
|
17587
|
+
if (!response || typeof response !== "object" || Array.isArray(response)) {
|
|
17588
|
+
return buildErrorResult({
|
|
17589
|
+
source: "grix_card_question_reply",
|
|
17590
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17591
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7F3A\u5C11\u7B54\u6848\u5185\u5BB9\u3002"
|
|
17592
|
+
});
|
|
17593
|
+
}
|
|
17594
|
+
const responseType = normalizeString29(response.type).toLowerCase();
|
|
17595
|
+
if (responseType === "single") {
|
|
17596
|
+
const value = normalizeString29(response.value);
|
|
17597
|
+
if (!value) {
|
|
17598
|
+
return buildErrorResult({
|
|
17599
|
+
source: "grix_card_question_reply",
|
|
17600
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17601
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7F3A\u5C11\u7B54\u6848\u5185\u5BB9\u3002"
|
|
17602
|
+
});
|
|
17603
|
+
}
|
|
17604
|
+
return buildSuccessResult({
|
|
17605
|
+
source: "grix_card_question_reply",
|
|
17606
|
+
actionType: localActionTypes.interactionReply,
|
|
17607
|
+
timeoutMs: 15e3,
|
|
17608
|
+
params: {
|
|
17609
|
+
kind: interactionKinds.elicitation,
|
|
17610
|
+
request_id: requestID,
|
|
17611
|
+
resolution: {
|
|
17612
|
+
type: interactionResolutionTypes.text,
|
|
17613
|
+
value
|
|
17614
|
+
}
|
|
17615
|
+
}
|
|
17616
|
+
});
|
|
17617
|
+
}
|
|
17618
|
+
if (responseType === "map") {
|
|
17619
|
+
const entries = normalizeResolutionMapEntries(response.entries);
|
|
17620
|
+
if (entries.length === 0) {
|
|
17621
|
+
return buildErrorResult({
|
|
17622
|
+
source: "grix_card_question_reply",
|
|
17623
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17624
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7F3A\u5C11\u6709\u6548\u7B54\u6848\u3002"
|
|
17625
|
+
});
|
|
17626
|
+
}
|
|
17627
|
+
return buildSuccessResult({
|
|
17628
|
+
source: "grix_card_question_reply",
|
|
17629
|
+
actionType: localActionTypes.interactionReply,
|
|
17630
|
+
timeoutMs: 15e3,
|
|
17631
|
+
params: {
|
|
17632
|
+
kind: interactionKinds.elicitation,
|
|
17633
|
+
request_id: requestID,
|
|
17634
|
+
resolution: {
|
|
17635
|
+
type: interactionResolutionTypes.map,
|
|
17636
|
+
entries
|
|
17637
|
+
}
|
|
17638
|
+
}
|
|
17639
|
+
});
|
|
17640
|
+
}
|
|
17641
|
+
return buildErrorResult({
|
|
17642
|
+
source: "grix_card_question_reply",
|
|
17643
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17644
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7C7B\u578B\u65E0\u6548\u3002"
|
|
17645
|
+
});
|
|
17646
|
+
}
|
|
17647
|
+
function parseOpenSessionAction(parsedURI) {
|
|
17648
|
+
const cwd = decodeUrlComponentRepeatedly(parsedURI?.searchParams?.get("cwd"));
|
|
17649
|
+
if (!cwd) {
|
|
17650
|
+
return buildErrorResult({
|
|
17651
|
+
source: "grix_card_open_session_submit",
|
|
17652
|
+
errorCode: sessionControlErrorCodes.cwdRequired,
|
|
17653
|
+
errorMsg: "\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u65F6\u7F3A\u5C11\u76EE\u5F55\u8DEF\u5F84\u3002"
|
|
17654
|
+
});
|
|
17655
|
+
}
|
|
17656
|
+
return buildSuccessResult({
|
|
17657
|
+
source: "grix_card_open_session_submit",
|
|
17658
|
+
actionType: localActionTypes.sessionControl,
|
|
17659
|
+
params: {
|
|
17660
|
+
verb: "open",
|
|
17661
|
+
cwd: path23.resolve(cwd)
|
|
17662
|
+
}
|
|
17663
|
+
});
|
|
17664
|
+
}
|
|
17665
|
+
function parseInboundInteractionAction(text) {
|
|
17666
|
+
const parsedURI = parseGrixCardURI(text);
|
|
17667
|
+
if (!parsedURI) {
|
|
17668
|
+
return buildUnmatchedResult();
|
|
17669
|
+
}
|
|
17670
|
+
const cardType = normalizeString29(parsedURI.pathname).replace(/^\/+/u, "");
|
|
17671
|
+
if (cardType === "agent_open_session_submit") {
|
|
17672
|
+
return parseOpenSessionAction(parsedURI);
|
|
17673
|
+
}
|
|
17674
|
+
if (cardType === "agent_question_reply") {
|
|
17675
|
+
return parseQuestionReplyAction(parsedURI);
|
|
17676
|
+
}
|
|
17677
|
+
return buildUnmatchedResult();
|
|
17678
|
+
}
|
|
17679
|
+
var init_inbound_interaction_action = __esm({
|
|
17680
|
+
"server/inbound-interaction-action.js"() {
|
|
17681
|
+
init_protocol_contract();
|
|
17682
|
+
}
|
|
17683
|
+
});
|
|
17684
|
+
|
|
17685
|
+
// server/daemon/session-control-action-handler.js
|
|
17686
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
17687
|
+
function normalizeString30(value) {
|
|
17688
|
+
return String(value ?? "").trim();
|
|
17689
|
+
}
|
|
17690
|
+
function buildBindingResult(binding) {
|
|
17691
|
+
return {
|
|
17692
|
+
aibot_session_id: normalizeString30(binding?.aibot_session_id),
|
|
17693
|
+
claude_session_id: normalizeString30(binding?.claude_session_id),
|
|
17694
|
+
cwd: normalizeString30(binding?.cwd),
|
|
17695
|
+
worker_status: normalizeString30(binding?.worker_status)
|
|
17696
|
+
};
|
|
17697
|
+
}
|
|
17698
|
+
function buildSuccessResult2(verb, outcome, binding) {
|
|
17699
|
+
return {
|
|
17700
|
+
status: localActionResultStatuses.ok,
|
|
17701
|
+
result: {
|
|
17702
|
+
domain: resultDomains.sessionControl,
|
|
17703
|
+
verb,
|
|
17704
|
+
outcome,
|
|
17705
|
+
binding: buildBindingResult(binding)
|
|
17706
|
+
}
|
|
17707
|
+
};
|
|
17708
|
+
}
|
|
17709
|
+
function buildFailure(errorCode, errorMsg) {
|
|
17710
|
+
return {
|
|
17711
|
+
status: localActionResultStatuses.failed,
|
|
17712
|
+
errorCode,
|
|
17713
|
+
errorMsg
|
|
17714
|
+
};
|
|
17715
|
+
}
|
|
17716
|
+
var DaemonSessionControlActionHandler;
|
|
17717
|
+
var init_session_control_action_handler = __esm({
|
|
17718
|
+
"server/daemon/session-control-action-handler.js"() {
|
|
17719
|
+
init_protocol_contract();
|
|
17720
|
+
init_daemon_paths();
|
|
17721
|
+
DaemonSessionControlActionHandler = class {
|
|
17722
|
+
constructor({
|
|
17723
|
+
env = process.env,
|
|
17724
|
+
bindingRegistry,
|
|
17725
|
+
workerProcessManager,
|
|
17726
|
+
bridgeServer,
|
|
17727
|
+
ensureWorker,
|
|
17728
|
+
ensureDirectoryExists: ensureDirectoryExists2
|
|
17729
|
+
} = {}) {
|
|
17730
|
+
this.env = env;
|
|
17731
|
+
this.bindingRegistry = bindingRegistry;
|
|
17732
|
+
this.workerProcessManager = workerProcessManager;
|
|
17733
|
+
this.bridgeServer = bridgeServer;
|
|
17734
|
+
this.ensureWorker = ensureWorker;
|
|
17735
|
+
this.ensureDirectoryExists = ensureDirectoryExists2;
|
|
17736
|
+
}
|
|
17737
|
+
getBinding(sessionID) {
|
|
17738
|
+
return this.bindingRegistry.getByAibotSessionID(sessionID);
|
|
17739
|
+
}
|
|
17740
|
+
async createBinding(sessionID, cwd) {
|
|
17741
|
+
const workerID = randomUUID6();
|
|
17742
|
+
const claudeSessionID = randomUUID6();
|
|
17743
|
+
const pluginDataDir = resolveWorkerPluginDataDir(sessionID, this.env);
|
|
17744
|
+
const now = Date.now();
|
|
17745
|
+
const created = await this.bindingRegistry.createBinding({
|
|
17746
|
+
aibot_session_id: sessionID,
|
|
17747
|
+
claude_session_id: claudeSessionID,
|
|
17748
|
+
cwd,
|
|
17749
|
+
worker_id: workerID,
|
|
17750
|
+
worker_status: bindingWorkerStatuses.starting,
|
|
17751
|
+
plugin_data_dir: pluginDataDir,
|
|
17752
|
+
created_at: now,
|
|
17753
|
+
updated_at: now,
|
|
17754
|
+
last_started_at: now,
|
|
17755
|
+
last_stopped_at: 0
|
|
17756
|
+
});
|
|
17757
|
+
await this.workerProcessManager.spawnWorker({
|
|
17758
|
+
aibotSessionID: created.aibot_session_id,
|
|
17759
|
+
cwd: created.cwd,
|
|
17760
|
+
pluginDataDir: created.plugin_data_dir,
|
|
17761
|
+
claudeSessionID: created.claude_session_id,
|
|
17762
|
+
workerID: created.worker_id,
|
|
17763
|
+
bridgeURL: this.bridgeServer.getURL(),
|
|
17764
|
+
bridgeToken: this.bridgeServer.token
|
|
17765
|
+
});
|
|
17766
|
+
return this.getBinding(sessionID) ?? created;
|
|
17767
|
+
}
|
|
17768
|
+
async handleOpen(sessionID, params) {
|
|
17769
|
+
const cwd = normalizeString30(params?.cwd);
|
|
17770
|
+
if (!cwd) {
|
|
17771
|
+
return buildFailure(sessionControlErrorCodes.cwdRequired, "session control cwd is required");
|
|
17772
|
+
}
|
|
17773
|
+
try {
|
|
17774
|
+
await this.ensureDirectoryExists(cwd);
|
|
17775
|
+
} catch (error) {
|
|
17776
|
+
return buildFailure(
|
|
17777
|
+
sessionControlErrorCodes.invalidCwd,
|
|
17778
|
+
normalizeString30(error?.message || error) || "session control cwd is invalid"
|
|
17779
|
+
);
|
|
17780
|
+
}
|
|
17781
|
+
const existing = this.getBinding(sessionID);
|
|
17782
|
+
if (existing) {
|
|
17783
|
+
if (existing.cwd !== cwd) {
|
|
17784
|
+
return buildFailure(
|
|
17785
|
+
sessionControlErrorCodes.rebindForbidden,
|
|
17786
|
+
"session binding cannot be changed to another working directory"
|
|
17787
|
+
);
|
|
17788
|
+
}
|
|
17789
|
+
try {
|
|
17790
|
+
await this.ensureWorker(existing, { ignoreAuthCooldown: true });
|
|
17791
|
+
} catch (error) {
|
|
17792
|
+
return buildFailure(
|
|
17793
|
+
sessionControlErrorCodes.runtimeError,
|
|
17794
|
+
normalizeString30(error?.message || error) || "session control open failed"
|
|
17795
|
+
);
|
|
17796
|
+
}
|
|
17797
|
+
return buildSuccessResult2(sessionControlVerbs.open, sessionControlOutcomes.alreadyBound, this.getBinding(sessionID) ?? existing);
|
|
17798
|
+
}
|
|
17799
|
+
try {
|
|
17800
|
+
const created = await this.createBinding(sessionID, cwd);
|
|
17801
|
+
return buildSuccessResult2(sessionControlVerbs.open, sessionControlOutcomes.opened, created);
|
|
17802
|
+
} catch (error) {
|
|
17803
|
+
return buildFailure(
|
|
17804
|
+
sessionControlErrorCodes.runtimeError,
|
|
17805
|
+
normalizeString30(error?.message || error) || "session control open failed"
|
|
17806
|
+
);
|
|
17807
|
+
}
|
|
17808
|
+
}
|
|
17809
|
+
handleStatus(sessionID) {
|
|
17810
|
+
const binding = this.getBinding(sessionID);
|
|
17811
|
+
if (!binding) {
|
|
17812
|
+
return buildFailure(sessionControlErrorCodes.bindingMissing, "session binding was not found");
|
|
17813
|
+
}
|
|
17814
|
+
return buildSuccessResult2(sessionControlVerbs.status, sessionControlOutcomes.status, binding);
|
|
17815
|
+
}
|
|
17816
|
+
handleWhere(sessionID) {
|
|
17817
|
+
const binding = this.getBinding(sessionID);
|
|
17818
|
+
if (!binding) {
|
|
17819
|
+
return buildFailure(sessionControlErrorCodes.bindingMissing, "session binding was not found");
|
|
17820
|
+
}
|
|
17821
|
+
return buildSuccessResult2(sessionControlVerbs.where, sessionControlOutcomes.where, binding);
|
|
17822
|
+
}
|
|
17823
|
+
async handleStop(sessionID) {
|
|
17824
|
+
const binding = this.getBinding(sessionID);
|
|
17825
|
+
if (!binding) {
|
|
17826
|
+
return buildFailure(sessionControlErrorCodes.bindingMissing, "session binding was not found");
|
|
17827
|
+
}
|
|
17828
|
+
try {
|
|
17829
|
+
if (binding.worker_id) {
|
|
17830
|
+
await this.workerProcessManager.stopWorker(binding.worker_id);
|
|
17831
|
+
}
|
|
17832
|
+
await this.bindingRegistry.markWorkerStopped(sessionID, {
|
|
17833
|
+
updatedAt: Date.now(),
|
|
17834
|
+
lastStoppedAt: Date.now()
|
|
17835
|
+
});
|
|
17836
|
+
} catch (error) {
|
|
17837
|
+
return buildFailure(
|
|
17838
|
+
sessionControlErrorCodes.runtimeError,
|
|
17839
|
+
normalizeString30(error?.message || error) || "session control stop failed"
|
|
17840
|
+
);
|
|
17841
|
+
}
|
|
17842
|
+
return buildSuccessResult2(sessionControlVerbs.stop, sessionControlOutcomes.stopped, this.getBinding(sessionID) ?? {
|
|
17843
|
+
...binding,
|
|
17844
|
+
worker_status: bindingWorkerStatuses.stopped
|
|
17845
|
+
});
|
|
17846
|
+
}
|
|
17847
|
+
async handleLocalAction(action) {
|
|
17848
|
+
if (normalizeString30(action?.action_type) !== localActionTypes.sessionControl) {
|
|
17849
|
+
return {
|
|
17850
|
+
handled: false
|
|
17851
|
+
};
|
|
17852
|
+
}
|
|
17853
|
+
const sessionID = normalizeString30(action?.params?.session_id);
|
|
17854
|
+
if (!sessionID) {
|
|
17855
|
+
return {
|
|
17856
|
+
handled: true,
|
|
17857
|
+
response: buildFailure(localActionErrorCodes.localActionRouteMissing, "local action session_id is required")
|
|
17858
|
+
};
|
|
17859
|
+
}
|
|
17860
|
+
const verb = normalizeString30(action?.params?.verb).toLowerCase();
|
|
17861
|
+
switch (verb) {
|
|
17862
|
+
case sessionControlVerbs.open:
|
|
17863
|
+
return {
|
|
17864
|
+
handled: true,
|
|
17865
|
+
response: await this.handleOpen(sessionID, action.params)
|
|
17866
|
+
};
|
|
17867
|
+
case sessionControlVerbs.status:
|
|
17868
|
+
return {
|
|
17869
|
+
handled: true,
|
|
17870
|
+
response: this.handleStatus(sessionID)
|
|
17871
|
+
};
|
|
17872
|
+
case sessionControlVerbs.where:
|
|
17873
|
+
return {
|
|
17874
|
+
handled: true,
|
|
17875
|
+
response: this.handleWhere(sessionID)
|
|
17876
|
+
};
|
|
17877
|
+
case sessionControlVerbs.stop:
|
|
17878
|
+
return {
|
|
17879
|
+
handled: true,
|
|
17880
|
+
response: await this.handleStop(sessionID)
|
|
17881
|
+
};
|
|
17882
|
+
default:
|
|
17883
|
+
return {
|
|
17884
|
+
handled: true,
|
|
17885
|
+
response: buildFailure(sessionControlErrorCodes.verbInvalid, "session control verb is invalid")
|
|
17886
|
+
};
|
|
17887
|
+
}
|
|
17190
17888
|
}
|
|
17191
17889
|
};
|
|
17192
17890
|
}
|
|
@@ -17194,7 +17892,7 @@ var init_session_queue = __esm({
|
|
|
17194
17892
|
|
|
17195
17893
|
// server/worker-probe.js
|
|
17196
17894
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
17197
|
-
function
|
|
17895
|
+
function normalizeString31(value) {
|
|
17198
17896
|
return String(value ?? "").trim();
|
|
17199
17897
|
}
|
|
17200
17898
|
function buildWorkerPingProbePayload({ sessionID, workerID = "", claudeSessionID = "" } = {}) {
|
|
@@ -17211,7 +17909,7 @@ function buildWorkerPingProbePayload({ sessionID, workerID = "", claudeSessionID
|
|
|
17211
17909
|
return {
|
|
17212
17910
|
event_id: `probe_${probeID}`,
|
|
17213
17911
|
event_type: "user_chat",
|
|
17214
|
-
session_id:
|
|
17912
|
+
session_id: normalizeString31(sessionID),
|
|
17215
17913
|
session_type: "1",
|
|
17216
17914
|
msg_id: `probe_msg_${probeID}`,
|
|
17217
17915
|
sender_id: probeSenderID,
|
|
@@ -17220,13 +17918,13 @@ function buildWorkerPingProbePayload({ sessionID, workerID = "", claudeSessionID
|
|
|
17220
17918
|
msg_type: "1",
|
|
17221
17919
|
content: "ping",
|
|
17222
17920
|
created_at: Date.now(),
|
|
17223
|
-
worker_id:
|
|
17224
|
-
claude_session_id:
|
|
17921
|
+
worker_id: normalizeString31(workerID),
|
|
17922
|
+
claude_session_id: normalizeString31(claudeSessionID),
|
|
17225
17923
|
channel_data: channelData
|
|
17226
17924
|
};
|
|
17227
17925
|
}
|
|
17228
17926
|
function isExpectedWorkerProbeReply(text, expectedReply = "pong") {
|
|
17229
|
-
return
|
|
17927
|
+
return normalizeString31(text).toLowerCase() === normalizeString31(expectedReply).toLowerCase();
|
|
17230
17928
|
}
|
|
17231
17929
|
var probeChannelNamespace, probeSenderID, probeKind, defaultWorkerPingProbeTimeoutMs;
|
|
17232
17930
|
var init_worker_probe = __esm({
|
|
@@ -17240,19 +17938,22 @@ var init_worker_probe = __esm({
|
|
|
17240
17938
|
|
|
17241
17939
|
// server/daemon/runtime.js
|
|
17242
17940
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
17243
|
-
import { stat as
|
|
17244
|
-
function
|
|
17941
|
+
import { stat as stat3 } from "node:fs/promises";
|
|
17942
|
+
function normalizeString32(value) {
|
|
17245
17943
|
return String(value ?? "").trim();
|
|
17246
17944
|
}
|
|
17247
|
-
function
|
|
17945
|
+
function isRecordOnlyMirror(event) {
|
|
17946
|
+
return normalizeString32(event?.mirror_mode) === "record_only";
|
|
17947
|
+
}
|
|
17948
|
+
function sleep3(ms) {
|
|
17248
17949
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17249
17950
|
}
|
|
17250
17951
|
async function ensureDirectoryExists(directoryPath) {
|
|
17251
17952
|
let info;
|
|
17252
17953
|
try {
|
|
17253
|
-
info = await
|
|
17954
|
+
info = await stat3(directoryPath);
|
|
17254
17955
|
} catch (error) {
|
|
17255
|
-
const code =
|
|
17956
|
+
const code = normalizeString32(error?.code);
|
|
17256
17957
|
if (code === "ENOENT") {
|
|
17257
17958
|
throw new Error("\u6307\u5B9A\u8DEF\u5F84\u4E0D\u5B58\u5728\u3002");
|
|
17258
17959
|
}
|
|
@@ -17265,44 +17966,6 @@ async function ensureDirectoryExists(directoryPath) {
|
|
|
17265
17966
|
throw new Error("\u6307\u5B9A\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\u3002");
|
|
17266
17967
|
}
|
|
17267
17968
|
}
|
|
17268
|
-
function formatBindingSummary(binding) {
|
|
17269
|
-
if (!binding) {
|
|
17270
|
-
return "\u5F53\u524D\u4F1A\u8BDD\u8FD8\u6CA1\u6709\u7ED1\u5B9A\u76EE\u5F55\u3002";
|
|
17271
|
-
}
|
|
17272
|
-
const lines = [
|
|
17273
|
-
`Aibot \u4F1A\u8BDD: ${binding.aibot_session_id}`,
|
|
17274
|
-
`Claude \u4F1A\u8BDD: ${binding.claude_session_id}`,
|
|
17275
|
-
`\u76EE\u5F55: ${binding.cwd}`,
|
|
17276
|
-
`Worker \u72B6\u6001: ${binding.worker_status}`,
|
|
17277
|
-
`\u53EF\u7528\u6027\u8BC4\u4F30: ${formatWorkerResponseAssessment(binding)}`
|
|
17278
|
-
];
|
|
17279
|
-
const responseReason = normalizeString30(binding?.worker_response_reason);
|
|
17280
|
-
if (responseReason) {
|
|
17281
|
-
lines.push(`\u8BC4\u4F30\u539F\u56E0: ${responseReason}`);
|
|
17282
|
-
}
|
|
17283
|
-
const lastReplyAt = formatStatusTimestamp(binding?.worker_last_reply_at);
|
|
17284
|
-
if (lastReplyAt) {
|
|
17285
|
-
lines.push(`\u6700\u8FD1\u6210\u529F: ${lastReplyAt}`);
|
|
17286
|
-
}
|
|
17287
|
-
const lastFailureAt = formatStatusTimestamp(binding?.worker_last_failure_at);
|
|
17288
|
-
if (lastFailureAt) {
|
|
17289
|
-
const failureCode = normalizeString30(binding?.worker_last_failure_code);
|
|
17290
|
-
lines.push(`\u6700\u8FD1\u5931\u8D25: ${lastFailureAt}${failureCode ? ` (${failureCode})` : ""}`);
|
|
17291
|
-
}
|
|
17292
|
-
const lastHookAt = formatStatusTimestamp(binding?.worker_last_hook_event_at);
|
|
17293
|
-
if (lastHookAt) {
|
|
17294
|
-
const lastHookSummary = summarizeHookSignalEvent({
|
|
17295
|
-
event_id: binding?.worker_last_hook_event_id,
|
|
17296
|
-
hook_event_name: binding?.worker_last_hook_event_name,
|
|
17297
|
-
event_at: binding?.worker_last_hook_event_at,
|
|
17298
|
-
detail: binding?.worker_last_hook_event_detail
|
|
17299
|
-
});
|
|
17300
|
-
if (lastHookSummary) {
|
|
17301
|
-
lines.push(`\u6700\u8FD1 Hook: ${lastHookSummary} @ ${lastHookAt}`);
|
|
17302
|
-
}
|
|
17303
|
-
}
|
|
17304
|
-
return lines.join("\n");
|
|
17305
|
-
}
|
|
17306
17969
|
function buildInterruptedEventNotice() {
|
|
17307
17970
|
return "Claude \u521A\u521A\u4E2D\u65AD\u4E86\uFF0C\u8FD9\u6761\u6D88\u606F\u6CA1\u6709\u5904\u7406\u5B8C\u6210\u3002\u8BF7\u518D\u53D1\u4E00\u6B21\u3002";
|
|
17308
17971
|
}
|
|
@@ -17312,46 +17975,147 @@ function buildAuthLoginRequiredEventNotice() {
|
|
|
17312
17975
|
function buildUsageLimitReachedEventNotice() {
|
|
17313
17976
|
return "Claude \u5F53\u524D\u989D\u5EA6\u5DF2\u7528\u5B8C\uFF0C\u6CA1\u6CD5\u7EE7\u7EED\u56DE\u590D\u3002\u8BF7\u5148\u5728 Claude \u91CC\u5904\u7406\u989D\u5EA6\u63D0\u793A\uFF0C\u7136\u540E\u628A\u8FD9\u6761\u6D88\u606F\u518D\u53D1\u4E00\u6B21\u3002";
|
|
17314
17977
|
}
|
|
17978
|
+
function buildBindingMissingEventNotice() {
|
|
17979
|
+
return buildAgentOpenSessionCardLink({
|
|
17980
|
+
summaryText: "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002",
|
|
17981
|
+
detailText: "\u5148\u63D0\u4EA4\u4E00\u4E2A\u5DE5\u4F5C\u76EE\u5F55\uFF0CClaude \u624D\u80FD\u7EE7\u7EED\u5904\u7406\u6D88\u606F\u3002\u63D0\u4EA4\u540E\uFF0C\u628A\u521A\u624D\u90A3\u6761\u6D88\u606F\u518D\u53D1\u4E00\u6B21\u3002"
|
|
17982
|
+
});
|
|
17983
|
+
}
|
|
17984
|
+
function buildSessionControlOpenCardNotice({
|
|
17985
|
+
summaryText = "",
|
|
17986
|
+
detailText = "",
|
|
17987
|
+
initialCwd = ""
|
|
17988
|
+
} = {}) {
|
|
17989
|
+
return buildAgentOpenSessionCardLink({
|
|
17990
|
+
summaryText: normalizeString32(summaryText) || "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002",
|
|
17991
|
+
detailText: normalizeString32(detailText) || "\u5148\u63D0\u4EA4\u4E00\u4E2A\u5DE5\u4F5C\u76EE\u5F55\uFF0CClaude \u624D\u80FD\u7EE7\u7EED\u5904\u7406\u6D88\u606F\u3002",
|
|
17992
|
+
initialCwd
|
|
17993
|
+
});
|
|
17994
|
+
}
|
|
17995
|
+
function formatSessionControlBindingSummary(binding) {
|
|
17996
|
+
const normalizedBinding = binding ?? {};
|
|
17997
|
+
const cwd = normalizeString32(normalizedBinding.cwd);
|
|
17998
|
+
const workerStatus = normalizeString32(normalizedBinding.worker_status);
|
|
17999
|
+
const lines = [];
|
|
18000
|
+
if (cwd) {
|
|
18001
|
+
lines.push(`\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}`);
|
|
18002
|
+
}
|
|
18003
|
+
if (workerStatus) {
|
|
18004
|
+
lines.push(`\u72B6\u6001\uFF1A${workerStatus}`);
|
|
18005
|
+
}
|
|
18006
|
+
return lines.join("\n");
|
|
18007
|
+
}
|
|
18008
|
+
function buildSessionControlSuccessNotice(result) {
|
|
18009
|
+
const verb = normalizeString32(result?.verb);
|
|
18010
|
+
const outcome = normalizeString32(result?.outcome);
|
|
18011
|
+
const binding = result?.binding ?? {};
|
|
18012
|
+
const summary = formatSessionControlBindingSummary(binding);
|
|
18013
|
+
if (verb === sessionControlVerbs.open) {
|
|
18014
|
+
const title = outcome === sessionControlOutcomes.alreadyBound ? "\u5F53\u524D\u5BF9\u8BDD\u5DF2\u7ECF\u6253\u5F00\u8FD9\u4E2A\u5DE5\u4F5C\u76EE\u5F55\u3002" : "\u5DF2\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18015
|
+
return summary ? `${title}
|
|
18016
|
+
|
|
18017
|
+
${summary}` : title;
|
|
18018
|
+
}
|
|
18019
|
+
if (verb === sessionControlVerbs.status) {
|
|
18020
|
+
return summary || "\u5F53\u524D\u5BF9\u8BDD\u5DF2\u7ECF\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18021
|
+
}
|
|
18022
|
+
if (verb === sessionControlVerbs.where) {
|
|
18023
|
+
const cwd = normalizeString32(binding.cwd);
|
|
18024
|
+
return cwd ? `\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}` : "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18025
|
+
}
|
|
18026
|
+
if (verb === sessionControlVerbs.stop) {
|
|
18027
|
+
return summary ? `\u5DF2\u505C\u6B62\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F1A\u8BDD\u3002
|
|
18028
|
+
|
|
18029
|
+
${summary}` : "\u5DF2\u505C\u6B62\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F1A\u8BDD\u3002";
|
|
18030
|
+
}
|
|
18031
|
+
return "\u5DE5\u4F5C\u76EE\u5F55\u64CD\u4F5C\u5DF2\u5B8C\u6210\u3002";
|
|
18032
|
+
}
|
|
18033
|
+
function buildSessionControlFailureNotice({
|
|
18034
|
+
errorCode = "",
|
|
18035
|
+
errorMsg = ""
|
|
18036
|
+
} = {}) {
|
|
18037
|
+
const normalizedErrorCode = normalizeString32(errorCode);
|
|
18038
|
+
const normalizedErrorMsg = normalizeString32(errorMsg);
|
|
18039
|
+
if (normalizedErrorCode === sessionControlErrorCodes.rebindForbidden) {
|
|
18040
|
+
return normalizedErrorMsg || "\u5F53\u524D\u5BF9\u8BDD\u5DF2\u7ECF\u56FA\u5B9A\u7ED1\u5B9A\u5230\u53E6\u4E00\u4E2A\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18041
|
+
}
|
|
18042
|
+
if (normalizedErrorCode === sessionControlErrorCodes.verbInvalid) {
|
|
18043
|
+
return normalizedErrorMsg || "\u547D\u4EE4\u683C\u5F0F\u4E0D\u6B63\u786E\u3002";
|
|
18044
|
+
}
|
|
18045
|
+
return normalizedErrorMsg || "\u5DE5\u4F5C\u76EE\u5F55\u64CD\u4F5C\u5931\u8D25\u3002";
|
|
18046
|
+
}
|
|
18047
|
+
function buildSessionControlCardSummary(errorCode, errorMsg) {
|
|
18048
|
+
const normalizedErrorCode = normalizeString32(errorCode);
|
|
18049
|
+
const normalizedErrorMsg = normalizeString32(errorMsg);
|
|
18050
|
+
if (normalizedErrorCode === sessionControlErrorCodes.bindingMissing) {
|
|
18051
|
+
return "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18052
|
+
}
|
|
18053
|
+
if (normalizedErrorCode === sessionControlErrorCodes.invalidCwd) {
|
|
18054
|
+
return normalizedErrorMsg || "\u6307\u5B9A\u8DEF\u5F84\u4E0D\u53EF\u7528\u3002";
|
|
18055
|
+
}
|
|
18056
|
+
if (normalizedErrorCode === sessionControlErrorCodes.cwdRequired) {
|
|
18057
|
+
return normalizedErrorMsg || "\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u65F6\u7F3A\u5C11\u76EE\u5F55\u8DEF\u5F84\u3002";
|
|
18058
|
+
}
|
|
18059
|
+
return normalizedErrorMsg || "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18060
|
+
}
|
|
18061
|
+
function buildInteractionReplyFailureNotice({
|
|
18062
|
+
errorCode = "",
|
|
18063
|
+
errorMsg = ""
|
|
18064
|
+
} = {}) {
|
|
18065
|
+
const normalizedErrorCode = normalizeString32(errorCode);
|
|
18066
|
+
const normalizedErrorMsg = normalizeString32(errorMsg);
|
|
18067
|
+
if (normalizedErrorCode === interactionReplyErrorCodes.requestNotPending) {
|
|
18068
|
+
return "\u8FD9\u6761\u4EA4\u4E92\u5DF2\u7ECF\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u3002";
|
|
18069
|
+
}
|
|
18070
|
+
if (normalizedErrorCode === interactionReplyErrorCodes.requestNotFound) {
|
|
18071
|
+
return "\u6CA1\u6709\u627E\u5230\u5BF9\u5E94\u7684\u4EA4\u4E92\u8BF7\u6C42\u3002";
|
|
18072
|
+
}
|
|
18073
|
+
if (normalizedErrorCode === interactionReplyErrorCodes.requestIDRequired || normalizedErrorCode === interactionReplyErrorCodes.resolutionInvalid) {
|
|
18074
|
+
return normalizedErrorMsg || "\u4EA4\u4E92\u56DE\u590D\u683C\u5F0F\u4E0D\u6B63\u786E\u3002";
|
|
18075
|
+
}
|
|
18076
|
+
if (normalizedErrorCode === "local_action_delivery_failed") {
|
|
18077
|
+
return "Claude \u8FD8\u6CA1\u51C6\u5907\u597D\u5904\u7406\u8FD9\u6761\u4EA4\u4E92\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";
|
|
18078
|
+
}
|
|
18079
|
+
if (normalizedErrorCode === "local_action_result_timeout") {
|
|
18080
|
+
return "\u4EA4\u4E92\u56DE\u590D\u63D0\u4EA4\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";
|
|
18081
|
+
}
|
|
18082
|
+
return normalizedErrorMsg || "\u4EA4\u4E92\u56DE\u590D\u63D0\u4EA4\u5931\u8D25\u3002";
|
|
18083
|
+
}
|
|
17315
18084
|
function buildWorkerStartupFailedNotice() {
|
|
17316
18085
|
return "Claude \u542F\u52A8\u672A\u5B8C\u6210\uFF0C\u6D88\u606F\u672A\u53D1\u9001\u3002\u8BF7\u6267\u884C grix-claude restart \u540E\u91CD\u8BD5\u3002";
|
|
17317
18086
|
}
|
|
17318
18087
|
function buildUsageLimitFailureOptions() {
|
|
17319
18088
|
return {
|
|
17320
18089
|
noticeText: buildUsageLimitReachedEventNotice(),
|
|
17321
|
-
replySource: "daemon_worker_usage_limit_reached",
|
|
17322
18090
|
resultCode: "claude_usage_limit_reached",
|
|
17323
18091
|
resultMessage: "claude usage limit reached; user action required"
|
|
17324
18092
|
};
|
|
17325
18093
|
}
|
|
17326
|
-
function
|
|
18094
|
+
function normalizeLocalActionPayload(rawPayload) {
|
|
17327
18095
|
return {
|
|
17328
|
-
|
|
17329
|
-
|
|
18096
|
+
action_id: normalizeString32(rawPayload?.action_id),
|
|
18097
|
+
event_id: normalizeString32(rawPayload?.event_id),
|
|
18098
|
+
action_type: normalizeString32(rawPayload?.action_type),
|
|
18099
|
+
params: rawPayload?.params && typeof rawPayload.params === "object" && !Array.isArray(rawPayload.params) ? rawPayload.params : {},
|
|
18100
|
+
timeout_ms: normalizeNonNegativeInt(rawPayload?.timeout_ms, 0)
|
|
17330
18101
|
};
|
|
17331
18102
|
}
|
|
17332
18103
|
function withWorkerLaunchFailure(binding, code) {
|
|
17333
18104
|
return {
|
|
17334
18105
|
...binding ?? {},
|
|
17335
|
-
worker_launch_failure:
|
|
18106
|
+
worker_launch_failure: normalizeString32(code)
|
|
17336
18107
|
};
|
|
17337
18108
|
}
|
|
17338
18109
|
function formatRuntimeError(error, fallback = "\u5904\u7406\u5931\u8D25\u3002") {
|
|
17339
|
-
const message =
|
|
18110
|
+
const message = normalizeString32(error?.message || error);
|
|
17340
18111
|
return message || fallback;
|
|
17341
18112
|
}
|
|
17342
|
-
function formatStatusTimestamp(value) {
|
|
17343
|
-
const numeric = Number(value);
|
|
17344
|
-
if (!Number.isFinite(numeric) || numeric <= 0) {
|
|
17345
|
-
return "";
|
|
17346
|
-
}
|
|
17347
|
-
return new Date(numeric).toISOString();
|
|
17348
|
-
}
|
|
17349
18113
|
function normalizeHookSignalRecord(input) {
|
|
17350
18114
|
if (!input || typeof input !== "object") {
|
|
17351
18115
|
return null;
|
|
17352
18116
|
}
|
|
17353
|
-
const eventID =
|
|
17354
|
-
const eventName =
|
|
18117
|
+
const eventID = normalizeString32(input.event_id);
|
|
18118
|
+
const eventName = normalizeString32(input.hook_event_name);
|
|
17355
18119
|
const eventAt = Number(input.event_at ?? 0);
|
|
17356
18120
|
if (!eventID || !eventName || !Number.isFinite(eventAt) || eventAt <= 0) {
|
|
17357
18121
|
return null;
|
|
@@ -17360,7 +18124,7 @@ function normalizeHookSignalRecord(input) {
|
|
|
17360
18124
|
event_id: eventID,
|
|
17361
18125
|
hook_event_name: eventName,
|
|
17362
18126
|
event_at: Math.floor(eventAt),
|
|
17363
|
-
detail:
|
|
18127
|
+
detail: normalizeString32(input.detail)
|
|
17364
18128
|
};
|
|
17365
18129
|
}
|
|
17366
18130
|
function listHookSignalRecords(pingPayload) {
|
|
@@ -17386,12 +18150,12 @@ function buildPingActivityTraceFields(pingPayload = {}) {
|
|
|
17386
18150
|
reported_mcp_ready: pingPayload?.mcp_ready === true ? true : pingPayload?.mcp_ready === false ? false : "",
|
|
17387
18151
|
reported_mcp_last_activity_at: normalizeNonNegativeInt(pingPayload?.mcp_last_activity_at, 0),
|
|
17388
18152
|
reported_hook_last_activity_at: normalizeNonNegativeInt(pingPayload?.hook_last_activity_at, 0),
|
|
17389
|
-
reported_hook_event_name:
|
|
18153
|
+
reported_hook_event_name: normalizeString32(pingPayload?.hook_latest_event?.hook_event_name)
|
|
17390
18154
|
};
|
|
17391
18155
|
}
|
|
17392
18156
|
function buildMcpHealthTraceFields(mcpHealth = {}) {
|
|
17393
18157
|
return {
|
|
17394
|
-
mcp_health_reason:
|
|
18158
|
+
mcp_health_reason: normalizeString32(mcpHealth?.reason),
|
|
17395
18159
|
mcp_health_idle_ms: normalizeNonNegativeInt(mcpHealth?.idleMs, 0),
|
|
17396
18160
|
inflight_event_count: normalizeNonNegativeInt(mcpHealth?.inFlightCount, 0),
|
|
17397
18161
|
latest_event_activity_at: normalizeNonNegativeInt(mcpHealth?.latestInteractionAt, 0),
|
|
@@ -17400,7 +18164,7 @@ function buildMcpHealthTraceFields(mcpHealth = {}) {
|
|
|
17400
18164
|
}
|
|
17401
18165
|
function buildMcpResultTimeoutTraceFields(details = {}) {
|
|
17402
18166
|
return {
|
|
17403
|
-
delivery_state:
|
|
18167
|
+
delivery_state: normalizeString32(details?.deliveryState),
|
|
17404
18168
|
record_updated_at: normalizeNonNegativeInt(details?.updatedAt, 0),
|
|
17405
18169
|
record_last_composing_at: normalizeNonNegativeInt(details?.lastComposingAt, 0),
|
|
17406
18170
|
record_interaction_at: normalizeNonNegativeInt(details?.recordInteractionAt, 0),
|
|
@@ -17416,6 +18180,9 @@ function normalizeNonNegativeInt(value, fallbackValue) {
|
|
|
17416
18180
|
}
|
|
17417
18181
|
return Math.max(0, Math.floor(numeric));
|
|
17418
18182
|
}
|
|
18183
|
+
function isSyntheticLocalActionID(actionID) {
|
|
18184
|
+
return normalizeString32(actionID).startsWith(syntheticLocalActionIDPrefix);
|
|
18185
|
+
}
|
|
17419
18186
|
function resolveExpectedWorkerPid(binding, runtime) {
|
|
17420
18187
|
const bindingPid = Number(binding?.worker_pid ?? 0);
|
|
17421
18188
|
if (Number.isFinite(bindingPid) && bindingPid > 0) {
|
|
@@ -17435,15 +18202,15 @@ function resolveExpectedIdentityWorkerPid(binding) {
|
|
|
17435
18202
|
return 0;
|
|
17436
18203
|
}
|
|
17437
18204
|
function buildRevokeDedupKey({ eventID = "", sessionID = "", msgID = "" } = {}) {
|
|
17438
|
-
const normalizedSessionID =
|
|
17439
|
-
const normalizedMsgID =
|
|
18205
|
+
const normalizedSessionID = normalizeString32(sessionID);
|
|
18206
|
+
const normalizedMsgID = normalizeString32(msgID);
|
|
17440
18207
|
if (normalizedSessionID && normalizedMsgID) {
|
|
17441
18208
|
return `${normalizedSessionID}:${normalizedMsgID}`;
|
|
17442
18209
|
}
|
|
17443
|
-
return
|
|
18210
|
+
return normalizeString32(eventID);
|
|
17444
18211
|
}
|
|
17445
18212
|
function classifyWorkerEventResult(payload) {
|
|
17446
|
-
const code =
|
|
18213
|
+
const code = normalizeString32(payload?.code);
|
|
17447
18214
|
if (workerResponseFailureCodes.has(code)) {
|
|
17448
18215
|
return {
|
|
17449
18216
|
state: "failed",
|
|
@@ -17453,27 +18220,28 @@ function classifyWorkerEventResult(payload) {
|
|
|
17453
18220
|
}
|
|
17454
18221
|
return {
|
|
17455
18222
|
state: "healthy",
|
|
17456
|
-
reason: code ||
|
|
18223
|
+
reason: code || normalizeString32(payload?.status) || "worker_event_result_observed",
|
|
17457
18224
|
failureCode: ""
|
|
17458
18225
|
};
|
|
17459
18226
|
}
|
|
17460
|
-
var defaultDeliveredInFlightMaxAgeMs, defaultWorkerControlProbeFailureThreshold, defaultMcpInteractionIdleMs, defaultMcpResultTimeoutMs, defaultRecentRevokeRetentionMs, defaultAuthFailureCooldownMs, defaultWorkerPingProbeRetentionMs, workerResponseFailureCodes, DaemonRuntime;
|
|
18227
|
+
var defaultDeliveredInFlightMaxAgeMs, defaultWorkerControlProbeFailureThreshold, defaultMcpInteractionIdleMs, defaultMcpResultTimeoutMs, defaultRecentRevokeRetentionMs, defaultAuthFailureCooldownMs, defaultWorkerPingProbeRetentionMs, syntheticLocalActionIDPrefix, workerResponseFailureCodes, DaemonRuntime;
|
|
17461
18228
|
var init_runtime = __esm({
|
|
17462
18229
|
"server/daemon/runtime.js"() {
|
|
17463
|
-
|
|
18230
|
+
init_agent_open_session_card();
|
|
17464
18231
|
init_inbound_event_meta();
|
|
17465
18232
|
init_message_delivery_store();
|
|
17466
18233
|
init_worker_control_client();
|
|
17467
|
-
init_control_card();
|
|
17468
18234
|
init_claude_session_store();
|
|
17469
|
-
init_control_command_handler();
|
|
17470
18235
|
init_worker_health_inspector();
|
|
17471
18236
|
init_pending_event_orchestrator();
|
|
17472
18237
|
init_session_queue();
|
|
17473
18238
|
init_process_control();
|
|
17474
18239
|
init_hook_signal_store();
|
|
18240
|
+
init_inbound_interaction_action();
|
|
18241
|
+
init_session_control_action_handler();
|
|
17475
18242
|
init_worker_state();
|
|
17476
18243
|
init_worker_probe();
|
|
18244
|
+
init_protocol_contract();
|
|
17477
18245
|
defaultDeliveredInFlightMaxAgeMs = 60 * 1e3;
|
|
17478
18246
|
defaultWorkerControlProbeFailureThreshold = 3;
|
|
17479
18247
|
defaultMcpInteractionIdleMs = 15 * 60 * 1e3;
|
|
@@ -17481,6 +18249,7 @@ var init_runtime = __esm({
|
|
|
17481
18249
|
defaultRecentRevokeRetentionMs = 24 * 60 * 60 * 1e3;
|
|
17482
18250
|
defaultAuthFailureCooldownMs = 60 * 1e3;
|
|
17483
18251
|
defaultWorkerPingProbeRetentionMs = 60 * 1e3;
|
|
18252
|
+
syntheticLocalActionIDPrefix = "synthetic-local-action:";
|
|
17484
18253
|
workerResponseFailureCodes = /* @__PURE__ */ new Set([
|
|
17485
18254
|
"claude_result_timeout",
|
|
17486
18255
|
"claude_usage_limit_reached",
|
|
@@ -17562,6 +18331,7 @@ var init_runtime = __esm({
|
|
|
17562
18331
|
this.workerControlProbeFailures = /* @__PURE__ */ new Map();
|
|
17563
18332
|
this.workerPingProbeRecords = /* @__PURE__ */ new Map();
|
|
17564
18333
|
this.workerPingProbeInFlight = /* @__PURE__ */ new Map();
|
|
18334
|
+
this.syntheticLocalActionWaiters = /* @__PURE__ */ new Map();
|
|
17565
18335
|
this.pendingEventWorkerLogCursors = /* @__PURE__ */ new Map();
|
|
17566
18336
|
this.ensureWorkerInFlight = /* @__PURE__ */ new Map();
|
|
17567
18337
|
this.resumeAuthRecoveryInFlight = /* @__PURE__ */ new Map();
|
|
@@ -17569,18 +18339,13 @@ var init_runtime = __esm({
|
|
|
17569
18339
|
this.sessionQueues = new SessionQueueRegistry(
|
|
17570
18340
|
(fields, level) => this.trace(fields, level)
|
|
17571
18341
|
);
|
|
17572
|
-
this.
|
|
18342
|
+
this.sessionControlActionHandler = new DaemonSessionControlActionHandler({
|
|
17573
18343
|
env: this.env,
|
|
17574
18344
|
bindingRegistry: this.bindingRegistry,
|
|
17575
18345
|
workerProcessManager: this.workerProcessManager,
|
|
17576
18346
|
bridgeServer: this.bridgeServer,
|
|
17577
18347
|
ensureWorker: async (...args) => this.ensureWorker(...args),
|
|
17578
|
-
|
|
17579
|
-
respondWithOpenWorkspaceCard: async (event, options = {}, result = {}) => this.respondWithOpenWorkspaceCard(event, options, result),
|
|
17580
|
-
ensureDirectoryExists,
|
|
17581
|
-
formatBindingSummary,
|
|
17582
|
-
buildMissingBindingCardOptions,
|
|
17583
|
-
formatRuntimeError
|
|
18348
|
+
ensureDirectoryExists
|
|
17584
18349
|
});
|
|
17585
18350
|
this.pendingEventOrchestrator = new PendingEventOrchestrator({
|
|
17586
18351
|
messageDeliveryStore: this.messageDeliveryStore,
|
|
@@ -17612,18 +18377,18 @@ var init_runtime = __esm({
|
|
|
17612
18377
|
}, { level });
|
|
17613
18378
|
}
|
|
17614
18379
|
async handleWorkerProcessExit({ workerID, aibotSessionID, exitCode, exitSignal }) {
|
|
17615
|
-
const sessionID =
|
|
18380
|
+
const sessionID = normalizeString32(aibotSessionID);
|
|
17616
18381
|
if (!sessionID) return;
|
|
17617
18382
|
const queue = this.sessionQueues.ensure(sessionID);
|
|
17618
18383
|
queue.run(async () => {
|
|
17619
18384
|
const binding = this.bindingRegistry.getByAibotSessionID(sessionID);
|
|
17620
|
-
if (!binding ||
|
|
18385
|
+
if (!binding || normalizeString32(binding.worker_id) !== normalizeString32(workerID)) {
|
|
17621
18386
|
return;
|
|
17622
18387
|
}
|
|
17623
18388
|
if (binding.worker_status === "stopped" || binding.worker_status === "failed") {
|
|
17624
18389
|
return;
|
|
17625
18390
|
}
|
|
17626
|
-
let signal =
|
|
18391
|
+
let signal = normalizeString32(exitSignal) || "wrapper_exited";
|
|
17627
18392
|
const hasAuthError = await this.workerProcessManager?.hasAuthLoginRequiredError?.(workerID);
|
|
17628
18393
|
if (hasAuthError) {
|
|
17629
18394
|
const runtime = this.workerProcessManager?.getWorkerRuntime?.(workerID);
|
|
@@ -17661,14 +18426,14 @@ var init_runtime = __esm({
|
|
|
17661
18426
|
});
|
|
17662
18427
|
}
|
|
17663
18428
|
getWorkerPingProbeRecord(eventID) {
|
|
17664
|
-
const normalizedEventID =
|
|
18429
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
17665
18430
|
if (!normalizedEventID) {
|
|
17666
18431
|
return null;
|
|
17667
18432
|
}
|
|
17668
18433
|
return this.workerPingProbeRecords.get(normalizedEventID) ?? null;
|
|
17669
18434
|
}
|
|
17670
18435
|
clearWorkerPingProbeRecord(eventID) {
|
|
17671
|
-
const normalizedEventID =
|
|
18436
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
17672
18437
|
if (!normalizedEventID) {
|
|
17673
18438
|
return;
|
|
17674
18439
|
}
|
|
@@ -17737,9 +18502,9 @@ var init_runtime = __esm({
|
|
|
17737
18502
|
event_id: record.eventID,
|
|
17738
18503
|
response_state: nextBinding?.worker_response_state,
|
|
17739
18504
|
response_reason: nextBinding?.worker_response_reason,
|
|
17740
|
-
terminal_status:
|
|
17741
|
-
terminal_code:
|
|
17742
|
-
probe_text:
|
|
18505
|
+
terminal_status: normalizeString32(payload?.status),
|
|
18506
|
+
terminal_code: normalizeString32(payload?.code),
|
|
18507
|
+
probe_text: normalizeString32(payload?.text)
|
|
17743
18508
|
}, level);
|
|
17744
18509
|
this.scheduleWorkerPingProbeRecordCleanup(record.eventID);
|
|
17745
18510
|
record.resolve?.(nextBinding);
|
|
@@ -17747,7 +18512,7 @@ var init_runtime = __esm({
|
|
|
17747
18512
|
return nextBinding;
|
|
17748
18513
|
}
|
|
17749
18514
|
async ensureWorkerPingProbe(binding) {
|
|
17750
|
-
const sessionID =
|
|
18515
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
17751
18516
|
if (!sessionID) {
|
|
17752
18517
|
return binding;
|
|
17753
18518
|
}
|
|
@@ -17769,7 +18534,7 @@ var init_runtime = __esm({
|
|
|
17769
18534
|
}
|
|
17770
18535
|
}
|
|
17771
18536
|
async runWorkerPingProbe(binding) {
|
|
17772
|
-
const sessionID =
|
|
18537
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
17773
18538
|
if (!sessionID || !hasReadyWorkerBridge(binding)) {
|
|
17774
18539
|
return binding;
|
|
17775
18540
|
}
|
|
@@ -17808,8 +18573,8 @@ var init_runtime = __esm({
|
|
|
17808
18573
|
const record = {
|
|
17809
18574
|
eventID: probePayload.event_id,
|
|
17810
18575
|
sessionID,
|
|
17811
|
-
workerID:
|
|
17812
|
-
claudeSessionID:
|
|
18576
|
+
workerID: normalizeString32(probingBinding?.worker_id),
|
|
18577
|
+
claudeSessionID: normalizeString32(probingBinding?.claude_session_id),
|
|
17813
18578
|
expectedReply: "pong",
|
|
17814
18579
|
state: "probing",
|
|
17815
18580
|
settled: false,
|
|
@@ -17849,7 +18614,7 @@ var init_runtime = __esm({
|
|
|
17849
18614
|
worker_id: record.workerID,
|
|
17850
18615
|
claude_session_id: record.claudeSessionID,
|
|
17851
18616
|
event_id: record.eventID,
|
|
17852
|
-
fallback_reason:
|
|
18617
|
+
fallback_reason: normalizeString32(record.lastControlPingReason) || "control_ping_unavailable"
|
|
17853
18618
|
}, "debug");
|
|
17854
18619
|
try {
|
|
17855
18620
|
await client.deliverEvent(probePayload);
|
|
@@ -17895,10 +18660,10 @@ var init_runtime = __esm({
|
|
|
17895
18660
|
}, "debug");
|
|
17896
18661
|
return null;
|
|
17897
18662
|
}
|
|
17898
|
-
const expectedWorkerID =
|
|
17899
|
-
const expectedClaudeSessionID =
|
|
17900
|
-
const currentWorkerID =
|
|
17901
|
-
const currentClaudeSessionID =
|
|
18663
|
+
const expectedWorkerID = normalizeString32(record?.workerID);
|
|
18664
|
+
const expectedClaudeSessionID = normalizeString32(record?.claudeSessionID);
|
|
18665
|
+
const currentWorkerID = normalizeString32(currentBinding?.worker_id);
|
|
18666
|
+
const currentClaudeSessionID = normalizeString32(currentBinding?.claude_session_id);
|
|
17902
18667
|
if (expectedWorkerID && currentWorkerID && expectedWorkerID !== currentWorkerID) {
|
|
17903
18668
|
record.lastControlPingReason = "worker_id_mismatch";
|
|
17904
18669
|
this.trace({
|
|
@@ -17940,26 +18705,26 @@ var init_runtime = __esm({
|
|
|
17940
18705
|
const runtime = this.workerProcessManager?.getWorkerRuntime?.(currentWorkerID);
|
|
17941
18706
|
const identityHealth = this.inspectWorkerIdentityHealth(currentBinding, runtime, pingPayload);
|
|
17942
18707
|
if (!identityHealth.ok) {
|
|
17943
|
-
record.lastControlPingReason =
|
|
18708
|
+
record.lastControlPingReason = normalizeString32(identityHealth.reason) || "identity_unhealthy";
|
|
17944
18709
|
this.trace({
|
|
17945
18710
|
stage: "worker_ping_probe_control_ping_unhealthy",
|
|
17946
18711
|
...traceContext,
|
|
17947
18712
|
reason: record.lastControlPingReason,
|
|
17948
18713
|
expected_pid: normalizeNonNegativeInt(identityHealth.expectedPid, 0),
|
|
17949
18714
|
reported_pid: normalizeNonNegativeInt(identityHealth.reportedPid, 0),
|
|
17950
|
-
expected_worker_id:
|
|
17951
|
-
reported_worker_id:
|
|
17952
|
-
expected_session_id:
|
|
17953
|
-
reported_session_id:
|
|
17954
|
-
expected_claude_session_id:
|
|
17955
|
-
reported_claude_session_id:
|
|
18715
|
+
expected_worker_id: normalizeString32(identityHealth.expectedWorkerID),
|
|
18716
|
+
reported_worker_id: normalizeString32(identityHealth.reportedWorkerID),
|
|
18717
|
+
expected_session_id: normalizeString32(identityHealth.expectedSessionID),
|
|
18718
|
+
reported_session_id: normalizeString32(identityHealth.reportedSessionID),
|
|
18719
|
+
expected_claude_session_id: normalizeString32(identityHealth.expectedClaudeSessionID),
|
|
18720
|
+
reported_claude_session_id: normalizeString32(identityHealth.reportedClaudeSessionID),
|
|
17956
18721
|
...buildPingActivityTraceFields(pingPayload)
|
|
17957
18722
|
});
|
|
17958
18723
|
return null;
|
|
17959
18724
|
}
|
|
17960
18725
|
const mcpHealth = this.inspectMcpInteractionHealth(currentBinding, pingPayload);
|
|
17961
18726
|
if (!mcpHealth.ok) {
|
|
17962
|
-
record.lastControlPingReason =
|
|
18727
|
+
record.lastControlPingReason = normalizeString32(mcpHealth.reason) || "mcp_unhealthy";
|
|
17963
18728
|
this.trace({
|
|
17964
18729
|
stage: "worker_ping_probe_control_ping_unhealthy",
|
|
17965
18730
|
...traceContext,
|
|
@@ -18020,7 +18785,7 @@ var init_runtime = __esm({
|
|
|
18020
18785
|
if (record.settled) {
|
|
18021
18786
|
return { handled: true, ack: { msg_id: `probe_${record.eventID}` } };
|
|
18022
18787
|
}
|
|
18023
|
-
const replyText =
|
|
18788
|
+
const replyText = normalizeString32(payload?.text);
|
|
18024
18789
|
if (isExpectedWorkerProbeReply(replyText, record.expectedReply)) {
|
|
18025
18790
|
await this.updateWorkerPingProbeOutcome(record, {
|
|
18026
18791
|
state: "healthy",
|
|
@@ -18044,8 +18809,8 @@ var init_runtime = __esm({
|
|
|
18044
18809
|
return { handled: false };
|
|
18045
18810
|
}
|
|
18046
18811
|
if (!record.settled) {
|
|
18047
|
-
const status =
|
|
18048
|
-
const code =
|
|
18812
|
+
const status = normalizeString32(payload?.status);
|
|
18813
|
+
const code = normalizeString32(payload?.code);
|
|
18049
18814
|
if (record.timeoutRecovering && status !== "responded" && code === "claude_result_timeout") {
|
|
18050
18815
|
this.trace({
|
|
18051
18816
|
stage: "worker_ping_probe_event_result_ignored_timeout_during_recovery",
|
|
@@ -18084,6 +18849,9 @@ var init_runtime = __esm({
|
|
|
18084
18849
|
this.clearWorkerPingProbeRecord(eventID);
|
|
18085
18850
|
}
|
|
18086
18851
|
this.workerPingProbeInFlight.clear();
|
|
18852
|
+
for (const actionID of [...this.syntheticLocalActionWaiters.keys()]) {
|
|
18853
|
+
this.clearSyntheticLocalActionWaiter(actionID);
|
|
18854
|
+
}
|
|
18087
18855
|
this.ensureWorkerInFlight.clear();
|
|
18088
18856
|
this.resumeAuthRecoveryInFlight.clear();
|
|
18089
18857
|
this.lastAuthRecoverySpawnAt.clear();
|
|
@@ -18120,8 +18888,8 @@ var init_runtime = __esm({
|
|
|
18120
18888
|
event_id: event.event_id,
|
|
18121
18889
|
status
|
|
18122
18890
|
};
|
|
18123
|
-
const normalizedCode =
|
|
18124
|
-
const normalizedMsg =
|
|
18891
|
+
const normalizedCode = normalizeString32(code);
|
|
18892
|
+
const normalizedMsg = normalizeString32(msg);
|
|
18125
18893
|
if (normalizedCode) {
|
|
18126
18894
|
payload.code = normalizedCode;
|
|
18127
18895
|
}
|
|
@@ -18142,26 +18910,278 @@ var init_runtime = __esm({
|
|
|
18142
18910
|
this.complete(event, result);
|
|
18143
18911
|
return response;
|
|
18144
18912
|
}
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
const
|
|
18152
|
-
|
|
18913
|
+
createSyntheticLocalActionWaiter(actionID, sessionID, timeoutMs) {
|
|
18914
|
+
const normalizedActionID = normalizeString32(actionID);
|
|
18915
|
+
const normalizedSessionID = normalizeString32(sessionID);
|
|
18916
|
+
const effectiveTimeoutMs = Math.max(1, normalizeNonNegativeInt(timeoutMs, 15e3));
|
|
18917
|
+
let resolvePromise = () => {
|
|
18918
|
+
};
|
|
18919
|
+
const promise = new Promise((resolve) => {
|
|
18920
|
+
resolvePromise = resolve;
|
|
18921
|
+
});
|
|
18922
|
+
const timer = setTimeout(() => {
|
|
18923
|
+
if (!this.syntheticLocalActionWaiters.has(normalizedActionID)) {
|
|
18924
|
+
return;
|
|
18925
|
+
}
|
|
18926
|
+
this.syntheticLocalActionWaiters.delete(normalizedActionID);
|
|
18927
|
+
resolvePromise({
|
|
18928
|
+
status: localActionResultStatuses.failed,
|
|
18929
|
+
result: void 0,
|
|
18930
|
+
errorCode: "local_action_result_timeout",
|
|
18931
|
+
errorMsg: "worker local action result timed out"
|
|
18932
|
+
});
|
|
18933
|
+
}, effectiveTimeoutMs);
|
|
18934
|
+
timer.unref?.();
|
|
18935
|
+
this.syntheticLocalActionWaiters.set(normalizedActionID, {
|
|
18936
|
+
sessionID: normalizedSessionID,
|
|
18937
|
+
resolve: resolvePromise,
|
|
18938
|
+
timer
|
|
18939
|
+
});
|
|
18940
|
+
return promise;
|
|
18941
|
+
}
|
|
18942
|
+
clearSyntheticLocalActionWaiter(actionID) {
|
|
18943
|
+
const normalizedActionID = normalizeString32(actionID);
|
|
18944
|
+
const pending = this.syntheticLocalActionWaiters.get(normalizedActionID);
|
|
18945
|
+
if (!pending) {
|
|
18946
|
+
return null;
|
|
18947
|
+
}
|
|
18948
|
+
clearTimeout(pending.timer);
|
|
18949
|
+
this.syntheticLocalActionWaiters.delete(normalizedActionID);
|
|
18950
|
+
return pending;
|
|
18951
|
+
}
|
|
18952
|
+
resolveSyntheticLocalActionWaiter(actionID, result) {
|
|
18953
|
+
const pending = this.clearSyntheticLocalActionWaiter(actionID);
|
|
18954
|
+
if (!pending) {
|
|
18955
|
+
return false;
|
|
18956
|
+
}
|
|
18957
|
+
pending.resolve(result);
|
|
18958
|
+
return true;
|
|
18959
|
+
}
|
|
18960
|
+
async observeWorkerLocalActionResult(payload) {
|
|
18961
|
+
const actionID = normalizeString32(payload?.action_id);
|
|
18962
|
+
if (!actionID) {
|
|
18963
|
+
return { handled: false };
|
|
18964
|
+
}
|
|
18965
|
+
const pending = this.syntheticLocalActionWaiters.get(actionID);
|
|
18966
|
+
if (!pending) {
|
|
18967
|
+
if (isSyntheticLocalActionID(actionID)) {
|
|
18968
|
+
this.trace({
|
|
18969
|
+
stage: "synthetic_local_action_result_ignored_late",
|
|
18970
|
+
action_id: actionID,
|
|
18971
|
+
session_id: this.resolveObservedSessionID(payload),
|
|
18972
|
+
worker_id: payload?.worker_id,
|
|
18973
|
+
claude_session_id: payload?.claude_session_id
|
|
18974
|
+
});
|
|
18975
|
+
return { handled: true };
|
|
18976
|
+
}
|
|
18977
|
+
return { handled: false };
|
|
18978
|
+
}
|
|
18979
|
+
const binding = this.bindingRegistry.getByAibotSessionID(pending.sessionID);
|
|
18980
|
+
if (binding && this.shouldIgnoreObservedWorker(binding, payload)) {
|
|
18981
|
+
this.trace({
|
|
18982
|
+
stage: "synthetic_local_action_result_ignored",
|
|
18983
|
+
action_id: actionID,
|
|
18984
|
+
session_id: pending.sessionID,
|
|
18985
|
+
worker_id: payload?.worker_id,
|
|
18986
|
+
claude_session_id: payload?.claude_session_id
|
|
18987
|
+
});
|
|
18988
|
+
return { handled: true };
|
|
18989
|
+
}
|
|
18990
|
+
this.trace({
|
|
18991
|
+
stage: "synthetic_local_action_result_observed",
|
|
18992
|
+
action_id: actionID,
|
|
18993
|
+
session_id: pending.sessionID,
|
|
18994
|
+
status: payload?.status,
|
|
18995
|
+
worker_id: payload?.worker_id
|
|
18996
|
+
});
|
|
18997
|
+
this.resolveSyntheticLocalActionWaiter(actionID, {
|
|
18998
|
+
status: normalizeString32(payload?.status) || localActionResultStatuses.failed,
|
|
18999
|
+
result: payload?.result,
|
|
19000
|
+
errorCode: normalizeString32(payload?.error_code),
|
|
19001
|
+
errorMsg: normalizeString32(payload?.error_msg)
|
|
19002
|
+
});
|
|
19003
|
+
return { handled: true };
|
|
19004
|
+
}
|
|
19005
|
+
async runSyntheticWorkerLocalAction(event, action) {
|
|
19006
|
+
const normalizedActionType = normalizeString32(action?.action_type);
|
|
19007
|
+
const params = action?.params && typeof action.params === "object" && !Array.isArray(action.params) ? action.params : {};
|
|
19008
|
+
const sessionID = normalizeString32(params.session_id) || normalizeString32(event?.session_id);
|
|
19009
|
+
if (!sessionID) {
|
|
19010
|
+
return {
|
|
19011
|
+
status: localActionResultStatuses.failed,
|
|
19012
|
+
result: void 0,
|
|
19013
|
+
errorCode: localActionErrorCodes.localActionRouteMissing,
|
|
19014
|
+
errorMsg: "local action session_id is required"
|
|
19015
|
+
};
|
|
19016
|
+
}
|
|
19017
|
+
const timeoutMs = Math.max(1, normalizeNonNegativeInt(action?.timeout_ms, 15e3));
|
|
19018
|
+
const actionID = `${syntheticLocalActionIDPrefix}${event?.event_id || randomUUID8()}:${randomUUID8()}`;
|
|
19019
|
+
const payload = {
|
|
19020
|
+
action_id: actionID,
|
|
19021
|
+
event_id: normalizeString32(event?.event_id),
|
|
19022
|
+
action_type: normalizedActionType,
|
|
19023
|
+
params: {
|
|
19024
|
+
...params,
|
|
19025
|
+
session_id: sessionID
|
|
19026
|
+
},
|
|
19027
|
+
timeout_ms: timeoutMs
|
|
19028
|
+
};
|
|
19029
|
+
const waitPromise = this.createSyntheticLocalActionWaiter(actionID, sessionID, timeoutMs);
|
|
19030
|
+
try {
|
|
19031
|
+
const routedBinding = await this.deliverWithRecovery(
|
|
19032
|
+
sessionID,
|
|
19033
|
+
payload,
|
|
19034
|
+
this.deliverLocalActionToWorker
|
|
19035
|
+
);
|
|
19036
|
+
if (routedBinding && canDeliverToWorker(routedBinding)) {
|
|
19037
|
+
return waitPromise;
|
|
19038
|
+
}
|
|
19039
|
+
this.resolveSyntheticLocalActionWaiter(actionID, {
|
|
19040
|
+
status: localActionResultStatuses.failed,
|
|
19041
|
+
result: void 0,
|
|
19042
|
+
errorCode: "local_action_delivery_failed",
|
|
19043
|
+
errorMsg: "worker is not ready for local action delivery"
|
|
19044
|
+
});
|
|
19045
|
+
return waitPromise;
|
|
19046
|
+
} catch (error) {
|
|
19047
|
+
this.resolveSyntheticLocalActionWaiter(actionID, {
|
|
19048
|
+
status: localActionResultStatuses.failed,
|
|
19049
|
+
result: void 0,
|
|
19050
|
+
errorCode: "local_action_delivery_failed",
|
|
19051
|
+
errorMsg: normalizeString32(error?.message || error) || "worker local action delivery failed"
|
|
19052
|
+
});
|
|
19053
|
+
return waitPromise;
|
|
19054
|
+
}
|
|
19055
|
+
}
|
|
19056
|
+
async handleSyntheticSessionControlEvent(event, action) {
|
|
19057
|
+
const params = action?.params && typeof action.params === "object" && !Array.isArray(action.params) ? action.params : {};
|
|
19058
|
+
const sessionControlResult = await this.sessionControlActionHandler.handleLocalAction({
|
|
19059
|
+
action_type: localActionTypes.sessionControl,
|
|
19060
|
+
params: {
|
|
19061
|
+
...params,
|
|
19062
|
+
session_id: event.session_id
|
|
19063
|
+
}
|
|
19064
|
+
});
|
|
19065
|
+
if (!sessionControlResult?.handled) {
|
|
19066
|
+
return false;
|
|
19067
|
+
}
|
|
19068
|
+
const response = sessionControlResult.response ?? {};
|
|
19069
|
+
const result = response.result ?? {};
|
|
19070
|
+
if (response.status === localActionResultStatuses.ok && normalizeString32(result.domain) === resultDomains.sessionControl) {
|
|
19071
|
+
await this.respond(event, buildSessionControlSuccessNotice(result), {}, {
|
|
19072
|
+
status: "responded"
|
|
19073
|
+
});
|
|
19074
|
+
return true;
|
|
19075
|
+
}
|
|
19076
|
+
const errorCode = normalizeString32(response.errorCode);
|
|
19077
|
+
const errorMsg = normalizeString32(response.errorMsg);
|
|
19078
|
+
if (errorCode === sessionControlErrorCodes.cwdRequired || errorCode === sessionControlErrorCodes.invalidCwd || errorCode === sessionControlErrorCodes.bindingMissing) {
|
|
19079
|
+
await this.respond(
|
|
19080
|
+
event,
|
|
19081
|
+
buildSessionControlOpenCardNotice({
|
|
19082
|
+
summaryText: buildSessionControlCardSummary(errorCode, errorMsg),
|
|
19083
|
+
initialCwd: normalizeString32(params.cwd)
|
|
19084
|
+
}),
|
|
19085
|
+
{},
|
|
19086
|
+
{
|
|
19087
|
+
status: "responded",
|
|
19088
|
+
code: errorCode,
|
|
19089
|
+
msg: errorMsg
|
|
19090
|
+
}
|
|
19091
|
+
);
|
|
19092
|
+
return true;
|
|
19093
|
+
}
|
|
19094
|
+
await this.respond(
|
|
18153
19095
|
event,
|
|
18154
|
-
|
|
19096
|
+
buildSessionControlFailureNotice({
|
|
19097
|
+
errorCode,
|
|
19098
|
+
errorMsg
|
|
19099
|
+
}),
|
|
19100
|
+
{},
|
|
18155
19101
|
{
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18162
|
-
|
|
18163
|
-
|
|
19102
|
+
status: "responded",
|
|
19103
|
+
code: errorCode,
|
|
19104
|
+
msg: errorMsg
|
|
19105
|
+
}
|
|
19106
|
+
);
|
|
19107
|
+
return true;
|
|
19108
|
+
}
|
|
19109
|
+
async handleSyntheticInteractionReplyEvent(event, action) {
|
|
19110
|
+
const actionResult = await this.runSyntheticWorkerLocalAction(event, action);
|
|
19111
|
+
if (normalizeString32(actionResult?.status) === localActionResultStatuses.ok) {
|
|
19112
|
+
this.complete(event, {
|
|
19113
|
+
status: "responded"
|
|
19114
|
+
});
|
|
19115
|
+
return true;
|
|
19116
|
+
}
|
|
19117
|
+
const errorCode = normalizeString32(actionResult?.errorCode);
|
|
19118
|
+
const errorMsg = normalizeString32(actionResult?.errorMsg);
|
|
19119
|
+
await this.respond(
|
|
19120
|
+
event,
|
|
19121
|
+
buildInteractionReplyFailureNotice({
|
|
19122
|
+
errorCode,
|
|
19123
|
+
errorMsg
|
|
19124
|
+
}),
|
|
19125
|
+
{},
|
|
19126
|
+
{
|
|
19127
|
+
status: "responded",
|
|
19128
|
+
code: errorCode,
|
|
19129
|
+
msg: errorMsg
|
|
19130
|
+
}
|
|
18164
19131
|
);
|
|
19132
|
+
return true;
|
|
19133
|
+
}
|
|
19134
|
+
async handleInteractionActionEvent(event) {
|
|
19135
|
+
const parsed = parseInboundInteractionAction(event.content);
|
|
19136
|
+
if (!parsed.matched) {
|
|
19137
|
+
return false;
|
|
19138
|
+
}
|
|
19139
|
+
this.trace({
|
|
19140
|
+
stage: "interaction_action_received",
|
|
19141
|
+
event_id: event.event_id,
|
|
19142
|
+
session_id: event.session_id,
|
|
19143
|
+
source: parsed.source,
|
|
19144
|
+
action_type: parsed.action?.action_type,
|
|
19145
|
+
ok: parsed.ok === true
|
|
19146
|
+
});
|
|
19147
|
+
if (!parsed.ok) {
|
|
19148
|
+
if (parsed.errorCode === sessionControlErrorCodes.cwdRequired) {
|
|
19149
|
+
await this.respond(
|
|
19150
|
+
event,
|
|
19151
|
+
buildSessionControlOpenCardNotice({
|
|
19152
|
+
summaryText: buildSessionControlCardSummary(parsed.errorCode, parsed.errorMsg)
|
|
19153
|
+
}),
|
|
19154
|
+
{},
|
|
19155
|
+
{
|
|
19156
|
+
status: "responded",
|
|
19157
|
+
code: parsed.errorCode,
|
|
19158
|
+
msg: parsed.errorMsg
|
|
19159
|
+
}
|
|
19160
|
+
);
|
|
19161
|
+
return true;
|
|
19162
|
+
}
|
|
19163
|
+
await this.respond(
|
|
19164
|
+
event,
|
|
19165
|
+
buildInteractionReplyFailureNotice({
|
|
19166
|
+
errorCode: parsed.errorCode,
|
|
19167
|
+
errorMsg: parsed.errorMsg
|
|
19168
|
+
}),
|
|
19169
|
+
{},
|
|
19170
|
+
{
|
|
19171
|
+
status: "responded",
|
|
19172
|
+
code: parsed.errorCode,
|
|
19173
|
+
msg: parsed.errorMsg
|
|
19174
|
+
}
|
|
19175
|
+
);
|
|
19176
|
+
return true;
|
|
19177
|
+
}
|
|
19178
|
+
if (normalizeString32(parsed.action?.action_type) === localActionTypes.sessionControl) {
|
|
19179
|
+
return this.handleSyntheticSessionControlEvent(event, parsed.action);
|
|
19180
|
+
}
|
|
19181
|
+
if (normalizeString32(parsed.action?.action_type) === localActionTypes.interactionReply) {
|
|
19182
|
+
return this.handleSyntheticInteractionReplyEvent(event, parsed.action);
|
|
19183
|
+
}
|
|
19184
|
+
return false;
|
|
18165
19185
|
}
|
|
18166
19186
|
ack(event) {
|
|
18167
19187
|
this.aibotClient.ackEvent(event.event_id, {
|
|
@@ -18177,8 +19197,8 @@ var init_runtime = __esm({
|
|
|
18177
19197
|
});
|
|
18178
19198
|
}
|
|
18179
19199
|
async shouldResumeClaudeSession(binding) {
|
|
18180
|
-
const claudeSessionID =
|
|
18181
|
-
const cwd =
|
|
19200
|
+
const claudeSessionID = normalizeString32(binding?.claude_session_id);
|
|
19201
|
+
const cwd = normalizeString32(binding?.cwd);
|
|
18182
19202
|
if (!claudeSessionID || !cwd) {
|
|
18183
19203
|
return false;
|
|
18184
19204
|
}
|
|
@@ -18198,19 +19218,19 @@ var init_runtime = __esm({
|
|
|
18198
19218
|
if (this.authFailureCooldownMs <= 0) {
|
|
18199
19219
|
return null;
|
|
18200
19220
|
}
|
|
18201
|
-
const normalizedStatus =
|
|
19221
|
+
const normalizedStatus = normalizeString32(binding?.worker_status);
|
|
18202
19222
|
if (normalizedStatus !== "stopped" && normalizedStatus !== "failed") {
|
|
18203
19223
|
return null;
|
|
18204
19224
|
}
|
|
18205
|
-
const workerID =
|
|
19225
|
+
const workerID = normalizeString32(binding?.worker_id);
|
|
18206
19226
|
if (!workerID) {
|
|
18207
19227
|
return null;
|
|
18208
19228
|
}
|
|
18209
19229
|
const runtime = this.workerProcessManager?.getWorkerRuntime?.(workerID);
|
|
18210
|
-
if (
|
|
19230
|
+
if (normalizeString32(runtime?.status) !== "stopped") {
|
|
18211
19231
|
return null;
|
|
18212
19232
|
}
|
|
18213
|
-
if (
|
|
19233
|
+
if (normalizeString32(runtime?.exit_signal) !== "auth_login_required") {
|
|
18214
19234
|
return null;
|
|
18215
19235
|
}
|
|
18216
19236
|
const runtimeStoppedAt = Number(runtime?.stopped_at ?? 0);
|
|
@@ -18233,7 +19253,7 @@ var init_runtime = __esm({
|
|
|
18233
19253
|
};
|
|
18234
19254
|
}
|
|
18235
19255
|
async ensureWorker(binding, { ignoreAuthCooldown = false } = {}) {
|
|
18236
|
-
const sessionID =
|
|
19256
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
18237
19257
|
if (!sessionID) {
|
|
18238
19258
|
return null;
|
|
18239
19259
|
}
|
|
@@ -18314,7 +19334,7 @@ var init_runtime = __esm({
|
|
|
18314
19334
|
};
|
|
18315
19335
|
}
|
|
18316
19336
|
const currentReadyFailed = hasReadyWorkerBridge(current) && normalizeWorkerResponseState(current?.worker_response_state) === "failed";
|
|
18317
|
-
const workerID2 =
|
|
19337
|
+
const workerID2 = normalizeString32(binding.worker_id);
|
|
18318
19338
|
if (!currentReadyFailed && workerID2) {
|
|
18319
19339
|
const existingRuntime = this.workerProcessManager?.getWorkerRuntime?.(workerID2);
|
|
18320
19340
|
const existingPid = Number(existingRuntime?.pid ?? 0);
|
|
@@ -18393,13 +19413,13 @@ var init_runtime = __esm({
|
|
|
18393
19413
|
if (current && current.worker_status === "ready" && current.worker_control_url && current.worker_control_token) {
|
|
18394
19414
|
return current;
|
|
18395
19415
|
}
|
|
18396
|
-
await
|
|
19416
|
+
await sleep3(intervalMs);
|
|
18397
19417
|
}
|
|
18398
19418
|
return this.bindingRegistry.getByAibotSessionID(aibotSessionID);
|
|
18399
19419
|
}
|
|
18400
19420
|
async resolveWorkerLaunchFailure(binding) {
|
|
18401
|
-
const workerID =
|
|
18402
|
-
const workerStatus =
|
|
19421
|
+
const workerID = normalizeString32(binding?.worker_id);
|
|
19422
|
+
const workerStatus = normalizeString32(binding?.worker_status);
|
|
18403
19423
|
if (!workerID || !["starting", "connected"].includes(workerStatus)) {
|
|
18404
19424
|
return "";
|
|
18405
19425
|
}
|
|
@@ -18433,27 +19453,27 @@ var init_runtime = __esm({
|
|
|
18433
19453
|
if (current2.worker_status === "stopped" || current2.worker_status === "failed") {
|
|
18434
19454
|
return current2;
|
|
18435
19455
|
}
|
|
18436
|
-
await
|
|
19456
|
+
await sleep3(intervalMs);
|
|
18437
19457
|
}
|
|
18438
19458
|
const current = this.bindingRegistry.getByAibotSessionID(aibotSessionID);
|
|
18439
19459
|
const launchFailure = await this.resolveWorkerLaunchFailure(current);
|
|
18440
19460
|
if (launchFailure) {
|
|
18441
19461
|
return withWorkerLaunchFailure(current, launchFailure);
|
|
18442
19462
|
}
|
|
18443
|
-
if (["starting", "connected"].includes(
|
|
19463
|
+
if (["starting", "connected"].includes(normalizeString32(current?.worker_status))) {
|
|
18444
19464
|
return withWorkerLaunchFailure(current, "startup_wait_timeout");
|
|
18445
19465
|
}
|
|
18446
19466
|
return current;
|
|
18447
19467
|
}
|
|
18448
19468
|
clearWorkerControlProbeFailure(workerID) {
|
|
18449
|
-
const normalizedWorkerID =
|
|
19469
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
18450
19470
|
if (!normalizedWorkerID) {
|
|
18451
19471
|
return;
|
|
18452
19472
|
}
|
|
18453
19473
|
this.workerControlProbeFailures.delete(normalizedWorkerID);
|
|
18454
19474
|
}
|
|
18455
19475
|
markWorkerControlProbeFailure(workerID, error, extraFields = {}) {
|
|
18456
|
-
const normalizedWorkerID =
|
|
19476
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
18457
19477
|
if (!normalizedWorkerID) {
|
|
18458
19478
|
return 0;
|
|
18459
19479
|
}
|
|
@@ -18492,22 +19512,22 @@ var init_runtime = __esm({
|
|
|
18492
19512
|
});
|
|
18493
19513
|
}
|
|
18494
19514
|
resolveObservedSessionID(payload = {}) {
|
|
18495
|
-
const explicitSessionID =
|
|
19515
|
+
const explicitSessionID = normalizeString32(payload?.session_id);
|
|
18496
19516
|
if (explicitSessionID) {
|
|
18497
19517
|
return explicitSessionID;
|
|
18498
19518
|
}
|
|
18499
|
-
return
|
|
19519
|
+
return normalizeString32(this.messageDeliveryStore.getRememberedSessionID(payload?.event_id));
|
|
18500
19520
|
}
|
|
18501
19521
|
shouldIgnoreObservedWorker(binding, payload = {}) {
|
|
18502
19522
|
if (!binding) {
|
|
18503
19523
|
return false;
|
|
18504
19524
|
}
|
|
18505
|
-
const observedWorkerID =
|
|
18506
|
-
if (observedWorkerID &&
|
|
19525
|
+
const observedWorkerID = normalizeString32(payload?.worker_id);
|
|
19526
|
+
if (observedWorkerID && normalizeString32(binding?.worker_id) && observedWorkerID !== normalizeString32(binding.worker_id)) {
|
|
18507
19527
|
return true;
|
|
18508
19528
|
}
|
|
18509
|
-
const observedClaudeSessionID =
|
|
18510
|
-
if (observedClaudeSessionID &&
|
|
19529
|
+
const observedClaudeSessionID = normalizeString32(payload?.claude_session_id);
|
|
19530
|
+
if (observedClaudeSessionID && normalizeString32(binding?.claude_session_id) && observedClaudeSessionID !== normalizeString32(binding.claude_session_id)) {
|
|
18511
19531
|
return true;
|
|
18512
19532
|
}
|
|
18513
19533
|
return false;
|
|
@@ -18517,10 +19537,10 @@ var init_runtime = __esm({
|
|
|
18517
19537
|
stage,
|
|
18518
19538
|
event_id: payload?.event_id,
|
|
18519
19539
|
session_id: this.resolveObservedSessionID(payload),
|
|
18520
|
-
worker_id:
|
|
18521
|
-
expected_worker_id:
|
|
18522
|
-
claude_session_id:
|
|
18523
|
-
expected_claude_session_id:
|
|
19540
|
+
worker_id: normalizeString32(payload?.worker_id),
|
|
19541
|
+
expected_worker_id: normalizeString32(binding?.worker_id),
|
|
19542
|
+
claude_session_id: normalizeString32(payload?.claude_session_id),
|
|
19543
|
+
expected_claude_session_id: normalizeString32(binding?.claude_session_id)
|
|
18524
19544
|
}, "error");
|
|
18525
19545
|
}
|
|
18526
19546
|
async recordWorkerReplyObserved(payload, { kind = "text" } = {}) {
|
|
@@ -18583,19 +19603,19 @@ var init_runtime = __esm({
|
|
|
18583
19603
|
response_state: nextBinding?.worker_response_state,
|
|
18584
19604
|
response_reason: nextBinding?.worker_response_reason,
|
|
18585
19605
|
event_id: payload?.event_id,
|
|
18586
|
-
terminal_status:
|
|
18587
|
-
terminal_code:
|
|
19606
|
+
terminal_status: normalizeString32(payload?.status),
|
|
19607
|
+
terminal_code: normalizeString32(payload?.code)
|
|
18588
19608
|
}, classification.state === "failed" ? "error" : "info");
|
|
18589
19609
|
return nextBinding;
|
|
18590
19610
|
}
|
|
18591
19611
|
async recordWorkerHookSignalsObserved(binding, pingPayload) {
|
|
18592
|
-
const sessionID =
|
|
19612
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
18593
19613
|
if (!sessionID) {
|
|
18594
19614
|
return binding;
|
|
18595
19615
|
}
|
|
18596
19616
|
let nextBinding = binding;
|
|
18597
19617
|
let lastEventAt = Number(binding?.worker_last_hook_event_at ?? 0);
|
|
18598
|
-
let lastEventID =
|
|
19618
|
+
let lastEventID = normalizeString32(binding?.worker_last_hook_event_id);
|
|
18599
19619
|
for (const event of listHookSignalRecords(pingPayload)) {
|
|
18600
19620
|
const isNewer = event.event_at > lastEventAt || event.event_at === lastEventAt && event.event_id !== lastEventID;
|
|
18601
19621
|
if (!isNewer) {
|
|
@@ -18625,16 +19645,16 @@ var init_runtime = __esm({
|
|
|
18625
19645
|
if (this.workerControlProbeFailureThreshold <= 0) {
|
|
18626
19646
|
return { ok: true };
|
|
18627
19647
|
}
|
|
18628
|
-
if (
|
|
19648
|
+
if (normalizeString32(binding?.worker_status) !== "ready") {
|
|
18629
19649
|
return { ok: true };
|
|
18630
19650
|
}
|
|
18631
|
-
const workerID =
|
|
19651
|
+
const workerID = normalizeString32(binding?.worker_id);
|
|
18632
19652
|
if (!workerID) {
|
|
18633
19653
|
return { ok: true };
|
|
18634
19654
|
}
|
|
18635
19655
|
const probeTraceFields = {
|
|
18636
|
-
session_id:
|
|
18637
|
-
claude_session_id:
|
|
19656
|
+
session_id: normalizeString32(binding?.aibot_session_id),
|
|
19657
|
+
claude_session_id: normalizeString32(binding?.claude_session_id),
|
|
18638
19658
|
expected_pid: resolveExpectedWorkerPid(binding, runtime)
|
|
18639
19659
|
};
|
|
18640
19660
|
let client = null;
|
|
@@ -18673,12 +19693,12 @@ var init_runtime = __esm({
|
|
|
18673
19693
|
reason: identityHealth.reason,
|
|
18674
19694
|
expected_pid: normalizeNonNegativeInt(identityHealth.expectedPid, 0),
|
|
18675
19695
|
reported_pid: normalizeNonNegativeInt(identityHealth.reportedPid, 0),
|
|
18676
|
-
expected_worker_id:
|
|
18677
|
-
reported_worker_id:
|
|
18678
|
-
expected_session_id:
|
|
18679
|
-
reported_session_id:
|
|
18680
|
-
expected_claude_session_id:
|
|
18681
|
-
reported_claude_session_id:
|
|
19696
|
+
expected_worker_id: normalizeString32(identityHealth.expectedWorkerID),
|
|
19697
|
+
reported_worker_id: normalizeString32(identityHealth.reportedWorkerID),
|
|
19698
|
+
expected_session_id: normalizeString32(identityHealth.expectedSessionID),
|
|
19699
|
+
reported_session_id: normalizeString32(identityHealth.reportedSessionID),
|
|
19700
|
+
expected_claude_session_id: normalizeString32(identityHealth.expectedClaudeSessionID),
|
|
19701
|
+
reported_claude_session_id: normalizeString32(identityHealth.reportedClaudeSessionID),
|
|
18682
19702
|
...buildPingActivityTraceFields(pingPayload)
|
|
18683
19703
|
});
|
|
18684
19704
|
const failures = this.markWorkerControlProbeFailure(
|
|
@@ -18750,6 +19770,13 @@ var init_runtime = __esm({
|
|
|
18750
19770
|
}
|
|
18751
19771
|
return client.deliverRevoke(rawPayload);
|
|
18752
19772
|
}
|
|
19773
|
+
async deliverLocalActionToWorker(binding, rawPayload) {
|
|
19774
|
+
const client = this.workerControlClientFactory(binding);
|
|
19775
|
+
if (!client?.isConfigured?.()) {
|
|
19776
|
+
throw new Error("worker control client is not configured");
|
|
19777
|
+
}
|
|
19778
|
+
return client.deliverLocalAction(rawPayload);
|
|
19779
|
+
}
|
|
18753
19780
|
async trackPendingEvent(rawPayload) {
|
|
18754
19781
|
return this.pendingEventOrchestrator.trackPendingEvent(rawPayload);
|
|
18755
19782
|
}
|
|
@@ -18766,22 +19793,22 @@ var init_runtime = __esm({
|
|
|
18766
19793
|
return this.pendingEventOrchestrator.markPendingEventInterrupted(eventID);
|
|
18767
19794
|
}
|
|
18768
19795
|
async clearPendingEvent(eventID) {
|
|
18769
|
-
const normalizedEventID =
|
|
19796
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
18770
19797
|
if (normalizedEventID) {
|
|
18771
19798
|
this.pendingEventWorkerLogCursors.delete(normalizedEventID);
|
|
18772
19799
|
}
|
|
18773
19800
|
return this.pendingEventOrchestrator.clearPendingEvent(eventID);
|
|
18774
19801
|
}
|
|
18775
19802
|
getPendingEventWorkerLogCursor(eventID) {
|
|
18776
|
-
const normalizedEventID =
|
|
19803
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
18777
19804
|
if (!normalizedEventID) {
|
|
18778
19805
|
return null;
|
|
18779
19806
|
}
|
|
18780
19807
|
return this.pendingEventWorkerLogCursors.get(normalizedEventID) ?? null;
|
|
18781
19808
|
}
|
|
18782
19809
|
async recordPendingEventWorkerLogCursor(eventID, workerID) {
|
|
18783
|
-
const normalizedEventID =
|
|
18784
|
-
const normalizedWorkerID =
|
|
19810
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
19811
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
18785
19812
|
if (!normalizedEventID || !normalizedWorkerID) {
|
|
18786
19813
|
return null;
|
|
18787
19814
|
}
|
|
@@ -18822,19 +19849,19 @@ var init_runtime = __esm({
|
|
|
18822
19849
|
return this.pendingEventOrchestrator.touchPendingEventComposing(eventID);
|
|
18823
19850
|
}
|
|
18824
19851
|
async handleWorkerSessionComposing(payload = {}) {
|
|
18825
|
-
const eventID =
|
|
19852
|
+
const eventID = normalizeString32(payload.ref_event_id);
|
|
18826
19853
|
if (!eventID) {
|
|
18827
19854
|
return null;
|
|
18828
19855
|
}
|
|
18829
|
-
const workerID =
|
|
18830
|
-
const workerSessionID =
|
|
18831
|
-
const claudeSessionID =
|
|
19856
|
+
const workerID = normalizeString32(payload.worker_id);
|
|
19857
|
+
const workerSessionID = normalizeString32(payload.session_id || payload.aibot_session_id);
|
|
19858
|
+
const claudeSessionID = normalizeString32(payload.claude_session_id);
|
|
18832
19859
|
const reportedPid = Number(payload.pid ?? 0);
|
|
18833
19860
|
const record = this.getPendingEvent(eventID);
|
|
18834
19861
|
if (!record) {
|
|
18835
19862
|
return null;
|
|
18836
19863
|
}
|
|
18837
|
-
const deliveryState =
|
|
19864
|
+
const deliveryState = normalizeString32(record.delivery_state);
|
|
18838
19865
|
if (deliveryState !== "dispatching" && deliveryState !== "delivered") {
|
|
18839
19866
|
this.trace({
|
|
18840
19867
|
stage: "pending_event_activity_rejected",
|
|
@@ -18845,7 +19872,7 @@ var init_runtime = __esm({
|
|
|
18845
19872
|
}, "error");
|
|
18846
19873
|
return null;
|
|
18847
19874
|
}
|
|
18848
|
-
const sessionID =
|
|
19875
|
+
const sessionID = normalizeString32(record.sessionID);
|
|
18849
19876
|
if (workerSessionID && workerSessionID !== sessionID) {
|
|
18850
19877
|
this.trace({
|
|
18851
19878
|
stage: "pending_event_activity_rejected",
|
|
@@ -18866,7 +19893,7 @@ var init_runtime = __esm({
|
|
|
18866
19893
|
}, "error");
|
|
18867
19894
|
return null;
|
|
18868
19895
|
}
|
|
18869
|
-
const expectedWorkerID =
|
|
19896
|
+
const expectedWorkerID = normalizeString32(binding.worker_id);
|
|
18870
19897
|
if (!workerID || !expectedWorkerID || workerID !== expectedWorkerID) {
|
|
18871
19898
|
this.trace({
|
|
18872
19899
|
stage: "pending_event_activity_rejected",
|
|
@@ -18892,7 +19919,7 @@ var init_runtime = __esm({
|
|
|
18892
19919
|
return null;
|
|
18893
19920
|
}
|
|
18894
19921
|
}
|
|
18895
|
-
const dispatchedWorkerID =
|
|
19922
|
+
const dispatchedWorkerID = normalizeString32(record.last_worker_id);
|
|
18896
19923
|
if (dispatchedWorkerID && workerID !== dispatchedWorkerID) {
|
|
18897
19924
|
this.trace({
|
|
18898
19925
|
stage: "pending_event_activity_rejected",
|
|
@@ -18904,7 +19931,7 @@ var init_runtime = __esm({
|
|
|
18904
19931
|
}, "error");
|
|
18905
19932
|
return null;
|
|
18906
19933
|
}
|
|
18907
|
-
const expectedClaudeSessionID =
|
|
19934
|
+
const expectedClaudeSessionID = normalizeString32(binding.claude_session_id);
|
|
18908
19935
|
if (!claudeSessionID || !expectedClaudeSessionID || claudeSessionID !== expectedClaudeSessionID) {
|
|
18909
19936
|
this.trace({
|
|
18910
19937
|
stage: "pending_event_activity_rejected",
|
|
@@ -18941,12 +19968,12 @@ var init_runtime = __esm({
|
|
|
18941
19968
|
async flushStalePendingEvents() {
|
|
18942
19969
|
const bindings = this.bindingRegistry?.listBindings?.() ?? [];
|
|
18943
19970
|
for (const binding of bindings) {
|
|
18944
|
-
const sessionID =
|
|
19971
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
18945
19972
|
if (!sessionID) continue;
|
|
18946
19973
|
if (!canDeliverToWorker(binding)) continue;
|
|
18947
19974
|
const pendingEvents = this.listPendingEventsForSession(sessionID);
|
|
18948
19975
|
const hasPending = pendingEvents.some(
|
|
18949
|
-
(r) =>
|
|
19976
|
+
(r) => normalizeString32(r.delivery_state) === "pending"
|
|
18950
19977
|
);
|
|
18951
19978
|
if (!hasPending) continue;
|
|
18952
19979
|
const queue = this.sessionQueues.ensure(sessionID);
|
|
@@ -18966,7 +19993,6 @@ var init_runtime = __esm({
|
|
|
18966
19993
|
async failPendingEvent(record, {
|
|
18967
19994
|
notifyText = true,
|
|
18968
19995
|
noticeText = buildInterruptedEventNotice(),
|
|
18969
|
-
replySource = "daemon_worker_interrupted",
|
|
18970
19996
|
resultCode = "worker_interrupted",
|
|
18971
19997
|
resultMessage = "worker interrupted while processing event"
|
|
18972
19998
|
} = {}) {
|
|
@@ -18983,10 +20009,7 @@ var init_runtime = __esm({
|
|
|
18983
20009
|
eventID: record.eventID,
|
|
18984
20010
|
sessionID: record.sessionID,
|
|
18985
20011
|
text: noticeText,
|
|
18986
|
-
quotedMessageID: record.msgID
|
|
18987
|
-
extra: {
|
|
18988
|
-
reply_source: replySource
|
|
18989
|
-
}
|
|
20012
|
+
quotedMessageID: record.msgID
|
|
18990
20013
|
});
|
|
18991
20014
|
} catch {
|
|
18992
20015
|
}
|
|
@@ -19009,7 +20032,7 @@ var init_runtime = __esm({
|
|
|
19009
20032
|
}, "error");
|
|
19010
20033
|
}
|
|
19011
20034
|
async resolveWorkerFailureEventOptions(workerID) {
|
|
19012
|
-
const normalizedWorkerID =
|
|
20035
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
19013
20036
|
if (!normalizedWorkerID) {
|
|
19014
20037
|
return null;
|
|
19015
20038
|
}
|
|
@@ -19027,23 +20050,22 @@ var init_runtime = __esm({
|
|
|
19027
20050
|
}
|
|
19028
20051
|
return {
|
|
19029
20052
|
noticeText: buildAuthLoginRequiredEventNotice(),
|
|
19030
|
-
replySource: "daemon_worker_auth_login_required",
|
|
19031
20053
|
resultCode: "claude_auth_login_required",
|
|
19032
20054
|
resultMessage: "claude authentication expired; run claude auth login"
|
|
19033
20055
|
};
|
|
19034
20056
|
}
|
|
19035
20057
|
resolveWorkerIDForEventResult(payload) {
|
|
19036
|
-
const explicitWorkerID =
|
|
20058
|
+
const explicitWorkerID = normalizeString32(payload?.worker_id);
|
|
19037
20059
|
if (explicitWorkerID) {
|
|
19038
20060
|
return explicitWorkerID;
|
|
19039
20061
|
}
|
|
19040
20062
|
const sessionID = this.resolveObservedSessionID(payload);
|
|
19041
20063
|
const binding = sessionID ? this.bindingRegistry.getByAibotSessionID(sessionID) : null;
|
|
19042
|
-
return
|
|
20064
|
+
return normalizeString32(binding?.worker_id);
|
|
19043
20065
|
}
|
|
19044
20066
|
async resolveWorkerEventResultFailureOptions(payload) {
|
|
19045
|
-
const status =
|
|
19046
|
-
const code =
|
|
20067
|
+
const status = normalizeString32(payload?.status);
|
|
20068
|
+
const code = normalizeString32(payload?.code);
|
|
19047
20069
|
if (status !== "failed" || code !== "claude_result_timeout") {
|
|
19048
20070
|
return null;
|
|
19049
20071
|
}
|
|
@@ -19051,7 +20073,7 @@ var init_runtime = __esm({
|
|
|
19051
20073
|
if (!workerID) {
|
|
19052
20074
|
return null;
|
|
19053
20075
|
}
|
|
19054
|
-
const eventID =
|
|
20076
|
+
const eventID = normalizeString32(payload?.event_id);
|
|
19055
20077
|
const logCursor = this.getPendingEventWorkerLogCursor(eventID);
|
|
19056
20078
|
const hasExtraUsageLimitPrompt = await this.workerProcessManager?.hasExtraUsageLimitPrompt?.(
|
|
19057
20079
|
workerID,
|
|
@@ -19079,7 +20101,7 @@ var init_runtime = __esm({
|
|
|
19079
20101
|
if (!failureOptions?.noticeText) {
|
|
19080
20102
|
return null;
|
|
19081
20103
|
}
|
|
19082
|
-
const eventID =
|
|
20104
|
+
const eventID = normalizeString32(payload?.event_id);
|
|
19083
20105
|
const record = this.getPendingEvent(eventID);
|
|
19084
20106
|
if (!record?.eventID || !record?.sessionID) {
|
|
19085
20107
|
return null;
|
|
@@ -19089,10 +20111,7 @@ var init_runtime = __esm({
|
|
|
19089
20111
|
eventID: record.eventID,
|
|
19090
20112
|
sessionID: record.sessionID,
|
|
19091
20113
|
text: failureOptions.noticeText,
|
|
19092
|
-
quotedMessageID: record.msgID
|
|
19093
|
-
extra: {
|
|
19094
|
-
reply_source: failureOptions.replySource
|
|
19095
|
-
}
|
|
20114
|
+
quotedMessageID: record.msgID
|
|
19096
20115
|
});
|
|
19097
20116
|
} catch {
|
|
19098
20117
|
return null;
|
|
@@ -19108,18 +20127,18 @@ var init_runtime = __esm({
|
|
|
19108
20127
|
return nextPayload;
|
|
19109
20128
|
}
|
|
19110
20129
|
async requeuePendingEventsForWorker(sessionID, workerID) {
|
|
19111
|
-
const normalizedSessionID =
|
|
19112
|
-
const normalizedWorkerID =
|
|
20130
|
+
const normalizedSessionID = normalizeString32(sessionID);
|
|
20131
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
19113
20132
|
if (!normalizedSessionID || !normalizedWorkerID) {
|
|
19114
20133
|
return 0;
|
|
19115
20134
|
}
|
|
19116
20135
|
let requeuedCount = 0;
|
|
19117
20136
|
const requeuedEventIDs = [];
|
|
19118
20137
|
for (const record of this.listPendingEventsForSession(normalizedSessionID)) {
|
|
19119
|
-
if (
|
|
20138
|
+
if (normalizeString32(record.last_worker_id) !== normalizedWorkerID) {
|
|
19120
20139
|
continue;
|
|
19121
20140
|
}
|
|
19122
|
-
const deliveryState =
|
|
20141
|
+
const deliveryState = normalizeString32(record.delivery_state);
|
|
19123
20142
|
if (!["dispatching", "delivered", "interrupted"].includes(deliveryState)) {
|
|
19124
20143
|
continue;
|
|
19125
20144
|
}
|
|
@@ -19142,8 +20161,8 @@ var init_runtime = __esm({
|
|
|
19142
20161
|
return requeuedCount;
|
|
19143
20162
|
}
|
|
19144
20163
|
async tryRecoverResumeAuthFailure(previousBinding, nextBinding) {
|
|
19145
|
-
const sessionID =
|
|
19146
|
-
const workerID =
|
|
20164
|
+
const sessionID = normalizeString32(nextBinding?.aibot_session_id || previousBinding?.aibot_session_id);
|
|
20165
|
+
const workerID = normalizeString32(previousBinding?.worker_id || nextBinding?.worker_id);
|
|
19147
20166
|
if (!sessionID || !workerID) {
|
|
19148
20167
|
return false;
|
|
19149
20168
|
}
|
|
@@ -19195,7 +20214,7 @@ var init_runtime = __esm({
|
|
|
19195
20214
|
return false;
|
|
19196
20215
|
}
|
|
19197
20216
|
const fallbackBinding = await this.rotateClaudeSession(latestBinding);
|
|
19198
|
-
const nextWorkerID =
|
|
20217
|
+
const nextWorkerID = normalizeString32(nextBinding?.worker_id) || workerID || randomUUID8();
|
|
19199
20218
|
await this.bindingRegistry.markWorkerStarting(sessionID, {
|
|
19200
20219
|
workerID: nextWorkerID,
|
|
19201
20220
|
updatedAt: Date.now(),
|
|
@@ -19232,7 +20251,7 @@ var init_runtime = __esm({
|
|
|
19232
20251
|
async reconcileWorkerProcesses() {
|
|
19233
20252
|
const bindings = this.bindingRegistry?.listBindings?.() ?? [];
|
|
19234
20253
|
for (const binding of bindings) {
|
|
19235
|
-
const sessionID =
|
|
20254
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
19236
20255
|
if (!sessionID) continue;
|
|
19237
20256
|
const queue = this.sessionQueues.ensure(sessionID);
|
|
19238
20257
|
queue.run(() => this.reconcileWorkerProcess(binding)).catch((err) => {
|
|
@@ -19241,11 +20260,11 @@ var init_runtime = __esm({
|
|
|
19241
20260
|
}
|
|
19242
20261
|
}
|
|
19243
20262
|
async reconcileWorkerProcess(binding) {
|
|
19244
|
-
const sessionID =
|
|
20263
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
19245
20264
|
if (!sessionID) return false;
|
|
19246
20265
|
const freshBinding = this.bindingRegistry?.getByAibotSessionID?.(sessionID) ?? binding;
|
|
19247
|
-
const workerID =
|
|
19248
|
-
const workerStatus =
|
|
20266
|
+
const workerID = normalizeString32(freshBinding?.worker_id);
|
|
20267
|
+
const workerStatus = normalizeString32(freshBinding?.worker_status);
|
|
19249
20268
|
if (!workerID || !["starting", "connected", "ready"].includes(workerStatus)) {
|
|
19250
20269
|
return false;
|
|
19251
20270
|
}
|
|
@@ -19297,7 +20316,7 @@ var init_runtime = __esm({
|
|
|
19297
20316
|
return true;
|
|
19298
20317
|
}
|
|
19299
20318
|
const previousBinding = this.bindingRegistry.getByAibotSessionID(sessionID) ?? binding;
|
|
19300
|
-
if (
|
|
20319
|
+
if (normalizeString32(previousBinding?.worker_id) !== workerID || ["stopped", "failed"].includes(normalizeString32(previousBinding?.worker_status))) {
|
|
19301
20320
|
return false;
|
|
19302
20321
|
}
|
|
19303
20322
|
const runtime = this.workerProcessManager?.getWorkerRuntime?.(workerID);
|
|
@@ -19306,7 +20325,7 @@ var init_runtime = __esm({
|
|
|
19306
20325
|
}
|
|
19307
20326
|
const pid = resolveExpectedWorkerPid(previousBinding, runtime);
|
|
19308
20327
|
if (Number.isFinite(pid) && pid > 0 && !this.isProcessRunning(pid)) {
|
|
19309
|
-
const exitSignal =
|
|
20328
|
+
const exitSignal = normalizeString32(runtime.exit_signal) || "worker_exited";
|
|
19310
20329
|
this.workerProcessManager?.markWorkerRuntimeStopped?.(workerID, {
|
|
19311
20330
|
exitCode: Number(runtime.exit_code ?? 0),
|
|
19312
20331
|
exitSignal
|
|
@@ -19350,7 +20369,7 @@ var init_runtime = __esm({
|
|
|
19350
20369
|
}, "error");
|
|
19351
20370
|
await this.bindingRegistry.markWorkerResponseFailed(sessionID, {
|
|
19352
20371
|
observedAt: Date.now(),
|
|
19353
|
-
reason:
|
|
20372
|
+
reason: normalizeString32(probe.reason) || "worker_control_unreachable",
|
|
19354
20373
|
failureCode: "worker_control_unreachable"
|
|
19355
20374
|
});
|
|
19356
20375
|
const nextBinding = await this.bindingRegistry.markWorkerStopped(sessionID, {
|
|
@@ -19421,7 +20440,7 @@ var init_runtime = __esm({
|
|
|
19421
20440
|
* handling.
|
|
19422
20441
|
*/
|
|
19423
20442
|
async handleWorkerStatusUpdateQueued(previousBinding, nextBinding) {
|
|
19424
|
-
const sessionID =
|
|
20443
|
+
const sessionID = normalizeString32(
|
|
19425
20444
|
nextBinding?.aibot_session_id || previousBinding?.aibot_session_id
|
|
19426
20445
|
);
|
|
19427
20446
|
if (!sessionID) {
|
|
@@ -19433,8 +20452,8 @@ var init_runtime = __esm({
|
|
|
19433
20452
|
);
|
|
19434
20453
|
}
|
|
19435
20454
|
async handleWorkerStatusUpdate(previousBinding, nextBinding) {
|
|
19436
|
-
const sessionID =
|
|
19437
|
-
const nextStatus =
|
|
20455
|
+
const sessionID = normalizeString32(nextBinding?.aibot_session_id || previousBinding?.aibot_session_id);
|
|
20456
|
+
const nextStatus = normalizeString32(nextBinding?.worker_status);
|
|
19438
20457
|
if (!sessionID || !nextStatus) {
|
|
19439
20458
|
return;
|
|
19440
20459
|
}
|
|
@@ -19446,8 +20465,8 @@ var init_runtime = __esm({
|
|
|
19446
20465
|
claude_session_id: nextBinding?.claude_session_id || previousBinding?.claude_session_id,
|
|
19447
20466
|
status: nextStatus
|
|
19448
20467
|
});
|
|
19449
|
-
const previousWorkerID =
|
|
19450
|
-
const nextWorkerID =
|
|
20468
|
+
const previousWorkerID = normalizeString32(previousBinding?.worker_id);
|
|
20469
|
+
const nextWorkerID = normalizeString32(nextBinding?.worker_id);
|
|
19451
20470
|
if (nextStatus === "ready" || nextStatus === "connected") {
|
|
19452
20471
|
if (nextWorkerID) {
|
|
19453
20472
|
this.clearWorkerControlProbeFailure(nextWorkerID);
|
|
@@ -19499,11 +20518,11 @@ var init_runtime = __esm({
|
|
|
19499
20518
|
}, "error");
|
|
19500
20519
|
}
|
|
19501
20520
|
for (const record of this.listPendingEventsForSession(sessionID)) {
|
|
19502
|
-
if (previousWorkerID &&
|
|
19503
|
-
if (
|
|
20521
|
+
if (previousWorkerID && normalizeString32(record.last_worker_id) !== previousWorkerID) {
|
|
20522
|
+
if (normalizeString32(record.last_worker_id)) {
|
|
19504
20523
|
continue;
|
|
19505
20524
|
}
|
|
19506
|
-
if (!["pending", "dispatching", "interrupted"].includes(
|
|
20525
|
+
if (!["pending", "dispatching", "interrupted"].includes(normalizeString32(record.delivery_state))) {
|
|
19507
20526
|
continue;
|
|
19508
20527
|
}
|
|
19509
20528
|
}
|
|
@@ -19513,7 +20532,7 @@ var init_runtime = __esm({
|
|
|
19513
20532
|
}
|
|
19514
20533
|
async handleEventCompleted(eventID) {
|
|
19515
20534
|
const record = this.getPendingEvent(eventID);
|
|
19516
|
-
const sessionID =
|
|
20535
|
+
const sessionID = normalizeString32(record?.sessionID || this.messageDeliveryStore.getRememberedSessionID(eventID));
|
|
19517
20536
|
await this.clearPendingEvent(eventID);
|
|
19518
20537
|
this.trace({
|
|
19519
20538
|
stage: "event_completed",
|
|
@@ -19581,7 +20600,6 @@ var init_runtime = __esm({
|
|
|
19581
20600
|
const currentRecord = this.getPendingEvent(record.eventID) ?? record;
|
|
19582
20601
|
await this.failPendingEvent(currentRecord, {
|
|
19583
20602
|
notifyText: false,
|
|
19584
|
-
replySource: "daemon_recover_failed",
|
|
19585
20603
|
resultCode: "worker_recover_failed",
|
|
19586
20604
|
resultMessage: message
|
|
19587
20605
|
});
|
|
@@ -19658,7 +20676,7 @@ var init_runtime = __esm({
|
|
|
19658
20676
|
});
|
|
19659
20677
|
return null;
|
|
19660
20678
|
}
|
|
19661
|
-
if (currentRecord && ["dispatching", "delivered"].includes(
|
|
20679
|
+
if (currentRecord && ["dispatching", "delivered"].includes(normalizeString32(currentRecord.delivery_state)) && normalizeString32(currentRecord.last_worker_id) === normalizeString32(readyBinding?.worker_id)) {
|
|
19662
20680
|
this.trace({
|
|
19663
20681
|
stage: "event_dispatch_skipped",
|
|
19664
20682
|
event_id: rawPayload?.event_id,
|
|
@@ -19710,7 +20728,7 @@ var init_runtime = __esm({
|
|
|
19710
20728
|
} else {
|
|
19711
20729
|
readyBinding = this.bindingRegistry.getByAibotSessionID(aibotSessionID) ?? readyBinding;
|
|
19712
20730
|
}
|
|
19713
|
-
if (readyBinding?.worker_launch_failure === "resume_session_missing" &&
|
|
20731
|
+
if (readyBinding?.worker_launch_failure === "resume_session_missing" && normalizeString32(binding.claude_session_id)) {
|
|
19714
20732
|
this.trace({
|
|
19715
20733
|
stage: "worker_resume_missing_recovering",
|
|
19716
20734
|
session_id: binding.aibot_session_id,
|
|
@@ -19764,9 +20782,6 @@ var init_runtime = __esm({
|
|
|
19764
20782
|
}
|
|
19765
20783
|
return readyBinding ?? binding;
|
|
19766
20784
|
}
|
|
19767
|
-
async handleControlCommand(event, parsed) {
|
|
19768
|
-
return this.controlCommandHandler.handleControlCommand(event, parsed);
|
|
19769
|
-
}
|
|
19770
20785
|
/**
|
|
19771
20786
|
* Queue-aware wrapper: routes handleEvent through the per-session
|
|
19772
20787
|
* serial queue to prevent races with reconcile and worker status updates.
|
|
@@ -19794,10 +20809,18 @@ var init_runtime = __esm({
|
|
|
19794
20809
|
sender_id: event.sender_id
|
|
19795
20810
|
});
|
|
19796
20811
|
this.ack(event);
|
|
20812
|
+
if (isRecordOnlyMirror(event)) {
|
|
20813
|
+
this.trace({
|
|
20814
|
+
stage: "event_mirrored_record_only",
|
|
20815
|
+
event_id: event.event_id,
|
|
20816
|
+
session_id: event.session_id,
|
|
20817
|
+
msg_id: event.msg_id,
|
|
20818
|
+
sender_id: event.sender_id
|
|
20819
|
+
});
|
|
20820
|
+
return;
|
|
20821
|
+
}
|
|
19797
20822
|
try {
|
|
19798
|
-
|
|
19799
|
-
if (parsed.matched) {
|
|
19800
|
-
await this.handleControlCommand(event, parsed);
|
|
20823
|
+
if (await this.handleInteractionActionEvent(event)) {
|
|
19801
20824
|
return;
|
|
19802
20825
|
}
|
|
19803
20826
|
const binding = this.bindingRegistry.getByAibotSessionID(event.session_id);
|
|
@@ -19807,9 +20830,10 @@ var init_runtime = __esm({
|
|
|
19807
20830
|
event_id: event.event_id,
|
|
19808
20831
|
session_id: event.session_id
|
|
19809
20832
|
}, "error");
|
|
19810
|
-
await this.
|
|
19811
|
-
|
|
19812
|
-
|
|
20833
|
+
await this.respond(event, buildBindingMissingEventNotice(), {}, {
|
|
20834
|
+
status: "responded",
|
|
20835
|
+
code: sessionControlErrorCodes.bindingMissing,
|
|
20836
|
+
msg: "session binding is required before event delivery"
|
|
19813
20837
|
});
|
|
19814
20838
|
return;
|
|
19815
20839
|
}
|
|
@@ -19827,9 +20851,7 @@ var init_runtime = __esm({
|
|
|
19827
20851
|
await this.respond(
|
|
19828
20852
|
event,
|
|
19829
20853
|
buildAuthLoginRequiredEventNotice(),
|
|
19830
|
-
{
|
|
19831
|
-
reply_source: "daemon_worker_auth_login_required"
|
|
19832
|
-
},
|
|
20854
|
+
{},
|
|
19833
20855
|
{
|
|
19834
20856
|
status: "failed",
|
|
19835
20857
|
code: "claude_auth_login_required",
|
|
@@ -19881,7 +20903,7 @@ var init_runtime = __esm({
|
|
|
19881
20903
|
}
|
|
19882
20904
|
const readyBinding = routedBinding ?? this.bindingRegistry.getByAibotSessionID(binding.aibot_session_id) ?? binding;
|
|
19883
20905
|
if (!readyBinding.worker_control_url || !readyBinding.worker_control_token) {
|
|
19884
|
-
const launchFailure =
|
|
20906
|
+
const launchFailure = normalizeString32(readyBinding?.worker_launch_failure);
|
|
19885
20907
|
this.trace({
|
|
19886
20908
|
stage: "event_worker_not_ready",
|
|
19887
20909
|
event_id: event.event_id,
|
|
@@ -19891,7 +20913,7 @@ var init_runtime = __esm({
|
|
|
19891
20913
|
worker_launch_failure: launchFailure
|
|
19892
20914
|
}, "error");
|
|
19893
20915
|
if (pending && (launchFailure === "startup_mcp_server_failed" || launchFailure === "startup_wait_timeout")) {
|
|
19894
|
-
const workerID =
|
|
20916
|
+
const workerID = normalizeString32(readyBinding?.worker_id);
|
|
19895
20917
|
if (workerID) {
|
|
19896
20918
|
try {
|
|
19897
20919
|
await this.workerProcessManager?.stopWorker?.(workerID);
|
|
@@ -19917,7 +20939,6 @@ var init_runtime = __esm({
|
|
|
19917
20939
|
await this.markPendingEventInterrupted(pending.eventID);
|
|
19918
20940
|
await this.failPendingEvent(pending, {
|
|
19919
20941
|
noticeText: buildWorkerStartupFailedNotice(),
|
|
19920
|
-
replySource: "daemon_worker_startup_failed",
|
|
19921
20942
|
resultCode: launchFailure === "startup_mcp_server_failed" ? "claude_startup_mcp_failed" : "claude_startup_timeout",
|
|
19922
20943
|
resultMessage: launchFailure === "startup_mcp_server_failed" ? "claude worker startup failed: mcp server not ready" : "claude worker startup timed out"
|
|
19923
20944
|
});
|
|
@@ -19933,9 +20954,7 @@ var init_runtime = __esm({
|
|
|
19933
20954
|
error: message
|
|
19934
20955
|
}, "error");
|
|
19935
20956
|
try {
|
|
19936
|
-
await this.respond(event, `\u5904\u7406\u5931\u8D25\uFF1A${message}`, {
|
|
19937
|
-
reply_source: "daemon_event_error"
|
|
19938
|
-
}, {
|
|
20957
|
+
await this.respond(event, `\u5904\u7406\u5931\u8D25\uFF1A${message}`, {}, {
|
|
19939
20958
|
status: "failed",
|
|
19940
20959
|
code: "daemon_event_handle_failed",
|
|
19941
20960
|
msg: message
|
|
@@ -19950,7 +20969,7 @@ var init_runtime = __esm({
|
|
|
19950
20969
|
}
|
|
19951
20970
|
}
|
|
19952
20971
|
async handleStopEvent(rawPayload) {
|
|
19953
|
-
const eventID =
|
|
20972
|
+
const eventID = normalizeString32(rawPayload?.event_id);
|
|
19954
20973
|
if (!eventID) {
|
|
19955
20974
|
return;
|
|
19956
20975
|
}
|
|
@@ -19960,7 +20979,7 @@ var init_runtime = __esm({
|
|
|
19960
20979
|
session_id: rawPayload?.session_id,
|
|
19961
20980
|
stop_id: rawPayload?.stop_id
|
|
19962
20981
|
});
|
|
19963
|
-
const sessionID =
|
|
20982
|
+
const sessionID = normalizeString32(rawPayload?.session_id) || this.messageDeliveryStore.getRememberedSessionID(eventID);
|
|
19964
20983
|
if (!sessionID) {
|
|
19965
20984
|
this.trace({
|
|
19966
20985
|
stage: "stop_route_missing",
|
|
@@ -19978,12 +20997,12 @@ var init_runtime = __esm({
|
|
|
19978
20997
|
});
|
|
19979
20998
|
}
|
|
19980
20999
|
async handleRevokeEvent(rawPayload) {
|
|
19981
|
-
const eventID =
|
|
21000
|
+
const eventID = normalizeString32(rawPayload?.event_id);
|
|
19982
21001
|
if (!eventID) {
|
|
19983
21002
|
return;
|
|
19984
21003
|
}
|
|
19985
21004
|
const receivedAt = Date.now();
|
|
19986
|
-
const resolvedSessionID =
|
|
21005
|
+
const resolvedSessionID = normalizeString32(rawPayload?.session_id) || this.messageDeliveryStore.getRememberedSessionID(eventID);
|
|
19987
21006
|
this.aibotClient.ackEvent(eventID, {
|
|
19988
21007
|
sessionID: resolvedSessionID,
|
|
19989
21008
|
msgID: rawPayload?.msg_id,
|
|
@@ -20028,12 +21047,80 @@ var init_runtime = __esm({
|
|
|
20028
21047
|
msg_id: rawPayload?.msg_id
|
|
20029
21048
|
});
|
|
20030
21049
|
}
|
|
21050
|
+
async handleLocalAction(rawPayload) {
|
|
21051
|
+
const action = normalizeLocalActionPayload(rawPayload);
|
|
21052
|
+
if (!action.action_id) {
|
|
21053
|
+
this.trace({
|
|
21054
|
+
stage: "local_action_invalid",
|
|
21055
|
+
reason: "missing_action_id",
|
|
21056
|
+
action_type: action.action_type
|
|
21057
|
+
}, "error");
|
|
21058
|
+
return;
|
|
21059
|
+
}
|
|
21060
|
+
const sessionControlResult = await this.sessionControlActionHandler.handleLocalAction(action);
|
|
21061
|
+
if (sessionControlResult?.handled) {
|
|
21062
|
+
await this.aibotClient.sendLocalActionResult({
|
|
21063
|
+
actionID: action.action_id,
|
|
21064
|
+
status: sessionControlResult.response?.status,
|
|
21065
|
+
result: sessionControlResult.response?.result,
|
|
21066
|
+
errorCode: sessionControlResult.response?.errorCode,
|
|
21067
|
+
errorMsg: sessionControlResult.response?.errorMsg,
|
|
21068
|
+
timeoutMs: action.timeout_ms
|
|
21069
|
+
});
|
|
21070
|
+
return;
|
|
21071
|
+
}
|
|
21072
|
+
const sessionID = normalizeString32(action.params?.session_id) || this.messageDeliveryStore.getRememberedSessionID(action.event_id);
|
|
21073
|
+
if (!sessionID) {
|
|
21074
|
+
this.trace({
|
|
21075
|
+
stage: "local_action_route_missing",
|
|
21076
|
+
action_id: action.action_id,
|
|
21077
|
+
action_type: action.action_type,
|
|
21078
|
+
event_id: action.event_id
|
|
21079
|
+
}, "error");
|
|
21080
|
+
await this.aibotClient.sendLocalActionResult({
|
|
21081
|
+
actionID: action.action_id,
|
|
21082
|
+
status: localActionResultStatuses.failed,
|
|
21083
|
+
errorCode: localActionErrorCodes.localActionRouteMissing,
|
|
21084
|
+
errorMsg: "local action session_id is required",
|
|
21085
|
+
timeoutMs: action.timeout_ms
|
|
21086
|
+
});
|
|
21087
|
+
return;
|
|
21088
|
+
}
|
|
21089
|
+
const routedBinding = await this.deliverWithRecovery(
|
|
21090
|
+
sessionID,
|
|
21091
|
+
action,
|
|
21092
|
+
this.deliverLocalActionToWorker
|
|
21093
|
+
);
|
|
21094
|
+
if (routedBinding && canDeliverToWorker(routedBinding)) {
|
|
21095
|
+
this.trace({
|
|
21096
|
+
stage: "local_action_forwarded",
|
|
21097
|
+
action_id: action.action_id,
|
|
21098
|
+
action_type: action.action_type,
|
|
21099
|
+
session_id: sessionID,
|
|
21100
|
+
worker_id: routedBinding?.worker_id
|
|
21101
|
+
});
|
|
21102
|
+
return;
|
|
21103
|
+
}
|
|
21104
|
+
this.trace({
|
|
21105
|
+
stage: "local_action_delivery_failed",
|
|
21106
|
+
action_id: action.action_id,
|
|
21107
|
+
action_type: action.action_type,
|
|
21108
|
+
session_id: sessionID
|
|
21109
|
+
}, "error");
|
|
21110
|
+
await this.aibotClient.sendLocalActionResult({
|
|
21111
|
+
actionID: action.action_id,
|
|
21112
|
+
status: "failed",
|
|
21113
|
+
errorCode: "local_action_delivery_failed",
|
|
21114
|
+
errorMsg: "worker is not ready for local action delivery",
|
|
21115
|
+
timeoutMs: action.timeout_ms
|
|
21116
|
+
});
|
|
21117
|
+
}
|
|
20031
21118
|
};
|
|
20032
21119
|
}
|
|
20033
21120
|
});
|
|
20034
21121
|
|
|
20035
21122
|
// server/session-activity-dispatcher.js
|
|
20036
|
-
function
|
|
21123
|
+
function normalizeString33(value) {
|
|
20037
21124
|
return String(value ?? "").trim();
|
|
20038
21125
|
}
|
|
20039
21126
|
function buildSessionActivityDispatchKey({
|
|
@@ -20042,10 +21129,10 @@ function buildSessionActivityDispatchKey({
|
|
|
20042
21129
|
refEventID = "",
|
|
20043
21130
|
refMsgID = ""
|
|
20044
21131
|
} = {}) {
|
|
20045
|
-
const normalizedSessionID =
|
|
20046
|
-
const normalizedKind =
|
|
20047
|
-
const normalizedRefEventID =
|
|
20048
|
-
const normalizedRefMsgID =
|
|
21132
|
+
const normalizedSessionID = normalizeString33(sessionID);
|
|
21133
|
+
const normalizedKind = normalizeString33(kind) || "composing";
|
|
21134
|
+
const normalizedRefEventID = normalizeString33(refEventID);
|
|
21135
|
+
const normalizedRefMsgID = normalizeString33(refMsgID);
|
|
20049
21136
|
if (normalizedRefEventID) {
|
|
20050
21137
|
return `event:${normalizedRefEventID}`;
|
|
20051
21138
|
}
|
|
@@ -20082,19 +21169,19 @@ var init_session_activity_dispatcher = __esm({
|
|
|
20082
21169
|
|
|
20083
21170
|
// server/daemon/session-log-writer.js
|
|
20084
21171
|
import { appendFile as appendFile2, mkdir as mkdir11 } from "node:fs/promises";
|
|
20085
|
-
import
|
|
20086
|
-
function
|
|
21172
|
+
import path24 from "node:path";
|
|
21173
|
+
function normalizeString34(value) {
|
|
20087
21174
|
return String(value ?? "").trim();
|
|
20088
21175
|
}
|
|
20089
21176
|
function normalizeSessionID(value) {
|
|
20090
|
-
return
|
|
21177
|
+
return normalizeString34(value).replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
20091
21178
|
}
|
|
20092
21179
|
function resolveSessionID(fields = {}) {
|
|
20093
|
-
const explicitSessionID =
|
|
21180
|
+
const explicitSessionID = normalizeString34(fields.session_id);
|
|
20094
21181
|
if (explicitSessionID) {
|
|
20095
21182
|
return explicitSessionID;
|
|
20096
21183
|
}
|
|
20097
|
-
return
|
|
21184
|
+
return normalizeString34(fields.aibot_session_id);
|
|
20098
21185
|
}
|
|
20099
21186
|
var SessionLogWriter;
|
|
20100
21187
|
var init_session_log_writer = __esm({
|
|
@@ -20109,7 +21196,7 @@ var init_session_log_writer = __esm({
|
|
|
20109
21196
|
appendFileImpl = appendFile2
|
|
20110
21197
|
} = {}) {
|
|
20111
21198
|
this.env = env;
|
|
20112
|
-
this.logFileName =
|
|
21199
|
+
this.logFileName = normalizeString34(logFileName) || "daemon-session.log";
|
|
20113
21200
|
this.mkdirImpl = typeof mkdirImpl === "function" ? mkdirImpl : mkdir11;
|
|
20114
21201
|
this.appendFileImpl = typeof appendFileImpl === "function" ? appendFileImpl : appendFile2;
|
|
20115
21202
|
this.writeQueues = /* @__PURE__ */ new Map();
|
|
@@ -20119,7 +21206,7 @@ var init_session_log_writer = __esm({
|
|
|
20119
21206
|
if (!normalizedSessionID) {
|
|
20120
21207
|
return "";
|
|
20121
21208
|
}
|
|
20122
|
-
return
|
|
21209
|
+
return path24.join(resolveWorkerLogsDir(normalizedSessionID, this.env), this.logFileName);
|
|
20123
21210
|
}
|
|
20124
21211
|
enqueueWrite(aibotSessionID, task) {
|
|
20125
21212
|
const normalizedSessionID = normalizeSessionID(aibotSessionID);
|
|
@@ -20143,7 +21230,7 @@ var init_session_log_writer = __esm({
|
|
|
20143
21230
|
return false;
|
|
20144
21231
|
}
|
|
20145
21232
|
const line = formatTraceLine({
|
|
20146
|
-
level:
|
|
21233
|
+
level: normalizeString34(level) || "info",
|
|
20147
21234
|
...fields
|
|
20148
21235
|
});
|
|
20149
21236
|
return this.enqueueWrite(sessionID, async () => {
|
|
@@ -20151,7 +21238,7 @@ var init_session_log_writer = __esm({
|
|
|
20151
21238
|
if (!logPath) {
|
|
20152
21239
|
return false;
|
|
20153
21240
|
}
|
|
20154
|
-
await this.mkdirImpl(
|
|
21241
|
+
await this.mkdirImpl(path24.dirname(logPath), { recursive: true });
|
|
20155
21242
|
await this.appendFileImpl(logPath, `${line}
|
|
20156
21243
|
`, "utf8");
|
|
20157
21244
|
return true;
|
|
@@ -20171,7 +21258,7 @@ __export(main_exports, {
|
|
|
20171
21258
|
shouldIgnoreWorkerStatusUpdate: () => shouldIgnoreWorkerStatusUpdate,
|
|
20172
21259
|
shouldNotifyWorkerReady: () => shouldNotifyWorkerReady
|
|
20173
21260
|
});
|
|
20174
|
-
import
|
|
21261
|
+
import process15 from "node:process";
|
|
20175
21262
|
function usage() {
|
|
20176
21263
|
return `\u7528\u6CD5:
|
|
20177
21264
|
grix-claude daemon [options]
|
|
@@ -20190,7 +21277,7 @@ function usage() {
|
|
|
20190
21277
|
`;
|
|
20191
21278
|
}
|
|
20192
21279
|
function print(message) {
|
|
20193
|
-
|
|
21280
|
+
process15.stdout.write(`${message}
|
|
20194
21281
|
`);
|
|
20195
21282
|
}
|
|
20196
21283
|
function parseArgs(argv) {
|
|
@@ -20216,7 +21303,7 @@ function readOption(argv, name) {
|
|
|
20216
21303
|
}
|
|
20217
21304
|
return value;
|
|
20218
21305
|
}
|
|
20219
|
-
function
|
|
21306
|
+
function normalizeString35(value) {
|
|
20220
21307
|
return String(value ?? "").trim();
|
|
20221
21308
|
}
|
|
20222
21309
|
function normalizePid3(value) {
|
|
@@ -20239,13 +21326,13 @@ function shouldIgnoreWorkerStatusUpdate(previousBinding, payload) {
|
|
|
20239
21326
|
if (!previousBinding) {
|
|
20240
21327
|
return false;
|
|
20241
21328
|
}
|
|
20242
|
-
const expectedWorkerID =
|
|
20243
|
-
const incomingWorkerID =
|
|
21329
|
+
const expectedWorkerID = normalizeString35(previousBinding.worker_id);
|
|
21330
|
+
const incomingWorkerID = normalizeString35(payload?.worker_id);
|
|
20244
21331
|
if (expectedWorkerID && incomingWorkerID && expectedWorkerID !== incomingWorkerID) {
|
|
20245
21332
|
return true;
|
|
20246
21333
|
}
|
|
20247
|
-
const expectedClaudeSessionID =
|
|
20248
|
-
const incomingClaudeSessionID =
|
|
21334
|
+
const expectedClaudeSessionID = normalizeString35(previousBinding.claude_session_id);
|
|
21335
|
+
const incomingClaudeSessionID = normalizeString35(payload?.claude_session_id);
|
|
20249
21336
|
if (expectedClaudeSessionID && incomingClaudeSessionID && expectedClaudeSessionID !== incomingClaudeSessionID) {
|
|
20250
21337
|
return true;
|
|
20251
21338
|
}
|
|
@@ -20260,13 +21347,10 @@ async function notifyWorkerReady(aibotClient, binding) {
|
|
|
20260
21347
|
}
|
|
20261
21348
|
return aibotClient.sendText({
|
|
20262
21349
|
sessionID: binding.aibot_session_id,
|
|
20263
|
-
text: buildWorkerReadyNoticeText(binding)
|
|
20264
|
-
extra: {
|
|
20265
|
-
reply_source: "daemon_worker_ready"
|
|
20266
|
-
}
|
|
21350
|
+
text: buildWorkerReadyNoticeText(binding)
|
|
20267
21351
|
});
|
|
20268
21352
|
}
|
|
20269
|
-
async function run(argv = [], env =
|
|
21353
|
+
async function run(argv = [], env = process15.env) {
|
|
20270
21354
|
const options = parseArgs(argv);
|
|
20271
21355
|
if (options.help) {
|
|
20272
21356
|
print(usage());
|
|
@@ -20514,6 +21598,25 @@ async function run(argv = [], env = process14.env) {
|
|
|
20514
21598
|
refEventID: payload.ref_event_id
|
|
20515
21599
|
});
|
|
20516
21600
|
return { ok: true };
|
|
21601
|
+
},
|
|
21602
|
+
onAgentInvoke: async (payload) => aibotClient.sendAgentInvoke({
|
|
21603
|
+
invokeID: payload?.invoke_id,
|
|
21604
|
+
action: payload?.action,
|
|
21605
|
+
params: payload?.params,
|
|
21606
|
+
timeoutMs: payload?.timeout_ms
|
|
21607
|
+
}),
|
|
21608
|
+
onLocalActionResult: async (payload) => {
|
|
21609
|
+
const syntheticResult = await runtime?.observeWorkerLocalActionResult?.(payload);
|
|
21610
|
+
if (syntheticResult?.handled) {
|
|
21611
|
+
return { ok: true };
|
|
21612
|
+
}
|
|
21613
|
+
return aibotClient.sendLocalActionResult({
|
|
21614
|
+
actionID: payload?.action_id,
|
|
21615
|
+
status: payload?.status,
|
|
21616
|
+
result: payload?.result,
|
|
21617
|
+
errorCode: payload?.error_code,
|
|
21618
|
+
errorMsg: payload?.error_msg
|
|
21619
|
+
});
|
|
20517
21620
|
}
|
|
20518
21621
|
});
|
|
20519
21622
|
try {
|
|
@@ -20538,6 +21641,9 @@ async function run(argv = [], env = process14.env) {
|
|
|
20538
21641
|
aibotClient.onEventRevoke = async (payload) => {
|
|
20539
21642
|
await runtime.handleRevokeEvent(payload);
|
|
20540
21643
|
};
|
|
21644
|
+
aibotClient.onLocalAction = async (payload) => {
|
|
21645
|
+
await runtime.handleLocalAction(payload);
|
|
21646
|
+
};
|
|
20541
21647
|
print("grix-claude daemon \u5DF2\u542F\u52A8\u3002");
|
|
20542
21648
|
print(`\u6570\u636E\u76EE\u5F55: ${dataDir}`);
|
|
20543
21649
|
print(`Bridge: ${bridgeServer.getURL()}`);
|
|
@@ -20577,15 +21683,15 @@ async function run(argv = [], env = process14.env) {
|
|
|
20577
21683
|
}
|
|
20578
21684
|
await new Promise((resolve) => {
|
|
20579
21685
|
const stop = async () => {
|
|
20580
|
-
|
|
20581
|
-
|
|
21686
|
+
process15.off("SIGINT", stop);
|
|
21687
|
+
process15.off("SIGTERM", stop);
|
|
20582
21688
|
await processState.markStopping("signal");
|
|
20583
21689
|
await aibotClient.stop();
|
|
20584
21690
|
await bridgeServer.stop();
|
|
20585
21691
|
resolve();
|
|
20586
21692
|
};
|
|
20587
|
-
|
|
20588
|
-
|
|
21693
|
+
process15.once("SIGINT", stop);
|
|
21694
|
+
process15.once("SIGTERM", stop);
|
|
20589
21695
|
});
|
|
20590
21696
|
await processState.release({
|
|
20591
21697
|
exitCode: 0,
|
|
@@ -20597,8 +21703,8 @@ async function run(argv = [], env = process14.env) {
|
|
|
20597
21703
|
throw error;
|
|
20598
21704
|
}
|
|
20599
21705
|
}
|
|
20600
|
-
async function main(argv =
|
|
20601
|
-
|
|
21706
|
+
async function main(argv = process15.argv.slice(2), env = process15.env) {
|
|
21707
|
+
process15.exitCode = await run(argv, env);
|
|
20602
21708
|
}
|
|
20603
21709
|
var workerReadySettleDelayMs;
|
|
20604
21710
|
var init_main2 = __esm({
|
|
@@ -20627,7 +21733,7 @@ __export(main_exports2, {
|
|
|
20627
21733
|
main: () => main2,
|
|
20628
21734
|
run: () => run2
|
|
20629
21735
|
});
|
|
20630
|
-
import
|
|
21736
|
+
import process16 from "node:process";
|
|
20631
21737
|
function usage2() {
|
|
20632
21738
|
return `\u7528\u6CD5:
|
|
20633
21739
|
grix-claude worker
|
|
@@ -20637,7 +21743,7 @@ function usage2() {
|
|
|
20637
21743
|
`;
|
|
20638
21744
|
}
|
|
20639
21745
|
function print2(message) {
|
|
20640
|
-
|
|
21746
|
+
process16.stdout.write(`${message}
|
|
20641
21747
|
`);
|
|
20642
21748
|
}
|
|
20643
21749
|
async function run2(argv = []) {
|
|
@@ -20648,8 +21754,8 @@ async function run2(argv = []) {
|
|
|
20648
21754
|
print2("\u4E0D\u8981\u624B\u52A8\u8FD0\u884C worker\u3002Claude \u4F1A\u8BDD\u4F1A\u5728 daemon \u8C03\u5EA6\u4E0B\u81EA\u52A8\u52A0\u8F7D\u5B83\u3002");
|
|
20649
21755
|
return 1;
|
|
20650
21756
|
}
|
|
20651
|
-
async function main2(argv =
|
|
20652
|
-
|
|
21757
|
+
async function main2(argv = process16.argv.slice(2)) {
|
|
21758
|
+
process16.exitCode = await run2(argv);
|
|
20653
21759
|
}
|
|
20654
21760
|
var init_main3 = __esm({
|
|
20655
21761
|
"server/worker/main.js"() {
|
|
@@ -20660,7 +21766,7 @@ var init_main3 = __esm({
|
|
|
20660
21766
|
init_config();
|
|
20661
21767
|
init_config_store();
|
|
20662
21768
|
init_daemon_paths();
|
|
20663
|
-
import
|
|
21769
|
+
import process17 from "node:process";
|
|
20664
21770
|
|
|
20665
21771
|
// server/service/service-manager.js
|
|
20666
21772
|
init_config();
|
|
@@ -21263,7 +22369,7 @@ var ServiceManager = class {
|
|
|
21263
22369
|
minUpdatedAt = 0,
|
|
21264
22370
|
timeoutMs = 5e3
|
|
21265
22371
|
} = {}) {
|
|
21266
|
-
const { setTimeout:
|
|
22372
|
+
const { setTimeout: sleep4 } = await import("node:timers/promises");
|
|
21267
22373
|
const start = this.now();
|
|
21268
22374
|
let lastState = null;
|
|
21269
22375
|
while (this.now() - start < timeoutMs) {
|
|
@@ -21273,7 +22379,7 @@ var ServiceManager = class {
|
|
|
21273
22379
|
if (state.running && state.pid && restarted) {
|
|
21274
22380
|
return state;
|
|
21275
22381
|
}
|
|
21276
|
-
await
|
|
22382
|
+
await sleep4(100);
|
|
21277
22383
|
}
|
|
21278
22384
|
throw new Error(
|
|
21279
22385
|
`daemon start timeout (${timeoutMs}ms), state=${lastState?.state || "unknown"}, pid=${Number(lastState?.pid ?? 0)}`
|
|
@@ -21502,11 +22608,11 @@ function parseArgs2(argv) {
|
|
|
21502
22608
|
return options;
|
|
21503
22609
|
}
|
|
21504
22610
|
function print3(message) {
|
|
21505
|
-
|
|
22611
|
+
process17.stdout.write(`${message}
|
|
21506
22612
|
`);
|
|
21507
22613
|
}
|
|
21508
22614
|
function printError(message) {
|
|
21509
|
-
|
|
22615
|
+
process17.stderr.write(`${message}
|
|
21510
22616
|
`);
|
|
21511
22617
|
}
|
|
21512
22618
|
function shellQuoteForDisplay(value) {
|
|
@@ -21545,10 +22651,10 @@ function formatRunningCommand(argv) {
|
|
|
21545
22651
|
return command.map((item) => shellQuoteForDisplay(item)).join(" ");
|
|
21546
22652
|
}
|
|
21547
22653
|
function formatRuntimeEntryCommand(argv) {
|
|
21548
|
-
const command = [
|
|
22654
|
+
const command = [process17.execPath, resolvePackageBinPath(), ...redactSensitiveArgs(argv)];
|
|
21549
22655
|
return command.map((item) => shellQuoteForDisplay(item)).join(" ");
|
|
21550
22656
|
}
|
|
21551
|
-
function createServiceManager(env =
|
|
22657
|
+
function createServiceManager(env = process17.env) {
|
|
21552
22658
|
return new ServiceManager({ env });
|
|
21553
22659
|
}
|
|
21554
22660
|
function buildRuntimeEnv(options, env) {
|
|
@@ -21566,7 +22672,7 @@ function buildDaemonStatus(configStore) {
|
|
|
21566
22672
|
configPath: configStore.filePath
|
|
21567
22673
|
};
|
|
21568
22674
|
}
|
|
21569
|
-
async function prepareDaemonConfig(options, env =
|
|
22675
|
+
async function prepareDaemonConfig(options, env = process17.env, { persistResolvedConfig = false } = {}) {
|
|
21570
22676
|
const runtimeEnv = buildRuntimeEnv(options, env);
|
|
21571
22677
|
const configStore = new ConfigStore(resolveDaemonConfigPath(runtimeEnv), {
|
|
21572
22678
|
env: runtimeEnv
|
|
@@ -21591,7 +22697,7 @@ async function prepareDaemonConfig(options, env = process16.env, { persistResolv
|
|
|
21591
22697
|
...buildDaemonStatus(configStore)
|
|
21592
22698
|
};
|
|
21593
22699
|
}
|
|
21594
|
-
async function runDefault(argv, env =
|
|
22700
|
+
async function runDefault(argv, env = process17.env) {
|
|
21595
22701
|
const options = parseArgs2(argv);
|
|
21596
22702
|
if (options.help) {
|
|
21597
22703
|
print3(usage3());
|
|
@@ -21705,7 +22811,7 @@ async function runSubcommand(name, argv, env, deps = {}) {
|
|
|
21705
22811
|
}
|
|
21706
22812
|
throw new Error(`\u672A\u77E5\u5B50\u547D\u4EE4: ${name}`);
|
|
21707
22813
|
}
|
|
21708
|
-
async function run3(argv, env =
|
|
22814
|
+
async function run3(argv, env = process17.env, deps = {}) {
|
|
21709
22815
|
const [first = ""] = argv;
|
|
21710
22816
|
if ([
|
|
21711
22817
|
"daemon",
|
|
@@ -21721,17 +22827,17 @@ async function run3(argv, env = process16.env, deps = {}) {
|
|
|
21721
22827
|
}
|
|
21722
22828
|
return runDefault(argv, env);
|
|
21723
22829
|
}
|
|
21724
|
-
async function main3(argv =
|
|
22830
|
+
async function main3(argv = process17.argv.slice(2), env = process17.env) {
|
|
21725
22831
|
try {
|
|
21726
22832
|
print3(`\u8FD0\u884C\u547D\u4EE4: ${formatRunningCommand(argv)}`);
|
|
21727
22833
|
print3(`\u5B9E\u9645\u5165\u53E3: ${formatRuntimeEntryCommand(argv)}`);
|
|
21728
22834
|
const exitCode = await run3(argv, env);
|
|
21729
|
-
|
|
22835
|
+
process17.exitCode = exitCode;
|
|
21730
22836
|
} catch (error) {
|
|
21731
22837
|
printError(error instanceof Error ? error.message : String(error));
|
|
21732
22838
|
printError("");
|
|
21733
22839
|
printError(usage3());
|
|
21734
|
-
|
|
22840
|
+
process17.exitCode = 1;
|
|
21735
22841
|
}
|
|
21736
22842
|
}
|
|
21737
22843
|
|