@nanobpm/nano-coder 0.1.0 → 0.2.1
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 +92 -4
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -20,11 +20,12 @@ cargo install nano-coder # or build from source
|
|
|
20
20
|
- **Sessions**: Append-only JSONL session logs with resume and input-ID deduplication
|
|
21
21
|
- **Lifecycle Hooks**: 6 hook events for observing/intercepting agent behavior
|
|
22
22
|
- **Configuration**: TOML-based config file at `~/.config/nano-coder/config.toml`
|
|
23
|
-
- **Commands**: `/help`, `/compact`, `/context`, `/verbosity`, `/settings`, `/tools`, `/exit`
|
|
23
|
+
- **Commands**: `/help`, `/compact`, `/context`, `/verbosity`, `/settings`, `/tools`, `/skills`, `/exit`
|
|
24
24
|
- **Streaming output**: answers stream in, thinking shows collapsed (Ctrl-O expands it), tool calls show inline
|
|
25
25
|
- **Status line** pinned to the bottom of the terminal, plus manual and automatic context compaction
|
|
26
26
|
- **Task plans**: `plan_*` tools keep a plan with notes outside the conversation, so long tasks survive compaction, resume and a change of worker
|
|
27
27
|
- **Project instructions**: `AGENTS.md` (or `CLAUDE.md`, `.github/copilot-instructions.md`) from the repository is added to the system prompt
|
|
28
|
+
- **Skills**: `SKILL.md` folders from the repository, `~/.agents/skills`, and an spm `ai.lock`, loaded on demand with `load_skill`
|
|
28
29
|
|
|
29
30
|
## Two Execution Modes
|
|
30
31
|
|
|
@@ -83,6 +84,8 @@ events c8ctl-nano's transcript producer records into the engine's AgentInstance
|
|
|
83
84
|
**Project instructions.** `session/new` and `session/load` results include
|
|
84
85
|
`_meta.projectInstructions`: the absolute paths of the instruction files that were added to
|
|
85
86
|
the system prompt for the session's `cwd` (see [Project Instructions](#project-instructions)).
|
|
87
|
+
`_meta.skills` lists the skills found for it, and `_meta.skillWarnings` (when present) explains
|
|
88
|
+
any that could not be loaded (see [Skills](#skills)).
|
|
86
89
|
|
|
87
90
|
**Plans.** Each plan change sends a `plan` update: ACP `entries` (`content`, `priority`,
|
|
88
91
|
`status`) plus `_meta.plan`, the full plan with ids, notes and dependencies. To continue a job
|
|
@@ -133,6 +136,8 @@ src/
|
|
|
133
136
|
├── instructions.rs # AGENTS.md / CLAUDE.md discovery for the system prompt
|
|
134
137
|
├── plan.rs # Task plan and the plan_add / plan_update / plan_show tools
|
|
135
138
|
├── goal.rs # report_outcome tool (completed / blocked)
|
|
139
|
+
├── commands.rs # Slash-command table for /help and the as-you-type menu
|
|
140
|
+
├── skills.rs # SKILL.md discovery, ai.lock sources and the load_skill tool
|
|
136
141
|
├── reminders.rs # <system-reminder> notes appended to tool results
|
|
137
142
|
├── settings.rs # /settings menu and config-file writer
|
|
138
143
|
└── config.rs # Configuration file loading and management
|
|
@@ -171,6 +176,8 @@ The harness exposes 6 lifecycle hook events:
|
|
|
171
176
|
- `plan_add`, `plan_update`, `plan_show` - The agent's task plan (see [Task Plans](#task-plans)).
|
|
172
177
|
- `report_outcome` - Report the task `completed` or `blocked`, with a `summary`; ends the turn
|
|
173
178
|
(see [Outcomes](#outcomes)).
|
|
179
|
+
- `load_skill` - Return a skill's instructions and list its other files; `name`. Offered only
|
|
180
|
+
when skills were found (see [Skills](#skills)).
|
|
174
181
|
|
|
175
182
|
Any other tool's result longer than 40,000 characters is cut the same way as bash output,
|
|
176
183
|
with the whole result saved under the temp directory (`nano-coder-<pid>/tool-<id>-<name>.txt`)
|
|
@@ -182,6 +189,10 @@ workspace.
|
|
|
182
189
|
|
|
183
190
|
## Commands
|
|
184
191
|
|
|
192
|
+
Typing `/` at the prompt lists the commands under it, and each further character narrows the
|
|
193
|
+
list. Tab completes the command, or the part all matches share. Esc hides the list. The
|
|
194
|
+
list is built from the same table as `/help` (`src/commands.rs`).
|
|
195
|
+
|
|
185
196
|
- `/help` - Show available commands
|
|
186
197
|
- `/compact [focus]` - Summarize older messages with the current model, keeping the latest
|
|
187
198
|
message. Optional text tells the summary what to focus on. Esc Esc or Ctrl-C cancels
|
|
@@ -199,6 +210,7 @@ workspace.
|
|
|
199
210
|
(`--config` or `~/.config/nano-coder/config.toml`), keeping comments and
|
|
200
211
|
other settings. Leaving with unsaved changes asks whether to save
|
|
201
212
|
- `/tools` - List registered tools
|
|
213
|
+
- `/skills` - List the skills the agent can load, where each lives, and any loading warnings
|
|
202
214
|
- `/plan` - Show the agent's task plan with all notes
|
|
203
215
|
- `/model [provider/model]` - Show or switch the model (conversation is kept)
|
|
204
216
|
- `/providers` - List providers, endpoints and whether their API key is available
|
|
@@ -242,11 +254,20 @@ auto_compact = true # summarize automatically when the conte
|
|
|
242
254
|
auto_compact_threshold = 0.8 # fraction of the context window
|
|
243
255
|
# context_window = 128000 # override the window (providers can set it too)
|
|
244
256
|
verbosity = "normal" # quiet | normal | verbose | debug (or --verbosity)
|
|
257
|
+
timestamps = true # prefix CLI messages with the local time (HH:MM:SS)
|
|
245
258
|
project_instructions = true # load AGENTS.md etc. (see Project Instructions)
|
|
246
259
|
project_instruction_files = ["AGENTS.md", "CLAUDE.md", ".github/copilot-instructions.md"]
|
|
247
260
|
plan_tools = true # offer the plan_* tools (see Task Plans)
|
|
248
261
|
outcome_tool = true # offer report_outcome (see Outcomes)
|
|
249
262
|
reminders = true # append <system-reminder> notes to tool results
|
|
263
|
+
|
|
264
|
+
[skills] # see Skills
|
|
265
|
+
enabled = true
|
|
266
|
+
dirs = [".agents/skills", ".github/skills", ".claude/skills"] # relative to the git root
|
|
267
|
+
user_dirs = ["~/.agents/skills"]
|
|
268
|
+
ai_lock = true # load skills pinned in ai.lock
|
|
269
|
+
fetch = true # fetch ai.lock commits missing from the spm store
|
|
270
|
+
allowed_hosts = ["github.com"] # hosts ai.lock entries may be fetched from ("*" = any)
|
|
250
271
|
```
|
|
251
272
|
|
|
252
273
|
The default model is `gpt-4o-mini` on the `mock` provider, so the harness still works offline.
|
|
@@ -268,8 +289,10 @@ Built-in presets:
|
|
|
268
289
|
| `groq` | openai | `https://api.groq.com/openai/v1` | `GROQ_API_KEY` |
|
|
269
290
|
| `together` | openai | `https://api.together.xyz/v1` | `TOGETHER_API_KEY` |
|
|
270
291
|
| `deepseek` | openai | `https://api.deepseek.com/v1` | `DEEPSEEK_API_KEY` |
|
|
292
|
+
| `kimi` | openai | `https://api.moonshot.ai/v1` | `MOONSHOT_API_KEY` |
|
|
271
293
|
| `mistral` | openai | `https://api.mistral.ai/v1` | `MISTRAL_API_KEY` |
|
|
272
294
|
| `gemini` | openai | `https://generativelanguage.googleapis.com/v1beta/openai` | `GEMINI_API_KEY` |
|
|
295
|
+
| `qwen` | openai | `https://dashscope-intl.aliyuncs.com/compatible-mode/v1` | `DASHSCOPE_API_KEY` |
|
|
273
296
|
| `ollama` | openai | `http://localhost:11434/v1` | — |
|
|
274
297
|
| `llamacpp` | openai | `http://localhost:8080/v1` | — |
|
|
275
298
|
| `github-copilot` | github-copilot | from session token | `GITHUB_COPILOT_OAUTH_TOKEN` or `--login` (unofficial, see below) |
|
|
@@ -307,7 +330,19 @@ timeout_secs = 300
|
|
|
307
330
|
max_retries = 3
|
|
308
331
|
```
|
|
309
332
|
|
|
310
|
-
|
|
333
|
+
`qwen` is Qwen Cloud (Alibaba Cloud Model Studio), e.g. `--model qwen/qwen3.8-max`. The
|
|
334
|
+
preset uses the Singapore endpoint. API keys are bound to a region, so for another region
|
|
335
|
+
or your workspace domain override `base_url`, e.g.
|
|
336
|
+
`https://dashscope-us.aliyuncs.com/compatible-mode/v1` or
|
|
337
|
+
`https://<WorkspaceId>.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1`.
|
|
338
|
+
|
|
339
|
+
`kimi` is the Kimi API from platform.kimi.ai, e.g. `--model kimi/kimi-k3` or
|
|
340
|
+
`kimi/kimi-k2.7-code`. The preset drops `temperature` (K3 fixes it) and sets
|
|
341
|
+
`replay_reasoning = true`, which sends each assistant message's `reasoning_content` back
|
|
342
|
+
as thinking models like K3 require. Set `extra_body = { reasoning_effort = "low" }` to
|
|
343
|
+
make K3 think less.
|
|
344
|
+
|
|
345
|
+
Other per-provider fields: `replay_reasoning`, `max_tokens_param` (`max_tokens`, or `max_completion_tokens`
|
|
311
346
|
which is the `openai` default), `retry_initial_backoff_ms`, `retry_max_backoff_ms` and
|
|
312
347
|
`retryable_statuses`.
|
|
313
348
|
|
|
@@ -384,6 +419,10 @@ Streaming uses server-sent events. Set `stream = false` on a provider whose endp
|
|
|
384
419
|
support it. ACP mode doesn't stream text, but sends each response's reasoning as an
|
|
385
420
|
`agent_thought_chunk` update.
|
|
386
421
|
|
|
422
|
+
Every message (your prompt, answers, tool calls and results, thinking, notes) starts with
|
|
423
|
+
the local time as `HH:MM:SS`. The prompt's time is rewritten when you press Enter, so it
|
|
424
|
+
shows when the message was sent. Turn this off with `timestamps = false`.
|
|
425
|
+
|
|
387
426
|
## Status Line and Compaction
|
|
388
427
|
|
|
389
428
|
In an interactive terminal the bottom row shows the provider/model, context usage
|
|
@@ -393,8 +432,22 @@ count, and what the agent is doing. It uses a terminal scroll region, follows re
|
|
|
393
432
|
off when stdin/stdout isn't a TTY or `AGENTIC_NO_STATUS` is set.
|
|
394
433
|
|
|
395
434
|
The context window comes from, in order: `context_window` in the config, `context_window`
|
|
396
|
-
on the provider, a built-in table of known models, then
|
|
397
|
-
|
|
435
|
+
on the provider, the window the endpoint reports, a built-in table of known models, then
|
|
436
|
+
128k. `/context` shows which one applied. If a provider rejects a request as too long, the
|
|
437
|
+
harness takes the limit from the error, compacts, and retries once.
|
|
438
|
+
|
|
439
|
+
The endpoint is asked at startup and on `/model` (at most 5 seconds; skipped when config
|
|
440
|
+
sets the window). The window a server has *loaded* is preferred over the model's maximum:
|
|
441
|
+
|
|
442
|
+
| Server | Source |
|
|
443
|
+
|---|---|
|
|
444
|
+
| vLLM | `/v1/models` `max_model_len` |
|
|
445
|
+
| DwarfStar ds4, OpenRouter, Together, Kimi | `/models` `context_length` |
|
|
446
|
+
| Groq / Mistral | `/models` `context_window` / `max_context_length` |
|
|
447
|
+
| llama.cpp | `/props` `n_ctx` (per slot) |
|
|
448
|
+
| LM Studio | `/api/v0/models` `loaded_context_length` |
|
|
449
|
+
| Ollama | `/api/ps` for a loaded model, else `num_ctx`; never the model maximum, since Ollama runs with a smaller default |
|
|
450
|
+
| GitHub Copilot | `/models` `max_prompt_tokens` |
|
|
398
451
|
|
|
399
452
|
Compaction asks the current model to summarize older messages, keeping the recent tail
|
|
400
453
|
(up to 20k tokens, never starting at a tool result). Auto-compaction runs before a model
|
|
@@ -424,6 +477,39 @@ Instructions are read again when a session is resumed, so edits to `AGENTS.md` t
|
|
|
424
477
|
`/context` lists the loaded files. To turn loading off, set `project_instructions = false`,
|
|
425
478
|
or set `AGENTIC_NO_PROJECT_INSTRUCTIONS`.
|
|
426
479
|
|
|
480
|
+
## Skills
|
|
481
|
+
|
|
482
|
+
A skill is a folder with a `SKILL.md`: YAML front matter with a `name` and a `description`,
|
|
483
|
+
then instructions, plus any scripts or reference files it needs. Only the name and description
|
|
484
|
+
of each skill go into the system prompt, under a "Skills" heading (8 KiB at most). When a task
|
|
485
|
+
matches one, the model calls `load_skill`, which returns the instructions (32 KiB at most),
|
|
486
|
+
the skill's directory, and a list of its other files for `read_file`.
|
|
487
|
+
|
|
488
|
+
Skills are found in this order, and the first skill with a given name wins:
|
|
489
|
+
|
|
490
|
+
1. **Repository**: `.agents/skills`, `.github/skills` and `.claude/skills` under the git root,
|
|
491
|
+
at any depth up to four folders (`skills/<group>/<skill>/SKILL.md` works).
|
|
492
|
+
2. **`ai.lock`**: skills pinned by [spm](https://github.com/camunda/spm-cli). Each locked
|
|
493
|
+
skill is loaded, and so is each skill bundled in a locked plugin (its
|
|
494
|
+
`.claude-plugin/plugin.json` `skills` folder, default `skills/`). Hooks, commands and MCP
|
|
495
|
+
servers in plugins are not loaded.
|
|
496
|
+
3. **User**: `~/.agents/skills`.
|
|
497
|
+
|
|
498
|
+
nano-coder reads `ai.lock` itself and never runs `spm install`, which edits the workspace
|
|
499
|
+
(`.gitignore`, vendor folders). Changes like that would end up in commits and PRs. Each
|
|
500
|
+
pinned commit is read from spm's store (`$SPM_HOME/store`, default `~/.spm/store`) if it is
|
|
501
|
+
there. Otherwise it is fetched once into the nano-coder cache (`<cache dir>/nano-coder/skills`).
|
|
502
|
+
`ai.lock` is committed to the repository, so its entries are checked the way spm checks them:
|
|
503
|
+
a full 40-character commit, a store key that matches the URL and commit, and paths that stay
|
|
504
|
+
inside the checkout. Fetches are limited to `skills.allowed_hosts` (`"file"` allows
|
|
505
|
+
`file://`). With `fetch = false`, only commits already in the spm store or the cache are used.
|
|
506
|
+
An `ai.json` without an `ai.lock` is skipped with a warning, because unpinned references are
|
|
507
|
+
never resolved.
|
|
508
|
+
|
|
509
|
+
Skills are found again when a session starts or is resumed. Problems are listed at startup
|
|
510
|
+
and by `/skills` (and returned as `_meta.skillWarnings` over ACP); they never stop a session.
|
|
511
|
+
To turn skills off, set `skills.enabled = false` or set `NANO_CODER_NO_SKILLS`.
|
|
512
|
+
|
|
427
513
|
## Task Plans
|
|
428
514
|
|
|
429
515
|
The `plan_*` tools give the agent a plan that lives outside the conversation. This helps most
|
|
@@ -479,6 +565,8 @@ When `persist_sessions` is on, each conversation is written to `<session_dir>/<i
|
|
|
479
565
|
The file is an append-only log whose first record is a versioned header, followed by
|
|
480
566
|
`input`, `message`, `turn_end` and `replace` (compaction / system-prompt reset) records.
|
|
481
567
|
Resume a session with `--resume <id>` or ACP `session/load`.
|
|
568
|
+
Record times and each message's `timestamp` are RFC 3339 with the local UTC offset
|
|
569
|
+
(for example `2026-09-24T13:02:12.44+12:00`). Older logs with UTC times still load.
|
|
482
570
|
|
|
483
571
|
- An unsupported format version is an explicit error on resume.
|
|
484
572
|
- Only records ending in a newline count as committed. A half-written last line from a
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nanobpm/nano-coder",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A 6MB coding agent. Run a fleet on your laptop.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"node": ">=18"
|
|
32
32
|
},
|
|
33
33
|
"optionalDependencies": {
|
|
34
|
-
"@nanobpm/nano-coder-darwin-arm64": "0.1
|
|
35
|
-
"@nanobpm/nano-coder-darwin-x64": "0.1
|
|
36
|
-
"@nanobpm/nano-coder-linux-arm64": "0.1
|
|
37
|
-
"@nanobpm/nano-coder-linux-x64": "0.1
|
|
34
|
+
"@nanobpm/nano-coder-darwin-arm64": "0.2.1",
|
|
35
|
+
"@nanobpm/nano-coder-darwin-x64": "0.2.1",
|
|
36
|
+
"@nanobpm/nano-coder-linux-arm64": "0.2.1",
|
|
37
|
+
"@nanobpm/nano-coder-linux-x64": "0.2.1"
|
|
38
38
|
}
|
|
39
39
|
}
|