claude-garage 0.3.0 → 0.3.1
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/daemon/src/statusline.js +5 -0
- package/daemon/src/transcript.js +37 -5
- package/package.json +1 -1
package/daemon/src/statusline.js
CHANGED
|
@@ -5,6 +5,7 @@ import { tokenMatches } from "./token-auth.js";
|
|
|
5
5
|
import { resolveSessionIds } from "./session-resolve.js";
|
|
6
6
|
import { readSettingsOrRefuse, writeSettingsAtomic } from "./settings-install.js";
|
|
7
7
|
import { claudeHome } from "./claude-home.js";
|
|
8
|
+
import { recordModelWindow } from "./transcript.js";
|
|
8
9
|
|
|
9
10
|
const PORT = Number(process.env.GARAGE_PORT ?? 4747);
|
|
10
11
|
const SETTINGS_PATH = join(claudeHome(), "settings.json");
|
|
@@ -181,6 +182,10 @@ export default async function statuslineRoutes(app) {
|
|
|
181
182
|
if (pct !== null) {
|
|
182
183
|
for (const id of ids) setContext(id, pct);
|
|
183
184
|
}
|
|
185
|
+
// Teach the transcript fallback this model's real window — the payload's
|
|
186
|
+
// context_window_size is Claude Code's own metadata, the only local
|
|
187
|
+
// source of a model id -> window mapping.
|
|
188
|
+
recordModelWindow(payload?.model?.id, payload?.context_window?.context_window_size);
|
|
184
189
|
setRateLimits(payload?.rate_limits);
|
|
185
190
|
|
|
186
191
|
return reply.code(200).send({ ok: true, applied: ids });
|
package/daemon/src/transcript.js
CHANGED
|
@@ -4,7 +4,7 @@ import { claudeHome } from "./claude-home.js";
|
|
|
4
4
|
|
|
5
5
|
const TAIL_BYTES = 256 * 1024;
|
|
6
6
|
const TTL_MS = 15_000;
|
|
7
|
-
const DEFAULT_WINDOW =
|
|
7
|
+
const DEFAULT_WINDOW = 1_000_000;
|
|
8
8
|
|
|
9
9
|
// Claude Code's own project-directory naming: the cwd with every `/`
|
|
10
10
|
// replaced by `-` (leading slash included). Exported — pure — for direct
|
|
@@ -17,13 +17,45 @@ export function transcriptPath(dir, claudeSessionId) {
|
|
|
17
17
|
return join(claudeHome(), "projects", slugifyCwd(dir), `${claudeSessionId}.jsonl`);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
20
|
+
// Model ids known to have a 200k window — Haiku, the 3.x family, and
|
|
21
|
+
// everything before Opus/Sonnet 4.6 (the 4.6+ generation and the 5 family
|
|
22
|
+
// are natively 1M). Prefix-matched so dated snapshot ids
|
|
23
|
+
// ("claude-sonnet-4-20250514") land in the right bucket.
|
|
24
|
+
const SMALL_WINDOW_PREFIXES = [
|
|
25
|
+
"claude-haiku",
|
|
26
|
+
"claude-3",
|
|
27
|
+
"claude-opus-4-0",
|
|
28
|
+
"claude-opus-4-1",
|
|
29
|
+
"claude-opus-4-2", // dated Opus 4 ids: claude-opus-4-20250514
|
|
30
|
+
"claude-opus-4-5",
|
|
31
|
+
"claude-sonnet-4-0",
|
|
32
|
+
"claude-sonnet-4-2", // dated Sonnet 4 ids: claude-sonnet-4-20250514
|
|
33
|
+
"claude-sonnet-4-5",
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
// Learned model id -> window size, fed by statusline posts (Claude Code's
|
|
37
|
+
// own `context_window.context_window_size`) — the only authoritative local
|
|
38
|
+
// source; no file on disk maps model ids to windows. In-memory like the
|
|
39
|
+
// statusline context store: wrong-until-first-post beats stale-forever.
|
|
40
|
+
const modelWindows = new Map();
|
|
41
|
+
|
|
42
|
+
export function recordModelWindow(model, size) {
|
|
43
|
+
if (typeof model !== "string" || !model) return;
|
|
44
|
+
if (typeof size !== "number" || !Number.isFinite(size) || size < 1000) return;
|
|
45
|
+
modelWindows.set(model, size);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Precedence: a window Claude Code told us about via statusline, then the
|
|
49
|
+
// "[1m]" beta-variant marker on old model ids
|
|
50
|
+
// ("claude-sonnet-4-5-20250929[1m]"), then the known-200k list, then the
|
|
51
|
+
// 1M default (everything current is natively 1M). A hint, not billing,
|
|
52
|
+
// per design.md.
|
|
24
53
|
export function windowForModel(model) {
|
|
25
54
|
if (typeof model !== "string") return DEFAULT_WINDOW;
|
|
55
|
+
const learned = modelWindows.get(model);
|
|
56
|
+
if (learned !== undefined) return learned;
|
|
26
57
|
if (model.includes("[1m]")) return 1_000_000;
|
|
58
|
+
if (SMALL_WINDOW_PREFIXES.some((p) => model.startsWith(p))) return 200_000;
|
|
27
59
|
return DEFAULT_WINDOW;
|
|
28
60
|
}
|
|
29
61
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-garage",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Multiple Claude agents driving you crazy? Park them all in one garage: a needs-input queue that follows you across projects, a full-screen terminal TUI, and a browser wall with diff review. tmux owns the sessions; close the app and nothing dies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Saiful Islam <saifulislamadar@gmail.com>",
|