atom-lite 0.0.0-stage → 0.4.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.
Files changed (250) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/LICENSE +21 -0
  3. package/README.md +313 -2
  4. package/dist/agent/loop.d.ts +32 -0
  5. package/dist/agent/loop.js +204 -0
  6. package/dist/agent/loop.js.map +1 -0
  7. package/dist/agent/types.d.ts +85 -0
  8. package/dist/agent/types.js +2 -0
  9. package/dist/agent/types.js.map +1 -0
  10. package/dist/cli/activity.d.ts +45 -0
  11. package/dist/cli/activity.js +141 -0
  12. package/dist/cli/activity.js.map +1 -0
  13. package/dist/cli/app.d.ts +1 -0
  14. package/dist/cli/app.js +1576 -0
  15. package/dist/cli/app.js.map +1 -0
  16. package/dist/cli/approval-prompt.d.ts +24 -0
  17. package/dist/cli/approval-prompt.js +82 -0
  18. package/dist/cli/approval-prompt.js.map +1 -0
  19. package/dist/cli/approvals.d.ts +1 -0
  20. package/dist/cli/approvals.js +2 -0
  21. package/dist/cli/approvals.js.map +1 -0
  22. package/dist/cli/banner.d.ts +12 -0
  23. package/dist/cli/banner.js +35 -0
  24. package/dist/cli/banner.js.map +1 -0
  25. package/dist/cli/commands.d.ts +94 -0
  26. package/dist/cli/commands.js +324 -0
  27. package/dist/cli/commands.js.map +1 -0
  28. package/dist/cli/diff.d.ts +1 -0
  29. package/dist/cli/diff.js +28 -0
  30. package/dist/cli/diff.js.map +1 -0
  31. package/dist/cli/input.d.ts +2 -0
  32. package/dist/cli/input.js +10 -0
  33. package/dist/cli/input.js.map +1 -0
  34. package/dist/cli/main.d.ts +2 -0
  35. package/dist/cli/main.js +22 -0
  36. package/dist/cli/main.js.map +1 -0
  37. package/dist/cli/mouse.d.ts +54 -0
  38. package/dist/cli/mouse.js +83 -0
  39. package/dist/cli/mouse.js.map +1 -0
  40. package/dist/cli/palette.d.ts +41 -0
  41. package/dist/cli/palette.js +212 -0
  42. package/dist/cli/palette.js.map +1 -0
  43. package/dist/cli/panel.d.ts +29 -0
  44. package/dist/cli/panel.js +48 -0
  45. package/dist/cli/panel.js.map +1 -0
  46. package/dist/cli/picker.d.ts +34 -0
  47. package/dist/cli/picker.js +173 -0
  48. package/dist/cli/picker.js.map +1 -0
  49. package/dist/cli/renderer.d.ts +1 -0
  50. package/dist/cli/renderer.js +5 -0
  51. package/dist/cli/renderer.js.map +1 -0
  52. package/dist/cli/secret-input.d.ts +21 -0
  53. package/dist/cli/secret-input.js +101 -0
  54. package/dist/cli/secret-input.js.map +1 -0
  55. package/dist/cli/status-line.d.ts +24 -0
  56. package/dist/cli/status-line.js +49 -0
  57. package/dist/cli/status-line.js.map +1 -0
  58. package/dist/cli/stream-text.d.ts +18 -0
  59. package/dist/cli/stream-text.js +63 -0
  60. package/dist/cli/stream-text.js.map +1 -0
  61. package/dist/cli/theme.d.ts +48 -0
  62. package/dist/cli/theme.js +158 -0
  63. package/dist/cli/theme.js.map +1 -0
  64. package/dist/cli/tool-box.d.ts +41 -0
  65. package/dist/cli/tool-box.js +177 -0
  66. package/dist/cli/tool-box.js.map +1 -0
  67. package/dist/cli/transcript.d.ts +26 -0
  68. package/dist/cli/transcript.js +64 -0
  69. package/dist/cli/transcript.js.map +1 -0
  70. package/dist/config/credentials.d.ts +26 -0
  71. package/dist/config/credentials.js +79 -0
  72. package/dist/config/credentials.js.map +1 -0
  73. package/dist/config/defaults.d.ts +34 -0
  74. package/dist/config/defaults.js +35 -0
  75. package/dist/config/defaults.js.map +1 -0
  76. package/dist/config/load.d.ts +9 -0
  77. package/dist/config/load.js +137 -0
  78. package/dist/config/load.js.map +1 -0
  79. package/dist/config/paths.d.ts +4 -0
  80. package/dist/config/paths.js +14 -0
  81. package/dist/config/paths.js.map +1 -0
  82. package/dist/config/schema.d.ts +132 -0
  83. package/dist/config/schema.js +83 -0
  84. package/dist/config/schema.js.map +1 -0
  85. package/dist/config/write.d.ts +20 -0
  86. package/dist/config/write.js +70 -0
  87. package/dist/config/write.js.map +1 -0
  88. package/dist/context/budget.d.ts +2 -0
  89. package/dist/context/budget.js +13 -0
  90. package/dist/context/budget.js.map +1 -0
  91. package/dist/context/builder.d.ts +7 -0
  92. package/dist/context/builder.js +11 -0
  93. package/dist/context/builder.js.map +1 -0
  94. package/dist/context/compaction.d.ts +1 -0
  95. package/dist/context/compaction.js +5 -0
  96. package/dist/context/compaction.js.map +1 -0
  97. package/dist/context/instructions.d.ts +3 -0
  98. package/dist/context/instructions.js +30 -0
  99. package/dist/context/instructions.js.map +1 -0
  100. package/dist/context/manager.d.ts +29 -0
  101. package/dist/context/manager.js +122 -0
  102. package/dist/context/manager.js.map +1 -0
  103. package/dist/extensions/api.d.ts +51 -0
  104. package/dist/extensions/api.js +101 -0
  105. package/dist/extensions/api.js.map +1 -0
  106. package/dist/extensions/discovery.d.ts +26 -0
  107. package/dist/extensions/discovery.js +243 -0
  108. package/dist/extensions/discovery.js.map +1 -0
  109. package/dist/extensions/loader.d.ts +27 -0
  110. package/dist/extensions/loader.js +113 -0
  111. package/dist/extensions/loader.js.map +1 -0
  112. package/dist/extensions/trust.d.ts +4 -0
  113. package/dist/extensions/trust.js +40 -0
  114. package/dist/extensions/trust.js.map +1 -0
  115. package/dist/extensions/types.d.ts +52 -0
  116. package/dist/extensions/types.js +2 -0
  117. package/dist/extensions/types.js.map +1 -0
  118. package/dist/index.d.ts +17 -0
  119. package/dist/index.js +17 -0
  120. package/dist/index.js.map +1 -0
  121. package/dist/mcp/client.d.ts +73 -0
  122. package/dist/mcp/client.js +363 -0
  123. package/dist/mcp/client.js.map +1 -0
  124. package/dist/mcp/format.d.ts +3 -0
  125. package/dist/mcp/format.js +37 -0
  126. package/dist/mcp/format.js.map +1 -0
  127. package/dist/mcp/index.d.ts +6 -0
  128. package/dist/mcp/index.js +7 -0
  129. package/dist/mcp/index.js.map +1 -0
  130. package/dist/mcp/manager.d.ts +53 -0
  131. package/dist/mcp/manager.js +349 -0
  132. package/dist/mcp/manager.js.map +1 -0
  133. package/dist/mcp/stdio-transport.d.ts +26 -0
  134. package/dist/mcp/stdio-transport.js +191 -0
  135. package/dist/mcp/stdio-transport.js.map +1 -0
  136. package/dist/mcp/tools.d.ts +22 -0
  137. package/dist/mcp/tools.js +162 -0
  138. package/dist/mcp/tools.js.map +1 -0
  139. package/dist/mcp/types.d.ts +92 -0
  140. package/dist/mcp/types.js +2 -0
  141. package/dist/mcp/types.js.map +1 -0
  142. package/dist/providers/catalog.d.ts +60 -0
  143. package/dist/providers/catalog.js +289 -0
  144. package/dist/providers/catalog.js.map +1 -0
  145. package/dist/providers/context-window.d.ts +11 -0
  146. package/dist/providers/context-window.js +87 -0
  147. package/dist/providers/context-window.js.map +1 -0
  148. package/dist/providers/factory.d.ts +2 -0
  149. package/dist/providers/factory.js +55 -0
  150. package/dist/providers/factory.js.map +1 -0
  151. package/dist/providers/fake.d.ts +14 -0
  152. package/dist/providers/fake.js +23 -0
  153. package/dist/providers/fake.js.map +1 -0
  154. package/dist/providers/gemini.d.ts +24 -0
  155. package/dist/providers/gemini.js +228 -0
  156. package/dist/providers/gemini.js.map +1 -0
  157. package/dist/providers/index.d.ts +5 -0
  158. package/dist/providers/index.js +4 -0
  159. package/dist/providers/index.js.map +1 -0
  160. package/dist/providers/ollama.d.ts +64 -0
  161. package/dist/providers/ollama.js +433 -0
  162. package/dist/providers/ollama.js.map +1 -0
  163. package/dist/providers/openai-compatible.d.ts +27 -0
  164. package/dist/providers/openai-compatible.js +282 -0
  165. package/dist/providers/openai-compatible.js.map +1 -0
  166. package/dist/providers/registry.d.ts +7 -0
  167. package/dist/providers/registry.js +13 -0
  168. package/dist/providers/registry.js.map +1 -0
  169. package/dist/providers/tool-calls.d.ts +18 -0
  170. package/dist/providers/tool-calls.js +42 -0
  171. package/dist/providers/tool-calls.js.map +1 -0
  172. package/dist/providers/types.d.ts +16 -0
  173. package/dist/providers/types.js +2 -0
  174. package/dist/providers/types.js.map +1 -0
  175. package/dist/runtime/approvals.d.ts +20 -0
  176. package/dist/runtime/approvals.js +20 -0
  177. package/dist/runtime/approvals.js.map +1 -0
  178. package/dist/runtime/executor.d.ts +2 -0
  179. package/dist/runtime/executor.js +4 -0
  180. package/dist/runtime/executor.js.map +1 -0
  181. package/dist/runtime/locks.d.ts +13 -0
  182. package/dist/runtime/locks.js +180 -0
  183. package/dist/runtime/locks.js.map +1 -0
  184. package/dist/runtime/scheduler.d.ts +7 -0
  185. package/dist/runtime/scheduler.js +110 -0
  186. package/dist/runtime/scheduler.js.map +1 -0
  187. package/dist/security/paths.d.ts +1 -0
  188. package/dist/security/paths.js +35 -0
  189. package/dist/security/paths.js.map +1 -0
  190. package/dist/security/process.d.ts +1 -0
  191. package/dist/security/process.js +8 -0
  192. package/dist/security/process.js.map +1 -0
  193. package/dist/security/redaction.d.ts +1 -0
  194. package/dist/security/redaction.js +4 -0
  195. package/dist/security/redaction.js.map +1 -0
  196. package/dist/sessions/events.d.ts +30 -0
  197. package/dist/sessions/events.js +92 -0
  198. package/dist/sessions/events.js.map +1 -0
  199. package/dist/sessions/history.d.ts +18 -0
  200. package/dist/sessions/history.js +76 -0
  201. package/dist/sessions/history.js.map +1 -0
  202. package/dist/sessions/index.d.ts +5 -0
  203. package/dist/sessions/index.js +6 -0
  204. package/dist/sessions/index.js.map +1 -0
  205. package/dist/sessions/recovery.d.ts +6 -0
  206. package/dist/sessions/recovery.js +35 -0
  207. package/dist/sessions/recovery.js.map +1 -0
  208. package/dist/sessions/search.d.ts +16 -0
  209. package/dist/sessions/search.js +136 -0
  210. package/dist/sessions/search.js.map +1 -0
  211. package/dist/sessions/store.d.ts +91 -0
  212. package/dist/sessions/store.js +360 -0
  213. package/dist/sessions/store.js.map +1 -0
  214. package/dist/skills/registry.d.ts +23 -0
  215. package/dist/skills/registry.js +129 -0
  216. package/dist/skills/registry.js.map +1 -0
  217. package/dist/tools/bash.d.ts +2 -0
  218. package/dist/tools/bash.js +159 -0
  219. package/dist/tools/bash.js.map +1 -0
  220. package/dist/tools/diff.d.ts +7 -0
  221. package/dist/tools/diff.js +40 -0
  222. package/dist/tools/diff.js.map +1 -0
  223. package/dist/tools/edit.d.ts +2 -0
  224. package/dist/tools/edit.js +118 -0
  225. package/dist/tools/edit.js.map +1 -0
  226. package/dist/tools/index.d.ts +8 -0
  227. package/dist/tools/index.js +8 -0
  228. package/dist/tools/index.js.map +1 -0
  229. package/dist/tools/read.d.ts +2 -0
  230. package/dist/tools/read.js +138 -0
  231. package/dist/tools/read.js.map +1 -0
  232. package/dist/tools/registry.d.ts +7 -0
  233. package/dist/tools/registry.js +13 -0
  234. package/dist/tools/registry.js.map +1 -0
  235. package/dist/tools/types.d.ts +27 -0
  236. package/dist/tools/types.js +2 -0
  237. package/dist/tools/types.js.map +1 -0
  238. package/dist/tools/webfetch.d.ts +2 -0
  239. package/dist/tools/webfetch.js +97 -0
  240. package/dist/tools/webfetch.js.map +1 -0
  241. package/dist/tools/websearch.d.ts +2 -0
  242. package/dist/tools/websearch.js +88 -0
  243. package/dist/tools/websearch.js.map +1 -0
  244. package/dist/tools/write.d.ts +2 -0
  245. package/dist/tools/write.js +91 -0
  246. package/dist/tools/write.js.map +1 -0
  247. package/dist/types.d.ts +84 -0
  248. package/dist/types.js +10 -0
  249. package/dist/types.js.map +1 -0
  250. package/package.json +74 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,72 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ ## [0.4.1] - 2026-11-04
13
+
14
+ ### Fixed
15
+
16
+ - npm publish retry after staged 0.4.0 conflict.
17
+
18
+ ## [0.4.0] - 2026-11-04
19
+
20
+ ### Added
21
+
22
+ - Extension discovery and manifest parsing (`src/extensions/discovery.ts`).
23
+ - Project trust gating and extension loader lifecycle with `/extensions`.
24
+ - `/export` for sessions.
25
+ - Markdown rendering for assistant responses and unified diff summaries in tool boxes.
26
+ - Literal edit replacement handling.
27
+ - Escape to cancel an active turn.
28
+ - TUI mouse capture fixes.
29
+
30
+ ### Fixed
31
+
32
+ - Mouse capture sequence and startup ordering for TUI mouse support.
33
+
34
+ [0.4.0]: https://github.com/beast-ofcourse/atom-lite/releases/tag/v0.4.0
35
+
36
+ ## [0.3.1] - 2026-11-04
37
+
38
+ ### Added
39
+
40
+ - MCP client over stdio: user-config-only `mcpServers`, lazy connections, tool
41
+ discovery and execution as `mcp__<server>__<tool>`, refresh on
42
+ `tools/list_changed`, `/mcp` and `/mcp reconnect`, and `/doctor` health.
43
+ - Session picker and search (`/sessions`, `/search`), resume in place, and
44
+ `/session rename`.
45
+ - Command palette (`ctrl+p`), semantic theme registry, and TUI mouse support.
46
+ - Configuration reference and documentation index.
47
+
48
+ ### Fixed
49
+
50
+ - Ollama provider profiles now forward the `think` option to the adapter.
51
+
52
+ [0.3.1]: https://github.com/beast-ofcourse/atom-lite/releases/tag/v0.3.1
53
+
54
+ ## [0.1.0] - 2026-11-04
55
+
56
+ ### Added
57
+
58
+ - Local-first interactive TUI with streaming assistant output, thinking display,
59
+ boxed tool calls, and collapsible transcripts.
60
+ - Single agent loop with a conflict-aware tool scheduler.
61
+ - Built-in `read`, `write`, `edit`, `bash`, `webfetch`, and `websearch` tools.
62
+ - Provider adapters for OpenAI-compatible endpoints, Ollama, and Gemini.
63
+ - Interactive `/provider` setup with hidden API-key input and validation.
64
+ - Fuzzy `/model` picker spanning every configured provider.
65
+ - Durable JSONL sessions with resume support.
66
+ - Context management with compaction, project instructions, and skill indexing.
67
+ - Live context-window usage in the status line (`tokens: 4.5k/256k`).
68
+ - Bold-red ANSI Shadow startup banner.
69
+ - Approval modes, workspace path boundaries, and hash-guarded writes.
70
+ - Non-gating performance benchmark suite for tools, startup, and TUI rendering.
71
+
72
+ [0.1.0]: https://github.com/beast-ofcourse/atom-lite/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Atom-lite contributors
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 CHANGED
@@ -1,3 +1,314 @@
1
- # Temporary Holding Version
1
+ # Atom-lite
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![npm](https://img.shields.io/npm/v/atom-lite?logo=npm)](https://www.npmjs.com/package/atom-lite)
4
+ [![CI](https://github.com/beast-ofcourse/atom-lite/actions/workflows/ci.yml/badge.svg)](https://github.com/beast-ofcourse/atom-lite/actions/workflows/ci.yml)
5
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D22.19-339933?logo=node.js&logoColor=white)](https://nodejs.org)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
8
+
9
+ **Atom-lite** is a local-first, model-agnostic coding agent with an intentionally small harness: one agent loop, four core built-in tools (`read`, `write`, `edit`, `bash`) plus network tools (`webfetch`, `websearch`), a deterministic conflict-aware scheduler, durable JSONL sessions, and explicit safety boundaries. It runs against local or hosted model providers through interchangeable adapters — no cloud account, telemetry service, or hosted control plane required.
10
+
11
+ > See [`docs/README.md`](./docs/README.md) for the documentation index and [`docs/adr/`](./docs/adr/) for architectural decisions.
12
+
13
+ ---
14
+
15
+ ## Table of contents
16
+
17
+ - [Why Atom-lite](#why-atom-lite)
18
+ - [Features](#features)
19
+ - [Install](#install)
20
+ - [Quick start](#quick-start)
21
+ - [Default provider](#default-provider)
22
+ - [Configuration](#configuration)
23
+ - [Usage](#usage)
24
+ - [Tools](#tools)
25
+ - [Providers](#providers)
26
+ - [Safety & security](#safety--security)
27
+ - [Sessions](#sessions)
28
+ - [Context management](#context-management)
29
+ - [Development](#development)
30
+ - [Architecture](#architecture)
31
+ - [Contributing](#contributing)
32
+ - [License](#license)
33
+
34
+ ## Why Atom-lite
35
+
36
+ Most coding agents accumulate tools, sub-agents, planning frameworks, retrieval pipelines, and orchestration layers until the harness itself becomes the product. Atom-lite takes the opposite stance:
37
+
38
+ - **Small core, strong primitives.** The core contains only a provider interface, a session model, a single agent loop, four core tools plus two network tools, a scheduler/executor, context-window management, configuration, and a CLI.
39
+ - **The model decides; the runtime enforces.** The model chooses which tool to call and what to do next. The runtime validates arguments, enforces workspace boundaries, applies approval rules, schedules calls safely, and returns accurate results. There is no hard-coded "plan → inspect → edit → test" workflow.
40
+ - **Thin harness, not weak engineering.** Provider-specific formats, streaming failures, concurrent file access, shell timeouts, large outputs, context exhaustion, and session recovery are all handled — they are the reliability layer that makes a small harness useful.
41
+
42
+ ## Features
43
+
44
+ - **Six built-in tools** — four core tools (`read`, `write`, `edit`, `bash`) plus `webfetch` and `websearch`. Everything else (search, tests, git, builds) goes through `bash`.
45
+ - **Single agent loop** — one agent, one conversation, one tool registry, one control loop. Parallelism lives inside a tool-call batch.
46
+ - **Conflict-aware scheduler** — per-file read/write locks and a global bash barrier. Parallelism is governed by resource conflicts, not applied blindly.
47
+ - **Durable sessions** — append-only JSONL event logs, resumable across CLI restarts, grouped by workspace.
48
+ - **Context management** — token estimation, compaction (summarization of older history) before the context budget is exceeded, while retaining the full transcript.
49
+ - **Live context meter** — the status line shows context tokens used against the selected model's real window (e.g. `tokens: 4.5k/256k`), resolved from provider metadata with known-model fallbacks.
50
+ - **Approval modes** — `ask` / `trusted` / `deny` for shell commands, with session-level trust.
51
+ - **Hash guards** — `expected_hash` rejects stale `write`/`edit` operations when the file changed since it was read.
52
+ - **Provider-agnostic** — Ollama, Gemini, and any OpenAI-compatible endpoint (LM Studio, llama.cpp, Kilo AI Gateway, OpenAI, Anthropic, OpenRouter, Groq, Mistral, xAI, …).
53
+ - **Interactive provider/model pickers** — `/provider` adds a provider and stores its key securely; `/model` fuzzy-searches every configured provider's models.
54
+ - **Command palette and themes** — `ctrl+p` fuzzy-searches commands, skills, providers, models, themes, and recent sessions. `/theme` switches between auto, dark, light, and no-colour modes.
55
+ - **Local-first** — runs fully against local providers with no cloud account, telemetry, or hosted database.
56
+ - **Safe path handling** — file tools resolve against the workspace and reject escapes; shell is an explicit, sandbox-aware boundary.
57
+
58
+ ## Install
59
+
60
+ ```sh
61
+ npm install -g atom-lite
62
+ ```
63
+
64
+ Or run without installing:
65
+
66
+ ```sh
67
+ npx atom-lite "fix the failing test"
68
+ ```
69
+
70
+ Requires **Node.js >= 22.19** (see `engines` in `package.json`).
71
+
72
+ ## Quick start
73
+
74
+ ```sh
75
+ atom-lite # interactive session in the current directory
76
+ atom-lite "task" # run one task, then exit
77
+ atom-lite --provider NAME # select a provider profile
78
+ atom-lite --continue # resume the most recent session
79
+ atom-lite --help
80
+ ```
81
+
82
+ Pipe a task via stdin:
83
+
84
+ ```sh
85
+ echo "summarize this repo" | atom-lite
86
+ ```
87
+
88
+ ## Default provider
89
+
90
+ Out of the box, Atom-lite uses the **Kilo AI Gateway** (`https://api.kilo.ai/api/gateway`) with the free `kilo-auto/free` model. No API key is required (rate-limited to 200 requests/hour per IP for anonymous use). Override via `--provider`/`--model` or config.
91
+
92
+ ## Configuration
93
+
94
+ User config: `~/.config/atom-lite/config.json`
95
+ Project config: `.atom-lite/config.json` (non-secrets only)
96
+
97
+ Precedence (low → high): defaults → user config → project config (non-secret) → environment → CLI overrides. Security-critical user settings (e.g. `approvalMode`) are **not** overridable by project config.
98
+
99
+ Secrets are stored in `~/.config/atom-lite/credentials.json` with owner-only permissions (`0600`). Environment variables named by a provider's `apiKeyEnv` take precedence over the stored key. Secrets are never written to project config or session files.
100
+
101
+ Environment overrides:
102
+
103
+ | Variable | Effect |
104
+ | --- | --- |
105
+ | `ATOM_LITE_PROVIDER` | Default provider profile name |
106
+ | `ATOM_LITE_APPROVAL_MODE` | `ask` / `trusted` / `deny` |
107
+
108
+ Example `config.json`:
109
+
110
+ ```json
111
+ {
112
+ "defaultProvider": "kilo",
113
+ "providers": {
114
+ "kilo": {
115
+ "type": "openai-compatible",
116
+ "baseUrl": "https://api.kilo.ai/api/gateway",
117
+ "model": "kilo-auto/free",
118
+ "apiKeyEnv": null
119
+ },
120
+ "ollama": {
121
+ "type": "ollama",
122
+ "baseUrl": "http://127.0.0.1:11434",
123
+ "model": "qwen2.5-coder:7b"
124
+ },
125
+ "gemini": {
126
+ "type": "gemini",
127
+ "model": "gemini-2.0-flash",
128
+ "apiKeyEnv": "GEMINI_API_KEY"
129
+ }
130
+ },
131
+ "runtime": {
132
+ "approvalMode": "ask",
133
+ "bashConcurrency": "serial",
134
+ "maxIterations": 40,
135
+ "maxToolCalls": 100
136
+ },
137
+ "context": {
138
+ "maxInputTokens": null,
139
+ "reserveOutputTokens": 4096,
140
+ "compactAtPercent": 85
141
+ }
142
+ }
143
+ ```
144
+
145
+ See [`docs/configuration.md`](./docs/configuration.md) for every field, default, and precedence rule.
146
+
147
+ ## Usage
148
+
149
+ ```
150
+ atom-lite [task] [--provider NAME] [--model MODEL] [--continue] [--session ID]
151
+ [--list-sessions] [--search-sessions QUERY] [--no-tools] [--json]
152
+ [--debug] [--theme NAME] [--no-color] [--version] [--help]
153
+ ```
154
+
155
+ | Flag | Description |
156
+ | --- | --- |
157
+ | `task` | One-shot task; agent runs it and exits |
158
+ | `--provider NAME` | Select a provider profile |
159
+ | `--model MODEL` | Override the model for this run |
160
+ | `--continue` | Resume the most recent session in this workspace |
161
+ | `--session ID` | Resume a specific session |
162
+ | `--list-sessions` | Print the session index and exit |
163
+ | `--search-sessions QUERY` | Print matching sessions with snippets and exit |
164
+ | `--no-tools` | Disable all tools (model-only chat) |
165
+ | `--json` | Non-interactive JSON output |
166
+ | `--debug` | Debug logging |
167
+ | `--theme NAME` | Use `auto`, `dark`, `light`, or `ansi` for this run |
168
+ | `--no-color` | Force the no-colour theme |
169
+ | `--version` | Print version |
170
+ | `--help` | Show help |
171
+
172
+ In the TUI, type `/help` to see every command grouped by category, or press
173
+ `ctrl+p` for the fuzzy command palette. `/theme` opens a live-preview picker and
174
+ persists your choice to user config; `NO_COLOR` and `--no-color` always win.
175
+ `/sessions` opens a searchable session picker scoped to the current workspace,
176
+ with a toggle for all workspaces, and `/search <query>` prints matching sessions
177
+ with content snippets. Mouse wheel scrolling and click-to-focus are enabled for
178
+ interactive terminals and can be disabled with `ui.mouse: false`.
179
+
180
+ ## Tools
181
+
182
+ Four core tools (see [ADR 0001](./docs/adr/0001-four-built-in-tools-only.md)) plus the additive network tools from [ADR 0006](./docs/adr/0006-expanded-toolset.md):
183
+
184
+ | Tool | Purpose |
185
+ | --- | --- |
186
+ | `read` | Inspect files (with optional line ranges) |
187
+ | `write` | Create or replace files safely (hash-guarded) |
188
+ | `edit` | Precise find-and-replace edits (hash-guarded) |
189
+ | `bash` | Execute shell commands (global exclusive barrier by default) |
190
+ | `webfetch` | Fetch a URL and convert HTML to markdown |
191
+ | `websearch` | Search the web and return ranked results |
192
+
193
+ File discovery, search, tests, Git, builds, formatters, and package managers are available through `bash`, not through additional built-in tools.
194
+
195
+ ## Providers
196
+
197
+ | Type | Adapter | Notes |
198
+ | --- | --- | --- |
199
+ | `openai-compatible` | `OpenAICompatibleAdapter` | LM Studio, llama.cpp/llama-server, Kilo AI Gateway, and other compatible endpoints |
200
+ | `ollama` | `OllamaAdapter` | Native Ollama chat API |
201
+ | `gemini` | `GeminiAdapter` | Official Gemini API |
202
+
203
+ Provider profiles are named combinations of endpoint, model, auth source, and options. Switching profiles mid-tool-exchange is disallowed.
204
+
205
+ ### Interactive setup
206
+
207
+ - `/provider` opens a searchable list of built-in providers (Kilo, OpenAI, Anthropic, Google Gemini, OpenRouter, Groq, Mistral, xAI, Ollama, LM Studio, llama.cpp). Selecting a hosted provider prompts for an API key with hidden input, validates it against the provider, and saves it to `~/.config/atom-lite/credentials.json` (`0600`).
208
+ - `/model` opens a fuzzy-searchable picker containing models from **every configured provider** (plus providers whose key is present in the environment). Live model lists are fetched in the background while the picker stays responsive.
209
+ - `/model <provider>/<model>` and `/provider <name>` are the non-interactive forms.
210
+
211
+ The selected provider/model is persisted to the user config, so the next session starts where you left off.
212
+
213
+ ## Safety & security
214
+
215
+ - **Workspace boundary** — `read`/`write`/`edit` resolve paths against the workspace and reject escapes. Shell commands are not constrained by this boundary (their effects are unknown), so `bash` runs as a global exclusive barrier.
216
+ - **Approval modes** — `ask` prompts before each shell command; `trusted` auto-approves; `deny` blocks. Session trust can be granted interactively (`t`).
217
+ - **Hash guards** — prevent stale overwrites when a file changed since it was read.
218
+ - **Sandboxing flags** — reported per command; see `src/security/`.
219
+ - **No secrets in config** — interactive provider setup stores API keys in `~/.config/atom-lite/credentials.json` with `0600` permissions; environment variables still take precedence.
220
+ - **Local-first** — no cloud account, telemetry, or remote control plane required (see [ADR 0004](./docs/adr/0004-local-first-no-cloud-dependency.md)).
221
+
222
+ ## Commands
223
+
224
+ Type `/help` for the grouped list, or press `ctrl+p` for the fuzzy command
225
+ palette. Common commands:
226
+
227
+ | Command | Description |
228
+ | --- | --- |
229
+ | `/model [model]` | Show or switch the active model |
230
+ | `/provider [profile]` | Show or switch the active provider |
231
+ | `/effort [low\|medium\|high]` | Set reasoning effort |
232
+ | `/session [rename <title>]` | Show or rename the current session |
233
+ | `/sessions [all]` | Search and resume a session |
234
+ | `/search <query>` | Search sessions by title or content |
235
+ | `/export [path]` | Export the session transcript |
236
+ | `/mcp [reconnect [server]]` | Inspect or reconnect MCP servers |
237
+ | `/extensions` | List loaded extensions |
238
+ | `/compact` | Compact older context |
239
+ | `/clear` | Clear the transcript view |
240
+ | `/approval` | Change approval mode |
241
+ | `/doctor` | Run diagnostics |
242
+ | `/thinking` | Toggle thinking display |
243
+ | `/theme [auto\|dark\|light\|ansi]` | Switch theme |
244
+ | `/skills`, `/skill <name>` | List or load a skill |
245
+ | `/exit` | Exit the TUI |
246
+
247
+ ## Sessions
248
+
249
+ Sessions are append-only JSONL event logs recording everything that happened in one conversation. They are resumable across CLI restarts and grouped by workspace. Stored under the session store (see `src/sessions/`). Compaction summarizes older history to stay within the context budget while retaining the full transcript.
250
+
251
+ The session index derives a title from the first user message unless `/session rename <title>` overrides it, and records the provider, update time, and message count. `/sessions` resumes a session in place: retained messages are replayed into the transcript and a `session_resumed` event is appended. `/search <query>` matches titles, message content, and workspace paths, ranking title hits first. `--list-sessions` and `--search-sessions` print the same index as stable tab-separated rows for scripts.
252
+
253
+ ## Context management
254
+
255
+ The context manager builds model input, estimates tokens, and triggers compaction before the context budget is exceeded. It also loads project instructions (e.g. `AGENTS.md`/`CLAUDE.md`-style files) subject to `maxProjectInstructionBytes`.
256
+
257
+ ## Development
258
+
259
+ ```sh
260
+ npm install
261
+ npm run dev # run via tsx (src/cli/main.ts)
262
+ npm start # build and run
263
+ npm run typecheck # tsc --noEmit
264
+ npm test # build + node --test
265
+ npm run build # tsc
266
+ npm run format # prettier --write .
267
+ ```
268
+
269
+ Tests live in `tests/` (agent, config, runtime, tools). The project is TypeScript (strict) on NodeNext ESM.
270
+
271
+ ### Releasing
272
+
273
+ 1. Update `version` in `package.json` and add a `CHANGELOG.md` entry.
274
+ 2. Run `npm run typecheck && npm test && npm run bench`.
275
+ 3. Commit, then tag and push: `git tag vX.Y.Z && git push origin master --tags`.
276
+ 4. The `Release` workflow stages the package on npm with provenance and opens a draft GitHub release. It requires an `NPM_TOKEN` repository secret with publish access.
277
+ 5. Approve the staged version on npm (Staged Packages tab, or `npm stage approve <stage-id>` with 2FA), then publish the draft release on GitHub.
278
+
279
+ npm requires a maintainer with 2FA to approve staged releases; CI cannot complete that step.
280
+
281
+ ## Architecture
282
+
283
+ ```
284
+ src/
285
+ agent/ # agent loop & types
286
+ cli/ # terminal UI, approvals, commands
287
+ config/ # schema, defaults, loader
288
+ context/ # builder, manager, compaction, budget, instructions
289
+ providers/ # adapters (openai-compatible, ollama, gemini, fake) + factory
290
+ runtime/ # scheduler, approvals
291
+ security/ # paths, process, redaction
292
+ sessions/ # store, events, recovery
293
+ tools/ # read, write, edit, bash, webfetch, websearch, registry
294
+ ```
295
+
296
+ Key design decisions are recorded as ADRs in [`docs/adr/`](./docs/adr/):
297
+
298
+ - [0001 — Four built-in tools only](./docs/adr/0001-four-built-in-tools-only.md)
299
+ - [0002 — Single agent loop, no sub-agents in v1](./docs/adr/0002-single-agent-loop.md)
300
+ - [0003 — `bash` is a global exclusive barrier](./docs/adr/0003-bash-as-global-exclusive-barrier.md)
301
+ - [0004 — Local-first, no cloud dependency](./docs/adr/0004-local-first-no-cloud-dependency.md)
302
+ - [0005 — OpenTUI for the terminal UI](./docs/adr/0005-opentui-for-terminal-ui.md) (superseded by 0007)
303
+ - [0006 — Expanded built-in toolset (webfetch, websearch)](./docs/adr/0006-expanded-toolset.md)
304
+ - [0007 — pi-tui replaces OpenTUI](./docs/adr/0007-pi-tui-replaces-opentui.md)
305
+
306
+ ## Contributing
307
+
308
+ Read [`CONTRIBUTING.md`](./CONTRIBUTING.md) before opening a pull request. Issues and specs live as markdown under `.scratch/` (see [`docs/agents/issue-tracker.md`](./docs/agents/issue-tracker.md)). Please keep changes consistent with the "small core" principle: new tools require strong justification against ADR 0001.
309
+
310
+ Report vulnerabilities privately as described in [`SECURITY.md`](./SECURITY.md).
311
+
312
+ ## License
313
+
314
+ MIT
@@ -0,0 +1,32 @@
1
+ import type { AgentRuntimeOptions, ContextUsage } from "./types.js";
2
+ import type { Message } from "../types.js";
3
+ export declare class AgentRuntime {
4
+ private provider;
5
+ private model;
6
+ private workspace;
7
+ private approvals;
8
+ private contextManager;
9
+ private onEvent;
10
+ private tools;
11
+ private effort;
12
+ private bashConcurrency;
13
+ private toolMap;
14
+ private limits;
15
+ private systemPrompt;
16
+ private contextWindow;
17
+ private contextUsed;
18
+ constructor(options: AgentRuntimeOptions);
19
+ switchModel(provider: AgentRuntimeOptions["provider"], model?: string): void;
20
+ /** Update the context window for the selected model (metadata may arrive late). */
21
+ setContextWindow(window: number | undefined): void;
22
+ getContextUsage(): ContextUsage;
23
+ private emitContextUsage;
24
+ setEffort(effort: string): void;
25
+ /** Replace the toolset, e.g. after MCP discovery or a list_changed refresh. */
26
+ setTools(tools: AgentRuntimeOptions["tools"]): void;
27
+ getEffort(): string;
28
+ runAgentTurn(input: string, session: {
29
+ messages: Message[];
30
+ appendMessage(m: Message): void;
31
+ }, signal: AbortSignal): Promise<string>;
32
+ }
@@ -0,0 +1,204 @@
1
+ import { DEFAULT_LIMITS } from "../types.js";
2
+ import { executeToolBatch } from "../runtime/scheduler.js";
3
+ import { ContextManager } from "../context/manager.js";
4
+ export class AgentRuntime {
5
+ provider;
6
+ model;
7
+ workspace;
8
+ approvals;
9
+ contextManager;
10
+ onEvent;
11
+ tools;
12
+ effort;
13
+ bashConcurrency;
14
+ toolMap;
15
+ limits;
16
+ systemPrompt;
17
+ contextWindow;
18
+ contextUsed;
19
+ constructor(options) {
20
+ this.provider = options.provider;
21
+ this.model = options.model ?? "default";
22
+ this.workspace = options.workspace ?? process.cwd();
23
+ this.approvals = options.approvals;
24
+ this.onEvent = options.onEvent;
25
+ this.tools = options.tools;
26
+ this.effort = options.effort ?? "medium";
27
+ this.bashConcurrency = options.bashConcurrency ?? "serial";
28
+ this.contextManager =
29
+ options.contextManager ??
30
+ new ContextManager({
31
+ systemPrompt: options.systemPrompt ?? "You are a coding assistant.",
32
+ maxInputTokens: null,
33
+ reserveOutputTokens: 4096,
34
+ compactAtPercent: 85,
35
+ maxProjectInstructionBytes: 30000,
36
+ provider: options.provider,
37
+ model: options.model ?? "default",
38
+ });
39
+ this.toolMap = new Map(options.tools.map((t) => [t.definition.name, t]));
40
+ this.limits = { ...DEFAULT_LIMITS, ...(options.limits ?? {}) };
41
+ this.systemPrompt = options.systemPrompt ?? "You are a coding assistant with tools: read, write, edit, bash, webfetch, websearch.";
42
+ this.contextWindow = options.contextWindow;
43
+ this.contextManager.setModelContextWindow(options.contextWindow);
44
+ }
45
+ switchModel(provider, model) {
46
+ this.provider = provider;
47
+ if (model)
48
+ this.model = model;
49
+ this.contextManager.setProvider(provider, this.model);
50
+ // The new model has a fresh window; usage from the old one is meaningless.
51
+ this.contextUsed = undefined;
52
+ this.onEvent?.({ type: "model_switched", provider: provider.id, model: this.model });
53
+ this.emitContextUsage();
54
+ }
55
+ /** Update the context window for the selected model (metadata may arrive late). */
56
+ setContextWindow(window) {
57
+ const next = typeof window === "number" && Number.isFinite(window) && window > 0
58
+ ? Math.floor(window)
59
+ : undefined;
60
+ if (next === this.contextWindow)
61
+ return;
62
+ this.contextWindow = next;
63
+ this.contextManager.setModelContextWindow(next);
64
+ this.emitContextUsage();
65
+ }
66
+ getContextUsage() {
67
+ return { used: this.contextUsed, window: this.contextWindow };
68
+ }
69
+ emitContextUsage() {
70
+ this.onEvent?.({
71
+ type: "context_usage",
72
+ used: this.contextUsed,
73
+ window: this.contextWindow,
74
+ });
75
+ }
76
+ setEffort(effort) {
77
+ this.effort = effort;
78
+ }
79
+ /** Replace the toolset, e.g. after MCP discovery or a list_changed refresh. */
80
+ setTools(tools) {
81
+ this.tools = tools;
82
+ this.toolMap = new Map(tools.map((t) => [t.definition.name, t]));
83
+ }
84
+ getEffort() {
85
+ return this.effort;
86
+ }
87
+ async runAgentTurn(input, session, signal) {
88
+ session.appendMessage({ role: "user", content: [{ type: "text", text: input }] });
89
+ let totalToolCalls = 0;
90
+ const start = Date.now();
91
+ for (let iteration = 0; iteration < this.limits.maxIterations; iteration++) {
92
+ if (signal.aborted) {
93
+ throw new Error("USER_CANCELLED");
94
+ }
95
+ if (Date.now() - start > this.limits.maxExecutionMs) {
96
+ return "TASK_BUDGET_REACHED";
97
+ }
98
+ const messages = await this.contextManager.build(this.workspace, session.messages);
99
+ if (this.contextManager.consumeCompaction()) {
100
+ // Peers treat usage as unknown after compaction until the next
101
+ // assistant response reports fresh numbers.
102
+ this.contextUsed = undefined;
103
+ this.emitContextUsage();
104
+ }
105
+ const request = {
106
+ model: this.model,
107
+ messages,
108
+ tools: this.tools.map((t) => t.definition),
109
+ signal,
110
+ options: { effort: this.effort },
111
+ };
112
+ let response;
113
+ let streamedText = "";
114
+ if (typeof this.provider.stream === "function") {
115
+ // Stream tokens as they arrive.
116
+ for await (const ev of this.provider.stream(request)) {
117
+ if (ev.type === "thinking") {
118
+ this.onEvent?.({ type: "thinking_delta", text: ev.text });
119
+ }
120
+ else if (ev.type === "text") {
121
+ streamedText += ev.text;
122
+ this.onEvent?.({ type: "assistant_delta", text: ev.text });
123
+ }
124
+ else if (ev.type === "done") {
125
+ response = ev.response;
126
+ }
127
+ }
128
+ if (!response) {
129
+ // Fallback if stream ended without done
130
+ response = {
131
+ message: { role: "assistant", content: streamedText ? [{ type: "text", text: streamedText }] : undefined, toolCalls: undefined },
132
+ toolCalls: [],
133
+ finishReason: "stop",
134
+ };
135
+ }
136
+ }
137
+ else {
138
+ response = await this.provider.generate(request);
139
+ const t = response.message.content?.map((p) => (p.type === "text" ? p.text : "")).join("") ?? "";
140
+ if (t)
141
+ this.onEvent?.({ type: "assistant_text", text: t });
142
+ streamedText = t;
143
+ }
144
+ session.appendMessage(response.message);
145
+ if (response.usage) {
146
+ this.onEvent?.({ type: "usage", input: response.usage.input, output: response.usage.output });
147
+ const used = (response.usage.input ?? 0) + (response.usage.output ?? 0);
148
+ if (used > 0) {
149
+ // The latest assistant step's prompt + generated tokens is the
150
+ // current context occupancy (not a cumulative session total).
151
+ this.contextUsed = used;
152
+ this.emitContextUsage();
153
+ }
154
+ }
155
+ const text = streamedText || (response.message.content?.map((p) => (p.type === "text" ? p.text : "")).join("") ?? "");
156
+ const toolCalls = response.toolCalls ?? [];
157
+ if (toolCalls.length === 0) {
158
+ this.onEvent?.({ type: "final", text });
159
+ return text;
160
+ }
161
+ for (const c of toolCalls)
162
+ this.onEvent?.({ type: "tool_call", id: c.id, name: c.name, args: c.arguments });
163
+ totalToolCalls += toolCalls.length;
164
+ if (totalToolCalls > this.limits.maxToolCalls) {
165
+ return "TASK_BUDGET_REACHED";
166
+ }
167
+ const ctx = {
168
+ workspace: this.workspace,
169
+ signal,
170
+ maxBashTimeMs: this.limits.maxBashTimeMs,
171
+ maxToolOutputBytes: this.limits.maxToolOutputBytes,
172
+ approvals: this.approvals,
173
+ onToolOutput: (call, stream, text) => {
174
+ this.onEvent?.({
175
+ type: "tool_output",
176
+ toolCallId: call.id,
177
+ name: call.name,
178
+ stream,
179
+ text,
180
+ });
181
+ },
182
+ };
183
+ const results = await executeToolBatch(toolCalls, this.toolMap, ctx, this.limits.maxParallelToolCalls, signal, undefined, this.bashConcurrency);
184
+ for (const r of results) {
185
+ session.appendMessage({
186
+ role: "tool",
187
+ toolCallId: r.toolCallId,
188
+ name: r.name,
189
+ content: r.content,
190
+ });
191
+ this.onEvent?.({
192
+ type: "tool_result",
193
+ toolCallId: r.toolCallId,
194
+ name: r.name,
195
+ content: r.content,
196
+ isError: r.isError,
197
+ diff: r.diff,
198
+ });
199
+ }
200
+ }
201
+ return "TASK_BUDGET_REACHED";
202
+ }
203
+ }
204
+ //# sourceMappingURL=loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}