jinzd-ai-cli 0.4.158 → 0.4.160

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.
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigManager
4
- } from "./chunk-EGPR6N2V.js";
4
+ } from "./chunk-B3ZHZ4NG.js";
5
5
  import "./chunk-2ZD3YTVM.js";
6
- import "./chunk-QBA2FGN7.js";
6
+ import "./chunk-EI2ZFRAG.js";
7
7
  import "./chunk-PDX44BCA.js";
8
8
 
9
9
  // src/cli/batch.ts
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CONFIG_DIR_NAME
4
- } from "./chunk-QBA2FGN7.js";
4
+ } from "./chunk-EI2ZFRAG.js";
5
5
 
6
6
  // src/diagnostics/tool-stats.ts
7
7
  import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-QBA2FGN7.js";
4
+ } from "./chunk-EI2ZFRAG.js";
5
5
 
6
6
  // src/tools/builtin/run-tests.ts
7
7
  import { execSync, spawnSync } from "child_process";
@@ -8,7 +8,7 @@ import {
8
8
  CONFIG_FILE_NAME,
9
9
  HISTORY_DIR_NAME,
10
10
  PLUGINS_DIR_NAME
11
- } from "./chunk-QBA2FGN7.js";
11
+ } from "./chunk-EI2ZFRAG.js";
12
12
 
13
13
  // src/config/config-manager.ts
14
14
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.158";
4
+ var VERSION = "0.4.160";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -6,7 +6,7 @@ import { platform } from "os";
6
6
  import chalk from "chalk";
7
7
 
8
8
  // src/core/constants.ts
9
- var VERSION = "0.4.158";
9
+ var VERSION = "0.4.160";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CONFIG_DIR_NAME,
4
4
  VERSION
5
- } from "./chunk-QBA2FGN7.js";
5
+ } from "./chunk-EI2ZFRAG.js";
6
6
 
7
7
  // src/diagnostics/crash-log.ts
8
8
  import {
@@ -5,10 +5,10 @@ import {
5
5
  } from "./chunk-HDSKW7Q3.js";
6
6
  import {
7
7
  runTestsTool
8
- } from "./chunk-OQIOCWRQ.js";
8
+ } from "./chunk-765BCB2J.js";
9
9
  import {
10
10
  runTool
11
- } from "./chunk-XM2OQUU6.js";
11
+ } from "./chunk-4INQZ4BA.js";
12
12
  import {
13
13
  getDangerLevel,
14
14
  isFileWriteTool
@@ -25,7 +25,7 @@ import {
25
25
  SUBAGENT_ALLOWED_TOOLS,
26
26
  SUBAGENT_DEFAULT_MAX_ROUNDS,
27
27
  SUBAGENT_MAX_ROUNDS_LIMIT
28
- } from "./chunk-QBA2FGN7.js";
28
+ } from "./chunk-EI2ZFRAG.js";
29
29
  import {
30
30
  fileCheckpoints
31
31
  } from "./chunk-4BKXL7SM.js";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  truncateForPersist
4
- } from "./chunk-F5EIB4RL.js";
4
+ } from "./chunk-SRIPX3MD.js";
5
5
  import {
6
6
  APP_NAME,
7
7
  CONFIG_DIR_NAME,
@@ -11,7 +11,7 @@ import {
11
11
  MCP_PROTOCOL_VERSION,
12
12
  MCP_TOOL_PREFIX,
13
13
  VERSION
14
- } from "./chunk-QBA2FGN7.js";
14
+ } from "./chunk-EI2ZFRAG.js";
15
15
 
16
16
  // src/mcp/client.ts
17
17
  import { spawn } from "child_process";
@@ -10,11 +10,11 @@ import {
10
10
  import "./chunk-NXXNLLSG.js";
11
11
  import {
12
12
  ConfigManager
13
- } from "./chunk-EGPR6N2V.js";
13
+ } from "./chunk-B3ZHZ4NG.js";
14
14
  import "./chunk-2ZD3YTVM.js";
15
15
  import {
16
16
  VERSION
17
- } from "./chunk-QBA2FGN7.js";
17
+ } from "./chunk-EI2ZFRAG.js";
18
18
  import "./chunk-PDX44BCA.js";
19
19
 
20
20
  // src/cli/ci.ts
@@ -36,7 +36,7 @@ import {
36
36
  TEST_TIMEOUT,
37
37
  VERSION,
38
38
  buildUserIdentityPrompt
39
- } from "./chunk-QBA2FGN7.js";
39
+ } from "./chunk-EI2ZFRAG.js";
40
40
  import "./chunk-PDX44BCA.js";
41
41
  export {
42
42
  AGENTIC_BEHAVIOR_GUIDELINE,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getConfigDirUsage,
4
4
  listRecentCrashes
5
- } from "./chunk-42NJBSWM.js";
5
+ } from "./chunk-NN3OZK33.js";
6
6
  import {
7
7
  ProviderRegistry
8
8
  } from "./chunk-AIZOARZY.js";
@@ -11,17 +11,17 @@ import {
11
11
  getTopFailingTools,
12
12
  getTopUsedTools,
13
13
  resetStats
14
- } from "./chunk-XM2OQUU6.js";
14
+ } from "./chunk-4INQZ4BA.js";
15
15
  import "./chunk-NXXNLLSG.js";
16
16
  import {
17
17
  ConfigManager
18
- } from "./chunk-EGPR6N2V.js";
18
+ } from "./chunk-B3ZHZ4NG.js";
19
19
  import "./chunk-2ZD3YTVM.js";
20
20
  import {
21
21
  DEV_STATE_FILE_NAME,
22
22
  MEMORY_FILE_NAME,
23
23
  VERSION
24
- } from "./chunk-QBA2FGN7.js";
24
+ } from "./chunk-EI2ZFRAG.js";
25
25
  import "./chunk-PDX44BCA.js";
26
26
 
27
27
  // src/diagnostics/doctor-cli.ts
@@ -36,7 +36,7 @@ import {
36
36
  VERSION,
37
37
  buildUserIdentityPrompt,
38
38
  runTestsTool
39
- } from "./chunk-O2DTCEFR.js";
39
+ } from "./chunk-JDH3E6WF.js";
40
40
  import {
41
41
  hasSemanticIndex,
42
42
  semanticSearch
@@ -13429,7 +13429,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
13429
13429
  case "test": {
13430
13430
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
13431
13431
  try {
13432
- const { executeTests } = await import("./run-tests-25AJ4GFH.js");
13432
+ const { executeTests } = await import("./run-tests-46E33OYV.js");
13433
13433
  const argStr = args.join(" ").trim();
13434
13434
  let testArgs = {};
13435
13435
  if (argStr) {
@@ -155,7 +155,7 @@ ${content}`);
155
155
  }
156
156
  }
157
157
  async function runTaskMode(config, providers, configManager, topic) {
158
- const { TaskOrchestrator } = await import("./task-orchestrator-KSSPHRG5.js");
158
+ const { TaskOrchestrator } = await import("./task-orchestrator-UGDAX76F.js");
159
159
  const orchestrator = new TaskOrchestrator(config, providers, configManager);
160
160
  let interrupted = false;
161
161
  const onSigint = () => {
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  saveDevState,
19
19
  sessionHasMeaningfulContent,
20
20
  setupProxy
21
- } from "./chunk-DLCRWPOH.js";
21
+ } from "./chunk-YXQ3GQKT.js";
22
22
  import {
23
23
  ToolExecutor,
24
24
  ToolRegistry,
@@ -37,10 +37,10 @@ import {
37
37
  spawnAgentContext,
38
38
  theme,
39
39
  undoStack
40
- } from "./chunk-F5EIB4RL.js";
40
+ } from "./chunk-SRIPX3MD.js";
41
41
  import "./chunk-HDSKW7Q3.js";
42
42
  import "./chunk-ZWVIDFGY.js";
43
- import "./chunk-OQIOCWRQ.js";
43
+ import "./chunk-765BCB2J.js";
44
44
  import {
45
45
  SessionManager,
46
46
  getContentText
@@ -49,7 +49,7 @@ import {
49
49
  getConfigDirUsage,
50
50
  listRecentCrashes,
51
51
  writeCrashLog
52
- } from "./chunk-42NJBSWM.js";
52
+ } from "./chunk-NN3OZK33.js";
53
53
  import {
54
54
  CONTENT_ONLY_STREAM_REMINDER,
55
55
  HALLUCINATION_CORRECTION_MESSAGE,
@@ -73,11 +73,11 @@ import {
73
73
  getTopFailingTools,
74
74
  getTopUsedTools,
75
75
  installFlushOnExit
76
- } from "./chunk-XM2OQUU6.js";
76
+ } from "./chunk-4INQZ4BA.js";
77
77
  import "./chunk-NXXNLLSG.js";
78
78
  import {
79
79
  ConfigManager
80
- } from "./chunk-EGPR6N2V.js";
80
+ } from "./chunk-B3ZHZ4NG.js";
81
81
  import {
82
82
  AuthError,
83
83
  ProviderError,
@@ -104,7 +104,7 @@ import {
104
104
  SKILLS_DIR_NAME,
105
105
  VERSION,
106
106
  buildUserIdentityPrompt
107
- } from "./chunk-QBA2FGN7.js";
107
+ } from "./chunk-EI2ZFRAG.js";
108
108
  import {
109
109
  formatGitContextForPrompt,
110
110
  getGitContext,
@@ -1773,7 +1773,7 @@ No tools match "${filter}".
1773
1773
  const { join: join6 } = await import("path");
1774
1774
  const { existsSync: existsSync6 } = await import("fs");
1775
1775
  const { getGitRoot: getGitRoot2 } = await import("./git-context-7KIP4X2V.js");
1776
- const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-ULU6R4KD.js");
1776
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-BVMY62SL.js");
1777
1777
  const { approveProject, hashMcpFile } = await import("./project-trust-IFM7FXEV.js");
1778
1778
  const cwd = process.cwd();
1779
1779
  const projectRoot = getGitRoot2(cwd) ?? cwd;
@@ -2834,7 +2834,7 @@ ${hint}` : "")
2834
2834
  usage: "/test [command|filter]",
2835
2835
  async execute(args, ctx) {
2836
2836
  try {
2837
- const { executeTests } = await import("./run-tests-DBQ5ISUY.js");
2837
+ const { executeTests } = await import("./run-tests-BRQALCV6.js");
2838
2838
  const argStr = args.join(" ").trim();
2839
2839
  let testArgs = {};
2840
2840
  if (argStr) {
@@ -7534,7 +7534,7 @@ program.command("web").description("Start Web UI server with browser-based chat
7534
7534
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
7535
7535
  process.exit(1);
7536
7536
  }
7537
- const { startWebServer } = await import("./server-Z3UEW3S7.js");
7537
+ const { startWebServer } = await import("./server-6YJUWYVY.js");
7538
7538
  await startWebServer({ port, host: options.host });
7539
7539
  });
7540
7540
  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) => {
@@ -7701,12 +7701,12 @@ program.command("sessions").description("List recent conversation sessions").opt
7701
7701
  console.log(footer + "\n");
7702
7702
  });
7703
7703
  program.command("doctor").description("Health check: API keys, config, MCP, recent crashes, tool usage, disk usage").option("--json", "Output as JSON (for scripting)").option("--reset-stats", "Reset accumulated tool usage statistics").action(async (options) => {
7704
- const { runDoctorCli } = await import("./doctor-cli-CKZLEQNH.js");
7704
+ const { runDoctorCli } = await import("./doctor-cli-P65JNRXQ.js");
7705
7705
  await runDoctorCli({ json: !!options.json, resetStats: !!options.resetStats });
7706
7706
  });
7707
7707
  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) => {
7708
7708
  try {
7709
- const batch = await import("./batch-OZMO6RYN.js");
7709
+ const batch = await import("./batch-7XWFAXYK.js");
7710
7710
  switch (action) {
7711
7711
  case "submit":
7712
7712
  if (!arg) {
@@ -7749,7 +7749,7 @@ program.command("batch <action> [arg] [arg2]").description("Anthropic Message Ba
7749
7749
  }
7750
7750
  });
7751
7751
  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) => {
7752
- const { startMcpServer } = await import("./server-CFOYC72D.js");
7752
+ const { startMcpServer } = await import("./server-ABMLGG6D.js");
7753
7753
  await startMcpServer({
7754
7754
  allowDestructive: !!options.allowDestructive,
7755
7755
  allowOutsideCwd: !!options.allowOutsideCwd,
@@ -7758,7 +7758,7 @@ program.command("mcp-serve").description("Start an MCP server over STDIO, exposi
7758
7758
  });
7759
7759
  });
7760
7760
  program.command("ci").description("Headless PR review (code + security) \u2014 reads git/gh diff, optionally posts to PR. Designed for GitHub Actions.").option("--pr <num>", "PR number; diff fetched via `gh pr diff <num>`", (v) => parseInt(v, 10)).option("--base <ref>", "Base ref for `git diff <ref>...HEAD` (ignored when --pr set)").option("--post", "Post review as a PR comment (requires gh CLI + GH_TOKEN, needs --pr)").option("--no-update", "Always create a new comment instead of updating the previous aicli review").option("--skip-code", "Skip the code review section").option("--skip-security", "Skip the security review section").option("--detailed", "Use the detailed code-review prompt").option("--max-diff <n>", "Max diff chars sent to the model (default 30000)", (v) => parseInt(v, 10)).option("--provider <id>", "Override provider (default: config.defaultProvider)").option("--model <id>", "Override model").option("--dry-run", "Print result to stdout instead of posting (overrides --post)").action(async (options) => {
7761
- const { runCi } = await import("./ci-GXPDJQN5.js");
7761
+ const { runCi } = await import("./ci-BORVHGFS.js");
7762
7762
  const result = await runCi({
7763
7763
  pr: options.pr,
7764
7764
  base: options.base,
@@ -7903,7 +7903,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
7903
7903
  }),
7904
7904
  config.get("customProviders")
7905
7905
  );
7906
- const { startHub } = await import("./hub-OLRMJ55R.js");
7906
+ const { startHub } = await import("./hub-3IWFFJNE.js");
7907
7907
  await startHub(
7908
7908
  {
7909
7909
  topic: topic ?? "",
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeTests,
3
3
  runTestsTool
4
- } from "./chunk-O2DTCEFR.js";
4
+ } from "./chunk-JDH3E6WF.js";
5
5
  import "./chunk-3RG5ZIWI.js";
6
6
  export {
7
7
  executeTests,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-OQIOCWRQ.js";
6
- import "./chunk-QBA2FGN7.js";
5
+ } from "./chunk-765BCB2J.js";
6
+ import "./chunk-EI2ZFRAG.js";
7
7
  import "./chunk-PDX44BCA.js";
8
8
  export {
9
9
  executeTests,
@@ -21,7 +21,7 @@ import {
21
21
  loadDevState,
22
22
  persistToolRound,
23
23
  setupProxy
24
- } from "./chunk-DLCRWPOH.js";
24
+ } from "./chunk-YXQ3GQKT.js";
25
25
  import {
26
26
  ToolExecutor,
27
27
  ToolRegistry,
@@ -39,10 +39,10 @@ import {
39
39
  spawnAgentContext,
40
40
  truncateOutput,
41
41
  undoStack
42
- } from "./chunk-F5EIB4RL.js";
42
+ } from "./chunk-SRIPX3MD.js";
43
43
  import "./chunk-HDSKW7Q3.js";
44
44
  import "./chunk-ZWVIDFGY.js";
45
- import "./chunk-OQIOCWRQ.js";
45
+ import "./chunk-765BCB2J.js";
46
46
  import {
47
47
  SessionManager,
48
48
  getContentText
@@ -63,13 +63,13 @@ import {
63
63
  } from "./chunk-AIZOARZY.js";
64
64
  import {
65
65
  runTool
66
- } from "./chunk-XM2OQUU6.js";
66
+ } from "./chunk-4INQZ4BA.js";
67
67
  import {
68
68
  getDangerLevel
69
69
  } from "./chunk-NXXNLLSG.js";
70
70
  import {
71
71
  ConfigManager
72
- } from "./chunk-EGPR6N2V.js";
72
+ } from "./chunk-B3ZHZ4NG.js";
73
73
  import "./chunk-2ZD3YTVM.js";
74
74
  import {
75
75
  AGENTIC_BEHAVIOR_GUIDELINE,
@@ -89,7 +89,7 @@ import {
89
89
  SKILLS_DIR_NAME,
90
90
  VERSION,
91
91
  buildUserIdentityPrompt
92
- } from "./chunk-QBA2FGN7.js";
92
+ } from "./chunk-EI2ZFRAG.js";
93
93
  import {
94
94
  formatGitContextForPrompt,
95
95
  getGitContext,
@@ -2575,7 +2575,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
2575
2575
  case "test": {
2576
2576
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
2577
2577
  try {
2578
- const { executeTests } = await import("./run-tests-DBQ5ISUY.js");
2578
+ const { executeTests } = await import("./run-tests-BRQALCV6.js");
2579
2579
  const argStr = args.join(" ").trim();
2580
2580
  let testArgs = {};
2581
2581
  if (argStr) {
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-F5EIB4RL.js";
4
+ } from "./chunk-SRIPX3MD.js";
5
5
  import "./chunk-HDSKW7Q3.js";
6
6
  import "./chunk-ZWVIDFGY.js";
7
- import "./chunk-OQIOCWRQ.js";
7
+ import "./chunk-765BCB2J.js";
8
8
  import {
9
9
  runTool
10
- } from "./chunk-XM2OQUU6.js";
10
+ } from "./chunk-4INQZ4BA.js";
11
11
  import {
12
12
  getDangerLevel,
13
13
  schemaToJsonSchema
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-2ZD3YTVM.js";
16
16
  import {
17
17
  VERSION
18
- } from "./chunk-QBA2FGN7.js";
18
+ } from "./chunk-EI2ZFRAG.js";
19
19
  import "./chunk-4BKXL7SM.js";
20
20
  import "./chunk-MM3F43H6.js";
21
21
  import "./chunk-KHYD3WXE.js";
@@ -3,20 +3,20 @@ import {
3
3
  ToolRegistry,
4
4
  googleSearchContext,
5
5
  truncateOutput
6
- } from "./chunk-F5EIB4RL.js";
6
+ } from "./chunk-SRIPX3MD.js";
7
7
  import "./chunk-HDSKW7Q3.js";
8
8
  import "./chunk-ZWVIDFGY.js";
9
- import "./chunk-OQIOCWRQ.js";
9
+ import "./chunk-765BCB2J.js";
10
10
  import {
11
11
  runTool
12
- } from "./chunk-XM2OQUU6.js";
12
+ } from "./chunk-4INQZ4BA.js";
13
13
  import {
14
14
  getDangerLevel
15
15
  } from "./chunk-NXXNLLSG.js";
16
16
  import "./chunk-2ZD3YTVM.js";
17
17
  import {
18
18
  SUBAGENT_ALLOWED_TOOLS
19
- } from "./chunk-QBA2FGN7.js";
19
+ } from "./chunk-EI2ZFRAG.js";
20
20
  import "./chunk-4BKXL7SM.js";
21
21
  import "./chunk-MM3F43H6.js";
22
22
  import "./chunk-KHYD3WXE.js";
@@ -113,6 +113,7 @@
113
113
  <button class="sidebar-tab flex-1 text-xs font-semibold py-2 px-1 text-center" data-tab="tools">🔧 Tools</button>
114
114
  <button class="sidebar-tab flex-1 text-xs font-semibold py-2 px-1 text-center" data-tab="files">📁 Files</button>
115
115
  <button class="sidebar-tab flex-1 text-xs font-semibold py-2 px-1 text-center" data-tab="memory" title="Chat memory semantic recall (B4, v0.4.90)">🧠 Memory</button>
116
+ <button class="sidebar-tab flex-1 text-xs font-semibold py-2 px-1 text-center" data-tab="hub" title="Multi-agent brainstorm room (P4)">🏛 Hub</button>
116
117
  </div>
117
118
  <!-- Sessions tab -->
118
119
  <div id="tab-sessions" class="sidebar-tab-content flex flex-col flex-1 overflow-hidden">
@@ -339,8 +340,20 @@
339
340
 
340
341
  <script src="app.js"></script>
341
342
  <script>
343
+ // Self-updating service worker (v0.4.159). A new SW postMessages
344
+ // 'sw-updated' (and triggers controllerchange) when it takes over; we
345
+ // reload once so the user never gets stuck on a stale index.html/app.js
346
+ // after upgrading aicli. index.html/app.js are also network-only in sw.js.
342
347
  if ('serviceWorker' in navigator) {
343
- navigator.serviceWorker.register('sw.js').catch(() => {});
348
+ let swReloaded = false;
349
+ const reloadOnce = () => { if (!swReloaded) { swReloaded = true; location.reload(); } };
350
+ navigator.serviceWorker.addEventListener('message', (e) => {
351
+ if (e.data && e.data.type === 'sw-updated') reloadOnce();
352
+ });
353
+ navigator.serviceWorker.addEventListener('controllerchange', reloadOnce);
354
+ navigator.serviceWorker.register('sw.js').then((reg) => {
355
+ reg.update();
356
+ }).catch(() => {});
344
357
  }
345
358
  </script>
346
359
  </body>
@@ -4,19 +4,24 @@
4
4
  * API calls and WebSocket are always network-first.
5
5
  */
6
6
 
7
- // v0.4.153: bumped v1 v2 so the `activate` handler evicts the old cache.
8
- // Without this, clients that cached the pre-fix index.html (which referenced
9
- // GFW-blocked CDNs) would keep serving the broken page forever.
10
- const CACHE_NAME = 'aicli-v2';
7
+ // v0.4.159: self-updating SW. Bumped to v3. The old v1/v2 service workers kept
8
+ // serving a stale index.html/app.js (no Hub tab, broken Light theme) because a
9
+ // new SW only "waits" it never told the page to reload. Now: install →
10
+ // skipWaiting (take over immediately), activate → evict old caches + claim +
11
+ // postMessage('reload') so every open tab refreshes once onto the new version.
12
+ // index.html / app.js are NEVER cached (always network), so a plain refresh
13
+ // after upgrade is enough even before the SW turns over.
14
+ const CACHE_NAME = 'aicli-v3';
11
15
 
12
- // App shellfiles needed for offline-capable startup. Now includes the
13
- // vendored Tailwind/DaisyUI/marked/highlight.js assets (previously CDN-hosted),
14
- // so the UI is fully self-contained and works behind a firewall / offline.
16
+ // HTML/JS that must always be fresh never served from the SW cache, so an
17
+ // upgraded server is reflected on the very next load. Other assets (vendored
18
+ // CSS/JS, icons) are large + content-stable and fine to cache.
19
+ const NEVER_CACHE = new Set(['/', '/index.html', '/app.js']);
20
+
21
+ // App shell to precache (offline-capable startup). Deliberately EXCLUDES the
22
+ // always-fresh HTML/JS in NEVER_CACHE — only large content-stable assets.
15
23
  const APP_SHELL = [
16
- '/',
17
- '/index.html',
18
24
  '/style.css',
19
- '/app.js',
20
25
  '/manifest.json',
21
26
  '/icon.svg',
22
27
  '/icon-192.png',
@@ -30,6 +35,7 @@ const APP_SHELL = [
30
35
  ];
31
36
 
32
37
  self.addEventListener('install', (event) => {
38
+ // Take over immediately rather than waiting for all old tabs to close.
33
39
  event.waitUntil(
34
40
  caches.open(CACHE_NAME)
35
41
  .then(cache => cache.addAll(APP_SHELL))
@@ -39,25 +45,33 @@ self.addEventListener('install', (event) => {
39
45
 
40
46
  self.addEventListener('activate', (event) => {
41
47
  event.waitUntil(
42
- caches.keys().then(keys =>
43
- Promise.all(keys
44
- .filter(k => k !== CACHE_NAME)
45
- .map(k => caches.delete(k))
46
- )
47
- ).then(() => self.clients.claim())
48
+ caches.keys()
49
+ .then(keys => Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))))
50
+ .then(() => self.clients.claim())
51
+ .then(async () => {
52
+ // Tell every open tab a new version is live so it can reload once.
53
+ const clients = await self.clients.matchAll({ type: 'window' });
54
+ for (const c of clients) c.postMessage({ type: 'sw-updated' });
55
+ })
48
56
  );
49
57
  });
50
58
 
51
59
  self.addEventListener('fetch', (event) => {
52
60
  const url = new URL(event.request.url);
53
61
 
54
- // Never cache API calls or WebSocket upgrades
62
+ // Never intercept API calls or WebSocket upgrades.
55
63
  if (url.pathname.startsWith('/api/') || event.request.headers.get('upgrade') === 'websocket') {
56
64
  return;
57
65
  }
58
66
 
59
- // App shell (now incl. same-origin /vendor/*): network-first with cache
60
- // fallback (always get latest from server)
67
+ // Always-fresh HTML/JS: network-only, never touch the cache. Guarantees an
68
+ // upgraded server shows up on the next load even if the SW hasn't turned over.
69
+ if (NEVER_CACHE.has(url.pathname)) {
70
+ event.respondWith(fetch(event.request).catch(() => caches.match(event.request)));
71
+ return;
72
+ }
73
+
74
+ // Everything else: network-first with cache fallback (offline support).
61
75
  event.respondWith(
62
76
  fetch(event.request)
63
77
  .then(response => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.158",
3
+ "version": "0.4.160",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",