jinzd-ai-cli 0.2.21 → 0.2.23

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.
@@ -8,7 +8,7 @@ import { platform } from "os";
8
8
  import chalk from "chalk";
9
9
 
10
10
  // src/core/constants.ts
11
- var VERSION = "0.2.21";
11
+ var VERSION = "0.2.23";
12
12
  var APP_NAME = "ai-cli";
13
13
  var CONFIG_DIR_NAME = ".aicli";
14
14
  var CONFIG_FILE_NAME = "config.json";
@@ -16,7 +16,7 @@ import {
16
16
  SUBAGENT_MAX_ROUNDS_LIMIT,
17
17
  VERSION,
18
18
  runTestsTool
19
- } from "./chunk-YULS53ZT.js";
19
+ } from "./chunk-M6BBSIGR.js";
20
20
 
21
21
  // src/config/config-manager.ts
22
22
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ import {
36
36
  theme,
37
37
  truncateOutput,
38
38
  undoStack
39
- } from "./chunk-TVSPBTDQ.js";
39
+ } from "./chunk-QZR2SIUB.js";
40
40
  import {
41
41
  AGENTIC_BEHAVIOR_GUIDELINE,
42
42
  AUTHOR,
@@ -56,7 +56,7 @@ import {
56
56
  REPO_URL,
57
57
  SKILLS_DIR_NAME,
58
58
  VERSION
59
- } from "./chunk-YULS53ZT.js";
59
+ } from "./chunk-M6BBSIGR.js";
60
60
 
61
61
  // src/index.ts
62
62
  import { program } from "commander";
@@ -1905,7 +1905,7 @@ ${hint}` : "")
1905
1905
  description: "Run project tests and show structured report",
1906
1906
  usage: "/test [command|filter]",
1907
1907
  async execute(args, _ctx) {
1908
- const { executeTests } = await import("./run-tests-WUWDJM5S.js");
1908
+ const { executeTests } = await import("./run-tests-A74MA54Z.js");
1909
1909
  const argStr = args.join(" ").trim();
1910
1910
  let testArgs = {};
1911
1911
  if (argStr) {
@@ -3394,12 +3394,14 @@ var Repl = class {
3394
3394
  _escHandler = null;
3395
3395
  /** User interjection: completed line queued for injection into agentic loop */
3396
3396
  _userInterjection = null;
3397
- /** User interjection: character accumulator (typed but not yet Enter'd) */
3398
- _interjectionBuf = "";
3399
- /** User interjection: stdin data handler reference */
3400
- _interjectionHandler = null;
3401
- /** Timestamp when confirm() completed used to discard residual \n bytes from Windows \r\n */
3402
- _confirmEndTime = 0;
3397
+ /** User interjection: typing-trigger stdin handler (detects first printable char) */
3398
+ _interjectionTrigger = null;
3399
+ /** Whether interjection system is active (agentic loop) */
3400
+ _interjectionActive = false;
3401
+ /** Whether user is currently in interjection typing mode (rl.question active) */
3402
+ _interjectionTyping = false;
3403
+ /** Reference to the current spinner, so interjection can pause/resume it */
3404
+ _currentSpinner = null;
3403
3405
  /** Multi-line input buffer: accumulates lines ending with \ */
3404
3406
  _multilineBuf = [];
3405
3407
  /** 运行时动态添加的额外上下文目录(/add-dir 命令) */
@@ -4534,7 +4536,7 @@ Session '${this.resumeSessionId}' not found.
4534
4536
  process.stdin.removeListener("data", this._escHandler);
4535
4537
  this._escHandler = null;
4536
4538
  }
4537
- if (!this._interjectionHandler) {
4539
+ if (!this._interjectionActive) {
4538
4540
  process.stdin.pause();
4539
4541
  }
4540
4542
  this.streamAbortController = null;
@@ -4546,54 +4548,50 @@ Session '${this.resumeSessionId}' not found.
4546
4548
  */
4547
4549
  setupInterjectionListener() {
4548
4550
  this._userInterjection = null;
4549
- this._interjectionBuf = "";
4550
- const handler = (data) => {
4551
+ this._interjectionActive = true;
4552
+ this._interjectionTyping = false;
4553
+ const trigger = (data) => {
4551
4554
  if (this.toolExecutor.confirming || askUserContext.prompting) return;
4552
- const str = data.toString("utf-8");
4553
- for (const ch of str) {
4554
- const code = ch.codePointAt(0);
4555
- if (code === 13 || code === 10) {
4556
- if (Date.now() - this._confirmEndTime < 100) continue;
4557
- if (this._interjectionBuf.length > 0) {
4558
- const line = this._interjectionBuf;
4559
- this._interjectionBuf = "";
4560
- process.stdout.write("\n");
4561
- if (line.startsWith("/")) {
4562
- this.toolExecutor.pendingSlashCommand = line;
4563
- process.stdout.write(theme.dim(` (command "${line}" queued)
4555
+ if (this._interjectionTyping) return;
4556
+ const byte = data[0];
4557
+ if (byte < 32 || byte === 127 || byte === 27) return;
4558
+ this._interjectionTyping = true;
4559
+ if (this._currentSpinner) this._currentSpinner.stop();
4560
+ const rlAny = this.rl;
4561
+ const savedOutput = rlAny.output;
4562
+ rlAny.output = process.stdout;
4563
+ process.stdout.write(theme.dim("\n \u25B8 "));
4564
+ const firstChar = data.toString("utf-8").replace(/[\x00-\x1f\x7f]/g, "");
4565
+ if (firstChar) process.stdout.write(firstChar);
4566
+ this.rl.question("", (answer) => {
4567
+ const fullLine = (firstChar + answer).trim();
4568
+ rlAny.output = savedOutput;
4569
+ this._interjectionTyping = false;
4570
+ if (fullLine.length === 0) {
4571
+ } else if (fullLine.startsWith("/")) {
4572
+ this.toolExecutor.pendingSlashCommand = fullLine;
4573
+ process.stdout.write(theme.dim(` (command "${fullLine}" queued)
4564
4574
  `));
4565
- } else {
4566
- this._userInterjection = line;
4567
- }
4568
- }
4569
- } else if (code === 127 || code === 8) {
4570
- if (this._interjectionBuf.length > 0) {
4571
- const chars = Array.from(this._interjectionBuf);
4572
- const removed = chars.pop();
4573
- this._interjectionBuf = chars.join("");
4574
- const width = removed.codePointAt(0) > 255 ? 2 : 1;
4575
- for (let w = 0; w < width; w++) process.stdout.write("\b \b");
4576
- }
4577
- } else if (code === 3 || code === 27) {
4578
- } else if (code >= 32) {
4579
- this._interjectionBuf += ch;
4580
- process.stdout.write(ch);
4575
+ } else {
4576
+ this._userInterjection = fullLine;
4581
4577
  }
4582
- }
4578
+ if (this._currentSpinner) this._currentSpinner.start();
4579
+ });
4583
4580
  };
4584
- this._interjectionHandler = handler;
4585
- process.stdin.on("data", handler);
4581
+ this._interjectionTrigger = trigger;
4582
+ process.stdin.prependListener("data", trigger);
4586
4583
  process.stdin.resume();
4587
4584
  }
4588
4585
  /**
4589
4586
  * Remove the interjection listener, clean up state.
4590
4587
  */
4591
4588
  teardownInterjectionListener() {
4592
- if (this._interjectionHandler) {
4593
- process.stdin.removeListener("data", this._interjectionHandler);
4594
- this._interjectionHandler = null;
4589
+ if (this._interjectionTrigger) {
4590
+ process.stdin.removeListener("data", this._interjectionTrigger);
4591
+ this._interjectionTrigger = null;
4595
4592
  }
4596
- this._interjectionBuf = "";
4593
+ this._interjectionActive = false;
4594
+ this._interjectionTyping = false;
4597
4595
  }
4598
4596
  /**
4599
4597
  * 注册 Ctrl+V 剪贴板图片粘贴快捷键。
@@ -4848,6 +4846,7 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds for this task. Plan ef
4848
4846
  const modelParams = this.getModelParams();
4849
4847
  const useStreaming = this.config.get("ui").streaming;
4850
4848
  const spinner = this.renderer.showSpinner("Thinking...");
4849
+ this._currentSpinner = spinner;
4851
4850
  const roundUsage = { inputTokens: 0, outputTokens: 0 };
4852
4851
  const supportsStreamingTools = useStreaming && typeof provider.chatWithToolsStream === "function";
4853
4852
  let consecutiveFreeRounds = 0;
@@ -5099,8 +5098,7 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds for this task. Plan ef
5099
5098
  }
5100
5099
  }
5101
5100
  }
5102
- if (this._interjectionHandler) {
5103
- this._confirmEndTime = Date.now();
5101
+ if (this._interjectionActive) {
5104
5102
  process.stdin.resume();
5105
5103
  }
5106
5104
  const reasoningContent = "reasoningContent" in result ? result.reasoningContent : void 0;
@@ -5256,6 +5254,7 @@ Tip: You can continue the conversation by asking the AI to proceed.`
5256
5254
  }
5257
5255
  } finally {
5258
5256
  this.teardownInterjectionListener();
5257
+ this._currentSpinner = null;
5259
5258
  spinner.stop();
5260
5259
  await this.checkContextPressure();
5261
5260
  }
@@ -5519,7 +5518,7 @@ program.command("web").description("Start Web UI server with browser-based chat
5519
5518
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
5520
5519
  process.exit(1);
5521
5520
  }
5522
- const { startWebServer } = await import("./server-FVVKVJBX.js");
5521
+ const { startWebServer } = await import("./server-LMXSNPOQ.js");
5523
5522
  await startWebServer({ port, host: options.host });
5524
5523
  });
5525
5524
  program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-YULS53ZT.js";
5
+ } from "./chunk-M6BBSIGR.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
@@ -24,7 +24,7 @@ import {
24
24
  setupProxy,
25
25
  spawnAgentContext,
26
26
  truncateOutput
27
- } from "./chunk-TVSPBTDQ.js";
27
+ } from "./chunk-QZR2SIUB.js";
28
28
  import {
29
29
  AGENTIC_BEHAVIOR_GUIDELINE,
30
30
  CONTEXT_FILE_CANDIDATES,
@@ -36,7 +36,7 @@ import {
36
36
  PLAN_MODE_SYSTEM_ADDON,
37
37
  SKILLS_DIR_NAME,
38
38
  VERSION
39
- } from "./chunk-YULS53ZT.js";
39
+ } from "./chunk-M6BBSIGR.js";
40
40
  import {
41
41
  AuthManager
42
42
  } from "./chunk-CPLT6CD3.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",