closer-code 1.0.0
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/.env.example +83 -0
- package/API_GUIDE.md +1411 -0
- package/AUTO_MKDIR_IMPROVEMENT.md +354 -0
- package/CLAUDE.md +55 -0
- package/CTRL_C_EXPERIMENT.md +90 -0
- package/PROJECT_CLEANUP_SUMMARY.md +121 -0
- package/README.md +686 -0
- package/cloco.md +51 -0
- package/config.example.json +116 -0
- package/dist/bash-runner.js +128 -0
- package/dist/batch-cli.js +20736 -0
- package/dist/closer-cli.js +21190 -0
- package/dist/index.js +31228 -0
- package/docs/EXPORT_COMMAND.md +152 -0
- package/docs/FILE_NAMING_IMPROVEMENT.md +168 -0
- package/docs/GLOBAL_CONFIG.md +128 -0
- package/docs/LONG_MESSAGE_DISPLAY_FIX.md +202 -0
- package/docs/PROJECT_HISTORY_ISOLATION.md +315 -0
- package/docs/QUICK_START_HISTORY.md +207 -0
- package/docs/TASK_PROGRESS_FEATURE.md +190 -0
- package/docs/THINKING_CONTENT_RESEARCH.md +267 -0
- package/docs/THINKING_FEATURE.md +187 -0
- package/docs/THINKING_IMPROVEMENT_COMPARISON.md +193 -0
- package/docs/THINKING_OPTIMIZATION_SUMMARY.md +242 -0
- package/docs/UI_IMPROVEMENTS_2025-01-18.md +256 -0
- package/docs/WHY_THINKING_SHORT.md +201 -0
- package/package.json +49 -0
- package/scenarios/README.md +234 -0
- package/scenarios/run-all-scenarios.js +342 -0
- package/scenarios/scenario1-batch-converter.js +247 -0
- package/scenarios/scenario2-code-analyzer.js +375 -0
- package/scenarios/scenario3-doc-generator.js +371 -0
- package/scenarios/scenario4-log-analyzer.js +496 -0
- package/scenarios/scenario5-tdd-helper.js +681 -0
- package/src/ai-client-legacy.js +171 -0
- package/src/ai-client.js +221 -0
- package/src/bash-runner.js +148 -0
- package/src/batch-cli.js +327 -0
- package/src/cli.jsx +166 -0
- package/src/closer-cli.jsx +1103 -0
- package/src/closer-cli.jsx.backup +948 -0
- package/src/commands/batch.js +62 -0
- package/src/commands/chat.js +10 -0
- package/src/commands/config.js +154 -0
- package/src/commands/help.js +76 -0
- package/src/commands/history.js +192 -0
- package/src/commands/setup.js +17 -0
- package/src/commands/upgrade.js +101 -0
- package/src/commands/workflow-tests.js +125 -0
- package/src/config.js +343 -0
- package/src/conversation.js +962 -0
- package/src/git-helper.js +349 -0
- package/src/index.js +88 -0
- package/src/logger.js +347 -0
- package/src/plan.js +193 -0
- package/src/planner.js +397 -0
- package/src/search.js +195 -0
- package/src/setup.js +147 -0
- package/src/shortcuts.js +269 -0
- package/src/snippets.js +430 -0
- package/src/test-modules.js +118 -0
- package/src/tools.js +398 -0
- package/src/utils/cli.js +124 -0
- package/src/utils/validator.js +184 -0
- package/src/utils/version.js +33 -0
- package/src/utils/workflow-test.js +271 -0
- package/src/utils/workflow.js +268 -0
- package/test/demo-file-naming.js +92 -0
- package/test/demo-thinking.js +124 -0
- package/test/final-verification-report.md +303 -0
- package/test/research-thinking.js +130 -0
- package/test/test-auto-mkdir.js +123 -0
- package/test/test-e2e-empty-dir.md +108 -0
- package/test/test-export-logic.js +119 -0
- package/test/test-global-cloco.js +126 -0
- package/test/test-history-isolation.js +291 -0
- package/test/test-improved-thinking.js +43 -0
- package/test/test-long-message.js +65 -0
- package/test/test-plan-functionality.js +95 -0
- package/test/test-real-scenario.js +216 -0
- package/test/test-thinking-display.js +65 -0
- package/test/ui-verification-test.js +203 -0
- package/test/verify-history-isolation.sh +71 -0
- package/test/verify-thinking.js +339 -0
- package/test/workflows/empty-dir-creation.md +51 -0
- package/test/workflows/inventor/ascii-teacup.js +199 -0
- package/test/workflows/inventor/ascii-teacup.mjs +199 -0
- package/test/workflows/inventor/ascii_apple.hs +84 -0
- package/test/workflows/inventor/ascii_apple.py +91 -0
- package/test/workflows/inventor/cloco.md +3 -0
- package/test/workflows/longtalk/cloco.md +19 -0
- package/test/workflows/longtalk/emoji_500.txt +63 -0
- package/test/workflows/longtalk/emoji_list.txt +20 -0
- package/test/workflows/programmer/adder.md +33 -0
- package/test/workflows/programmer/expect.md +2 -0
- package/test/workflows/programmer/prompt.md +3 -0
- package/test/workflows/test-empty-dir-creation.js +113 -0
- package/test-ctrl-c.jsx +126 -0
- package/test-manual-file-creation.js +151 -0
- package/winfix.md +3 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Closer Code 配置示例
|
|
2
|
+
|
|
3
|
+
# 将此文件复制到 ~/.closer-code/config.json 并根据需要修改
|
|
4
|
+
|
|
5
|
+
{
|
|
6
|
+
# AI 提供商配置
|
|
7
|
+
"ai": {
|
|
8
|
+
# 选择提供商: "anthropic", "openai", 或 "ollama"
|
|
9
|
+
"provider": "anthropic",
|
|
10
|
+
|
|
11
|
+
# Anthropic Claude 配置
|
|
12
|
+
"anthropic": {
|
|
13
|
+
# API 密钥 (也可以通过 ANTHROPIC_API_KEY 环境变量设置)
|
|
14
|
+
"apiKey": "",
|
|
15
|
+
|
|
16
|
+
# API 基础 URL
|
|
17
|
+
"baseURL": "https://api.anthropic.com",
|
|
18
|
+
|
|
19
|
+
# 使用的模型
|
|
20
|
+
"model": "claude-sonnet-4-5-20250929",
|
|
21
|
+
|
|
22
|
+
# 最大 token 数
|
|
23
|
+
"maxTokens": 8192
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
# OpenAI 配置
|
|
27
|
+
"openai": {
|
|
28
|
+
# API 密钥 (也可以通过 OPENAI_API_KEY 环境变量设置)
|
|
29
|
+
"apiKey": "",
|
|
30
|
+
|
|
31
|
+
# API 基础 URL
|
|
32
|
+
"baseURL": "https://api.openai.com/v1",
|
|
33
|
+
|
|
34
|
+
# 使用的模型
|
|
35
|
+
"model": "gpt-4o",
|
|
36
|
+
|
|
37
|
+
# 最大 token 数
|
|
38
|
+
"maxTokens": 4096
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
# Ollama (本地运行) 配置
|
|
42
|
+
"ollama": {
|
|
43
|
+
# Ollama 服务地址
|
|
44
|
+
"baseURL": "http://localhost:11434",
|
|
45
|
+
|
|
46
|
+
# 使用的模型
|
|
47
|
+
"model": "llama3.1",
|
|
48
|
+
|
|
49
|
+
# 最大 token 数
|
|
50
|
+
"maxTokens": 4096
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
# 行为配置
|
|
55
|
+
"behavior": {
|
|
56
|
+
# 自动规划任务
|
|
57
|
+
"autoPlan": true,
|
|
58
|
+
|
|
59
|
+
# 自动执行低风险操作
|
|
60
|
+
"autoExecute": false,
|
|
61
|
+
|
|
62
|
+
# 危险操作需要确认
|
|
63
|
+
"confirmDestructive": true,
|
|
64
|
+
|
|
65
|
+
# 失败重试次数
|
|
66
|
+
"maxRetries": 3,
|
|
67
|
+
|
|
68
|
+
# 操作超时时间 (毫秒)
|
|
69
|
+
"timeout": 30000,
|
|
70
|
+
|
|
71
|
+
# 默认工作目录
|
|
72
|
+
"workingDir": "/path/to/your/project"
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
# 工具配置
|
|
76
|
+
"tools": {
|
|
77
|
+
# 启用的工具列表
|
|
78
|
+
"enabled": [
|
|
79
|
+
"bash", # 执行 shell 命令
|
|
80
|
+
"readFile", # 读取文件
|
|
81
|
+
"writeFile", # 写入文件
|
|
82
|
+
"editFile", # 编辑文件
|
|
83
|
+
"searchFiles", # 搜索文件
|
|
84
|
+
"searchCode", # 搜索代码
|
|
85
|
+
"listFiles", # 列出文件
|
|
86
|
+
"analyzeError", # 分析错误
|
|
87
|
+
"runTests", # 运行测试
|
|
88
|
+
"planTask" # 规划任务
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
# UI 配置
|
|
93
|
+
"ui": {
|
|
94
|
+
# 主题: "default", "dark", "light"
|
|
95
|
+
"theme": "default",
|
|
96
|
+
|
|
97
|
+
# 显示行号
|
|
98
|
+
"showLineNumbers": true,
|
|
99
|
+
|
|
100
|
+
# 最大输出行数
|
|
101
|
+
"maxOutputLines": 100,
|
|
102
|
+
|
|
103
|
+
# 自动滚动
|
|
104
|
+
"autoScroll": true
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# 使用方法:
|
|
109
|
+
# 1. 创建配置目录
|
|
110
|
+
# mkdir -p ~/.closer-code
|
|
111
|
+
#
|
|
112
|
+
# 2. 复制此文件到配置目录
|
|
113
|
+
# cp config.example.json ~/.closer-code/config.json
|
|
114
|
+
#
|
|
115
|
+
# 3. 编辑配置文件,填入你的 API 密钥和偏好设置
|
|
116
|
+
# nano ~/.closer-code/config.json
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// src/bash-runner.js
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
function executeBashCommand(command, options = {}) {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
5
|
+
const {
|
|
6
|
+
shell = "bash",
|
|
7
|
+
cwd = process.cwd(),
|
|
8
|
+
env = process.env,
|
|
9
|
+
timeout = 3e4
|
|
10
|
+
} = options;
|
|
11
|
+
const bashProcess = spawn(shell, ["-c", command], {
|
|
12
|
+
cwd,
|
|
13
|
+
env,
|
|
14
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
15
|
+
});
|
|
16
|
+
let stdout = "";
|
|
17
|
+
let stderr = "";
|
|
18
|
+
let timer = null;
|
|
19
|
+
if (timeout > 0) {
|
|
20
|
+
timer = setTimeout(() => {
|
|
21
|
+
bashProcess.kill("SIGTERM");
|
|
22
|
+
reject(new BashResult({
|
|
23
|
+
command,
|
|
24
|
+
stdout,
|
|
25
|
+
stderr,
|
|
26
|
+
exitCode: null,
|
|
27
|
+
signal: "SIGTERM",
|
|
28
|
+
timedOut: true,
|
|
29
|
+
error: `Command timed out after ${timeout}ms`
|
|
30
|
+
}));
|
|
31
|
+
}, timeout);
|
|
32
|
+
}
|
|
33
|
+
bashProcess.stdout.on("data", (data) => {
|
|
34
|
+
stdout += data.toString();
|
|
35
|
+
});
|
|
36
|
+
bashProcess.stderr.on("data", (data) => {
|
|
37
|
+
stderr += data.toString();
|
|
38
|
+
});
|
|
39
|
+
bashProcess.on("close", (code, signal) => {
|
|
40
|
+
if (timer)
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
const result = new BashResult({
|
|
43
|
+
command,
|
|
44
|
+
stdout,
|
|
45
|
+
stderr,
|
|
46
|
+
exitCode: code,
|
|
47
|
+
signal,
|
|
48
|
+
timedOut: false
|
|
49
|
+
});
|
|
50
|
+
resolve(result);
|
|
51
|
+
});
|
|
52
|
+
bashProcess.on("error", (error) => {
|
|
53
|
+
if (timer)
|
|
54
|
+
clearTimeout(timer);
|
|
55
|
+
reject(new BashResult({
|
|
56
|
+
command,
|
|
57
|
+
stdout,
|
|
58
|
+
stderr,
|
|
59
|
+
exitCode: null,
|
|
60
|
+
error: error.message
|
|
61
|
+
}));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
var BashResult = class {
|
|
66
|
+
constructor({
|
|
67
|
+
command,
|
|
68
|
+
stdout = "",
|
|
69
|
+
stderr = "",
|
|
70
|
+
exitCode = null,
|
|
71
|
+
signal = null,
|
|
72
|
+
timedOut = false,
|
|
73
|
+
error = null
|
|
74
|
+
}) {
|
|
75
|
+
this.command = command;
|
|
76
|
+
this.stdout = stdout;
|
|
77
|
+
this.stderr = stderr;
|
|
78
|
+
this.exitCode = exitCode;
|
|
79
|
+
this.signal = signal;
|
|
80
|
+
this.timedOut = timedOut;
|
|
81
|
+
this.error = error;
|
|
82
|
+
this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
83
|
+
}
|
|
84
|
+
/** 是否成功执行(退出码为0) */
|
|
85
|
+
get success() {
|
|
86
|
+
return this.exitCode === 0 && !this.error && !this.timedOut;
|
|
87
|
+
}
|
|
88
|
+
/** 获取完整的输出(stdout + stderr) */
|
|
89
|
+
get output() {
|
|
90
|
+
return this.stdout + this.stderr;
|
|
91
|
+
}
|
|
92
|
+
/** 转换为 JSON 格式 */
|
|
93
|
+
toJSON() {
|
|
94
|
+
return {
|
|
95
|
+
command: this.command,
|
|
96
|
+
stdout: this.stdout,
|
|
97
|
+
stderr: this.stderr,
|
|
98
|
+
exitCode: this.exitCode,
|
|
99
|
+
signal: this.signal,
|
|
100
|
+
success: this.success,
|
|
101
|
+
timedOut: this.timedOut,
|
|
102
|
+
error: this.error,
|
|
103
|
+
timestamp: this.timestamp
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** 格式化输出 */
|
|
107
|
+
toString() {
|
|
108
|
+
const parts = [];
|
|
109
|
+
parts.push(`Command: ${this.command}`);
|
|
110
|
+
parts.push(`Exit Code: ${this.exitCode}`);
|
|
111
|
+
if (this.stdout)
|
|
112
|
+
parts.push(`
|
|
113
|
+
Stdout:
|
|
114
|
+
${this.stdout}`);
|
|
115
|
+
if (this.stderr)
|
|
116
|
+
parts.push(`
|
|
117
|
+
Stderr:
|
|
118
|
+
${this.stderr}`);
|
|
119
|
+
if (this.error)
|
|
120
|
+
parts.push(`
|
|
121
|
+
Error: ${this.error}`);
|
|
122
|
+
return parts.join("\n");
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
export {
|
|
126
|
+
BashResult,
|
|
127
|
+
executeBashCommand
|
|
128
|
+
};
|