@nyxa/automation 0.1.0

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 (48) hide show
  1. package/README.md +559 -0
  2. package/dist/cancellation.d.ts +1 -0
  3. package/dist/cancellation.js +5 -0
  4. package/dist/claude-code.d.ts +19 -0
  5. package/dist/claude-code.js +182 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.js +487 -0
  8. package/dist/codex-output.d.ts +6 -0
  9. package/dist/codex-output.js +167 -0
  10. package/dist/codex.d.ts +17 -0
  11. package/dist/codex.js +228 -0
  12. package/dist/doctor.d.ts +17 -0
  13. package/dist/doctor.js +138 -0
  14. package/dist/errors.d.ts +30 -0
  15. package/dist/errors.js +51 -0
  16. package/dist/events.d.ts +55 -0
  17. package/dist/events.js +51 -0
  18. package/dist/filesystem.d.ts +2 -0
  19. package/dist/filesystem.js +13 -0
  20. package/dist/harness-process.d.ts +39 -0
  21. package/dist/harness-process.js +359 -0
  22. package/dist/harness-prompt.d.ts +2 -0
  23. package/dist/harness-prompt.js +14 -0
  24. package/dist/harness.d.ts +44 -0
  25. package/dist/harness.js +68 -0
  26. package/dist/index.d.ts +10 -0
  27. package/dist/index.js +9 -0
  28. package/dist/init.d.ts +1 -0
  29. package/dist/init.js +305 -0
  30. package/dist/json.d.ts +4 -0
  31. package/dist/json.js +1 -0
  32. package/dist/kimi-code.d.ts +16 -0
  33. package/dist/kimi-code.js +299 -0
  34. package/dist/opencode.d.ts +15 -0
  35. package/dist/opencode.js +164 -0
  36. package/dist/run-coordination.d.ts +10 -0
  37. package/dist/run-coordination.js +96 -0
  38. package/dist/run-journal.d.ts +14 -0
  39. package/dist/run-journal.js +129 -0
  40. package/dist/schema.d.ts +167 -0
  41. package/dist/schema.js +516 -0
  42. package/dist/standard-input.d.ts +1 -0
  43. package/dist/standard-input.js +7 -0
  44. package/dist/type-utils.d.ts +1 -0
  45. package/dist/type-utils.js +1 -0
  46. package/dist/workflow.d.ts +160 -0
  47. package/dist/workflow.js +530 -0
  48. package/package.json +51 -0
package/README.md ADDED
@@ -0,0 +1,559 @@
1
+ # @nyxa/automation
2
+
3
+ Write trusted TypeScript Workflows and execute them explicitly from Node.js or
4
+ the `automation` CLI. Node.js 22 or later is required.
5
+
6
+ ## Security and responsibility
7
+
8
+ A Workflow is trusted local code, not a sandboxed configuration file. It runs
9
+ with the permissions of the process that starts Automation and can use the same
10
+ filesystem, environment, and network access as that process. Only execute
11
+ Workflows whose source you trust, and choose each Run's Access Policy
12
+ deliberately.
13
+
14
+ Automation invokes the user's local Codex, Claude Code, Kimi Code, and OpenCode
15
+ CLIs.
16
+ Their authentication, subscriptions, and quotas remain the user's
17
+ responsibility; Automation does not manage provider accounts, credentials,
18
+ billing, or limits.
19
+
20
+ ## Install
21
+
22
+ ```sh
23
+ npm install --save-dev @nyxa/automation
24
+ ```
25
+
26
+ The package includes its TypeScript runtime loader. A project does not need a
27
+ global TypeScript or `tsx` installation to run a Workflow.
28
+
29
+ ## Initialize an existing project
30
+
31
+ Run `init` from a project that already has a `package.json`. It refuses to
32
+ overwrite the requested Workflow and detects npm, pnpm, or Yarn from the
33
+ project lockfile before offering to add Automation as a development dependency:
34
+
35
+ ```sh
36
+ npx @nyxa/automation init workflows/first.ts
37
+ ```
38
+
39
+ Choose the Harness explicitly for non-interactive use. `--no-install` only
40
+ generates the Workflow; `--yes` accepts installation and, when `--harness` is
41
+ omitted, selects a Harness only if exactly one local Harness is operational.
42
+
43
+ ```sh
44
+ npx @nyxa/automation init workflows/codex.ts --harness codex --yes
45
+ npx @nyxa/automation init workflows/claude.ts --harness claude-code --no-install
46
+ npx @nyxa/automation init workflows/kimi.ts --harness kimi-code --no-install
47
+ npx @nyxa/automation init workflows/opencode.ts --harness opencode --no-install
48
+ ```
49
+
50
+ The generated Workflow imports only the selected Harness, requests a documented
51
+ structured result, and handles a `needs_input` result with ordinary TypeScript
52
+ control flow.
53
+
54
+ ## Diagnose the local environment
55
+
56
+ Run `doctor` before a Workflow to check Node.js, the project-local Automation
57
+ package, and the installed Codex, Claude Code, Kimi Code, and OpenCode
58
+ Harnesses:
59
+
60
+ ```sh
61
+ npx automation doctor
62
+ npx automation doctor --harness codex
63
+ npx automation doctor --harness claude-code
64
+ npx automation doctor --harness kimi-code
65
+ npx automation doctor --harness opencode
66
+ ```
67
+
68
+ The command checks Harness versions and verifies authentication headlessly.
69
+ For Kimi Code it performs the ACP initialization and authentication handshake;
70
+ it never launches `kimi login`. For OpenCode it reads `opencode auth list` and
71
+ considers authentication verified only when the CLI reports a stored credential
72
+ or authentication environment variable. It does not import a Workflow, change
73
+ project files, install software, or start an interactive authentication flow.
74
+ Without a filter, one fully operational Harness is sufficient and missing
75
+ Harnesses are reported as warnings. With `--harness`, the requested Harness
76
+ must be fully operational.
77
+
78
+ ## Define a Workflow
79
+
80
+ ```ts
81
+ // workflow.ts
82
+ import { defineWorkflow } from "@nyxa/automation";
83
+
84
+ const workflow = defineWorkflow({
85
+ async run() {
86
+ return { status: "ready", count: 1 };
87
+ },
88
+ });
89
+
90
+ export default workflow;
91
+ ```
92
+
93
+ Importing this module only creates an inert Workflow Definition. Execution is
94
+ always explicit:
95
+
96
+ ```ts
97
+ import { executeWorkflow } from "@nyxa/automation";
98
+ import workflow from "./workflow.js";
99
+
100
+ const result = await executeWorkflow(workflow);
101
+ // result is inferred as { status: string; count: number }
102
+ ```
103
+
104
+ ## Run Codex
105
+
106
+ Use the local Codex CLI as a Harness. Automation requires Codex CLI 0.144.0 or
107
+ later, performs the version preflight once per resolved executable, and keeps
108
+ the user's existing authentication and local configuration.
109
+
110
+ ```ts
111
+ import { codex, defineWorkflow } from "@nyxa/automation";
112
+
113
+ const workflow = defineWorkflow({
114
+ harness: codex(),
115
+ async run(context) {
116
+ return context.run("Inspect this project and summarize its architecture.", {
117
+ access: "read",
118
+ });
119
+ },
120
+ });
121
+
122
+ export default workflow;
123
+ ```
124
+
125
+ Runs are headless and require an explicit Access Policy. A Run can replace the
126
+ Workflow's default Harness, and Codex-specific options are only passed when
127
+ declared:
128
+
129
+ ```ts
130
+ const reviewHarness = codex({
131
+ executable: "/opt/codex/bin/codex",
132
+ model: "gpt-test",
133
+ effort: "high",
134
+ profile: "ci",
135
+ });
136
+
137
+ const reviewWorkflow = defineWorkflow({
138
+ async run(context) {
139
+ return context.run("Review the proposed change.", {
140
+ access: "read",
141
+ harness: reviewHarness,
142
+ name: "review",
143
+ });
144
+ },
145
+ });
146
+ ```
147
+
148
+ ## Run Claude Code
149
+
150
+ Use `claudeCode()` to run the same Workflow contract with the local Claude Code
151
+ CLI. Automation requires Claude Code 2.1.205 or later. Omitting an option keeps
152
+ the corresponding local Harness configuration; Automation does not require a
153
+ model name or reasoning effort.
154
+
155
+ ```ts
156
+ import { claudeCode, defineWorkflow } from "@nyxa/automation";
157
+
158
+ const workflow = defineWorkflow({
159
+ harness: claudeCode({
160
+ model: "claude-test",
161
+ effort: "high",
162
+ fallbackModel: "claude-fallback",
163
+ maxTurns: 8,
164
+ maxBudgetUsd: 2,
165
+ }),
166
+ run: (context) =>
167
+ context.run("Inspect this project and summarize its architecture.", {
168
+ access: "read",
169
+ }),
170
+ });
171
+
172
+ export default workflow;
173
+ ```
174
+
175
+ ## Run Kimi Code
176
+
177
+ Use `kimiCode()` with Kimi Code CLI 0.28.1 or later. Automation starts the
178
+ official `kimi acp` server over stdio; ACP remains an adapter-private transport,
179
+ so the portable Workflow, Run, Session, event, and error APIs do not expose
180
+ JSON-RPC details. Install and authenticate Kimi Code separately before running
181
+ the Workflow.
182
+
183
+ ```ts
184
+ import { defineWorkflow, kimiCode } from "@nyxa/automation";
185
+
186
+ const workflow = defineWorkflow({
187
+ harness: kimiCode({
188
+ executable: "/opt/kimi/bin/kimi",
189
+ model: "kimi-for-coding",
190
+ effort: "high",
191
+ }),
192
+ run: (context) =>
193
+ context.run("Implement the requested change.", {
194
+ access: "full",
195
+ approval: "deny",
196
+ }),
197
+ });
198
+
199
+ export default workflow;
200
+ ```
201
+
202
+ Kimi model catalogs declare their own effort levels, so `effort` intentionally
203
+ accepts a string and is checked against the options advertised by the selected
204
+ model. An unsupported model or effort fails with
205
+ `HARNESS_CAPABILITY_UNSUPPORTED`.
206
+
207
+ ## Run OpenCode
208
+
209
+ Use `opencode()` with OpenCode CLI 1.18.4 or later. Automation invokes
210
+ `opencode run --format json`, keeps the local OpenCode configuration and
211
+ authentication, exposes completed JSONL records as native events, and resumes
212
+ explicit Sessions with the native OpenCode Session identifier.
213
+
214
+ ```ts
215
+ import { defineWorkflow, opencode } from "@nyxa/automation";
216
+
217
+ const workflow = defineWorkflow({
218
+ harness: opencode({
219
+ executable: "/opt/opencode/bin/opencode",
220
+ model: "provider/model",
221
+ effort: "high",
222
+ }),
223
+ run: (context) =>
224
+ context.run("Implement the requested change.", {
225
+ access: "full",
226
+ approval: "deny",
227
+ }),
228
+ });
229
+
230
+ export default workflow;
231
+ ```
232
+
233
+ OpenCode calls provider-specific reasoning levels “variants”, so Automation
234
+ maps the typed `effort` option to its native `--variant` flag. The adapter does
235
+ not accept arbitrary CLI arguments or override the locally configured default
236
+ agent.
237
+
238
+ All four factories accept an optional executable path, model, and effort. Codex
239
+ also accepts a local profile; Claude Code also accepts a fallback model, maximum
240
+ turn count, and budget in US dollars. A Run can override the Workflow's default
241
+ Harness without changing the portable Run API.
242
+
243
+ ## Continue a Session explicitly
244
+
245
+ Create a lazy Session handle when several sequential Runs should share one
246
+ native Codex, Claude Code, Kimi Code, or OpenCode conversation:
247
+
248
+ ```ts
249
+ const workflow = defineWorkflow({
250
+ async run(context) {
251
+ const session = context.session({
252
+ harness: codex({ model: "gpt-test", effort: "high" }),
253
+ cwd: "packages/api",
254
+ env: { REVIEW_MODE: "security" },
255
+ name: "authentication-review",
256
+ });
257
+
258
+ await session.run("Inspect the authentication flow.", { access: "read" });
259
+ return session.run("Propose the smallest safe change.", {
260
+ access: "write-workspace",
261
+ approval: "deny",
262
+ });
263
+ },
264
+ });
265
+ ```
266
+
267
+ Creating the handle does not inspect or start the Harness. Its Harness
268
+ configuration, `cwd`, environment overlay, and optional observability `name`
269
+ are fixed at creation. Each `session.run()` keeps its own Access Policy,
270
+ Approval Policy, Run name, and Output Contract, and may override or remove
271
+ variables from the Session environment.
272
+ Runs on one handle are sequential: an overlapping call fails immediately with
273
+ `SESSION_BUSY`.
274
+
275
+ After a clean native completion, later Runs resume the same conversation. If a
276
+ process or protocol failure makes continuity uncertain, the handle becomes
277
+ unavailable and later calls fail with `SESSION_UNAVAILABLE`; Automation never
278
+ silently creates a replacement. Ordinary `context.run()` calls and separate
279
+ Workflow executions always start independent Sessions.
280
+
281
+ ## Control Run execution
282
+
283
+ Every Run declares an `access` ceiling: `read`, `write-workspace`, or `full`.
284
+ The Approval Policy defaults to `deny`; `approval: "auto"` uses only a native
285
+ automatic mechanism and fails with `HARNESS_CAPABILITY_UNSUPPORTED` when the
286
+ selected Harness cannot provide one. The v1 API has no human approval mode.
287
+
288
+ ```ts
289
+ await context.run("Update the package documentation.", {
290
+ access: "write-workspace",
291
+ approval: "deny",
292
+ cwd: "packages/docs",
293
+ env: {
294
+ CI: "1",
295
+ DEBUG: undefined,
296
+ },
297
+ });
298
+ ```
299
+
300
+ `cwd` is resolved from the execution's Workspace root and must remain inside
301
+ it, including after symbolic links are resolved. Harness processes inherit the
302
+ host environment; `env` overlays string values and removes variables assigned
303
+ `undefined`.
304
+
305
+ An execution admits up to four concurrent Runs by default. Set another positive
306
+ integer through the library or CLI when the Workflow should use a different
307
+ global limit:
308
+
309
+ ```ts
310
+ await executeWorkflow(workflow, { concurrency: 2 });
311
+ ```
312
+
313
+ ```sh
314
+ npx automation workflow.ts --concurrency 2
315
+ ```
316
+
317
+ Several `read` Runs can share a Workspace within that limit. A
318
+ `write-workspace` or `full` Run requires exclusive access and fails immediately
319
+ with `WORKSPACE_CONCURRENCY_CONFLICT` when another Run is already reading or
320
+ writing the same canonical Workspace root. Automation does not queue that
321
+ conflict or create an isolated Workspace. To run writes in parallel, invoke the
322
+ Workflows with explicitly distinct `workspaceRoot` directories.
323
+
324
+ Each Run has a 30-minute timeout by default. Set `timeout` in milliseconds or
325
+ use `false` for an intentionally unbounded Run. Expiration fails the Run with
326
+ `RUN_TIMED_OUT`, terminates the Harness process tree, and makes an explicit
327
+ Session unavailable because its continuity can no longer be proven.
328
+
329
+ ```ts
330
+ await context.run("Perform the long-running review.", {
331
+ access: "read",
332
+ timeout: 5 * 60 * 1_000,
333
+ });
334
+ ```
335
+
336
+ Pass an `AbortSignal` to cancel a complete Workflow execution. The Workflow
337
+ Context exposes the execution signal so trusted Workflow logic can stop its own
338
+ non-Run work too. Cancellation fails active Runs with `RUN_CANCELLED` and
339
+ releases their concurrency slots and Workspace access.
340
+
341
+ ```ts
342
+ const controller = new AbortController();
343
+ const result = executeWorkflow(workflow, { signal: controller.signal });
344
+
345
+ controller.abort();
346
+ await result;
347
+ ```
348
+
349
+ In the CLI, the first Ctrl-C requests cancellation and allows up to five
350
+ seconds for cleanup. A second Ctrl-C forces the Harness process tree to stop
351
+ immediately. User-requested cancellation exits with status `130`; human mode
352
+ does not write a Workflow Result, while `--json` keeps `stdout` as Automation
353
+ Events JSONL only.
354
+
355
+ Codex maps the three access levels to its native sandboxes and rejects
356
+ automatic approval because its headless CLI has no non-human equivalent.
357
+ Claude Code maps the same levels to its permission and sandbox mechanisms and
358
+ uses its native `auto` mode when requested.
359
+
360
+ Kimi Code currently exposes no native ceiling that can guarantee `read` or
361
+ `write-workspace`, so its adapter refuses those Access Policies before starting
362
+ ACP. It supports only `full`: `approval: "deny"` selects ACP `default` mode and
363
+ rejects permission requests, while `approval: "auto"` selects ACP `auto` mode.
364
+ Interactive questions are always cancelled because Runs remain headless.
365
+
366
+ OpenCode also exposes no native shell sandbox that can guarantee `read` or
367
+ `write-workspace`, so those policies fail before the CLI is inspected or
368
+ started. It supports only `full`: with `approval: "deny"`, native permission
369
+ requests are rejected; with `approval: "auto"`, Automation passes OpenCode's
370
+ `--auto` flag. OpenCode's explicit local permission denials remain effective.
371
+
372
+ | Harness | `read` | `write-workspace` | `full` / `deny` | `full` / `auto` |
373
+ | --- | --- | --- | --- | --- |
374
+ | Codex | native read-only sandbox | native workspace sandbox | native full access, approvals denied | unsupported |
375
+ | Claude Code | native plan mode | native edit sandbox | native bypass mode | native auto mode |
376
+ | Kimi Code | unsupported | unsupported | ACP `default`, permissions denied | ACP `auto`, questions cancelled |
377
+ | OpenCode | unsupported | unsupported | full local CLI access, permission requests denied | full local CLI access, native `--auto` |
378
+
379
+ Runs never open an interactive input channel. Automation appends a headless
380
+ instruction to every prompt, and the Claude Code adapter disables its native
381
+ `AskUserQuestion` tool. If missing information is an expected outcome, model it
382
+ as a branch of the Output Contract and handle the typed value with ordinary
383
+ TypeScript control flow:
384
+
385
+ ```ts
386
+ const outcome = schema.union([
387
+ schema.object({
388
+ status: schema.literal("completed"),
389
+ result: schema.string(),
390
+ }).describe("Use when the task can be completed."),
391
+ schema.object({
392
+ status: schema.literal("needs_input"),
393
+ question: schema.string(),
394
+ choices: schema.array(schema.string()),
395
+ }).describe("Use when required information is missing."),
396
+ ]);
397
+
398
+ const result = await context.run("Choose the deployment target.", {
399
+ access: "read",
400
+ output: outcome,
401
+ });
402
+
403
+ if (result.status === "needs_input") {
404
+ return result;
405
+ }
406
+ ```
407
+
408
+ `needs_input` is an ordinary valid business result, not a Run Failure or a
409
+ reserved engine status. Codex and Claude Code receive the generated JSON Schema
410
+ through their native structured-output mechanisms. Kimi Code and OpenCode
411
+ receive the schema in the prompt and must return one JSON value without
412
+ surrounding text; their adapters parse it strictly. In every case Automation
413
+ validates the returned value independently before exposing it to the Workflow.
414
+
415
+ ## Observe execution
416
+
417
+ `executeWorkflow()` can deliver an ordered stream of correlated Automation
418
+ Events. Every event carries a Workflow identifier, sequence number, and
419
+ timestamp. Run events also carry technical Run and Session identifiers plus an
420
+ optional non-unique `name`.
421
+
422
+ ```ts
423
+ const result = await executeWorkflow(workflow, {
424
+ async onEvent(event) {
425
+ await persistEvent(event);
426
+
427
+ if (event.type === "run.failed") {
428
+ console.error(event.error.code, event.runId);
429
+ }
430
+ },
431
+ });
432
+ ```
433
+
434
+ Observers are awaited one at a time. If an observer fails, Automation stops all
435
+ active Harness processes and rejects with `EVENT_OBSERVER_FAILED`. Native
436
+ Harness events are available on `run.native` under an explicitly non-portable
437
+ envelope: `event.native` is `{ portable: false, event: unknown }`.
438
+
439
+ Execution failures use `AutomationError` with a stable `code`, the available
440
+ Workflow, Run, and Session identifiers, the Harness name, and an optional
441
+ native `cause`. Use `isAutomationError()` to narrow unknown failures.
442
+ Authentication refusals use `HARNESS_NOT_AUTHENTICATED`, unsupported
443
+ model-effort combinations use `HARNESS_CAPABILITY_UNSUPPORTED`, and a Run
444
+ Journal that cannot be initialized uses `RUN_JOURNAL_UNAVAILABLE`.
445
+
446
+ ## Record executions safely
447
+
448
+ Every execution creates a JSONL Run Journal in the user's private state
449
+ directory, outside the Workspace. By default, the journal contains ordered
450
+ Automation Event metadata, identifiers, names, durations, states, and portable
451
+ errors. It omits Workflow Inputs, prompts, Workflow Results, structured Run
452
+ outputs, native events, and environment values.
453
+
454
+ Use `record: "full"` only when sensitive diagnostic content may be persisted:
455
+
456
+ ```ts
457
+ await executeWorkflow(workflow, {
458
+ record: "full",
459
+ });
460
+ ```
461
+
462
+ Disable the journal with `record: false` or `--no-record`:
463
+
464
+ ```ts
465
+ await executeWorkflow(workflow, { record: false });
466
+ ```
467
+
468
+ ```sh
469
+ npx automation workflow.ts --no-record
470
+ ```
471
+
472
+ On Linux, journals use `$XDG_STATE_HOME/automation/run-journals` when that
473
+ variable contains an absolute path, otherwise
474
+ `~/.local/state/automation/run-journals`. Run Journals are diagnostic only:
475
+ Automation never reads them as a cache or checkpoint, and every invocation
476
+ starts the Workflow again from its Workflow Input. If the configured state
477
+ directory resolves inside the Workspace, Automation refuses to create the
478
+ journal; configure a state directory outside the Workspace or disable
479
+ recording for that invocation.
480
+
481
+ ## Validate Workflow boundaries
482
+
483
+ Use the built-in portable schema DSL for Workflow Inputs and Results. Schemas
484
+ also validate values directly with `parse()` or `safeParse()`.
485
+
486
+ ```ts
487
+ import { defineWorkflow, executeWorkflow, schema } from "@nyxa/automation";
488
+
489
+ const workflow = defineWorkflow({
490
+ input: schema.object({
491
+ name: schema.string().minLength(1).describe("The person to greet"),
492
+ language: schema.enum(["en", "fr"]).optional(),
493
+ }),
494
+ output: schema.object({ message: schema.string() }),
495
+ run({ input }) {
496
+ return { message: `Hello ${input.name}` };
497
+ },
498
+ });
499
+
500
+ const result = await executeWorkflow(workflow, {
501
+ input: { name: "Nyxa", language: "en" },
502
+ });
503
+ ```
504
+
505
+ ## Run from the CLI
506
+
507
+ The direct and explicit forms are equivalent:
508
+
509
+ ```sh
510
+ npx automation workflow.ts
511
+ npx automation run workflow.ts
512
+ ```
513
+
514
+ Provide a declared Workflow Input as inline JSON, from a file, or from standard
515
+ input. These sources are mutually exclusive.
516
+
517
+ ```sh
518
+ npx automation workflow.ts --input '{"name":"Nyxa"}'
519
+ npx automation workflow.ts --input-file input.json
520
+ printf '%s' '{"name":"Nyxa"}' | npx automation workflow.ts --input -
521
+ ```
522
+
523
+ Use `--json` for a JSONL stream containing only Automation Events on `stdout`.
524
+ The terminal `workflow.completed` event carries the Workflow Result.
525
+
526
+ ```sh
527
+ npx automation workflow.ts --json
528
+ ```
529
+
530
+ Strings are written to `stdout` as-is, other JSON values are serialized, and
531
+ an absent result writes nothing. Diagnostics use `stderr`; argument and module
532
+ loading errors exit with status `2`, while execution failures exit with status
533
+ `1`, successful execution exits with `0`, and cancelled execution exits with
534
+ `130`. Human-mode Run progress is also written to `stderr`, keeping `stdout`
535
+ reserved for the Workflow Result.
536
+
537
+ ## v1 scope
538
+
539
+ The v1 package includes the TypeScript library, CLI, schema DSL, and the Codex,
540
+ Claude Code, Kimi Code, and OpenCode Harness Adapters backed by their local
541
+ CLIs. It supports typed Workflow Inputs and Results, Output Contracts, explicit
542
+ Sessions, headless policies, Automation Events, Run Journals, `init`, and
543
+ `doctor`.
544
+
545
+ The following remain outside the v1 contract:
546
+
547
+ - direct provider API calls and model SDKs;
548
+ - a public plugin API for third-party Harness Adapters;
549
+ - interactive questions or human approvals during a Run;
550
+ - built-in retries, backoff, or idempotency guarantees;
551
+ - transparent resume, checkpoints, or cached Run reuse;
552
+ - automatic creation of isolated Workspaces or worktrees;
553
+ - arbitrary native Harness CLI arguments; and
554
+ - automated real-Harness smoke tests requiring installations, accounts, or
555
+ subscriptions.
556
+
557
+ Retries and repeated Runs must be explicit TypeScript control flow. Run
558
+ Journals are diagnostic records only and never enable transparent execution
559
+ resume.
@@ -0,0 +1 @@
1
+ export declare function throwIfAborted(signal: AbortSignal | undefined): void;
@@ -0,0 +1,5 @@
1
+ export function throwIfAborted(signal) {
2
+ if (signal?.aborted === true) {
3
+ throw signal.reason;
4
+ }
5
+ }
@@ -0,0 +1,19 @@
1
+ import { type Harness } from "./harness.js";
2
+ import type { NoExtraKeys } from "./type-utils.js";
3
+ export declare const CLAUDE_CODE_HARNESS_PREFLIGHT: {
4
+ readonly harnessName: "Claude Code";
5
+ readonly minimumVersion: readonly [2, 1, 205];
6
+ readonly unsupportedVersionMessage: "Claude Code CLI 2.1.205 or later is required.";
7
+ readonly versionPattern: RegExp;
8
+ };
9
+ export type ClaudeCodeEffort = "low" | "medium" | "high" | "xhigh" | "max" | "ultracode";
10
+ export interface ClaudeCodeOptions {
11
+ readonly executable?: string;
12
+ readonly model?: string;
13
+ readonly effort?: ClaudeCodeEffort;
14
+ readonly fallbackModel?: string;
15
+ readonly maxTurns?: number;
16
+ readonly maxBudgetUsd?: number;
17
+ }
18
+ export declare function claudeCode(): Harness;
19
+ export declare function claudeCode<const TOptions extends ClaudeCodeOptions>(options: TOptions & NoExtraKeys<TOptions, ClaudeCodeOptions>): Harness;