jinzd-ai-cli 0.4.156 → 0.4.158

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-UAPNBQLU.js";
4
+ } from "./chunk-EGPR6N2V.js";
5
5
  import "./chunk-2ZD3YTVM.js";
6
- import "./chunk-3WLEDKOW.js";
6
+ import "./chunk-QBA2FGN7.js";
7
7
  import "./chunk-PDX44BCA.js";
8
8
 
9
9
  // src/cli/batch.ts
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  CONFIG_DIR_NAME,
4
4
  VERSION
5
- } from "./chunk-3WLEDKOW.js";
5
+ } from "./chunk-QBA2FGN7.js";
6
6
 
7
7
  // src/diagnostics/crash-log.ts
8
8
  import {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  truncateForPersist
4
- } from "./chunk-Z2UJDFJK.js";
4
+ } from "./chunk-F5EIB4RL.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-3WLEDKOW.js";
14
+ } from "./chunk-QBA2FGN7.js";
15
15
 
16
16
  // src/mcp/client.ts
17
17
  import { spawn } 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-3WLEDKOW.js";
11
+ } from "./chunk-QBA2FGN7.js";
12
12
 
13
13
  // src/config/config-manager.ts
14
14
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -5,10 +5,10 @@ import {
5
5
  } from "./chunk-HDSKW7Q3.js";
6
6
  import {
7
7
  runTestsTool
8
- } from "./chunk-AACNCJMD.js";
8
+ } from "./chunk-OQIOCWRQ.js";
9
9
  import {
10
10
  runTool
11
- } from "./chunk-3SQMKA4I.js";
11
+ } from "./chunk-XM2OQUU6.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-3WLEDKOW.js";
28
+ } from "./chunk-QBA2FGN7.js";
29
29
  import {
30
30
  fileCheckpoints
31
31
  } from "./chunk-4BKXL7SM.js";
@@ -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.156";
9
+ var VERSION = "0.4.158";
10
10
  var APP_NAME = "ai-cli";
11
11
  var CONFIG_DIR_NAME = ".aicli";
12
12
  var CONFIG_FILE_NAME = "config.json";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  TEST_TIMEOUT
4
- } from "./chunk-3WLEDKOW.js";
4
+ } from "./chunk-QBA2FGN7.js";
5
5
 
6
6
  // src/tools/builtin/run-tests.ts
7
7
  import { execSync, spawnSync } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/core/constants.ts
4
- var VERSION = "0.4.156";
4
+ var VERSION = "0.4.158";
5
5
  var APP_NAME = "ai-cli";
6
6
  var CONFIG_DIR_NAME = ".aicli";
7
7
  var CONFIG_FILE_NAME = "config.json";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CONFIG_DIR_NAME
4
- } from "./chunk-3WLEDKOW.js";
4
+ } from "./chunk-QBA2FGN7.js";
5
5
 
6
6
  // src/diagnostics/tool-stats.ts
7
7
  import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync } from "fs";
@@ -10,11 +10,11 @@ import {
10
10
  import "./chunk-NXXNLLSG.js";
11
11
  import {
12
12
  ConfigManager
13
- } from "./chunk-UAPNBQLU.js";
13
+ } from "./chunk-EGPR6N2V.js";
14
14
  import "./chunk-2ZD3YTVM.js";
15
15
  import {
16
16
  VERSION
17
- } from "./chunk-3WLEDKOW.js";
17
+ } from "./chunk-QBA2FGN7.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-3WLEDKOW.js";
39
+ } from "./chunk-QBA2FGN7.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-3DCAQKVZ.js";
5
+ } from "./chunk-42NJBSWM.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-3SQMKA4I.js";
14
+ } from "./chunk-XM2OQUU6.js";
15
15
  import "./chunk-NXXNLLSG.js";
16
16
  import {
17
17
  ConfigManager
18
- } from "./chunk-UAPNBQLU.js";
18
+ } from "./chunk-EGPR6N2V.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-3WLEDKOW.js";
24
+ } from "./chunk-QBA2FGN7.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-7OCOFVQP.js";
39
+ } from "./chunk-O2DTCEFR.js";
40
40
  import {
41
41
  hasSemanticIndex,
42
42
  semanticSearch
@@ -11400,6 +11400,8 @@ var SessionHandler = class _SessionHandler {
11400
11400
  processing = false;
11401
11401
  /** P4: active hub discussion orchestrator (web room), if any. */
11402
11402
  hubOrchestrator = null;
11403
+ /** P4b: pending between-rounds human-steer prompts (requestId → resolver). */
11404
+ pendingHubReview = /* @__PURE__ */ new Map();
11403
11405
  /** Pending ask_user promises */
11404
11406
  pendingAskUser = /* @__PURE__ */ new Map();
11405
11407
  /** Pending auto-pause promises */
@@ -11543,6 +11545,14 @@ var SessionHandler = class _SessionHandler {
11543
11545
  case "hub_abort":
11544
11546
  this.hubOrchestrator?.abort();
11545
11547
  return;
11548
+ case "hub_steer": {
11549
+ const resolve7 = this.pendingHubReview.get(msg.requestId);
11550
+ if (resolve7) {
11551
+ this.pendingHubReview.delete(msg.requestId);
11552
+ resolve7({ action: msg.action, message: msg.message });
11553
+ }
11554
+ return;
11555
+ }
11546
11556
  case "interjection":
11547
11557
  this.userInterjection = msg.content;
11548
11558
  return;
@@ -11674,7 +11684,8 @@ var SessionHandler = class _SessionHandler {
11674
11684
  defaultProvider,
11675
11685
  defaultModel,
11676
11686
  maxRounds: msg.maxRounds && msg.maxRounds > 0 ? Math.min(msg.maxRounds, 20) : 6,
11677
- voteConverge: msg.vote === true
11687
+ voteConverge: msg.vote === true,
11688
+ humanSteer: msg.steer === true
11678
11689
  };
11679
11690
  this.send({
11680
11691
  type: "hub_started",
@@ -11685,6 +11696,13 @@ var SessionHandler = class _SessionHandler {
11685
11696
  const orchestrator = new DiscussionOrchestrator(config, this.providers);
11686
11697
  this.hubOrchestrator = orchestrator;
11687
11698
  orchestrator.onEvent = (event) => this.send({ type: "hub_event", event });
11699
+ if (config.humanSteer) {
11700
+ orchestrator.onRoundReview = ({ round, maxRounds }) => new Promise((resolve7) => {
11701
+ const requestId = `hubrev_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
11702
+ this.pendingHubReview.set(requestId, resolve7);
11703
+ this.send({ type: "hub_review", requestId, round, maxRounds });
11704
+ });
11705
+ }
11688
11706
  this.processing = true;
11689
11707
  try {
11690
11708
  const state2 = await orchestrator.run(topic);
@@ -13411,7 +13429,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
13411
13429
  case "test": {
13412
13430
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
13413
13431
  try {
13414
- const { executeTests } = await import("./run-tests-NPWSCWP5.js");
13432
+ const { executeTests } = await import("./run-tests-25AJ4GFH.js");
13415
13433
  const argStr = args.join(" ").trim();
13416
13434
  let testArgs = {};
13417
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-GF6ZMNUK.js");
158
+ const { TaskOrchestrator } = await import("./task-orchestrator-KSSPHRG5.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-GQ647SF3.js";
21
+ } from "./chunk-DLCRWPOH.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-Z2UJDFJK.js";
40
+ } from "./chunk-F5EIB4RL.js";
41
41
  import "./chunk-HDSKW7Q3.js";
42
42
  import "./chunk-ZWVIDFGY.js";
43
- import "./chunk-AACNCJMD.js";
43
+ import "./chunk-OQIOCWRQ.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-3DCAQKVZ.js";
52
+ } from "./chunk-42NJBSWM.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-3SQMKA4I.js";
76
+ } from "./chunk-XM2OQUU6.js";
77
77
  import "./chunk-NXXNLLSG.js";
78
78
  import {
79
79
  ConfigManager
80
- } from "./chunk-UAPNBQLU.js";
80
+ } from "./chunk-EGPR6N2V.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-3WLEDKOW.js";
107
+ } from "./chunk-QBA2FGN7.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-QDTWBWWC.js");
1776
+ const { MCP_PROJECT_CONFIG_NAME: MCP_PROJECT_CONFIG_NAME2 } = await import("./constants-ULU6R4KD.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-CNURD2ST.js");
2837
+ const { executeTests } = await import("./run-tests-DBQ5ISUY.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-RRUCZMMM.js");
7537
+ const { startWebServer } = await import("./server-Z3UEW3S7.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-4MTG6SFH.js");
7704
+ const { runDoctorCli } = await import("./doctor-cli-CKZLEQNH.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-DBOCPVH5.js");
7709
+ const batch = await import("./batch-OZMO6RYN.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-HFG2SM3Y.js");
7752
+ const { startMcpServer } = await import("./server-CFOYC72D.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-AWA6KC3X.js");
7761
+ const { runCi } = await import("./ci-GXPDJQN5.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-QRDXG527.js");
7906
+ const { startHub } = await import("./hub-OLRMJ55R.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-7OCOFVQP.js";
4
+ } from "./chunk-O2DTCEFR.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-AACNCJMD.js";
6
- import "./chunk-3WLEDKOW.js";
5
+ } from "./chunk-OQIOCWRQ.js";
6
+ import "./chunk-QBA2FGN7.js";
7
7
  import "./chunk-PDX44BCA.js";
8
8
  export {
9
9
  executeTests,
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ToolRegistry
4
- } from "./chunk-Z2UJDFJK.js";
4
+ } from "./chunk-F5EIB4RL.js";
5
5
  import "./chunk-HDSKW7Q3.js";
6
6
  import "./chunk-ZWVIDFGY.js";
7
- import "./chunk-AACNCJMD.js";
7
+ import "./chunk-OQIOCWRQ.js";
8
8
  import {
9
9
  runTool
10
- } from "./chunk-3SQMKA4I.js";
10
+ } from "./chunk-XM2OQUU6.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-3WLEDKOW.js";
18
+ } from "./chunk-QBA2FGN7.js";
19
19
  import "./chunk-4BKXL7SM.js";
20
20
  import "./chunk-MM3F43H6.js";
21
21
  import "./chunk-KHYD3WXE.js";
@@ -21,7 +21,7 @@ import {
21
21
  loadDevState,
22
22
  persistToolRound,
23
23
  setupProxy
24
- } from "./chunk-GQ647SF3.js";
24
+ } from "./chunk-DLCRWPOH.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-Z2UJDFJK.js";
42
+ } from "./chunk-F5EIB4RL.js";
43
43
  import "./chunk-HDSKW7Q3.js";
44
44
  import "./chunk-ZWVIDFGY.js";
45
- import "./chunk-AACNCJMD.js";
45
+ import "./chunk-OQIOCWRQ.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-3SQMKA4I.js";
66
+ } from "./chunk-XM2OQUU6.js";
67
67
  import {
68
68
  getDangerLevel
69
69
  } from "./chunk-NXXNLLSG.js";
70
70
  import {
71
71
  ConfigManager
72
- } from "./chunk-UAPNBQLU.js";
72
+ } from "./chunk-EGPR6N2V.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-3WLEDKOW.js";
92
+ } from "./chunk-QBA2FGN7.js";
93
93
  import {
94
94
  formatGitContextForPrompt,
95
95
  getGitContext,
@@ -546,6 +546,8 @@ var SessionHandler = class _SessionHandler {
546
546
  processing = false;
547
547
  /** P4: active hub discussion orchestrator (web room), if any. */
548
548
  hubOrchestrator = null;
549
+ /** P4b: pending between-rounds human-steer prompts (requestId → resolver). */
550
+ pendingHubReview = /* @__PURE__ */ new Map();
549
551
  /** Pending ask_user promises */
550
552
  pendingAskUser = /* @__PURE__ */ new Map();
551
553
  /** Pending auto-pause promises */
@@ -689,6 +691,14 @@ var SessionHandler = class _SessionHandler {
689
691
  case "hub_abort":
690
692
  this.hubOrchestrator?.abort();
691
693
  return;
694
+ case "hub_steer": {
695
+ const resolve3 = this.pendingHubReview.get(msg.requestId);
696
+ if (resolve3) {
697
+ this.pendingHubReview.delete(msg.requestId);
698
+ resolve3({ action: msg.action, message: msg.message });
699
+ }
700
+ return;
701
+ }
692
702
  case "interjection":
693
703
  this.userInterjection = msg.content;
694
704
  return;
@@ -820,7 +830,8 @@ var SessionHandler = class _SessionHandler {
820
830
  defaultProvider,
821
831
  defaultModel,
822
832
  maxRounds: msg.maxRounds && msg.maxRounds > 0 ? Math.min(msg.maxRounds, 20) : 6,
823
- voteConverge: msg.vote === true
833
+ voteConverge: msg.vote === true,
834
+ humanSteer: msg.steer === true
824
835
  };
825
836
  this.send({
826
837
  type: "hub_started",
@@ -831,6 +842,13 @@ var SessionHandler = class _SessionHandler {
831
842
  const orchestrator = new DiscussionOrchestrator(config, this.providers);
832
843
  this.hubOrchestrator = orchestrator;
833
844
  orchestrator.onEvent = (event) => this.send({ type: "hub_event", event });
845
+ if (config.humanSteer) {
846
+ orchestrator.onRoundReview = ({ round, maxRounds }) => new Promise((resolve3) => {
847
+ const requestId = `hubrev_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
848
+ this.pendingHubReview.set(requestId, resolve3);
849
+ this.send({ type: "hub_review", requestId, round, maxRounds });
850
+ });
851
+ }
834
852
  this.processing = true;
835
853
  try {
836
854
  const state = await orchestrator.run(topic);
@@ -2557,7 +2575,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
2557
2575
  case "test": {
2558
2576
  this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
2559
2577
  try {
2560
- const { executeTests } = await import("./run-tests-CNURD2ST.js");
2578
+ const { executeTests } = await import("./run-tests-DBQ5ISUY.js");
2561
2579
  const argStr = args.join(" ").trim();
2562
2580
  let testArgs = {};
2563
2581
  if (argStr) {
@@ -3,20 +3,20 @@ import {
3
3
  ToolRegistry,
4
4
  googleSearchContext,
5
5
  truncateOutput
6
- } from "./chunk-Z2UJDFJK.js";
6
+ } from "./chunk-F5EIB4RL.js";
7
7
  import "./chunk-HDSKW7Q3.js";
8
8
  import "./chunk-ZWVIDFGY.js";
9
- import "./chunk-AACNCJMD.js";
9
+ import "./chunk-OQIOCWRQ.js";
10
10
  import {
11
11
  runTool
12
- } from "./chunk-3SQMKA4I.js";
12
+ } from "./chunk-XM2OQUU6.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-3WLEDKOW.js";
19
+ } from "./chunk-QBA2FGN7.js";
20
20
  import "./chunk-4BKXL7SM.js";
21
21
  import "./chunk-MM3F43H6.js";
22
22
  import "./chunk-KHYD3WXE.js";
@@ -202,6 +202,7 @@ function handleServerMessage(msg) {
202
202
  case 'hub_started': hubStarted(msg); break;
203
203
  case 'hub_event': hubEvent(msg.event); break;
204
204
  case 'hub_done': hubDone(msg); break;
205
+ case 'hub_review': hubReview(msg); break;
205
206
  case 'info': addInfoMessage(msg.message); break;
206
207
  case 'error': addErrorMessage(msg.message); hideRoundProgress(); clearAllToolTimers(); setProcessing(false); break;
207
208
  case 'round_progress': handleRoundProgress(msg); break;
@@ -3119,6 +3120,13 @@ const HUB_COLORS = { cyan: '#22d3ee', green: '#4ade80', red: '#f87171', magenta:
3119
3120
  let hubRoles = {}; // roleId → { name, color, provider, model }
3120
3121
  let hubStreamEl = null; // current streaming agent message element
3121
3122
  let hubStreamRoleId = null;
3123
+ let hubLaneMode = false; // P4b-2: render agents in side-by-side columns
3124
+ let hubLaneBody = {}; // roleId → that column's scrollable body element
3125
+
3126
+ /** Where an agent's turn block should be appended: its lane (lane mode) or the flow. */
3127
+ function hubAgentContainer(roleId) {
3128
+ return hubLaneMode && hubLaneBody[roleId] ? hubLaneBody[roleId] : messagesEl;
3129
+ }
3122
3130
 
3123
3131
  function hubColor(c) { return HUB_COLORS[c] || '#9ca3af'; }
3124
3132
 
@@ -3132,6 +3140,7 @@ window.startHub = function () {
3132
3140
  maxRounds: parseInt(document.getElementById('hub-rounds').value, 10) || 6,
3133
3141
  mix: document.getElementById('hub-mix').checked,
3134
3142
  vote: document.getElementById('hub-vote').checked,
3143
+ steer: document.getElementById('hub-steer').checked,
3135
3144
  });
3136
3145
  document.getElementById('hub-start-btn').classList.add('hidden');
3137
3146
  document.getElementById('hub-abort-btn').classList.remove('hidden');
@@ -3161,16 +3170,43 @@ function hubStarted(msg) {
3161
3170
  <div class="text-xs opacity-70 mb-1">up to ${msg.maxRounds} rounds</div>
3162
3171
  <div class="text-xs">${legend}</div>`;
3163
3172
  messagesEl.appendChild(el);
3173
+
3174
+ // P4b-2: lanes view — build one column per role; agent turns route into them.
3175
+ hubLaneMode = !!document.getElementById('hub-lanes')?.checked;
3176
+ hubLaneBody = {};
3177
+ if (hubLaneMode) {
3178
+ const lanes = document.createElement('div');
3179
+ lanes.className = 'hub-lanes flex gap-2 my-2 overflow-x-auto';
3180
+ for (const r of msg.roles) {
3181
+ const col = document.createElement('div');
3182
+ col.className = 'hub-lane flex-1 min-w-[200px] border rounded-lg overflow-hidden';
3183
+ col.style.borderColor = hubColor(r.color);
3184
+ col.innerHTML = `<div class="text-xs font-bold px-2 py-1" style="background:${hubColor(r.color)}22;color:${hubColor(r.color)}">${escapeHtml(r.name)}</div><div class="hub-lane-body p-2 text-sm flex flex-col gap-2"></div>`;
3185
+ lanes.appendChild(col);
3186
+ hubLaneBody[r.id] = col.querySelector('.hub-lane-body');
3187
+ }
3188
+ messagesEl.appendChild(lanes);
3189
+ }
3164
3190
  scrollToBottom();
3165
3191
  }
3166
3192
 
3167
3193
  function hubEvent(ev) {
3168
3194
  switch (ev.type) {
3169
3195
  case 'round_start': {
3170
- const el = document.createElement('div');
3171
- el.className = 'hub-round text-xs opacity-50 text-center my-2';
3172
- el.textContent = `── Round ${ev.round}/${ev.maxRounds} ──`;
3173
- messagesEl.appendChild(el);
3196
+ if (hubLaneMode) {
3197
+ // Per-lane round chip so each column stays self-contained.
3198
+ for (const body of Object.values(hubLaneBody)) {
3199
+ const chip = document.createElement('div');
3200
+ chip.className = 'text-[10px] opacity-40 text-center border-t border-base-content/10 pt-1';
3201
+ chip.textContent = `Round ${ev.round}/${ev.maxRounds}`;
3202
+ body.appendChild(chip);
3203
+ }
3204
+ } else {
3205
+ const el = document.createElement('div');
3206
+ el.className = 'hub-round text-xs opacity-50 text-center my-2';
3207
+ el.textContent = `── Round ${ev.round}/${ev.maxRounds} ──`;
3208
+ messagesEl.appendChild(el);
3209
+ }
3174
3210
  scrollToBottom();
3175
3211
  break;
3176
3212
  }
@@ -3178,10 +3214,16 @@ function hubEvent(ev) {
3178
3214
  if (hubStreamRoleId !== ev.roleId || !hubStreamEl) {
3179
3215
  const role = hubRoles[ev.roleId] || { name: ev.roleId, color: 'white' };
3180
3216
  hubStreamEl = document.createElement('div');
3181
- hubStreamEl.className = 'hub-msg border-l-2 pl-2 my-2';
3182
- hubStreamEl.style.borderColor = hubColor(role.color);
3183
- hubStreamEl.innerHTML = `<div class="text-xs font-bold mb-1" style="color:${hubColor(role.color)}">${escapeHtml(role.name)}</div><div class="hub-body text-sm"></div>`;
3184
- messagesEl.appendChild(hubStreamEl);
3217
+ if (hubLaneMode) {
3218
+ // Column header already shows the role name — just the body here.
3219
+ hubStreamEl.className = 'hub-msg';
3220
+ hubStreamEl.innerHTML = `<div class="hub-body text-sm"></div>`;
3221
+ } else {
3222
+ hubStreamEl.className = 'hub-msg border-l-2 pl-2 my-2';
3223
+ hubStreamEl.style.borderColor = hubColor(role.color);
3224
+ hubStreamEl.innerHTML = `<div class="text-xs font-bold mb-1" style="color:${hubColor(role.color)}">${escapeHtml(role.name)}</div><div class="hub-body text-sm"></div>`;
3225
+ }
3226
+ hubAgentContainer(ev.roleId).appendChild(hubStreamEl);
3185
3227
  hubStreamRoleId = ev.roleId;
3186
3228
  hubStreamEl._raw = '';
3187
3229
  }
@@ -3198,8 +3240,8 @@ function hubEvent(ev) {
3198
3240
  const role = hubRoles[ev.roleId] || { name: ev.roleId };
3199
3241
  const el = document.createElement('div');
3200
3242
  el.className = 'text-xs opacity-40 italic pl-2 my-1';
3201
- el.textContent = `${role.name} passed`;
3202
- messagesEl.appendChild(el);
3243
+ el.textContent = hubLaneMode ? 'passed' : `${role.name} passed`;
3244
+ hubAgentContainer(ev.roleId).appendChild(el);
3203
3245
  hubStreamEl = null; hubStreamRoleId = null;
3204
3246
  break;
3205
3247
  }
@@ -3245,5 +3287,39 @@ function hubDone(msg) {
3245
3287
  status.textContent = msg.saved ? 'Saved to history.' : 'Done (not saved).';
3246
3288
  }
3247
3289
  hubStreamEl = null; hubStreamRoleId = null;
3290
+ hubLaneMode = false; hubLaneBody = {};
3291
+ scrollToBottom();
3292
+ }
3293
+
3294
+ function hubReview(msg) {
3295
+ // Inline between-rounds steering card. Submitting guidance continues with it
3296
+ // injected; Continue (empty) proceeds; Stop ends early and jumps to summary.
3297
+ const card = document.createElement('div');
3298
+ card.className = 'hub-review border border-info/40 rounded-lg p-3 my-2 bg-info/5';
3299
+ card.innerHTML = `
3300
+ <div class="text-sm font-semibold mb-2">🧭 Round ${msg.round}/${msg.maxRounds} done — steer the next round?</div>
3301
+ <input type="text" class="input input-bordered input-sm w-full mb-2" placeholder="Optional guidance for all agents…">
3302
+ <div class="flex gap-2">
3303
+ <button class="btn btn-primary btn-sm flex-1">Continue ▶</button>
3304
+ <button class="btn btn-error btn-outline btn-sm">Stop ⏹</button>
3305
+ </div>`;
3306
+ const input = card.querySelector('input');
3307
+ const [contBtn, stopBtn] = card.querySelectorAll('button');
3308
+ let answered = false;
3309
+ const finish = (action) => {
3310
+ if (answered) return;
3311
+ answered = true;
3312
+ const message = input.value.trim();
3313
+ send({ type: 'hub_steer', requestId: msg.requestId, action, message: message || undefined });
3314
+ card.querySelectorAll('input,button').forEach(e => e.disabled = true);
3315
+ card.querySelector('.text-sm').textContent = action === 'stop'
3316
+ ? '🧭 Stopping…'
3317
+ : (message ? `🧭 Steered: ${message}` : '🧭 Continuing…');
3318
+ };
3319
+ contBtn.addEventListener('click', () => finish('continue'));
3320
+ stopBtn.addEventListener('click', () => finish('stop'));
3321
+ input.addEventListener('keydown', (e) => { if (e.key === 'Enter') finish('continue'); });
3322
+ messagesEl.appendChild(card);
3248
3323
  scrollToBottom();
3324
+ setTimeout(() => input.focus(), 50);
3249
3325
  }
@@ -209,6 +209,12 @@
209
209
  <label class="flex items-center gap-2 text-xs cursor-pointer">
210
210
  <input id="hub-vote" type="checkbox" class="checkbox checkbox-xs" checked> Convergence voting (2/3 ends early)
211
211
  </label>
212
+ <label class="flex items-center gap-2 text-xs cursor-pointer">
213
+ <input id="hub-steer" type="checkbox" class="checkbox checkbox-xs"> Human steering (pause each round to guide/stop)
214
+ </label>
215
+ <label class="flex items-center gap-2 text-xs cursor-pointer">
216
+ <input id="hub-lanes" type="checkbox" class="checkbox checkbox-xs"> Lanes view (one column per agent)
217
+ </label>
212
218
  <button id="hub-start-btn" class="btn btn-primary btn-sm w-full" onclick="startHub()">🏛 Start discussion</button>
213
219
  <button id="hub-abort-btn" class="btn btn-error btn-outline btn-xs w-full hidden" onclick="abortHub()">⏹ Stop</button>
214
220
  <div id="hub-status" class="text-xs opacity-60"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.4.156",
3
+ "version": "0.4.158",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",