jinzd-ai-cli 0.4.114 → 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-VBV7HTLQ.js → auth-7KK5BOCA.js} +3 -1
- package/dist/{batch-Q5NQCXKN.js → batch-SHNIUSW2.js} +2 -2
- package/dist/{chunk-E24HT62E.js → chunk-FMPWML3F.js} +63 -11
- package/dist/{chunk-W45U3KQE.js → chunk-KQZU2VS5.js} +1 -1
- package/dist/{chunk-5UPFMM2A.js → chunk-O7NM4WTS.js} +14 -2
- package/dist/{chunk-UF62SHR7.js → chunk-OHUHYWBR.js} +1 -1
- package/dist/{chunk-2WAF7FOX.js → chunk-PEMNYHIS.js} +1 -1
- package/dist/{chunk-XXKWSBRC.js → chunk-TJGRPTJS.js} +3 -3
- package/dist/{chunk-CP6PALA4.js → chunk-UZLNS3QG.js} +1 -1
- package/dist/{constants-YEBRZDBP.js → constants-Y6LRE5TI.js} +1 -1
- package/dist/electron-server.js +108 -17
- package/dist/{hub-DGJC2RRF.js → hub-E3WMJGYK.js} +1 -1
- package/dist/index.js +108 -35
- package/dist/{run-tests-OB4CWKKX.js → run-tests-7VYL7OVA.js} +1 -1
- package/dist/{run-tests-7WN5Q7YV.js → run-tests-TWE7TJ4T.js} +2 -2
- package/dist/{server-NQ5J6FAL.js → server-3P5BYK74.js} +3 -3
- package/dist/{server-AKG7HG36.js → server-RODHACCH.js} +42 -11
- package/dist/{task-orchestrator-32YQ6HB2.js → task-orchestrator-24IGVXYP.js} +3 -3
- package/dist/web/client/style.css +129 -129
- package/package.json +1 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AuthManager,
|
|
4
|
+
TOKEN_EXPIRY_MS,
|
|
4
5
|
__resetLoginAttemptsForTests
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-O7NM4WTS.js";
|
|
6
7
|
import "./chunk-PDX44BCA.js";
|
|
7
8
|
export {
|
|
8
9
|
AuthManager,
|
|
10
|
+
TOKEN_EXPIRY_MS,
|
|
9
11
|
__resetLoginAttemptsForTests
|
|
10
12
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UZLNS3QG.js";
|
|
5
5
|
import "./chunk-2ZD3YTVM.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-OHUHYWBR.js";
|
|
7
7
|
import "./chunk-PDX44BCA.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/batch.ts
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
schemaToJsonSchema,
|
|
4
4
|
truncateForPersist
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-TJGRPTJS.js";
|
|
6
6
|
import {
|
|
7
7
|
AuthError,
|
|
8
8
|
ProviderError,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
MCP_PROTOCOL_VERSION,
|
|
19
19
|
MCP_TOOL_PREFIX,
|
|
20
20
|
VERSION
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-OHUHYWBR.js";
|
|
22
22
|
import {
|
|
23
23
|
redactJson
|
|
24
24
|
} from "./chunk-7ZJN4KLV.js";
|
|
@@ -72,10 +72,20 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
72
72
|
]
|
|
73
73
|
};
|
|
74
74
|
async initialize(apiKey, options) {
|
|
75
|
-
|
|
75
|
+
const clientOptions = {
|
|
76
76
|
apiKey,
|
|
77
77
|
baseURL: options?.baseUrl
|
|
78
|
-
}
|
|
78
|
+
};
|
|
79
|
+
const proxyUrl = options?.proxy;
|
|
80
|
+
try {
|
|
81
|
+
const { Agent, ProxyAgent, fetch: undiciFetch } = await import("undici");
|
|
82
|
+
const STREAM_BODY_TIMEOUT = 30 * 60 * 1e3;
|
|
83
|
+
const STREAM_HEADERS_TIMEOUT = 5 * 60 * 1e3;
|
|
84
|
+
const dispatcher = proxyUrl ? new ProxyAgent({ uri: proxyUrl, bodyTimeout: STREAM_BODY_TIMEOUT, headersTimeout: STREAM_HEADERS_TIMEOUT }) : new Agent({ bodyTimeout: STREAM_BODY_TIMEOUT, headersTimeout: STREAM_HEADERS_TIMEOUT });
|
|
85
|
+
clientOptions.fetch = ((url, init) => undiciFetch(url, { ...init, dispatcher }));
|
|
86
|
+
} catch {
|
|
87
|
+
}
|
|
88
|
+
this.client = new Anthropic(clientOptions);
|
|
79
89
|
}
|
|
80
90
|
/**
|
|
81
91
|
* 将内部 MessageContentPart[] 格式转换为 Anthropic SDK 期望的 ContentBlockParam[]。
|
|
@@ -932,13 +942,20 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
932
942
|
timeout: this.defaultTimeout
|
|
933
943
|
};
|
|
934
944
|
const proxyUrl = options?.proxy;
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
945
|
+
try {
|
|
946
|
+
const { Agent, ProxyAgent, fetch: undiciFetch } = await import("undici");
|
|
947
|
+
const STREAM_BODY_TIMEOUT = 30 * 60 * 1e3;
|
|
948
|
+
const STREAM_HEADERS_TIMEOUT = 5 * 60 * 1e3;
|
|
949
|
+
const dispatcher = proxyUrl ? new ProxyAgent({
|
|
950
|
+
uri: proxyUrl,
|
|
951
|
+
bodyTimeout: STREAM_BODY_TIMEOUT,
|
|
952
|
+
headersTimeout: STREAM_HEADERS_TIMEOUT
|
|
953
|
+
}) : new Agent({
|
|
954
|
+
bodyTimeout: STREAM_BODY_TIMEOUT,
|
|
955
|
+
headersTimeout: STREAM_HEADERS_TIMEOUT
|
|
956
|
+
});
|
|
957
|
+
clientOptions.fetch = ((url, init) => undiciFetch(url, { ...init, dispatcher }));
|
|
958
|
+
} catch {
|
|
942
959
|
}
|
|
943
960
|
this.client = new OpenAI(clientOptions);
|
|
944
961
|
}
|
|
@@ -1854,6 +1871,40 @@ function peelMetaNarration(content) {
|
|
|
1854
1871
|
}
|
|
1855
1872
|
return out.trim();
|
|
1856
1873
|
}
|
|
1874
|
+
var META_NARRATION_HARD_MARKERS = [
|
|
1875
|
+
/\[⚠️\s*CONTENT GENERATION MODE\]/,
|
|
1876
|
+
/CONTENT_ONLY_STREAM_REMINDER\b/,
|
|
1877
|
+
/<system-reminder>/i
|
|
1878
|
+
];
|
|
1879
|
+
var META_NARRATION_HEURISTICS = [
|
|
1880
|
+
/\bthe user (?:is asking me|wants me|is requesting|expects me)\b/i,
|
|
1881
|
+
/\blet me (?:re-?read|re-?consider|reconsider|think about|carefully (?:re-?read|consider))\b/i,
|
|
1882
|
+
/\bI'?m (?:in (?:a )?content-only|in CONTENT-ONLY|currently in)\b/i,
|
|
1883
|
+
/\bI think (?:there might be|I should|I cannot|the (?:user|best)|maybe)\b/i,
|
|
1884
|
+
/\bWait,?\s+let me\b/i,
|
|
1885
|
+
/\bActually,?\s+I\b/i,
|
|
1886
|
+
/\bI need to be honest with the user\b/i,
|
|
1887
|
+
/\bI(?:'m| am) in a special mode\b/i,
|
|
1888
|
+
/\bGiven that I cannot\b/i
|
|
1889
|
+
];
|
|
1890
|
+
function detectMetaNarration(content) {
|
|
1891
|
+
if (!content) return null;
|
|
1892
|
+
const head = content.slice(0, 2e3);
|
|
1893
|
+
for (const re of META_NARRATION_HARD_MARKERS) {
|
|
1894
|
+
if (re.test(head)) return re.source;
|
|
1895
|
+
}
|
|
1896
|
+
if (/^#{1,3}\s+\S/m.test(head)) return null;
|
|
1897
|
+
let hits = 0;
|
|
1898
|
+
let firstMatch = "";
|
|
1899
|
+
for (const re of META_NARRATION_HEURISTICS) {
|
|
1900
|
+
if (re.test(head)) {
|
|
1901
|
+
hits++;
|
|
1902
|
+
if (!firstMatch) firstMatch = re.source;
|
|
1903
|
+
if (hits >= 2) return `meta-narration:${firstMatch}`;
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
return null;
|
|
1907
|
+
}
|
|
1857
1908
|
function looksLikeDocumentBody(content) {
|
|
1858
1909
|
if (!content || content.length < 200) return false;
|
|
1859
1910
|
if (/^#{1,6}\s+\S/m.test(content)) return true;
|
|
@@ -4156,6 +4207,7 @@ export {
|
|
|
4156
4207
|
buildPhantomCorrectionMessage,
|
|
4157
4208
|
detectPseudoToolCalls,
|
|
4158
4209
|
stripPseudoToolCalls,
|
|
4210
|
+
detectMetaNarration,
|
|
4159
4211
|
looksLikeDocumentBody,
|
|
4160
4212
|
stripToolCallReminder,
|
|
4161
4213
|
TEE_FINAL_USER_NUDGE,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/web/auth.ts
|
|
4
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, copyFileSync } from "fs";
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, copyFileSync, renameSync, unlinkSync } from "fs";
|
|
5
5
|
import { join } from "path";
|
|
6
6
|
import { createHmac, randomBytes, timingSafeEqual, pbkdf2Sync } from "crypto";
|
|
7
7
|
var USERS_FILE = "users.json";
|
|
8
8
|
var TOKEN_EXPIRY_HOURS = 24;
|
|
9
|
+
var TOKEN_EXPIRY_MS = TOKEN_EXPIRY_HOURS * 3600 * 1e3;
|
|
9
10
|
var USERS_DIR = "users";
|
|
10
11
|
var LOGIN_MAX_FAILS = 5;
|
|
11
12
|
var LOGIN_LOCKOUT_MS = 15 * 60 * 1e3;
|
|
@@ -252,7 +253,17 @@ var AuthManager = class {
|
|
|
252
253
|
}
|
|
253
254
|
saveDB(db) {
|
|
254
255
|
mkdirSync(this.baseDir, { recursive: true });
|
|
255
|
-
|
|
256
|
+
const tmp = `${this.usersFile}.tmp`;
|
|
257
|
+
try {
|
|
258
|
+
writeFileSync(tmp, JSON.stringify(db, null, 2), "utf-8");
|
|
259
|
+
renameSync(tmp, this.usersFile);
|
|
260
|
+
} catch (err) {
|
|
261
|
+
try {
|
|
262
|
+
unlinkSync(tmp);
|
|
263
|
+
} catch {
|
|
264
|
+
}
|
|
265
|
+
throw err;
|
|
266
|
+
}
|
|
256
267
|
}
|
|
257
268
|
/** Legacy hash — kept only for migrating old users (v0.2.x) */
|
|
258
269
|
hashPasswordLegacy(password, salt) {
|
|
@@ -278,6 +289,7 @@ var AuthManager = class {
|
|
|
278
289
|
};
|
|
279
290
|
|
|
280
291
|
export {
|
|
292
|
+
TOKEN_EXPIRY_MS,
|
|
281
293
|
__resetLoginAttemptsForTests,
|
|
282
294
|
AuthManager
|
|
283
295
|
};
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-3BICTI5M.js";
|
|
6
6
|
import {
|
|
7
7
|
runTestsTool
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-PEMNYHIS.js";
|
|
9
9
|
import {
|
|
10
10
|
EnvLoader,
|
|
11
11
|
NetworkError,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
SUBAGENT_ALLOWED_TOOLS,
|
|
19
19
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
20
20
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-OHUHYWBR.js";
|
|
22
22
|
import {
|
|
23
23
|
fileCheckpoints
|
|
24
24
|
} from "./chunk-4BKXL7SM.js";
|
|
@@ -372,7 +372,7 @@ Important rules:
|
|
|
372
372
|
}
|
|
373
373
|
updateCwdFromCommand(command, effectiveCwd);
|
|
374
374
|
pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
|
|
375
|
-
const result =
|
|
375
|
+
const result = Buffer.isBuffer(stdout) ? stdout.toString("utf-8") : String(stdout ?? "");
|
|
376
376
|
return result || "(command completed with no output)";
|
|
377
377
|
} catch (err) {
|
|
378
378
|
pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
|
package/dist/electron-server.js
CHANGED
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
VERSION,
|
|
37
37
|
buildUserIdentityPrompt,
|
|
38
38
|
runTestsTool
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-KQZU2VS5.js";
|
|
40
40
|
import {
|
|
41
41
|
hasSemanticIndex,
|
|
42
42
|
semanticSearch
|
|
@@ -604,10 +604,20 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
604
604
|
]
|
|
605
605
|
};
|
|
606
606
|
async initialize(apiKey, options) {
|
|
607
|
-
|
|
607
|
+
const clientOptions = {
|
|
608
608
|
apiKey,
|
|
609
609
|
baseURL: options?.baseUrl
|
|
610
|
-
}
|
|
610
|
+
};
|
|
611
|
+
const proxyUrl = options?.proxy;
|
|
612
|
+
try {
|
|
613
|
+
const { Agent, ProxyAgent, fetch: undiciFetch } = await import("undici");
|
|
614
|
+
const STREAM_BODY_TIMEOUT = 30 * 60 * 1e3;
|
|
615
|
+
const STREAM_HEADERS_TIMEOUT = 5 * 60 * 1e3;
|
|
616
|
+
const dispatcher = proxyUrl ? new ProxyAgent({ uri: proxyUrl, bodyTimeout: STREAM_BODY_TIMEOUT, headersTimeout: STREAM_HEADERS_TIMEOUT }) : new Agent({ bodyTimeout: STREAM_BODY_TIMEOUT, headersTimeout: STREAM_HEADERS_TIMEOUT });
|
|
617
|
+
clientOptions.fetch = ((url, init) => undiciFetch(url, { ...init, dispatcher }));
|
|
618
|
+
} catch {
|
|
619
|
+
}
|
|
620
|
+
this.client = new Anthropic(clientOptions);
|
|
611
621
|
}
|
|
612
622
|
/**
|
|
613
623
|
* 将内部 MessageContentPart[] 格式转换为 Anthropic SDK 期望的 ContentBlockParam[]。
|
|
@@ -1464,13 +1474,20 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1464
1474
|
timeout: this.defaultTimeout
|
|
1465
1475
|
};
|
|
1466
1476
|
const proxyUrl = options?.proxy;
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1477
|
+
try {
|
|
1478
|
+
const { Agent, ProxyAgent, fetch: undiciFetch } = await import("undici");
|
|
1479
|
+
const STREAM_BODY_TIMEOUT = 30 * 60 * 1e3;
|
|
1480
|
+
const STREAM_HEADERS_TIMEOUT = 5 * 60 * 1e3;
|
|
1481
|
+
const dispatcher = proxyUrl ? new ProxyAgent({
|
|
1482
|
+
uri: proxyUrl,
|
|
1483
|
+
bodyTimeout: STREAM_BODY_TIMEOUT,
|
|
1484
|
+
headersTimeout: STREAM_HEADERS_TIMEOUT
|
|
1485
|
+
}) : new Agent({
|
|
1486
|
+
bodyTimeout: STREAM_BODY_TIMEOUT,
|
|
1487
|
+
headersTimeout: STREAM_HEADERS_TIMEOUT
|
|
1488
|
+
});
|
|
1489
|
+
clientOptions.fetch = ((url, init) => undiciFetch(url, { ...init, dispatcher }));
|
|
1490
|
+
} catch {
|
|
1474
1491
|
}
|
|
1475
1492
|
this.client = new OpenAI(clientOptions);
|
|
1476
1493
|
}
|
|
@@ -2268,6 +2285,40 @@ function peelMetaNarration(content) {
|
|
|
2268
2285
|
}
|
|
2269
2286
|
return out.trim();
|
|
2270
2287
|
}
|
|
2288
|
+
var META_NARRATION_HARD_MARKERS = [
|
|
2289
|
+
/\[⚠️\s*CONTENT GENERATION MODE\]/,
|
|
2290
|
+
/CONTENT_ONLY_STREAM_REMINDER\b/,
|
|
2291
|
+
/<system-reminder>/i
|
|
2292
|
+
];
|
|
2293
|
+
var META_NARRATION_HEURISTICS = [
|
|
2294
|
+
/\bthe user (?:is asking me|wants me|is requesting|expects me)\b/i,
|
|
2295
|
+
/\blet me (?:re-?read|re-?consider|reconsider|think about|carefully (?:re-?read|consider))\b/i,
|
|
2296
|
+
/\bI'?m (?:in (?:a )?content-only|in CONTENT-ONLY|currently in)\b/i,
|
|
2297
|
+
/\bI think (?:there might be|I should|I cannot|the (?:user|best)|maybe)\b/i,
|
|
2298
|
+
/\bWait,?\s+let me\b/i,
|
|
2299
|
+
/\bActually,?\s+I\b/i,
|
|
2300
|
+
/\bI need to be honest with the user\b/i,
|
|
2301
|
+
/\bI(?:'m| am) in a special mode\b/i,
|
|
2302
|
+
/\bGiven that I cannot\b/i
|
|
2303
|
+
];
|
|
2304
|
+
function detectMetaNarration(content) {
|
|
2305
|
+
if (!content) return null;
|
|
2306
|
+
const head = content.slice(0, 2e3);
|
|
2307
|
+
for (const re of META_NARRATION_HARD_MARKERS) {
|
|
2308
|
+
if (re.test(head)) return re.source;
|
|
2309
|
+
}
|
|
2310
|
+
if (/^#{1,3}\s+\S/m.test(head)) return null;
|
|
2311
|
+
let hits = 0;
|
|
2312
|
+
let firstMatch = "";
|
|
2313
|
+
for (const re of META_NARRATION_HEURISTICS) {
|
|
2314
|
+
if (re.test(head)) {
|
|
2315
|
+
hits++;
|
|
2316
|
+
if (!firstMatch) firstMatch = re.source;
|
|
2317
|
+
if (hits >= 2) return `meta-narration:${firstMatch}`;
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
return null;
|
|
2321
|
+
}
|
|
2271
2322
|
function looksLikeDocumentBody(content) {
|
|
2272
2323
|
if (!content || content.length < 200) return false;
|
|
2273
2324
|
if (/^#{1,6}\s+\S/m.test(content)) return true;
|
|
@@ -3885,7 +3936,7 @@ Important rules:
|
|
|
3885
3936
|
}
|
|
3886
3937
|
updateCwdFromCommand(command, effectiveCwd);
|
|
3887
3938
|
pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
|
|
3888
|
-
const result =
|
|
3939
|
+
const result = Buffer.isBuffer(stdout) ? stdout.toString("utf-8") : String(stdout ?? "");
|
|
3889
3940
|
return result || "(command completed with no output)";
|
|
3890
3941
|
} catch (err) {
|
|
3891
3942
|
pushBashUndoEntries(beforeSnapshot, parsedTargetsBefore, effectiveCwd);
|
|
@@ -10842,6 +10893,31 @@ ${summaryResult.content}`,
|
|
|
10842
10893
|
await new Promise((resolve7, reject) => {
|
|
10843
10894
|
fileStream.end((err) => err ? reject(err) : resolve7());
|
|
10844
10895
|
});
|
|
10896
|
+
const metaMatch = detectMetaNarration(fullContent);
|
|
10897
|
+
if (metaMatch) {
|
|
10898
|
+
try {
|
|
10899
|
+
unlinkSync4(saveToFile);
|
|
10900
|
+
} catch {
|
|
10901
|
+
}
|
|
10902
|
+
isError = true;
|
|
10903
|
+
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.
|
|
10904
|
+
|
|
10905
|
+
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.`;
|
|
10906
|
+
if (teeUsage) {
|
|
10907
|
+
roundUsage.inputTokens += teeUsage.inputTokens;
|
|
10908
|
+
roundUsage.outputTokens += teeUsage.outputTokens;
|
|
10909
|
+
roundUsage.cacheCreationTokens += teeUsage.cacheCreationTokens ?? 0;
|
|
10910
|
+
roundUsage.cacheReadTokens += teeUsage.cacheReadTokens ?? 0;
|
|
10911
|
+
}
|
|
10912
|
+
this.send({
|
|
10913
|
+
type: "tool_call_result",
|
|
10914
|
+
callId: call.id,
|
|
10915
|
+
result: summary,
|
|
10916
|
+
isError: true,
|
|
10917
|
+
endTime: Date.now()
|
|
10918
|
+
});
|
|
10919
|
+
return { content: "", summary, isError: true };
|
|
10920
|
+
}
|
|
10845
10921
|
const pseudoMatch = detectPseudoToolCalls(fullContent);
|
|
10846
10922
|
if (pseudoMatch) {
|
|
10847
10923
|
const cleaned = stripPseudoToolCalls(fullContent);
|
|
@@ -10879,9 +10955,13 @@ ${summaryResult.content}`,
|
|
|
10879
10955
|
} catch {
|
|
10880
10956
|
}
|
|
10881
10957
|
}
|
|
10958
|
+
try {
|
|
10959
|
+
unlinkSync4(saveToFile);
|
|
10960
|
+
} catch {
|
|
10961
|
+
}
|
|
10882
10962
|
isError = true;
|
|
10883
10963
|
const msg = err instanceof Error ? err.message : String(err);
|
|
10884
|
-
summary = `[save_last_response failed] ${msg}
|
|
10964
|
+
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).`;
|
|
10885
10965
|
}
|
|
10886
10966
|
this.send({
|
|
10887
10967
|
type: "tool_call_result",
|
|
@@ -11960,7 +12040,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
11960
12040
|
case "test": {
|
|
11961
12041
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
11962
12042
|
try {
|
|
11963
|
-
const { executeTests } = await import("./run-tests-
|
|
12043
|
+
const { executeTests } = await import("./run-tests-7VYL7OVA.js");
|
|
11964
12044
|
const argStr = args.join(" ").trim();
|
|
11965
12045
|
let testArgs = {};
|
|
11966
12046
|
if (argStr) {
|
|
@@ -12944,11 +13024,12 @@ async function setupProxy(configProxy) {
|
|
|
12944
13024
|
}
|
|
12945
13025
|
|
|
12946
13026
|
// src/web/auth.ts
|
|
12947
|
-
import { existsSync as existsSync21, readFileSync as readFileSync14, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, readdirSync as readdirSync10, copyFileSync } from "fs";
|
|
13027
|
+
import { existsSync as existsSync21, readFileSync as readFileSync14, writeFileSync as writeFileSync9, mkdirSync as mkdirSync10, readdirSync as readdirSync10, copyFileSync, renameSync as renameSync2, unlinkSync as unlinkSync5 } from "fs";
|
|
12948
13028
|
import { join as join14 } from "path";
|
|
12949
13029
|
import { createHmac, randomBytes, timingSafeEqual, pbkdf2Sync } from "crypto";
|
|
12950
13030
|
var USERS_FILE = "users.json";
|
|
12951
13031
|
var TOKEN_EXPIRY_HOURS = 24;
|
|
13032
|
+
var TOKEN_EXPIRY_MS = TOKEN_EXPIRY_HOURS * 3600 * 1e3;
|
|
12952
13033
|
var USERS_DIR = "users";
|
|
12953
13034
|
var LOGIN_MAX_FAILS = 5;
|
|
12954
13035
|
var LOGIN_LOCKOUT_MS = 15 * 60 * 1e3;
|
|
@@ -13192,7 +13273,17 @@ var AuthManager = class {
|
|
|
13192
13273
|
}
|
|
13193
13274
|
saveDB(db) {
|
|
13194
13275
|
mkdirSync10(this.baseDir, { recursive: true });
|
|
13195
|
-
|
|
13276
|
+
const tmp = `${this.usersFile}.tmp`;
|
|
13277
|
+
try {
|
|
13278
|
+
writeFileSync9(tmp, JSON.stringify(db, null, 2), "utf-8");
|
|
13279
|
+
renameSync2(tmp, this.usersFile);
|
|
13280
|
+
} catch (err) {
|
|
13281
|
+
try {
|
|
13282
|
+
unlinkSync5(tmp);
|
|
13283
|
+
} catch {
|
|
13284
|
+
}
|
|
13285
|
+
throw err;
|
|
13286
|
+
}
|
|
13196
13287
|
}
|
|
13197
13288
|
/** Legacy hash — kept only for migrating old users (v0.2.x) */
|
|
13198
13289
|
hashPasswordLegacy(password, salt) {
|
|
@@ -13406,7 +13497,7 @@ async function startWebServer(options = {}) {
|
|
|
13406
13497
|
}
|
|
13407
13498
|
const token = authManager.login(username, password);
|
|
13408
13499
|
console.log(` \u2713 User registered via API: ${username}${firstRun ? " (first-run)" : ""}`);
|
|
13409
|
-
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge:
|
|
13500
|
+
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge: TOKEN_EXPIRY_MS });
|
|
13410
13501
|
res.json({ success: true, username });
|
|
13411
13502
|
});
|
|
13412
13503
|
app.post("/api/auth/login", (req, res) => {
|
|
@@ -13420,7 +13511,7 @@ async function startWebServer(options = {}) {
|
|
|
13420
13511
|
res.status(401).json({ error: "Invalid username or password" });
|
|
13421
13512
|
return;
|
|
13422
13513
|
}
|
|
13423
|
-
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge:
|
|
13514
|
+
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge: TOKEN_EXPIRY_MS });
|
|
13424
13515
|
res.json({ success: true, username });
|
|
13425
13516
|
});
|
|
13426
13517
|
app.post("/api/auth/logout", (_req, res) => {
|
|
@@ -386,7 +386,7 @@ ${content}`);
|
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
388
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
389
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
389
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-24IGVXYP.js");
|
|
390
390
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
391
391
|
let interrupted = false;
|
|
392
392
|
const onSigint = () => {
|
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
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) => {
|
|
6889
|
-
const { AuthManager } = await import("./auth-
|
|
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") {
|
|
@@ -7018,7 +7091,7 @@ program.command("sessions").description("List recent conversation sessions").act
|
|
|
7018
7091
|
});
|
|
7019
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) => {
|
|
7020
7093
|
try {
|
|
7021
|
-
const batch = await import("./batch-
|
|
7094
|
+
const batch = await import("./batch-SHNIUSW2.js");
|
|
7022
7095
|
switch (action) {
|
|
7023
7096
|
case "submit":
|
|
7024
7097
|
if (!arg) {
|
|
@@ -7061,7 +7134,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
|
|
|
7061
7134
|
}
|
|
7062
7135
|
});
|
|
7063
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) => {
|
|
7064
|
-
const { startMcpServer } = await import("./server-
|
|
7137
|
+
const { startMcpServer } = await import("./server-3P5BYK74.js");
|
|
7065
7138
|
await startMcpServer({
|
|
7066
7139
|
allowDestructive: !!options.allowDestructive,
|
|
7067
7140
|
allowOutsideCwd: !!options.allowOutsideCwd,
|
|
@@ -7188,7 +7261,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
7188
7261
|
}),
|
|
7189
7262
|
config.get("customProviders")
|
|
7190
7263
|
);
|
|
7191
|
-
const { startHub } = await import("./hub-
|
|
7264
|
+
const { startHub } = await import("./hub-E3WMJGYK.js");
|
|
7192
7265
|
await startHub(
|
|
7193
7266
|
{
|
|
7194
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";
|
|
@@ -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,
|
|
@@ -1294,6 +1296,31 @@ ${summaryResult.content}`,
|
|
|
1294
1296
|
await new Promise((resolve3, reject) => {
|
|
1295
1297
|
fileStream.end((err) => err ? reject(err) : resolve3());
|
|
1296
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
|
+
}
|
|
1297
1324
|
const pseudoMatch = detectPseudoToolCalls(fullContent);
|
|
1298
1325
|
if (pseudoMatch) {
|
|
1299
1326
|
const cleaned = stripPseudoToolCalls(fullContent);
|
|
@@ -1331,9 +1358,13 @@ ${summaryResult.content}`,
|
|
|
1331
1358
|
} catch {
|
|
1332
1359
|
}
|
|
1333
1360
|
}
|
|
1361
|
+
try {
|
|
1362
|
+
unlinkSync(saveToFile);
|
|
1363
|
+
} catch {
|
|
1364
|
+
}
|
|
1334
1365
|
isError = true;
|
|
1335
1366
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1336
|
-
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).`;
|
|
1337
1368
|
}
|
|
1338
1369
|
this.send({
|
|
1339
1370
|
type: "tool_call_result",
|
|
@@ -2412,7 +2443,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2412
2443
|
case "test": {
|
|
2413
2444
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2414
2445
|
try {
|
|
2415
|
-
const { executeTests } = await import("./run-tests-
|
|
2446
|
+
const { executeTests } = await import("./run-tests-TWE7TJ4T.js");
|
|
2416
2447
|
const argStr = args.join(" ").trim();
|
|
2417
2448
|
let testArgs = {};
|
|
2418
2449
|
if (argStr) {
|
|
@@ -3573,7 +3604,7 @@ async function startWebServer(options = {}) {
|
|
|
3573
3604
|
}
|
|
3574
3605
|
const token = authManager.login(username, password);
|
|
3575
3606
|
console.log(` \u2713 User registered via API: ${username}${firstRun ? " (first-run)" : ""}`);
|
|
3576
|
-
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge:
|
|
3607
|
+
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge: TOKEN_EXPIRY_MS });
|
|
3577
3608
|
res.json({ success: true, username });
|
|
3578
3609
|
});
|
|
3579
3610
|
app.post("/api/auth/login", (req, res) => {
|
|
@@ -3587,7 +3618,7 @@ async function startWebServer(options = {}) {
|
|
|
3587
3618
|
res.status(401).json({ error: "Invalid username or password" });
|
|
3588
3619
|
return;
|
|
3589
3620
|
}
|
|
3590
|
-
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge:
|
|
3621
|
+
res.cookie("aicli_token", token, { httpOnly: true, sameSite: "strict", maxAge: TOKEN_EXPIRY_MS });
|
|
3591
3622
|
res.json({ success: true, username });
|
|
3592
3623
|
});
|
|
3593
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";
|
|
@@ -845,132 +845,132 @@ button, a, .session-item, .file-tree-row, .template-item, .tool-item, .mcp-serve
|
|
|
845
845
|
@media (display-mode: standalone) {
|
|
846
846
|
.navbar { padding-top: env(safe-area-inset-top, 0px); }
|
|
847
847
|
}
|
|
848
|
-
|
|
849
|
-
/* ── Session Replay (B1) ───────────────────────────── */
|
|
850
|
-
.replay-step {
|
|
851
|
-
border-left: 3px solid hsl(var(--b3));
|
|
852
|
-
padding: 0.5rem 0.6rem;
|
|
853
|
-
background: hsl(var(--b1));
|
|
854
|
-
border-radius: 0 0.35rem 0.35rem 0;
|
|
855
|
-
font-size: 0.85rem;
|
|
856
|
-
}
|
|
857
|
-
.replay-step.role-user { border-left-color: #3b82f6; }
|
|
858
|
-
.replay-step.role-assistant { border-left-color: #10b981; }
|
|
859
|
-
.replay-step.role-tool { border-left-color: #f59e0b; }
|
|
860
|
-
.replay-step.role-tool.error { border-left-color: #ef4444; }
|
|
861
|
-
.replay-step-header {
|
|
862
|
-
display: flex;
|
|
863
|
-
gap: 0.5rem;
|
|
864
|
-
align-items: center;
|
|
865
|
-
font-size: 0.72rem;
|
|
866
|
-
opacity: 0.75;
|
|
867
|
-
margin-bottom: 0.25rem;
|
|
868
|
-
}
|
|
869
|
-
.replay-step-header .role-tag {
|
|
870
|
-
font-weight: 600;
|
|
871
|
-
padding: 0 0.35rem;
|
|
872
|
-
border-radius: 0.25rem;
|
|
873
|
-
background: hsl(var(--b3));
|
|
874
|
-
}
|
|
875
|
-
.replay-step-body {
|
|
876
|
-
white-space: pre-wrap;
|
|
877
|
-
word-break: break-word;
|
|
878
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
879
|
-
font-size: 0.78rem;
|
|
880
|
-
max-height: 18rem;
|
|
881
|
-
overflow-y: auto;
|
|
882
|
-
}
|
|
883
|
-
.replay-step-body.text-body {
|
|
884
|
-
font-family: inherit;
|
|
885
|
-
font-size: 0.85rem;
|
|
886
|
-
}
|
|
887
|
-
.replay-tool-block {
|
|
888
|
-
margin-top: 0.3rem;
|
|
889
|
-
padding: 0.4rem;
|
|
890
|
-
background: hsl(var(--b2));
|
|
891
|
-
border-radius: 0.3rem;
|
|
892
|
-
font-size: 0.78rem;
|
|
893
|
-
}
|
|
894
|
-
.replay-tool-block .tool-name {
|
|
895
|
-
font-weight: 600;
|
|
896
|
-
color: #f59e0b;
|
|
897
|
-
}
|
|
898
|
-
.replay-tool-block pre {
|
|
899
|
-
margin: 0.2rem 0 0;
|
|
900
|
-
white-space: pre-wrap;
|
|
901
|
-
word-break: break-word;
|
|
902
|
-
font-size: 0.72rem;
|
|
903
|
-
max-height: 12rem;
|
|
904
|
-
overflow-y: auto;
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
/* ── B2 Branch picker (sidebar) ─────────────────────────── */
|
|
908
|
-
.branch-item {
|
|
909
|
-
display: flex;
|
|
910
|
-
align-items: center;
|
|
911
|
-
gap: 0.35rem;
|
|
912
|
-
padding: 0.35rem 0.5rem;
|
|
913
|
-
border-radius: 0.35rem;
|
|
914
|
-
cursor: pointer;
|
|
915
|
-
border: 1px solid transparent;
|
|
916
|
-
transition: background 0.1s, border-color 0.1s;
|
|
917
|
-
font-size: 0.78rem;
|
|
918
|
-
line-height: 1.25;
|
|
919
|
-
position: relative;
|
|
920
|
-
}
|
|
921
|
-
.branch-item:hover {
|
|
922
|
-
background: rgba(128, 128, 128, 0.12);
|
|
923
|
-
}
|
|
924
|
-
.branch-item.active {
|
|
925
|
-
background: rgba(34, 197, 94, 0.12);
|
|
926
|
-
border-color: rgba(34, 197, 94, 0.45);
|
|
927
|
-
}
|
|
928
|
-
.branch-item .branch-marker {
|
|
929
|
-
flex-shrink: 0;
|
|
930
|
-
width: 0.8rem;
|
|
931
|
-
color: rgb(34, 197, 94);
|
|
932
|
-
}
|
|
933
|
-
.branch-item .branch-title {
|
|
934
|
-
flex: 1;
|
|
935
|
-
min-width: 0;
|
|
936
|
-
overflow: hidden;
|
|
937
|
-
text-overflow: ellipsis;
|
|
938
|
-
white-space: nowrap;
|
|
939
|
-
}
|
|
940
|
-
.branch-item .branch-id {
|
|
941
|
-
flex-shrink: 0;
|
|
942
|
-
opacity: 0.5;
|
|
943
|
-
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
944
|
-
font-size: 0.7rem;
|
|
945
|
-
}
|
|
946
|
-
.branch-item .branch-count {
|
|
947
|
-
flex-shrink: 0;
|
|
948
|
-
opacity: 0.55;
|
|
949
|
-
font-size: 0.7rem;
|
|
950
|
-
}
|
|
951
|
-
.branch-item .branch-actions {
|
|
952
|
-
display: none;
|
|
953
|
-
gap: 0.15rem;
|
|
954
|
-
flex-shrink: 0;
|
|
955
|
-
}
|
|
956
|
-
.branch-item:hover .branch-actions {
|
|
957
|
-
display: flex;
|
|
958
|
-
}
|
|
959
|
-
.branch-item .branch-actions button {
|
|
960
|
-
background: transparent;
|
|
961
|
-
border: none;
|
|
962
|
-
padding: 0 0.2rem;
|
|
963
|
-
font-size: 0.72rem;
|
|
964
|
-
cursor: pointer;
|
|
965
|
-
opacity: 0.7;
|
|
966
|
-
}
|
|
967
|
-
.branch-item .branch-actions button:hover {
|
|
968
|
-
opacity: 1;
|
|
969
|
-
}
|
|
970
|
-
.branch-item .branch-indent {
|
|
971
|
-
flex-shrink: 0;
|
|
972
|
-
color: rgba(128, 128, 128, 0.5);
|
|
973
|
-
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
974
|
-
font-size: 0.72rem;
|
|
975
|
-
white-space: pre;
|
|
976
|
-
}
|
|
848
|
+
|
|
849
|
+
/* ── Session Replay (B1) ───────────────────────────── */
|
|
850
|
+
.replay-step {
|
|
851
|
+
border-left: 3px solid hsl(var(--b3));
|
|
852
|
+
padding: 0.5rem 0.6rem;
|
|
853
|
+
background: hsl(var(--b1));
|
|
854
|
+
border-radius: 0 0.35rem 0.35rem 0;
|
|
855
|
+
font-size: 0.85rem;
|
|
856
|
+
}
|
|
857
|
+
.replay-step.role-user { border-left-color: #3b82f6; }
|
|
858
|
+
.replay-step.role-assistant { border-left-color: #10b981; }
|
|
859
|
+
.replay-step.role-tool { border-left-color: #f59e0b; }
|
|
860
|
+
.replay-step.role-tool.error { border-left-color: #ef4444; }
|
|
861
|
+
.replay-step-header {
|
|
862
|
+
display: flex;
|
|
863
|
+
gap: 0.5rem;
|
|
864
|
+
align-items: center;
|
|
865
|
+
font-size: 0.72rem;
|
|
866
|
+
opacity: 0.75;
|
|
867
|
+
margin-bottom: 0.25rem;
|
|
868
|
+
}
|
|
869
|
+
.replay-step-header .role-tag {
|
|
870
|
+
font-weight: 600;
|
|
871
|
+
padding: 0 0.35rem;
|
|
872
|
+
border-radius: 0.25rem;
|
|
873
|
+
background: hsl(var(--b3));
|
|
874
|
+
}
|
|
875
|
+
.replay-step-body {
|
|
876
|
+
white-space: pre-wrap;
|
|
877
|
+
word-break: break-word;
|
|
878
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
879
|
+
font-size: 0.78rem;
|
|
880
|
+
max-height: 18rem;
|
|
881
|
+
overflow-y: auto;
|
|
882
|
+
}
|
|
883
|
+
.replay-step-body.text-body {
|
|
884
|
+
font-family: inherit;
|
|
885
|
+
font-size: 0.85rem;
|
|
886
|
+
}
|
|
887
|
+
.replay-tool-block {
|
|
888
|
+
margin-top: 0.3rem;
|
|
889
|
+
padding: 0.4rem;
|
|
890
|
+
background: hsl(var(--b2));
|
|
891
|
+
border-radius: 0.3rem;
|
|
892
|
+
font-size: 0.78rem;
|
|
893
|
+
}
|
|
894
|
+
.replay-tool-block .tool-name {
|
|
895
|
+
font-weight: 600;
|
|
896
|
+
color: #f59e0b;
|
|
897
|
+
}
|
|
898
|
+
.replay-tool-block pre {
|
|
899
|
+
margin: 0.2rem 0 0;
|
|
900
|
+
white-space: pre-wrap;
|
|
901
|
+
word-break: break-word;
|
|
902
|
+
font-size: 0.72rem;
|
|
903
|
+
max-height: 12rem;
|
|
904
|
+
overflow-y: auto;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/* ── B2 Branch picker (sidebar) ─────────────────────────── */
|
|
908
|
+
.branch-item {
|
|
909
|
+
display: flex;
|
|
910
|
+
align-items: center;
|
|
911
|
+
gap: 0.35rem;
|
|
912
|
+
padding: 0.35rem 0.5rem;
|
|
913
|
+
border-radius: 0.35rem;
|
|
914
|
+
cursor: pointer;
|
|
915
|
+
border: 1px solid transparent;
|
|
916
|
+
transition: background 0.1s, border-color 0.1s;
|
|
917
|
+
font-size: 0.78rem;
|
|
918
|
+
line-height: 1.25;
|
|
919
|
+
position: relative;
|
|
920
|
+
}
|
|
921
|
+
.branch-item:hover {
|
|
922
|
+
background: rgba(128, 128, 128, 0.12);
|
|
923
|
+
}
|
|
924
|
+
.branch-item.active {
|
|
925
|
+
background: rgba(34, 197, 94, 0.12);
|
|
926
|
+
border-color: rgba(34, 197, 94, 0.45);
|
|
927
|
+
}
|
|
928
|
+
.branch-item .branch-marker {
|
|
929
|
+
flex-shrink: 0;
|
|
930
|
+
width: 0.8rem;
|
|
931
|
+
color: rgb(34, 197, 94);
|
|
932
|
+
}
|
|
933
|
+
.branch-item .branch-title {
|
|
934
|
+
flex: 1;
|
|
935
|
+
min-width: 0;
|
|
936
|
+
overflow: hidden;
|
|
937
|
+
text-overflow: ellipsis;
|
|
938
|
+
white-space: nowrap;
|
|
939
|
+
}
|
|
940
|
+
.branch-item .branch-id {
|
|
941
|
+
flex-shrink: 0;
|
|
942
|
+
opacity: 0.5;
|
|
943
|
+
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
944
|
+
font-size: 0.7rem;
|
|
945
|
+
}
|
|
946
|
+
.branch-item .branch-count {
|
|
947
|
+
flex-shrink: 0;
|
|
948
|
+
opacity: 0.55;
|
|
949
|
+
font-size: 0.7rem;
|
|
950
|
+
}
|
|
951
|
+
.branch-item .branch-actions {
|
|
952
|
+
display: none;
|
|
953
|
+
gap: 0.15rem;
|
|
954
|
+
flex-shrink: 0;
|
|
955
|
+
}
|
|
956
|
+
.branch-item:hover .branch-actions {
|
|
957
|
+
display: flex;
|
|
958
|
+
}
|
|
959
|
+
.branch-item .branch-actions button {
|
|
960
|
+
background: transparent;
|
|
961
|
+
border: none;
|
|
962
|
+
padding: 0 0.2rem;
|
|
963
|
+
font-size: 0.72rem;
|
|
964
|
+
cursor: pointer;
|
|
965
|
+
opacity: 0.7;
|
|
966
|
+
}
|
|
967
|
+
.branch-item .branch-actions button:hover {
|
|
968
|
+
opacity: 1;
|
|
969
|
+
}
|
|
970
|
+
.branch-item .branch-indent {
|
|
971
|
+
flex-shrink: 0;
|
|
972
|
+
color: rgba(128, 128, 128, 0.5);
|
|
973
|
+
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
974
|
+
font-size: 0.72rem;
|
|
975
|
+
white-space: pre;
|
|
976
|
+
}
|