jinzd-ai-cli 0.4.210 → 0.4.212
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 +122 -1
- package/README.zh-CN.md +63 -0
- package/dist/{batch-MFPYHOIL.js → batch-WIKFEOAZ.js} +2 -2
- package/dist/{chat-index-UBCWHBLR.js → chat-index-R2E27VXN.js} +1 -1
- package/dist/{chunk-GRJNQJA5.js → chunk-GBBVCZ4W.js} +1 -1
- package/dist/{chunk-7JWT3KXO.js → chunk-HW2ALWQJ.js} +2 -2
- package/dist/{chunk-E2ZWWE6Q.js → chunk-HX6N6QEY.js} +1 -1
- package/dist/{chunk-DJ35G5VO.js → chunk-IFZX26K7.js} +1 -1
- package/dist/{chunk-HZQVX7VF.js → chunk-KE4B3NOQ.js} +1 -1
- package/dist/{chunk-NWP7C6CC.js → chunk-LU6FBJQ5.js} +1 -1
- package/dist/{chunk-NEPFADHX.js → chunk-N5LB3PPL.js} +567 -87
- package/dist/{chunk-P6MTFCXB.js → chunk-NYCBOVNF.js} +62 -5
- package/dist/{chunk-W7UKO3PS.js → chunk-OQGVGPEK.js} +5 -0
- package/dist/{ci-QLJUDLMY.js → ci-X3LNUFZV.js} +2 -2
- package/dist/{constants-47OR72MV.js → constants-KDWG4KR4.js} +1 -1
- package/dist/{doctor-cli-32COMA5K.js → doctor-cli-TJTWIW7U.js} +4 -4
- package/dist/electron-server.js +947 -280
- package/dist/{hub-3NWJUCLK.js → hub-JWSV4MKC.js} +1 -1
- package/dist/index.js +160 -18
- package/dist/{run-tests-NT2UIUVB.js → run-tests-D7YBY4XB.js} +1 -1
- package/dist/{run-tests-UT7RZ7Y3.js → run-tests-H4Q2PRX6.js} +2 -2
- package/dist/{server-AIHVMLNU.js → server-OFKGDRYI.js} +4 -4
- package/dist/{server-E5D54DIZ.js → server-VNCN7AY5.js} +187 -29
- package/dist/{task-orchestrator-BFDSTSOH.js → task-orchestrator-AL2E642M.js} +4 -4
- package/dist/{usage-P4B2RZKL.js → usage-LB6REWPO.js} +2 -2
- package/dist/web/client/app.js +1 -1
- package/package.json +1 -1
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
scanDirTree,
|
|
25
25
|
scanProject,
|
|
26
26
|
setupProxy
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-HW2ALWQJ.js";
|
|
28
28
|
import {
|
|
29
29
|
buildReviewPrompt,
|
|
30
30
|
buildSecurityReviewPrompt
|
|
@@ -33,13 +33,17 @@ import {
|
|
|
33
33
|
ToolExecutor,
|
|
34
34
|
ToolRegistry,
|
|
35
35
|
askUserContext,
|
|
36
|
-
|
|
36
|
+
checkNetworkPolicy,
|
|
37
|
+
checkPermissionWithProfile,
|
|
37
38
|
cleanupRejectedTeeFile,
|
|
38
39
|
estimateTokens,
|
|
40
|
+
formatPermissionProfileWarning,
|
|
41
|
+
getPendingHookTrust,
|
|
39
42
|
googleSearchContext,
|
|
40
43
|
groupCallsByPhase,
|
|
41
44
|
renderDiff,
|
|
42
45
|
runHook,
|
|
46
|
+
runLifecycleHooks,
|
|
43
47
|
runSafePhases,
|
|
44
48
|
runWithSessionKey,
|
|
45
49
|
setContextWindow,
|
|
@@ -47,10 +51,10 @@ import {
|
|
|
47
51
|
spawnAgentContext,
|
|
48
52
|
truncateOutput,
|
|
49
53
|
undoStack
|
|
50
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-N5LB3PPL.js";
|
|
51
55
|
import "./chunk-T2NL5ZIA.js";
|
|
52
56
|
import "./chunk-BXP6YZ2P.js";
|
|
53
|
-
import "./chunk-
|
|
57
|
+
import "./chunk-HX6N6QEY.js";
|
|
54
58
|
import {
|
|
55
59
|
SessionManager,
|
|
56
60
|
getContentText
|
|
@@ -64,7 +68,7 @@ import {
|
|
|
64
68
|
} from "./chunk-QMXC327F.js";
|
|
65
69
|
import {
|
|
66
70
|
runTool
|
|
67
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-IFZX26K7.js";
|
|
68
72
|
import {
|
|
69
73
|
CONTENT_ONLY_STREAM_REMINDER,
|
|
70
74
|
TEE_FINAL_USER_NUDGE,
|
|
@@ -83,7 +87,7 @@ import {
|
|
|
83
87
|
} from "./chunk-XPBEJB27.js";
|
|
84
88
|
import {
|
|
85
89
|
ConfigManager
|
|
86
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-NYCBOVNF.js";
|
|
87
91
|
import "./chunk-TZQHYZKT.js";
|
|
88
92
|
import {
|
|
89
93
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
@@ -102,7 +106,7 @@ import {
|
|
|
102
106
|
SKILLS_DIR_NAME,
|
|
103
107
|
VERSION,
|
|
104
108
|
buildUserIdentityPrompt
|
|
105
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-GBBVCZ4W.js";
|
|
106
110
|
import {
|
|
107
111
|
formatGitContextForPrompt,
|
|
108
112
|
getGitContext,
|
|
@@ -111,7 +115,9 @@ import {
|
|
|
111
115
|
import "./chunk-4BKXL7SM.js";
|
|
112
116
|
import "./chunk-TB4W4Y4T.js";
|
|
113
117
|
import "./chunk-KHYD3WXE.js";
|
|
114
|
-
import
|
|
118
|
+
import {
|
|
119
|
+
scanString
|
|
120
|
+
} from "./chunk-SLSWPBK3.js";
|
|
115
121
|
import "./chunk-K3CF65QH.js";
|
|
116
122
|
import "./chunk-CKH4KQ4E.js";
|
|
117
123
|
import {
|
|
@@ -128,6 +134,7 @@ import { networkInterfaces } from "os";
|
|
|
128
134
|
|
|
129
135
|
// src/web/tool-executor-web.ts
|
|
130
136
|
import { randomUUID } from "crypto";
|
|
137
|
+
import { tmpdir } from "os";
|
|
131
138
|
import { existsSync, readFileSync } from "fs";
|
|
132
139
|
var ToolExecutorWeb = class _ToolExecutorWeb {
|
|
133
140
|
constructor(registry, ws) {
|
|
@@ -139,6 +146,12 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
|
|
|
139
146
|
hookConfig;
|
|
140
147
|
permissionRules = [];
|
|
141
148
|
defaultPermission = "confirm";
|
|
149
|
+
permissionProfileName = "legacy";
|
|
150
|
+
permissionProfile;
|
|
151
|
+
allowedPermissionProfiles = [];
|
|
152
|
+
workspaceRoot = process.cwd();
|
|
153
|
+
networkPolicy;
|
|
154
|
+
hookConfigDir = process.cwd();
|
|
142
155
|
/** Pending confirm promises keyed by requestId */
|
|
143
156
|
pendingConfirms = /* @__PURE__ */ new Map();
|
|
144
157
|
/** Pending batch confirm promises */
|
|
@@ -173,6 +186,12 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
|
|
|
173
186
|
this.hookConfig = opts.hookConfig;
|
|
174
187
|
if (opts.permissionRules) this.permissionRules = opts.permissionRules;
|
|
175
188
|
if (opts.defaultPermission) this.defaultPermission = opts.defaultPermission;
|
|
189
|
+
if (opts.permissionProfileName) this.permissionProfileName = opts.permissionProfileName;
|
|
190
|
+
if (opts.permissionProfile) this.permissionProfile = opts.permissionProfile;
|
|
191
|
+
if (opts.allowedPermissionProfiles) this.allowedPermissionProfiles = opts.allowedPermissionProfiles;
|
|
192
|
+
if (opts.workspaceRoot) this.workspaceRoot = opts.workspaceRoot;
|
|
193
|
+
if (opts.networkPolicy) this.networkPolicy = opts.networkPolicy;
|
|
194
|
+
if (opts.hookConfigDir) this.hookConfigDir = opts.hookConfigDir;
|
|
176
195
|
}
|
|
177
196
|
/** Clear M7 timeout timer for a requestId */
|
|
178
197
|
clearPendingTimer(requestId) {
|
|
@@ -329,30 +348,96 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
|
|
|
329
348
|
return { callId: call.id, content: `Unknown tool: ${call.name}`, isError: true };
|
|
330
349
|
}
|
|
331
350
|
const dangerLevel = getDangerLevel(call.name, call.arguments);
|
|
351
|
+
let toolCallStarted = false;
|
|
332
352
|
runHook(this.hookConfig?.preToolExecution, {
|
|
333
353
|
tool: call.name,
|
|
334
354
|
dangerLevel,
|
|
335
355
|
args: JSON.stringify(call.arguments).slice(0, 200)
|
|
336
356
|
});
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
357
|
+
const preToolDecisions = runLifecycleHooks(
|
|
358
|
+
this.hookConfig,
|
|
359
|
+
"PreToolUse",
|
|
360
|
+
{ tool: call.name, dangerLevel, args: call.arguments },
|
|
361
|
+
{ configDir: this.hookConfigDir, onSummary: (message) => this.send({ type: "info", message: `[hook] ${message}` }) }
|
|
362
|
+
);
|
|
363
|
+
const preDeny = preToolDecisions.find((d) => d.action === "deny");
|
|
364
|
+
if (preDeny) {
|
|
365
|
+
const result = {
|
|
366
|
+
callId: call.id,
|
|
367
|
+
content: `[Hook denied] ${preDeny.reason ?? `PreToolUse blocked ${call.name}`}. Do not retry without asking.`,
|
|
368
|
+
isError: true
|
|
369
|
+
};
|
|
370
|
+
this.sendToolCallResult(call, result.content, true);
|
|
371
|
+
return result;
|
|
372
|
+
}
|
|
373
|
+
for (const d of preToolDecisions) {
|
|
374
|
+
const warnings = [d.warning, ...d.warnings ?? []].filter(Boolean);
|
|
375
|
+
for (const warning of warnings) this.send({ type: "info", message: `[hook] ${warning}` });
|
|
376
|
+
}
|
|
377
|
+
const permission = checkPermissionWithProfile(
|
|
378
|
+
call.name,
|
|
379
|
+
call.arguments,
|
|
380
|
+
dangerLevel,
|
|
381
|
+
this.permissionRules,
|
|
382
|
+
this.defaultPermission,
|
|
383
|
+
{
|
|
384
|
+
profileName: this.permissionProfileName,
|
|
385
|
+
profile: this.permissionProfile,
|
|
386
|
+
allowedProfiles: this.allowedPermissionProfiles,
|
|
387
|
+
workspaceRoot: this.workspaceRoot,
|
|
388
|
+
tempDirs: [tmpdir()]
|
|
341
389
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
390
|
+
);
|
|
391
|
+
const networkPermission = checkNetworkPolicy(call.name, call.arguments, this.networkPolicy);
|
|
392
|
+
if (networkPermission?.action === "confirm" || permission.action === "confirm") {
|
|
393
|
+
runLifecycleHooks(
|
|
394
|
+
this.hookConfig,
|
|
395
|
+
"PermissionRequest",
|
|
396
|
+
{ tool: call.name, dangerLevel, args: call.arguments, reason: networkPermission?.reason ?? permission.reason },
|
|
397
|
+
{ configDir: this.hookConfigDir, onSummary: (message) => this.send({ type: "info", message: "[hook] " + message }) }
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
if (networkPermission?.action === "deny") {
|
|
401
|
+
const reason = networkPermission.reason ? ` (${networkPermission.reason})` : "";
|
|
402
|
+
return {
|
|
403
|
+
callId: call.id,
|
|
404
|
+
content: `[Permission denied] Tool ${call.name} is blocked by networkPolicy${reason}. Do not retry.`,
|
|
405
|
+
isError: true
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
if (permission.action === "deny") {
|
|
409
|
+
const reason = permission.reason ? ` (${permission.reason})` : "";
|
|
410
|
+
return {
|
|
411
|
+
callId: call.id,
|
|
412
|
+
content: `[Permission denied] Tool ${call.name} is blocked by permission profile "${permission.profileName}"${reason}. Do not retry.`,
|
|
413
|
+
isError: true
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
if (permission.action === "auto-approve" && networkPermission?.action !== "confirm") {
|
|
417
|
+
this.sendToolCallStart(call);
|
|
418
|
+
try {
|
|
419
|
+
const rawContent = await runTool(tool, call.arguments, call.name);
|
|
420
|
+
const content = truncateOutput(rawContent, call.name);
|
|
421
|
+
this.sendToolCallResult(call, rawContent, false);
|
|
422
|
+
runHook(this.hookConfig?.postToolExecution, { tool: call.name, status: "ok" });
|
|
423
|
+
runLifecycleHooks(this.hookConfig, "PostToolUse", { tool: call.name, status: "ok" }, { configDir: this.hookConfigDir });
|
|
424
|
+
return { callId: call.id, content, isError: false };
|
|
425
|
+
} catch (err) {
|
|
426
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
427
|
+
this.sendToolCallResult(call, message, true);
|
|
428
|
+
runHook(this.hookConfig?.postToolExecution, { tool: call.name, status: "error" });
|
|
429
|
+
runLifecycleHooks(this.hookConfig, "PostToolUse", { tool: call.name, status: "error", error: message }, { configDir: this.hookConfigDir });
|
|
430
|
+
return { callId: call.id, content: message, isError: true };
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (networkPermission?.action === "confirm" && dangerLevel === "safe") {
|
|
434
|
+
this.sendToolCallStart(call);
|
|
435
|
+
toolCallStarted = true;
|
|
436
|
+
const confirmed = await this.confirm(call, "write");
|
|
437
|
+
if (!confirmed) {
|
|
438
|
+
const rejectionMsg = `[User cancelled] The user declined network access for ${call.name}. Do not retry without asking.`;
|
|
439
|
+
this.sendToolCallResult(call, rejectionMsg, true);
|
|
440
|
+
return { callId: call.id, content: rejectionMsg, isError: true };
|
|
356
441
|
}
|
|
357
442
|
}
|
|
358
443
|
this.sendToolCallStart(call);
|
|
@@ -362,11 +447,13 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
|
|
|
362
447
|
const content = truncateOutput(rawContent, call.name);
|
|
363
448
|
this.sendToolCallResult(call, rawContent, false);
|
|
364
449
|
runHook(this.hookConfig?.postToolExecution, { tool: call.name, status: "ok" });
|
|
450
|
+
runLifecycleHooks(this.hookConfig, "PostToolUse", { tool: call.name, status: "ok" }, { configDir: this.hookConfigDir });
|
|
365
451
|
return { callId: call.id, content, isError: false };
|
|
366
452
|
} catch (err) {
|
|
367
453
|
const message = err instanceof Error ? err.message : String(err);
|
|
368
454
|
this.sendToolCallResult(call, message, true);
|
|
369
455
|
runHook(this.hookConfig?.postToolExecution, { tool: call.name, status: "error" });
|
|
456
|
+
runLifecycleHooks(this.hookConfig, "PostToolUse", { tool: call.name, status: "error", error: message }, { configDir: this.hookConfigDir });
|
|
370
457
|
return { callId: call.id, content: message, isError: true };
|
|
371
458
|
}
|
|
372
459
|
}
|
|
@@ -384,11 +471,13 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
|
|
|
384
471
|
const content = truncateOutput(rawContent, call.name);
|
|
385
472
|
this.sendToolCallResult(call, rawContent, false);
|
|
386
473
|
runHook(this.hookConfig?.postToolExecution, { tool: call.name, status: "ok" });
|
|
474
|
+
runLifecycleHooks(this.hookConfig, "PostToolUse", { tool: call.name, status: "ok" }, { configDir: this.hookConfigDir });
|
|
387
475
|
return { callId: call.id, content, isError: false };
|
|
388
476
|
} catch (err) {
|
|
389
477
|
const message = err instanceof Error ? err.message : String(err);
|
|
390
478
|
this.sendToolCallResult(call, message, true);
|
|
391
479
|
runHook(this.hookConfig?.postToolExecution, { tool: call.name, status: "error" });
|
|
480
|
+
runLifecycleHooks(this.hookConfig, "PostToolUse", { tool: call.name, status: "error", error: message }, { configDir: this.hookConfigDir });
|
|
392
481
|
return { callId: call.id, content: message, isError: true };
|
|
393
482
|
}
|
|
394
483
|
}
|
|
@@ -411,6 +500,9 @@ var ToolExecutorWeb = class _ToolExecutorWeb {
|
|
|
411
500
|
return results;
|
|
412
501
|
}
|
|
413
502
|
async executeBatchFileWrites(items) {
|
|
503
|
+
if (this.permissionProfileName !== "legacy" || this.permissionRules.length > 0) {
|
|
504
|
+
return Promise.all(items.map(({ call }) => this.execute(call)));
|
|
505
|
+
}
|
|
414
506
|
const calls = items.map((i) => i.call);
|
|
415
507
|
const decision = this.sessionAutoApprove ? "all" : await this.batchConfirm(calls);
|
|
416
508
|
const results = new Array(calls.length);
|
|
@@ -624,7 +716,28 @@ var SessionHandler = class {
|
|
|
624
716
|
const hooks = this.config.get("hooks");
|
|
625
717
|
const permissionRules = this.config.get("permissionRules");
|
|
626
718
|
const defaultPermission = this.config.get("defaultPermission");
|
|
627
|
-
this.
|
|
719
|
+
const permissionProfileName = this.config.get("defaultPermissionProfile") ?? "legacy";
|
|
720
|
+
const permissionProfiles = this.config.get("permissionProfiles") ?? {};
|
|
721
|
+
this.toolExecutor.setConfig({
|
|
722
|
+
hookConfig: hooks,
|
|
723
|
+
hookConfigDir: this.config.getConfigDir(),
|
|
724
|
+
permissionRules,
|
|
725
|
+
defaultPermission,
|
|
726
|
+
permissionProfileName,
|
|
727
|
+
permissionProfile: permissionProfiles[permissionProfileName],
|
|
728
|
+
allowedPermissionProfiles: this.config.get("allowedPermissionProfiles") ?? [],
|
|
729
|
+
workspaceRoot: process.cwd(),
|
|
730
|
+
networkPolicy: this.config.get("networkPolicy")
|
|
731
|
+
});
|
|
732
|
+
const permissionProfileWarning = formatPermissionProfileWarning(permissionProfileName);
|
|
733
|
+
if (permissionProfileWarning) {
|
|
734
|
+
this.send({ type: "info", message: permissionProfileWarning });
|
|
735
|
+
}
|
|
736
|
+
const pendingHooks = getPendingHookTrust(hooks, this.config.getConfigDir());
|
|
737
|
+
if (pendingHooks.length > 0) {
|
|
738
|
+
this.send({ type: "info", message: `${pendingHooks.length} project hook(s) require trust. Use /hooks list and /hooks trust <id>.` });
|
|
739
|
+
}
|
|
740
|
+
runLifecycleHooks(hooks, "SessionStart", { source: "web" }, { configDir: this.config.getConfigDir() });
|
|
628
741
|
this.sendStatus();
|
|
629
742
|
askUserContext.rl = null;
|
|
630
743
|
askUserContext.prompting = false;
|
|
@@ -659,6 +772,7 @@ var SessionHandler = class {
|
|
|
659
772
|
messageCount: this.sessions.current?.messages.length ?? 0,
|
|
660
773
|
planMode: this.planMode,
|
|
661
774
|
thinkingMode: this.runtimeThinking ?? false,
|
|
775
|
+
permissionProfile: this.config.get("defaultPermissionProfile") ?? "legacy",
|
|
662
776
|
tokenUsage: { ...this.sessionTokenUsage },
|
|
663
777
|
costUsd,
|
|
664
778
|
providers: providerList,
|
|
@@ -732,6 +846,7 @@ var SessionHandler = class {
|
|
|
732
846
|
}
|
|
733
847
|
}
|
|
734
848
|
onDisconnect() {
|
|
849
|
+
runLifecycleHooks(this.config.get("hooks") ?? void 0, "Stop", { sessionId: this.sessions.current?.id }, { configDir: this.config.getConfigDir() });
|
|
735
850
|
this.toolExecutor.cancelAll();
|
|
736
851
|
if (this.abortController) this.abortController.abort();
|
|
737
852
|
for (const resolve3 of this.pendingAskUser.values()) resolve3(null);
|
|
@@ -909,6 +1024,26 @@ var SessionHandler = class {
|
|
|
909
1024
|
try {
|
|
910
1025
|
this.ensureSession();
|
|
911
1026
|
const session = this.sessions.current;
|
|
1027
|
+
const promptDecisions = runLifecycleHooks(
|
|
1028
|
+
this.config.get("hooks") ?? void 0,
|
|
1029
|
+
"UserPromptSubmit",
|
|
1030
|
+
{ sessionId: session.id, prompt: content },
|
|
1031
|
+
{ configDir: this.config.getConfigDir(), onSummary: (message) => this.send({ type: "info", message: "[hook] " + message }) }
|
|
1032
|
+
);
|
|
1033
|
+
const promptDeny = promptDecisions.find((d) => d.action === "deny");
|
|
1034
|
+
if (promptDeny) {
|
|
1035
|
+
this.send({ type: "error", message: "Prompt blocked by hook: " + (promptDeny.reason ?? "UserPromptSubmit denied") });
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
for (const d of promptDecisions) {
|
|
1039
|
+
const warnings = [d.warning, ...d.warnings ?? []].filter(Boolean);
|
|
1040
|
+
for (const warning of warnings) this.send({ type: "info", message: "[hook] " + warning });
|
|
1041
|
+
}
|
|
1042
|
+
const secretHits = scanString(content, { customRegexes: [] });
|
|
1043
|
+
if (secretHits.length > 0) {
|
|
1044
|
+
const kinds = [...new Set(secretHits.map((h) => h.kind))].join(", ");
|
|
1045
|
+
this.send({ type: "info", message: "Possible secret in prompt (" + kinds + ")." });
|
|
1046
|
+
}
|
|
912
1047
|
const ALLOWED_IMAGE_MIMES = /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"]);
|
|
913
1048
|
const MAX_IMAGE_SIZE = 10 * 1024 * 1024;
|
|
914
1049
|
let msgContent;
|
|
@@ -2464,7 +2599,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2464
2599
|
case "test": {
|
|
2465
2600
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2466
2601
|
try {
|
|
2467
|
-
const { executeTests } = await import("./run-tests-
|
|
2602
|
+
const { executeTests } = await import("./run-tests-H4Q2PRX6.js");
|
|
2468
2603
|
const argStr = args.join(" ").trim();
|
|
2469
2604
|
let testArgs = {};
|
|
2470
2605
|
if (argStr) {
|
|
@@ -2814,6 +2949,21 @@ Add .md files to create commands.` });
|
|
|
2814
2949
|
this.send({ type: "info", message: "Not enough messages to compact." });
|
|
2815
2950
|
return;
|
|
2816
2951
|
}
|
|
2952
|
+
const preDecisions = runLifecycleHooks(
|
|
2953
|
+
this.config.get("hooks") ?? void 0,
|
|
2954
|
+
"PreCompact",
|
|
2955
|
+
{ sessionId: session.id, messageCount: session.messages.length, instruction },
|
|
2956
|
+
{ configDir: this.config.getConfigDir(), onSummary: (message) => this.send({ type: "info", message: "[hook] " + message }) }
|
|
2957
|
+
);
|
|
2958
|
+
const preDeny = preDecisions.find((d) => d.action === "deny");
|
|
2959
|
+
if (preDeny) {
|
|
2960
|
+
this.send({ type: "error", message: "Compact blocked by hook: " + (preDeny.reason ?? "PreCompact denied") });
|
|
2961
|
+
return;
|
|
2962
|
+
}
|
|
2963
|
+
for (const d of preDecisions) {
|
|
2964
|
+
const warnings = [d.warning, ...d.warnings ?? []].filter(Boolean);
|
|
2965
|
+
for (const warning of warnings) this.send({ type: "info", message: "[hook] " + warning });
|
|
2966
|
+
}
|
|
2817
2967
|
const provider = this.providers.get(this.currentProvider);
|
|
2818
2968
|
if (!provider) return;
|
|
2819
2969
|
this.send({ type: "info", message: "Compacting conversation..." });
|
|
@@ -2833,7 +2983,15 @@ Add .md files to create commands.` });
|
|
|
2833
2983
|
});
|
|
2834
2984
|
const summaryMsg = { role: "user", content: "[Conversation summary]", timestamp: /* @__PURE__ */ new Date() };
|
|
2835
2985
|
const ackMsg = { role: "assistant", content: response.content, timestamp: /* @__PURE__ */ new Date() };
|
|
2836
|
-
session.
|
|
2986
|
+
const beforeCount = session.messages.length;
|
|
2987
|
+
const removedCount = session.compact(summaryMsg, ackMsg, keepLast);
|
|
2988
|
+
const afterCount = session.messages.length;
|
|
2989
|
+
runLifecycleHooks(
|
|
2990
|
+
this.config.get("hooks") ?? void 0,
|
|
2991
|
+
"PostCompact",
|
|
2992
|
+
{ sessionId: session.id, beforeCount, afterCount, removedCount, keepLast, instruction },
|
|
2993
|
+
{ configDir: this.config.getConfigDir(), onSummary: (message) => this.send({ type: "info", message: "[hook] " + message }) }
|
|
2994
|
+
);
|
|
2837
2995
|
this.send({ type: "info", message: `Compacted: removed ${toSummarize.length} messages, kept last ${keepLast}.` });
|
|
2838
2996
|
this.sendStatus();
|
|
2839
2997
|
} catch (err) {
|
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
ToolRegistry,
|
|
4
4
|
googleSearchContext,
|
|
5
5
|
truncateOutput
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-N5LB3PPL.js";
|
|
7
7
|
import "./chunk-T2NL5ZIA.js";
|
|
8
8
|
import "./chunk-BXP6YZ2P.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-HX6N6QEY.js";
|
|
10
10
|
import {
|
|
11
11
|
runTool
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-IFZX26K7.js";
|
|
13
13
|
import {
|
|
14
14
|
getDangerLevel,
|
|
15
15
|
runLeanAgentLoop
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import "./chunk-TZQHYZKT.js";
|
|
18
18
|
import {
|
|
19
19
|
SUBAGENT_ALLOWED_TOOLS
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-GBBVCZ4W.js";
|
|
21
21
|
import "./chunk-4BKXL7SM.js";
|
|
22
22
|
import "./chunk-TB4W4Y4T.js";
|
|
23
23
|
import "./chunk-KHYD3WXE.js";
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
} from "./chunk-E44DTERW.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigManager
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-NYCBOVNF.js";
|
|
12
12
|
import "./chunk-TZQHYZKT.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-GBBVCZ4W.js";
|
|
14
14
|
import "./chunk-IW3Q7AE5.js";
|
|
15
15
|
|
|
16
16
|
// src/cli/usage.ts
|
package/dist/web/client/app.js
CHANGED
|
@@ -548,7 +548,7 @@ function handleStatus(msg) {
|
|
|
548
548
|
// Active tab: full UI reflection
|
|
549
549
|
btnThink.classList.toggle('btn-active-toggle', msg.thinkingMode);
|
|
550
550
|
btnPlan.classList.toggle('btn-active-toggle', msg.planMode);
|
|
551
|
-
statusSession.textContent =
|
|
551
|
+
statusSession.textContent = '📋 ' + (msg.sessionId?.slice(0, 8) || '—') + ' (' + msg.messageCount + ' msgs) · ' + (msg.permissionProfile || 'legacy') + (msg.networkPolicyEnabled ? ' · net:on' : '') + (msg.pendingHookTrustCount ? ' · hooks:' + msg.pendingHookTrustCount : '');
|
|
552
552
|
if (msg.tokenUsage) {
|
|
553
553
|
const u = msg.tokenUsage;
|
|
554
554
|
const cacheRead = u.cacheReadTokens || 0;
|