@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.
- package/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/app-SB2L34JW.js +6217 -0
- package/dist/chunk-2DGO2BUB.js +4490 -0
- package/dist/chunk-2SVAHH5N.js +60 -0
- package/dist/chunk-3XVZXTB6.js +4469 -0
- package/dist/chunk-5UWA2UBM.js +69 -0
- package/dist/chunk-7TBYMFMG.js +147 -0
- package/dist/chunk-B67BK5GQ.js +34 -0
- package/dist/chunk-BY4DP7IE.js +20 -0
- package/dist/chunk-DKVIN43T.js +54 -0
- package/dist/chunk-DTWKSZXY.js +162 -0
- package/dist/chunk-F2IALVBU.js +212 -0
- package/dist/chunk-FFYBY2NA.js +392 -0
- package/dist/chunk-FGVJFMK5.js +123 -0
- package/dist/chunk-H2FDGPVW.js +42 -0
- package/dist/chunk-HBSC2HT2.js +85 -0
- package/dist/chunk-IW2KBAVZ.js +21 -0
- package/dist/chunk-JWAEW7AJ.js +121 -0
- package/dist/chunk-NNTIACT4.js +163 -0
- package/dist/chunk-O74BDQKS.js +28 -0
- package/dist/chunk-PGOYDOI4.js +426 -0
- package/dist/chunk-QF4MP6BS.js +69 -0
- package/dist/chunk-SSDLHWSF.js +35 -0
- package/dist/chunk-TOPZL5SU.js +1052 -0
- package/dist/chunk-YBWTCXUS.js +153 -0
- package/dist/chunk-YILDXPSI.js +1363 -0
- package/dist/clean-YOQATBMZ.js +18 -0
- package/dist/cli.js +1495 -0
- package/dist/discover-5URG7C4J.js +52 -0
- package/dist/fix-HBBOTUWM.js +34 -0
- package/dist/frontmatter-UNIPNLLO.js +6 -0
- package/dist/git-VTSZALSR.js +6 -0
- package/dist/install-O34KMWJB.js +113 -0
- package/dist/main-branch-KGWUINYQ.js +19 -0
- package/dist/ongoing-OV5XROTU.js +70 -0
- package/dist/project-graph-IOPCSZUA.js +56 -0
- package/dist/run-LQOZ5I7Z.js +610 -0
- package/dist/save-skills-OHYGVTQ4.js +13 -0
- package/dist/source-cache-XEK5WN7I.js +29 -0
- package/dist/trace-ZMB7LT7W.js +66 -0
- package/dist/trace-adopt-C6TUWFJL.js +79 -0
- package/dist/trace-run-F23MFTY4.js +24 -0
- package/dist/triage-2J3T5PVQ.js +30 -0
- package/dist/verify-WQ3GHION.js +479 -0
- package/dist/worktree-F7TWLWLN.js +87 -0
- 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).
|