@hasna/statusline 0.0.1 → 0.0.2

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/dist/index.js ADDED
@@ -0,0 +1,646 @@
1
+ // @bun
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
12
+ var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
20
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
21
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
+ for (let key of __getOwnPropNames(mod))
23
+ if (!__hasOwnProp.call(to, key))
24
+ __defProp(to, key, {
25
+ get: __accessProp.bind(mod, key),
26
+ enumerable: true
27
+ });
28
+ if (canCache)
29
+ cache.set(mod, to);
30
+ return to;
31
+ };
32
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
33
+ var __returnValue = (v) => v;
34
+ function __exportSetter(name, newValue) {
35
+ this[name] = __returnValue.bind(null, newValue);
36
+ }
37
+ var __export = (target, all) => {
38
+ for (var name in all)
39
+ __defProp(target, name, {
40
+ get: all[name],
41
+ enumerable: true,
42
+ configurable: true,
43
+ set: __exportSetter.bind(all, name)
44
+ });
45
+ };
46
+
47
+ // src/config.ts
48
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
49
+ import { homedir } from "os";
50
+ import { dirname, join } from "path";
51
+ function defaultConfig() {
52
+ return {
53
+ separator: " \xB7 ",
54
+ segments: [
55
+ "machine",
56
+ "project",
57
+ "commit-age",
58
+ "loc",
59
+ "model-context",
60
+ "context-remaining",
61
+ "cost"
62
+ ]
63
+ };
64
+ }
65
+ function configPath(path) {
66
+ if (path)
67
+ return path;
68
+ if (process.env.STATUSLINE_CONFIG)
69
+ return process.env.STATUSLINE_CONFIG;
70
+ const base = process.env.XDG_CONFIG_HOME || join(homedir(), ".config");
71
+ return join(base, "statusline", "config.json");
72
+ }
73
+ function loadConfig(path = configPath()) {
74
+ if (!existsSync(path))
75
+ return defaultConfig();
76
+ try {
77
+ const raw = JSON.parse(readFileSync(path, "utf8"));
78
+ const fallback = defaultConfig();
79
+ return {
80
+ separator: typeof raw.separator === "string" ? raw.separator : fallback.separator,
81
+ segments: Array.isArray(raw.segments) ? raw.segments.filter((s) => typeof s === "string") : fallback.segments
82
+ };
83
+ } catch {
84
+ return defaultConfig();
85
+ }
86
+ }
87
+ function saveConfig(cfg, path = configPath()) {
88
+ mkdirSync(dirname(path), { recursive: true });
89
+ writeFileSync(path, JSON.stringify(cfg, null, 2) + `
90
+ `);
91
+ }
92
+
93
+ // src/providers/claude.ts
94
+ function parseClaudeInput(input) {
95
+ const cwd = input?.cwd || input?.workspace?.current_dir || process.cwd();
96
+ return {
97
+ provider: "claude",
98
+ cwd,
99
+ projectDir: input?.workspace?.project_dir || undefined,
100
+ model: input?.model ? { id: input.model.id || undefined, displayName: input.model.display_name || undefined } : undefined,
101
+ cost: input?.cost ? {
102
+ totalCostUsd: numberOr(input.cost.total_cost_usd),
103
+ totalDurationMs: numberOr(input.cost.total_duration_ms),
104
+ totalLinesAdded: numberOr(input.cost.total_lines_added),
105
+ totalLinesRemoved: numberOr(input.cost.total_lines_removed)
106
+ } : undefined,
107
+ transcriptPath: input?.transcript_path || undefined,
108
+ sessionId: input?.session_id || undefined,
109
+ version: input?.version || undefined,
110
+ outputStyle: input?.output_style?.name || undefined
111
+ };
112
+ }
113
+ function numberOr(v) {
114
+ return typeof v === "number" && Number.isFinite(v) ? v : undefined;
115
+ }
116
+
117
+ // src/segments/index.ts
118
+ import { hostname } from "os";
119
+
120
+ // src/format.ts
121
+ function compactAge(seconds) {
122
+ if (seconds < 60)
123
+ return `${Math.floor(seconds)}s`;
124
+ if (seconds < 3600)
125
+ return `${Math.floor(seconds / 60)}m`;
126
+ if (seconds < 86400)
127
+ return `${Math.floor(seconds / 3600)}h`;
128
+ if (seconds < 604800)
129
+ return `${Math.floor(seconds / 86400)}d`;
130
+ if (seconds < 2592000)
131
+ return `${Math.floor(seconds / 604800)}w`;
132
+ if (seconds < 31536000)
133
+ return `${Math.floor(seconds / 2592000)}mo`;
134
+ return `${Math.floor(seconds / 31536000)}y`;
135
+ }
136
+ function trimmed(value) {
137
+ const fixed = value.toFixed(1);
138
+ return fixed.endsWith(".0") ? fixed.slice(0, -2) : fixed;
139
+ }
140
+ function compactNum(n) {
141
+ if (n >= 1e6)
142
+ return `${trimmed(n / 1e6)}m`;
143
+ if (n >= 1e4)
144
+ return `${Math.floor(n / 1000)}k`;
145
+ if (n >= 1000)
146
+ return `${trimmed(n / 1000)}k`;
147
+ return `${n}`;
148
+ }
149
+ function money(n) {
150
+ return `$${n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
151
+ }
152
+ function compactDuration(ms) {
153
+ const s = Math.floor(ms / 1000);
154
+ if (s < 60)
155
+ return `${s}s`;
156
+ if (s < 3600) {
157
+ const rem2 = s % 60;
158
+ return rem2 ? `${Math.floor(s / 60)}m${rem2}s` : `${Math.floor(s / 60)}m`;
159
+ }
160
+ const rem = Math.floor(s % 3600 / 60);
161
+ return rem ? `${Math.floor(s / 3600)}h${rem}m` : `${Math.floor(s / 3600)}h`;
162
+ }
163
+
164
+ // src/git.ts
165
+ function run(cwd, args) {
166
+ try {
167
+ const proc = Bun.spawnSync(["git", "-c", "gc.auto=0", ...args], {
168
+ cwd,
169
+ stdout: "pipe",
170
+ stderr: "ignore"
171
+ });
172
+ if (proc.exitCode !== 0)
173
+ return null;
174
+ const out = proc.stdout.toString().trim();
175
+ return out.length ? out : null;
176
+ } catch {
177
+ return null;
178
+ }
179
+ }
180
+ function gitRoot(cwd) {
181
+ return run(cwd, ["rev-parse", "--show-toplevel"]);
182
+ }
183
+ function gitBranch(cwd) {
184
+ return run(cwd, ["branch", "--show-current"]);
185
+ }
186
+ function gitProjectName(cwd) {
187
+ const root = gitRoot(cwd);
188
+ if (!root)
189
+ return null;
190
+ const remote = run(root, ["config", "--get", "remote.origin.url"]);
191
+ if (remote)
192
+ return remote.replace(/\.git$/, "").split("/").pop() || null;
193
+ return root.split("/").pop() || null;
194
+ }
195
+ function lastCommitEpoch(cwd) {
196
+ const out = run(cwd, ["log", "-1", "--format=%ct"]);
197
+ if (!out)
198
+ return null;
199
+ const ts = Number(out);
200
+ return Number.isFinite(ts) ? ts : null;
201
+ }
202
+ function trackedLineCount(cwd) {
203
+ const root = gitRoot(cwd);
204
+ if (!root)
205
+ return null;
206
+ try {
207
+ const proc = Bun.spawnSync(["bash", "-c", "git -c gc.auto=0 ls-files -z | xargs -0 wc -l 2>/dev/null | awk 'END {print $1+0}'"], { cwd: root, stdout: "pipe", stderr: "ignore" });
208
+ if (proc.exitCode !== 0)
209
+ return null;
210
+ const n = Number(proc.stdout.toString().trim());
211
+ return Number.isFinite(n) && n > 0 ? n : null;
212
+ } catch {
213
+ return null;
214
+ }
215
+ }
216
+
217
+ // src/context-window.ts
218
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
219
+ function contextUsage(ctx) {
220
+ const path = ctx.transcriptPath;
221
+ if (!path || !existsSync2(path))
222
+ return null;
223
+ let lines;
224
+ try {
225
+ lines = readFileSync2(path, "utf8").split(`
226
+ `);
227
+ } catch {
228
+ return null;
229
+ }
230
+ for (let i = lines.length - 1;i >= 0; i--) {
231
+ const line = lines[i];
232
+ if (!line || !line.includes('"usage"'))
233
+ continue;
234
+ try {
235
+ const entry = JSON.parse(line);
236
+ const usage = entry?.message?.usage;
237
+ if (!usage || typeof usage.input_tokens !== "number")
238
+ continue;
239
+ const used = usage.input_tokens + (usage.cache_creation_input_tokens || 0) + (usage.cache_read_input_tokens || 0);
240
+ return {
241
+ used,
242
+ output: usage.output_tokens || 0,
243
+ window: windowSize(ctx)
244
+ };
245
+ } catch {
246
+ continue;
247
+ }
248
+ }
249
+ return null;
250
+ }
251
+ function windowSize(ctx) {
252
+ return ctx.model?.id?.includes("[1m]") ? 1e6 : 200000;
253
+ }
254
+
255
+ // src/segments/index.ts
256
+ function friendlyModel(id) {
257
+ let tag = null;
258
+ let mid = id;
259
+ const tagMatch = mid.match(/\[([^\]]+)\]$/);
260
+ if (tagMatch) {
261
+ tag = `[${tagMatch[1]}]`;
262
+ mid = mid.slice(0, mid.length - tagMatch[0].length);
263
+ }
264
+ mid = mid.replace(/^claude-/, "").replace(/-\d{8}$/, "");
265
+ const tokens = mid.split("-").filter(Boolean);
266
+ const words = tokens.filter((t) => !/^\d+$/.test(t));
267
+ const nums = tokens.filter((t) => /^\d+$/.test(t));
268
+ const name = [words.join(" "), nums.join(".")].filter(Boolean).join(" ");
269
+ return { name: name || mid, tag };
270
+ }
271
+ var dir = (ctx) => ctx.cwd || process.cwd();
272
+ var segments = [
273
+ {
274
+ id: "machine",
275
+ description: "Machine hostname (short)",
276
+ defaultEnabled: true,
277
+ render: () => hostname().split(".")[0] || null
278
+ },
279
+ {
280
+ id: "project",
281
+ description: "Project name with current Git branch",
282
+ defaultEnabled: true,
283
+ render(ctx) {
284
+ const name = gitProjectName(dir(ctx)) || dir(ctx).split("/").pop() || null;
285
+ if (!name)
286
+ return null;
287
+ const branch = gitBranch(dir(ctx));
288
+ return branch ? `${name} (${branch})` : name;
289
+ }
290
+ },
291
+ {
292
+ id: "project-name",
293
+ description: "Project name (omitted when unavailable)",
294
+ defaultEnabled: false,
295
+ render: (ctx) => gitProjectName(dir(ctx)) || dir(ctx).split("/").pop() || null
296
+ },
297
+ {
298
+ id: "git-branch",
299
+ description: "Current Git branch (omitted when unavailable)",
300
+ defaultEnabled: false,
301
+ render: (ctx) => gitBranch(dir(ctx))
302
+ },
303
+ {
304
+ id: "commit-age",
305
+ description: "Time since last commit (compact)",
306
+ defaultEnabled: true,
307
+ render(ctx) {
308
+ const ts = lastCommitEpoch(dir(ctx));
309
+ if (!ts)
310
+ return null;
311
+ return compactAge(Date.now() / 1000 - ts);
312
+ }
313
+ },
314
+ {
315
+ id: "loc",
316
+ description: "Lines of code tracked by Git (compact)",
317
+ defaultEnabled: true,
318
+ render(ctx) {
319
+ const n = trackedLineCount(dir(ctx));
320
+ return n ? compactNum(n) : null;
321
+ }
322
+ },
323
+ {
324
+ id: "current-dir",
325
+ description: "Current working directory (basename)",
326
+ defaultEnabled: false,
327
+ render: (ctx) => dir(ctx).split("/").pop() || null
328
+ },
329
+ {
330
+ id: "model",
331
+ description: "Current model name",
332
+ defaultEnabled: false,
333
+ render(ctx) {
334
+ if (!ctx.model?.id)
335
+ return null;
336
+ return friendlyModel(ctx.model.id).name;
337
+ }
338
+ },
339
+ {
340
+ id: "model-context",
341
+ description: "Model name with context-size tag (e.g. [1m])",
342
+ defaultEnabled: true,
343
+ render(ctx) {
344
+ if (!ctx.model?.id)
345
+ return null;
346
+ const { name, tag } = friendlyModel(ctx.model.id);
347
+ return tag ? `${name} ${tag}` : name;
348
+ }
349
+ },
350
+ {
351
+ id: "context-used",
352
+ description: "Percentage of context window used (omitted when unknown)",
353
+ defaultEnabled: false,
354
+ render(ctx) {
355
+ const u = contextUsage(ctx);
356
+ if (!u)
357
+ return null;
358
+ return `${Math.min(100, Math.round(u.used / u.window * 100))}%`;
359
+ }
360
+ },
361
+ {
362
+ id: "context-remaining",
363
+ description: "Percentage of context window remaining (omitted when unknown)",
364
+ defaultEnabled: true,
365
+ render(ctx) {
366
+ const u = contextUsage(ctx);
367
+ if (!u)
368
+ return null;
369
+ return `${Math.max(0, 100 - Math.round(u.used / u.window * 100))}% left`;
370
+ }
371
+ },
372
+ {
373
+ id: "used-tokens",
374
+ description: "Total tokens in the context window (omitted when unknown)",
375
+ defaultEnabled: false,
376
+ render(ctx) {
377
+ const u = contextUsage(ctx);
378
+ if (!u)
379
+ return null;
380
+ return `${compactNum(u.used + u.output)} tok`;
381
+ }
382
+ },
383
+ {
384
+ id: "cost",
385
+ description: "Session cost in USD (omitted when zero)",
386
+ defaultEnabled: true,
387
+ render(ctx) {
388
+ const c = ctx.cost?.totalCostUsd;
389
+ return c ? money(c) : null;
390
+ }
391
+ },
392
+ {
393
+ id: "duration",
394
+ description: "Session wall-clock duration",
395
+ defaultEnabled: false,
396
+ render(ctx) {
397
+ const ms = ctx.cost?.totalDurationMs;
398
+ return ms ? compactDuration(ms) : null;
399
+ }
400
+ },
401
+ {
402
+ id: "lines-changed",
403
+ description: "Lines added/removed this session (omitted when zero)",
404
+ defaultEnabled: false,
405
+ render(ctx) {
406
+ const a = ctx.cost?.totalLinesAdded || 0;
407
+ const r = ctx.cost?.totalLinesRemoved || 0;
408
+ if (!a && !r)
409
+ return null;
410
+ return `+${a}/-${r}`;
411
+ }
412
+ },
413
+ {
414
+ id: "output-style",
415
+ description: "Active output style (omitted when default)",
416
+ defaultEnabled: false,
417
+ render(ctx) {
418
+ const s = ctx.outputStyle;
419
+ return s && s !== "default" ? s : null;
420
+ }
421
+ },
422
+ {
423
+ id: "agent-version",
424
+ description: "Host agent version (e.g. Claude Code version)",
425
+ defaultEnabled: false,
426
+ render: (ctx) => ctx.version ? `v${ctx.version}` : null
427
+ },
428
+ {
429
+ id: "session-id",
430
+ description: "Session identifier (short)",
431
+ defaultEnabled: false,
432
+ render: (ctx) => ctx.sessionId ? ctx.sessionId.split("-")[0] : null
433
+ }
434
+ ];
435
+ function getSegment(id) {
436
+ return segments.find((s) => s.id === id);
437
+ }
438
+
439
+ // src/render.ts
440
+ async function renderLine(ctx, cfg) {
441
+ const parts = [];
442
+ for (const id of cfg.segments) {
443
+ const segment = getSegment(id);
444
+ if (!segment)
445
+ continue;
446
+ try {
447
+ const out = await segment.render(ctx);
448
+ if (out)
449
+ parts.push(out);
450
+ } catch {}
451
+ }
452
+ return parts.join(cfg.separator);
453
+ }
454
+ // package.json
455
+ var package_default = {
456
+ name: "@hasna/statusline",
457
+ version: "0.0.2",
458
+ description: "Tiny composable statusline CLI for AI coding agents \u2014 pre-built toggleable segments for Claude Code, with a provider model for others",
459
+ license: "Apache-2.0",
460
+ type: "module",
461
+ main: "./dist/index.js",
462
+ types: "./dist/index.d.ts",
463
+ bin: {
464
+ statusline: "./dist/cli.js",
465
+ "statusline-mcp": "./dist/mcp/index.js"
466
+ },
467
+ exports: {
468
+ ".": {
469
+ types: "./dist/index.d.ts",
470
+ import: "./dist/index.js"
471
+ },
472
+ "./cli": {
473
+ types: "./dist/cli.d.ts",
474
+ import: "./dist/cli.js"
475
+ },
476
+ "./mcp": {
477
+ types: "./dist/mcp/index.d.ts",
478
+ import: "./dist/mcp/index.js"
479
+ }
480
+ },
481
+ files: [
482
+ "dist",
483
+ "LICENSE",
484
+ "README.md"
485
+ ],
486
+ scripts: {
487
+ build: "rm -rf dist && bun build src/index.ts src/cli.ts src/mcp/index.ts --outdir dist --target bun && tsc -p tsconfig.build.json && chmod +x dist/cli.js dist/mcp/index.js",
488
+ typecheck: "tsc --noEmit",
489
+ test: "bun test",
490
+ check: "bun run typecheck && bun test && bun run build",
491
+ prepack: "bun run build",
492
+ prepublishOnly: "bun run typecheck && bun test && bun run build"
493
+ },
494
+ repository: {
495
+ type: "git",
496
+ url: "git+https://github.com/hasna/statusline.git"
497
+ },
498
+ homepage: "https://github.com/hasna/statusline#readme",
499
+ bugs: {
500
+ url: "https://github.com/hasna/statusline/issues"
501
+ },
502
+ keywords: [
503
+ "statusline",
504
+ "status-bar",
505
+ "claude-code",
506
+ "cli",
507
+ "bun"
508
+ ],
509
+ publishConfig: {
510
+ registry: "https://registry.npmjs.org",
511
+ access: "public"
512
+ },
513
+ engines: {
514
+ bun: ">=1.0.0"
515
+ },
516
+ dependencies: {
517
+ "@modelcontextprotocol/sdk": "^1.12.1",
518
+ zod: "^3.25.76"
519
+ },
520
+ devDependencies: {
521
+ "@types/bun": "^1.2.4",
522
+ typescript: "^5.7.3"
523
+ }
524
+ };
525
+ // src/install.ts
526
+ import { copyFileSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
527
+ import { homedir as homedir2 } from "os";
528
+ import { dirname as dirname2, join as join2 } from "path";
529
+ function installClaude(settingsPath = join2(homedir2(), ".claude", "settings.json")) {
530
+ const binary = Bun.which("statusline") || "statusline";
531
+ let settings = {};
532
+ if (existsSync3(settingsPath)) {
533
+ settings = JSON.parse(readFileSync3(settingsPath, "utf8"));
534
+ copyFileSync(settingsPath, `${settingsPath}.bak-statusline`);
535
+ }
536
+ settings.statusLine = { type: "command", command: `${binary} render` };
537
+ mkdirSync2(dirname2(settingsPath), { recursive: true });
538
+ writeFileSync2(settingsPath, JSON.stringify(settings, null, 2) + `
539
+ `);
540
+ return settingsPath;
541
+ }
542
+
543
+ // src/index.ts
544
+ var statuslineVersion = package_default.version;
545
+ function listSegments(config = loadConfig()) {
546
+ const enabled = new Set(config.segments);
547
+ return segments.map((segment) => ({
548
+ id: segment.id,
549
+ description: segment.description,
550
+ defaultEnabled: segment.defaultEnabled,
551
+ enabled: enabled.has(segment.id)
552
+ }));
553
+ }
554
+ function requireKnownSegments(ids) {
555
+ const unknown = ids.filter((id) => !getSegment(id));
556
+ if (unknown.length) {
557
+ throw new Error(`unknown segment(s): ${unknown.join(", ")}`);
558
+ }
559
+ return ids;
560
+ }
561
+ function enableSegments(ids, config = loadConfig()) {
562
+ requireKnownSegments(ids);
563
+ const next = { ...config, segments: [...config.segments] };
564
+ const changed = [];
565
+ for (const id of ids) {
566
+ if (!next.segments.includes(id)) {
567
+ next.segments.push(id);
568
+ changed.push(id);
569
+ }
570
+ }
571
+ return { config: next, changed };
572
+ }
573
+ function disableSegments(ids, config = loadConfig()) {
574
+ requireKnownSegments(ids);
575
+ const nextSegments = config.segments.filter((id) => !ids.includes(id));
576
+ return {
577
+ config: { ...config, segments: nextSegments },
578
+ changed: config.segments.filter((id) => ids.includes(id))
579
+ };
580
+ }
581
+ function orderSegments(ids, config = loadConfig()) {
582
+ requireKnownSegments(ids);
583
+ if (ids.length === 0)
584
+ throw new Error("at least one segment id is required");
585
+ return { config: { ...config, segments: [...ids] }, changed: [...ids] };
586
+ }
587
+ function setSeparator(separator, config = loadConfig()) {
588
+ if (!separator)
589
+ throw new Error("separator must be a non-empty string");
590
+ return { config: { ...config, separator }, changed: ["separator"] };
591
+ }
592
+ function resetStatuslineConfig() {
593
+ return defaultConfig();
594
+ }
595
+ async function renderStatusline(input = {}, config = loadConfig()) {
596
+ return renderLine(parseClaudeInput(input), config);
597
+ }
598
+ function sampleClaudeInput(cwd = process.cwd()) {
599
+ return {
600
+ cwd,
601
+ model: { id: "claude-fable-5[1m]", display_name: "Fable" },
602
+ cost: { total_cost_usd: 12.34, total_duration_ms: 5400000, total_lines_added: 42, total_lines_removed: 7 },
603
+ version: statuslineVersion,
604
+ session_id: "preview0-0000-0000-0000-000000000000"
605
+ };
606
+ }
607
+ async function previewStatusline(config = loadConfig(), cwd = process.cwd()) {
608
+ return renderStatusline(sampleClaudeInput(cwd), config);
609
+ }
610
+ function saveUpdatedConfig(result, path = configPath()) {
611
+ saveConfig(result.config, path);
612
+ return result.config;
613
+ }
614
+ export {
615
+ trackedLineCount,
616
+ statuslineVersion,
617
+ setSeparator,
618
+ segments,
619
+ saveUpdatedConfig,
620
+ saveConfig,
621
+ sampleClaudeInput,
622
+ resetStatuslineConfig,
623
+ requireKnownSegments,
624
+ renderStatusline,
625
+ renderLine,
626
+ previewStatusline,
627
+ parseClaudeInput,
628
+ orderSegments,
629
+ money,
630
+ loadConfig,
631
+ listSegments,
632
+ lastCommitEpoch,
633
+ installClaude,
634
+ gitRoot,
635
+ gitProjectName,
636
+ gitBranch,
637
+ getSegment,
638
+ enableSegments,
639
+ disableSegments,
640
+ defaultConfig,
641
+ contextUsage,
642
+ configPath,
643
+ compactNum,
644
+ compactDuration,
645
+ compactAge
646
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Wire the statusline into Claude Code's user settings. Existing settings
3
+ * are preserved; the previous file is backed up alongside it.
4
+ */
5
+ export declare function installClaude(settingsPath?: string): string;
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env bun
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ export declare function buildServer(): McpServer;
4
+ export declare function startMcpServer(): Promise<void>;