amness 0.0.0-stage → 0.1.2

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 (235) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +237 -2
  3. package/dist/cli/acpcli.d.ts +7 -0
  4. package/dist/cli/acpcli.js +14 -0
  5. package/dist/cli/amness.d.ts +2 -0
  6. package/dist/cli/amness.js +694 -0
  7. package/dist/cli/benchcli.d.ts +5 -0
  8. package/dist/cli/benchcli.js +160 -0
  9. package/dist/cli/config.d.ts +79 -0
  10. package/dist/cli/config.js +111 -0
  11. package/dist/cli/demo.d.ts +13 -0
  12. package/dist/cli/demo.js +44 -0
  13. package/dist/cli/detect.d.ts +2 -0
  14. package/dist/cli/detect.js +20 -0
  15. package/dist/cli/evalcli.d.ts +15 -0
  16. package/dist/cli/evalcli.js +198 -0
  17. package/dist/cli/format.d.ts +5 -0
  18. package/dist/cli/format.js +55 -0
  19. package/dist/cli/headless.d.ts +2 -0
  20. package/dist/cli/headless.js +169 -0
  21. package/dist/cli/keystore.d.ts +9 -0
  22. package/dist/cli/keystore.js +108 -0
  23. package/dist/cli/model.d.ts +11 -0
  24. package/dist/cli/model.js +19 -0
  25. package/dist/cli/plugincli.d.ts +2 -0
  26. package/dist/cli/plugincli.js +176 -0
  27. package/dist/cli/schedulecli.d.ts +2 -0
  28. package/dist/cli/schedulecli.js +66 -0
  29. package/dist/cli/state.d.ts +11 -0
  30. package/dist/cli/state.js +19 -0
  31. package/dist/cli/tui/ansi.d.ts +38 -0
  32. package/dist/cli/tui/ansi.js +142 -0
  33. package/dist/cli/tui/app.d.ts +328 -0
  34. package/dist/cli/tui/app.js +1358 -0
  35. package/dist/cli/tui/blocks.d.ts +151 -0
  36. package/dist/cli/tui/blocks.js +128 -0
  37. package/dist/cli/tui/brand.d.ts +9 -0
  38. package/dist/cli/tui/brand.js +16 -0
  39. package/dist/cli/tui/canvas.d.ts +92 -0
  40. package/dist/cli/tui/canvas.js +199 -0
  41. package/dist/cli/tui/cards.d.ts +44 -0
  42. package/dist/cli/tui/cards.js +215 -0
  43. package/dist/cli/tui/clipboard.d.ts +5 -0
  44. package/dist/cli/tui/clipboard.js +29 -0
  45. package/dist/cli/tui/commands.d.ts +10 -0
  46. package/dist/cli/tui/commands.js +650 -0
  47. package/dist/cli/tui/complete.d.ts +39 -0
  48. package/dist/cli/tui/complete.js +113 -0
  49. package/dist/cli/tui/custom.d.ts +9 -0
  50. package/dist/cli/tui/custom.js +34 -0
  51. package/dist/cli/tui/diffview.d.ts +25 -0
  52. package/dist/cli/tui/diffview.js +130 -0
  53. package/dist/cli/tui/editor.d.ts +60 -0
  54. package/dist/cli/tui/editor.js +230 -0
  55. package/dist/cli/tui/full.d.ts +86 -0
  56. package/dist/cli/tui/full.js +630 -0
  57. package/dist/cli/tui/keys.d.ts +31 -0
  58. package/dist/cli/tui/keys.js +134 -0
  59. package/dist/cli/tui/markdown.d.ts +37 -0
  60. package/dist/cli/tui/markdown.js +155 -0
  61. package/dist/cli/tui/mentions.d.ts +15 -0
  62. package/dist/cli/tui/mentions.js +48 -0
  63. package/dist/cli/tui/modal.d.ts +26 -0
  64. package/dist/cli/tui/modal.js +107 -0
  65. package/dist/cli/tui/overlays.d.ts +98 -0
  66. package/dist/cli/tui/overlays.js +237 -0
  67. package/dist/cli/tui/pager.d.ts +15 -0
  68. package/dist/cli/tui/pager.js +66 -0
  69. package/dist/cli/tui/pricing.d.ts +9 -0
  70. package/dist/cli/tui/pricing.js +23 -0
  71. package/dist/cli/tui/rich.d.ts +16 -0
  72. package/dist/cli/tui/rich.js +72 -0
  73. package/dist/cli/tui/screen.d.ts +30 -0
  74. package/dist/cli/tui/screen.js +62 -0
  75. package/dist/cli/tui/session.d.ts +77 -0
  76. package/dist/cli/tui/session.js +103 -0
  77. package/dist/cli/tui/sidebar.d.ts +84 -0
  78. package/dist/cli/tui/sidebar.js +114 -0
  79. package/dist/cli/tui/text.d.ts +15 -0
  80. package/dist/cli/tui/text.js +94 -0
  81. package/dist/cli/tui/theme.d.ts +59 -0
  82. package/dist/cli/tui/theme.js +148 -0
  83. package/dist/cli/tui/themes.d.ts +56 -0
  84. package/dist/cli/tui/themes.js +80 -0
  85. package/dist/cli/tui/tokens.d.ts +39 -0
  86. package/dist/cli/tui/tokens.js +71 -0
  87. package/dist/cli/tui/view.d.ts +60 -0
  88. package/dist/cli/tui/view.js +178 -0
  89. package/dist/cli/ui.d.ts +34 -0
  90. package/dist/cli/ui.js +224 -0
  91. package/dist/src/acp.d.ts +28 -0
  92. package/dist/src/acp.js +111 -0
  93. package/dist/src/agents.d.ts +23 -0
  94. package/dist/src/agents.js +71 -0
  95. package/dist/src/anthropic.d.ts +30 -0
  96. package/dist/src/anthropic.js +91 -0
  97. package/dist/src/approver.d.ts +15 -0
  98. package/dist/src/approver.js +40 -0
  99. package/dist/src/bench.d.ts +67 -0
  100. package/dist/src/bench.js +201 -0
  101. package/dist/src/bundle.d.ts +36 -0
  102. package/dist/src/bundle.js +55 -0
  103. package/dist/src/chaos.d.ts +15 -0
  104. package/dist/src/chaos.js +26 -0
  105. package/dist/src/code.d.ts +187 -0
  106. package/dist/src/code.js +590 -0
  107. package/dist/src/codeindex.d.ts +65 -0
  108. package/dist/src/codeindex.js +300 -0
  109. package/dist/src/deep.d.ts +62 -0
  110. package/dist/src/deep.js +177 -0
  111. package/dist/src/diff.d.ts +8 -0
  112. package/dist/src/diff.js +74 -0
  113. package/dist/src/dynamic.d.ts +42 -0
  114. package/dist/src/dynamic.js +133 -0
  115. package/dist/src/embed.d.ts +8 -0
  116. package/dist/src/embed.js +25 -0
  117. package/dist/src/evalcases.d.ts +11 -0
  118. package/dist/src/evalcases.js +196 -0
  119. package/dist/src/evals.d.ts +197 -0
  120. package/dist/src/evals.js +340 -0
  121. package/dist/src/gitflow.d.ts +27 -0
  122. package/dist/src/gitflow.js +56 -0
  123. package/dist/src/grade.d.ts +42 -0
  124. package/dist/src/grade.js +96 -0
  125. package/dist/src/guidance.d.ts +15 -0
  126. package/dist/src/guidance.js +68 -0
  127. package/dist/src/hardcases.d.ts +2 -0
  128. package/dist/src/hardcases.js +94 -0
  129. package/dist/src/harness.d.ts +411 -0
  130. package/dist/src/harness.js +725 -0
  131. package/dist/src/hooks.d.ts +44 -0
  132. package/dist/src/hooks.js +116 -0
  133. package/dist/src/images.d.ts +13 -0
  134. package/dist/src/images.js +27 -0
  135. package/dist/src/index.d.ts +57 -0
  136. package/dist/src/index.js +57 -0
  137. package/dist/src/ledger.d.ts +58 -0
  138. package/dist/src/ledger.js +78 -0
  139. package/dist/src/live.d.ts +16 -0
  140. package/dist/src/live.js +80 -0
  141. package/dist/src/lsp.d.ts +31 -0
  142. package/dist/src/lsp.js +147 -0
  143. package/dist/src/memory.d.ts +128 -0
  144. package/dist/src/memory.js +390 -0
  145. package/dist/src/metrics.d.ts +3 -0
  146. package/dist/src/metrics.js +42 -0
  147. package/dist/src/mining.d.ts +49 -0
  148. package/dist/src/mining.js +126 -0
  149. package/dist/src/openai.d.ts +50 -0
  150. package/dist/src/openai.js +307 -0
  151. package/dist/src/parallel.d.ts +66 -0
  152. package/dist/src/parallel.js +135 -0
  153. package/dist/src/patch.d.ts +45 -0
  154. package/dist/src/patch.js +219 -0
  155. package/dist/src/permissions.d.ts +46 -0
  156. package/dist/src/permissions.js +245 -0
  157. package/dist/src/plugins.d.ts +148 -0
  158. package/dist/src/plugins.js +225 -0
  159. package/dist/src/pluginscan.d.ts +8 -0
  160. package/dist/src/pluginscan.js +20 -0
  161. package/dist/src/procs.d.ts +41 -0
  162. package/dist/src/procs.js +94 -0
  163. package/dist/src/profiles.d.ts +36 -0
  164. package/dist/src/profiles.js +61 -0
  165. package/dist/src/progress.d.ts +29 -0
  166. package/dist/src/progress.js +75 -0
  167. package/dist/src/prompts.d.ts +10 -0
  168. package/dist/src/prompts.js +28 -0
  169. package/dist/src/ratelimit.d.ts +34 -0
  170. package/dist/src/ratelimit.js +116 -0
  171. package/dist/src/replay.d.ts +25 -0
  172. package/dist/src/replay.js +99 -0
  173. package/dist/src/review.d.ts +20 -0
  174. package/dist/src/review.js +49 -0
  175. package/dist/src/route.d.ts +9 -0
  176. package/dist/src/route.js +30 -0
  177. package/dist/src/router.d.ts +61 -0
  178. package/dist/src/router.js +126 -0
  179. package/dist/src/sandbox.d.ts +13 -0
  180. package/dist/src/sandbox.js +68 -0
  181. package/dist/src/schedule.d.ts +20 -0
  182. package/dist/src/schedule.js +59 -0
  183. package/dist/src/schema.d.ts +13 -0
  184. package/dist/src/schema.js +36 -0
  185. package/dist/src/secrets.d.ts +10 -0
  186. package/dist/src/secrets.js +41 -0
  187. package/dist/src/shell.d.ts +34 -0
  188. package/dist/src/shell.js +95 -0
  189. package/dist/src/skills.d.ts +20 -0
  190. package/dist/src/skills.js +112 -0
  191. package/dist/src/snapshot.d.ts +20 -0
  192. package/dist/src/snapshot.js +93 -0
  193. package/dist/src/stats.d.ts +24 -0
  194. package/dist/src/stats.js +62 -0
  195. package/dist/src/strategies.d.ts +16 -0
  196. package/dist/src/strategies.js +35 -0
  197. package/dist/src/suites.d.ts +30 -0
  198. package/dist/src/suites.js +112 -0
  199. package/dist/src/trace.d.ts +63 -0
  200. package/dist/src/trace.js +153 -0
  201. package/dist/src/tune.d.ts +38 -0
  202. package/dist/src/tune.js +49 -0
  203. package/dist/src/web.d.ts +19 -0
  204. package/dist/src/web.js +56 -0
  205. package/dist/src/worktree.d.ts +24 -0
  206. package/dist/src/worktree.js +85 -0
  207. package/docs/agent-loop.md +222 -0
  208. package/docs/architecture.md +228 -0
  209. package/docs/bench.md +292 -0
  210. package/docs/budgets.md +185 -0
  211. package/docs/build-your-own-harness.md +424 -0
  212. package/docs/cookbook.md +375 -0
  213. package/docs/development.md +150 -0
  214. package/docs/evaluation.md +450 -0
  215. package/docs/features.md +1320 -0
  216. package/docs/getting-started.md +205 -0
  217. package/docs/headless.md +188 -0
  218. package/docs/images/approval.png +0 -0
  219. package/docs/images/chat.png +0 -0
  220. package/docs/images/daylight.png +0 -0
  221. package/docs/images/loop.png +0 -0
  222. package/docs/images/palette.png +0 -0
  223. package/docs/images/running.png +0 -0
  224. package/docs/images/subagent-done.png +0 -0
  225. package/docs/images/subagent-running.png +0 -0
  226. package/docs/images/welcome.png +0 -0
  227. package/docs/index.md +25 -0
  228. package/docs/library.md +267 -0
  229. package/docs/plugins.md +691 -0
  230. package/docs/providers.md +175 -0
  231. package/docs/safety.md +250 -0
  232. package/docs/usage.md +348 -0
  233. package/docs/why.md +155 -0
  234. package/docs/writing-guide.md +39 -0
  235. package/package.json +66 -4
@@ -0,0 +1,375 @@
1
+ # Cookbook: short recipes
2
+
3
+ Each recipe shows one task you may want to do, with the exact commands and what you will see.
4
+
5
+ In this page you will learn how to:
6
+
7
+ - run Amness in CI, with several attempts or with parts in parallel
8
+ - control cost, and use a local model
9
+ - add your own rules, and measure them
10
+ - replay, review and schedule work
11
+
12
+ Commands marked "calls your model" cost tokens. The others call no model.
13
+
14
+ ## 1. Run a fix in CI, with several attempts
15
+
16
+ *Calls your model.* Use `amness run` for a one-shot run with no terminal. `--verify` is a command that must exit 0 before the agent may finish.
17
+
18
+ ```bash
19
+ amness run --verify "npm test" --json "fix the failing test"
20
+ ```
21
+
22
+ You will see one JSON event per line, then a last line with `"kind":"result"`. The exit code is `0` if the agent finished, `1` if it did not, and `2` for a usage or configuration error. Risky commands are denied unless you add `--yes`.
23
+
24
+ Project hooks and plugins are skipped in headless runs unless you add `--trust-project`. See [Headless and CI](headless.md).
25
+
26
+ Want more than one try? Add `--best-of 3`. Amness then runs the task up to three times in separate git worktrees and stops at the first attempt that passes `--verify`. It applies that result to your folder.
27
+
28
+ ```bash
29
+ amness run --best-of 3 --verify "npm test" "fix the failing test"
30
+ ```
31
+
32
+ While it runs, you will see lines such as `attempt 1: failed verify (41200 tokens)`. At the end you will see `attempt 2 won and was applied`. If no attempt passes, you see `no attempt passed npm test (3 tried, N tokens)`. `--verify` is required, and the folder must be a git repository with at least one commit. The token cap is shared between the attempts. Whether best-of-n improves results is not measured yet.
33
+
34
+ ## 2. Split work into parts
35
+
36
+ *Calls your model.* `--parts` runs independent tasks at the same time, each in its own worktree. Amness merges them one at a time and runs `--verify` after each merge.
37
+
38
+ 1. Write `parts.json`:
39
+
40
+ ```json
41
+ [
42
+ { "name": "docs", "task": "Fix the typos in README.md" },
43
+ { "name": "tests", "task": "Add a test for the parse function in src/parse.ts" }
44
+ ]
45
+ ```
46
+
47
+ 2. Run it:
48
+
49
+ ```bash
50
+ amness run --parts parts.json --verify "npm test"
51
+ ```
52
+
53
+ You will see one line per part, with a status such as `merged`, `conflict`, `failed-verify`, `broke-verify`, `no-change`, `error` or `skipped-budget`. A conflict is reported and not applied. The exit code is `0` only if every part is `merged`. Use parts only for work that does not touch the same files.
54
+
55
+ ## 3. Limit cost
56
+
57
+ The cap is the most tokens one turn may use. Cached input counts as a tenth, because it costs less.
58
+
59
+ In the chat:
60
+
61
+ ```text
62
+ /budget
63
+ /budget 500k
64
+ ```
65
+
66
+ The first line shows the cap, and the tokens used in the last turn. The second sets a new cap. The cap must be at least 10000 tokens. You can write `400000`, `400k` or `1m`.
67
+
68
+ At 50%, 75% and 90% of the cap, Amness tells the model to wrap up. Just before the cap, the model writes a short final report. In a headless run, use a flag:
69
+
70
+ ```bash
71
+ amness run --max-tokens 200000 --verify "npm test" "fix the failing test"
72
+ ```
73
+
74
+ The default for headless runs is 300000. A very small cap can stop a task before it is done. See [Budgets and subagents](budgets.md).
75
+
76
+ ## 4. Use a local model
77
+
78
+ Any server with an OpenAI-compatible `/v1` address works. Ollama is one example.
79
+
80
+ ```bash
81
+ ollama pull qwen2.5-coder:7b
82
+ amness run --provider ollama --model qwen2.5-coder:7b "list the TODO comments in src"
83
+ ```
84
+
85
+ In the chat, pick the provider and model with `/provider` and `/model` instead: the interactive `amness` command does not read `--provider` or `--model`.
86
+
87
+ The address defaults to `http://localhost:11434/v1`. For another server, use `amness run --provider custom --base-url http://localhost:1234/v1 --model <model-name>`. You need no API key for a local server.
88
+
89
+ Limits: the model must support tool calling. Small models often work better with `/mode plan` and a `--max-tokens` limit. How well any local model performs is not measured here. To measure it, run `amness eval --variants ab` with that model. See [Providers and models](providers.md).
90
+
91
+ ## 5. Add a house rule as a plugin
92
+
93
+ A plugin can block an action in code. This one blocks hand edits of `package-lock.json`.
94
+
95
+ 1. Save `.amness/plugins/no-lockfiles.ts`:
96
+
97
+ ```ts
98
+ export default {
99
+ name: "no-lockfiles",
100
+ hooks: {
101
+ PreToolUse: ({ tool, args }: { tool: string; args: any }) =>
102
+ (tool === "write_file" || tool === "edit_file") && /package-lock\.json$/.test(String(args.path))
103
+ ? { block: "lockfiles are generated: run the package manager instead" }
104
+ : undefined,
105
+ },
106
+ };
107
+ ```
108
+
109
+ 2. Start `amness` and choose "Yes, trust this version" when it asks.
110
+ 3. Type `/plugins`. You will see `no-lockfiles` and `hooks: PreToolUse`.
111
+
112
+ When the agent tries to edit the lockfile, it gets `BLOCKED BY A HOOK: lockfiles are generated: run the package manager instead`. See [Plugins](plugins.md) for the full steps.
113
+
114
+ ## 6. Compare two harness variants
115
+
116
+ *Calls your model.* First check the tasks. This is free.
117
+
118
+ ```bash
119
+ amness eval --selftest
120
+ ```
121
+
122
+ Then compare the full harness with the one that has the reviewer:
123
+
124
+ ```bash
125
+ amness eval --variants full,full+review --trials 3 --jobs 2
126
+ ```
127
+
128
+ Amness prints a plan and asks before it starts. Add `--yes` to skip the question. You will see a table with `pass [95% CI]`, `pass^3`, `tok/solved`, `cache`, `steps`, `secs` and `pareto`, and a second table with the change against the first variant. A `verdict` of `inconclusive` means the data cannot tell. See [Evaluating the harness](evaluation.md) for how to read each column.
129
+
130
+ ## 7. Write your own eval task
131
+
132
+ Use a task from your own work. A task is a JSON file with files, a task text and a held-out check.
133
+
134
+ 1. Save `my-tasks/fix-add.json`:
135
+
136
+ ```json
137
+ {
138
+ "name": "fix-add",
139
+ "files": {
140
+ "add.js": "exports.add = (a, b) => a - b;\n",
141
+ "test.js": "const { add } = require('./add');\nif (add(2, 3) !== 5) process.exit(1);\n"
142
+ },
143
+ "task": "The add function is wrong. Fix it.",
144
+ "verify": "node test.js",
145
+ "check": "node test.js",
146
+ "solution": { "add.js": "exports.add = (a, b) => a + b;\n" }
147
+ }
148
+ ```
149
+
150
+ 2. Check it. This calls no model:
151
+
152
+ ```bash
153
+ amness eval --cases ./my-tasks --selftest
154
+ ```
155
+
156
+ You will see `ok fix-add`.
157
+
158
+ 3. Run it (calls your model):
159
+
160
+ ```bash
161
+ amness eval --cases ./my-tasks --variants ab --trials 3
162
+ ```
163
+
164
+ One task is too few to compare variants. Add more tasks first.
165
+
166
+ ## 8. Replay a saved trace after you change the harness
167
+
168
+ Replay feeds a recorded session back through the current harness. It calls no model and runs no tool. Only the harness rules can differ, so you can test a change for free.
169
+
170
+ 1. Find a trace. Chat sessions write them to `.amness/traces/`. For a headless run, add `--trace`:
171
+
172
+ ```bash
173
+ ls .amness/traces
174
+ ```
175
+
176
+ 2. Replay one, here with the `nudge` guard off:
177
+
178
+ ```bash
179
+ amness replay .amness/traces/<session>.jsonl --off nudge
180
+ ```
181
+
182
+ Replace `<session>` with a file name from step 1.
183
+
184
+ You will see a line such as `run 1: 12 model turn(s), identical harness behaviour`, or `3 difference(s)` followed by lines that start with `- recorded only:` and `+ replay only:`. The exit code is `0` if all runs match and `1` if not. Other flags are `--stagnation-turns n`, `--max-steps n` and `--context-budget chars`.
185
+
186
+ Limits: after the first difference, the recording no longer matches what the model would have said, so later lines are only a hint. Old traces without model messages cannot be replayed.
187
+
188
+ ## 9. Find recurring failures
189
+
190
+ Amness reads your session traces and groups what went wrong.
191
+
192
+ ```bash
193
+ amness traces
194
+ ```
195
+
196
+ You will see a summary line, then patterns with a count, for example `24× ran out of budget: budget N% used (10 sessions)`, and the sessions with the most trouble. In the chat, type `/report` for the same view.
197
+
198
+ To keep a failure from coming back, turn it into an eval task. The `--check` command must exit 0 only when the task is really done:
199
+
200
+ ```bash
201
+ amness traces --case my-bug --task "Fix the date parsing bug" --check "npm test"
202
+ ```
203
+
204
+ Amness copies the tracked files at git `HEAD` to `.amness/evals/cases/my-bug.json`. Run it with `amness eval --cases .amness/evals/cases --variants ab --trials 3`.
205
+
206
+ ## 10. Schedule a nightly run
207
+
208
+ *Calls your model when the job runs.* Schedules use cron. The five fields are minute, hour, day of month, month and day of week.
209
+
210
+ 1. Add a schedule for this project (3:00 on weekdays):
211
+
212
+ ```bash
213
+ amness schedule add nightly "0 3 * * 1-5" "run the tests and fix small failures" --verify "npm test"
214
+ ```
215
+
216
+ You will see the text: saved "nightly". Run `amness schedule install` to see the crontab line.
217
+
218
+ 2. Look at the crontab line. This writes nothing:
219
+
220
+ ```bash
221
+ amness schedule install
222
+ ```
223
+
224
+ 3. Put it in your crontab:
225
+
226
+ ```bash
227
+ amness schedule install --write
228
+ ```
229
+
230
+ Other commands are `amness schedule list`, `amness schedule remove nightly` and `amness schedule uninstall`. Amness only changes a marked block for this project in your crontab.
231
+
232
+ Each run is `amness run --json`, so risky commands are denied. The output goes to `.amness/schedule-logs/nightly.jsonl`. Cron must be able to find `amness` and your API key. Set them in the crontab environment or use a wrapper script. Cron names such as `MON` are not accepted. Use numbers.
233
+
234
+ ## 11. Use it from an editor
235
+
236
+ Editors such as Zed and JetBrains can start Amness as their coding agent with the Agent Client Protocol (ACP). You do not run the command by hand.
237
+
238
+ For Zed, add this to your settings:
239
+
240
+ ```json
241
+ "agent_servers": { "Amness": { "command": "amness", "args": ["acp"] } }
242
+ ```
243
+
244
+ Amness uses your configured provider and model. When the agent wants to do something risky, the editor shows a permission request with the choices Allow and Reject.
245
+
246
+ Limits: Amness does not implement `session/load`, `authenticate`, `fs/*` or `terminal/*`. Only the Zed setting above comes from the built-in help. JetBrains setup is not verified here.
247
+
248
+ ## 12. Review your changes before a pull request
249
+
250
+ In the chat, inside a git repository:
251
+
252
+ ```text
253
+ /review
254
+ ```
255
+
256
+ The agent reads your changes against the base branch and lists findings, or says `review: no problems found`. Use `/review main` to name the base branch. The review is read-only and costs model calls.
257
+
258
+ To create the pull request:
259
+
260
+ ```text
261
+ /pr
262
+ ```
263
+
264
+ Amness drafts a title and a description from your diff and commits. It shows them and asks "Create this pull request on GitHub?" with "Create it", "Create it as a draft" and "Cancel". If the branch is not on the remote, it asks before it pushes. Use `/pr draft` for a draft.
265
+
266
+ Limits: `/pr` needs the GitHub CLI (`gh`) and a branch that is not the base branch. It creates nothing without your choice.
267
+
268
+ ## 13. Write a finish gate
269
+
270
+ A *finish gate* is a check that must pass before the agent may finish. Save `.amness/plugins/gate.ts`:
271
+
272
+ ```ts
273
+ export default {
274
+ name: "gate",
275
+ gates: [{
276
+ name: "tests-after-edit",
277
+ check: (ctx: any) => ctx.changed.length && ctx.testsAfterLastEdit === false
278
+ ? "you changed files but did not run the tests after the last edit" : true,
279
+ }],
280
+ };
281
+ ```
282
+
283
+ Start `amness` and approve the plugin. If the agent edits files and tries to finish without a test run, it sees `REJECTED by a hook: gate "tests-after-edit" (plugin gate) found problems:`. After 2 rejections for the same task, the run finishes anyway with a warning. Details: [Plugins](plugins.md#add-a-finish-gate). Tested with scripted models only.
284
+
285
+ ## 14. Deny a tool with a policy and test it on past traces
286
+
287
+ 1. Save `.amness/plugins/nocurl.ts`:
288
+
289
+ ```ts
290
+ export default {
291
+ name: "nocurl",
292
+ policy: ({ tool, args }: any) =>
293
+ tool === "sh" && /\bcurl\b/.test(String(args.cmd)) ? { action: "deny", reason: "no curl" } : undefined,
294
+ };
295
+ ```
296
+
297
+ 2. Replay your old sessions through it. This calls no model:
298
+
299
+ ```bash
300
+ amness plugin policy .amness/traces --plugin .amness/plugins/nocurl.ts
301
+ ```
302
+
303
+ You will see a line such as `40 trace file(s): 2 denied, 0 would ask, 0 allowed by the policy, 900 without an opinion`, then the denied calls. Deny beats ask, and ask beats allow. A policy cannot loosen the safety floor. Details: [Plugins](plugins.md#write-policy-as-code).
304
+
305
+ ## 15. Try a loop strategy and measure it
306
+
307
+ *Calls your model.* Try it in the chat first:
308
+
309
+ ```text
310
+ /strategy plan-first
311
+ ```
312
+
313
+ Then measure it against the default:
314
+
315
+ ```bash
316
+ amness eval --variants full,strategy:plan-first --builtin hard --trials 3 --metrics diff-lines,tool-calls
317
+ ```
318
+
319
+ Read the report as in recipe 6. On one run with `gpt-4.1-mini` (6 tasks), `plan-first` and `full` had the same pass rate and the result was inconclusive. See [Evaluating the harness](evaluation.md#loop-strategies-2026-10-30).
320
+
321
+ ## 16. Stop regressions in CI with `--gate`
322
+
323
+ *Calls your model.* Save a baseline once and commit it:
324
+
325
+ ```bash
326
+ amness eval --variants full --builtin hard --trials 3 --yes --out evals/baseline.json
327
+ ```
328
+
329
+ In CI, run the same command with a gate:
330
+
331
+ ```bash
332
+ amness eval --variants full --builtin hard --trials 3 --yes --gate evals/baseline.json
333
+ ```
334
+
335
+ The exit code is 1 when the pass rate dropped by more than 5 points and the drop is clear, or when tokens per solved task grew by more than 25%. Change the limits with `--gate-tol` and `--gate-cost`. A drop that noise could explain is only a warning. See [Custom metrics and the regression gate](evaluation.md#custom-metrics-and-the-regression-gate).
336
+
337
+ ## 17. Make things fail on purpose with a chaos variant
338
+
339
+ *Calls your model.* Check that the harness recovers when tools or the API fail:
340
+
341
+ ```bash
342
+ amness eval --variants full,chaos:tools,chaos:429 --trials 3
343
+ ```
344
+
345
+ `chaos:tools` makes about 1 in 4 tool calls fail. `chaos:429` makes about 3 in 10 model calls fail with a rate-limit error. Other kinds are `chaos:args` and `chaos:slow-tools`. A lower pass rate under chaos shows where the harness does not recover. Not measured on a real model yet.
346
+
347
+ ## 18. Compare Amness with Claude Code and Codex
348
+
349
+ *Calls your models and costs money.* Install and log in to the other tools yourself. Then check, plan and probe before the real run:
350
+
351
+ ```bash
352
+ amness bench --init
353
+ amness bench --check
354
+ amness bench --config bench.json --dry-run
355
+ amness bench --config bench.json --probe
356
+ amness bench --config bench.json --builtin code
357
+ ```
358
+
359
+ Set a model for each contestant in `bench.json` and set a spending limit first. The result is a table with pass rate, tokens, cost and time. With 13 tasks, only large differences can be seen. Read [Compare coding agents with `amness bench`](bench.md), especially the Windows setup and the fair-play list. The `claude` and `codex` presets have not been run on a real machine by the author.
360
+
361
+ ## Related pages
362
+
363
+ - [Compare coding agents](bench.md)
364
+ - [Headless and CI](headless.md)
365
+ - [Evaluating the harness](evaluation.md)
366
+ - [Plugins](plugins.md)
367
+ - [Providers and models](providers.md)
368
+ - [Budgets and subagents](budgets.md)
369
+
370
+ ## Next steps
371
+
372
+ - Start with recipe 6 or 7 to measure the harness on your own work.
373
+ - Recipes 13 to 17 cover finish gates, policies, strategies, CI gates and chaos.
374
+ - Read [Features in depth](features.md) for permissions, sandbox and memory.
375
+ - Read [Using the chat](usage.md) for all slash commands.
@@ -0,0 +1,150 @@
1
+ # Development and limitations
2
+
3
+ This page shows you how to run the tests, where the code lives, how to add a feature, and what Amness cannot do yet.
4
+
5
+ In this page you will learn:
6
+
7
+ - how to run the type check and the tests
8
+ - what each folder contains
9
+ - how to add a tool, a guard or a command
10
+ - the known limits of the project
11
+
12
+ You need Node.js 22.18 or newer (the `engines` field in `package.json`) and `git`. The pseudo-terminal tests also need `python3`.
13
+
14
+ ## Run the tests
15
+
16
+ **What it is.** The project has a type check, unit tests, UI tests, and tests that run the real program in a pseudo-terminal. A *pseudo-terminal* is a fake terminal that a script can type into and read from.
17
+
18
+ **Why you would use it.** Run them before every change. CI runs the same commands on every push to `main` and every pull request.
19
+
20
+ **How to use it.**
21
+
22
+ 1. Install the packages:
23
+
24
+ ```bash
25
+ npm install
26
+ ```
27
+
28
+ 2. Check the types. This runs `tsc --noEmit` over `src`, `cli`, `examples` and `test`:
29
+
30
+ ```bash
31
+ npm run typecheck
32
+ ```
33
+
34
+ 3. Run the tests. This uses the Node.js built-in test runner on `test/**/*.test.ts`, with a 180 second limit per test:
35
+
36
+ ```bash
37
+ npm test
38
+ ```
39
+
40
+ 4. Run the terminal tests (needs `python3`). This starts the real `amness` program in a pseudo-terminal against a mock server:
41
+
42
+ ```bash
43
+ npm run test:pty
44
+ ```
45
+
46
+ 5. Run one test file:
47
+
48
+ ```bash
49
+ node --test test/permissions.test.ts
50
+ ```
51
+
52
+ **Example.** When all tests pass, the summary at the end of `npm test` shows `fail 0`, and the command exits with code 0. The exact format depends on your Node.js version.
53
+
54
+ **Limits and common problems.**
55
+
56
+ - The Linux sandbox tests skip themselves when Bubblewrap cannot create namespaces. CI has one extra step that sets `AMNESS_REQUIRE_SANDBOX=1`, so a skipped sandbox test shows up there. This step is informational and does not fail the build.
57
+ - The tests do not call real model APIs. They use scripted models and mock HTTP servers (see below). Use `amness eval` against a real model to measure behavior. See [Evaluating the harness](evaluation.md).
58
+ - Some tests set `AMNESS_HOME` to a temporary folder. If you run Amness by hand while testing, set `AMNESS_HOME` too, so you do not change your real `~/.amness`.
59
+
60
+ ## Know what CI runs
61
+
62
+ The file `.github/workflows/ci.yml` has these jobs:
63
+
64
+ | Job | What it does |
65
+ |---|---|
66
+ | `test` | `npm ci`, `npm run typecheck`, `npm test` on Node 22 and Node 24, with Bubblewrap installed |
67
+ | `terminal` | `python3 test/pty/tui.py` on Node 24 |
68
+ | `package` | `npm pack`, installs the tarball in a new folder, runs `npx amness --version`, and checks that `import("amness")` exports `createCodeAgent` |
69
+ | `docker` | builds the `Dockerfile`, runs `--version` and `eval --selftest --only off-by-one` |
70
+ | `windows` | `npm run typecheck` and `npm test` on Windows. It is informational (`continue-on-error`) |
71
+ | `action` | runs the GitHub Action (`action.yml`) with no API key and checks that it reports instead of crashing |
72
+
73
+ A second workflow, `.github/workflows/publish.yml`, runs type check and tests, then `npm stage publish --provenance`, when you push a tag that starts with `v`. It needs an `NPM_TOKEN` secret (a stage-only token is enough). It only stages the version; you release it with `npm stage approve <id>` and your 2FA code.
74
+
75
+ ## Find your way around the project
76
+
77
+ | Path | What is in it |
78
+ |---|---|
79
+ | `src/` | The library: the loop (`harness.ts`), the coding agent (`code.ts`), the research agent (`deep.ts`), model adapters (`openai.ts`, `anthropic.ts`), permissions, sandbox, secrets, hooks, plugins, memory, evals. `src/index.ts` exports everything |
80
+ | `cli/` | The program: `amness.ts` is the entry point. `headless.ts` is `amness run`. `evalcli.ts` is `amness eval`. `config.ts` reads `~/.amness/config.json`. `cli/tui/` is the chat interface (`app.ts`, `commands.ts` for slash commands, `full.ts` for the full-screen view) |
81
+ | `test/` | Tests, one file per area, for example `permissions.test.ts`, `sandbox.test.ts`, `taint.test.ts`, `harness.test.ts`. UI tests start with `tui-`. |
82
+ | `test/helpers/` | `vterm.ts` (a small VT100 emulator that reads the screen back) and `apprig.ts` |
83
+ | `test/pty/tui.py` | The pseudo-terminal tests |
84
+ | `test/fake-mcp.mjs` | A fake MCP server for tests |
85
+ | `examples/` | Runnable examples: `code.ts`, `research.ts`, `eval.ts`, `cases.ts`, `plugins/house-rules.ts` |
86
+ | `docs/` | These pages. Read [How we write the documentation](writing-guide.md) before you edit them |
87
+ | `dist/` | Build output from `npm run build`. Do not edit it |
88
+
89
+ For the layers and how the screen is drawn, see [Architecture](architecture.md).
90
+
91
+ ## How the tests work
92
+
93
+ - The UI tests start the real `App` class, send fake key presses, and read the screen back through `test/helpers/vterm.ts`. They check layout, cursor place and redraw, not only text.
94
+ - Model providers are tested with scripted models and mock HTTP servers. One mock reproduces the OpenAI error "Function tools with reasoning_effort are not supported" (see `test/pty/tui.py`).
95
+ - Many tests use a scripted model. This is a function that returns prepared answers, so a test is fast and repeatable.
96
+
97
+ ## Add a feature
98
+
99
+ **1. Add a tool for the coding agent.**
100
+
101
+ 1. Open `src/code.ts`. Tools are made with `defineTool` and listed in `codeTools`.
102
+ 2. Give the tool a `name`, a `description`, a JSON `schema`, a `run` function, and the flags that fit: `readOnly: true` for tools that change nothing, `risky` for tools that need approval, `untrusted: true` for tools that return text from outside.
103
+ 3. Write a test in `test/` that uses a scripted model.
104
+ 4. Run `npm run typecheck` and `npm test`.
105
+
106
+ If you only need a tool for yourself, write a plugin instead. A plugin needs no change to the source. See [Plugins](plugins.md).
107
+
108
+ **2. Add a guard to the loop.**
109
+
110
+ 1. Open `src/harness.ts`. The loop is the function `run` inside `createHarness`.
111
+ 2. Add the guard name to the `Guard` type, so `off` and `amness eval` can switch it off. Also add it to the `GUARDS` list in `src/profiles.ts`.
112
+ 3. Emit an event with `emit(...)` so the chat and traces can show it. Add the event to the `Event` type.
113
+ 4. Test it with a scripted model that makes the mistake. Add a case to `src/evalcases.ts` if you want to measure it with `amness eval`.
114
+
115
+ **3. Add a slash command.**
116
+
117
+ 1. Open `cli/tui/commands.ts`. Each command is an object with `name`, `help` and `run`.
118
+ 2. Add yours. Run the program and type `/help` to see it.
119
+ 3. Add a test in `test/tui-app.test.ts` or a similar file.
120
+
121
+ **4. Add a model provider.**
122
+
123
+ A model is a function `(messages, tools, opts) => Promise<Message>`. Write one function in a new file under `src/`, export it from `src/index.ts`, and test it with a mock HTTP server. The providers in `cli/config.ts` list what the chat can choose.
124
+
125
+ **Before you open a pull request.** Make sure `npm run typecheck` and `npm test` pass. Update the docs page that describes the feature, and keep to the [writing guide](writing-guide.md).
126
+
127
+ ## Known limits
128
+
129
+ - **Platforms.** Amness is developed and tested on macOS and Linux terminals. The CI job for Windows is informational. There is no Windows sandbox.
130
+ - **Real providers.** The automated tests use scripted models and mock servers. Behavior against live provider APIs was checked by hand only. Provider APIs change. If one breaks, open an issue with the error text.
131
+ - **Cost figures.** They are estimates, not invoices. Cached input is assumed to cost about 10% of the input price. Some models have no price listed.
132
+ - **New features.** Cache keep-alive, semantic memory and `amness eval` against a real model are covered by tests with scripted models. They were not run against live provider APIs in the tests. Numbers quoted from papers belong to those papers. They are not measurements of Amness.
133
+ - **Semantic memory.** It sends note text and your messages to the embeddings endpoint of your provider. It needs an OpenAI-compatible provider. Claude has none.
134
+ - **Local models.** Tool-calling quality with small local models varies a lot.
135
+ - **Node.js.** Amness runs TypeScript directly with Node.js type stripping, so it needs Node 22.18 or newer. The package build in `dist/` is checked by the CI job `package`.
136
+ - **Docker.** CI builds the image and runs two commands in it. It does not run a full task.
137
+ - **Missing features.** The file [ROADMAP.md](../ROADMAP.md) lists what is done and what is planned.
138
+
139
+ ## Related pages
140
+
141
+ - [Architecture](architecture.md)
142
+ - [Plugins](plugins.md)
143
+ - [Evaluating the harness](evaluation.md)
144
+ - [Use it as a library](library.md)
145
+
146
+ ## Next steps
147
+
148
+ - Read how the loop works: [The agent loop](agent-loop.md)
149
+ - Add your own rules without changing the source: [Plugins](plugins.md)
150
+ - Return to the [documentation index](index.md)