@hizliemre/horse-code 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -0
  3. package/dist/app-SB2L34JW.js +6217 -0
  4. package/dist/chunk-2DGO2BUB.js +4490 -0
  5. package/dist/chunk-2SVAHH5N.js +60 -0
  6. package/dist/chunk-3XVZXTB6.js +4469 -0
  7. package/dist/chunk-5UWA2UBM.js +69 -0
  8. package/dist/chunk-7TBYMFMG.js +147 -0
  9. package/dist/chunk-B67BK5GQ.js +34 -0
  10. package/dist/chunk-BY4DP7IE.js +20 -0
  11. package/dist/chunk-DKVIN43T.js +54 -0
  12. package/dist/chunk-DTWKSZXY.js +162 -0
  13. package/dist/chunk-F2IALVBU.js +212 -0
  14. package/dist/chunk-FFYBY2NA.js +392 -0
  15. package/dist/chunk-FGVJFMK5.js +123 -0
  16. package/dist/chunk-H2FDGPVW.js +42 -0
  17. package/dist/chunk-HBSC2HT2.js +85 -0
  18. package/dist/chunk-IW2KBAVZ.js +21 -0
  19. package/dist/chunk-JWAEW7AJ.js +121 -0
  20. package/dist/chunk-NNTIACT4.js +163 -0
  21. package/dist/chunk-O74BDQKS.js +28 -0
  22. package/dist/chunk-PGOYDOI4.js +426 -0
  23. package/dist/chunk-QF4MP6BS.js +69 -0
  24. package/dist/chunk-SSDLHWSF.js +35 -0
  25. package/dist/chunk-TOPZL5SU.js +1052 -0
  26. package/dist/chunk-YBWTCXUS.js +153 -0
  27. package/dist/chunk-YILDXPSI.js +1363 -0
  28. package/dist/clean-YOQATBMZ.js +18 -0
  29. package/dist/cli.js +1495 -0
  30. package/dist/discover-5URG7C4J.js +52 -0
  31. package/dist/fix-HBBOTUWM.js +34 -0
  32. package/dist/frontmatter-UNIPNLLO.js +6 -0
  33. package/dist/git-VTSZALSR.js +6 -0
  34. package/dist/install-O34KMWJB.js +113 -0
  35. package/dist/main-branch-KGWUINYQ.js +19 -0
  36. package/dist/ongoing-OV5XROTU.js +70 -0
  37. package/dist/project-graph-IOPCSZUA.js +56 -0
  38. package/dist/run-LQOZ5I7Z.js +610 -0
  39. package/dist/save-skills-OHYGVTQ4.js +13 -0
  40. package/dist/source-cache-XEK5WN7I.js +29 -0
  41. package/dist/trace-ZMB7LT7W.js +66 -0
  42. package/dist/trace-adopt-C6TUWFJL.js +79 -0
  43. package/dist/trace-run-F23MFTY4.js +24 -0
  44. package/dist/triage-2J3T5PVQ.js +30 -0
  45. package/dist/verify-WQ3GHION.js +479 -0
  46. package/dist/worktree-F7TWLWLN.js +87 -0
  47. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Emre Hızlı
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,150 @@
1
+ # horse-code
2
+
3
+ A terminal coding agent that takes a feature request from one sentence to reviewed, committed code — in its own git worktree, without touching your checkout.
4
+
5
+ ```
6
+ hcode # interactive REPL
7
+ hcode "add a supplier routing table" # one prompt, run to completion
8
+ ```
9
+
10
+ It is a single Node CLI (`hcode`), written in TypeScript, with an [Ink](https://github.com/vadimdemedes/ink) terminal UI. Node 20+.
11
+
12
+ ---
13
+
14
+ ## What it actually does
15
+
16
+ Given a request, it runs a pipeline rather than a single agent:
17
+
18
+ ```
19
+ refine → size → brainstorm → constitution → specify → clarify → plan → tasks
20
+
21
+ ┌─────────────────────────────────────────────┘
22
+
23
+ implement → code review → test suite → acceptance gate → commit
24
+ ▲ │
25
+ └────────────┘ (revision rounds, escalating model tier)
26
+ ```
27
+
28
+ Each document stage (spec, plan) is written by one role, then read by a **team of lenses** — separate agents with one perspective each (`spec-clarity`, `code-security`, `code-concurrency`, …). When the team splits, a five-member **council** votes. When the council splits, a **judge** rules. Only the judge may decide that a question belongs to you.
29
+
30
+ Implementation tasks run in parallel, each in its own worktree, and escalate through model tiers (`coder` → `senior-coder` → `architect` / `principal-coder`) when a task does not close.
31
+
32
+ ## Why it is shaped this way
33
+
34
+ Three constraints drove most of the design:
35
+
36
+ **One session, one worktree.** A run never writes to the checkout you are working in. Every file an agent writes is committed as a `wip(…)` checkpoint, so a bad change is recoverable and the review always sees the whole diff — an unstaged file is a hole in the evidence.
37
+
38
+ **Every message an agent reads is a decision point.** A tool that answers "unknown tool: `view_file`" costs a full model turn to say nothing. So error messages name what exists, suggest the near miss, and say what to do next. Much of this repository is that: the difference between a syscall name and an answer.
39
+
40
+ **Measure before changing.** Almost every non-obvious line here carries the measurement that caused it, in the comment above it — how many calls, how much context, which run. If you are changing behaviour, the comment tells you what breaks.
41
+
42
+ ## Install
43
+
44
+ ```bash
45
+ npm install -g @hizliemre/horse-code
46
+ ```
47
+
48
+ The package is scoped; the command it installs is `hcode`.
49
+
50
+ Or from source:
51
+
52
+ ```bash
53
+ git clone https://github.com/hizliemre/horse-code && cd horse-code
54
+ npm install # `prepare` builds automatically
55
+ npm link # puts `hcode` on your PATH
56
+ ```
57
+
58
+ Then, in the project you want to work on:
59
+
60
+ ```bash
61
+ hcode init # writes .horsecode/ and asks for the essentials
62
+ hcode # start the REPL
63
+ ```
64
+
65
+ ## Configuration
66
+
67
+ `~/.horsecode/config.json` (global) and `.horsecode/config.json` (per project) are merged, project last.
68
+
69
+ ```jsonc
70
+ {
71
+ "apiKey": "…",
72
+ "baseUrl": "https://…", // any OpenAI-compatible endpoint
73
+ "model": "cc/claude-opus-5",
74
+ "mode": "ask", // ask | acceptEdits | auto
75
+ "allowlist": ["npm test", "git status"],
76
+ "maxParallel": 4, // parallel implementation tasks
77
+ "roles": {
78
+ "coder": { "models": ["cc/claude-opus-5", "cx/gpt-5.6-terra"], "effort": "high" }
79
+ },
80
+ "team": { "code": [{ "name": "code-security", "perspective": "…", "models": ["…"] }] },
81
+ "council": { "members": [ /* … */ ] },
82
+ "mcp": { /* Model Context Protocol servers */ },
83
+ "telemetry": true // JSONL run traces under ~/.horsecode/telemetry
84
+ }
85
+ ```
86
+
87
+ Every role resolves to an ordered **model chain**: the head is tried first, and a transport failure falls to the next. A model that is overloaded is benched briefly; one that is out of quota is benched for the session, and the roles it was serving are moved and moved back when it recovers.
88
+
89
+ Claude models are sent over Anthropic's own `/v1/messages` so that `effort` actually reaches them — the OpenAI-compatible endpoint accepts the field and drops it.
90
+
91
+ ## In the REPL
92
+
93
+ | | |
94
+ |---|---|
95
+ | `/model`, `/roles` | see and change the model chains, per role |
96
+ | `/mode` | ask / acceptEdits / auto |
97
+ | `/memories`, `/remember`, `/forget` | the project's durable facts |
98
+ | `/skills`, `/sources` | installed skills and where they come from |
99
+ | `/graph` | build the code graph; `/graph trace` writes per-file traces |
100
+ | `/mcp` | connected MCP servers and their tools |
101
+ | `/parallel`, `/next`, `/resume`, `/sessions` | run control |
102
+ | `/clean-worktrees` | remove finished session worktrees |
103
+ | `/monitor`, `/watch` | live view of a running job |
104
+
105
+ ## Memory
106
+
107
+ Facts an agent learns — a command that only works from a subdirectory, a file that is not where it looks — are written to `.horsecode/memory.jsonl` in the session worktree, so they ship with the work rather than sitting in someone's checkout. They are retrieved lexically and injected into later turns, including a slice reserved for **operational** lessons that only implementers receive.
108
+
109
+ Each role is asked, at the close of its turn, whether anything cost it more than one attempt. That question is the difference between a run that learns and one that rediscovers.
110
+
111
+ ## Tools an agent has
112
+
113
+ `read_file` `write_file` `edit_file` `grep` `glob` `shell` `git` (read-only) `git_write` `web_fetch` `ask_user` `remember_fact` `propose_memory` `skill` `find_tool` `find_unfinished`, plus the graph tools (`graph_overview`, `graph_find`, `graph_context`, `graph_impact`, `graph_trace`) and every tool exposed by a connected MCP server.
114
+
115
+ Some boundaries are enforced rather than requested, because an instruction is advice and advice is what a model skips:
116
+
117
+ - `shell` refuses to rewrite a file (`edit_file` reports what changed; a heredoc does not).
118
+ - `shell` refuses a `cd` out of the working directory, and the git commands that throw away uncommitted work wholesale (`reset --hard`, `checkout -- .`).
119
+ - `git` is read-only; the writing verbs live in a separate tool.
120
+ - A call whose arguments arrive truncated is a stream that stopped, not a call — it is retried, not handed to the model as broken JSON.
121
+
122
+ ## Development
123
+
124
+ ```bash
125
+ npm test # vitest — 3200+ tests
126
+ npm run typecheck # tsc --noEmit (tsup does NOT typecheck; run this)
127
+ npm run build # tsup → dist/
128
+
129
+ CI=1 npm test # what CI runs — see below
130
+ ```
131
+
132
+ `CI=1` is not decoration: libraries change behaviour under it. Ink stops repainting, so a terminal test
133
+ reads an empty frame; colour libraries switch themselves off, so an escape a test asserts is never
134
+ emitted. Six failures that only appeared on the runner reproduced locally the moment that variable was
135
+ set. Set it before blaming the runner.
136
+
137
+ Tests carry the measurement that motivated them in the describe block. A test whose comment says "measured live: 27 of 90 calls" is documentation as much as a guard — if you change the behaviour, that number is what you are trading away.
138
+
139
+ Releases are cut by tag: `npm version <patch|minor|major>` then push the tag. The workflow refuses to publish
140
+ if the tag and `package.json` disagree, or if that version is already on the registry — npm versions are
141
+ permanent, so both are checked before anything is built.
142
+
143
+ ## Status
144
+
145
+ Working software, used daily against a real .NET + Angular monorepo. Pre-1.0 is honest: interfaces move when
146
+ a measurement says they should.
147
+
148
+ ## License
149
+
150
+ MIT — see [LICENSE](LICENSE).