jinzd-ai-cli 0.4.113 → 0.4.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth-7KK5BOCA.js +12 -0
- package/dist/{batch-NF26OYWB.js → batch-SHNIUSW2.js} +2 -2
- package/dist/{chunk-TFYDLG7E.js → chunk-FMPWML3F.js} +63 -11
- package/dist/{chunk-2WAEM5B6.js → chunk-KQZU2VS5.js} +1 -1
- package/dist/{chunk-BYNY5JPB.js → chunk-O7NM4WTS.js} +86 -7
- package/dist/{chunk-SRU5SYZI.js → chunk-OHUHYWBR.js} +1 -1
- package/dist/{chunk-SIDKPVRD.js → chunk-PEMNYHIS.js} +1 -1
- package/dist/{chunk-3GUNDGUV.js → chunk-TJGRPTJS.js} +52 -11
- package/dist/{chunk-WLZ2PWQV.js → chunk-UZLNS3QG.js} +1 -1
- package/dist/{constants-2Z7YP252.js → constants-Y6LRE5TI.js} +1 -1
- package/dist/electron-server.js +247 -30
- package/dist/{hub-KRNH76Y3.js → hub-E3WMJGYK.js} +1 -1
- package/dist/index.js +123 -37
- package/dist/{run-tests-YOBAV24V.js → run-tests-7VYL7OVA.js} +1 -1
- package/dist/{run-tests-BUDXHVNF.js → run-tests-TWE7TJ4T.js} +2 -2
- package/dist/{server-ABNZXOV2.js → server-3P5BYK74.js} +32 -13
- package/dist/{server-MJGOR6FU.js → server-RODHACCH.js} +64 -11
- package/dist/{task-orchestrator-KZISH5DT.js → task-orchestrator-24IGVXYP.js} +3 -3
- package/dist/web/client/style.css +129 -129
- package/package.json +2 -1
- package/dist/auth-SC6KHHI3.js +0 -8
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
buildWriteRoundReminder,
|
|
15
15
|
clearDevState,
|
|
16
16
|
computeCost,
|
|
17
|
+
detectMetaNarration,
|
|
17
18
|
detectPseudoToolCalls,
|
|
18
19
|
detectsHallucinatedFileOp,
|
|
19
20
|
extractWrittenFilePaths,
|
|
@@ -31,10 +32,10 @@ import {
|
|
|
31
32
|
setupProxy,
|
|
32
33
|
stripPseudoToolCalls,
|
|
33
34
|
stripToolCallReminder
|
|
34
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-FMPWML3F.js";
|
|
35
36
|
import {
|
|
36
37
|
ConfigManager
|
|
37
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-UZLNS3QG.js";
|
|
38
39
|
import {
|
|
39
40
|
ToolExecutor,
|
|
40
41
|
ToolRegistry,
|
|
@@ -53,10 +54,10 @@ import {
|
|
|
53
54
|
spawnAgentContext,
|
|
54
55
|
theme,
|
|
55
56
|
undoStack
|
|
56
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-TJGRPTJS.js";
|
|
57
58
|
import "./chunk-3BICTI5M.js";
|
|
58
59
|
import "./chunk-2DXY7UGF.js";
|
|
59
|
-
import "./chunk-
|
|
60
|
+
import "./chunk-PEMNYHIS.js";
|
|
60
61
|
import "./chunk-2ZD3YTVM.js";
|
|
61
62
|
import {
|
|
62
63
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
@@ -79,7 +80,7 @@ import {
|
|
|
79
80
|
SKILLS_DIR_NAME,
|
|
80
81
|
VERSION,
|
|
81
82
|
buildUserIdentityPrompt
|
|
82
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-OHUHYWBR.js";
|
|
83
84
|
import {
|
|
84
85
|
formatGitContextForPrompt,
|
|
85
86
|
getGitContext,
|
|
@@ -411,6 +412,7 @@ var Renderer = class {
|
|
|
411
412
|
buf = "";
|
|
412
413
|
};
|
|
413
414
|
let interrupted = false;
|
|
415
|
+
let streamErr = null;
|
|
414
416
|
try {
|
|
415
417
|
for await (const chunk of stream) {
|
|
416
418
|
if (options?.signal?.aborted) {
|
|
@@ -435,41 +437,51 @@ var Renderer = class {
|
|
|
435
437
|
interrupted = true;
|
|
436
438
|
if (!inThinking) flushBuf();
|
|
437
439
|
} else {
|
|
438
|
-
|
|
440
|
+
streamErr = err;
|
|
439
441
|
}
|
|
440
442
|
}
|
|
441
443
|
if (interrupted) {
|
|
442
444
|
process.stdout.write(theme.dim(" [interrupted]\n"));
|
|
443
445
|
}
|
|
444
446
|
let tokensShown = false;
|
|
445
|
-
if (
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
447
|
+
if (!streamErr) {
|
|
448
|
+
if (options?.showTokens) {
|
|
449
|
+
process.stdout.write("\n");
|
|
450
|
+
if (usage) {
|
|
451
|
+
const sessionTotal = options.sessionTotal;
|
|
452
|
+
const updatedTotal = sessionTotal ? { inputTokens: sessionTotal.inputTokens + usage.inputTokens, outputTokens: sessionTotal.outputTokens + usage.outputTokens } : void 0;
|
|
453
|
+
this.renderUsage(usage, updatedTotal);
|
|
454
|
+
tokensShown = true;
|
|
455
|
+
} else if (fullContent.length > 0) {
|
|
456
|
+
const est = Math.ceil(fullContent.length / 2.5);
|
|
457
|
+
process.stdout.write(theme.dim(`\u{1F4CA} ~${est.toLocaleString()} output tokens (estimated)
|
|
455
458
|
|
|
456
459
|
`));
|
|
457
|
-
|
|
460
|
+
tokensShown = true;
|
|
461
|
+
} else {
|
|
462
|
+
process.stdout.write("\n");
|
|
463
|
+
}
|
|
458
464
|
} else {
|
|
459
|
-
process.stdout.write("\n");
|
|
465
|
+
process.stdout.write("\n\n");
|
|
460
466
|
}
|
|
461
467
|
} else {
|
|
462
|
-
process.stdout.write("\n
|
|
468
|
+
process.stdout.write("\n");
|
|
463
469
|
}
|
|
464
470
|
if (fileStream) {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
471
|
+
try {
|
|
472
|
+
await new Promise((resolve3) => {
|
|
473
|
+
fileStream.end(() => resolve3());
|
|
474
|
+
});
|
|
475
|
+
} catch {
|
|
476
|
+
}
|
|
477
|
+
if (!streamErr) {
|
|
478
|
+
const kb = (Buffer.byteLength(fullContent, "utf-8") / 1024).toFixed(1);
|
|
479
|
+
process.stdout.write(theme.success(` \u2705 Saved: ${options.saveToFile} (${kb} KB)
|
|
470
480
|
|
|
471
481
|
`));
|
|
482
|
+
}
|
|
472
483
|
}
|
|
484
|
+
if (streamErr) throw streamErr;
|
|
473
485
|
return { content: fullContent, usage, tokensShown };
|
|
474
486
|
}
|
|
475
487
|
renderResponse(content) {
|
|
@@ -1600,7 +1612,7 @@ ${text}
|
|
|
1600
1612
|
const { join: join6 } = await import("path");
|
|
1601
1613
|
const { existsSync: existsSync6 } = await import("fs");
|
|
1602
1614
|
const { getGitRoot: getGitRoot2 } = await import("./git-context-7KIP4X2V.js");
|
|
1603
|
-
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-
|
|
1615
|
+
const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-Y6LRE5TI.js");
|
|
1604
1616
|
const { approveProject, hashMcpFile } = await import("./project-trust-IFM7FXEV.js");
|
|
1605
1617
|
const cwd = process.cwd();
|
|
1606
1618
|
const projectRoot = getGitRoot2(cwd) ?? cwd;
|
|
@@ -2650,7 +2662,7 @@ ${hint}` : "")
|
|
|
2650
2662
|
usage: "/test [command|filter]",
|
|
2651
2663
|
async execute(args, ctx) {
|
|
2652
2664
|
try {
|
|
2653
|
-
const { executeTests } = await import("./run-tests-
|
|
2665
|
+
const { executeTests } = await import("./run-tests-TWE7TJ4T.js");
|
|
2654
2666
|
const argStr = args.join(" ").trim();
|
|
2655
2667
|
let testArgs = {};
|
|
2656
2668
|
if (argStr) {
|
|
@@ -6260,10 +6272,71 @@ ${mcpBudgetNote}` : "");
|
|
|
6260
6272
|
_extraMessages: teeExtraMessages
|
|
6261
6273
|
});
|
|
6262
6274
|
const teeShowTokens = this.shouldShowTokens();
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6275
|
+
let genContent;
|
|
6276
|
+
let genUsage;
|
|
6277
|
+
let teeTokShown = false;
|
|
6278
|
+
try {
|
|
6279
|
+
const teeResult = await this.renderer.renderStream(
|
|
6280
|
+
genStream,
|
|
6281
|
+
{ saveToFile, showTokens: teeShowTokens, sessionTotal: teeShowTokens ? { ...this.sessionTokenUsage } : void 0, signal: teeAc.signal }
|
|
6282
|
+
);
|
|
6283
|
+
genContent = teeResult.content;
|
|
6284
|
+
genUsage = teeResult.usage;
|
|
6285
|
+
teeTokShown = teeResult.tokensShown;
|
|
6286
|
+
} catch (teeErr) {
|
|
6287
|
+
try {
|
|
6288
|
+
unlinkSync2(saveToFile);
|
|
6289
|
+
} catch {
|
|
6290
|
+
}
|
|
6291
|
+
const errMsg = teeErr instanceof Error ? teeErr.message : String(teeErr);
|
|
6292
|
+
process.stdout.write(theme.error(
|
|
6293
|
+
`
|
|
6294
|
+
\u2717 tee stream failed: ${errMsg}
|
|
6295
|
+
${saveToFile} (partial) was deleted. Asking model to retry.
|
|
6296
|
+
|
|
6297
|
+
`
|
|
6298
|
+
));
|
|
6299
|
+
const errorResults = result.toolCalls.map((tc) => ({
|
|
6300
|
+
callId: tc.id,
|
|
6301
|
+
content: tc.name === "save_last_response" ? `[save_last_response failed] streaming was interrupted: ${errMsg}. ${saveToFile} was NOT saved. Retry \u2014 and consider producing a more compact output (split very large reports across multiple save_last_response calls if the previous attempt timed out).` : `[skipped: save_last_response failed]`,
|
|
6302
|
+
isError: tc.name === "save_last_response"
|
|
6303
|
+
}));
|
|
6304
|
+
const reasoningContent3 = "reasoningContent" in result ? result.reasoningContent : void 0;
|
|
6305
|
+
const newMsgs3 = provider.buildToolResultMessages(result.toolCalls, errorResults, reasoningContent3);
|
|
6306
|
+
extraMessages.push(...newMsgs3);
|
|
6307
|
+
continue;
|
|
6308
|
+
}
|
|
6309
|
+
const metaMatch = detectMetaNarration(genContent);
|
|
6310
|
+
if (metaMatch) {
|
|
6311
|
+
try {
|
|
6312
|
+
unlinkSync2(saveToFile);
|
|
6313
|
+
} catch {
|
|
6314
|
+
}
|
|
6315
|
+
process.stdout.write(theme.error(
|
|
6316
|
+
`
|
|
6317
|
+
\u2717 Rejected save: response was meta-narration / leaked reasoning, not document body (matched: ${metaMatch})
|
|
6318
|
+
${saveToFile} was deleted; asking model to retry.
|
|
6319
|
+
|
|
6320
|
+
`
|
|
6321
|
+
));
|
|
6322
|
+
const errorResults = result.toolCalls.map((tc) => ({
|
|
6323
|
+
callId: tc.id,
|
|
6324
|
+
content: tc.name === "save_last_response" ? `[save_last_response REJECTED] Your output was internal reasoning / meta-narration about the task (e.g. "Let me re-read\u2026", "the user is asking me to\u2026") instead of the requested document body. ${saveToFile} was NOT saved.
|
|
6325
|
+
|
|
6326
|
+
This fresh stream has NO tools. Produce ONLY the document body: start with a markdown heading like "# \u5BA1\u8BA1\u62A5\u544A" / "# Audit Report" and write the full content. Do NOT narrate that you will produce the document \u2014 produce it.` : `[skipped: save_last_response was rejected and other parallel calls are abandoned]`,
|
|
6327
|
+
isError: tc.name === "save_last_response"
|
|
6328
|
+
}));
|
|
6329
|
+
const reasoningContent3 = "reasoningContent" in result ? result.reasoningContent : void 0;
|
|
6330
|
+
const newMsgs3 = provider.buildToolResultMessages(result.toolCalls, errorResults, reasoningContent3);
|
|
6331
|
+
extraMessages.push(...newMsgs3);
|
|
6332
|
+
if (genUsage) {
|
|
6333
|
+
roundUsage.inputTokens += genUsage.inputTokens;
|
|
6334
|
+
roundUsage.outputTokens += genUsage.outputTokens;
|
|
6335
|
+
roundUsage.cacheCreationTokens += genUsage.cacheCreationTokens ?? 0;
|
|
6336
|
+
roundUsage.cacheReadTokens += genUsage.cacheReadTokens ?? 0;
|
|
6337
|
+
}
|
|
6338
|
+
continue;
|
|
6339
|
+
}
|
|
6267
6340
|
const pseudoMatch = detectPseudoToolCalls(genContent);
|
|
6268
6341
|
if (pseudoMatch) {
|
|
6269
6342
|
const cleaned = stripPseudoToolCalls(genContent);
|
|
@@ -6882,11 +6955,11 @@ program.command("web").description("Start Web UI server with browser-based chat
|
|
|
6882
6955
|
console.error("Error: Invalid port number. Must be between 1 and 65535.");
|
|
6883
6956
|
process.exit(1);
|
|
6884
6957
|
}
|
|
6885
|
-
const { startWebServer } = await import("./server-
|
|
6958
|
+
const { startWebServer } = await import("./server-RODHACCH.js");
|
|
6886
6959
|
await startWebServer({ port, host: options.host });
|
|
6887
6960
|
});
|
|
6888
|
-
program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
|
|
6889
|
-
const { AuthManager } = await import("./auth-
|
|
6961
|
+
program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | logout-all <name> | migrate <name>)").action(async (action, username) => {
|
|
6962
|
+
const { AuthManager } = await import("./auth-7KK5BOCA.js");
|
|
6890
6963
|
const config = new ConfigManager();
|
|
6891
6964
|
const auth = new AuthManager(config.getConfigDir());
|
|
6892
6965
|
if (!action || action === "list") {
|
|
@@ -6961,6 +7034,19 @@ ${users.length} user(s) registered (auth enabled):
|
|
|
6961
7034
|
console.log(`\u2713 Password reset for '${username}'.`);
|
|
6962
7035
|
return;
|
|
6963
7036
|
}
|
|
7037
|
+
if (action === "logout-all") {
|
|
7038
|
+
if (!username) {
|
|
7039
|
+
console.error("Usage: aicli user logout-all <username>");
|
|
7040
|
+
process.exit(1);
|
|
7041
|
+
}
|
|
7042
|
+
const ok = auth.logoutAll(username);
|
|
7043
|
+
if (!ok) {
|
|
7044
|
+
console.error(`Error: User '${username}' not found.`);
|
|
7045
|
+
process.exit(1);
|
|
7046
|
+
}
|
|
7047
|
+
console.log(`\u2713 All outstanding sessions for '${username}' revoked.`);
|
|
7048
|
+
return;
|
|
7049
|
+
}
|
|
6964
7050
|
if (action === "migrate") {
|
|
6965
7051
|
if (!username) {
|
|
6966
7052
|
console.error("Usage: aicli user migrate <username>");
|
|
@@ -6980,7 +7066,7 @@ ${users.length} user(s) registered (auth enabled):
|
|
|
6980
7066
|
return;
|
|
6981
7067
|
}
|
|
6982
7068
|
console.error(`Unknown action: ${action}`);
|
|
6983
|
-
console.error("Available: list, create, delete, reset-password, migrate");
|
|
7069
|
+
console.error("Available: list, create, delete, reset-password, logout-all, migrate");
|
|
6984
7070
|
process.exit(1);
|
|
6985
7071
|
});
|
|
6986
7072
|
program.command("sessions").description("List recent conversation sessions").action(async () => {
|
|
@@ -7005,7 +7091,7 @@ program.command("sessions").description("List recent conversation sessions").act
|
|
|
7005
7091
|
});
|
|
7006
7092
|
program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
|
|
7007
7093
|
try {
|
|
7008
|
-
const batch = await import("./batch-
|
|
7094
|
+
const batch = await import("./batch-SHNIUSW2.js");
|
|
7009
7095
|
switch (action) {
|
|
7010
7096
|
case "submit":
|
|
7011
7097
|
if (!arg) {
|
|
@@ -7048,7 +7134,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
|
|
|
7048
7134
|
}
|
|
7049
7135
|
});
|
|
7050
7136
|
program.command("mcp-serve").description("Start an MCP server over STDIO, exposing aicli's built-in tools to Claude Desktop / Cursor / other MCP clients").option("--allow-destructive", "Allow bash / run_interactive / task_create (always destructive in MCP mode)").option("--allow-outside-cwd", "Allow tool path arguments to escape the sandbox root \u2014 disabled by default").option("--tools <list>", "Comma-separated whitelist of tools to expose (default: all eligible tools)").option("--cwd <path>", "Working directory AND sandbox root (default: current directory)").action(async (options) => {
|
|
7051
|
-
const { startMcpServer } = await import("./server-
|
|
7137
|
+
const { startMcpServer } = await import("./server-3P5BYK74.js");
|
|
7052
7138
|
await startMcpServer({
|
|
7053
7139
|
allowDestructive: !!options.allowDestructive,
|
|
7054
7140
|
allowOutsideCwd: !!options.allowOutsideCwd,
|
|
@@ -7175,7 +7261,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
7175
7261
|
}),
|
|
7176
7262
|
config.get("customProviders")
|
|
7177
7263
|
);
|
|
7178
|
-
const { startHub } = await import("./hub-
|
|
7264
|
+
const { startHub } = await import("./hub-E3WMJGYK.js");
|
|
7179
7265
|
await startHub(
|
|
7180
7266
|
{
|
|
7181
7267
|
topic: topic ?? "",
|
|
@@ -3,14 +3,14 @@ import {
|
|
|
3
3
|
ToolRegistry,
|
|
4
4
|
getDangerLevel,
|
|
5
5
|
schemaToJsonSchema
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-TJGRPTJS.js";
|
|
7
7
|
import "./chunk-3BICTI5M.js";
|
|
8
8
|
import "./chunk-2DXY7UGF.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-PEMNYHIS.js";
|
|
10
10
|
import "./chunk-2ZD3YTVM.js";
|
|
11
11
|
import {
|
|
12
12
|
VERSION
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-OHUHYWBR.js";
|
|
14
14
|
import "./chunk-4BKXL7SM.js";
|
|
15
15
|
import "./chunk-7ZJN4KLV.js";
|
|
16
16
|
import "./chunk-KHYD3WXE.js";
|
|
@@ -23,6 +23,14 @@ import { createInterface } from "readline";
|
|
|
23
23
|
import { resolve } from "path";
|
|
24
24
|
import { realpathSync } from "fs";
|
|
25
25
|
var STDIN_TOOLS = /* @__PURE__ */ new Set(["ask_user", "spawn_agent"]);
|
|
26
|
+
function looksLikePath(s) {
|
|
27
|
+
if (s.startsWith("/")) return true;
|
|
28
|
+
if (s.startsWith("\\\\")) return true;
|
|
29
|
+
if (/^[a-zA-Z]:[\\/]/.test(s)) return true;
|
|
30
|
+
if (s.startsWith("../") || s.startsWith("..\\")) return true;
|
|
31
|
+
if (s === "..") return true;
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
26
34
|
var MCP_ALWAYS_DESTRUCTIVE = /* @__PURE__ */ new Set([
|
|
27
35
|
"bash",
|
|
28
36
|
"run_interactive",
|
|
@@ -237,19 +245,30 @@ var McpServer = class {
|
|
|
237
245
|
validatePathArgs(toolName, args) {
|
|
238
246
|
if (this.opts.allowOutsideCwd) return void 0;
|
|
239
247
|
const keys = TOOL_PATH_ARGS[toolName];
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
if (keys) {
|
|
249
|
+
for (const key of keys) {
|
|
250
|
+
const value = args[key];
|
|
251
|
+
if (value === void 0 || value === null) continue;
|
|
252
|
+
const list = Array.isArray(value) ? value : [value];
|
|
253
|
+
for (const entry of list) {
|
|
254
|
+
if (typeof entry !== "string" || entry.length === 0) continue;
|
|
255
|
+
const abs = resolve(this.sandboxRoot, entry);
|
|
256
|
+
if (!this.isInsideSandbox(abs)) {
|
|
257
|
+
return `Path '${entry}' escapes sandbox root '${this.sandboxRoot}'. Pass --allow-outside-cwd to permit.`;
|
|
258
|
+
}
|
|
250
259
|
}
|
|
251
260
|
}
|
|
252
261
|
}
|
|
262
|
+
const knownKeys = new Set(keys ?? []);
|
|
263
|
+
for (const [k, v] of Object.entries(args)) {
|
|
264
|
+
if (knownKeys.has(k)) continue;
|
|
265
|
+
if (typeof v !== "string" || v.length === 0) continue;
|
|
266
|
+
if (!looksLikePath(v)) continue;
|
|
267
|
+
const abs = resolve(this.sandboxRoot, v);
|
|
268
|
+
if (!this.isInsideSandbox(abs)) {
|
|
269
|
+
return `Path-like argument '${k}=${v}' escapes sandbox root '${this.sandboxRoot}'. Pass --allow-outside-cwd to permit.`;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
253
272
|
return void 0;
|
|
254
273
|
}
|
|
255
274
|
isInsideSandbox(abs) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
AuthManager
|
|
4
|
-
|
|
3
|
+
AuthManager,
|
|
4
|
+
TOKEN_EXPIRY_MS
|
|
5
|
+
} from "./chunk-O7NM4WTS.js";
|
|
5
6
|
import {
|
|
6
7
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
7
8
|
HALLUCINATION_CORRECTION_MESSAGE,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
TOOL_CALL_REMINDER,
|
|
14
15
|
autoTrimSessionIfNeeded,
|
|
15
16
|
computeCost,
|
|
17
|
+
detectMetaNarration,
|
|
16
18
|
detectPseudoToolCalls,
|
|
17
19
|
detectsHallucinatedFileOp,
|
|
18
20
|
formatCost,
|
|
@@ -24,10 +26,10 @@ import {
|
|
|
24
26
|
setupProxy,
|
|
25
27
|
stripPseudoToolCalls,
|
|
26
28
|
stripToolCallReminder
|
|
27
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-FMPWML3F.js";
|
|
28
30
|
import {
|
|
29
31
|
ConfigManager
|
|
30
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-UZLNS3QG.js";
|
|
31
33
|
import {
|
|
32
34
|
ToolExecutor,
|
|
33
35
|
ToolRegistry,
|
|
@@ -45,10 +47,10 @@ import {
|
|
|
45
47
|
spawnAgentContext,
|
|
46
48
|
truncateOutput,
|
|
47
49
|
undoStack
|
|
48
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-TJGRPTJS.js";
|
|
49
51
|
import "./chunk-3BICTI5M.js";
|
|
50
52
|
import "./chunk-2DXY7UGF.js";
|
|
51
|
-
import "./chunk-
|
|
53
|
+
import "./chunk-PEMNYHIS.js";
|
|
52
54
|
import "./chunk-2ZD3YTVM.js";
|
|
53
55
|
import {
|
|
54
56
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
@@ -68,7 +70,7 @@ import {
|
|
|
68
70
|
SKILLS_DIR_NAME,
|
|
69
71
|
VERSION,
|
|
70
72
|
buildUserIdentityPrompt
|
|
71
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-OHUHYWBR.js";
|
|
72
74
|
import {
|
|
73
75
|
formatGitContextForPrompt,
|
|
74
76
|
getGitContext,
|
|
@@ -539,6 +541,7 @@ var SessionHandler = class _SessionHandler {
|
|
|
539
541
|
this.mcpManager = shared.mcpManager;
|
|
540
542
|
this.skillManager = shared.skillManager;
|
|
541
543
|
this.toolExecutor = new ToolExecutorWeb(shared.toolRegistry, ws);
|
|
544
|
+
this.toolExecutor.setSessionKey(`web-${Math.random().toString(36).slice(2)}-${Date.now()}`);
|
|
542
545
|
this.currentProvider = this.config.get("defaultProvider");
|
|
543
546
|
const allDefaultModels = this.config.get("defaultModels");
|
|
544
547
|
try {
|
|
@@ -1293,6 +1296,31 @@ ${summaryResult.content}`,
|
|
|
1293
1296
|
await new Promise((resolve3, reject) => {
|
|
1294
1297
|
fileStream.end((err) => err ? reject(err) : resolve3());
|
|
1295
1298
|
});
|
|
1299
|
+
const metaMatch = detectMetaNarration(fullContent);
|
|
1300
|
+
if (metaMatch) {
|
|
1301
|
+
try {
|
|
1302
|
+
unlinkSync(saveToFile);
|
|
1303
|
+
} catch {
|
|
1304
|
+
}
|
|
1305
|
+
isError = true;
|
|
1306
|
+
summary = `[save_last_response REJECTED] Your output was internal reasoning / meta-narration (e.g. "Let me re-read\u2026", "the user is asking me to\u2026") instead of the requested document body (matched: ${metaMatch}). ${saveToFile} was NOT saved.
|
|
1307
|
+
|
|
1308
|
+
This fresh stream has NO tools. Produce ONLY the document body: start with a markdown heading and write the full content. Do NOT narrate that you will produce the document \u2014 produce it.`;
|
|
1309
|
+
if (teeUsage) {
|
|
1310
|
+
roundUsage.inputTokens += teeUsage.inputTokens;
|
|
1311
|
+
roundUsage.outputTokens += teeUsage.outputTokens;
|
|
1312
|
+
roundUsage.cacheCreationTokens += teeUsage.cacheCreationTokens ?? 0;
|
|
1313
|
+
roundUsage.cacheReadTokens += teeUsage.cacheReadTokens ?? 0;
|
|
1314
|
+
}
|
|
1315
|
+
this.send({
|
|
1316
|
+
type: "tool_call_result",
|
|
1317
|
+
callId: call.id,
|
|
1318
|
+
result: summary,
|
|
1319
|
+
isError: true,
|
|
1320
|
+
endTime: Date.now()
|
|
1321
|
+
});
|
|
1322
|
+
return { content: "", summary, isError: true };
|
|
1323
|
+
}
|
|
1296
1324
|
const pseudoMatch = detectPseudoToolCalls(fullContent);
|
|
1297
1325
|
if (pseudoMatch) {
|
|
1298
1326
|
const cleaned = stripPseudoToolCalls(fullContent);
|
|
@@ -1330,9 +1358,13 @@ ${summaryResult.content}`,
|
|
|
1330
1358
|
} catch {
|
|
1331
1359
|
}
|
|
1332
1360
|
}
|
|
1361
|
+
try {
|
|
1362
|
+
unlinkSync(saveToFile);
|
|
1363
|
+
} catch {
|
|
1364
|
+
}
|
|
1333
1365
|
isError = true;
|
|
1334
1366
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1335
|
-
summary = `[save_last_response failed] ${msg}
|
|
1367
|
+
summary = `[save_last_response failed] streaming was interrupted: ${msg}. ${saveToFile} (partial) was deleted. Retry \u2014 and consider producing a more compact output (split very large reports across multiple save_last_response calls if the previous attempt timed out).`;
|
|
1336
1368
|
}
|
|
1337
1369
|
this.send({
|
|
1338
1370
|
type: "tool_call_result",
|
|
@@ -2411,7 +2443,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2411
2443
|
case "test": {
|
|
2412
2444
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2413
2445
|
try {
|
|
2414
|
-
const { executeTests } = await import("./run-tests-
|
|
2446
|
+
const { executeTests } = await import("./run-tests-TWE7TJ4T.js");
|
|
2415
2447
|
const argStr = args.join(" ").trim();
|
|
2416
2448
|
let testArgs = {};
|
|
2417
2449
|
if (argStr) {
|
|
@@ -3467,6 +3499,27 @@ async function startWebServer(options = {}) {
|
|
|
3467
3499
|
skillManager
|
|
3468
3500
|
};
|
|
3469
3501
|
const app = express();
|
|
3502
|
+
app.use((_req, res, next) => {
|
|
3503
|
+
res.setHeader(
|
|
3504
|
+
"Content-Security-Policy",
|
|
3505
|
+
[
|
|
3506
|
+
"default-src 'self'",
|
|
3507
|
+
"script-src 'self'",
|
|
3508
|
+
"style-src 'self' 'unsafe-inline'",
|
|
3509
|
+
"img-src 'self' data: blob:",
|
|
3510
|
+
"font-src 'self' data:",
|
|
3511
|
+
"connect-src 'self' ws: wss:",
|
|
3512
|
+
"frame-ancestors 'none'",
|
|
3513
|
+
"base-uri 'self'",
|
|
3514
|
+
"form-action 'self'"
|
|
3515
|
+
].join("; ")
|
|
3516
|
+
);
|
|
3517
|
+
res.setHeader("X-Content-Type-Options", "nosniff");
|
|
3518
|
+
res.setHeader("Referrer-Policy", "no-referrer");
|
|
3519
|
+
res.setHeader("X-Frame-Options", "DENY");
|
|
3520
|
+
res.setHeader("Permissions-Policy", "geolocation=(), microphone=(), camera=()");
|
|
3521
|
+
next();
|
|
3522
|
+
});
|
|
3470
3523
|
const server = createServer(app);
|
|
3471
3524
|
const WS_MAX_PAYLOAD = 1 * 1024 * 1024;
|
|
3472
3525
|
const WS_MSG_RATE_PER_SEC = 30;
|
|
@@ -3551,7 +3604,7 @@ async function startWebServer(options = {}) {
|
|
|
3551
3604
|
}
|
|
3552
3605
|
const token = authManager.login(username, password);
|
|
3553
3606
|
console.log(` \u2713 User registered via API: ${username}${firstRun ? " (first-run)" : ""}`);
|
|
3554
|
-
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge:
|
|
3607
|
+
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge: TOKEN_EXPIRY_MS });
|
|
3555
3608
|
res.json({ success: true, username });
|
|
3556
3609
|
});
|
|
3557
3610
|
app.post("/api/auth/login", (req, res) => {
|
|
@@ -3565,7 +3618,7 @@ async function startWebServer(options = {}) {
|
|
|
3565
3618
|
res.status(401).json({ error: "Invalid username or password" });
|
|
3566
3619
|
return;
|
|
3567
3620
|
}
|
|
3568
|
-
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge:
|
|
3621
|
+
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge: TOKEN_EXPIRY_MS });
|
|
3569
3622
|
res.json({ success: true, username });
|
|
3570
3623
|
});
|
|
3571
3624
|
app.post("/api/auth/logout", (_req, res) => {
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
getDangerLevel,
|
|
5
5
|
googleSearchContext,
|
|
6
6
|
truncateOutput
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TJGRPTJS.js";
|
|
8
8
|
import "./chunk-3BICTI5M.js";
|
|
9
9
|
import "./chunk-2DXY7UGF.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-PEMNYHIS.js";
|
|
11
11
|
import "./chunk-2ZD3YTVM.js";
|
|
12
12
|
import {
|
|
13
13
|
SUBAGENT_ALLOWED_TOOLS
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-OHUHYWBR.js";
|
|
15
15
|
import "./chunk-4BKXL7SM.js";
|
|
16
16
|
import "./chunk-7ZJN4KLV.js";
|
|
17
17
|
import "./chunk-KHYD3WXE.js";
|