jinzd-ai-cli 0.4.19 → 0.4.21
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.
- package/README.md +7 -6
- package/README.zh-CN.md +7 -6
- package/dist/{chunk-PR5JZVNN.js → chunk-2JOMWVTE.js} +1 -1
- package/dist/{chunk-6WLDJKHU.js → chunk-6CJX3RST.js} +31 -1
- package/dist/{chunk-DBEYB76P.js → chunk-7T2W4LN3.js} +21 -3
- package/dist/{chunk-JNAZORS2.js → chunk-AR656G5C.js} +31 -1
- package/dist/{hub-RJRNBB5G.js → hub-CNSFX47B.js} +1 -1
- package/dist/index.js +175 -32
- package/dist/{run-tests-AUTWQ5NB.js → run-tests-3PLCZ4P3.js} +1 -1
- package/dist/{run-tests-HP4MMQAP.js → run-tests-ZTVEN2O7.js} +1 -1
- package/dist/{server-JFLTWF7Q.js → server-IDPMZAUF.js} +16 -7
- package/dist/{task-orchestrator-JKY2T2W3.js → task-orchestrator-UZQRB7AO.js} +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://www.npmjs.com/package/jinzd-ai-cli)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
[](https://nodejs.org)
|
|
10
|
-
[]()
|
|
11
11
|
[](https://github.com/jinzhengdong/ai-cli/releases)
|
|
12
12
|
[](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml)
|
|
13
13
|
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
- **PWA Support** — Install Web UI as a desktop/mobile app, accessible over LAN
|
|
35
35
|
- **Hierarchical Context** — 3-layer context files (global / project / subdirectory) auto-injected
|
|
36
36
|
- **Headless Mode** — `ai-cli -p "prompt"` for CI/CD pipelines and scripting
|
|
37
|
-
- **
|
|
37
|
+
- **38 REPL Commands** — Session management, checkpointing, code review, scaffolding, user identity, and more
|
|
38
38
|
- **GitHub Actions CI/CD** — Automated testing on Node 20/22 + npm publish on release tags
|
|
39
39
|
- **Cross-Platform** — Windows, macOS, Linux
|
|
40
40
|
|
|
@@ -75,7 +75,7 @@ Pre-built CLI binaries (no Node.js required, ~56 MB):
|
|
|
75
75
|
aicli
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
On first run, an interactive setup wizard guides you through
|
|
78
|
+
On first run, an interactive setup wizard guides you through setting up your profile and entering your API key. Your identity is persisted and injected into every AI conversation.
|
|
79
79
|
|
|
80
80
|
```
|
|
81
81
|
[deepseek] > Hello! Tell me about this project
|
|
@@ -167,12 +167,13 @@ AI autonomously invokes these 16 tools during conversations:
|
|
|
167
167
|
| `/undo` | Undo last file operation |
|
|
168
168
|
| `/doctor` | Health check (API keys, MCP, context) |
|
|
169
169
|
| `/export` | Export session as Markdown or JSON |
|
|
170
|
+
| `/profile` | View/edit your identity (AI knows who you are across all providers) |
|
|
170
171
|
| `/config` | Open configuration wizard |
|
|
171
172
|
| `/help` | Show all available commands |
|
|
172
173
|
|
|
173
174
|
**Multi-line input**: Use `\` at end of line for continuation, or paste multi-line content directly (auto-detected and merged).
|
|
174
175
|
|
|
175
|
-
Type `/help` in the REPL to see all
|
|
176
|
+
Type `/help` in the REPL to see all 38 commands.
|
|
176
177
|
|
|
177
178
|
## CLI Parameters
|
|
178
179
|
|
|
@@ -348,11 +349,11 @@ The Web UI (`aicli web`) provides a full-featured browser interface:
|
|
|
348
349
|
## Testing
|
|
349
350
|
|
|
350
351
|
```bash
|
|
351
|
-
npm test # Run all
|
|
352
|
+
npm test # Run all 282 tests
|
|
352
353
|
npm run test:watch # Watch mode
|
|
353
354
|
```
|
|
354
355
|
|
|
355
|
-
|
|
356
|
+
18 test suites covering: authentication, sessions, tool types & danger levels, permissions, output truncation, diff rendering, edit-file similarity, error hierarchy, config management, env loading, provider registry, web-fetch, grep-files, hub renderer, hub discussion, hub presets, dev-state.
|
|
356
357
|
|
|
357
358
|
## Documentation
|
|
358
359
|
|
package/README.zh-CN.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](https://www.npmjs.com/package/jinzd-ai-cli)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
[](https://nodejs.org)
|
|
10
|
-
[]()
|
|
11
11
|
[](https://github.com/jinzhengdong/ai-cli/releases)
|
|
12
12
|
[](https://github.com/jinzhengdong/ai-cli/actions/workflows/ci.yml)
|
|
13
13
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
- **PWA 支持** — Web UI 可安装为桌面/移动应用,支持局域网访问
|
|
27
27
|
- **三层级上下文** — 全局 / 项目 / 子目录上下文文件自动注入
|
|
28
28
|
- **无头模式** — `aicli -p "提示词"` 用于 CI/CD 管道和脚本
|
|
29
|
-
- **
|
|
29
|
+
- **38 个 REPL 命令** — 会话管理、检查点、代码审查、脚手架、用户身份等
|
|
30
30
|
- **GitHub Actions CI/CD** — Node 20/22 自动测试 + Release tag 自动发布 npm
|
|
31
31
|
- **跨平台** — Windows、macOS、Linux
|
|
32
32
|
|
|
@@ -67,7 +67,7 @@ npm install -g jinzd-ai-cli
|
|
|
67
67
|
aicli
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
首次运行会进入交互式配置向导,先设置你的身份档案,再选择 Provider 并输入 API Key。身份信息会注入每次 AI 对话。
|
|
71
71
|
|
|
72
72
|
```
|
|
73
73
|
[deepseek] > 你好!帮我分析一下这个项目
|
|
@@ -159,12 +159,13 @@ AI 在对话中可自主调用 16 个工具:
|
|
|
159
159
|
| `/undo` | 撤销上次文件操作 |
|
|
160
160
|
| `/doctor` | 健康检查(API Key、MCP、上下文) |
|
|
161
161
|
| `/export` | 导出会话为 Markdown 或 JSON |
|
|
162
|
+
| `/profile` | 查看/编辑身份档案(AI 跨 Provider 认识你) |
|
|
162
163
|
| `/config` | 打开配置向导 |
|
|
163
164
|
| `/help` | 显示所有命令 |
|
|
164
165
|
|
|
165
166
|
**多行输入**:行末加 `\` 续行,或直接粘贴多行内容(自动检测合并)。
|
|
166
167
|
|
|
167
|
-
在 REPL 中输入 `/help` 查看全部
|
|
168
|
+
在 REPL 中输入 `/help` 查看全部 38 个命令。
|
|
168
169
|
|
|
169
170
|
## CLI 参数
|
|
170
171
|
|
|
@@ -361,11 +362,11 @@ Web UI(`aicli web`)提供功能完备的浏览器界面:
|
|
|
361
362
|
## 测试
|
|
362
363
|
|
|
363
364
|
```bash
|
|
364
|
-
npm test # 运行全部
|
|
365
|
+
npm test # 运行全部 282 个测试
|
|
365
366
|
npm run test:watch # 监听模式
|
|
366
367
|
```
|
|
367
368
|
|
|
368
|
-
|
|
369
|
+
18 个测试套件覆盖:认证、会话、工具类型与危险级别、权限、输出截断、diff 渲染、edit-file 相似度、错误层级、配置管理、环境变量、Provider 注册、web-fetch、grep-files、Hub 渲染、Hub 讨论、Hub 预设、开发状态。
|
|
369
370
|
|
|
370
371
|
## 文档
|
|
371
372
|
|
|
@@ -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.
|
|
9
|
+
var VERSION = "0.4.21";
|
|
10
10
|
var APP_NAME = "ai-cli";
|
|
11
11
|
var CONFIG_DIR_NAME = ".aicli";
|
|
12
12
|
var CONFIG_FILE_NAME = "config.json";
|
|
@@ -85,6 +85,35 @@ var AGENTIC_BEHAVIOR_GUIDELINE = `# Important Behavioral Guidelines
|
|
|
85
85
|
- Only begin using write/execute tools when the user **explicitly requests** an action (e.g., "generate", "create", "modify", "run", "start", etc.).
|
|
86
86
|
- 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.
|
|
87
87
|
- 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.`;
|
|
88
|
+
function buildUserIdentityPrompt(profile) {
|
|
89
|
+
const lines = [];
|
|
90
|
+
const displayName = profile.nickname || profile.name;
|
|
91
|
+
if (displayName) {
|
|
92
|
+
lines.push(`The user's name is **${profile.name || displayName}**${profile.nickname && profile.name ? ` (prefers to be called **${profile.nickname}**)` : ""}.`);
|
|
93
|
+
}
|
|
94
|
+
if (profile.role) {
|
|
95
|
+
lines.push(`Role: ${profile.role}.`);
|
|
96
|
+
}
|
|
97
|
+
if (profile.bio) {
|
|
98
|
+
lines.push(`About: ${profile.bio}`);
|
|
99
|
+
}
|
|
100
|
+
if (profile.interests && profile.interests.length > 0) {
|
|
101
|
+
lines.push(`Interests & expertise: ${profile.interests.join(", ")}.`);
|
|
102
|
+
}
|
|
103
|
+
if (profile.locale) {
|
|
104
|
+
lines.push(`Preferred language: ${profile.locale}. Please respond in this language unless the user explicitly uses another language.`);
|
|
105
|
+
}
|
|
106
|
+
if (profile.extra) {
|
|
107
|
+
lines.push(`
|
|
108
|
+
${profile.extra}`);
|
|
109
|
+
}
|
|
110
|
+
if (lines.length === 0) return null;
|
|
111
|
+
return `# Who You're Talking To
|
|
112
|
+
|
|
113
|
+
${lines.join("\n")}
|
|
114
|
+
|
|
115
|
+
Address the user personally and adapt your communication style to their background. This identity persists across all conversations and all AI providers.`;
|
|
116
|
+
}
|
|
88
117
|
var AUTHOR = "Jin Zhengdong";
|
|
89
118
|
var AUTHOR_EMAIL = "zhengdong.jin@gmail.com";
|
|
90
119
|
var DESCRIPTION = "Cross-platform REPL-style AI conversation tool with multi-provider and agentic tool calling support";
|
|
@@ -468,6 +497,7 @@ export {
|
|
|
468
497
|
SUBAGENT_MAX_ROUNDS_LIMIT,
|
|
469
498
|
SUBAGENT_ALLOWED_TOOLS,
|
|
470
499
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
500
|
+
buildUserIdentityPrompt,
|
|
471
501
|
AUTHOR,
|
|
472
502
|
AUTHOR_EMAIL,
|
|
473
503
|
DESCRIPTION,
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
ProviderNotFoundError,
|
|
8
8
|
RateLimitError,
|
|
9
9
|
schemaToJsonSchema
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2JOMWVTE.js";
|
|
11
11
|
import {
|
|
12
12
|
APP_NAME,
|
|
13
13
|
CONFIG_DIR_NAME,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
MCP_TOOL_PREFIX,
|
|
21
21
|
PLUGINS_DIR_NAME,
|
|
22
22
|
VERSION
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-AR656G5C.js";
|
|
24
24
|
|
|
25
25
|
// src/config/config-manager.ts
|
|
26
26
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
@@ -58,8 +58,26 @@ var ModelParamsSchema = z.object({
|
|
|
58
58
|
/** thinking 模式的 token 预算(最小 1024,仅 Claude Extended Thinking 使用) */
|
|
59
59
|
thinkingBudget: z.number().int().min(1024).optional()
|
|
60
60
|
});
|
|
61
|
+
var UserProfileSchema = z.object({
|
|
62
|
+
/** 真实姓名(如 "Jin Zhengdong") */
|
|
63
|
+
name: z.string().optional(),
|
|
64
|
+
/** 昵称/称呼偏好(如 "东叔"),AI 会以此称呼你 */
|
|
65
|
+
nickname: z.string().optional(),
|
|
66
|
+
/** 职业角色(如 "Full-stack developer"、"Data scientist") */
|
|
67
|
+
role: z.string().optional(),
|
|
68
|
+
/** 个人简介 / 专长描述(1-3 句话) */
|
|
69
|
+
bio: z.string().optional(),
|
|
70
|
+
/** 兴趣领域或技术栈(如 ["TypeScript", "Rust", "AI/ML"]) */
|
|
71
|
+
interests: z.array(z.string()).default([]),
|
|
72
|
+
/** 语言偏好(如 "zh-CN"、"en"),AI 将据此选择交流语言 */
|
|
73
|
+
locale: z.string().optional(),
|
|
74
|
+
/** 自定义人设补充(自由格式,直接注入 system prompt) */
|
|
75
|
+
extra: z.string().optional()
|
|
76
|
+
}).default({});
|
|
61
77
|
var ConfigSchema = z.object({
|
|
62
78
|
version: z.string().default("1.0.0"),
|
|
79
|
+
// 用户身份档案 — 跨 Provider 的 "灵魂"
|
|
80
|
+
userProfile: UserProfileSchema,
|
|
63
81
|
defaultProvider: z.string().default("claude"),
|
|
64
82
|
// 每个 provider 的默认模型(key 为 provider ID)
|
|
65
83
|
defaultModels: z.record(z.string()).default({}),
|
|
@@ -3441,7 +3459,7 @@ function saveDevState(content) {
|
|
|
3441
3459
|
if (trimmed.length > DEV_STATE_MAX_CHARS) {
|
|
3442
3460
|
trimmed = trimmed.slice(0, DEV_STATE_MAX_CHARS);
|
|
3443
3461
|
const lastNewline = trimmed.lastIndexOf("\n");
|
|
3444
|
-
if (lastNewline >
|
|
3462
|
+
if (lastNewline > 0) {
|
|
3445
3463
|
trimmed = trimmed.slice(0, lastNewline);
|
|
3446
3464
|
}
|
|
3447
3465
|
trimmed += "\n\n[...truncated]";
|
|
@@ -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.4.
|
|
11
|
+
var VERSION = "0.4.21";
|
|
12
12
|
var APP_NAME = "ai-cli";
|
|
13
13
|
var CONFIG_DIR_NAME = ".aicli";
|
|
14
14
|
var CONFIG_FILE_NAME = "config.json";
|
|
@@ -88,6 +88,35 @@ var AGENTIC_BEHAVIOR_GUIDELINE = `# Important Behavioral Guidelines
|
|
|
88
88
|
- Only begin using write/execute tools when the user **explicitly requests** an action (e.g., "generate", "create", "modify", "run", "start", etc.).
|
|
89
89
|
- 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.
|
|
90
90
|
- 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.`;
|
|
91
|
+
function buildUserIdentityPrompt(profile) {
|
|
92
|
+
const lines = [];
|
|
93
|
+
const displayName = profile.nickname || profile.name;
|
|
94
|
+
if (displayName) {
|
|
95
|
+
lines.push(`The user's name is **${profile.name || displayName}**${profile.nickname && profile.name ? ` (prefers to be called **${profile.nickname}**)` : ""}.`);
|
|
96
|
+
}
|
|
97
|
+
if (profile.role) {
|
|
98
|
+
lines.push(`Role: ${profile.role}.`);
|
|
99
|
+
}
|
|
100
|
+
if (profile.bio) {
|
|
101
|
+
lines.push(`About: ${profile.bio}`);
|
|
102
|
+
}
|
|
103
|
+
if (profile.interests && profile.interests.length > 0) {
|
|
104
|
+
lines.push(`Interests & expertise: ${profile.interests.join(", ")}.`);
|
|
105
|
+
}
|
|
106
|
+
if (profile.locale) {
|
|
107
|
+
lines.push(`Preferred language: ${profile.locale}. Please respond in this language unless the user explicitly uses another language.`);
|
|
108
|
+
}
|
|
109
|
+
if (profile.extra) {
|
|
110
|
+
lines.push(`
|
|
111
|
+
${profile.extra}`);
|
|
112
|
+
}
|
|
113
|
+
if (lines.length === 0) return null;
|
|
114
|
+
return `# Who You're Talking To
|
|
115
|
+
|
|
116
|
+
${lines.join("\n")}
|
|
117
|
+
|
|
118
|
+
Address the user personally and adapt your communication style to their background. This identity persists across all conversations and all AI providers.`;
|
|
119
|
+
}
|
|
91
120
|
var AUTHOR = "Jin Zhengdong";
|
|
92
121
|
var AUTHOR_EMAIL = "zhengdong.jin@gmail.com";
|
|
93
122
|
var DESCRIPTION = "Cross-platform REPL-style AI conversation tool with multi-provider and agentic tool calling support";
|
|
@@ -473,6 +502,7 @@ export {
|
|
|
473
502
|
SUBAGENT_ALLOWED_TOOLS,
|
|
474
503
|
CONTEXT_PRESSURE_THRESHOLD,
|
|
475
504
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
505
|
+
buildUserIdentityPrompt,
|
|
476
506
|
AUTHOR,
|
|
477
507
|
AUTHOR_EMAIL,
|
|
478
508
|
DESCRIPTION,
|
|
@@ -387,7 +387,7 @@ ${content}`);
|
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
389
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
390
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
390
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-UZQRB7AO.js");
|
|
391
391
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
392
392
|
let interrupted = false;
|
|
393
393
|
const onSigint = () => {
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
saveDevState,
|
|
24
24
|
sessionHasMeaningfulContent,
|
|
25
25
|
setupProxy
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-7T2W4LN3.js";
|
|
27
27
|
import {
|
|
28
28
|
ToolRegistry,
|
|
29
29
|
askUserContext,
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
theme,
|
|
39
39
|
truncateOutput,
|
|
40
40
|
undoStack
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-2JOMWVTE.js";
|
|
42
42
|
import {
|
|
43
43
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
44
44
|
AUTHOR,
|
|
@@ -57,8 +57,9 @@ import {
|
|
|
57
57
|
PLAN_MODE_SYSTEM_ADDON,
|
|
58
58
|
REPO_URL,
|
|
59
59
|
SKILLS_DIR_NAME,
|
|
60
|
-
VERSION
|
|
61
|
-
|
|
60
|
+
VERSION,
|
|
61
|
+
buildUserIdentityPrompt
|
|
62
|
+
} from "./chunk-AR656G5C.js";
|
|
62
63
|
|
|
63
64
|
// src/index.ts
|
|
64
65
|
import { program } from "commander";
|
|
@@ -166,14 +167,16 @@ var Renderer = class {
|
|
|
166
167
|
const configured = options?.wrapWidth ?? 0;
|
|
167
168
|
this.wrapWidth = configured > 0 ? configured : 0;
|
|
168
169
|
}
|
|
169
|
-
printWelcome(provider, model, contextWindow) {
|
|
170
|
+
printWelcome(provider, model, contextWindow, userNickname) {
|
|
170
171
|
const ctxStr = contextWindow ? theme.dim(` (ctx: ${fmtContextWindow(contextWindow)})`) : "";
|
|
172
|
+
const greeting = userNickname ? ` \u{1F44B} Hello, ${userNickname}!` : "";
|
|
171
173
|
console.log();
|
|
172
174
|
console.log(theme.heading(" \u{1F916} ai-cli") + theme.dim(` v${VERSION}`) + theme.dim(" \u2014 " + AUTHOR + " <" + AUTHOR_EMAIL + ">"));
|
|
175
|
+
if (greeting) console.log(theme.accent(greeting));
|
|
173
176
|
console.log(theme.dim(" " + "\u2500".repeat(55)));
|
|
174
177
|
console.log(theme.dim(` Provider : `) + theme.prompt(provider));
|
|
175
178
|
console.log(theme.dim(` Model : `) + chalk.white(model) + ctxStr);
|
|
176
|
-
console.log(theme.dim(" Commands : ") + theme.dim("/help \xB7 /about \xB7 Ctrl+C to exit"));
|
|
179
|
+
console.log(theme.dim(" Commands : ") + theme.dim("/help \xB7 /about \xB7 /profile \xB7 Ctrl+C to exit"));
|
|
177
180
|
console.log();
|
|
178
181
|
}
|
|
179
182
|
printAbout(pluginCount = 0, mcpInfo) {
|
|
@@ -217,12 +220,12 @@ var Renderer = class {
|
|
|
217
220
|
console.log(tool("spawn_agent", "Delegate to independent sub-agent (isolated dialog + auto tool-call loop)"));
|
|
218
221
|
console.log(tool("run_tests", "Run project tests and return structured report (auto-detect Maven/npm/pytest etc.)"));
|
|
219
222
|
console.log(HR);
|
|
220
|
-
console.log(theme.dim(" REPL Commands (
|
|
223
|
+
console.log(theme.dim(" REPL Commands (38):"));
|
|
221
224
|
console.log(theme.dim(" /help /about /provider /model /clear /compact /plan /session"));
|
|
222
225
|
console.log(theme.dim(" /system /context /status /search /undo /export /copy /paste"));
|
|
223
226
|
console.log(theme.dim(" /cost /init /skill /tools /plugins /mcp /config /checkpoint"));
|
|
224
|
-
console.log(theme.dim(" /review /commands /test /scaffold /add-dir /memory /
|
|
225
|
-
console.log(theme.dim(" /bug /think /diff /fork /yolo /exit"));
|
|
227
|
+
console.log(theme.dim(" /review /commands /test /scaffold /add-dir /memory /profile"));
|
|
228
|
+
console.log(theme.dim(" /doctor /bug /think /diff /fork /yolo /exit"));
|
|
226
229
|
console.log(HR);
|
|
227
230
|
console.log(theme.dim(" Key Features:"));
|
|
228
231
|
console.log(feat("Agentic loop (up to 25 tool-call rounds, final answer streamed)"));
|
|
@@ -233,6 +236,7 @@ var Renderer = class {
|
|
|
233
236
|
console.log(feat("File operation undo (/undo [list|<n>], supports write_file / edit_file / bash-created files/dirs)"));
|
|
234
237
|
console.log(feat("Thinking mode collapse (<think> blocks auto-collapsed, GLM-5 etc.)"));
|
|
235
238
|
console.log(feat("Token usage tracking (per-response + session cumulative, Gemini/Claude/DeepSeek etc.)"));
|
|
239
|
+
console.log(feat("User identity (/profile): persistent profile injected into every AI provider \u2014 AI knows who you are"));
|
|
236
240
|
console.log(feat("MCP protocol support: connect external MCP server tools (config.json mcpServers)"));
|
|
237
241
|
console.log(feat("Plugin system: ~/.aicli/plugins/*.js custom tools (requires allowPlugins:true, off by default)"));
|
|
238
242
|
console.log(feat("Plan Mode: /plan enters read-only planning, AI uses safe tools only, /plan execute resumes"));
|
|
@@ -350,7 +354,7 @@ var Renderer = class {
|
|
|
350
354
|
} catch (err) {
|
|
351
355
|
if (err?.name === "AbortError") {
|
|
352
356
|
interrupted = true;
|
|
353
|
-
flushBuf();
|
|
357
|
+
if (!inThinking) flushBuf();
|
|
354
358
|
} else {
|
|
355
359
|
throw err;
|
|
356
360
|
}
|
|
@@ -423,6 +427,9 @@ var Renderer = class {
|
|
|
423
427
|
process.stdout.write(theme.dim("\n\u{1F4AD} Thinking...\n"));
|
|
424
428
|
}
|
|
425
429
|
}
|
|
430
|
+
if (this.wrapWidth > 0) {
|
|
431
|
+
displayed = wrapText(displayed, this.wrapWidth);
|
|
432
|
+
}
|
|
426
433
|
const CHUNK_SIZE = 12;
|
|
427
434
|
const DELAY_MS = 8;
|
|
428
435
|
let pos = 0;
|
|
@@ -881,6 +888,7 @@ function createDefaultCommands() {
|
|
|
881
888
|
" /test [command|filter] - Run project tests and show structured report",
|
|
882
889
|
" /scaffold <description> - Generate project scaffolding with AI",
|
|
883
890
|
" /add-dir [path|remove] - Add/remove a directory from AI context",
|
|
891
|
+
" /profile [show|set|clear] - View or edit your identity (AI knows who you are)",
|
|
884
892
|
" /memory [show|add|clear] - View or edit persistent memory (memory.md)",
|
|
885
893
|
" /doctor - Health check (API keys, config, MCP status)",
|
|
886
894
|
" /bug [--copy] - Generate bug report template (--copy to clipboard)",
|
|
@@ -1038,11 +1046,18 @@ function createDefaultCommands() {
|
|
|
1038
1046
|
return;
|
|
1039
1047
|
}
|
|
1040
1048
|
const sessions = ctx.sessions.listSessions();
|
|
1041
|
-
const
|
|
1042
|
-
if (
|
|
1049
|
+
const matches = sessions.filter((s) => s.id.startsWith(id));
|
|
1050
|
+
if (matches.length === 0) {
|
|
1043
1051
|
ctx.renderer.renderError(`Session '${id}' not found.`);
|
|
1044
1052
|
return;
|
|
1045
1053
|
}
|
|
1054
|
+
if (matches.length > 1) {
|
|
1055
|
+
console.log(theme.warning(` \u26A0 Ambiguous prefix '${id}' matches ${matches.length} sessions \u2014 loading most recent:`));
|
|
1056
|
+
for (const m of matches.slice(0, 5)) {
|
|
1057
|
+
console.log(theme.dim(` ${m.id.slice(0, 12)} ${m.title ?? "(untitled)"}`));
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
const match = matches[0];
|
|
1046
1061
|
ctx.sessions.loadSession(match.id);
|
|
1047
1062
|
ctx.setProvider(match.provider, match.model);
|
|
1048
1063
|
ctx.resetSessionTokenUsage();
|
|
@@ -1155,7 +1170,8 @@ function createDefaultCommands() {
|
|
|
1155
1170
|
const estStr = fmtCtx(estimated);
|
|
1156
1171
|
const winStr = fmtCtx(ctxWindowSize);
|
|
1157
1172
|
const pctColor = pct >= 80 ? theme.error : pct >= 60 ? theme.warning : theme.success;
|
|
1158
|
-
|
|
1173
|
+
const pctDisplay = pct > 100 ? `${pct}% \u26A0 over limit` : `${pct}%`;
|
|
1174
|
+
console.log(` Context% : ~${estStr} / ${winStr} tokens (${pctColor(pctDisplay)})`);
|
|
1159
1175
|
}
|
|
1160
1176
|
console.log();
|
|
1161
1177
|
}
|
|
@@ -1821,7 +1837,8 @@ ${hint}` : "")
|
|
|
1821
1837
|
}
|
|
1822
1838
|
const ok = ctx.restoreCheckpoint(name);
|
|
1823
1839
|
if (ok) {
|
|
1824
|
-
|
|
1840
|
+
ctx.resetSessionTokenUsage();
|
|
1841
|
+
console.log(theme.success(` \u2713 Restored to checkpoint "${name}" (${session.messages.length} messages, token usage reset)`));
|
|
1825
1842
|
} else {
|
|
1826
1843
|
ctx.renderer.renderError(`Checkpoint "${name}" not found.`);
|
|
1827
1844
|
}
|
|
@@ -1925,17 +1942,21 @@ ${hint}` : "")
|
|
|
1925
1942
|
name: "test",
|
|
1926
1943
|
description: "Run project tests and show structured report",
|
|
1927
1944
|
usage: "/test [command|filter]",
|
|
1928
|
-
async execute(args,
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1945
|
+
async execute(args, ctx) {
|
|
1946
|
+
try {
|
|
1947
|
+
const { executeTests } = await import("./run-tests-ZTVEN2O7.js");
|
|
1948
|
+
const argStr = args.join(" ").trim();
|
|
1949
|
+
let testArgs = {};
|
|
1950
|
+
if (argStr) {
|
|
1951
|
+
const isCommand = argStr.includes(" ") || /^(mvn|gradle|npm|pytest|cargo|go)\b/.test(argStr);
|
|
1952
|
+
testArgs = isCommand ? { command: argStr } : { filter: argStr };
|
|
1953
|
+
}
|
|
1954
|
+
const report = await executeTests(testArgs);
|
|
1955
|
+
const firstLines = report.split("\n").slice(0, 3).join("\n");
|
|
1956
|
+
console.log(theme.dim(firstLines));
|
|
1957
|
+
} catch (err) {
|
|
1958
|
+
ctx.renderer.renderError(`Test execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1959
|
+
}
|
|
1939
1960
|
}
|
|
1940
1961
|
},
|
|
1941
1962
|
{
|
|
@@ -2017,6 +2038,64 @@ ${hint}` : "")
|
|
|
2017
2038
|
}
|
|
2018
2039
|
}
|
|
2019
2040
|
},
|
|
2041
|
+
// ── /profile ───────────────────────────────────────────────────────────────
|
|
2042
|
+
{
|
|
2043
|
+
name: "profile",
|
|
2044
|
+
description: 'View or edit your identity profile (the "soul" of AI)',
|
|
2045
|
+
usage: "/profile [show|edit|set <field> <value>|clear]",
|
|
2046
|
+
execute(args, ctx) {
|
|
2047
|
+
const sub = args[0] ?? "show";
|
|
2048
|
+
const profile = ctx.config.get("userProfile") ?? {};
|
|
2049
|
+
if (sub === "show" || sub === "view") {
|
|
2050
|
+
const hasProfile = profile.name || profile.nickname || profile.role;
|
|
2051
|
+
if (!hasProfile) {
|
|
2052
|
+
console.log(theme.dim("\n No profile configured yet. Use /profile edit or /config to set up.\n"));
|
|
2053
|
+
return;
|
|
2054
|
+
}
|
|
2055
|
+
console.log(theme.heading("\n\u{1F464} Your Profile\n") + theme.dim("\u2500".repeat(50)));
|
|
2056
|
+
if (profile.name) console.log(` ${theme.dim("Name:")} ${chalk2.white(profile.name)}`);
|
|
2057
|
+
if (profile.nickname) console.log(` ${theme.dim("Nickname:")} ${theme.accent(profile.nickname)}`);
|
|
2058
|
+
if (profile.role) console.log(` ${theme.dim("Role:")} ${chalk2.white(profile.role)}`);
|
|
2059
|
+
if (profile.bio) console.log(` ${theme.dim("Bio:")} ${chalk2.white(profile.bio)}`);
|
|
2060
|
+
if (profile.interests?.length) console.log(` ${theme.dim("Interests:")} ${chalk2.white(profile.interests.join(", "))}`);
|
|
2061
|
+
if (profile.locale) console.log(` ${theme.dim("Locale:")} ${chalk2.white(profile.locale)}`);
|
|
2062
|
+
if (profile.extra) console.log(` ${theme.dim("Extra:")} ${chalk2.white(profile.extra.slice(0, 80))}${profile.extra.length > 80 ? "\u2026" : ""}`);
|
|
2063
|
+
console.log(theme.dim("\u2500".repeat(50)));
|
|
2064
|
+
console.log(theme.dim(" This identity is injected into every AI conversation.\n"));
|
|
2065
|
+
} else if (sub === "edit") {
|
|
2066
|
+
ctx.renderer.printInfo("Use /config to open the interactive profile editor, or use:\n /profile set <field> <value>\n Fields: name, nickname, role, bio, interests, locale, extra");
|
|
2067
|
+
} else if (sub === "set") {
|
|
2068
|
+
const field = args[1];
|
|
2069
|
+
const value = args.slice(2).join(" ").trim();
|
|
2070
|
+
const validFields = ["name", "nickname", "role", "bio", "interests", "locale", "extra"];
|
|
2071
|
+
if (!field || !validFields.includes(field)) {
|
|
2072
|
+
ctx.renderer.printInfo(`Usage: /profile set <field> <value>
|
|
2073
|
+
Fields: ${validFields.join(", ")}`);
|
|
2074
|
+
return;
|
|
2075
|
+
}
|
|
2076
|
+
if (!value) {
|
|
2077
|
+
ctx.renderer.printInfo(`Usage: /profile set ${field} <value>`);
|
|
2078
|
+
return;
|
|
2079
|
+
}
|
|
2080
|
+
const updated = { ...profile };
|
|
2081
|
+
if (field === "interests") {
|
|
2082
|
+
updated.interests = value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
2083
|
+
} else {
|
|
2084
|
+
updated[field] = value;
|
|
2085
|
+
}
|
|
2086
|
+
ctx.config.set("userProfile", updated);
|
|
2087
|
+
ctx.config.save();
|
|
2088
|
+
const displayVal = field === "interests" ? updated.interests : value;
|
|
2089
|
+
ctx.renderer.printSuccess(`Profile updated: ${field} = ${JSON.stringify(displayVal)}`);
|
|
2090
|
+
} else if (sub === "clear") {
|
|
2091
|
+
ctx.config.set("userProfile", {});
|
|
2092
|
+
ctx.config.save();
|
|
2093
|
+
ctx.renderer.printSuccess("Profile cleared. AI will no longer know who you are.");
|
|
2094
|
+
} else {
|
|
2095
|
+
ctx.renderer.printInfo("Usage: /profile [show|edit|set <field> <value>|clear]");
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
},
|
|
2020
2099
|
// ── /memory ────────────────────────────────────────────────────────────────
|
|
2021
2100
|
{
|
|
2022
2101
|
name: "memory",
|
|
@@ -2993,8 +3072,10 @@ var SetupWizard = class {
|
|
|
2993
3072
|
}
|
|
2994
3073
|
async runFirstRun() {
|
|
2995
3074
|
console.log(theme.heading("\nWelcome to ai-cli!\n"));
|
|
2996
|
-
console.log("Let's set up your
|
|
3075
|
+
console.log("Let's get to know you first, then set up your AI provider.\n");
|
|
2997
3076
|
try {
|
|
3077
|
+
await this.setupProfile();
|
|
3078
|
+
console.log();
|
|
2998
3079
|
const providerId = await select({
|
|
2999
3080
|
message: "Which AI provider do you want to set up first?",
|
|
3000
3081
|
choices: PROVIDERS
|
|
@@ -3002,7 +3083,11 @@ var SetupWizard = class {
|
|
|
3002
3083
|
await this.setupProvider(providerId);
|
|
3003
3084
|
this.config.set("defaultProvider", providerId);
|
|
3004
3085
|
this.config.save();
|
|
3005
|
-
|
|
3086
|
+
const nickname = this.config.get("userProfile")?.nickname;
|
|
3087
|
+
const greeting = nickname ? `Setup complete, ${nickname}!` : "Setup complete!";
|
|
3088
|
+
console.log(theme.success(`
|
|
3089
|
+
${greeting} Starting ai-cli...
|
|
3090
|
+
`));
|
|
3006
3091
|
return true;
|
|
3007
3092
|
} catch {
|
|
3008
3093
|
return false;
|
|
@@ -3015,9 +3100,12 @@ var SetupWizard = class {
|
|
|
3015
3100
|
const currentProxy = this.config.get("proxy") ?? "";
|
|
3016
3101
|
const proxyStatus = currentProxy ? theme.success(`[${currentProxy}]`) : theme.dim("[not configured]");
|
|
3017
3102
|
const googleKeyStatus = this.config.getApiKey("google-search") ? theme.success("[configured]") : theme.dim("[not configured]");
|
|
3103
|
+
const profileName = this.config.get("userProfile")?.nickname || this.config.get("userProfile")?.name;
|
|
3104
|
+
const profileStatus = profileName ? theme.success(`[${profileName}]`) : theme.dim("[not configured]");
|
|
3018
3105
|
const action = await select({
|
|
3019
3106
|
message: "What would you like to configure?",
|
|
3020
3107
|
choices: [
|
|
3108
|
+
{ value: "profile", name: `Edit your profile (identity) ${profileStatus}` },
|
|
3021
3109
|
{ value: "apikey", name: "Manage API key for a provider" },
|
|
3022
3110
|
{ value: "default", name: "Change default provider" },
|
|
3023
3111
|
{ value: "proxy", name: `Configure proxy (HTTP/HTTPS) ${proxyStatus}` },
|
|
@@ -3025,7 +3113,9 @@ var SetupWizard = class {
|
|
|
3025
3113
|
{ value: "done", name: "Done" }
|
|
3026
3114
|
]
|
|
3027
3115
|
});
|
|
3028
|
-
if (action === "
|
|
3116
|
+
if (action === "profile") {
|
|
3117
|
+
await this.setupProfile();
|
|
3118
|
+
} else if (action === "proxy") {
|
|
3029
3119
|
await this.setupProxy();
|
|
3030
3120
|
} else if (action === "google") {
|
|
3031
3121
|
await this.setupGoogleSearch();
|
|
@@ -3198,6 +3288,50 @@ Managing ${displayName} API Key`);
|
|
|
3198
3288
|
}
|
|
3199
3289
|
console.log();
|
|
3200
3290
|
}
|
|
3291
|
+
/** 收集用户身份档案 — aicli 的 "灵魂" 功能 */
|
|
3292
|
+
async setupProfile() {
|
|
3293
|
+
const existing = this.config.get("userProfile") ?? {};
|
|
3294
|
+
console.log(theme.heading("\n\u{1F464} Your Profile"));
|
|
3295
|
+
console.log(theme.dim(" This helps AI know who you are \u2014 across all providers and sessions.\n"));
|
|
3296
|
+
const name = await input({
|
|
3297
|
+
message: "Your name:",
|
|
3298
|
+
default: existing.name || void 0
|
|
3299
|
+
});
|
|
3300
|
+
const nickname = await input({
|
|
3301
|
+
message: "Preferred nickname (AI will call you this):",
|
|
3302
|
+
default: existing.nickname || void 0
|
|
3303
|
+
});
|
|
3304
|
+
const role = await input({
|
|
3305
|
+
message: 'Your role (e.g. "Full-stack developer", "Student"):',
|
|
3306
|
+
default: existing.role || void 0
|
|
3307
|
+
});
|
|
3308
|
+
const bio = await input({
|
|
3309
|
+
message: "Brief intro (1-2 sentences about your background):",
|
|
3310
|
+
default: existing.bio || void 0
|
|
3311
|
+
});
|
|
3312
|
+
const interestsStr = await input({
|
|
3313
|
+
message: "Interests / tech stack (comma-separated):",
|
|
3314
|
+
default: existing.interests?.join(", ") || void 0
|
|
3315
|
+
});
|
|
3316
|
+
const locale = await input({
|
|
3317
|
+
message: 'Preferred language (e.g. "zh-CN", "en", "ja"):',
|
|
3318
|
+
default: existing.locale || void 0
|
|
3319
|
+
});
|
|
3320
|
+
const profile = {};
|
|
3321
|
+
if (name) profile.name = name;
|
|
3322
|
+
if (nickname) profile.nickname = nickname;
|
|
3323
|
+
if (role) profile.role = role;
|
|
3324
|
+
if (bio) profile.bio = bio;
|
|
3325
|
+
if (interestsStr) profile.interests = interestsStr.split(",").map((s) => s.trim()).filter(Boolean);
|
|
3326
|
+
if (locale) profile.locale = locale;
|
|
3327
|
+
if (existing.extra) profile.extra = existing.extra;
|
|
3328
|
+
this.config.set("userProfile", profile);
|
|
3329
|
+
this.config.save();
|
|
3330
|
+
const displayName = nickname || name || "User";
|
|
3331
|
+
console.log(theme.success(`
|
|
3332
|
+
Profile saved! AI will know you as "${displayName}".
|
|
3333
|
+
`));
|
|
3334
|
+
}
|
|
3201
3335
|
};
|
|
3202
3336
|
|
|
3203
3337
|
// src/repl/custom-commands.ts
|
|
@@ -3857,7 +3991,15 @@ You have a maximum of ${MAX_TOOL_ROUNDS} tool call rounds per conversation turn.
|
|
|
3857
3991
|
- On Windows, use PowerShell cmdlets (Invoke-RestMethod, Get-ChildItem) instead of Unix commands (curl, grep, find).
|
|
3858
3992
|
- If starting a long-running server process via bash, use background execution \u2014 do not block the tool round.
|
|
3859
3993
|
- Prioritize the most critical tasks first in case you run out of rounds.`;
|
|
3860
|
-
const parts = [dateTimeInfo + "\n" + envInfo
|
|
3994
|
+
const parts = [dateTimeInfo + "\n" + envInfo];
|
|
3995
|
+
const userProfile = this.config.get("userProfile");
|
|
3996
|
+
if (userProfile) {
|
|
3997
|
+
const identityPrompt = buildUserIdentityPrompt(userProfile);
|
|
3998
|
+
if (identityPrompt) {
|
|
3999
|
+
parts.push(identityPrompt);
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
4002
|
+
parts.push(AGENTIC_BEHAVIOR_GUIDELINE + budgetInfo);
|
|
3861
4003
|
const memory = this.loadMemoryContent();
|
|
3862
4004
|
if (memory) {
|
|
3863
4005
|
parts.push(`# Persistent Memory
|
|
@@ -4097,7 +4239,8 @@ Session '${this.resumeSessionId}' not found.
|
|
|
4097
4239
|
const pluginCount = await this.toolRegistry.loadPlugins(this.config.getPluginsDir(), allowPlugins);
|
|
4098
4240
|
const welcomeProvider = this.providers.get(this.currentProvider);
|
|
4099
4241
|
const welcomeModelInfo = welcomeProvider?.info.models.find((m) => m.id === this.currentModel);
|
|
4100
|
-
this.
|
|
4242
|
+
const profileNickname = this.config.get("userProfile")?.nickname || this.config.get("userProfile")?.name;
|
|
4243
|
+
this.renderer.printWelcome(this.currentProvider, this.currentModel, welcomeModelInfo?.contextWindow, profileNickname);
|
|
4101
4244
|
if (welcomeModelInfo?.contextWindow) setContextWindow(welcomeModelInfo.contextWindow);
|
|
4102
4245
|
if (this.resumeSessionId) {
|
|
4103
4246
|
const session = this.sessions.current;
|
|
@@ -5548,7 +5691,7 @@ program.command("web").description("Start Web UI server with browser-based chat
|
|
|
5548
5691
|
console.error("Error: Invalid port number. Must be between 1 and 65535.");
|
|
5549
5692
|
process.exit(1);
|
|
5550
5693
|
}
|
|
5551
|
-
const { startWebServer } = await import("./server-
|
|
5694
|
+
const { startWebServer } = await import("./server-IDPMZAUF.js");
|
|
5552
5695
|
await startWebServer({ port, host: options.host });
|
|
5553
5696
|
});
|
|
5554
5697
|
program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
|
|
@@ -5781,7 +5924,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
5781
5924
|
}),
|
|
5782
5925
|
config.get("customProviders")
|
|
5783
5926
|
);
|
|
5784
|
-
const { startHub } = await import("./hub-
|
|
5927
|
+
const { startHub } = await import("./hub-CNSFX47B.js");
|
|
5785
5928
|
await startHub(
|
|
5786
5929
|
{
|
|
5787
5930
|
topic: topic ?? "",
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
renderDiff,
|
|
19
19
|
runHook,
|
|
20
20
|
setupProxy
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-7T2W4LN3.js";
|
|
22
22
|
import {
|
|
23
23
|
AuthManager
|
|
24
24
|
} from "./chunk-BYNY5JPB.js";
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
spawnAgentContext,
|
|
33
33
|
truncateOutput,
|
|
34
34
|
undoStack
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-2JOMWVTE.js";
|
|
36
36
|
import {
|
|
37
37
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
38
38
|
AUTHOR,
|
|
@@ -48,8 +48,9 @@ import {
|
|
|
48
48
|
PLAN_MODE_SYSTEM_ADDON,
|
|
49
49
|
PLUGINS_DIR_NAME,
|
|
50
50
|
SKILLS_DIR_NAME,
|
|
51
|
-
VERSION
|
|
52
|
-
|
|
51
|
+
VERSION,
|
|
52
|
+
buildUserIdentityPrompt
|
|
53
|
+
} from "./chunk-AR656G5C.js";
|
|
53
54
|
|
|
54
55
|
// src/web/server.ts
|
|
55
56
|
import express from "express";
|
|
@@ -396,7 +397,14 @@ function buildSystemPrompt(ctx) {
|
|
|
396
397
|
const envInfo = `OS: ${osName}
|
|
397
398
|
${shellInfo}
|
|
398
399
|
Working directory: ${process.cwd()}`;
|
|
399
|
-
const parts = [dateTimeInfo + "\n" + envInfo
|
|
400
|
+
const parts = [dateTimeInfo + "\n" + envInfo];
|
|
401
|
+
if (ctx.userProfile) {
|
|
402
|
+
const identityPrompt = buildUserIdentityPrompt(ctx.userProfile);
|
|
403
|
+
if (identityPrompt) {
|
|
404
|
+
parts.push(identityPrompt);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
parts.push(AGENTIC_BEHAVIOR_GUIDELINE);
|
|
400
408
|
if (ctx.configDir) {
|
|
401
409
|
const memory = loadMemoryContent(ctx.configDir);
|
|
402
410
|
if (memory) {
|
|
@@ -1490,7 +1498,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
1490
1498
|
case "test": {
|
|
1491
1499
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
1492
1500
|
try {
|
|
1493
|
-
const { executeTests } = await import("./run-tests-
|
|
1501
|
+
const { executeTests } = await import("./run-tests-ZTVEN2O7.js");
|
|
1494
1502
|
const argStr = args.join(" ").trim();
|
|
1495
1503
|
let testArgs = {};
|
|
1496
1504
|
if (argStr) {
|
|
@@ -2041,7 +2049,8 @@ Add .md files to create commands.` });
|
|
|
2041
2049
|
activeSystemPrompt: this.activeSystemPrompt,
|
|
2042
2050
|
activeSkill,
|
|
2043
2051
|
planMode: this.planMode,
|
|
2044
|
-
configDir: this.config.getConfigDir()
|
|
2052
|
+
configDir: this.config.getConfigDir(),
|
|
2053
|
+
userProfile: this.config.get("userProfile")
|
|
2045
2054
|
});
|
|
2046
2055
|
if (this.addedDirs.size > 0) {
|
|
2047
2056
|
const MAX_DIR_CONTEXT = 4e4;
|
|
@@ -4,10 +4,10 @@ import {
|
|
|
4
4
|
getDangerLevel,
|
|
5
5
|
googleSearchContext,
|
|
6
6
|
truncateOutput
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-2JOMWVTE.js";
|
|
8
8
|
import {
|
|
9
9
|
SUBAGENT_ALLOWED_TOOLS
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-AR656G5C.js";
|
|
11
11
|
|
|
12
12
|
// src/hub/task-orchestrator.ts
|
|
13
13
|
import { createInterface } from "readline";
|