codegrunt 0.1.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.
Files changed (89) hide show
  1. package/README.md +351 -0
  2. package/dist/cli/at-resolver.d.ts +10 -0
  3. package/dist/cli/at-resolver.js +138 -0
  4. package/dist/cli/at-resolver.js.map +1 -0
  5. package/dist/cli/banner.d.ts +1 -0
  6. package/dist/cli/banner.js +111 -0
  7. package/dist/cli/banner.js.map +1 -0
  8. package/dist/cli/commands.d.ts +25 -0
  9. package/dist/cli/commands.js +799 -0
  10. package/dist/cli/commands.js.map +1 -0
  11. package/dist/cli/index.d.ts +2 -0
  12. package/dist/cli/index.js +142 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/cli/input.d.ts +14 -0
  15. package/dist/cli/input.js +742 -0
  16. package/dist/cli/input.js.map +1 -0
  17. package/dist/cli/repl.d.ts +2 -0
  18. package/dist/cli/repl.js +217 -0
  19. package/dist/cli/repl.js.map +1 -0
  20. package/dist/cli/setup.d.ts +7 -0
  21. package/dist/cli/setup.js +82 -0
  22. package/dist/cli/setup.js.map +1 -0
  23. package/dist/cli/skills.d.ts +28 -0
  24. package/dist/cli/skills.js +299 -0
  25. package/dist/cli/skills.js.map +1 -0
  26. package/dist/cli/update.d.ts +7 -0
  27. package/dist/cli/update.js +135 -0
  28. package/dist/cli/update.js.map +1 -0
  29. package/dist/config.d.ts +19 -0
  30. package/dist/config.js +93 -0
  31. package/dist/config.js.map +1 -0
  32. package/dist/core/agent/loop.d.ts +17 -0
  33. package/dist/core/agent/loop.js +353 -0
  34. package/dist/core/agent/loop.js.map +1 -0
  35. package/dist/core/context/manager.d.ts +26 -0
  36. package/dist/core/context/manager.js +98 -0
  37. package/dist/core/context/manager.js.map +1 -0
  38. package/dist/core/context/project-guide.d.ts +1 -0
  39. package/dist/core/context/project-guide.js +17 -0
  40. package/dist/core/context/project-guide.js.map +1 -0
  41. package/dist/core/tools/edit_file.d.ts +2 -0
  42. package/dist/core/tools/edit_file.js +54 -0
  43. package/dist/core/tools/edit_file.js.map +1 -0
  44. package/dist/core/tools/execute_shell.d.ts +2 -0
  45. package/dist/core/tools/execute_shell.js +67 -0
  46. package/dist/core/tools/execute_shell.js.map +1 -0
  47. package/dist/core/tools/executor.d.ts +3 -0
  48. package/dist/core/tools/executor.js +86 -0
  49. package/dist/core/tools/executor.js.map +1 -0
  50. package/dist/core/tools/list_directory.d.ts +2 -0
  51. package/dist/core/tools/list_directory.js +74 -0
  52. package/dist/core/tools/list_directory.js.map +1 -0
  53. package/dist/core/tools/read_file.d.ts +2 -0
  54. package/dist/core/tools/read_file.js +40 -0
  55. package/dist/core/tools/read_file.js.map +1 -0
  56. package/dist/core/tools/registry.d.ts +4 -0
  57. package/dist/core/tools/registry.js +24 -0
  58. package/dist/core/tools/registry.js.map +1 -0
  59. package/dist/core/tools/search_files.d.ts +2 -0
  60. package/dist/core/tools/search_files.js +88 -0
  61. package/dist/core/tools/search_files.js.map +1 -0
  62. package/dist/core/tools/write_file.d.ts +2 -0
  63. package/dist/core/tools/write_file.js +43 -0
  64. package/dist/core/tools/write_file.js.map +1 -0
  65. package/dist/providers/deepseek/client.d.ts +8 -0
  66. package/dist/providers/deepseek/client.js +27 -0
  67. package/dist/providers/deepseek/client.js.map +1 -0
  68. package/dist/providers/deepseek/provider.d.ts +8 -0
  69. package/dist/providers/deepseek/provider.js +165 -0
  70. package/dist/providers/deepseek/provider.js.map +1 -0
  71. package/dist/types.d.ts +111 -0
  72. package/dist/types.js +3 -0
  73. package/dist/types.js.map +1 -0
  74. package/dist/utils/billing.d.ts +40 -0
  75. package/dist/utils/billing.js +165 -0
  76. package/dist/utils/billing.js.map +1 -0
  77. package/dist/utils/confirm.d.ts +3 -0
  78. package/dist/utils/confirm.js +242 -0
  79. package/dist/utils/confirm.js.map +1 -0
  80. package/dist/utils/display.d.ts +10 -0
  81. package/dist/utils/display.js +121 -0
  82. package/dist/utils/display.js.map +1 -0
  83. package/dist/utils/interrupt.d.ts +5 -0
  84. package/dist/utils/interrupt.js +13 -0
  85. package/dist/utils/interrupt.js.map +1 -0
  86. package/dist/utils/markdown.d.ts +18 -0
  87. package/dist/utils/markdown.js +223 -0
  88. package/dist/utils/markdown.js.map +1 -0
  89. package/package.json +42 -0
package/README.md ADDED
@@ -0,0 +1,351 @@
1
+ # CodeGrunt <small>(代码民工)</small>
2
+
3
+ <p align="center">
4
+ <img src="./assets/logo.png" alt="CodeGrunt Logo" width="50%" />
5
+ </p>
6
+
7
+ > **代码民工** — 终端原生的 AI 命令行编程助手,基于 DeepSeek 构建。
8
+
9
+ [![npm version](https://img.shields.io/npm/v/codegrunt.svg)](https://www.npmjs.com/package/codegrunt)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)](https://www.typescriptlang.org/)
12
+ [![Node.js](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/)
13
+
14
+ CodeGrunt 是一个开源的终端原生 AI 编程助手。它能读懂你的代码库、理解上下文,帮助你在命令行中编写、重构、调试和交付代码。
15
+
16
+ ```bash
17
+ # 交互式 REPL
18
+ codegrunt
19
+
20
+ # 单次任务
21
+ codegrunt "把 auth 模块重构为 async/await"
22
+ ```
23
+
24
+ ---
25
+
26
+ ## 特性
27
+
28
+ - **🤖 智能代理** — 使用 ReAct(推理 + 行动)循环,自主执行多步骤任务:读取文件、编辑代码、运行 Shell、搜索代码库
29
+ - **📂 理解代码库** — 通过 `@` 文件引用和项目指南文件(`CODEGRUNT.md` / `CLAUDE.md`)理解你的项目结构、模块导入和编码约定
30
+ - **🔌 DeepSeek 驱动** — 内置支持 DeepSeek Chat、V4 Flash、V4 Pro 和 R1 推理模型
31
+ - **🛠️ 工具调用** — 6 个内置工具:文件读写/编辑、Shell 执行、目录列表、代码搜索,破坏性操作会显示 diff 预览并请求用户确认
32
+ - **⚡ 流式输出** — 实时 Token 流式传输,支持 Markdown 渲染和推理过程可见,终端体验流畅
33
+ - **📎 @-引用** — 使用 `@file.ts`、`@src/` 或 `@https://example.com` 将文件内容、目录列表或网页内容直接注入提示词
34
+ - **🎯 斜杠命令** — `/init` 自动生成项目指南、`/model` 切换模型、`/compact` 压缩对话历史、`/review` 审查变更、`/skills` 管理技能等
35
+ - **🔒 默认安全** — 破坏性操作(写入/编辑/Shell)显示 diff 预览并要求用户确认后执行
36
+ - **🔧 技能系统** — 从 `.zip` 文件安装可复用的提示词模板,作为斜杠命令运行
37
+ - **💲 费用追踪** — 使用 `/cost` 和 `/balance` 命令实时查看会话 Token 用量和费用
38
+
39
+ ---
40
+
41
+ ## 快速开始
42
+
43
+ ```bash
44
+ # 全局安装
45
+ npm install -g codegrunt
46
+
47
+ # 设置 API 密钥
48
+ export DEEPSEEK_API_KEY=your_key_here
49
+
50
+ # 启动交互式会话
51
+ codegrunt
52
+
53
+ # 单次任务
54
+ codegrunt "解释这个项目的架构"
55
+ ```
56
+
57
+ 首次运行且未配置 API 密钥时,CodeGrunt 会启动交互式设置向导引导你完成配置。
58
+
59
+ ---
60
+
61
+ ## 安装
62
+
63
+ **环境要求:** Node.js 18+
64
+
65
+ ### npm(推荐)
66
+
67
+ ```bash
68
+ npm install -g codegrunt
69
+ ```
70
+
71
+ ### pnpm
72
+
73
+ ```bash
74
+ pnpm add -g codegrunt
75
+ ```
76
+
77
+ ### 从源码构建
78
+
79
+ ```bash
80
+ git clone https://github.com/your-org/codegrunt.git
81
+ cd codegrunt
82
+ npm install
83
+ npm run build
84
+ npm link
85
+ ```
86
+
87
+ ---
88
+
89
+ ## 使用方法
90
+
91
+ ### 交互式 REPL
92
+
93
+ ```bash
94
+ codegrunt
95
+ ```
96
+
97
+ 启动交互式会话,提供:
98
+
99
+ - 显示当前模型的 ASCII 艺术横幅
100
+ - `>` 提示符用于输入任务
101
+ - 文件路径(`@`)和斜杠命令(`/`)的 Tab 补全
102
+ - 多行输入支持
103
+ - 方向键历史记录导航
104
+
105
+ ### 单次任务模式
106
+
107
+ ```bash
108
+ codegrunt "你的任务描述"
109
+ ```
110
+
111
+ 执行单个任务后退出。适用于脚本编写和快速查询。
112
+
113
+ ### 斜杠命令
114
+
115
+ | 命令 | 描述 |
116
+ |---|---|
117
+ | `/help` | 显示帮助信息和所有可用命令 |
118
+ | `/model` | 交互式切换模型(方向键选择器) |
119
+ | `/model <id>` | 切换到指定模型(例如 `/model deepseek-v4-pro`) |
120
+ | `/init` | 分析代码库并生成 `CODEGRUNT.md` 项目指南 |
121
+ | `/clear` | 清除对话上下文 |
122
+ | `/compact` | 总结并压缩对话历史以节省 Token |
123
+ | `/review` | 审查本次会话的变更是否有逻辑问题 |
124
+ | `/cost` | 显示会话 Token 使用量和预估费用 |
125
+ | `/balance` | 显示账户余额和用量(今日 / 本月) |
126
+ | `/config` | 显示或修改配置设置 |
127
+ | `/reasoning` / `/effort` | 设置 R1 模型的推理强度(low/medium/high) |
128
+ | `/token` | 更新 DeepSeek API 密钥 |
129
+ | `/skills` | 列出和管理技能(创建、列表) |
130
+ | `/exit` | 退出 CodeGrunt |
131
+
132
+ ### @-引用
133
+
134
+ 在提示词中直接引用文件、目录或 URL:
135
+
136
+ | 语法 | 描述 | 示例 |
137
+ |---|---|---|
138
+ | `@<文件>` | 注入文件内容 | `@src/index.ts` |
139
+ | `@<目录>` | 注入目录列表(最多 20 条) | `@src/components/` |
140
+ | `@<网址>` | 获取并注入网页内容 | `@https://example.com` |
141
+
142
+ 支持文件和目录路径的 Tab 补全。
143
+
144
+ ---
145
+
146
+ ## 配置
147
+
148
+ CodeGrunt 通过环境变量或 `~/.codegrunt/config.json` 文件配置。
149
+
150
+ ### 环境变量
151
+
152
+ | 变量 | 描述 | 默认值 |
153
+ |---|---|---|
154
+ | `DEEPSEEK_API_KEY` | DeepSeek API 密钥 | — |
155
+ | `CODEGRUNT_MODEL` | 使用的模型 ID | `deepseek-v4-pro` |
156
+ | `CODEGRUNT_PROVIDER` | LLM 提供商 | `deepseek` |
157
+ | `CODEGRUNT_MAX_TOKENS` | 每次响应的最大 Token 数 | `8192` |
158
+ | `CODEGRUNT_TEMPERATURE` | 响应温度 (0-2) | `0.2` |
159
+ | `CODEGRUNT_BASE_URL` | 自定义 API 基础 URL | `https://api.deepseek.com` |
160
+ | `CODEGRUNT_REASONING_EFFORT` | R1 推理强度:`low` \| `medium` \| `high` | `medium` |
161
+ | `CODEGRUNT_TOP_P` | 核采样 (0-1) | `1` |
162
+ | `CODEGRUNT_FREQUENCY_PENALTY` | 重复惩罚 (-2 到 2) | `0` |
163
+ | `CODEGRUNT_PRESENCE_PENALTY` | 主题多样性惩罚 (-2 到 2) | `0` |
164
+
165
+ ### 配置文件 (`~/.codegrunt/config.json`)
166
+
167
+ ```json
168
+ {
169
+ "apiKey": "sk-xxxxxxxx",
170
+ "model": "deepseek-v4-pro",
171
+ "maxTokens": 8192,
172
+ "temperature": 0.2,
173
+ "reasoningEffort": "medium",
174
+ "topP": 1,
175
+ "frequencyPenalty": 0,
176
+ "presencePenalty": 0
177
+ }
178
+ ```
179
+
180
+ 配置文件在首次运行时通过设置向导自动生成。环境变量优先级高于配置文件。
181
+
182
+ ---
183
+
184
+ ## 支持的模型
185
+
186
+ | 提供商 | 模型 | 状态 |
187
+ |---|---|---|
188
+ | [DeepSeek](https://platform.deepseek.com/) | `deepseek-chat`、`deepseek-v4-flash`、`deepseek-v4-pro`、`deepseek-reasoner` | ✅ 支持 |
189
+
190
+ ---
191
+
192
+ ## 架构
193
+
194
+ ```
195
+ codegrunt/
196
+ ├── src/
197
+ │ ├── cli/ # CLI 入口、REPL、参数解析
198
+ │ │ ├── index.ts # 入口(commander 驱动)
199
+ │ │ ├── repl.ts # 交互式 REPL 循环
200
+ │ │ ├── input.ts # 多行输入、Tab 补全、列表选择器
201
+ │ │ ├── commands.ts # 斜杠命令(/help, /model, /init 等)
202
+ │ │ ├── setup.ts # 首次运行设置向导
203
+ │ │ ├── skills.ts # 技能加载和管理
204
+ │ │ ├── update.ts # 版本检查和升级
205
+ │ │ ├── banner.ts # ASCII 艺术横幅
206
+ │ │ └── at-resolver.ts # @文件/@URL 引用展开
207
+ │ ├── core/
208
+ │ │ ├── agent/
209
+ │ │ │ └── loop.ts # 代理循环 — 核心 ReAct 推理/行动循环
210
+ │ │ ├── tools/
211
+ │ │ │ ├── registry.ts # 工具注册和查找
212
+ │ │ │ ├── executor.ts # 工具执行(含用户确认)
213
+ │ │ │ ├── read_file.ts # 读取文件内容
214
+ │ │ │ ├── write_file.ts # 写入内容到文件
215
+ │ │ │ ├── edit_file.ts # 替换文件中的精确字符串
216
+ │ │ │ ├── execute_shell.ts # 运行 Shell 命令
217
+ │ │ │ ├── list_directory.ts # 列出目录树
218
+ │ │ │ └── search_files.ts # 在文件中搜索文本
219
+ │ │ └── context/
220
+ │ │ ├── manager.ts # 上下文窗口管理(Token 预算、裁剪)
221
+ │ │ └── project-guide.ts # 加载 CODEGRUNT.md / CLAUDE.md 项目指南
222
+ │ ├── providers/
223
+ │ │ └── deepseek/
224
+ │ │ ├── provider.ts # DeepSeek LLM 提供商实现
225
+ │ │ └── client.ts # OpenAI 兼容客户端工厂
226
+ │ ├── utils/
227
+ │ │ ├── display.ts # 终端输出格式化
228
+ │ │ ├── confirm.ts # Diff 预览和用户确认
229
+ │ │ ├── billing.ts # 余额/用量查询和费用展示
230
+ │ │ ├── markdown.ts # 流式 Markdown 转终端渲染器
231
+ │ │ └── interrupt.ts # SIGINT 处理
232
+ │ ├── config.ts # 配置加载(环境变量、配置文件)
233
+ │ └── types.ts # 共享 TypeScript 类型和接口
234
+ ├── tests/
235
+ │ ├── tools/
236
+ │ │ ├── read_file.test.ts
237
+ │ │ ├── write_file.test.ts
238
+ │ │ └── execute_shell.test.ts
239
+ ├── docs/
240
+ │ ├── development-guide.md # 开发指南(英文)
241
+ │ ├── development-guide.zh-CN.md # 开发者指南(中文)
242
+ │ └── VERSION.md # 发版流程指南
243
+ ├── package.json
244
+ ├── tsconfig.json
245
+ ├── vitest.config.ts
246
+ ├── CODEGRUNT.md # CodeGrunt 项目指南
247
+ ├── CLAUDE.md # AI 编码助手项目指南
248
+ └── README.md # 本文件
249
+ ```
250
+
251
+ ### 整体流程
252
+
253
+ ```
254
+ 用户输入 (CLI / REPL)
255
+
256
+
257
+ ┌─────────────┐
258
+ │ 代理循环 │ ◄──── LLM 提供商(流式)
259
+ │ (loop.ts) │ ────► 工具执行
260
+ └──────┬──────┘
261
+
262
+ ┌────┴────┐
263
+ │ 工具 │
264
+ │ (6 个) │
265
+ └─────────┘
266
+ ```
267
+
268
+ ### 代理循环 (`src/core/agent/loop.ts`)
269
+
270
+ 代理循环是 CodeGrunt 的核心,遵循 ReAct(推理 + 行动)模式:
271
+
272
+ 1. **系统提示**在每次会话中构建一次(保持稳定以最大化提示缓存命中率)
273
+ 2. **用户消息**附加 `[cwd]` 和 `[date]` 前缀以提供上下文
274
+ 3. **流式响应**来自 LLM — 处理文本增量、推理增量和工具调用增量
275
+ 4. **如果收到工具调用**,执行每个工具并将结果反馈给 LLM
276
+ 5. **如果是文本响应**(finish_reason = "stop"),输出给用户并结束
277
+ 6. **循环**最多 30 次迭代以处理多步骤任务
278
+
279
+ 关键设计决策:
280
+
281
+ - **系统提示稳定性**:系统提示只构建一次,会话期间不会更改。这最大化 DeepSeek 的提示缓存命中率。
282
+ - **上下文管理**:`ContextManager` 跟踪 Token 使用情况,超出预算时裁剪旧消息。
283
+ - **流式优先**:所有 LLM 通信通过 `AsyncIterable` 流式传输,实现实时终端输出。
284
+
285
+ ### 工具系统
286
+
287
+ 工具是 LLM 与用户环境交互的方式。每个工具实现 `Tool` 接口。
288
+
289
+ | 工具 | 描述 |
290
+ |---|---|
291
+ | `read_file` | 读取文件内容(截断至 30,000 字符) |
292
+ | `write_file` | 写入内容到文件(自动创建目录) |
293
+ | `edit_file` | 替换文件中的精确字符串 |
294
+ | `execute_shell` | 运行 Shell 命令(带超时) |
295
+ | `list_directory` | 列出目录树(可配置深度) |
296
+ | `search_files` | 在文件中搜索文本模式 |
297
+
298
+ **安全机制**:在执行破坏性操作(`write_file`、`edit_file`、`execute_shell`)之前,执行器会显示 diff 预览并请求用户确认,提供三个选项:是、本次会话全部允许、否。
299
+
300
+ ### 上下文管理 (`src/core/context/manager.ts`)
301
+
302
+ `ContextManager` 维护对话历史:
303
+
304
+ - **Token 估算**:使用简单的 4:1 字符与 Token 比率
305
+ - **裁剪**:当估算 Token 数超过预算时,移除最旧的非系统消息
306
+ - **预算**:聊天模型默认 90,000 Token,推理模型 100,000 Token(1M 上下文窗口)
307
+
308
+ ### 提供商系统
309
+
310
+ DeepSeek 提供商实现 `LLMProvider` 接口。`StreamChunk` 判别联合类型支持:
311
+
312
+ - `text_delta` — 增量文本输出
313
+ - `reasoning_delta` — 思维链推理(显示为 "Thinking...")
314
+ - `tool_call_delta` — 流式工具调用参数
315
+ - `finish` — 流结束,包含结束原因
316
+
317
+ ---
318
+
319
+ ## 开发
320
+
321
+ ### 命令
322
+
323
+ ```bash
324
+ npm run dev # 开发模式,热重载 (tsx)
325
+ npm run build # 编译 TypeScript 到 dist/
326
+ npm run typecheck # 仅类型检查,不输出文件
327
+ npm test # 运行 vitest 测试套件
328
+ npm start # 运行编译后的 dist/cli/index.js
329
+
330
+ # 运行单个测试文件
331
+ npx vitest run tests/tools/read_file.test.ts
332
+ ```
333
+
334
+ ### 项目结构
335
+
336
+ - `src/cli/` — 入口、REPL 循环、参数解析、技能、更新
337
+ - `src/core/agent/` — 代理循环和任务规划
338
+ - `src/core/tools/` — 文件读写、Shell 执行、搜索工具实现
339
+ - `src/core/context/` — 上下文窗口管理和项目指南加载
340
+ - `src/providers/` — LLM 提供商适配器,实现共享的 `LLMProvider` 接口
341
+ - `src/utils/` — 共享工具(显示、确认、计费、Markdown、中断)
342
+
343
+ 详细开发说明请参阅:
344
+ - [开发指南(英文)](docs/development-guide.md)
345
+ - [开发者指南(中文)](docs/development-guide.zh-CN.md)
346
+
347
+ ---
348
+
349
+ ## 许可证
350
+
351
+ MIT
@@ -0,0 +1,10 @@
1
+ export interface AtReference {
2
+ raw: string;
3
+ type: 'file' | 'directory' | 'url';
4
+ target: string;
5
+ content: string;
6
+ }
7
+ export declare function resolveAtReferences(input: string, cwd: string): Promise<{
8
+ expanded: string;
9
+ refs: AtReference[];
10
+ }>;
@@ -0,0 +1,138 @@
1
+ import { readFile, readdir, stat } from 'fs/promises';
2
+ import { resolve, relative, join } from 'path';
3
+ import chalk from 'chalk';
4
+ const MAX_FILE_CHARS = 8000;
5
+ const MAX_DIR_FILES = 20;
6
+ const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', '.next', '__pycache__', '.cache']);
7
+ // Match @something — file path, directory, or URL
8
+ // Stops at whitespace. Supports quoted paths: @"path with spaces"
9
+ const AT_PATTERN = /@(?:"([^"]+)"|(\S+))/g;
10
+ export async function resolveAtReferences(input, cwd) {
11
+ const matches = [...input.matchAll(AT_PATTERN)];
12
+ if (matches.length === 0)
13
+ return { expanded: input, refs: [] };
14
+ const refs = [];
15
+ for (const match of matches) {
16
+ const raw = match[0];
17
+ const target = match[1] ?? match[2]; // quoted or unquoted
18
+ const ref = await resolveOne(raw, target, cwd);
19
+ if (ref)
20
+ refs.push(ref);
21
+ }
22
+ // Replace @tokens with a placeholder; append expanded content at the end
23
+ let expanded = input;
24
+ const attachments = [];
25
+ for (const ref of refs) {
26
+ expanded = expanded.replace(ref.raw, chalk.cyan(ref.raw));
27
+ attachments.push(formatAttachment(ref));
28
+ }
29
+ // Strip chalk codes for the actual message sent to the model
30
+ const plainExpanded = stripAnsi(expanded);
31
+ const fullMessage = attachments.length > 0
32
+ ? plainExpanded + '\n\n' + attachments.join('\n\n')
33
+ : plainExpanded;
34
+ return { expanded: fullMessage, refs };
35
+ }
36
+ async function resolveOne(raw, target, cwd) {
37
+ // URL
38
+ if (target.startsWith('http://') || target.startsWith('https://')) {
39
+ const content = await fetchUrl(target);
40
+ return { raw, type: 'url', target, content };
41
+ }
42
+ const absPath = resolve(cwd, target);
43
+ try {
44
+ const info = await stat(absPath);
45
+ if (info.isDirectory()) {
46
+ const content = await readDirContents(absPath, cwd);
47
+ return { raw, type: 'directory', target: absPath, content };
48
+ }
49
+ else {
50
+ const content = await readFileContents(absPath);
51
+ return { raw, type: 'file', target: absPath, content };
52
+ }
53
+ }
54
+ catch {
55
+ // path doesn't exist — leave as-is, don't inject
56
+ process.stderr.write(chalk.yellow(` @ warning: "${target}" not found, skipping\n`));
57
+ return null;
58
+ }
59
+ }
60
+ async function readFileContents(filePath) {
61
+ const raw = await readFile(filePath, 'utf-8');
62
+ if (raw.length > MAX_FILE_CHARS) {
63
+ return raw.slice(0, MAX_FILE_CHARS) + `\n\n[truncated — ${raw.length} total chars]`;
64
+ }
65
+ return raw;
66
+ }
67
+ async function readDirContents(dirPath, cwd) {
68
+ const lines = [];
69
+ await collectFiles(dirPath, dirPath, lines);
70
+ const rel = relative(cwd, dirPath) || '.';
71
+ return `Directory: ${rel}\n` + lines.join('\n');
72
+ }
73
+ async function collectFiles(root, dir, lines, depth = 0) {
74
+ if (lines.length >= MAX_DIR_FILES)
75
+ return;
76
+ const entries = await readdir(dir, { withFileTypes: true });
77
+ entries.sort((a, b) => {
78
+ if (a.isDirectory() !== b.isDirectory())
79
+ return a.isDirectory() ? -1 : 1;
80
+ return a.name.localeCompare(b.name);
81
+ });
82
+ for (const entry of entries) {
83
+ if (lines.length >= MAX_DIR_FILES)
84
+ break;
85
+ if (entry.name.startsWith('.'))
86
+ continue;
87
+ const full = join(dir, entry.name);
88
+ const rel = relative(root, full);
89
+ const indent = ' '.repeat(depth);
90
+ if (entry.isDirectory()) {
91
+ if (SKIP_DIRS.has(entry.name))
92
+ continue;
93
+ lines.push(`${indent}${entry.name}/`);
94
+ await collectFiles(root, full, lines, depth + 1);
95
+ }
96
+ else {
97
+ lines.push(`${indent}${entry.name}`);
98
+ }
99
+ }
100
+ }
101
+ async function fetchUrl(url) {
102
+ try {
103
+ const res = await fetch(url, { signal: AbortSignal.timeout(10_000) });
104
+ if (!res.ok)
105
+ return `[HTTP ${res.status} fetching ${url}]`;
106
+ const text = await res.text();
107
+ // Strip HTML tags for readability
108
+ const stripped = text.replace(/<[^>]+>/g, ' ').replace(/\s{2,}/g, ' ').trim();
109
+ return stripped.length > MAX_FILE_CHARS
110
+ ? stripped.slice(0, MAX_FILE_CHARS) + '\n[truncated]'
111
+ : stripped;
112
+ }
113
+ catch (err) {
114
+ return `[Failed to fetch ${url}: ${err instanceof Error ? err.message : String(err)}]`;
115
+ }
116
+ }
117
+ function formatAttachment(ref) {
118
+ const label = ref.type === 'url' ? `URL: ${ref.target}` :
119
+ ref.type === 'directory' ? `Directory: ${ref.target}` :
120
+ `File: ${ref.target}`;
121
+ const fence = ref.type === 'url' ? '' : detectLanguage(ref.target);
122
+ return `<attachment ${label}>\n\`\`\`${fence}\n${ref.content}\n\`\`\`\n</attachment>`;
123
+ }
124
+ function detectLanguage(filePath) {
125
+ const ext = filePath.split('.').pop()?.toLowerCase() ?? '';
126
+ const map = {
127
+ ts: 'typescript', tsx: 'tsx', js: 'javascript', jsx: 'jsx',
128
+ py: 'python', rs: 'rust', go: 'go', java: 'java',
129
+ json: 'json', md: 'markdown', yaml: 'yaml', yml: 'yaml',
130
+ sh: 'bash', css: 'css', html: 'html', sql: 'sql',
131
+ };
132
+ return map[ext] ?? '';
133
+ }
134
+ function stripAnsi(str) {
135
+ // eslint-disable-next-line no-control-regex
136
+ return str.replace(/\x1B\[[0-9;]*m/g, '');
137
+ }
138
+ //# sourceMappingURL=at-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"at-resolver.js","sourceRoot":"","sources":["../../src/cli/at-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function printBanner(model: string): void;
@@ -0,0 +1,111 @@
1
+ import chalk from 'chalk';
2
+ // ── CODEGRUNT wordmark — pixel art ──────────────────────────────────────────
3
+ const GLYPHS = {
4
+ C: [
5
+ ' ▄███▄ ',
6
+ ' ██ ',
7
+ ' ██ ',
8
+ ' ██ ',
9
+ ' ▀███▀ ',
10
+ ],
11
+ O: [
12
+ ' ▄███▄ ',
13
+ ' ██ █ ',
14
+ ' ██ █ ',
15
+ ' ██ █ ',
16
+ ' ▀███▀ ',
17
+ ],
18
+ D: [
19
+ ' ████▄ ',
20
+ ' ██ █ ',
21
+ ' ██ █ ',
22
+ ' ██ █ ',
23
+ ' ████▀ ',
24
+ ],
25
+ E: [
26
+ ' █████ ',
27
+ ' ██ ',
28
+ ' ████ ',
29
+ ' ██ ',
30
+ ' █████ ',
31
+ ],
32
+ G: [
33
+ ' ▄███▄ ',
34
+ ' ██ ',
35
+ ' ██ ██ ',
36
+ ' ██ █ ',
37
+ ' ▀███▀ ',
38
+ ],
39
+ R: [
40
+ ' ████▄ ',
41
+ ' ██ █ ',
42
+ ' ████▀ ',
43
+ ' ██▄ ',
44
+ ' ██ █ ',
45
+ ],
46
+ U: [
47
+ ' █ █ ',
48
+ ' █ █ ',
49
+ ' █ █ ',
50
+ ' █ █ ',
51
+ ' ▀███▀ ',
52
+ ],
53
+ N: [
54
+ ' █ █ ',
55
+ ' ██ █ ',
56
+ ' █ █ █ ',
57
+ ' █ ██ ',
58
+ ' █ █ ',
59
+ ],
60
+ T: [
61
+ ' █████ ',
62
+ ' █ ',
63
+ ' █ ',
64
+ ' █ ',
65
+ ' █ ',
66
+ ],
67
+ ' ': [
68
+ ' ',
69
+ ' ',
70
+ ' ',
71
+ ' ',
72
+ ' ',
73
+ ],
74
+ };
75
+ const WORD = 'CODEGRUNT';
76
+ export function printBanner(model) {
77
+ const cols = process.stdout.columns || 80;
78
+ const termH = process.stdout.rows || 24;
79
+ // Blue accent
80
+ const blue = (s) => chalk.hex('#4A90D9')(s);
81
+ const dim = chalk.gray;
82
+ const bold = chalk.bold;
83
+ // Skip glyphs when terminal is too short
84
+ const skipGlyphs = termH < 14;
85
+ if (!skipGlyphs) {
86
+ // Build the wordmark row by row
87
+ const rows = Array.from({ length: 5 }, () => '');
88
+ for (let i = 0; i < WORD.length; i++) {
89
+ const ch = WORD[i];
90
+ const glyph = GLYPHS[ch] ?? GLYPHS[' '];
91
+ for (let r = 0; r < 5; r++) {
92
+ rows[r] += (i > 0 ? ' ' : '') + glyph[r];
93
+ }
94
+ }
95
+ // Centre the wordmark
96
+ process.stdout.write('\n');
97
+ for (const row of rows) {
98
+ const pad = Math.max(0, Math.floor((cols - row.length) / 2));
99
+ process.stdout.write(' '.repeat(pad) + blue(row) + '\n');
100
+ }
101
+ process.stdout.write('\n');
102
+ }
103
+ // ── Version/model info line ────────────────────────────────────────────
104
+ process.stdout.write(' ' +
105
+ bold.white('CodeGrunt') +
106
+ dim(' v0.1.0 · model: ') +
107
+ blue(model) +
108
+ dim(' · /help for commands') +
109
+ '\n\n');
110
+ }
111
+ //# sourceMappingURL=banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/cli/banner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { LLMProvider, CodeGruntConfig } from '../types.js';
2
+ import type { ContextManager } from '../core/context/manager.js';
3
+ import type { Skill } from './skills.js';
4
+ export type SlashCommandResult = {
5
+ type: 'handled';
6
+ } | {
7
+ type: 'clear';
8
+ } | {
9
+ type: 'config_changed';
10
+ config: CodeGruntConfig;
11
+ } | {
12
+ type: 'model_changed';
13
+ config: CodeGruntConfig;
14
+ } | {
15
+ type: 'exit';
16
+ } | {
17
+ type: 'skill_run';
18
+ prompt: string;
19
+ system?: string;
20
+ } | {
21
+ type: 'skills_reload';
22
+ } | {
23
+ type: 'not_a_command';
24
+ };
25
+ export declare function handleSlashCommand(input: string, cwd: string, config: CodeGruntConfig, provider: LLMProvider, context: ContextManager, skills?: Skill[]): Promise<SlashCommandResult>;