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.
@@ -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 });
@@ -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 = 200_000;
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
- // Small map of known exceptions to the 200k default — "[1m]" marks the
21
- // 1M-context beta variants of a model id (e.g.
22
- // "claude-sonnet-4-5-20250929[1m]"). Anything else, including an unknown or
23
- // missing model id, gets the default: a hint, not billing, per design.md.
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.0",
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>",