engine7 7.1.6 → 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 +658 -170
- package/dist/engine-startup.mjs +198 -108
- package/dist/main.mjs +198 -108
- package/package.json +10 -3
package/dist/engine-startup.mjs
CHANGED
|
@@ -480,9 +480,9 @@ async function execCommandHook(hook, hookEvent, hookName, jsonInput, signal, hoo
|
|
|
480
480
|
child.stderr.on("data", (chunk) => {
|
|
481
481
|
stderr += chunk;
|
|
482
482
|
});
|
|
483
|
-
const exitCode = await new Promise((
|
|
484
|
-
child.on("close", (code) =>
|
|
485
|
-
child.on("error", () =>
|
|
483
|
+
const exitCode = await new Promise((resolve12) => {
|
|
484
|
+
child.on("close", (code) => resolve12(code ?? 0));
|
|
485
|
+
child.on("error", () => resolve12(1));
|
|
486
486
|
});
|
|
487
487
|
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
488
488
|
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(args, searchPath, signal) {
|
|
7356
|
-
return new Promise((
|
|
7356
|
+
return new Promise((resolve12) => {
|
|
7357
7357
|
const fullArgs = [...args, searchPath];
|
|
7358
7358
|
const child = execFile2("rg", fullArgs, {
|
|
7359
7359
|
maxBuffer: 50 * 1024 * 1024,
|
|
@@ -7362,11 +7362,11 @@ function ripGrep(args, 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 = args.command.trim();
|
|
11496
11496
|
const timeout = args.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
|
});
|
|
@@ -12124,15 +12124,15 @@ async function canStealStaleLock(lockPath2) {
|
|
|
12124
12124
|
return !isProcessLikelyAlive(ownerPid);
|
|
12125
12125
|
}
|
|
12126
12126
|
async function sleep5(ms) {
|
|
12127
|
-
await new Promise((
|
|
12128
|
-
setTimeout(
|
|
12127
|
+
await new Promise((resolve12) => {
|
|
12128
|
+
setTimeout(resolve12, ms);
|
|
12129
12129
|
});
|
|
12130
12130
|
}
|
|
12131
12131
|
async function withInProcessShortTermLock(lockPath2, task) {
|
|
12132
12132
|
const previous = inProcessShortTermLocks.get(lockPath2) ?? Promise.resolve();
|
|
12133
12133
|
let releaseCurrent;
|
|
12134
|
-
const current = new Promise((
|
|
12135
|
-
releaseCurrent =
|
|
12134
|
+
const current = new Promise((resolve12) => {
|
|
12135
|
+
releaseCurrent = resolve12;
|
|
12136
12136
|
});
|
|
12137
12137
|
const queued = previous.catch(() => void 0).then(() => current);
|
|
12138
12138
|
inProcessShortTermLocks.set(lockPath2, queued);
|
|
@@ -23118,7 +23118,7 @@ var init_handler = __esm({
|
|
|
23118
23118
|
this._addToNodeFs(path55, initialAdd, wh, depth + 1);
|
|
23119
23119
|
}
|
|
23120
23120
|
}).on(EV.ERROR, this._boundHandleError);
|
|
23121
|
-
return new Promise((
|
|
23121
|
+
return new Promise((resolve12, reject) => {
|
|
23122
23122
|
if (!stream)
|
|
23123
23123
|
return reject();
|
|
23124
23124
|
stream.once(STR_END, () => {
|
|
@@ -23127,7 +23127,7 @@ var init_handler = __esm({
|
|
|
23127
23127
|
return;
|
|
23128
23128
|
}
|
|
23129
23129
|
const wasThrottled = throttler ? throttler.clear() : false;
|
|
23130
|
-
|
|
23130
|
+
resolve12(void 0);
|
|
23131
23131
|
previous.getChildren().filter((item) => {
|
|
23132
23132
|
return item !== directory && !current.has(item);
|
|
23133
23133
|
}).forEach((item) => {
|
|
@@ -24427,8 +24427,8 @@ function createSessionSyncYield(total) {
|
|
|
24427
24427
|
return async () => {
|
|
24428
24428
|
completed += 1;
|
|
24429
24429
|
if (completed < total && completed % SESSION_SYNC_YIELD_EVERY === 0) {
|
|
24430
|
-
await new Promise((
|
|
24431
|
-
setImmediate(
|
|
24430
|
+
await new Promise((resolve12) => {
|
|
24431
|
+
setImmediate(resolve12);
|
|
24432
24432
|
});
|
|
24433
24433
|
}
|
|
24434
24434
|
};
|
|
@@ -24630,8 +24630,8 @@ var init_manager_sync_ops = __esm({
|
|
|
24630
24630
|
);
|
|
24631
24631
|
rowCount += 1;
|
|
24632
24632
|
if (rowCount % SEED_EMBEDDING_YIELD_EVERY === 0) {
|
|
24633
|
-
await new Promise((
|
|
24634
|
-
setImmediate(
|
|
24633
|
+
await new Promise((resolve12) => {
|
|
24634
|
+
setImmediate(resolve12);
|
|
24635
24635
|
});
|
|
24636
24636
|
}
|
|
24637
24637
|
}
|
|
@@ -25908,7 +25908,7 @@ var init_manager_embedding_ops = __esm({
|
|
|
25908
25908
|
EMBEDDING_RETRY_MAX_DELAY_MS
|
|
25909
25909
|
);
|
|
25910
25910
|
log2.warn(`memory embeddings rate limited; ${action} in ${waitMs}ms`);
|
|
25911
|
-
await new Promise((
|
|
25911
|
+
await new Promise((resolve12) => setTimeout(resolve12, waitMs));
|
|
25912
25912
|
}
|
|
25913
25913
|
resolveEmbeddingTimeout(kind) {
|
|
25914
25914
|
return resolveEmbeddingTimeoutMs({
|
|
@@ -25950,8 +25950,8 @@ var init_manager_embedding_ops = __esm({
|
|
|
25950
25950
|
async withBatchFailureLock(fn) {
|
|
25951
25951
|
let release2;
|
|
25952
25952
|
const wait = this.batchFailureLock;
|
|
25953
|
-
this.batchFailureLock = new Promise((
|
|
25954
|
-
release2 =
|
|
25953
|
+
this.batchFailureLock = new Promise((resolve12) => {
|
|
25954
|
+
release2 = resolve12;
|
|
25955
25955
|
});
|
|
25956
25956
|
await wait;
|
|
25957
25957
|
try {
|
|
@@ -28948,7 +28948,7 @@ var reply_blocklist_exports = {};
|
|
|
28948
28948
|
__export(reply_blocklist_exports, {
|
|
28949
28949
|
isUserBlocked: () => isUserBlocked
|
|
28950
28950
|
});
|
|
28951
|
-
import { readFileSync as readFileSync26, writeFileSync as writeFileSync15, existsSync as
|
|
28951
|
+
import { readFileSync as readFileSync26, writeFileSync as writeFileSync15, existsSync as existsSync24 } from "node:fs";
|
|
28952
28952
|
import { join as join39 } from "node:path";
|
|
28953
28953
|
function ensureLoaded(workspace, configIds) {
|
|
28954
28954
|
if (loaded) return;
|
|
@@ -28959,7 +28959,7 @@ function ensureLoaded(workspace, configIds) {
|
|
|
28959
28959
|
}
|
|
28960
28960
|
const path55 = join39(workspace, ".reply-blocklist.json");
|
|
28961
28961
|
try {
|
|
28962
|
-
if (
|
|
28962
|
+
if (existsSync24(path55)) {
|
|
28963
28963
|
const raw = readFileSync26(path55, "utf-8");
|
|
28964
28964
|
const parsed = JSON.parse(raw);
|
|
28965
28965
|
if (parsed.blockedUserIds) {
|
|
@@ -29699,12 +29699,12 @@ var MAX_DELAY_MS = 32e3;
|
|
|
29699
29699
|
var DEFAULT_TIMEOUT_MS = 6e5;
|
|
29700
29700
|
var READ_TIMEOUT_MS = 6e4;
|
|
29701
29701
|
function sleep(ms, signal) {
|
|
29702
|
-
return new Promise((
|
|
29702
|
+
return new Promise((resolve12, reject) => {
|
|
29703
29703
|
if (signal?.aborted) {
|
|
29704
29704
|
reject(new DOMException("Aborted", "AbortError"));
|
|
29705
29705
|
return;
|
|
29706
29706
|
}
|
|
29707
|
-
const timer = setTimeout(
|
|
29707
|
+
const timer = setTimeout(resolve12, ms);
|
|
29708
29708
|
const onAbort = () => {
|
|
29709
29709
|
clearTimeout(timer);
|
|
29710
29710
|
reject(new DOMException("Aborted", "AbortError"));
|
|
@@ -33815,7 +33815,7 @@ var MAX_TRANSCRIPT_READ_BYTES = 50 * 1024 * 1024;
|
|
|
33815
33815
|
async function readSessionHeader(filePath) {
|
|
33816
33816
|
const stream = fs7.createReadStream(filePath, { encoding: "utf-8" });
|
|
33817
33817
|
const rl = readline.createInterface({ input: stream });
|
|
33818
|
-
return new Promise((
|
|
33818
|
+
return new Promise((resolve12) => {
|
|
33819
33819
|
let resolved = false;
|
|
33820
33820
|
rl.on("line", (line) => {
|
|
33821
33821
|
try {
|
|
@@ -33824,7 +33824,7 @@ async function readSessionHeader(filePath) {
|
|
|
33824
33824
|
resolved = true;
|
|
33825
33825
|
rl.close();
|
|
33826
33826
|
stream.destroy();
|
|
33827
|
-
|
|
33827
|
+
resolve12({
|
|
33828
33828
|
id: obj.id,
|
|
33829
33829
|
timestamp: obj.timestamp,
|
|
33830
33830
|
cwd: obj.cwd,
|
|
@@ -33836,10 +33836,10 @@ async function readSessionHeader(filePath) {
|
|
|
33836
33836
|
}
|
|
33837
33837
|
});
|
|
33838
33838
|
rl.on("close", () => {
|
|
33839
|
-
if (!resolved)
|
|
33839
|
+
if (!resolved) resolve12(null);
|
|
33840
33840
|
});
|
|
33841
33841
|
rl.on("error", () => {
|
|
33842
|
-
if (!resolved)
|
|
33842
|
+
if (!resolved) resolve12(null);
|
|
33843
33843
|
});
|
|
33844
33844
|
});
|
|
33845
33845
|
}
|
|
@@ -34067,9 +34067,9 @@ async function readAllLines(filePath) {
|
|
|
34067
34067
|
const stream = fs7.createReadStream(filePath, { encoding: "utf-8" });
|
|
34068
34068
|
const rl = readline.createInterface({ input: stream });
|
|
34069
34069
|
const lines = [];
|
|
34070
|
-
return new Promise((
|
|
34070
|
+
return new Promise((resolve12, reject) => {
|
|
34071
34071
|
rl.on("line", (line) => lines.push(line));
|
|
34072
|
-
rl.on("close", () =>
|
|
34072
|
+
rl.on("close", () => resolve12(lines));
|
|
34073
34073
|
rl.on("error", (err) => reject(err));
|
|
34074
34074
|
});
|
|
34075
34075
|
}
|
|
@@ -36760,8 +36760,8 @@ function startCliLoop(deps, cliConfig, channelManager, dispatcher) {
|
|
|
36760
36760
|
process.stdout.write("AI> ");
|
|
36761
36761
|
let inToolCall = false;
|
|
36762
36762
|
let resolveDone;
|
|
36763
|
-
const done2 = new Promise((
|
|
36764
|
-
resolveDone =
|
|
36763
|
+
const done2 = new Promise((resolve12) => {
|
|
36764
|
+
resolveDone = resolve12;
|
|
36765
36765
|
});
|
|
36766
36766
|
dispatcher.submitMessage({
|
|
36767
36767
|
text: trimmed,
|
|
@@ -37057,8 +37057,8 @@ ${basePrompt}`;
|
|
|
37057
37057
|
}, timeoutMs);
|
|
37058
37058
|
if (this.dispatcher) {
|
|
37059
37059
|
let resolveDone;
|
|
37060
|
-
const done2 = new Promise((
|
|
37061
|
-
resolveDone =
|
|
37060
|
+
const done2 = new Promise((resolve12) => {
|
|
37061
|
+
resolveDone = resolve12;
|
|
37062
37062
|
});
|
|
37063
37063
|
this.dispatcher.submitMessage({
|
|
37064
37064
|
text: prompt,
|
|
@@ -37433,7 +37433,7 @@ var NudgePlugin = class {
|
|
|
37433
37433
|
}, intervalMs);
|
|
37434
37434
|
this.registerStopHook(sessions);
|
|
37435
37435
|
}
|
|
37436
|
-
/** 注册 Stop hook
|
|
37436
|
+
/** 注册 Stop hook:你停止前用 LLM 判断是否在等外部条件 → 注册 5min notification */
|
|
37437
37437
|
registerStopHook(sessions) {
|
|
37438
37438
|
registerCallbackHook("Stop", {
|
|
37439
37439
|
type: "callback",
|
|
@@ -37447,7 +37447,7 @@ var NudgePlugin = class {
|
|
|
37447
37447
|
console.log(`[stop-hook] skipping voice-chat (channel=${msgChannel})`);
|
|
37448
37448
|
return { outcome: { outcome: "success" } };
|
|
37449
37449
|
}
|
|
37450
|
-
if (!lastMsg
|
|
37450
|
+
if (!lastMsg) {
|
|
37451
37451
|
return { outcome: { outcome: "success" } };
|
|
37452
37452
|
}
|
|
37453
37453
|
let contextStr = "";
|
|
@@ -37463,9 +37463,10 @@ var NudgePlugin = class {
|
|
|
37463
37463
|
console.warn(`[stop-hook] recentMessages error: ${e.message}`);
|
|
37464
37464
|
}
|
|
37465
37465
|
const judgeInput = `${contextStr}
|
|
37466
|
-
|
|
37466
|
+
\u4F60: ${lastMsg.slice(0, 300)}`;
|
|
37467
37467
|
let isWaiting = false;
|
|
37468
37468
|
let waitDesc = "";
|
|
37469
|
+
let pushedDecision = false;
|
|
37469
37470
|
try {
|
|
37470
37471
|
const excludeCases = this.cfg.stopHookExcludeCases || [];
|
|
37471
37472
|
const excludeSection = excludeCases.length > 0 ? [
|
|
@@ -37476,20 +37477,22 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37476
37477
|
const stream = this.provider.streamChat({
|
|
37477
37478
|
model: this.model,
|
|
37478
37479
|
systemPrompt: [
|
|
37479
|
-
"\u4F60\u662F\u4E00\u4E2A\u5224\u65AD\u5668\u3002\u8BFB
|
|
37480
|
+
"\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",
|
|
37480
37481
|
"",
|
|
37481
37482
|
"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",
|
|
37482
37483
|
'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',
|
|
37483
37484
|
"3. \u9047\u5230\u95EE\u9898\u6CA1\u6709\u81EA\u5DF1\u89E3\u51B3\u4E5F\u6CA1\u6709\u6392\u8FDB calendar\uFF0C\u53EA\u662F\u6401\u7F6E\u7740",
|
|
37484
37485
|
"",
|
|
37485
|
-
"\u5173\u952E\u533A\u5206\uFF1A
|
|
37486
|
-
|
|
37487
|
-
|
|
37486
|
+
"\u5173\u952E\u533A\u5206\uFF1A",
|
|
37487
|
+
'- \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',
|
|
37488
|
+
'- \u7B49\u771F\u6B63\u7684\u5916\u90E8\u6761\u4EF6\uFF08\u670D\u52A1\u3001SSH\u3001\u5F02\u6B65\u4EFB\u52A1\uFF09 \u2192 "waiting": true',
|
|
37489
|
+
"- \u4F60\u5DF2\u7ECF\u505A\u4E86\u51B3\u5B9A\u5E76\u6392\u8FDB calendar \u6216\u5DF2\u5F00\u59CB\u6267\u884C \u2192 \u4E24\u4E2A\u90FD false",
|
|
37488
37490
|
excludeSection,
|
|
37489
37491
|
"",
|
|
37490
37492
|
"\u53EA\u56DE\u590D JSON\uFF1A",
|
|
37491
|
-
'- \
|
|
37492
|
-
'- \
|
|
37493
|
+
'- \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"}',
|
|
37494
|
+
'- \u771F\u7B49\u5916\u90E8\u6761\u4EF6\uFF1A{"waiting": true, "desc": "\u7B80\u77ED\u8BF4\u660E"}',
|
|
37495
|
+
'- \u4E0D\u7B26\u5408\uFF1A{"waiting": false, "pushedDecision": false}'
|
|
37493
37496
|
].join("\n"),
|
|
37494
37497
|
messages: [{ role: "user", content: judgeInput }],
|
|
37495
37498
|
maxTokens: 128,
|
|
@@ -37507,11 +37510,37 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37507
37510
|
const parsed = JSON.parse(match[0]);
|
|
37508
37511
|
isWaiting = !!parsed.waiting;
|
|
37509
37512
|
waitDesc = parsed.desc || "";
|
|
37513
|
+
pushedDecision = !!parsed.pushedDecision;
|
|
37510
37514
|
}
|
|
37511
|
-
console.log(`[stop-hook] Judge result: waiting=${isWaiting}, desc="${waitDesc}"`);
|
|
37515
|
+
console.log(`[stop-hook] Judge result: waiting=${isWaiting}, pushedDecision=${pushedDecision}, desc="${waitDesc}"`);
|
|
37512
37516
|
} catch (e) {
|
|
37513
37517
|
console.warn(`[stop-hook] LLM judge error: ${e.message}`);
|
|
37514
37518
|
}
|
|
37519
|
+
if (pushedDecision && waitDesc) {
|
|
37520
|
+
console.log(`[stop-hook] DETECTED pushedDecision! Injecting corrective message to ${sessionId}`);
|
|
37521
|
+
try {
|
|
37522
|
+
const correctiveMsg = [
|
|
37523
|
+
"\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",
|
|
37524
|
+
"",
|
|
37525
|
+
`\u8BCA\u65AD\uFF1A${waitDesc}`,
|
|
37526
|
+
"",
|
|
37527
|
+
"\u660E\u77E5\u9053\u600E\u4E48\u505A\u5BF9\u7684\u4E8B \u2192 \u76F4\u63A5\u505A \u2192 \u6C47\u62A5\u7ED3\u679C\u3002",
|
|
37528
|
+
"\u95EE = \u5361\u4F4F\u3002",
|
|
37529
|
+
"",
|
|
37530
|
+
"\u8BF7\u7ACB\u523B\uFF1A",
|
|
37531
|
+
"1. \u64A4\u56DE\u4F60\u7684\u95EE\u9898\uFF08\u4E0D\u8981\u7B49\u5BF9\u65B9\u56DE\u590D\uFF09",
|
|
37532
|
+
"2. \u81EA\u5DF1\u9009\u6700\u4F18\u65B9\u6848\u76F4\u63A5\u6267\u884C",
|
|
37533
|
+
'3. \u6267\u884C\u5B8C\u6C47\u62A5\u7ED3\u679C\uFF08"\u5DF2\u5904\u7406" / "\u5DF2 commit" / "\u5DF2 archive"\uFF09',
|
|
37534
|
+
"",
|
|
37535
|
+
"\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"
|
|
37536
|
+
].join("\n");
|
|
37537
|
+
if (this.dispatcher) {
|
|
37538
|
+
this.dispatcher.submitMessage(correctiveMsg, sessionId);
|
|
37539
|
+
}
|
|
37540
|
+
} catch (e) {
|
|
37541
|
+
console.warn(`[stop-hook] Failed to inject corrective message: ${e.message}`);
|
|
37542
|
+
}
|
|
37543
|
+
}
|
|
37515
37544
|
if (!isWaiting) {
|
|
37516
37545
|
return { outcome: { outcome: "success" } };
|
|
37517
37546
|
}
|
|
@@ -37530,13 +37559,15 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37530
37559
|
}
|
|
37531
37560
|
}
|
|
37532
37561
|
const wakeAt = new Date(Date.now() + 5 * 6e4).toISOString();
|
|
37562
|
+
const notifId = `wake-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
37533
37563
|
notifs.push({
|
|
37564
|
+
id: notifId,
|
|
37534
37565
|
description: waitDesc || lastMsg.slice(0, 200),
|
|
37535
37566
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
37536
37567
|
wakeAt
|
|
37537
37568
|
});
|
|
37538
37569
|
fs17.writeFileSync(notifPath, JSON.stringify(notifs, null, 2));
|
|
37539
|
-
console.log(`[stop-hook] Registered wake-up at ${wakeAt} (sessionId=${sessionId}): ${waitDesc}`);
|
|
37570
|
+
console.log(`[stop-hook] Registered wake-up ${notifId} at ${wakeAt} (sessionId=${sessionId}): ${waitDesc}`);
|
|
37540
37571
|
} catch (e) {
|
|
37541
37572
|
console.warn(`[stop-hook] Failed to register: ${e.message}`);
|
|
37542
37573
|
}
|
|
@@ -37569,7 +37600,7 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37569
37600
|
return null;
|
|
37570
37601
|
}
|
|
37571
37602
|
}
|
|
37572
|
-
/** 检查 stop-hook-notifications
|
|
37603
|
+
/** 检查 stop-hook-notifications:你停止前注册的等待唤起 */
|
|
37573
37604
|
checkStopHookNotifications() {
|
|
37574
37605
|
const notifPath = path17.join(this.workspace, ".nudge", "stop-hook-notifications.json");
|
|
37575
37606
|
try {
|
|
@@ -37577,26 +37608,56 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37577
37608
|
const notifs = JSON.parse(fs17.readFileSync(notifPath, "utf-8"));
|
|
37578
37609
|
if (notifs.length === 0) return null;
|
|
37579
37610
|
const now = Date.now();
|
|
37580
|
-
const due = notifs.filter((n) => new Date(n.wakeAt).getTime() <= now);
|
|
37611
|
+
const due = notifs.filter((n) => new Date(n.wakeAt).getTime() <= now && !n.notified);
|
|
37581
37612
|
if (due.length === 0) return null;
|
|
37582
37613
|
const latest = due[due.length - 1];
|
|
37583
|
-
console.log(`[nudge] Stop-hook notification triggered: ${latest.description.slice(0, 80)}...`);
|
|
37584
|
-
const
|
|
37585
|
-
|
|
37586
|
-
fs17.writeFileSync(notifPath, JSON.stringify(remaining, null, 2));
|
|
37587
|
-
} else {
|
|
37588
|
-
fs17.unlinkSync(notifPath);
|
|
37589
|
-
}
|
|
37614
|
+
console.log(`[nudge] Stop-hook notification ${latest.id} triggered: ${latest.description.slice(0, 80)}...`);
|
|
37615
|
+
const updated = notifs.map((n) => n.id === latest.id ? { ...n, notified: true } : n);
|
|
37616
|
+
fs17.writeFileSync(notifPath, JSON.stringify(updated, null, 2));
|
|
37590
37617
|
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
|
|
37591
37618
|
|
|
37619
|
+
[\u901A\u77E5ID: ${latest.id}]
|
|
37592
37620
|
\u4E0A\u6B21\u8BF4\uFF1A${latest.description}
|
|
37593
37621
|
|
|
37594
|
-
\u68C0\u67E5\u6761\u4EF6\u662F\u5426\u6EE1\u8DB3\uFF0C\u6EE1\u8DB3\u5C31\u7EE7\u7EED\u5E72\u6D3B\uFF0C\u4E0D\u6EE1\u8DB3\u5C31\
|
|
37622
|
+
\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`);
|
|
37595
37623
|
} catch (e) {
|
|
37596
37624
|
console.warn(`[nudge] checkStopHookNotifications error: ${e.message}`);
|
|
37597
37625
|
return null;
|
|
37598
37626
|
}
|
|
37599
37627
|
}
|
|
37628
|
+
/** 读最近消息,如果发现"<notifId> 过期了"→ 精确清理对应的 wake-up notification */
|
|
37629
|
+
cleanupStaleNotificationsFromMessages(sessions) {
|
|
37630
|
+
try {
|
|
37631
|
+
const recent = recentMessages(sessions, 0.5, 6);
|
|
37632
|
+
const fiveMinAgo = Date.now() - 5 * 60 * 1e3;
|
|
37633
|
+
const recentTexts = recent.filter((r) => new Date(r.timestamp || r.createdAt || Date.now()).getTime() > fiveMinAgo).map((r) => r.text);
|
|
37634
|
+
const notifPath = path17.join(this.workspace, ".nudge", "stop-hook-notifications.json");
|
|
37635
|
+
if (!fs17.existsSync(notifPath)) return;
|
|
37636
|
+
const notifs = JSON.parse(fs17.readFileSync(notifPath, "utf-8"));
|
|
37637
|
+
if (notifs.length === 0) return;
|
|
37638
|
+
const expiredIds = /* @__PURE__ */ new Set();
|
|
37639
|
+
for (const text of recentTexts) {
|
|
37640
|
+
for (const n of notifs) {
|
|
37641
|
+
if (text.includes(`${n.id} \u8FC7\u671F\u4E86`) || text.includes(`${n.id}\u8FC7\u671F\u4E86`)) {
|
|
37642
|
+
expiredIds.add(n.id);
|
|
37643
|
+
}
|
|
37644
|
+
}
|
|
37645
|
+
}
|
|
37646
|
+
if (expiredIds.size === 0) return;
|
|
37647
|
+
const remaining = notifs.filter((n) => !expiredIds.has(n.id));
|
|
37648
|
+
const cleaned = notifs.length - remaining.length;
|
|
37649
|
+
if (cleaned > 0) {
|
|
37650
|
+
if (remaining.length > 0) {
|
|
37651
|
+
fs17.writeFileSync(notifPath, JSON.stringify(remaining, null, 2));
|
|
37652
|
+
} else {
|
|
37653
|
+
fs17.unlinkSync(notifPath);
|
|
37654
|
+
}
|
|
37655
|
+
console.log(`[nudge] Cleaned ${cleaned} stale notification(s) by explicit id: ${[...expiredIds].join(", ")}`);
|
|
37656
|
+
}
|
|
37657
|
+
} catch (e) {
|
|
37658
|
+
console.warn(`[nudge] cleanupStaleNotificationsFromMessages error: ${e.message}`);
|
|
37659
|
+
}
|
|
37660
|
+
}
|
|
37600
37661
|
async tick(sessions, deps) {
|
|
37601
37662
|
if (this.running) {
|
|
37602
37663
|
console.log("[nudge] Previous tick still running, skipping");
|
|
@@ -37622,6 +37683,7 @@ agent: ${lastMsg.slice(0, 300)}`;
|
|
|
37622
37683
|
}
|
|
37623
37684
|
this.running = true;
|
|
37624
37685
|
try {
|
|
37686
|
+
this.cleanupStaleNotificationsFromMessages(sessions);
|
|
37625
37687
|
const stopNotifs = this.checkStopHookNotifications();
|
|
37626
37688
|
if (stopNotifs) {
|
|
37627
37689
|
const route2 = this.getRoute(sessions);
|
|
@@ -39068,6 +39130,8 @@ function formatBeijingTs(d) {
|
|
|
39068
39130
|
}
|
|
39069
39131
|
|
|
39070
39132
|
// src/calendar/commands.ts
|
|
39133
|
+
import { existsSync as existsSync13, statSync as statSync7 } from "node:fs";
|
|
39134
|
+
import { isAbsolute as isAbsolute4, resolve as resolve7 } from "node:path";
|
|
39071
39135
|
var WEEKDAYS2 = ["\u5468\u4E00", "\u5468\u4E8C", "\u5468\u4E09", "\u5468\u56DB", "\u5468\u4E94", "\u5468\u516D", "\u5468\u65E5"];
|
|
39072
39136
|
function fmtEnd(start, durationMin) {
|
|
39073
39137
|
const [hh, mm] = start.split(":").map(Number);
|
|
@@ -39230,7 +39294,29 @@ ${skipped.map((s2) => ` ${s2}`).join("\n")}`;
|
|
|
39230
39294
|
return result;
|
|
39231
39295
|
}
|
|
39232
39296
|
function addTask(db, args) {
|
|
39233
|
-
const { dateStr, timeExact, event } = args;
|
|
39297
|
+
const { dateStr, timeExact, event, docPath } = args;
|
|
39298
|
+
if (!docPath || !docPath.trim()) {
|
|
39299
|
+
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Aadd-task \u5FC5\u987B\u4F20 doc_path\u3002
|
|
39300
|
+
\u6CA1\u6709\u6587\u6863\u652F\u6491\u7684 task \u4E0D\u662F\u5408\u683C\u7684 task\u3002
|
|
39301
|
+
\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`;
|
|
39302
|
+
}
|
|
39303
|
+
try {
|
|
39304
|
+
const absPath = isAbsolute4(docPath) ? docPath : resolve7(process.cwd(), docPath);
|
|
39305
|
+
if (!existsSync13(absPath)) {
|
|
39306
|
+
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728
|
|
39307
|
+
\u8DEF\u5F84: ${docPath}
|
|
39308
|
+
\u89E3\u6790\u540E: ${absPath}
|
|
39309
|
+
\u8BF7\u5148\u521B\u5EFA\u6587\u6863\u518D add-task\u3002`;
|
|
39310
|
+
}
|
|
39311
|
+
const stat8 = statSync7(absPath);
|
|
39312
|
+
if (!stat8.isFile()) {
|
|
39313
|
+
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u4E0D\u662F\u6587\u4EF6\uFF08\u53EF\u80FD\u662F\u76EE\u5F55\uFF09
|
|
39314
|
+
\u8DEF\u5F84: ${docPath}`;
|
|
39315
|
+
}
|
|
39316
|
+
} catch (err) {
|
|
39317
|
+
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u6821\u9A8C\u51FA\u9519\uFF1A${err.message}
|
|
39318
|
+
\u8DEF\u5F84: ${docPath}`;
|
|
39319
|
+
}
|
|
39234
39320
|
let remindMin = 60;
|
|
39235
39321
|
if (args.remind) {
|
|
39236
39322
|
const v2 = args.remind;
|
|
@@ -39244,10 +39330,11 @@ function addTask(db, args) {
|
|
|
39244
39330
|
const prox = checkTaskProximity(taskRows, timeExact);
|
|
39245
39331
|
const remindAt = computeRemindAt(dateStr, timeExact, remindMin);
|
|
39246
39332
|
const r = db.prepare(
|
|
39247
|
-
`INSERT INTO events (type,status,event,date_str,time_exact,remind_before_min,remind_at,reminded,created_at,created_channel,created_channel_target)
|
|
39248
|
-
VALUES ('task','pending'
|
|
39249
|
-
).run(event, dateStr, timeExact, remindMin, remindAt, 0, nowIso(), args.channel || null, args.channelTarget || null);
|
|
39250
|
-
let msg2 = `#${r.lastInsertRowid} \u5DF2\u6DFB\u52A0\u4EFB\u52A1: [${dateStr} ${timeExact}] ${event} (\u63D0\u524D${remindMin}min\u63D0\u9192)
|
|
39333
|
+
`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)
|
|
39334
|
+
VALUES ('task','pending',?,?,?,?,?,?,?,?,?,?)`
|
|
39335
|
+
).run(event, dateStr, timeExact, remindMin, remindAt, 0, nowIso(), args.channel || null, args.channelTarget || null, docPath);
|
|
39336
|
+
let msg2 = `#${r.lastInsertRowid} \u5DF2\u6DFB\u52A0\u4EFB\u52A1: [${dateStr} ${timeExact}] ${event} (\u63D0\u524D${remindMin}min\u63D0\u9192)
|
|
39337
|
+
\u{1F4C4} \u6587\u6863: ${docPath}`;
|
|
39251
39338
|
if (prox) {
|
|
39252
39339
|
msg2 += `
|
|
39253
39340
|
\u26A0\uFE0F \u65F6\u95F4\u63A5\u8FD1\uFF1A\u4E0E #${prox.id}\u300C${prox.event}\u300D(${prox.time}) \u4EC5\u76F8\u5DEE ${prox.diffMin}min`;
|
|
@@ -39581,7 +39668,7 @@ function registerVoiceChatBridge(httpServer, dispatcher, deps, config, sessions,
|
|
|
39581
39668
|
const https = await import("node:https");
|
|
39582
39669
|
const url = new URL(callbackUrl);
|
|
39583
39670
|
const postData = JSON.stringify({ session_id: ctx.inbound.from, text: ctx.response });
|
|
39584
|
-
await new Promise((
|
|
39671
|
+
await new Promise((resolve12, reject) => {
|
|
39585
39672
|
const req = https.request(url, {
|
|
39586
39673
|
method: "POST",
|
|
39587
39674
|
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(postData) },
|
|
@@ -39589,7 +39676,7 @@ function registerVoiceChatBridge(httpServer, dispatcher, deps, config, sessions,
|
|
|
39589
39676
|
}, (res) => {
|
|
39590
39677
|
console.log(`[voice-chat] Reply POST ${callbackUrl}: ${res.statusCode} (${ctx.response.length} chars)`);
|
|
39591
39678
|
res.resume();
|
|
39592
|
-
|
|
39679
|
+
resolve12();
|
|
39593
39680
|
});
|
|
39594
39681
|
req.on("error", reject);
|
|
39595
39682
|
req.write(postData);
|
|
@@ -39878,27 +39965,27 @@ var VoiceChatPlugin = class _VoiceChatPlugin {
|
|
|
39878
39965
|
};
|
|
39879
39966
|
}
|
|
39880
39967
|
async isPortAlive(port) {
|
|
39881
|
-
return new Promise((
|
|
39968
|
+
return new Promise((resolve12) => {
|
|
39882
39969
|
const socket = new net.Socket();
|
|
39883
39970
|
socket.setTimeout(2e3);
|
|
39884
39971
|
socket.on("connect", () => {
|
|
39885
39972
|
socket.destroy();
|
|
39886
|
-
|
|
39973
|
+
resolve12(true);
|
|
39887
39974
|
});
|
|
39888
39975
|
socket.on("timeout", () => {
|
|
39889
39976
|
socket.destroy();
|
|
39890
|
-
|
|
39977
|
+
resolve12(false);
|
|
39891
39978
|
});
|
|
39892
39979
|
socket.on("error", () => {
|
|
39893
39980
|
socket.destroy();
|
|
39894
|
-
|
|
39981
|
+
resolve12(false);
|
|
39895
39982
|
});
|
|
39896
39983
|
socket.connect(port, "127.0.0.1");
|
|
39897
39984
|
});
|
|
39898
39985
|
}
|
|
39899
39986
|
async killProcessOnPort(port) {
|
|
39900
|
-
const run = (cmd) => new Promise((
|
|
39901
|
-
exec(cmd, { timeout: 5e3 }, (err, stdout) =>
|
|
39987
|
+
const run = (cmd) => new Promise((resolve12) => {
|
|
39988
|
+
exec(cmd, { timeout: 5e3 }, (err, stdout) => resolve12(err ? "" : stdout));
|
|
39902
39989
|
});
|
|
39903
39990
|
try {
|
|
39904
39991
|
if (process.platform === "win32") {
|
|
@@ -40387,27 +40474,27 @@ var CogniFoldPlugin = class {
|
|
|
40387
40474
|
throw new Error(`CogniFold not ready after ${timeoutMs}ms at ${url}`);
|
|
40388
40475
|
}
|
|
40389
40476
|
async isPortAlive(port) {
|
|
40390
|
-
return new Promise((
|
|
40477
|
+
return new Promise((resolve12) => {
|
|
40391
40478
|
const socket = new net2.Socket();
|
|
40392
40479
|
socket.setTimeout(2e3);
|
|
40393
40480
|
socket.on("connect", () => {
|
|
40394
40481
|
socket.destroy();
|
|
40395
|
-
|
|
40482
|
+
resolve12(true);
|
|
40396
40483
|
});
|
|
40397
40484
|
socket.on("timeout", () => {
|
|
40398
40485
|
socket.destroy();
|
|
40399
|
-
|
|
40486
|
+
resolve12(false);
|
|
40400
40487
|
});
|
|
40401
40488
|
socket.on("error", () => {
|
|
40402
40489
|
socket.destroy();
|
|
40403
|
-
|
|
40490
|
+
resolve12(false);
|
|
40404
40491
|
});
|
|
40405
40492
|
socket.connect(port, "127.0.0.1");
|
|
40406
40493
|
});
|
|
40407
40494
|
}
|
|
40408
40495
|
async killProcessOnPort(port) {
|
|
40409
|
-
const run = (cmd) => new Promise((
|
|
40410
|
-
exec2(cmd, { timeout: 5e3 }, (err, stdout) =>
|
|
40496
|
+
const run = (cmd) => new Promise((resolve12) => {
|
|
40497
|
+
exec2(cmd, { timeout: 5e3 }, (err, stdout) => resolve12(err ? "" : stdout));
|
|
40411
40498
|
});
|
|
40412
40499
|
try {
|
|
40413
40500
|
if (process.platform === "win32") {
|
|
@@ -41652,7 +41739,7 @@ registry.register({
|
|
|
41652
41739
|
init_registry();
|
|
41653
41740
|
registry.register({
|
|
41654
41741
|
name: "calendar",
|
|
41655
|
-
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.',
|
|
41742
|
+
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.',
|
|
41656
41743
|
schema: {
|
|
41657
41744
|
type: "object",
|
|
41658
41745
|
properties: {
|
|
@@ -41669,7 +41756,7 @@ registry.register({
|
|
|
41669
41756
|
remind: { type: "string", description: "\u63D0\u524D\u63D0\u9192\uFF08add-task \u7528\uFF0C\u5982 30m=30\u5206\u949F, 1h=1\u5C0F\u65F6, \u9ED8\u8BA460m\uFF09" },
|
|
41670
41757
|
id: { type: "number", description: "\u4E8B\u4EF6 ID\uFF08done/archive/reschedule/link-doc/find-doc \u7528\uFF09" },
|
|
41671
41758
|
all: { type: "boolean", description: "\u67E5\u770B\u5168\u90E8\uFF08list \u7528\uFF09" },
|
|
41672
|
-
doc_path: { type: "string", description: "\u6587\u6863\u8DEF\u5F84\uFF08link-doc \u7528\uFF0C\u5982 docs/todo/xxx.md\uFF09" }
|
|
41759
|
+
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" }
|
|
41673
41760
|
},
|
|
41674
41761
|
required: ["action"]
|
|
41675
41762
|
},
|
|
@@ -41708,10 +41795,12 @@ registry.register({
|
|
|
41708
41795
|
const event = args.event?.trim();
|
|
41709
41796
|
const date = args.date?.trim();
|
|
41710
41797
|
const timeExact = args.time_exact?.trim();
|
|
41798
|
+
const docPath = args.doc_path?.trim();
|
|
41711
41799
|
if (!event) return { content: "Error: add-task needs event", isError: true };
|
|
41712
41800
|
if (!date) return { content: "Error: add-task needs date (e.g. 7/5)", isError: true };
|
|
41713
41801
|
if (!timeExact || !timeExact.includes(":")) return { content: "Error: add-task needs time_exact (HH:MM, e.g. 14:00)", isError: true };
|
|
41714
|
-
|
|
41802
|
+
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 };
|
|
41803
|
+
result = addTask(db, { dateStr: date, timeExact, event, remind: args.remind, channel: ctx.channel, channelTarget: ctx.channelTarget, docPath });
|
|
41715
41804
|
} else if (action === "reschedule") {
|
|
41716
41805
|
if (args.id == null) return { content: "Error: reschedule needs id", isError: true };
|
|
41717
41806
|
const date = args.date?.trim();
|
|
@@ -41752,7 +41841,8 @@ registry.register({
|
|
|
41752
41841
|
return { content: `Error: unknown action '${action}'`, isError: true };
|
|
41753
41842
|
}
|
|
41754
41843
|
db.close();
|
|
41755
|
-
|
|
41844
|
+
const isFailed = result.startsWith("\u274C") || result.includes("Error") || result.includes("\u7528\u6CD5");
|
|
41845
|
+
if (isAddTask && !isFailed) {
|
|
41756
41846
|
const { enqueueNotification: enqueueNotification2, buildCalendarNotification: buildCalendarNotification2 } = await Promise.resolve().then(() => (init_task_manager(), task_manager_exports));
|
|
41757
41847
|
const sessionId = ctx.sessionId || "main";
|
|
41758
41848
|
const channel = ctx.channel;
|
|
@@ -41863,7 +41953,7 @@ registry.register({
|
|
|
41863
41953
|
lines.push(`start: spawned PID ${pid} (background${svcArgs ? ", args=" + svcArgs : ""})`);
|
|
41864
41954
|
if (svc.healthCheck) {
|
|
41865
41955
|
for (let i = 0; i < 6; i++) {
|
|
41866
|
-
await new Promise((
|
|
41956
|
+
await new Promise((resolve12) => setTimeout(resolve12, 5e3));
|
|
41867
41957
|
const after2 = await checkStatus();
|
|
41868
41958
|
if (after2.running) {
|
|
41869
41959
|
lines.push(`health: \u2705 running (after ${(i + 1) * 5}s)`);
|
|
@@ -41873,7 +41963,7 @@ registry.register({
|
|
|
41873
41963
|
const after = await checkStatus();
|
|
41874
41964
|
lines.push(`health: \u274C not responding after 30s \u2014 ${after.detail}`);
|
|
41875
41965
|
} else {
|
|
41876
|
-
await new Promise((
|
|
41966
|
+
await new Promise((resolve12) => setTimeout(resolve12, 3e3));
|
|
41877
41967
|
lines.push(`start: PID ${pid} spawned (no healthCheck, waited 3s)`);
|
|
41878
41968
|
}
|
|
41879
41969
|
} else {
|
|
@@ -41898,7 +41988,7 @@ registry.register({
|
|
|
41898
41988
|
const before = await checkStatus();
|
|
41899
41989
|
if (before.running) {
|
|
41900
41990
|
results.push(await doStop());
|
|
41901
|
-
await new Promise((
|
|
41991
|
+
await new Promise((resolve12) => setTimeout(resolve12, 2e3));
|
|
41902
41992
|
} else {
|
|
41903
41993
|
results.push("stop: already stopped");
|
|
41904
41994
|
}
|
|
@@ -43260,7 +43350,7 @@ var AgentChannelRegistry = class {
|
|
|
43260
43350
|
const pending2 = this.waiters.get(agentName);
|
|
43261
43351
|
if (pending2) {
|
|
43262
43352
|
this.waiters.delete(agentName);
|
|
43263
|
-
for (const
|
|
43353
|
+
for (const resolve12 of pending2) resolve12(channelId);
|
|
43264
43354
|
}
|
|
43265
43355
|
}
|
|
43266
43356
|
/**
|
|
@@ -43270,10 +43360,10 @@ var AgentChannelRegistry = class {
|
|
|
43270
43360
|
waitForChannel(agentName) {
|
|
43271
43361
|
const existing = this.findByAgentName(agentName);
|
|
43272
43362
|
if (existing?.channelId) return Promise.resolve(existing.channelId);
|
|
43273
|
-
return new Promise((
|
|
43363
|
+
return new Promise((resolve12) => {
|
|
43274
43364
|
const list2 = this.waiters.get(agentName);
|
|
43275
|
-
if (list2) list2.push(
|
|
43276
|
-
else this.waiters.set(agentName, [
|
|
43365
|
+
if (list2) list2.push(resolve12);
|
|
43366
|
+
else this.waiters.set(agentName, [resolve12]);
|
|
43277
43367
|
});
|
|
43278
43368
|
}
|
|
43279
43369
|
/** 查找 agent 对应的频道 ID */
|
|
@@ -43805,7 +43895,7 @@ async function startEngine(config, opts) {
|
|
|
43805
43895
|
if (!fs54.existsSync(dailyDir)) {
|
|
43806
43896
|
fs54.mkdirSync(dailyDir, { recursive: true });
|
|
43807
43897
|
}
|
|
43808
|
-
const sessionsDir = path54.join(
|
|
43898
|
+
const sessionsDir = path54.join(config.stateDir, "agents", "main", "sessions");
|
|
43809
43899
|
const sessionFile = path54.join(sessionsDir, `${sessionId}.jsonl`);
|
|
43810
43900
|
const recentLines = [];
|
|
43811
43901
|
if (fs54.existsSync(sessionFile)) {
|
|
@@ -45757,7 +45847,7 @@ ${actionsJson}
|
|
|
45757
45847
|
}
|
|
45758
45848
|
}
|
|
45759
45849
|
}
|
|
45760
|
-
const shutdownPromise = new Promise((
|
|
45850
|
+
const shutdownPromise = new Promise((resolve12) => {
|
|
45761
45851
|
const shutdown = (signal) => {
|
|
45762
45852
|
console.log(`[engine] ${signal} received, shutting down...`);
|
|
45763
45853
|
try {
|
|
@@ -45765,7 +45855,7 @@ ${actionsJson}
|
|
|
45765
45855
|
} catch {
|
|
45766
45856
|
}
|
|
45767
45857
|
engine.interrupt();
|
|
45768
|
-
|
|
45858
|
+
resolve12();
|
|
45769
45859
|
};
|
|
45770
45860
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
45771
45861
|
process.on("SIGINT", () => shutdown("SIGINT"));
|