@unity-china/codely-cli 1.0.0-beta.32 → 1.0.0-beta.34
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 +12 -4
- package/README.zh-CN.md +335 -0
- package/bundle/gemini.js +310 -56
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@unity-china/codely-cli)
|
|
8
8
|
[](./LICENSE)
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
|
|
12
12
|
**AI-powered command-line workflow tool for developers**
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
🌐 [Official Website](https://codely.tuanjie.cn/) • 📖 [Documentation](https://yousandi.feishu.cn/wiki/Sqmlw31sYiTm8qkh7s1cSlbenmb) • 🇨🇳 [中文文档](./README.zh-CN.md)
|
|
15
|
+
|
|
16
|
+
[Installation](#installation) • [Quick Start](#quick-start) • [Features](#key-features)
|
|
15
17
|
|
|
16
18
|
</div>
|
|
17
19
|
|
|
@@ -21,6 +23,10 @@
|
|
|
21
23
|
- **Workflow Automation** - Automate operational tasks like handling pull requests and complex rebases
|
|
22
24
|
- **AI Agent System** - Specialized intelligent agents for deep codebase analysis and automated tasks
|
|
23
25
|
- **MCP Integration** - Extend capabilities with Model Context Protocol servers for external tools and services
|
|
26
|
+
- **Unity Integration** - Direct integration with Unity/Tuanjie Engine for game development tasks
|
|
27
|
+
- **Screenshot Analysis** - Analyze screenshots and images to understand UI/UX and extract information
|
|
28
|
+
- **Sandboxing** - Secure execution environment with multiple sandboxing modes
|
|
29
|
+
- **IDE Plugin** - VS Code extension for seamless integration
|
|
24
30
|
|
|
25
31
|
## 🤖 AI Agent System
|
|
26
32
|
|
|
@@ -314,9 +320,11 @@ Remove an MCP server with the specified name.
|
|
|
314
320
|
|
|
315
321
|
## Troubleshooting
|
|
316
322
|
|
|
317
|
-
If you encounter issues, check the
|
|
323
|
+
If you encounter issues, please check the error messages and ensure:
|
|
324
|
+
- Node.js version is 20 or higher
|
|
325
|
+
- All dependencies are properly installed
|
|
326
|
+
- API keys are correctly configured in settings
|
|
318
327
|
|
|
319
328
|
## License
|
|
320
329
|
|
|
321
330
|
[LICENSE](./LICENSE)
|
|
322
|
-
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# Codely CLI
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@unity-china/codely-cli)
|
|
8
|
+
[](./LICENSE)
|
|
9
|
+
[](https://nodejs.org/)
|
|
10
|
+
[](https://www.npmjs.com/package/@unity-china/codely-cli)
|
|
11
|
+
|
|
12
|
+
**面向开发者的 AI 驱动命令行工作流工具**
|
|
13
|
+
|
|
14
|
+
🌐 [官方网站](https://codely.tuanjie.cn/) • 📖 [使用手册](https://yousandi.feishu.cn/wiki/Sqmlw31sYiTm8qkh7s1cSlbenmb) • 🇺🇸 [English](./README.md)
|
|
15
|
+
|
|
16
|
+
[安装](#安装) • [快速开始](#快速开始) • [核心功能](#核心功能)
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
## 核心功能
|
|
21
|
+
|
|
22
|
+
- **代码理解与编辑** - 查询和编辑超出传统上下文窗口限制的大型代码库
|
|
23
|
+
- **工作流自动化** - 自动化处理拉取请求和复杂变基等操作任务
|
|
24
|
+
- **AI 智能体系统** - 专业的智能代理,用于深度代码库分析和自动化任务
|
|
25
|
+
- **MCP 集成** - 通过模型上下文协议服务器扩展外部工具和服务能力
|
|
26
|
+
- **Unity 集成** - 与 Unity/团结引擎直接集成,支持游戏开发任务
|
|
27
|
+
- **截图分析** - 分析截图和图像以理解 UI/UX 并提取信息
|
|
28
|
+
- **沙箱环境** - 多种沙箱模式的安全执行环境
|
|
29
|
+
- **IDE 插件** - VS Code 扩展实现无缝集成
|
|
30
|
+
|
|
31
|
+
## 🤖 AI 智能体系统
|
|
32
|
+
|
|
33
|
+
Codely CLI 包含强大的智能体系统,提供专业的 AI 助手处理复杂的开发任务:
|
|
34
|
+
|
|
35
|
+
### 智能体使用
|
|
36
|
+
|
|
37
|
+
**交互模式**(智能体自动调用):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
codely
|
|
41
|
+
> 分析这个 React 项目的组件架构并识别性能瓶颈
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**非交互模式**支持不同的输出格式:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# 标准文本输出
|
|
48
|
+
codely --prompt "分析 API 端点和安全措施"
|
|
49
|
+
|
|
50
|
+
# JSON 输出用于自动化
|
|
51
|
+
codely --output-format json --prompt "调查代码库结构" > analysis.json
|
|
52
|
+
|
|
53
|
+
# 流式 JSON 用于实时监控
|
|
54
|
+
codely --output-format stream-json --prompt "记录数据流" | jq '.type == "agent_think"'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 智能体管理
|
|
58
|
+
|
|
59
|
+
**列出可用的智能体:**
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
/agents list
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**创建自定义智能体:**
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# 项目级别智能体
|
|
69
|
+
/agents create security-auditor
|
|
70
|
+
|
|
71
|
+
# 全局智能体
|
|
72
|
+
/agents create my-helper --global
|
|
73
|
+
|
|
74
|
+
# 带自定义描述
|
|
75
|
+
/agents create api-analyzer "分析 API 端点和文档"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**智能体位置:**
|
|
79
|
+
|
|
80
|
+
- **项目智能体**:`.codely-cli/agents/`(与团队共享)
|
|
81
|
+
- **全局智能体**:`~/.codely-cli/agents/`(个人使用)
|
|
82
|
+
|
|
83
|
+
### 智能体输出示例
|
|
84
|
+
|
|
85
|
+
智能体提供结构化的完整结果:
|
|
86
|
+
|
|
87
|
+
**交互式进度:**
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
🚀 委派给 codebase_investigator 子智能体...
|
|
91
|
+
🔧 [1] 列出目录 - 扫描项目结构
|
|
92
|
+
✅ 列出目录完成 - 找到 45 个目录
|
|
93
|
+
🤖💭 正在分析 package.json 依赖...
|
|
94
|
+
🔧 [2] 读取文件 - package.json
|
|
95
|
+
✅ 读取文件完成 - 分析依赖中
|
|
96
|
+
📋 结果:
|
|
97
|
+
{
|
|
98
|
+
"SummaryOfFindings": "React 应用采用三层架构...",
|
|
99
|
+
"ExplorationTrace": ["分析项目结构", "检查路由"],
|
|
100
|
+
"RelevantLocations": ["src/components/App.tsx", "src/api/routes.ts"]
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 安装
|
|
105
|
+
|
|
106
|
+
### 前置要求
|
|
107
|
+
|
|
108
|
+
确保已安装 [Node.js 20](https://nodejs.org/en/download) 或更高版本。
|
|
109
|
+
|
|
110
|
+
### 直接安装
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npm i -g @unity-china/codely-cli
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## 快速开始
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# 启动
|
|
120
|
+
codely
|
|
121
|
+
|
|
122
|
+
# 示例命令
|
|
123
|
+
> 解释这个代码库结构
|
|
124
|
+
> 帮我重构这个函数
|
|
125
|
+
> 为这个模块生成单元测试
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 会话管理
|
|
129
|
+
|
|
130
|
+
通过可配置的会话限制控制您的 token 使用量,以优化成本和性能。
|
|
131
|
+
|
|
132
|
+
#### 配置会话 Token 限制
|
|
133
|
+
|
|
134
|
+
在您的主目录中创建或编辑 `.codely-cli/settings.json`:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"sessionTokenLimit": 32000
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### 会话命令
|
|
143
|
+
|
|
144
|
+
- **`/compress`** - 压缩对话历史以继续在 token 限制内使用
|
|
145
|
+
- **`/clear`** - 清除所有对话历史并重新开始
|
|
146
|
+
- **`/stats`** - 检查当前 token 使用情况和限制
|
|
147
|
+
|
|
148
|
+
> 📝 **注意**:会话 token 限制适用于单次对话,而非累计 API 调用。
|
|
149
|
+
|
|
150
|
+
## 使用示例
|
|
151
|
+
|
|
152
|
+
### 🔍 探索代码库
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
cd your-project/
|
|
156
|
+
codely
|
|
157
|
+
|
|
158
|
+
# 架构分析
|
|
159
|
+
> 描述这个系统架构的主要部分
|
|
160
|
+
> 关键依赖是什么,它们如何交互?
|
|
161
|
+
> 查找所有 API 端点及其认证方法
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### 💻 代码开发
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# 重构
|
|
168
|
+
> 重构这个函数以提高可读性和性能
|
|
169
|
+
> 将这个类转换为使用依赖注入
|
|
170
|
+
> 将这个大模块拆分成更小、更专注的组件
|
|
171
|
+
|
|
172
|
+
# 代码生成
|
|
173
|
+
> 创建一个用户管理的 REST API 端点
|
|
174
|
+
> 为认证模块生成单元测试
|
|
175
|
+
> 为所有数据库操作添加错误处理
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 🔄 自动化工作流
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Git 自动化
|
|
182
|
+
> 分析过去 7 天的 git 提交,按功能分组
|
|
183
|
+
> 从最近的提交创建变更日志
|
|
184
|
+
> 查找所有 TODO 注释并创建 GitHub issues
|
|
185
|
+
|
|
186
|
+
# 文件操作
|
|
187
|
+
> 将此目录中的所有图像转换为 PNG 格式
|
|
188
|
+
> 将所有测试文件重命名为 *.test.ts 模式
|
|
189
|
+
> 查找并删除所有 console.log 语句
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 🐛 调试与分析
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
# 性能分析
|
|
196
|
+
> 识别这个 React 组件中的性能瓶颈
|
|
197
|
+
> 在代码库中查找所有 N+1 查询问题
|
|
198
|
+
|
|
199
|
+
# 安全审计
|
|
200
|
+
> 检查潜在的 SQL 注入漏洞
|
|
201
|
+
> 查找所有硬编码的凭据或 API 密钥
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## 常用任务
|
|
205
|
+
|
|
206
|
+
### 📚 理解新代码库
|
|
207
|
+
|
|
208
|
+
```text
|
|
209
|
+
> 核心业务逻辑组件是什么?
|
|
210
|
+
> 有哪些安全机制?
|
|
211
|
+
> 数据如何在系统中流动?
|
|
212
|
+
> 使用了哪些主要设计模式?
|
|
213
|
+
> 为这个模块生成依赖关系图
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 🔨 代码重构与优化
|
|
217
|
+
|
|
218
|
+
```text
|
|
219
|
+
> 这个模块的哪些部分可以优化?
|
|
220
|
+
> 帮我重构这个类以遵循 SOLID 原则
|
|
221
|
+
> 添加适当的错误处理和日志记录
|
|
222
|
+
> 将回调转换为 async/await 模式
|
|
223
|
+
> 为昂贵的操作实现缓存
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### 📝 文档与测试
|
|
227
|
+
|
|
228
|
+
```text
|
|
229
|
+
> 为所有公共 API 生成全面的 JSDoc 注释
|
|
230
|
+
> 编写包含边界情况的单元测试
|
|
231
|
+
> 以 OpenAPI 格式创建 API 文档
|
|
232
|
+
> 添加解释复杂算法的内联注释
|
|
233
|
+
> 为这个模块生成 README
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### 🚀 开发加速
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
> 设置一个带认证的新 Express 服务器
|
|
240
|
+
> 创建一个带 TypeScript 和测试的 React 组件
|
|
241
|
+
> 实现一个速率限制中间件
|
|
242
|
+
> 为新架构添加数据库迁移
|
|
243
|
+
> 为这个项目配置 CI/CD 流水线
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## 命令与快捷键
|
|
247
|
+
|
|
248
|
+
### 会话命令
|
|
249
|
+
|
|
250
|
+
- `/help` - 显示可用命令
|
|
251
|
+
- `/clear` - 清除对话历史
|
|
252
|
+
- `/compress` - 压缩历史以节省 tokens
|
|
253
|
+
- `/stats` - 显示当前会话信息
|
|
254
|
+
- `/exit` 或 `/quit` - 退出 Codely CLI
|
|
255
|
+
|
|
256
|
+
### MCP 命令
|
|
257
|
+
|
|
258
|
+
管理模型上下文协议(MCP)服务器以扩展 Codely 的外部工具和服务能力:
|
|
259
|
+
|
|
260
|
+
- `/mcp` - 列出已配置的 MCP 服务器及其可用工具
|
|
261
|
+
- `/mcp desc` - 显示服务器和工具的详细描述
|
|
262
|
+
- `/mcp schema` - 显示工具参数架构
|
|
263
|
+
- `/mcp auth <server-name>` - 对启用 OAuth 的 MCP 服务器进行身份验证
|
|
264
|
+
- `/mcp refresh` - 刷新 MCP 服务器和工具列表
|
|
265
|
+
|
|
266
|
+
管理 MCP 服务器配置的 CLI 命令:
|
|
267
|
+
|
|
268
|
+
#### `codely mcp add <name> <commandOrUrl> [args...]`
|
|
269
|
+
|
|
270
|
+
添加具有指定名称和连接详情的新 MCP 服务器。
|
|
271
|
+
|
|
272
|
+
**选项:**
|
|
273
|
+
|
|
274
|
+
- `--scope` (`-s`) - 配置范围(user 或 project)
|
|
275
|
+
- `--transport` (`-t`) - 传输类型(stdio、sse、http)
|
|
276
|
+
- `--env` (`-e`) - 为 stdio 传输设置环境变量(例如 `-e KEY=value`)
|
|
277
|
+
- `--header` (`-H`) - 为 SSE 和 HTTP 传输设置 HTTP 头(例如 `-H "X-Api-Key: abc123"`)
|
|
278
|
+
- `--timeout` - 连接超时时间(毫秒)
|
|
279
|
+
- `--trust` - 信任服务器(绕过所有工具调用确认提示)
|
|
280
|
+
- `--description` - 服务器描述
|
|
281
|
+
- `--include-tools` - 要包含的工具的逗号分隔列表
|
|
282
|
+
- `--exclude-tools` - 要排除的工具的逗号分隔列表
|
|
283
|
+
|
|
284
|
+
**传输类型:**
|
|
285
|
+
|
|
286
|
+
- `stdio`(默认)- 使用指定的命令和参数启动进程
|
|
287
|
+
- `sse` - 使用服务器发送事件协议连接到服务器
|
|
288
|
+
- `http` - 使用 HTTP 协议连接到服务器
|
|
289
|
+
|
|
290
|
+
**示例:**
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# 添加 stdio 服务器
|
|
294
|
+
codely mcp add my-server python /path/to/server.py --env API_KEY=abc123
|
|
295
|
+
|
|
296
|
+
# 添加 HTTP 服务器
|
|
297
|
+
codely mcp add my-http-server http://localhost:8000 --transport http --header "Authorization: Bearer token"
|
|
298
|
+
|
|
299
|
+
# 添加具有范围配置的服务器
|
|
300
|
+
codely mcp add my-server python /path/to/server.py --scope user
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
#### `codely mcp list`
|
|
304
|
+
|
|
305
|
+
列出所有已配置的 MCP 服务器及其连接状态。
|
|
306
|
+
|
|
307
|
+
#### `codely mcp remove <name>`
|
|
308
|
+
|
|
309
|
+
删除具有指定名称的 MCP 服务器。
|
|
310
|
+
|
|
311
|
+
**选项:**
|
|
312
|
+
|
|
313
|
+
- `--scope` (`-s`) - 配置范围(user 或 project)
|
|
314
|
+
|
|
315
|
+
### 键盘快捷键
|
|
316
|
+
|
|
317
|
+
- `Ctrl+C` - 取消当前操作
|
|
318
|
+
- `Ctrl+D` - 退出(在空行上)
|
|
319
|
+
- `上/下箭头` - 浏览命令历史
|
|
320
|
+
|
|
321
|
+
## 故障排除
|
|
322
|
+
|
|
323
|
+
如果您遇到问题,请检查错误消息并确保:
|
|
324
|
+
- Node.js 版本为 20 或更高
|
|
325
|
+
- 所有依赖项已正确安装
|
|
326
|
+
- API 密钥在设置中正确配置
|
|
327
|
+
|
|
328
|
+
如需更多帮助,请访问:
|
|
329
|
+
- 🌐 [官方网站](https://codely.tuanjie.cn/)
|
|
330
|
+
- 📖 [使用手册](https://yousandi.feishu.cn/wiki/Sqmlw31sYiTm8qkh7s1cSlbenmb)
|
|
331
|
+
|
|
332
|
+
## 许可证
|
|
333
|
+
|
|
334
|
+
[LICENSE](./LICENSE)
|
|
335
|
+
|
package/bundle/gemini.js
CHANGED
|
@@ -376088,7 +376088,9 @@ async function executeToolCall(config3, toolCallRequest, toolRegistry, abortSign
|
|
|
376088
376088
|
};
|
|
376089
376089
|
logToolCall(config3, toolCallEvent);
|
|
376090
376090
|
exportToolCallWithResultToSentry(config3, toolCallEvent, toolType, tool);
|
|
376091
|
-
|
|
376091
|
+
if (config3.getDebugMode()) {
|
|
376092
|
+
console.error(`Non-interactive tool execution error for ${toolCallRequest.name}:`, error2);
|
|
376093
|
+
}
|
|
376092
376094
|
return {
|
|
376093
376095
|
callId: toolCallRequest.callId,
|
|
376094
376096
|
responseParts: [
|
|
@@ -378869,10 +378871,11 @@ var init_subagent_tool_wrapper = __esm({
|
|
|
378869
378871
|
createInvocation(params) {
|
|
378870
378872
|
const outputFormat = this.config.getOutputFormat();
|
|
378871
378873
|
const isJsonMode = outputFormat === "json" || outputFormat === "stream-json";
|
|
378872
|
-
if (!isJsonMode) {
|
|
378873
|
-
console.
|
|
378874
|
-
console.
|
|
378875
|
-
console.
|
|
378874
|
+
if (!isJsonMode && this.config.getDebugMode()) {
|
|
378875
|
+
console.debug(`\u{1F3B2} [TOOL WRAPPER] Main LLM is invoking agent tool: ${this.definition.name}`);
|
|
378876
|
+
console.debug(`\u{1F3B2} [TOOL WRAPPER] Display name: ${this.displayName}`);
|
|
378877
|
+
console.debug(`\u{1F3B2} [TOOL WRAPPER] Parameters received:
|
|
378878
|
+
${JSON.stringify(params, null, 2)}`);
|
|
378876
378879
|
}
|
|
378877
378880
|
return new SubagentInvocation(params, this.definition, this.config);
|
|
378878
378881
|
}
|
|
@@ -384337,12 +384340,13 @@ var init_stream_json_formatter = __esm({
|
|
|
384337
384340
|
};
|
|
384338
384341
|
this.emitEvent(event);
|
|
384339
384342
|
}
|
|
384340
|
-
emitMessage(role, content, delta = false) {
|
|
384343
|
+
emitMessage(role, content, delta = false, reasoning_content) {
|
|
384341
384344
|
const event = {
|
|
384342
384345
|
type: JsonStreamEventType.MESSAGE,
|
|
384343
384346
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
384344
384347
|
role,
|
|
384345
384348
|
content,
|
|
384349
|
+
...reasoning_content !== void 0 ? { reasoning_content } : {},
|
|
384346
384350
|
delta
|
|
384347
384351
|
};
|
|
384348
384352
|
this.emitEvent(event);
|
|
@@ -417067,14 +417071,50 @@ import * as fs55 from "fs";
|
|
|
417067
417071
|
var __filename = fileURLToPath6(import.meta.url);
|
|
417068
417072
|
var __dirname3 = path56.dirname(__filename);
|
|
417069
417073
|
var packageJson;
|
|
417074
|
+
function hasCodelyBin(parsed) {
|
|
417075
|
+
if (!parsed || typeof parsed !== "object") {
|
|
417076
|
+
return false;
|
|
417077
|
+
}
|
|
417078
|
+
const bin = parsed.bin;
|
|
417079
|
+
if (!bin) {
|
|
417080
|
+
return false;
|
|
417081
|
+
}
|
|
417082
|
+
if (typeof bin === "string") {
|
|
417083
|
+
return true;
|
|
417084
|
+
}
|
|
417085
|
+
if (typeof bin === "object") {
|
|
417086
|
+
const codely = bin.codely;
|
|
417087
|
+
return typeof codely === "string" && codely.length > 0;
|
|
417088
|
+
}
|
|
417089
|
+
return false;
|
|
417090
|
+
}
|
|
417091
|
+
function isCliPackageJson(parsed) {
|
|
417092
|
+
if (!parsed || typeof parsed !== "object") {
|
|
417093
|
+
return false;
|
|
417094
|
+
}
|
|
417095
|
+
const { name: name3, version: version2 } = parsed;
|
|
417096
|
+
const supportedNames = /* @__PURE__ */ new Set([
|
|
417097
|
+
"@codely/cli",
|
|
417098
|
+
"@codely/codely-cli",
|
|
417099
|
+
"@unity-china/codely-cli",
|
|
417100
|
+
"@unity-china/cli"
|
|
417101
|
+
]);
|
|
417102
|
+
if (typeof name3 === "string" && supportedNames.has(name3)) {
|
|
417103
|
+
return true;
|
|
417104
|
+
}
|
|
417105
|
+
if (hasCodelyBin(parsed)) {
|
|
417106
|
+
return true;
|
|
417107
|
+
}
|
|
417108
|
+
return typeof name3 === "string" && typeof version2 === "string";
|
|
417109
|
+
}
|
|
417070
417110
|
async function tryLoadPackageJson(packagePath) {
|
|
417071
417111
|
try {
|
|
417072
417112
|
const packageJsonContent = await fs55.promises.readFile(packagePath, "utf-8");
|
|
417073
417113
|
const parsed = JSON.parse(packageJsonContent);
|
|
417074
|
-
if (parsed
|
|
417075
|
-
return
|
|
417114
|
+
if (!isCliPackageJson(parsed)) {
|
|
417115
|
+
return null;
|
|
417076
417116
|
}
|
|
417077
|
-
return
|
|
417117
|
+
return parsed;
|
|
417078
417118
|
} catch (_) {
|
|
417079
417119
|
return null;
|
|
417080
417120
|
}
|
|
@@ -417084,7 +417124,11 @@ async function getPackageJson2() {
|
|
|
417084
417124
|
return packageJson;
|
|
417085
417125
|
}
|
|
417086
417126
|
const candidatePaths = [
|
|
417127
|
+
// dist/** -> package.json
|
|
417128
|
+
path56.resolve(__dirname3, "../../package.json"),
|
|
417129
|
+
// bundle/** -> package.json
|
|
417087
417130
|
path56.resolve(__dirname3, "../package.json"),
|
|
417131
|
+
// monorepo root (historical)
|
|
417088
417132
|
path56.resolve(__dirname3, "../../../../package.json")
|
|
417089
417133
|
];
|
|
417090
417134
|
for (const packagePath of candidatePaths) {
|
|
@@ -417100,7 +417144,7 @@ async function getPackageJson2() {
|
|
|
417100
417144
|
// packages/cli/src/utils/version.ts
|
|
417101
417145
|
async function getCliVersion() {
|
|
417102
417146
|
const pkgJson = await getPackageJson2();
|
|
417103
|
-
return "1.0.0-beta.
|
|
417147
|
+
return "1.0.0-beta.34";
|
|
417104
417148
|
}
|
|
417105
417149
|
|
|
417106
417150
|
// packages/cli/src/ui/commands/types.ts
|
|
@@ -417592,7 +417636,7 @@ import process30 from "node:process";
|
|
|
417592
417636
|
|
|
417593
417637
|
// packages/cli/src/generated/git-commit.ts
|
|
417594
417638
|
init_esbuild_polyfill();
|
|
417595
|
-
var GIT_COMMIT_INFO = "
|
|
417639
|
+
var GIT_COMMIT_INFO = "193365d8";
|
|
417596
417640
|
|
|
417597
417641
|
// packages/cli/src/ui/commands/bugCommand.ts
|
|
417598
417642
|
var bugCommand = {
|
|
@@ -487197,7 +487241,7 @@ init_dist6();
|
|
|
487197
487241
|
import * as fs83 from "fs";
|
|
487198
487242
|
import * as path85 from "path";
|
|
487199
487243
|
import * as childProcess2 from "child_process";
|
|
487200
|
-
function getInstallationInfo(projectRoot, isAutoUpdateDisabled) {
|
|
487244
|
+
function getInstallationInfo(projectRoot, isAutoUpdateDisabled, packageName = "@codely/codely-cli") {
|
|
487201
487245
|
const cliPath = process.argv[1];
|
|
487202
487246
|
if (!cliPath) {
|
|
487203
487247
|
return { packageManager: "unknown" /* UNKNOWN */, isGlobal: false };
|
|
@@ -487206,6 +487250,7 @@ function getInstallationInfo(projectRoot, isAutoUpdateDisabled) {
|
|
|
487206
487250
|
const realPath = fs83.realpathSync(cliPath).replace(/\\/g, "/");
|
|
487207
487251
|
const normalizedProjectRoot = projectRoot?.replace(/\\/g, "/");
|
|
487208
487252
|
const isGit = isGitRepository(process.cwd());
|
|
487253
|
+
const registryFlag = packageName.startsWith("@unity-china/") ? " --registry https://registry.npmjs.org/" : "";
|
|
487209
487254
|
if (isGit && normalizedProjectRoot && realPath.startsWith(normalizedProjectRoot) && !realPath.includes("/node_modules/")) {
|
|
487210
487255
|
return {
|
|
487211
487256
|
packageManager: "unknown" /* UNKNOWN */,
|
|
@@ -487242,7 +487287,7 @@ function getInstallationInfo(projectRoot, isAutoUpdateDisabled) {
|
|
|
487242
487287
|
}
|
|
487243
487288
|
}
|
|
487244
487289
|
if (realPath.includes("/.pnpm/global")) {
|
|
487245
|
-
const updateCommand3 =
|
|
487290
|
+
const updateCommand3 = `pnpm add -g ${packageName}@latest${registryFlag}`;
|
|
487246
487291
|
return {
|
|
487247
487292
|
packageManager: "pnpm" /* PNPM */,
|
|
487248
487293
|
isGlobal: true,
|
|
@@ -487251,7 +487296,7 @@ function getInstallationInfo(projectRoot, isAutoUpdateDisabled) {
|
|
|
487251
487296
|
};
|
|
487252
487297
|
}
|
|
487253
487298
|
if (realPath.includes("/.yarn/global")) {
|
|
487254
|
-
const updateCommand3 =
|
|
487299
|
+
const updateCommand3 = `yarn global add ${packageName}@latest${registryFlag}`;
|
|
487255
487300
|
return {
|
|
487256
487301
|
packageManager: "yarn" /* YARN */,
|
|
487257
487302
|
isGlobal: true,
|
|
@@ -487267,7 +487312,7 @@ function getInstallationInfo(projectRoot, isAutoUpdateDisabled) {
|
|
|
487267
487312
|
};
|
|
487268
487313
|
}
|
|
487269
487314
|
if (realPath.includes("/.bun/bin")) {
|
|
487270
|
-
const updateCommand3 =
|
|
487315
|
+
const updateCommand3 = `bun add -g ${packageName}@latest`;
|
|
487271
487316
|
return {
|
|
487272
487317
|
packageManager: "bun" /* BUN */,
|
|
487273
487318
|
isGlobal: true,
|
|
@@ -487290,7 +487335,7 @@ function getInstallationInfo(projectRoot, isAutoUpdateDisabled) {
|
|
|
487290
487335
|
updateMessage: "Locally installed. Please update via your project's package.json."
|
|
487291
487336
|
};
|
|
487292
487337
|
}
|
|
487293
|
-
const updateCommand2 =
|
|
487338
|
+
const updateCommand2 = `npm install -g ${packageName}@latest${registryFlag}`;
|
|
487294
487339
|
return {
|
|
487295
487340
|
packageManager: "npm" /* NPM */,
|
|
487296
487341
|
isGlobal: true,
|
|
@@ -487335,9 +487380,11 @@ function handleAutoUpdate(info, settings, projectRoot, spawnFn = spawnWrapper) {
|
|
|
487335
487380
|
if (settings.merged.disableUpdateNag) {
|
|
487336
487381
|
return;
|
|
487337
487382
|
}
|
|
487383
|
+
const packageName = info.update.name && (info.update.name.startsWith("@") || info.update.name.includes("/")) ? info.update.name : void 0;
|
|
487338
487384
|
const installationInfo = getInstallationInfo(
|
|
487339
487385
|
projectRoot,
|
|
487340
|
-
settings.merged.disableAutoUpdate ?? false
|
|
487386
|
+
settings.merged.disableAutoUpdate ?? false,
|
|
487387
|
+
packageName
|
|
487341
487388
|
);
|
|
487342
487389
|
let combinedMessage = info.message;
|
|
487343
487390
|
if (installationInfo.updateMessage) {
|
|
@@ -487350,15 +487397,22 @@ ${installationInfo.updateMessage}`;
|
|
|
487350
487397
|
if (settings.merged.disableAutoUpdate) {
|
|
487351
487398
|
return;
|
|
487352
487399
|
}
|
|
487353
|
-
if (
|
|
487354
|
-
|
|
487355
|
-
|
|
487356
|
-
|
|
487400
|
+
if (info.update.downloadUrl) {
|
|
487401
|
+
performTgzUpdate(info.update.downloadUrl, info.update.latest, spawnFn);
|
|
487402
|
+
return;
|
|
487403
|
+
}
|
|
487404
|
+
if (installationInfo.updateCommand) {
|
|
487405
|
+
performCommandUpdate(installationInfo.updateCommand, spawnFn);
|
|
487406
|
+
return;
|
|
487407
|
+
}
|
|
487408
|
+
if (!installationInfo.isGlobal) {
|
|
487357
487409
|
return;
|
|
487358
487410
|
}
|
|
487359
|
-
|
|
487411
|
+
updateEventEmitter.emit("update-failed", {
|
|
487412
|
+
message: "Automatic update is not available for this installation. Please try updating manually."
|
|
487413
|
+
});
|
|
487360
487414
|
}
|
|
487361
|
-
async function
|
|
487415
|
+
async function performTgzUpdate(downloadUrl, version2, spawnFn) {
|
|
487362
487416
|
try {
|
|
487363
487417
|
updateEventEmitter.emit("update-info", {
|
|
487364
487418
|
message: "Downloading update..."
|
|
@@ -487411,6 +487465,41 @@ async function performUpdate(downloadUrl, version2, spawnFn) {
|
|
|
487411
487465
|
});
|
|
487412
487466
|
}
|
|
487413
487467
|
}
|
|
487468
|
+
function performCommandUpdate(updateCommand2, spawnFn) {
|
|
487469
|
+
try {
|
|
487470
|
+
updateEventEmitter.emit("update-info", {
|
|
487471
|
+
message: "Installing update..."
|
|
487472
|
+
});
|
|
487473
|
+
const updateProcess = spawnFn(updateCommand2, {
|
|
487474
|
+
stdio: "pipe",
|
|
487475
|
+
shell: true
|
|
487476
|
+
});
|
|
487477
|
+
let errorOutput = "";
|
|
487478
|
+
updateProcess.stderr.on("data", (data) => {
|
|
487479
|
+
errorOutput += data.toString();
|
|
487480
|
+
});
|
|
487481
|
+
updateProcess.on("close", (code2) => {
|
|
487482
|
+
if (code2 === 0) {
|
|
487483
|
+
updateEventEmitter.emit("update-success", {
|
|
487484
|
+
message: "Update successful! The new version will be used on your next run."
|
|
487485
|
+
});
|
|
487486
|
+
} else {
|
|
487487
|
+
updateEventEmitter.emit("update-failed", {
|
|
487488
|
+
message: `Automatic update failed. Please try updating manually. (command: ${updateCommand2}, stderr: ${errorOutput.trim()})`
|
|
487489
|
+
});
|
|
487490
|
+
}
|
|
487491
|
+
});
|
|
487492
|
+
updateProcess.on("error", (err) => {
|
|
487493
|
+
updateEventEmitter.emit("update-failed", {
|
|
487494
|
+
message: `Automatic update failed. Please try updating manually. (error: ${err.message})`
|
|
487495
|
+
});
|
|
487496
|
+
});
|
|
487497
|
+
} catch (error2) {
|
|
487498
|
+
updateEventEmitter.emit("update-failed", {
|
|
487499
|
+
message: `Automatic update failed. Please try updating manually. (${error2 instanceof Error ? error2.message : "Unknown error"})`
|
|
487500
|
+
});
|
|
487501
|
+
}
|
|
487502
|
+
}
|
|
487414
487503
|
function setUpdateHandler(addItem, setUpdateInfo) {
|
|
487415
487504
|
let successfullyInstalled = false;
|
|
487416
487505
|
const handleUpdateRecieved = (info) => {
|
|
@@ -489223,8 +489312,9 @@ var thinkBuffer = "";
|
|
|
489223
489312
|
var hasSeenNonWhitespaceOutput = false;
|
|
489224
489313
|
var hasHandledLeadingThinkBlock = false;
|
|
489225
489314
|
function processThinkTagsForNonInteractive(text) {
|
|
489226
|
-
if (!text) return text;
|
|
489227
|
-
let
|
|
489315
|
+
if (!text) return { content: text, reasoning_content: "" };
|
|
489316
|
+
let content = "";
|
|
489317
|
+
let reasoning_content = "";
|
|
489228
489318
|
let currentText = text;
|
|
489229
489319
|
if (isInThinkBlock && thinkBuffer) {
|
|
489230
489320
|
currentText = thinkBuffer + currentText;
|
|
@@ -489240,10 +489330,23 @@ function processThinkTagsForNonInteractive(text) {
|
|
|
489240
489330
|
closeTagLength = "</think>".length;
|
|
489241
489331
|
}
|
|
489242
489332
|
if (closeTagIndex !== -1) {
|
|
489333
|
+
reasoning_content += currentText.slice(i3, closeTagIndex);
|
|
489243
489334
|
i3 = closeTagIndex + closeTagLength;
|
|
489244
489335
|
isInThinkBlock = false;
|
|
489245
489336
|
} else {
|
|
489246
|
-
|
|
489337
|
+
const remaining = currentText.slice(i3);
|
|
489338
|
+
const maxCloseTagLen = Math.max(
|
|
489339
|
+
"</thinking>".length,
|
|
489340
|
+
"</think>".length
|
|
489341
|
+
);
|
|
489342
|
+
const keepTail = Math.max(0, maxCloseTagLen - 1);
|
|
489343
|
+
if (remaining.length > keepTail) {
|
|
489344
|
+
const emitLen = remaining.length - keepTail;
|
|
489345
|
+
reasoning_content += remaining.slice(0, emitLen);
|
|
489346
|
+
thinkBuffer = remaining.slice(emitLen);
|
|
489347
|
+
} else {
|
|
489348
|
+
thinkBuffer = remaining;
|
|
489349
|
+
}
|
|
489247
489350
|
break;
|
|
489248
489351
|
}
|
|
489249
489352
|
} else {
|
|
@@ -489251,7 +489354,7 @@ function processThinkTagsForNonInteractive(text) {
|
|
|
489251
489354
|
const nextThink = currentText.indexOf("<think>", i3);
|
|
489252
489355
|
if (nextThinking === -1 && nextThink === -1) {
|
|
489253
489356
|
const tail = currentText.slice(i3);
|
|
489254
|
-
|
|
489357
|
+
content += tail;
|
|
489255
489358
|
if (!hasSeenNonWhitespaceOutput && /\S/.test(tail)) {
|
|
489256
489359
|
hasSeenNonWhitespaceOutput = true;
|
|
489257
489360
|
}
|
|
@@ -489272,14 +489375,14 @@ function processThinkTagsForNonInteractive(text) {
|
|
|
489272
489375
|
i3,
|
|
489273
489376
|
openTagIndex + openTagLength
|
|
489274
489377
|
);
|
|
489275
|
-
|
|
489378
|
+
content += literalSegment;
|
|
489276
489379
|
if (!hasSeenNonWhitespaceOutput && /\S/.test(literalSegment)) {
|
|
489277
489380
|
hasSeenNonWhitespaceOutput = true;
|
|
489278
489381
|
}
|
|
489279
489382
|
i3 = openTagIndex + openTagLength;
|
|
489280
489383
|
continue;
|
|
489281
489384
|
}
|
|
489282
|
-
|
|
489385
|
+
content += beforeTag;
|
|
489283
489386
|
hasHandledLeadingThinkBlock = true;
|
|
489284
489387
|
const afterOpenTag = openTagIndex + openTagLength;
|
|
489285
489388
|
const closeTagIndex = currentText.indexOf(closeTagToCheck, afterOpenTag);
|
|
@@ -489291,7 +489394,7 @@ function processThinkTagsForNonInteractive(text) {
|
|
|
489291
489394
|
}
|
|
489292
489395
|
}
|
|
489293
489396
|
}
|
|
489294
|
-
return
|
|
489397
|
+
return { content, reasoning_content };
|
|
489295
489398
|
}
|
|
489296
489399
|
function resetThinkTagState() {
|
|
489297
489400
|
isInThinkBlock = false;
|
|
@@ -489333,6 +489436,9 @@ async function runNonInteractive(config3, input, prompt_id) {
|
|
|
489333
489436
|
while (true) {
|
|
489334
489437
|
turnCount++;
|
|
489335
489438
|
if (config3.getMaxSessionTurns() >= 0 && turnCount > config3.getMaxSessionTurns()) {
|
|
489439
|
+
if (process.exitCode === void 0 || process.exitCode === 0) {
|
|
489440
|
+
process.exitCode = 1;
|
|
489441
|
+
}
|
|
489336
489442
|
if (streamFormatter) {
|
|
489337
489443
|
streamFormatter.emitError("error", "Maximum session turns exceeded");
|
|
489338
489444
|
streamFormatter.emitResult("error", void 0, {
|
|
@@ -489349,7 +489455,8 @@ async function runNonInteractive(config3, input, prompt_id) {
|
|
|
489349
489455
|
void 0,
|
|
489350
489456
|
jsonError
|
|
489351
489457
|
);
|
|
489352
|
-
|
|
489458
|
+
process.stdout.write(`${jsonOutput}
|
|
489459
|
+
`);
|
|
489353
489460
|
} else if (!jsonFormatter) {
|
|
489354
489461
|
console.error("Maximum session turns exceeded. Stopping.");
|
|
489355
489462
|
}
|
|
@@ -489368,18 +489475,33 @@ async function runNonInteractive(config3, input, prompt_id) {
|
|
|
489368
489475
|
switch (event.type) {
|
|
489369
489476
|
case GeminiEventType.Content:
|
|
489370
489477
|
if (typeof event.value === "string" && event.value) {
|
|
489371
|
-
const processedContent = processThinkTagsForNonInteractive(
|
|
489372
|
-
event.value
|
|
489373
|
-
);
|
|
489478
|
+
const { content: processedContent, reasoning_content } = processThinkTagsForNonInteractive(event.value);
|
|
489374
489479
|
responseText += event.value;
|
|
489375
489480
|
if (streamFormatter) {
|
|
489376
|
-
|
|
489481
|
+
if (processedContent || reasoning_content) {
|
|
489482
|
+
streamFormatter.emitMessage(
|
|
489483
|
+
"assistant",
|
|
489484
|
+
processedContent,
|
|
489485
|
+
true,
|
|
489486
|
+
reasoning_content || void 0
|
|
489487
|
+
);
|
|
489488
|
+
}
|
|
489377
489489
|
} else if (jsonFormatter) {
|
|
489378
489490
|
} else if (processedContent) {
|
|
489379
489491
|
process.stdout.write(processedContent);
|
|
489380
489492
|
}
|
|
489381
489493
|
}
|
|
489382
489494
|
break;
|
|
489495
|
+
case GeminiEventType.Thought:
|
|
489496
|
+
if (streamFormatter && event.value) {
|
|
489497
|
+
const subject = typeof event.value.subject === "string" ? String(event.value.subject) : "";
|
|
489498
|
+
const description = typeof event.value.description === "string" ? String(event.value.description) : "";
|
|
489499
|
+
const thoughtText = [subject, description].filter(Boolean).join(subject && description ? "\n" : "");
|
|
489500
|
+
if (thoughtText) {
|
|
489501
|
+
streamFormatter.emitMessage("assistant", "", true, thoughtText);
|
|
489502
|
+
}
|
|
489503
|
+
}
|
|
489504
|
+
break;
|
|
489383
489505
|
case GeminiEventType.ToolCallRequest:
|
|
489384
489506
|
{
|
|
489385
489507
|
const toolCallRequest = event.value;
|
|
@@ -489399,6 +489521,9 @@ async function runNonInteractive(config3, input, prompt_id) {
|
|
|
489399
489521
|
}
|
|
489400
489522
|
break;
|
|
489401
489523
|
case GeminiEventType.LoopDetected: {
|
|
489524
|
+
if (process.exitCode === void 0 || process.exitCode === 0) {
|
|
489525
|
+
process.exitCode = 1;
|
|
489526
|
+
}
|
|
489402
489527
|
const reasonMessage = event && typeof event.value?.message === "string" && event.value.message ? String(event.value.message) : "";
|
|
489403
489528
|
if (streamFormatter) {
|
|
489404
489529
|
streamFormatter.emitError(
|
|
@@ -489415,6 +489540,9 @@ Reason: ${reasonMessage}` : "Loop detected in conversation. Stopping."
|
|
|
489415
489540
|
break;
|
|
489416
489541
|
}
|
|
489417
489542
|
case GeminiEventType.MaxSessionTurns:
|
|
489543
|
+
if (process.exitCode === void 0 || process.exitCode === 0) {
|
|
489544
|
+
process.exitCode = 1;
|
|
489545
|
+
}
|
|
489418
489546
|
if (streamFormatter) {
|
|
489419
489547
|
streamFormatter.emitError(
|
|
489420
489548
|
"error",
|
|
@@ -489442,14 +489570,11 @@ Reason: ${reasonMessage}` : "Loop detected in conversation. Stopping."
|
|
|
489442
489570
|
);
|
|
489443
489571
|
try {
|
|
489444
489572
|
} catch (error2) {
|
|
489445
|
-
if (
|
|
489446
|
-
|
|
489573
|
+
if (config3.getDebugMode()) {
|
|
489574
|
+
logger6.error(
|
|
489447
489575
|
`Error recording completed tool call information: ${error2}`
|
|
489448
489576
|
);
|
|
489449
489577
|
}
|
|
489450
|
-
logger6.debug(
|
|
489451
|
-
`Error recording completed tool call information: ${error2}`
|
|
489452
|
-
);
|
|
489453
489578
|
}
|
|
489454
489579
|
currentMessages = [{ role: "user", parts: toolResponseParts }];
|
|
489455
489580
|
} else {
|
|
@@ -489462,9 +489587,10 @@ Reason: ${reasonMessage}` : "Loop detected in conversation. Stopping."
|
|
|
489462
489587
|
streamFormatter.emitResult("success", metrics2);
|
|
489463
489588
|
} else if (jsonFormatter) {
|
|
489464
489589
|
const metrics2 = uiTelemetryService.getMetrics();
|
|
489465
|
-
const processedResponse =
|
|
489590
|
+
const processedResponse = stripLeadingThinkTags(responseText);
|
|
489466
489591
|
const jsonOutput = jsonFormatter.format(processedResponse, metrics2);
|
|
489467
|
-
|
|
489592
|
+
process.stdout.write(`${jsonOutput}
|
|
489593
|
+
`);
|
|
489468
489594
|
} else if (responseText && !jsonFormatter) {
|
|
489469
489595
|
process.stdout.write("\n");
|
|
489470
489596
|
}
|
|
@@ -489486,24 +489612,70 @@ Reason: ${reasonMessage}` : "Loop detected in conversation. Stopping."
|
|
|
489486
489612
|
message: errorMessage
|
|
489487
489613
|
};
|
|
489488
489614
|
const jsonOutput = jsonFormatter.format(void 0, void 0, jsonError);
|
|
489489
|
-
|
|
489615
|
+
process.stdout.write(`${jsonOutput}
|
|
489616
|
+
`);
|
|
489490
489617
|
} else {
|
|
489491
|
-
|
|
489492
|
-
|
|
489493
|
-
|
|
489494
|
-
|
|
489495
|
-
|
|
489496
|
-
|
|
489618
|
+
if (config3.getDebugMode()) {
|
|
489619
|
+
console.error(`Error: ${errorMessage}`);
|
|
489620
|
+
if (apiError !== errorMessage) {
|
|
489621
|
+
console.error(apiError);
|
|
489622
|
+
}
|
|
489623
|
+
if (error2 instanceof Error && error2.stack) {
|
|
489624
|
+
console.error(`Stack trace:
|
|
489497
489625
|
${error2.stack}`);
|
|
489626
|
+
}
|
|
489498
489627
|
}
|
|
489499
489628
|
}
|
|
489500
489629
|
} finally {
|
|
489630
|
+
try {
|
|
489631
|
+
await forceLogChatInteractionForNonInteractiveMode(config3, prompt_id);
|
|
489632
|
+
} catch (error2) {
|
|
489633
|
+
if (config3.getDebugMode()) {
|
|
489634
|
+
console.debug(
|
|
489635
|
+
"[NonInteractiveCli] Failed to flush CodelyLogger chatInteraction event:",
|
|
489636
|
+
error2
|
|
489637
|
+
);
|
|
489638
|
+
}
|
|
489639
|
+
}
|
|
489501
489640
|
consolePatcher.cleanup();
|
|
489502
489641
|
if (isTelemetrySdkInitialized()) {
|
|
489503
489642
|
await shutdownTelemetry(config3);
|
|
489504
489643
|
}
|
|
489505
489644
|
}
|
|
489506
489645
|
}
|
|
489646
|
+
function stripLeadingThinkTags(text) {
|
|
489647
|
+
if (!text) return text;
|
|
489648
|
+
const firstNonWhitespaceIndex = text.search(/\S/);
|
|
489649
|
+
if (firstNonWhitespaceIndex === -1) return text;
|
|
489650
|
+
const tailLower = text.slice(firstNonWhitespaceIndex).toLowerCase();
|
|
489651
|
+
let openTagLength = 0;
|
|
489652
|
+
if (tailLower.startsWith("<thinking>")) {
|
|
489653
|
+
openTagLength = "<thinking>".length;
|
|
489654
|
+
} else if (tailLower.startsWith("<think>")) {
|
|
489655
|
+
openTagLength = "<think>".length;
|
|
489656
|
+
} else {
|
|
489657
|
+
return text;
|
|
489658
|
+
}
|
|
489659
|
+
const leadingWhitespace = text.slice(0, firstNonWhitespaceIndex);
|
|
489660
|
+
const afterOpenTag = text.slice(firstNonWhitespaceIndex + openTagLength);
|
|
489661
|
+
const afterOpenLower = afterOpenTag.toLowerCase();
|
|
489662
|
+
const closeThinkIndex = afterOpenLower.indexOf("</think>");
|
|
489663
|
+
const closeThinkingIndex = afterOpenLower.indexOf("</thinking>");
|
|
489664
|
+
let closeIndex = -1;
|
|
489665
|
+
let closeTagLength = 0;
|
|
489666
|
+
if (closeThinkIndex !== -1 && (closeThinkingIndex === -1 || closeThinkIndex < closeThinkingIndex)) {
|
|
489667
|
+
closeIndex = closeThinkIndex;
|
|
489668
|
+
closeTagLength = "</think>".length;
|
|
489669
|
+
} else if (closeThinkingIndex !== -1) {
|
|
489670
|
+
closeIndex = closeThinkingIndex;
|
|
489671
|
+
closeTagLength = "</thinking>".length;
|
|
489672
|
+
}
|
|
489673
|
+
if (closeIndex === -1) {
|
|
489674
|
+
return leadingWhitespace;
|
|
489675
|
+
}
|
|
489676
|
+
const afterCloseTag = afterOpenTag.slice(closeIndex + closeTagLength);
|
|
489677
|
+
return leadingWhitespace + afterCloseTag;
|
|
489678
|
+
}
|
|
489507
489679
|
async function processToolCalls(functionCalls, config3, toolRegistry, abortSignal, prompt_id, streamFormatter, jsonFormatter) {
|
|
489508
489680
|
const toolResponseParts = [];
|
|
489509
489681
|
for (const fc of functionCalls) {
|
|
@@ -489516,8 +489688,8 @@ async function processToolCalls(functionCalls, config3, toolRegistry, abortSigna
|
|
|
489516
489688
|
prompt_id
|
|
489517
489689
|
};
|
|
489518
489690
|
try {
|
|
489519
|
-
logger6.debug(`\u{1F527} Calling tool: ${fc.name}`);
|
|
489520
489691
|
if (config3.getDebugMode()) {
|
|
489692
|
+
logger6.debug(`\u{1F527} Calling tool: ${fc.name}`);
|
|
489521
489693
|
logger6.debug(`\u{1F527} Parameters:
|
|
489522
489694
|
${JSON.stringify(fc.args, null, 2)}
|
|
489523
489695
|
`);
|
|
@@ -489589,7 +489761,7 @@ ${JSON.stringify(fc.args, null, 2)}
|
|
|
489589
489761
|
);
|
|
489590
489762
|
}
|
|
489591
489763
|
if (completedToolCall.error) {
|
|
489592
|
-
if (
|
|
489764
|
+
if (config3.getDebugMode()) {
|
|
489593
489765
|
logger6.error(
|
|
489594
489766
|
`Error executing tool ${fc.name}: ${completedToolCall.error.message}`
|
|
489595
489767
|
);
|
|
@@ -489604,8 +489776,10 @@ ${completedToolCall.resultDisplay}
|
|
|
489604
489776
|
`);
|
|
489605
489777
|
}
|
|
489606
489778
|
} else {
|
|
489607
|
-
|
|
489608
|
-
|
|
489779
|
+
process.stderr.write(
|
|
489780
|
+
`
|
|
489781
|
+
\u2705 Tool completed: ${fc.name}, parameters: ${JSON.stringify(fc.args, null, 2)} result: ${completedToolCall.resultDisplay}
|
|
489782
|
+
`
|
|
489609
489783
|
);
|
|
489610
489784
|
}
|
|
489611
489785
|
} else {
|
|
@@ -489621,7 +489795,7 @@ ${completedToolCall.resultDisplay}
|
|
|
489621
489795
|
}
|
|
489622
489796
|
} catch (error2) {
|
|
489623
489797
|
const errorMessage = error2 instanceof Error ? error2.message : String(error2);
|
|
489624
|
-
if (!streamFormatter && !jsonFormatter) {
|
|
489798
|
+
if (config3.getDebugMode() && !streamFormatter && !jsonFormatter) {
|
|
489625
489799
|
logger6.error(`\u274C Tool "${fc.name}" failed: ${errorMessage}`);
|
|
489626
489800
|
}
|
|
489627
489801
|
if (streamFormatter) {
|
|
@@ -489698,6 +489872,52 @@ function getServerBaseUrl2() {
|
|
|
489698
489872
|
|
|
489699
489873
|
// packages/cli/src/ui/utils/updateCheck.ts
|
|
489700
489874
|
var FETCH_TIMEOUT_MS = 2e3;
|
|
489875
|
+
function normalizeUpdateSource(value) {
|
|
489876
|
+
if (!value) {
|
|
489877
|
+
return null;
|
|
489878
|
+
}
|
|
489879
|
+
const normalized2 = value.trim().toLowerCase();
|
|
489880
|
+
if (normalized2 === "api" || normalized2 === "server") {
|
|
489881
|
+
return "api";
|
|
489882
|
+
}
|
|
489883
|
+
if (normalized2 === "npm" || normalized2 === "registry") {
|
|
489884
|
+
return "npm";
|
|
489885
|
+
}
|
|
489886
|
+
return null;
|
|
489887
|
+
}
|
|
489888
|
+
function encodeNpmPackageNameForRegistry(packageName) {
|
|
489889
|
+
if (packageName.startsWith("@")) {
|
|
489890
|
+
const parts = packageName.split("/");
|
|
489891
|
+
if (parts.length === 2 && parts[0] && parts[1]) {
|
|
489892
|
+
return `${parts[0]}%2F${parts[1]}`;
|
|
489893
|
+
}
|
|
489894
|
+
}
|
|
489895
|
+
return packageName;
|
|
489896
|
+
}
|
|
489897
|
+
async function fetchLatestVersionFromNpm(packageName) {
|
|
489898
|
+
try {
|
|
489899
|
+
const encodedName = encodeNpmPackageNameForRegistry(packageName);
|
|
489900
|
+
const url3 = `https://registry.npmjs.org/${encodedName}/latest`;
|
|
489901
|
+
const controller = new AbortController();
|
|
489902
|
+
const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
489903
|
+
const response = await fetch(url3, {
|
|
489904
|
+
method: "GET",
|
|
489905
|
+
headers: {
|
|
489906
|
+
accept: "application/json"
|
|
489907
|
+
},
|
|
489908
|
+
signal: controller.signal
|
|
489909
|
+
});
|
|
489910
|
+
clearTimeout(timeoutId);
|
|
489911
|
+
if (!response.ok) {
|
|
489912
|
+
return null;
|
|
489913
|
+
}
|
|
489914
|
+
const data = await response.json();
|
|
489915
|
+
return data.version || null;
|
|
489916
|
+
} catch (error2) {
|
|
489917
|
+
console.warn("Failed to fetch latest version from npm registry:", error2);
|
|
489918
|
+
return null;
|
|
489919
|
+
}
|
|
489920
|
+
}
|
|
489701
489921
|
async function fetchVersionFromApi() {
|
|
489702
489922
|
try {
|
|
489703
489923
|
const platform15 = os42.platform() === "win32" ? "win32" : os42.platform();
|
|
@@ -489734,6 +489954,33 @@ async function checkForUpdates() {
|
|
|
489734
489954
|
if (!currentVersion || currentVersion === "unknown") {
|
|
489735
489955
|
return null;
|
|
489736
489956
|
}
|
|
489957
|
+
const pkgJson = await getPackageJson2();
|
|
489958
|
+
const packageName = pkgJson?.name;
|
|
489959
|
+
const forcedSource = normalizeUpdateSource(
|
|
489960
|
+
process.env.CODELY_CLI_UPDATE_SOURCE
|
|
489961
|
+
);
|
|
489962
|
+
const source2 = forcedSource || (packageName && packageName.startsWith("@unity-china/") ? "npm" : "api");
|
|
489963
|
+
if (source2 === "npm") {
|
|
489964
|
+
if (!packageName) {
|
|
489965
|
+
return null;
|
|
489966
|
+
}
|
|
489967
|
+
const latestVersion2 = await fetchLatestVersionFromNpm(packageName);
|
|
489968
|
+
if (!latestVersion2) {
|
|
489969
|
+
return null;
|
|
489970
|
+
}
|
|
489971
|
+
if (import_semver2.default.gt(latestVersion2, currentVersion)) {
|
|
489972
|
+
const type = import_semver2.default.diff(currentVersion, latestVersion2) || "major";
|
|
489973
|
+
const message = `Codely Cli update available! ${currentVersion} \u2192 ${latestVersion2}`;
|
|
489974
|
+
const update2 = {
|
|
489975
|
+
current: currentVersion,
|
|
489976
|
+
latest: latestVersion2,
|
|
489977
|
+
type,
|
|
489978
|
+
name: packageName
|
|
489979
|
+
};
|
|
489980
|
+
return { message, update: update2 };
|
|
489981
|
+
}
|
|
489982
|
+
return null;
|
|
489983
|
+
}
|
|
489737
489984
|
const versionData = await fetchVersionFromApi();
|
|
489738
489985
|
if (!versionData || !versionData.active) {
|
|
489739
489986
|
return null;
|
|
@@ -489745,7 +489992,9 @@ async function checkForUpdates() {
|
|
|
489745
489992
|
current: currentVersion,
|
|
489746
489993
|
latest: latestVersion,
|
|
489747
489994
|
type: "major",
|
|
489748
|
-
name
|
|
489995
|
+
// Prefer the actual installed npm package name so the updater can
|
|
489996
|
+
// generate correct update commands (e.g. @codely/cli vs @unity-china/codely-cli).
|
|
489997
|
+
name: packageName ?? versionData.name,
|
|
489749
489998
|
downloadUrl: versionData.download_url
|
|
489750
489999
|
};
|
|
489751
490000
|
return {
|
|
@@ -491535,7 +491784,7 @@ async function main() {
|
|
|
491535
491784
|
config3
|
|
491536
491785
|
);
|
|
491537
491786
|
await runNonInteractive(nonInteractiveConfig, input, prompt_id);
|
|
491538
|
-
process.exit(0);
|
|
491787
|
+
process.exit(process.exitCode ?? 0);
|
|
491539
491788
|
}
|
|
491540
491789
|
function setWindowTitle(title, settings) {
|
|
491541
491790
|
if (!settings.merged.hideWindowTitle) {
|
|
@@ -491587,6 +491836,11 @@ main().catch((error2) => {
|
|
|
491587
491836
|
* Copyright 2025 Qwen
|
|
491588
491837
|
* SPDX-License-Identifier: Apache-2.0
|
|
491589
491838
|
*/
|
|
491839
|
+
/**
|
|
491840
|
+
* @license
|
|
491841
|
+
* Copyright 2026 Google LLC
|
|
491842
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
491843
|
+
*/
|
|
491590
491844
|
/*! Bundled license information:
|
|
491591
491845
|
|
|
491592
491846
|
react/cjs/react.production.js:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unity-china/codely-cli",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.34",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20.0.0"
|
|
6
6
|
},
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"files": [
|
|
61
61
|
"bundle/",
|
|
62
62
|
"README.md",
|
|
63
|
+
"README.zh-CN.md",
|
|
63
64
|
"LICENSE"
|
|
64
65
|
],
|
|
65
66
|
"publishConfig": {
|
|
@@ -103,7 +104,6 @@
|
|
|
103
104
|
"yargs": "^17.7.2"
|
|
104
105
|
},
|
|
105
106
|
"dependencies": {
|
|
106
|
-
"@unity-china/codely-cli": "^1.0.0-beta.31",
|
|
107
107
|
"extract-zip": "^2.0.1",
|
|
108
108
|
"gpt-tokenizer": "^3.0.1",
|
|
109
109
|
"node-fetch": "^3.3.2",
|