@karowanorg/orc-sdk 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.
package/LICENSE ADDED
@@ -0,0 +1,14 @@
1
+ BSD Zero Clause License (0BSD)
2
+
3
+ Copyright (c) 2026 Kyle Rowan
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted.
7
+
8
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @karowanorg/orc-sdk
2
+
3
+ Embedded TypeScript SDK for orc: launch, watch, and collect runs in-process.
4
+
5
+ Part of orc - model-authored promise-native agent programs with deterministic replay, live monitoring, and pluggable harnesses. See the orc repository README for the full picture.
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @karowanorg/orc-sdk — the embedded TypeScript SDK. Types are inferred from the zod-first
3
+ * operation registry; the Orc class is a thin ergonomic layer over the same op
4
+ * handlers the CLI and MCP call.
5
+ */
6
+ import { z } from "zod";
7
+ import { launch as launchOp, validate as validateOp, type OpContext } from "@karowanorg/orc-ops";
8
+ import { type Json, type RunStatus } from "@karowanorg/orc-core";
9
+ export type LaunchInput = z.input<typeof launchOp.input>;
10
+ export type ValidateInput = z.input<typeof validateOp.input>;
11
+ export type RunEvent = {
12
+ kind: "status";
13
+ status: RunStatus;
14
+ } | {
15
+ kind: "approval-requested";
16
+ approvalId: string;
17
+ toolName: string;
18
+ input: Json;
19
+ respond(d: {
20
+ behavior: "allow" | "deny";
21
+ message?: string;
22
+ }): Promise<void>;
23
+ } | {
24
+ kind: "done";
25
+ status: RunStatus;
26
+ };
27
+ export declare class OrcRun {
28
+ private readonly orc;
29
+ readonly runId: string;
30
+ constructor(orc: Orc, runId: string);
31
+ status(): Promise<RunStatus>;
32
+ wait(timeoutSeconds?: number): Promise<RunStatus>;
33
+ /** Typed event stream: status ticks, answerable approvals, terminal done. */
34
+ watch(pollMs?: number): AsyncIterable<RunEvent>;
35
+ result(): Promise<Json>;
36
+ cancel(): Promise<void>;
37
+ }
38
+ export declare class Orc {
39
+ private readonly opts;
40
+ private context?;
41
+ constructor(opts?: {
42
+ defaultHarness?: string;
43
+ cwd?: string;
44
+ });
45
+ /** @internal */
46
+ ctx(): Promise<OpContext>;
47
+ launch(input: LaunchInput): Promise<OrcRun & {
48
+ info: Awaited<ReturnType<typeof launchOp.handler>>;
49
+ }>;
50
+ validate(input: ValidateInput): Promise<Awaited<ReturnType<typeof validateOp.handler>>>;
51
+ resume(runId: string, wait?: boolean): Promise<OrcRun>;
52
+ capabilities(host?: string): Promise<unknown>;
53
+ run(runId: string): OrcRun;
54
+ status(runId: string): Promise<RunStatus>;
55
+ approvals(runId: string): Promise<import("@karowanorg/orc-core").ApprovalRequest[]>;
56
+ }
package/dist/index.js ADDED
@@ -0,0 +1,101 @@
1
+ import { buildRegistry, launch as launchOp, status as statusOp, wait as waitOp, getResult as getResultOp, resume as resumeOp, cancel as cancelOp, capabilities as capabilitiesOp, respondApproval as respondOp, listApprovals as listApprovalsOp, validate as validateOp, } from "@karowanorg/orc-ops";
2
+ import { readTraces, openApprovals, statusForRun } from "@karowanorg/orc-core";
3
+ export class OrcRun {
4
+ orc;
5
+ runId;
6
+ constructor(orc, runId) {
7
+ this.orc = orc;
8
+ this.runId = runId;
9
+ }
10
+ async status() {
11
+ return statusForRun(this.runId);
12
+ }
13
+ async wait(timeoutSeconds = 300) {
14
+ const input = waitOp.input.parse({ runId: this.runId, timeoutSeconds });
15
+ const ctx = await this.orc.ctx();
16
+ return (await waitOp.handler(input, ctx)).status;
17
+ }
18
+ /** Typed event stream: status ticks, answerable approvals, terminal done. */
19
+ async *watch(pollMs = 1000) {
20
+ const ctx = await this.orc.ctx();
21
+ const seenApprovals = new Set();
22
+ for (;;) {
23
+ const s = statusForRun(this.runId);
24
+ for (const approval of openApprovals(readTraces(this.runId))) {
25
+ if (!seenApprovals.has(approval.id)) {
26
+ seenApprovals.add(approval.id);
27
+ yield {
28
+ kind: "approval-requested",
29
+ approvalId: approval.id,
30
+ toolName: approval.toolName,
31
+ input: approval.input,
32
+ respond: async (d) => {
33
+ await respondOp.handler({ runId: this.runId, approvalId: approval.id, behavior: d.behavior, message: d.message }, ctx);
34
+ },
35
+ };
36
+ }
37
+ }
38
+ if (s.state !== "running") {
39
+ yield { kind: "done", status: s };
40
+ return;
41
+ }
42
+ yield { kind: "status", status: s };
43
+ await new Promise((r) => setTimeout(r, pollMs));
44
+ }
45
+ }
46
+ async result() {
47
+ const ctx = await this.orc.ctx();
48
+ const res = await getResultOp.handler({ runId: this.runId }, ctx);
49
+ return res.body;
50
+ }
51
+ async cancel() {
52
+ const ctx = await this.orc.ctx();
53
+ await cancelOp.handler({ runId: this.runId }, ctx);
54
+ }
55
+ }
56
+ export class Orc {
57
+ opts;
58
+ context;
59
+ constructor(opts = {}) {
60
+ this.opts = opts;
61
+ }
62
+ /** @internal */
63
+ async ctx() {
64
+ this.context ??= {
65
+ registry: await buildRegistry({ cwd: this.opts.cwd, defaultHarness: this.opts.defaultHarness }),
66
+ registryCwd: this.opts.cwd,
67
+ };
68
+ return this.context;
69
+ }
70
+ async launch(input) {
71
+ const ctx = await this.ctx();
72
+ const info = await launchOp.handler(launchOp.input.parse(input), ctx);
73
+ const run = new OrcRun(this, info.runId);
74
+ run.info = info;
75
+ return run;
76
+ }
77
+ async validate(input) {
78
+ const ctx = await this.ctx();
79
+ return validateOp.handler(validateOp.input.parse(input), ctx);
80
+ }
81
+ async resume(runId, wait = false) {
82
+ const ctx = await this.ctx();
83
+ await resumeOp.handler(resumeOp.input.parse({ runId, wait }), ctx);
84
+ return new OrcRun(this, runId);
85
+ }
86
+ async capabilities(host) {
87
+ const ctx = await this.ctx();
88
+ return capabilitiesOp.handler({ host, refresh: false }, ctx);
89
+ }
90
+ run(runId) {
91
+ return new OrcRun(this, runId);
92
+ }
93
+ async status(runId) {
94
+ const ctx = await this.ctx();
95
+ return statusOp.handler({ runId }, ctx);
96
+ }
97
+ async approvals(runId) {
98
+ const ctx = await this.ctx();
99
+ return listApprovalsOp.handler({ runId }, ctx);
100
+ }
101
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @karowanorg/orc-sdk/program — type-only surface for program authors. Import with
3
+ * `import type` (runtime imports are rejected by the sandbox).
4
+ */
5
+ export type Json = null | boolean | number | string | Json[] | {
6
+ [k: string]: Json;
7
+ };
8
+ export interface AgentOptions {
9
+ /** Optional trace label — makes waterfall rows read semantically. */
10
+ id?: string;
11
+ /** "claude" | "codex" | a config-registered harness. Default: caller affinity. */
12
+ harness?: string;
13
+ model?: string;
14
+ reasoningEffort?: string;
15
+ /** JSON Schema for structured output. */
16
+ schema?: Json;
17
+ /** Default true. false requires the run's allow-writes grant (fail-closed). */
18
+ readOnly?: boolean;
19
+ /** Plain path on the leaf's host. Defaults to the run cwd. */
20
+ cwd?: string;
21
+ /** SSH destination (separate field — never a URI). Defaults to the run host. */
22
+ host?: string;
23
+ /** Output-idle watchdog for this call, ms; false disables. */
24
+ idleTimeout?: number | false;
25
+ phase?: string;
26
+ }
27
+ export interface ParallelSpec extends AgentOptions {
28
+ prompt: string;
29
+ }
30
+ export type Settled<T> = {
31
+ status: "ok";
32
+ value: T;
33
+ } | {
34
+ status: "error";
35
+ error: string;
36
+ };
37
+ export interface OrcApi {
38
+ agent(prompt: string, opts?: AgentOptions): Promise<Json>;
39
+ /**
40
+ * Independent fan-out: every lane runs to completion (one failing lane never
41
+ * cancels the others) and comes back as a per-lane settled outcome, in order.
42
+ * For fail-fast, use Promise.all over agent() instead.
43
+ */
44
+ parallel(specs: ParallelSpec[]): Promise<Settled<Json>[]>;
45
+ /** Labels every call made inside fn for the waterfall. */
46
+ phase<T>(name: string, fn: () => T | Promise<T>): Promise<T>;
47
+ log(message: string): void;
48
+ /** Envelope helper: collect a failing lane without sinking the run. */
49
+ settle<T>(p: Promise<T>): Promise<Settled<T>>;
50
+ /** Config-registered extension leaves — journaled exactly like agent(). */
51
+ ext: Record<string, (payload?: Json) => Promise<Json>>;
52
+ }
53
+ export type Program = (api: OrcApi) => Promise<Json>;
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@karowanorg/orc-sdk",
3
+ "version": "0.1.0",
4
+ "license": "0BSD",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "dependencies": {
8
+ "@karowanorg/orc-ops": "^0.1.0",
9
+ "@karowanorg/orc-core": "^0.1.0",
10
+ "zod": "^4.1.0"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "./program": {
18
+ "types": "./dist/program.d.ts",
19
+ "default": "./dist/program.js"
20
+ }
21
+ },
22
+ "description": "Embedded TypeScript SDK for orc: launch, watch, and collect runs in-process.",
23
+ "types": "dist/index.d.ts",
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "engines": {
31
+ "node": ">=20"
32
+ }
33
+ }