@oka-core/reason 0.2.15 → 0.2.17

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 (161) hide show
  1. package/dist/abort-controller.d.ts +19 -0
  2. package/dist/abort-controller.d.ts.map +1 -0
  3. package/dist/abort-controller.js +53 -0
  4. package/dist/activity-tracker.d.ts +48 -0
  5. package/dist/activity-tracker.d.ts.map +1 -0
  6. package/dist/activity-tracker.js +80 -0
  7. package/dist/analytics.d.ts +49 -0
  8. package/dist/analytics.d.ts.map +1 -0
  9. package/dist/analytics.js +88 -0
  10. package/dist/array.d.ts +12 -0
  11. package/dist/array.d.ts.map +1 -0
  12. package/dist/array.js +20 -0
  13. package/dist/async-context.d.ts +20 -0
  14. package/dist/async-context.d.ts.map +1 -0
  15. package/dist/async-context.js +25 -0
  16. package/dist/binary-check.d.ts +16 -0
  17. package/dist/binary-check.d.ts.map +1 -0
  18. package/dist/binary-check.js +43 -0
  19. package/dist/buffered-writer.d.ts +30 -0
  20. package/dist/buffered-writer.d.ts.map +1 -0
  21. package/dist/buffered-writer.js +87 -0
  22. package/dist/circular-buffer.d.ts +28 -0
  23. package/dist/circular-buffer.d.ts.map +1 -0
  24. package/dist/circular-buffer.js +61 -0
  25. package/dist/cleanup-registry.d.ts +23 -0
  26. package/dist/cleanup-registry.d.ts.map +1 -0
  27. package/dist/cleanup-registry.js +34 -0
  28. package/dist/client.d.ts +4 -0
  29. package/dist/client.d.ts.map +1 -1
  30. package/dist/client.js +32 -10
  31. package/dist/combined-abort-signal.d.ts +25 -0
  32. package/dist/combined-abort-signal.d.ts.map +1 -0
  33. package/dist/combined-abort-signal.js +47 -0
  34. package/dist/cron-lock.d.ts +29 -0
  35. package/dist/cron-lock.d.ts.map +1 -0
  36. package/dist/cron-lock.js +127 -0
  37. package/dist/cron-scheduler.d.ts +41 -0
  38. package/dist/cron-scheduler.d.ts.map +1 -0
  39. package/dist/cron-scheduler.js +189 -0
  40. package/dist/cron-tasks.d.ts +86 -0
  41. package/dist/cron-tasks.d.ts.map +1 -0
  42. package/dist/cron-tasks.js +205 -0
  43. package/dist/cron.d.ts +35 -0
  44. package/dist/cron.d.ts.map +1 -0
  45. package/dist/cron.js +215 -0
  46. package/dist/env.d.ts +26 -0
  47. package/dist/env.d.ts.map +1 -0
  48. package/dist/env.js +50 -0
  49. package/dist/errors.d.ts +99 -0
  50. package/dist/errors.d.ts.map +1 -0
  51. package/dist/errors.js +214 -0
  52. package/dist/format.d.ts +21 -0
  53. package/dist/format.d.ts.map +1 -0
  54. package/dist/format.js +48 -0
  55. package/dist/fps-tracker.d.ts +22 -0
  56. package/dist/fps-tracker.d.ts.map +1 -0
  57. package/dist/fps-tracker.js +44 -0
  58. package/dist/graceful-shutdown.d.ts +35 -0
  59. package/dist/graceful-shutdown.d.ts.map +1 -0
  60. package/dist/graceful-shutdown.js +89 -0
  61. package/dist/hash.d.ts +21 -0
  62. package/dist/hash.d.ts.map +1 -0
  63. package/dist/hash.js +31 -0
  64. package/dist/heap-diagnostics.d.ts +68 -0
  65. package/dist/heap-diagnostics.d.ts.map +1 -0
  66. package/dist/heap-diagnostics.js +110 -0
  67. package/dist/idle-timeout.d.ts +21 -0
  68. package/dist/idle-timeout.d.ts.map +1 -0
  69. package/dist/idle-timeout.js +42 -0
  70. package/dist/index.d.ts +2 -1
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +11 -0
  73. package/dist/intl.d.ts +18 -0
  74. package/dist/intl.d.ts.map +1 -0
  75. package/dist/intl.js +75 -0
  76. package/dist/jsonl.d.ts +16 -0
  77. package/dist/jsonl.d.ts.map +1 -0
  78. package/dist/jsonl.js +60 -0
  79. package/dist/lazy-schema.d.ts +6 -0
  80. package/dist/lazy-schema.d.ts.map +1 -0
  81. package/dist/lazy-schema.js +8 -0
  82. package/dist/memo.d.ts +64 -0
  83. package/dist/memo.d.ts.map +1 -0
  84. package/dist/memo.js +162 -0
  85. package/dist/pkce.d.ts +13 -0
  86. package/dist/pkce.d.ts.map +1 -0
  87. package/dist/pkce.js +28 -0
  88. package/dist/priority-queue.d.ts +36 -0
  89. package/dist/priority-queue.d.ts.map +1 -0
  90. package/dist/priority-queue.js +97 -0
  91. package/dist/process-utils.d.ts +20 -0
  92. package/dist/process-utils.d.ts.map +1 -0
  93. package/dist/process-utils.js +54 -0
  94. package/dist/query-guard.d.ts +34 -0
  95. package/dist/query-guard.d.ts.map +1 -0
  96. package/dist/query-guard.js +74 -0
  97. package/dist/retry.d.ts +60 -0
  98. package/dist/retry.d.ts.map +1 -0
  99. package/dist/retry.js +89 -0
  100. package/dist/schemas.d.ts +6 -6
  101. package/dist/secrets.d.ts +44 -0
  102. package/dist/secrets.d.ts.map +1 -0
  103. package/dist/secrets.js +115 -0
  104. package/dist/semantic-types.d.ts +39 -0
  105. package/dist/semantic-types.d.ts.map +1 -0
  106. package/dist/semantic-types.js +49 -0
  107. package/dist/sequential.d.ts +21 -0
  108. package/dist/sequential.d.ts.map +1 -0
  109. package/dist/sequential.js +49 -0
  110. package/dist/signal.d.ts +29 -0
  111. package/dist/signal.d.ts.map +1 -0
  112. package/dist/signal.js +39 -0
  113. package/dist/sleep.d.ts +21 -0
  114. package/dist/sleep.d.ts.map +1 -0
  115. package/dist/sleep.js +58 -0
  116. package/dist/slow-ops.d.ts +41 -0
  117. package/dist/slow-ops.d.ts.map +1 -0
  118. package/dist/slow-ops.js +133 -0
  119. package/dist/store.d.ts +20 -0
  120. package/dist/store.d.ts.map +1 -0
  121. package/dist/store.js +34 -0
  122. package/dist/stream.d.ts +29 -0
  123. package/dist/stream.d.ts.map +1 -0
  124. package/dist/stream.js +92 -0
  125. package/dist/string-utils.d.ts +46 -0
  126. package/dist/string-utils.d.ts.map +1 -0
  127. package/dist/string-utils.js +69 -0
  128. package/dist/strip-bom.d.ts +8 -0
  129. package/dist/strip-bom.d.ts.map +1 -0
  130. package/dist/strip-bom.js +10 -0
  131. package/dist/subprocess-env.d.ts +25 -0
  132. package/dist/subprocess-env.d.ts.map +1 -0
  133. package/dist/subprocess-env.js +55 -0
  134. package/dist/telemetry.d.ts +16 -0
  135. package/dist/telemetry.d.ts.map +1 -0
  136. package/dist/telemetry.js +61 -0
  137. package/dist/temp-file.d.ts +18 -0
  138. package/dist/temp-file.d.ts.map +1 -0
  139. package/dist/temp-file.js +26 -0
  140. package/dist/tool-contract.d.ts +85 -0
  141. package/dist/tool-contract.d.ts.map +1 -0
  142. package/dist/tool-contract.js +101 -0
  143. package/dist/tools/read.d.ts +2 -10
  144. package/dist/tools/read.d.ts.map +1 -1
  145. package/dist/tools/read.js +662 -537
  146. package/dist/tools/write.d.ts +3 -2
  147. package/dist/tools/write.d.ts.map +1 -1
  148. package/dist/tools/write.js +329 -177
  149. package/dist/uuid.d.ts +20 -0
  150. package/dist/uuid.d.ts.map +1 -0
  151. package/dist/uuid.js +28 -0
  152. package/dist/validation.d.ts +64 -0
  153. package/dist/validation.d.ts.map +1 -0
  154. package/dist/validation.js +236 -0
  155. package/dist/with-resolvers.d.ts +12 -0
  156. package/dist/with-resolvers.d.ts.map +1 -0
  157. package/dist/with-resolvers.js +14 -0
  158. package/dist/xml-escape.d.ts +12 -0
  159. package/dist/xml-escape.d.ts.map +1 -0
  160. package/dist/xml-escape.js +15 -0
  161. package/package.json +8 -1
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Frame-rate tracker with percentile-based metrics.
3
+ *
4
+ * Records individual frame durations and computes:
5
+ * - averageFps: total frames / elapsed wall-clock time
6
+ * - low1PctFps: 1/p99-frame-duration (worst 1% frames)
7
+ *
8
+ * Useful for render loops, streaming pipelines, or any periodic work
9
+ * where throughput and tail latency matter.
10
+ */
11
+ export type FpsMetrics = {
12
+ averageFps: number;
13
+ low1PctFps: number;
14
+ };
15
+ export declare class FpsTracker {
16
+ private frameDurations;
17
+ private firstRenderTime;
18
+ private lastRenderTime;
19
+ record(durationMs: number): void;
20
+ getMetrics(): FpsMetrics | undefined;
21
+ }
22
+ //# sourceMappingURL=fps-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fps-tracker.d.ts","sourceRoot":"","sources":["../src/fps-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,UAAU,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,UAAU;IACrB,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,cAAc,CAAqB;IAE3C,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAShC,UAAU,IAAI,UAAU,GAAG,SAAS;CA2BrC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Frame-rate tracker with percentile-based metrics.
3
+ *
4
+ * Records individual frame durations and computes:
5
+ * - averageFps: total frames / elapsed wall-clock time
6
+ * - low1PctFps: 1/p99-frame-duration (worst 1% frames)
7
+ *
8
+ * Useful for render loops, streaming pipelines, or any periodic work
9
+ * where throughput and tail latency matter.
10
+ */
11
+ export class FpsTracker {
12
+ frameDurations = [];
13
+ firstRenderTime;
14
+ lastRenderTime;
15
+ record(durationMs) {
16
+ const now = performance.now();
17
+ if (this.firstRenderTime === undefined) {
18
+ this.firstRenderTime = now;
19
+ }
20
+ this.lastRenderTime = now;
21
+ this.frameDurations.push(durationMs);
22
+ }
23
+ getMetrics() {
24
+ if (this.frameDurations.length === 0 ||
25
+ this.firstRenderTime === undefined ||
26
+ this.lastRenderTime === undefined) {
27
+ return undefined;
28
+ }
29
+ const totalTimeMs = this.lastRenderTime - this.firstRenderTime;
30
+ if (totalTimeMs <= 0) {
31
+ return undefined;
32
+ }
33
+ const totalFrames = this.frameDurations.length;
34
+ const averageFps = totalFrames / (totalTimeMs / 1000);
35
+ const sorted = this.frameDurations.slice().sort((a, b) => b - a);
36
+ const p99Index = Math.max(0, Math.ceil(sorted.length * 0.01) - 1);
37
+ const p99FrameTimeMs = sorted[p99Index];
38
+ const low1PctFps = p99FrameTimeMs > 0 ? 1000 / p99FrameTimeMs : 0;
39
+ return {
40
+ averageFps: Math.round(averageFps * 100) / 100,
41
+ low1PctFps: Math.round(low1PctFps * 100) / 100,
42
+ };
43
+ }
44
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Graceful shutdown orchestrator — depends on cleanup-registry.ts, sleep.ts.
3
+ *
4
+ * Registers signal handlers, runs cleanup phases in order, and guarantees
5
+ * process exit via a failsafe timer.
6
+ *
7
+ * Inspired by Claude Code's `src/utils/gracefulShutdown.ts` (simplified).
8
+ */
9
+ export type ShutdownOptions = {
10
+ /** Time budget in ms for cleanup before force-exit. Default: 5000. */
11
+ budget?: number;
12
+ /** Called when shutdown starts. */
13
+ onShutdown?: (reason: string) => void;
14
+ /** Called after cleanup, before exit. Use for analytics flush. */
15
+ onBeforeExit?: () => Promise<void>;
16
+ };
17
+ /** Whether the process is currently shutting down. */
18
+ export declare function isShuttingDown(): boolean;
19
+ /**
20
+ * Register SIGINT, SIGTERM, SIGHUP handlers for graceful shutdown.
21
+ * Idempotent — safe to call multiple times.
22
+ */
23
+ export declare function setupGracefulShutdown(opts?: ShutdownOptions): void;
24
+ /**
25
+ * Execute a graceful shutdown sequence:
26
+ * 1. Run cleanup registry functions (parallel, with timeout)
27
+ * 2. Call onBeforeExit hook (e.g., analytics flush)
28
+ * 3. Exit process
29
+ */
30
+ export declare function gracefulShutdown(exitCode?: number, reason?: string, opts?: ShutdownOptions): Promise<never>;
31
+ /**
32
+ * Reset shutdown state (for testing only).
33
+ */
34
+ export declare function _resetShutdownForTesting(): void;
35
+ //# sourceMappingURL=graceful-shutdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graceful-shutdown.d.ts","sourceRoot":"","sources":["../src/graceful-shutdown.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,MAAM,MAAM,eAAe,GAAG;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC,CAAC;AAEF,sDAAsD;AACtD,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,CAAC,EAAE,eAAe,GAAG,IAAI,CAiBlE;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,SAAI,EACZ,MAAM,SAAa,EACnB,IAAI,CAAC,EAAE,eAAe,GACrB,OAAO,CAAC,KAAK,CAAC,CA8ChB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAG/C"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Graceful shutdown orchestrator — depends on cleanup-registry.ts, sleep.ts.
3
+ *
4
+ * Registers signal handlers, runs cleanup phases in order, and guarantees
5
+ * process exit via a failsafe timer.
6
+ *
7
+ * Inspired by Claude Code's `src/utils/gracefulShutdown.ts` (simplified).
8
+ */
9
+ import { runCleanupFunctions } from "./cleanup-registry.js";
10
+ // ─── State ──────────────────────────────────────────────────────────
11
+ let shuttingDown = false;
12
+ let setupDone = false;
13
+ /** Whether the process is currently shutting down. */
14
+ export function isShuttingDown() {
15
+ return shuttingDown;
16
+ }
17
+ /**
18
+ * Register SIGINT, SIGTERM, SIGHUP handlers for graceful shutdown.
19
+ * Idempotent — safe to call multiple times.
20
+ */
21
+ export function setupGracefulShutdown(opts) {
22
+ if (setupDone)
23
+ return;
24
+ setupDone = true;
25
+ const handler = (signal) => {
26
+ if (shuttingDown) {
27
+ // Double-signal: force immediate exit
28
+ process.exit(1);
29
+ }
30
+ void gracefulShutdown(0, signal, opts);
31
+ };
32
+ process.on("SIGINT", () => handler("SIGINT"));
33
+ process.on("SIGTERM", () => handler("SIGTERM"));
34
+ if (process.platform !== "win32") {
35
+ process.on("SIGHUP", () => handler("SIGHUP"));
36
+ }
37
+ }
38
+ /**
39
+ * Execute a graceful shutdown sequence:
40
+ * 1. Run cleanup registry functions (parallel, with timeout)
41
+ * 2. Call onBeforeExit hook (e.g., analytics flush)
42
+ * 3. Exit process
43
+ */
44
+ export async function gracefulShutdown(exitCode = 0, reason = "shutdown", opts) {
45
+ if (shuttingDown) {
46
+ process.exit(exitCode);
47
+ }
48
+ shuttingDown = true;
49
+ const budget = opts?.budget ?? 5000;
50
+ // Failsafe: guarantee exit even if cleanup hangs
51
+ const failsafe = setTimeout(() => {
52
+ process.exit(exitCode || 1);
53
+ }, budget);
54
+ if (typeof failsafe === "object" && "unref" in failsafe) {
55
+ failsafe.unref();
56
+ }
57
+ opts?.onShutdown?.(reason);
58
+ // Phase 1: Run registered cleanup functions
59
+ try {
60
+ await Promise.race([
61
+ runCleanupFunctions(),
62
+ new Promise((resolve) => setTimeout(resolve, Math.floor(budget * 0.6))),
63
+ ]);
64
+ }
65
+ catch {
66
+ // Continue shutdown even if cleanup fails
67
+ }
68
+ // Phase 2: Before-exit hook (analytics flush, etc.)
69
+ if (opts?.onBeforeExit) {
70
+ try {
71
+ await Promise.race([
72
+ opts.onBeforeExit(),
73
+ new Promise((resolve) => setTimeout(resolve, Math.floor(budget * 0.3))),
74
+ ]);
75
+ }
76
+ catch {
77
+ // Continue shutdown
78
+ }
79
+ }
80
+ clearTimeout(failsafe);
81
+ process.exit(exitCode);
82
+ }
83
+ /**
84
+ * Reset shutdown state (for testing only).
85
+ */
86
+ export function _resetShutdownForTesting() {
87
+ shuttingDown = false;
88
+ setupDone = false;
89
+ }
package/dist/hash.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Content hashing utilities — uses Node built-in `crypto`.
3
+ *
4
+ * Inspired by Claude Code's `src/utils/hash.ts`.
5
+ */
6
+ /**
7
+ * Fast non-cryptographic DJB2 hash.
8
+ * Returns a signed 32-bit integer. Deterministic across runtimes.
9
+ */
10
+ export declare function djb2Hash(str: string): number;
11
+ /**
12
+ * SHA-256 content hash. Returns a hex string.
13
+ * Suitable for change detection and content-addressable caching (not crypto-signing).
14
+ */
15
+ export declare function hashContent(content: string): string;
16
+ /**
17
+ * Hash two strings together without concatenation allocation.
18
+ * Uses a null separator to disambiguate ("ab","c") from ("a","bc").
19
+ */
20
+ export declare function hashPair(a: string, b: string): string;
21
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD"}
package/dist/hash.js ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Content hashing utilities — uses Node built-in `crypto`.
3
+ *
4
+ * Inspired by Claude Code's `src/utils/hash.ts`.
5
+ */
6
+ import { createHash } from "node:crypto";
7
+ /**
8
+ * Fast non-cryptographic DJB2 hash.
9
+ * Returns a signed 32-bit integer. Deterministic across runtimes.
10
+ */
11
+ export function djb2Hash(str) {
12
+ let hash = 5381;
13
+ for (let i = 0; i < str.length; i++) {
14
+ hash = ((hash << 5) + hash + str.charCodeAt(i)) | 0;
15
+ }
16
+ return hash;
17
+ }
18
+ /**
19
+ * SHA-256 content hash. Returns a hex string.
20
+ * Suitable for change detection and content-addressable caching (not crypto-signing).
21
+ */
22
+ export function hashContent(content) {
23
+ return createHash("sha256").update(content).digest("hex");
24
+ }
25
+ /**
26
+ * Hash two strings together without concatenation allocation.
27
+ * Uses a null separator to disambiguate ("ab","c") from ("a","bc").
28
+ */
29
+ export function hashPair(a, b) {
30
+ return createHash("sha256").update(a).update("\0").update(b).digest("hex");
31
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * V8 heap diagnostics and leak detection.
3
+ *
4
+ * Pure diagnostic capture — no snapshot writing, no CC-specific deps.
5
+ * Extracted from Claude Code's heapDumpService.
6
+ */
7
+ export type MemoryDiagnostics = {
8
+ timestamp: string;
9
+ uptimeSeconds: number;
10
+ memoryUsage: {
11
+ heapUsed: number;
12
+ heapTotal: number;
13
+ external: number;
14
+ arrayBuffers: number;
15
+ rss: number;
16
+ };
17
+ memoryGrowthRate: {
18
+ bytesPerSecond: number;
19
+ mbPerHour: number;
20
+ };
21
+ v8HeapStats: {
22
+ heapSizeLimit: number;
23
+ mallocedMemory: number;
24
+ peakMallocedMemory: number;
25
+ detachedContexts: number;
26
+ nativeContexts: number;
27
+ };
28
+ v8HeapSpaces?: Array<{
29
+ name: string;
30
+ size: number;
31
+ used: number;
32
+ available: number;
33
+ }>;
34
+ resourceUsage: {
35
+ maxRSS: number;
36
+ userCPUTime: number;
37
+ systemCPUTime: number;
38
+ };
39
+ activeHandles: number;
40
+ activeRequests: number;
41
+ openFileDescriptors?: number;
42
+ analysis: LeakAnalysis;
43
+ smapsRollup?: string;
44
+ platform: string;
45
+ nodeVersion: string;
46
+ };
47
+ export type LeakAnalysis = {
48
+ potentialLeaks: string[];
49
+ recommendation: string;
50
+ };
51
+ export type DiagnosticsOptions = {
52
+ /** Override timestamp (for testing). */
53
+ timestamp?: string;
54
+ };
55
+ /** Capture a full memory diagnostics snapshot. */
56
+ export declare function captureMemoryDiagnostics(options?: DiagnosticsOptions): Promise<MemoryDiagnostics>;
57
+ type LeakInputs = {
58
+ detachedContexts: number;
59
+ activeHandles: number;
60
+ nativeMemory: number;
61
+ heapUsed: number;
62
+ mbPerHour: number;
63
+ openFileDescriptors?: number;
64
+ };
65
+ /** Analyze memory metrics for potential leak indicators. */
66
+ export declare function analyzeLeaks(inputs: LeakInputs): LeakAnalysis;
67
+ export {};
68
+ //# sourceMappingURL=heap-diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heap-diagnostics.d.ts","sourceRoot":"","sources":["../src/heap-diagnostics.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,gBAAgB,EAAE;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,WAAW,EAAE;QACX,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,YAAY,CAAC,EAAE,KAAK,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,aAAa,EAAE;QACb,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,kDAAkD;AAClD,wBAAsB,wBAAwB,CAC5C,OAAO,CAAC,EAAE,kBAAkB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAmF5B;AAED,KAAK,UAAU,GAAG;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAkC7D"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * V8 heap diagnostics and leak detection.
3
+ *
4
+ * Pure diagnostic capture — no snapshot writing, no CC-specific deps.
5
+ * Extracted from Claude Code's heapDumpService.
6
+ */
7
+ import { readdir, readFile } from "node:fs/promises";
8
+ import { getHeapSpaceStatistics, getHeapStatistics, } from "node:v8";
9
+ /** Capture a full memory diagnostics snapshot. */
10
+ export async function captureMemoryDiagnostics(options) {
11
+ const usage = process.memoryUsage();
12
+ const heapStats = getHeapStatistics();
13
+ const resourceUsage = process.resourceUsage();
14
+ const uptimeSeconds = process.uptime();
15
+ let heapSpaceStats;
16
+ try {
17
+ heapSpaceStats = getHeapSpaceStatistics();
18
+ }
19
+ catch {
20
+ // Not available in Bun runtime
21
+ }
22
+ const activeHandles = process._getActiveHandles().length;
23
+ const activeRequests = process._getActiveRequests().length;
24
+ let openFileDescriptors;
25
+ try {
26
+ openFileDescriptors = (await readdir("/proc/self/fd")).length;
27
+ }
28
+ catch {
29
+ // Not on Linux
30
+ }
31
+ let smapsRollup;
32
+ try {
33
+ smapsRollup = await readFile("/proc/self/smaps_rollup", "utf8");
34
+ }
35
+ catch {
36
+ // Not on Linux or no access
37
+ }
38
+ const bytesPerSecond = uptimeSeconds > 0 ? usage.rss / uptimeSeconds : 0;
39
+ const mbPerHour = (bytesPerSecond * 3600) / (1024 * 1024);
40
+ const analysis = analyzeLeaks({
41
+ detachedContexts: heapStats.number_of_detached_contexts,
42
+ activeHandles,
43
+ nativeMemory: usage.rss - usage.heapUsed,
44
+ heapUsed: usage.heapUsed,
45
+ mbPerHour,
46
+ openFileDescriptors,
47
+ });
48
+ return {
49
+ timestamp: options?.timestamp ?? new Date().toISOString(),
50
+ uptimeSeconds,
51
+ memoryUsage: {
52
+ heapUsed: usage.heapUsed,
53
+ heapTotal: usage.heapTotal,
54
+ external: usage.external,
55
+ arrayBuffers: usage.arrayBuffers,
56
+ rss: usage.rss,
57
+ },
58
+ memoryGrowthRate: { bytesPerSecond, mbPerHour },
59
+ v8HeapStats: {
60
+ heapSizeLimit: heapStats.heap_size_limit,
61
+ mallocedMemory: heapStats.malloced_memory,
62
+ peakMallocedMemory: heapStats.peak_malloced_memory,
63
+ detachedContexts: heapStats.number_of_detached_contexts,
64
+ nativeContexts: heapStats.number_of_native_contexts,
65
+ },
66
+ v8HeapSpaces: heapSpaceStats?.map((space) => ({
67
+ name: space.space_name,
68
+ size: space.space_size,
69
+ used: space.space_used_size,
70
+ available: space.space_available_size,
71
+ })),
72
+ resourceUsage: {
73
+ maxRSS: resourceUsage.maxRSS * 1024,
74
+ userCPUTime: resourceUsage.userCPUTime,
75
+ systemCPUTime: resourceUsage.systemCPUTime,
76
+ },
77
+ activeHandles,
78
+ activeRequests,
79
+ openFileDescriptors,
80
+ analysis,
81
+ smapsRollup,
82
+ platform: process.platform,
83
+ nodeVersion: process.version,
84
+ };
85
+ }
86
+ /** Analyze memory metrics for potential leak indicators. */
87
+ export function analyzeLeaks(inputs) {
88
+ const potentialLeaks = [];
89
+ if (inputs.detachedContexts > 0) {
90
+ potentialLeaks.push(`${inputs.detachedContexts} detached context(s) - possible iframe/context leak`);
91
+ }
92
+ if (inputs.activeHandles > 100) {
93
+ potentialLeaks.push(`${inputs.activeHandles} active handles - possible timer/socket leak`);
94
+ }
95
+ if (inputs.nativeMemory > inputs.heapUsed) {
96
+ potentialLeaks.push("Native memory > heap - leak may be in native addons");
97
+ }
98
+ if (inputs.mbPerHour > 100) {
99
+ potentialLeaks.push(`High memory growth rate: ${inputs.mbPerHour.toFixed(1)} MB/hour`);
100
+ }
101
+ if (inputs.openFileDescriptors && inputs.openFileDescriptors > 500) {
102
+ potentialLeaks.push(`${inputs.openFileDescriptors} open file descriptors - possible file/socket leak`);
103
+ }
104
+ return {
105
+ potentialLeaks,
106
+ recommendation: potentialLeaks.length > 0
107
+ ? `WARNING: ${potentialLeaks.length} potential leak indicator(s) found. See potentialLeaks array.`
108
+ : "No obvious leak indicators. Check heap snapshot for retained objects.",
109
+ };
110
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Idle timeout manager for long-running services.
3
+ *
4
+ * Configurable via options or environment variable. Calls a shutdown
5
+ * callback after continuous idle duration exceeds threshold.
6
+ *
7
+ * Inspired by Claude Code's `src/utils/idleTimeout.ts`.
8
+ */
9
+ export type IdleTimeoutOptions = {
10
+ /** Returns true when the system is idle. */
11
+ isIdle: () => boolean;
12
+ /** Idle duration in ms before triggering shutdown. Default: from OKA_EXIT_AFTER_IDLE_MS env. */
13
+ delayMs?: number;
14
+ /** Called when idle timeout fires. Default: process.exit(0). */
15
+ onTimeout?: () => void;
16
+ };
17
+ export declare function createIdleTimeoutManager(opts: IdleTimeoutOptions): {
18
+ start: () => void;
19
+ stop: () => void;
20
+ };
21
+ //# sourceMappingURL=idle-timeout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idle-timeout.d.ts","sourceRoot":"","sources":["../src/idle-timeout.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,4CAA4C;IAC5C,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,gGAAgG;IAChG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,kBAAkB,GAAG;IAClE,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAsCA"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Idle timeout manager for long-running services.
3
+ *
4
+ * Configurable via options or environment variable. Calls a shutdown
5
+ * callback after continuous idle duration exceeds threshold.
6
+ *
7
+ * Inspired by Claude Code's `src/utils/idleTimeout.ts`.
8
+ */
9
+ export function createIdleTimeoutManager(opts) {
10
+ const envDelay = process.env["OKA_EXIT_AFTER_IDLE_MS"];
11
+ const delayMs = opts.delayMs ?? (envDelay ? parseInt(envDelay, 10) : undefined);
12
+ const isValidDelay = delayMs !== undefined && !isNaN(delayMs) && delayMs > 0;
13
+ const onTimeout = opts.onTimeout ?? (() => process.exit(0));
14
+ let timer = null;
15
+ let lastIdleTime = 0;
16
+ return {
17
+ start() {
18
+ if (timer) {
19
+ clearTimeout(timer);
20
+ timer = null;
21
+ }
22
+ if (isValidDelay && delayMs) {
23
+ lastIdleTime = Date.now();
24
+ timer = setTimeout(() => {
25
+ const idleDuration = Date.now() - lastIdleTime;
26
+ if (opts.isIdle() && idleDuration >= delayMs) {
27
+ onTimeout();
28
+ }
29
+ }, delayMs);
30
+ if (typeof timer === "object" && "unref" in timer) {
31
+ timer.unref();
32
+ }
33
+ }
34
+ },
35
+ stop() {
36
+ if (timer) {
37
+ clearTimeout(timer);
38
+ timer = null;
39
+ }
40
+ },
41
+ };
42
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export { analytics } from "./analytics.js";
3
+ export type { AnalyticsSink } from "./analytics.js";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAWA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -7,8 +7,16 @@ import { registerWriteTools } from "./tools/write.js";
7
7
  import { registerReadTools } from "./tools/read.js";
8
8
  import { registerAuthTools } from "./tools/auth.js";
9
9
  import { loadEnvFile } from "./auth.js";
10
+ import { analytics } from "./analytics.js";
11
+ import { initTelemetry, shutdownTelemetry } from "./telemetry.js";
12
+ export { analytics } from "./analytics.js";
10
13
  // Load .env from the project root (cwd), env vars take precedence
11
14
  loadEnvFile(process.cwd());
15
+ // Initialize OTel tracing (no-op if OTEL_EXPORTER_OTLP_ENDPOINT is not set)
16
+ await initTelemetry();
17
+ // Attach a no-op sink so analytics events don't queue indefinitely.
18
+ // Downstream consumers can replace this by calling analytics.attach() with a real sink.
19
+ analytics.attach({ track: () => { } });
12
20
  const require = createRequire(import.meta.url);
13
21
  const { version } = require("../package.json");
14
22
  const server = new McpServer({
@@ -22,4 +30,7 @@ registerWriteTools(server, client);
22
30
  registerReadTools(server, client);
23
31
  registerAuthTools(server, client);
24
32
  const transport = new StdioServerTransport();
33
+ // Flush OTel spans on shutdown
34
+ process.on("SIGTERM", () => void shutdownTelemetry());
35
+ process.on("SIGINT", () => void shutdownTelemetry());
25
36
  await server.connect(transport);
package/dist/intl.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Lazy-cached Intl object instances.
3
+ *
4
+ * Intl constructors are expensive (~0.05-0.1ms each). Caching avoids
5
+ * re-instantiation across hot paths.
6
+ *
7
+ * Inspired by Claude Code's `src/utils/intl.ts`.
8
+ */
9
+ export declare function getGraphemeSegmenter(): Intl.Segmenter;
10
+ /** Extract the first grapheme cluster from a string. */
11
+ export declare function firstGrapheme(text: string): string;
12
+ /** Extract the last grapheme cluster from a string. */
13
+ export declare function lastGrapheme(text: string): string;
14
+ export declare function getWordSegmenter(): Intl.Segmenter;
15
+ export declare function getRelativeTimeFormat(style: "long" | "short" | "narrow", numeric: "always" | "auto"): Intl.RelativeTimeFormat;
16
+ export declare function getTimeZone(): string;
17
+ export declare function getSystemLocaleLanguage(): string | undefined;
18
+ //# sourceMappingURL=intl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intl.d.ts","sourceRoot":"","sources":["../src/intl.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,SAAS,CAOrD;AAED,wDAAwD;AACxD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAKjD;AAMD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,EAClC,OAAO,EAAE,QAAQ,GAAG,MAAM,GACzB,IAAI,CAAC,kBAAkB,CAQzB;AAMD,wBAAgB,WAAW,IAAI,MAAM,CAKpC;AAID,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,SAAS,CAU5D"}
package/dist/intl.js ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Lazy-cached Intl object instances.
3
+ *
4
+ * Intl constructors are expensive (~0.05-0.1ms each). Caching avoids
5
+ * re-instantiation across hot paths.
6
+ *
7
+ * Inspired by Claude Code's `src/utils/intl.ts`.
8
+ */
9
+ // ── Segmenters ────────────────────────────────────────────────────
10
+ let graphemeSegmenter = null;
11
+ let wordSegmenter = null;
12
+ export function getGraphemeSegmenter() {
13
+ if (!graphemeSegmenter) {
14
+ graphemeSegmenter = new Intl.Segmenter(undefined, {
15
+ granularity: "grapheme",
16
+ });
17
+ }
18
+ return graphemeSegmenter;
19
+ }
20
+ /** Extract the first grapheme cluster from a string. */
21
+ export function firstGrapheme(text) {
22
+ if (!text)
23
+ return "";
24
+ const segments = getGraphemeSegmenter().segment(text);
25
+ const first = segments[Symbol.iterator]().next().value;
26
+ return first?.segment ?? "";
27
+ }
28
+ /** Extract the last grapheme cluster from a string. */
29
+ export function lastGrapheme(text) {
30
+ if (!text)
31
+ return "";
32
+ let last = "";
33
+ for (const { segment } of getGraphemeSegmenter().segment(text)) {
34
+ last = segment;
35
+ }
36
+ return last;
37
+ }
38
+ export function getWordSegmenter() {
39
+ if (!wordSegmenter) {
40
+ wordSegmenter = new Intl.Segmenter(undefined, { granularity: "word" });
41
+ }
42
+ return wordSegmenter;
43
+ }
44
+ // ── RelativeTimeFormat ────────────────────────────────────────────
45
+ const rtfCache = new Map();
46
+ export function getRelativeTimeFormat(style, numeric) {
47
+ const key = `${style}:${numeric}`;
48
+ let rtf = rtfCache.get(key);
49
+ if (!rtf) {
50
+ rtf = new Intl.RelativeTimeFormat("en", { style, numeric });
51
+ rtfCache.set(key, rtf);
52
+ }
53
+ return rtf;
54
+ }
55
+ // ── Timezone & locale ─────────────────────────────────────────────
56
+ let cachedTimeZone = null;
57
+ export function getTimeZone() {
58
+ if (!cachedTimeZone) {
59
+ cachedTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
60
+ }
61
+ return cachedTimeZone;
62
+ }
63
+ let cachedSystemLocaleLanguage = null;
64
+ export function getSystemLocaleLanguage() {
65
+ if (cachedSystemLocaleLanguage === null) {
66
+ try {
67
+ const locale = Intl.DateTimeFormat().resolvedOptions().locale;
68
+ cachedSystemLocaleLanguage = new Intl.Locale(locale).language;
69
+ }
70
+ catch {
71
+ cachedSystemLocaleLanguage = undefined;
72
+ }
73
+ }
74
+ return cachedSystemLocaleLanguage;
75
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * JSONL parsing and safe JSON utilities.
3
+ *
4
+ * Inspired by Claude Code's `src/utils/json.ts` (generic parts only).
5
+ */
6
+ /**
7
+ * Parse JSON safely, returning `null` on failure.
8
+ * Results are LRU-memoized (50 entries max, keys ≤ 8KB).
9
+ */
10
+ export declare function safeParseJSON<T = unknown>(json: string | null | undefined): T | null;
11
+ /**
12
+ * Parse a JSONL string into an array of typed values.
13
+ * Skips blank lines and silently drops malformed lines.
14
+ */
15
+ export declare function parseJSONL<T = unknown>(data: string): T[];
16
+ //# sourceMappingURL=jsonl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl.d.ts","sourceRoot":"","sources":["../src/jsonl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,GAAG,OAAO,EACvC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,CAAC,GAAG,IAAI,CAyBV;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,CAkBzD"}