@dhf-claude/grix 0.1.8 → 0.1.10
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/.claude-plugin/plugin.json +1 -1
- 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 +2059 -905
- package/dist/index.js +1364 -2033
- package/hooks/hooks.json +34 -1
- package/package.json +8 -6
- 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.10",
|
|
15678
|
+
description: "Claude Code channel plugin for Aibot Grix",
|
|
15679
|
+
type: "module",
|
|
15680
|
+
repository: {
|
|
15681
|
+
type: "git",
|
|
15682
|
+
url: "git+ssh://git@github.com/askie/grix-claude.git"
|
|
15683
|
+
},
|
|
15684
|
+
bugs: {
|
|
15685
|
+
url: "https://github.com/askie/grix-claude/issues"
|
|
15686
|
+
},
|
|
15687
|
+
homepage: "https://github.com/askie/grix-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,40 @@ 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
|
}
|
|
15948
|
+
function normalizeSessionActivityKind(value) {
|
|
15949
|
+
const normalized = normalizeString20(value);
|
|
15950
|
+
if (!normalized || normalized === "composing") {
|
|
15951
|
+
return "typing";
|
|
15952
|
+
}
|
|
15953
|
+
return normalized;
|
|
15954
|
+
}
|
|
15571
15955
|
function buildAuthPayload(config) {
|
|
15956
|
+
const clientVersion = normalizeString20(config?.clientVersion) || pluginVersion;
|
|
15957
|
+
const hostVersion = normalizeString20(config?.hostVersion) || clientVersion;
|
|
15572
15958
|
return {
|
|
15573
15959
|
agent_id: config.agentID,
|
|
15574
15960
|
api_key: config.apiKey,
|
|
15575
15961
|
client: "claude-grix-claude-channel",
|
|
15576
|
-
client_type: "claude"
|
|
15962
|
+
client_type: "claude",
|
|
15963
|
+
contract_version: contractVersion,
|
|
15964
|
+
client_version: clientVersion,
|
|
15965
|
+
host_type: "claude",
|
|
15966
|
+
host_version: hostVersion,
|
|
15967
|
+
protocol_version: protocolVersion,
|
|
15968
|
+
capabilities: [...declaredCapabilities],
|
|
15969
|
+
local_actions: [...declaredLocalActions],
|
|
15970
|
+
adapter_hint: adapterHint
|
|
15577
15971
|
};
|
|
15578
15972
|
}
|
|
15579
15973
|
function buildSessionActivityPayload({
|
|
@@ -15585,8 +15979,8 @@ function buildSessionActivityPayload({
|
|
|
15585
15979
|
refEventID = ""
|
|
15586
15980
|
}) {
|
|
15587
15981
|
const payload = {
|
|
15588
|
-
session_id:
|
|
15589
|
-
kind:
|
|
15982
|
+
session_id: normalizeString20(sessionID),
|
|
15983
|
+
kind: normalizeSessionActivityKind(kind),
|
|
15590
15984
|
active: active === true
|
|
15591
15985
|
};
|
|
15592
15986
|
if (Number.isFinite(Number(ttlMs)) && Number(ttlMs) > 0) {
|
|
@@ -15596,17 +15990,21 @@ function buildSessionActivityPayload({
|
|
|
15596
15990
|
withOptionalString(payload, "ref_event_id", refEventID);
|
|
15597
15991
|
return payload;
|
|
15598
15992
|
}
|
|
15599
|
-
var verboseDebugEnabled, verboseDebugLogPath, AibotClient;
|
|
15993
|
+
var verboseDebugEnabled, verboseDebugLogPath, pluginVersion, AibotClient;
|
|
15600
15994
|
var init_aibot_client = __esm({
|
|
15601
15995
|
"server/aibot-client.js"() {
|
|
15602
15996
|
init_wrapper();
|
|
15997
|
+
init_package();
|
|
15998
|
+
init_protocol_contract();
|
|
15603
15999
|
verboseDebugEnabled = process.env.GRIX_CLAUDE_E2E_DEBUG === "1";
|
|
15604
|
-
verboseDebugLogPath =
|
|
16000
|
+
verboseDebugLogPath = normalizeString20(process.env.GRIX_CLAUDE_E2E_DEBUG_LOG);
|
|
16001
|
+
pluginVersion = normalizeString20(package_default?.version) || "0.1.0";
|
|
15605
16002
|
AibotClient = class {
|
|
15606
|
-
constructor({ onEventMessage, onEventStop, onEventRevoke, onStatus } = {}) {
|
|
16003
|
+
constructor({ onEventMessage, onEventStop, onEventRevoke, onLocalAction, onStatus } = {}) {
|
|
15607
16004
|
this.onEventMessage = onEventMessage;
|
|
15608
16005
|
this.onEventStop = onEventStop;
|
|
15609
16006
|
this.onEventRevoke = onEventRevoke;
|
|
16007
|
+
this.onLocalAction = onLocalAction;
|
|
15610
16008
|
this.onStatus = onStatus;
|
|
15611
16009
|
this.desired = false;
|
|
15612
16010
|
this.config = null;
|
|
@@ -15736,10 +16134,10 @@ var init_aibot_client = __esm({
|
|
|
15736
16134
|
expected: ["auth_ack"],
|
|
15737
16135
|
timeoutMs: 1e4
|
|
15738
16136
|
});
|
|
15739
|
-
logDebug(`auth response code=${Number(auth?.payload?.code ?? 0)} msg=${
|
|
16137
|
+
logDebug(`auth response code=${Number(auth?.payload?.code ?? 0)} msg=${normalizeString20(auth?.payload?.msg)}`);
|
|
15740
16138
|
const code = Number(auth?.payload?.code ?? 0);
|
|
15741
16139
|
if (code !== 0) {
|
|
15742
|
-
throw new Error(
|
|
16140
|
+
throw new Error(normalizeString20(auth?.payload?.msg) || `auth failed code=${code}`);
|
|
15743
16141
|
}
|
|
15744
16142
|
this.setStatus({
|
|
15745
16143
|
connecting: false,
|
|
@@ -15847,7 +16245,7 @@ var init_aibot_client = __esm({
|
|
|
15847
16245
|
}
|
|
15848
16246
|
async handleMessage(text) {
|
|
15849
16247
|
const packet = JSON.parse(text);
|
|
15850
|
-
const cmd =
|
|
16248
|
+
const cmd = normalizeString20(packet.cmd);
|
|
15851
16249
|
const seq = Number(packet.seq ?? 0);
|
|
15852
16250
|
logDebug(`recv cmd=${cmd} seq=${seq}`);
|
|
15853
16251
|
if (cmd === "ping") {
|
|
@@ -15871,6 +16269,10 @@ var init_aibot_client = __esm({
|
|
|
15871
16269
|
}
|
|
15872
16270
|
if (cmd === "event_revoke" && this.onEventRevoke) {
|
|
15873
16271
|
await this.onEventRevoke(packet.payload ?? {});
|
|
16272
|
+
return;
|
|
16273
|
+
}
|
|
16274
|
+
if (cmd === "local_action" && this.onLocalAction) {
|
|
16275
|
+
await this.onLocalAction(packet.payload ?? {});
|
|
15874
16276
|
}
|
|
15875
16277
|
}
|
|
15876
16278
|
setStatus(patch) {
|
|
@@ -15940,7 +16342,7 @@ var init_aibot_client = __esm({
|
|
|
15940
16342
|
}
|
|
15941
16343
|
ackEvent(eventID, { sessionID, msgID, receivedAt = Date.now() } = {}) {
|
|
15942
16344
|
const payload = {
|
|
15943
|
-
event_id:
|
|
16345
|
+
event_id: normalizeString20(eventID),
|
|
15944
16346
|
received_at: Math.floor(receivedAt)
|
|
15945
16347
|
};
|
|
15946
16348
|
withOptionalString(payload, "session_id", sessionID);
|
|
@@ -15949,8 +16351,8 @@ var init_aibot_client = __esm({
|
|
|
15949
16351
|
}
|
|
15950
16352
|
sendEventResult({ event_id, status, code = "", msg = "", updated_at = Date.now() }) {
|
|
15951
16353
|
const payload = {
|
|
15952
|
-
event_id:
|
|
15953
|
-
status:
|
|
16354
|
+
event_id: normalizeString20(event_id),
|
|
16355
|
+
status: normalizeString20(status),
|
|
15954
16356
|
updated_at: Math.floor(updated_at)
|
|
15955
16357
|
};
|
|
15956
16358
|
withOptionalString(payload, "code", code);
|
|
@@ -15959,7 +16361,7 @@ var init_aibot_client = __esm({
|
|
|
15959
16361
|
}
|
|
15960
16362
|
sendEventStopAck({ event_id, stop_id = "", accepted, updated_at = Date.now() }) {
|
|
15961
16363
|
const payload = {
|
|
15962
|
-
event_id:
|
|
16364
|
+
event_id: normalizeString20(event_id),
|
|
15963
16365
|
accepted: accepted === true,
|
|
15964
16366
|
updated_at: Math.floor(updated_at)
|
|
15965
16367
|
};
|
|
@@ -15975,8 +16377,8 @@ var init_aibot_client = __esm({
|
|
|
15975
16377
|
updated_at = Date.now()
|
|
15976
16378
|
}) {
|
|
15977
16379
|
const payload = {
|
|
15978
|
-
event_id:
|
|
15979
|
-
status:
|
|
16380
|
+
event_id: normalizeString20(event_id),
|
|
16381
|
+
status: normalizeString20(status),
|
|
15980
16382
|
updated_at: Math.floor(updated_at)
|
|
15981
16383
|
};
|
|
15982
16384
|
withOptionalString(payload, "stop_id", stop_id);
|
|
@@ -16013,8 +16415,8 @@ var init_aibot_client = __esm({
|
|
|
16013
16415
|
extra = {}
|
|
16014
16416
|
}) {
|
|
16015
16417
|
const payload = {
|
|
16016
|
-
session_id:
|
|
16017
|
-
client_msg_id:
|
|
16418
|
+
session_id: normalizeString20(sessionID),
|
|
16419
|
+
client_msg_id: normalizeString20(clientMsgID),
|
|
16018
16420
|
msg_type: 1,
|
|
16019
16421
|
content: String(text ?? ""),
|
|
16020
16422
|
extra
|
|
@@ -16040,11 +16442,11 @@ var init_aibot_client = __esm({
|
|
|
16040
16442
|
extra = {}
|
|
16041
16443
|
}) {
|
|
16042
16444
|
const payload = {
|
|
16043
|
-
session_id:
|
|
16044
|
-
client_msg_id:
|
|
16445
|
+
session_id: normalizeString20(sessionID),
|
|
16446
|
+
client_msg_id: normalizeString20(clientMsgID),
|
|
16045
16447
|
msg_type: 2,
|
|
16046
|
-
content:
|
|
16047
|
-
media_url:
|
|
16448
|
+
content: normalizeString20(caption) || "[attachment]",
|
|
16449
|
+
media_url: normalizeString20(mediaURL),
|
|
16048
16450
|
extra
|
|
16049
16451
|
};
|
|
16050
16452
|
withOptionalString(payload, "event_id", eventID);
|
|
@@ -16058,9 +16460,69 @@ var init_aibot_client = __esm({
|
|
|
16058
16460
|
}
|
|
16059
16461
|
return packet.payload ?? {};
|
|
16060
16462
|
}
|
|
16463
|
+
async sendAgentInvoke({
|
|
16464
|
+
invokeID = randomUUID5(),
|
|
16465
|
+
action,
|
|
16466
|
+
params = {},
|
|
16467
|
+
timeoutMs = 15e3
|
|
16468
|
+
} = {}) {
|
|
16469
|
+
const normalizedAction = normalizeString20(action);
|
|
16470
|
+
if (!normalizedAction) {
|
|
16471
|
+
throw new Error("sendAgentInvoke requires action");
|
|
16472
|
+
}
|
|
16473
|
+
const normalizedTimeoutMs = Number.isFinite(Number(timeoutMs)) && Number(timeoutMs) > 0 ? Math.floor(Number(timeoutMs)) : 15e3;
|
|
16474
|
+
const packet = await this.request("agent_invoke", {
|
|
16475
|
+
invoke_id: normalizeString20(invokeID) || randomUUID5(),
|
|
16476
|
+
action: normalizedAction,
|
|
16477
|
+
params: params && typeof params === "object" && !Array.isArray(params) ? params : {},
|
|
16478
|
+
timeout_ms: normalizedTimeoutMs
|
|
16479
|
+
}, {
|
|
16480
|
+
expected: ["agent_invoke_result", "error"],
|
|
16481
|
+
timeoutMs: normalizedTimeoutMs + 1e3
|
|
16482
|
+
});
|
|
16483
|
+
if (packet.cmd !== "agent_invoke_result") {
|
|
16484
|
+
throw buildSendNackError(packet);
|
|
16485
|
+
}
|
|
16486
|
+
return packet.payload ?? {};
|
|
16487
|
+
}
|
|
16488
|
+
async sendLocalActionResult({
|
|
16489
|
+
actionID,
|
|
16490
|
+
status,
|
|
16491
|
+
result = void 0,
|
|
16492
|
+
errorCode = "",
|
|
16493
|
+
errorMsg = "",
|
|
16494
|
+
timeoutMs = 15e3
|
|
16495
|
+
} = {}) {
|
|
16496
|
+
const normalizedActionID = normalizeString20(actionID);
|
|
16497
|
+
if (!normalizedActionID) {
|
|
16498
|
+
throw new Error("sendLocalActionResult requires actionID");
|
|
16499
|
+
}
|
|
16500
|
+
const normalizedStatus = normalizeString20(status);
|
|
16501
|
+
if (!normalizedStatus) {
|
|
16502
|
+
throw new Error("sendLocalActionResult requires status");
|
|
16503
|
+
}
|
|
16504
|
+
const normalizedTimeoutMs = Number.isFinite(Number(timeoutMs)) && Number(timeoutMs) > 0 ? Math.floor(Number(timeoutMs)) : 15e3;
|
|
16505
|
+
const payload = {
|
|
16506
|
+
action_id: normalizedActionID,
|
|
16507
|
+
status: normalizedStatus
|
|
16508
|
+
};
|
|
16509
|
+
if (arguments[0] && Object.prototype.hasOwnProperty.call(arguments[0], "result")) {
|
|
16510
|
+
payload.result = result;
|
|
16511
|
+
}
|
|
16512
|
+
withOptionalString(payload, "error_code", errorCode);
|
|
16513
|
+
withOptionalString(payload, "error_msg", errorMsg);
|
|
16514
|
+
const packet = await this.request("local_action_result", payload, {
|
|
16515
|
+
expected: ["local_action_ack", "error"],
|
|
16516
|
+
timeoutMs: normalizedTimeoutMs
|
|
16517
|
+
});
|
|
16518
|
+
if (packet.cmd !== "local_action_ack") {
|
|
16519
|
+
throw buildSendNackError(packet);
|
|
16520
|
+
}
|
|
16521
|
+
return packet.payload ?? {};
|
|
16522
|
+
}
|
|
16061
16523
|
async deleteMessage(sessionID, messageID, { timeoutMs = 2e4 } = {}) {
|
|
16062
|
-
const normalizedSessionID =
|
|
16063
|
-
const normalizedMessageID =
|
|
16524
|
+
const normalizedSessionID = normalizeString20(sessionID);
|
|
16525
|
+
const normalizedMessageID = normalizeString20(messageID);
|
|
16064
16526
|
if (!normalizedSessionID) {
|
|
16065
16527
|
throw new Error("deleteMessage requires sessionID");
|
|
16066
16528
|
}
|
|
@@ -16083,74 +16545,113 @@ var init_aibot_client = __esm({
|
|
|
16083
16545
|
}
|
|
16084
16546
|
});
|
|
16085
16547
|
|
|
16086
|
-
// server/
|
|
16087
|
-
|
|
16088
|
-
function normalizeString20(value) {
|
|
16548
|
+
// server/grix-card-link.js
|
|
16549
|
+
function normalizeString21(value) {
|
|
16089
16550
|
return String(value ?? "").trim();
|
|
16090
16551
|
}
|
|
16091
|
-
function
|
|
16092
|
-
return
|
|
16552
|
+
function hasComplexPayload(payload) {
|
|
16553
|
+
return Object.values(payload ?? {}).some((value) => Array.isArray(value) || value && typeof value === "object");
|
|
16093
16554
|
}
|
|
16094
|
-
function
|
|
16095
|
-
const
|
|
16096
|
-
|
|
16097
|
-
|
|
16098
|
-
|
|
16099
|
-
|
|
16100
|
-
|
|
16101
|
-
|
|
16555
|
+
function appendFlatPayload(params, payload) {
|
|
16556
|
+
for (const [rawKey, value] of Object.entries(payload ?? {})) {
|
|
16557
|
+
const key = normalizeString21(rawKey);
|
|
16558
|
+
if (!key || value == null) {
|
|
16559
|
+
continue;
|
|
16560
|
+
}
|
|
16561
|
+
if (typeof value === "string") {
|
|
16562
|
+
if (!value) {
|
|
16563
|
+
continue;
|
|
16564
|
+
}
|
|
16565
|
+
params.set(key, value);
|
|
16566
|
+
continue;
|
|
16567
|
+
}
|
|
16568
|
+
if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
16569
|
+
params.set(key, String(value));
|
|
16570
|
+
}
|
|
16102
16571
|
}
|
|
16103
|
-
|
|
16104
|
-
|
|
16105
|
-
|
|
16572
|
+
}
|
|
16573
|
+
function buildGrixCardURI(cardType, payload = {}) {
|
|
16574
|
+
const normalizedType = normalizeString21(cardType);
|
|
16575
|
+
if (!normalizedType) {
|
|
16576
|
+
throw new Error("cardType is required");
|
|
16106
16577
|
}
|
|
16107
|
-
const
|
|
16108
|
-
if (
|
|
16109
|
-
|
|
16578
|
+
const params = new URLSearchParams();
|
|
16579
|
+
if (hasComplexPayload(payload)) {
|
|
16580
|
+
params.set("d", JSON.stringify(payload));
|
|
16581
|
+
} else {
|
|
16582
|
+
appendFlatPayload(params, payload);
|
|
16110
16583
|
}
|
|
16111
|
-
|
|
16112
|
-
|
|
16113
|
-
|
|
16114
|
-
|
|
16115
|
-
|
|
16116
|
-
|
|
16117
|
-
|
|
16118
|
-
|
|
16119
|
-
|
|
16120
|
-
|
|
16121
|
-
|
|
16122
|
-
},
|
|
16123
|
-
error: ""
|
|
16124
|
-
};
|
|
16584
|
+
const query = params.toString();
|
|
16585
|
+
return `grix://card/${encodeURIComponent(normalizedType)}${query ? `?${query}` : ""}`;
|
|
16586
|
+
}
|
|
16587
|
+
function buildGrixCardLink({
|
|
16588
|
+
fallbackText,
|
|
16589
|
+
cardType,
|
|
16590
|
+
payload = {}
|
|
16591
|
+
}) {
|
|
16592
|
+
const normalizedFallbackText = normalizeString21(fallbackText);
|
|
16593
|
+
if (!normalizedFallbackText) {
|
|
16594
|
+
throw new Error("fallbackText is required");
|
|
16125
16595
|
}
|
|
16126
|
-
|
|
16127
|
-
|
|
16128
|
-
|
|
16129
|
-
|
|
16130
|
-
command,
|
|
16131
|
-
args: {},
|
|
16132
|
-
error: ""
|
|
16133
|
-
};
|
|
16596
|
+
return `[${normalizedFallbackText}](${buildGrixCardURI(cardType, payload)})`;
|
|
16597
|
+
}
|
|
16598
|
+
var init_grix_card_link = __esm({
|
|
16599
|
+
"server/grix-card-link.js"() {
|
|
16134
16600
|
}
|
|
16135
|
-
|
|
16601
|
+
});
|
|
16602
|
+
|
|
16603
|
+
// server/agent-open-session-card.js
|
|
16604
|
+
function normalizeString22(value) {
|
|
16605
|
+
return String(value ?? "").trim();
|
|
16606
|
+
}
|
|
16607
|
+
function buildAgentOpenSessionCardLink({
|
|
16608
|
+
fallbackText = "\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55",
|
|
16609
|
+
summaryText = "",
|
|
16610
|
+
detailText = "",
|
|
16611
|
+
initialCwd = "",
|
|
16612
|
+
submittedPath = ""
|
|
16613
|
+
} = {}) {
|
|
16614
|
+
const payload = {};
|
|
16615
|
+
const normalizedSummaryText = normalizeString22(summaryText);
|
|
16616
|
+
const normalizedDetailText = normalizeString22(detailText);
|
|
16617
|
+
const normalizedInitialCwd = normalizeString22(initialCwd);
|
|
16618
|
+
const normalizedSubmittedPath = normalizeString22(submittedPath);
|
|
16619
|
+
if (normalizedSummaryText) {
|
|
16620
|
+
payload.summary_text = normalizedSummaryText;
|
|
16621
|
+
}
|
|
16622
|
+
if (normalizedDetailText) {
|
|
16623
|
+
payload.detail_text = normalizedDetailText;
|
|
16624
|
+
}
|
|
16625
|
+
if (normalizedInitialCwd) {
|
|
16626
|
+
payload.initial_cwd = normalizedInitialCwd;
|
|
16627
|
+
}
|
|
16628
|
+
if (normalizedSubmittedPath) {
|
|
16629
|
+
payload.submitted_path = normalizedSubmittedPath;
|
|
16630
|
+
}
|
|
16631
|
+
return buildGrixCardLink({
|
|
16632
|
+
fallbackText: normalizeString22(fallbackText) || "\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55",
|
|
16633
|
+
cardType: "agent_open_session",
|
|
16634
|
+
payload
|
|
16635
|
+
});
|
|
16136
16636
|
}
|
|
16137
|
-
var
|
|
16138
|
-
"server/
|
|
16637
|
+
var init_agent_open_session_card = __esm({
|
|
16638
|
+
"server/agent-open-session-card.js"() {
|
|
16639
|
+
init_grix_card_link();
|
|
16139
16640
|
}
|
|
16140
16641
|
});
|
|
16141
16642
|
|
|
16142
16643
|
// server/inbound-event-meta.js
|
|
16143
|
-
function
|
|
16644
|
+
function normalizeString23(value) {
|
|
16144
16645
|
return String(value ?? "").trim();
|
|
16145
16646
|
}
|
|
16146
16647
|
function normalizeOptionalString(value) {
|
|
16147
|
-
return
|
|
16648
|
+
return normalizeString23(value) || "";
|
|
16148
16649
|
}
|
|
16149
16650
|
function normalizeStringArray(value) {
|
|
16150
16651
|
if (!Array.isArray(value)) {
|
|
16151
16652
|
return [];
|
|
16152
16653
|
}
|
|
16153
|
-
return value.map((item) =>
|
|
16654
|
+
return value.map((item) => normalizeString23(item)).filter((item) => item);
|
|
16154
16655
|
}
|
|
16155
16656
|
function normalizeJSONObject(value) {
|
|
16156
16657
|
if (!value) {
|
|
@@ -16206,6 +16707,43 @@ function normalizeAttachmentRecord(value) {
|
|
|
16206
16707
|
}
|
|
16207
16708
|
return attachment;
|
|
16208
16709
|
}
|
|
16710
|
+
function normalizeContextMessageRecord(value) {
|
|
16711
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
16712
|
+
return null;
|
|
16713
|
+
}
|
|
16714
|
+
const normalized = {
|
|
16715
|
+
msg_id: normalizeOptionalString(value.msg_id),
|
|
16716
|
+
sender_id: normalizeOptionalString(value.sender_id),
|
|
16717
|
+
sender_type: Number(value.sender_type ?? 0),
|
|
16718
|
+
msg_type: Number(value.msg_type ?? 0),
|
|
16719
|
+
content: String(value.content ?? ""),
|
|
16720
|
+
quoted_message_id: normalizeOptionalString(value.quoted_message_id),
|
|
16721
|
+
mention_user_ids: normalizeStringArray(value.mention_user_ids),
|
|
16722
|
+
created_at: Number(value.created_at ?? 0)
|
|
16723
|
+
};
|
|
16724
|
+
if (!normalized.msg_id) {
|
|
16725
|
+
return null;
|
|
16726
|
+
}
|
|
16727
|
+
return normalized;
|
|
16728
|
+
}
|
|
16729
|
+
function normalizeContextMessageArray(value) {
|
|
16730
|
+
if (Array.isArray(value)) {
|
|
16731
|
+
return value.map((item) => normalizeContextMessageRecord(item)).filter(Boolean);
|
|
16732
|
+
}
|
|
16733
|
+
if (typeof value === "string") {
|
|
16734
|
+
const trimmed = value.trim();
|
|
16735
|
+
if (!trimmed) {
|
|
16736
|
+
return [];
|
|
16737
|
+
}
|
|
16738
|
+
try {
|
|
16739
|
+
const parsed = JSON.parse(trimmed);
|
|
16740
|
+
return normalizeContextMessageArray(parsed);
|
|
16741
|
+
} catch {
|
|
16742
|
+
return [];
|
|
16743
|
+
}
|
|
16744
|
+
}
|
|
16745
|
+
return [];
|
|
16746
|
+
}
|
|
16209
16747
|
function deriveAttachments(payload, extra) {
|
|
16210
16748
|
const explicit = normalizeJSONArray(payload.attachments).map((item) => normalizeAttachmentRecord(item)).filter(Boolean);
|
|
16211
16749
|
if (explicit.length > 0) {
|
|
@@ -16235,19 +16773,25 @@ function stringifyJSON(value) {
|
|
|
16235
16773
|
}
|
|
16236
16774
|
return JSON.stringify(value);
|
|
16237
16775
|
}
|
|
16776
|
+
function deriveContextMessages(payload) {
|
|
16777
|
+
const currentMsgID = normalizeString23(payload.msg_id);
|
|
16778
|
+
return normalizeContextMessageArray(payload.context_messages).filter((entry) => entry.msg_id !== currentMsgID);
|
|
16779
|
+
}
|
|
16238
16780
|
function normalizeInboundEventPayload(rawPayload) {
|
|
16239
16781
|
const extra = normalizeJSONObject(rawPayload.extra);
|
|
16240
16782
|
const attachments = deriveAttachments(rawPayload, extra);
|
|
16241
16783
|
const bizCard = normalizeJSONObject(rawPayload.biz_card) ?? normalizeJSONObject(extra?.biz_card);
|
|
16242
16784
|
const channelData = normalizeJSONObject(rawPayload.channel_data) ?? normalizeJSONObject(extra?.channel_data);
|
|
16785
|
+
const contextMessages = deriveContextMessages(rawPayload);
|
|
16243
16786
|
return {
|
|
16244
|
-
event_id:
|
|
16245
|
-
event_type:
|
|
16246
|
-
|
|
16787
|
+
event_id: normalizeString23(rawPayload.event_id),
|
|
16788
|
+
event_type: normalizeString23(rawPayload.event_type),
|
|
16789
|
+
mirror_mode: normalizeString23(rawPayload.mirror_mode),
|
|
16790
|
+
session_id: normalizeString23(rawPayload.session_id),
|
|
16247
16791
|
session_type: normalizeOptionalString(rawPayload.session_type),
|
|
16248
|
-
msg_id:
|
|
16792
|
+
msg_id: normalizeString23(rawPayload.msg_id),
|
|
16249
16793
|
quoted_message_id: normalizeOptionalString(rawPayload.quoted_message_id),
|
|
16250
|
-
sender_id:
|
|
16794
|
+
sender_id: normalizeString23(rawPayload.sender_id),
|
|
16251
16795
|
owner_id: normalizeOptionalString(rawPayload.owner_id),
|
|
16252
16796
|
agent_id: normalizeOptionalString(rawPayload.agent_id),
|
|
16253
16797
|
msg_type: normalizeOptionalString(rawPayload.msg_type),
|
|
@@ -16258,7 +16802,8 @@ function normalizeInboundEventPayload(rawPayload) {
|
|
|
16258
16802
|
attachments_json: stringifyJSON(attachments),
|
|
16259
16803
|
attachment_count: attachments.length > 0 ? String(attachments.length) : "",
|
|
16260
16804
|
biz_card_json: stringifyJSON(bizCard),
|
|
16261
|
-
channel_data_json: stringifyJSON(channelData)
|
|
16805
|
+
channel_data_json: stringifyJSON(channelData),
|
|
16806
|
+
context_messages_json: stringifyJSON(contextMessages)
|
|
16262
16807
|
};
|
|
16263
16808
|
}
|
|
16264
16809
|
var init_inbound_event_meta = __esm({
|
|
@@ -16267,7 +16812,7 @@ var init_inbound_event_meta = __esm({
|
|
|
16267
16812
|
});
|
|
16268
16813
|
|
|
16269
16814
|
// server/daemon/worker-control-client.js
|
|
16270
|
-
function
|
|
16815
|
+
function normalizeString24(value) {
|
|
16271
16816
|
return String(value ?? "").trim();
|
|
16272
16817
|
}
|
|
16273
16818
|
async function parseJSONResponse(response) {
|
|
@@ -16282,8 +16827,8 @@ var init_worker_control_client = __esm({
|
|
|
16282
16827
|
"server/daemon/worker-control-client.js"() {
|
|
16283
16828
|
WorkerControlClient = class {
|
|
16284
16829
|
constructor({ controlURL, token, fetchImpl = globalThis.fetch, pingTimeoutMs = 5e3, deliverTimeoutMs = 1e4 } = {}) {
|
|
16285
|
-
this.controlURL =
|
|
16286
|
-
this.token =
|
|
16830
|
+
this.controlURL = normalizeString24(controlURL).replace(/\/+$/u, "");
|
|
16831
|
+
this.token = normalizeString24(token);
|
|
16287
16832
|
this.fetchImpl = fetchImpl;
|
|
16288
16833
|
this.pingTimeoutMs = pingTimeoutMs;
|
|
16289
16834
|
this.deliverTimeoutMs = deliverTimeoutMs;
|
|
@@ -16291,135 +16836,52 @@ var init_worker_control_client = __esm({
|
|
|
16291
16836
|
isConfigured() {
|
|
16292
16837
|
return Boolean(this.controlURL && this.token && typeof this.fetchImpl === "function");
|
|
16293
16838
|
}
|
|
16294
|
-
async
|
|
16839
|
+
async post(pathname, payload, timeoutMs) {
|
|
16295
16840
|
if (!this.isConfigured()) {
|
|
16296
16841
|
throw new Error("worker control is not configured");
|
|
16297
16842
|
}
|
|
16298
|
-
const response = await this.fetchImpl(`${this.controlURL}
|
|
16843
|
+
const response = await this.fetchImpl(`${this.controlURL}${pathname}`, {
|
|
16299
16844
|
method: "POST",
|
|
16300
16845
|
headers: {
|
|
16301
16846
|
"content-type": "application/json",
|
|
16302
16847
|
authorization: `Bearer ${this.token}`
|
|
16303
16848
|
},
|
|
16304
|
-
body: JSON.stringify(
|
|
16305
|
-
signal: AbortSignal.timeout(
|
|
16849
|
+
body: JSON.stringify(payload),
|
|
16850
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
16306
16851
|
});
|
|
16307
16852
|
const json = await parseJSONResponse(response);
|
|
16308
16853
|
if (!response.ok) {
|
|
16309
|
-
throw new Error(
|
|
16854
|
+
throw new Error(normalizeString24(json.error) || `worker control failed ${response.status}`);
|
|
16310
16855
|
}
|
|
16311
16856
|
return json;
|
|
16312
16857
|
}
|
|
16858
|
+
async deliverEvent(rawPayload) {
|
|
16859
|
+
return this.post("/v1/worker/deliver-event", { payload: rawPayload }, this.deliverTimeoutMs);
|
|
16860
|
+
}
|
|
16313
16861
|
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;
|
|
16862
|
+
return this.post("/v1/worker/deliver-stop", { payload: rawPayload }, this.deliverTimeoutMs);
|
|
16331
16863
|
}
|
|
16332
16864
|
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;
|
|
16865
|
+
return this.post("/v1/worker/deliver-revoke", { payload: rawPayload }, this.deliverTimeoutMs);
|
|
16866
|
+
}
|
|
16867
|
+
async deliverLocalAction(rawPayload) {
|
|
16868
|
+
return this.post("/v1/worker/deliver-local-action", { payload: rawPayload }, this.deliverTimeoutMs);
|
|
16350
16869
|
}
|
|
16351
16870
|
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;
|
|
16871
|
+
return this.post("/v1/worker/ping", {}, this.pingTimeoutMs);
|
|
16369
16872
|
}
|
|
16370
16873
|
};
|
|
16371
16874
|
}
|
|
16372
16875
|
});
|
|
16373
16876
|
|
|
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
16877
|
// server/daemon/claude-session-store.js
|
|
16416
16878
|
import path22 from "node:path";
|
|
16417
16879
|
import { access } from "node:fs/promises";
|
|
16418
|
-
function
|
|
16880
|
+
function normalizeString25(value) {
|
|
16419
16881
|
return String(value ?? "").trim();
|
|
16420
16882
|
}
|
|
16421
16883
|
function encodeClaudeProjectPath(cwd) {
|
|
16422
|
-
const normalized =
|
|
16884
|
+
const normalized = normalizeString25(cwd);
|
|
16423
16885
|
if (!normalized) {
|
|
16424
16886
|
return "";
|
|
16425
16887
|
}
|
|
@@ -16427,8 +16889,8 @@ function encodeClaudeProjectPath(cwd) {
|
|
|
16427
16889
|
}
|
|
16428
16890
|
function resolveClaudeSessionPath({ cwd, claudeSessionID, env = process.env } = {}) {
|
|
16429
16891
|
const projectKey = encodeClaudeProjectPath(cwd);
|
|
16430
|
-
const sessionID =
|
|
16431
|
-
const homeDir =
|
|
16892
|
+
const sessionID = normalizeString25(claudeSessionID);
|
|
16893
|
+
const homeDir = normalizeString25(env?.HOME);
|
|
16432
16894
|
if (!projectKey || !sessionID || !homeDir) {
|
|
16433
16895
|
return "";
|
|
16434
16896
|
}
|
|
@@ -16451,228 +16913,6 @@ var init_claude_session_store = __esm({
|
|
|
16451
16913
|
}
|
|
16452
16914
|
});
|
|
16453
16915
|
|
|
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
16916
|
// server/daemon/worker-health-inspector.js
|
|
16677
16917
|
function normalizeString26(value) {
|
|
16678
16918
|
return String(value ?? "").trim();
|
|
@@ -16930,7 +17170,7 @@ function resolveRecordInFlightActivityAt(record) {
|
|
|
16930
17170
|
const normalizedComposingAt = Number.isFinite(composingAt) && composingAt > 0 ? composingAt : 0;
|
|
16931
17171
|
return Math.max(normalizedUpdatedAt, normalizedComposingAt);
|
|
16932
17172
|
}
|
|
16933
|
-
function
|
|
17173
|
+
function sleep2(ms) {
|
|
16934
17174
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
16935
17175
|
}
|
|
16936
17176
|
var PendingEventOrchestrator;
|
|
@@ -17077,7 +17317,7 @@ var init_pending_event_orchestrator = __esm({
|
|
|
17077
17317
|
error: error instanceof Error ? error.message : String(error)
|
|
17078
17318
|
}, "error");
|
|
17079
17319
|
}
|
|
17080
|
-
await
|
|
17320
|
+
await sleep2(this.retryDelayMs);
|
|
17081
17321
|
const latestBinding = this.bindingRegistry.getByAibotSessionID(normalizedSessionID);
|
|
17082
17322
|
if (!canDeliverToWorker(latestBinding)) {
|
|
17083
17323
|
this.trace({
|
|
@@ -17192,9 +17432,474 @@ var init_session_queue = __esm({
|
|
|
17192
17432
|
}
|
|
17193
17433
|
});
|
|
17194
17434
|
|
|
17435
|
+
// server/inbound-interaction-action.js
|
|
17436
|
+
import path23 from "node:path";
|
|
17437
|
+
function normalizeString29(value) {
|
|
17438
|
+
return String(value ?? "").trim();
|
|
17439
|
+
}
|
|
17440
|
+
function buildUnmatchedResult() {
|
|
17441
|
+
return {
|
|
17442
|
+
matched: false,
|
|
17443
|
+
ok: false,
|
|
17444
|
+
source: "",
|
|
17445
|
+
action: null,
|
|
17446
|
+
errorCode: "",
|
|
17447
|
+
errorMsg: ""
|
|
17448
|
+
};
|
|
17449
|
+
}
|
|
17450
|
+
function buildErrorResult({
|
|
17451
|
+
source,
|
|
17452
|
+
errorCode,
|
|
17453
|
+
errorMsg
|
|
17454
|
+
} = {}) {
|
|
17455
|
+
return {
|
|
17456
|
+
matched: true,
|
|
17457
|
+
ok: false,
|
|
17458
|
+
source: normalizeString29(source),
|
|
17459
|
+
action: null,
|
|
17460
|
+
errorCode: normalizeString29(errorCode),
|
|
17461
|
+
errorMsg: normalizeString29(errorMsg)
|
|
17462
|
+
};
|
|
17463
|
+
}
|
|
17464
|
+
function buildSuccessResult({
|
|
17465
|
+
source,
|
|
17466
|
+
actionType,
|
|
17467
|
+
params,
|
|
17468
|
+
timeoutMs = 0
|
|
17469
|
+
} = {}) {
|
|
17470
|
+
return {
|
|
17471
|
+
matched: true,
|
|
17472
|
+
ok: true,
|
|
17473
|
+
source: normalizeString29(source),
|
|
17474
|
+
action: {
|
|
17475
|
+
action_type: normalizeString29(actionType),
|
|
17476
|
+
params: params && typeof params === "object" && !Array.isArray(params) ? params : {},
|
|
17477
|
+
timeout_ms: Number.isFinite(Number(timeoutMs)) && Number(timeoutMs) > 0 ? Math.floor(Number(timeoutMs)) : 0
|
|
17478
|
+
},
|
|
17479
|
+
errorCode: "",
|
|
17480
|
+
errorMsg: ""
|
|
17481
|
+
};
|
|
17482
|
+
}
|
|
17483
|
+
function decodeUrlComponentRepeatedly(value) {
|
|
17484
|
+
let current = normalizeString29(value);
|
|
17485
|
+
if (!current) {
|
|
17486
|
+
return "";
|
|
17487
|
+
}
|
|
17488
|
+
for (let index = 0; index < 3; index += 1) {
|
|
17489
|
+
try {
|
|
17490
|
+
const decoded = decodeURIComponent(current);
|
|
17491
|
+
if (decoded === current) {
|
|
17492
|
+
break;
|
|
17493
|
+
}
|
|
17494
|
+
current = decoded;
|
|
17495
|
+
} catch {
|
|
17496
|
+
break;
|
|
17497
|
+
}
|
|
17498
|
+
}
|
|
17499
|
+
return normalizeString29(current);
|
|
17500
|
+
}
|
|
17501
|
+
function extractGrixCardURI(text) {
|
|
17502
|
+
const normalizedText = normalizeString29(text).replace(/&/giu, "&");
|
|
17503
|
+
if (!normalizedText) {
|
|
17504
|
+
return "";
|
|
17505
|
+
}
|
|
17506
|
+
const match = normalizedText.match(/grix:\/\/card\/[^\s)]+/u);
|
|
17507
|
+
return normalizeString29(match?.[0] ?? normalizedText);
|
|
17508
|
+
}
|
|
17509
|
+
function parseGrixCardURI(text) {
|
|
17510
|
+
const rawURI = extractGrixCardURI(text);
|
|
17511
|
+
if (!rawURI) {
|
|
17512
|
+
return null;
|
|
17513
|
+
}
|
|
17514
|
+
let parsed;
|
|
17515
|
+
try {
|
|
17516
|
+
parsed = new URL(rawURI);
|
|
17517
|
+
} catch {
|
|
17518
|
+
return null;
|
|
17519
|
+
}
|
|
17520
|
+
if (parsed.protocol !== "grix:" || normalizeString29(parsed.hostname) !== "card") {
|
|
17521
|
+
return null;
|
|
17522
|
+
}
|
|
17523
|
+
return parsed;
|
|
17524
|
+
}
|
|
17525
|
+
function normalizeResolutionMapEntries(entries) {
|
|
17526
|
+
if (!Array.isArray(entries)) {
|
|
17527
|
+
return [];
|
|
17528
|
+
}
|
|
17529
|
+
return entries.map((entry) => {
|
|
17530
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
17531
|
+
return null;
|
|
17532
|
+
}
|
|
17533
|
+
const key = normalizeString29(entry.key);
|
|
17534
|
+
const value = normalizeString29(entry.value);
|
|
17535
|
+
if (!key || !value) {
|
|
17536
|
+
return null;
|
|
17537
|
+
}
|
|
17538
|
+
return { key, value };
|
|
17539
|
+
}).filter(Boolean);
|
|
17540
|
+
}
|
|
17541
|
+
function parseQuestionReplyPayload(rawPayload) {
|
|
17542
|
+
const decoded = decodeUrlComponentRepeatedly(rawPayload);
|
|
17543
|
+
if (!decoded) {
|
|
17544
|
+
return null;
|
|
17545
|
+
}
|
|
17546
|
+
try {
|
|
17547
|
+
const parsed = JSON.parse(decoded);
|
|
17548
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
17549
|
+
} catch {
|
|
17550
|
+
return null;
|
|
17551
|
+
}
|
|
17552
|
+
}
|
|
17553
|
+
function parseQuestionReplyAction(parsedURI) {
|
|
17554
|
+
const payload = parseQuestionReplyPayload(parsedURI?.searchParams?.get("d"));
|
|
17555
|
+
if (!payload) {
|
|
17556
|
+
return buildErrorResult({
|
|
17557
|
+
source: "grix_card_question_reply",
|
|
17558
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17559
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u5185\u5BB9\u683C\u5F0F\u4E0D\u6B63\u786E\u3002"
|
|
17560
|
+
});
|
|
17561
|
+
}
|
|
17562
|
+
const requestID = normalizeString29(payload.request_id);
|
|
17563
|
+
if (!requestID) {
|
|
17564
|
+
return buildErrorResult({
|
|
17565
|
+
source: "grix_card_question_reply",
|
|
17566
|
+
errorCode: interactionReplyErrorCodes.requestIDRequired,
|
|
17567
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7F3A\u5C11 request_id\u3002"
|
|
17568
|
+
});
|
|
17569
|
+
}
|
|
17570
|
+
const action = normalizeString29(payload.action).toLowerCase();
|
|
17571
|
+
if (action) {
|
|
17572
|
+
if (!["accept", "cancel", "decline"].includes(action)) {
|
|
17573
|
+
return buildErrorResult({
|
|
17574
|
+
source: "grix_card_question_reply",
|
|
17575
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17576
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u52A8\u4F5C\u65E0\u6548\u3002"
|
|
17577
|
+
});
|
|
17578
|
+
}
|
|
17579
|
+
return buildSuccessResult({
|
|
17580
|
+
source: "grix_card_question_reply",
|
|
17581
|
+
actionType: localActionTypes.interactionReply,
|
|
17582
|
+
timeoutMs: 15e3,
|
|
17583
|
+
params: {
|
|
17584
|
+
kind: interactionKinds.elicitation,
|
|
17585
|
+
request_id: requestID,
|
|
17586
|
+
resolution: {
|
|
17587
|
+
type: interactionResolutionTypes.action,
|
|
17588
|
+
value: action
|
|
17589
|
+
}
|
|
17590
|
+
}
|
|
17591
|
+
});
|
|
17592
|
+
}
|
|
17593
|
+
const response = payload.response;
|
|
17594
|
+
if (!response || typeof response !== "object" || Array.isArray(response)) {
|
|
17595
|
+
return buildErrorResult({
|
|
17596
|
+
source: "grix_card_question_reply",
|
|
17597
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17598
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7F3A\u5C11\u7B54\u6848\u5185\u5BB9\u3002"
|
|
17599
|
+
});
|
|
17600
|
+
}
|
|
17601
|
+
const responseType = normalizeString29(response.type).toLowerCase();
|
|
17602
|
+
if (responseType === "single") {
|
|
17603
|
+
const value = normalizeString29(response.value);
|
|
17604
|
+
if (!value) {
|
|
17605
|
+
return buildErrorResult({
|
|
17606
|
+
source: "grix_card_question_reply",
|
|
17607
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17608
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7F3A\u5C11\u7B54\u6848\u5185\u5BB9\u3002"
|
|
17609
|
+
});
|
|
17610
|
+
}
|
|
17611
|
+
return buildSuccessResult({
|
|
17612
|
+
source: "grix_card_question_reply",
|
|
17613
|
+
actionType: localActionTypes.interactionReply,
|
|
17614
|
+
timeoutMs: 15e3,
|
|
17615
|
+
params: {
|
|
17616
|
+
kind: interactionKinds.elicitation,
|
|
17617
|
+
request_id: requestID,
|
|
17618
|
+
resolution: {
|
|
17619
|
+
type: interactionResolutionTypes.text,
|
|
17620
|
+
value
|
|
17621
|
+
}
|
|
17622
|
+
}
|
|
17623
|
+
});
|
|
17624
|
+
}
|
|
17625
|
+
if (responseType === "map") {
|
|
17626
|
+
const entries = normalizeResolutionMapEntries(response.entries);
|
|
17627
|
+
if (entries.length === 0) {
|
|
17628
|
+
return buildErrorResult({
|
|
17629
|
+
source: "grix_card_question_reply",
|
|
17630
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17631
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7F3A\u5C11\u6709\u6548\u7B54\u6848\u3002"
|
|
17632
|
+
});
|
|
17633
|
+
}
|
|
17634
|
+
return buildSuccessResult({
|
|
17635
|
+
source: "grix_card_question_reply",
|
|
17636
|
+
actionType: localActionTypes.interactionReply,
|
|
17637
|
+
timeoutMs: 15e3,
|
|
17638
|
+
params: {
|
|
17639
|
+
kind: interactionKinds.elicitation,
|
|
17640
|
+
request_id: requestID,
|
|
17641
|
+
resolution: {
|
|
17642
|
+
type: interactionResolutionTypes.map,
|
|
17643
|
+
entries
|
|
17644
|
+
}
|
|
17645
|
+
}
|
|
17646
|
+
});
|
|
17647
|
+
}
|
|
17648
|
+
return buildErrorResult({
|
|
17649
|
+
source: "grix_card_question_reply",
|
|
17650
|
+
errorCode: interactionReplyErrorCodes.resolutionInvalid,
|
|
17651
|
+
errorMsg: "\u4EA4\u4E92\u56DE\u590D\u7C7B\u578B\u65E0\u6548\u3002"
|
|
17652
|
+
});
|
|
17653
|
+
}
|
|
17654
|
+
function parseOpenSessionAction(parsedURI) {
|
|
17655
|
+
const cwd = decodeUrlComponentRepeatedly(parsedURI?.searchParams?.get("cwd"));
|
|
17656
|
+
if (!cwd) {
|
|
17657
|
+
return buildErrorResult({
|
|
17658
|
+
source: "grix_card_open_session_submit",
|
|
17659
|
+
errorCode: sessionControlErrorCodes.cwdRequired,
|
|
17660
|
+
errorMsg: "\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u65F6\u7F3A\u5C11\u76EE\u5F55\u8DEF\u5F84\u3002"
|
|
17661
|
+
});
|
|
17662
|
+
}
|
|
17663
|
+
return buildSuccessResult({
|
|
17664
|
+
source: "grix_card_open_session_submit",
|
|
17665
|
+
actionType: localActionTypes.sessionControl,
|
|
17666
|
+
params: {
|
|
17667
|
+
verb: "open",
|
|
17668
|
+
cwd: path23.resolve(cwd)
|
|
17669
|
+
}
|
|
17670
|
+
});
|
|
17671
|
+
}
|
|
17672
|
+
function parseInboundInteractionAction(text) {
|
|
17673
|
+
const parsedURI = parseGrixCardURI(text);
|
|
17674
|
+
if (!parsedURI) {
|
|
17675
|
+
return buildUnmatchedResult();
|
|
17676
|
+
}
|
|
17677
|
+
const cardType = normalizeString29(parsedURI.pathname).replace(/^\/+/u, "");
|
|
17678
|
+
if (cardType === "agent_open_session_submit") {
|
|
17679
|
+
return parseOpenSessionAction(parsedURI);
|
|
17680
|
+
}
|
|
17681
|
+
if (cardType === "agent_question_reply") {
|
|
17682
|
+
return parseQuestionReplyAction(parsedURI);
|
|
17683
|
+
}
|
|
17684
|
+
return buildUnmatchedResult();
|
|
17685
|
+
}
|
|
17686
|
+
var init_inbound_interaction_action = __esm({
|
|
17687
|
+
"server/inbound-interaction-action.js"() {
|
|
17688
|
+
init_protocol_contract();
|
|
17689
|
+
}
|
|
17690
|
+
});
|
|
17691
|
+
|
|
17692
|
+
// server/daemon/session-control-action-handler.js
|
|
17693
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
17694
|
+
function normalizeString30(value) {
|
|
17695
|
+
return String(value ?? "").trim();
|
|
17696
|
+
}
|
|
17697
|
+
function buildBindingResult(binding) {
|
|
17698
|
+
return {
|
|
17699
|
+
aibot_session_id: normalizeString30(binding?.aibot_session_id),
|
|
17700
|
+
claude_session_id: normalizeString30(binding?.claude_session_id),
|
|
17701
|
+
cwd: normalizeString30(binding?.cwd),
|
|
17702
|
+
worker_status: normalizeString30(binding?.worker_status)
|
|
17703
|
+
};
|
|
17704
|
+
}
|
|
17705
|
+
function buildSuccessResult2(verb, outcome, binding) {
|
|
17706
|
+
return {
|
|
17707
|
+
status: localActionResultStatuses.ok,
|
|
17708
|
+
result: {
|
|
17709
|
+
domain: resultDomains.sessionControl,
|
|
17710
|
+
verb,
|
|
17711
|
+
outcome,
|
|
17712
|
+
binding: buildBindingResult(binding)
|
|
17713
|
+
}
|
|
17714
|
+
};
|
|
17715
|
+
}
|
|
17716
|
+
function buildFailure(errorCode, errorMsg) {
|
|
17717
|
+
return {
|
|
17718
|
+
status: localActionResultStatuses.failed,
|
|
17719
|
+
errorCode,
|
|
17720
|
+
errorMsg
|
|
17721
|
+
};
|
|
17722
|
+
}
|
|
17723
|
+
var DaemonSessionControlActionHandler;
|
|
17724
|
+
var init_session_control_action_handler = __esm({
|
|
17725
|
+
"server/daemon/session-control-action-handler.js"() {
|
|
17726
|
+
init_protocol_contract();
|
|
17727
|
+
init_daemon_paths();
|
|
17728
|
+
DaemonSessionControlActionHandler = class {
|
|
17729
|
+
constructor({
|
|
17730
|
+
env = process.env,
|
|
17731
|
+
bindingRegistry,
|
|
17732
|
+
workerProcessManager,
|
|
17733
|
+
bridgeServer,
|
|
17734
|
+
ensureWorker,
|
|
17735
|
+
ensureDirectoryExists: ensureDirectoryExists2
|
|
17736
|
+
} = {}) {
|
|
17737
|
+
this.env = env;
|
|
17738
|
+
this.bindingRegistry = bindingRegistry;
|
|
17739
|
+
this.workerProcessManager = workerProcessManager;
|
|
17740
|
+
this.bridgeServer = bridgeServer;
|
|
17741
|
+
this.ensureWorker = ensureWorker;
|
|
17742
|
+
this.ensureDirectoryExists = ensureDirectoryExists2;
|
|
17743
|
+
}
|
|
17744
|
+
getBinding(sessionID) {
|
|
17745
|
+
return this.bindingRegistry.getByAibotSessionID(sessionID);
|
|
17746
|
+
}
|
|
17747
|
+
async createBinding(sessionID, cwd) {
|
|
17748
|
+
const workerID = randomUUID6();
|
|
17749
|
+
const claudeSessionID = randomUUID6();
|
|
17750
|
+
const pluginDataDir = resolveWorkerPluginDataDir(sessionID, this.env);
|
|
17751
|
+
const now = Date.now();
|
|
17752
|
+
const created = await this.bindingRegistry.createBinding({
|
|
17753
|
+
aibot_session_id: sessionID,
|
|
17754
|
+
claude_session_id: claudeSessionID,
|
|
17755
|
+
cwd,
|
|
17756
|
+
worker_id: workerID,
|
|
17757
|
+
worker_status: bindingWorkerStatuses.starting,
|
|
17758
|
+
plugin_data_dir: pluginDataDir,
|
|
17759
|
+
created_at: now,
|
|
17760
|
+
updated_at: now,
|
|
17761
|
+
last_started_at: now,
|
|
17762
|
+
last_stopped_at: 0
|
|
17763
|
+
});
|
|
17764
|
+
await this.workerProcessManager.spawnWorker({
|
|
17765
|
+
aibotSessionID: created.aibot_session_id,
|
|
17766
|
+
cwd: created.cwd,
|
|
17767
|
+
pluginDataDir: created.plugin_data_dir,
|
|
17768
|
+
claudeSessionID: created.claude_session_id,
|
|
17769
|
+
workerID: created.worker_id,
|
|
17770
|
+
bridgeURL: this.bridgeServer.getURL(),
|
|
17771
|
+
bridgeToken: this.bridgeServer.token
|
|
17772
|
+
});
|
|
17773
|
+
return this.getBinding(sessionID) ?? created;
|
|
17774
|
+
}
|
|
17775
|
+
async handleOpen(sessionID, params) {
|
|
17776
|
+
const cwd = normalizeString30(params?.cwd);
|
|
17777
|
+
if (!cwd) {
|
|
17778
|
+
return buildFailure(sessionControlErrorCodes.cwdRequired, "session control cwd is required");
|
|
17779
|
+
}
|
|
17780
|
+
try {
|
|
17781
|
+
await this.ensureDirectoryExists(cwd);
|
|
17782
|
+
} catch (error) {
|
|
17783
|
+
return buildFailure(
|
|
17784
|
+
sessionControlErrorCodes.invalidCwd,
|
|
17785
|
+
normalizeString30(error?.message || error) || "session control cwd is invalid"
|
|
17786
|
+
);
|
|
17787
|
+
}
|
|
17788
|
+
const existing = this.getBinding(sessionID);
|
|
17789
|
+
if (existing) {
|
|
17790
|
+
if (existing.cwd !== cwd) {
|
|
17791
|
+
return buildFailure(
|
|
17792
|
+
sessionControlErrorCodes.rebindForbidden,
|
|
17793
|
+
"session binding cannot be changed to another working directory"
|
|
17794
|
+
);
|
|
17795
|
+
}
|
|
17796
|
+
try {
|
|
17797
|
+
await this.ensureWorker(existing, { ignoreAuthCooldown: true });
|
|
17798
|
+
} catch (error) {
|
|
17799
|
+
return buildFailure(
|
|
17800
|
+
sessionControlErrorCodes.runtimeError,
|
|
17801
|
+
normalizeString30(error?.message || error) || "session control open failed"
|
|
17802
|
+
);
|
|
17803
|
+
}
|
|
17804
|
+
return buildSuccessResult2(sessionControlVerbs.open, sessionControlOutcomes.alreadyBound, this.getBinding(sessionID) ?? existing);
|
|
17805
|
+
}
|
|
17806
|
+
try {
|
|
17807
|
+
const created = await this.createBinding(sessionID, cwd);
|
|
17808
|
+
return buildSuccessResult2(sessionControlVerbs.open, sessionControlOutcomes.opened, created);
|
|
17809
|
+
} catch (error) {
|
|
17810
|
+
return buildFailure(
|
|
17811
|
+
sessionControlErrorCodes.runtimeError,
|
|
17812
|
+
normalizeString30(error?.message || error) || "session control open failed"
|
|
17813
|
+
);
|
|
17814
|
+
}
|
|
17815
|
+
}
|
|
17816
|
+
handleStatus(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.status, sessionControlOutcomes.status, binding);
|
|
17822
|
+
}
|
|
17823
|
+
handleWhere(sessionID) {
|
|
17824
|
+
const binding = this.getBinding(sessionID);
|
|
17825
|
+
if (!binding) {
|
|
17826
|
+
return buildFailure(sessionControlErrorCodes.bindingMissing, "session binding was not found");
|
|
17827
|
+
}
|
|
17828
|
+
return buildSuccessResult2(sessionControlVerbs.where, sessionControlOutcomes.where, binding);
|
|
17829
|
+
}
|
|
17830
|
+
async handleStop(sessionID) {
|
|
17831
|
+
const binding = this.getBinding(sessionID);
|
|
17832
|
+
if (!binding) {
|
|
17833
|
+
return buildFailure(sessionControlErrorCodes.bindingMissing, "session binding was not found");
|
|
17834
|
+
}
|
|
17835
|
+
try {
|
|
17836
|
+
if (binding.worker_id) {
|
|
17837
|
+
await this.workerProcessManager.stopWorker(binding.worker_id);
|
|
17838
|
+
}
|
|
17839
|
+
await this.bindingRegistry.markWorkerStopped(sessionID, {
|
|
17840
|
+
updatedAt: Date.now(),
|
|
17841
|
+
lastStoppedAt: Date.now()
|
|
17842
|
+
});
|
|
17843
|
+
} catch (error) {
|
|
17844
|
+
return buildFailure(
|
|
17845
|
+
sessionControlErrorCodes.runtimeError,
|
|
17846
|
+
normalizeString30(error?.message || error) || "session control stop failed"
|
|
17847
|
+
);
|
|
17848
|
+
}
|
|
17849
|
+
return buildSuccessResult2(sessionControlVerbs.stop, sessionControlOutcomes.stopped, this.getBinding(sessionID) ?? {
|
|
17850
|
+
...binding,
|
|
17851
|
+
worker_status: bindingWorkerStatuses.stopped
|
|
17852
|
+
});
|
|
17853
|
+
}
|
|
17854
|
+
async handleLocalAction(action) {
|
|
17855
|
+
if (normalizeString30(action?.action_type) !== localActionTypes.sessionControl) {
|
|
17856
|
+
return {
|
|
17857
|
+
handled: false
|
|
17858
|
+
};
|
|
17859
|
+
}
|
|
17860
|
+
const sessionID = normalizeString30(action?.params?.session_id);
|
|
17861
|
+
if (!sessionID) {
|
|
17862
|
+
return {
|
|
17863
|
+
handled: true,
|
|
17864
|
+
response: buildFailure(localActionErrorCodes.localActionRouteMissing, "local action session_id is required")
|
|
17865
|
+
};
|
|
17866
|
+
}
|
|
17867
|
+
const verb = normalizeString30(action?.params?.verb).toLowerCase();
|
|
17868
|
+
switch (verb) {
|
|
17869
|
+
case sessionControlVerbs.open:
|
|
17870
|
+
return {
|
|
17871
|
+
handled: true,
|
|
17872
|
+
response: await this.handleOpen(sessionID, action.params)
|
|
17873
|
+
};
|
|
17874
|
+
case sessionControlVerbs.status:
|
|
17875
|
+
return {
|
|
17876
|
+
handled: true,
|
|
17877
|
+
response: this.handleStatus(sessionID)
|
|
17878
|
+
};
|
|
17879
|
+
case sessionControlVerbs.where:
|
|
17880
|
+
return {
|
|
17881
|
+
handled: true,
|
|
17882
|
+
response: this.handleWhere(sessionID)
|
|
17883
|
+
};
|
|
17884
|
+
case sessionControlVerbs.stop:
|
|
17885
|
+
return {
|
|
17886
|
+
handled: true,
|
|
17887
|
+
response: await this.handleStop(sessionID)
|
|
17888
|
+
};
|
|
17889
|
+
default:
|
|
17890
|
+
return {
|
|
17891
|
+
handled: true,
|
|
17892
|
+
response: buildFailure(sessionControlErrorCodes.verbInvalid, "session control verb is invalid")
|
|
17893
|
+
};
|
|
17894
|
+
}
|
|
17895
|
+
}
|
|
17896
|
+
};
|
|
17897
|
+
}
|
|
17898
|
+
});
|
|
17899
|
+
|
|
17195
17900
|
// server/worker-probe.js
|
|
17196
17901
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
17197
|
-
function
|
|
17902
|
+
function normalizeString31(value) {
|
|
17198
17903
|
return String(value ?? "").trim();
|
|
17199
17904
|
}
|
|
17200
17905
|
function buildWorkerPingProbePayload({ sessionID, workerID = "", claudeSessionID = "" } = {}) {
|
|
@@ -17211,7 +17916,7 @@ function buildWorkerPingProbePayload({ sessionID, workerID = "", claudeSessionID
|
|
|
17211
17916
|
return {
|
|
17212
17917
|
event_id: `probe_${probeID}`,
|
|
17213
17918
|
event_type: "user_chat",
|
|
17214
|
-
session_id:
|
|
17919
|
+
session_id: normalizeString31(sessionID),
|
|
17215
17920
|
session_type: "1",
|
|
17216
17921
|
msg_id: `probe_msg_${probeID}`,
|
|
17217
17922
|
sender_id: probeSenderID,
|
|
@@ -17220,13 +17925,13 @@ function buildWorkerPingProbePayload({ sessionID, workerID = "", claudeSessionID
|
|
|
17220
17925
|
msg_type: "1",
|
|
17221
17926
|
content: "ping",
|
|
17222
17927
|
created_at: Date.now(),
|
|
17223
|
-
worker_id:
|
|
17224
|
-
claude_session_id:
|
|
17928
|
+
worker_id: normalizeString31(workerID),
|
|
17929
|
+
claude_session_id: normalizeString31(claudeSessionID),
|
|
17225
17930
|
channel_data: channelData
|
|
17226
17931
|
};
|
|
17227
17932
|
}
|
|
17228
17933
|
function isExpectedWorkerProbeReply(text, expectedReply = "pong") {
|
|
17229
|
-
return
|
|
17934
|
+
return normalizeString31(text).toLowerCase() === normalizeString31(expectedReply).toLowerCase();
|
|
17230
17935
|
}
|
|
17231
17936
|
var probeChannelNamespace, probeSenderID, probeKind, defaultWorkerPingProbeTimeoutMs;
|
|
17232
17937
|
var init_worker_probe = __esm({
|
|
@@ -17240,19 +17945,22 @@ var init_worker_probe = __esm({
|
|
|
17240
17945
|
|
|
17241
17946
|
// server/daemon/runtime.js
|
|
17242
17947
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
17243
|
-
import { stat as
|
|
17244
|
-
function
|
|
17948
|
+
import { stat as stat3 } from "node:fs/promises";
|
|
17949
|
+
function normalizeString32(value) {
|
|
17245
17950
|
return String(value ?? "").trim();
|
|
17246
17951
|
}
|
|
17247
|
-
function
|
|
17952
|
+
function isRecordOnlyMirror(event) {
|
|
17953
|
+
return normalizeString32(event?.mirror_mode) === "record_only";
|
|
17954
|
+
}
|
|
17955
|
+
function sleep3(ms) {
|
|
17248
17956
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17249
17957
|
}
|
|
17250
17958
|
async function ensureDirectoryExists(directoryPath) {
|
|
17251
17959
|
let info;
|
|
17252
17960
|
try {
|
|
17253
|
-
info = await
|
|
17961
|
+
info = await stat3(directoryPath);
|
|
17254
17962
|
} catch (error) {
|
|
17255
|
-
const code =
|
|
17963
|
+
const code = normalizeString32(error?.code);
|
|
17256
17964
|
if (code === "ENOENT") {
|
|
17257
17965
|
throw new Error("\u6307\u5B9A\u8DEF\u5F84\u4E0D\u5B58\u5728\u3002");
|
|
17258
17966
|
}
|
|
@@ -17265,44 +17973,6 @@ async function ensureDirectoryExists(directoryPath) {
|
|
|
17265
17973
|
throw new Error("\u6307\u5B9A\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55\u3002");
|
|
17266
17974
|
}
|
|
17267
17975
|
}
|
|
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
17976
|
function buildInterruptedEventNotice() {
|
|
17307
17977
|
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
17978
|
}
|
|
@@ -17312,46 +17982,147 @@ function buildAuthLoginRequiredEventNotice() {
|
|
|
17312
17982
|
function buildUsageLimitReachedEventNotice() {
|
|
17313
17983
|
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
17984
|
}
|
|
17985
|
+
function buildBindingMissingEventNotice() {
|
|
17986
|
+
return buildAgentOpenSessionCardLink({
|
|
17987
|
+
summaryText: "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002",
|
|
17988
|
+
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"
|
|
17989
|
+
});
|
|
17990
|
+
}
|
|
17991
|
+
function buildSessionControlOpenCardNotice({
|
|
17992
|
+
summaryText = "",
|
|
17993
|
+
detailText = "",
|
|
17994
|
+
initialCwd = ""
|
|
17995
|
+
} = {}) {
|
|
17996
|
+
return buildAgentOpenSessionCardLink({
|
|
17997
|
+
summaryText: normalizeString32(summaryText) || "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002",
|
|
17998
|
+
detailText: normalizeString32(detailText) || "\u5148\u63D0\u4EA4\u4E00\u4E2A\u5DE5\u4F5C\u76EE\u5F55\uFF0CClaude \u624D\u80FD\u7EE7\u7EED\u5904\u7406\u6D88\u606F\u3002",
|
|
17999
|
+
initialCwd
|
|
18000
|
+
});
|
|
18001
|
+
}
|
|
18002
|
+
function formatSessionControlBindingSummary(binding) {
|
|
18003
|
+
const normalizedBinding = binding ?? {};
|
|
18004
|
+
const cwd = normalizeString32(normalizedBinding.cwd);
|
|
18005
|
+
const workerStatus = normalizeString32(normalizedBinding.worker_status);
|
|
18006
|
+
const lines = [];
|
|
18007
|
+
if (cwd) {
|
|
18008
|
+
lines.push(`\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}`);
|
|
18009
|
+
}
|
|
18010
|
+
if (workerStatus) {
|
|
18011
|
+
lines.push(`\u72B6\u6001\uFF1A${workerStatus}`);
|
|
18012
|
+
}
|
|
18013
|
+
return lines.join("\n");
|
|
18014
|
+
}
|
|
18015
|
+
function buildSessionControlSuccessNotice(result) {
|
|
18016
|
+
const verb = normalizeString32(result?.verb);
|
|
18017
|
+
const outcome = normalizeString32(result?.outcome);
|
|
18018
|
+
const binding = result?.binding ?? {};
|
|
18019
|
+
const summary = formatSessionControlBindingSummary(binding);
|
|
18020
|
+
if (verb === sessionControlVerbs.open) {
|
|
18021
|
+
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";
|
|
18022
|
+
return summary ? `${title}
|
|
18023
|
+
|
|
18024
|
+
${summary}` : title;
|
|
18025
|
+
}
|
|
18026
|
+
if (verb === sessionControlVerbs.status) {
|
|
18027
|
+
return summary || "\u5F53\u524D\u5BF9\u8BDD\u5DF2\u7ECF\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18028
|
+
}
|
|
18029
|
+
if (verb === sessionControlVerbs.where) {
|
|
18030
|
+
const cwd = normalizeString32(binding.cwd);
|
|
18031
|
+
return cwd ? `\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF1A${cwd}` : "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18032
|
+
}
|
|
18033
|
+
if (verb === sessionControlVerbs.stop) {
|
|
18034
|
+
return summary ? `\u5DF2\u505C\u6B62\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F1A\u8BDD\u3002
|
|
18035
|
+
|
|
18036
|
+
${summary}` : "\u5DF2\u505C\u6B62\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4F1A\u8BDD\u3002";
|
|
18037
|
+
}
|
|
18038
|
+
return "\u5DE5\u4F5C\u76EE\u5F55\u64CD\u4F5C\u5DF2\u5B8C\u6210\u3002";
|
|
18039
|
+
}
|
|
18040
|
+
function buildSessionControlFailureNotice({
|
|
18041
|
+
errorCode = "",
|
|
18042
|
+
errorMsg = ""
|
|
18043
|
+
} = {}) {
|
|
18044
|
+
const normalizedErrorCode = normalizeString32(errorCode);
|
|
18045
|
+
const normalizedErrorMsg = normalizeString32(errorMsg);
|
|
18046
|
+
if (normalizedErrorCode === sessionControlErrorCodes.rebindForbidden) {
|
|
18047
|
+
return normalizedErrorMsg || "\u5F53\u524D\u5BF9\u8BDD\u5DF2\u7ECF\u56FA\u5B9A\u7ED1\u5B9A\u5230\u53E6\u4E00\u4E2A\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18048
|
+
}
|
|
18049
|
+
if (normalizedErrorCode === sessionControlErrorCodes.verbInvalid) {
|
|
18050
|
+
return normalizedErrorMsg || "\u547D\u4EE4\u683C\u5F0F\u4E0D\u6B63\u786E\u3002";
|
|
18051
|
+
}
|
|
18052
|
+
return normalizedErrorMsg || "\u5DE5\u4F5C\u76EE\u5F55\u64CD\u4F5C\u5931\u8D25\u3002";
|
|
18053
|
+
}
|
|
18054
|
+
function buildSessionControlCardSummary(errorCode, errorMsg) {
|
|
18055
|
+
const normalizedErrorCode = normalizeString32(errorCode);
|
|
18056
|
+
const normalizedErrorMsg = normalizeString32(errorMsg);
|
|
18057
|
+
if (normalizedErrorCode === sessionControlErrorCodes.bindingMissing) {
|
|
18058
|
+
return "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18059
|
+
}
|
|
18060
|
+
if (normalizedErrorCode === sessionControlErrorCodes.invalidCwd) {
|
|
18061
|
+
return normalizedErrorMsg || "\u6307\u5B9A\u8DEF\u5F84\u4E0D\u53EF\u7528\u3002";
|
|
18062
|
+
}
|
|
18063
|
+
if (normalizedErrorCode === sessionControlErrorCodes.cwdRequired) {
|
|
18064
|
+
return normalizedErrorMsg || "\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u65F6\u7F3A\u5C11\u76EE\u5F55\u8DEF\u5F84\u3002";
|
|
18065
|
+
}
|
|
18066
|
+
return normalizedErrorMsg || "\u5F53\u524D\u5BF9\u8BDD\u8FD8\u6CA1\u6709\u6253\u5F00\u5DE5\u4F5C\u76EE\u5F55\u3002";
|
|
18067
|
+
}
|
|
18068
|
+
function buildInteractionReplyFailureNotice({
|
|
18069
|
+
errorCode = "",
|
|
18070
|
+
errorMsg = ""
|
|
18071
|
+
} = {}) {
|
|
18072
|
+
const normalizedErrorCode = normalizeString32(errorCode);
|
|
18073
|
+
const normalizedErrorMsg = normalizeString32(errorMsg);
|
|
18074
|
+
if (normalizedErrorCode === interactionReplyErrorCodes.requestNotPending) {
|
|
18075
|
+
return "\u8FD9\u6761\u4EA4\u4E92\u5DF2\u7ECF\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u3002";
|
|
18076
|
+
}
|
|
18077
|
+
if (normalizedErrorCode === interactionReplyErrorCodes.requestNotFound) {
|
|
18078
|
+
return "\u6CA1\u6709\u627E\u5230\u5BF9\u5E94\u7684\u4EA4\u4E92\u8BF7\u6C42\u3002";
|
|
18079
|
+
}
|
|
18080
|
+
if (normalizedErrorCode === interactionReplyErrorCodes.requestIDRequired || normalizedErrorCode === interactionReplyErrorCodes.resolutionInvalid) {
|
|
18081
|
+
return normalizedErrorMsg || "\u4EA4\u4E92\u56DE\u590D\u683C\u5F0F\u4E0D\u6B63\u786E\u3002";
|
|
18082
|
+
}
|
|
18083
|
+
if (normalizedErrorCode === "local_action_delivery_failed") {
|
|
18084
|
+
return "Claude \u8FD8\u6CA1\u51C6\u5907\u597D\u5904\u7406\u8FD9\u6761\u4EA4\u4E92\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";
|
|
18085
|
+
}
|
|
18086
|
+
if (normalizedErrorCode === "local_action_result_timeout") {
|
|
18087
|
+
return "\u4EA4\u4E92\u56DE\u590D\u63D0\u4EA4\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";
|
|
18088
|
+
}
|
|
18089
|
+
return normalizedErrorMsg || "\u4EA4\u4E92\u56DE\u590D\u63D0\u4EA4\u5931\u8D25\u3002";
|
|
18090
|
+
}
|
|
17315
18091
|
function buildWorkerStartupFailedNotice() {
|
|
17316
18092
|
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
18093
|
}
|
|
17318
18094
|
function buildUsageLimitFailureOptions() {
|
|
17319
18095
|
return {
|
|
17320
18096
|
noticeText: buildUsageLimitReachedEventNotice(),
|
|
17321
|
-
replySource: "daemon_worker_usage_limit_reached",
|
|
17322
18097
|
resultCode: "claude_usage_limit_reached",
|
|
17323
18098
|
resultMessage: "claude usage limit reached; user action required"
|
|
17324
18099
|
};
|
|
17325
18100
|
}
|
|
17326
|
-
function
|
|
18101
|
+
function normalizeLocalActionPayload(rawPayload) {
|
|
17327
18102
|
return {
|
|
17328
|
-
|
|
17329
|
-
|
|
18103
|
+
action_id: normalizeString32(rawPayload?.action_id),
|
|
18104
|
+
event_id: normalizeString32(rawPayload?.event_id),
|
|
18105
|
+
action_type: normalizeString32(rawPayload?.action_type),
|
|
18106
|
+
params: rawPayload?.params && typeof rawPayload.params === "object" && !Array.isArray(rawPayload.params) ? rawPayload.params : {},
|
|
18107
|
+
timeout_ms: normalizeNonNegativeInt(rawPayload?.timeout_ms, 0)
|
|
17330
18108
|
};
|
|
17331
18109
|
}
|
|
17332
18110
|
function withWorkerLaunchFailure(binding, code) {
|
|
17333
18111
|
return {
|
|
17334
18112
|
...binding ?? {},
|
|
17335
|
-
worker_launch_failure:
|
|
18113
|
+
worker_launch_failure: normalizeString32(code)
|
|
17336
18114
|
};
|
|
17337
18115
|
}
|
|
17338
18116
|
function formatRuntimeError(error, fallback = "\u5904\u7406\u5931\u8D25\u3002") {
|
|
17339
|
-
const message =
|
|
18117
|
+
const message = normalizeString32(error?.message || error);
|
|
17340
18118
|
return message || fallback;
|
|
17341
18119
|
}
|
|
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
18120
|
function normalizeHookSignalRecord(input) {
|
|
17350
18121
|
if (!input || typeof input !== "object") {
|
|
17351
18122
|
return null;
|
|
17352
18123
|
}
|
|
17353
|
-
const eventID =
|
|
17354
|
-
const eventName =
|
|
18124
|
+
const eventID = normalizeString32(input.event_id);
|
|
18125
|
+
const eventName = normalizeString32(input.hook_event_name);
|
|
17355
18126
|
const eventAt = Number(input.event_at ?? 0);
|
|
17356
18127
|
if (!eventID || !eventName || !Number.isFinite(eventAt) || eventAt <= 0) {
|
|
17357
18128
|
return null;
|
|
@@ -17360,7 +18131,7 @@ function normalizeHookSignalRecord(input) {
|
|
|
17360
18131
|
event_id: eventID,
|
|
17361
18132
|
hook_event_name: eventName,
|
|
17362
18133
|
event_at: Math.floor(eventAt),
|
|
17363
|
-
detail:
|
|
18134
|
+
detail: normalizeString32(input.detail)
|
|
17364
18135
|
};
|
|
17365
18136
|
}
|
|
17366
18137
|
function listHookSignalRecords(pingPayload) {
|
|
@@ -17386,12 +18157,12 @@ function buildPingActivityTraceFields(pingPayload = {}) {
|
|
|
17386
18157
|
reported_mcp_ready: pingPayload?.mcp_ready === true ? true : pingPayload?.mcp_ready === false ? false : "",
|
|
17387
18158
|
reported_mcp_last_activity_at: normalizeNonNegativeInt(pingPayload?.mcp_last_activity_at, 0),
|
|
17388
18159
|
reported_hook_last_activity_at: normalizeNonNegativeInt(pingPayload?.hook_last_activity_at, 0),
|
|
17389
|
-
reported_hook_event_name:
|
|
18160
|
+
reported_hook_event_name: normalizeString32(pingPayload?.hook_latest_event?.hook_event_name)
|
|
17390
18161
|
};
|
|
17391
18162
|
}
|
|
17392
18163
|
function buildMcpHealthTraceFields(mcpHealth = {}) {
|
|
17393
18164
|
return {
|
|
17394
|
-
mcp_health_reason:
|
|
18165
|
+
mcp_health_reason: normalizeString32(mcpHealth?.reason),
|
|
17395
18166
|
mcp_health_idle_ms: normalizeNonNegativeInt(mcpHealth?.idleMs, 0),
|
|
17396
18167
|
inflight_event_count: normalizeNonNegativeInt(mcpHealth?.inFlightCount, 0),
|
|
17397
18168
|
latest_event_activity_at: normalizeNonNegativeInt(mcpHealth?.latestInteractionAt, 0),
|
|
@@ -17400,7 +18171,7 @@ function buildMcpHealthTraceFields(mcpHealth = {}) {
|
|
|
17400
18171
|
}
|
|
17401
18172
|
function buildMcpResultTimeoutTraceFields(details = {}) {
|
|
17402
18173
|
return {
|
|
17403
|
-
delivery_state:
|
|
18174
|
+
delivery_state: normalizeString32(details?.deliveryState),
|
|
17404
18175
|
record_updated_at: normalizeNonNegativeInt(details?.updatedAt, 0),
|
|
17405
18176
|
record_last_composing_at: normalizeNonNegativeInt(details?.lastComposingAt, 0),
|
|
17406
18177
|
record_interaction_at: normalizeNonNegativeInt(details?.recordInteractionAt, 0),
|
|
@@ -17416,6 +18187,9 @@ function normalizeNonNegativeInt(value, fallbackValue) {
|
|
|
17416
18187
|
}
|
|
17417
18188
|
return Math.max(0, Math.floor(numeric));
|
|
17418
18189
|
}
|
|
18190
|
+
function isSyntheticLocalActionID(actionID) {
|
|
18191
|
+
return normalizeString32(actionID).startsWith(syntheticLocalActionIDPrefix);
|
|
18192
|
+
}
|
|
17419
18193
|
function resolveExpectedWorkerPid(binding, runtime) {
|
|
17420
18194
|
const bindingPid = Number(binding?.worker_pid ?? 0);
|
|
17421
18195
|
if (Number.isFinite(bindingPid) && bindingPid > 0) {
|
|
@@ -17435,15 +18209,15 @@ function resolveExpectedIdentityWorkerPid(binding) {
|
|
|
17435
18209
|
return 0;
|
|
17436
18210
|
}
|
|
17437
18211
|
function buildRevokeDedupKey({ eventID = "", sessionID = "", msgID = "" } = {}) {
|
|
17438
|
-
const normalizedSessionID =
|
|
17439
|
-
const normalizedMsgID =
|
|
18212
|
+
const normalizedSessionID = normalizeString32(sessionID);
|
|
18213
|
+
const normalizedMsgID = normalizeString32(msgID);
|
|
17440
18214
|
if (normalizedSessionID && normalizedMsgID) {
|
|
17441
18215
|
return `${normalizedSessionID}:${normalizedMsgID}`;
|
|
17442
18216
|
}
|
|
17443
|
-
return
|
|
18217
|
+
return normalizeString32(eventID);
|
|
17444
18218
|
}
|
|
17445
18219
|
function classifyWorkerEventResult(payload) {
|
|
17446
|
-
const code =
|
|
18220
|
+
const code = normalizeString32(payload?.code);
|
|
17447
18221
|
if (workerResponseFailureCodes.has(code)) {
|
|
17448
18222
|
return {
|
|
17449
18223
|
state: "failed",
|
|
@@ -17453,27 +18227,28 @@ function classifyWorkerEventResult(payload) {
|
|
|
17453
18227
|
}
|
|
17454
18228
|
return {
|
|
17455
18229
|
state: "healthy",
|
|
17456
|
-
reason: code ||
|
|
18230
|
+
reason: code || normalizeString32(payload?.status) || "worker_event_result_observed",
|
|
17457
18231
|
failureCode: ""
|
|
17458
18232
|
};
|
|
17459
18233
|
}
|
|
17460
|
-
var defaultDeliveredInFlightMaxAgeMs, defaultWorkerControlProbeFailureThreshold, defaultMcpInteractionIdleMs, defaultMcpResultTimeoutMs, defaultRecentRevokeRetentionMs, defaultAuthFailureCooldownMs, defaultWorkerPingProbeRetentionMs, workerResponseFailureCodes, DaemonRuntime;
|
|
18234
|
+
var defaultDeliveredInFlightMaxAgeMs, defaultWorkerControlProbeFailureThreshold, defaultMcpInteractionIdleMs, defaultMcpResultTimeoutMs, defaultRecentRevokeRetentionMs, defaultAuthFailureCooldownMs, defaultWorkerPingProbeRetentionMs, syntheticLocalActionIDPrefix, workerResponseFailureCodes, DaemonRuntime;
|
|
17461
18235
|
var init_runtime = __esm({
|
|
17462
18236
|
"server/daemon/runtime.js"() {
|
|
17463
|
-
|
|
18237
|
+
init_agent_open_session_card();
|
|
17464
18238
|
init_inbound_event_meta();
|
|
17465
18239
|
init_message_delivery_store();
|
|
17466
18240
|
init_worker_control_client();
|
|
17467
|
-
init_control_card();
|
|
17468
18241
|
init_claude_session_store();
|
|
17469
|
-
init_control_command_handler();
|
|
17470
18242
|
init_worker_health_inspector();
|
|
17471
18243
|
init_pending_event_orchestrator();
|
|
17472
18244
|
init_session_queue();
|
|
17473
18245
|
init_process_control();
|
|
17474
18246
|
init_hook_signal_store();
|
|
18247
|
+
init_inbound_interaction_action();
|
|
18248
|
+
init_session_control_action_handler();
|
|
17475
18249
|
init_worker_state();
|
|
17476
18250
|
init_worker_probe();
|
|
18251
|
+
init_protocol_contract();
|
|
17477
18252
|
defaultDeliveredInFlightMaxAgeMs = 60 * 1e3;
|
|
17478
18253
|
defaultWorkerControlProbeFailureThreshold = 3;
|
|
17479
18254
|
defaultMcpInteractionIdleMs = 15 * 60 * 1e3;
|
|
@@ -17481,6 +18256,7 @@ var init_runtime = __esm({
|
|
|
17481
18256
|
defaultRecentRevokeRetentionMs = 24 * 60 * 60 * 1e3;
|
|
17482
18257
|
defaultAuthFailureCooldownMs = 60 * 1e3;
|
|
17483
18258
|
defaultWorkerPingProbeRetentionMs = 60 * 1e3;
|
|
18259
|
+
syntheticLocalActionIDPrefix = "synthetic-local-action:";
|
|
17484
18260
|
workerResponseFailureCodes = /* @__PURE__ */ new Set([
|
|
17485
18261
|
"claude_result_timeout",
|
|
17486
18262
|
"claude_usage_limit_reached",
|
|
@@ -17562,6 +18338,7 @@ var init_runtime = __esm({
|
|
|
17562
18338
|
this.workerControlProbeFailures = /* @__PURE__ */ new Map();
|
|
17563
18339
|
this.workerPingProbeRecords = /* @__PURE__ */ new Map();
|
|
17564
18340
|
this.workerPingProbeInFlight = /* @__PURE__ */ new Map();
|
|
18341
|
+
this.syntheticLocalActionWaiters = /* @__PURE__ */ new Map();
|
|
17565
18342
|
this.pendingEventWorkerLogCursors = /* @__PURE__ */ new Map();
|
|
17566
18343
|
this.ensureWorkerInFlight = /* @__PURE__ */ new Map();
|
|
17567
18344
|
this.resumeAuthRecoveryInFlight = /* @__PURE__ */ new Map();
|
|
@@ -17569,18 +18346,13 @@ var init_runtime = __esm({
|
|
|
17569
18346
|
this.sessionQueues = new SessionQueueRegistry(
|
|
17570
18347
|
(fields, level) => this.trace(fields, level)
|
|
17571
18348
|
);
|
|
17572
|
-
this.
|
|
18349
|
+
this.sessionControlActionHandler = new DaemonSessionControlActionHandler({
|
|
17573
18350
|
env: this.env,
|
|
17574
18351
|
bindingRegistry: this.bindingRegistry,
|
|
17575
18352
|
workerProcessManager: this.workerProcessManager,
|
|
17576
18353
|
bridgeServer: this.bridgeServer,
|
|
17577
18354
|
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
|
|
18355
|
+
ensureDirectoryExists
|
|
17584
18356
|
});
|
|
17585
18357
|
this.pendingEventOrchestrator = new PendingEventOrchestrator({
|
|
17586
18358
|
messageDeliveryStore: this.messageDeliveryStore,
|
|
@@ -17612,18 +18384,18 @@ var init_runtime = __esm({
|
|
|
17612
18384
|
}, { level });
|
|
17613
18385
|
}
|
|
17614
18386
|
async handleWorkerProcessExit({ workerID, aibotSessionID, exitCode, exitSignal }) {
|
|
17615
|
-
const sessionID =
|
|
18387
|
+
const sessionID = normalizeString32(aibotSessionID);
|
|
17616
18388
|
if (!sessionID) return;
|
|
17617
18389
|
const queue = this.sessionQueues.ensure(sessionID);
|
|
17618
18390
|
queue.run(async () => {
|
|
17619
18391
|
const binding = this.bindingRegistry.getByAibotSessionID(sessionID);
|
|
17620
|
-
if (!binding ||
|
|
18392
|
+
if (!binding || normalizeString32(binding.worker_id) !== normalizeString32(workerID)) {
|
|
17621
18393
|
return;
|
|
17622
18394
|
}
|
|
17623
18395
|
if (binding.worker_status === "stopped" || binding.worker_status === "failed") {
|
|
17624
18396
|
return;
|
|
17625
18397
|
}
|
|
17626
|
-
let signal =
|
|
18398
|
+
let signal = normalizeString32(exitSignal) || "wrapper_exited";
|
|
17627
18399
|
const hasAuthError = await this.workerProcessManager?.hasAuthLoginRequiredError?.(workerID);
|
|
17628
18400
|
if (hasAuthError) {
|
|
17629
18401
|
const runtime = this.workerProcessManager?.getWorkerRuntime?.(workerID);
|
|
@@ -17661,14 +18433,14 @@ var init_runtime = __esm({
|
|
|
17661
18433
|
});
|
|
17662
18434
|
}
|
|
17663
18435
|
getWorkerPingProbeRecord(eventID) {
|
|
17664
|
-
const normalizedEventID =
|
|
18436
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
17665
18437
|
if (!normalizedEventID) {
|
|
17666
18438
|
return null;
|
|
17667
18439
|
}
|
|
17668
18440
|
return this.workerPingProbeRecords.get(normalizedEventID) ?? null;
|
|
17669
18441
|
}
|
|
17670
18442
|
clearWorkerPingProbeRecord(eventID) {
|
|
17671
|
-
const normalizedEventID =
|
|
18443
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
17672
18444
|
if (!normalizedEventID) {
|
|
17673
18445
|
return;
|
|
17674
18446
|
}
|
|
@@ -17737,9 +18509,9 @@ var init_runtime = __esm({
|
|
|
17737
18509
|
event_id: record.eventID,
|
|
17738
18510
|
response_state: nextBinding?.worker_response_state,
|
|
17739
18511
|
response_reason: nextBinding?.worker_response_reason,
|
|
17740
|
-
terminal_status:
|
|
17741
|
-
terminal_code:
|
|
17742
|
-
probe_text:
|
|
18512
|
+
terminal_status: normalizeString32(payload?.status),
|
|
18513
|
+
terminal_code: normalizeString32(payload?.code),
|
|
18514
|
+
probe_text: normalizeString32(payload?.text)
|
|
17743
18515
|
}, level);
|
|
17744
18516
|
this.scheduleWorkerPingProbeRecordCleanup(record.eventID);
|
|
17745
18517
|
record.resolve?.(nextBinding);
|
|
@@ -17747,7 +18519,7 @@ var init_runtime = __esm({
|
|
|
17747
18519
|
return nextBinding;
|
|
17748
18520
|
}
|
|
17749
18521
|
async ensureWorkerPingProbe(binding) {
|
|
17750
|
-
const sessionID =
|
|
18522
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
17751
18523
|
if (!sessionID) {
|
|
17752
18524
|
return binding;
|
|
17753
18525
|
}
|
|
@@ -17769,7 +18541,7 @@ var init_runtime = __esm({
|
|
|
17769
18541
|
}
|
|
17770
18542
|
}
|
|
17771
18543
|
async runWorkerPingProbe(binding) {
|
|
17772
|
-
const sessionID =
|
|
18544
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
17773
18545
|
if (!sessionID || !hasReadyWorkerBridge(binding)) {
|
|
17774
18546
|
return binding;
|
|
17775
18547
|
}
|
|
@@ -17808,8 +18580,8 @@ var init_runtime = __esm({
|
|
|
17808
18580
|
const record = {
|
|
17809
18581
|
eventID: probePayload.event_id,
|
|
17810
18582
|
sessionID,
|
|
17811
|
-
workerID:
|
|
17812
|
-
claudeSessionID:
|
|
18583
|
+
workerID: normalizeString32(probingBinding?.worker_id),
|
|
18584
|
+
claudeSessionID: normalizeString32(probingBinding?.claude_session_id),
|
|
17813
18585
|
expectedReply: "pong",
|
|
17814
18586
|
state: "probing",
|
|
17815
18587
|
settled: false,
|
|
@@ -17849,7 +18621,7 @@ var init_runtime = __esm({
|
|
|
17849
18621
|
worker_id: record.workerID,
|
|
17850
18622
|
claude_session_id: record.claudeSessionID,
|
|
17851
18623
|
event_id: record.eventID,
|
|
17852
|
-
fallback_reason:
|
|
18624
|
+
fallback_reason: normalizeString32(record.lastControlPingReason) || "control_ping_unavailable"
|
|
17853
18625
|
}, "debug");
|
|
17854
18626
|
try {
|
|
17855
18627
|
await client.deliverEvent(probePayload);
|
|
@@ -17895,10 +18667,10 @@ var init_runtime = __esm({
|
|
|
17895
18667
|
}, "debug");
|
|
17896
18668
|
return null;
|
|
17897
18669
|
}
|
|
17898
|
-
const expectedWorkerID =
|
|
17899
|
-
const expectedClaudeSessionID =
|
|
17900
|
-
const currentWorkerID =
|
|
17901
|
-
const currentClaudeSessionID =
|
|
18670
|
+
const expectedWorkerID = normalizeString32(record?.workerID);
|
|
18671
|
+
const expectedClaudeSessionID = normalizeString32(record?.claudeSessionID);
|
|
18672
|
+
const currentWorkerID = normalizeString32(currentBinding?.worker_id);
|
|
18673
|
+
const currentClaudeSessionID = normalizeString32(currentBinding?.claude_session_id);
|
|
17902
18674
|
if (expectedWorkerID && currentWorkerID && expectedWorkerID !== currentWorkerID) {
|
|
17903
18675
|
record.lastControlPingReason = "worker_id_mismatch";
|
|
17904
18676
|
this.trace({
|
|
@@ -17940,26 +18712,26 @@ var init_runtime = __esm({
|
|
|
17940
18712
|
const runtime = this.workerProcessManager?.getWorkerRuntime?.(currentWorkerID);
|
|
17941
18713
|
const identityHealth = this.inspectWorkerIdentityHealth(currentBinding, runtime, pingPayload);
|
|
17942
18714
|
if (!identityHealth.ok) {
|
|
17943
|
-
record.lastControlPingReason =
|
|
18715
|
+
record.lastControlPingReason = normalizeString32(identityHealth.reason) || "identity_unhealthy";
|
|
17944
18716
|
this.trace({
|
|
17945
18717
|
stage: "worker_ping_probe_control_ping_unhealthy",
|
|
17946
18718
|
...traceContext,
|
|
17947
18719
|
reason: record.lastControlPingReason,
|
|
17948
18720
|
expected_pid: normalizeNonNegativeInt(identityHealth.expectedPid, 0),
|
|
17949
18721
|
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:
|
|
18722
|
+
expected_worker_id: normalizeString32(identityHealth.expectedWorkerID),
|
|
18723
|
+
reported_worker_id: normalizeString32(identityHealth.reportedWorkerID),
|
|
18724
|
+
expected_session_id: normalizeString32(identityHealth.expectedSessionID),
|
|
18725
|
+
reported_session_id: normalizeString32(identityHealth.reportedSessionID),
|
|
18726
|
+
expected_claude_session_id: normalizeString32(identityHealth.expectedClaudeSessionID),
|
|
18727
|
+
reported_claude_session_id: normalizeString32(identityHealth.reportedClaudeSessionID),
|
|
17956
18728
|
...buildPingActivityTraceFields(pingPayload)
|
|
17957
18729
|
});
|
|
17958
18730
|
return null;
|
|
17959
18731
|
}
|
|
17960
18732
|
const mcpHealth = this.inspectMcpInteractionHealth(currentBinding, pingPayload);
|
|
17961
18733
|
if (!mcpHealth.ok) {
|
|
17962
|
-
record.lastControlPingReason =
|
|
18734
|
+
record.lastControlPingReason = normalizeString32(mcpHealth.reason) || "mcp_unhealthy";
|
|
17963
18735
|
this.trace({
|
|
17964
18736
|
stage: "worker_ping_probe_control_ping_unhealthy",
|
|
17965
18737
|
...traceContext,
|
|
@@ -18020,7 +18792,7 @@ var init_runtime = __esm({
|
|
|
18020
18792
|
if (record.settled) {
|
|
18021
18793
|
return { handled: true, ack: { msg_id: `probe_${record.eventID}` } };
|
|
18022
18794
|
}
|
|
18023
|
-
const replyText =
|
|
18795
|
+
const replyText = normalizeString32(payload?.text);
|
|
18024
18796
|
if (isExpectedWorkerProbeReply(replyText, record.expectedReply)) {
|
|
18025
18797
|
await this.updateWorkerPingProbeOutcome(record, {
|
|
18026
18798
|
state: "healthy",
|
|
@@ -18044,8 +18816,8 @@ var init_runtime = __esm({
|
|
|
18044
18816
|
return { handled: false };
|
|
18045
18817
|
}
|
|
18046
18818
|
if (!record.settled) {
|
|
18047
|
-
const status =
|
|
18048
|
-
const code =
|
|
18819
|
+
const status = normalizeString32(payload?.status);
|
|
18820
|
+
const code = normalizeString32(payload?.code);
|
|
18049
18821
|
if (record.timeoutRecovering && status !== "responded" && code === "claude_result_timeout") {
|
|
18050
18822
|
this.trace({
|
|
18051
18823
|
stage: "worker_ping_probe_event_result_ignored_timeout_during_recovery",
|
|
@@ -18084,6 +18856,9 @@ var init_runtime = __esm({
|
|
|
18084
18856
|
this.clearWorkerPingProbeRecord(eventID);
|
|
18085
18857
|
}
|
|
18086
18858
|
this.workerPingProbeInFlight.clear();
|
|
18859
|
+
for (const actionID of [...this.syntheticLocalActionWaiters.keys()]) {
|
|
18860
|
+
this.clearSyntheticLocalActionWaiter(actionID);
|
|
18861
|
+
}
|
|
18087
18862
|
this.ensureWorkerInFlight.clear();
|
|
18088
18863
|
this.resumeAuthRecoveryInFlight.clear();
|
|
18089
18864
|
this.lastAuthRecoverySpawnAt.clear();
|
|
@@ -18120,14 +18895,19 @@ var init_runtime = __esm({
|
|
|
18120
18895
|
event_id: event.event_id,
|
|
18121
18896
|
status
|
|
18122
18897
|
};
|
|
18123
|
-
const normalizedCode =
|
|
18124
|
-
const normalizedMsg =
|
|
18898
|
+
const normalizedCode = normalizeString32(code);
|
|
18899
|
+
const normalizedMsg = normalizeString32(msg);
|
|
18125
18900
|
if (normalizedCode) {
|
|
18126
18901
|
payload.code = normalizedCode;
|
|
18127
18902
|
}
|
|
18128
18903
|
if (normalizedMsg) {
|
|
18129
18904
|
payload.msg = normalizedMsg;
|
|
18130
18905
|
}
|
|
18906
|
+
this.stopTypingForEvent({
|
|
18907
|
+
eventID: event.event_id,
|
|
18908
|
+
sessionID: event.session_id,
|
|
18909
|
+
msgID: event.msg_id
|
|
18910
|
+
});
|
|
18131
18911
|
this.aibotClient.sendEventResult(payload);
|
|
18132
18912
|
this.trace({
|
|
18133
18913
|
stage: "event_result_sent",
|
|
@@ -18142,26 +18922,278 @@ var init_runtime = __esm({
|
|
|
18142
18922
|
this.complete(event, result);
|
|
18143
18923
|
return response;
|
|
18144
18924
|
}
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
const
|
|
18152
|
-
|
|
18925
|
+
createSyntheticLocalActionWaiter(actionID, sessionID, timeoutMs) {
|
|
18926
|
+
const normalizedActionID = normalizeString32(actionID);
|
|
18927
|
+
const normalizedSessionID = normalizeString32(sessionID);
|
|
18928
|
+
const effectiveTimeoutMs = Math.max(1, normalizeNonNegativeInt(timeoutMs, 15e3));
|
|
18929
|
+
let resolvePromise = () => {
|
|
18930
|
+
};
|
|
18931
|
+
const promise = new Promise((resolve) => {
|
|
18932
|
+
resolvePromise = resolve;
|
|
18933
|
+
});
|
|
18934
|
+
const timer = setTimeout(() => {
|
|
18935
|
+
if (!this.syntheticLocalActionWaiters.has(normalizedActionID)) {
|
|
18936
|
+
return;
|
|
18937
|
+
}
|
|
18938
|
+
this.syntheticLocalActionWaiters.delete(normalizedActionID);
|
|
18939
|
+
resolvePromise({
|
|
18940
|
+
status: localActionResultStatuses.failed,
|
|
18941
|
+
result: void 0,
|
|
18942
|
+
errorCode: "local_action_result_timeout",
|
|
18943
|
+
errorMsg: "worker local action result timed out"
|
|
18944
|
+
});
|
|
18945
|
+
}, effectiveTimeoutMs);
|
|
18946
|
+
timer.unref?.();
|
|
18947
|
+
this.syntheticLocalActionWaiters.set(normalizedActionID, {
|
|
18948
|
+
sessionID: normalizedSessionID,
|
|
18949
|
+
resolve: resolvePromise,
|
|
18950
|
+
timer
|
|
18951
|
+
});
|
|
18952
|
+
return promise;
|
|
18953
|
+
}
|
|
18954
|
+
clearSyntheticLocalActionWaiter(actionID) {
|
|
18955
|
+
const normalizedActionID = normalizeString32(actionID);
|
|
18956
|
+
const pending = this.syntheticLocalActionWaiters.get(normalizedActionID);
|
|
18957
|
+
if (!pending) {
|
|
18958
|
+
return null;
|
|
18959
|
+
}
|
|
18960
|
+
clearTimeout(pending.timer);
|
|
18961
|
+
this.syntheticLocalActionWaiters.delete(normalizedActionID);
|
|
18962
|
+
return pending;
|
|
18963
|
+
}
|
|
18964
|
+
resolveSyntheticLocalActionWaiter(actionID, result) {
|
|
18965
|
+
const pending = this.clearSyntheticLocalActionWaiter(actionID);
|
|
18966
|
+
if (!pending) {
|
|
18967
|
+
return false;
|
|
18968
|
+
}
|
|
18969
|
+
pending.resolve(result);
|
|
18970
|
+
return true;
|
|
18971
|
+
}
|
|
18972
|
+
async observeWorkerLocalActionResult(payload) {
|
|
18973
|
+
const actionID = normalizeString32(payload?.action_id);
|
|
18974
|
+
if (!actionID) {
|
|
18975
|
+
return { handled: false };
|
|
18976
|
+
}
|
|
18977
|
+
const pending = this.syntheticLocalActionWaiters.get(actionID);
|
|
18978
|
+
if (!pending) {
|
|
18979
|
+
if (isSyntheticLocalActionID(actionID)) {
|
|
18980
|
+
this.trace({
|
|
18981
|
+
stage: "synthetic_local_action_result_ignored_late",
|
|
18982
|
+
action_id: actionID,
|
|
18983
|
+
session_id: this.resolveObservedSessionID(payload),
|
|
18984
|
+
worker_id: payload?.worker_id,
|
|
18985
|
+
claude_session_id: payload?.claude_session_id
|
|
18986
|
+
});
|
|
18987
|
+
return { handled: true };
|
|
18988
|
+
}
|
|
18989
|
+
return { handled: false };
|
|
18990
|
+
}
|
|
18991
|
+
const binding = this.bindingRegistry.getByAibotSessionID(pending.sessionID);
|
|
18992
|
+
if (binding && this.shouldIgnoreObservedWorker(binding, payload)) {
|
|
18993
|
+
this.trace({
|
|
18994
|
+
stage: "synthetic_local_action_result_ignored",
|
|
18995
|
+
action_id: actionID,
|
|
18996
|
+
session_id: pending.sessionID,
|
|
18997
|
+
worker_id: payload?.worker_id,
|
|
18998
|
+
claude_session_id: payload?.claude_session_id
|
|
18999
|
+
});
|
|
19000
|
+
return { handled: true };
|
|
19001
|
+
}
|
|
19002
|
+
this.trace({
|
|
19003
|
+
stage: "synthetic_local_action_result_observed",
|
|
19004
|
+
action_id: actionID,
|
|
19005
|
+
session_id: pending.sessionID,
|
|
19006
|
+
status: payload?.status,
|
|
19007
|
+
worker_id: payload?.worker_id
|
|
19008
|
+
});
|
|
19009
|
+
this.resolveSyntheticLocalActionWaiter(actionID, {
|
|
19010
|
+
status: normalizeString32(payload?.status) || localActionResultStatuses.failed,
|
|
19011
|
+
result: payload?.result,
|
|
19012
|
+
errorCode: normalizeString32(payload?.error_code),
|
|
19013
|
+
errorMsg: normalizeString32(payload?.error_msg)
|
|
19014
|
+
});
|
|
19015
|
+
return { handled: true };
|
|
19016
|
+
}
|
|
19017
|
+
async runSyntheticWorkerLocalAction(event, action) {
|
|
19018
|
+
const normalizedActionType = normalizeString32(action?.action_type);
|
|
19019
|
+
const params = action?.params && typeof action.params === "object" && !Array.isArray(action.params) ? action.params : {};
|
|
19020
|
+
const sessionID = normalizeString32(params.session_id) || normalizeString32(event?.session_id);
|
|
19021
|
+
if (!sessionID) {
|
|
19022
|
+
return {
|
|
19023
|
+
status: localActionResultStatuses.failed,
|
|
19024
|
+
result: void 0,
|
|
19025
|
+
errorCode: localActionErrorCodes.localActionRouteMissing,
|
|
19026
|
+
errorMsg: "local action session_id is required"
|
|
19027
|
+
};
|
|
19028
|
+
}
|
|
19029
|
+
const timeoutMs = Math.max(1, normalizeNonNegativeInt(action?.timeout_ms, 15e3));
|
|
19030
|
+
const actionID = `${syntheticLocalActionIDPrefix}${event?.event_id || randomUUID8()}:${randomUUID8()}`;
|
|
19031
|
+
const payload = {
|
|
19032
|
+
action_id: actionID,
|
|
19033
|
+
event_id: normalizeString32(event?.event_id),
|
|
19034
|
+
action_type: normalizedActionType,
|
|
19035
|
+
params: {
|
|
19036
|
+
...params,
|
|
19037
|
+
session_id: sessionID
|
|
19038
|
+
},
|
|
19039
|
+
timeout_ms: timeoutMs
|
|
19040
|
+
};
|
|
19041
|
+
const waitPromise = this.createSyntheticLocalActionWaiter(actionID, sessionID, timeoutMs);
|
|
19042
|
+
try {
|
|
19043
|
+
const routedBinding = await this.deliverWithRecovery(
|
|
19044
|
+
sessionID,
|
|
19045
|
+
payload,
|
|
19046
|
+
this.deliverLocalActionToWorker
|
|
19047
|
+
);
|
|
19048
|
+
if (routedBinding && canDeliverToWorker(routedBinding)) {
|
|
19049
|
+
return waitPromise;
|
|
19050
|
+
}
|
|
19051
|
+
this.resolveSyntheticLocalActionWaiter(actionID, {
|
|
19052
|
+
status: localActionResultStatuses.failed,
|
|
19053
|
+
result: void 0,
|
|
19054
|
+
errorCode: "local_action_delivery_failed",
|
|
19055
|
+
errorMsg: "worker is not ready for local action delivery"
|
|
19056
|
+
});
|
|
19057
|
+
return waitPromise;
|
|
19058
|
+
} catch (error) {
|
|
19059
|
+
this.resolveSyntheticLocalActionWaiter(actionID, {
|
|
19060
|
+
status: localActionResultStatuses.failed,
|
|
19061
|
+
result: void 0,
|
|
19062
|
+
errorCode: "local_action_delivery_failed",
|
|
19063
|
+
errorMsg: normalizeString32(error?.message || error) || "worker local action delivery failed"
|
|
19064
|
+
});
|
|
19065
|
+
return waitPromise;
|
|
19066
|
+
}
|
|
19067
|
+
}
|
|
19068
|
+
async handleSyntheticSessionControlEvent(event, action) {
|
|
19069
|
+
const params = action?.params && typeof action.params === "object" && !Array.isArray(action.params) ? action.params : {};
|
|
19070
|
+
const sessionControlResult = await this.sessionControlActionHandler.handleLocalAction({
|
|
19071
|
+
action_type: localActionTypes.sessionControl,
|
|
19072
|
+
params: {
|
|
19073
|
+
...params,
|
|
19074
|
+
session_id: event.session_id
|
|
19075
|
+
}
|
|
19076
|
+
});
|
|
19077
|
+
if (!sessionControlResult?.handled) {
|
|
19078
|
+
return false;
|
|
19079
|
+
}
|
|
19080
|
+
const response = sessionControlResult.response ?? {};
|
|
19081
|
+
const result = response.result ?? {};
|
|
19082
|
+
if (response.status === localActionResultStatuses.ok && normalizeString32(result.domain) === resultDomains.sessionControl) {
|
|
19083
|
+
await this.respond(event, buildSessionControlSuccessNotice(result), {}, {
|
|
19084
|
+
status: "responded"
|
|
19085
|
+
});
|
|
19086
|
+
return true;
|
|
19087
|
+
}
|
|
19088
|
+
const errorCode = normalizeString32(response.errorCode);
|
|
19089
|
+
const errorMsg = normalizeString32(response.errorMsg);
|
|
19090
|
+
if (errorCode === sessionControlErrorCodes.cwdRequired || errorCode === sessionControlErrorCodes.invalidCwd || errorCode === sessionControlErrorCodes.bindingMissing) {
|
|
19091
|
+
await this.respond(
|
|
19092
|
+
event,
|
|
19093
|
+
buildSessionControlOpenCardNotice({
|
|
19094
|
+
summaryText: buildSessionControlCardSummary(errorCode, errorMsg),
|
|
19095
|
+
initialCwd: normalizeString32(params.cwd)
|
|
19096
|
+
}),
|
|
19097
|
+
{},
|
|
19098
|
+
{
|
|
19099
|
+
status: "responded",
|
|
19100
|
+
code: errorCode,
|
|
19101
|
+
msg: errorMsg
|
|
19102
|
+
}
|
|
19103
|
+
);
|
|
19104
|
+
return true;
|
|
19105
|
+
}
|
|
19106
|
+
await this.respond(
|
|
19107
|
+
event,
|
|
19108
|
+
buildSessionControlFailureNotice({
|
|
19109
|
+
errorCode,
|
|
19110
|
+
errorMsg
|
|
19111
|
+
}),
|
|
19112
|
+
{},
|
|
19113
|
+
{
|
|
19114
|
+
status: "responded",
|
|
19115
|
+
code: errorCode,
|
|
19116
|
+
msg: errorMsg
|
|
19117
|
+
}
|
|
19118
|
+
);
|
|
19119
|
+
return true;
|
|
19120
|
+
}
|
|
19121
|
+
async handleSyntheticInteractionReplyEvent(event, action) {
|
|
19122
|
+
const actionResult = await this.runSyntheticWorkerLocalAction(event, action);
|
|
19123
|
+
if (normalizeString32(actionResult?.status) === localActionResultStatuses.ok) {
|
|
19124
|
+
this.complete(event, {
|
|
19125
|
+
status: "responded"
|
|
19126
|
+
});
|
|
19127
|
+
return true;
|
|
19128
|
+
}
|
|
19129
|
+
const errorCode = normalizeString32(actionResult?.errorCode);
|
|
19130
|
+
const errorMsg = normalizeString32(actionResult?.errorMsg);
|
|
19131
|
+
await this.respond(
|
|
18153
19132
|
event,
|
|
18154
|
-
|
|
19133
|
+
buildInteractionReplyFailureNotice({
|
|
19134
|
+
errorCode,
|
|
19135
|
+
errorMsg
|
|
19136
|
+
}),
|
|
19137
|
+
{},
|
|
18155
19138
|
{
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
initialCwd
|
|
18161
|
-
})
|
|
18162
|
-
},
|
|
18163
|
-
result
|
|
19139
|
+
status: "responded",
|
|
19140
|
+
code: errorCode,
|
|
19141
|
+
msg: errorMsg
|
|
19142
|
+
}
|
|
18164
19143
|
);
|
|
19144
|
+
return true;
|
|
19145
|
+
}
|
|
19146
|
+
async handleInteractionActionEvent(event) {
|
|
19147
|
+
const parsed = parseInboundInteractionAction(event.content);
|
|
19148
|
+
if (!parsed.matched) {
|
|
19149
|
+
return false;
|
|
19150
|
+
}
|
|
19151
|
+
this.trace({
|
|
19152
|
+
stage: "interaction_action_received",
|
|
19153
|
+
event_id: event.event_id,
|
|
19154
|
+
session_id: event.session_id,
|
|
19155
|
+
source: parsed.source,
|
|
19156
|
+
action_type: parsed.action?.action_type,
|
|
19157
|
+
ok: parsed.ok === true
|
|
19158
|
+
});
|
|
19159
|
+
if (!parsed.ok) {
|
|
19160
|
+
if (parsed.errorCode === sessionControlErrorCodes.cwdRequired) {
|
|
19161
|
+
await this.respond(
|
|
19162
|
+
event,
|
|
19163
|
+
buildSessionControlOpenCardNotice({
|
|
19164
|
+
summaryText: buildSessionControlCardSummary(parsed.errorCode, parsed.errorMsg)
|
|
19165
|
+
}),
|
|
19166
|
+
{},
|
|
19167
|
+
{
|
|
19168
|
+
status: "responded",
|
|
19169
|
+
code: parsed.errorCode,
|
|
19170
|
+
msg: parsed.errorMsg
|
|
19171
|
+
}
|
|
19172
|
+
);
|
|
19173
|
+
return true;
|
|
19174
|
+
}
|
|
19175
|
+
await this.respond(
|
|
19176
|
+
event,
|
|
19177
|
+
buildInteractionReplyFailureNotice({
|
|
19178
|
+
errorCode: parsed.errorCode,
|
|
19179
|
+
errorMsg: parsed.errorMsg
|
|
19180
|
+
}),
|
|
19181
|
+
{},
|
|
19182
|
+
{
|
|
19183
|
+
status: "responded",
|
|
19184
|
+
code: parsed.errorCode,
|
|
19185
|
+
msg: parsed.errorMsg
|
|
19186
|
+
}
|
|
19187
|
+
);
|
|
19188
|
+
return true;
|
|
19189
|
+
}
|
|
19190
|
+
if (normalizeString32(parsed.action?.action_type) === localActionTypes.sessionControl) {
|
|
19191
|
+
return this.handleSyntheticSessionControlEvent(event, parsed.action);
|
|
19192
|
+
}
|
|
19193
|
+
if (normalizeString32(parsed.action?.action_type) === localActionTypes.interactionReply) {
|
|
19194
|
+
return this.handleSyntheticInteractionReplyEvent(event, parsed.action);
|
|
19195
|
+
}
|
|
19196
|
+
return false;
|
|
18165
19197
|
}
|
|
18166
19198
|
ack(event) {
|
|
18167
19199
|
this.aibotClient.ackEvent(event.event_id, {
|
|
@@ -18176,9 +19208,36 @@ var init_runtime = __esm({
|
|
|
18176
19208
|
msg_id: event.msg_id
|
|
18177
19209
|
});
|
|
18178
19210
|
}
|
|
19211
|
+
stopTypingForEvent({
|
|
19212
|
+
eventID,
|
|
19213
|
+
sessionID = "",
|
|
19214
|
+
msgID = ""
|
|
19215
|
+
} = {}) {
|
|
19216
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
19217
|
+
const normalizedSessionID = normalizeString32(sessionID) || this.messageDeliveryStore.getRememberedSessionID(normalizedEventID);
|
|
19218
|
+
if (!normalizedEventID || !normalizedSessionID || typeof this.aibotClient?.setSessionComposing !== "function") {
|
|
19219
|
+
return;
|
|
19220
|
+
}
|
|
19221
|
+
try {
|
|
19222
|
+
this.aibotClient.setSessionComposing({
|
|
19223
|
+
sessionID: normalizedSessionID,
|
|
19224
|
+
kind: "typing",
|
|
19225
|
+
active: false,
|
|
19226
|
+
refMsgID: normalizeString32(msgID),
|
|
19227
|
+
refEventID: normalizedEventID
|
|
19228
|
+
});
|
|
19229
|
+
} catch (error) {
|
|
19230
|
+
this.trace({
|
|
19231
|
+
stage: "event_typing_stop_failed",
|
|
19232
|
+
event_id: normalizedEventID,
|
|
19233
|
+
session_id: normalizedSessionID,
|
|
19234
|
+
error: error instanceof Error ? error.message : String(error)
|
|
19235
|
+
}, "error");
|
|
19236
|
+
}
|
|
19237
|
+
}
|
|
18179
19238
|
async shouldResumeClaudeSession(binding) {
|
|
18180
|
-
const claudeSessionID =
|
|
18181
|
-
const cwd =
|
|
19239
|
+
const claudeSessionID = normalizeString32(binding?.claude_session_id);
|
|
19240
|
+
const cwd = normalizeString32(binding?.cwd);
|
|
18182
19241
|
if (!claudeSessionID || !cwd) {
|
|
18183
19242
|
return false;
|
|
18184
19243
|
}
|
|
@@ -18198,19 +19257,19 @@ var init_runtime = __esm({
|
|
|
18198
19257
|
if (this.authFailureCooldownMs <= 0) {
|
|
18199
19258
|
return null;
|
|
18200
19259
|
}
|
|
18201
|
-
const normalizedStatus =
|
|
19260
|
+
const normalizedStatus = normalizeString32(binding?.worker_status);
|
|
18202
19261
|
if (normalizedStatus !== "stopped" && normalizedStatus !== "failed") {
|
|
18203
19262
|
return null;
|
|
18204
19263
|
}
|
|
18205
|
-
const workerID =
|
|
19264
|
+
const workerID = normalizeString32(binding?.worker_id);
|
|
18206
19265
|
if (!workerID) {
|
|
18207
19266
|
return null;
|
|
18208
19267
|
}
|
|
18209
19268
|
const runtime = this.workerProcessManager?.getWorkerRuntime?.(workerID);
|
|
18210
|
-
if (
|
|
19269
|
+
if (normalizeString32(runtime?.status) !== "stopped") {
|
|
18211
19270
|
return null;
|
|
18212
19271
|
}
|
|
18213
|
-
if (
|
|
19272
|
+
if (normalizeString32(runtime?.exit_signal) !== "auth_login_required") {
|
|
18214
19273
|
return null;
|
|
18215
19274
|
}
|
|
18216
19275
|
const runtimeStoppedAt = Number(runtime?.stopped_at ?? 0);
|
|
@@ -18233,7 +19292,7 @@ var init_runtime = __esm({
|
|
|
18233
19292
|
};
|
|
18234
19293
|
}
|
|
18235
19294
|
async ensureWorker(binding, { ignoreAuthCooldown = false } = {}) {
|
|
18236
|
-
const sessionID =
|
|
19295
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
18237
19296
|
if (!sessionID) {
|
|
18238
19297
|
return null;
|
|
18239
19298
|
}
|
|
@@ -18314,7 +19373,7 @@ var init_runtime = __esm({
|
|
|
18314
19373
|
};
|
|
18315
19374
|
}
|
|
18316
19375
|
const currentReadyFailed = hasReadyWorkerBridge(current) && normalizeWorkerResponseState(current?.worker_response_state) === "failed";
|
|
18317
|
-
const workerID2 =
|
|
19376
|
+
const workerID2 = normalizeString32(binding.worker_id);
|
|
18318
19377
|
if (!currentReadyFailed && workerID2) {
|
|
18319
19378
|
const existingRuntime = this.workerProcessManager?.getWorkerRuntime?.(workerID2);
|
|
18320
19379
|
const existingPid = Number(existingRuntime?.pid ?? 0);
|
|
@@ -18393,13 +19452,13 @@ var init_runtime = __esm({
|
|
|
18393
19452
|
if (current && current.worker_status === "ready" && current.worker_control_url && current.worker_control_token) {
|
|
18394
19453
|
return current;
|
|
18395
19454
|
}
|
|
18396
|
-
await
|
|
19455
|
+
await sleep3(intervalMs);
|
|
18397
19456
|
}
|
|
18398
19457
|
return this.bindingRegistry.getByAibotSessionID(aibotSessionID);
|
|
18399
19458
|
}
|
|
18400
19459
|
async resolveWorkerLaunchFailure(binding) {
|
|
18401
|
-
const workerID =
|
|
18402
|
-
const workerStatus =
|
|
19460
|
+
const workerID = normalizeString32(binding?.worker_id);
|
|
19461
|
+
const workerStatus = normalizeString32(binding?.worker_status);
|
|
18403
19462
|
if (!workerID || !["starting", "connected"].includes(workerStatus)) {
|
|
18404
19463
|
return "";
|
|
18405
19464
|
}
|
|
@@ -18433,27 +19492,27 @@ var init_runtime = __esm({
|
|
|
18433
19492
|
if (current2.worker_status === "stopped" || current2.worker_status === "failed") {
|
|
18434
19493
|
return current2;
|
|
18435
19494
|
}
|
|
18436
|
-
await
|
|
19495
|
+
await sleep3(intervalMs);
|
|
18437
19496
|
}
|
|
18438
19497
|
const current = this.bindingRegistry.getByAibotSessionID(aibotSessionID);
|
|
18439
19498
|
const launchFailure = await this.resolveWorkerLaunchFailure(current);
|
|
18440
19499
|
if (launchFailure) {
|
|
18441
19500
|
return withWorkerLaunchFailure(current, launchFailure);
|
|
18442
19501
|
}
|
|
18443
|
-
if (["starting", "connected"].includes(
|
|
19502
|
+
if (["starting", "connected"].includes(normalizeString32(current?.worker_status))) {
|
|
18444
19503
|
return withWorkerLaunchFailure(current, "startup_wait_timeout");
|
|
18445
19504
|
}
|
|
18446
19505
|
return current;
|
|
18447
19506
|
}
|
|
18448
19507
|
clearWorkerControlProbeFailure(workerID) {
|
|
18449
|
-
const normalizedWorkerID =
|
|
19508
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
18450
19509
|
if (!normalizedWorkerID) {
|
|
18451
19510
|
return;
|
|
18452
19511
|
}
|
|
18453
19512
|
this.workerControlProbeFailures.delete(normalizedWorkerID);
|
|
18454
19513
|
}
|
|
18455
19514
|
markWorkerControlProbeFailure(workerID, error, extraFields = {}) {
|
|
18456
|
-
const normalizedWorkerID =
|
|
19515
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
18457
19516
|
if (!normalizedWorkerID) {
|
|
18458
19517
|
return 0;
|
|
18459
19518
|
}
|
|
@@ -18492,22 +19551,22 @@ var init_runtime = __esm({
|
|
|
18492
19551
|
});
|
|
18493
19552
|
}
|
|
18494
19553
|
resolveObservedSessionID(payload = {}) {
|
|
18495
|
-
const explicitSessionID =
|
|
19554
|
+
const explicitSessionID = normalizeString32(payload?.session_id);
|
|
18496
19555
|
if (explicitSessionID) {
|
|
18497
19556
|
return explicitSessionID;
|
|
18498
19557
|
}
|
|
18499
|
-
return
|
|
19558
|
+
return normalizeString32(this.messageDeliveryStore.getRememberedSessionID(payload?.event_id));
|
|
18500
19559
|
}
|
|
18501
19560
|
shouldIgnoreObservedWorker(binding, payload = {}) {
|
|
18502
19561
|
if (!binding) {
|
|
18503
19562
|
return false;
|
|
18504
19563
|
}
|
|
18505
|
-
const observedWorkerID =
|
|
18506
|
-
if (observedWorkerID &&
|
|
19564
|
+
const observedWorkerID = normalizeString32(payload?.worker_id);
|
|
19565
|
+
if (observedWorkerID && normalizeString32(binding?.worker_id) && observedWorkerID !== normalizeString32(binding.worker_id)) {
|
|
18507
19566
|
return true;
|
|
18508
19567
|
}
|
|
18509
|
-
const observedClaudeSessionID =
|
|
18510
|
-
if (observedClaudeSessionID &&
|
|
19568
|
+
const observedClaudeSessionID = normalizeString32(payload?.claude_session_id);
|
|
19569
|
+
if (observedClaudeSessionID && normalizeString32(binding?.claude_session_id) && observedClaudeSessionID !== normalizeString32(binding.claude_session_id)) {
|
|
18511
19570
|
return true;
|
|
18512
19571
|
}
|
|
18513
19572
|
return false;
|
|
@@ -18517,10 +19576,10 @@ var init_runtime = __esm({
|
|
|
18517
19576
|
stage,
|
|
18518
19577
|
event_id: payload?.event_id,
|
|
18519
19578
|
session_id: this.resolveObservedSessionID(payload),
|
|
18520
|
-
worker_id:
|
|
18521
|
-
expected_worker_id:
|
|
18522
|
-
claude_session_id:
|
|
18523
|
-
expected_claude_session_id:
|
|
19579
|
+
worker_id: normalizeString32(payload?.worker_id),
|
|
19580
|
+
expected_worker_id: normalizeString32(binding?.worker_id),
|
|
19581
|
+
claude_session_id: normalizeString32(payload?.claude_session_id),
|
|
19582
|
+
expected_claude_session_id: normalizeString32(binding?.claude_session_id)
|
|
18524
19583
|
}, "error");
|
|
18525
19584
|
}
|
|
18526
19585
|
async recordWorkerReplyObserved(payload, { kind = "text" } = {}) {
|
|
@@ -18583,19 +19642,19 @@ var init_runtime = __esm({
|
|
|
18583
19642
|
response_state: nextBinding?.worker_response_state,
|
|
18584
19643
|
response_reason: nextBinding?.worker_response_reason,
|
|
18585
19644
|
event_id: payload?.event_id,
|
|
18586
|
-
terminal_status:
|
|
18587
|
-
terminal_code:
|
|
19645
|
+
terminal_status: normalizeString32(payload?.status),
|
|
19646
|
+
terminal_code: normalizeString32(payload?.code)
|
|
18588
19647
|
}, classification.state === "failed" ? "error" : "info");
|
|
18589
19648
|
return nextBinding;
|
|
18590
19649
|
}
|
|
18591
19650
|
async recordWorkerHookSignalsObserved(binding, pingPayload) {
|
|
18592
|
-
const sessionID =
|
|
19651
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
18593
19652
|
if (!sessionID) {
|
|
18594
19653
|
return binding;
|
|
18595
19654
|
}
|
|
18596
19655
|
let nextBinding = binding;
|
|
18597
19656
|
let lastEventAt = Number(binding?.worker_last_hook_event_at ?? 0);
|
|
18598
|
-
let lastEventID =
|
|
19657
|
+
let lastEventID = normalizeString32(binding?.worker_last_hook_event_id);
|
|
18599
19658
|
for (const event of listHookSignalRecords(pingPayload)) {
|
|
18600
19659
|
const isNewer = event.event_at > lastEventAt || event.event_at === lastEventAt && event.event_id !== lastEventID;
|
|
18601
19660
|
if (!isNewer) {
|
|
@@ -18625,16 +19684,16 @@ var init_runtime = __esm({
|
|
|
18625
19684
|
if (this.workerControlProbeFailureThreshold <= 0) {
|
|
18626
19685
|
return { ok: true };
|
|
18627
19686
|
}
|
|
18628
|
-
if (
|
|
19687
|
+
if (normalizeString32(binding?.worker_status) !== "ready") {
|
|
18629
19688
|
return { ok: true };
|
|
18630
19689
|
}
|
|
18631
|
-
const workerID =
|
|
19690
|
+
const workerID = normalizeString32(binding?.worker_id);
|
|
18632
19691
|
if (!workerID) {
|
|
18633
19692
|
return { ok: true };
|
|
18634
19693
|
}
|
|
18635
19694
|
const probeTraceFields = {
|
|
18636
|
-
session_id:
|
|
18637
|
-
claude_session_id:
|
|
19695
|
+
session_id: normalizeString32(binding?.aibot_session_id),
|
|
19696
|
+
claude_session_id: normalizeString32(binding?.claude_session_id),
|
|
18638
19697
|
expected_pid: resolveExpectedWorkerPid(binding, runtime)
|
|
18639
19698
|
};
|
|
18640
19699
|
let client = null;
|
|
@@ -18673,12 +19732,12 @@ var init_runtime = __esm({
|
|
|
18673
19732
|
reason: identityHealth.reason,
|
|
18674
19733
|
expected_pid: normalizeNonNegativeInt(identityHealth.expectedPid, 0),
|
|
18675
19734
|
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:
|
|
19735
|
+
expected_worker_id: normalizeString32(identityHealth.expectedWorkerID),
|
|
19736
|
+
reported_worker_id: normalizeString32(identityHealth.reportedWorkerID),
|
|
19737
|
+
expected_session_id: normalizeString32(identityHealth.expectedSessionID),
|
|
19738
|
+
reported_session_id: normalizeString32(identityHealth.reportedSessionID),
|
|
19739
|
+
expected_claude_session_id: normalizeString32(identityHealth.expectedClaudeSessionID),
|
|
19740
|
+
reported_claude_session_id: normalizeString32(identityHealth.reportedClaudeSessionID),
|
|
18682
19741
|
...buildPingActivityTraceFields(pingPayload)
|
|
18683
19742
|
});
|
|
18684
19743
|
const failures = this.markWorkerControlProbeFailure(
|
|
@@ -18750,6 +19809,13 @@ var init_runtime = __esm({
|
|
|
18750
19809
|
}
|
|
18751
19810
|
return client.deliverRevoke(rawPayload);
|
|
18752
19811
|
}
|
|
19812
|
+
async deliverLocalActionToWorker(binding, rawPayload) {
|
|
19813
|
+
const client = this.workerControlClientFactory(binding);
|
|
19814
|
+
if (!client?.isConfigured?.()) {
|
|
19815
|
+
throw new Error("worker control client is not configured");
|
|
19816
|
+
}
|
|
19817
|
+
return client.deliverLocalAction(rawPayload);
|
|
19818
|
+
}
|
|
18753
19819
|
async trackPendingEvent(rawPayload) {
|
|
18754
19820
|
return this.pendingEventOrchestrator.trackPendingEvent(rawPayload);
|
|
18755
19821
|
}
|
|
@@ -18766,22 +19832,22 @@ var init_runtime = __esm({
|
|
|
18766
19832
|
return this.pendingEventOrchestrator.markPendingEventInterrupted(eventID);
|
|
18767
19833
|
}
|
|
18768
19834
|
async clearPendingEvent(eventID) {
|
|
18769
|
-
const normalizedEventID =
|
|
19835
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
18770
19836
|
if (normalizedEventID) {
|
|
18771
19837
|
this.pendingEventWorkerLogCursors.delete(normalizedEventID);
|
|
18772
19838
|
}
|
|
18773
19839
|
return this.pendingEventOrchestrator.clearPendingEvent(eventID);
|
|
18774
19840
|
}
|
|
18775
19841
|
getPendingEventWorkerLogCursor(eventID) {
|
|
18776
|
-
const normalizedEventID =
|
|
19842
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
18777
19843
|
if (!normalizedEventID) {
|
|
18778
19844
|
return null;
|
|
18779
19845
|
}
|
|
18780
19846
|
return this.pendingEventWorkerLogCursors.get(normalizedEventID) ?? null;
|
|
18781
19847
|
}
|
|
18782
19848
|
async recordPendingEventWorkerLogCursor(eventID, workerID) {
|
|
18783
|
-
const normalizedEventID =
|
|
18784
|
-
const normalizedWorkerID =
|
|
19849
|
+
const normalizedEventID = normalizeString32(eventID);
|
|
19850
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
18785
19851
|
if (!normalizedEventID || !normalizedWorkerID) {
|
|
18786
19852
|
return null;
|
|
18787
19853
|
}
|
|
@@ -18822,19 +19888,19 @@ var init_runtime = __esm({
|
|
|
18822
19888
|
return this.pendingEventOrchestrator.touchPendingEventComposing(eventID);
|
|
18823
19889
|
}
|
|
18824
19890
|
async handleWorkerSessionComposing(payload = {}) {
|
|
18825
|
-
const eventID =
|
|
19891
|
+
const eventID = normalizeString32(payload.ref_event_id);
|
|
18826
19892
|
if (!eventID) {
|
|
18827
19893
|
return null;
|
|
18828
19894
|
}
|
|
18829
|
-
const workerID =
|
|
18830
|
-
const workerSessionID =
|
|
18831
|
-
const claudeSessionID =
|
|
19895
|
+
const workerID = normalizeString32(payload.worker_id);
|
|
19896
|
+
const workerSessionID = normalizeString32(payload.session_id || payload.aibot_session_id);
|
|
19897
|
+
const claudeSessionID = normalizeString32(payload.claude_session_id);
|
|
18832
19898
|
const reportedPid = Number(payload.pid ?? 0);
|
|
18833
19899
|
const record = this.getPendingEvent(eventID);
|
|
18834
19900
|
if (!record) {
|
|
18835
19901
|
return null;
|
|
18836
19902
|
}
|
|
18837
|
-
const deliveryState =
|
|
19903
|
+
const deliveryState = normalizeString32(record.delivery_state);
|
|
18838
19904
|
if (deliveryState !== "dispatching" && deliveryState !== "delivered") {
|
|
18839
19905
|
this.trace({
|
|
18840
19906
|
stage: "pending_event_activity_rejected",
|
|
@@ -18845,7 +19911,7 @@ var init_runtime = __esm({
|
|
|
18845
19911
|
}, "error");
|
|
18846
19912
|
return null;
|
|
18847
19913
|
}
|
|
18848
|
-
const sessionID =
|
|
19914
|
+
const sessionID = normalizeString32(record.sessionID);
|
|
18849
19915
|
if (workerSessionID && workerSessionID !== sessionID) {
|
|
18850
19916
|
this.trace({
|
|
18851
19917
|
stage: "pending_event_activity_rejected",
|
|
@@ -18866,7 +19932,7 @@ var init_runtime = __esm({
|
|
|
18866
19932
|
}, "error");
|
|
18867
19933
|
return null;
|
|
18868
19934
|
}
|
|
18869
|
-
const expectedWorkerID =
|
|
19935
|
+
const expectedWorkerID = normalizeString32(binding.worker_id);
|
|
18870
19936
|
if (!workerID || !expectedWorkerID || workerID !== expectedWorkerID) {
|
|
18871
19937
|
this.trace({
|
|
18872
19938
|
stage: "pending_event_activity_rejected",
|
|
@@ -18892,7 +19958,7 @@ var init_runtime = __esm({
|
|
|
18892
19958
|
return null;
|
|
18893
19959
|
}
|
|
18894
19960
|
}
|
|
18895
|
-
const dispatchedWorkerID =
|
|
19961
|
+
const dispatchedWorkerID = normalizeString32(record.last_worker_id);
|
|
18896
19962
|
if (dispatchedWorkerID && workerID !== dispatchedWorkerID) {
|
|
18897
19963
|
this.trace({
|
|
18898
19964
|
stage: "pending_event_activity_rejected",
|
|
@@ -18904,7 +19970,7 @@ var init_runtime = __esm({
|
|
|
18904
19970
|
}, "error");
|
|
18905
19971
|
return null;
|
|
18906
19972
|
}
|
|
18907
|
-
const expectedClaudeSessionID =
|
|
19973
|
+
const expectedClaudeSessionID = normalizeString32(binding.claude_session_id);
|
|
18908
19974
|
if (!claudeSessionID || !expectedClaudeSessionID || claudeSessionID !== expectedClaudeSessionID) {
|
|
18909
19975
|
this.trace({
|
|
18910
19976
|
stage: "pending_event_activity_rejected",
|
|
@@ -18941,12 +20007,12 @@ var init_runtime = __esm({
|
|
|
18941
20007
|
async flushStalePendingEvents() {
|
|
18942
20008
|
const bindings = this.bindingRegistry?.listBindings?.() ?? [];
|
|
18943
20009
|
for (const binding of bindings) {
|
|
18944
|
-
const sessionID =
|
|
20010
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
18945
20011
|
if (!sessionID) continue;
|
|
18946
20012
|
if (!canDeliverToWorker(binding)) continue;
|
|
18947
20013
|
const pendingEvents = this.listPendingEventsForSession(sessionID);
|
|
18948
20014
|
const hasPending = pendingEvents.some(
|
|
18949
|
-
(r) =>
|
|
20015
|
+
(r) => normalizeString32(r.delivery_state) === "pending"
|
|
18950
20016
|
);
|
|
18951
20017
|
if (!hasPending) continue;
|
|
18952
20018
|
const queue = this.sessionQueues.ensure(sessionID);
|
|
@@ -18966,7 +20032,6 @@ var init_runtime = __esm({
|
|
|
18966
20032
|
async failPendingEvent(record, {
|
|
18967
20033
|
notifyText = true,
|
|
18968
20034
|
noticeText = buildInterruptedEventNotice(),
|
|
18969
|
-
replySource = "daemon_worker_interrupted",
|
|
18970
20035
|
resultCode = "worker_interrupted",
|
|
18971
20036
|
resultMessage = "worker interrupted while processing event"
|
|
18972
20037
|
} = {}) {
|
|
@@ -18983,10 +20048,7 @@ var init_runtime = __esm({
|
|
|
18983
20048
|
eventID: record.eventID,
|
|
18984
20049
|
sessionID: record.sessionID,
|
|
18985
20050
|
text: noticeText,
|
|
18986
|
-
quotedMessageID: record.msgID
|
|
18987
|
-
extra: {
|
|
18988
|
-
reply_source: replySource
|
|
18989
|
-
}
|
|
20051
|
+
quotedMessageID: record.msgID
|
|
18990
20052
|
});
|
|
18991
20053
|
} catch {
|
|
18992
20054
|
}
|
|
@@ -19009,7 +20071,7 @@ var init_runtime = __esm({
|
|
|
19009
20071
|
}, "error");
|
|
19010
20072
|
}
|
|
19011
20073
|
async resolveWorkerFailureEventOptions(workerID) {
|
|
19012
|
-
const normalizedWorkerID =
|
|
20074
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
19013
20075
|
if (!normalizedWorkerID) {
|
|
19014
20076
|
return null;
|
|
19015
20077
|
}
|
|
@@ -19027,23 +20089,22 @@ var init_runtime = __esm({
|
|
|
19027
20089
|
}
|
|
19028
20090
|
return {
|
|
19029
20091
|
noticeText: buildAuthLoginRequiredEventNotice(),
|
|
19030
|
-
replySource: "daemon_worker_auth_login_required",
|
|
19031
20092
|
resultCode: "claude_auth_login_required",
|
|
19032
20093
|
resultMessage: "claude authentication expired; run claude auth login"
|
|
19033
20094
|
};
|
|
19034
20095
|
}
|
|
19035
20096
|
resolveWorkerIDForEventResult(payload) {
|
|
19036
|
-
const explicitWorkerID =
|
|
20097
|
+
const explicitWorkerID = normalizeString32(payload?.worker_id);
|
|
19037
20098
|
if (explicitWorkerID) {
|
|
19038
20099
|
return explicitWorkerID;
|
|
19039
20100
|
}
|
|
19040
20101
|
const sessionID = this.resolveObservedSessionID(payload);
|
|
19041
20102
|
const binding = sessionID ? this.bindingRegistry.getByAibotSessionID(sessionID) : null;
|
|
19042
|
-
return
|
|
20103
|
+
return normalizeString32(binding?.worker_id);
|
|
19043
20104
|
}
|
|
19044
20105
|
async resolveWorkerEventResultFailureOptions(payload) {
|
|
19045
|
-
const status =
|
|
19046
|
-
const code =
|
|
20106
|
+
const status = normalizeString32(payload?.status);
|
|
20107
|
+
const code = normalizeString32(payload?.code);
|
|
19047
20108
|
if (status !== "failed" || code !== "claude_result_timeout") {
|
|
19048
20109
|
return null;
|
|
19049
20110
|
}
|
|
@@ -19051,7 +20112,7 @@ var init_runtime = __esm({
|
|
|
19051
20112
|
if (!workerID) {
|
|
19052
20113
|
return null;
|
|
19053
20114
|
}
|
|
19054
|
-
const eventID =
|
|
20115
|
+
const eventID = normalizeString32(payload?.event_id);
|
|
19055
20116
|
const logCursor = this.getPendingEventWorkerLogCursor(eventID);
|
|
19056
20117
|
const hasExtraUsageLimitPrompt = await this.workerProcessManager?.hasExtraUsageLimitPrompt?.(
|
|
19057
20118
|
workerID,
|
|
@@ -19079,7 +20140,7 @@ var init_runtime = __esm({
|
|
|
19079
20140
|
if (!failureOptions?.noticeText) {
|
|
19080
20141
|
return null;
|
|
19081
20142
|
}
|
|
19082
|
-
const eventID =
|
|
20143
|
+
const eventID = normalizeString32(payload?.event_id);
|
|
19083
20144
|
const record = this.getPendingEvent(eventID);
|
|
19084
20145
|
if (!record?.eventID || !record?.sessionID) {
|
|
19085
20146
|
return null;
|
|
@@ -19089,10 +20150,7 @@ var init_runtime = __esm({
|
|
|
19089
20150
|
eventID: record.eventID,
|
|
19090
20151
|
sessionID: record.sessionID,
|
|
19091
20152
|
text: failureOptions.noticeText,
|
|
19092
|
-
quotedMessageID: record.msgID
|
|
19093
|
-
extra: {
|
|
19094
|
-
reply_source: failureOptions.replySource
|
|
19095
|
-
}
|
|
20153
|
+
quotedMessageID: record.msgID
|
|
19096
20154
|
});
|
|
19097
20155
|
} catch {
|
|
19098
20156
|
return null;
|
|
@@ -19103,23 +20161,29 @@ var init_runtime = __esm({
|
|
|
19103
20161
|
const nextPayload = this.buildForwardedWorkerEventResult(payload, failureOptions);
|
|
19104
20162
|
await this.recordWorkerEventResultObserved(nextPayload);
|
|
19105
20163
|
await this.notifyWorkerEventResultFailure(nextPayload, failureOptions);
|
|
20164
|
+
const record = this.getPendingEvent(nextPayload?.event_id);
|
|
20165
|
+
this.stopTypingForEvent({
|
|
20166
|
+
eventID: nextPayload?.event_id,
|
|
20167
|
+
sessionID: nextPayload?.session_id || record?.sessionID,
|
|
20168
|
+
msgID: record?.msgID
|
|
20169
|
+
});
|
|
19106
20170
|
this.aibotClient.sendEventResult(nextPayload);
|
|
19107
20171
|
await this.handleEventCompleted(nextPayload?.event_id);
|
|
19108
20172
|
return nextPayload;
|
|
19109
20173
|
}
|
|
19110
20174
|
async requeuePendingEventsForWorker(sessionID, workerID) {
|
|
19111
|
-
const normalizedSessionID =
|
|
19112
|
-
const normalizedWorkerID =
|
|
20175
|
+
const normalizedSessionID = normalizeString32(sessionID);
|
|
20176
|
+
const normalizedWorkerID = normalizeString32(workerID);
|
|
19113
20177
|
if (!normalizedSessionID || !normalizedWorkerID) {
|
|
19114
20178
|
return 0;
|
|
19115
20179
|
}
|
|
19116
20180
|
let requeuedCount = 0;
|
|
19117
20181
|
const requeuedEventIDs = [];
|
|
19118
20182
|
for (const record of this.listPendingEventsForSession(normalizedSessionID)) {
|
|
19119
|
-
if (
|
|
20183
|
+
if (normalizeString32(record.last_worker_id) !== normalizedWorkerID) {
|
|
19120
20184
|
continue;
|
|
19121
20185
|
}
|
|
19122
|
-
const deliveryState =
|
|
20186
|
+
const deliveryState = normalizeString32(record.delivery_state);
|
|
19123
20187
|
if (!["dispatching", "delivered", "interrupted"].includes(deliveryState)) {
|
|
19124
20188
|
continue;
|
|
19125
20189
|
}
|
|
@@ -19142,8 +20206,8 @@ var init_runtime = __esm({
|
|
|
19142
20206
|
return requeuedCount;
|
|
19143
20207
|
}
|
|
19144
20208
|
async tryRecoverResumeAuthFailure(previousBinding, nextBinding) {
|
|
19145
|
-
const sessionID =
|
|
19146
|
-
const workerID =
|
|
20209
|
+
const sessionID = normalizeString32(nextBinding?.aibot_session_id || previousBinding?.aibot_session_id);
|
|
20210
|
+
const workerID = normalizeString32(previousBinding?.worker_id || nextBinding?.worker_id);
|
|
19147
20211
|
if (!sessionID || !workerID) {
|
|
19148
20212
|
return false;
|
|
19149
20213
|
}
|
|
@@ -19195,7 +20259,7 @@ var init_runtime = __esm({
|
|
|
19195
20259
|
return false;
|
|
19196
20260
|
}
|
|
19197
20261
|
const fallbackBinding = await this.rotateClaudeSession(latestBinding);
|
|
19198
|
-
const nextWorkerID =
|
|
20262
|
+
const nextWorkerID = normalizeString32(nextBinding?.worker_id) || workerID || randomUUID8();
|
|
19199
20263
|
await this.bindingRegistry.markWorkerStarting(sessionID, {
|
|
19200
20264
|
workerID: nextWorkerID,
|
|
19201
20265
|
updatedAt: Date.now(),
|
|
@@ -19232,7 +20296,7 @@ var init_runtime = __esm({
|
|
|
19232
20296
|
async reconcileWorkerProcesses() {
|
|
19233
20297
|
const bindings = this.bindingRegistry?.listBindings?.() ?? [];
|
|
19234
20298
|
for (const binding of bindings) {
|
|
19235
|
-
const sessionID =
|
|
20299
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
19236
20300
|
if (!sessionID) continue;
|
|
19237
20301
|
const queue = this.sessionQueues.ensure(sessionID);
|
|
19238
20302
|
queue.run(() => this.reconcileWorkerProcess(binding)).catch((err) => {
|
|
@@ -19241,11 +20305,11 @@ var init_runtime = __esm({
|
|
|
19241
20305
|
}
|
|
19242
20306
|
}
|
|
19243
20307
|
async reconcileWorkerProcess(binding) {
|
|
19244
|
-
const sessionID =
|
|
20308
|
+
const sessionID = normalizeString32(binding?.aibot_session_id);
|
|
19245
20309
|
if (!sessionID) return false;
|
|
19246
20310
|
const freshBinding = this.bindingRegistry?.getByAibotSessionID?.(sessionID) ?? binding;
|
|
19247
|
-
const workerID =
|
|
19248
|
-
const workerStatus =
|
|
20311
|
+
const workerID = normalizeString32(freshBinding?.worker_id);
|
|
20312
|
+
const workerStatus = normalizeString32(freshBinding?.worker_status);
|
|
19249
20313
|
if (!workerID || !["starting", "connected", "ready"].includes(workerStatus)) {
|
|
19250
20314
|
return false;
|
|
19251
20315
|
}
|
|
@@ -19297,7 +20361,7 @@ var init_runtime = __esm({
|
|
|
19297
20361
|
return true;
|
|
19298
20362
|
}
|
|
19299
20363
|
const previousBinding = this.bindingRegistry.getByAibotSessionID(sessionID) ?? binding;
|
|
19300
|
-
if (
|
|
20364
|
+
if (normalizeString32(previousBinding?.worker_id) !== workerID || ["stopped", "failed"].includes(normalizeString32(previousBinding?.worker_status))) {
|
|
19301
20365
|
return false;
|
|
19302
20366
|
}
|
|
19303
20367
|
const runtime = this.workerProcessManager?.getWorkerRuntime?.(workerID);
|
|
@@ -19306,7 +20370,7 @@ var init_runtime = __esm({
|
|
|
19306
20370
|
}
|
|
19307
20371
|
const pid = resolveExpectedWorkerPid(previousBinding, runtime);
|
|
19308
20372
|
if (Number.isFinite(pid) && pid > 0 && !this.isProcessRunning(pid)) {
|
|
19309
|
-
const exitSignal =
|
|
20373
|
+
const exitSignal = normalizeString32(runtime.exit_signal) || "worker_exited";
|
|
19310
20374
|
this.workerProcessManager?.markWorkerRuntimeStopped?.(workerID, {
|
|
19311
20375
|
exitCode: Number(runtime.exit_code ?? 0),
|
|
19312
20376
|
exitSignal
|
|
@@ -19350,7 +20414,7 @@ var init_runtime = __esm({
|
|
|
19350
20414
|
}, "error");
|
|
19351
20415
|
await this.bindingRegistry.markWorkerResponseFailed(sessionID, {
|
|
19352
20416
|
observedAt: Date.now(),
|
|
19353
|
-
reason:
|
|
20417
|
+
reason: normalizeString32(probe.reason) || "worker_control_unreachable",
|
|
19354
20418
|
failureCode: "worker_control_unreachable"
|
|
19355
20419
|
});
|
|
19356
20420
|
const nextBinding = await this.bindingRegistry.markWorkerStopped(sessionID, {
|
|
@@ -19421,7 +20485,7 @@ var init_runtime = __esm({
|
|
|
19421
20485
|
* handling.
|
|
19422
20486
|
*/
|
|
19423
20487
|
async handleWorkerStatusUpdateQueued(previousBinding, nextBinding) {
|
|
19424
|
-
const sessionID =
|
|
20488
|
+
const sessionID = normalizeString32(
|
|
19425
20489
|
nextBinding?.aibot_session_id || previousBinding?.aibot_session_id
|
|
19426
20490
|
);
|
|
19427
20491
|
if (!sessionID) {
|
|
@@ -19433,8 +20497,8 @@ var init_runtime = __esm({
|
|
|
19433
20497
|
);
|
|
19434
20498
|
}
|
|
19435
20499
|
async handleWorkerStatusUpdate(previousBinding, nextBinding) {
|
|
19436
|
-
const sessionID =
|
|
19437
|
-
const nextStatus =
|
|
20500
|
+
const sessionID = normalizeString32(nextBinding?.aibot_session_id || previousBinding?.aibot_session_id);
|
|
20501
|
+
const nextStatus = normalizeString32(nextBinding?.worker_status);
|
|
19438
20502
|
if (!sessionID || !nextStatus) {
|
|
19439
20503
|
return;
|
|
19440
20504
|
}
|
|
@@ -19446,8 +20510,8 @@ var init_runtime = __esm({
|
|
|
19446
20510
|
claude_session_id: nextBinding?.claude_session_id || previousBinding?.claude_session_id,
|
|
19447
20511
|
status: nextStatus
|
|
19448
20512
|
});
|
|
19449
|
-
const previousWorkerID =
|
|
19450
|
-
const nextWorkerID =
|
|
20513
|
+
const previousWorkerID = normalizeString32(previousBinding?.worker_id);
|
|
20514
|
+
const nextWorkerID = normalizeString32(nextBinding?.worker_id);
|
|
19451
20515
|
if (nextStatus === "ready" || nextStatus === "connected") {
|
|
19452
20516
|
if (nextWorkerID) {
|
|
19453
20517
|
this.clearWorkerControlProbeFailure(nextWorkerID);
|
|
@@ -19499,11 +20563,11 @@ var init_runtime = __esm({
|
|
|
19499
20563
|
}, "error");
|
|
19500
20564
|
}
|
|
19501
20565
|
for (const record of this.listPendingEventsForSession(sessionID)) {
|
|
19502
|
-
if (previousWorkerID &&
|
|
19503
|
-
if (
|
|
20566
|
+
if (previousWorkerID && normalizeString32(record.last_worker_id) !== previousWorkerID) {
|
|
20567
|
+
if (normalizeString32(record.last_worker_id)) {
|
|
19504
20568
|
continue;
|
|
19505
20569
|
}
|
|
19506
|
-
if (!["pending", "dispatching", "interrupted"].includes(
|
|
20570
|
+
if (!["pending", "dispatching", "interrupted"].includes(normalizeString32(record.delivery_state))) {
|
|
19507
20571
|
continue;
|
|
19508
20572
|
}
|
|
19509
20573
|
}
|
|
@@ -19513,7 +20577,7 @@ var init_runtime = __esm({
|
|
|
19513
20577
|
}
|
|
19514
20578
|
async handleEventCompleted(eventID) {
|
|
19515
20579
|
const record = this.getPendingEvent(eventID);
|
|
19516
|
-
const sessionID =
|
|
20580
|
+
const sessionID = normalizeString32(record?.sessionID || this.messageDeliveryStore.getRememberedSessionID(eventID));
|
|
19517
20581
|
await this.clearPendingEvent(eventID);
|
|
19518
20582
|
this.trace({
|
|
19519
20583
|
stage: "event_completed",
|
|
@@ -19581,7 +20645,6 @@ var init_runtime = __esm({
|
|
|
19581
20645
|
const currentRecord = this.getPendingEvent(record.eventID) ?? record;
|
|
19582
20646
|
await this.failPendingEvent(currentRecord, {
|
|
19583
20647
|
notifyText: false,
|
|
19584
|
-
replySource: "daemon_recover_failed",
|
|
19585
20648
|
resultCode: "worker_recover_failed",
|
|
19586
20649
|
resultMessage: message
|
|
19587
20650
|
});
|
|
@@ -19658,7 +20721,7 @@ var init_runtime = __esm({
|
|
|
19658
20721
|
});
|
|
19659
20722
|
return null;
|
|
19660
20723
|
}
|
|
19661
|
-
if (currentRecord && ["dispatching", "delivered"].includes(
|
|
20724
|
+
if (currentRecord && ["dispatching", "delivered"].includes(normalizeString32(currentRecord.delivery_state)) && normalizeString32(currentRecord.last_worker_id) === normalizeString32(readyBinding?.worker_id)) {
|
|
19662
20725
|
this.trace({
|
|
19663
20726
|
stage: "event_dispatch_skipped",
|
|
19664
20727
|
event_id: rawPayload?.event_id,
|
|
@@ -19710,7 +20773,7 @@ var init_runtime = __esm({
|
|
|
19710
20773
|
} else {
|
|
19711
20774
|
readyBinding = this.bindingRegistry.getByAibotSessionID(aibotSessionID) ?? readyBinding;
|
|
19712
20775
|
}
|
|
19713
|
-
if (readyBinding?.worker_launch_failure === "resume_session_missing" &&
|
|
20776
|
+
if (readyBinding?.worker_launch_failure === "resume_session_missing" && normalizeString32(binding.claude_session_id)) {
|
|
19714
20777
|
this.trace({
|
|
19715
20778
|
stage: "worker_resume_missing_recovering",
|
|
19716
20779
|
session_id: binding.aibot_session_id,
|
|
@@ -19764,9 +20827,6 @@ var init_runtime = __esm({
|
|
|
19764
20827
|
}
|
|
19765
20828
|
return readyBinding ?? binding;
|
|
19766
20829
|
}
|
|
19767
|
-
async handleControlCommand(event, parsed) {
|
|
19768
|
-
return this.controlCommandHandler.handleControlCommand(event, parsed);
|
|
19769
|
-
}
|
|
19770
20830
|
/**
|
|
19771
20831
|
* Queue-aware wrapper: routes handleEvent through the per-session
|
|
19772
20832
|
* serial queue to prevent races with reconcile and worker status updates.
|
|
@@ -19776,12 +20836,13 @@ var init_runtime = __esm({
|
|
|
19776
20836
|
if (!event.event_id || !event.session_id || !event.msg_id) {
|
|
19777
20837
|
return;
|
|
19778
20838
|
}
|
|
20839
|
+
this.ack(event);
|
|
19779
20840
|
const queue = this.sessionQueues.ensure(event.session_id);
|
|
19780
|
-
queue.run(() => this.handleEvent(rawPayload)).catch((err) => {
|
|
20841
|
+
queue.run(() => this.handleEvent(rawPayload, { alreadyAcked: true })).catch((err) => {
|
|
19781
20842
|
this.trace({ stage: "handle_event_error", session_id: event.session_id, event_id: event.event_id, error: String(err?.message ?? err) }, "error");
|
|
19782
20843
|
});
|
|
19783
20844
|
}
|
|
19784
|
-
async handleEvent(rawPayload) {
|
|
20845
|
+
async handleEvent(rawPayload, { alreadyAcked = false } = {}) {
|
|
19785
20846
|
const event = normalizeInboundEventPayload(rawPayload);
|
|
19786
20847
|
if (!event.event_id || !event.session_id || !event.msg_id) {
|
|
19787
20848
|
return;
|
|
@@ -19793,11 +20854,21 @@ var init_runtime = __esm({
|
|
|
19793
20854
|
msg_id: event.msg_id,
|
|
19794
20855
|
sender_id: event.sender_id
|
|
19795
20856
|
});
|
|
19796
|
-
|
|
20857
|
+
if (!alreadyAcked) {
|
|
20858
|
+
this.ack(event);
|
|
20859
|
+
}
|
|
20860
|
+
if (isRecordOnlyMirror(event)) {
|
|
20861
|
+
this.trace({
|
|
20862
|
+
stage: "event_mirrored_record_only",
|
|
20863
|
+
event_id: event.event_id,
|
|
20864
|
+
session_id: event.session_id,
|
|
20865
|
+
msg_id: event.msg_id,
|
|
20866
|
+
sender_id: event.sender_id
|
|
20867
|
+
});
|
|
20868
|
+
return;
|
|
20869
|
+
}
|
|
19797
20870
|
try {
|
|
19798
|
-
|
|
19799
|
-
if (parsed.matched) {
|
|
19800
|
-
await this.handleControlCommand(event, parsed);
|
|
20871
|
+
if (await this.handleInteractionActionEvent(event)) {
|
|
19801
20872
|
return;
|
|
19802
20873
|
}
|
|
19803
20874
|
const binding = this.bindingRegistry.getByAibotSessionID(event.session_id);
|
|
@@ -19807,9 +20878,10 @@ var init_runtime = __esm({
|
|
|
19807
20878
|
event_id: event.event_id,
|
|
19808
20879
|
session_id: event.session_id
|
|
19809
20880
|
}, "error");
|
|
19810
|
-
await this.
|
|
19811
|
-
|
|
19812
|
-
|
|
20881
|
+
await this.respond(event, buildBindingMissingEventNotice(), {}, {
|
|
20882
|
+
status: "responded",
|
|
20883
|
+
code: sessionControlErrorCodes.bindingMissing,
|
|
20884
|
+
msg: "session binding is required before event delivery"
|
|
19813
20885
|
});
|
|
19814
20886
|
return;
|
|
19815
20887
|
}
|
|
@@ -19827,9 +20899,7 @@ var init_runtime = __esm({
|
|
|
19827
20899
|
await this.respond(
|
|
19828
20900
|
event,
|
|
19829
20901
|
buildAuthLoginRequiredEventNotice(),
|
|
19830
|
-
{
|
|
19831
|
-
reply_source: "daemon_worker_auth_login_required"
|
|
19832
|
-
},
|
|
20902
|
+
{},
|
|
19833
20903
|
{
|
|
19834
20904
|
status: "failed",
|
|
19835
20905
|
code: "claude_auth_login_required",
|
|
@@ -19881,7 +20951,7 @@ var init_runtime = __esm({
|
|
|
19881
20951
|
}
|
|
19882
20952
|
const readyBinding = routedBinding ?? this.bindingRegistry.getByAibotSessionID(binding.aibot_session_id) ?? binding;
|
|
19883
20953
|
if (!readyBinding.worker_control_url || !readyBinding.worker_control_token) {
|
|
19884
|
-
const launchFailure =
|
|
20954
|
+
const launchFailure = normalizeString32(readyBinding?.worker_launch_failure);
|
|
19885
20955
|
this.trace({
|
|
19886
20956
|
stage: "event_worker_not_ready",
|
|
19887
20957
|
event_id: event.event_id,
|
|
@@ -19891,7 +20961,7 @@ var init_runtime = __esm({
|
|
|
19891
20961
|
worker_launch_failure: launchFailure
|
|
19892
20962
|
}, "error");
|
|
19893
20963
|
if (pending && (launchFailure === "startup_mcp_server_failed" || launchFailure === "startup_wait_timeout")) {
|
|
19894
|
-
const workerID =
|
|
20964
|
+
const workerID = normalizeString32(readyBinding?.worker_id);
|
|
19895
20965
|
if (workerID) {
|
|
19896
20966
|
try {
|
|
19897
20967
|
await this.workerProcessManager?.stopWorker?.(workerID);
|
|
@@ -19917,7 +20987,6 @@ var init_runtime = __esm({
|
|
|
19917
20987
|
await this.markPendingEventInterrupted(pending.eventID);
|
|
19918
20988
|
await this.failPendingEvent(pending, {
|
|
19919
20989
|
noticeText: buildWorkerStartupFailedNotice(),
|
|
19920
|
-
replySource: "daemon_worker_startup_failed",
|
|
19921
20990
|
resultCode: launchFailure === "startup_mcp_server_failed" ? "claude_startup_mcp_failed" : "claude_startup_timeout",
|
|
19922
20991
|
resultMessage: launchFailure === "startup_mcp_server_failed" ? "claude worker startup failed: mcp server not ready" : "claude worker startup timed out"
|
|
19923
20992
|
});
|
|
@@ -19933,9 +21002,7 @@ var init_runtime = __esm({
|
|
|
19933
21002
|
error: message
|
|
19934
21003
|
}, "error");
|
|
19935
21004
|
try {
|
|
19936
|
-
await this.respond(event, `\u5904\u7406\u5931\u8D25\uFF1A${message}`, {
|
|
19937
|
-
reply_source: "daemon_event_error"
|
|
19938
|
-
}, {
|
|
21005
|
+
await this.respond(event, `\u5904\u7406\u5931\u8D25\uFF1A${message}`, {}, {
|
|
19939
21006
|
status: "failed",
|
|
19940
21007
|
code: "daemon_event_handle_failed",
|
|
19941
21008
|
msg: message
|
|
@@ -19950,7 +21017,7 @@ var init_runtime = __esm({
|
|
|
19950
21017
|
}
|
|
19951
21018
|
}
|
|
19952
21019
|
async handleStopEvent(rawPayload) {
|
|
19953
|
-
const eventID =
|
|
21020
|
+
const eventID = normalizeString32(rawPayload?.event_id);
|
|
19954
21021
|
if (!eventID) {
|
|
19955
21022
|
return;
|
|
19956
21023
|
}
|
|
@@ -19960,7 +21027,7 @@ var init_runtime = __esm({
|
|
|
19960
21027
|
session_id: rawPayload?.session_id,
|
|
19961
21028
|
stop_id: rawPayload?.stop_id
|
|
19962
21029
|
});
|
|
19963
|
-
const sessionID =
|
|
21030
|
+
const sessionID = normalizeString32(rawPayload?.session_id) || this.messageDeliveryStore.getRememberedSessionID(eventID);
|
|
19964
21031
|
if (!sessionID) {
|
|
19965
21032
|
this.trace({
|
|
19966
21033
|
stage: "stop_route_missing",
|
|
@@ -19978,12 +21045,12 @@ var init_runtime = __esm({
|
|
|
19978
21045
|
});
|
|
19979
21046
|
}
|
|
19980
21047
|
async handleRevokeEvent(rawPayload) {
|
|
19981
|
-
const eventID =
|
|
21048
|
+
const eventID = normalizeString32(rawPayload?.event_id);
|
|
19982
21049
|
if (!eventID) {
|
|
19983
21050
|
return;
|
|
19984
21051
|
}
|
|
19985
21052
|
const receivedAt = Date.now();
|
|
19986
|
-
const resolvedSessionID =
|
|
21053
|
+
const resolvedSessionID = normalizeString32(rawPayload?.session_id) || this.messageDeliveryStore.getRememberedSessionID(eventID);
|
|
19987
21054
|
this.aibotClient.ackEvent(eventID, {
|
|
19988
21055
|
sessionID: resolvedSessionID,
|
|
19989
21056
|
msgID: rawPayload?.msg_id,
|
|
@@ -20028,12 +21095,80 @@ var init_runtime = __esm({
|
|
|
20028
21095
|
msg_id: rawPayload?.msg_id
|
|
20029
21096
|
});
|
|
20030
21097
|
}
|
|
21098
|
+
async handleLocalAction(rawPayload) {
|
|
21099
|
+
const action = normalizeLocalActionPayload(rawPayload);
|
|
21100
|
+
if (!action.action_id) {
|
|
21101
|
+
this.trace({
|
|
21102
|
+
stage: "local_action_invalid",
|
|
21103
|
+
reason: "missing_action_id",
|
|
21104
|
+
action_type: action.action_type
|
|
21105
|
+
}, "error");
|
|
21106
|
+
return;
|
|
21107
|
+
}
|
|
21108
|
+
const sessionControlResult = await this.sessionControlActionHandler.handleLocalAction(action);
|
|
21109
|
+
if (sessionControlResult?.handled) {
|
|
21110
|
+
await this.aibotClient.sendLocalActionResult({
|
|
21111
|
+
actionID: action.action_id,
|
|
21112
|
+
status: sessionControlResult.response?.status,
|
|
21113
|
+
result: sessionControlResult.response?.result,
|
|
21114
|
+
errorCode: sessionControlResult.response?.errorCode,
|
|
21115
|
+
errorMsg: sessionControlResult.response?.errorMsg,
|
|
21116
|
+
timeoutMs: action.timeout_ms
|
|
21117
|
+
});
|
|
21118
|
+
return;
|
|
21119
|
+
}
|
|
21120
|
+
const sessionID = normalizeString32(action.params?.session_id) || this.messageDeliveryStore.getRememberedSessionID(action.event_id);
|
|
21121
|
+
if (!sessionID) {
|
|
21122
|
+
this.trace({
|
|
21123
|
+
stage: "local_action_route_missing",
|
|
21124
|
+
action_id: action.action_id,
|
|
21125
|
+
action_type: action.action_type,
|
|
21126
|
+
event_id: action.event_id
|
|
21127
|
+
}, "error");
|
|
21128
|
+
await this.aibotClient.sendLocalActionResult({
|
|
21129
|
+
actionID: action.action_id,
|
|
21130
|
+
status: localActionResultStatuses.failed,
|
|
21131
|
+
errorCode: localActionErrorCodes.localActionRouteMissing,
|
|
21132
|
+
errorMsg: "local action session_id is required",
|
|
21133
|
+
timeoutMs: action.timeout_ms
|
|
21134
|
+
});
|
|
21135
|
+
return;
|
|
21136
|
+
}
|
|
21137
|
+
const routedBinding = await this.deliverWithRecovery(
|
|
21138
|
+
sessionID,
|
|
21139
|
+
action,
|
|
21140
|
+
this.deliverLocalActionToWorker
|
|
21141
|
+
);
|
|
21142
|
+
if (routedBinding && canDeliverToWorker(routedBinding)) {
|
|
21143
|
+
this.trace({
|
|
21144
|
+
stage: "local_action_forwarded",
|
|
21145
|
+
action_id: action.action_id,
|
|
21146
|
+
action_type: action.action_type,
|
|
21147
|
+
session_id: sessionID,
|
|
21148
|
+
worker_id: routedBinding?.worker_id
|
|
21149
|
+
});
|
|
21150
|
+
return;
|
|
21151
|
+
}
|
|
21152
|
+
this.trace({
|
|
21153
|
+
stage: "local_action_delivery_failed",
|
|
21154
|
+
action_id: action.action_id,
|
|
21155
|
+
action_type: action.action_type,
|
|
21156
|
+
session_id: sessionID
|
|
21157
|
+
}, "error");
|
|
21158
|
+
await this.aibotClient.sendLocalActionResult({
|
|
21159
|
+
actionID: action.action_id,
|
|
21160
|
+
status: "failed",
|
|
21161
|
+
errorCode: "local_action_delivery_failed",
|
|
21162
|
+
errorMsg: "worker is not ready for local action delivery",
|
|
21163
|
+
timeoutMs: action.timeout_ms
|
|
21164
|
+
});
|
|
21165
|
+
}
|
|
20031
21166
|
};
|
|
20032
21167
|
}
|
|
20033
21168
|
});
|
|
20034
21169
|
|
|
20035
21170
|
// server/session-activity-dispatcher.js
|
|
20036
|
-
function
|
|
21171
|
+
function normalizeString33(value) {
|
|
20037
21172
|
return String(value ?? "").trim();
|
|
20038
21173
|
}
|
|
20039
21174
|
function buildSessionActivityDispatchKey({
|
|
@@ -20042,10 +21177,10 @@ function buildSessionActivityDispatchKey({
|
|
|
20042
21177
|
refEventID = "",
|
|
20043
21178
|
refMsgID = ""
|
|
20044
21179
|
} = {}) {
|
|
20045
|
-
const normalizedSessionID =
|
|
20046
|
-
const normalizedKind =
|
|
20047
|
-
const normalizedRefEventID =
|
|
20048
|
-
const normalizedRefMsgID =
|
|
21180
|
+
const normalizedSessionID = normalizeString33(sessionID);
|
|
21181
|
+
const normalizedKind = normalizeString33(kind) || "composing";
|
|
21182
|
+
const normalizedRefEventID = normalizeString33(refEventID);
|
|
21183
|
+
const normalizedRefMsgID = normalizeString33(refMsgID);
|
|
20049
21184
|
if (normalizedRefEventID) {
|
|
20050
21185
|
return `event:${normalizedRefEventID}`;
|
|
20051
21186
|
}
|
|
@@ -20082,19 +21217,19 @@ var init_session_activity_dispatcher = __esm({
|
|
|
20082
21217
|
|
|
20083
21218
|
// server/daemon/session-log-writer.js
|
|
20084
21219
|
import { appendFile as appendFile2, mkdir as mkdir11 } from "node:fs/promises";
|
|
20085
|
-
import
|
|
20086
|
-
function
|
|
21220
|
+
import path24 from "node:path";
|
|
21221
|
+
function normalizeString34(value) {
|
|
20087
21222
|
return String(value ?? "").trim();
|
|
20088
21223
|
}
|
|
20089
21224
|
function normalizeSessionID(value) {
|
|
20090
|
-
return
|
|
21225
|
+
return normalizeString34(value).replace(/[^a-zA-Z0-9._-]+/g, "-");
|
|
20091
21226
|
}
|
|
20092
21227
|
function resolveSessionID(fields = {}) {
|
|
20093
|
-
const explicitSessionID =
|
|
21228
|
+
const explicitSessionID = normalizeString34(fields.session_id);
|
|
20094
21229
|
if (explicitSessionID) {
|
|
20095
21230
|
return explicitSessionID;
|
|
20096
21231
|
}
|
|
20097
|
-
return
|
|
21232
|
+
return normalizeString34(fields.aibot_session_id);
|
|
20098
21233
|
}
|
|
20099
21234
|
var SessionLogWriter;
|
|
20100
21235
|
var init_session_log_writer = __esm({
|
|
@@ -20109,7 +21244,7 @@ var init_session_log_writer = __esm({
|
|
|
20109
21244
|
appendFileImpl = appendFile2
|
|
20110
21245
|
} = {}) {
|
|
20111
21246
|
this.env = env;
|
|
20112
|
-
this.logFileName =
|
|
21247
|
+
this.logFileName = normalizeString34(logFileName) || "daemon-session.log";
|
|
20113
21248
|
this.mkdirImpl = typeof mkdirImpl === "function" ? mkdirImpl : mkdir11;
|
|
20114
21249
|
this.appendFileImpl = typeof appendFileImpl === "function" ? appendFileImpl : appendFile2;
|
|
20115
21250
|
this.writeQueues = /* @__PURE__ */ new Map();
|
|
@@ -20119,7 +21254,7 @@ var init_session_log_writer = __esm({
|
|
|
20119
21254
|
if (!normalizedSessionID) {
|
|
20120
21255
|
return "";
|
|
20121
21256
|
}
|
|
20122
|
-
return
|
|
21257
|
+
return path24.join(resolveWorkerLogsDir(normalizedSessionID, this.env), this.logFileName);
|
|
20123
21258
|
}
|
|
20124
21259
|
enqueueWrite(aibotSessionID, task) {
|
|
20125
21260
|
const normalizedSessionID = normalizeSessionID(aibotSessionID);
|
|
@@ -20143,7 +21278,7 @@ var init_session_log_writer = __esm({
|
|
|
20143
21278
|
return false;
|
|
20144
21279
|
}
|
|
20145
21280
|
const line = formatTraceLine({
|
|
20146
|
-
level:
|
|
21281
|
+
level: normalizeString34(level) || "info",
|
|
20147
21282
|
...fields
|
|
20148
21283
|
});
|
|
20149
21284
|
return this.enqueueWrite(sessionID, async () => {
|
|
@@ -20151,7 +21286,7 @@ var init_session_log_writer = __esm({
|
|
|
20151
21286
|
if (!logPath) {
|
|
20152
21287
|
return false;
|
|
20153
21288
|
}
|
|
20154
|
-
await this.mkdirImpl(
|
|
21289
|
+
await this.mkdirImpl(path24.dirname(logPath), { recursive: true });
|
|
20155
21290
|
await this.appendFileImpl(logPath, `${line}
|
|
20156
21291
|
`, "utf8");
|
|
20157
21292
|
return true;
|
|
@@ -20171,7 +21306,7 @@ __export(main_exports, {
|
|
|
20171
21306
|
shouldIgnoreWorkerStatusUpdate: () => shouldIgnoreWorkerStatusUpdate,
|
|
20172
21307
|
shouldNotifyWorkerReady: () => shouldNotifyWorkerReady
|
|
20173
21308
|
});
|
|
20174
|
-
import
|
|
21309
|
+
import process15 from "node:process";
|
|
20175
21310
|
function usage() {
|
|
20176
21311
|
return `\u7528\u6CD5:
|
|
20177
21312
|
grix-claude daemon [options]
|
|
@@ -20190,7 +21325,7 @@ function usage() {
|
|
|
20190
21325
|
`;
|
|
20191
21326
|
}
|
|
20192
21327
|
function print(message) {
|
|
20193
|
-
|
|
21328
|
+
process15.stdout.write(`${message}
|
|
20194
21329
|
`);
|
|
20195
21330
|
}
|
|
20196
21331
|
function parseArgs(argv) {
|
|
@@ -20216,7 +21351,7 @@ function readOption(argv, name) {
|
|
|
20216
21351
|
}
|
|
20217
21352
|
return value;
|
|
20218
21353
|
}
|
|
20219
|
-
function
|
|
21354
|
+
function normalizeString35(value) {
|
|
20220
21355
|
return String(value ?? "").trim();
|
|
20221
21356
|
}
|
|
20222
21357
|
function normalizePid3(value) {
|
|
@@ -20239,13 +21374,13 @@ function shouldIgnoreWorkerStatusUpdate(previousBinding, payload) {
|
|
|
20239
21374
|
if (!previousBinding) {
|
|
20240
21375
|
return false;
|
|
20241
21376
|
}
|
|
20242
|
-
const expectedWorkerID =
|
|
20243
|
-
const incomingWorkerID =
|
|
21377
|
+
const expectedWorkerID = normalizeString35(previousBinding.worker_id);
|
|
21378
|
+
const incomingWorkerID = normalizeString35(payload?.worker_id);
|
|
20244
21379
|
if (expectedWorkerID && incomingWorkerID && expectedWorkerID !== incomingWorkerID) {
|
|
20245
21380
|
return true;
|
|
20246
21381
|
}
|
|
20247
|
-
const expectedClaudeSessionID =
|
|
20248
|
-
const incomingClaudeSessionID =
|
|
21382
|
+
const expectedClaudeSessionID = normalizeString35(previousBinding.claude_session_id);
|
|
21383
|
+
const incomingClaudeSessionID = normalizeString35(payload?.claude_session_id);
|
|
20249
21384
|
if (expectedClaudeSessionID && incomingClaudeSessionID && expectedClaudeSessionID !== incomingClaudeSessionID) {
|
|
20250
21385
|
return true;
|
|
20251
21386
|
}
|
|
@@ -20260,13 +21395,10 @@ async function notifyWorkerReady(aibotClient, binding) {
|
|
|
20260
21395
|
}
|
|
20261
21396
|
return aibotClient.sendText({
|
|
20262
21397
|
sessionID: binding.aibot_session_id,
|
|
20263
|
-
text: buildWorkerReadyNoticeText(binding)
|
|
20264
|
-
extra: {
|
|
20265
|
-
reply_source: "daemon_worker_ready"
|
|
20266
|
-
}
|
|
21398
|
+
text: buildWorkerReadyNoticeText(binding)
|
|
20267
21399
|
});
|
|
20268
21400
|
}
|
|
20269
|
-
async function run(argv = [], env =
|
|
21401
|
+
async function run(argv = [], env = process15.env) {
|
|
20270
21402
|
const options = parseArgs(argv);
|
|
20271
21403
|
if (options.help) {
|
|
20272
21404
|
print(usage());
|
|
@@ -20514,6 +21646,25 @@ async function run(argv = [], env = process14.env) {
|
|
|
20514
21646
|
refEventID: payload.ref_event_id
|
|
20515
21647
|
});
|
|
20516
21648
|
return { ok: true };
|
|
21649
|
+
},
|
|
21650
|
+
onAgentInvoke: async (payload) => aibotClient.sendAgentInvoke({
|
|
21651
|
+
invokeID: payload?.invoke_id,
|
|
21652
|
+
action: payload?.action,
|
|
21653
|
+
params: payload?.params,
|
|
21654
|
+
timeoutMs: payload?.timeout_ms
|
|
21655
|
+
}),
|
|
21656
|
+
onLocalActionResult: async (payload) => {
|
|
21657
|
+
const syntheticResult = await runtime?.observeWorkerLocalActionResult?.(payload);
|
|
21658
|
+
if (syntheticResult?.handled) {
|
|
21659
|
+
return { ok: true };
|
|
21660
|
+
}
|
|
21661
|
+
return aibotClient.sendLocalActionResult({
|
|
21662
|
+
actionID: payload?.action_id,
|
|
21663
|
+
status: payload?.status,
|
|
21664
|
+
result: payload?.result,
|
|
21665
|
+
errorCode: payload?.error_code,
|
|
21666
|
+
errorMsg: payload?.error_msg
|
|
21667
|
+
});
|
|
20517
21668
|
}
|
|
20518
21669
|
});
|
|
20519
21670
|
try {
|
|
@@ -20538,6 +21689,9 @@ async function run(argv = [], env = process14.env) {
|
|
|
20538
21689
|
aibotClient.onEventRevoke = async (payload) => {
|
|
20539
21690
|
await runtime.handleRevokeEvent(payload);
|
|
20540
21691
|
};
|
|
21692
|
+
aibotClient.onLocalAction = async (payload) => {
|
|
21693
|
+
await runtime.handleLocalAction(payload);
|
|
21694
|
+
};
|
|
20541
21695
|
print("grix-claude daemon \u5DF2\u542F\u52A8\u3002");
|
|
20542
21696
|
print(`\u6570\u636E\u76EE\u5F55: ${dataDir}`);
|
|
20543
21697
|
print(`Bridge: ${bridgeServer.getURL()}`);
|
|
@@ -20577,15 +21731,15 @@ async function run(argv = [], env = process14.env) {
|
|
|
20577
21731
|
}
|
|
20578
21732
|
await new Promise((resolve) => {
|
|
20579
21733
|
const stop = async () => {
|
|
20580
|
-
|
|
20581
|
-
|
|
21734
|
+
process15.off("SIGINT", stop);
|
|
21735
|
+
process15.off("SIGTERM", stop);
|
|
20582
21736
|
await processState.markStopping("signal");
|
|
20583
21737
|
await aibotClient.stop();
|
|
20584
21738
|
await bridgeServer.stop();
|
|
20585
21739
|
resolve();
|
|
20586
21740
|
};
|
|
20587
|
-
|
|
20588
|
-
|
|
21741
|
+
process15.once("SIGINT", stop);
|
|
21742
|
+
process15.once("SIGTERM", stop);
|
|
20589
21743
|
});
|
|
20590
21744
|
await processState.release({
|
|
20591
21745
|
exitCode: 0,
|
|
@@ -20597,8 +21751,8 @@ async function run(argv = [], env = process14.env) {
|
|
|
20597
21751
|
throw error;
|
|
20598
21752
|
}
|
|
20599
21753
|
}
|
|
20600
|
-
async function main(argv =
|
|
20601
|
-
|
|
21754
|
+
async function main(argv = process15.argv.slice(2), env = process15.env) {
|
|
21755
|
+
process15.exitCode = await run(argv, env);
|
|
20602
21756
|
}
|
|
20603
21757
|
var workerReadySettleDelayMs;
|
|
20604
21758
|
var init_main2 = __esm({
|
|
@@ -20627,7 +21781,7 @@ __export(main_exports2, {
|
|
|
20627
21781
|
main: () => main2,
|
|
20628
21782
|
run: () => run2
|
|
20629
21783
|
});
|
|
20630
|
-
import
|
|
21784
|
+
import process16 from "node:process";
|
|
20631
21785
|
function usage2() {
|
|
20632
21786
|
return `\u7528\u6CD5:
|
|
20633
21787
|
grix-claude worker
|
|
@@ -20637,7 +21791,7 @@ function usage2() {
|
|
|
20637
21791
|
`;
|
|
20638
21792
|
}
|
|
20639
21793
|
function print2(message) {
|
|
20640
|
-
|
|
21794
|
+
process16.stdout.write(`${message}
|
|
20641
21795
|
`);
|
|
20642
21796
|
}
|
|
20643
21797
|
async function run2(argv = []) {
|
|
@@ -20648,8 +21802,8 @@ async function run2(argv = []) {
|
|
|
20648
21802
|
print2("\u4E0D\u8981\u624B\u52A8\u8FD0\u884C worker\u3002Claude \u4F1A\u8BDD\u4F1A\u5728 daemon \u8C03\u5EA6\u4E0B\u81EA\u52A8\u52A0\u8F7D\u5B83\u3002");
|
|
20649
21803
|
return 1;
|
|
20650
21804
|
}
|
|
20651
|
-
async function main2(argv =
|
|
20652
|
-
|
|
21805
|
+
async function main2(argv = process16.argv.slice(2)) {
|
|
21806
|
+
process16.exitCode = await run2(argv);
|
|
20653
21807
|
}
|
|
20654
21808
|
var init_main3 = __esm({
|
|
20655
21809
|
"server/worker/main.js"() {
|
|
@@ -20660,7 +21814,7 @@ var init_main3 = __esm({
|
|
|
20660
21814
|
init_config();
|
|
20661
21815
|
init_config_store();
|
|
20662
21816
|
init_daemon_paths();
|
|
20663
|
-
import
|
|
21817
|
+
import process17 from "node:process";
|
|
20664
21818
|
|
|
20665
21819
|
// server/service/service-manager.js
|
|
20666
21820
|
init_config();
|
|
@@ -21263,7 +22417,7 @@ var ServiceManager = class {
|
|
|
21263
22417
|
minUpdatedAt = 0,
|
|
21264
22418
|
timeoutMs = 5e3
|
|
21265
22419
|
} = {}) {
|
|
21266
|
-
const { setTimeout:
|
|
22420
|
+
const { setTimeout: sleep4 } = await import("node:timers/promises");
|
|
21267
22421
|
const start = this.now();
|
|
21268
22422
|
let lastState = null;
|
|
21269
22423
|
while (this.now() - start < timeoutMs) {
|
|
@@ -21273,7 +22427,7 @@ var ServiceManager = class {
|
|
|
21273
22427
|
if (state.running && state.pid && restarted) {
|
|
21274
22428
|
return state;
|
|
21275
22429
|
}
|
|
21276
|
-
await
|
|
22430
|
+
await sleep4(100);
|
|
21277
22431
|
}
|
|
21278
22432
|
throw new Error(
|
|
21279
22433
|
`daemon start timeout (${timeoutMs}ms), state=${lastState?.state || "unknown"}, pid=${Number(lastState?.pid ?? 0)}`
|
|
@@ -21502,11 +22656,11 @@ function parseArgs2(argv) {
|
|
|
21502
22656
|
return options;
|
|
21503
22657
|
}
|
|
21504
22658
|
function print3(message) {
|
|
21505
|
-
|
|
22659
|
+
process17.stdout.write(`${message}
|
|
21506
22660
|
`);
|
|
21507
22661
|
}
|
|
21508
22662
|
function printError(message) {
|
|
21509
|
-
|
|
22663
|
+
process17.stderr.write(`${message}
|
|
21510
22664
|
`);
|
|
21511
22665
|
}
|
|
21512
22666
|
function shellQuoteForDisplay(value) {
|
|
@@ -21545,10 +22699,10 @@ function formatRunningCommand(argv) {
|
|
|
21545
22699
|
return command.map((item) => shellQuoteForDisplay(item)).join(" ");
|
|
21546
22700
|
}
|
|
21547
22701
|
function formatRuntimeEntryCommand(argv) {
|
|
21548
|
-
const command = [
|
|
22702
|
+
const command = [process17.execPath, resolvePackageBinPath(), ...redactSensitiveArgs(argv)];
|
|
21549
22703
|
return command.map((item) => shellQuoteForDisplay(item)).join(" ");
|
|
21550
22704
|
}
|
|
21551
|
-
function createServiceManager(env =
|
|
22705
|
+
function createServiceManager(env = process17.env) {
|
|
21552
22706
|
return new ServiceManager({ env });
|
|
21553
22707
|
}
|
|
21554
22708
|
function buildRuntimeEnv(options, env) {
|
|
@@ -21566,7 +22720,7 @@ function buildDaemonStatus(configStore) {
|
|
|
21566
22720
|
configPath: configStore.filePath
|
|
21567
22721
|
};
|
|
21568
22722
|
}
|
|
21569
|
-
async function prepareDaemonConfig(options, env =
|
|
22723
|
+
async function prepareDaemonConfig(options, env = process17.env, { persistResolvedConfig = false } = {}) {
|
|
21570
22724
|
const runtimeEnv = buildRuntimeEnv(options, env);
|
|
21571
22725
|
const configStore = new ConfigStore(resolveDaemonConfigPath(runtimeEnv), {
|
|
21572
22726
|
env: runtimeEnv
|
|
@@ -21591,7 +22745,7 @@ async function prepareDaemonConfig(options, env = process16.env, { persistResolv
|
|
|
21591
22745
|
...buildDaemonStatus(configStore)
|
|
21592
22746
|
};
|
|
21593
22747
|
}
|
|
21594
|
-
async function runDefault(argv, env =
|
|
22748
|
+
async function runDefault(argv, env = process17.env) {
|
|
21595
22749
|
const options = parseArgs2(argv);
|
|
21596
22750
|
if (options.help) {
|
|
21597
22751
|
print3(usage3());
|
|
@@ -21705,7 +22859,7 @@ async function runSubcommand(name, argv, env, deps = {}) {
|
|
|
21705
22859
|
}
|
|
21706
22860
|
throw new Error(`\u672A\u77E5\u5B50\u547D\u4EE4: ${name}`);
|
|
21707
22861
|
}
|
|
21708
|
-
async function run3(argv, env =
|
|
22862
|
+
async function run3(argv, env = process17.env, deps = {}) {
|
|
21709
22863
|
const [first = ""] = argv;
|
|
21710
22864
|
if ([
|
|
21711
22865
|
"daemon",
|
|
@@ -21721,17 +22875,17 @@ async function run3(argv, env = process16.env, deps = {}) {
|
|
|
21721
22875
|
}
|
|
21722
22876
|
return runDefault(argv, env);
|
|
21723
22877
|
}
|
|
21724
|
-
async function main3(argv =
|
|
22878
|
+
async function main3(argv = process17.argv.slice(2), env = process17.env) {
|
|
21725
22879
|
try {
|
|
21726
22880
|
print3(`\u8FD0\u884C\u547D\u4EE4: ${formatRunningCommand(argv)}`);
|
|
21727
22881
|
print3(`\u5B9E\u9645\u5165\u53E3: ${formatRuntimeEntryCommand(argv)}`);
|
|
21728
22882
|
const exitCode = await run3(argv, env);
|
|
21729
|
-
|
|
22883
|
+
process17.exitCode = exitCode;
|
|
21730
22884
|
} catch (error) {
|
|
21731
22885
|
printError(error instanceof Error ? error.message : String(error));
|
|
21732
22886
|
printError("");
|
|
21733
22887
|
printError(usage3());
|
|
21734
|
-
|
|
22888
|
+
process17.exitCode = 1;
|
|
21735
22889
|
}
|
|
21736
22890
|
}
|
|
21737
22891
|
|