aicodeman 1.0.0 → 1.1.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.
Files changed (169) hide show
  1. package/README.md +2 -1
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +27 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config/dependency-registry.d.ts +42 -0
  6. package/dist/config/dependency-registry.d.ts.map +1 -0
  7. package/dist/config/dependency-registry.js +104 -0
  8. package/dist/config/dependency-registry.js.map +1 -0
  9. package/dist/document-conversion-limiter.d.ts +27 -0
  10. package/dist/document-conversion-limiter.d.ts.map +1 -0
  11. package/dist/document-conversion-limiter.js +64 -0
  12. package/dist/document-conversion-limiter.js.map +1 -0
  13. package/dist/document-preview-cache.d.ts +15 -0
  14. package/dist/document-preview-cache.d.ts.map +1 -0
  15. package/dist/document-preview-cache.js +261 -0
  16. package/dist/document-preview-cache.js.map +1 -0
  17. package/dist/document-thumbnailer.d.ts +9 -0
  18. package/dist/document-thumbnailer.d.ts.map +1 -0
  19. package/dist/document-thumbnailer.js +70 -0
  20. package/dist/document-thumbnailer.js.map +1 -0
  21. package/dist/hooks-config.d.ts +34 -0
  22. package/dist/hooks-config.d.ts.map +1 -1
  23. package/dist/hooks-config.js +203 -73
  24. package/dist/hooks-config.js.map +1 -1
  25. package/dist/image-watcher.d.ts.map +1 -1
  26. package/dist/image-watcher.js +2 -6
  27. package/dist/image-watcher.js.map +1 -1
  28. package/dist/session-attachment-history.d.ts +19 -0
  29. package/dist/session-attachment-history.d.ts.map +1 -0
  30. package/dist/session-attachment-history.js +63 -0
  31. package/dist/session-attachment-history.js.map +1 -0
  32. package/dist/session.d.ts +10 -0
  33. package/dist/session.d.ts.map +1 -1
  34. package/dist/session.js +27 -0
  35. package/dist/session.js.map +1 -1
  36. package/dist/types/session.d.ts +35 -0
  37. package/dist/types/session.d.ts.map +1 -1
  38. package/dist/types/session.js.map +1 -1
  39. package/dist/usage-telemetry.d.ts +102 -0
  40. package/dist/usage-telemetry.d.ts.map +1 -0
  41. package/dist/usage-telemetry.js +130 -0
  42. package/dist/usage-telemetry.js.map +1 -0
  43. package/dist/utils/dependency-checker.d.ts +42 -0
  44. package/dist/utils/dependency-checker.d.ts.map +1 -0
  45. package/dist/utils/dependency-checker.js +167 -0
  46. package/dist/utils/dependency-checker.js.map +1 -0
  47. package/dist/utils/dependency-report.d.ts +26 -0
  48. package/dist/utils/dependency-report.d.ts.map +1 -0
  49. package/dist/utils/dependency-report.js +68 -0
  50. package/dist/utils/dependency-report.js.map +1 -0
  51. package/dist/web/middleware/auth.d.ts +4 -8
  52. package/dist/web/middleware/auth.d.ts.map +1 -1
  53. package/dist/web/middleware/auth.js +18 -25
  54. package/dist/web/middleware/auth.js.map +1 -1
  55. package/dist/web/plan-usage-latest.d.ts +15 -0
  56. package/dist/web/plan-usage-latest.d.ts.map +1 -0
  57. package/dist/web/plan-usage-latest.js +20 -0
  58. package/dist/web/plan-usage-latest.js.map +1 -0
  59. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  60. package/dist/web/public/app.92f49a9d.js +37 -0
  61. package/dist/web/public/app.92f49a9d.js.br +0 -0
  62. package/dist/web/public/app.92f49a9d.js.gz +0 -0
  63. package/dist/web/public/{constants.aa510a4d.js → constants.59faac65.js} +16 -0
  64. package/dist/web/public/constants.59faac65.js.br +0 -0
  65. package/dist/web/public/constants.59faac65.js.gz +0 -0
  66. package/dist/web/public/image-input.0ea86695.js.gz +0 -0
  67. package/dist/web/public/index.html +40 -27
  68. package/dist/web/public/index.html.br +0 -0
  69. package/dist/web/public/index.html.gz +0 -0
  70. package/dist/web/public/input-cjk.b8686b5e.js.gz +0 -0
  71. package/dist/web/public/keyboard-accessory.bc753cc7.js.gz +0 -0
  72. package/dist/web/public/{mobile-handlers.763a7439.js → mobile-handlers.db3dc3c8.js} +3 -0
  73. package/dist/web/public/mobile-handlers.db3dc3c8.js.br +0 -0
  74. package/dist/web/public/mobile-handlers.db3dc3c8.js.gz +0 -0
  75. package/dist/web/public/mobile.06b38d3a.css +1 -0
  76. package/dist/web/public/mobile.06b38d3a.css.br +0 -0
  77. package/dist/web/public/mobile.06b38d3a.css.gz +0 -0
  78. package/dist/web/public/notification-manager.9c984ac2.js.gz +0 -0
  79. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  80. package/dist/web/public/{panels-ui.ba0b0f1a.js → panels-ui.2f467969.js} +141 -87
  81. package/dist/web/public/panels-ui.2f467969.js.br +0 -0
  82. package/dist/web/public/panels-ui.2f467969.js.gz +0 -0
  83. package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
  84. package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
  85. package/dist/web/public/respawn-ui.2d249da9.js.gz +0 -0
  86. package/dist/web/public/sanitize-html.bc7078d6.js +1 -0
  87. package/dist/web/public/sanitize-html.bc7078d6.js.br +0 -0
  88. package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
  89. package/dist/web/public/session-ui.1463b824.js +36 -0
  90. package/dist/web/public/session-ui.1463b824.js.br +0 -0
  91. package/dist/web/public/session-ui.1463b824.js.gz +0 -0
  92. package/dist/web/public/settings-ui.44b99ce0.js +55 -0
  93. package/dist/web/public/settings-ui.44b99ce0.js.br +0 -0
  94. package/dist/web/public/settings-ui.44b99ce0.js.gz +0 -0
  95. package/dist/web/public/styles.8e1ea0c6.css +1 -0
  96. package/dist/web/public/styles.8e1ea0c6.css.br +0 -0
  97. package/dist/web/public/styles.8e1ea0c6.css.gz +0 -0
  98. package/dist/web/public/subagent-windows.a366a4ad.js.gz +0 -0
  99. package/dist/web/public/sw.js.gz +0 -0
  100. package/dist/web/public/terminal-ui.a7e046da.js +3 -0
  101. package/dist/web/public/terminal-ui.a7e046da.js.br +0 -0
  102. package/dist/web/public/terminal-ui.a7e046da.js.gz +0 -0
  103. package/dist/web/public/upload.html.gz +0 -0
  104. package/dist/web/public/vendor/dompurify.min.js +3 -0
  105. package/dist/web/public/vendor/dompurify.min.js.br +0 -0
  106. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  107. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  108. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  109. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  110. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  111. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  112. package/dist/web/public/vendor/xterm-zerolag-input.137ad9f0.js.gz +0 -0
  113. package/dist/web/public/vendor/xterm.css.gz +0 -0
  114. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  115. package/dist/web/public/voice-input.085e9e73.js.gz +0 -0
  116. package/dist/web/routes/file-routes.d.ts +2 -2
  117. package/dist/web/routes/file-routes.d.ts.map +1 -1
  118. package/dist/web/routes/file-routes.js +298 -1
  119. package/dist/web/routes/file-routes.js.map +1 -1
  120. package/dist/web/routes/index.d.ts +1 -0
  121. package/dist/web/routes/index.d.ts.map +1 -1
  122. package/dist/web/routes/index.js +1 -0
  123. package/dist/web/routes/index.js.map +1 -1
  124. package/dist/web/routes/session-routes.d.ts.map +1 -1
  125. package/dist/web/routes/session-routes.js +27 -1
  126. package/dist/web/routes/session-routes.js.map +1 -1
  127. package/dist/web/routes/status-telemetry-routes.d.ts +17 -0
  128. package/dist/web/routes/status-telemetry-routes.d.ts.map +1 -0
  129. package/dist/web/routes/status-telemetry-routes.js +57 -0
  130. package/dist/web/routes/status-telemetry-routes.js.map +1 -0
  131. package/dist/web/routes/system-routes.d.ts.map +1 -1
  132. package/dist/web/routes/system-routes.js +21 -1
  133. package/dist/web/routes/system-routes.js.map +1 -1
  134. package/dist/web/schemas.d.ts +30 -1
  135. package/dist/web/schemas.d.ts.map +1 -1
  136. package/dist/web/schemas.js +52 -0
  137. package/dist/web/schemas.js.map +1 -1
  138. package/dist/web/server.d.ts.map +1 -1
  139. package/dist/web/server.js +51 -5
  140. package/dist/web/server.js.map +1 -1
  141. package/dist/web/sse-events.d.ts +3 -0
  142. package/dist/web/sse-events.d.ts.map +1 -1
  143. package/dist/web/sse-events.js +3 -0
  144. package/dist/web/sse-events.js.map +1 -1
  145. package/package.json +1 -1
  146. package/dist/web/public/app.95e6e231.js +0 -35
  147. package/dist/web/public/app.95e6e231.js.br +0 -0
  148. package/dist/web/public/app.95e6e231.js.gz +0 -0
  149. package/dist/web/public/constants.aa510a4d.js.br +0 -0
  150. package/dist/web/public/constants.aa510a4d.js.gz +0 -0
  151. package/dist/web/public/mobile-handlers.763a7439.js.br +0 -0
  152. package/dist/web/public/mobile-handlers.763a7439.js.gz +0 -0
  153. package/dist/web/public/mobile.c7513aed.css +0 -1
  154. package/dist/web/public/mobile.c7513aed.css.br +0 -0
  155. package/dist/web/public/mobile.c7513aed.css.gz +0 -0
  156. package/dist/web/public/panels-ui.ba0b0f1a.js.br +0 -0
  157. package/dist/web/public/panels-ui.ba0b0f1a.js.gz +0 -0
  158. package/dist/web/public/session-ui.34f25fdf.js +0 -36
  159. package/dist/web/public/session-ui.34f25fdf.js.br +0 -0
  160. package/dist/web/public/session-ui.34f25fdf.js.gz +0 -0
  161. package/dist/web/public/settings-ui.bf79c4c0.js +0 -55
  162. package/dist/web/public/settings-ui.bf79c4c0.js.br +0 -0
  163. package/dist/web/public/settings-ui.bf79c4c0.js.gz +0 -0
  164. package/dist/web/public/styles.f3cc9833.css +0 -1
  165. package/dist/web/public/styles.f3cc9833.css.br +0 -0
  166. package/dist/web/public/styles.f3cc9833.css.gz +0 -0
  167. package/dist/web/public/terminal-ui.5bf97f7e.js +0 -3
  168. package/dist/web/public/terminal-ui.5bf97f7e.js.br +0 -0
  169. package/dist/web/public/terminal-ui.5bf97f7e.js.gz +0 -0
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @fileoverview Pure parsing + formatting of Claude Code statusline telemetry.
3
+ *
4
+ * Claude Code (v2.1.80+) pipes a JSON blob to a configured `statusLine.command`
5
+ * on each render. On Pro/Max subscriptions that blob carries a `rate_limits`
6
+ * object with the 5-hour rolling and 7-day weekly plan windows. The
7
+ * Codeman-managed statusLine exporter (see `hooks-config.generateStatusLineCommand`)
8
+ * POSTs that blob to `/api/status-telemetry`; these helpers normalize the subset
9
+ * Codeman displays and format the compact in-terminal footer string.
10
+ *
11
+ * Confirmed schema (empirically captured, CC 2.1.177, Claude Max — see
12
+ * `docs/usage-limits-display-plan.md`):
13
+ * rate_limits.{five_hour,seven_day}.{used_percentage: number 0-100,
14
+ * resets_at: number EPOCH-SECONDS}
15
+ * Only those two windows exist (no Opus-weekly field). `rate_limits` is absent
16
+ * before the first API response and for non-subscriber auth — both yield null.
17
+ *
18
+ * All functions are pure for testability. See `test/usage-telemetry.test.ts`.
19
+ *
20
+ * @module usage-telemetry
21
+ */
22
+ function clampPct(n) {
23
+ if (!Number.isFinite(n))
24
+ return 0;
25
+ return Math.max(0, Math.min(100, n));
26
+ }
27
+ function parseWindow(w) {
28
+ if (!w || typeof w.used_percentage !== 'number' || typeof w.resets_at !== 'number')
29
+ return undefined;
30
+ if (!Number.isFinite(w.resets_at) || w.resets_at <= 0)
31
+ return undefined;
32
+ return { usedPercentage: clampPct(w.used_percentage), resetAt: Math.round(w.resets_at * 1000) };
33
+ }
34
+ /**
35
+ * Normalize a raw statusline payload to the telemetry Codeman displays. Returns
36
+ * null when there is no plan-limit data to show (pre-first-response or a
37
+ * non-subscriber account) so the caller can skip broadcasting.
38
+ */
39
+ export function parseStatusTelemetry(data) {
40
+ if (!data)
41
+ return null;
42
+ const fiveHour = parseWindow(data.rate_limits?.five_hour);
43
+ const sevenDay = parseWindow(data.rate_limits?.seven_day);
44
+ if (!fiveHour && !sevenDay)
45
+ return null;
46
+ const t = {};
47
+ if (fiveHour)
48
+ t.fiveHour = fiveHour;
49
+ if (sevenDay)
50
+ t.sevenDay = sevenDay;
51
+ if (typeof data.context_window?.used_percentage === 'number') {
52
+ t.contextUsedPercentage = clampPct(data.context_window.used_percentage);
53
+ }
54
+ if (typeof data.cost?.total_cost_usd === 'number' && Number.isFinite(data.cost.total_cost_usd)) {
55
+ t.costUsd = data.cost.total_cost_usd;
56
+ }
57
+ if (typeof data.model?.display_name === 'string' && data.model.display_name) {
58
+ t.modelDisplayName = data.model.display_name.slice(0, 60);
59
+ }
60
+ return t;
61
+ }
62
+ /** Group a non-negative integer with thousands separators: 562411 → "562,411". */
63
+ function withCommas(n) {
64
+ return Math.max(0, Math.round(n))
65
+ .toString()
66
+ .replace(/\B(?=(\d{3})+(?!\d))/g, ',');
67
+ }
68
+ /** Extract current-session status (footer) from the raw payload. */
69
+ export function parseSessionStatus(data) {
70
+ if (!data)
71
+ return null;
72
+ const s = {};
73
+ if (typeof data.model?.display_name === 'string' && data.model.display_name) {
74
+ s.modelDisplayName = data.model.display_name.slice(0, 60);
75
+ }
76
+ const cw = data.context_window;
77
+ if (typeof cw?.total_input_tokens === 'number' && Number.isFinite(cw.total_input_tokens)) {
78
+ s.inputTokens = Math.max(0, cw.total_input_tokens);
79
+ }
80
+ if (typeof cw?.total_output_tokens === 'number' && Number.isFinite(cw.total_output_tokens)) {
81
+ s.outputTokens = Math.max(0, cw.total_output_tokens);
82
+ }
83
+ if (typeof cw?.used_percentage === 'number') {
84
+ s.contextUsedPercentage = clampPct(cw.used_percentage);
85
+ }
86
+ return Object.keys(s).length ? s : null;
87
+ }
88
+ /**
89
+ * Format the in-terminal statusline footer: the CURRENT SESSION's status —
90
+ * `Opus 4.8 (1M context) in:562,411 out:1,188 ctx:56%` — NOT the plan limits,
91
+ * which live in the Codeman header chip. Claude requires a statusLine command to
92
+ * emit the rate_limits JSON at all, so this is what that command prints back.
93
+ */
94
+ export function formatSessionStatusText(s) {
95
+ if (!s)
96
+ return 'codeman';
97
+ const groups = [];
98
+ if (s.modelDisplayName)
99
+ groups.push(s.modelDisplayName);
100
+ const tok = [];
101
+ if (s.inputTokens != null)
102
+ tok.push(`in:${withCommas(s.inputTokens)}`);
103
+ if (s.outputTokens != null)
104
+ tok.push(`out:${withCommas(s.outputTokens)}`);
105
+ if (tok.length)
106
+ groups.push(tok.join(' '));
107
+ if (s.contextUsedPercentage != null)
108
+ groups.push(`ctx:${Math.round(clampPct(s.contextUsedPercentage))}%`);
109
+ return groups.length ? groups.join(' ') : 'codeman';
110
+ }
111
+ /**
112
+ * Stable signature for change-detection — the statusline fires on every
113
+ * assistant message, so the route only rebroadcasts when this value changes.
114
+ *
115
+ * Keys on EXACTLY the values the header chip displays: the two windows' ROUNDED
116
+ * percentages (the chip renders `Math.round`) + their reset times. Deliberately
117
+ * excludes contextUsedPercentage / costUsd / modelDisplayName — none are shown
118
+ * in the chip, and contextUsedPercentage in particular drifts on every assistant
119
+ * message, which would defeat the dedup and fan out a redundant SSE broadcast +
120
+ * localStorage write + identical chip re-render each time.
121
+ */
122
+ export function telemetrySignature(t) {
123
+ return JSON.stringify([
124
+ t.fiveHour ? Math.round(t.fiveHour.usedPercentage) : null,
125
+ t.fiveHour?.resetAt ?? null,
126
+ t.sevenDay ? Math.round(t.sevenDay.usedPercentage) : null,
127
+ t.sevenDay?.resetAt ?? null,
128
+ ]);
129
+ }
130
+ //# sourceMappingURL=usage-telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-telemetry.js","sourceRoot":"","sources":["../src/usage-telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @fileoverview Probe engine for `codeman doctor`. Resolves each registry tool
3
+ * against an injectable ProbeHost (real impl uses child_process/fs; tests inject
4
+ * fakes) and returns structured results. Pure given the host — no global I/O.
5
+ *
6
+ * @module utils/dependency-checker
7
+ */
8
+ import type { ProbeEnvironment, ToolCategory, ToolDependency } from '../config/dependency-registry.js';
9
+ export interface EnvDetectionInputs {
10
+ platform: NodeJS.Platform;
11
+ procVersion: string;
12
+ hasWindowsInterop: boolean;
13
+ }
14
+ export declare function detectEnvironment(inputs: EnvDetectionInputs): ProbeEnvironment;
15
+ export declare function extractVersion(text: string, re?: RegExp): string | undefined;
16
+ /** Returns -1 if a < b, 0 if equal, 1 if a > b (numeric, component-wise). */
17
+ export declare function compareVersions(a: string, b: string): number;
18
+ export type ToolStatus = 'ok' | 'missing' | 'outdated' | 'skipped' | 'error';
19
+ export interface ToolResult {
20
+ id: string;
21
+ label: string;
22
+ category: ToolCategory;
23
+ required: boolean;
24
+ usedBy: string[];
25
+ status: ToolStatus;
26
+ version?: string;
27
+ path?: string;
28
+ installHint?: string;
29
+ reason?: string;
30
+ }
31
+ export interface ProbeHost {
32
+ environment: ProbeEnvironment;
33
+ which(bin: string): string | null;
34
+ fileExists(path: string): boolean;
35
+ runVersion(bin: string, args: string[]): string | null;
36
+ windowsProgramRoots(): string[];
37
+ windowsFileVersion(winPath: string): string | null;
38
+ }
39
+ export declare function checkTool(tool: ToolDependency, host: ProbeHost): ToolResult;
40
+ export declare function checkAll(registry: ToolDependency[], host: ProbeHost): ToolResult[];
41
+ export declare function createRealHost(): ProbeHost;
42
+ //# sourceMappingURL=dependency-checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-checker.d.ts","sourceRoot":"","sources":["../../src/utils/dependency-checker.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEvG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB,GAAG,gBAAgB,CAK9E;AAID,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG5E;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAS5D;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;AAE7E,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAClC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;IACvD,mBAAmB,IAAI,MAAM,EAAE,CAAC;IAChC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACpD;AAeD,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,UAAU,CAyC3E;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,SAAS,GAAG,UAAU,EAAE,CAElF;AAqED,wBAAgB,cAAc,IAAI,SAAS,CAc1C"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * @fileoverview Probe engine for `codeman doctor`. Resolves each registry tool
3
+ * against an injectable ProbeHost (real impl uses child_process/fs; tests inject
4
+ * fakes) and returns structured results. Pure given the host — no global I/O.
5
+ *
6
+ * @module utils/dependency-checker
7
+ */
8
+ import { execFileSync } from 'node:child_process';
9
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
10
+ import { EXEC_TIMEOUT_MS } from '../config/exec-timeout.js';
11
+ export function detectEnvironment(inputs) {
12
+ if (inputs.platform === 'win32')
13
+ return 'win32';
14
+ if (inputs.platform === 'darwin')
15
+ return 'darwin';
16
+ const isWsl = /microsoft|wsl/i.test(inputs.procVersion) && inputs.hasWindowsInterop;
17
+ return isWsl ? 'wsl' : 'linux';
18
+ }
19
+ const DEFAULT_VERSION_RE = /(\d+\.\d+(?:\.\d+)?)/;
20
+ export function extractVersion(text, re) {
21
+ const m = (re ?? DEFAULT_VERSION_RE).exec(text);
22
+ return m ? m[1] : undefined;
23
+ }
24
+ /** Returns -1 if a < b, 0 if equal, 1 if a > b (numeric, component-wise). */
25
+ export function compareVersions(a, b) {
26
+ const pa = a.split('.').map((n) => parseInt(n, 10) || 0);
27
+ const pb = b.split('.').map((n) => parseInt(n, 10) || 0);
28
+ const len = Math.max(pa.length, pb.length);
29
+ for (let i = 0; i < len; i++) {
30
+ const d = (pa[i] || 0) - (pb[i] || 0);
31
+ if (d !== 0)
32
+ return d < 0 ? -1 : 1;
33
+ }
34
+ return 0;
35
+ }
36
+ function finalize(base, tool, path, version) {
37
+ if (tool.minVersion) {
38
+ if (!version)
39
+ return { ...base, status: 'error', path, reason: 'version required but could not be parsed' };
40
+ if (compareVersions(version, tool.minVersion) < 0)
41
+ return { ...base, status: 'outdated', path, version };
42
+ }
43
+ return { ...base, status: 'ok', path, version };
44
+ }
45
+ export function checkTool(tool, host) {
46
+ const base = {
47
+ id: tool.id,
48
+ label: tool.label,
49
+ category: tool.category,
50
+ required: tool.required,
51
+ usedBy: tool.usedBy ?? [],
52
+ };
53
+ const installHint = tool.installHint?.[host.environment];
54
+ const spec = tool.resolvers.find((r) => r.match.includes(host.environment));
55
+ if (!spec)
56
+ return { ...base, status: 'skipped', reason: `not applicable on ${host.environment}` };
57
+ if (spec.resolver.kind === 'path') {
58
+ const { bins, versionArg, versionRegex } = spec.resolver;
59
+ for (const bin of bins) {
60
+ const resolved = host.which(bin);
61
+ if (resolved) {
62
+ const out = host.runVersion(bin, [versionArg ?? '--version']);
63
+ const version = out ? extractVersion(out, versionRegex) : undefined;
64
+ return finalize(base, tool, resolved, version);
65
+ }
66
+ }
67
+ return { ...base, status: 'missing', installHint };
68
+ }
69
+ // windows-side
70
+ const { appDirs, exes } = spec.resolver;
71
+ for (const root of host.windowsProgramRoots()) {
72
+ for (const dir of appDirs) {
73
+ for (const exe of exes) {
74
+ const winPath = `${root}/${dir}/${exe}`;
75
+ if (host.fileExists(winPath)) {
76
+ const raw = host.windowsFileVersion(winPath);
77
+ const version = raw ? extractVersion(raw) : undefined;
78
+ return finalize(base, tool, winPath, version);
79
+ }
80
+ }
81
+ }
82
+ }
83
+ return { ...base, status: 'missing', installHint };
84
+ }
85
+ export function checkAll(registry, host) {
86
+ return registry.map((tool) => checkTool(tool, host));
87
+ }
88
+ function safeWhich(bin) {
89
+ try {
90
+ const out = execFileSync(process.platform === 'win32' ? 'where' : 'which', [bin], {
91
+ encoding: 'utf-8',
92
+ timeout: EXEC_TIMEOUT_MS,
93
+ }).trim();
94
+ const first = out.split(/\r?\n/)[0]?.trim();
95
+ return first && existsSync(first) ? first : null;
96
+ }
97
+ catch {
98
+ return null;
99
+ }
100
+ }
101
+ function safeRunVersion(bin, args) {
102
+ try {
103
+ return execFileSync(bin, args, {
104
+ encoding: 'utf-8',
105
+ timeout: EXEC_TIMEOUT_MS,
106
+ stdio: ['ignore', 'pipe', 'ignore'],
107
+ });
108
+ }
109
+ catch (err) {
110
+ // Some tools (e.g. ffmpeg) exit non-zero on -version but still print to stdout
111
+ const stdout = err?.stdout;
112
+ return stdout ? stdout.toString() : null;
113
+ }
114
+ }
115
+ function readProcVersion() {
116
+ try {
117
+ return readFileSync('/proc/version', 'utf-8');
118
+ }
119
+ catch {
120
+ return '';
121
+ }
122
+ }
123
+ function listWindowsProgramRoots() {
124
+ const roots = [];
125
+ try {
126
+ for (const entry of readdirSync('/mnt')) {
127
+ for (const pf of ['Program Files', 'Program Files (x86)']) {
128
+ const root = `/mnt/${entry}/${pf}`;
129
+ if (existsSync(root))
130
+ roots.push(root);
131
+ }
132
+ }
133
+ }
134
+ catch {
135
+ // /mnt absent (not WSL) -> no roots
136
+ }
137
+ return roots;
138
+ }
139
+ function readWindowsFileVersion(winPath) {
140
+ try {
141
+ const windowsPath = execFileSync('wslpath', ['-w', winPath], {
142
+ encoding: 'utf-8',
143
+ timeout: EXEC_TIMEOUT_MS,
144
+ }).trim();
145
+ const out = execFileSync('powershell.exe', ['-NoProfile', '-Command', `(Get-Item '${windowsPath.replace(/'/g, "''")}').VersionInfo.ProductVersion`], { encoding: 'utf-8', timeout: EXEC_TIMEOUT_MS }).trim();
146
+ return out || null;
147
+ }
148
+ catch {
149
+ return null;
150
+ }
151
+ }
152
+ export function createRealHost() {
153
+ const environment = detectEnvironment({
154
+ platform: process.platform,
155
+ procVersion: readProcVersion(),
156
+ hasWindowsInterop: safeWhich('cmd.exe') !== null || safeWhich('powershell.exe') !== null,
157
+ });
158
+ return {
159
+ environment,
160
+ which: safeWhich,
161
+ fileExists: existsSync,
162
+ runVersion: safeRunVersion,
163
+ windowsProgramRoots: listWindowsProgramRoots,
164
+ windowsFileVersion: readWindowsFileVersion,
165
+ };
166
+ }
167
+ //# sourceMappingURL=dependency-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-checker.js","sourceRoot":"","sources":["../../src/utils/dependency-checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @fileoverview Renders ToolResult[] from the dependency checker into a
3
+ * human-readable grouped table or JSON, and computes the process exit code.
4
+ * Plain text only (no color) so output is stable and snapshot-friendly; the
5
+ * CLI layer may colorize.
6
+ *
7
+ * @module utils/dependency-report
8
+ */
9
+ import type { ProbeEnvironment } from '../config/dependency-registry.js';
10
+ import type { ToolResult } from './dependency-checker.js';
11
+ export declare function computeExitCode(results: ToolResult[]): number;
12
+ export declare function renderTable(results: ToolResult[], environment: ProbeEnvironment): string;
13
+ export interface DependencyReportJson {
14
+ platform: {
15
+ environment: ProbeEnvironment;
16
+ };
17
+ summary: {
18
+ ok: number;
19
+ requiredMissing: number;
20
+ optionalMissing: number;
21
+ exitCode: number;
22
+ };
23
+ tools: ToolResult[];
24
+ }
25
+ export declare function renderJson(results: ToolResult[], environment: ProbeEnvironment): DependencyReportJson;
26
+ //# sourceMappingURL=dependency-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-report.d.ts","sourceRoot":"","sources":["../../src/utils/dependency-report.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,kCAAkC,CAAC;AACvF,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,yBAAyB,CAAC;AAkBtE,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,CAK7D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,gBAAgB,GAAG,MAAM,CAmBxF;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE;QAAE,WAAW,EAAE,gBAAgB,CAAA;KAAE,CAAC;IAC5C,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5F,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,gBAAgB,GAAG,oBAAoB,CAYrG"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @fileoverview Renders ToolResult[] from the dependency checker into a
3
+ * human-readable grouped table or JSON, and computes the process exit code.
4
+ * Plain text only (no color) so output is stable and snapshot-friendly; the
5
+ * CLI layer may colorize.
6
+ *
7
+ * @module utils/dependency-report
8
+ */
9
+ const CATEGORY_ORDER = ['core', 'office', 'other'];
10
+ function glyph(r) {
11
+ if (r.status === 'ok')
12
+ return '✓';
13
+ if (r.status === 'skipped')
14
+ return '○';
15
+ return r.required ? '✗' : '○';
16
+ }
17
+ function statusText(r) {
18
+ if (r.status === 'ok')
19
+ return r.version ?? 'installed';
20
+ if (r.status === 'outdated')
21
+ return `${r.version ?? '?'} (below minimum)`;
22
+ if (r.status === 'skipped')
23
+ return 'n/a';
24
+ if (r.status === 'error')
25
+ return 'version error';
26
+ return 'not found';
27
+ }
28
+ export function computeExitCode(results) {
29
+ const failed = results.some((r) => r.required && (r.status === 'missing' || r.status === 'outdated' || r.status === 'error'));
30
+ return failed ? 1 : 0;
31
+ }
32
+ export function renderTable(results, environment) {
33
+ const lines = [`Codeman dependency check — ${environment}`, ''];
34
+ for (const category of CATEGORY_ORDER) {
35
+ const rows = results.filter((r) => r.category === category);
36
+ if (rows.length === 0)
37
+ continue;
38
+ lines.push(category.toUpperCase());
39
+ for (const r of rows) {
40
+ const detail = r.path ? ` ${r.path}` : '';
41
+ lines.push(` ${glyph(r)} ${r.label.padEnd(14)} ${statusText(r).padEnd(22)}${detail}`);
42
+ if (r.usedBy.length)
43
+ lines.push(` used by: ${r.usedBy.join(', ')}`);
44
+ if (r.installHint)
45
+ lines.push(` install: ${r.installHint}`);
46
+ }
47
+ lines.push('');
48
+ }
49
+ const ok = results.filter((r) => r.status === 'ok').length;
50
+ const requiredMissing = results.filter((r) => r.required && r.status !== 'ok' && r.status !== 'skipped').length;
51
+ const optionalMissing = results.filter((r) => !r.required && r.status === 'missing').length;
52
+ lines.push(`Summary: ${ok} ok · ${requiredMissing} required missing · ${optionalMissing} optional missing`);
53
+ return lines.join('\n');
54
+ }
55
+ export function renderJson(results, environment) {
56
+ const byStatus = (s) => results.filter((r) => r.status === s).length;
57
+ return {
58
+ platform: { environment },
59
+ summary: {
60
+ ok: byStatus('ok'),
61
+ requiredMissing: results.filter((r) => r.required && r.status !== 'ok' && r.status !== 'skipped').length,
62
+ optionalMissing: results.filter((r) => !r.required && r.status === 'missing').length,
63
+ exitCode: computeExitCode(results),
64
+ },
65
+ tools: results,
66
+ };
67
+ }
68
+ //# sourceMappingURL=dependency-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-report.js","sourceRoot":"","sources":["../../src/utils/dependency-report.ts"],"names":[],"mappings":"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"}
@@ -23,16 +23,12 @@ interface AuthState {
23
23
  * Register HTTP Basic Auth middleware with session cookies and rate limiting.
24
24
  * Only active when CODEMAN_PASSWORD is set.
25
25
  *
26
- * @param getTunnelRunning - returns true while a managed tunnel is active. Used
27
- * to gate the `/api/hook-event` localhost bypass: when a tunnel is up, tunneled
28
- * internet traffic reaches the loopback origin with `req.ip === 127.0.0.1`, so
29
- * the bypass additionally requires the shared hook secret (COD-54). When no
30
- * tunnel is running (loopback-only, the normal case) the plain localhost bypass
31
- * is kept so already-deployed (pre-secret) hooks + the loop channel keep working.
32
- * Optional; defaults to "no tunnel" (unchanged behavior) when omitted.
26
+ * The `/api/hook-event` + `/api/status-telemetry` localhost bypass requires the
27
+ * shared hook secret unconditionally (COD-91) see the onRequest hook below.
28
+ *
33
29
  * @returns AuthState for lifecycle management (dispose on server stop)
34
30
  */
35
- export declare function registerAuthMiddleware(app: FastifyInstance, https: boolean, getTunnelRunning?: () => boolean): AuthState;
31
+ export declare function registerAuthMiddleware(app: FastifyInstance, https: boolean): AuthState;
36
32
  /**
37
33
  * Register the anti-DNS-rebinding Host allowlist + cross-site (CSRF) Origin guard.
38
34
  *
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/web/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAgD,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAU1G,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAElD,8EAA8E;AAC9E,UAAU,SAAS;IACjB,YAAY,EAAE,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,IAAI,CAAC;IACnE,YAAY,EAAE,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACxD,cAAc,EAAE,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC1D,kBAAkB,EAAE,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC/D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,OAAO,EACd,gBAAgB,GAAE,MAAM,OAAqB,GAC5C,SAAS,CAuKX;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,GAAG,IAAI,CAazF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAqDlF"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/web/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAgD,KAAK,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAU1G,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAElD,8EAA8E;AAC9E,UAAU,SAAS;IACjB,YAAY,EAAE,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,IAAI,CAAC;IACnE,YAAY,EAAE,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACxD,cAAc,EAAE,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC1D,kBAAkB,EAAE,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CAC/D;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,CAoKtF;AAKD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,GAAG,IAAI,CAazF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAqDlF"}
@@ -18,16 +18,12 @@ export const AUTH_COOKIE_NAME = 'codeman_session';
18
18
  * Register HTTP Basic Auth middleware with session cookies and rate limiting.
19
19
  * Only active when CODEMAN_PASSWORD is set.
20
20
  *
21
- * @param getTunnelRunning - returns true while a managed tunnel is active. Used
22
- * to gate the `/api/hook-event` localhost bypass: when a tunnel is up, tunneled
23
- * internet traffic reaches the loopback origin with `req.ip === 127.0.0.1`, so
24
- * the bypass additionally requires the shared hook secret (COD-54). When no
25
- * tunnel is running (loopback-only, the normal case) the plain localhost bypass
26
- * is kept so already-deployed (pre-secret) hooks + the loop channel keep working.
27
- * Optional; defaults to "no tunnel" (unchanged behavior) when omitted.
21
+ * The `/api/hook-event` + `/api/status-telemetry` localhost bypass requires the
22
+ * shared hook secret unconditionally (COD-91) see the onRequest hook below.
23
+ *
28
24
  * @returns AuthState for lifecycle management (dispose on server stop)
29
25
  */
30
- export function registerAuthMiddleware(app, https, getTunnelRunning = () => false) {
26
+ export function registerAuthMiddleware(app, https) {
31
27
  const state = {
32
28
  authSessions: null,
33
29
  authFailures: null,
@@ -73,36 +69,33 @@ export function registerAuthMiddleware(app, https, getTunnelRunning = () => fals
73
69
  reply.code(429).send('Too Many Requests — try again later');
74
70
  }
75
71
  app.addHook('onRequest', (req, reply, done) => {
76
- // Hook events come from local Claude Code hooks (curl from localhost) — no
77
- // Basic-Auth credentials available. Validated downstream by HookEventSchema.
72
+ // Hook events + statusline telemetry come from local Claude Code (curl from
73
+ // localhost) — no Basic-Auth credentials available. Validated downstream by
74
+ // HookEventSchema / StatusTelemetrySchema. Same loopback+hook-secret gate.
78
75
  //
79
76
  // COD-54: the bare localhost bypass is unsafe while a tunnel is running, because
80
77
  // `cloudflared --url http://127.0.0.1:port` proxies internet traffic INTO the
81
78
  // loopback origin, so a tunneled request arrives with req.ip === 127.0.0.1 and
82
- // would pass. So:
83
- // - tunnel running bypass requires the shared hook secret (local hooks present
84
- // it via the X-Codeman-Hook-Secret header; internet traffic can't know it),
85
- // - tunnel not running (loopback-only, the normal case) keep the plain
86
- // localhost bypass so already-deployed (pre-secret) hooks + the loop's own
87
- // credential-less hook channel keep working.
88
- if (req.url === '/api/hook-event' && req.method === 'POST') {
79
+ // would pass. COD-91: require the shared hook secret on the loopback bypass
80
+ // UNCONDITIONALLY (not just while the managed tunnel is up). Codeman can't detect
81
+ // a user's own loopback reverse proxy (their own `cloudflared --url`, `tailscale
82
+ // serve`, nginx 127.0.0.1), so tunnel-gating left that path with the unsafe plain
83
+ // bypass. Managed-session hooks always present the secret (X-Codeman-Hook-Secret,
84
+ // from $CODEMAN_HOOK_SECRET_FILE generated for every instance), so requiring it
85
+ // always closes the gap without breaking the legitimate hook channel.
86
+ if ((req.url === '/api/hook-event' || req.url === '/api/status-telemetry') && req.method === 'POST') {
89
87
  const ip = req.ip;
90
88
  const isLoopback = ip === '127.0.0.1' || ip === '::1' || ip === '::ffff:127.0.0.1';
91
89
  if (isLoopback) {
92
- if (!getTunnelRunning()) {
93
- // Loopback-only: unchanged behavior.
94
- done();
95
- return;
96
- }
97
- // Tunnel up: require the shared secret (constant-time compare).
90
+ // Always require the shared secret (constant-time compare).
98
91
  const presented = Buffer.from(req.headers[HOOK_SECRET_HEADER.toLowerCase()]?.toString() ?? '');
99
92
  const expected = Buffer.from(getHookSecret());
100
93
  if (presented.length === expected.length && timingSafeEqual(presented, expected)) {
101
94
  done();
102
95
  return;
103
96
  }
104
- // Wrong/absent secret while tunneled — rate-limit per IP in the DEDICATED
105
- // hook bucket (never authFailures, which would lock out the login path).
97
+ // Wrong/absent secret — rate-limit per IP in the DEDICATED hook bucket
98
+ // (never authFailures, which would lock out the login path).
106
99
  const hookIp = req.ip;
107
100
  const hookFailures = hookSecretFailures.get(hookIp) ?? 0;
108
101
  if (hookFailures >= AUTH_FAILURE_MAX) {
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/web/middleware/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/web/middleware/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @fileoverview Process-wide last-known plan-usage telemetry (account-global).
3
+ *
4
+ * The status-telemetry route writes the latest broadcast value here; the SSE
5
+ * init snapshot (`getLightState`) replays it so the header "Plan Usage Limits"
6
+ * chip shows immediately on a fresh page load / SSE reconnect — before any new
7
+ * statusline render arrives, and without relying on per-browser localStorage.
8
+ *
9
+ * Null until the first telemetry of the process; cleared naturally on restart.
10
+ *
11
+ * @module plan-usage-latest
12
+ */
13
+ export declare function setLatestPlanUsage(value: Record<string, unknown>): void;
14
+ export declare function getLatestPlanUsage(): Record<string, unknown> | null;
15
+ //# sourceMappingURL=plan-usage-latest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-usage-latest.d.ts","sourceRoot":"","sources":["../../src/web/plan-usage-latest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvE;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEnE"}