hankweave 0.5.7 → 0.6.2

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 (79) hide show
  1. package/README.md +12 -11
  2. package/dist/base-process-manager.d.ts +30 -0
  3. package/dist/budget.d.ts +315 -0
  4. package/dist/checkpoint-git.d.ts +98 -0
  5. package/dist/claude-agent-sdk-manager.d.ts +144 -0
  6. package/dist/claude-log-parser.d.ts +63 -0
  7. package/dist/claude-runtime-extractor.d.ts +73 -0
  8. package/dist/codex-runtime-extractor.d.ts +107 -0
  9. package/dist/codon-runner.d.ts +278 -0
  10. package/dist/config-validation/model-validator.d.ts +16 -0
  11. package/dist/config-validation/sentinel.schema.d.ts +6967 -0
  12. package/dist/config.d.ts +40815 -0
  13. package/dist/cost-tracker.d.ts +72 -0
  14. package/dist/execution-planner.d.ts +62 -0
  15. package/dist/execution-thread.d.ts +71 -0
  16. package/dist/exports/schemas.d.ts +9 -0
  17. package/dist/exports/schemas.js +1019 -0
  18. package/dist/exports/types.d.ts +15 -0
  19. package/dist/exports/types.js +60 -0
  20. package/dist/file-resolver.d.ts +33 -0
  21. package/dist/index.js +380 -293
  22. package/dist/index.js.map +33 -29
  23. package/dist/llm/llm-provider-registry.d.ts +207 -0
  24. package/dist/llm/models-dev-schema.d.ts +679 -0
  25. package/dist/llm/provider-config.d.ts +30 -0
  26. package/dist/prompt-builder.d.ts +75 -0
  27. package/dist/prompt-frontmatter.d.ts +61 -0
  28. package/dist/replay-process-manager.d.ts +82 -0
  29. package/dist/runtime-extractor-base.d.ts +120 -0
  30. package/dist/schemas/event-schemas.d.ts +8389 -0
  31. package/dist/schemas/websocket-log-schemas.d.ts +4502 -0
  32. package/dist/shim-process-manager.d.ts +98 -0
  33. package/dist/shim-runtime-extractor.d.ts +51 -0
  34. package/dist/shims/codex/README.md +129 -0
  35. package/dist/shims/codex/THIRDPARTY.md +18 -0
  36. package/dist/shims/codex/VERSION +1 -0
  37. package/dist/shims/codex/common/package.json +24 -0
  38. package/dist/shims/codex/index.js +1154 -970
  39. package/dist/shims/codex/package.json +46 -0
  40. package/dist/shims/codex/tsup.config.ts +16 -0
  41. package/dist/shims/gemini/README.md +59 -0
  42. package/dist/shims/gemini/THIRDPARTY.md +32 -0
  43. package/dist/shims/gemini/VERSION +1 -0
  44. package/dist/shims/gemini/common/package.json +24 -0
  45. package/dist/shims/gemini/index.js +1359 -30
  46. package/dist/shims/gemini/package.json +37 -0
  47. package/dist/shims/opencode/README.md +82 -0
  48. package/dist/shims/opencode/THIRDPARTY.md +32 -0
  49. package/dist/shims/opencode/VERSION +1 -0
  50. package/dist/shims/opencode/common/package.json +24 -0
  51. package/dist/shims/opencode/index.js +1476 -0
  52. package/dist/shims/opencode/package.json +38 -0
  53. package/dist/shims/pi/README.md +87 -0
  54. package/dist/shims/pi/THIRDPARTY.md +24 -0
  55. package/dist/shims/pi/VERSION +1 -0
  56. package/dist/shims/pi/common/package.json +24 -0
  57. package/dist/shims/pi/index.js +249832 -0
  58. package/dist/shims/pi/package.json +53 -0
  59. package/dist/state-manager.d.ts +161 -0
  60. package/dist/state-transition-guards.d.ts +37 -0
  61. package/dist/telemetry/telemetry-types.d.ts +206 -0
  62. package/dist/typed-event-emitter.d.ts +57 -0
  63. package/dist/types/branded-types.d.ts +15 -0
  64. package/dist/types/budget-types.d.ts +82 -0
  65. package/dist/types/claude-session-schema.d.ts +2430 -0
  66. package/dist/types/error-types.d.ts +44 -0
  67. package/dist/types/input-ai-types.d.ts +1070 -0
  68. package/dist/types/llm-call-types.d.ts +3829 -0
  69. package/dist/types/sentinel-types.d.ts +66 -0
  70. package/dist/types/state-types.d.ts +1099 -0
  71. package/dist/types/tool-types.d.ts +86 -0
  72. package/dist/types/types.d.ts +367 -0
  73. package/dist/types/websocket-log-types.d.ts +7 -0
  74. package/dist/utils.d.ts +452 -0
  75. package/package.json +15 -2
  76. package/schemas/hank.schema.json +158 -3
  77. package/schemas/hankweave.schema.json +17 -1
  78. package/shims/codex/index.js +0 -1583
  79. package/shims/gemini/index.js +0 -31
@@ -0,0 +1,452 @@
1
+ import WebSocket from "crossws/websocket";
2
+ import { z } from "zod";
3
+ import type { ClientCommand, FileNode, ServerEvent } from "./types/types.js";
4
+ export { WebSocket };
5
+ export declare function generateId(): string;
6
+ export declare class Logger {
7
+ private logFile;
8
+ constructor(logFile: string);
9
+ log(message: string, level?: "info" | "error" | "debug"): void;
10
+ /**
11
+ * Log WebSocket traffic as JSONL (JSON Lines format).
12
+ * Each line is a complete JSON object representing a WebSocket message.
13
+ *
14
+ * @param socketLogFile - Path to the websocket log file
15
+ * @param direction - Whether this is an incoming or outgoing message
16
+ * @param data - The actual WebSocket message (ClientCommand or ServerEvent)
17
+ */
18
+ logWebSocketMessage(socketLogFile: string, direction: "in" | "out", data: ClientCommand | ServerEvent): void;
19
+ /**
20
+ * @deprecated Use logWebSocketMessage instead
21
+ */
22
+ logSocketTraffic(socketLogFile: string, direction: "in" | "out", data: unknown): void;
23
+ }
24
+ /**
25
+ * Build a hierarchical file tree from files matching a pattern.
26
+ *
27
+ * Creates a tree structure suitable for UI display, with directories
28
+ * as nodes containing their children. Used for filetree.updated events.
29
+ * Includes last modified times for files.
30
+ *
31
+ * @param projectPath - Base directory
32
+ * @param pattern - Glob pattern to match files
33
+ * @returns Root nodes of the file tree
34
+ */
35
+ export declare function buildFileTree(projectPath: string, pattern: string): Promise<FileNode[]>;
36
+ /**
37
+ * Escape a string for safe use in shell commands.
38
+ * Replaces single quotes with '\'' and wraps in single quotes.
39
+ */
40
+ export declare function escapeShellArg(arg: string): string;
41
+ /**
42
+ * Supported JavaScript runtimes.
43
+ */
44
+ export type Runtime = "bun" | "node" | "deno";
45
+ /**
46
+ * Detect the current JavaScript runtime.
47
+ * Uses global object inspection following the crossws pattern.
48
+ *
49
+ * @returns The detected runtime ('bun', 'deno', or 'node')
50
+ */
51
+ export declare function detectRuntime(): Runtime;
52
+ /**
53
+ * Get the current runtime name and version as a string.
54
+ * e.g. "bun 1.2.0", "node 22.0.0", "deno 2.1.0"
55
+ */
56
+ export declare function getRuntimeVersion(): string;
57
+ /**
58
+ * Detects if we're running from a compiled Bun executable.
59
+ *
60
+ * When compiled, Bun puts files in a virtual filesystem at:
61
+ * - On Unix: /$bunfs/root/...
62
+ * - On Windows: X:/~BUN/root/... (drive letter varies)
63
+ *
64
+ * @returns true if running from a compiled executable, false otherwise
65
+ */
66
+ export declare function isCompiledExecutable(): boolean;
67
+ /**
68
+ * Schema for application metadata.
69
+ * This is embedded in compiled executables and used to track version info.
70
+ */
71
+ export declare const metadataSchema: z.ZodObject<{
72
+ version: z.ZodString;
73
+ buildDate: z.ZodOptional<z.ZodString>;
74
+ buildTarget: z.ZodOptional<z.ZodString>;
75
+ }, "strip", z.ZodTypeAny, {
76
+ version: string;
77
+ buildDate?: string | undefined;
78
+ buildTarget?: string | undefined;
79
+ }, {
80
+ version: string;
81
+ buildDate?: string | undefined;
82
+ buildTarget?: string | undefined;
83
+ }>;
84
+ export type Metadata = z.infer<typeof metadataSchema>;
85
+ /**
86
+ * Metadata class for managing application metadata.
87
+ * Supports serialization/deserialization and validation via Zod.
88
+ */
89
+ export declare class AppMetadata {
90
+ private data;
91
+ private constructor();
92
+ /**
93
+ * Create metadata from object (validates with Zod schema)
94
+ */
95
+ static create(data: unknown): AppMetadata;
96
+ /**
97
+ * Deserialize metadata from JSON string
98
+ */
99
+ static deserialize(json: string): AppMetadata;
100
+ /**
101
+ * Serialize metadata to JSON string
102
+ */
103
+ serialize(): string;
104
+ /**
105
+ * Get the version string
106
+ */
107
+ get version(): string;
108
+ /**
109
+ * Get the build date (if available)
110
+ */
111
+ get buildDate(): string | undefined;
112
+ /**
113
+ * Get the build target (if available)
114
+ */
115
+ get buildTarget(): string | undefined;
116
+ /**
117
+ * Get raw metadata object
118
+ */
119
+ toObject(): Metadata;
120
+ }
121
+ /**
122
+ * Get application metadata (version, build info, etc.).
123
+ * Works in both development (reads from filesystem) and compiled executable
124
+ * (uses build-time constants) contexts.
125
+ *
126
+ * In compiled mode: Uses BUILD_VERSION, BUILD_DATE, BUILD_TARGET constants
127
+ * In dev mode: Reads from package.json
128
+ *
129
+ * @returns AppMetadata instance, or metadata with fallback version
130
+ */
131
+ export declare function getMetadata(): AppMetadata;
132
+ /**
133
+ * Render the startup banner box with version and platform info.
134
+ * Matches the style of the codon structure boxes.
135
+ */
136
+ export declare function renderStartupBanner(): void;
137
+ /**
138
+ * Shorten a path by replacing the home directory with ~
139
+ */
140
+ export declare function shortenPath(fullPath: string): string;
141
+ export interface StartupInfo {
142
+ executionId: string;
143
+ isResuming: boolean;
144
+ sourcePath: string;
145
+ executionPath: string;
146
+ linkType: string;
147
+ sdks: Array<{
148
+ name: string;
149
+ version: string;
150
+ cached: boolean;
151
+ }>;
152
+ }
153
+ /**
154
+ * Render the execution info section after the startup banner.
155
+ */
156
+ export declare function renderStartupInfo(info: StartupInfo): void;
157
+ /**
158
+ * Get the appropriate command array to run a script in the current runtime.
159
+ * This ensures shims and other scripts are executed with the correct runtime.
160
+ *
161
+ * For compiled executables, we check if 'bun' is available on PATH and use it
162
+ * if present (for better performance), otherwise fall back to 'node'.
163
+ * This ensures standalone executables work on systems without Bun installed.
164
+ *
165
+ * @param scriptPath - Path to the script to execute
166
+ * @returns Command array suitable for spawn/exec (e.g., ['bun', scriptPath])
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * // In Bun (source): ['bun', '/path/to/shim.mjs']
171
+ * // In compiled executable with bun on PATH: ['bun', '/path/to/shim.mjs']
172
+ * // In compiled executable without bun: ['node', '/path/to/shim.mjs']
173
+ * // In Node: ['node', '/path/to/shim.mjs']
174
+ * // In Deno: ['deno', 'run', '--allow-all', '/path/to/shim.mjs']
175
+ * const cmd = getRuntimeCommand('/path/to/shim.mjs');
176
+ * spawn(cmd[0], cmd.slice(1), options);
177
+ * ```
178
+ */
179
+ export declare function getRuntimeCommand(scriptPath: string): string[];
180
+ /**
181
+ * Type guard to check if a value is an Error instance.
182
+ */
183
+ export declare function isError(error: unknown): error is Error;
184
+ /**
185
+ * Convert any value to an Error instance.
186
+ * If already an Error, returns it unchanged.
187
+ * Otherwise creates a new Error with string representation.
188
+ */
189
+ export declare function toError(error: unknown): Error;
190
+ /**
191
+ * Helper type to check if two types are exactly equal at compile time.
192
+ * Returns `true` if the types match, `never` if they don't.
193
+ *
194
+ * Use this to enforce type constraints that must be validated at compile time.
195
+ *
196
+ * @example
197
+ * // Ensure all event types are categorized
198
+ * const _check: AssertEqual<EventType, CategoryA | CategoryB> = true;
199
+ */
200
+ export type AssertEqual<T, U> = (<G>() => G extends T ? 1 : 2) extends <G>() => G extends U ? 1 : 2 ? true : never;
201
+ /**
202
+ * Exhaustive checking helper for switch statements.
203
+ * Use this in the default case to ensure all union cases are handled.
204
+ * TypeScript will error if a case is missing.
205
+ */
206
+ export declare function assertNever(x: never): never;
207
+ export declare class IdleTimeoutError extends Error {
208
+ readonly timeoutMs: number;
209
+ constructor(timeoutMs: number);
210
+ }
211
+ /**
212
+ * Wraps an async iterable with an idle timeout. If no event is received
213
+ * within `timeoutMs` milliseconds, throws an `IdleTimeoutError`.
214
+ *
215
+ * The timer resets on each received event, so long-running operations
216
+ * that produce regular events will not be interrupted.
217
+ */
218
+ export declare function withIdleTimeout<T>(events: AsyncIterable<T>, timeoutMs: number): AsyncGenerator<T>;
219
+ /**
220
+ * Calculate the total size of a directory recursively.
221
+ * Includes a timeout to prevent hanging on large directories.
222
+ */
223
+ export declare function getDirectorySize(dirPath: string, timeoutMs?: number): Promise<number>;
224
+ /**
225
+ * Format a byte size into a human-readable string.
226
+ */
227
+ export declare function formatSize(bytes: number): string;
228
+ /**
229
+ * Generate a non-conflicting filename by adding a numbered suffix with timestamp.
230
+ * Format: file_<counter>_<timestamp>.txt (e.g., report_1_1738678800.txt)
231
+ *
232
+ * @param destPath - The desired destination path
233
+ * @returns Object with resolved path and conflict info
234
+ * @throws Error if more than MAX_CONFLICT_COPIES exist (prevents runaway loops)
235
+ */
236
+ export declare function resolveFileConflict(destPath: string): Promise<{
237
+ resolvedPath: string;
238
+ hadConflict: boolean;
239
+ conflictNumber?: number;
240
+ timestamp?: number;
241
+ }>;
242
+ /**
243
+ * Copy files from a source directory to a destination directory using glob patterns.
244
+ *
245
+ * This function uses fast-glob directly to resolve file patterns without respecting
246
+ * .gitignore rules (unlike UnifiedFileResolver), ensuring all matching files are copied regardless of git ignore status.
247
+ *
248
+ * @param sourceDirectory - The source directory path from which to copy files
249
+ * @param filesToCopy - Array of glob patterns to match files for copying (e.g., `["*.txt"]`)
250
+ * @param destinationDirectory - The destination directory path where files will be copied
251
+ * @param logger - Logger instance for debug and info messages
252
+ * @param options - Optional settings
253
+ * @param options.overwrite - When true, overwrite existing files instead of renaming
254
+ * @returns Promise with conflicts array listing any files that were renamed
255
+ */
256
+ export declare function copyFiles(sourceDirectory: string, filesToCopy: string[], destinationDirectory: string, logger: Logger, options?: {
257
+ overwrite?: boolean;
258
+ }): Promise<{
259
+ conflicts: Array<{
260
+ original: string;
261
+ resolved: string;
262
+ }>;
263
+ }>;
264
+ /**
265
+ * Deep merge multiple objects with proper handling of nested structures.
266
+ *
267
+ * Uses lodash.merge for deep merging. Note that arrays are merged by index
268
+ * (not replaced entirely).
269
+ *
270
+ * Merging rules:
271
+ * - Plain objects are merged recursively
272
+ * - Arrays are merged by index (e.g., [1,2,3] + [4,5] = [4,5,3])
273
+ * - Primitives (string, number, boolean, null) are replaced
274
+ * - Later sources take precedence over earlier ones
275
+ *
276
+ * @param sources - Objects to merge, in priority order (later = higher priority)
277
+ * @returns Merged object with all properties from all sources
278
+ *
279
+ * @example
280
+ * const defaults = { port: 8080, sentinel: { enabled: true, timeout: 1000 } };
281
+ * const userConfig = { port: 3000, sentinel: { timeout: 5000 } };
282
+ * const merged = deepMerge(defaults, userConfig);
283
+ * // Result: { port: 3000, sentinel: { enabled: true, timeout: 5000 } }
284
+ */
285
+ export declare function deepMerge<T extends Record<string, unknown>>(...sources: Array<T | undefined>): T;
286
+ /**
287
+ * Rename file with retry logic for Windows file locking issues.
288
+ *
289
+ * On Windows, EPERM/EBUSY errors can occur transiently due to:
290
+ * - Antivirus scanning (Windows Defender in CI environments)
291
+ * - File handles not fully released after previous operations
292
+ * - Windows filesystem timing differences vs Unix
293
+ *
294
+ * This implements exponential backoff retry to handle these transient locks.
295
+ *
296
+ * @param source - Source file path
297
+ * @param target - Target file path
298
+ * @param options - Retry configuration options
299
+ * @param options.maxRetries - Maximum number of retry attempts (default: 5)
300
+ * @param options.initialDelay - Initial delay in milliseconds (default: 10ms)
301
+ * @param options.logger - Optional logger for debugging retry attempts
302
+ * @returns Promise that resolves when rename succeeds
303
+ * @throws Error if rename fails after all retries or encounters non-retryable error
304
+ *
305
+ * @example
306
+ * ```ts
307
+ * // Basic usage
308
+ * await renameWithRetry('temp.json', 'state.json');
309
+ *
310
+ * // With custom retry settings and logging
311
+ * await renameWithRetry('temp.json', 'state.json', {
312
+ * maxRetries: 10,
313
+ * initialDelay: 20,
314
+ * logger: myLogger
315
+ * });
316
+ * ```
317
+ */
318
+ export declare function renameWithRetry(source: string, target: string, options?: {
319
+ maxRetries?: number;
320
+ initialDelay?: number;
321
+ logger?: Logger;
322
+ }): Promise<void>;
323
+ /**
324
+ * Synchronous version of renameWithRetry for use in synchronous contexts.
325
+ *
326
+ * Same behavior as renameWithRetry but uses synchronous fs operations.
327
+ * Useful for scenarios where async/await cannot be used.
328
+ *
329
+ * @param source - Source file path
330
+ * @param target - Target file path
331
+ * @param options - Retry configuration options
332
+ * @param options.maxRetries - Maximum number of retry attempts (default: 5)
333
+ * @param options.initialDelay - Initial delay in milliseconds (default: 10ms)
334
+ * @param options.logger - Optional logger for debugging retry attempts
335
+ * @throws Error if rename fails after all retries or encounters non-retryable error
336
+ *
337
+ * @example
338
+ * ```ts
339
+ * renameWithRetrySync('temp.json', 'state.json');
340
+ * ```
341
+ */
342
+ export declare function renameWithRetrySync(source: string, target: string, options?: {
343
+ maxRetries?: number;
344
+ initialDelay?: number;
345
+ logger?: Logger;
346
+ }): void;
347
+ /**
348
+ * Synchronous directory/file removal with retry logic for Windows file locking issues.
349
+ *
350
+ * On Windows, file handles can take time to release after process termination,
351
+ * causing EBUSY/EPERM errors when trying to delete directories. This function
352
+ * retries the operation with exponential backoff to handle these transient errors.
353
+ *
354
+ * @param targetPath - Path to file or directory to remove
355
+ * @param options - Removal and retry configuration options
356
+ * @param options.recursive - Allow recursive removal of directories (default: false)
357
+ * @param options.force - Continue even if path doesn't exist (default: false)
358
+ * @param options.maxRetries - Maximum number of retry attempts (default: 5)
359
+ * @param options.initialDelay - Initial delay in milliseconds (default: 10ms)
360
+ * @param options.logger - Optional logger for debugging retry attempts
361
+ * @throws Error if removal fails after all retries or encounters non-retryable error
362
+ *
363
+ * @example
364
+ * ```ts
365
+ * rmSyncWithRetry(tempDir, { recursive: true, force: true, logger });
366
+ * ```
367
+ */
368
+ export declare function rmSyncWithRetry(targetPath: string, options?: {
369
+ recursive?: boolean;
370
+ force?: boolean;
371
+ maxRetries?: number;
372
+ initialDelay?: number;
373
+ logger?: Logger;
374
+ }): void;
375
+ /**
376
+ * Abstraction over server instances providing a common interface.
377
+ * This allows the codebase to be runtime-agnostic.
378
+ */
379
+ export interface HankweaveServer {
380
+ /** Stop the server and clean up resources */
381
+ stop(): void;
382
+ /** The actual port the server is listening on (may differ from configured port if 0 was specified) */
383
+ readonly port: number;
384
+ }
385
+ /**
386
+ * Runtime-agnostic WebSocket interface.
387
+ * Provides a common interface that works across Bun, Node.js, and other runtimes.
388
+ */
389
+ export interface HankweaveWebSocket<T = unknown> {
390
+ /** Custom data attached to this WebSocket connection */
391
+ data: T;
392
+ /** Send a message to the client */
393
+ send(message: string | Buffer): void;
394
+ /** Close the WebSocket connection */
395
+ close(code?: number, reason?: string): void;
396
+ }
397
+ /**
398
+ * Configuration options for creating an HTTP or WebSocket server.
399
+ * Provides a runtime-agnostic interface for both HTTP and WebSocket servers.
400
+ *
401
+ * The generic type T represents the WebSocket connection data type.
402
+ */
403
+ export interface ServeOptions<T = unknown> {
404
+ /** Port number to listen on */
405
+ port: number;
406
+ /** Idle timeout in seconds (optional, only for HTTP servers) */
407
+ idleTimeout?: number;
408
+ /** HTTP request handler (required for HTTP servers) */
409
+ fetch?: (request: Request, server?: unknown) => Response | Promise<Response> | undefined;
410
+ /** WebSocket handlers (required for WebSocket servers) */
411
+ websocket?: {
412
+ /**
413
+ * Called before upgrading to WebSocket.
414
+ * Return context data to attach to the connection.
415
+ */
416
+ upgrade?: (request: Request) => T | Promise<T>;
417
+ /** Called when a WebSocket connection is opened */
418
+ open?: (ws: HankweaveWebSocket<T>) => void;
419
+ /** Called when a message is received on the WebSocket */
420
+ message?: (ws: HankweaveWebSocket<T>, message: string | Buffer) => void;
421
+ /** Called when a WebSocket connection is closed */
422
+ close?: (ws: HankweaveWebSocket<T>) => void;
423
+ };
424
+ }
425
+ /**
426
+ * Create an HTTP or WebSocket server using crossws.
427
+ *
428
+ * This provides a runtime-agnostic interface that works with Bun, Node.js, Deno,
429
+ * and other runtimes via the crossws library.
430
+ *
431
+ * @param options - Server configuration options
432
+ * @returns Server instance with stop() method
433
+ *
434
+ * @example
435
+ * // HTTP server
436
+ * const server = serve({
437
+ * port: 3000,
438
+ * fetch: async (req) => new Response("Hello"),
439
+ * });
440
+ *
441
+ * @example
442
+ * // WebSocket server
443
+ * const server = serve({
444
+ * port: 8080,
445
+ * websocket: {
446
+ * open: (ws) => console.log("connected"),
447
+ * message: (ws, msg) => console.log(msg),
448
+ * },
449
+ * fetch: (req, server) => server.upgrade(req),
450
+ * });
451
+ */
452
+ export declare function serve<T = unknown>(options: ServeOptions<T>): HankweaveServer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hankweave",
3
- "version": "0.5.7",
3
+ "version": "0.6.2",
4
4
  "description": "Orchestration runtime for antibrittle agentic workflows",
5
5
  "author": {
6
6
  "name": "Southbridge AI",
@@ -18,9 +18,21 @@
18
18
  "hankweave": "dist/index.js"
19
19
  },
20
20
  "main": "./dist/index.js",
21
+ "exports": {
22
+ ".": "./dist/index.js",
23
+ "./schemas": {
24
+ "types": "./dist/exports/schemas.d.ts",
25
+ "import": "./dist/exports/schemas.js",
26
+ "default": "./dist/exports/schemas.js"
27
+ },
28
+ "./types": {
29
+ "types": "./dist/exports/types.d.ts",
30
+ "import": "./dist/exports/types.js",
31
+ "default": "./dist/exports/types.js"
32
+ }
33
+ },
21
34
  "files": [
22
35
  "dist",
23
- "shims",
24
36
  "schemas"
25
37
  ],
26
38
  "engines": {
@@ -54,6 +66,7 @@
54
66
  "cleanup": "echo 'Error: --cleanup requires --config' && exit 1",
55
67
  "cleanup:example": "bun server/index.ts --cleanup --config=hank.json",
56
68
  "cleanup:force": "bun server/index.ts --cleanup --config=hank.json -y",
69
+ "test:shims": "bun scripts/test-shims.ts",
57
70
  "test:cross-runtime:bun": "bun scripts/run-cross-runtime-tests.ts bun",
58
71
  "test:cross-runtime:node": "bun scripts/run-cross-runtime-tests.ts node",
59
72
  "test:cross-runtime:deno": "bun scripts/run-cross-runtime-tests.ts deno",
@@ -76,8 +76,51 @@
76
76
  "shimIdleTimeout": {
77
77
  "type": "integer",
78
78
  "exclusiveMinimum": 0,
79
- "maximum": 600,
79
+ "maximum": 1800,
80
80
  "description": "Default shim idle timeout for all codons in this hank (seconds)"
81
+ },
82
+ "budget": {
83
+ "type": "object",
84
+ "properties": {
85
+ "maxDollars": {
86
+ "type": "number",
87
+ "exclusiveMinimum": 0,
88
+ "description": "Total cost budget in USD."
89
+ },
90
+ "maxTimeSeconds": {
91
+ "type": "number",
92
+ "exclusiveMinimum": 0,
93
+ "description": "Wall-clock time limit in seconds."
94
+ },
95
+ "allocation": {
96
+ "type": "string",
97
+ "enum": [
98
+ "shared",
99
+ "proportional",
100
+ "proportional-strict"
101
+ ],
102
+ "default": "shared",
103
+ "description": "How the dollar budget is distributed among children. 'shared': first-past-the-post (default). 'proportional': pre-allocate shares, unspent flows back. 'proportional-strict': pre-allocate shares, unspent evaporates."
104
+ },
105
+ "shares": {
106
+ "type": "object",
107
+ "additionalProperties": {
108
+ "type": "number",
109
+ "exclusiveMinimum": 0,
110
+ "maximum": 1
111
+ },
112
+ "description": "Map of child codon/loop ID to fraction (0-1) of the budget."
113
+ },
114
+ "onExceeded": {
115
+ "type": "string",
116
+ "enum": [
117
+ "complete",
118
+ "fail"
119
+ ],
120
+ "description": "What happens when budget is exceeded. 'complete' = graceful completion (default). 'fail' = codon failure, triggers onFailure policy."
121
+ }
122
+ },
123
+ "additionalProperties": false
81
124
  }
82
125
  },
83
126
  "additionalProperties": false,
@@ -1098,8 +1141,42 @@
1098
1141
  "shimIdleTimeout": {
1099
1142
  "type": "integer",
1100
1143
  "exclusiveMinimum": 0,
1101
- "maximum": 600,
1144
+ "maximum": 1800,
1102
1145
  "description": "Max seconds between agent events before the shim aborts (idle timeout). Overrides hank-level and runtime defaults. If unset, falls back to hank override, runtime config, or shim default (120s)."
1146
+ },
1147
+ "budget": {
1148
+ "type": "object",
1149
+ "properties": {
1150
+ "maxDollars": {
1151
+ "type": "number",
1152
+ "exclusiveMinimum": 0,
1153
+ "description": "Max cost in USD. Execution stopped when exceeded."
1154
+ },
1155
+ "maxTimeSeconds": {
1156
+ "type": "number",
1157
+ "exclusiveMinimum": 0,
1158
+ "description": "Max wall-clock time in seconds."
1159
+ },
1160
+ "maxOutputTokens": {
1161
+ "type": "integer",
1162
+ "exclusiveMinimum": 0,
1163
+ "description": "Max output tokens."
1164
+ },
1165
+ "maxContextTokens": {
1166
+ "type": "integer",
1167
+ "exclusiveMinimum": 0,
1168
+ "description": "Max context window tokens (high-water mark of input+output per turn). Useful for capping context growth independent of cost."
1169
+ },
1170
+ "onExceeded": {
1171
+ "type": "string",
1172
+ "enum": [
1173
+ "complete",
1174
+ "fail"
1175
+ ],
1176
+ "description": "Override hank-level onExceeded for this codon."
1177
+ }
1178
+ },
1179
+ "additionalProperties": false
1103
1180
  }
1104
1181
  },
1105
1182
  "required": [
@@ -2181,8 +2258,42 @@
2181
2258
  "shimIdleTimeout": {
2182
2259
  "type": "integer",
2183
2260
  "exclusiveMinimum": 0,
2184
- "maximum": 600,
2261
+ "maximum": 1800,
2185
2262
  "description": "Max seconds between agent events before the shim aborts (idle timeout). Overrides hank-level and runtime defaults. If unset, falls back to hank override, runtime config, or shim default (120s)."
2263
+ },
2264
+ "budget": {
2265
+ "type": "object",
2266
+ "properties": {
2267
+ "maxDollars": {
2268
+ "type": "number",
2269
+ "exclusiveMinimum": 0,
2270
+ "description": "Max cost in USD. Execution stopped when exceeded."
2271
+ },
2272
+ "maxTimeSeconds": {
2273
+ "type": "number",
2274
+ "exclusiveMinimum": 0,
2275
+ "description": "Max wall-clock time in seconds."
2276
+ },
2277
+ "maxOutputTokens": {
2278
+ "type": "integer",
2279
+ "exclusiveMinimum": 0,
2280
+ "description": "Max output tokens."
2281
+ },
2282
+ "maxContextTokens": {
2283
+ "type": "integer",
2284
+ "exclusiveMinimum": 0,
2285
+ "description": "Max context window tokens (high-water mark of input+output per turn). Useful for capping context growth independent of cost."
2286
+ },
2287
+ "onExceeded": {
2288
+ "type": "string",
2289
+ "enum": [
2290
+ "complete",
2291
+ "fail"
2292
+ ],
2293
+ "description": "Override hank-level onExceeded for this codon."
2294
+ }
2295
+ },
2296
+ "additionalProperties": false
2186
2297
  }
2187
2298
  },
2188
2299
  "required": [
@@ -2196,6 +2307,50 @@
2196
2307
  "minItems": 1,
2197
2308
  "description": "Array of codons to execute in each iteration"
2198
2309
  },
2310
+ "budget": {
2311
+ "type": "object",
2312
+ "properties": {
2313
+ "maxDollars": {
2314
+ "type": "number",
2315
+ "exclusiveMinimum": 0,
2316
+ "description": "Total cost budget in USD."
2317
+ },
2318
+ "maxTimeSeconds": {
2319
+ "type": "number",
2320
+ "exclusiveMinimum": 0,
2321
+ "description": "Wall-clock time limit in seconds."
2322
+ },
2323
+ "allocation": {
2324
+ "type": "string",
2325
+ "enum": [
2326
+ "shared",
2327
+ "proportional",
2328
+ "proportional-strict"
2329
+ ],
2330
+ "default": "shared",
2331
+ "description": "How the dollar budget is distributed among children. 'shared': first-past-the-post (default). 'proportional': pre-allocate shares, unspent flows back. 'proportional-strict': pre-allocate shares, unspent evaporates."
2332
+ },
2333
+ "shares": {
2334
+ "type": "object",
2335
+ "additionalProperties": {
2336
+ "type": "number",
2337
+ "exclusiveMinimum": 0,
2338
+ "maximum": 1
2339
+ },
2340
+ "description": "Map of child codon/loop ID to fraction (0-1) of the budget."
2341
+ },
2342
+ "onExceeded": {
2343
+ "type": "string",
2344
+ "enum": [
2345
+ "complete",
2346
+ "fail"
2347
+ ],
2348
+ "description": "What happens when budget is exceeded. 'complete' = graceful completion (default). 'fail' = codon failure, triggers onFailure policy."
2349
+ }
2350
+ },
2351
+ "additionalProperties": false,
2352
+ "description": "Budget scope for this loop."
2353
+ },
2199
2354
  "archiveOnSuccess": {
2200
2355
  "type": "array",
2201
2356
  "items": {