@botiverse/oar 0.0.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 (183) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +13 -0
  3. package/dist/contracts/account-usage.d.ts +33 -0
  4. package/dist/contracts/account-usage.d.ts.map +1 -0
  5. package/dist/contracts/account-usage.js +2 -0
  6. package/dist/contracts/account-usage.js.map +1 -0
  7. package/dist/contracts/installation.d.ts +27 -0
  8. package/dist/contracts/installation.d.ts.map +1 -0
  9. package/dist/contracts/installation.js +2 -0
  10. package/dist/contracts/installation.js.map +1 -0
  11. package/dist/contracts/runtime.d.ts +12 -0
  12. package/dist/contracts/runtime.d.ts.map +1 -0
  13. package/dist/contracts/runtime.js +4 -0
  14. package/dist/contracts/runtime.js.map +1 -0
  15. package/dist/contracts/session.d.ts +188 -0
  16. package/dist/contracts/session.d.ts.map +1 -0
  17. package/dist/contracts/session.js +2 -0
  18. package/dist/contracts/session.js.map +1 -0
  19. package/dist/index.d.ts +28 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +23 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/installation.d.ts +15 -0
  24. package/dist/installation.d.ts.map +1 -0
  25. package/dist/installation.js +60 -0
  26. package/dist/installation.js.map +1 -0
  27. package/dist/observe/agent-status.d.ts +39 -0
  28. package/dist/observe/agent-status.d.ts.map +1 -0
  29. package/dist/observe/agent-status.js +31 -0
  30. package/dist/observe/agent-status.js.map +1 -0
  31. package/dist/observe/aggregate-events.d.ts +15 -0
  32. package/dist/observe/aggregate-events.d.ts.map +1 -0
  33. package/dist/observe/aggregate-events.js +70 -0
  34. package/dist/observe/aggregate-events.js.map +1 -0
  35. package/dist/observe/index.d.ts +17 -0
  36. package/dist/observe/index.d.ts.map +1 -0
  37. package/dist/observe/index.js +13 -0
  38. package/dist/observe/index.js.map +1 -0
  39. package/dist/observe/observe-agent.d.ts +38 -0
  40. package/dist/observe/observe-agent.d.ts.map +1 -0
  41. package/dist/observe/observe-agent.js +61 -0
  42. package/dist/observe/observe-agent.js.map +1 -0
  43. package/dist/observe/stall-observer.d.ts +19 -0
  44. package/dist/observe/stall-observer.d.ts.map +1 -0
  45. package/dist/observe/stall-observer.js +36 -0
  46. package/dist/observe/stall-observer.js.map +1 -0
  47. package/dist/observe/tool-activity.d.ts +21 -0
  48. package/dist/observe/tool-activity.d.ts.map +1 -0
  49. package/dist/observe/tool-activity.js +87 -0
  50. package/dist/observe/tool-activity.js.map +1 -0
  51. package/dist/registry.d.ts +10 -0
  52. package/dist/registry.d.ts.map +1 -0
  53. package/dist/registry.js +30 -0
  54. package/dist/registry.js.map +1 -0
  55. package/dist/runtimes/claude/account-usage.d.ts +29 -0
  56. package/dist/runtimes/claude/account-usage.d.ts.map +1 -0
  57. package/dist/runtimes/claude/account-usage.js +179 -0
  58. package/dist/runtimes/claude/account-usage.js.map +1 -0
  59. package/dist/runtimes/claude/context-usage.d.ts +10 -0
  60. package/dist/runtimes/claude/context-usage.d.ts.map +1 -0
  61. package/dist/runtimes/claude/context-usage.js +23 -0
  62. package/dist/runtimes/claude/context-usage.js.map +1 -0
  63. package/dist/runtimes/claude/index.d.ts +9 -0
  64. package/dist/runtimes/claude/index.d.ts.map +1 -0
  65. package/dist/runtimes/claude/index.js +13 -0
  66. package/dist/runtimes/claude/index.js.map +1 -0
  67. package/dist/runtimes/claude/installation.d.ts +2 -0
  68. package/dist/runtimes/claude/installation.d.ts.map +1 -0
  69. package/dist/runtimes/claude/installation.js +3 -0
  70. package/dist/runtimes/claude/installation.js.map +1 -0
  71. package/dist/runtimes/claude/projection.d.ts +46 -0
  72. package/dist/runtimes/claude/projection.d.ts.map +1 -0
  73. package/dist/runtimes/claude/projection.js +110 -0
  74. package/dist/runtimes/claude/projection.js.map +1 -0
  75. package/dist/runtimes/claude/session.d.ts +3 -0
  76. package/dist/runtimes/claude/session.d.ts.map +1 -0
  77. package/dist/runtimes/claude/session.js +166 -0
  78. package/dist/runtimes/claude/session.js.map +1 -0
  79. package/dist/runtimes/codex/account-usage.d.ts +40 -0
  80. package/dist/runtimes/codex/account-usage.d.ts.map +1 -0
  81. package/dist/runtimes/codex/account-usage.js +185 -0
  82. package/dist/runtimes/codex/account-usage.js.map +1 -0
  83. package/dist/runtimes/codex/app-server-client.d.ts +17 -0
  84. package/dist/runtimes/codex/app-server-client.d.ts.map +1 -0
  85. package/dist/runtimes/codex/app-server-client.js +68 -0
  86. package/dist/runtimes/codex/app-server-client.js.map +1 -0
  87. package/dist/runtimes/codex/context-usage.d.ts +10 -0
  88. package/dist/runtimes/codex/context-usage.d.ts.map +1 -0
  89. package/dist/runtimes/codex/context-usage.js +16 -0
  90. package/dist/runtimes/codex/context-usage.js.map +1 -0
  91. package/dist/runtimes/codex/index.d.ts +9 -0
  92. package/dist/runtimes/codex/index.d.ts.map +1 -0
  93. package/dist/runtimes/codex/index.js +13 -0
  94. package/dist/runtimes/codex/index.js.map +1 -0
  95. package/dist/runtimes/codex/installation.d.ts +2 -0
  96. package/dist/runtimes/codex/installation.d.ts.map +1 -0
  97. package/dist/runtimes/codex/installation.js +17 -0
  98. package/dist/runtimes/codex/installation.js.map +1 -0
  99. package/dist/runtimes/codex/item-detail.d.ts +4 -0
  100. package/dist/runtimes/codex/item-detail.d.ts.map +1 -0
  101. package/dist/runtimes/codex/item-detail.js +47 -0
  102. package/dist/runtimes/codex/item-detail.js.map +1 -0
  103. package/dist/runtimes/codex/projection.d.ts +28 -0
  104. package/dist/runtimes/codex/projection.d.ts.map +1 -0
  105. package/dist/runtimes/codex/projection.js +98 -0
  106. package/dist/runtimes/codex/projection.js.map +1 -0
  107. package/dist/runtimes/codex/reasoning.d.ts +4 -0
  108. package/dist/runtimes/codex/reasoning.d.ts.map +1 -0
  109. package/dist/runtimes/codex/reasoning.js +23 -0
  110. package/dist/runtimes/codex/reasoning.js.map +1 -0
  111. package/dist/runtimes/codex/session.d.ts +3 -0
  112. package/dist/runtimes/codex/session.d.ts.map +1 -0
  113. package/dist/runtimes/codex/session.js +199 -0
  114. package/dist/runtimes/codex/session.js.map +1 -0
  115. package/dist/runtimes/pi/index.d.ts +12 -0
  116. package/dist/runtimes/pi/index.d.ts.map +1 -0
  117. package/dist/runtimes/pi/index.js +15 -0
  118. package/dist/runtimes/pi/index.js.map +1 -0
  119. package/dist/runtimes/pi/installation.d.ts +10 -0
  120. package/dist/runtimes/pi/installation.d.ts.map +1 -0
  121. package/dist/runtimes/pi/installation.js +33 -0
  122. package/dist/runtimes/pi/installation.js.map +1 -0
  123. package/dist/runtimes/pi/projection.d.ts +39 -0
  124. package/dist/runtimes/pi/projection.d.ts.map +1 -0
  125. package/dist/runtimes/pi/projection.js +112 -0
  126. package/dist/runtimes/pi/projection.js.map +1 -0
  127. package/dist/runtimes/pi/session.d.ts +11 -0
  128. package/dist/runtimes/pi/session.d.ts.map +1 -0
  129. package/dist/runtimes/pi/session.js +201 -0
  130. package/dist/runtimes/pi/session.js.map +1 -0
  131. package/dist/runtimes/pi/tool-detail.d.ts +4 -0
  132. package/dist/runtimes/pi/tool-detail.d.ts.map +1 -0
  133. package/dist/runtimes/pi/tool-detail.js +14 -0
  134. package/dist/runtimes/pi/tool-detail.js.map +1 -0
  135. package/dist/shared/diagnostic-text.d.ts +2 -0
  136. package/dist/shared/diagnostic-text.d.ts.map +1 -0
  137. package/dist/shared/diagnostic-text.js +15 -0
  138. package/dist/shared/diagnostic-text.js.map +1 -0
  139. package/dist/shared/executable/index.d.ts +8 -0
  140. package/dist/shared/executable/index.d.ts.map +1 -0
  141. package/dist/shared/executable/index.js +5 -0
  142. package/dist/shared/executable/index.js.map +1 -0
  143. package/dist/shared/executable/process.d.ts +27 -0
  144. package/dist/shared/executable/process.d.ts.map +1 -0
  145. package/dist/shared/executable/process.js +77 -0
  146. package/dist/shared/executable/process.js.map +1 -0
  147. package/dist/shared/executable/resolve.d.ts +16 -0
  148. package/dist/shared/executable/resolve.d.ts.map +1 -0
  149. package/dist/shared/executable/resolve.js +63 -0
  150. package/dist/shared/executable/resolve.js.map +1 -0
  151. package/dist/shared/executable/run.d.ts +13 -0
  152. package/dist/shared/executable/run.d.ts.map +1 -0
  153. package/dist/shared/executable/run.js +26 -0
  154. package/dist/shared/executable/run.js.map +1 -0
  155. package/dist/shared/executable/version.d.ts +6 -0
  156. package/dist/shared/executable/version.d.ts.map +1 -0
  157. package/dist/shared/executable/version.js +17 -0
  158. package/dist/shared/executable/version.js.map +1 -0
  159. package/dist/shared/failure-class.d.ts +8 -0
  160. package/dist/shared/failure-class.d.ts.map +1 -0
  161. package/dist/shared/failure-class.js +24 -0
  162. package/dist/shared/failure-class.js.map +1 -0
  163. package/dist/shared/installation.d.ts +9 -0
  164. package/dist/shared/installation.d.ts.map +1 -0
  165. package/dist/shared/installation.js +53 -0
  166. package/dist/shared/installation.js.map +1 -0
  167. package/dist/shared/instant.d.ts +4 -0
  168. package/dist/shared/instant.d.ts.map +1 -0
  169. package/dist/shared/instant.js +4 -0
  170. package/dist/shared/instant.js.map +1 -0
  171. package/dist/shared/json.d.ts +10 -0
  172. package/dist/shared/json.d.ts.map +1 -0
  173. package/dist/shared/json.js +29 -0
  174. package/dist/shared/json.js.map +1 -0
  175. package/dist/shared/seal-session.d.ts +8 -0
  176. package/dist/shared/seal-session.d.ts.map +1 -0
  177. package/dist/shared/seal-session.js +24 -0
  178. package/dist/shared/seal-session.js.map +1 -0
  179. package/dist/shared/session-kernel.d.ts +25 -0
  180. package/dist/shared/session-kernel.d.ts.map +1 -0
  181. package/dist/shared/session-kernel.js +64 -0
  182. package/dist/shared/session-kernel.js.map +1 -0
  183. package/package.json +47 -0
@@ -0,0 +1,29 @@
1
+ import type { AccountUsageReader, AccountUsageSnapshot } from "../../contracts/account-usage.js";
2
+ export declare function projectClaudeUsage(content: string, referenceInstant?: Date): AccountUsageSnapshot;
3
+ /**
4
+ * `claude -p /usage --output-format json` has two observed shapes.
5
+ * Without login, `result` is only an invocation summary:
6
+ *
7
+ * ```json
8
+ * {
9
+ * "type": "result",
10
+ * "total_cost_usd": 0,
11
+ * "usage": { "input_tokens": 0, "output_tokens": 0 },
12
+ * "result": "Total cost: $0.0000\nUsage: 0 input, 0 output, 0 cache read, 0 cache write"
13
+ * }
14
+ * ```
15
+ *
16
+ * With a subscription login, `result` contains account usage windows:
17
+ *
18
+ * ```json
19
+ * {
20
+ * "type": "result",
21
+ * "result": "You are currently using your subscription to power your Claude Code usage\n\nCurrent session: 7% used · resets Aug 21 at 7:39pm (Asia/Shanghai)\nCurrent week (all models): 0% used · resets Aug 28 at 2:59pm (Asia/Shanghai)\nCurrent week (Fable): 0% used"
22
+ * }
23
+ * ```
24
+ *
25
+ * Reset text has no year, so it is interpreted as the next occurrence in its
26
+ * named IANA time zone relative to when the command result is projected.
27
+ */
28
+ export declare const claudeAccountUsage: AccountUsageReader;
29
+ //# sourceMappingURL=account-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-usage.d.ts","sourceRoot":"","sources":["../../../src/runtimes/claude/account-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EAGrB,MAAM,kCAAkC,CAAC;AAgG1C,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,IAAiB,GAClC,oBAAoB,CA6BtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAyChC,CAAC"}
@@ -0,0 +1,179 @@
1
+ import { runExecutable } from "../../shared/executable/index.js";
2
+ import { utcInstantFromDate } from "../../shared/instant.js";
3
+ import { asRecord, parseJson } from "../../shared/json.js";
4
+ const MONTHS = new Map([
5
+ ["Jan", 0], ["Feb", 1], ["Mar", 2], ["Apr", 3], ["May", 4], ["Jun", 5],
6
+ ["Jul", 6], ["Aug", 7], ["Sep", 8], ["Oct", 9], ["Nov", 10], ["Dec", 11],
7
+ ]);
8
+ function zonedParts(instant, timeZone) {
9
+ try {
10
+ const parts = new Intl.DateTimeFormat("en-CA", {
11
+ timeZone,
12
+ calendar: "gregory",
13
+ numberingSystem: "latn",
14
+ year: "numeric",
15
+ month: "2-digit",
16
+ day: "2-digit",
17
+ hour: "2-digit",
18
+ minute: "2-digit",
19
+ hourCycle: "h23",
20
+ }).formatToParts(instant);
21
+ const values = Object.fromEntries(parts.map((part) => [part.type, part.value]));
22
+ const result = {
23
+ year: Number(values.year),
24
+ month: Number(values.month) - 1,
25
+ day: Number(values.day),
26
+ hour: Number(values.hour),
27
+ minute: Number(values.minute),
28
+ };
29
+ return Object.values(result).every((value) => Number.isFinite(value)) ? result : null;
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ function localInstant(value, timeZone) {
36
+ const target = Date.UTC(value.year, value.month, value.day, value.hour, value.minute);
37
+ let instant = target;
38
+ for (let attempt = 0; attempt < 4; attempt += 1) {
39
+ const observed = zonedParts(instant, timeZone);
40
+ if (observed === null) {
41
+ return null;
42
+ }
43
+ const correction = target
44
+ - Date.UTC(observed.year, observed.month, observed.day, observed.hour, observed.minute);
45
+ if (correction === 0) {
46
+ return instant;
47
+ }
48
+ instant += correction;
49
+ }
50
+ return null;
51
+ }
52
+ function resetInstant(resetText, referenceInstant) {
53
+ const match = /^(\w{3}) (\d{1,2}) at (\d{1,2}):(\d{2})(am|pm) \(([^)]+)\)$/u.exec(resetText);
54
+ const month = MONTHS.get(match?.[1] ?? "");
55
+ const day = Number(match?.[2]);
56
+ const twelveHour = Number(match?.[3]);
57
+ const minute = Number(match?.[4]);
58
+ const meridiem = match?.[5];
59
+ const timeZone = match?.[6];
60
+ if (month === undefined || timeZone === undefined || day < 1 || day > 31
61
+ || twelveHour < 1 || twelveHour > 12 || minute < 0 || minute > 59
62
+ || (meridiem !== "am" && meridiem !== "pm")) {
63
+ return null;
64
+ }
65
+ const reference = zonedParts(referenceInstant.getTime(), timeZone);
66
+ if (reference === null) {
67
+ return null;
68
+ }
69
+ const hour = twelveHour % 12 + (meridiem === "pm" ? 12 : 0);
70
+ const cutoff = referenceInstant.getTime() - 60_000;
71
+ for (const year of [reference.year, reference.year + 1]) {
72
+ const instant = localInstant({ year, month, day, hour, minute }, timeZone);
73
+ if (instant !== null && instant >= cutoff) {
74
+ return utcInstantFromDate(new Date(instant));
75
+ }
76
+ }
77
+ return null;
78
+ }
79
+ function resultText(stdout) {
80
+ const result = asRecord(parseJson(stdout))?.result;
81
+ return typeof result === "string" && result.trim().length > 0 ? result : null;
82
+ }
83
+ export function projectClaudeUsage(content, referenceInstant = new Date()) {
84
+ const windows = [];
85
+ for (const line of content.split(/\r?\n/u)) {
86
+ const match = /^(.+?): (\d+(?:\.\d+)?)% used(?: · resets (.+))?$/u.exec(line.trim());
87
+ const label = match?.[1];
88
+ const percentage = match?.[2];
89
+ if (label === undefined || percentage === undefined) {
90
+ continue;
91
+ }
92
+ const usedPercent = Number(percentage);
93
+ if (!Number.isFinite(usedPercent) || usedPercent < 0 || usedPercent > 100) {
94
+ continue;
95
+ }
96
+ const resetText = match?.[3];
97
+ const resetsAt = resetText === undefined ? null : resetInstant(resetText, referenceInstant);
98
+ windows.push({
99
+ label,
100
+ usedRatio: Number((usedPercent / 100).toFixed(6)),
101
+ ...(resetsAt === null ? {} : { resetsAt }),
102
+ });
103
+ }
104
+ if (windows.length === 0) {
105
+ throw new Error("Claude returned no usable account usage windows");
106
+ }
107
+ return {
108
+ kind: "available",
109
+ rateLimited: windows.some((window) => window.usedRatio >= 1),
110
+ windows,
111
+ };
112
+ }
113
+ /**
114
+ * `claude -p /usage --output-format json` has two observed shapes.
115
+ * Without login, `result` is only an invocation summary:
116
+ *
117
+ * ```json
118
+ * {
119
+ * "type": "result",
120
+ * "total_cost_usd": 0,
121
+ * "usage": { "input_tokens": 0, "output_tokens": 0 },
122
+ * "result": "Total cost: $0.0000\nUsage: 0 input, 0 output, 0 cache read, 0 cache write"
123
+ * }
124
+ * ```
125
+ *
126
+ * With a subscription login, `result` contains account usage windows:
127
+ *
128
+ * ```json
129
+ * {
130
+ * "type": "result",
131
+ * "result": "You are currently using your subscription to power your Claude Code usage\n\nCurrent session: 7% used · resets Aug 21 at 7:39pm (Asia/Shanghai)\nCurrent week (all models): 0% used · resets Aug 28 at 2:59pm (Asia/Shanghai)\nCurrent week (Fable): 0% used"
132
+ * }
133
+ * ```
134
+ *
135
+ * Reset text has no year, so it is interpreted as the next occurrence in its
136
+ * named IANA time zone relative to when the command result is projected.
137
+ */
138
+ export const claudeAccountUsage = async (installation, options = {}) => {
139
+ if (installation.via !== "executable") {
140
+ return { kind: "unsupported" };
141
+ }
142
+ const command = installation.command;
143
+ const timeoutMs = options.timeoutMs ?? 15_000;
144
+ const env = { ...process.env, CLAUDECODE: undefined };
145
+ const auth = await runExecutable(command, ["auth", "status", "--json"], { env, timeoutMs });
146
+ if (!auth.ok && auth.exitCode === null) {
147
+ throw new Error("Failed to read Claude authentication status");
148
+ }
149
+ const authStatus = asRecord(parseJson(auth.stdout));
150
+ if (!auth.ok || authStatus?.loggedIn === false) {
151
+ return { kind: "reauth_required" };
152
+ }
153
+ if (typeof authStatus?.apiKeySource === "string") {
154
+ // An API key takes precedence over any claude.ai login, and API-key
155
+ // billing has no subscription usage windows — /usage would return only a
156
+ // cost report (pinned by the claude vendor usage test).
157
+ return { kind: "unsupported" };
158
+ }
159
+ const usage = await runExecutable(command, ["-p", "/usage", "--output-format", "json"], {
160
+ env,
161
+ timeoutMs,
162
+ });
163
+ if (!usage.ok && usage.exitCode === null) {
164
+ throw new Error("Failed to execute Claude account usage");
165
+ }
166
+ if (!usage.ok) {
167
+ const output = `${usage.stdout}\n${usage.stderr}`;
168
+ if (/auth(?:entication)?\s*(?:missing|required)|log(?:ged)?\s*in/iu.test(output)) {
169
+ return { kind: "reauth_required" };
170
+ }
171
+ throw new Error("Claude account usage command failed");
172
+ }
173
+ const content = resultText(usage.stdout);
174
+ if (content === null) {
175
+ throw new Error("Claude returned no account usage result");
176
+ }
177
+ return projectClaudeUsage(content);
178
+ };
179
+ //# sourceMappingURL=account-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-usage.js","sourceRoot":"","sources":["../../../src/runtimes/claude/account-usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { ContextUsage } from "../../contracts/session.js";
2
+ import { type JsonRecord } from "../../shared/json.js";
3
+ /**
4
+ * Claude reports context usage in the result frame (structured — no need for
5
+ * the human-facing /context command): usage.{input,cache_read,cache_creation}
6
+ * tokens are the context sent, and modelUsage[model].contextWindow is the
7
+ * window. We cache the latest as the current snapshot (last-write-wins).
8
+ */
9
+ export declare function claudeContextUsageFromResult(message: JsonRecord): ContextUsage | null;
10
+ //# sourceMappingURL=context-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-usage.d.ts","sourceRoot":"","sources":["../../../src/runtimes/claude/context-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,UAAU,GAAG,YAAY,GAAG,IAAI,CAcrF"}
@@ -0,0 +1,23 @@
1
+ import { asNumber, asRecord } from "../../shared/json.js";
2
+ /**
3
+ * Claude reports context usage in the result frame (structured — no need for
4
+ * the human-facing /context command): usage.{input,cache_read,cache_creation}
5
+ * tokens are the context sent, and modelUsage[model].contextWindow is the
6
+ * window. We cache the latest as the current snapshot (last-write-wins).
7
+ */
8
+ export function claudeContextUsageFromResult(message) {
9
+ const usage = asRecord(message.usage);
10
+ if (usage === null) {
11
+ return null;
12
+ }
13
+ const input = asNumber(usage.input_tokens) ?? 0;
14
+ const cacheRead = asNumber(usage.cache_read_input_tokens) ?? 0;
15
+ const cacheCreate = asNumber(usage.cache_creation_input_tokens) ?? 0;
16
+ const tokens = input + cacheRead + cacheCreate;
17
+ const modelUsage = asRecord(message.modelUsage);
18
+ const firstModel = modelUsage === null ? null : asRecord(Object.values(modelUsage)[0]);
19
+ const contextWindow = firstModel === null ? null : asNumber(firstModel.contextWindow) ?? null;
20
+ const percent = contextWindow === null || contextWindow === 0 ? null : Math.round((tokens / contextWindow) * 100);
21
+ return { tokens, contextWindow, percent };
22
+ }
23
+ //# sourceMappingURL=context-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-usage.js","sourceRoot":"","sources":["../../../src/runtimes/claude/context-usage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,UAAU,4BAA4B,CAAC,OAAmB;IAC9D,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,CAAC;IAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF,MAAM,aAAa,GAAG,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC;IAC9F,MAAM,OAAO,GAAG,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;IAClH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare const claudeRuntime: {
2
+ readonly id: "claude";
3
+ readonly installation: import("../../index.js").InstallationProbe;
4
+ readonly accountUsage: import("../../index.js").AccountUsageReader;
5
+ readonly session: import("../../index.js").StartSession;
6
+ };
7
+ export { claudeAccountUsage } from "./account-usage.js";
8
+ export { claudeSession } from "./session.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/runtimes/claude/index.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa;;;;;CAKxB,CAAC;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { defineRuntime } from "../../contracts/runtime.js";
2
+ import { claudeAccountUsage } from "./account-usage.js";
3
+ import { claudeInstallation } from "./installation.js";
4
+ import { claudeSession } from "./session.js";
5
+ export const claudeRuntime = defineRuntime({
6
+ id: "claude",
7
+ installation: claudeInstallation,
8
+ accountUsage: claudeAccountUsage,
9
+ session: claudeSession,
10
+ });
11
+ export { claudeAccountUsage } from "./account-usage.js";
12
+ export { claudeSession } from "./session.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/runtimes/claude/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,EAAE,EAAE,QAAQ;IACZ,YAAY,EAAE,kBAAkB;IAChC,YAAY,EAAE,kBAAkB;IAChC,OAAO,EAAE,aAAa;CACvB,CAAC,CAAC;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const claudeInstallation: import("../../index.js").InstallationProbe;
2
+ //# sourceMappingURL=installation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installation.d.ts","sourceRoot":"","sources":["../../../src/runtimes/claude/installation.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,kBAAkB,4CAAqD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { executableInstallation } from "../../shared/installation.js";
2
+ export const claudeInstallation = executableInstallation("OAR_CLAUDE_BIN", "claude");
3
+ //# sourceMappingURL=installation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installation.js","sourceRoot":"","sources":["../../../src/runtimes/claude/installation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { SessionEventBody, TurnOutcome } from "../../contracts/session.js";
2
+ import { type JsonRecord } from "../../shared/json.js";
3
+ /**
4
+ * The claude stdout → SessionEvent projection as a PURE FOLD. It is the same
5
+ * family as observe/reduceStatus, one layer earlier: a reducer over the raw
6
+ * provider stream that emits kernel COMMANDS (begin a turn, emit an event,
7
+ * settle an outcome) instead of touching the kernel itself. The live adapter
8
+ * applies the commands to a real kernel; tests apply them to nothing and
9
+ * snapshot the list. No transport, no side effects — so it is trivially
10
+ * unit-testable and shared verbatim between live and replay.
11
+ *
12
+ * Not generic: each runtime speaks a different wire vocabulary, so each has
13
+ * its own fold. What IS shared is the OUTPUT — SessionEventBody and this
14
+ * command algebra.
15
+ */
16
+ export type ProjectionCommand = {
17
+ readonly kind: "begin";
18
+ } | {
19
+ readonly kind: "emit";
20
+ readonly body: SessionEventBody;
21
+ } | {
22
+ readonly kind: "settle";
23
+ readonly outcome: TurnOutcome;
24
+ };
25
+ /**
26
+ * Fold state. `inTurn` is the projection's own view of turn framing (set true
27
+ * by the control plane on prompt, by the fold on a spontaneous init).
28
+ * `abortRequested` is the one input that is NOT in the provider stream — abort
29
+ * is a control-plane intent, and claude reports its result as an ordinary
30
+ * result frame, so the flag is how the fold tells aborted from completed. It
31
+ * makes explicit that projection folds over provider events ⊎ control intent.
32
+ */
33
+ export interface ClaudeProjectionState {
34
+ readonly inTurn: boolean;
35
+ readonly abortRequested: boolean;
36
+ }
37
+ export declare const initialClaudeProjection: ClaudeProjectionState;
38
+ /** Control plane → state: a prompt opens a turn; an abort arms the flag. */
39
+ export declare function claudePrompted(): ClaudeProjectionState;
40
+ export declare function claudeAbortRequested(state: ClaudeProjectionState): ClaudeProjectionState;
41
+ /** Fold one parsed claude stdout frame into the next state plus commands. */
42
+ export declare function foldClaudeStdout(state: ClaudeProjectionState, message: JsonRecord): {
43
+ readonly state: ClaudeProjectionState;
44
+ readonly commands: readonly ProjectionCommand[];
45
+ };
46
+ //# sourceMappingURL=projection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../../src/runtimes/claude/projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEhF,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEjE;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,iBAAiB,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1D;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAE/D;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAAgE,CAAC;AAEvG,4EAA4E;AAC5E,wBAAgB,cAAc,IAAI,qBAAqB,CAEtD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB,GAAG,qBAAqB,CAExF;AAiFD,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,qBAAqB,EAC5B,OAAO,EAAE,UAAU,GAClB;IAAE,QAAQ,CAAC,KAAK,EAAE,qBAAqB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAA;CAAE,CAsB5F"}
@@ -0,0 +1,110 @@
1
+ import { classifyFailure } from "../../shared/failure-class.js";
2
+ import { asRecord } from "../../shared/json.js";
3
+ export const initialClaudeProjection = { inTurn: false, abortRequested: false };
4
+ /** Control plane → state: a prompt opens a turn; an abort arms the flag. */
5
+ export function claudePrompted() {
6
+ return { inTurn: true, abortRequested: false };
7
+ }
8
+ export function claudeAbortRequested(state) {
9
+ return { ...state, abortRequested: true };
10
+ }
11
+ function contentBlocks(message) {
12
+ const inner = asRecord(message.message);
13
+ const content = inner?.content;
14
+ if (!Array.isArray(content)) {
15
+ return [];
16
+ }
17
+ return content.map((block) => asRecord(block)).filter((block) => block !== null);
18
+ }
19
+ function assistantEvents(message) {
20
+ const out = [];
21
+ for (const block of contentBlocks(message)) {
22
+ switch (String(block.type)) {
23
+ case "text": {
24
+ if (typeof block.text === "string") {
25
+ out.push({ kind: "text_delta", text: block.text });
26
+ }
27
+ break;
28
+ }
29
+ case "thinking": {
30
+ const content = typeof block.thinking === "string" && block.thinking.length > 0
31
+ ? { kind: "text", text: block.thinking }
32
+ : { kind: "empty" };
33
+ out.push({ kind: "reasoning", content });
34
+ break;
35
+ }
36
+ case "redacted_thinking": {
37
+ out.push({ kind: "reasoning", content: { kind: "redacted" } });
38
+ break;
39
+ }
40
+ case "tool_use": {
41
+ const started = {
42
+ kind: "tool_call_started",
43
+ callId: typeof block.id === "string" ? block.id : "unknown",
44
+ tool: typeof block.name === "string" ? block.name : "unknown",
45
+ };
46
+ const input = block.input === undefined ? undefined : JSON.stringify(block.input);
47
+ out.push(input === undefined ? started : { ...started, input });
48
+ break;
49
+ }
50
+ default:
51
+ break;
52
+ }
53
+ }
54
+ return out;
55
+ }
56
+ function toolResultEvents(message) {
57
+ const out = [];
58
+ for (const block of contentBlocks(message)) {
59
+ if (block.type === "tool_result" && typeof block.tool_use_id === "string") {
60
+ const output = block.content === undefined ? undefined : JSON.stringify(block.content);
61
+ out.push(output === undefined
62
+ ? { kind: "tool_call_ended", callId: block.tool_use_id }
63
+ : { kind: "tool_call_ended", callId: block.tool_use_id, output });
64
+ }
65
+ }
66
+ return out;
67
+ }
68
+ function resultOutcome(state, message) {
69
+ if (state.abortRequested) {
70
+ return { kind: "aborted" };
71
+ }
72
+ if (message.is_error === true) {
73
+ // Vendor quirk (pinned 2026-08-22): claude can report is_error=true with
74
+ // subtype "success" and put the actual error text in result.
75
+ const text = typeof message.result === "string" && message.result.length > 0
76
+ ? message.result
77
+ : undefined;
78
+ const subtype = typeof message.subtype === "string" && message.subtype !== "success"
79
+ ? message.subtype
80
+ : undefined;
81
+ const reason = text ?? subtype ?? "error";
82
+ return { kind: "failed", reason, failure: classifyFailure(reason) };
83
+ }
84
+ return { kind: "completed" };
85
+ }
86
+ /** Fold one parsed claude stdout frame into the next state plus commands. */
87
+ export function foldClaudeStdout(state, message) {
88
+ // A system/init with no active turn is claude starting a run on its own (a
89
+ // steer that landed past the turn's end) — a spontaneous turn.
90
+ if (message.type === "system" && message.subtype === "init" && !state.inTurn) {
91
+ return { state: { ...state, inTurn: true }, commands: [{ kind: "begin" }] };
92
+ }
93
+ if (!state.inTurn) {
94
+ return { state, commands: [] };
95
+ }
96
+ switch (String(message.type)) {
97
+ case "assistant":
98
+ return { state, commands: assistantEvents(message).map((body) => ({ kind: "emit", body })) };
99
+ case "user":
100
+ return { state, commands: toolResultEvents(message).map((body) => ({ kind: "emit", body })) };
101
+ case "result":
102
+ return {
103
+ state: { inTurn: false, abortRequested: false },
104
+ commands: [{ kind: "settle", outcome: resultOutcome(state, message) }],
105
+ };
106
+ default:
107
+ return { state, commands: [] };
108
+ }
109
+ }
110
+ //# sourceMappingURL=projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projection.js","sourceRoot":"","sources":["../../../src/runtimes/claude/projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { StartSession } from "../../contracts/session.js";
2
+ export declare const claudeSession: StartSession;
3
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/runtimes/claude/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,YAAY,EAEb,MAAM,4BAA4B,CAAC;AA0CpC,eAAO,MAAM,aAAa,EAAE,YA8I3B,CAAC"}