@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 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.