@oka-core/reason 0.2.15 → 0.2.16

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 (158) 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 +5 -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/temp-file.d.ts +18 -0
  135. package/dist/temp-file.d.ts.map +1 -0
  136. package/dist/temp-file.js +26 -0
  137. package/dist/tool-contract.d.ts +85 -0
  138. package/dist/tool-contract.d.ts.map +1 -0
  139. package/dist/tool-contract.js +101 -0
  140. package/dist/tools/read.d.ts +2 -10
  141. package/dist/tools/read.d.ts.map +1 -1
  142. package/dist/tools/read.js +662 -537
  143. package/dist/tools/write.d.ts +3 -2
  144. package/dist/tools/write.d.ts.map +1 -1
  145. package/dist/tools/write.js +329 -177
  146. package/dist/uuid.d.ts +20 -0
  147. package/dist/uuid.d.ts.map +1 -0
  148. package/dist/uuid.js +28 -0
  149. package/dist/validation.d.ts +64 -0
  150. package/dist/validation.d.ts.map +1 -0
  151. package/dist/validation.js +236 -0
  152. package/dist/with-resolvers.d.ts +12 -0
  153. package/dist/with-resolvers.d.ts.map +1 -0
  154. package/dist/with-resolvers.js +14 -0
  155. package/dist/xml-escape.d.ts +12 -0
  156. package/dist/xml-escape.d.ts.map +1 -0
  157. package/dist/xml-escape.js +15 -0
  158. package/package.json +1 -1
package/dist/signal.js ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Typed event signal primitive — zero external dependencies.
3
+ *
4
+ * Collapses the ~8-line `new Set(); subscribe/notify` boilerplate into a
5
+ * reusable, typed primitive. Compatible with React's `useSyncExternalStore`.
6
+ *
7
+ * Inspired by Claude Code's `src/utils/signal.ts`.
8
+ */
9
+ // ─── Factory ────────────────────────────────────────────────────────
10
+ /**
11
+ * Create a typed event signal.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const changed = createSignal<[newValue: number]>();
16
+ * const unsub = changed.subscribe((v) => console.log(v));
17
+ * changed.emit(42); // logs 42
18
+ * unsub();
19
+ * ```
20
+ */
21
+ export function createSignal() {
22
+ const listeners = new Set();
23
+ return {
24
+ subscribe(listener) {
25
+ listeners.add(listener);
26
+ return () => {
27
+ listeners.delete(listener);
28
+ };
29
+ },
30
+ emit(...args) {
31
+ for (const listener of listeners) {
32
+ listener(...args);
33
+ }
34
+ },
35
+ clear() {
36
+ listeners.clear();
37
+ },
38
+ };
39
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Abort-aware sleep and promise timeout — zero external dependencies.
3
+ *
4
+ * Inspired by Claude Code's `src/utils/sleep.ts`.
5
+ */
6
+ /**
7
+ * Sleep for `ms` milliseconds, optionally respecting an AbortSignal.
8
+ *
9
+ * - If `signal` is already aborted, rejects immediately.
10
+ * - If `signal` aborts during sleep, rejects with the signal's reason.
11
+ * - If `opts.unref` is true, the timer won't keep the process alive.
12
+ */
13
+ export declare function sleep(ms: number, signal?: AbortSignal, opts?: {
14
+ unref?: boolean;
15
+ }): Promise<void>;
16
+ /**
17
+ * Race a promise against a timeout. Rejects with an Error if the timeout
18
+ * fires first. The timer is cleaned up when the promise settles.
19
+ */
20
+ export declare function withTimeout<T>(promise: Promise<T>, ms: number, message?: string): Promise<T>;
21
+ //# sourceMappingURL=sleep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sleep.d.ts","sourceRoot":"","sources":["../src/sleep.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,wBAAgB,KAAK,CACnB,EAAE,EAAE,MAAM,EACV,MAAM,CAAC,EAAE,WAAW,EACpB,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GACzB,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,EAAE,EAAE,MAAM,EACV,OAAO,SAAwB,GAC9B,OAAO,CAAC,CAAC,CAAC,CAaZ"}
package/dist/sleep.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Abort-aware sleep and promise timeout — zero external dependencies.
3
+ *
4
+ * Inspired by Claude Code's `src/utils/sleep.ts`.
5
+ */
6
+ /**
7
+ * Sleep for `ms` milliseconds, optionally respecting an AbortSignal.
8
+ *
9
+ * - If `signal` is already aborted, rejects immediately.
10
+ * - If `signal` aborts during sleep, rejects with the signal's reason.
11
+ * - If `opts.unref` is true, the timer won't keep the process alive.
12
+ */
13
+ export function sleep(ms, signal, opts) {
14
+ return new Promise((resolve, reject) => {
15
+ if (signal?.aborted) {
16
+ reject(signal.reason ?? new Error("Operation aborted"));
17
+ return;
18
+ }
19
+ let timer;
20
+ let onAbort;
21
+ const cleanup = () => {
22
+ if (onAbort && signal) {
23
+ signal.removeEventListener("abort", onAbort);
24
+ }
25
+ };
26
+ timer = setTimeout(() => {
27
+ cleanup();
28
+ resolve();
29
+ }, ms);
30
+ if (opts?.unref && typeof timer === "object" && "unref" in timer) {
31
+ timer.unref();
32
+ }
33
+ if (signal) {
34
+ onAbort = () => {
35
+ clearTimeout(timer);
36
+ cleanup();
37
+ reject(signal.reason ?? new Error("Operation aborted"));
38
+ };
39
+ signal.addEventListener("abort", onAbort, { once: true });
40
+ }
41
+ });
42
+ }
43
+ /**
44
+ * Race a promise against a timeout. Rejects with an Error if the timeout
45
+ * fires first. The timer is cleaned up when the promise settles.
46
+ */
47
+ export function withTimeout(promise, ms, message = "Operation timed out") {
48
+ let timer;
49
+ const timeout = new Promise((_, reject) => {
50
+ timer = setTimeout(() => reject(new Error(message)), ms);
51
+ if (typeof timer === "object" && "unref" in timer) {
52
+ timer.unref();
53
+ }
54
+ });
55
+ return Promise.race([promise, timeout]).finally(() => {
56
+ clearTimeout(timer);
57
+ });
58
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Slow operation instrumentation using Symbol.dispose.
3
+ *
4
+ * Uses the `using` keyword to automatically time operations and warn
5
+ * when they exceed a threshold. Zero cost on the fast path — the
6
+ * description string is only materialized when slow.
7
+ *
8
+ * Inspired by Claude Code's `src/utils/slowOperations.ts` (simplified).
9
+ */
10
+ /**
11
+ * Register a callback for slow operation notifications (e.g., logging).
12
+ * Returns an unregister function.
13
+ */
14
+ export declare function onSlowOperation(cb: (op: {
15
+ description: string;
16
+ durationMs: number;
17
+ caller: string;
18
+ }) => void): () => void;
19
+ /**
20
+ * Extract the caller's filename:line from an Error stack trace.
21
+ */
22
+ export declare function callerFrame(stack: string | undefined): string;
23
+ /**
24
+ * Tagged template literal for slow operation monitoring.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * using _ = slowLogging`JSON.stringify(${data})`;
29
+ * const result = JSON.stringify(data);
30
+ * ```
31
+ *
32
+ * The description is only materialized if the operation exceeds the threshold.
33
+ */
34
+ export declare const slowLogging: (strings: TemplateStringsArray, ...values: unknown[]) => Disposable;
35
+ /** JSON.stringify with slow-op logging. */
36
+ export declare function jsonStringify(value: unknown, replacer?: (key: string, value: unknown) => unknown, space?: string | number): string;
37
+ /** JSON.parse with slow-op logging. */
38
+ export declare function jsonParse(text: string): unknown;
39
+ /** structuredClone with slow-op logging. */
40
+ export declare function clone<T>(value: T): T;
41
+ //# sourceMappingURL=slow-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slow-ops.d.ts","sourceRoot":"","sources":["../src/slow-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,CAAC,EAAE,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,GAC5E,MAAM,IAAI,CAMZ;AAID;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAY7D;AAMD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,EAAE,CACxB,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,OAAO,EAAE,KACjB,UA4BgE,CAAC;AAItE,2CAA2C;AAC3C,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,EACnD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAcR;AAED,uCAAuC;AACvC,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAc/C;AAED,4CAA4C;AAC5C,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAcpC"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Slow operation instrumentation using Symbol.dispose.
3
+ *
4
+ * Uses the `using` keyword to automatically time operations and warn
5
+ * when they exceed a threshold. Zero cost on the fast path — the
6
+ * description string is only materialized when slow.
7
+ *
8
+ * Inspired by Claude Code's `src/utils/slowOperations.ts` (simplified).
9
+ */
10
+ // ─── Configuration ──────────────────────────────────────────────────
11
+ const THRESHOLD_MS = Number(process.env["SLOW_OP_THRESHOLD_MS"] ?? Infinity);
12
+ /** Callbacks notified when a slow operation is detected. */
13
+ const onSlowCallbacks = [];
14
+ /**
15
+ * Register a callback for slow operation notifications (e.g., logging).
16
+ * Returns an unregister function.
17
+ */
18
+ export function onSlowOperation(cb) {
19
+ onSlowCallbacks.push(cb);
20
+ return () => {
21
+ const idx = onSlowCallbacks.indexOf(cb);
22
+ if (idx >= 0)
23
+ onSlowCallbacks.splice(idx, 1);
24
+ };
25
+ }
26
+ // ─── Caller extraction ──────────────────────────────────────────────
27
+ /**
28
+ * Extract the caller's filename:line from an Error stack trace.
29
+ */
30
+ export function callerFrame(stack) {
31
+ if (!stack)
32
+ return "<unknown>";
33
+ const lines = stack.split("\n");
34
+ // Skip Error line + slowLogging frame + tagged template frame
35
+ for (let i = 3; i < lines.length; i++) {
36
+ const line = lines[i]?.trim();
37
+ if (!line || !line.startsWith("at "))
38
+ continue;
39
+ // Extract (file:line:col) or file:line:col
40
+ const match = line.match(/\((.+)\)$/) ?? line.match(/at (.+)$/);
41
+ if (match?.[1])
42
+ return match[1];
43
+ }
44
+ return "<unknown>";
45
+ }
46
+ // ─── Tagged template ────────────────────────────────────────────────
47
+ const hasDispose = typeof Symbol.dispose !== "undefined";
48
+ /**
49
+ * Tagged template literal for slow operation monitoring.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * using _ = slowLogging`JSON.stringify(${data})`;
54
+ * const result = JSON.stringify(data);
55
+ * ```
56
+ *
57
+ * The description is only materialized if the operation exceeds the threshold.
58
+ */
59
+ export const slowLogging = hasDispose
60
+ ? (strings, ...values) => {
61
+ if (THRESHOLD_MS === Infinity) {
62
+ return { [Symbol.dispose]() { } };
63
+ }
64
+ const start = performance.now();
65
+ const stack = new Error().stack;
66
+ return {
67
+ [Symbol.dispose]() {
68
+ const elapsed = performance.now() - start;
69
+ if (elapsed < THRESHOLD_MS)
70
+ return;
71
+ // Materialize description only when slow
72
+ let desc = strings[0] ?? "";
73
+ for (let i = 0; i < values.length; i++) {
74
+ desc += String(values[i]) + (strings[i + 1] ?? "");
75
+ }
76
+ const caller = callerFrame(stack);
77
+ for (const cb of onSlowCallbacks) {
78
+ cb({ description: desc, durationMs: Math.round(elapsed), caller });
79
+ }
80
+ },
81
+ };
82
+ }
83
+ : // Fallback for runtimes without Symbol.dispose
84
+ () => ({ [Symbol.dispose ?? Symbol.for("Symbol.dispose")]() { } });
85
+ // ─── Instrumented wrappers ──────────────────────────────────────────
86
+ /** JSON.stringify with slow-op logging. */
87
+ export function jsonStringify(value, replacer, space) {
88
+ const start = performance.now();
89
+ const result = JSON.stringify(value, replacer, space);
90
+ const elapsed = performance.now() - start;
91
+ if (elapsed >= THRESHOLD_MS) {
92
+ for (const cb of onSlowCallbacks) {
93
+ cb({
94
+ description: `jsonStringify (${result?.length ?? 0} chars)`,
95
+ durationMs: Math.round(elapsed),
96
+ caller: callerFrame(new Error().stack),
97
+ });
98
+ }
99
+ }
100
+ return result;
101
+ }
102
+ /** JSON.parse with slow-op logging. */
103
+ export function jsonParse(text) {
104
+ const start = performance.now();
105
+ const result = JSON.parse(text);
106
+ const elapsed = performance.now() - start;
107
+ if (elapsed >= THRESHOLD_MS) {
108
+ for (const cb of onSlowCallbacks) {
109
+ cb({
110
+ description: `jsonParse (${text.length} chars)`,
111
+ durationMs: Math.round(elapsed),
112
+ caller: callerFrame(new Error().stack),
113
+ });
114
+ }
115
+ }
116
+ return result;
117
+ }
118
+ /** structuredClone with slow-op logging. */
119
+ export function clone(value) {
120
+ const start = performance.now();
121
+ const result = structuredClone(value);
122
+ const elapsed = performance.now() - start;
123
+ if (elapsed >= THRESHOLD_MS) {
124
+ for (const cb of onSlowCallbacks) {
125
+ cb({
126
+ description: "clone (structuredClone)",
127
+ durationMs: Math.round(elapsed),
128
+ caller: callerFrame(new Error().stack),
129
+ });
130
+ }
131
+ }
132
+ return result;
133
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Minimal reactive state container — zero external dependencies.
3
+ *
4
+ * Compatible with React's `useSyncExternalStore` via `subscribe`/`getState`.
5
+ * Uses `Object.is()` for structural deduplication.
6
+ *
7
+ * Inspired by Claude Code's `src/state/store.ts`.
8
+ */
9
+ export type Listener = () => void;
10
+ export type OnChange<T> = (args: {
11
+ newState: T;
12
+ oldState: T;
13
+ }) => void;
14
+ export type Store<T> = {
15
+ getState: () => T;
16
+ setState: (updater: (prev: T) => T) => void;
17
+ subscribe: (listener: Listener) => () => void;
18
+ };
19
+ export declare function createStore<T>(initialState: T, onChange?: OnChange<T>): Store<T>;
20
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,CAAC,CAAA;CAAE,KAAK,IAAI,CAAC;AAEvE,MAAM,MAAM,KAAK,CAAC,CAAC,IAAI;IACrB,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,QAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;IAC5C,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,MAAM,IAAI,CAAC;CAC/C,CAAC;AAIF,wBAAgB,WAAW,CAAC,CAAC,EAC3B,YAAY,EAAE,CAAC,EACf,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,GACrB,KAAK,CAAC,CAAC,CAAC,CAyBV"}
package/dist/store.js ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Minimal reactive state container — zero external dependencies.
3
+ *
4
+ * Compatible with React's `useSyncExternalStore` via `subscribe`/`getState`.
5
+ * Uses `Object.is()` for structural deduplication.
6
+ *
7
+ * Inspired by Claude Code's `src/state/store.ts`.
8
+ */
9
+ // ─── Factory ────────────────────────────────────────────────────────
10
+ export function createStore(initialState, onChange) {
11
+ let state = initialState;
12
+ const listeners = new Set();
13
+ return {
14
+ getState: () => state,
15
+ setState(updater) {
16
+ const next = updater(state);
17
+ if (Object.is(state, next))
18
+ return;
19
+ const prev = state;
20
+ state = next;
21
+ if (onChange)
22
+ onChange({ newState: next, oldState: prev });
23
+ for (const listener of listeners) {
24
+ listener();
25
+ }
26
+ },
27
+ subscribe(listener) {
28
+ listeners.add(listener);
29
+ return () => {
30
+ listeners.delete(listener);
31
+ };
32
+ },
33
+ };
34
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Push-based AsyncIterator — zero external dependencies.
3
+ *
4
+ * Bridges push-based producers (event handlers, WebSocket messages) and
5
+ * pull-based consumers (async iteration / `for await`).
6
+ *
7
+ * Inspired by Claude Code's `src/utils/stream.ts`.
8
+ */
9
+ export declare class Stream<T> implements AsyncIterable<T>, AsyncIterator<T> {
10
+ private readonly returned?;
11
+ private queue;
12
+ private readResolve?;
13
+ private readReject?;
14
+ private isDone;
15
+ private errorValue;
16
+ private hasError;
17
+ private started;
18
+ constructor(returned?: (() => void) | undefined);
19
+ /** Enqueue a value for the consumer. */
20
+ enqueue(value: T): void;
21
+ /** Signal that no more values will be produced. */
22
+ done(): void;
23
+ /** Signal an error to the consumer. */
24
+ error(err: unknown): void;
25
+ next(): Promise<IteratorResult<T>>;
26
+ return(): Promise<IteratorResult<T>>;
27
+ [Symbol.asyncIterator](): AsyncIterator<T>;
28
+ }
29
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qBAAa,MAAM,CAAC,CAAC,CAAE,YAAW,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;IAStD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IARtC,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,WAAW,CAAC,CAAsC;IAC1D,OAAO,CAAC,UAAU,CAAC,CAA2B;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;gBAEK,QAAQ,CAAC,GAAE,MAAM,IAAI,aAAA;IAElD,wCAAwC;IACxC,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAavB,mDAAmD;IACnD,IAAI,IAAI,IAAI;IAYZ,uCAAuC;IACvC,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAezB,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAoBlC,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAOpC,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC;CAO3C"}
package/dist/stream.js ADDED
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Push-based AsyncIterator — zero external dependencies.
3
+ *
4
+ * Bridges push-based producers (event handlers, WebSocket messages) and
5
+ * pull-based consumers (async iteration / `for await`).
6
+ *
7
+ * Inspired by Claude Code's `src/utils/stream.ts`.
8
+ */
9
+ export class Stream {
10
+ returned;
11
+ queue = [];
12
+ readResolve;
13
+ readReject;
14
+ isDone = false;
15
+ errorValue = undefined;
16
+ hasError = false;
17
+ started = false;
18
+ constructor(returned) {
19
+ this.returned = returned;
20
+ }
21
+ /** Enqueue a value for the consumer. */
22
+ enqueue(value) {
23
+ if (this.isDone || this.hasError)
24
+ return;
25
+ if (this.readResolve) {
26
+ const resolve = this.readResolve;
27
+ this.readResolve = undefined;
28
+ this.readReject = undefined;
29
+ resolve({ value, done: false });
30
+ }
31
+ else {
32
+ this.queue.push(value);
33
+ }
34
+ }
35
+ /** Signal that no more values will be produced. */
36
+ done() {
37
+ if (this.isDone)
38
+ return;
39
+ this.isDone = true;
40
+ if (this.readResolve) {
41
+ const resolve = this.readResolve;
42
+ this.readResolve = undefined;
43
+ this.readReject = undefined;
44
+ resolve({ value: undefined, done: true });
45
+ }
46
+ }
47
+ /** Signal an error to the consumer. */
48
+ error(err) {
49
+ if (this.isDone || this.hasError)
50
+ return;
51
+ this.hasError = true;
52
+ this.errorValue = err;
53
+ if (this.readReject) {
54
+ const reject = this.readReject;
55
+ this.readResolve = undefined;
56
+ this.readReject = undefined;
57
+ reject(err);
58
+ }
59
+ }
60
+ // ─── AsyncIterator protocol ─────────────────────────────────────
61
+ next() {
62
+ if (this.queue.length > 0) {
63
+ return Promise.resolve({ value: this.queue.shift(), done: false });
64
+ }
65
+ if (this.hasError) {
66
+ return Promise.reject(this.errorValue);
67
+ }
68
+ if (this.isDone) {
69
+ return Promise.resolve({
70
+ value: undefined,
71
+ done: true,
72
+ });
73
+ }
74
+ return new Promise((resolve, reject) => {
75
+ this.readResolve = resolve;
76
+ this.readReject = reject;
77
+ });
78
+ }
79
+ return() {
80
+ this.isDone = true;
81
+ this.queue.length = 0;
82
+ this.returned?.();
83
+ return Promise.resolve({ value: undefined, done: true });
84
+ }
85
+ [Symbol.asyncIterator]() {
86
+ if (this.started) {
87
+ throw new Error("Stream can only be iterated once");
88
+ }
89
+ this.started = true;
90
+ return this;
91
+ }
92
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Generic string utilities — zero dependencies.
3
+ *
4
+ * Cherry-picked from Claude Code's `src/utils/stringUtils.ts`.
5
+ */
6
+ /**
7
+ * Escape special regex characters so a string can be used as a literal
8
+ * pattern in a RegExp constructor.
9
+ */
10
+ export declare function escapeRegExp(str: string): string;
11
+ /**
12
+ * Uppercase the first character, leaving the rest unchanged.
13
+ * Unlike lodash `capitalize`, does NOT lowercase the remaining characters.
14
+ */
15
+ export declare function capitalize(str: string): string;
16
+ /**
17
+ * Return singular or plural form based on count.
18
+ *
19
+ * @example plural(1, 'file') → 'file'
20
+ * @example plural(3, 'file') → 'files'
21
+ * @example plural(2, 'entry', 'entries') → 'entries'
22
+ */
23
+ export declare function plural(n: number, word: string, pluralWord?: string): string;
24
+ /** Return the first line of a string without allocating a split array. */
25
+ export declare function firstLineOf(s: string): string;
26
+ /**
27
+ * Count occurrences of `char` in `str` using indexOf jumps.
28
+ * Structurally typed so Buffer works too.
29
+ */
30
+ export declare function countCharInString(str: {
31
+ indexOf(search: string, start?: number): number;
32
+ }, char: string, start?: number): number;
33
+ /**
34
+ * Normalize full-width (zenkaku) digits to half-width.
35
+ * Useful for CJK IME input.
36
+ */
37
+ export declare function normalizeFullWidthDigits(input: string): string;
38
+ /**
39
+ * Normalize full-width space (U+3000) to half-width space (U+0020).
40
+ */
41
+ export declare function normalizeFullWidthSpace(input: string): string;
42
+ /**
43
+ * Truncate text to a maximum number of lines, appending "…" if truncated.
44
+ */
45
+ export declare function truncateToLines(text: string, maxLines: number): string;
46
+ //# sourceMappingURL=string-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"string-utils.d.ts","sourceRoot":"","sources":["../src/string-utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CACpB,CAAC,EAAE,MAAM,EACT,IAAI,EAAE,MAAM,EACZ,UAAU,SAAa,GACtB,MAAM,CAER;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE;IAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,EACxD,IAAI,EAAE,MAAM,EACZ,KAAK,SAAI,GACR,MAAM,CAQR;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI9D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAItE"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Generic string utilities — zero dependencies.
3
+ *
4
+ * Cherry-picked from Claude Code's `src/utils/stringUtils.ts`.
5
+ */
6
+ /**
7
+ * Escape special regex characters so a string can be used as a literal
8
+ * pattern in a RegExp constructor.
9
+ */
10
+ export function escapeRegExp(str) {
11
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12
+ }
13
+ /**
14
+ * Uppercase the first character, leaving the rest unchanged.
15
+ * Unlike lodash `capitalize`, does NOT lowercase the remaining characters.
16
+ */
17
+ export function capitalize(str) {
18
+ return str.charAt(0).toUpperCase() + str.slice(1);
19
+ }
20
+ /**
21
+ * Return singular or plural form based on count.
22
+ *
23
+ * @example plural(1, 'file') → 'file'
24
+ * @example plural(3, 'file') → 'files'
25
+ * @example plural(2, 'entry', 'entries') → 'entries'
26
+ */
27
+ export function plural(n, word, pluralWord = word + "s") {
28
+ return n === 1 ? word : pluralWord;
29
+ }
30
+ /** Return the first line of a string without allocating a split array. */
31
+ export function firstLineOf(s) {
32
+ const nl = s.indexOf("\n");
33
+ return nl === -1 ? s : s.slice(0, nl);
34
+ }
35
+ /**
36
+ * Count occurrences of `char` in `str` using indexOf jumps.
37
+ * Structurally typed so Buffer works too.
38
+ */
39
+ export function countCharInString(str, char, start = 0) {
40
+ let n = 0;
41
+ let i = str.indexOf(char, start);
42
+ while (i !== -1) {
43
+ n++;
44
+ i = str.indexOf(char, i + 1);
45
+ }
46
+ return n;
47
+ }
48
+ /**
49
+ * Normalize full-width (zenkaku) digits to half-width.
50
+ * Useful for CJK IME input.
51
+ */
52
+ export function normalizeFullWidthDigits(input) {
53
+ return input.replace(/[0-9]/g, (ch) => String.fromCharCode(ch.charCodeAt(0) - 0xfee0));
54
+ }
55
+ /**
56
+ * Normalize full-width space (U+3000) to half-width space (U+0020).
57
+ */
58
+ export function normalizeFullWidthSpace(input) {
59
+ return input.replace(/\u3000/g, " ");
60
+ }
61
+ /**
62
+ * Truncate text to a maximum number of lines, appending "…" if truncated.
63
+ */
64
+ export function truncateToLines(text, maxLines) {
65
+ const lines = text.split("\n");
66
+ if (lines.length <= maxLines)
67
+ return text;
68
+ return lines.slice(0, maxLines).join("\n") + "…";
69
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Strip UTF-8 BOM (U+FEFF) from string content.
3
+ *
4
+ * PowerShell 5.x writes UTF-8 with BOM by default (Out-File, Set-Content).
5
+ * Without stripping, JSON.parse fails with "Unexpected token".
6
+ */
7
+ export declare function stripBOM(content: string): string;
8
+ //# sourceMappingURL=strip-bom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strip-bom.d.ts","sourceRoot":"","sources":["../src/strip-bom.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhD"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Strip UTF-8 BOM (U+FEFF) from string content.
3
+ *
4
+ * PowerShell 5.x writes UTF-8 with BOM by default (Out-File, Set-Content).
5
+ * Without stripping, JSON.parse fails with "Unexpected token".
6
+ */
7
+ const UTF8_BOM = "\uFEFF";
8
+ export function stripBOM(content) {
9
+ return content.startsWith(UTF8_BOM) ? content.slice(1) : content;
10
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Secret-aware environment scrubbing for subprocess spawning.
3
+ *
4
+ * Strips sensitive variables (API keys, cloud credentials, OIDC tokens)
5
+ * from child process environments to prevent exfiltration via shell
6
+ * expansion in CI/CD and agent contexts.
7
+ *
8
+ * Inspired by Claude Code's `src/utils/subprocessEnv.ts`.
9
+ */
10
+ export type SubprocessEnvOptions = {
11
+ /** Environment variable that gates scrubbing. Default: OKA_SUBPROCESS_ENV_SCRUB. */
12
+ enableEnvVar?: string;
13
+ /** Additional variables to scrub beyond defaults. */
14
+ extraScrubList?: readonly string[];
15
+ /** Completely replace the default scrub list. */
16
+ scrubList?: readonly string[];
17
+ };
18
+ /**
19
+ * Create a scrubbed copy of `process.env` for subprocess spawning.
20
+ *
21
+ * Scrubbing is only active when the gate env var is truthy.
22
+ * Also scrubs `INPUT_<NAME>` variants (GitHub Actions auto-creates these).
23
+ */
24
+ export declare function createSubprocessEnv(opts?: SubprocessEnvOptions): NodeJS.ProcessEnv;
25
+ //# sourceMappingURL=subprocess-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subprocess-env.d.ts","sourceRoot":"","sources":["../src/subprocess-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA+BH,MAAM,MAAM,oBAAoB,GAAG;IACjC,oFAAoF;IACpF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qDAAqD;IACrD,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,iDAAiD;IACjD,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,CAAC,EAAE,oBAAoB,GAC1B,MAAM,CAAC,UAAU,CAmBnB"}