heartcode 0.1.15 → 0.1.24
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/CHANGELOG.md +186 -0
- package/SKILL.md +5 -3
- package/bin/heartcode.js +199 -71
- package/package.json +1 -1
- package/prompts/agent.md +147 -17
- package/prompts/guided.md +6 -3
- package/src/acp.js +2 -2
- package/src/agent.js +418 -34
- package/src/client.js +59 -3
- package/src/config.js +11 -6
- package/src/headless.js +1 -1
- package/src/lsp.js +168 -49
- package/src/mcp.js +20 -2
- package/src/sessions.js +2 -3
- package/src/settings.html +262 -131
- package/src/settings.js +11 -2
- package/src/skills.js +20 -1
- package/src/tabs.js +22 -7
- package/src/tools.js +68 -6
- package/src/ui.js +525 -94
- package/src/voice.js +70 -6
- package/src/web.js +211 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,192 @@
|
|
|
2
2
|
|
|
3
3
|
What changed in each version of HeartCode, newest first.
|
|
4
4
|
|
|
5
|
+
## 0.1.24 (2026-10-31)
|
|
6
|
+
|
|
7
|
+
- A pinned model (one picked with /select_model, or -m) is now used by the helpers it spawns too:
|
|
8
|
+
with a model pinned, HeartCode won't hand a helper's job to another of your models, and a
|
|
9
|
+
helper uses the pinned model even if a different one is named. Auto mode still spreads work
|
|
10
|
+
across your models as before.
|
|
11
|
+
- A built page is now actually driven like a user before it's called done, not just loaded: HeartCode
|
|
12
|
+
fills the inputs, clicks every button, and toggles every checkbox in the headless browser, and
|
|
13
|
+
any error a control throws (a dead button, a popup that fails) is a must-fix, fed back to the
|
|
14
|
+
model to fix and re-test — like Replit's test-and-fix loop. (Navigation is blocked so one click
|
|
15
|
+
can't end the test.) These failures also become lessons.
|
|
16
|
+
- HeartCode now learns from its mistakes in any language, not just web: when something it ran
|
|
17
|
+
failed and then passed after a fix (a Python traceback, a failing test, a build error, a
|
|
18
|
+
broken button in the browser…), it saves the fix as a one-line rule in memory, tagged by
|
|
19
|
+
technology, and recalls it on later tasks of the same kind so the mistake isn't repeated.
|
|
20
|
+
Near-duplicate lessons are skipped. A rerun only counts as a fix if a file was edited between.
|
|
21
|
+
|
|
22
|
+
- When the model uses any external tool, library, API or framework, it now goes to the official
|
|
23
|
+
source first — always, even when it's sure it knows — assumes its memory is stale, relearns the
|
|
24
|
+
current way from that official page, then acts on it. Official docs/sites/repos come first;
|
|
25
|
+
blogs, listicles and memory are a last resort. (A change to the project's own code, or a question
|
|
26
|
+
the code answers, still needs no lookup.)
|
|
27
|
+
This reminder is repeated across the prompt (research, how it works, on a failure, using a tool,
|
|
28
|
+
every message, and for small models) so a model is far more likely to actually do it.
|
|
29
|
+
|
|
30
|
+
## 0.1.23 (2026-10-31)
|
|
31
|
+
|
|
32
|
+
- The "retrying in 0 seconds" message no longer lingers on the spinner while the retried request is
|
|
33
|
+
in flight: the countdown is cleared the moment the wait ends and the new request starts.
|
|
34
|
+
- "Make sure it works" now applies to everything the model builds, not just web pages: before it
|
|
35
|
+
finishes it must run what it made and see it work — a CLI with real input, a server by calling
|
|
36
|
+
its endpoints, a library by a small usage snippet, tests if there are any — not just "no error".
|
|
37
|
+
- A page the model builds is now checked that it actually works, not just how it looks: HeartCode
|
|
38
|
+
reads the browser console when it opens the page, and any JavaScript error (an unclosed brace, a
|
|
39
|
+
wrong name, a blocked resource) is a must-fix blocker fed back to the model before it can finish.
|
|
40
|
+
- While retrying, the retry message and the "responding / waiting for model" timer are on separate
|
|
41
|
+
lines instead of one long line that got cut off.
|
|
42
|
+
- A page the model builds is now checked that it actually works even when no browser is available,
|
|
43
|
+
and verification never passes silently: HeartCode statically catches JavaScript that doesn't
|
|
44
|
+
parse and the Tailwind-CDN @apply trap (applying a class you defined yourself, which throws
|
|
45
|
+
"Cannot apply unknown utility class"); and if it couldn't open the page in a browser at all,
|
|
46
|
+
the model is told so and must verify it itself before finishing, instead of assuming it's fine.
|
|
47
|
+
- A model pinned in one CLI (/select_model) is now truly session-local: changing the model order
|
|
48
|
+
on the settings page (or in another instance) no longer unpins it or switches its model — that
|
|
49
|
+
only affects instances on auto. The pin isn't written to disk either, so it can't become
|
|
50
|
+
another instance's #1. (Before, a model-order change silently switched every running instance.)
|
|
51
|
+
- /select_model now picks the model(s) for this session: tick one to pin it (no rotation), several
|
|
52
|
+
to rotate among just those, or all/none for auto (your whole list). /select_model <model> pins,
|
|
53
|
+
/select_model a, b, c chooses a set, /select_model auto goes back to the list. It's session-local
|
|
54
|
+
— your saved ranking (settings page) is untouched and stays the default for new sessions. The
|
|
55
|
+
status bar shows it: "auto (model) (N)", a pinned model's name alone, or "model (K chosen)".
|
|
56
|
+
A single pinned/chosen set is also what spawned helpers use (no handing off outside the set).
|
|
57
|
+
In the picker, Ctrl+A ticks all and Ctrl+N unticks all, so you can clear then tick what you want.
|
|
58
|
+
- Command and @file suggestions now show while the model is working, not only at an empty prompt:
|
|
59
|
+
type `/` or `@`, use ↑/↓ and Tab to complete; Enter queues the command to run when the task is done.
|
|
60
|
+
- The browser (chrome-devtools) no longer litters the project: it runs in its own scratch directory,
|
|
61
|
+
so a screenshot or snapshot the model saves by a bare name (screenshot.png, snapshot.txt) lands
|
|
62
|
+
there instead of the project folder. Pages are still opened by absolute path, so nothing breaks.
|
|
63
|
+
- The built-in Chrome (chrome-devtools) runs headless (no window) with its own throwaway profile, so
|
|
64
|
+
it doesn't pop up a window, works over SSH, and runs don't fight over one profile. Override `args`
|
|
65
|
+
in ~/.heart/mcp.json for a visible browser.
|
|
66
|
+
|
|
67
|
+
## 0.1.22 (2026-10-31)
|
|
68
|
+
|
|
69
|
+
- Times are written out: "responding 5 hours 33 minutes", "took 1 minute 25 seconds", "retrying in
|
|
70
|
+
10 seconds", "thought for 12 seconds", "resumed … 3 hours ago" (the two biggest units).
|
|
71
|
+
- Ctrl+R no longer starts voice: /voice does (keybindings.json can still give it a key).
|
|
72
|
+
- Click a tab to go to it.
|
|
73
|
+
- /rewind puts a message of several lines back in the input box whole (only its last line came back).
|
|
74
|
+
- The key hints say what a key does: "Shift+Tab change permissions", "Ctrl+T open a new tab".
|
|
75
|
+
- Finding its way in a project, in this order: the model sees every entry of the project root
|
|
76
|
+
(names only; what .gitignore leaves out is marked), then goes folder by folder (list_files with
|
|
77
|
+
a path) and searches; a language server only when the task needs code followed across files.
|
|
78
|
+
- Language servers are the model's choice, for any language: it finds out which one fits, checks
|
|
79
|
+
it's installed, and uses it with the new lsp tool (definition, references, hover, errors).
|
|
80
|
+
HeartCode remembers it for the project, and checks each edit of such files with it. No built-in
|
|
81
|
+
list any more.
|
|
82
|
+
- find_command: the model checks whether a command is installed before it relies on it (instant,
|
|
83
|
+
runs nothing).
|
|
84
|
+
- Building a UI: the model researches the best real examples of that exact kind of screen and
|
|
85
|
+
the current UI library for the stack, writes a design brief and its own checklist from them,
|
|
86
|
+
builds with the library, then looks at screenshots (desktop and phone) and fixes what's off. A
|
|
87
|
+
model that can't see has one of your models that can check them.
|
|
88
|
+
- The status bar says how many providers are on and how many models are in your list:
|
|
89
|
+
"local (2) · qwen3 (3)".
|
|
90
|
+
- A queue for messages typed while it works: Enter adds one (shown above the input, numbered).
|
|
91
|
+
When the answer is done they go all together, as one message, or one by one: Ctrl+_ switches
|
|
92
|
+
(saved). Ctrl+] stops the answer and sends the first one now, Ctrl+\ sends them all now, as one
|
|
93
|
+
message (one request). The model no longer gets them in the middle of an answer.
|
|
94
|
+
- Web search asks several engines at once and puts their results together: public SearXNG
|
|
95
|
+
instances (from searx.space; five at a time, the next five when none answers well, pages 2–3
|
|
96
|
+
when the first has few good results), Mwmbl, DuckDuckGo, and for coding questions Stack Overflow,
|
|
97
|
+
npm and GitHub. Each result is ranked by the query's words in it (rare words count more) and by
|
|
98
|
+
how many engines found it, and says where it came from. Searching fails only when every engine
|
|
99
|
+
does; then the model is told search can't be reached, instead of "try other words" again and again.
|
|
100
|
+
- What the model makes: stability and UI/UX come first.
|
|
101
|
+
- A page it builds or restyles is opened in the built-in browser when it says it's done: a model
|
|
102
|
+
that can see reviews the screenshots (desktop and phone width) in a request of its own and lists
|
|
103
|
+
what's wrong, and the model fixes it (twice per message at most).
|
|
104
|
+
- A reply that goes into a loop (the same text over and over) is cut, and the model asked again.
|
|
105
|
+
- A path the model copied wrong (the project's long path without its first "/", or with folder
|
|
106
|
+
names run together) is read as the project path it meant; a command that went outside the
|
|
107
|
+
project says where the project is.
|
|
108
|
+
- Searches, page reads and file reads asked for in one reply run at the same time, and servers are
|
|
109
|
+
asked for several calls per reply (parallel_tool_calls). The model is told to look things up
|
|
110
|
+
together, and to get everything a task needs before doing it, as much as it takes.
|
|
111
|
+
- A search, page, read or command made again in the same message, with nothing changed since,
|
|
112
|
+
isn't run again: the model gets the earlier result. Ten such repeats stop the message; four
|
|
113
|
+
failing commands in a row get a "rethink this" note.
|
|
114
|
+
- The model researches the kind of thing it's asked to make, not the names in the request, and
|
|
115
|
+
installs only what its plan needs, after making sure it's the real one.
|
|
116
|
+
|
|
117
|
+
## 0.1.21 (2026-10-31)
|
|
118
|
+
|
|
119
|
+
- How long HeartCode took to answer: the spinner counts "responding 45s" while it works, and when
|
|
120
|
+
it's done a line stays under the answer ("✻ took 1m 12s"). Time spent waiting for your answer
|
|
121
|
+
to its questions isn't counted, and the line doesn't keep counting after it's done.
|
|
122
|
+
- The mouse wheel scrolls just the conversation: the tabs, the input and the status bar stay where
|
|
123
|
+
they are.
|
|
124
|
+
- Select text in the conversation by dragging with the mouse: it's highlighted and copied when you
|
|
125
|
+
let go ("copied 42 characters"). A click or a key clears it.
|
|
126
|
+
- Keys to scroll the conversation: Shift+↑/↓ (3 lines), Alt+↑/↓ or PgUp/PgDn (a page).
|
|
127
|
+
- Closing a tab (Ctrl+Q, or the new /close_tab) asks first.
|
|
128
|
+
- The model's answers are drawn as Markdown as they stream in: headings, **bold**, *italic*,
|
|
129
|
+
`code`, lists, quotes, code blocks and rules (/copy and /export keep the Markdown as written).
|
|
130
|
+
The thinking too, and answers in sessions and tabs from before, when they're shown again.
|
|
131
|
+
- The model is told to give choices as a numbered list, and to keep to simple Markdown (no tables).
|
|
132
|
+
|
|
133
|
+
## 0.1.20 (2026-10-31)
|
|
134
|
+
|
|
135
|
+
- The settings page's accent is green.
|
|
136
|
+
- A System / Light / Dark switch at the bottom of the settings page's sidebar (System follows your
|
|
137
|
+
computer's setting).
|
|
138
|
+
- Voice works like Claude Code's: /voice (or Ctrl+R), Space to talk (again to pause, again to go
|
|
139
|
+
on), Enter to finish, Esc to cancel; what you say shows in the input box as you say it.
|
|
140
|
+
|
|
141
|
+
## 0.1.19 (2026-10-30)
|
|
142
|
+
|
|
143
|
+
- The settings page, redone: one accent color, calmer lists (a row's buttons
|
|
144
|
+
show when you point at it), clearer type, hover, press and focus states, dialogs that animate in,
|
|
145
|
+
and a layout that works on a phone too.
|
|
146
|
+
- A provider switched off is gone from everywhere it was still showing: the status bar (it showed
|
|
147
|
+
the off provider's model when only one other model was on), `heart providers`, /select_model,
|
|
148
|
+
and on the settings page Your models, its count, Test all and the provider ranking. Its models
|
|
149
|
+
keep their places in your list for when it's on again.
|
|
150
|
+
- /rewind numbers your messages, newest first.
|
|
151
|
+
- The settings page says "Disconnected" and can't be used once it's turned off (in HeartCode or
|
|
152
|
+
with Ctrl+C), instead of failing quietly.
|
|
153
|
+
- The compaction switch on the settings page says 85%, as it is now.
|
|
154
|
+
|
|
155
|
+
## 0.1.18 (2026-10-30)
|
|
156
|
+
|
|
157
|
+
- Before building anything, the model researches it first (the current, most recommended way and
|
|
158
|
+
the latest stable versions, from the web and the official docs), plans the whole job, and asks
|
|
159
|
+
what it still isn't sure of: free models' training data is old.
|
|
160
|
+
- Tab names are at most 20 characters, "..." included.
|
|
161
|
+
- Settings changed while HeartCode works now reach it at once, every time: before every request and
|
|
162
|
+
before each tool's result is cut to the context window, HeartCode takes in what changed (it no longer
|
|
163
|
+
depends on the file watcher being quick enough). A model's context window, set up on the settings
|
|
164
|
+
page mid-task, is used from the next step, also by helpers (the agent tool) already at work, which
|
|
165
|
+
used to keep the old one until they finished.
|
|
166
|
+
- Auto-compact when the conversation takes 85% of the window of the model answering (room is kept
|
|
167
|
+
for the reply), no longer every 100 messages: a long session is no longer summarized at a few
|
|
168
|
+
percent of a big window. When the model list moves on to a model with a smaller window, the
|
|
169
|
+
conversation is compacted for that model before it's sent, instead of being refused as too big.
|
|
170
|
+
The spinner says how full it is ("context 86% full (~660k of 768k)").
|
|
171
|
+
- A running HeartCode no longer overwrites what you set up for a model: saving what it learned
|
|
172
|
+
about the model (token counts, limits) used to write its old copy of your settings back over them.
|
|
173
|
+
|
|
174
|
+
## 0.1.17 (2026-10-30)
|
|
175
|
+
|
|
176
|
+
- Stronger system prompts (tool mode and guided mode for small models): act instead of describing,
|
|
177
|
+
don't guess paths or APIs, search the web when unsure or knowledge is dated, never stop until the
|
|
178
|
+
request is done, verify by output, and answer short and to the point. Small local models follow
|
|
179
|
+
these far better.
|
|
180
|
+
- The system prompt now tells the model the OS and shell it's running on (e.g. "macOS (darwin, arm64),
|
|
181
|
+
shell zsh"), and how to find and install a tool it needs: use what's already there, else install it
|
|
182
|
+
the right way for this OS (asking first unless commands are already allowed).
|
|
183
|
+
|
|
184
|
+
## 0.1.16 (2026-10-30)
|
|
185
|
+
|
|
186
|
+
- Switch a provider off (and on again) on the settings page, without deleting it: its key and its
|
|
187
|
+
models in your list stay, but `auto` skips them, also in a HeartCode running already. `-m
|
|
188
|
+
provider/model` still runs one of its models. `heart providers` says which are off; `heart models
|
|
189
|
+
--all --json` gives them `off: true`.
|
|
190
|
+
|
|
5
191
|
## 0.1.15 (2026-10-30)
|
|
6
192
|
|
|
7
193
|
- Settings page, Providers & models: Test on each model sends it "Hello" and shows what was sent
|
package/SKILL.md
CHANGED
|
@@ -50,7 +50,8 @@ No model set up yet: `models` is empty (and `heart -p` fails with "no model set
|
|
|
50
50
|
`heart models [--all] <filter>` keeps only the ids that contain `<filter>`.
|
|
51
51
|
|
|
52
52
|
`providers` (only with `--all`): every provider's models. `list: false`: the user switched that
|
|
53
|
-
provider's list off, and `models` are the ones they added by name.
|
|
53
|
+
provider's list off, and `models` are the ones they added by name. `off: true`: the user switched
|
|
54
|
+
the provider off; `auto` skips its models (they aren't in `models`), but `-m provider/model` still runs one. A provider that can't be
|
|
54
55
|
reached has an `error` (in text: a line on stderr) and is skipped; the command still exits `0`.
|
|
55
56
|
|
|
56
57
|
**Which model to pass:**
|
|
@@ -70,8 +71,9 @@ all refused the request outright, else after `--max-retries` (10) whole rounds o
|
|
|
70
71
|
model (`-m <model>`) waits out rate limits and outages, up to `--max-retries` tries, and stops at
|
|
71
72
|
any other error. A provider that refuses a part of the request HeartCode can do without (the
|
|
72
73
|
model's thinking sent back, keys in the tools' schemas, images) gets it again without that part,
|
|
73
|
-
and that is remembered for the model for a day. A
|
|
74
|
-
|
|
74
|
+
and that is remembered for the model for a day. A conversation is summarized when it takes 85% of
|
|
75
|
+
the window of the model answering (room is kept for the reply); when the list moves on to a model
|
|
76
|
+
with a smaller window, it's summarized for that model before it's sent.
|
|
75
77
|
Each request is fitted to the model it goes to: one that can't see gets a note in place of each
|
|
76
78
|
image, one that can't call tools gets the tool calls as text.
|
|
77
79
|
|