@twinklerg/coden 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.
- package/LICENSE +21 -0
- package/README.md +219 -0
- package/dist/index.js +21269 -0
- package/package.json +48 -0
- package/src/cli/agent-command.ts +497 -0
- package/src/cli/format.ts +42 -0
- package/src/cli/index.ts +149 -0
- package/src/cli/plugin-command.ts +217 -0
- package/src/config/config.ts +96 -0
- package/src/config/trust.ts +35 -0
- package/src/context/manager.ts +186 -0
- package/src/context/truncate.ts +9 -0
- package/src/core/events.ts +32 -0
- package/src/core/runtime.ts +402 -0
- package/src/core/types.ts +97 -0
- package/src/index.ts +14 -0
- package/src/observability/terminal.ts +201 -0
- package/src/observability/trace.ts +30 -0
- package/src/permissions/policy.ts +56 -0
- package/src/permissions/workspace.ts +139 -0
- package/src/plugins/api.ts +68 -0
- package/src/plugins/bun-package-manager.ts +35 -0
- package/src/plugins/installed-loader.ts +144 -0
- package/src/plugins/installer.ts +314 -0
- package/src/plugins/manifest.ts +89 -0
- package/src/plugins/package-manager.ts +10 -0
- package/src/plugins/package-metadata.ts +95 -0
- package/src/plugins/paths.ts +43 -0
- package/src/plugins/specifier.ts +63 -0
- package/src/plugins/transaction.ts +403 -0
- package/src/process/runner.ts +134 -0
- package/src/providers/anthropic.ts +117 -0
- package/src/providers/openai.ts +96 -0
- package/src/providers/scripted.ts +28 -0
- package/src/sessions/store.ts +278 -0
- package/src/tools/builtin/bash.ts +56 -0
- package/src/tools/builtin/edit.ts +42 -0
- package/src/tools/builtin/index.ts +9 -0
- package/src/tools/builtin/read.ts +91 -0
- package/src/tools/builtin/write.ts +34 -0
- package/src/tools/executor.ts +90 -0
- package/src/tools/plugin-loader.ts +122 -0
- package/src/tools/registry.ts +97 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TwinklerG
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# CodeN
|
|
2
|
+
|
|
3
|
+
<!-- markdownlint-disable MD013 -->
|
|
4
|
+
|
|
5
|
+
CodeN(Code NJU)是一个用 TypeScript 独立实现的极简编程智能体。它直接使用模型原生 Tool Calling,在本地读取、修改文件和执行命令;不依赖 Agent 框架或服务端代码执行。
|
|
6
|
+
|
|
7
|
+
## 要求与安装
|
|
8
|
+
|
|
9
|
+
- [Bun](https://bun.sh/) 1.1+
|
|
10
|
+
- [Just](https://github.com/casey/just)
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bun install
|
|
14
|
+
just check
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
源码仅使用标准 Web/Node.js API;Bun 负责依赖、脚本和 TypeScript 插件运行。
|
|
18
|
+
|
|
19
|
+
## 使用
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
export CODEN_OPENAI_API_KEY=...
|
|
23
|
+
bun run src/cli/index.ts "修复当前项目的测试失败"
|
|
24
|
+
bun run src/cli/index.ts -p --auto "实现功能并运行测试"
|
|
25
|
+
|
|
26
|
+
export CODEN_ANTHROPIC_API_KEY=...
|
|
27
|
+
bun run src/cli/index.ts --provider anthropic --model claude-sonnet-4-20250514
|
|
28
|
+
|
|
29
|
+
bun run src/cli/index.ts --resume <session-id>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
也可执行 `just run -- --help`。无 prompt 时进入 REPL,支持 `/help`、`/session`、`/compact`、`/reload`、`/new` 和 `/quit`。
|
|
33
|
+
|
|
34
|
+
核心选项:`--provider`、`--model`、`--resume`、`--auto`、`--verbose`、`--max-steps` 和可重复的 `--plugin`。
|
|
35
|
+
|
|
36
|
+
## 配置
|
|
37
|
+
|
|
38
|
+
优先级:CLI > 环境变量 > `<workspace>/.coden/config.json` > `~/.config/coden/config.json` > 默认值。
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"provider": "openai",
|
|
43
|
+
"model": "gpt-5-mini",
|
|
44
|
+
"maxSteps": 20,
|
|
45
|
+
"contextWindow": 128000,
|
|
46
|
+
"reservedOutputTokens": 8192,
|
|
47
|
+
"safetyMargin": 4096,
|
|
48
|
+
"plugins": []
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
支持 `CODEN_PROVIDER`、`CODEN_MODEL`、`CODEN_MAX_STEPS`、`CODEN_OPENAI_API_KEY`、`CODEN_OPENAI_BASE_URL`、`CODEN_ANTHROPIC_API_KEY`、`XDG_CONFIG_HOME` 和 `XDG_DATA_HOME`。凭据只从环境读取。
|
|
53
|
+
|
|
54
|
+
会话和 trace 位于 `$XDG_DATA_HOME/coden/sessions/<workspace-hash>/`(默认 `~/.local/share/coden`)。
|
|
55
|
+
|
|
56
|
+
## 工具与权限
|
|
57
|
+
|
|
58
|
+
默认且仅默认暴露四个工具:`read`、`write`、`edit` 和 `bash`。文件工具拒绝工作区外路径及符号链接逃逸。默认模式自动执行读取,修改需确认,递归删除、`sudo`、破坏性 Git 等高风险命令每次确认。`--auto` 跳过确认,但仍进行 Schema 校验和文件工作区检查。
|
|
59
|
+
|
|
60
|
+
**这不是通用安全沙箱。** `bash` 和 TypeScript 插件拥有当前用户进程权限;风险分类是防误操作的启发式护栏。Bash 超时会终止其进程组;主进程内的插件只能通过 `AbortSignal` 协作取消,忽略信号的可信插件可能在超时结果返回后继续运行。
|
|
61
|
+
|
|
62
|
+
## 本地 TypeScript 插件
|
|
63
|
+
|
|
64
|
+
CodeN 扫描:
|
|
65
|
+
|
|
66
|
+
- `~/.config/coden/plugins/*.ts`
|
|
67
|
+
- `<workspace>/.coden/plugins/*.ts`
|
|
68
|
+
- `--plugin` 或配置中的附加目录
|
|
69
|
+
|
|
70
|
+
项目插件首次加载需信任确认(`--auto` 跳过)。插件应避免模块顶层副作用;`/reload` 基于内容哈希重建模块并原子替换 Registry(内容未变的插件复用已加载模块)。
|
|
71
|
+
|
|
72
|
+
**插件必须是自包含单文件**:Bun 的模块缓存按真实路径去重且忽略查询参数,因此 CodeN 通过 `data:text/typescript` URL 加载插件源码以保证重载生效——相对路径导入(`./helper.ts`)无法解析,npm 包导入(`import pc from "picocolors"`)正常工作。
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
import type { ToolDefinition } from "../../src/core/types.js";
|
|
76
|
+
|
|
77
|
+
const tool: ToolDefinition = {
|
|
78
|
+
name: "line_count",
|
|
79
|
+
description: "Count lines in supplied text",
|
|
80
|
+
risk: "read",
|
|
81
|
+
inputSchema: {
|
|
82
|
+
type: "object",
|
|
83
|
+
additionalProperties: false,
|
|
84
|
+
required: ["text"],
|
|
85
|
+
properties: { text: { type: "string" } },
|
|
86
|
+
},
|
|
87
|
+
async execute(input) {
|
|
88
|
+
const { text } = input as { text: string };
|
|
89
|
+
return { content: String(text.split("\n").length) };
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export default tool;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
插件失败或重名不会覆盖内置工具,也不会阻止其他插件。
|
|
97
|
+
|
|
98
|
+
## npm 插件
|
|
99
|
+
|
|
100
|
+
CodeN 也支持从公开 npmjs 安装构建后的工具插件。首版只接受 `npm:<package>` 或 `npm:<package>@<version-or-tag>`,固定使用 `https://registry.npmjs.org`,不支持私有 Registry、Git、URL 或本地目录源。
|
|
101
|
+
|
|
102
|
+
常用命令:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
coden plugin install npm:@scope/coden-plugin-example
|
|
106
|
+
coden plugin install npm:@scope/coden-plugin-example@^2 --global
|
|
107
|
+
coden plugin list
|
|
108
|
+
coden plugin sync
|
|
109
|
+
coden plugin remove @scope/coden-plugin-example
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
默认安装到当前项目;`--global` 安装到当前用户。项目级文件位于:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
<workspace>/.coden/plugins.json
|
|
116
|
+
<workspace>/.coden/plugin-runtime/.gitignore
|
|
117
|
+
<workspace>/.coden/plugin-runtime/bun.lock
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
这些文件应提交到版本控制;`plugin-runtime/package.json` 由 `plugins.json` 确定性生成,`node_modules/` 不提交。全局插件位于 `$XDG_DATA_HOME/coden/plugins/`(默认 `~/.local/share/coden/plugins/`),不属于项目仓库。
|
|
121
|
+
|
|
122
|
+
项目级 npm 插件需要信任当前工作区:`plugin install` 或 `plugin sync` 确认后会记录工作区真实路径;Agent 启动时未信任的项目 npm 插件会被跳过并提示修复。全局插件视为用户主动安装,不在每次启动时重复确认。
|
|
123
|
+
|
|
124
|
+
安装默认禁用 npm 生命周期脚本(等价于 Bun 的 `--ignore-scripts`)。只有显式传入 `--allow-scripts` 才允许当前包及传递依赖运行 `preinstall`、`install` 或 `postinstall`;`--yes` 只跳过确认,不会自动启用脚本。即使禁用生命周期脚本,CodeN 也会在安装校验时导入插件入口,因此插件顶层代码和静态依赖会以当前用户权限运行。
|
|
125
|
+
|
|
126
|
+
**npm 插件不是安全沙箱。** 它们在 CodeN 主进程中执行,拥有完整用户进程权限,可访问文件、网络、环境变量和子进程。工具 `risk` 只影响调用确认,不隔离权限。
|
|
127
|
+
|
|
128
|
+
安装、删除或升级 npm 插件后需要重启 CodeN。`/reload` 仍只保证重新读取本地 `.ts` 插件;npm 包及其依赖通过真实文件 URL 导入,会被运行时模块缓存。
|
|
129
|
+
|
|
130
|
+
### npm 插件作者协议
|
|
131
|
+
|
|
132
|
+
插件包必须发布构建后的 `.js` 或 `.mjs` 入口(例如 `dist/index.js`),不能发布仅需 CodeN 直接加载的 TypeScript 源码。`package.json` 必须包含 `type: "module"` 和 `coden` 元数据:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"name": "@scope/coden-plugin-example",
|
|
137
|
+
"version": "1.0.0",
|
|
138
|
+
"type": "module",
|
|
139
|
+
"files": ["dist"],
|
|
140
|
+
"coden": {
|
|
141
|
+
"apiVersion": 1,
|
|
142
|
+
"plugin": "./dist/index.js"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
单工具默认导出一个兼容 `ToolDefinition` 的对象:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import type { ToolDefinition } from "coden/plugin";
|
|
151
|
+
|
|
152
|
+
const tool: ToolDefinition = {
|
|
153
|
+
name: "example_echo",
|
|
154
|
+
description: "Echo supplied text",
|
|
155
|
+
risk: "read",
|
|
156
|
+
inputSchema: {
|
|
157
|
+
type: "object",
|
|
158
|
+
additionalProperties: false,
|
|
159
|
+
required: ["text"],
|
|
160
|
+
properties: { text: { type: "string" } },
|
|
161
|
+
},
|
|
162
|
+
async execute(input) {
|
|
163
|
+
const { text } = input as { text: string };
|
|
164
|
+
return { content: text };
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export default tool;
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
多工具默认导出 `CodeNPlugin`,其中 `name` 必须等于 npm 包名:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import type { CodeNPlugin, ToolDefinition } from "coden/plugin";
|
|
175
|
+
|
|
176
|
+
const readTool: ToolDefinition = {
|
|
177
|
+
name: "example_read",
|
|
178
|
+
description: "Read example data",
|
|
179
|
+
risk: "read",
|
|
180
|
+
inputSchema: { type: "object", additionalProperties: false },
|
|
181
|
+
async execute() {
|
|
182
|
+
return { content: "read" };
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const writeTool: ToolDefinition = {
|
|
187
|
+
...readTool,
|
|
188
|
+
name: "example_write",
|
|
189
|
+
description: "Write example data",
|
|
190
|
+
risk: "modify",
|
|
191
|
+
async execute() {
|
|
192
|
+
return { content: "write" };
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const plugin: CodeNPlugin = {
|
|
197
|
+
apiVersion: 1,
|
|
198
|
+
name: "@scope/coden-plugin-example",
|
|
199
|
+
tools: [readTool, writeTool],
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
export default plugin;
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
插件可以把 `coden` 放入 `devDependencies` 以获得 `coden/plugin` 类型;构建产物中的类型导入会被移除,运行时不应加载另一份 CodeN。
|
|
206
|
+
|
|
207
|
+
## 开发与测试
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
just fmt # Biome format
|
|
211
|
+
just test # offline Vitest
|
|
212
|
+
just check # Biome lint + strict tsc + complete offline tests
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
离线集成测试用 `ScriptedProvider` 覆盖工具循环、拒绝、重试和恢复。真实 API 冒烟测试(`test/live.test.ts`)默认跳过,仅在显式设置后运行:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
CODEN_LIVE_TEST=1 CODEN_OPENAI_API_KEY=... bun run test # 可选 CODEN_LIVE_OPENAI_MODEL / CODEN_LIVE_ANTHROPIC_MODEL
|
|
219
|
+
```
|