jinzd-ai-cli 0.1.74 → 0.1.75

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.1.74";
11
+ var VERSION = "0.1.75";
12
12
  var APP_NAME = "ai-cli";
13
13
  var CONFIG_DIR_NAME = ".aicli";
14
14
  var CONFIG_FILE_NAME = "config.json";
@@ -75,9 +75,11 @@ var CONTEXT_PRESSURE_THRESHOLD = 0.8;
75
75
  var TEST_TIMEOUT = 3e5;
76
76
  var AGENTIC_BEHAVIOR_GUIDELINE = `# Important Behavioral Guidelines
77
77
 
78
- **Distinguish between "understanding" and "executing"**:
78
+ **Respond appropriately to the user's intent \u2014 do NOT over-react**:
79
+ - For **greetings and casual chat** (e.g., "hello", "hi", "hey", "\u4F60\u597D", "what's up"): respond naturally with a friendly greeting. Do NOT use any tools. Do NOT explore directories, read files, or start any project work. Just chat.
79
80
  - When the user asks you to "read", "understand", "review", "analyze", "examine", or "look at" files or a project, your task is only to **read and summarize**, then wait for the user's next instruction. Do not automatically start executing tasks described in the project.
80
81
  - Only begin using write/execute tools when the user **explicitly requests** an action (e.g., "generate", "create", "modify", "run", "start", etc.).
82
+ - Project context files (CLAUDE.md, AICLI.md) provide background information about the project. They are NOT instructions to start working. Only use them as reference when the user asks a project-related question or task.
81
83
  - If you are unsure about the user's intent, use the ask_user tool to confirm with the user, rather than assuming and executing on your own.`;
82
84
  var AUTHOR = "Jin Zhengdong";
83
85
  var AUTHOR_EMAIL = "zhengdong.jin@gmail.com";
@@ -16,7 +16,7 @@ import {
16
16
  SUBAGENT_MAX_ROUNDS_LIMIT,
17
17
  VERSION,
18
18
  runTestsTool
19
- } from "./chunk-WRFXLV34.js";
19
+ } from "./chunk-KDXXHXYU.js";
20
20
 
21
21
  // src/config/config-manager.ts
22
22
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
@@ -5405,6 +5405,17 @@ var SkillManager = class {
5405
5405
  }
5406
5406
  };
5407
5407
 
5408
+ // src/core/proxy.ts
5409
+ async function setupProxy(configProxy) {
5410
+ const proxyUrl = process.env.HTTPS_PROXY ?? process.env.HTTP_PROXY ?? process.env.https_proxy ?? process.env.http_proxy ?? configProxy;
5411
+ if (!proxyUrl) return;
5412
+ try {
5413
+ const { ProxyAgent, setGlobalDispatcher } = await import("undici");
5414
+ setGlobalDispatcher(new ProxyAgent({ uri: proxyUrl }));
5415
+ } catch {
5416
+ }
5417
+ }
5418
+
5408
5419
  // src/repl/dev-state.ts
5409
5420
  import { existsSync as existsSync14, readFileSync as readFileSync8, writeFileSync as writeFileSync7, unlinkSync as unlinkSync2, mkdirSync as mkdirSync8 } from "fs";
5410
5421
  import { join as join10 } from "path";
@@ -5722,5 +5733,6 @@ export {
5722
5733
  loadDevState,
5723
5734
  clearDevState,
5724
5735
  McpManager,
5725
- SkillManager
5736
+ SkillManager,
5737
+ setupProxy
5726
5738
  };
package/dist/index.js CHANGED
@@ -30,11 +30,12 @@ import {
30
30
  runHook,
31
31
  saveDevState,
32
32
  sessionHasMeaningfulContent,
33
+ setupProxy,
33
34
  spawnAgentContext,
34
35
  theme,
35
36
  truncateOutput,
36
37
  undoStack
37
- } from "./chunk-37AZXVX2.js";
38
+ } from "./chunk-MD2SRFU4.js";
38
39
  import {
39
40
  AGENTIC_BEHAVIOR_GUIDELINE,
40
41
  AUTHOR,
@@ -54,7 +55,7 @@ import {
54
55
  REPO_URL,
55
56
  SKILLS_DIR_NAME,
56
57
  VERSION
57
- } from "./chunk-WRFXLV34.js";
58
+ } from "./chunk-KDXXHXYU.js";
58
59
 
59
60
  // src/index.ts
60
61
  import { program } from "commander";
@@ -1903,7 +1904,7 @@ ${hint}` : "")
1903
1904
  description: "Run project tests and show structured report",
1904
1905
  usage: "/test [command|filter]",
1905
1906
  async execute(args, _ctx) {
1906
- const { executeTests } = await import("./run-tests-IJDQJJ3N.js");
1907
+ const { executeTests } = await import("./run-tests-D5RGQY6A.js");
1907
1908
  const argStr = args.join(" ").trim();
1908
1909
  let testArgs = {};
1909
1910
  if (argStr) {
@@ -5290,7 +5291,7 @@ program.command("web").description("Start Web UI server with browser-based chat
5290
5291
  console.error("Error: Invalid port number. Must be between 1 and 65535.");
5291
5292
  process.exit(1);
5292
5293
  }
5293
- const { startWebServer } = await import("./server-4LKAYB5Y.js");
5294
+ const { startWebServer } = await import("./server-4ZYMNPYO.js");
5294
5295
  await startWebServer({ port, host: options.host });
5295
5296
  });
5296
5297
  program.command("sessions").description("List recent conversation sessions").action(async () => {
@@ -5314,15 +5315,6 @@ program.command("sessions").description("List recent conversation sessions").act
5314
5315
  console.log();
5315
5316
  });
5316
5317
  program.parse();
5317
- async function setupProxy(configProxy) {
5318
- const proxyUrl = process.env.HTTPS_PROXY ?? process.env.HTTP_PROXY ?? process.env.https_proxy ?? process.env.http_proxy ?? configProxy;
5319
- if (!proxyUrl) return;
5320
- try {
5321
- const { ProxyAgent, setGlobalDispatcher } = await import("undici");
5322
- setGlobalDispatcher(new ProxyAgent({ uri: proxyUrl }));
5323
- } catch {
5324
- }
5325
- }
5326
5318
  async function readStdin() {
5327
5319
  if (process.stdin.isTTY) return "";
5328
5320
  return new Promise((resolve3, reject) => {
@@ -5525,3 +5517,6 @@ Provider '${options.provider}' is not configured. Run: ai-cli config
5525
5517
  });
5526
5518
  await repl.start();
5527
5519
  }
5520
+ export {
5521
+ setupProxy
5522
+ };
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  executeTests,
4
4
  runTestsTool
5
- } from "./chunk-WRFXLV34.js";
5
+ } from "./chunk-KDXXHXYU.js";
6
6
  export {
7
7
  executeTests,
8
8
  runTestsTool
@@ -19,11 +19,13 @@ import {
19
19
  loadDevState,
20
20
  renderDiff,
21
21
  runHook,
22
+ setupProxy,
22
23
  spawnAgentContext,
23
24
  truncateOutput
24
- } from "./chunk-37AZXVX2.js";
25
+ } from "./chunk-MD2SRFU4.js";
25
26
  import {
26
27
  AGENTIC_BEHAVIOR_GUIDELINE,
28
+ CONTEXT_FILE_CANDIDATES,
27
29
  DEFAULT_MAX_TOKENS,
28
30
  MCP_PROJECT_CONFIG_NAME,
29
31
  MEMORY_FILE_NAME,
@@ -32,13 +34,13 @@ import {
32
34
  PLAN_MODE_SYSTEM_ADDON,
33
35
  SKILLS_DIR_NAME,
34
36
  VERSION
35
- } from "./chunk-WRFXLV34.js";
37
+ } from "./chunk-KDXXHXYU.js";
36
38
 
37
39
  // src/web/server.ts
38
40
  import express from "express";
39
41
  import { createServer } from "http";
40
42
  import { WebSocketServer } from "ws";
41
- import { join as join3, dirname, resolve } from "path";
43
+ import { join as join3, dirname, resolve as resolve2 } from "path";
42
44
  import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
43
45
 
44
46
  // src/web/tool-executor-web.ts
@@ -71,31 +73,31 @@ var ToolExecutorWeb = class {
71
73
  }
72
74
  /** Resolve a pending confirm from client response */
73
75
  resolveConfirm(requestId, approved) {
74
- const resolve2 = this.pendingConfirms.get(requestId);
75
- if (resolve2) {
76
+ const resolve3 = this.pendingConfirms.get(requestId);
77
+ if (resolve3) {
76
78
  this.pendingConfirms.delete(requestId);
77
79
  this.confirming = false;
78
- resolve2(approved);
80
+ resolve3(approved);
79
81
  }
80
82
  }
81
83
  /** Resolve a pending batch confirm from client response */
82
84
  resolveBatchConfirm(requestId, decision) {
83
- const resolve2 = this.pendingBatchConfirms.get(requestId);
84
- if (resolve2) {
85
+ const resolve3 = this.pendingBatchConfirms.get(requestId);
86
+ if (resolve3) {
85
87
  this.pendingBatchConfirms.delete(requestId);
86
88
  this.confirming = false;
87
89
  if (decision === "all" || decision === "none") {
88
- resolve2(decision);
90
+ resolve3(decision);
89
91
  } else {
90
- resolve2(new Set(decision));
92
+ resolve3(new Set(decision));
91
93
  }
92
94
  }
93
95
  }
94
96
  /** Cancel all pending confirms (e.g., on disconnect) */
95
97
  cancelAll() {
96
- for (const resolve2 of this.pendingConfirms.values()) resolve2(false);
98
+ for (const resolve3 of this.pendingConfirms.values()) resolve3(false);
97
99
  this.pendingConfirms.clear();
98
- for (const resolve2 of this.pendingBatchConfirms.values()) resolve2("none");
100
+ for (const resolve3 of this.pendingBatchConfirms.values()) resolve3("none");
99
101
  this.pendingBatchConfirms.clear();
100
102
  this.confirming = false;
101
103
  }
@@ -164,8 +166,8 @@ var ToolExecutorWeb = class {
164
166
  diff: this.getDiffPreview(call)
165
167
  };
166
168
  this.send(msg);
167
- return new Promise((resolve2) => {
168
- this.pendingConfirms.set(requestId, resolve2);
169
+ return new Promise((resolve3) => {
170
+ this.pendingConfirms.set(requestId, resolve3);
169
171
  });
170
172
  }
171
173
  /** WebSocket-based batch confirm */
@@ -184,8 +186,8 @@ var ToolExecutorWeb = class {
184
186
  files
185
187
  };
186
188
  this.send(msg);
187
- return new Promise((resolve2) => {
188
- this.pendingBatchConfirms.set(requestId, resolve2);
189
+ return new Promise((resolve3) => {
190
+ this.pendingBatchConfirms.set(requestId, resolve3);
189
191
  });
190
192
  }
191
193
  async execute(call) {
@@ -387,7 +389,7 @@ function loadMemoryContent(configDir) {
387
389
 
388
390
  // src/web/session-handler.ts
389
391
  import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
390
- import { join as join2 } from "path";
392
+ import { join as join2, resolve } from "path";
391
393
  var MAX_TOOL_ROUNDS = 25;
392
394
  var FREE_ROUND_TOOLS = /* @__PURE__ */ new Set(["write_todos"]);
393
395
  var MAX_CONSECUTIVE_FREE_ROUNDS = 5;
@@ -488,10 +490,10 @@ var SessionHandler = class {
488
490
  return;
489
491
  }
490
492
  case "ask_user_response": {
491
- const resolve2 = this.pendingAskUser.get(msg.requestId);
492
- if (resolve2) {
493
+ const resolve3 = this.pendingAskUser.get(msg.requestId);
494
+ if (resolve3) {
493
495
  this.pendingAskUser.delete(msg.requestId);
494
- resolve2(msg.answer);
496
+ resolve3(msg.answer);
495
497
  }
496
498
  return;
497
499
  }
@@ -508,7 +510,7 @@ var SessionHandler = class {
508
510
  onDisconnect() {
509
511
  this.toolExecutor.cancelAll();
510
512
  if (this.abortController) this.abortController.abort();
511
- for (const resolve2 of this.pendingAskUser.values()) resolve2(null);
513
+ for (const resolve3 of this.pendingAskUser.values()) resolve3(null);
512
514
  this.pendingAskUser.clear();
513
515
  this.sessions.save();
514
516
  }
@@ -962,19 +964,43 @@ Tokens: in=${this.sessionTokenUsage.inputTokens} out=${this.sessionTokenUsage.ou
962
964
  }
963
965
  return defs;
964
966
  }
965
- loadContextFiles() {
966
- const cwd = process.cwd();
967
- const candidates = ["AICLI.md", "CLAUDE.md"];
968
- for (const name of candidates) {
969
- const fullPath = join2(cwd, name);
967
+ /**
968
+ * Find first matching context file in a directory.
969
+ */
970
+ findContextFile(dir) {
971
+ for (const name of CONTEXT_FILE_CANDIDATES) {
972
+ const fullPath = join2(dir, name);
970
973
  try {
971
974
  if (existsSync3(fullPath)) {
972
- return readFileSync3(fullPath, "utf-8").trim() || void 0;
975
+ const content = readFileSync3(fullPath, "utf-8").trim();
976
+ if (content) return content;
973
977
  }
974
978
  } catch {
975
979
  }
976
980
  }
977
- return void 0;
981
+ return null;
982
+ }
983
+ /**
984
+ * Load hierarchical context files (same as CLI):
985
+ * 1. Global: ~/.aicli/AICLI.md or CLAUDE.md
986
+ * 2. Project: <git-root>/AICLI.md or CLAUDE.md
987
+ * 3. Subdir: <cwd>/AICLI.md or CLAUDE.md (only if cwd ≠ project root)
988
+ */
989
+ loadContextFiles() {
990
+ const parts = [];
991
+ const cwd = process.cwd();
992
+ const configDir = this.config.getConfigDir();
993
+ const globalCtx = this.findContextFile(configDir);
994
+ if (globalCtx) parts.push(globalCtx);
995
+ const gitRoot = getGitRoot(cwd);
996
+ const projectRoot = gitRoot ?? cwd;
997
+ const projectCtx = this.findContextFile(projectRoot);
998
+ if (projectCtx) parts.push(projectCtx);
999
+ if (resolve(cwd) !== resolve(projectRoot)) {
1000
+ const localCtx = this.findContextFile(cwd);
1001
+ if (localCtx) parts.push(localCtx);
1002
+ }
1003
+ return parts.length > 0 ? parts.join("\n\n---\n\n") : void 0;
978
1004
  }
979
1005
  };
980
1006
 
@@ -988,7 +1014,7 @@ function getModuleDir() {
988
1014
  }
989
1015
  } catch {
990
1016
  }
991
- return resolve(".");
1017
+ return resolve2(".");
992
1018
  }
993
1019
  async function startWebServer(options = {}) {
994
1020
  const port = options.port ?? 3e3;
@@ -996,6 +1022,7 @@ async function startWebServer(options = {}) {
996
1022
  console.log(`\u{1F916} ai-cli Web UI v${VERSION}`);
997
1023
  console.log(` Initializing...`);
998
1024
  const config = new ConfigManager();
1025
+ await setupProxy(config.get("proxy"));
999
1026
  const providers = new ProviderRegistry();
1000
1027
  const sessions = new SessionManager(config);
1001
1028
  const toolRegistry = new ToolRegistry();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jinzd-ai-cli",
3
- "version": "0.1.74",
3
+ "version": "0.1.75",
4
4
  "description": "Cross-platform REPL-style AI CLI with multi-provider support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",