jinzd-ai-cli 0.2.22 → 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.22";
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-TYZVSHVJ.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-FUR3Z67Z.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-TYZVSHVJ.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-HCONBTQL.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 (echo-only) */
3400
- _interjectionHandler = null;
3401
- /** Whether interjection listener is active (agentic loop) */
3397
+ /** User interjection: typing-trigger stdin handler (detects first printable char) */
3398
+ _interjectionTrigger = null;
3399
+ /** Whether interjection system is active (agentic loop) */
3402
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 命令) */
@@ -4184,18 +4186,6 @@ Session '${this.resumeSessionId}' not found.
4184
4186
  if (this.toolExecutor.confirming) return;
4185
4187
  if (this.selecting) return;
4186
4188
  if (askUserContext.prompting) return;
4187
- if (processing && this._interjectionActive) {
4188
- const trimmed = line.trim();
4189
- if (trimmed.length === 0) return;
4190
- if (trimmed.startsWith("/")) {
4191
- this.toolExecutor.pendingSlashCommand = trimmed;
4192
- process.stdout.write(theme.dim(` (command "${trimmed}" queued)
4193
- `));
4194
- } else {
4195
- this._userInterjection = trimmed;
4196
- }
4197
- return;
4198
- }
4199
4189
  if (processing) return;
4200
4190
  const rawTrimmed = line.trimEnd();
4201
4191
  if (rawTrimmed.endsWith("\\")) {
@@ -4558,45 +4548,50 @@ Session '${this.resumeSessionId}' not found.
4558
4548
  */
4559
4549
  setupInterjectionListener() {
4560
4550
  this._userInterjection = null;
4561
- this._interjectionBuf = "";
4562
4551
  this._interjectionActive = true;
4563
- this.rl.resume();
4564
- const handler = (data) => {
4552
+ this._interjectionTyping = false;
4553
+ const trigger = (data) => {
4565
4554
  if (this.toolExecutor.confirming || askUserContext.prompting) return;
4566
- const str = data.toString("utf-8");
4567
- for (const ch of str) {
4568
- const code = ch.codePointAt(0);
4569
- if (code === 13 || code === 10) {
4570
- this._interjectionBuf = "";
4571
- } else if (code === 127 || code === 8) {
4572
- if (this._interjectionBuf.length > 0) {
4573
- const chars = Array.from(this._interjectionBuf);
4574
- const removed = chars.pop();
4575
- this._interjectionBuf = chars.join("");
4576
- const width = removed.codePointAt(0) > 255 ? 2 : 1;
4577
- for (let w = 0; w < width; w++) process.stdout.write("\b \b");
4578
- }
4579
- } else if (code === 3 || code === 27) {
4580
- } else if (code >= 32) {
4581
- this._interjectionBuf += ch;
4582
- process.stdout.write(ch);
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)
4574
+ `));
4575
+ } else {
4576
+ this._userInterjection = fullLine;
4583
4577
  }
4584
- }
4578
+ if (this._currentSpinner) this._currentSpinner.start();
4579
+ });
4585
4580
  };
4586
- this._interjectionHandler = handler;
4587
- process.stdin.on("data", handler);
4581
+ this._interjectionTrigger = trigger;
4582
+ process.stdin.prependListener("data", trigger);
4583
+ process.stdin.resume();
4588
4584
  }
4589
4585
  /**
4590
4586
  * Remove the interjection listener, clean up state.
4591
4587
  */
4592
4588
  teardownInterjectionListener() {
4593
- if (this._interjectionHandler) {
4594
- process.stdin.removeListener("data", this._interjectionHandler);
4595
- this._interjectionHandler = null;
4589
+ if (this._interjectionTrigger) {
4590
+ process.stdin.removeListener("data", this._interjectionTrigger);
4591
+ this._interjectionTrigger = null;
4596
4592
  }
4597
- this._interjectionBuf = "";
4598
4593
  this._interjectionActive = false;
4599
- this.rl.pause();
4594
+ this._interjectionTyping = false;
4600
4595
  }
4601
4596
  /**
4602
4597
  * 注册 Ctrl+V 剪贴板图片粘贴快捷键。
@@ -4851,6 +4846,7 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds for this task. Plan ef
4851
4846
  const modelParams = this.getModelParams();
4852
4847
  const useStreaming = this.config.get("ui").streaming;
4853
4848
  const spinner = this.renderer.showSpinner("Thinking...");
4849
+ this._currentSpinner = spinner;
4854
4850
  const roundUsage = { inputTokens: 0, outputTokens: 0 };
4855
4851
  const supportsStreamingTools = useStreaming && typeof provider.chatWithToolsStream === "function";
4856
4852
  let consecutiveFreeRounds = 0;
@@ -5103,7 +5099,7 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds for this task. Plan ef
5103
5099
  }
5104
5100
  }
5105
5101
  if (this._interjectionActive) {
5106
- this.rl.resume();
5102
+ process.stdin.resume();
5107
5103
  }
5108
5104
  const reasoningContent = "reasoningContent" in result ? result.reasoningContent : void 0;
5109
5105
  const newMsgs = provider.buildToolResultMessages(result.toolCalls, toolResults, reasoningContent);
@@ -5258,6 +5254,7 @@ Tip: You can continue the conversation by asking the AI to proceed.`
5258
5254
  }
5259
5255
  } finally {
5260
5256
  this.teardownInterjectionListener();
5257
+ this._currentSpinner = null;
5261
5258
  spinner.stop();
5262
5259
  await this.checkContextPressure();
5263
5260
  }
@@ -5521,7 +5518,7 @@ program.command("web").description("Start Web UI server with browser-based chat
5521
5518
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
5522
5519
  process.exit(1);
5523
5520
  }
5524
- const { startWebServer } = await import("./server-LC5U6FSV.js");
5521
+ const { startWebServer } = await import("./server-LMXSNPOQ.js");
5525
5522
  await startWebServer({ port, host: options.host });
5526
5523
  });
5527
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-TYZVSHVJ.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-FUR3Z67Z.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-TYZVSHVJ.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.22",
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",