engine7 7.1.7 → 7.1.8
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/dist/cli.mjs +655 -118
- package/dist/engine-startup.mjs +198 -108
- package/dist/main.mjs +198 -108
- package/package.json +10 -3
package/dist/main.mjs
CHANGED
|
@@ -739,9 +739,9 @@ async function execCommandHook(hook, hookEvent, hookName, jsonInput, signal, hoo
|
|
|
739
739
|
child.stderr.on("data", (chunk) => {
|
|
740
740
|
stderr += chunk;
|
|
741
741
|
});
|
|
742
|
-
const exitCode = await new Promise((
|
|
743
|
-
child.on("close", (code) =>
|
|
744
|
-
child.on("error", () =>
|
|
742
|
+
const exitCode = await new Promise((resolve12) => {
|
|
743
|
+
child.on("close", (code) => resolve12(code ?? 0));
|
|
744
|
+
child.on("error", () => resolve12(1));
|
|
745
745
|
});
|
|
746
746
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
747
747
|
signal.removeEventListener("abort", onAbort);
|
|
@@ -4117,7 +4117,7 @@ For commands that are harder to parse at a glance (piped commands, obscure flags
|
|
|
4117
4117
|
const osMod = await import("node:os");
|
|
4118
4118
|
const outputFile = path10.join(osMod.tmpdir(), `exec-${Date.now()}-${Math.random().toString(36).slice(2)}.out`);
|
|
4119
4119
|
const outputHandle = await fs9.promises.open(outputFile, "w");
|
|
4120
|
-
return new Promise((
|
|
4120
|
+
return new Promise((resolve12) => {
|
|
4121
4121
|
const { shell, args: shellArgs } = findShell();
|
|
4122
4122
|
const child = spawn2(shell, [...shellArgs, command], {
|
|
4123
4123
|
cwd,
|
|
@@ -4164,7 +4164,7 @@ For commands that are harder to parse at a glance (piped commands, obscure flags
|
|
|
4164
4164
|
errorMessage = errorMessage ? `${timeoutMsg} ${errorMessage}` : timeoutMsg;
|
|
4165
4165
|
}
|
|
4166
4166
|
const parts = [processedStdout, errorMessage, truncationSuffix].filter(Boolean);
|
|
4167
|
-
|
|
4167
|
+
resolve12({
|
|
4168
4168
|
content: parts.join("\n") || "(no output)",
|
|
4169
4169
|
isError: aborted
|
|
4170
4170
|
});
|
|
@@ -4579,16 +4579,16 @@ async function writeTeamFileAsync(teamName, teamFile) {
|
|
|
4579
4579
|
}
|
|
4580
4580
|
async function withTeamFileLock(teamName, fn) {
|
|
4581
4581
|
const prev = teamFileMutex.get(teamName) || Promise.resolve();
|
|
4582
|
-
let
|
|
4582
|
+
let resolve12;
|
|
4583
4583
|
const next = new Promise((r) => {
|
|
4584
|
-
|
|
4584
|
+
resolve12 = r;
|
|
4585
4585
|
});
|
|
4586
4586
|
teamFileMutex.set(teamName, next);
|
|
4587
4587
|
await prev;
|
|
4588
4588
|
try {
|
|
4589
4589
|
return await fn();
|
|
4590
4590
|
} finally {
|
|
4591
|
-
|
|
4591
|
+
resolve12();
|
|
4592
4592
|
if (teamFileMutex.get(teamName) === next) teamFileMutex.delete(teamName);
|
|
4593
4593
|
}
|
|
4594
4594
|
}
|
|
@@ -4725,7 +4725,7 @@ async function ensureInboxDir(teamName) {
|
|
|
4725
4725
|
await mkdir2(inboxDir, { recursive: true });
|
|
4726
4726
|
}
|
|
4727
4727
|
async function sleep3(ms) {
|
|
4728
|
-
return new Promise((
|
|
4728
|
+
return new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
4729
4729
|
}
|
|
4730
4730
|
function parseLockContent(raw) {
|
|
4731
4731
|
const [pidStr, tsStr] = raw.split("-");
|
|
@@ -6468,15 +6468,15 @@ function blockTask(stateDir, listId, fromTaskId, toTaskId) {
|
|
|
6468
6468
|
}
|
|
6469
6469
|
function withTaskLock(listId, fn) {
|
|
6470
6470
|
const prev = taskMutex.get(listId) || Promise.resolve();
|
|
6471
|
-
let
|
|
6471
|
+
let resolve12;
|
|
6472
6472
|
const next = new Promise((r) => {
|
|
6473
|
-
|
|
6473
|
+
resolve12 = r;
|
|
6474
6474
|
});
|
|
6475
6475
|
taskMutex.set(listId, next);
|
|
6476
6476
|
try {
|
|
6477
6477
|
return fn();
|
|
6478
6478
|
} finally {
|
|
6479
|
-
|
|
6479
|
+
resolve12();
|
|
6480
6480
|
if (taskMutex.get(listId) === next) taskMutex.delete(listId);
|
|
6481
6481
|
}
|
|
6482
6482
|
}
|
|
@@ -7263,7 +7263,7 @@ function findFiles(dir, pattern, limit, baseDir) {
|
|
|
7263
7263
|
if (VCS_DIRS.has(entry.name)) continue;
|
|
7264
7264
|
walk(fullPath);
|
|
7265
7265
|
} else if (entry.isFile()) {
|
|
7266
|
-
const relativePath = path36.relative(baseDir, fullPath);
|
|
7266
|
+
const relativePath = path36.relative(baseDir, fullPath).replace(/\\/g, "/");
|
|
7267
7267
|
const patternsToTry = [pattern];
|
|
7268
7268
|
if (pattern.startsWith("**/")) {
|
|
7269
7269
|
patternsToTry.push(pattern.slice(3));
|
|
@@ -7353,7 +7353,7 @@ var grep_exports = {};
|
|
|
7353
7353
|
import { execFile as execFile2 } from "node:child_process";
|
|
7354
7354
|
import * as path37 from "node:path";
|
|
7355
7355
|
function ripGrep(args2, searchPath, signal) {
|
|
7356
|
-
return new Promise((
|
|
7356
|
+
return new Promise((resolve12) => {
|
|
7357
7357
|
const fullArgs = [...args2, searchPath];
|
|
7358
7358
|
const child = execFile2("rg", fullArgs, {
|
|
7359
7359
|
maxBuffer: 50 * 1024 * 1024,
|
|
@@ -7362,11 +7362,11 @@ function ripGrep(args2, searchPath, signal) {
|
|
|
7362
7362
|
signal
|
|
7363
7363
|
}, (error, stdout, stderr) => {
|
|
7364
7364
|
if (error && error.killed) {
|
|
7365
|
-
|
|
7365
|
+
resolve12({ lines: [], exitCode: -1, timedOut: true });
|
|
7366
7366
|
return;
|
|
7367
7367
|
}
|
|
7368
7368
|
const lines = stdout ? stdout.split("\n").filter(Boolean) : [];
|
|
7369
|
-
|
|
7369
|
+
resolve12({ lines, exitCode: error ? error.code || 1 : 0, timedOut: false });
|
|
7370
7370
|
});
|
|
7371
7371
|
});
|
|
7372
7372
|
}
|
|
@@ -7553,7 +7553,7 @@ ${filenames.join("\n")}${truncatedNote}`
|
|
|
7553
7553
|
// src/tools/task-output.ts
|
|
7554
7554
|
var task_output_exports = {};
|
|
7555
7555
|
async function sleep4(ms) {
|
|
7556
|
-
return new Promise((
|
|
7556
|
+
return new Promise((resolve12) => setTimeout(resolve12, ms));
|
|
7557
7557
|
}
|
|
7558
7558
|
async function waitForTaskCompletion(taskId, timeoutMs, signal) {
|
|
7559
7559
|
const startTime = Date.now();
|
|
@@ -8581,13 +8581,13 @@ function waitForAllIdle(timeoutMs = 6e4) {
|
|
|
8581
8581
|
([, info]) => info.status === "running"
|
|
8582
8582
|
);
|
|
8583
8583
|
if (working.length === 0) return Promise.resolve({ timedOut: false, remaining: 0 });
|
|
8584
|
-
return new Promise((
|
|
8584
|
+
return new Promise((resolve12) => {
|
|
8585
8585
|
let remaining = working.length;
|
|
8586
8586
|
let settled = false;
|
|
8587
8587
|
const done2 = (timedOut) => {
|
|
8588
8588
|
if (settled) return;
|
|
8589
8589
|
settled = true;
|
|
8590
|
-
|
|
8590
|
+
resolve12({ timedOut, remaining });
|
|
8591
8591
|
};
|
|
8592
8592
|
const timer = setTimeout(() => {
|
|
8593
8593
|
console.warn(`[spawnInProcess] waitForAllIdle timed out after ${timeoutMs}ms, ${remaining} still running`);
|
|
@@ -11044,8 +11044,8 @@ async function executeAndDeliver(task, now, deps) {
|
|
|
11044
11044
|
}
|
|
11045
11045
|
}
|
|
11046
11046
|
let resolveResult;
|
|
11047
|
-
const resultPromise = new Promise((
|
|
11048
|
-
resolveResult =
|
|
11047
|
+
const resultPromise = new Promise((resolve12) => {
|
|
11048
|
+
resolveResult = resolve12;
|
|
11049
11049
|
});
|
|
11050
11050
|
deps.dispatcher.submitMessage({
|
|
11051
11051
|
text: promptText,
|
|
@@ -11075,7 +11075,7 @@ async function executeAndDeliver(task, now, deps) {
|
|
|
11075
11075
|
const inputFile = path55.join(resultsDirTmp, `${task.id}.input.txt`);
|
|
11076
11076
|
fs54.writeFileSync(inputFile, result, "utf-8");
|
|
11077
11077
|
const { execFile: execFile3 } = await import("child_process");
|
|
11078
|
-
await new Promise((
|
|
11078
|
+
await new Promise((resolve12) => {
|
|
11079
11079
|
execFile3("python", [scriptPath, "main", "--file", inputFile], {
|
|
11080
11080
|
cwd: deps.sessions["config"].stateDir,
|
|
11081
11081
|
timeout: 3e4,
|
|
@@ -11092,7 +11092,7 @@ async function executeAndDeliver(task, now, deps) {
|
|
|
11092
11092
|
}
|
|
11093
11093
|
if (stderr) console.log(`[cron] postProcess stderr: ${stderr.trim()}`);
|
|
11094
11094
|
}
|
|
11095
|
-
|
|
11095
|
+
resolve12();
|
|
11096
11096
|
});
|
|
11097
11097
|
});
|
|
11098
11098
|
} catch (err) {
|
|
@@ -11495,7 +11495,7 @@ var init_wx_query = __esm({
|
|
|
11495
11495
|
const cmd = args2.command.trim();
|
|
11496
11496
|
const timeout = args2.timeout || 12e4;
|
|
11497
11497
|
const fullCmd = `${PYTHON} "${SCRIPT}" ${cmd.replace(/^python3\s+.*wx_query\.py\s*/, "")}`;
|
|
11498
|
-
return new Promise((
|
|
11498
|
+
return new Promise((resolve12) => {
|
|
11499
11499
|
const child = spawn7(shell.shell, [...shell.args, fullCmd], {
|
|
11500
11500
|
timeout,
|
|
11501
11501
|
env: { ...process.env }
|
|
@@ -11510,16 +11510,16 @@ var init_wx_query = __esm({
|
|
|
11510
11510
|
});
|
|
11511
11511
|
child.on("close", (code) => {
|
|
11512
11512
|
if (code === 0) {
|
|
11513
|
-
|
|
11513
|
+
resolve12({ content: stdout });
|
|
11514
11514
|
} else {
|
|
11515
|
-
|
|
11515
|
+
resolve12({
|
|
11516
11516
|
content: stderr || stdout || "(no output)",
|
|
11517
11517
|
isError: true
|
|
11518
11518
|
});
|
|
11519
11519
|
}
|
|
11520
11520
|
});
|
|
11521
11521
|
child.on("error", (err) => {
|
|
11522
|
-
|
|
11522
|
+
resolve12({
|
|
11523
11523
|
content: `wx_query error: ${err.message}`,
|
|
11524
11524
|
isError: true
|
|
11525
11525
|
});
|
|
@@ -12479,15 +12479,15 @@ async function canStealStaleLock(lockPath2) {
|
|
|
12479
12479
|
return !isProcessLikelyAlive(ownerPid);
|
|
12480
12480
|
}
|
|
12481
12481
|
async function sleep5(ms) {
|
|
12482
|
-
await new Promise((
|
|
12483
|
-
setTimeout(
|
|
12482
|
+
await new Promise((resolve12) => {
|
|
12483
|
+
setTimeout(resolve12, ms);
|
|
12484
12484
|
});
|
|
12485
12485
|
}
|
|
12486
12486
|
async function withInProcessShortTermLock(lockPath2, task) {
|
|
12487
12487
|
const previous = inProcessShortTermLocks.get(lockPath2) ?? Promise.resolve();
|
|
12488
12488
|
let releaseCurrent;
|
|
12489
|
-
const current = new Promise((
|
|
12490
|
-
releaseCurrent =
|
|
12489
|
+
const current = new Promise((resolve12) => {
|
|
12490
|
+
releaseCurrent = resolve12;
|
|
12491
12491
|
});
|
|
12492
12492
|
const queued = previous.catch(() => void 0).then(() => current);
|
|
12493
12493
|
inProcessShortTermLocks.set(lockPath2, queued);
|
|
@@ -23473,7 +23473,7 @@ var init_handler = __esm({
|
|
|
23473
23473
|
this._addToNodeFs(path55, initialAdd, wh, depth + 1);
|
|
23474
23474
|
}
|
|
23475
23475
|
}).on(EV.ERROR, this._boundHandleError);
|
|
23476
|
-
return new Promise((
|
|
23476
|
+
return new Promise((resolve12, reject) => {
|
|
23477
23477
|
if (!stream)
|
|
23478
23478
|
return reject();
|
|
23479
23479
|
stream.once(STR_END, () => {
|
|
@@ -23482,7 +23482,7 @@ var init_handler = __esm({
|
|
|
23482
23482
|
return;
|
|
23483
23483
|
}
|
|
23484
23484
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
23485
|
-
|
|
23485
|
+
resolve12(void 0);
|
|
23486
23486
|
previous.getChildren().filter((item) => {
|
|
23487
23487
|
return item !== directory && !current.has(item);
|
|
23488
23488
|
}).forEach((item) => {
|
|
@@ -24782,8 +24782,8 @@ function createSessionSyncYield(total) {
|
|
|
24782
24782
|
return async () => {
|
|
24783
24783
|
completed += 1;
|
|
24784
24784
|
if (completed < total && completed % SESSION_SYNC_YIELD_EVERY === 0) {
|
|
24785
|
-
await new Promise((
|
|
24786
|
-
setImmediate(
|
|
24785
|
+
await new Promise((resolve12) => {
|
|
24786
|
+
setImmediate(resolve12);
|
|
24787
24787
|
});
|
|
24788
24788
|
}
|
|
24789
24789
|
};
|
|
@@ -24985,8 +24985,8 @@ var init_manager_sync_ops = __esm({
|
|
|
24985
24985
|
);
|
|
24986
24986
|
rowCount += 1;
|
|
24987
24987
|
if (rowCount % SEED_EMBEDDING_YIELD_EVERY === 0) {
|
|
24988
|
-
await new Promise((
|
|
24989
|
-
setImmediate(
|
|
24988
|
+
await new Promise((resolve12) => {
|
|
24989
|
+
setImmediate(resolve12);
|
|
24990
24990
|
});
|
|
24991
24991
|
}
|
|
24992
24992
|
}
|
|
@@ -26263,7 +26263,7 @@ var init_manager_embedding_ops = __esm({
|
|
|
26263
26263
|
EMBEDDING_RETRY_MAX_DELAY_MS
|
|
26264
26264
|
);
|
|
26265
26265
|
log2.warn(`memory embeddings rate limited; ${action} in ${waitMs}ms`);
|
|
26266
|
-
await new Promise((
|
|
26266
|
+
await new Promise((resolve12) => setTimeout(resolve12, waitMs));
|
|
26267
26267
|
}
|
|
26268
26268
|
resolveEmbeddingTimeout(kind) {
|
|
26269
26269
|
return resolveEmbeddingTimeoutMs({
|
|
@@ -26305,8 +26305,8 @@ var init_manager_embedding_ops = __esm({
|
|
|
26305
26305
|
async withBatchFailureLock(fn) {
|
|
26306
26306
|
let release2;
|
|
26307
26307
|
const wait = this.batchFailureLock;
|
|
26308
|
-
this.batchFailureLock = new Promise((
|
|
26309
|
-
release2 =
|
|
26308
|
+
this.batchFailureLock = new Promise((resolve12) => {
|
|
26309
|
+
release2 = resolve12;
|
|
26310
26310
|
});
|
|
26311
26311
|
await wait;
|
|
26312
26312
|
try {
|
|
@@ -29303,7 +29303,7 @@ var reply_blocklist_exports = {};
|
|
|
29303
29303
|
__export(reply_blocklist_exports, {
|
|
29304
29304
|
isUserBlocked: () => isUserBlocked
|
|
29305
29305
|
});
|
|
29306
|
-
import { readFileSync as readFileSync26, writeFileSync as writeFileSync15, existsSync as
|
|
29306
|
+
import { readFileSync as readFileSync26, writeFileSync as writeFileSync15, existsSync as existsSync24 } from "node:fs";
|
|
29307
29307
|
import { join as join39 } from "node:path";
|
|
29308
29308
|
function ensureLoaded(workspace, configIds) {
|
|
29309
29309
|
if (loaded) return;
|
|
@@ -29314,7 +29314,7 @@ function ensureLoaded(workspace, configIds) {
|
|
|
29314
29314
|
}
|
|
29315
29315
|
const path55 = join39(workspace, ".reply-blocklist.json");
|
|
29316
29316
|
try {
|
|
29317
|
-
if (
|
|
29317
|
+
if (existsSync24(path55)) {
|
|
29318
29318
|
const raw = readFileSync26(path55, "utf-8");
|
|
29319
29319
|
const parsed = JSON.parse(raw);
|
|
29320
29320
|
if (parsed.blockedUserIds) {
|
|
@@ -30057,12 +30057,12 @@ var MAX_DELAY_MS = 32e3;
|
|
|
30057
30057
|
var DEFAULT_TIMEOUT_MS = 6e5;
|
|
30058
30058
|
var READ_TIMEOUT_MS = 6e4;
|
|
30059
30059
|
function sleep(ms, signal) {
|
|
30060
|
-
return new Promise((
|
|
30060
|
+
return new Promise((resolve12, reject) => {
|
|
30061
30061
|
if (signal?.aborted) {
|
|
30062
30062
|
reject(new DOMException("Aborted", "AbortError"));
|
|
30063
30063
|
return;
|
|
30064
30064
|
}
|
|
30065
|
-
const timer = setTimeout(
|
|
30065
|
+
const timer = setTimeout(resolve12, ms);
|
|
30066
30066
|
const onAbort = () => {
|
|
30067
30067
|
clearTimeout(timer);
|
|
30068
30068
|
reject(new DOMException("Aborted", "AbortError"));
|
|
@@ -34173,7 +34173,7 @@ var MAX_TRANSCRIPT_READ_BYTES = 50 * 1024 * 1024;
|
|
|
34173
34173
|
async function readSessionHeader(filePath) {
|
|
34174
34174
|
const stream = fs7.createReadStream(filePath, { encoding: "utf-8" });
|
|
34175
34175
|
const rl = readline.createInterface({ input: stream });
|
|
34176
|
-
return new Promise((
|
|
34176
|
+
return new Promise((resolve12) => {
|
|
34177
34177
|
let resolved = false;
|
|
34178
34178
|
rl.on("line", (line) => {
|
|
34179
34179
|
try {
|
|
@@ -34182,7 +34182,7 @@ async function readSessionHeader(filePath) {
|
|
|
34182
34182
|
resolved = true;
|
|
34183
34183
|
rl.close();
|
|
34184
34184
|
stream.destroy();
|
|
34185
|
-
|
|
34185
|
+
resolve12({
|
|
34186
34186
|
id: obj.id,
|
|
34187
34187
|
timestamp: obj.timestamp,
|
|
34188
34188
|
cwd: obj.cwd,
|
|
@@ -34194,10 +34194,10 @@ async function readSessionHeader(filePath) {
|
|
|
34194
34194
|
}
|
|
34195
34195
|
});
|
|
34196
34196
|
rl.on("close", () => {
|
|
34197
|
-
if (!resolved)
|
|
34197
|
+
if (!resolved) resolve12(null);
|
|
34198
34198
|
});
|
|
34199
34199
|
rl.on("error", () => {
|
|
34200
|
-
if (!resolved)
|
|
34200
|
+
if (!resolved) resolve12(null);
|
|
34201
34201
|
});
|
|
34202
34202
|
});
|
|
34203
34203
|
}
|
|
@@ -34425,9 +34425,9 @@ async function readAllLines(filePath) {
|
|
|
34425
34425
|
const stream = fs7.createReadStream(filePath, { encoding: "utf-8" });
|
|
34426
34426
|
const rl = readline.createInterface({ input: stream });
|
|
34427
34427
|
const lines = [];
|
|
34428
|
-
return new Promise((
|
|
34428
|
+
return new Promise((resolve12, reject) => {
|
|
34429
34429
|
rl.on("line", (line) => lines.push(line));
|
|
34430
|
-
rl.on("close", () =>
|
|
34430
|
+
rl.on("close", () => resolve12(lines));
|
|
34431
34431
|
rl.on("error", (err) => reject(err));
|
|
34432
34432
|
});
|
|
34433
34433
|
}
|
|
@@ -37118,8 +37118,8 @@ function startCliLoop(deps, cliConfig, channelManager, dispatcher) {
|
|
|
37118
37118
|
process.stdout.write("AI> ");
|
|
37119
37119
|
let inToolCall = false;
|
|
37120
37120
|
let resolveDone;
|
|
37121
|
-
const done2 = new Promise((
|
|
37122
|
-
resolveDone =
|
|
37121
|
+
const done2 = new Promise((resolve12) => {
|
|
37122
|
+
resolveDone = resolve12;
|
|
37123
37123
|
});
|
|
37124
37124
|
dispatcher.submitMessage({
|
|
37125
37125
|
text: trimmed,
|
|
@@ -37415,8 +37415,8 @@ ${basePrompt}`;
|
|
|
37415
37415
|
}, timeoutMs);
|
|
37416
37416
|
if (this.dispatcher) {
|
|
37417
37417
|
let resolveDone;
|
|
37418
|
-
const done2 = new Promise((
|
|
37419
|
-
resolveDone =
|
|
37418
|
+
const done2 = new Promise((resolve12) => {
|
|
37419
|
+
resolveDone = resolve12;
|
|
37420
37420
|
});
|
|
37421
37421
|
this.dispatcher.submitMessage({
|
|
37422
37422
|
text: prompt,
|
|
@@ -37791,7 +37791,7 @@ var NudgePlugin = class {
|
|
|
37791
37791
|
}, intervalMs);
|
|
37792
37792
|
this.registerStopHook(sessions);
|
|
37793
37793
|
}
|
|
37794
|
-
/** 注册 Stop hook
|
|
37794
|
+
/** 注册 Stop hook:你停止前用 LLM 判断是否在等外部条件 → 注册 5min notification */
|
|
37795
37795
|
registerStopHook(sessions) {
|
|
37796
37796
|
registerCallbackHook("Stop", {
|
|
37797
37797
|
type: "callback",
|
|
@@ -37805,7 +37805,7 @@ var NudgePlugin = class {
|
|
|
37805
37805
|
console.log(`[stop-hook] skipping voice-chat (channel=${msgChannel})`);
|
|
37806
37806
|
return { outcome: { outcome: "success" } };
|
|
37807
37807
|
}
|
|
37808
|
-
if (!lastMsg
|
|
37808
|
+
if (!lastMsg) {
|
|
37809
37809
|
return { outcome: { outcome: "success" } };
|
|
37810
37810
|
}
|
|
37811
37811
|
let contextStr = "";
|
|
@@ -37821,9 +37821,10 @@ var NudgePlugin = class {
|
|
|
37821
37821
|
console.warn(`[stop-hook] recentMessages error: ${e.message}`);
|
|
37822
37822
|
}
|
|
37823
37823
|
const judgeInput = `${contextStr}
|
|
37824
|
-
|
|
37824
|
+
\u4F60: ${lastMsg.slice(0, 300)}`;
|
|
37825
37825
|
let isWaiting = false;
|
|
37826
37826
|
let waitDesc = "";
|
|
37827
|
+
let pushedDecision = false;
|
|
37827
37828
|
try {
|
|
37828
37829
|
const excludeCases = this.cfg.stopHookExcludeCases || [];
|
|
37829
37830
|
const excludeSection = excludeCases.length > 0 ? [
|
|
@@ -37834,20 +37835,22 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37834
37835
|
const stream = this.provider.streamChat({
|
|
37835
37836
|
model: this.model,
|
|
37836
37837
|
systemPrompt: [
|
|
37837
|
-
"\u4F60\u662F\u4E00\u4E2A\u5224\u65AD\u5668\u3002\u8BFB
|
|
37838
|
+
"\u4F60\u662F\u4E00\u4E2A\u5224\u65AD\u5668\u3002\u8BFB\u4F60\u6700\u8FD1\u7684\u5BF9\u8BDD\u4E0A\u4E0B\u6587\uFF0C\u5224\u65AD\u4F60\uFF08\u5C0F\u67EF\uFF09\u662F\u5426\u5904\u4E8E\u4EE5\u4E0B\u72B6\u6001\u4E4B\u4E00\uFF1A",
|
|
37838
37839
|
"",
|
|
37839
37840
|
"1. \u5728\u7B49\u5F85\u67D0\u4E2A\u5916\u90E8\u6761\u4EF6\uFF08\u670D\u52A1\u91CD\u542F\u3001SSH\u6062\u590D\u3001\u6587\u4EF6\u52A0\u8F7D\u3001\u5F02\u6B65\u4EFB\u52A1\u5B8C\u6210\u7B49\uFF09",
|
|
37840
37841
|
'2. \u628A\u672C\u8BE5\u81EA\u5DF1\u505A\u7684\u51B3\u5B9A\u63A8\u7ED9\u4E86\u5BF9\u65B9\uFF08\u4F8B\u5982\u95EE"\u8981\u73B0\u5728\u6539\u8FD8\u662F\u6392\u540E\u9762\uFF1F""\u8981\u4E0D\u8981\u8BD5\u8BD5X\uFF1F"\u4F46\u660E\u660E\u81EA\u5DF1\u80FD\u5B9A\uFF09',
|
|
37841
37842
|
"3. \u9047\u5230\u95EE\u9898\u6CA1\u6709\u81EA\u5DF1\u89E3\u51B3\u4E5F\u6CA1\u6709\u6392\u8FDB calendar\uFF0C\u53EA\u662F\u6401\u7F6E\u7740",
|
|
37842
37843
|
"",
|
|
37843
|
-
"\u5173\u952E\u533A\u5206\uFF1A
|
|
37844
|
-
|
|
37845
|
-
|
|
37844
|
+
"\u5173\u952E\u533A\u5206\uFF1A",
|
|
37845
|
+
'- \u7B49\u5BF9\u65B9\u56DE\u590D\u4E00\u4E2A\u81EA\u5DF1\u5C31\u80FD\u505A\u7684\u51B3\u5B9A \u2192 "pushedDecision": true\uFF08\u4E0D\u662F\u5355\u7EAF waiting\uFF0C\u8FD9\u662F\u66F4\u4E25\u91CD\u7684\u8FDD\u89C4\uFF09',
|
|
37846
|
+
'- \u7B49\u771F\u6B63\u7684\u5916\u90E8\u6761\u4EF6\uFF08\u670D\u52A1\u3001SSH\u3001\u5F02\u6B65\u4EFB\u52A1\uFF09 \u2192 "waiting": true',
|
|
37847
|
+
"- \u4F60\u5DF2\u7ECF\u505A\u4E86\u51B3\u5B9A\u5E76\u6392\u8FDB calendar \u6216\u5DF2\u5F00\u59CB\u6267\u884C \u2192 \u4E24\u4E2A\u90FD false",
|
|
37846
37848
|
excludeSection,
|
|
37847
37849
|
"",
|
|
37848
37850
|
"\u53EA\u56DE\u590D JSON\uFF1A",
|
|
37849
|
-
'- \
|
|
37850
|
-
'- \
|
|
37851
|
+
'- \u63A8\u51B3\u5B9A\u7ED9\u5BF9\u65B9\uFF08\u81EA\u5DF1\u80FD\u5B9A\u5374\u95EE\uFF09\uFF1A{"pushedDecision": true, "desc": "\u7B80\u77ED\u8BF4\u660E + \u5EFA\u8BAE\u600E\u4E48\u505A"}',
|
|
37852
|
+
'- \u771F\u7B49\u5916\u90E8\u6761\u4EF6\uFF1A{"waiting": true, "desc": "\u7B80\u77ED\u8BF4\u660E"}',
|
|
37853
|
+
'- \u4E0D\u7B26\u5408\uFF1A{"waiting": false, "pushedDecision": false}'
|
|
37851
37854
|
].join("\n"),
|
|
37852
37855
|
messages: [{ role: "user", content: judgeInput }],
|
|
37853
37856
|
maxTokens: 128,
|
|
@@ -37865,11 +37868,37 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37865
37868
|
const parsed = JSON.parse(match[0]);
|
|
37866
37869
|
isWaiting = !!parsed.waiting;
|
|
37867
37870
|
waitDesc = parsed.desc || "";
|
|
37871
|
+
pushedDecision = !!parsed.pushedDecision;
|
|
37868
37872
|
}
|
|
37869
|
-
console.log(`[stop-hook] Judge result: waiting=${isWaiting}, desc="${waitDesc}"`);
|
|
37873
|
+
console.log(`[stop-hook] Judge result: waiting=${isWaiting}, pushedDecision=${pushedDecision}, desc="${waitDesc}"`);
|
|
37870
37874
|
} catch (e) {
|
|
37871
37875
|
console.warn(`[stop-hook] LLM judge error: ${e.message}`);
|
|
37872
37876
|
}
|
|
37877
|
+
if (pushedDecision && waitDesc) {
|
|
37878
|
+
console.log(`[stop-hook] DETECTED pushedDecision! Injecting corrective message to ${sessionId}`);
|
|
37879
|
+
try {
|
|
37880
|
+
const correctiveMsg = [
|
|
37881
|
+
"\u{1F6A8} [stop-hook \u81EA\u4E3B\u6267\u884C\u7EA0\u6B63] \u4F60\u521A\u624D\u628A\u4E00\u4E2A\u81EA\u5DF1\u80FD\u5B9A\u7684\u51B3\u5B9A\u63A8\u7ED9\u4E86\u5BF9\u65B9\u3002",
|
|
37882
|
+
"",
|
|
37883
|
+
`\u8BCA\u65AD\uFF1A${waitDesc}`,
|
|
37884
|
+
"",
|
|
37885
|
+
"\u660E\u77E5\u9053\u600E\u4E48\u505A\u5BF9\u7684\u4E8B \u2192 \u76F4\u63A5\u505A \u2192 \u6C47\u62A5\u7ED3\u679C\u3002",
|
|
37886
|
+
"\u95EE = \u5361\u4F4F\u3002",
|
|
37887
|
+
"",
|
|
37888
|
+
"\u8BF7\u7ACB\u523B\uFF1A",
|
|
37889
|
+
"1. \u64A4\u56DE\u4F60\u7684\u95EE\u9898\uFF08\u4E0D\u8981\u7B49\u5BF9\u65B9\u56DE\u590D\uFF09",
|
|
37890
|
+
"2. \u81EA\u5DF1\u9009\u6700\u4F18\u65B9\u6848\u76F4\u63A5\u6267\u884C",
|
|
37891
|
+
'3. \u6267\u884C\u5B8C\u6C47\u62A5\u7ED3\u679C\uFF08"\u5DF2\u5904\u7406" / "\u5DF2 commit" / "\u5DF2 archive"\uFF09',
|
|
37892
|
+
"",
|
|
37893
|
+
"\u5982\u679C\u4E0D\u662F\u5FC5\u987B\u95EE\u7684\uFF08\u6D89\u53CA\u82B1\u94B1/\u5BF9\u5916\u53D1\u5E03/\u91CD\u5927\u51B3\u7B56\uFF09\uFF0C\u4E0D\u8981\u95EE\u3002"
|
|
37894
|
+
].join("\n");
|
|
37895
|
+
if (this.dispatcher) {
|
|
37896
|
+
this.dispatcher.submitMessage(correctiveMsg, sessionId);
|
|
37897
|
+
}
|
|
37898
|
+
} catch (e) {
|
|
37899
|
+
console.warn(`[stop-hook] Failed to inject corrective message: ${e.message}`);
|
|
37900
|
+
}
|
|
37901
|
+
}
|
|
37873
37902
|
if (!isWaiting) {
|
|
37874
37903
|
return { outcome: { outcome: "success" } };
|
|
37875
37904
|
}
|
|
@@ -37888,13 +37917,15 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37888
37917
|
}
|
|
37889
37918
|
}
|
|
37890
37919
|
const wakeAt = new Date(Date.now() + 5 * 6e4).toISOString();
|
|
37920
|
+
const notifId = `wake-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
37891
37921
|
notifs.push({
|
|
37922
|
+
id: notifId,
|
|
37892
37923
|
description: waitDesc || lastMsg.slice(0, 200),
|
|
37893
37924
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
37894
37925
|
wakeAt
|
|
37895
37926
|
});
|
|
37896
37927
|
fs17.writeFileSync(notifPath, JSON.stringify(notifs, null, 2));
|
|
37897
|
-
console.log(`[stop-hook] Registered wake-up at ${wakeAt} (sessionId=${sessionId}): ${waitDesc}`);
|
|
37928
|
+
console.log(`[stop-hook] Registered wake-up ${notifId} at ${wakeAt} (sessionId=${sessionId}): ${waitDesc}`);
|
|
37898
37929
|
} catch (e) {
|
|
37899
37930
|
console.warn(`[stop-hook] Failed to register: ${e.message}`);
|
|
37900
37931
|
}
|
|
@@ -37927,7 +37958,7 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37927
37958
|
return null;
|
|
37928
37959
|
}
|
|
37929
37960
|
}
|
|
37930
|
-
/** 检查 stop-hook-notifications
|
|
37961
|
+
/** 检查 stop-hook-notifications:你停止前注册的等待唤起 */
|
|
37931
37962
|
checkStopHookNotifications() {
|
|
37932
37963
|
const notifPath = path17.join(this.workspace, ".nudge", "stop-hook-notifications.json");
|
|
37933
37964
|
try {
|
|
@@ -37935,26 +37966,56 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37935
37966
|
const notifs = JSON.parse(fs17.readFileSync(notifPath, "utf-8"));
|
|
37936
37967
|
if (notifs.length === 0) return null;
|
|
37937
37968
|
const now = Date.now();
|
|
37938
|
-
const due = notifs.filter((n) => new Date(n.wakeAt).getTime() <= now);
|
|
37969
|
+
const due = notifs.filter((n) => new Date(n.wakeAt).getTime() <= now && !n.notified);
|
|
37939
37970
|
if (due.length === 0) return null;
|
|
37940
37971
|
const latest = due[due.length - 1];
|
|
37941
|
-
console.log(`[nudge] Stop-hook notification triggered: ${latest.description.slice(0, 80)}...`);
|
|
37942
|
-
const
|
|
37943
|
-
|
|
37944
|
-
fs17.writeFileSync(notifPath, JSON.stringify(remaining, null, 2));
|
|
37945
|
-
} else {
|
|
37946
|
-
fs17.unlinkSync(notifPath);
|
|
37947
|
-
}
|
|
37972
|
+
console.log(`[nudge] Stop-hook notification ${latest.id} triggered: ${latest.description.slice(0, 80)}...`);
|
|
37973
|
+
const updated = notifs.map((n) => n.id === latest.id ? { ...n, notified: true } : n);
|
|
37974
|
+
fs17.writeFileSync(notifPath, JSON.stringify(updated, null, 2));
|
|
37948
37975
|
return buildNudgeNotification("wake", `\u4F60\u4E4B\u524D\u5728\u7B49\u5F85\u67D0\u4E2A\u5916\u90E8\u6761\u4EF6\uFF0C\u65F6\u95F4\u5230\u4E86\uFF0C\u56DE\u53BB\u68C0\u67E5\uFF01
|
|
37949
37976
|
|
|
37977
|
+
[\u901A\u77E5ID: ${latest.id}]
|
|
37950
37978
|
\u4E0A\u6B21\u8BF4\uFF1A${latest.description}
|
|
37951
37979
|
|
|
37952
|
-
\u68C0\u67E5\u6761\u4EF6\u662F\u5426\u6EE1\u8DB3\uFF0C\u6EE1\u8DB3\u5C31\u7EE7\u7EED\u5E72\u6D3B\uFF0C\u4E0D\u6EE1\u8DB3\u5C31\
|
|
37980
|
+
\u68C0\u67E5\u6761\u4EF6\u662F\u5426\u6EE1\u8DB3\uFF0C\u6EE1\u8DB3\u5C31\u7EE7\u7EED\u5E72\u6D3B\uFF0C\u4E0D\u6EE1\u8DB3\u5C31\u56DE\u590D"${latest.id} \u8FC7\u671F\u4E86"\u544A\u8BC9 nudge \u7CBE\u786E\u6E05\u7406\u8FD9\u6761\u3002`);
|
|
37953
37981
|
} catch (e) {
|
|
37954
37982
|
console.warn(`[nudge] checkStopHookNotifications error: ${e.message}`);
|
|
37955
37983
|
return null;
|
|
37956
37984
|
}
|
|
37957
37985
|
}
|
|
37986
|
+
/** 读最近消息,如果发现"<notifId> 过期了"→ 精确清理对应的 wake-up notification */
|
|
37987
|
+
cleanupStaleNotificationsFromMessages(sessions) {
|
|
37988
|
+
try {
|
|
37989
|
+
const recent = recentMessages(sessions, 0.5, 6);
|
|
37990
|
+
const fiveMinAgo = Date.now() - 5 * 60 * 1e3;
|
|
37991
|
+
const recentTexts = recent.filter((r) => new Date(r.timestamp || r.createdAt || Date.now()).getTime() > fiveMinAgo).map((r) => r.text);
|
|
37992
|
+
const notifPath = path17.join(this.workspace, ".nudge", "stop-hook-notifications.json");
|
|
37993
|
+
if (!fs17.existsSync(notifPath)) return;
|
|
37994
|
+
const notifs = JSON.parse(fs17.readFileSync(notifPath, "utf-8"));
|
|
37995
|
+
if (notifs.length === 0) return;
|
|
37996
|
+
const expiredIds = /* @__PURE__ */ new Set();
|
|
37997
|
+
for (const text of recentTexts) {
|
|
37998
|
+
for (const n of notifs) {
|
|
37999
|
+
if (text.includes(`${n.id} \u8FC7\u671F\u4E86`) || text.includes(`${n.id}\u8FC7\u671F\u4E86`)) {
|
|
38000
|
+
expiredIds.add(n.id);
|
|
38001
|
+
}
|
|
38002
|
+
}
|
|
38003
|
+
}
|
|
38004
|
+
if (expiredIds.size === 0) return;
|
|
38005
|
+
const remaining = notifs.filter((n) => !expiredIds.has(n.id));
|
|
38006
|
+
const cleaned = notifs.length - remaining.length;
|
|
38007
|
+
if (cleaned > 0) {
|
|
38008
|
+
if (remaining.length > 0) {
|
|
38009
|
+
fs17.writeFileSync(notifPath, JSON.stringify(remaining, null, 2));
|
|
38010
|
+
} else {
|
|
38011
|
+
fs17.unlinkSync(notifPath);
|
|
38012
|
+
}
|
|
38013
|
+
console.log(`[nudge] Cleaned ${cleaned} stale notification(s) by explicit id: ${[...expiredIds].join(", ")}`);
|
|
38014
|
+
}
|
|
38015
|
+
} catch (e) {
|
|
38016
|
+
console.warn(`[nudge] cleanupStaleNotificationsFromMessages error: ${e.message}`);
|
|
38017
|
+
}
|
|
38018
|
+
}
|
|
37958
38019
|
async tick(sessions, deps) {
|
|
37959
38020
|
if (this.running) {
|
|
37960
38021
|
console.log("[nudge] Previous tick still running, skipping");
|
|
@@ -37980,6 +38041,7 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37980
38041
|
}
|
|
37981
38042
|
this.running = true;
|
|
37982
38043
|
try {
|
|
38044
|
+
this.cleanupStaleNotificationsFromMessages(sessions);
|
|
37983
38045
|
const stopNotifs = this.checkStopHookNotifications();
|
|
37984
38046
|
if (stopNotifs) {
|
|
37985
38047
|
const route2 = this.getRoute(sessions);
|
|
@@ -39426,6 +39488,8 @@ function formatBeijingTs(d) {
|
|
|
39426
39488
|
}
|
|
39427
39489
|
|
|
39428
39490
|
// src/calendar/commands.ts
|
|
39491
|
+
import { existsSync as existsSync13, statSync as statSync7 } from "node:fs";
|
|
39492
|
+
import { isAbsolute as isAbsolute4, resolve as resolve7 } from "node:path";
|
|
39429
39493
|
var WEEKDAYS2 = ["\u5468\u4E00", "\u5468\u4E8C", "\u5468\u4E09", "\u5468\u56DB", "\u5468\u4E94", "\u5468\u516D", "\u5468\u65E5"];
|
|
39430
39494
|
function fmtEnd(start, durationMin) {
|
|
39431
39495
|
const [hh, mm] = start.split(":").map(Number);
|
|
@@ -39588,7 +39652,29 @@ ${skipped.map((s2) => ` ${s2}`).join("\n")}`;
|
|
|
39588
39652
|
return result;
|
|
39589
39653
|
}
|
|
39590
39654
|
function addTask(db, args2) {
|
|
39591
|
-
const { dateStr, timeExact, event } = args2;
|
|
39655
|
+
const { dateStr, timeExact, event, docPath } = args2;
|
|
39656
|
+
if (!docPath || !docPath.trim()) {
|
|
39657
|
+
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Aadd-task \u5FC5\u987B\u4F20 doc_path\u3002
|
|
39658
|
+
\u6CA1\u6709\u6587\u6863\u652F\u6491\u7684 task \u4E0D\u662F\u5408\u683C\u7684 task\u3002
|
|
39659
|
+
\u8BF7\u5148\u5728 docs/todo/ \u4E0B\u521B\u5EFA\u6587\u6863\uFF08\u547D\u540D\uFF1AYYYY-MM-DD_\u4E3B\u9898.md \u6216 \u4EFB\u52A1\u540D.md\uFF09\uFF0C\u7136\u540E\u4F20 doc_path \u53C2\u6570\u3002`;
|
|
39660
|
+
}
|
|
39661
|
+
try {
|
|
39662
|
+
const absPath = isAbsolute4(docPath) ? docPath : resolve7(process.cwd(), docPath);
|
|
39663
|
+
if (!existsSync13(absPath)) {
|
|
39664
|
+
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728
|
|
39665
|
+
\u8DEF\u5F84: ${docPath}
|
|
39666
|
+
\u89E3\u6790\u540E: ${absPath}
|
|
39667
|
+
\u8BF7\u5148\u521B\u5EFA\u6587\u6863\u518D add-task\u3002`;
|
|
39668
|
+
}
|
|
39669
|
+
const stat8 = statSync7(absPath);
|
|
39670
|
+
if (!stat8.isFile()) {
|
|
39671
|
+
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u4E0D\u662F\u6587\u4EF6\uFF08\u53EF\u80FD\u662F\u76EE\u5F55\uFF09
|
|
39672
|
+
\u8DEF\u5F84: ${docPath}`;
|
|
39673
|
+
}
|
|
39674
|
+
} catch (err) {
|
|
39675
|
+
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u6821\u9A8C\u51FA\u9519\uFF1A${err.message}
|
|
39676
|
+
\u8DEF\u5F84: ${docPath}`;
|
|
39677
|
+
}
|
|
39592
39678
|
let remindMin = 60;
|
|
39593
39679
|
if (args2.remind) {
|
|
39594
39680
|
const v2 = args2.remind;
|
|
@@ -39602,10 +39688,11 @@ function addTask(db, args2) {
|
|
|
39602
39688
|
const prox = checkTaskProximity(taskRows, timeExact);
|
|
39603
39689
|
const remindAt = computeRemindAt(dateStr, timeExact, remindMin);
|
|
39604
39690
|
const r = db.prepare(
|
|
39605
|
-
`INSERT INTO events (type,status,event,date_str,time_exact,remind_before_min,remind_at,reminded,created_at,created_channel,created_channel_target)
|
|
39606
|
-
VALUES ('task','pending'
|
|
39607
|
-
).run(event, dateStr, timeExact, remindMin, remindAt, 0, nowIso(), args2.channel || null, args2.channelTarget || null);
|
|
39608
|
-
let msg2 = `#${r.lastInsertRowid} \u5DF2\u6DFB\u52A0\u4EFB\u52A1: [${dateStr} ${timeExact}] ${event} (\u63D0\u524D${remindMin}min\u63D0\u9192)
|
|
39691
|
+
`INSERT INTO events (type,status,event,date_str,time_exact,remind_before_min,remind_at,reminded,created_at,created_channel,created_channel_target,doc_path)
|
|
39692
|
+
VALUES ('task','pending',?,?,?,?,?,?,?,?,?,?)`
|
|
39693
|
+
).run(event, dateStr, timeExact, remindMin, remindAt, 0, nowIso(), args2.channel || null, args2.channelTarget || null, docPath);
|
|
39694
|
+
let msg2 = `#${r.lastInsertRowid} \u5DF2\u6DFB\u52A0\u4EFB\u52A1: [${dateStr} ${timeExact}] ${event} (\u63D0\u524D${remindMin}min\u63D0\u9192)
|
|
39695
|
+
\u{1F4C4} \u6587\u6863: ${docPath}`;
|
|
39609
39696
|
if (prox) {
|
|
39610
39697
|
msg2 += `
|
|
39611
39698
|
\u26A0\uFE0F \u65F6\u95F4\u63A5\u8FD1\uFF1A\u4E0E #${prox.id}\u300C${prox.event}\u300D(${prox.time}) \u4EC5\u76F8\u5DEE ${prox.diffMin}min`;
|
|
@@ -39939,7 +40026,7 @@ function registerVoiceChatBridge(httpServer, dispatcher, deps, config2, sessions
|
|
|
39939
40026
|
const https = await import("node:https");
|
|
39940
40027
|
const url = new URL(callbackUrl);
|
|
39941
40028
|
const postData = JSON.stringify({ session_id: ctx.inbound.from, text: ctx.response });
|
|
39942
|
-
await new Promise((
|
|
40029
|
+
await new Promise((resolve12, reject) => {
|
|
39943
40030
|
const req = https.request(url, {
|
|
39944
40031
|
method: "POST",
|
|
39945
40032
|
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) },
|
|
@@ -39947,7 +40034,7 @@ function registerVoiceChatBridge(httpServer, dispatcher, deps, config2, sessions
|
|
|
39947
40034
|
}, (res) => {
|
|
39948
40035
|
console.log(`[voice-chat] Reply POST ${callbackUrl}: ${res.statusCode} (${ctx.response.length} chars)`);
|
|
39949
40036
|
res.resume();
|
|
39950
|
-
|
|
40037
|
+
resolve12();
|
|
39951
40038
|
});
|
|
39952
40039
|
req.on("error", reject);
|
|
39953
40040
|
req.write(postData);
|
|
@@ -40236,27 +40323,27 @@ var VoiceChatPlugin = class _VoiceChatPlugin {
|
|
|
40236
40323
|
};
|
|
40237
40324
|
}
|
|
40238
40325
|
async isPortAlive(port) {
|
|
40239
|
-
return new Promise((
|
|
40326
|
+
return new Promise((resolve12) => {
|
|
40240
40327
|
const socket = new net.Socket();
|
|
40241
40328
|
socket.setTimeout(2e3);
|
|
40242
40329
|
socket.on("connect", () => {
|
|
40243
40330
|
socket.destroy();
|
|
40244
|
-
|
|
40331
|
+
resolve12(true);
|
|
40245
40332
|
});
|
|
40246
40333
|
socket.on("timeout", () => {
|
|
40247
40334
|
socket.destroy();
|
|
40248
|
-
|
|
40335
|
+
resolve12(false);
|
|
40249
40336
|
});
|
|
40250
40337
|
socket.on("error", () => {
|
|
40251
40338
|
socket.destroy();
|
|
40252
|
-
|
|
40339
|
+
resolve12(false);
|
|
40253
40340
|
});
|
|
40254
40341
|
socket.connect(port, "127.0.0.1");
|
|
40255
40342
|
});
|
|
40256
40343
|
}
|
|
40257
40344
|
async killProcessOnPort(port) {
|
|
40258
|
-
const run = (cmd) => new Promise((
|
|
40259
|
-
exec(cmd, { timeout: 5e3 }, (err, stdout) =>
|
|
40345
|
+
const run = (cmd) => new Promise((resolve12) => {
|
|
40346
|
+
exec(cmd, { timeout: 5e3 }, (err, stdout) => resolve12(err ? "" : stdout));
|
|
40260
40347
|
});
|
|
40261
40348
|
try {
|
|
40262
40349
|
if (process.platform === "win32") {
|
|
@@ -40745,27 +40832,27 @@ var CogniFoldPlugin = class {
|
|
|
40745
40832
|
throw new Error(`CogniFold not ready after ${timeoutMs}ms at ${url}`);
|
|
40746
40833
|
}
|
|
40747
40834
|
async isPortAlive(port) {
|
|
40748
|
-
return new Promise((
|
|
40835
|
+
return new Promise((resolve12) => {
|
|
40749
40836
|
const socket = new net2.Socket();
|
|
40750
40837
|
socket.setTimeout(2e3);
|
|
40751
40838
|
socket.on("connect", () => {
|
|
40752
40839
|
socket.destroy();
|
|
40753
|
-
|
|
40840
|
+
resolve12(true);
|
|
40754
40841
|
});
|
|
40755
40842
|
socket.on("timeout", () => {
|
|
40756
40843
|
socket.destroy();
|
|
40757
|
-
|
|
40844
|
+
resolve12(false);
|
|
40758
40845
|
});
|
|
40759
40846
|
socket.on("error", () => {
|
|
40760
40847
|
socket.destroy();
|
|
40761
|
-
|
|
40848
|
+
resolve12(false);
|
|
40762
40849
|
});
|
|
40763
40850
|
socket.connect(port, "127.0.0.1");
|
|
40764
40851
|
});
|
|
40765
40852
|
}
|
|
40766
40853
|
async killProcessOnPort(port) {
|
|
40767
|
-
const run = (cmd) => new Promise((
|
|
40768
|
-
exec2(cmd, { timeout: 5e3 }, (err, stdout) =>
|
|
40854
|
+
const run = (cmd) => new Promise((resolve12) => {
|
|
40855
|
+
exec2(cmd, { timeout: 5e3 }, (err, stdout) => resolve12(err ? "" : stdout));
|
|
40769
40856
|
});
|
|
40770
40857
|
try {
|
|
40771
40858
|
if (process.platform === "win32") {
|
|
@@ -42010,7 +42097,7 @@ registry.register({
|
|
|
42010
42097
|
init_registry();
|
|
42011
42098
|
registry.register({
|
|
42012
42099
|
name: "calendar",
|
|
42013
|
-
description: 'Manage family calendar (SQLite). add: \u52A0\u65E5\u7A0B (repeat=daily \u6BCF\u5929/weekdays \u5DE5\u4F5C\u65E5/weekly \u6BCF\u5468\u9009\u5468\u51E0/once \u4E00\u6B21\u6027) \u2014 **\u7528\u4E8E\u65E5\u5E38\u65F6\u95F4\u5B89\u6392** (\u4E0A\u8BFE/\u7EA6\u4F1A/\u8BFE\u8868). add-batch: \u6279\u91CF\u52A0\u65E5\u7A0B (dates=\u9017\u53F7\u5206\u9694\u65E5\u671F\u6216\u8303\u56F4, \u5982 "7/2,7/4,7/6-7/10") \u2014 **\u7528\u4E8E\u65E5\u5E38\u65F6\u95F4\u5B89\u6392**. add-task: \u52A0\u4EFB\u52A1 (\u5F3A\u5236\u5E26\u65E5\u671F+\u65F6\u95F4, \u662F\u52A0\u4EFB\u52A1\u7684\u552F\u4E00\u5165\u53E3) \u2014 **\u4EC5\u7528\u4E8E\u5DE5\u4F5C\u7C7B\u4EFB\u52A1** (\u6D3E\u6D3B/\u8DDF\u8FDB/\u9650\u65F6\u4EA4\u4ED8). list: \u67E5\u770B (all=true \u5168\u90E8). done <id>: \u6807\u8BB0\u5B8C\u6210. search <keyword>: \u68C0\u7D22. pending: \u5F85\u5904\u7406. archive <id>: \u5F52\u6863\uFF08\u4E0D\u5220\u9664\uFF0C\u53EF\u6062\u590D\uFF09. reschedule <id>: \u6539\u671F\uFF08\u9700\u8981 date + time_exact\uFF09. cleanup: \u81EA\u52A8\u5F52\u6863\u8FC7\u671F. stats: \u7EDF\u8BA1. **\u6838\u5FC3\u89C4\u5219**\uFF1A\u5B69\u5B50\u4EEC\u7684\u8BFE\u3001\u4E0A\u8BFE/\u7EA6\u4F1A/\u5BB6\u5EAD\u6D3B\u52A8\u7528 add \u6216 add-batch\uFF08\u4E00\u6B21\u6027\u6216\u6BCF\u5468\u56FA\u5B9A\uFF09\uFF1B\u5DE5\u4F5C\u6D3E\u6D3B/\u9650\u65F6\u4EFB\u52A1\u7528 add-task. **\u6DF7\u6DC6\u8FD9\u4E24\u7C7B\u4F1A\u5BFC\u81F4\uFF1Aadd \u7684\u4E8B\u4EF6\u6709\u51B2\u7A81\u68C0\u6D4B\u3001add-task \u6CA1\u6709**. Triggers: \u8BB0\u65E5\u7A0B/\u52A0\u65E5\u5386/\u52A0\u4EFB\u52A1/\u4ECA\u5929\u6709\u4EC0\u4E48/\u65E5\u7A0B/\u63D0\u9192/\u5220\u9664\u65E5\u7A0B/\u6E05\u7406\u65E5\u5386/\u67E5\u65E5\u7A0B.',
|
|
42100
|
+
description: 'Manage family calendar (SQLite). add: \u52A0\u65E5\u7A0B (repeat=daily \u6BCF\u5929/weekdays \u5DE5\u4F5C\u65E5/weekly \u6BCF\u5468\u9009\u5468\u51E0/once \u4E00\u6B21\u6027) \u2014 **\u7528\u4E8E\u65E5\u5E38\u65F6\u95F4\u5B89\u6392** (\u4E0A\u8BFE/\u7EA6\u4F1A/\u8BFE\u8868). add-batch: \u6279\u91CF\u52A0\u65E5\u7A0B (dates=\u9017\u53F7\u5206\u9694\u65E5\u671F\u6216\u8303\u56F4, \u5982 "7/2,7/4,7/6-7/10") \u2014 **\u7528\u4E8E\u65E5\u5E38\u65F6\u95F4\u5B89\u6392**. add-task: \u52A0\u4EFB\u52A1 (\u5F3A\u5236\u5E26\u65E5\u671F+\u65F6\u95F4, \u662F\u52A0\u4EFB\u52A1\u7684\u552F\u4E00\u5165\u53E3) \u2014 **\u4EC5\u7528\u4E8E\u5DE5\u4F5C\u7C7B\u4EFB\u52A1** (\u6D3E\u6D3B/\u8DDF\u8FDB/\u9650\u65F6\u4EA4\u4ED8). **\u5F3A\u5236\u8981\u6C42 doc_path** \u2014 \u6CA1\u6587\u6863\u652F\u6491\u7684 task \u4E0D\u662F\u5408\u683C\u7684 task,add-task \u4F1A\u62D2\u7EDD\u521B\u5EFA\u5E76\u63D0\u793A\u6587\u6863\u8DEF\u5F84. list: \u67E5\u770B (all=true \u5168\u90E8). done <id>: \u6807\u8BB0\u5B8C\u6210. search <keyword>: \u68C0\u7D22. pending: \u5F85\u5904\u7406. archive <id>: \u5F52\u6863\uFF08\u4E0D\u5220\u9664\uFF0C\u53EF\u6062\u590D\uFF09. reschedule <id>: \u6539\u671F\uFF08\u9700\u8981 date + time_exact\uFF09. cleanup: \u81EA\u52A8\u5F52\u6863\u8FC7\u671F. stats: \u7EDF\u8BA1. **\u6838\u5FC3\u89C4\u5219**\uFF1A\u5B69\u5B50\u4EEC\u7684\u8BFE\u3001\u4E0A\u8BFE/\u7EA6\u4F1A/\u5BB6\u5EAD\u6D3B\u52A8\u7528 add \u6216 add-batch\uFF08\u4E00\u6B21\u6027\u6216\u6BCF\u5468\u56FA\u5B9A\uFF09\uFF1B\u5DE5\u4F5C\u6D3E\u6D3B/\u9650\u65F6\u4EFB\u52A1\u7528 add-task. **\u6DF7\u6DC6\u8FD9\u4E24\u7C7B\u4F1A\u5BFC\u81F4\uFF1Aadd \u7684\u4E8B\u4EF6\u6709\u51B2\u7A81\u68C0\u6D4B\u3001add-task \u6CA1\u6709**. Triggers: \u8BB0\u65E5\u7A0B/\u52A0\u65E5\u5386/\u52A0\u4EFB\u52A1/\u4ECA\u5929\u6709\u4EC0\u4E48/\u65E5\u7A0B/\u63D0\u9192/\u5220\u9664\u65E5\u7A0B/\u6E05\u7406\u65E5\u5386/\u67E5\u65E5\u7A0B.',
|
|
42014
42101
|
schema: {
|
|
42015
42102
|
type: "object",
|
|
42016
42103
|
properties: {
|
|
@@ -42027,7 +42114,7 @@ registry.register({
|
|
|
42027
42114
|
remind: { type: "string", description: "\u63D0\u524D\u63D0\u9192\uFF08add-task \u7528\uFF0C\u5982 30m=30\u5206\u949F, 1h=1\u5C0F\u65F6, \u9ED8\u8BA460m\uFF09" },
|
|
42028
42115
|
id: { type: "number", description: "\u4E8B\u4EF6 ID\uFF08done/archive/reschedule/link-doc/find-doc \u7528\uFF09" },
|
|
42029
42116
|
all: { type: "boolean", description: "\u67E5\u770B\u5168\u90E8\uFF08list \u7528\uFF09" },
|
|
42030
|
-
doc_path: { type: "string", description: "\u6587\u6863\u8DEF\u5F84\uFF08link-doc \u7528\uFF0C\u5982 docs/todo/xxx.md\uFF09" }
|
|
42117
|
+
doc_path: { type: "string", description: "\u6587\u6863\u8DEF\u5F84\uFF08link-doc \u7528\uFF0C\u5982 docs/todo/xxx.md\uFF1Badd-task \u5FC5\u586B\uFF0C\u76F8\u5BF9 workspace \u7684\u8DEF\u5F84\u6216\u7EDD\u5BF9\u8DEF\u5F84\uFF09" }
|
|
42031
42118
|
},
|
|
42032
42119
|
required: ["action"]
|
|
42033
42120
|
},
|
|
@@ -42066,10 +42153,12 @@ registry.register({
|
|
|
42066
42153
|
const event = args2.event?.trim();
|
|
42067
42154
|
const date = args2.date?.trim();
|
|
42068
42155
|
const timeExact = args2.time_exact?.trim();
|
|
42156
|
+
const docPath = args2.doc_path?.trim();
|
|
42069
42157
|
if (!event) return { content: "Error: add-task needs event", isError: true };
|
|
42070
42158
|
if (!date) return { content: "Error: add-task needs date (e.g. 7/5)", isError: true };
|
|
42071
42159
|
if (!timeExact || !timeExact.includes(":")) return { content: "Error: add-task needs time_exact (HH:MM, e.g. 14:00)", isError: true };
|
|
42072
|
-
|
|
42160
|
+
if (!docPath) return { content: "\u274C \u521B\u5EFA\u5931\u8D25\uFF1Aadd-task \u5FC5\u987B\u4F20 doc_path\u3002\n\u6CA1\u6709\u6587\u6863\u652F\u6491\u7684 task \u4E0D\u662F\u5408\u683C\u7684 task\u3002\n\u8BF7\u5148\u5728 docs/todo/ \u4E0B\u521B\u5EFA\u6587\u6863\uFF08\u547D\u540D\uFF1AYYYY-MM-DD_\u4E3B\u9898.md \u6216 \u4EFB\u52A1\u540D.md\uFF09\uFF0C\u7136\u540E\u4F20 doc_path \u53C2\u6570\u3002", isError: true };
|
|
42161
|
+
result = addTask(db, { dateStr: date, timeExact, event, remind: args2.remind, channel: ctx.channel, channelTarget: ctx.channelTarget, docPath });
|
|
42073
42162
|
} else if (action === "reschedule") {
|
|
42074
42163
|
if (args2.id == null) return { content: "Error: reschedule needs id", isError: true };
|
|
42075
42164
|
const date = args2.date?.trim();
|
|
@@ -42110,7 +42199,8 @@ registry.register({
|
|
|
42110
42199
|
return { content: `Error: unknown action '${action}'`, isError: true };
|
|
42111
42200
|
}
|
|
42112
42201
|
db.close();
|
|
42113
|
-
|
|
42202
|
+
const isFailed = result.startsWith("\u274C") || result.includes("Error") || result.includes("\u7528\u6CD5");
|
|
42203
|
+
if (isAddTask && !isFailed) {
|
|
42114
42204
|
const { enqueueNotification: enqueueNotification2, buildCalendarNotification: buildCalendarNotification2 } = await Promise.resolve().then(() => (init_task_manager(), task_manager_exports));
|
|
42115
42205
|
const sessionId = ctx.sessionId || "main";
|
|
42116
42206
|
const channel = ctx.channel;
|
|
@@ -42221,7 +42311,7 @@ registry.register({
|
|
|
42221
42311
|
lines.push(`start: spawned PID ${pid} (background${svcArgs ? ", args=" + svcArgs : ""})`);
|
|
42222
42312
|
if (svc.healthCheck) {
|
|
42223
42313
|
for (let i = 0; i < 6; i++) {
|
|
42224
|
-
await new Promise((
|
|
42314
|
+
await new Promise((resolve12) => setTimeout(resolve12, 5e3));
|
|
42225
42315
|
const after2 = await checkStatus();
|
|
42226
42316
|
if (after2.running) {
|
|
42227
42317
|
lines.push(`health: \u2705 running (after ${(i + 1) * 5}s)`);
|
|
@@ -42231,7 +42321,7 @@ registry.register({
|
|
|
42231
42321
|
const after = await checkStatus();
|
|
42232
42322
|
lines.push(`health: \u274C not responding after 30s \u2014 ${after.detail}`);
|
|
42233
42323
|
} else {
|
|
42234
|
-
await new Promise((
|
|
42324
|
+
await new Promise((resolve12) => setTimeout(resolve12, 3e3));
|
|
42235
42325
|
lines.push(`start: PID ${pid} spawned (no healthCheck, waited 3s)`);
|
|
42236
42326
|
}
|
|
42237
42327
|
} else {
|
|
@@ -42256,7 +42346,7 @@ registry.register({
|
|
|
42256
42346
|
const before = await checkStatus();
|
|
42257
42347
|
if (before.running) {
|
|
42258
42348
|
results.push(await doStop());
|
|
42259
|
-
await new Promise((
|
|
42349
|
+
await new Promise((resolve12) => setTimeout(resolve12, 2e3));
|
|
42260
42350
|
} else {
|
|
42261
42351
|
results.push("stop: already stopped");
|
|
42262
42352
|
}
|
|
@@ -43326,7 +43416,7 @@ var AgentChannelRegistry = class {
|
|
|
43326
43416
|
const pending2 = this.waiters.get(agentName);
|
|
43327
43417
|
if (pending2) {
|
|
43328
43418
|
this.waiters.delete(agentName);
|
|
43329
|
-
for (const
|
|
43419
|
+
for (const resolve12 of pending2) resolve12(channelId);
|
|
43330
43420
|
}
|
|
43331
43421
|
}
|
|
43332
43422
|
/**
|
|
@@ -43336,10 +43426,10 @@ var AgentChannelRegistry = class {
|
|
|
43336
43426
|
waitForChannel(agentName) {
|
|
43337
43427
|
const existing = this.findByAgentName(agentName);
|
|
43338
43428
|
if (existing?.channelId) return Promise.resolve(existing.channelId);
|
|
43339
|
-
return new Promise((
|
|
43429
|
+
return new Promise((resolve12) => {
|
|
43340
43430
|
const list2 = this.waiters.get(agentName);
|
|
43341
|
-
if (list2) list2.push(
|
|
43342
|
-
else this.waiters.set(agentName, [
|
|
43431
|
+
if (list2) list2.push(resolve12);
|
|
43432
|
+
else this.waiters.set(agentName, [resolve12]);
|
|
43343
43433
|
});
|
|
43344
43434
|
}
|
|
43345
43435
|
/** 查找 agent 对应的频道 ID */
|
|
@@ -43871,7 +43961,7 @@ async function startEngine(config2, opts) {
|
|
|
43871
43961
|
if (!fs54.existsSync(dailyDir)) {
|
|
43872
43962
|
fs54.mkdirSync(dailyDir, { recursive: true });
|
|
43873
43963
|
}
|
|
43874
|
-
const sessionsDir = path54.join(
|
|
43964
|
+
const sessionsDir = path54.join(config2.stateDir, "agents", "main", "sessions");
|
|
43875
43965
|
const sessionFile = path54.join(sessionsDir, `${sessionId}.jsonl`);
|
|
43876
43966
|
const recentLines = [];
|
|
43877
43967
|
if (fs54.existsSync(sessionFile)) {
|
|
@@ -45823,7 +45913,7 @@ ${actionsJson}
|
|
|
45823
45913
|
}
|
|
45824
45914
|
}
|
|
45825
45915
|
}
|
|
45826
|
-
const shutdownPromise = new Promise((
|
|
45916
|
+
const shutdownPromise = new Promise((resolve12) => {
|
|
45827
45917
|
const shutdown = (signal) => {
|
|
45828
45918
|
console.log(`[engine] ${signal} received, shutting down...`);
|
|
45829
45919
|
try {
|
|
@@ -45831,7 +45921,7 @@ ${actionsJson}
|
|
|
45831
45921
|
} catch {
|
|
45832
45922
|
}
|
|
45833
45923
|
engine.interrupt();
|
|
45834
|
-
|
|
45924
|
+
resolve12();
|
|
45835
45925
|
};
|
|
45836
45926
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
45837
45927
|
process.on("SIGINT", () => shutdown("SIGINT"));
|