@lwmxiaobei/xbcode 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/LICENSE +21 -0
- package/README.md +631 -0
- package/README.zh-CN.md +542 -0
- package/dist/agent.js +1450 -0
- package/dist/busy-status.js +29 -0
- package/dist/clipboard-image.js +97 -0
- package/dist/commands.js +109 -0
- package/dist/compact.js +262 -0
- package/dist/config.js +516 -0
- package/dist/error-log.js +80 -0
- package/dist/http.js +89 -0
- package/dist/idle-watchdog.js +88 -0
- package/dist/index.js +2031 -0
- package/dist/input-submit.js +41 -0
- package/dist/mcp/client.js +466 -0
- package/dist/mcp/manager.js +275 -0
- package/dist/mcp/runtime.js +420 -0
- package/dist/mcp/types.js +12 -0
- package/dist/message-bus.js +180 -0
- package/dist/oauth/openai.js +326 -0
- package/dist/prompt.js +156 -0
- package/dist/session-store.js +186 -0
- package/dist/skills/frontmatter.js +85 -0
- package/dist/skills/index.js +2 -0
- package/dist/skills/loader.js +88 -0
- package/dist/skills/render.js +35 -0
- package/dist/skills/types.js +1 -0
- package/dist/subagents.js +64 -0
- package/dist/supervisor.js +58 -0
- package/dist/task-manager.js +280 -0
- package/dist/team-types.js +1 -0
- package/dist/teammate-manager.js +266 -0
- package/dist/tools.js +1068 -0
- package/dist/trust-store.js +42 -0
- package/dist/types.js +1 -0
- package/dist/usage.js +226 -0
- package/dist/utils.js +21 -0
- package/package.json +67 -0
- package/scripts/postinstall.mjs +30 -0
- package/skills/code-review/SKILL.md +22 -0
- package/skills/pdf/SKILL.md +18 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lin Weimin
|
|
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,631 @@
|
|
|
1
|
+
[English](./README.md) | [简体中文](./README.zh-CN.md)
|
|
2
|
+
|
|
3
|
+
# xbcode
|
|
4
|
+
|
|
5
|
+
`xbcode` is a TypeScript-based CLI coding agent built with OpenAI SDK and Ink. It runs in the terminal, streams model output, executes tools inside the current workspace, supports persistent tasks, skills, MCP integration, and lightweight multi-agent teamwork.
|
|
6
|
+
|
|
7
|
+
The project is positioned as a compact, hackable alternative to heavier coding agents: small enough to read end-to-end, but already opinionated enough to be useful in day-to-day coding workflows.
|
|
8
|
+
|
|
9
|
+
## Project Status
|
|
10
|
+
|
|
11
|
+
`xbcode` is an early open source product focused on being practical, readable, and easy to extend. The current priority is reliability, usability, and contributor experience.
|
|
12
|
+
|
|
13
|
+
Related project docs:
|
|
14
|
+
|
|
15
|
+
- [Roadmap](./ROADMAP.md)
|
|
16
|
+
- [Changelog](./CHANGELOG.md)
|
|
17
|
+
- [Contributing](./CONTRIBUTING.md)
|
|
18
|
+
- [Security Policy](./SECURITY.md)
|
|
19
|
+
- [Code of Conduct](./CODE_OF_CONDUCT.md)
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- Terminal-first interactive coding agent UI built with Ink and React
|
|
24
|
+
- Dual API support: OpenAI Responses API and Chat Completions API
|
|
25
|
+
- Workspace-scoped file and shell tools
|
|
26
|
+
- Persistent task board stored on disk in `.tasks/`
|
|
27
|
+
- Skills system with global and repo-local skill loading
|
|
28
|
+
- MCP integration with dynamic MCP tool exposure plus prompt/resource access
|
|
29
|
+
- Persistent teammates with inbox-based asynchronous coordination
|
|
30
|
+
- Context compaction for long-running conversations
|
|
31
|
+
- ESM TypeScript codebase with a small, readable architecture
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install -g @lwmxiaobei/xbcode
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Or run locally in this repo:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install
|
|
45
|
+
npm run dev
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### First-run configuration
|
|
49
|
+
|
|
50
|
+
On install, `xbcode` creates a default config file at:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
~/.xbcode/settings.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Minimal example:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"providers": {
|
|
61
|
+
"openai": {
|
|
62
|
+
"models": ["gpt-4.1", "gpt-4.1-mini", "o3-mini"],
|
|
63
|
+
"apiKey": "YOUR_OPENAI_API_KEY",
|
|
64
|
+
"baseURL": "https://api.openai.com/v1",
|
|
65
|
+
"apiMode": "responses"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"defaultProvider": "openai",
|
|
69
|
+
"showThinking": false,
|
|
70
|
+
"mcp": {
|
|
71
|
+
"servers": []
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Start the CLI
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
xbcode
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Local development:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm run dev
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Build and run compiled output:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm run build
|
|
92
|
+
npm start
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### First prompt
|
|
96
|
+
|
|
97
|
+
After launch, enter a request such as:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
Read the project structure and explain how the agent loop works.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
If `MODEL_ID` is not preset in the environment, the CLI will guide you through interactive provider/model selection from `~/.xbcode/settings.json`.
|
|
104
|
+
|
|
105
|
+
## How It Works
|
|
106
|
+
|
|
107
|
+
At a high level, `xbcode` runs a standard think-act loop:
|
|
108
|
+
|
|
109
|
+
1. Build a system prompt from built-in rules, loaded skill descriptions, MCP instructions, and optional project `AGENTS.md`.
|
|
110
|
+
2. Send the current turn to the selected model.
|
|
111
|
+
3. Stream assistant output into the Ink UI.
|
|
112
|
+
4. Execute tool calls when the model asks for them.
|
|
113
|
+
5. Feed tool results back to the model.
|
|
114
|
+
6. Repeat until the model stops requesting tools.
|
|
115
|
+
|
|
116
|
+
The current implementation supports two backend styles:
|
|
117
|
+
|
|
118
|
+
- `responses`
|
|
119
|
+
Uses OpenAI Responses API and chains turns via `previous_response_id`
|
|
120
|
+
- `chat-completions`
|
|
121
|
+
Uses local chat history and supports compatible endpoints such as DeepSeek-style APIs
|
|
122
|
+
|
|
123
|
+
## User Guide
|
|
124
|
+
|
|
125
|
+
### Commands
|
|
126
|
+
|
|
127
|
+
Package scripts:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npm run dev
|
|
131
|
+
npm run build
|
|
132
|
+
npm run test
|
|
133
|
+
npm start
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Published binary:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
xbcode
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Slash commands
|
|
143
|
+
|
|
144
|
+
Built-in slash commands currently include:
|
|
145
|
+
|
|
146
|
+
- `/help`
|
|
147
|
+
- `/status`
|
|
148
|
+
- `/login`
|
|
149
|
+
- `/logout`
|
|
150
|
+
- `/mcp`
|
|
151
|
+
- `/mcp refresh`
|
|
152
|
+
- `/team`
|
|
153
|
+
- `/inbox`
|
|
154
|
+
- `/provider`
|
|
155
|
+
- `/model`
|
|
156
|
+
- `/compact`
|
|
157
|
+
- `/new`
|
|
158
|
+
- `/exit`
|
|
159
|
+
|
|
160
|
+
Skill prompt-commands are also exposed as slash commands when available from loaded skills.
|
|
161
|
+
|
|
162
|
+
### Provider and model configuration
|
|
163
|
+
|
|
164
|
+
Providers are configured in `~/.xbcode/settings.json`:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"providers": {
|
|
169
|
+
"openai": {
|
|
170
|
+
"models": [
|
|
171
|
+
"gpt-4.1",
|
|
172
|
+
{ "id": "gpt-4.1-mini", "name": "GPT-4.1 Mini", "description": "Fast general model" }
|
|
173
|
+
],
|
|
174
|
+
"apiKey": "YOUR_KEY",
|
|
175
|
+
"baseURL": "https://api.openai.com/v1",
|
|
176
|
+
"apiMode": "responses",
|
|
177
|
+
"auth": {
|
|
178
|
+
"type": "oauth"
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"aliyun": {
|
|
182
|
+
"models": ["qwen-plus", "qwen-turbo", "qwen-max"],
|
|
183
|
+
"apiKey": "sk-xxx",
|
|
184
|
+
"baseURL": "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"defaultProvider": "openai",
|
|
188
|
+
"showThinking": false
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Key fields:
|
|
193
|
+
|
|
194
|
+
- `providers`
|
|
195
|
+
Named provider profiles
|
|
196
|
+
- `models`
|
|
197
|
+
A list of model IDs or richer model descriptors
|
|
198
|
+
- `defaultProvider`
|
|
199
|
+
Used when no provider is explicitly selected
|
|
200
|
+
- `showThinking`
|
|
201
|
+
Enables display of model reasoning deltas when supported
|
|
202
|
+
- `apiMode`
|
|
203
|
+
Either `responses` or `chat-completions`
|
|
204
|
+
- `auth`
|
|
205
|
+
Optional provider auth mode. Today only `{ "type": "oauth" }` is supported, and only for OpenAI.
|
|
206
|
+
|
|
207
|
+
API mode can be explicit, or derived automatically. For example, DeepSeek-compatible base URLs default to `chat-completions`.
|
|
208
|
+
|
|
209
|
+
When OpenAI OAuth is enabled:
|
|
210
|
+
|
|
211
|
+
- Static provider settings remain in `~/.xbcode/settings.json`
|
|
212
|
+
- Dynamic OAuth credentials are stored separately in `~/.xbcode/credentials.json`
|
|
213
|
+
- Runtime auth prefers a valid OAuth `access_token`
|
|
214
|
+
- If refresh fails, `xbcode` falls back to the provider `apiKey` when one is configured
|
|
215
|
+
|
|
216
|
+
OAuth commands:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
/login openai
|
|
220
|
+
/logout openai
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
`/login` without an argument uses the current provider. In this first version, the CLI prints the OpenAI authorization URL in the terminal and waits for the localhost callback to complete.
|
|
224
|
+
|
|
225
|
+
### Workspace behavior
|
|
226
|
+
|
|
227
|
+
`xbcode` operates relative to the current working directory:
|
|
228
|
+
|
|
229
|
+
- File tools are sandboxed to `process.cwd()`
|
|
230
|
+
- Shell commands run with `cwd = process.cwd()`
|
|
231
|
+
- Local skills are loaded from `<workdir>/skills`
|
|
232
|
+
- Team state lives under `<workdir>/.team`
|
|
233
|
+
- Tasks are stored under `<workdir>/.tasks`
|
|
234
|
+
|
|
235
|
+
If the current project contains an `AGENTS.md`, its contents are injected into the system prompt and influence agent behavior.
|
|
236
|
+
|
|
237
|
+
### Built-in tools
|
|
238
|
+
|
|
239
|
+
The lead agent has access to:
|
|
240
|
+
|
|
241
|
+
- `bash`
|
|
242
|
+
- `read_file`
|
|
243
|
+
- `write_file`
|
|
244
|
+
- `edit_file`
|
|
245
|
+
- `task_create`
|
|
246
|
+
- `task_update`
|
|
247
|
+
- `task_list`
|
|
248
|
+
- `task_get`
|
|
249
|
+
- `list_mcp_resources`
|
|
250
|
+
- `read_mcp_resource`
|
|
251
|
+
- `mcp_call`
|
|
252
|
+
- `load_skill`
|
|
253
|
+
- `task`
|
|
254
|
+
- `message_send`
|
|
255
|
+
- `teammate_spawn`
|
|
256
|
+
- `teammate_list`
|
|
257
|
+
- `teammate_shutdown`
|
|
258
|
+
- `lead_inbox`
|
|
259
|
+
|
|
260
|
+
Teammates get a reduced tool surface:
|
|
261
|
+
|
|
262
|
+
- Base tools
|
|
263
|
+
- `message_send`
|
|
264
|
+
|
|
265
|
+
This is a deliberate constraint to prevent uncontrolled recursive delegation.
|
|
266
|
+
|
|
267
|
+
### Tasks
|
|
268
|
+
|
|
269
|
+
The task system is persistent and file-backed. Each task is stored as a JSON file under:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
.tasks/task_<id>.json
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Task fields include:
|
|
276
|
+
|
|
277
|
+
- `id`
|
|
278
|
+
- `subject`
|
|
279
|
+
- `description`
|
|
280
|
+
- `status`
|
|
281
|
+
- `blockedBy`
|
|
282
|
+
- `blocks`
|
|
283
|
+
|
|
284
|
+
Supported statuses:
|
|
285
|
+
|
|
286
|
+
- `pending`
|
|
287
|
+
- `in_progress`
|
|
288
|
+
- `completed`
|
|
289
|
+
|
|
290
|
+
When a task is marked `completed`, dependent tasks are automatically unblocked.
|
|
291
|
+
|
|
292
|
+
### Skills
|
|
293
|
+
|
|
294
|
+
Skills provide reusable instructions and domain-specific guidance. They are loaded from three locations:
|
|
295
|
+
|
|
296
|
+
- Global (preferred): `~/.xbcode/skills`
|
|
297
|
+
- Global (Claude-compatible): `~/.claude/skills`
|
|
298
|
+
- Local: `<workdir>/skills`
|
|
299
|
+
|
|
300
|
+
Loading order matters:
|
|
301
|
+
|
|
302
|
+
- `~/.xbcode/skills` is loaded first
|
|
303
|
+
- `~/.claude/skills` is loaded next for compatibility
|
|
304
|
+
- Local skills are loaded last and override global skills with the same `name`
|
|
305
|
+
|
|
306
|
+
Each skill is defined by a `SKILL.md` file with frontmatter. The loader exposes:
|
|
307
|
+
|
|
308
|
+
- skill descriptions for prompt construction
|
|
309
|
+
- prompt commands
|
|
310
|
+
- rendered skill content via `load_skill`
|
|
311
|
+
|
|
312
|
+
Two example local skills ship in this repo:
|
|
313
|
+
|
|
314
|
+
- `skills/pdf/SKILL.md`
|
|
315
|
+
- `skills/code-review/SKILL.md`
|
|
316
|
+
|
|
317
|
+
### MCP
|
|
318
|
+
|
|
319
|
+
MCP server configuration lives in:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
~/.xbcode/settings.json
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Supported transports:
|
|
326
|
+
|
|
327
|
+
- `stdio`
|
|
328
|
+
- `streamable-http`
|
|
329
|
+
|
|
330
|
+
Example:
|
|
331
|
+
|
|
332
|
+
```json
|
|
333
|
+
{
|
|
334
|
+
"mcp": {
|
|
335
|
+
"servers": [
|
|
336
|
+
{
|
|
337
|
+
"name": "filesystem",
|
|
338
|
+
"enabled": true,
|
|
339
|
+
"transport": "stdio",
|
|
340
|
+
"command": "npx",
|
|
341
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
|
|
342
|
+
"cwd": "/path/to/project",
|
|
343
|
+
"timeoutMs": 30000
|
|
344
|
+
}
|
|
345
|
+
]
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
Current MCP behavior:
|
|
351
|
+
|
|
352
|
+
- MCP servers are initialized through a shared runtime manager
|
|
353
|
+
- MCP tools are dynamically surfaced as normal function tools
|
|
354
|
+
- MCP resources can be discovered with `list_mcp_resources`
|
|
355
|
+
- Cached resources can be read with `read_mcp_resource`
|
|
356
|
+
- MCP prompts are retrieved through `mcp_call`
|
|
357
|
+
|
|
358
|
+
For deeper details, see:
|
|
359
|
+
|
|
360
|
+
- [docs/mcp-overview.md](./docs/mcp-overview.md)
|
|
361
|
+
- [docs/mcp-implementation.md](./docs/mcp-implementation.md)
|
|
362
|
+
- [docs/mcp-config.md](./docs/mcp-config.md)
|
|
363
|
+
|
|
364
|
+
### Team mode
|
|
365
|
+
|
|
366
|
+
`xbcode` supports persistent teammates instead of only one-shot sub-agents.
|
|
367
|
+
|
|
368
|
+
Conceptually:
|
|
369
|
+
|
|
370
|
+
- `lead` is the main CLI-facing agent
|
|
371
|
+
- teammates are long-lived worker agents with names and roles
|
|
372
|
+
- coordination happens through append-only inbox files
|
|
373
|
+
|
|
374
|
+
Team state is stored under:
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
.team/
|
|
378
|
+
config.json
|
|
379
|
+
inbox/
|
|
380
|
+
lead.jsonl
|
|
381
|
+
<teammate>.jsonl
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
Useful tools:
|
|
385
|
+
|
|
386
|
+
- `teammate_spawn`
|
|
387
|
+
- `teammate_list`
|
|
388
|
+
- `teammate_shutdown`
|
|
389
|
+
- `message_send`
|
|
390
|
+
- `lead_inbox`
|
|
391
|
+
|
|
392
|
+
This model supports asynchronous collaboration while keeping contexts isolated per agent.
|
|
393
|
+
|
|
394
|
+
For the design background, see [docs/agent-teams.md](./docs/agent-teams.md).
|
|
395
|
+
|
|
396
|
+
## Developer Guide
|
|
397
|
+
|
|
398
|
+
### Project layout
|
|
399
|
+
|
|
400
|
+
```text
|
|
401
|
+
code-agent/
|
|
402
|
+
src/
|
|
403
|
+
index.tsx CLI UI and input loop
|
|
404
|
+
agent.ts core agent loop
|
|
405
|
+
tools.ts tool definitions and handlers
|
|
406
|
+
config.ts settings loading and provider resolution
|
|
407
|
+
prompt.ts system prompt construction
|
|
408
|
+
compact.ts context compaction logic
|
|
409
|
+
task-manager.ts persistent task storage
|
|
410
|
+
message-bus.ts inbox-based messaging
|
|
411
|
+
teammate-manager.ts persistent teammate lifecycle
|
|
412
|
+
mcp/ MCP runtime, manager, client, types
|
|
413
|
+
skills/ skill parsing and rendering
|
|
414
|
+
test/ node:test test suite
|
|
415
|
+
docs/ design and implementation notes
|
|
416
|
+
skills/ example local skills
|
|
417
|
+
scripts/postinstall.mjs default config bootstrap
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Core modules
|
|
421
|
+
|
|
422
|
+
#### `src/index.tsx`
|
|
423
|
+
|
|
424
|
+
Responsible for:
|
|
425
|
+
|
|
426
|
+
- terminal UI rendering through Ink
|
|
427
|
+
- input handling
|
|
428
|
+
- provider/model selection
|
|
429
|
+
- slash command dispatch
|
|
430
|
+
- bridge from streaming agent events into the UI
|
|
431
|
+
|
|
432
|
+
#### `src/agent.ts`
|
|
433
|
+
|
|
434
|
+
Responsible for:
|
|
435
|
+
|
|
436
|
+
- main turn orchestration
|
|
437
|
+
- tool/runtime preparation
|
|
438
|
+
- Responses API loop
|
|
439
|
+
- Chat Completions loop
|
|
440
|
+
- interruption handling
|
|
441
|
+
- context compaction triggers
|
|
442
|
+
- teammate runtime behavior
|
|
443
|
+
|
|
444
|
+
#### `src/tools.ts`
|
|
445
|
+
|
|
446
|
+
Responsible for:
|
|
447
|
+
|
|
448
|
+
- tool schemas
|
|
449
|
+
- tool permission boundaries
|
|
450
|
+
- local file and shell handlers
|
|
451
|
+
- task and team operations
|
|
452
|
+
- skill loading bridge
|
|
453
|
+
- MCP entry points
|
|
454
|
+
|
|
455
|
+
#### `src/config.ts`
|
|
456
|
+
|
|
457
|
+
Responsible for:
|
|
458
|
+
|
|
459
|
+
- reading `~/.xbcode/settings.json`
|
|
460
|
+
- normalizing provider settings
|
|
461
|
+
- selecting models
|
|
462
|
+
- validating and normalizing MCP server configs
|
|
463
|
+
|
|
464
|
+
#### `src/prompt.ts`
|
|
465
|
+
|
|
466
|
+
Responsible for building the static system prompt from:
|
|
467
|
+
|
|
468
|
+
- workdir
|
|
469
|
+
- available skill descriptions
|
|
470
|
+
- MCP prompt instructions
|
|
471
|
+
- optional project-level `AGENTS.md`
|
|
472
|
+
|
|
473
|
+
#### `src/compact.ts`
|
|
474
|
+
|
|
475
|
+
Implements two levels of history control:
|
|
476
|
+
|
|
477
|
+
- `microCompact`
|
|
478
|
+
Shrinks old tool outputs in local chat history
|
|
479
|
+
- `autoCompact`
|
|
480
|
+
Summarizes history and replaces it with a compressed summary
|
|
481
|
+
|
|
482
|
+
Responses mode uses a different strategy: periodic reset of the `previous_response_id` chain.
|
|
483
|
+
|
|
484
|
+
### API modes
|
|
485
|
+
|
|
486
|
+
#### Responses API mode
|
|
487
|
+
|
|
488
|
+
Best fit for:
|
|
489
|
+
|
|
490
|
+
- OpenAI-native models
|
|
491
|
+
- simpler server-side context chaining
|
|
492
|
+
|
|
493
|
+
Behavior:
|
|
494
|
+
|
|
495
|
+
- chains turns through `previous_response_id`
|
|
496
|
+
- periodically resets the chain to cap growth
|
|
497
|
+
- does not maintain the same local history structure as chat mode
|
|
498
|
+
|
|
499
|
+
#### Chat Completions mode
|
|
500
|
+
|
|
501
|
+
Best fit for:
|
|
502
|
+
|
|
503
|
+
- compatible non-OpenAI endpoints
|
|
504
|
+
- providers that only expose chat-completions style APIs
|
|
505
|
+
|
|
506
|
+
Behavior:
|
|
507
|
+
|
|
508
|
+
- stores local message history
|
|
509
|
+
- compacts history when token estimates cross thresholds
|
|
510
|
+
- supports tool-loop behavior through standard tool calls
|
|
511
|
+
|
|
512
|
+
### Sub-agents vs teammates
|
|
513
|
+
|
|
514
|
+
There are two delegation models:
|
|
515
|
+
|
|
516
|
+
- `task`
|
|
517
|
+
Creates a one-shot isolated sub-agent with a clean context and a bounded maximum round count
|
|
518
|
+
- teammates
|
|
519
|
+
Persistent workers with identities, inboxes, statuses, and wake/sleep lifecycle
|
|
520
|
+
|
|
521
|
+
Use `task` for isolated execution. Use teammates for ongoing coordination.
|
|
522
|
+
|
|
523
|
+
### Testing
|
|
524
|
+
|
|
525
|
+
Run the test suite with:
|
|
526
|
+
|
|
527
|
+
```bash
|
|
528
|
+
npm test
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
Current tests cover areas such as:
|
|
532
|
+
|
|
533
|
+
- input submit deduplication
|
|
534
|
+
- prompt building
|
|
535
|
+
- skill loading and rendering
|
|
536
|
+
- utility behavior
|
|
537
|
+
|
|
538
|
+
The test runner uses native `node:test` with `tsx`.
|
|
539
|
+
|
|
540
|
+
### Publishing
|
|
541
|
+
|
|
542
|
+
The package is published as:
|
|
543
|
+
|
|
544
|
+
```text
|
|
545
|
+
@lwmxiaobei/xbcode
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Important package details:
|
|
549
|
+
|
|
550
|
+
- binary name: `xbcode`
|
|
551
|
+
- module format: ESM
|
|
552
|
+
- build output: `dist/`
|
|
553
|
+
- `prepublishOnly` runs build plus tests
|
|
554
|
+
|
|
555
|
+
## Design Notes and Trade-offs
|
|
556
|
+
|
|
557
|
+
### Safety boundaries
|
|
558
|
+
|
|
559
|
+
The current implementation intentionally enforces several simple constraints:
|
|
560
|
+
|
|
561
|
+
- file access is restricted to the current workspace through `safePath()`
|
|
562
|
+
- shell commands have a timeout
|
|
563
|
+
- very dangerous shell snippets are blocked
|
|
564
|
+
- tool output is truncated to avoid blowing up context size
|
|
565
|
+
- teammate tool permissions are narrower than lead permissions
|
|
566
|
+
|
|
567
|
+
This is not a hardened sandbox. It is a pragmatic local-agent safety layer.
|
|
568
|
+
|
|
569
|
+
### Why the project stays small
|
|
570
|
+
|
|
571
|
+
The codebase favors:
|
|
572
|
+
|
|
573
|
+
- direct composition over deep abstractions
|
|
574
|
+
- file-backed persistence over databases
|
|
575
|
+
- explicit modules over framework-heavy orchestration
|
|
576
|
+
- readable control flow over maximum generality
|
|
577
|
+
|
|
578
|
+
That makes it easier to understand, modify, and compare against larger agent implementations.
|
|
579
|
+
|
|
580
|
+
### Current limitations
|
|
581
|
+
|
|
582
|
+
Notable limitations in the current implementation:
|
|
583
|
+
|
|
584
|
+
- no git worktree isolation for teammates or sub-agents
|
|
585
|
+
- no long-lived scheduler beyond teammate wake/sleep behavior
|
|
586
|
+
- dangerous command filtering is intentionally simple, not exhaustive
|
|
587
|
+
- Responses API compaction is a chain reset, not a summary-preserving merge
|
|
588
|
+
- teammate execution is intentionally capability-limited
|
|
589
|
+
|
|
590
|
+
## Documentation
|
|
591
|
+
|
|
592
|
+
Additional project notes live under `docs/`:
|
|
593
|
+
|
|
594
|
+
- [docs/TUTORIAL.md](./docs/TUTORIAL.md)
|
|
595
|
+
- [docs/task-dag.md](./docs/task-dag.md)
|
|
596
|
+
- [docs/context-compaction.md](./docs/context-compaction.md)
|
|
597
|
+
- [docs/mcp-plan.md](./docs/mcp-plan.md)
|
|
598
|
+
- [docs/mcp-overview.md](./docs/mcp-overview.md)
|
|
599
|
+
- [docs/mcp-implementation.md](./docs/mcp-implementation.md)
|
|
600
|
+
- [docs/mcp-config.md](./docs/mcp-config.md)
|
|
601
|
+
- [docs/agent-teams.md](./docs/agent-teams.md)
|
|
602
|
+
|
|
603
|
+
## Development
|
|
604
|
+
|
|
605
|
+
Install dependencies:
|
|
606
|
+
|
|
607
|
+
```bash
|
|
608
|
+
npm install
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
Run in development:
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
npm run dev
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
Run tests:
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
npm test
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
Build:
|
|
624
|
+
|
|
625
|
+
```bash
|
|
626
|
+
npm run build
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
## License
|
|
630
|
+
|
|
631
|
+
No license file is included in this repository snapshot. Add one before public redistribution if needed.
|