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.
Files changed (27) hide show
  1. package/README.md +122 -1
  2. package/README.zh-CN.md +63 -0
  3. package/dist/{batch-MFPYHOIL.js → batch-WIKFEOAZ.js} +2 -2
  4. package/dist/{chat-index-UBCWHBLR.js → chat-index-R2E27VXN.js} +1 -1
  5. package/dist/{chunk-GRJNQJA5.js → chunk-GBBVCZ4W.js} +1 -1
  6. package/dist/{chunk-7JWT3KXO.js → chunk-HW2ALWQJ.js} +2 -2
  7. package/dist/{chunk-E2ZWWE6Q.js → chunk-HX6N6QEY.js} +1 -1
  8. package/dist/{chunk-DJ35G5VO.js → chunk-IFZX26K7.js} +1 -1
  9. package/dist/{chunk-HZQVX7VF.js → chunk-KE4B3NOQ.js} +1 -1
  10. package/dist/{chunk-NWP7C6CC.js → chunk-LU6FBJQ5.js} +1 -1
  11. package/dist/{chunk-NEPFADHX.js → chunk-N5LB3PPL.js} +567 -87
  12. package/dist/{chunk-P6MTFCXB.js → chunk-NYCBOVNF.js} +62 -5
  13. package/dist/{chunk-W7UKO3PS.js → chunk-OQGVGPEK.js} +5 -0
  14. package/dist/{ci-QLJUDLMY.js → ci-X3LNUFZV.js} +2 -2
  15. package/dist/{constants-47OR72MV.js → constants-KDWG4KR4.js} +1 -1
  16. package/dist/{doctor-cli-32COMA5K.js → doctor-cli-TJTWIW7U.js} +4 -4
  17. package/dist/electron-server.js +947 -280
  18. package/dist/{hub-3NWJUCLK.js → hub-JWSV4MKC.js} +1 -1
  19. package/dist/index.js +160 -18
  20. package/dist/{run-tests-NT2UIUVB.js → run-tests-D7YBY4XB.js} +1 -1
  21. package/dist/{run-tests-UT7RZ7Y3.js → run-tests-H4Q2PRX6.js} +2 -2
  22. package/dist/{server-AIHVMLNU.js → server-OFKGDRYI.js} +4 -4
  23. package/dist/{server-E5D54DIZ.js → server-VNCN7AY5.js} +187 -29
  24. package/dist/{task-orchestrator-BFDSTSOH.js → task-orchestrator-AL2E642M.js} +4 -4
  25. package/dist/{usage-P4B2RZKL.js → usage-LB6REWPO.js} +2 -2
  26. package/dist/web/client/app.js +1 -1
  27. package/package.json +1 -1
@@ -24,7 +24,7 @@ import {
24
24
  scanDirTree,
25
25
  scanProject,
26
26
  setupProxy
27
- } from "./chunk-7JWT3KXO.js";
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
- checkPermission,
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-NEPFADHX.js";
54
+ } from "./chunk-N5LB3PPL.js";
51
55
  import "./chunk-T2NL5ZIA.js";
52
56
  import "./chunk-BXP6YZ2P.js";
53
- import "./chunk-E2ZWWE6Q.js";
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-DJ35G5VO.js";
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-P6MTFCXB.js";
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-GRJNQJA5.js";
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 "./chunk-SLSWPBK3.js";
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
- if (this.permissionRules.length > 0) {
338
- const action = checkPermission(call.name, call.arguments, dangerLevel, this.permissionRules, this.defaultPermission);
339
- if (action === "deny") {
340
- return { callId: call.id, content: `[Permission denied] Tool ${call.name} is blocked by permission rules. Do not retry.`, isError: true };
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
- if (action === "auto-approve") {
343
- this.sendToolCallStart(call);
344
- try {
345
- const rawContent = await runTool(tool, call.arguments, call.name);
346
- const content = truncateOutput(rawContent, call.name);
347
- this.sendToolCallResult(call, rawContent, false);
348
- runHook(this.hookConfig?.postToolExecution, { tool: call.name, status: "ok" });
349
- return { callId: call.id, content, isError: false };
350
- } catch (err) {
351
- const message = err instanceof Error ? err.message : String(err);
352
- this.sendToolCallResult(call, message, true);
353
- runHook(this.hookConfig?.postToolExecution, { tool: call.name, status: "error" });
354
- return { callId: call.id, content: message, isError: true };
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.toolExecutor.setConfig({ hookConfig: hooks, permissionRules, defaultPermission });
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-UT7RZ7Y3.js");
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.compact(summaryMsg, ackMsg, keepLast);
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-NEPFADHX.js";
6
+ } from "./chunk-N5LB3PPL.js";
7
7
  import "./chunk-T2NL5ZIA.js";
8
8
  import "./chunk-BXP6YZ2P.js";
9
- import "./chunk-E2ZWWE6Q.js";
9
+ import "./chunk-HX6N6QEY.js";
10
10
  import {
11
11
  runTool
12
- } from "./chunk-DJ35G5VO.js";
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-GRJNQJA5.js";
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-P6MTFCXB.js";
11
+ } from "./chunk-NYCBOVNF.js";
12
12
  import "./chunk-TZQHYZKT.js";
13
- import "./chunk-GRJNQJA5.js";
13
+ import "./chunk-GBBVCZ4W.js";
14
14
  import "./chunk-IW3Q7AE5.js";
15
15
 
16
16
  // src/cli/usage.ts
@@ -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 = `📋 ${msg.sessionId?.slice(0, 8) || '—'} (${msg.messageCount} msgs)`;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.210",
3
+ "version": "0.4.212",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",