little-coder 1.4.2 → 1.4.3
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
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to little-coder are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and little-coder's public interface (CLI, providers, tools, skills) follows semver starting at `v0.0.1` post-rename.
|
|
4
4
|
|
|
5
|
+
## [v1.4.3] — 2026-05-19
|
|
6
|
+
|
|
7
|
+
Follow-up to v1.4.2: clean up two cosmetic regressions that the @earendil-works scope migration surfaced.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **Pi's `What's New` block no longer appears inside little-coder's TUI after a version bump.** Root cause: pi's interactive mode reads its own bundled `CHANGELOG.md` on startup and renders every entry strictly newer than the `lastChangelogVersion` field in `~/.pi/agent/settings.json` (`interactive-mode.js:getChangelogForDisplay`). v1.4.2 jumped the bundled pi from 0.68.1 to 0.75.3, so users who had previously launched any older little-coder saw pi's full 0.68 → 0.75 upstream changelog dumped *underneath* little-coder's own startup banner. That's wrong because little-coder is the surface and pi is the substrate — the chrome above shouldn't suddenly start advertising the substrate's release notes. The launcher (`bin/little-coder.mjs`) now pre-stamps `lastChangelogVersion` to the currently bundled pi version (resolved from `node_modules/@earendil-works/pi-coding-agent/package.json#version`, the same file we already read to find pi's cli.js, so there's no second source of truth) *before* pi starts. Pi then sees "user already saw this changelog" and the block never renders. The merge into `~/.pi/agent/settings.json` is non-destructive — `quietStartup: true` and every other existing key are preserved. Users who genuinely want pi's upstream changelog can still pull it up with `/changelog` inside the TUI.
|
|
11
|
+
- **`npm install -g little-coder` no longer prints `node-domexception@1.0.0` deprecation warning.** Root cause: a 5-hop transitive — `@earendil-works/pi-ai` → `@google/genai` → `google-auth-library` → `gaxios` → `node-fetch@3` → `fetch-blob@3` → `node-domexception@1.0.0`. The `node-domexception` package is just a 16-line shim that sets `globalThis.DOMException` when undefined, and native `DOMException` has been built into Node since 18 — so on our `Node >= 22.19` floor, the entire shim is dead code. Replaced it via `package.json#overrides` pointing at a bundled stub at `./vendor/node-domexception/` that exports `module.exports = globalThis.DOMException` directly. The stub ships in the npm tarball (`files` array now includes `vendor/`). Since npm's `overrides` field is honored when little-coder is the install root (which it is for `npm install -g little-coder`), the deprecated upstream package never reaches the user's tree, and npm prints no warning. Functional behavior is identical because the only call site (`fetch-blob/from.js:import DOMException from 'node-domexception'`) sees the same `globalThis.DOMException` it would have gotten from the upstream shim.
|
|
12
|
+
|
|
13
|
+
### Notes for upgraders
|
|
14
|
+
- The bundled stub lives at `vendor/node-domexception/` inside the published package — it's listed under `files` in `package.json`. If you'd added your own `overrides` field that touches `node-domexception` in a hand-rolled fork of little-coder, our entry will take precedence when you publish; in the unlikely case that breaks something for you, override it back in your fork's root `package.json`.
|
|
15
|
+
- The `lastChangelogVersion` pre-stamp is one-directional: it writes the *currently bundled* pi version into settings on every launch. If you'd like to see pi's upstream changelog for a future bump, `/changelog` inside the TUI is the unconditional path — it doesn't consult `lastChangelogVersion`.
|
|
16
|
+
- No CLI flag, models.json shape, skill-pack, extension API, or per-model profile changes. Little-coder's own startup banner, tagline, and keybind hints (the branding extension at `.pi/extensions/branding/`) are byte-for-byte unchanged from v1.4.2.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
5
20
|
## [v1.4.2] — 2026-05-19
|
|
6
21
|
|
|
7
22
|
Bundled-pi maintenance release. Closes [#22](https://github.com/itayinbarr/little-coder/issues/22), [#23](https://github.com/itayinbarr/little-coder/issues/23), [#25](https://github.com/itayinbarr/little-coder/issues/25). The pi runtime moves from `@mariozechner/pi-coding-agent@^0.68.1` to `@earendil-works/pi-coding-agent@^0.75.3` — same author, same project, new npm scope — which makes the deprecation warnings disappear, pulls in pi's recent Windows / undici / cmd-shim fixes, and (because pi 0.75 raised its floor) bumps the supported Node range to ≥ 22.19. No CLI flag, settings, extension API, or skill-pack changes.
|
package/bin/little-coder.mjs
CHANGED
|
@@ -131,15 +131,30 @@ if (process.env.PI_SKIP_VERSION_CHECK === undefined) {
|
|
|
131
131
|
process.env.PI_SKIP_VERSION_CHECK = "1";
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
// ---- 8. Force pi's global quietStartup
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
134
|
+
// ---- 8. Force pi's global quietStartup + pin lastChangelogVersion ----
|
|
135
|
+
// Two non-destructive merges into ~/.pi/agent/settings.json (or the dir pointed
|
|
136
|
+
// to by PI_CODING_AGENT_DIR):
|
|
137
|
+
//
|
|
138
|
+
// 1. quietStartup: true
|
|
139
|
+
// Pi's interactive mode otherwise dumps an [Extensions] / [Skills] /
|
|
140
|
+
// [Prompts] inventory on every launch. Pi reads global settings from
|
|
141
|
+
// <agentDir>/settings.json — NOT from our npm-installed package dir —
|
|
142
|
+
// so our shipped .pi/settings.json doesn't reach it. To see the
|
|
143
|
+
// inventory anyway, run `little-coder --verbose`.
|
|
144
|
+
//
|
|
145
|
+
// 2. lastChangelogVersion: <currently installed pi version>
|
|
146
|
+
// Pi reads its own bundled CHANGELOG.md on startup and renders a
|
|
147
|
+
// "What's New" block for every entry strictly newer than this stored
|
|
148
|
+
// version (interactive-mode.js:getChangelogForDisplay). That makes pi's
|
|
149
|
+
// upstream changelog show up inside little-coder's TUI every time we
|
|
150
|
+
// bump the bundled pi dep — which is jarring because little-coder is
|
|
151
|
+
// the surface, not pi. We pre-stamp this field to the version we just
|
|
152
|
+
// bundled BEFORE pi starts, so pi sees "user already saw this", and
|
|
153
|
+
// the block never renders. Users who genuinely want to read pi's
|
|
154
|
+
// upstream changelog can still do so with `/changelog` inside the TUI.
|
|
155
|
+
//
|
|
156
|
+
// Existing keys are preserved. We only write when the desired value differs
|
|
157
|
+
// from what's already on disk, so this is a no-op on warm launches.
|
|
143
158
|
try {
|
|
144
159
|
const agentDirEnv = process.env.PI_CODING_AGENT_DIR;
|
|
145
160
|
let agentDir;
|
|
@@ -164,8 +179,32 @@ try {
|
|
|
164
179
|
globalSettings = {};
|
|
165
180
|
}
|
|
166
181
|
}
|
|
182
|
+
|
|
183
|
+
// Read the bundled pi version. We resolve via the same package.json we used
|
|
184
|
+
// to find piEntry, so this stays consistent with whichever pi we actually
|
|
185
|
+
// spawn — no second source of truth.
|
|
186
|
+
let bundledPiVersion;
|
|
187
|
+
try {
|
|
188
|
+
const piPkgJson = JSON.parse(
|
|
189
|
+
readFileSync(join(piPkgRoot, "package.json"), "utf-8"),
|
|
190
|
+
);
|
|
191
|
+
if (typeof piPkgJson?.version === "string") bundledPiVersion = piPkgJson.version;
|
|
192
|
+
} catch {
|
|
193
|
+
// If we can't read pi's version, fall back to leaving lastChangelogVersion
|
|
194
|
+
// alone — pi will then show its own changelog on the next launch. Better
|
|
195
|
+
// than writing garbage into the user's settings.
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
let mutated = false;
|
|
167
199
|
if (globalSettings.quietStartup !== true) {
|
|
168
200
|
globalSettings.quietStartup = true;
|
|
201
|
+
mutated = true;
|
|
202
|
+
}
|
|
203
|
+
if (bundledPiVersion && globalSettings.lastChangelogVersion !== bundledPiVersion) {
|
|
204
|
+
globalSettings.lastChangelogVersion = bundledPiVersion;
|
|
205
|
+
mutated = true;
|
|
206
|
+
}
|
|
207
|
+
if (mutated) {
|
|
169
208
|
writeFileSync(globalSettingsPath, JSON.stringify(globalSettings, null, 2));
|
|
170
209
|
}
|
|
171
210
|
} catch {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "little-coder",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "A pi-based coding agent optimized for small local language models. Reproduces the whitepaper's scaffold-model-fit adaptations as pi extensions.",
|
|
5
5
|
"homepage": "https://github.com/itayinbarr/little-coder",
|
|
6
6
|
"repository": {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
".pi/extensions/",
|
|
24
24
|
".pi/settings.json",
|
|
25
25
|
"models.json",
|
|
26
|
+
"vendor/",
|
|
26
27
|
"LICENSE",
|
|
27
28
|
"NOTICE",
|
|
28
29
|
"README.md",
|
|
@@ -39,6 +40,9 @@
|
|
|
39
40
|
"@sinclair/typebox": "^0.34.49",
|
|
40
41
|
"playwright": "^1.59.1"
|
|
41
42
|
},
|
|
43
|
+
"overrides": {
|
|
44
|
+
"node-domexception": "file:./vendor/node-domexception"
|
|
45
|
+
},
|
|
42
46
|
"devDependencies": {
|
|
43
47
|
"typescript": "^5.6.0",
|
|
44
48
|
"vitest": "^2.1.0"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Drop-in replacement for the deprecated `node-domexception@1.0.0` shim.
|
|
2
|
+
// Bundled with little-coder; wired in via `package.json#overrides` so the
|
|
3
|
+
// transitive `fetch-blob -> node-domexception` chain (pulled in via
|
|
4
|
+
// @earendil-works/pi-ai -> @google/genai -> google-auth-library -> gaxios ->
|
|
5
|
+
// node-fetch -> fetch-blob) doesn't emit a deprecation warning during
|
|
6
|
+
// `npm install -g little-coder`. Native `globalThis.DOMException` has been
|
|
7
|
+
// available since Node 18, and little-coder requires Node >= 22.19, so this
|
|
8
|
+
// is always defined at import time.
|
|
9
|
+
module.exports = globalThis.DOMException;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "node-domexception",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Bundled with little-coder. Returns Node's native globalThis.DOMException (built-in since Node 18). Replaces the deprecated upstream node-domexception@1.0.0 via npm overrides so `npm install -g little-coder` no longer prints its deprecation warning. We pin engines.node to >= 18 because that's where native DOMException landed; the launcher's own preflight enforces >= 22.19, so this is satisfied transitively.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=18.0.0"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT"
|
|
10
|
+
}
|