@ironbee-ai/cli 0.13.0 → 0.14.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 (112) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +9 -0
  3. package/dist/clients/claude/hooks/activity-start.d.ts.map +1 -1
  4. package/dist/clients/claude/hooks/activity-start.js +4 -0
  5. package/dist/clients/claude/hooks/activity-start.js.map +1 -1
  6. package/dist/clients/claude/hooks/session-start.d.ts.map +1 -1
  7. package/dist/clients/claude/hooks/session-start.js +4 -0
  8. package/dist/clients/claude/hooks/session-start.js.map +1 -1
  9. package/dist/clients/claude/hooks/session-status.d.ts +5 -0
  10. package/dist/clients/claude/hooks/session-status.d.ts.map +1 -1
  11. package/dist/clients/claude/hooks/session-status.js +120 -17
  12. package/dist/clients/claude/hooks/session-status.js.map +1 -1
  13. package/dist/clients/claude/index.d.ts +10 -0
  14. package/dist/clients/claude/index.d.ts.map +1 -1
  15. package/dist/clients/claude/index.js +105 -0
  16. package/dist/clients/claude/index.js.map +1 -1
  17. package/dist/clients/claude/oauth.d.ts +96 -0
  18. package/dist/clients/claude/oauth.d.ts.map +1 -0
  19. package/dist/clients/claude/oauth.js +290 -0
  20. package/dist/clients/claude/oauth.js.map +1 -0
  21. package/dist/commands/claude.d.ts +30 -0
  22. package/dist/commands/claude.d.ts.map +1 -0
  23. package/dist/commands/claude.js +188 -0
  24. package/dist/commands/claude.js.map +1 -0
  25. package/dist/commands/config.d.ts.map +1 -1
  26. package/dist/commands/config.js +1 -0
  27. package/dist/commands/config.js.map +1 -1
  28. package/dist/commands/otel.d.ts +20 -0
  29. package/dist/commands/otel.d.ts.map +1 -0
  30. package/dist/commands/otel.js +132 -0
  31. package/dist/commands/otel.js.map +1 -0
  32. package/dist/index.js +6 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/lib/config.d.ts +88 -0
  35. package/dist/lib/config.d.ts.map +1 -1
  36. package/dist/lib/config.js +98 -3
  37. package/dist/lib/config.js.map +1 -1
  38. package/dist/lib/event.d.ts +112 -0
  39. package/dist/lib/event.d.ts.map +1 -1
  40. package/dist/lib/event.js +1 -0
  41. package/dist/lib/event.js.map +1 -1
  42. package/dist/lib/gitignore.d.ts.map +1 -1
  43. package/dist/lib/gitignore.js +6 -0
  44. package/dist/lib/gitignore.js.map +1 -1
  45. package/dist/lib/version.d.ts +5 -0
  46. package/dist/lib/version.d.ts.map +1 -1
  47. package/dist/lib/version.js +5 -0
  48. package/dist/lib/version.js.map +1 -1
  49. package/dist/otel/collector.d.ts +66 -0
  50. package/dist/otel/collector.d.ts.map +1 -0
  51. package/dist/otel/collector.js +317 -0
  52. package/dist/otel/collector.js.map +1 -0
  53. package/dist/otel/context/build.d.ts +37 -0
  54. package/dist/otel/context/build.d.ts.map +1 -0
  55. package/dist/otel/context/build.js +103 -0
  56. package/dist/otel/context/build.js.map +1 -0
  57. package/dist/otel/context/classify.d.ts +40 -0
  58. package/dist/otel/context/classify.d.ts.map +1 -0
  59. package/dist/otel/context/classify.js +228 -0
  60. package/dist/otel/context/classify.js.map +1 -0
  61. package/dist/otel/context/extract.d.ts +39 -0
  62. package/dist/otel/context/extract.d.ts.map +1 -0
  63. package/dist/otel/context/extract.js +76 -0
  64. package/dist/otel/context/extract.js.map +1 -0
  65. package/dist/otel/context/markers.d.ts +37 -0
  66. package/dist/otel/context/markers.d.ts.map +1 -0
  67. package/dist/otel/context/markers.js +179 -0
  68. package/dist/otel/context/markers.js.map +1 -0
  69. package/dist/otel/context/util.d.ts +15 -0
  70. package/dist/otel/context/util.d.ts.map +1 -0
  71. package/dist/otel/context/util.js +33 -0
  72. package/dist/otel/context/util.js.map +1 -0
  73. package/dist/otel/daemon/ensure.d.ts +52 -0
  74. package/dist/otel/daemon/ensure.d.ts.map +1 -0
  75. package/dist/otel/daemon/ensure.js +226 -0
  76. package/dist/otel/daemon/ensure.js.map +1 -0
  77. package/dist/otel/daemon/forward.d.ts +47 -0
  78. package/dist/otel/daemon/forward.d.ts.map +1 -0
  79. package/dist/otel/daemon/forward.js +0 -0
  80. package/dist/otel/daemon/forward.js.map +1 -0
  81. package/dist/otel/daemon/paths.d.ts +24 -0
  82. package/dist/otel/daemon/paths.d.ts.map +1 -0
  83. package/dist/otel/daemon/paths.js +47 -0
  84. package/dist/otel/daemon/paths.js.map +1 -0
  85. package/dist/otel/daemon/process.d.ts +21 -0
  86. package/dist/otel/daemon/process.d.ts.map +1 -0
  87. package/dist/otel/daemon/process.js +149 -0
  88. package/dist/otel/daemon/process.js.map +1 -0
  89. package/dist/otel/daemon/reprocess.d.ts +27 -0
  90. package/dist/otel/daemon/reprocess.d.ts.map +1 -0
  91. package/dist/otel/daemon/reprocess.js +112 -0
  92. package/dist/otel/daemon/reprocess.js.map +1 -0
  93. package/dist/otel/log-handler.d.ts +37 -0
  94. package/dist/otel/log-handler.d.ts.map +1 -0
  95. package/dist/otel/log-handler.js +332 -0
  96. package/dist/otel/log-handler.js.map +1 -0
  97. package/dist/otel/metric-handler.d.ts +12 -0
  98. package/dist/otel/metric-handler.d.ts.map +1 -0
  99. package/dist/otel/metric-handler.js +18 -0
  100. package/dist/otel/metric-handler.js.map +1 -0
  101. package/dist/otel/trace-handler.d.ts +12 -0
  102. package/dist/otel/trace-handler.d.ts.map +1 -0
  103. package/dist/otel/trace-handler.js +18 -0
  104. package/dist/otel/trace-handler.js.map +1 -0
  105. package/dist/otel/types.d.ts +105 -0
  106. package/dist/otel/types.d.ts.map +1 -0
  107. package/dist/otel/types.js +15 -0
  108. package/dist/otel/types.js.map +1 -0
  109. package/dist/tui/config/schema.d.ts.map +1 -1
  110. package/dist/tui/config/schema.js +63 -0
  111. package/dist/tui/config/schema.js.map +1 -1
  112. package/package.json +2 -1
@@ -0,0 +1,52 @@
1
+ /**
2
+ * IronBee — OTEL collector daemon liveness `ensure` (+ version self-replace)
3
+ *
4
+ * `ensureOTELCollector` is the fire-and-forget helper hooks call to make sure a
5
+ * current daemon is running. It probes `/health`, then either uses the running
6
+ * daemon, spawns one, or replaces a stale-version one. It must never block the
7
+ * host hook's critical path and never throw.
8
+ *
9
+ * Singleton arbitration is the OS port bind (see `collector.ts`); this module
10
+ * only decides whether to *attempt* a spawn. The version-compare decision is
11
+ * isolated in {@link decideEnsureAction} for unit testing.
12
+ */
13
+ import { OTELHealth } from "../types";
14
+ /** Result of probing the daemon's `/health`. */
15
+ export type HealthProbe = {
16
+ kind: "ok";
17
+ health: OTELHealth;
18
+ } | {
19
+ kind: "unreachable";
20
+ } | {
21
+ kind: "foreign";
22
+ };
23
+ /** What `ensure` should do after probing. */
24
+ export type EnsureDecision = "disabled" | "use-existing" | "spawn" | "replace" | "foreign";
25
+ /**
26
+ * Pure decision: given whether the feature is enabled, the health probe, and
27
+ * our own CLI version, decide the action. Isolated for unit testing.
28
+ *
29
+ * - feature off → `disabled`
30
+ * - nothing on the port → `spawn`
31
+ * - a foreign listener → `foreign` (warn + stand down)
32
+ * - running version < mine → `replace` (newest build wins)
33
+ * - running version >= mine → `use-existing`
34
+ */
35
+ export declare function decideEnsureAction(opts: {
36
+ enabled: boolean;
37
+ probe: HealthProbe;
38
+ myVersion: string;
39
+ }): EnsureDecision;
40
+ /** GET `/health` and classify the response. Never throws / never rejects. */
41
+ export declare function fetchHealth(port: number, host?: string, timeoutMs?: number): Promise<HealthProbe>;
42
+ /** POST `/admin/shutdown` (best-effort; resolves regardless of outcome). */
43
+ export declare function requestShutdown(port: number, host?: string, timeoutMs?: number): Promise<void>;
44
+ /** POST `/admin/reprocess` (best-effort; resolves regardless of outcome). */
45
+ export declare function requestReprocess(port: number, host?: string, timeoutMs?: number): Promise<void>;
46
+ export declare function spawnDaemon(port: number): void;
47
+ /**
48
+ * Ensure a current OTEL collector daemon is running for this machine.
49
+ * Fire-and-forget, non-blocking, never throws — safe on a hook's hot path.
50
+ */
51
+ export declare function ensureOTELCollector(projectDir?: string): Promise<void>;
52
+ //# sourceMappingURL=ensure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure.d.ts","sourceRoot":"","sources":["../../../src/otel/daemon/ensure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,OAAO,EAAE,UAAU,EAAqB,MAAM,UAAU,CAAC;AAQzD,gDAAgD;AAChD,MAAM,MAAM,WAAW,GACjB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAE1B,6CAA6C;AAC7C,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAE3F;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACrB,GAAG,cAAc,CAWjB;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CACvB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAqB,EAC3B,SAAS,GAAE,MAAyB,GACrC,OAAO,CAAC,WAAW,CAAC,CAoCtB;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAqB,EAC3B,SAAS,GAAE,MAAyB,GACrC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,6EAA6E;AAC7E,wBAAgB,gBAAgB,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAqB,EAC3B,SAAS,GAAE,MAAyB,GACrC,OAAO,CAAC,IAAI,CAAC,CAoBf;AA2CD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAiB9C;AAMD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC5E"}
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ /**
3
+ * IronBee — OTEL collector daemon liveness `ensure` (+ version self-replace)
4
+ *
5
+ * `ensureOTELCollector` is the fire-and-forget helper hooks call to make sure a
6
+ * current daemon is running. It probes `/health`, then either uses the running
7
+ * daemon, spawns one, or replaces a stale-version one. It must never block the
8
+ * host hook's critical path and never throw.
9
+ *
10
+ * Singleton arbitration is the OS port bind (see `collector.ts`); this module
11
+ * only decides whether to *attempt* a spawn. The version-compare decision is
12
+ * isolated in {@link decideEnsureAction} for unit testing.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.decideEnsureAction = decideEnsureAction;
16
+ exports.fetchHealth = fetchHealth;
17
+ exports.requestShutdown = requestShutdown;
18
+ exports.requestReprocess = requestReprocess;
19
+ exports.spawnDaemon = spawnDaemon;
20
+ exports.ensureOTELCollector = ensureOTELCollector;
21
+ const http_1 = require("http");
22
+ const child_process_1 = require("child_process");
23
+ const fs_1 = require("fs");
24
+ const os_1 = require("os");
25
+ const path_1 = require("path");
26
+ const config_1 = require("../../lib/config");
27
+ const version_1 = require("../../lib/version");
28
+ const logger_1 = require("../../lib/logger");
29
+ const types_1 = require("../types");
30
+ const DEFAULT_HOST = "127.0.0.1";
31
+ /** Health-probe timeout — tiny so a hook never blocks on it. */
32
+ const PROBE_TIMEOUT_MS = 300;
33
+ /** Brief wait after a stale daemon's shutdown before spawning its replacement. */
34
+ const REPLACE_PORT_RELEASE_MS = 400;
35
+ /**
36
+ * Pure decision: given whether the feature is enabled, the health probe, and
37
+ * our own CLI version, decide the action. Isolated for unit testing.
38
+ *
39
+ * - feature off → `disabled`
40
+ * - nothing on the port → `spawn`
41
+ * - a foreign listener → `foreign` (warn + stand down)
42
+ * - running version < mine → `replace` (newest build wins)
43
+ * - running version >= mine → `use-existing`
44
+ */
45
+ function decideEnsureAction(opts) {
46
+ if (!opts.enabled) {
47
+ return "disabled";
48
+ }
49
+ if (opts.probe.kind === "unreachable") {
50
+ return "spawn";
51
+ }
52
+ if (opts.probe.kind === "foreign") {
53
+ return "foreign";
54
+ }
55
+ return (0, version_1.compareVersions)(opts.probe.health.version, opts.myVersion) < 0 ? "replace" : "use-existing";
56
+ }
57
+ /** GET `/health` and classify the response. Never throws / never rejects. */
58
+ function fetchHealth(port, host = DEFAULT_HOST, timeoutMs = PROBE_TIMEOUT_MS) {
59
+ return new Promise((resolve) => {
60
+ let settled = false;
61
+ const done = (p) => {
62
+ if (settled) {
63
+ return;
64
+ }
65
+ settled = true;
66
+ resolve(p);
67
+ };
68
+ const req = (0, http_1.request)({ host, port, path: "/health", method: "GET", timeout: timeoutMs }, (res) => {
69
+ let body = "";
70
+ res.setEncoding("utf-8");
71
+ res.on("data", (d) => { body += d; });
72
+ res.on("end", () => {
73
+ try {
74
+ const parsed = JSON.parse(body);
75
+ if (parsed !== null && typeof parsed === "object"
76
+ && parsed.service === types_1.OTEL_SERVICE_NAME
77
+ && typeof parsed.version === "string") {
78
+ done({ kind: "ok", health: parsed });
79
+ return;
80
+ }
81
+ }
82
+ catch {
83
+ // fall through — not our JSON shape
84
+ }
85
+ done({ kind: "foreign" });
86
+ });
87
+ });
88
+ req.on("error", () => { done({ kind: "unreachable" }); });
89
+ req.on("timeout", () => { req.destroy(); done({ kind: "unreachable" }); });
90
+ req.end();
91
+ });
92
+ }
93
+ /** POST `/admin/shutdown` (best-effort; resolves regardless of outcome). */
94
+ function requestShutdown(port, host = DEFAULT_HOST, timeoutMs = PROBE_TIMEOUT_MS) {
95
+ return new Promise((resolve) => {
96
+ let settled = false;
97
+ const done = () => {
98
+ if (!settled) {
99
+ settled = true;
100
+ resolve();
101
+ }
102
+ };
103
+ const req = (0, http_1.request)({ host, port, path: "/admin/shutdown", method: "POST", timeout: timeoutMs }, (res) => {
104
+ res.on("data", () => { });
105
+ res.on("end", done);
106
+ });
107
+ req.on("error", done);
108
+ req.on("timeout", () => { req.destroy(); done(); });
109
+ req.end();
110
+ });
111
+ }
112
+ /** POST `/admin/reprocess` (best-effort; resolves regardless of outcome). */
113
+ function requestReprocess(port, host = DEFAULT_HOST, timeoutMs = PROBE_TIMEOUT_MS) {
114
+ return new Promise((resolve) => {
115
+ let settled = false;
116
+ const done = () => {
117
+ if (!settled) {
118
+ settled = true;
119
+ resolve();
120
+ }
121
+ };
122
+ const req = (0, http_1.request)({ host, port, path: "/admin/reprocess", method: "POST", timeout: timeoutMs }, (res) => {
123
+ res.on("data", () => { });
124
+ res.on("end", done);
125
+ });
126
+ req.on("error", done);
127
+ req.on("timeout", () => { req.destroy(); done(); });
128
+ req.end();
129
+ });
130
+ }
131
+ /** Resolve how to re-invoke the CLI for a detached child (mirrors queue/spawn). */
132
+ function resolveInvocation() {
133
+ const override = process.env.IRONBEE_BIN;
134
+ if (override) {
135
+ return { command: override, args: [] };
136
+ }
137
+ const argv0 = process.argv[0];
138
+ const argv1 = process.argv[1] ?? "";
139
+ if (argv1.endsWith("index.js") || argv1.endsWith("index.ts")) {
140
+ return { command: argv0, args: [argv1] };
141
+ }
142
+ return { command: "ironbee", args: [] };
143
+ }
144
+ /** Spawn a detached `ironbee otel run --port <port>`. Returns immediately. */
145
+ /** Cap on the daemon log before a startup truncate (single-generation rotation). */
146
+ const DAEMON_LOG_MAX_BYTES = 5 * 1024 * 1024;
147
+ /**
148
+ * Open `~/.ironbee/otel/daemon.log` for the detached daemon's stdout/stderr, so
149
+ * the otherwise-invisible daemon (forward results, collector rejections, errors)
150
+ * is observable. Truncates past {@link DAEMON_LOG_MAX_BYTES}. Returns `"ignore"`
151
+ * (discard) when the log can't be opened — never blocks the spawn.
152
+ */
153
+ function openDaemonLogTarget() {
154
+ try {
155
+ const dir = (0, path_1.join)((0, os_1.homedir)(), ".ironbee", "otel");
156
+ (0, fs_1.mkdirSync)(dir, { recursive: true });
157
+ const logPath = (0, path_1.join)(dir, "daemon.log");
158
+ let truncate = false;
159
+ try {
160
+ truncate = (0, fs_1.statSync)(logPath).size > DAEMON_LOG_MAX_BYTES;
161
+ }
162
+ catch {
163
+ // no existing log — append-open creates it
164
+ }
165
+ return (0, fs_1.openSync)(logPath, truncate ? "w" : "a");
166
+ }
167
+ catch {
168
+ return "ignore";
169
+ }
170
+ }
171
+ function spawnDaemon(port) {
172
+ const inv = resolveInvocation();
173
+ const logTarget = openDaemonLogTarget();
174
+ const child = (0, child_process_1.spawn)(inv.command, [...inv.args, "otel", "run", "--port", String(port)], { detached: true, stdio: ["ignore", logTarget, logTarget], env: process.env });
175
+ child.unref();
176
+ if (typeof logTarget === "number") {
177
+ // The child holds its own dup'd fd; release the parent's copy.
178
+ try {
179
+ (0, fs_1.closeSync)(logTarget);
180
+ }
181
+ catch {
182
+ // already closed / race — fine
183
+ }
184
+ }
185
+ }
186
+ function delay(ms) {
187
+ return new Promise((resolve) => { setTimeout(resolve, ms); });
188
+ }
189
+ /**
190
+ * Ensure a current OTEL collector daemon is running for this machine.
191
+ * Fire-and-forget, non-blocking, never throws — safe on a hook's hot path.
192
+ */
193
+ async function ensureOTELCollector(projectDir) {
194
+ try {
195
+ const config = (0, config_1.loadConfig)(projectDir);
196
+ if (!(0, config_1.isOTELEnabled)(config)) {
197
+ return; // disabled short-circuit — no probe, no spawn
198
+ }
199
+ const port = (0, config_1.getOTELPort)(config);
200
+ const probe = await fetchHealth(port);
201
+ const decision = decideEnsureAction({
202
+ enabled: true,
203
+ probe,
204
+ myVersion: (0, version_1.getLocalVersion)(),
205
+ });
206
+ switch (decision) {
207
+ case "spawn":
208
+ spawnDaemon(port);
209
+ break;
210
+ case "replace":
211
+ await requestShutdown(port);
212
+ await delay(REPLACE_PORT_RELEASE_MS);
213
+ spawnDaemon(port);
214
+ break;
215
+ case "foreign":
216
+ logger_1.logger.warn(`otel: a non-ironbee service is listening on ${DEFAULT_HOST}:${port}; OTEL collector not started`);
217
+ break;
218
+ default:
219
+ break; // use-existing / disabled → nothing
220
+ }
221
+ }
222
+ catch (e) {
223
+ logger_1.logger.debug(`otel: ensureOTELCollector failed: ${e instanceof Error ? e.message : String(e)}`);
224
+ }
225
+ }
226
+ //# sourceMappingURL=ensure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ensure.js","sourceRoot":"","sources":["../../../src/otel/daemon/ensure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * IronBee — OTEL forward pipeline.
3
+ *
4
+ * Turns submitted body files into `session_context` events and ships them to
5
+ * the IronBee Collector, grouped per **collector target** (events for different
6
+ * projects/targets can't share a POST). Delivery is **delete-after-confirm**:
7
+ * a request file is unlinked only on a 2xx (or a permanent 4xx); a transient
8
+ * failure keeps it for catch-up retry. Spec: `docs/otel-session-context.md`
9
+ * §7.1 / §9.
10
+ */
11
+ import { OTELHealthCounters } from "../types";
12
+ import { ApiRequestBodyMeta } from "../context/extract";
13
+ export declare class ForwardPipeline {
14
+ private pending;
15
+ private failed;
16
+ private dropped;
17
+ private reprocessing;
18
+ private flushTimer;
19
+ private readonly buffers;
20
+ /** Per-session last-admitted epoch ms — drives the `emitMinIntervalSeconds` throttle. */
21
+ private readonly lastEmitMs;
22
+ private readonly flushMs;
23
+ constructor(flushMs?: number);
24
+ /** Observability counters for `/health`. */
25
+ counters(): OTELHealthCounters;
26
+ /** Submit a body file for async processing + forwarding (fire-and-forget). */
27
+ submit(meta: ApiRequestBodyMeta): void;
28
+ private process;
29
+ /**
30
+ * Leading-edge per-session throttle for `otel.emitMinIntervalSeconds`.
31
+ * Returns `true` when this request should be coalesced away (dropped). The
32
+ * interval is read live per project (config can change between requests);
33
+ * `0` (the default) disables the throttle entirely.
34
+ */
35
+ private shouldThrottle;
36
+ private scheduleFlush;
37
+ /**
38
+ * Flush every per-target buffer. All-or-nothing per batch:
39
+ * - 2xx → unlink all contributing request files (delivered)
40
+ * - permanent 4xx → unlink (retry won't help) + log
41
+ * - 429 / 5xx / net → keep the files (catch-up / `otel retry` re-sends)
42
+ */
43
+ flushAll(): Promise<void>;
44
+ /** Re-scan registry otel dirs and resubmit orphans. Non-reentrant. */
45
+ reprocess(): void;
46
+ }
47
+ //# sourceMappingURL=forward.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forward.d.ts","sourceRoot":"","sources":["../../../src/otel/daemon/forward.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAkCxD,qBAAa,eAAe;IACxB,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,yFAAyF;IACzF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAC7D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,GAAE,MAAyB;IAI9C,4CAA4C;IAC5C,QAAQ,IAAI,kBAAkB;IAS9B,8EAA8E;IAC9E,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI;YAWxB,OAAO;IA8BrB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAiBtB,OAAO,CAAC,aAAa;IAWrB;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC/B,sEAAsE;IACtE,SAAS,IAAI,IAAI;CAapB"}
Binary file
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forward.js","sourceRoot":"","sources":["../../../src/otel/daemon/forward.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * IronBee — OTEL body-ref path helpers (pure, path-aware, cross-platform).
3
+ *
4
+ * A raw body file lives at `<project_dir>/.ironbee/otel/<uuid>.request.json`.
5
+ * The daemon derives the project dir from that path (no registry walk), and the
6
+ * same check is the security gate: the daemon only reads / unlinks files that
7
+ * actually sit inside a `.ironbee/otel` directory (a loopback POST must not make
8
+ * it touch arbitrary paths).
9
+ */
10
+ /**
11
+ * Derive `<project_dir>` from a `body_ref` of the shape
12
+ * `<project_dir>/.ironbee/otel/<file>`. Returns `null` when the path is not
13
+ * inside a `.ironbee/otel` directory — which doubles as the security gate
14
+ * (reject anything outside). Path-aware: never splits on a hardcoded `/`.
15
+ */
16
+ export declare function projectDirFromBodyRef(bodyRef: string): string | null;
17
+ /** True when `body_ref` is inside a `.ironbee/otel` dir (the security gate). */
18
+ export declare function isInsideOTELDir(bodyRef: string): boolean;
19
+ /**
20
+ * The request/response uuid from a body-ref filename:
21
+ * `<uuid>.request.json` → `<uuid>`, `<request_id>.response.json` → `<request_id>`.
22
+ */
23
+ export declare function requestUuidFromBodyRef(bodyRef: string): string;
24
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/otel/daemon/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAapE;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9D"}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * IronBee — OTEL body-ref path helpers (pure, path-aware, cross-platform).
4
+ *
5
+ * A raw body file lives at `<project_dir>/.ironbee/otel/<uuid>.request.json`.
6
+ * The daemon derives the project dir from that path (no registry walk), and the
7
+ * same check is the security gate: the daemon only reads / unlinks files that
8
+ * actually sit inside a `.ironbee/otel` directory (a loopback POST must not make
9
+ * it touch arbitrary paths).
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.projectDirFromBodyRef = projectDirFromBodyRef;
13
+ exports.isInsideOTELDir = isInsideOTELDir;
14
+ exports.requestUuidFromBodyRef = requestUuidFromBodyRef;
15
+ const path_1 = require("path");
16
+ const OTEL_DIRNAME = "otel";
17
+ const IRONBEE_DIRNAME = ".ironbee";
18
+ /**
19
+ * Derive `<project_dir>` from a `body_ref` of the shape
20
+ * `<project_dir>/.ironbee/otel/<file>`. Returns `null` when the path is not
21
+ * inside a `.ironbee/otel` directory — which doubles as the security gate
22
+ * (reject anything outside). Path-aware: never splits on a hardcoded `/`.
23
+ */
24
+ function projectDirFromBodyRef(bodyRef) {
25
+ const otelDir = (0, path_1.dirname)(bodyRef);
26
+ const ironbeeDir = (0, path_1.dirname)(otelDir);
27
+ const projectDir = (0, path_1.dirname)(ironbeeDir);
28
+ if ((0, path_1.basename)(otelDir) === OTEL_DIRNAME
29
+ && (0, path_1.basename)(ironbeeDir) === IRONBEE_DIRNAME
30
+ && projectDir.length > 0
31
+ && projectDir !== ironbeeDir) {
32
+ return projectDir;
33
+ }
34
+ return null;
35
+ }
36
+ /** True when `body_ref` is inside a `.ironbee/otel` dir (the security gate). */
37
+ function isInsideOTELDir(bodyRef) {
38
+ return projectDirFromBodyRef(bodyRef) !== null;
39
+ }
40
+ /**
41
+ * The request/response uuid from a body-ref filename:
42
+ * `<uuid>.request.json` → `<uuid>`, `<request_id>.response.json` → `<request_id>`.
43
+ */
44
+ function requestUuidFromBodyRef(bodyRef) {
45
+ return (0, path_1.basename)(bodyRef).replace(/\.(request|response)\.json$/i, "");
46
+ }
47
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/otel/daemon/paths.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAaH,sDAaC;AAGD,0CAEC;AAMD,wDAEC;AArCD,+BAAyC;AAEzC,MAAM,YAAY,GAAW,MAAM,CAAC;AACpC,MAAM,eAAe,GAAW,UAAU,CAAC;AAE3C;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,OAAe;IACjD,MAAM,OAAO,GAAW,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC;IACzC,MAAM,UAAU,GAAW,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAW,IAAA,cAAO,EAAC,UAAU,CAAC,CAAC;IAC/C,IACI,IAAA,eAAQ,EAAC,OAAO,CAAC,KAAK,YAAY;WAC/B,IAAA,eAAQ,EAAC,UAAU,CAAC,KAAK,eAAe;WACxC,UAAU,CAAC,MAAM,GAAG,CAAC;WACrB,UAAU,KAAK,UAAU,EAC9B,CAAC;QACC,OAAO,UAAU,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,gFAAgF;AAChF,SAAgB,eAAe,CAAC,OAAe;IAC3C,OAAO,qBAAqB,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,OAAe;IAClD,OAAO,IAAA,eAAQ,EAAC,OAAO,CAAC,CAAC,OAAO,CAAC,8BAA8B,EAAE,EAAE,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * IronBee — read a raw `*.request.json` body file and build its
3
+ * `session_context` event. Handles the security gate (path must be inside
4
+ * `.ironbee/otel`), the partial-write guard (size vs `body_length`), and
5
+ * identity resolution (session_id / project_name / model / base fields). Returns
6
+ * the built event + the owning project dir, or `null` to skip.
7
+ */
8
+ import { SessionContextEvent } from "../../lib/event";
9
+ import { ApiRequestBodyMeta } from "../context/extract";
10
+ export interface ProcessedBody {
11
+ event: SessionContextEvent;
12
+ projectDir: string;
13
+ bodyRef: string;
14
+ }
15
+ /**
16
+ * Read + build. Returns `null` (skip) on: a path outside `.ironbee/otel`
17
+ * (security gate), a missing / unreadable file, unparseable JSON, or no
18
+ * resolvable session_id.
19
+ */
20
+ export declare function processBodyFile(meta: ApiRequestBodyMeta): Promise<ProcessedBody | null>;
21
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../../src/otel/daemon/process.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,EAAE,mBAAmB,EAAa,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAMxD,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,mBAAmB,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB;AAmFD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA0D7F"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ /**
3
+ * IronBee — read a raw `*.request.json` body file and build its
4
+ * `session_context` event. Handles the security gate (path must be inside
5
+ * `.ironbee/otel`), the partial-write guard (size vs `body_length`), and
6
+ * identity resolution (session_id / project_name / model / base fields). Returns
7
+ * the built event + the owning project dir, or `null` to skip.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.processBodyFile = processBodyFile;
11
+ const fs_1 = require("fs");
12
+ const path_1 = require("path");
13
+ const logger_1 = require("../../lib/logger");
14
+ const util_1 = require("../context/util");
15
+ const classify_1 = require("../context/classify");
16
+ const build_1 = require("../context/build");
17
+ const paths_1 = require("./paths");
18
+ const PARTIAL_WRITE_RETRIES = 3;
19
+ const PARTIAL_WRITE_DELAY_MS = 50;
20
+ function delay(ms) {
21
+ return new Promise((resolve) => { setTimeout(resolve, ms); });
22
+ }
23
+ function isObject(v) {
24
+ return v !== null && typeof v === "object" && !Array.isArray(v);
25
+ }
26
+ function readJsonObject(path) {
27
+ try {
28
+ const parsed = JSON.parse((0, fs_1.readFileSync)(path, "utf8"));
29
+ return isObject(parsed) ? parsed : null;
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ /**
36
+ * The model the request was actually sent with — `body.model` is the ground
37
+ * truth and is always present on a real Messages request. Preferred over the
38
+ * OTLP event's `model` attribute, which is empty on the catch-up path
39
+ * (`orphanMeta`) and which the collector rejects (empty `model` → HTTP 400).
40
+ */
41
+ function modelFromBody(body) {
42
+ if (isObject(body) && typeof body.model === "string" && body.model.length > 0) {
43
+ return body.model;
44
+ }
45
+ return null;
46
+ }
47
+ /** Recover `session_id` from the body's double-encoded `metadata.user_id` (catch-up fallback). */
48
+ function sessionIdFromBody(body) {
49
+ if (!isObject(body) || !isObject(body.metadata)) {
50
+ return null;
51
+ }
52
+ const userId = body.metadata.user_id;
53
+ if (typeof userId !== "string") {
54
+ return null;
55
+ }
56
+ try {
57
+ const parsed = JSON.parse(userId);
58
+ if (isObject(parsed) && typeof parsed.session_id === "string") {
59
+ return parsed.session_id;
60
+ }
61
+ }
62
+ catch {
63
+ // malformed → no fallback
64
+ }
65
+ return null;
66
+ }
67
+ /** Best-effort read of base fields from the session's state.json (may be absent). */
68
+ function readSessionState(projectDir, sessionId) {
69
+ const j = readJsonObject((0, path_1.join)(projectDir, ".ironbee", "sessions", sessionId, "state.json"));
70
+ if (!j) {
71
+ return {};
72
+ }
73
+ const out = {};
74
+ if (typeof j.userEmail === "string") {
75
+ out.user_email = j.userEmail;
76
+ }
77
+ if (j.usageType === "api" || j.usageType === "subscription") {
78
+ out.usage_type = j.usageType;
79
+ }
80
+ if (typeof j.usagePlan === "string") {
81
+ out.usage_plan = j.usagePlan;
82
+ }
83
+ if (typeof j.projectName === "string") {
84
+ out.projectName = j.projectName;
85
+ }
86
+ return out;
87
+ }
88
+ /**
89
+ * Read + build. Returns `null` (skip) on: a path outside `.ironbee/otel`
90
+ * (security gate), a missing / unreadable file, unparseable JSON, or no
91
+ * resolvable session_id.
92
+ */
93
+ async function processBodyFile(meta) {
94
+ const projectDir = (0, paths_1.projectDirFromBodyRef)(meta.body_ref);
95
+ if (projectDir === null) {
96
+ logger_1.logger.warn(`otel: refusing body_ref outside a .ironbee/otel dir: ${meta.body_ref}`);
97
+ return null;
98
+ }
99
+ // Read with a partial-write guard: a size mismatch vs body_length means the
100
+ // write was still in flight when the event fired → brief retry.
101
+ let content = null;
102
+ for (let attempt = 0; attempt < PARTIAL_WRITE_RETRIES; attempt++) {
103
+ try {
104
+ content = (0, fs_1.readFileSync)(meta.body_ref, "utf8");
105
+ }
106
+ catch {
107
+ return null; // gone / unreadable
108
+ }
109
+ if (meta.body_length === null || (0, util_1.byteLen)(content) === meta.body_length || attempt === PARTIAL_WRITE_RETRIES - 1) {
110
+ break;
111
+ }
112
+ await delay(PARTIAL_WRITE_DELAY_MS);
113
+ }
114
+ if (content === null) {
115
+ return null;
116
+ }
117
+ let body;
118
+ try {
119
+ body = JSON.parse(content);
120
+ }
121
+ catch {
122
+ logger_1.logger.debug(`otel: unparseable body file ${meta.body_ref}`);
123
+ return null;
124
+ }
125
+ const sessionId = meta.session_id ?? sessionIdFromBody(body);
126
+ if (!sessionId) {
127
+ logger_1.logger.debug(`otel: no session_id for ${meta.body_ref}; skipping`);
128
+ return null;
129
+ }
130
+ const state = readSessionState(projectDir, sessionId);
131
+ const projectName = meta.project_name ?? state.projectName ?? (0, path_1.basename)(projectDir);
132
+ const classification = (0, classify_1.classifyRequestBody)(body);
133
+ const scMeta = {
134
+ session_id: sessionId,
135
+ project_name: projectName,
136
+ // Prefer the body's authoritative model; the event attr is "" on catch-up.
137
+ model: modelFromBody(body) ?? meta.model,
138
+ query_source: meta.query_source,
139
+ sequence_number: meta.sequence_number,
140
+ timestamp: meta.timestamp,
141
+ request_uuid: (0, paths_1.requestUuidFromBodyRef)(meta.body_ref),
142
+ user_email: state.user_email,
143
+ usage_type: state.usage_type,
144
+ usage_plan: state.usage_plan,
145
+ };
146
+ const event = (0, build_1.buildSessionContextEvent)(scMeta, classification);
147
+ return { event, projectDir, bodyRef: meta.body_ref };
148
+ }
149
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../../src/otel/daemon/process.ts"],"names":[],"mappings":"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"}