@epoch-agent/core 0.10.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -28
- package/dist/index.d.ts +644 -7
- package/dist/index.js +648 -161
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { existsSync, statSync, readdirSync, readFileSync, mkdirSync, writeFileSy
|
|
|
2
2
|
import { homedir, platform, tmpdir, hostname } from 'os';
|
|
3
3
|
import { join, dirname, resolve, relative, isAbsolute, sep, extname, basename } from 'path';
|
|
4
4
|
import { execFile, execSync, execFileSync, spawn } from 'child_process';
|
|
5
|
-
import { createLogger, dbPath, resolveHomeDir, DEFAULT_MAX_TURNS, PROJECT_DIR_NAME, t, openDatabase, migrate, releaseDatabase,
|
|
5
|
+
import { createLogger, dbPath, resolveHomeDir, DEFAULT_MAX_TURNS, PROJECT_DIR_NAME, t, suggestKey, misspelledKeyIssues, openDatabase, migrate, releaseDatabase, parseLenient, issueDetails, splitWords, unknownKeyIssues, checkpointsDir, pluginsDir, projectHooksPath, projectClaudeSettingsPath, projectClaudeLocalSettingsPath, projectSettingsPath, projectLocalSettingsPath, projectPoliciesDir, trustedImportsPath, budgetStatePath, artifactsDir, UNLIMITED_TURNS, turnLimitOf, configPath, managedSettingsPath, getSecretValues, listStoredSecretNames, maskApiKey, setSectionField, isInWorkspace, workspacesPath, samePath, lastSessionsPath, automationLogsDir, projectComplianceDir, projectSkillsDir, attachmentsDir, trustPath, projectCommandsDir, detectBackend, EXEC_PATH_AS_NODE_ENV, isolate, createStreamDecoder, parseShellCommand, writeArtifact, envPath, checkDangerousCommand, checkObfuscation, countCodePoints, keepHeadAndTail, normalizeForMatch, isReadOnlyCommand, CODE_EXEC_ROOTS, headCodePoints, tailCodePoints } from '@epoch-agent/infra';
|
|
6
6
|
export { IS_WINDOWS, WINDOWS_HIDE_FLAGS, buildBwrapArgs, buildProfile, checkDangerousCommand, checkObfuscation, createLogger, detectBackend, getDefaultShell, getPythonCommand, isInWorkspace, isReadOnlyCommand, isolate, maskApiKey, probeBubblewrap, probeSeatbelt, complianceDir as resolveComplianceDir, policiesDir as resolvePoliciesDir, setLogLevel } from '@epoch-agent/infra';
|
|
7
7
|
import { PROVIDER_TYPES, OPERATION_TYPES as OPERATION_TYPES$1, COMPLIANCE_CATEGORIES, COMPLIANCE_ACTIONS, SEARCH_PROVIDER_TYPES, CURRENCIES, LANGS, PERMISSION_LEVELS, SHELL_KINDS, ToolExposure, MAX_OPTIONS, MIN_OPTIONS, MAX_HEADER_CHARS, MAX_QUESTIONS, SCHEDULE_INTERVAL_MINUTES, isPermissionLevel, SCHEDULE_DRAFT_TOOL, isValidAgentRoleName, DEFAULT_AGENT_ROLE, isValidCommandName, RESERVED_COMMAND_NAMES, parseModelRef, isWirePluginArchiveName, systemNote, formatMoney, totalUsageTokens, NOOP_TELEMETRY, METRIC, contentToText, GEN_AI, isPromptOversize, promptTokens, apiKeyEnvVar, PROVIDER_INFOS, isProviderType, API_KEY_ENV_VARS, KEY_ACTIONS, tableOf, perAction, isKeyAction, parseSequence, RESERVED_CHORDS, chordId, sequenceId, ACTION_CONTEXTS, SEQUENCE_CONTEXTS, assertNeverPart, MAX_ATTACH_FILES, MAX_ATTACH_TOTAL_BYTES, MAX_SESSION_REFS, utf8ByteLength, truncateToBudget, attachSessionSurface, isContextNearlyFull, isOperationType, normalizeApproval, imagePartOmittedSummary, MAX_ATTACH_BYTES, SIMULTANEOUS_CONTEXTS, SESSION_REFERENCE_ERROR_CODES, filePartSummary, sessionPartSummary } from '@epoch-agent/protocol';
|
|
8
8
|
export { API_KEY_ENV_VARS, COMPLIANCE_ACTIONS, COMPLIANCE_CATEGORIES, MAX_ATTACH_BYTES, MAX_ATTACH_FILES, MAX_ATTACH_TOTAL_BYTES, MAX_SESSION_ATTACH_BYTES, MAX_SESSION_REFS, OPERATION_TYPES, PERMISSION_LEVELS, PLAN_OUTCOMES, PROVIDER_INFOS, PROVIDER_TYPES, ToolExposure, apiKeyEnvVar, extractAllMentions, extractMentions, extractSessionMentions, getProviderInfo, isOperationType, isPermissionLevel, isPlanOutcome, isProviderType, normalizeApproval } from '@epoch-agent/protocol';
|
|
@@ -264,7 +264,7 @@ function createLaunchdBackend(opts = {}) {
|
|
|
264
264
|
mkdirSync(input.logDir, { recursive: true });
|
|
265
265
|
writeFileSync(path, renderPlist(label, input), "utf-8");
|
|
266
266
|
} catch (err) {
|
|
267
|
-
return { ok: false, detail: `plist-write-failed: ${
|
|
267
|
+
return { ok: false, detail: `plist-write-failed: ${describe8(err)}` };
|
|
268
268
|
}
|
|
269
269
|
await run("launchctl", ["bootout", `${guiDomain()}/${label}`]);
|
|
270
270
|
const toggle = await backend.setEnabled(label, input.enabled);
|
|
@@ -280,7 +280,7 @@ function createLaunchdBackend(opts = {}) {
|
|
|
280
280
|
try {
|
|
281
281
|
rmSync(plistPath(label), { force: true });
|
|
282
282
|
} catch (err) {
|
|
283
|
-
return { ok: false, detail: `plist-remove-failed: ${
|
|
283
|
+
return { ok: false, detail: `plist-remove-failed: ${describe8(err)}` };
|
|
284
284
|
}
|
|
285
285
|
return { ok: true };
|
|
286
286
|
},
|
|
@@ -435,7 +435,7 @@ function detailOf2(what, res) {
|
|
|
435
435
|
const msg = (res.stderr || res.stdout).trim();
|
|
436
436
|
return `${what} exit ${res.code}${msg ? `: ${msg}` : ""}`;
|
|
437
437
|
}
|
|
438
|
-
function
|
|
438
|
+
function describe8(err) {
|
|
439
439
|
return err instanceof Error ? err.message : String(err);
|
|
440
440
|
}
|
|
441
441
|
var LAUNCHD_LABEL_PREFIX;
|
|
@@ -475,10 +475,10 @@ function intervalSlots(everyMinutes) {
|
|
|
475
475
|
var runCommand2;
|
|
476
476
|
var init_backend = __esm({
|
|
477
477
|
"src/schedule/os/backend.ts"() {
|
|
478
|
-
runCommand2 = (file, args) => new Promise((
|
|
478
|
+
runCommand2 = (file, args) => new Promise((resolve16) => {
|
|
479
479
|
execFile(file, [...args], { encoding: "buffer", windowsHide: true }, (err, stdout, stderr) => {
|
|
480
480
|
const code = err && typeof err.code === "number" ? err.code ?? 1 : err ? 1 : 0;
|
|
481
|
-
|
|
481
|
+
resolve16({ code, stdout: decodeOutput(stdout), stderr: decodeOutput(stderr) });
|
|
482
482
|
});
|
|
483
483
|
});
|
|
484
484
|
}
|
|
@@ -629,7 +629,7 @@ var ToolRegistry = class {
|
|
|
629
629
|
this.addTool(tool, source);
|
|
630
630
|
}
|
|
631
631
|
registerTools(tools, source = "builtin") {
|
|
632
|
-
for (const
|
|
632
|
+
for (const t81 of tools) this.addTool(t81, source);
|
|
633
633
|
}
|
|
634
634
|
addTool(tool, source) {
|
|
635
635
|
const existing = this.tools.get(tool.name);
|
|
@@ -678,14 +678,14 @@ var ToolRegistry = class {
|
|
|
678
678
|
return isCodeModeDeferred(tool) ? ToolExposure.Deferred : declared;
|
|
679
679
|
}
|
|
680
680
|
exposed() {
|
|
681
|
-
return this.list().filter((
|
|
681
|
+
return this.list().filter((t81) => this.exposureOf(t81) === ToolExposure.Direct);
|
|
682
682
|
}
|
|
683
683
|
byExposure(exposure) {
|
|
684
|
-
return this.list().filter((
|
|
684
|
+
return this.list().filter((t81) => this.exposureOf(t81) === exposure);
|
|
685
685
|
}
|
|
686
686
|
codeModeDeclared() {
|
|
687
687
|
if (!this.codeMode) return [];
|
|
688
|
-
return this.list().filter((
|
|
688
|
+
return this.list().filter((t81) => isCodeModeDeferred(t81));
|
|
689
689
|
}
|
|
690
690
|
sourceOf(name) {
|
|
691
691
|
return this.tools.get(name)?.source;
|
|
@@ -734,7 +734,7 @@ var ToolRegistry = class {
|
|
|
734
734
|
function staticToolProvider(tools) {
|
|
735
735
|
return {
|
|
736
736
|
list: () => tools,
|
|
737
|
-
get: (name) => tools.find((
|
|
737
|
+
get: (name) => tools.find((t81) => t81.name === name)
|
|
738
738
|
};
|
|
739
739
|
}
|
|
740
740
|
var log = createLogger("tokenizer");
|
|
@@ -1146,7 +1146,7 @@ var DelegateManager = class {
|
|
|
1146
1146
|
}
|
|
1147
1147
|
normalizeTasks(args) {
|
|
1148
1148
|
if (args.tasks && args.tasks.length > 0) {
|
|
1149
|
-
return args.role ? args.tasks.map((
|
|
1149
|
+
return args.role ? args.tasks.map((t81) => ({ ...t81, role: t81.role ?? args.role })) : args.tasks;
|
|
1150
1150
|
}
|
|
1151
1151
|
if (args.goal) return [{ goal: args.goal, ...args.role ? { role: args.role } : {} }];
|
|
1152
1152
|
return [];
|
|
@@ -1156,7 +1156,7 @@ var DelegateManager = class {
|
|
|
1156
1156
|
for (let i = 0; i < tasks.length; i += maxConcurrent) {
|
|
1157
1157
|
const batch = tasks.slice(i, i + maxConcurrent);
|
|
1158
1158
|
const batchResults = await Promise.allSettled(
|
|
1159
|
-
batch.map((
|
|
1159
|
+
batch.map((t81) => this.runSingleTask(t81, parentSessionId))
|
|
1160
1160
|
);
|
|
1161
1161
|
for (const r of batchResults) {
|
|
1162
1162
|
if (r.status === "fulfilled") {
|
|
@@ -1297,21 +1297,21 @@ function createDelegateTool(runner, config, roles) {
|
|
|
1297
1297
|
operation: "command",
|
|
1298
1298
|
describeTarget: (args) => {
|
|
1299
1299
|
const tasks = Array.isArray(args["tasks"]) ? args["tasks"] : [];
|
|
1300
|
-
const goals = tasks.map((
|
|
1300
|
+
const goals = tasks.map((t81) => String(t81["goal"] ?? ""));
|
|
1301
1301
|
const single = typeof args["goal"] === "string" ? args["goal"] : "";
|
|
1302
1302
|
return [...goals, single].filter(Boolean).join(" | ");
|
|
1303
1303
|
},
|
|
1304
1304
|
async execute(args, ctx) {
|
|
1305
1305
|
const start = Date.now();
|
|
1306
1306
|
const rawTasks = Array.isArray(args["tasks"]) ? args["tasks"] : void 0;
|
|
1307
|
-
const tasks = rawTasks?.map((
|
|
1308
|
-
const o =
|
|
1307
|
+
const tasks = rawTasks?.map((t81) => {
|
|
1308
|
+
const o = t81;
|
|
1309
1309
|
return {
|
|
1310
1310
|
goal: String(o["goal"] ?? "").trim(),
|
|
1311
1311
|
context: String(o["context"] ?? ""),
|
|
1312
1312
|
...typeof o["role"] === "string" && o["role"].trim() ? { role: o["role"].trim() } : {}
|
|
1313
1313
|
};
|
|
1314
|
-
}).filter((
|
|
1314
|
+
}).filter((t81) => t81.goal.length > 0);
|
|
1315
1315
|
const goal = typeof args["goal"] === "string" ? args["goal"].trim() : "";
|
|
1316
1316
|
const topRole = typeof args["role"] === "string" ? args["role"].trim() : "";
|
|
1317
1317
|
if ((!tasks || tasks.length === 0) && !goal) {
|
|
@@ -1327,7 +1327,7 @@ function createDelegateTool(runner, config, roles) {
|
|
|
1327
1327
|
};
|
|
1328
1328
|
}
|
|
1329
1329
|
const known = listRoles();
|
|
1330
|
-
const requested = [...(tasks ?? []).map((
|
|
1330
|
+
const requested = [...(tasks ?? []).map((t81) => t81.role), topRole].filter(
|
|
1331
1331
|
(r) => Boolean(r)
|
|
1332
1332
|
);
|
|
1333
1333
|
const unknown = [...new Set(requested)].filter((r) => !known.some((k) => k.name === r));
|
|
@@ -1500,8 +1500,8 @@ function createGoalTool(deps) {
|
|
|
1500
1500
|
}
|
|
1501
1501
|
var VALID_TARGETS = ["memory", "user"];
|
|
1502
1502
|
var VALID_ACTIONS = ["add", "replace", "remove", "search", "read", "budget"];
|
|
1503
|
-
function isValidTarget(
|
|
1504
|
-
return typeof
|
|
1503
|
+
function isValidTarget(t81) {
|
|
1504
|
+
return typeof t81 === "string" && VALID_TARGETS.includes(t81);
|
|
1505
1505
|
}
|
|
1506
1506
|
function isValidAction(a) {
|
|
1507
1507
|
return VALID_ACTIONS.includes(a);
|
|
@@ -1773,7 +1773,7 @@ async function runCode(input) {
|
|
|
1773
1773
|
let toolCalls = 0;
|
|
1774
1774
|
let capped2 = false;
|
|
1775
1775
|
let ending = null;
|
|
1776
|
-
return await new Promise((
|
|
1776
|
+
return await new Promise((resolve16) => {
|
|
1777
1777
|
let settled = false;
|
|
1778
1778
|
const finish = () => {
|
|
1779
1779
|
if (settled) return;
|
|
@@ -1782,7 +1782,7 @@ async function runCode(input) {
|
|
|
1782
1782
|
clearInterval(abortWatch);
|
|
1783
1783
|
void worker.terminate().catch(() => {
|
|
1784
1784
|
}).then(() => Promise.race([drained, delay(STREAM_DRAIN_MS)])).then(() => {
|
|
1785
|
-
|
|
1785
|
+
resolve16(toOutcome(ending, { printed, toolCalls, capped: capped2, limits}));
|
|
1786
1786
|
});
|
|
1787
1787
|
};
|
|
1788
1788
|
const timer = setTimeout(() => {
|
|
@@ -1853,14 +1853,14 @@ async function runCode(input) {
|
|
|
1853
1853
|
var ABORT_POLL_MS = 100;
|
|
1854
1854
|
var STREAM_DRAIN_MS = 500;
|
|
1855
1855
|
function streamEnd(stream) {
|
|
1856
|
-
return new Promise((
|
|
1857
|
-
stream.once("end", () =>
|
|
1858
|
-
stream.once("close", () =>
|
|
1856
|
+
return new Promise((resolve16) => {
|
|
1857
|
+
stream.once("end", () => resolve16());
|
|
1858
|
+
stream.once("close", () => resolve16());
|
|
1859
1859
|
});
|
|
1860
1860
|
}
|
|
1861
1861
|
function delay(ms) {
|
|
1862
|
-
return new Promise((
|
|
1863
|
-
setTimeout(
|
|
1862
|
+
return new Promise((resolve16) => {
|
|
1863
|
+
setTimeout(resolve16, ms).unref();
|
|
1864
1864
|
});
|
|
1865
1865
|
}
|
|
1866
1866
|
function timeoutMessage(timeoutMs, toolCalls) {
|
|
@@ -4205,6 +4205,7 @@ var SkillFrontmatterSchema = z.object({
|
|
|
4205
4205
|
tags: looseStringList.optional().catch(void 0)
|
|
4206
4206
|
});
|
|
4207
4207
|
var FRONTMATTER_KEYS = Object.keys(SkillFrontmatterSchema.shape);
|
|
4208
|
+
var METADATA_KEYS = ["tags"];
|
|
4208
4209
|
function parseSkillFrontmatter(raw, label) {
|
|
4209
4210
|
const parsed = parseFrontmatter(raw);
|
|
4210
4211
|
if ("error" in parsed) {
|
|
@@ -4232,7 +4233,13 @@ function parseSkillFrontmatter(raw, label) {
|
|
|
4232
4233
|
const raw_ = isRecord3(data) ? data : {};
|
|
4233
4234
|
for (const key of Object.keys(raw_)) {
|
|
4234
4235
|
if (!FRONTMATTER_KEYS.includes(key)) {
|
|
4235
|
-
|
|
4236
|
+
const suggest = suggestKey(key, FRONTMATTER_KEYS);
|
|
4237
|
+
if (suggest !== void 0) {
|
|
4238
|
+
issues.push({
|
|
4239
|
+
path: `${label}.${key}`,
|
|
4240
|
+
message: t("infra_misc.schema_misspelled_key", { suggest })
|
|
4241
|
+
});
|
|
4242
|
+
}
|
|
4236
4243
|
continue;
|
|
4237
4244
|
}
|
|
4238
4245
|
if (raw_[key] !== void 0 && result.data[key] === void 0) {
|
|
@@ -4248,6 +4255,7 @@ function parseSkillFrontmatter(raw, label) {
|
|
|
4248
4255
|
});
|
|
4249
4256
|
}
|
|
4250
4257
|
}
|
|
4258
|
+
issues.push(...misspelledKeyIssues(METADATA_KEYS, raw_.metadata, `${label}.metadata`));
|
|
4251
4259
|
const fm = {};
|
|
4252
4260
|
if (result.data.name !== void 0) fm.name = result.data.name;
|
|
4253
4261
|
if (result.data.description !== void 0) fm.description = result.data.description;
|
|
@@ -4499,7 +4507,7 @@ function available(tools) {
|
|
|
4499
4507
|
if (tools.length === 0) {
|
|
4500
4508
|
return "No deferred tools in this session \u2014 every tool is already in your tool list.";
|
|
4501
4509
|
}
|
|
4502
|
-
const names = tools.map((
|
|
4510
|
+
const names = tools.map((t81) => t81.name).sort();
|
|
4503
4511
|
const shown = names.slice(0, MAX_LISTED);
|
|
4504
4512
|
const rest = names.length - shown.length;
|
|
4505
4513
|
return `Searchable tools: ${shown.join(", ")}${rest > 0 ? ` (\u2026and ${rest} more)` : ""}.`;
|
|
@@ -4619,15 +4627,15 @@ var TrackerDB = class {
|
|
|
4619
4627
|
);
|
|
4620
4628
|
this.db.transaction(() => {
|
|
4621
4629
|
this.db.prepare("DELETE FROM todos WHERE session_id = ?").run(sessionId);
|
|
4622
|
-
for (const
|
|
4630
|
+
for (const t81 of todos) {
|
|
4623
4631
|
insertStmt.run({
|
|
4624
|
-
id:
|
|
4632
|
+
id: t81.id,
|
|
4625
4633
|
session_id: sessionId,
|
|
4626
|
-
content:
|
|
4627
|
-
status:
|
|
4628
|
-
reason:
|
|
4629
|
-
created_at:
|
|
4630
|
-
updated_at:
|
|
4634
|
+
content: t81.content,
|
|
4635
|
+
status: t81.status,
|
|
4636
|
+
reason: t81.reason || null,
|
|
4637
|
+
created_at: t81.created_at,
|
|
4638
|
+
updated_at: t81.updated_at
|
|
4631
4639
|
});
|
|
4632
4640
|
}
|
|
4633
4641
|
})();
|
|
@@ -4649,9 +4657,9 @@ function formatTodoList(todos, pendingCount) {
|
|
|
4649
4657
|
cancelled: "\u5DF2\u53D6\u6D88"
|
|
4650
4658
|
};
|
|
4651
4659
|
lines.push(`[todo] \u72B6\u6001\u6C47\u603B: ${pendingCount} \u4E2A\u5F85\u5B8C\u6210`);
|
|
4652
|
-
for (const
|
|
4653
|
-
const label = statusLabel[
|
|
4654
|
-
lines.push(`- [${label}] ${
|
|
4660
|
+
for (const t81 of todos) {
|
|
4661
|
+
const label = statusLabel[t81.status] || t81.status;
|
|
4662
|
+
lines.push(`- [${label}] ${t81.content}${t81.reason ? ` \u2014\u2014 ${t81.reason}` : ""}`);
|
|
4655
4663
|
}
|
|
4656
4664
|
return lines.join("\n");
|
|
4657
4665
|
}
|
|
@@ -4725,14 +4733,14 @@ function createTodoTool(db) {
|
|
|
4725
4733
|
};
|
|
4726
4734
|
}
|
|
4727
4735
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
4728
|
-
const existing = new Map(db.listBySession(ctx.sessionId).map((
|
|
4729
|
-
const todos = rawTodos.map((
|
|
4730
|
-
const prev =
|
|
4731
|
-
const status = isValidStatus(
|
|
4732
|
-
const reason9 = normalizeReason(status,
|
|
4736
|
+
const existing = new Map(db.listBySession(ctx.sessionId).map((t81) => [t81.id, t81]));
|
|
4737
|
+
const todos = rawTodos.map((t81) => {
|
|
4738
|
+
const prev = t81.id ? existing.get(t81.id) : void 0;
|
|
4739
|
+
const status = isValidStatus(t81.status) ? t81.status : "pending";
|
|
4740
|
+
const reason9 = normalizeReason(status, t81.reason);
|
|
4733
4741
|
return {
|
|
4734
|
-
id:
|
|
4735
|
-
content: String(
|
|
4742
|
+
id: t81.id || generateShortId(),
|
|
4743
|
+
content: String(t81.content || "").slice(0, 500),
|
|
4736
4744
|
status,
|
|
4737
4745
|
...reason9 ? { reason: reason9 } : {},
|
|
4738
4746
|
created_at: prev?.created_at || now,
|
|
@@ -4740,7 +4748,7 @@ function createTodoTool(db) {
|
|
|
4740
4748
|
};
|
|
4741
4749
|
});
|
|
4742
4750
|
db.replaceAll(ctx.sessionId, todos);
|
|
4743
|
-
const pendingCount = todos.filter((
|
|
4751
|
+
const pendingCount = todos.filter((t81) => isOpenTodo(t81.status)).length;
|
|
4744
4752
|
return {
|
|
4745
4753
|
success: true,
|
|
4746
4754
|
output: formatTodoList(todos, pendingCount),
|
|
@@ -4889,7 +4897,7 @@ function parseRoleDefinition(raw, file, source) {
|
|
|
4889
4897
|
};
|
|
4890
4898
|
}
|
|
4891
4899
|
const parsed = split.data;
|
|
4892
|
-
const issues =
|
|
4900
|
+
const issues = misspelledKeyIssues(FRONTMATTER_KEYS2, parsed, file);
|
|
4893
4901
|
const outcome = parseLenient(FrontmatterSchema.optional(), parsed, void 0);
|
|
4894
4902
|
if (!outcome.value) {
|
|
4895
4903
|
issues.push(
|
|
@@ -5075,7 +5083,7 @@ function intersectNames(base, incoming) {
|
|
|
5075
5083
|
if (!base) return incoming ? [...incoming] : void 0;
|
|
5076
5084
|
if (!incoming) return [...base];
|
|
5077
5085
|
const baseSet = new Set(base);
|
|
5078
|
-
return incoming.filter((
|
|
5086
|
+
return incoming.filter((t81) => baseSet.has(t81));
|
|
5079
5087
|
}
|
|
5080
5088
|
function findRole(roles, name) {
|
|
5081
5089
|
return roles.find((r) => r.name === name);
|
|
@@ -5152,6 +5160,64 @@ function driftOf(role, name, input) {
|
|
|
5152
5160
|
function describe(err) {
|
|
5153
5161
|
return err instanceof Error ? err.message : String(err);
|
|
5154
5162
|
}
|
|
5163
|
+
function removeRoleFile(name, opts) {
|
|
5164
|
+
const wanted = name.trim();
|
|
5165
|
+
const hits = matchingFiles(opts.dir, wanted);
|
|
5166
|
+
if (hits.length > 1) {
|
|
5167
|
+
return {
|
|
5168
|
+
ok: false,
|
|
5169
|
+
reason: "ambiguous",
|
|
5170
|
+
detail: t(
|
|
5171
|
+
"role_write.ambiguous_files",
|
|
5172
|
+
{
|
|
5173
|
+
name: wanted,
|
|
5174
|
+
paths: hits.join(t("role_write.path_sep", void 0, opts.lang))
|
|
5175
|
+
},
|
|
5176
|
+
opts.lang
|
|
5177
|
+
)
|
|
5178
|
+
};
|
|
5179
|
+
}
|
|
5180
|
+
const [path] = hits;
|
|
5181
|
+
if (path === void 0) {
|
|
5182
|
+
return {
|
|
5183
|
+
ok: false,
|
|
5184
|
+
reason: "not-found",
|
|
5185
|
+
detail: t("role_write.no_such_file", { name: wanted }, opts.lang)
|
|
5186
|
+
};
|
|
5187
|
+
}
|
|
5188
|
+
try {
|
|
5189
|
+
rmSync(path);
|
|
5190
|
+
} catch (err) {
|
|
5191
|
+
return { ok: false, reason: "failed", detail: describe2(err, path, opts.lang) };
|
|
5192
|
+
}
|
|
5193
|
+
return { ok: true, path };
|
|
5194
|
+
}
|
|
5195
|
+
function matchingFiles(dir, name) {
|
|
5196
|
+
if (!existsSync(dir)) return [];
|
|
5197
|
+
let files;
|
|
5198
|
+
try {
|
|
5199
|
+
files = readdirSync(dir).filter((f) => f.endsWith(".md")).sort();
|
|
5200
|
+
} catch {
|
|
5201
|
+
return [];
|
|
5202
|
+
}
|
|
5203
|
+
const hits = [];
|
|
5204
|
+
for (const file of files) {
|
|
5205
|
+
const path = join(dir, file);
|
|
5206
|
+
let raw;
|
|
5207
|
+
try {
|
|
5208
|
+
raw = readFileSync(path, "utf-8");
|
|
5209
|
+
} catch {
|
|
5210
|
+
continue;
|
|
5211
|
+
}
|
|
5212
|
+
const parsed = parseRoleDefinition(raw, file, "user");
|
|
5213
|
+
if (parsed.role?.name === name) hits.push(path);
|
|
5214
|
+
}
|
|
5215
|
+
return hits;
|
|
5216
|
+
}
|
|
5217
|
+
function describe2(err, path, lang) {
|
|
5218
|
+
const reason9 = err instanceof Error ? err.message : String(err);
|
|
5219
|
+
return t("role_write.remove_failed", { path, reason: reason9 }, lang);
|
|
5220
|
+
}
|
|
5155
5221
|
// src/agent-role/scope.ts
|
|
5156
5222
|
function roleScopedProvider(base, role, blocked) {
|
|
5157
5223
|
const blockedSet = new Set(blocked);
|
|
@@ -5161,7 +5227,7 @@ function roleScopedProvider(base, role, blocked) {
|
|
|
5161
5227
|
return allow ? allow.has(name) : true;
|
|
5162
5228
|
};
|
|
5163
5229
|
return {
|
|
5164
|
-
list: () => base.list().filter((
|
|
5230
|
+
list: () => base.list().filter((t81) => permitted(t81.name)),
|
|
5165
5231
|
get: (name) => permitted(name) ? base.get(name) : void 0
|
|
5166
5232
|
};
|
|
5167
5233
|
}
|
|
@@ -5188,7 +5254,7 @@ function createRoleScope(base, sessionRole, blocked) {
|
|
|
5188
5254
|
}
|
|
5189
5255
|
function unknownRoleTools(base, role, blocked) {
|
|
5190
5256
|
if (!role?.tools) return [];
|
|
5191
|
-
const available2 = new Set(base.list().map((
|
|
5257
|
+
const available2 = new Set(base.list().map((t81) => t81.name));
|
|
5192
5258
|
const blockedSet = new Set(blocked);
|
|
5193
5259
|
return role.tools.filter((name) => !available2.has(name) && !blockedSet.has(name));
|
|
5194
5260
|
}
|
|
@@ -5308,7 +5374,7 @@ function loadCommandFile(file, source, prefix) {
|
|
|
5308
5374
|
]
|
|
5309
5375
|
};
|
|
5310
5376
|
}
|
|
5311
|
-
const issues =
|
|
5377
|
+
const issues = misspelledKeyIssues(FRONTMATTER_KEYS3, parsed.data, at);
|
|
5312
5378
|
const checked = parseLenient(CommandFrontmatterSchema.optional(), parsed.data, void 0);
|
|
5313
5379
|
if (!checked.value) {
|
|
5314
5380
|
issues.push(
|
|
@@ -5524,7 +5590,7 @@ function createToolScope(base) {
|
|
|
5524
5590
|
const permitted = (name) => allow ? allow.has(name) : true;
|
|
5525
5591
|
return {
|
|
5526
5592
|
provider: {
|
|
5527
|
-
list: () => base.list().filter((
|
|
5593
|
+
list: () => base.list().filter((t81) => permitted(t81.name)),
|
|
5528
5594
|
get: (name) => permitted(name) ? base.get(name) : void 0
|
|
5529
5595
|
},
|
|
5530
5596
|
enter: (next) => {
|
|
@@ -5694,7 +5760,7 @@ function scanHooks(dir, issues) {
|
|
|
5694
5760
|
return [...parsed.entries].map(([type, list]) => ({
|
|
5695
5761
|
type,
|
|
5696
5762
|
count: list.reduce((sum, entry) => sum + entry.hooks.length, 0)
|
|
5697
|
-
})).filter((
|
|
5763
|
+
})).filter((t81) => t81.count > 0).sort((a, b) => a.type.localeCompare(b.type));
|
|
5698
5764
|
}
|
|
5699
5765
|
function scanMcp(dir, plugin, issues) {
|
|
5700
5766
|
const path = join(dir, PLUGIN_LAYOUT.mcp);
|
|
@@ -5781,6 +5847,7 @@ var PluginAuthorSchema = z.object({
|
|
|
5781
5847
|
email: z.string().min(1).optional(),
|
|
5782
5848
|
url: z.string().min(1).optional()
|
|
5783
5849
|
});
|
|
5850
|
+
var PLUGIN_VISIBILITY = ["private", "public"];
|
|
5784
5851
|
var ManifestSchema = z.object({
|
|
5785
5852
|
name: z.string().min(1),
|
|
5786
5853
|
version: z.string().min(1),
|
|
@@ -5788,9 +5855,14 @@ var ManifestSchema = z.object({
|
|
|
5788
5855
|
author: PluginAuthorSchema.optional(),
|
|
5789
5856
|
epochVersion: z.string().min(1).optional(),
|
|
5790
5857
|
homepage: z.string().min(1).optional(),
|
|
5791
|
-
keywords: z.array(z.string().min(1)).optional()
|
|
5858
|
+
keywords: z.array(z.string().min(1)).optional(),
|
|
5859
|
+
displayName: z.string().min(1).optional(),
|
|
5860
|
+
category: z.string().min(1).optional(),
|
|
5861
|
+
icon: z.string().min(1).optional(),
|
|
5862
|
+
changelog: z.string().min(1).optional(),
|
|
5863
|
+
visibility: z.enum(PLUGIN_VISIBILITY).optional().catch(void 0)
|
|
5792
5864
|
});
|
|
5793
|
-
var
|
|
5865
|
+
var PLUGIN_MANIFEST_KEYS = Object.keys(ManifestSchema.shape);
|
|
5794
5866
|
function readPluginManifest(dir) {
|
|
5795
5867
|
const path = join(dir, PLUGIN_MANIFEST_FILE);
|
|
5796
5868
|
let raw;
|
|
@@ -5815,7 +5887,17 @@ function readPluginManifest(dir) {
|
|
|
5815
5887
|
issues: [{ path, message: t("plugin_manifest.bad_json", { reason: firstLine2(err) }) }]
|
|
5816
5888
|
};
|
|
5817
5889
|
}
|
|
5818
|
-
const issues = unknownKeyIssues(
|
|
5890
|
+
const issues = unknownKeyIssues(PLUGIN_MANIFEST_KEYS, parsed, PLUGIN_MANIFEST_FILE);
|
|
5891
|
+
const rawVisibility = parsed?.visibility;
|
|
5892
|
+
if (rawVisibility !== void 0 && !PLUGIN_VISIBILITY.includes(rawVisibility)) {
|
|
5893
|
+
issues.push({
|
|
5894
|
+
path: `${path}.visibility`,
|
|
5895
|
+
message: t("plugin_manifest.bad_visibility", {
|
|
5896
|
+
raw: String(rawVisibility),
|
|
5897
|
+
allowed: PLUGIN_VISIBILITY.join(" / ")
|
|
5898
|
+
})
|
|
5899
|
+
});
|
|
5900
|
+
}
|
|
5819
5901
|
const checked = parseLenient(ManifestSchema.optional(), parsed, void 0);
|
|
5820
5902
|
if (!checked.value) {
|
|
5821
5903
|
issues.push(
|
|
@@ -6095,7 +6177,7 @@ var PluginStore = class {
|
|
|
6095
6177
|
}
|
|
6096
6178
|
};
|
|
6097
6179
|
function sleep(ms) {
|
|
6098
|
-
return new Promise((
|
|
6180
|
+
return new Promise((resolve16) => setTimeout(resolve16, ms));
|
|
6099
6181
|
}
|
|
6100
6182
|
// src/plugin/loader.ts
|
|
6101
6183
|
var MODULE = "Plugin";
|
|
@@ -6298,7 +6380,7 @@ function runCommand(file, args, opts = {}) {
|
|
|
6298
6380
|
resolvePromise({ ok: true, stdout: out, stderr: errOut });
|
|
6299
6381
|
return;
|
|
6300
6382
|
}
|
|
6301
|
-
const detail =
|
|
6383
|
+
const detail = describe3(file, err, errOut);
|
|
6302
6384
|
resolvePromise({
|
|
6303
6385
|
ok: false,
|
|
6304
6386
|
detail,
|
|
@@ -6317,7 +6399,7 @@ function escapeForCmd(arg) {
|
|
|
6317
6399
|
const quoted = `"${arg.replace(/(\\*)"/g, '$1$1\\"').replace(/(\\*)$/, "$1$1")}"`;
|
|
6318
6400
|
return quoted.replace(/([()%!^<>&|;,"])/g, "^$1");
|
|
6319
6401
|
}
|
|
6320
|
-
function
|
|
6402
|
+
function describe3(file, err, stderr) {
|
|
6321
6403
|
if (err.code === "ENOENT") return t("plugin_cmd.not_found", { file });
|
|
6322
6404
|
if (err.killed) return t("plugin_cmd.timeout", { file });
|
|
6323
6405
|
const tail = stderr.trim().split("\n").slice(-4).join("\n").trim();
|
|
@@ -6900,7 +6982,7 @@ var EntrySchema = z.object({
|
|
|
6900
6982
|
changelog: z.string().min(1).optional(),
|
|
6901
6983
|
size: z.number().int().positive().optional(),
|
|
6902
6984
|
homepage: z.string().min(1).optional(),
|
|
6903
|
-
visibility: z.enum(
|
|
6985
|
+
visibility: z.enum(PLUGIN_VISIBILITY).optional().catch(void 0),
|
|
6904
6986
|
status: z.enum(["listed", "reviewing", "rejected", "offline"]).optional().catch(void 0)
|
|
6905
6987
|
});
|
|
6906
6988
|
var MARKETPLACE_DISPLAY_FIELDS = [
|
|
@@ -7403,14 +7485,14 @@ var CheckpointStore = class {
|
|
|
7403
7485
|
}
|
|
7404
7486
|
async enforceTotalSize(protectSession, protectTurnIndex) {
|
|
7405
7487
|
const turns = await this.collectTurns();
|
|
7406
|
-
let total = turns.reduce((sum,
|
|
7488
|
+
let total = turns.reduce((sum, t81) => sum + t81.bytes, 0);
|
|
7407
7489
|
if (total <= this.maxTotalBytes) return;
|
|
7408
7490
|
turns.sort((a, b) => a.createdAt - b.createdAt);
|
|
7409
|
-
for (const
|
|
7491
|
+
for (const t81 of turns) {
|
|
7410
7492
|
if (total <= this.maxTotalBytes) return;
|
|
7411
|
-
if (
|
|
7412
|
-
await this.removeTurn(
|
|
7413
|
-
total -=
|
|
7493
|
+
if (t81.sessionId === protectSession && t81.turnIndex === protectTurnIndex) continue;
|
|
7494
|
+
await this.removeTurn(t81.sessionId, t81.turnIndex);
|
|
7495
|
+
total -= t81.bytes;
|
|
7414
7496
|
}
|
|
7415
7497
|
}
|
|
7416
7498
|
async collectTurns() {
|
|
@@ -8116,8 +8198,8 @@ function sanitizeToolOutput(text) {
|
|
|
8116
8198
|
if (!stripped.includes("\r")) return stripped;
|
|
8117
8199
|
return stripped.split("\n").map((line) => line.includes("\r") ? line.slice(line.lastIndexOf("\r") + 1) : line).join("\n");
|
|
8118
8200
|
}
|
|
8119
|
-
var sleep2 = (ms) => new Promise((
|
|
8120
|
-
setTimeout(
|
|
8201
|
+
var sleep2 = (ms) => new Promise((resolve16) => {
|
|
8202
|
+
setTimeout(resolve16, ms);
|
|
8121
8203
|
});
|
|
8122
8204
|
async function* pumpToolOutput(target, start, options = {}) {
|
|
8123
8205
|
const flushMs = options.flushMs ?? FLUSH_MS;
|
|
@@ -8185,8 +8267,8 @@ async function* pumpToolOutput(target, start, options = {}) {
|
|
|
8185
8267
|
continue;
|
|
8186
8268
|
}
|
|
8187
8269
|
if (!running) break;
|
|
8188
|
-
await new Promise((
|
|
8189
|
-
wake =
|
|
8270
|
+
await new Promise((resolve16) => {
|
|
8271
|
+
wake = resolve16;
|
|
8190
8272
|
});
|
|
8191
8273
|
if (running && flushMs > 0) await sleep2(flushMs);
|
|
8192
8274
|
}
|
|
@@ -8595,7 +8677,7 @@ function decideTrust(dir) {
|
|
|
8595
8677
|
return ambient ? ambient.decide(dir) : noGate();
|
|
8596
8678
|
}
|
|
8597
8679
|
var FILE_VERSION = 1;
|
|
8598
|
-
function
|
|
8680
|
+
function describe4(err) {
|
|
8599
8681
|
return err instanceof Error ? err.message : String(err);
|
|
8600
8682
|
}
|
|
8601
8683
|
var ImportTrustStore = class {
|
|
@@ -8637,7 +8719,7 @@ var ImportTrustStore = class {
|
|
|
8637
8719
|
raw = readFileSync(this.filePath, "utf-8");
|
|
8638
8720
|
} catch (err) {
|
|
8639
8721
|
this.loadErrors.push(
|
|
8640
|
-
t("import_trust.read_failed", { path: this.filePath, reason:
|
|
8722
|
+
t("import_trust.read_failed", { path: this.filePath, reason: describe4(err) })
|
|
8641
8723
|
);
|
|
8642
8724
|
return;
|
|
8643
8725
|
}
|
|
@@ -8646,7 +8728,7 @@ var ImportTrustStore = class {
|
|
|
8646
8728
|
parsed = JSON.parse(raw);
|
|
8647
8729
|
} catch (err) {
|
|
8648
8730
|
this.loadErrors.push(
|
|
8649
|
-
t("import_trust.bad_json", { path: this.filePath, reason:
|
|
8731
|
+
t("import_trust.bad_json", { path: this.filePath, reason: describe4(err) })
|
|
8650
8732
|
);
|
|
8651
8733
|
return;
|
|
8652
8734
|
}
|
|
@@ -8704,7 +8786,7 @@ var ImportTrustStore = class {
|
|
|
8704
8786
|
} catch (err) {
|
|
8705
8787
|
rmSync(tmp, { force: true });
|
|
8706
8788
|
throw new Error(
|
|
8707
|
-
t("import_trust.write_failed", { path: this.filePath, reason:
|
|
8789
|
+
t("import_trust.write_failed", { path: this.filePath, reason: describe4(err) })
|
|
8708
8790
|
);
|
|
8709
8791
|
}
|
|
8710
8792
|
}
|
|
@@ -9516,7 +9598,6 @@ ${this.describeWarning(status)}
|
|
|
9516
9598
|
});
|
|
9517
9599
|
}
|
|
9518
9600
|
};
|
|
9519
|
-
// src/provider/errors.ts
|
|
9520
9601
|
var ProviderError = class extends Error {
|
|
9521
9602
|
constructor(message, code, recoverable, recovery = "abort") {
|
|
9522
9603
|
super(message);
|
|
@@ -9544,6 +9625,40 @@ function isAbortError(err) {
|
|
|
9544
9625
|
}
|
|
9545
9626
|
return false;
|
|
9546
9627
|
}
|
|
9628
|
+
function causeChain(err) {
|
|
9629
|
+
const out = [];
|
|
9630
|
+
for (let cur = err, depth = 0; cur && depth < 5; depth++) {
|
|
9631
|
+
if (typeof cur !== "object") break;
|
|
9632
|
+
const e = cur;
|
|
9633
|
+
out.push({
|
|
9634
|
+
message: typeof e.message === "string" ? e.message : "",
|
|
9635
|
+
...typeof e.code === "string" ? { code: e.code } : {}
|
|
9636
|
+
});
|
|
9637
|
+
cur = e.cause;
|
|
9638
|
+
}
|
|
9639
|
+
return out;
|
|
9640
|
+
}
|
|
9641
|
+
var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
9642
|
+
"ECONNRESET",
|
|
9643
|
+
"ECONNREFUSED",
|
|
9644
|
+
"ETIMEDOUT",
|
|
9645
|
+
"ENOTFOUND",
|
|
9646
|
+
"EPIPE",
|
|
9647
|
+
"EAI_AGAIN",
|
|
9648
|
+
"UND_ERR_SOCKET",
|
|
9649
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
9650
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
9651
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
9652
|
+
"UND_ERR_RESPONSE_STATUS_CODE"
|
|
9653
|
+
]);
|
|
9654
|
+
var NETWORK_MESSAGE_RE = /timeout|timed.?out|etimedout|econnreset|enotfound|socket.?hang.?up|other.?side.?closed|terminated|network.?error|fetch.?failed/i;
|
|
9655
|
+
function describeProviderError(err) {
|
|
9656
|
+
const chain = causeChain(err);
|
|
9657
|
+
const head = chain[0]?.message ?? (typeof err === "string" ? err : String(err));
|
|
9658
|
+
if (chain.length === 0) return head;
|
|
9659
|
+
const root = [...chain].reverse().find((link) => link.message !== "" && link.message !== head)?.message;
|
|
9660
|
+
return root ? t("provider_route.root_cause", { message: head, cause: root }) : head;
|
|
9661
|
+
}
|
|
9547
9662
|
function extractStatus(err) {
|
|
9548
9663
|
if (!err || typeof err !== "object") return void 0;
|
|
9549
9664
|
const e = err;
|
|
@@ -9576,8 +9691,7 @@ function classifyProviderError(err) {
|
|
|
9576
9691
|
return { code: 1040, recovery: "switch_model" };
|
|
9577
9692
|
if (/overloaded|server.?error|bad.?gateway|service.?unavailable/i.test(msg))
|
|
9578
9693
|
return { code: 1020, recovery: "retry" };
|
|
9579
|
-
if (
|
|
9580
|
-
return { code: 1041, recovery: "retry" };
|
|
9694
|
+
if (NETWORK_MESSAGE_RE.test(msg)) return { code: 1041, recovery: "retry" };
|
|
9581
9695
|
const code = status ?? extractStatusFromMessage(msg);
|
|
9582
9696
|
if (code !== void 0) {
|
|
9583
9697
|
if (code === 401 || code === 403) return { code: 1001, recovery: "rotate_credential" };
|
|
@@ -9587,6 +9701,10 @@ function classifyProviderError(err) {
|
|
|
9587
9701
|
if (code >= 500) return { code: 1020, recovery: "retry" };
|
|
9588
9702
|
if (code >= 400) return { code: 1050, recovery: "abort" };
|
|
9589
9703
|
}
|
|
9704
|
+
for (const link of causeChain(err)) {
|
|
9705
|
+
if (link.code && NETWORK_ERROR_CODES.has(link.code)) return { code: 1041, recovery: "retry" };
|
|
9706
|
+
if (NETWORK_MESSAGE_RE.test(link.message)) return { code: 1041, recovery: "retry" };
|
|
9707
|
+
}
|
|
9590
9708
|
return { code: 9999, recovery: "retry" };
|
|
9591
9709
|
}
|
|
9592
9710
|
function toModelMessages(messages) {
|
|
@@ -9777,6 +9895,28 @@ function droppedUserContentParts(warnings) {
|
|
|
9777
9895
|
});
|
|
9778
9896
|
}
|
|
9779
9897
|
var DROPPED_PART_HINTS = ["image", "file"];
|
|
9898
|
+
// src/agent/blank-turn-detector.ts
|
|
9899
|
+
var NEAR_BLANK_MAX_CHARS = 4;
|
|
9900
|
+
var ACKNOWLEDGEMENTS = [
|
|
9901
|
+
{
|
|
9902
|
+
zh: /^[一-鿿]{0,2}(?:完|好|到)(?:了|啦|的)?[。..!!]?$/,
|
|
9903
|
+
en: /^(?:done|finished|complete[d]?)[.!]?$/i
|
|
9904
|
+
},
|
|
9905
|
+
{
|
|
9906
|
+
zh: /^(?:完成|搞定|收工|行|可以|嗯|是|是的|对|对的|没错)(?:了|啦)?[。..!!]?$/,
|
|
9907
|
+
en: /^(?:ok(?:ay)?|sure|yes|yep|yeah|right|no|nope)[.!]?$/i
|
|
9908
|
+
}
|
|
9909
|
+
];
|
|
9910
|
+
function isAcknowledgement(text) {
|
|
9911
|
+
return ACKNOWLEDGEMENTS.some((a) => a.zh.test(text) || a.en.test(text));
|
|
9912
|
+
}
|
|
9913
|
+
function blankFinish(text, didToolWork) {
|
|
9914
|
+
if (!didToolWork) return false;
|
|
9915
|
+
const trimmed = text.trim();
|
|
9916
|
+
if (trimmed.length === 0) return true;
|
|
9917
|
+
if (trimmed.length > NEAR_BLANK_MAX_CHARS) return false;
|
|
9918
|
+
return !isAcknowledgement(trimmed);
|
|
9919
|
+
}
|
|
9780
9920
|
// src/agent/hooks.ts
|
|
9781
9921
|
var HookDispatcher = class {
|
|
9782
9922
|
constructor(manager, workDir) {
|
|
@@ -10080,6 +10220,14 @@ function announcedButIdleNote() {
|
|
|
10080
10220
|
"\u771F\u505A\u4E0D\u4E0B\u53BB\uFF08\u7F3A\u51ED\u636E\u3001\u8981\u82B1\u94B1\u3001\u53D6\u6570\u4E00\u76F4\u5931\u8D25\uFF09\u5C31\u8BF4\u6E05\u5361\u5728\u54EA\u4E00\u6B65\u7684\u54EA\u4E00\u73AF\u3002"
|
|
10081
10221
|
].join("\n");
|
|
10082
10222
|
}
|
|
10223
|
+
function blankResponseNote(chars) {
|
|
10224
|
+
return [
|
|
10225
|
+
`\u4F60\u4E0A\u4E00\u8F6E\u628A\u5DE5\u5177\u8DD1\u5B8C\u4E86\uFF0C\u4F46\u4EA4\u5230\u7528\u6237\u5C4F\u5E55\u4E0A\u7684\u6B63\u6587\u53EA\u6709 ${chars} \u4E2A\u5B57 \u2014\u2014 \u5728\u7528\u6237\u90A3\u8FB9\uFF0C\u8FD9\u4E00\u8F6E\u7B49\u4E8E\u6CA1\u6709\u56DE\u590D\u3002`,
|
|
10226
|
+
"\u73B0\u5728\u628A\u7ED3\u8BBA\u5B8C\u6574\u5199\u51FA\u6765\uFF1A\u7528\u6237\u95EE\u7684\u90A3\u4EF6\u4E8B\uFF0C\u7B54\u6848\u662F\u4EC0\u4E48\u3002\u522B\u53EA\u56DE\u4E00\u53E5\u300C\u597D\u7684\u300D\u300C\u5B8C\u6210\u4E86\u300D\u300C\u5DF2\u5904\u7406\u300D\u3002",
|
|
10227
|
+
"\u5982\u679C\u4F60\u89C9\u5F97\u81EA\u5DF1\u4E0A\u4E00\u8F6E\u5176\u5B9E\u5DF2\u7ECF\u7B54\u5B8C\u4E86\uFF0C\u90A3\u5C31\u628A\u90A3\u6BB5\u7ED3\u8BBA\u5B8C\u6574\u5730\u518D\u8BF4\u4E00\u904D \u2014\u2014 \u5B83\u6CA1\u6709\u5230\u8FBE\u7528\u6237\u3002",
|
|
10228
|
+
"\u4E0A\u4E00\u8F6E\u7684\u5DE5\u5177\u7ED3\u679C\u90FD\u8FD8\u5728\u4E0A\u9762\u7684\u4E0A\u4E0B\u6587\u91CC\uFF0C\u76F4\u63A5\u636E\u6B64\u4F5C\u7B54\uFF0C\u522B\u628A\u90A3\u4E9B\u5DE5\u5177\u91CD\u8DD1\u4E00\u904D\u3002"
|
|
10229
|
+
].join("\n");
|
|
10230
|
+
}
|
|
10083
10231
|
var CODE_VERIFICATION_POLICY = [
|
|
10084
10232
|
"<code_verification>",
|
|
10085
10233
|
"\u6539\u5B8C\u4EE3\u7801\u3001\u5BA3\u5E03\u5B8C\u6210\u4E4B\u524D\uFF0C\u8C03\u4E00\u6B21 `lsp_diagnostics`\uFF0C\u628A\u672C\u8F6E\u65B0\u5EFA\u6216\u4FEE\u6539\u8FC7\u7684\u6E90\u6587\u4EF6\u5217\u8FDB\u53BB\u3002",
|
|
@@ -10123,11 +10271,11 @@ var PromptBuilder = class {
|
|
|
10123
10271
|
memoryInitialized = false;
|
|
10124
10272
|
projectBlock(tools) {
|
|
10125
10273
|
const permLevel = this.deps.permissionManager?.getLevel() || "default";
|
|
10126
|
-
const hasPlanTool = tools.some((
|
|
10127
|
-
const hasLspTool = tools.some((
|
|
10128
|
-
const hasAskTool = tools.some((
|
|
10129
|
-
const hasTodoTool = tools.some((
|
|
10130
|
-
const hasTerminal = tools.some((
|
|
10274
|
+
const hasPlanTool = tools.some((t81) => t81.name === "enter_plan_mode");
|
|
10275
|
+
const hasLspTool = tools.some((t81) => t81.name === "lsp_diagnostics");
|
|
10276
|
+
const hasAskTool = tools.some((t81) => t81.name === "ask_user_question");
|
|
10277
|
+
const hasTodoTool = tools.some((t81) => t81.name === "todo");
|
|
10278
|
+
const hasTerminal = tools.some((t81) => t81.name === "terminal");
|
|
10131
10279
|
const needsCommandApproval = hasTerminal && permLevel === "default";
|
|
10132
10280
|
const plan = this.deps.approvedPlan?.()?.trim();
|
|
10133
10281
|
const codeSdk = renderSdkDeclaration(this.deps.codeModeTools?.() ?? []);
|
|
@@ -11006,8 +11154,8 @@ function imageParts(content) {
|
|
|
11006
11154
|
return typeof content === "string" ? [] : content.filter((p) => p.type === "image");
|
|
11007
11155
|
}
|
|
11008
11156
|
function toolSignatureOf(config, tools) {
|
|
11009
|
-
const direct = tools.map((
|
|
11010
|
-
const declared = (config.codeModeTools?.() ?? []).map((
|
|
11157
|
+
const direct = tools.map((t81) => t81.name).join("\0");
|
|
11158
|
+
const declared = (config.codeModeTools?.() ?? []).map((t81) => t81.name).join("\0");
|
|
11011
11159
|
return declared ? `${direct}|${declared}` : direct;
|
|
11012
11160
|
}
|
|
11013
11161
|
function modelSignatureOf(info) {
|
|
@@ -11126,6 +11274,15 @@ var AgentLoop = class {
|
|
|
11126
11274
|
isAborted(signal) {
|
|
11127
11275
|
return this.aborted || signal?.aborted === true;
|
|
11128
11276
|
}
|
|
11277
|
+
async *drainSteer(input, messages) {
|
|
11278
|
+
const items = input.steer?.take() ?? [];
|
|
11279
|
+
for (const item of items) {
|
|
11280
|
+
const text = contentToText(item);
|
|
11281
|
+
const parts = typeof item === "string" ? void 0 : item;
|
|
11282
|
+
messages.push({ role: "user", content: text, ...parts ? { parts } : {} });
|
|
11283
|
+
yield { type: "steer", text, ...parts ? { parts } : {} };
|
|
11284
|
+
}
|
|
11285
|
+
}
|
|
11129
11286
|
contextBreakdown(opts) {
|
|
11130
11287
|
const seg2 = this.prompt.segments();
|
|
11131
11288
|
return buildContextBreakdown({
|
|
@@ -11310,6 +11467,8 @@ var AgentLoop = class {
|
|
|
11310
11467
|
const taskNotice = new TaskNoticeTracker(this.config.backgroundTasks);
|
|
11311
11468
|
let todoNudged = false;
|
|
11312
11469
|
let idleNudged = false;
|
|
11470
|
+
let blankNudged = false;
|
|
11471
|
+
let blankAfterNudge = false;
|
|
11313
11472
|
for (let turn = 1; turn <= maxTurns; turn++) {
|
|
11314
11473
|
if (this.isAborted(input.signal)) {
|
|
11315
11474
|
yield finish("aborted");
|
|
@@ -11332,6 +11491,7 @@ var AgentLoop = class {
|
|
|
11332
11491
|
}
|
|
11333
11492
|
const notice2 = taskNotice.notice();
|
|
11334
11493
|
if (notice2) messages.push({ role: "user", content: notice2 });
|
|
11494
|
+
if (turn > 1) yield* this.drainSteer(input, messages);
|
|
11335
11495
|
this.hooks.fire("turn:before", {
|
|
11336
11496
|
sessionId: input.sessionId,
|
|
11337
11497
|
userMessage: transformed,
|
|
@@ -11409,7 +11569,8 @@ var AgentLoop = class {
|
|
|
11409
11569
|
tools,
|
|
11410
11570
|
system,
|
|
11411
11571
|
maxSteps: 1,
|
|
11412
|
-
...isAbortSignal(input.signal) ? { signal: input.signal } : {}
|
|
11572
|
+
...isAbortSignal(input.signal) ? { signal: input.signal } : {},
|
|
11573
|
+
...this.config.maxOutputTokens ? { maxTokens: this.config.maxOutputTokens } : {}
|
|
11413
11574
|
},
|
|
11414
11575
|
streaming,
|
|
11415
11576
|
...guard ? { guard } : {},
|
|
@@ -11561,6 +11722,11 @@ ${finalText}` };
|
|
|
11561
11722
|
usage: result.usage,
|
|
11562
11723
|
turn
|
|
11563
11724
|
});
|
|
11725
|
+
if (turn < maxTurns && input.steer?.pending() === true) {
|
|
11726
|
+
messages.push({ role: "assistant", content: finalText || NO_OUTPUT_TEXT });
|
|
11727
|
+
yield* this.drainSteer(input, messages);
|
|
11728
|
+
continue;
|
|
11729
|
+
}
|
|
11564
11730
|
const wantContinue = await this.hooks.wantsContinue(
|
|
11565
11731
|
input.sessionId,
|
|
11566
11732
|
finalText,
|
|
@@ -11578,6 +11744,23 @@ ${finalText}` };
|
|
|
11578
11744
|
);
|
|
11579
11745
|
continue;
|
|
11580
11746
|
}
|
|
11747
|
+
const didToolWork = turns.some((r) => r.toolCalls.length > 0);
|
|
11748
|
+
if (!truncated && blankFinish(finalText, didToolWork)) {
|
|
11749
|
+
if (!blankNudged && turn < maxTurns) {
|
|
11750
|
+
blankNudged = true;
|
|
11751
|
+
yield {
|
|
11752
|
+
type: "notice",
|
|
11753
|
+
code: "blank-response",
|
|
11754
|
+
text: t("agent_run.blank_response")
|
|
11755
|
+
};
|
|
11756
|
+
messages.push(
|
|
11757
|
+
{ role: "assistant", content: finalText || NO_OUTPUT_TEXT },
|
|
11758
|
+
{ role: "user", content: systemNote(blankResponseNote(finalText.trim().length)) }
|
|
11759
|
+
);
|
|
11760
|
+
continue;
|
|
11761
|
+
}
|
|
11762
|
+
blankAfterNudge = blankNudged;
|
|
11763
|
+
}
|
|
11581
11764
|
if (!todoNudged && turn < maxTurns) {
|
|
11582
11765
|
const open = this.config.pendingTodos?.(input.sessionId);
|
|
11583
11766
|
if (open !== void 0 && open > 0) {
|
|
@@ -11606,8 +11789,8 @@ ${finalText}` };
|
|
|
11606
11789
|
totalTokens: totalInput + totalOutput,
|
|
11607
11790
|
turns
|
|
11608
11791
|
});
|
|
11609
|
-
this.maybeLearn(userText, finalText);
|
|
11610
|
-
yield finish(truncated ? "length" : "stop");
|
|
11792
|
+
if (!blankAfterNudge) this.maybeLearn(userText, finalText);
|
|
11793
|
+
yield finish(truncated ? "length" : blankAfterNudge ? "blank" : "stop");
|
|
11611
11794
|
return;
|
|
11612
11795
|
}
|
|
11613
11796
|
messages.push({
|
|
@@ -11801,7 +11984,12 @@ ${finalText}` };
|
|
|
11801
11984
|
"epoch.summary_skipped": compressed.summarySkipped === true,
|
|
11802
11985
|
"epoch.pruned_tokens": compressed.prunedTokens
|
|
11803
11986
|
});
|
|
11804
|
-
return {
|
|
11987
|
+
return {
|
|
11988
|
+
messages: compressed.messages.map((m) => unflattenMessage(m)),
|
|
11989
|
+
...bill,
|
|
11990
|
+
...compressed.carriedHead === void 0 ? {} : { carriedHead: compressed.carriedHead },
|
|
11991
|
+
...compressed.carriedTail === void 0 ? {} : { carriedTail: compressed.carriedTail }
|
|
11992
|
+
};
|
|
11805
11993
|
} catch {
|
|
11806
11994
|
return { messages };
|
|
11807
11995
|
}
|
|
@@ -11955,6 +12143,11 @@ var ArtifactsSchema = z.object({
|
|
|
11955
12143
|
maxAgeDays: z.int().positive().max(3650).default(ARTIFACT_RETENTION_DEFAULTS.maxAgeDays),
|
|
11956
12144
|
maxTotalBytes: z.int().positive().default(ARTIFACT_RETENTION_DEFAULTS.maxTotalBytes)
|
|
11957
12145
|
});
|
|
12146
|
+
var SessionsSchema = z.object({
|
|
12147
|
+
autoPrune: z.boolean().default(false),
|
|
12148
|
+
retentionDays: z.int().positive().max(3650).default(90),
|
|
12149
|
+
vacuumAfterPrune: z.boolean().default(true)
|
|
12150
|
+
});
|
|
11958
12151
|
var TelemetrySchema = z.object({
|
|
11959
12152
|
enabled: z.boolean().optional(),
|
|
11960
12153
|
target: z.enum(["file", "console", "otlp"]).optional(),
|
|
@@ -11968,6 +12161,7 @@ var EpochConfigSchema = z.object({
|
|
|
11968
12161
|
shell: z.enum(SHELL_KINDS).optional(),
|
|
11969
12162
|
maxTurns: z.int().nonnegative().default(DEFAULT_MAX_TURNS),
|
|
11970
12163
|
contextLength: z.int().positive().default(2e5),
|
|
12164
|
+
maxOutputTokens: z.int().positive().optional(),
|
|
11971
12165
|
homeDir: z.string().min(1).default(() => resolveHomeDir()),
|
|
11972
12166
|
dbPath: z.string().min(1).default(() => dbPath(resolveHomeDir())),
|
|
11973
12167
|
permission: z.enum(PERMISSION_LEVELS).default("default"),
|
|
@@ -11991,6 +12185,7 @@ var EpochConfigSchema = z.object({
|
|
|
11991
12185
|
compression: CompressionSchema.prefault({}),
|
|
11992
12186
|
memory: MemorySchema.prefault({}),
|
|
11993
12187
|
artifacts: ArtifactsSchema.prefault({}),
|
|
12188
|
+
sessions: SessionsSchema.prefault({}),
|
|
11994
12189
|
budget: BudgetSchema.optional(),
|
|
11995
12190
|
compliance: ComplianceSchema.optional(),
|
|
11996
12191
|
headless: HeadlessSchema.optional(),
|
|
@@ -12212,12 +12407,12 @@ function finishLayer(source, read, execTrusted, issues) {
|
|
|
12212
12407
|
status: gated ? "gated" : "loaded",
|
|
12213
12408
|
lists: checked.lists,
|
|
12214
12409
|
scalars: {},
|
|
12215
|
-
detail:
|
|
12410
|
+
detail: describe5(layer, gated, checked.lists)
|
|
12216
12411
|
},
|
|
12217
12412
|
file: { ...file, permissions: checked.lists }
|
|
12218
12413
|
};
|
|
12219
12414
|
}
|
|
12220
|
-
function
|
|
12415
|
+
function describe5(layer, gated, lists) {
|
|
12221
12416
|
const label = layerLabel(layer);
|
|
12222
12417
|
if (gated) {
|
|
12223
12418
|
const deny = lists.deny?.length ?? 0;
|
|
@@ -12476,7 +12671,11 @@ function parseRawConfig(raw, issues, track) {
|
|
|
12476
12671
|
const migrated = migrateRawConfig(expanded);
|
|
12477
12672
|
issues.push(...migrated.issues);
|
|
12478
12673
|
issues.push(...unknownKeyIssues(CONFIG_KEYS, migrated.raw));
|
|
12479
|
-
const outcome = parseLenient(
|
|
12674
|
+
const outcome = parseLenient(
|
|
12675
|
+
EpochConfigSchema,
|
|
12676
|
+
dropEmptySections(migrated.raw),
|
|
12677
|
+
EpochConfigSchema.parse({})
|
|
12678
|
+
);
|
|
12480
12679
|
issues.push(...outcome.issues);
|
|
12481
12680
|
if (outcome.issues.length === 0) collectKeyPaths(migrated.raw, track.file);
|
|
12482
12681
|
return outcome.value;
|
|
@@ -13086,6 +13285,7 @@ function getCapability(modelId, homeDir, provider) {
|
|
|
13086
13285
|
}
|
|
13087
13286
|
return {
|
|
13088
13287
|
contextLength: DEFAULT_CONTEXT_LENGTH2,
|
|
13288
|
+
contextLengthUnknown: true,
|
|
13089
13289
|
maxOutputTokens: 4096,
|
|
13090
13290
|
supportsTools: true,
|
|
13091
13291
|
...images,
|
|
@@ -13598,7 +13798,7 @@ var ProviderRouter = class {
|
|
|
13598
13798
|
}
|
|
13599
13799
|
async recover(err, state) {
|
|
13600
13800
|
const { code, recovery } = classifyProviderError(err);
|
|
13601
|
-
const message =
|
|
13801
|
+
const message = describeProviderError(err);
|
|
13602
13802
|
const stay = { kind: "continue", ct: state.ct, cm: state.cm };
|
|
13603
13803
|
if (code === PROVIDER_ABORTED) return { kind: "give-up", message, code };
|
|
13604
13804
|
if (recovery === "rotate_credential" && this.rotateCredential())
|
|
@@ -13789,7 +13989,7 @@ var ProviderRouter = class {
|
|
|
13789
13989
|
} catch (err) {
|
|
13790
13990
|
const cause = streamPartError ?? err;
|
|
13791
13991
|
if (emitted) {
|
|
13792
|
-
yield { type: "error", error:
|
|
13992
|
+
yield { type: "error", error: describeProviderError(cause) };
|
|
13793
13993
|
return;
|
|
13794
13994
|
}
|
|
13795
13995
|
const plan = await this.recover(cause, state);
|
|
@@ -14033,6 +14233,7 @@ var SETTING_WRITE_KEYS = [
|
|
|
14033
14233
|
"models.utility",
|
|
14034
14234
|
"fallback.model",
|
|
14035
14235
|
"contextLength",
|
|
14236
|
+
"maxOutputTokens",
|
|
14036
14237
|
"compression.enabled",
|
|
14037
14238
|
"compression.threshold",
|
|
14038
14239
|
"memory.memoryCharLimit",
|
|
@@ -14042,6 +14243,9 @@ var SETTING_WRITE_KEYS = [
|
|
|
14042
14243
|
"budget.maxTokens",
|
|
14043
14244
|
"budget.warnAtPercent",
|
|
14044
14245
|
"budget.onUnknownPricing",
|
|
14246
|
+
"sessions.autoPrune",
|
|
14247
|
+
"sessions.retentionDays",
|
|
14248
|
+
"sessions.vacuumAfterPrune",
|
|
14045
14249
|
"permission"
|
|
14046
14250
|
];
|
|
14047
14251
|
function isWritableSettingKey(value) {
|
|
@@ -14096,6 +14300,7 @@ var VALUE_SCHEMA = {
|
|
|
14096
14300
|
"models.utility": EpochConfigSchema.shape.models.unwrap().shape.utility.unwrap(),
|
|
14097
14301
|
"fallback.model": EpochConfigSchema.shape.fallback.unwrap().shape.model.unwrap(),
|
|
14098
14302
|
contextLength: EpochConfigSchema.shape.contextLength.unwrap(),
|
|
14303
|
+
maxOutputTokens: EpochConfigSchema.shape.maxOutputTokens.unwrap(),
|
|
14099
14304
|
"compression.enabled": EpochConfigSchema.shape.compression.unwrap().shape.enabled.unwrap(),
|
|
14100
14305
|
"compression.threshold": EpochConfigSchema.shape.compression.unwrap().shape.threshold.unwrap(),
|
|
14101
14306
|
"memory.memoryCharLimit": EpochConfigSchema.shape.memory.unwrap().shape.memoryCharLimit.unwrap(),
|
|
@@ -14105,6 +14310,9 @@ var VALUE_SCHEMA = {
|
|
|
14105
14310
|
"budget.maxTokens": EpochConfigSchema.shape.budget.unwrap().shape.maxTokens.unwrap(),
|
|
14106
14311
|
"budget.warnAtPercent": EpochConfigSchema.shape.budget.unwrap().shape.warnAtPercent.unwrap(),
|
|
14107
14312
|
"budget.onUnknownPricing": EpochConfigSchema.shape.budget.unwrap().shape.onUnknownPricing.unwrap(),
|
|
14313
|
+
"sessions.autoPrune": EpochConfigSchema.shape.sessions.unwrap().shape.autoPrune.unwrap(),
|
|
14314
|
+
"sessions.retentionDays": EpochConfigSchema.shape.sessions.unwrap().shape.retentionDays.unwrap(),
|
|
14315
|
+
"sessions.vacuumAfterPrune": EpochConfigSchema.shape.sessions.unwrap().shape.vacuumAfterPrune.unwrap(),
|
|
14108
14316
|
permission: EpochConfigSchema.shape.permission.unwrap()
|
|
14109
14317
|
};
|
|
14110
14318
|
function settingValueKind(key) {
|
|
@@ -14513,11 +14721,11 @@ function buildSearchQuery(query) {
|
|
|
14513
14721
|
}
|
|
14514
14722
|
const latinPart = cleaned.replace(CJK_RUN, " ");
|
|
14515
14723
|
for (const w of latinPart.split(/\s+/)) {
|
|
14516
|
-
const
|
|
14517
|
-
if (
|
|
14724
|
+
const t81 = w.trim();
|
|
14725
|
+
if (t81.length >= 2) terms.add(t81);
|
|
14518
14726
|
}
|
|
14519
14727
|
if (terms.size === 0) return null;
|
|
14520
|
-
return [...terms].map((
|
|
14728
|
+
return [...terms].map((t81) => `"${t81.replace(/"/g, "")}"`).join(" OR ");
|
|
14521
14729
|
}
|
|
14522
14730
|
// src/memory/db.ts
|
|
14523
14731
|
var NS2 = "memory";
|
|
@@ -15846,6 +16054,27 @@ var SESSION_MIGRATIONS = [
|
|
|
15846
16054
|
up: (db) => {
|
|
15847
16055
|
db.exec(`ALTER TABLE sessions ADD COLUMN priced_call_count INTEGER NOT NULL DEFAULT 0;`);
|
|
15848
16056
|
}
|
|
16057
|
+
},
|
|
16058
|
+
{
|
|
16059
|
+
id: "session-meta-kv",
|
|
16060
|
+
version: 11,
|
|
16061
|
+
description: "\u7EF4\u62A4\u7528\u7684 key/value \u8868\uFF08\u81EA\u52A8\u6E05\u7406\u7684\u8282\u6D41\u65F6\u523B\uFF0C2026-09-15\uFF09",
|
|
16062
|
+
up: (db) => {
|
|
16063
|
+
db.exec(`
|
|
16064
|
+
CREATE TABLE IF NOT EXISTS session_meta (
|
|
16065
|
+
key TEXT PRIMARY KEY,
|
|
16066
|
+
value TEXT NOT NULL
|
|
16067
|
+
);
|
|
16068
|
+
`);
|
|
16069
|
+
}
|
|
16070
|
+
},
|
|
16071
|
+
{
|
|
16072
|
+
id: "sessions-open-turn-from",
|
|
16073
|
+
version: 13,
|
|
16074
|
+
description: "\u4F1A\u8BDD\u8868\u52A0 open_turn_from \u4E00\u5217\uFF08\u88AB\u4E2D\u65AD\u7684\u90A3\u4E00\u8F6E\u8BA4\u5F97\u51FA\u6765\uFF0C2026-09-16\uFF09",
|
|
16075
|
+
up: (db) => {
|
|
16076
|
+
db.exec(`ALTER TABLE sessions ADD COLUMN open_turn_from INTEGER`);
|
|
16077
|
+
}
|
|
15849
16078
|
}
|
|
15850
16079
|
];
|
|
15851
16080
|
var FTS_EXTERNAL_SCHEMA = `
|
|
@@ -15896,7 +16125,7 @@ var FTS_EXTERNAL_SCHEMA = `
|
|
|
15896
16125
|
var FTS_EXTERNAL_MIGRATIONS = [
|
|
15897
16126
|
{
|
|
15898
16127
|
id: "fts-external-content",
|
|
15899
|
-
version:
|
|
16128
|
+
version: 14,
|
|
15900
16129
|
description: "\u4E24\u5F20 FTS \u8868\u6539\u6210\u5916\u90E8\u5185\u5BB9\u8868\uFF08\u6B63\u6587\u4E0D\u518D\u5B58\u4E09\u4EFD\uFF0C2026-08-21\uFF09",
|
|
15901
16130
|
up: (db) => {
|
|
15902
16131
|
db.exec(FTS_EXTERNAL_SCHEMA);
|
|
@@ -16092,12 +16321,27 @@ var SessionDB = class {
|
|
|
16092
16321
|
}
|
|
16093
16322
|
getMessages(sessionId, activeOnly = true) {
|
|
16094
16323
|
const where = activeOnly ? "session_id = ? AND active = 1" : "session_id = ?";
|
|
16095
|
-
const rows = this.db.prepare(`SELECT * FROM messages WHERE ${where} ORDER BY timestamp ASC`).all(sessionId);
|
|
16324
|
+
const rows = this.db.prepare(`SELECT * FROM messages WHERE ${where} ORDER BY timestamp ASC, id ASC`).all(sessionId);
|
|
16096
16325
|
return rows.map((r) => this.rowToMessage(r));
|
|
16097
16326
|
}
|
|
16098
16327
|
markObserved(sessionId, messageId) {
|
|
16099
16328
|
this.db.prepare("UPDATE messages SET observed = 1 WHERE session_id = ? AND id <= ?").run(sessionId, messageId);
|
|
16100
16329
|
}
|
|
16330
|
+
attachTurnFacts(sessionId, messageId, input) {
|
|
16331
|
+
const sets = [];
|
|
16332
|
+
if (input.turnFacts !== void 0) sets.push("turn_facts = @turnFacts");
|
|
16333
|
+
if (input.finishReason !== void 0) sets.push("finish_reason = @finishReason");
|
|
16334
|
+
if (sets.length === 0) return;
|
|
16335
|
+
this.db.prepare(`UPDATE messages SET ${sets.join(", ")} WHERE session_id = @sessionId AND id = @id`).run({
|
|
16336
|
+
sessionId,
|
|
16337
|
+
id: messageId,
|
|
16338
|
+
turnFacts: encodeTurnFacts(input.turnFacts),
|
|
16339
|
+
finishReason: input.finishReason ?? null
|
|
16340
|
+
});
|
|
16341
|
+
}
|
|
16342
|
+
setOpenTurn(sessionId, from) {
|
|
16343
|
+
this.db.prepare("UPDATE sessions SET open_turn_from = ? WHERE id = ?").run(from, sessionId);
|
|
16344
|
+
}
|
|
16101
16345
|
lastMessageId(sessionId) {
|
|
16102
16346
|
const row = this.db.prepare("SELECT MAX(id) AS maxId FROM messages WHERE session_id = ?").get(sessionId);
|
|
16103
16347
|
return row?.maxId ?? 0;
|
|
@@ -16199,6 +16443,46 @@ var SessionDB = class {
|
|
|
16199
16443
|
}
|
|
16200
16444
|
return { results };
|
|
16201
16445
|
}
|
|
16446
|
+
pruneCandidates(input) {
|
|
16447
|
+
const clauses = ["ended_at IS NOT NULL", "updated_at < @cutoff"];
|
|
16448
|
+
const params = { cutoff: input.olderThanMs };
|
|
16449
|
+
if (typeof input.archived === "boolean") {
|
|
16450
|
+
clauses.push("archived = @archived");
|
|
16451
|
+
params["archived"] = input.archived ? 1 : 0;
|
|
16452
|
+
}
|
|
16453
|
+
if (!input.includePinned) clauses.push("COALESCE(pinned, 0) = 0");
|
|
16454
|
+
const rows = this.db.prepare(`SELECT * FROM sessions WHERE ${clauses.join(" AND ")} ORDER BY updated_at ASC`).all(params);
|
|
16455
|
+
return rows.map((r) => this.rowToMeta(r));
|
|
16456
|
+
}
|
|
16457
|
+
openPruneMatches(input) {
|
|
16458
|
+
const clauses = ["ended_at IS NULL", "updated_at < @cutoff"];
|
|
16459
|
+
if (!input.includePinned) clauses.push("COALESCE(pinned, 0) = 0");
|
|
16460
|
+
const row = this.db.prepare(`SELECT COUNT(*) AS n FROM sessions WHERE ${clauses.join(" AND ")}`).get({ cutoff: input.olderThanMs });
|
|
16461
|
+
return row.n;
|
|
16462
|
+
}
|
|
16463
|
+
freelistRatio() {
|
|
16464
|
+
const pages = Number(this.db.pragma("page_count", { simple: true }));
|
|
16465
|
+
if (pages <= 0) return 0;
|
|
16466
|
+
return Number(this.db.pragma("freelist_count", { simple: true })) / pages;
|
|
16467
|
+
}
|
|
16468
|
+
getMeta(key) {
|
|
16469
|
+
const row = this.db.prepare("SELECT value FROM session_meta WHERE key = ?").get(key);
|
|
16470
|
+
return row?.value ?? null;
|
|
16471
|
+
}
|
|
16472
|
+
setMeta(key, value) {
|
|
16473
|
+
this.db.prepare(
|
|
16474
|
+
"INSERT INTO session_meta (key, value) VALUES (@key, @value) ON CONFLICT(key) DO UPDATE SET value = @value"
|
|
16475
|
+
).run({ key, value });
|
|
16476
|
+
}
|
|
16477
|
+
claimMaintenanceSlot(key, minIntervalMs, now) {
|
|
16478
|
+
const run = this.db.transaction(() => {
|
|
16479
|
+
const last = this.getMeta(key);
|
|
16480
|
+
if (last !== null && now - Number(last) < minIntervalMs) return false;
|
|
16481
|
+
this.setMeta(key, String(now));
|
|
16482
|
+
return true;
|
|
16483
|
+
});
|
|
16484
|
+
return run();
|
|
16485
|
+
}
|
|
16202
16486
|
compact(sessionId, summary, beforeCount, keep) {
|
|
16203
16487
|
const messages = this.db.prepare(
|
|
16204
16488
|
"SELECT id FROM messages WHERE session_id = ? AND active = 1 ORDER BY timestamp DESC"
|
|
@@ -16217,6 +16501,29 @@ var SessionDB = class {
|
|
|
16217
16501
|
duration: 0
|
|
16218
16502
|
};
|
|
16219
16503
|
}
|
|
16504
|
+
archiveAndCompact(sessionId, input) {
|
|
16505
|
+
const run = this.db.transaction(() => {
|
|
16506
|
+
const rows = this.db.prepare(
|
|
16507
|
+
"SELECT id, timestamp FROM messages WHERE session_id = ? AND active = 1 AND id <= ? ORDER BY timestamp ASC, id ASC"
|
|
16508
|
+
).all(sessionId, input.watermark);
|
|
16509
|
+
const end = rows.length - input.tailCount;
|
|
16510
|
+
const middle = end > input.headCount ? rows.slice(input.headCount, end) : [];
|
|
16511
|
+
if (middle.length === 0) return null;
|
|
16512
|
+
const mark = this.db.prepare("UPDATE messages SET active = 0, compacted = 1 WHERE id = ?");
|
|
16513
|
+
for (const row of middle) mark.run(row.id);
|
|
16514
|
+
const summaryId = this.nextMessageId();
|
|
16515
|
+
this.insertMessage({
|
|
16516
|
+
sessionId,
|
|
16517
|
+
id: summaryId,
|
|
16518
|
+
role: "user",
|
|
16519
|
+
content: input.summary,
|
|
16520
|
+
timestamp: middle[0].timestamp
|
|
16521
|
+
});
|
|
16522
|
+
this.db.prepare("UPDATE sessions SET summary = @s WHERE id = @id").run({ s: input.summary, id: sessionId });
|
|
16523
|
+
return { archived: middle.length, summaryId };
|
|
16524
|
+
});
|
|
16525
|
+
return run();
|
|
16526
|
+
}
|
|
16220
16527
|
getSummary(sessionId) {
|
|
16221
16528
|
const row = this.db.prepare("SELECT summary FROM sessions WHERE id = ?").get(sessionId);
|
|
16222
16529
|
return row?.summary ?? null;
|
|
@@ -16303,6 +16610,7 @@ var SessionDB = class {
|
|
|
16303
16610
|
workspaceRoot: row["workspace_root"] ?? void 0,
|
|
16304
16611
|
startedAt: new Date(row["started_at"]),
|
|
16305
16612
|
updatedAt: new Date(row["updated_at"] ?? row["started_at"]),
|
|
16613
|
+
openTurnFrom: row["open_turn_from"] ?? null,
|
|
16306
16614
|
endedAt: row["ended_at"] ? new Date(row["ended_at"]) : void 0,
|
|
16307
16615
|
endReason: row["end_reason"]
|
|
16308
16616
|
};
|
|
@@ -16415,7 +16723,7 @@ function checkFtsHealth(db) {
|
|
|
16415
16723
|
messages,
|
|
16416
16724
|
tables,
|
|
16417
16725
|
missingTriggers,
|
|
16418
|
-
healthy: missingTriggers.length === 0 && tables.every((
|
|
16726
|
+
healthy: missingTriggers.length === 0 && tables.every((t81) => t81.error === null && t81.drift === null && t81.rows === messages),
|
|
16419
16727
|
indexBytes: indexBytesOf(db),
|
|
16420
16728
|
space: spaceOf(db)
|
|
16421
16729
|
};
|
|
@@ -16561,6 +16869,7 @@ var SessionReferences = class {
|
|
|
16561
16869
|
}
|
|
16562
16870
|
};
|
|
16563
16871
|
// src/session/manager.ts
|
|
16872
|
+
var AUTO_VACUUM_MIN_FREELIST_RATIO = 0.25;
|
|
16564
16873
|
var SessionManager = class {
|
|
16565
16874
|
db;
|
|
16566
16875
|
queries;
|
|
@@ -16655,6 +16964,44 @@ var SessionManager = class {
|
|
|
16655
16964
|
unarchive(id) {
|
|
16656
16965
|
this.db.unarchiveSession(id);
|
|
16657
16966
|
}
|
|
16967
|
+
pruneCandidates(input) {
|
|
16968
|
+
return this.db.pruneCandidates(input);
|
|
16969
|
+
}
|
|
16970
|
+
openPruneMatches(input) {
|
|
16971
|
+
return this.db.openPruneMatches(input);
|
|
16972
|
+
}
|
|
16973
|
+
freelistRatio() {
|
|
16974
|
+
return this.db.freelistRatio();
|
|
16975
|
+
}
|
|
16976
|
+
maybeAutoPrune(opts) {
|
|
16977
|
+
const result = { skipped: false, pruned: 0, vacuumed: false };
|
|
16978
|
+
if (!opts.enabled) return { ...result, skipped: true };
|
|
16979
|
+
const now = opts.now?.() ?? Date.now();
|
|
16980
|
+
const minInterval = opts.minIntervalMs ?? 24 * 60 * 60 * 1e3;
|
|
16981
|
+
const minVacuumInterval = opts.minVacuumIntervalMs ?? 30 * 24 * 60 * 60 * 1e3;
|
|
16982
|
+
try {
|
|
16983
|
+
if (!this.db.claimMaintenanceSlot("last_auto_prune", minInterval, now)) {
|
|
16984
|
+
return { ...result, skipped: true };
|
|
16985
|
+
}
|
|
16986
|
+
const cutoff = now - opts.retentionDays * 24 * 60 * 60 * 1e3;
|
|
16987
|
+
const victims = this.db.pruneCandidates({ olderThanMs: cutoff });
|
|
16988
|
+
let pruned = 0;
|
|
16989
|
+
for (const s of victims) if (this.db.deleteSession(s.id)) pruned++;
|
|
16990
|
+
let vacuumed = false;
|
|
16991
|
+
if (opts.vacuum && pruned > 0) {
|
|
16992
|
+
const lastVacuum = this.db.getMeta("last_vacuum");
|
|
16993
|
+
const vacuumDue = lastVacuum === null || now - Number(lastVacuum) >= minVacuumInterval;
|
|
16994
|
+
if (vacuumDue && this.db.freelistRatio() > AUTO_VACUUM_MIN_FREELIST_RATIO) {
|
|
16995
|
+
const report3 = reclaimFtsSpace(this.db.db, true);
|
|
16996
|
+
vacuumed = report3.vacuumed;
|
|
16997
|
+
if (vacuumed) this.db.setMeta("last_vacuum", String(now));
|
|
16998
|
+
}
|
|
16999
|
+
}
|
|
17000
|
+
return { skipped: false, pruned, vacuumed };
|
|
17001
|
+
} catch (cause) {
|
|
17002
|
+
return { ...result, error: cause instanceof Error ? cause.message : String(cause) };
|
|
17003
|
+
}
|
|
17004
|
+
}
|
|
16658
17005
|
delete(id) {
|
|
16659
17006
|
return this.db.deleteSession(id);
|
|
16660
17007
|
}
|
|
@@ -16665,11 +17012,18 @@ var SessionManager = class {
|
|
|
16665
17012
|
const id = this.db.nextMessageId();
|
|
16666
17013
|
this.db.insertMessage({ ...msg, sessionId, id, timestamp: Date.now() });
|
|
16667
17014
|
const meta = this.db.getSessionMeta(sessionId);
|
|
16668
|
-
if (!meta) return;
|
|
17015
|
+
if (!meta) return id;
|
|
16669
17016
|
if (!meta.title && msg.role === "user") {
|
|
16670
17017
|
const title = msg.content.slice(0, 50).replace(/\n/g, " ");
|
|
16671
17018
|
this.db.updateSessionMeta(sessionId, { title });
|
|
16672
17019
|
}
|
|
17020
|
+
return id;
|
|
17021
|
+
}
|
|
17022
|
+
attachTurnFacts(sessionId, messageId, input) {
|
|
17023
|
+
this.db.attachTurnFacts(sessionId, messageId, input);
|
|
17024
|
+
}
|
|
17025
|
+
setOpenTurn(sessionId, from) {
|
|
17026
|
+
this.db.setOpenTurn(sessionId, from);
|
|
16673
17027
|
}
|
|
16674
17028
|
recordUsage(sessionId, usage) {
|
|
16675
17029
|
this.db.recordUsage(sessionId, usage);
|
|
@@ -16705,6 +17059,9 @@ var SessionManager = class {
|
|
|
16705
17059
|
const summary = toSummarize.length === 0 ? "" : await this.buildSummary(toSummarize, summarize3) ?? outlineOf(toSummarize);
|
|
16706
17060
|
return this.db.compact(sessionId, summary, beforeCount, IMPORTANT_ROUNDS * 2);
|
|
16707
17061
|
}
|
|
17062
|
+
archiveAndCompact(sessionId, input) {
|
|
17063
|
+
return this.db.archiveAndCompact(sessionId, input);
|
|
17064
|
+
}
|
|
16708
17065
|
async buildSummary(msgs, summarize3) {
|
|
16709
17066
|
if (!summarize3) return null;
|
|
16710
17067
|
const transcript = msgs.map((m) => `[${m.role}] ${m.content}`).join("\n\n");
|
|
@@ -17114,7 +17471,7 @@ function inspect(input, resolved, root, accepted) {
|
|
|
17114
17471
|
}
|
|
17115
17472
|
var MAX_RECENT_WORKSPACES = 20;
|
|
17116
17473
|
var FILE_VERSION2 = 1;
|
|
17117
|
-
function
|
|
17474
|
+
function describe6(err) {
|
|
17118
17475
|
return err instanceof Error ? err.message : String(err);
|
|
17119
17476
|
}
|
|
17120
17477
|
var RecentWorkspaces = class {
|
|
@@ -17131,8 +17488,8 @@ var RecentWorkspaces = class {
|
|
|
17131
17488
|
}
|
|
17132
17489
|
remember(dir, now, name) {
|
|
17133
17490
|
const root = resolve(dir);
|
|
17134
|
-
const kept = this.entries.find((e) => e.root
|
|
17135
|
-
const rest = this.entries.filter((e) => e.root
|
|
17491
|
+
const kept = this.entries.find((e) => samePath(e.root, root))?.name;
|
|
17492
|
+
const rest = this.entries.filter((e) => !samePath(e.root, root));
|
|
17136
17493
|
this.entries = [
|
|
17137
17494
|
{ root, name: name || kept || basename(root) || root, usedAt: now },
|
|
17138
17495
|
...rest
|
|
@@ -17141,7 +17498,7 @@ var RecentWorkspaces = class {
|
|
|
17141
17498
|
}
|
|
17142
17499
|
forget(dir) {
|
|
17143
17500
|
const root = resolve(dir);
|
|
17144
|
-
const next = this.entries.filter((e) => e.root
|
|
17501
|
+
const next = this.entries.filter((e) => !samePath(e.root, root));
|
|
17145
17502
|
if (next.length === this.entries.length) return;
|
|
17146
17503
|
this.entries = next;
|
|
17147
17504
|
this.save();
|
|
@@ -17154,7 +17511,7 @@ var RecentWorkspaces = class {
|
|
|
17154
17511
|
parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
17155
17512
|
} catch (err) {
|
|
17156
17513
|
this.loadErrors.push(
|
|
17157
|
-
(lang) => t("workspace.recent_unreadable", { path: this.filePath, reason:
|
|
17514
|
+
(lang) => t("workspace.recent_unreadable", { path: this.filePath, reason: describe6(err) }, lang)
|
|
17158
17515
|
);
|
|
17159
17516
|
return;
|
|
17160
17517
|
}
|
|
@@ -17207,7 +17564,7 @@ var RecentWorkspaces = class {
|
|
|
17207
17564
|
} catch (err) {
|
|
17208
17565
|
rmSync(tmp, { force: true });
|
|
17209
17566
|
this.writeErrors.push(
|
|
17210
|
-
(lang) => t("workspace.recent_write_failed", { path: this.filePath, reason:
|
|
17567
|
+
(lang) => t("workspace.recent_write_failed", { path: this.filePath, reason: describe6(err) }, lang)
|
|
17211
17568
|
);
|
|
17212
17569
|
}
|
|
17213
17570
|
}
|
|
@@ -17217,6 +17574,87 @@ function isRecentWorkspace(value) {
|
|
|
17217
17574
|
const v = value;
|
|
17218
17575
|
return typeof v["root"] === "string" && v["root"].length > 0 && typeof v["name"] === "string" && typeof v["usedAt"] === "number";
|
|
17219
17576
|
}
|
|
17577
|
+
var MAX_LAST_OPEN_SESSIONS = 20;
|
|
17578
|
+
var FILE_VERSION3 = 1;
|
|
17579
|
+
function describe7(err) {
|
|
17580
|
+
return err instanceof Error ? err.message : String(err);
|
|
17581
|
+
}
|
|
17582
|
+
var LastOpenSessions = class {
|
|
17583
|
+
constructor(filePath = lastSessionsPath()) {
|
|
17584
|
+
this.filePath = filePath;
|
|
17585
|
+
this.load();
|
|
17586
|
+
}
|
|
17587
|
+
filePath;
|
|
17588
|
+
entries = [];
|
|
17589
|
+
loadErrors = [];
|
|
17590
|
+
writeErrors = [];
|
|
17591
|
+
get(root) {
|
|
17592
|
+
const key = resolve(root);
|
|
17593
|
+
return this.entries.find((e) => samePath(e.root, key))?.sessionId ?? null;
|
|
17594
|
+
}
|
|
17595
|
+
remember(root, sessionId, now) {
|
|
17596
|
+
const key = resolve(root);
|
|
17597
|
+
const head = this.entries[0];
|
|
17598
|
+
if (head && samePath(head.root, key) && head.sessionId === sessionId) return;
|
|
17599
|
+
const rest = this.entries.filter((e) => !samePath(e.root, key));
|
|
17600
|
+
this.entries = [{ root: key, sessionId, at: now }, ...rest].slice(0, MAX_LAST_OPEN_SESSIONS);
|
|
17601
|
+
this.save();
|
|
17602
|
+
}
|
|
17603
|
+
forget(root) {
|
|
17604
|
+
const key = resolve(root);
|
|
17605
|
+
const next = this.entries.filter((e) => !samePath(e.root, key));
|
|
17606
|
+
if (next.length === this.entries.length) return;
|
|
17607
|
+
this.entries = next;
|
|
17608
|
+
this.save();
|
|
17609
|
+
}
|
|
17610
|
+
load() {
|
|
17611
|
+
this.entries = [];
|
|
17612
|
+
if (!existsSync(this.filePath)) return;
|
|
17613
|
+
let parsed;
|
|
17614
|
+
try {
|
|
17615
|
+
parsed = JSON.parse(readFileSync(this.filePath, "utf-8"));
|
|
17616
|
+
} catch (err) {
|
|
17617
|
+
this.loadErrors.push(
|
|
17618
|
+
(lang) => t("last_session.unreadable", { path: this.filePath, reason: describe7(err) }, lang)
|
|
17619
|
+
);
|
|
17620
|
+
return;
|
|
17621
|
+
}
|
|
17622
|
+
this.adopt(parsed);
|
|
17623
|
+
}
|
|
17624
|
+
adopt(parsed) {
|
|
17625
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return;
|
|
17626
|
+
const file = parsed;
|
|
17627
|
+
if (file.version !== FILE_VERSION3) return;
|
|
17628
|
+
if (!Array.isArray(file.sessions)) return;
|
|
17629
|
+
this.entries = file.sessions.filter(isLastOpenSession).sort((a, b) => b.at - a.at).slice(0, MAX_LAST_OPEN_SESSIONS);
|
|
17630
|
+
}
|
|
17631
|
+
save() {
|
|
17632
|
+
const body2 = JSON.stringify(
|
|
17633
|
+
{ version: FILE_VERSION3, sessions: this.entries },
|
|
17634
|
+
null,
|
|
17635
|
+
2
|
|
17636
|
+
);
|
|
17637
|
+
const tmp = `${this.filePath}.${process.pid}.tmp`;
|
|
17638
|
+
try {
|
|
17639
|
+
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
17640
|
+
writeFileSync(tmp, body2, { encoding: "utf-8", mode: 384 });
|
|
17641
|
+
renameSync(tmp, this.filePath);
|
|
17642
|
+
} catch (err) {
|
|
17643
|
+
rmSync(tmp, { force: true });
|
|
17644
|
+
this.writeErrors.push(
|
|
17645
|
+
(lang) => t("last_session.write_failed", { path: this.filePath, reason: describe7(err) }, lang)
|
|
17646
|
+
);
|
|
17647
|
+
}
|
|
17648
|
+
}
|
|
17649
|
+
};
|
|
17650
|
+
function isLastOpenSession(value) {
|
|
17651
|
+
if (typeof value !== "object" || value === null) return false;
|
|
17652
|
+
const v = value;
|
|
17653
|
+
return typeof v["root"] === "string" && v["root"].length > 0 && typeof v["sessionId"] === "string" && v["sessionId"].length > 0 && typeof v["at"] === "number";
|
|
17654
|
+
}
|
|
17655
|
+
function ruleAskActive(level) {
|
|
17656
|
+
return level !== "bypass";
|
|
17657
|
+
}
|
|
17220
17658
|
function checkCodeExec(isolation) {
|
|
17221
17659
|
if (isolation === "os") {
|
|
17222
17660
|
return { allowed: true, reason: t("permission_reason.sandbox_os"), code: "sandbox-isolation" };
|
|
@@ -17228,8 +17666,7 @@ function checkCodeExec(isolation) {
|
|
|
17228
17666
|
code: "sandbox-isolation"
|
|
17229
17667
|
};
|
|
17230
17668
|
}
|
|
17231
|
-
function checkAuto(
|
|
17232
|
-
if (operation.type === "code_exec") return checkCodeExec(isolation);
|
|
17669
|
+
function checkAuto() {
|
|
17233
17670
|
return { allowed: true, code: "level-default" };
|
|
17234
17671
|
}
|
|
17235
17672
|
function checkPlan(operation) {
|
|
@@ -17287,7 +17724,7 @@ function decideByLevel(level, operation, isolation, extraRoots = []) {
|
|
|
17287
17724
|
case "bypass":
|
|
17288
17725
|
return { allowed: true, code: "level-default" };
|
|
17289
17726
|
case "auto":
|
|
17290
|
-
return checkAuto(
|
|
17727
|
+
return checkAuto();
|
|
17291
17728
|
case "plan":
|
|
17292
17729
|
return checkPlan(operation);
|
|
17293
17730
|
case "acceptEdits":
|
|
@@ -17465,11 +17902,11 @@ var ApprovalCache = class {
|
|
|
17465
17902
|
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
17466
17903
|
}
|
|
17467
17904
|
normalizeTarget(target) {
|
|
17468
|
-
const
|
|
17469
|
-
if (!
|
|
17470
|
-
const unix =
|
|
17905
|
+
const t81 = target.trim();
|
|
17906
|
+
if (!t81) return "";
|
|
17907
|
+
const unix = t81.replace(/\\/g, "/");
|
|
17471
17908
|
if (unix.startsWith("/") || /^[A-Za-z]:\//.test(unix)) return resolve(unix);
|
|
17472
|
-
return
|
|
17909
|
+
return t81;
|
|
17473
17910
|
}
|
|
17474
17911
|
load() {
|
|
17475
17912
|
try {
|
|
@@ -17572,9 +18009,9 @@ function createSharedPermissionState(cache) {
|
|
|
17572
18009
|
};
|
|
17573
18010
|
}
|
|
17574
18011
|
function cacheKeyFor(raw) {
|
|
17575
|
-
const
|
|
17576
|
-
if (!
|
|
17577
|
-
return
|
|
18012
|
+
const t81 = raw.trim();
|
|
18013
|
+
if (!t81) return null;
|
|
18014
|
+
return t81.slice(0, 500);
|
|
17578
18015
|
}
|
|
17579
18016
|
// src/permission/manager.ts
|
|
17580
18017
|
var log3 = createLogger("permission");
|
|
@@ -17747,16 +18184,22 @@ var PermissionManager = class _PermissionManager {
|
|
|
17747
18184
|
}
|
|
17748
18185
|
const cached = this.approvalCacheActive() ? this.cachedDecision(operation) : null;
|
|
17749
18186
|
if (cached) return cached;
|
|
17750
|
-
|
|
17751
|
-
|
|
17752
|
-
|
|
17753
|
-
|
|
17754
|
-
|
|
17755
|
-
|
|
17756
|
-
|
|
17757
|
-
|
|
18187
|
+
const asked = listMatch?.verdict === "ask" ? {
|
|
18188
|
+
allowed: false,
|
|
18189
|
+
requireApproval: true,
|
|
18190
|
+
reason: t("permission_reason.rule_ask", { rule: listMatch.rule }),
|
|
18191
|
+
code: "rule-match"
|
|
18192
|
+
} : ruleDecision?.requireApproval ?? false ? ruleDecision : null;
|
|
18193
|
+
if (asked) {
|
|
18194
|
+
if (!ruleAskActive(this.level)) {
|
|
18195
|
+
return {
|
|
18196
|
+
allowed: true,
|
|
18197
|
+
reason: t("permission_reason.bypass_rule_ask", { reason: asked.reason ?? "" }),
|
|
18198
|
+
code: asked.code
|
|
18199
|
+
};
|
|
18200
|
+
}
|
|
18201
|
+
return { ...asked, ...this.rememberFlag() };
|
|
17758
18202
|
}
|
|
17759
|
-
if (ruleDecision?.requireApproval) return { ...ruleDecision, ...this.rememberFlag() };
|
|
17760
18203
|
if (listMatch?.verdict === "allow") {
|
|
17761
18204
|
return {
|
|
17762
18205
|
allowed: true,
|
|
@@ -17904,10 +18347,13 @@ function byRule(rules, probe) {
|
|
|
17904
18347
|
}
|
|
17905
18348
|
return hit ? { ...hit, conditional } : { verdict: null, conditional };
|
|
17906
18349
|
}
|
|
18350
|
+
function effectiveRules(rules, level) {
|
|
18351
|
+
return ruleAskActive(level) ? rules : { ...rules, ask: [] };
|
|
18352
|
+
}
|
|
17907
18353
|
function gateForTool(tool, rules, level, isolation) {
|
|
17908
18354
|
const type = mapOperation(tool);
|
|
17909
18355
|
const probe = { type, toolName: tool.name };
|
|
17910
|
-
const rule = byRule(rules, probe);
|
|
18356
|
+
const rule = byRule(effectiveRules(rules, level), probe);
|
|
17911
18357
|
if (rule.verdict) {
|
|
17912
18358
|
return {
|
|
17913
18359
|
type,
|
|
@@ -18380,6 +18826,24 @@ function acquireScheduleLock(db, scheduleId, clock2 = Date.now) {
|
|
|
18380
18826
|
}
|
|
18381
18827
|
};
|
|
18382
18828
|
}
|
|
18829
|
+
function isLive(holder, now) {
|
|
18830
|
+
if (holder.heartbeatAt < now - LOCK_STALE_MS) return false;
|
|
18831
|
+
return holder.host !== hostname() || pidAlive(holder.pid);
|
|
18832
|
+
}
|
|
18833
|
+
function listRunningSchedules(db, clock2 = Date.now) {
|
|
18834
|
+
const now = clock2();
|
|
18835
|
+
const rows = db.prepare(
|
|
18836
|
+
`SELECT schedule_id AS scheduleId, pid, host,
|
|
18837
|
+
acquired_at AS acquiredAt, heartbeat_at AS heartbeatAt
|
|
18838
|
+
FROM schedule_locks`
|
|
18839
|
+
).all();
|
|
18840
|
+
return rows.filter((row) => isLive(row, now)).map((row) => ({
|
|
18841
|
+
scheduleId: row.scheduleId,
|
|
18842
|
+
startedAt: row.acquiredAt,
|
|
18843
|
+
pid: row.pid,
|
|
18844
|
+
host: row.host
|
|
18845
|
+
}));
|
|
18846
|
+
}
|
|
18383
18847
|
function readHolder(db, scheduleId) {
|
|
18384
18848
|
const row = db.prepare(
|
|
18385
18849
|
"SELECT pid, host, acquired_at AS acquiredAt, heartbeat_at AS heartbeatAt FROM schedule_locks WHERE schedule_id = ?"
|
|
@@ -18481,6 +18945,12 @@ function pruneRecordings(dir, opts = {}) {
|
|
|
18481
18945
|
}
|
|
18482
18946
|
return { removed: removed.filter((p) => !existsSync(p)), remainingBytes: Math.max(0, total) };
|
|
18483
18947
|
}
|
|
18948
|
+
function removeRecordings(dir) {
|
|
18949
|
+
try {
|
|
18950
|
+
rmSync(dir, { recursive: true, force: true });
|
|
18951
|
+
} catch {
|
|
18952
|
+
}
|
|
18953
|
+
}
|
|
18484
18954
|
function readRecording(path) {
|
|
18485
18955
|
if (!existsSync(path)) return [];
|
|
18486
18956
|
const out = [];
|
|
@@ -18620,9 +19090,15 @@ var ScheduleRegistrar = class {
|
|
|
18620
19090
|
this.opts.store.setEnabled(def.id, enabled);
|
|
18621
19091
|
return { ok: false, reason: "unsupported-platform" };
|
|
18622
19092
|
}
|
|
18623
|
-
if (enabled)
|
|
18624
|
-
|
|
18625
|
-
|
|
19093
|
+
if (enabled) {
|
|
19094
|
+
this.opts.store.setEnabled(def.id, true);
|
|
19095
|
+
const on = { ...def, enabled: true };
|
|
19096
|
+
if (!def.osTaskId) return this.register(on);
|
|
19097
|
+
const res2 = await backend.setEnabled(def.osTaskId, true);
|
|
19098
|
+
return res2.ok ? { ok: true, warnings: [] } : this.register(on);
|
|
19099
|
+
}
|
|
19100
|
+
const res = def.osTaskId ? await backend.setEnabled(def.osTaskId, false) : { ok: true };
|
|
19101
|
+
this.opts.store.setEnabled(def.id, false);
|
|
18626
19102
|
return res.ok ? { ok: true, warnings: [] } : { ok: false, reason: "backend-error", detail: res.detail };
|
|
18627
19103
|
}
|
|
18628
19104
|
async retire(def) {
|
|
@@ -19733,7 +20209,7 @@ function runCommandHook(config, event, workDir) {
|
|
|
19733
20209
|
const baseEnv = sanitizeEnvironment(process.env);
|
|
19734
20210
|
const injectedEnv = injectEpochEnv(event, config.pluginRoot);
|
|
19735
20211
|
const hookEnv = { ...baseEnv, ...injectedEnv, ...config.env };
|
|
19736
|
-
return new Promise((
|
|
20212
|
+
return new Promise((resolve16) => {
|
|
19737
20213
|
const child = spawn(config.command, {
|
|
19738
20214
|
shell: true,
|
|
19739
20215
|
cwd: workDir,
|
|
@@ -19747,7 +20223,7 @@ function runCommandHook(config, event, workDir) {
|
|
|
19747
20223
|
if (!settled) {
|
|
19748
20224
|
settled = true;
|
|
19749
20225
|
child.kill("SIGKILL");
|
|
19750
|
-
|
|
20226
|
+
resolve16({
|
|
19751
20227
|
exitCode: -1,
|
|
19752
20228
|
stdout,
|
|
19753
20229
|
stderr,
|
|
@@ -19783,7 +20259,7 @@ function runCommandHook(config, event, workDir) {
|
|
|
19783
20259
|
}
|
|
19784
20260
|
} catch {
|
|
19785
20261
|
}
|
|
19786
|
-
|
|
20262
|
+
resolve16({
|
|
19787
20263
|
exitCode,
|
|
19788
20264
|
stdout: stdout.trim(),
|
|
19789
20265
|
stderr: stderr.trim(),
|
|
@@ -19796,7 +20272,7 @@ function runCommandHook(config, event, workDir) {
|
|
|
19796
20272
|
clearTimeout(timer);
|
|
19797
20273
|
if (settled) return;
|
|
19798
20274
|
settled = true;
|
|
19799
|
-
|
|
20275
|
+
resolve16({
|
|
19800
20276
|
exitCode: -1,
|
|
19801
20277
|
stdout,
|
|
19802
20278
|
stderr,
|
|
@@ -19909,7 +20385,7 @@ var HookManager = class {
|
|
|
19909
20385
|
return { blocked: true, reason: result.rejectReason || t("hook_load.rejected") };
|
|
19910
20386
|
}
|
|
19911
20387
|
} catch (err) {
|
|
19912
|
-
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${
|
|
20388
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe9(err)}`, {
|
|
19913
20389
|
hookType: type,
|
|
19914
20390
|
command: config.command
|
|
19915
20391
|
});
|
|
@@ -19927,7 +20403,7 @@ var HookManager = class {
|
|
|
19927
20403
|
(_, reject2) => setTimeout(() => reject2(new Error("Hook timeout")), HOOK_TIMEOUT_MS)
|
|
19928
20404
|
)
|
|
19929
20405
|
]).catch((err) => {
|
|
19930
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${
|
|
20406
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe9(err)}`, {
|
|
19931
20407
|
hookType: type,
|
|
19932
20408
|
plugin: reg.plugin
|
|
19933
20409
|
});
|
|
@@ -19939,7 +20415,7 @@ var HookManager = class {
|
|
|
19939
20415
|
if (!matchesHook(entry.matcher, event)) continue;
|
|
19940
20416
|
for (const config of entry.configs) {
|
|
19941
20417
|
runCommandHook(config, event, ctx.workDir).then((result) => reportIfNeverRan(this.log, type, config, result)).catch((err) => {
|
|
19942
|
-
this.log("warn", `[HookManager] ${type} \u7684 command hook \u5F02\u6B65\u5F02\u5E38: ${
|
|
20418
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u5F02\u6B65\u5F02\u5E38: ${describe9(err)}`, {
|
|
19943
20419
|
hookType: type,
|
|
19944
20420
|
command: config.command
|
|
19945
20421
|
});
|
|
@@ -19960,7 +20436,7 @@ var HookManager = class {
|
|
|
19960
20436
|
]);
|
|
19961
20437
|
if (result !== null && result !== void 0) return result;
|
|
19962
20438
|
} catch (err) {
|
|
19963
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${
|
|
20439
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe9(err)}`, {
|
|
19964
20440
|
hookType: type,
|
|
19965
20441
|
plugin: reg.plugin
|
|
19966
20442
|
});
|
|
@@ -19981,7 +20457,7 @@ var HookManager = class {
|
|
|
19981
20457
|
]);
|
|
19982
20458
|
if (result) results.push(result);
|
|
19983
20459
|
} catch (err) {
|
|
19984
|
-
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${
|
|
20460
|
+
this.log("warn", `[HookManager] ${type} (${reg.plugin}) \u5931\u8D25: ${describe9(err)}`, {
|
|
19985
20461
|
hookType: type,
|
|
19986
20462
|
plugin: reg.plugin
|
|
19987
20463
|
});
|
|
@@ -19998,7 +20474,7 @@ var HookManager = class {
|
|
|
19998
20474
|
const verdict = verdictOf2(result);
|
|
19999
20475
|
if (verdict) results.push(verdict);
|
|
20000
20476
|
} catch (err) {
|
|
20001
|
-
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${
|
|
20477
|
+
this.log("warn", `[HookManager] ${type} \u7684 command hook \u6267\u884C\u5F02\u5E38: ${describe9(err)}`, {
|
|
20002
20478
|
hookType: type,
|
|
20003
20479
|
command: config.command
|
|
20004
20480
|
});
|
|
@@ -20014,7 +20490,7 @@ var HookManager = class {
|
|
|
20014
20490
|
return [...list].sort((a, b) => a.priority - b.priority);
|
|
20015
20491
|
}
|
|
20016
20492
|
};
|
|
20017
|
-
function
|
|
20493
|
+
function describe9(err) {
|
|
20018
20494
|
return err instanceof Error ? err.message : String(err);
|
|
20019
20495
|
}
|
|
20020
20496
|
function verdictOf2(result) {
|
|
@@ -21311,7 +21787,7 @@ async function withStaged(source, opts, fn) {
|
|
|
21311
21787
|
shape = existsSync(join(unpacked, SKILL_FILE)) ? "skill-dir" : "tree";
|
|
21312
21788
|
}
|
|
21313
21789
|
const staged = stageImport(root, staging, shape, opts.lang);
|
|
21314
|
-
const preview3 =
|
|
21790
|
+
const preview3 = describe10(source, form, staged.skills, staged.issues, opts.existing, opts.lang);
|
|
21315
21791
|
if (preview3.skills.length === 0) {
|
|
21316
21792
|
const detail = t("skill.import_empty", { path: source }, opts.lang);
|
|
21317
21793
|
return { ok: false, reason: "empty", detail, issues: preview3.issues };
|
|
@@ -21322,7 +21798,7 @@ async function withStaged(source, opts, fn) {
|
|
|
21322
21798
|
rmSync(unpacked, { recursive: true, force: true });
|
|
21323
21799
|
}
|
|
21324
21800
|
}
|
|
21325
|
-
function
|
|
21801
|
+
function describe10(source, form, staged, issues, existing, lang) {
|
|
21326
21802
|
const byName = new Map(existing.map((s) => [s.name, s.scope]));
|
|
21327
21803
|
const entries2 = [];
|
|
21328
21804
|
const taken = /* @__PURE__ */ new Set();
|
|
@@ -21992,6 +22468,19 @@ var ContextCompressor = class {
|
|
|
21992
22468
|
};
|
|
21993
22469
|
}
|
|
21994
22470
|
const { head, middle, tail } = this.determineBoundaries(pruned.messages, config);
|
|
22471
|
+
if (middle.length === 0) {
|
|
22472
|
+
const kept = this.cleanupOrphans(pruned.messages);
|
|
22473
|
+
this.turnsSinceCompress = 0;
|
|
22474
|
+
return {
|
|
22475
|
+
messages: kept,
|
|
22476
|
+
summary: "",
|
|
22477
|
+
...prunedCounters,
|
|
22478
|
+
summarizedMessages: 0,
|
|
22479
|
+
newTokenCount: this.estimateTokens(kept),
|
|
22480
|
+
droppedOrphans: pruned.messages.length - kept.length,
|
|
22481
|
+
summarySkipped: true
|
|
22482
|
+
};
|
|
22483
|
+
}
|
|
21995
22484
|
const nl = "\n";
|
|
21996
22485
|
const middleText = middle.map((m) => `${m.role}: ${m.content}`).join(nl);
|
|
21997
22486
|
const summarized = await this.generateSummary(
|
|
@@ -22027,6 +22516,7 @@ var ContextCompressor = class {
|
|
|
22027
22516
|
summarizedMessages: middle.length,
|
|
22028
22517
|
newTokenCount: this.estimateTokens(result),
|
|
22029
22518
|
droppedOrphans,
|
|
22519
|
+
...summary && droppedOrphans === 0 && middle.length > 0 ? { carriedHead: head.length, carriedTail: tail.length } : {},
|
|
22030
22520
|
...summarized?.usage ? { usage: summarized.usage } : {},
|
|
22031
22521
|
...summarized?.model ? { model: summarized.model } : {}
|
|
22032
22522
|
};
|
|
@@ -22158,10 +22648,10 @@ ${extra}` : withGoal;
|
|
|
22158
22648
|
return messages.reduce((sum, m) => sum + estimateTokens(m.content), 0);
|
|
22159
22649
|
}
|
|
22160
22650
|
};
|
|
22161
|
-
var
|
|
22651
|
+
var FILE_VERSION4 = 1;
|
|
22162
22652
|
var LEVELS = ["trusted", "untrusted"];
|
|
22163
22653
|
var SCOPES = ["directory", "directory-tree"];
|
|
22164
|
-
function
|
|
22654
|
+
function describe11(err) {
|
|
22165
22655
|
return err instanceof Error ? err.message : String(err);
|
|
22166
22656
|
}
|
|
22167
22657
|
function covers(base, target, scope) {
|
|
@@ -22170,9 +22660,6 @@ function covers(base, target, scope) {
|
|
|
22170
22660
|
const rel = relative(base, target);
|
|
22171
22661
|
return !rel.startsWith("..") && !isAbsolute(rel);
|
|
22172
22662
|
}
|
|
22173
|
-
function samePath(a, b) {
|
|
22174
|
-
return relative(a, b) === "";
|
|
22175
|
-
}
|
|
22176
22663
|
var TrustManager = class {
|
|
22177
22664
|
constructor(filePath = trustPath()) {
|
|
22178
22665
|
this.filePath = filePath;
|
|
@@ -22238,7 +22725,7 @@ var TrustManager = class {
|
|
|
22238
22725
|
raw = readFileSync(this.filePath, "utf-8");
|
|
22239
22726
|
} catch (err) {
|
|
22240
22727
|
this.loadErrors.push(
|
|
22241
|
-
t("trust_gate.record_read_failed", { path: this.filePath, reason:
|
|
22728
|
+
t("trust_gate.record_read_failed", { path: this.filePath, reason: describe11(err) })
|
|
22242
22729
|
);
|
|
22243
22730
|
return;
|
|
22244
22731
|
}
|
|
@@ -22247,7 +22734,7 @@ var TrustManager = class {
|
|
|
22247
22734
|
parsed = JSON.parse(raw);
|
|
22248
22735
|
} catch (err) {
|
|
22249
22736
|
this.loadErrors.push(
|
|
22250
|
-
t("trust_gate.record_bad_json", { path: this.filePath, reason:
|
|
22737
|
+
t("trust_gate.record_bad_json", { path: this.filePath, reason: describe11(err) })
|
|
22251
22738
|
);
|
|
22252
22739
|
return;
|
|
22253
22740
|
}
|
|
@@ -22259,12 +22746,12 @@ var TrustManager = class {
|
|
|
22259
22746
|
return;
|
|
22260
22747
|
}
|
|
22261
22748
|
const file = parsed;
|
|
22262
|
-
if (file.version !==
|
|
22749
|
+
if (file.version !== FILE_VERSION4) {
|
|
22263
22750
|
this.loadErrors.push(
|
|
22264
22751
|
t("trust_gate.record_bad_version", {
|
|
22265
22752
|
path: this.filePath,
|
|
22266
22753
|
found: String(file.version),
|
|
22267
|
-
expected:
|
|
22754
|
+
expected: FILE_VERSION4
|
|
22268
22755
|
})
|
|
22269
22756
|
);
|
|
22270
22757
|
return;
|
|
@@ -22285,7 +22772,7 @@ var TrustManager = class {
|
|
|
22285
22772
|
save() {
|
|
22286
22773
|
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
22287
22774
|
const body2 = JSON.stringify(
|
|
22288
|
-
{ version:
|
|
22775
|
+
{ version: FILE_VERSION4, records: this.records },
|
|
22289
22776
|
null,
|
|
22290
22777
|
2
|
|
22291
22778
|
);
|
|
@@ -22296,7 +22783,7 @@ var TrustManager = class {
|
|
|
22296
22783
|
} catch (err) {
|
|
22297
22784
|
rmSync(tmp, { force: true });
|
|
22298
22785
|
throw new Error(
|
|
22299
|
-
t("trust_gate.record_write_failed", { path: this.filePath, reason:
|
|
22786
|
+
t("trust_gate.record_write_failed", { path: this.filePath, reason: describe11(err) })
|
|
22300
22787
|
);
|
|
22301
22788
|
}
|
|
22302
22789
|
}
|
|
@@ -22539,7 +23026,7 @@ var CodeSandbox = class {
|
|
|
22539
23026
|
...IS_WINDOWS ? { windowsHide: true } : {}
|
|
22540
23027
|
};
|
|
22541
23028
|
const child = spawn(command, args, spawnOpts);
|
|
22542
|
-
return new Promise((
|
|
23029
|
+
return new Promise((resolve16) => {
|
|
22543
23030
|
let stdout = "";
|
|
22544
23031
|
let stderr = "";
|
|
22545
23032
|
let killedForOutput = false;
|
|
@@ -22565,7 +23052,7 @@ var CodeSandbox = class {
|
|
|
22565
23052
|
child.on("error", (err) => {
|
|
22566
23053
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
22567
23054
|
if (err.code === "ENOENT") {
|
|
22568
|
-
|
|
23055
|
+
resolve16({
|
|
22569
23056
|
success: false,
|
|
22570
23057
|
output: "",
|
|
22571
23058
|
error: `[\u9519\u8BEF] \u627E\u4E0D\u5230\u89E3\u91CA\u5668: ${command}`,
|
|
@@ -22574,7 +23061,7 @@ var CodeSandbox = class {
|
|
|
22574
23061
|
});
|
|
22575
23062
|
return;
|
|
22576
23063
|
}
|
|
22577
|
-
|
|
23064
|
+
resolve16({
|
|
22578
23065
|
success: false,
|
|
22579
23066
|
output: "",
|
|
22580
23067
|
error: `[\u9519\u8BEF] ${err.message}`,
|
|
@@ -22588,7 +23075,7 @@ var CodeSandbox = class {
|
|
|
22588
23075
|
if (stderr.length < MAX_OUTPUT) stderr += errDecoder?.end() ?? "";
|
|
22589
23076
|
const duration = Date.now() - start;
|
|
22590
23077
|
if (killedForOutput) {
|
|
22591
|
-
|
|
23078
|
+
resolve16({
|
|
22592
23079
|
success: false,
|
|
22593
23080
|
output: trunc(stdout, stderr),
|
|
22594
23081
|
error: `[\u8F93\u51FA\u8D85\u9650] \u8D85\u8FC7 ${MAX_OUTPUT} \u5B57\u8282\uFF0C\u5DF2\u7EC8\u6B62`,
|
|
@@ -22598,7 +23085,7 @@ var CodeSandbox = class {
|
|
|
22598
23085
|
return;
|
|
22599
23086
|
}
|
|
22600
23087
|
if (sig) {
|
|
22601
|
-
|
|
23088
|
+
resolve16({
|
|
22602
23089
|
success: false,
|
|
22603
23090
|
output: trunc(stdout, stderr),
|
|
22604
23091
|
error: opts.signal?.aborted ? "[\u5DF2\u53D6\u6D88]" : "[\u8D85\u65F6] \u6267\u884C\u8D85\u65F6",
|
|
@@ -22610,7 +23097,7 @@ var CodeSandbox = class {
|
|
|
22610
23097
|
const output = trunc(stdout, stderr);
|
|
22611
23098
|
if (code !== 0 && code !== null) {
|
|
22612
23099
|
const oom = /heap out of memory|allocation failed/i.test(stderr);
|
|
22613
|
-
|
|
23100
|
+
resolve16({
|
|
22614
23101
|
success: false,
|
|
22615
23102
|
output,
|
|
22616
23103
|
error: oom ? `[\u5185\u5B58\u8D85\u9650] \u8D85\u8FC7 ${MAX_MEMORY}MB` : `[\u8FD0\u884C\u65F6\u9519\u8BEF] exit ${code}: ${stderr.slice(0, 200)}`,
|
|
@@ -22619,7 +23106,7 @@ var CodeSandbox = class {
|
|
|
22619
23106
|
});
|
|
22620
23107
|
return;
|
|
22621
23108
|
}
|
|
22622
|
-
|
|
23109
|
+
resolve16({ success: true, output, duration });
|
|
22623
23110
|
});
|
|
22624
23111
|
});
|
|
22625
23112
|
}
|
|
@@ -22679,4 +23166,4 @@ function trunc(stdout, stderr) {
|
|
|
22679
23166
|
* `--tree` 的命令帮助里,让用户自己知道 `--tree` 意味着什么。
|
|
22680
23167
|
*/
|
|
22681
23168
|
|
|
22682
|
-
export { AGENT_ROLE_DIAG_MODULE, ARTIFACT_MAX_TOTAL_BYTES, ARTIFACT_RETENTION_DEFAULTS, ATTACHMENT_MAX_TOTAL_BYTES, ATTACHMENT_RETENTION_DEFAULTS, AgentLoop, ApprovalCache, BLOCKED_TOOLS, BudgetGuard, BudgetStore, CHECKPOINT_MAX_TOTAL_BYTES, CLAUDE_EVENT_NAMES, CLAUDE_TOOL_NAMES, CODE_MODE_LIMITS, CODE_MODE_SDK_TAG, CONFIG_KEYS, CURRENT_CONFIG_VERSION, CheckpointManager, CheckpointStore, CodeSandbox, ComplianceEngine, ContextCompressor, DEFAULT_COMPLIANCE_ACTIONS, DEFAULT_COMPLIANCE_SETTINGS, DEFAULT_COMPRESSION_THRESHOLD, DEFAULT_GOAL_MAX_ROUNDS, DEFAULT_MAX_HOLD_CHARS, DelegateManager, EMPTY_RULES, EPOCH_DISK_LEDGER, EpochConfigSchema, FTS_TABLES, FTS_TRIGGERS, GOAL_BLOCK_CODES, GoalService, GoalStore, HEADLESS_AUDIT_CODES, HookManager, INSTRUCTION_BUDGET_CHARS, INSTRUCTION_FILES, ImageLoadError, ImportTrustStore, LAUNCHD_LABEL_PREFIX, LOCK_HEARTBEAT_MS, LOCK_STALE_MS, MARKETPLACE_DISPLAY_FIELDS, MARKETPLACE_FILE, MAX_AUDIT_ENTRIES, MAX_COMMAND_DEPTH, MAX_GOAL_MAX_ROUNDS, MAX_IMPORT_DEPTH, MAX_OBJECTIVE_CHARS, MAX_REASON_CHARS, MAX_RECENT_WORKSPACES, MODEL_GIVE_UP_THRESHOLD, MULTIMODAL_DEFAULTS, ManagedPolicyError, ManagedSettingsSchema, MemoryManager, MemoryReviewer, ModelFailureTracker, NOMINAL_TOTAL_BYTES, NO_REVEALED_TOOLS, PACK_EXCLUDES, PACK_MAX_BYTES, PACK_MAX_FILES, PERMISSION_AUDIT_CODES, PLUGIN_LAYOUT, PLUGIN_MANIFEST_FILE, PLUGIN_NAME_PATTERN, PLUGIN_ROOT_ENV, PLUGIN_ROOT_TOKEN, POLICY_DECISIONS, PROBE_VERSION, PROJECT_AGENTS_SUBDIR, PROVIDER_NO_CREDENTIAL, PermissionManager, PlanModeState, PluginAuthorSchema, PluginStore, PolicyRuleSchema, ProviderError, ProviderRouter, RECORDING_KEEP_RUNS, RECORDING_MAX_BYTES, ROLE_FRONTMATTER_SCHEMA, RUN_CODE_TOOL, RecentWorkspaces, SANDBOX_COVERS, SANDBOX_EXCLUDES, SCALAR_KEYS, SCHEDULE_DEFAULTS, SCHEDULE_DEFAULT_ALLOWLIST, SCHEDULE_ISSUE_CODES, SCHTASKS_FOLDER, SESSION_MESSAGES_READ_TOOL, SESSION_MESSAGES_SEARCH_TOOL, SESSION_QUERY_TOOLS, SESSION_SEARCH_TOOL, SESSION_TRACE_TOOL, SETTINGS_LAYER_ORDER, SETTING_WRITE_KEYS, SETTING_WRITE_LAYERS, SKILL_CREATE_TOOL, SKILL_EDIT_TOOL, SKILL_PATCH_TOOL, SKILL_VIEW_TOOL, SKILL_WRITE_FILE_TOOL, SLASH_COMMANDS_DIAG_MODULE, ScheduleRecorder, ScheduleRegistrar, ScheduleStore, SessionManager, SessionQueries, SessionReferences, SettingsFileError, SettingsFileSchema, SkillLearner, SkillSystem, TOOL_SEARCH_TOOL, TaskNoticeTracker, ToolRegistry, TrackerDB, TrustManager, Workspace, acquireScheduleLock, addMarketplace, addUsage, admitArtifact, admitArtifacts, affectedPaths, artifactLaunchArgv, artifactOpenRefusal, assertLevelAllowed, blockedRoleTools, buildContextBreakdown, buildFireArgv, buildFtsMatchQuery, buildSchemaExports, buildSystemPrompt, buildTrigramMatchQuery, builtinRoles, checkEpochVersion, checkFtsHealth, checkShadowing, classifyProviderError, clearModelCache, coalesceRecording, codeModeWorkerPath, commandNameFromRelPath, compileRuleLists, compressionOptions, computeCost, computeCostMicros, computeExecHash, countRules, createAllowAllGate, createAllowAllImportGate, createAskQuestionTool, createCodeExecTool, createDelegateTool, createDenyAllGate, createDenyAllImportGate, createGoalTool, createImportGate, createMemoryTool, createPlanModeTools, createRoleFile, createRoleScope, createRunCodeTool, createScheduleDraftTool, createSessionMessagesReadTool, createSessionMessagesSearchTool, createSessionSearchTool, createSessionSearchTools, createSessionTraceTool, createSkillViewTool, createSkillWriteTools, createTodoTool, createToolRevealState, createToolScope, createToolSearchTool, createTrustGate, currentEpochVersion, decideImport, decideTrust, defaultConfig, defaultModelOf, describeArtifactRefusal, describeBackgroundTask, describeHeadlessPolicy, describeIsolation, describeJsonError, diagnoseSchedules, discoverMarkdown, discoverModels, discoverProject, displayCurrency, draftCommandLine, draftWidening, escapeRuleContent, estimateImageTokens, estimateRunTokens, estimateTokens, evaluateSelection, expandCommand, expandImports, explainSetting, extractArchive, findInstructionFiles, findProjectInstructions, findRole, formatBytes, formatSkillIndex, formatUsd, gateForTool, getCapability, getConfigIssues, getConfigOrigins, getImportGate, getTrustGate, hasDedicatedExecContent, hasExecTierContent, hasPromptCaching, hasProviderCredentials, hasReadTierContent, imageFromBase64, imageFromPath, imagePartTokens, importSkills, installPlugin, instructionDirs, instructionNotices, intervalSlots, inventoryProjectExtensions, inventoryTotal, isBlockCode, isCodeModeDeferred, isEmptyRules, isGoalPhase, isNonInteractive, isReadOnlySubCall, isSettingWriteLayer, isValidPluginName, isWithinWindow, isWritableSettingKey, labelSlug, layerRank, listSessionCandidates, listWorkspaceFiles, loadCommandDefinitions, loadCommandFile, loadCommands, loadConfig, loadHookSources, loadKeybindings, loadLexiconDir, loadLexiconFiles, loadPlugins, loadPolicyFiles, loadPolicyRules, loadRoleDefinitions, loadRoleDir, loadedImports, localDateString, managedSwitchNotes, mapClaudeToolName, mapEpochToolName, mapOperationType, matchPreauthorization, matchRuleLists, matchesHook, mentionsPluginRoot, mergeHeadlessPolicy, mergeRoles, mergeSchedulePatch, microsToUsd, modelListCandidates, needsAllowlist, nextFallbackModel, nextRunAt, noConfigOrigins, noManagedPolicy, noPlugins, openArtifact, originOf, packFileName, packPlugin, parseClaudeSettingsHooks, parseClock, parseDate, parseFrontmatter, parseHooksConfig, parseHooksConfigVerbose, parseImportLine, parseModelList, parseRoleDefinition, parseScheduleDraft, parseSkillFrontmatter, parseTrigger, pendingImageTokens, persistParts, persistToolResults, persistedUsage, planPack, previewSkillImport, pricingFor, projectEntryForDisplay, pruneArtifacts, pruneAttachments, pruneRecordings, pruneSchedules, readImageSize, readMarketplaces, readPluginManifest, readPluginRecords, readProviderKeyEnv, readRecording, readSessionSurface, reclaimFtsSpace, redactLine, refreshOpenRouterMetadata, removeMarketplace, removeSessionArtifacts, removeSessionAttachments, renderImportTree, renderProjectContext, renderSdkDeclaration, renderSelfIndex, repairSchedules, resolveArtifactRetention, resolveCodeModeWorker, resolveComplianceDirs, resolveEntrySource, resolveInWorkspace, resolveMarketplaceRef, resolveMentions, resolveMultimodalPolicy, resolvePolicyDirs, resolvePricingAt, resolveProjectRoot, resolveScheduleBackend, resolveSessionReference, resolveSessionVisibility, resolveSettings, resolveSkillDirs, resolveSource, resolveTar, resolveWorkspace, restoreParts, revealScopedProvider, roleScopedProvider, roleSourceLabel, ruleCovers, ruleFromString, ruleToString, runCode, runCommand2 as runCommand, sanitizeArgNames, sanitizeCommand, sanitizeFtsQuery, sanitizePath, sanitizeToolOutput, scanInstructions, scanPluginDir, scanSkillDirs, searchMarketplaces, setDisplayCurrency, setImportGate, setPluginEnabled, setTrustGate, settingValueChoices, settingValueKind, settingWriteApply, settingWriteLayers, settingWriteTargets, skillIndexDescription, skillIndexResidency, skillIndexStats, sniffMediaType, splitFrontmatter, staticToolProvider, stripArtifactData, substitutePluginRoot, suggestRuleFromApproval, systemOpenArgv, systemPromptSegments, toPosix, toolDefinitionTokens, toolMatches, toolTableTokens, totalTokens, traceSession, triggerPeriodMs, unescapeRuleContent, uninstallPlugin, unknownRoleSkills, unknownRoleTools, unloadedInstructionFiles, updateMarketplace, updatePlugin, usdToMicros, validateSchedule, validateTrigger, validateWindow, withGoalCompression, withGoalPrompt, workspaceDisplayPath, writeSettingValue };
|
|
23169
|
+
export { AGENT_ROLE_DIAG_MODULE, ARTIFACT_MAX_TOTAL_BYTES, ARTIFACT_RETENTION_DEFAULTS, ATTACHMENT_MAX_TOTAL_BYTES, ATTACHMENT_RETENTION_DEFAULTS, AgentLoop, ApprovalCache, BLOCKED_TOOLS, BudgetGuard, BudgetStore, CHECKPOINT_MAX_TOTAL_BYTES, CLAUDE_EVENT_NAMES, CLAUDE_TOOL_NAMES, CODE_MODE_LIMITS, CODE_MODE_SDK_TAG, CONFIG_KEYS, CURRENT_CONFIG_VERSION, CheckpointManager, CheckpointStore, CodeSandbox, ComplianceEngine, ContextCompressor, DEFAULT_COMPLIANCE_ACTIONS, DEFAULT_COMPLIANCE_SETTINGS, DEFAULT_COMPRESSION_THRESHOLD, DEFAULT_GOAL_MAX_ROUNDS, DEFAULT_MAX_HOLD_CHARS, DelegateManager, EMPTY_RULES, EPOCH_DISK_LEDGER, EpochConfigSchema, FTS_TABLES, FTS_TRIGGERS, GOAL_BLOCK_CODES, GoalService, GoalStore, HEADLESS_AUDIT_CODES, HookManager, INSTRUCTION_BUDGET_CHARS, INSTRUCTION_FILES, ImageLoadError, ImportTrustStore, LAUNCHD_LABEL_PREFIX, LOCK_HEARTBEAT_MS, LOCK_STALE_MS, LastOpenSessions, MARKETPLACE_DISPLAY_FIELDS, MARKETPLACE_FILE, MAX_AUDIT_ENTRIES, MAX_COMMAND_DEPTH, MAX_GOAL_MAX_ROUNDS, MAX_IMPORT_DEPTH, MAX_LAST_OPEN_SESSIONS, MAX_OBJECTIVE_CHARS, MAX_REASON_CHARS, MAX_RECENT_WORKSPACES, MODEL_GIVE_UP_THRESHOLD, MULTIMODAL_DEFAULTS, ManagedPolicyError, ManagedSettingsSchema, MemoryManager, MemoryReviewer, ModelFailureTracker, NOMINAL_TOTAL_BYTES, NO_REVEALED_TOOLS, PACK_EXCLUDES, PACK_MAX_BYTES, PACK_MAX_FILES, PERMISSION_AUDIT_CODES, PLUGIN_LAYOUT, PLUGIN_MANIFEST_FILE, PLUGIN_MANIFEST_KEYS, PLUGIN_NAME_PATTERN, PLUGIN_ROOT_ENV, PLUGIN_ROOT_TOKEN, PLUGIN_VISIBILITY, POLICY_DECISIONS, PROBE_VERSION, PROJECT_AGENTS_SUBDIR, PROVIDER_NO_CREDENTIAL, PermissionManager, PlanModeState, PluginAuthorSchema, PluginStore, PolicyRuleSchema, ProviderError, ProviderRouter, RECORDING_KEEP_RUNS, RECORDING_MAX_BYTES, ROLE_FRONTMATTER_SCHEMA, RUN_CODE_TOOL, RecentWorkspaces, SANDBOX_COVERS, SANDBOX_EXCLUDES, SCALAR_KEYS, SCHEDULE_DEFAULTS, SCHEDULE_DEFAULT_ALLOWLIST, SCHEDULE_ISSUE_CODES, SCHTASKS_FOLDER, SESSION_MESSAGES_READ_TOOL, SESSION_MESSAGES_SEARCH_TOOL, SESSION_QUERY_TOOLS, SESSION_SEARCH_TOOL, SESSION_TRACE_TOOL, SETTINGS_LAYER_ORDER, SETTING_WRITE_KEYS, SETTING_WRITE_LAYERS, SKILL_CREATE_TOOL, SKILL_EDIT_TOOL, SKILL_PATCH_TOOL, SKILL_VIEW_TOOL, SKILL_WRITE_FILE_TOOL, SLASH_COMMANDS_DIAG_MODULE, ScheduleRecorder, ScheduleRegistrar, ScheduleStore, SessionManager, SessionQueries, SessionReferences, SettingsFileError, SettingsFileSchema, SkillLearner, SkillSystem, TOOL_SEARCH_TOOL, TaskNoticeTracker, ToolRegistry, TrackerDB, TrustManager, Workspace, acquireScheduleLock, addMarketplace, addUsage, admitArtifact, admitArtifacts, affectedPaths, artifactLaunchArgv, artifactOpenRefusal, assertLevelAllowed, blockedRoleTools, buildContextBreakdown, buildFireArgv, buildFtsMatchQuery, buildSchemaExports, buildSystemPrompt, buildTrigramMatchQuery, builtinRoles, checkEpochVersion, checkFtsHealth, checkShadowing, classifyProviderError, clearModelCache, coalesceRecording, codeModeWorkerPath, commandNameFromRelPath, compileRuleLists, compressionOptions, computeCost, computeCostMicros, computeExecHash, countRules, createAllowAllGate, createAllowAllImportGate, createAskQuestionTool, createCodeExecTool, createDelegateTool, createDenyAllGate, createDenyAllImportGate, createGoalTool, createImportGate, createMemoryTool, createPlanModeTools, createRoleFile, createRoleScope, createRunCodeTool, createScheduleDraftTool, createSessionMessagesReadTool, createSessionMessagesSearchTool, createSessionSearchTool, createSessionSearchTools, createSessionTraceTool, createSkillViewTool, createSkillWriteTools, createTodoTool, createToolRevealState, createToolScope, createToolSearchTool, createTrustGate, currentEpochVersion, decideImport, decideTrust, defaultConfig, defaultModelOf, describeArtifactRefusal, describeBackgroundTask, describeHeadlessPolicy, describeIsolation, describeJsonError, diagnoseSchedules, discoverMarkdown, discoverModels, discoverProject, displayCurrency, draftCommandLine, draftWidening, escapeRuleContent, estimateImageTokens, estimateRunTokens, estimateTokens, evaluateSelection, expandCommand, expandImports, explainSetting, extractArchive, findInstructionFiles, findProjectInstructions, findRole, formatBytes, formatSkillIndex, formatUsd, gateForTool, getCapability, getConfigIssues, getConfigOrigins, getImportGate, getTrustGate, hasDedicatedExecContent, hasExecTierContent, hasPromptCaching, hasProviderCredentials, hasReadTierContent, imageFromBase64, imageFromPath, imagePartTokens, importSkills, installPlugin, instructionDirs, instructionNotices, intervalSlots, inventoryProjectExtensions, inventoryTotal, isBlockCode, isCodeModeDeferred, isEmptyRules, isGoalPhase, isNonInteractive, isReadOnlySubCall, isSettingWriteLayer, isValidPluginName, isWithinWindow, isWritableSettingKey, labelSlug, layerRank, listRunningSchedules, listSessionCandidates, listWorkspaceFiles, loadCommandDefinitions, loadCommandFile, loadCommands, loadConfig, loadHookSources, loadKeybindings, loadLexiconDir, loadLexiconFiles, loadPlugins, loadPolicyFiles, loadPolicyRules, loadRoleDefinitions, loadRoleDir, loadedImports, localDateString, managedSwitchNotes, mapClaudeToolName, mapEpochToolName, mapOperationType, matchPreauthorization, matchRuleLists, matchesHook, mentionsPluginRoot, mergeHeadlessPolicy, mergeRoles, mergeSchedulePatch, microsToUsd, modelListCandidates, needsAllowlist, nextFallbackModel, nextRunAt, noConfigOrigins, noManagedPolicy, noPlugins, openArtifact, originOf, packFileName, packPlugin, parseClaudeSettingsHooks, parseClock, parseDate, parseFrontmatter, parseHooksConfig, parseHooksConfigVerbose, parseImportLine, parseModelList, parseRoleDefinition, parseScheduleDraft, parseSkillFrontmatter, parseTrigger, pendingImageTokens, persistParts, persistToolResults, persistedUsage, planPack, previewSkillImport, pricingFor, projectEntryForDisplay, pruneArtifacts, pruneAttachments, pruneRecordings, pruneSchedules, readImageSize, readMarketplaces, readPluginManifest, readPluginRecords, readProviderKeyEnv, readRecording, readSessionSurface, reclaimFtsSpace, redactLine, refreshOpenRouterMetadata, removeMarketplace, removeRecordings, removeRoleFile, removeSessionArtifacts, removeSessionAttachments, renderImportTree, renderProjectContext, renderSdkDeclaration, renderSelfIndex, repairSchedules, resolveArtifactRetention, resolveCodeModeWorker, resolveComplianceDirs, resolveEntrySource, resolveInWorkspace, resolveMarketplaceRef, resolveMentions, resolveMultimodalPolicy, resolvePolicyDirs, resolvePricingAt, resolveProjectRoot, resolveScheduleBackend, resolveSessionReference, resolveSessionVisibility, resolveSettings, resolveSkillDirs, resolveSource, resolveTar, resolveWorkspace, restoreParts, revealScopedProvider, roleScopedProvider, roleSourceLabel, ruleCovers, ruleFromString, ruleToString, runCode, runCommand2 as runCommand, sanitizeArgNames, sanitizeCommand, sanitizeFtsQuery, sanitizePath, sanitizeToolOutput, scanInstructions, scanPluginDir, scanSkillDirs, searchMarketplaces, setDisplayCurrency, setImportGate, setPluginEnabled, setTrustGate, settingValueChoices, settingValueKind, settingWriteApply, settingWriteLayers, settingWriteTargets, skillIndexDescription, skillIndexResidency, skillIndexStats, sniffMediaType, splitFrontmatter, staticToolProvider, stripArtifactData, substitutePluginRoot, suggestRuleFromApproval, systemOpenArgv, systemPromptSegments, toPosix, toolDefinitionTokens, toolMatches, toolTableTokens, totalTokens, traceSession, triggerPeriodMs, unescapeRuleContent, uninstallPlugin, unknownRoleSkills, unknownRoleTools, unloadedInstructionFiles, updateMarketplace, updatePlugin, usdToMicros, validateSchedule, validateTrigger, validateWindow, withGoalCompression, withGoalPrompt, workspaceDisplayPath, writeSettingValue };
|