@bang404/openagent-harness 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 +21 -0
- package/README.md +22 -0
- package/dist/client.d.ts +28 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +140 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +19 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +75 -0
- package/dist/node.js.map +1 -0
- package/dist/types.d.ts +77 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/openapi.yaml +294 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 BANG404
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# OpenAgent Harness Client
|
|
2
|
+
|
|
3
|
+
Thin TypeScript client for the private OpenAgent runtime. The package contains
|
|
4
|
+
only the public wire contract and process-management helpers; the agent loop,
|
|
5
|
+
prompts, providers, tools, persistence, and checkpoint implementation remain in
|
|
6
|
+
the private `openagent-server` binary.
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
import { spawnOpenAgent } from "@bang404/openagent-harness/node";
|
|
10
|
+
|
|
11
|
+
const agent = await spawnOpenAgent({ workspace: process.cwd() });
|
|
12
|
+
const [workspace] = await agent.client.listWorkspaces();
|
|
13
|
+
const session = await agent.client.createSession(workspace.id);
|
|
14
|
+
const result = await agent.client.runToCompletion(session.session_id, {
|
|
15
|
+
input: "Fix the failing tests",
|
|
16
|
+
});
|
|
17
|
+
console.log(result.status);
|
|
18
|
+
await agent.stop();
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The daemon listens on an ephemeral loopback port and uses a process-scoped
|
|
22
|
+
Bearer token. Do not expose the endpoint or token to untrusted code.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type CreateRunRequest, type HarnessCapabilities, type HarnessClientOptions, type HarnessEventEnvelope, type HarnessRunAccepted, type HarnessRunState, type HarnessSession, type HarnessWorkspace, type RunEventOptions, type UploadedAttachment } from "./types.js";
|
|
2
|
+
export declare class OpenAgentHarnessError extends Error {
|
|
3
|
+
readonly status?: number | undefined;
|
|
4
|
+
constructor(message: string, status?: number | undefined);
|
|
5
|
+
}
|
|
6
|
+
export declare class OpenAgentHarnessClient {
|
|
7
|
+
private readonly endpoint;
|
|
8
|
+
private readonly token;
|
|
9
|
+
private readonly fetchRequest;
|
|
10
|
+
constructor(options: HarnessClientOptions);
|
|
11
|
+
capabilities(): Promise<HarnessCapabilities>;
|
|
12
|
+
listWorkspaces(): Promise<HarnessWorkspace[]>;
|
|
13
|
+
createSession(workspaceId: string, roleId?: string): Promise<HarnessSession>;
|
|
14
|
+
getSession(sessionId: string): Promise<HarnessSession>;
|
|
15
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
16
|
+
uploadAttachment(name: string, contentBase64: string): Promise<UploadedAttachment>;
|
|
17
|
+
createRun(sessionId: string, input: CreateRunRequest): Promise<HarnessRunAccepted>;
|
|
18
|
+
getRun(runId: string): Promise<HarnessRunState>;
|
|
19
|
+
cancelRun(runId: string): Promise<void>;
|
|
20
|
+
respondToInterrupt(runId: string, interruptId: string, response: unknown): Promise<void>;
|
|
21
|
+
events(runId: string, options?: RunEventOptions): AsyncGenerator<HarnessEventEnvelope>;
|
|
22
|
+
runToCompletion(sessionId: string, input: CreateRunRequest, options?: RunEventOptions): Promise<HarnessRunState>;
|
|
23
|
+
private request;
|
|
24
|
+
private headers;
|
|
25
|
+
private url;
|
|
26
|
+
private responseError;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EAEzB,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAEpB,qBAAa,qBAAsB,SAAQ,KAAK;IAG5C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;gBADxB,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,MAAM,YAAA;CAK3B;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;gBAEhC,OAAO,EAAE,oBAAoB;IAMnC,YAAY,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAUlD,cAAc,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAI7C,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAO5E,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAIhD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAOlF,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAYlF,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAIzC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvF,MAAM,CACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAAC,oBAAoB,CAAC;IAyCjC,eAAe,CACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,gBAAgB,EACvB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,eAAe,CAAC;YAUb,OAAO;IAcrB,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,GAAG;YAIG,aAAa;CAO5B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { OPENAGENT_HARNESS_PROTOCOL_VERSION, } from "./types.js";
|
|
2
|
+
export class OpenAgentHarnessError extends Error {
|
|
3
|
+
status;
|
|
4
|
+
constructor(message, status) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.status = status;
|
|
7
|
+
this.name = "OpenAgentHarnessError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class OpenAgentHarnessClient {
|
|
11
|
+
endpoint;
|
|
12
|
+
token;
|
|
13
|
+
fetchRequest;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.endpoint = options.endpoint.replace(/\/$/, "");
|
|
16
|
+
this.token = options.token;
|
|
17
|
+
this.fetchRequest = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
18
|
+
}
|
|
19
|
+
async capabilities() {
|
|
20
|
+
const capabilities = await this.request("/v1/capabilities");
|
|
21
|
+
if (capabilities.protocol_version !== OPENAGENT_HARNESS_PROTOCOL_VERSION) {
|
|
22
|
+
throw new OpenAgentHarnessError(`OpenAgent protocol mismatch: server ${capabilities.protocol_version}, client ${OPENAGENT_HARNESS_PROTOCOL_VERSION}`);
|
|
23
|
+
}
|
|
24
|
+
return capabilities;
|
|
25
|
+
}
|
|
26
|
+
listWorkspaces() {
|
|
27
|
+
return this.request("/v1/workspaces");
|
|
28
|
+
}
|
|
29
|
+
createSession(workspaceId, roleId) {
|
|
30
|
+
return this.request("/v1/sessions", {
|
|
31
|
+
method: "POST",
|
|
32
|
+
body: JSON.stringify({ workspace_id: workspaceId, role_id: roleId }),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
getSession(sessionId) {
|
|
36
|
+
return this.request(`/v1/sessions/${encodeURIComponent(sessionId)}`);
|
|
37
|
+
}
|
|
38
|
+
async deleteSession(sessionId) {
|
|
39
|
+
await this.request(`/v1/sessions/${encodeURIComponent(sessionId)}`, { method: "DELETE" });
|
|
40
|
+
}
|
|
41
|
+
uploadAttachment(name, contentBase64) {
|
|
42
|
+
return this.request("/v1/attachments", {
|
|
43
|
+
method: "POST",
|
|
44
|
+
body: JSON.stringify({ name, content_base64: contentBase64 }),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
createRun(sessionId, input) {
|
|
48
|
+
return this.request(`/v1/sessions/${encodeURIComponent(sessionId)}/runs`, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
body: JSON.stringify({
|
|
51
|
+
input: input.input,
|
|
52
|
+
attachments: input.attachments ?? [],
|
|
53
|
+
model: input.model,
|
|
54
|
+
idempotency_key: input.idempotencyKey,
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
getRun(runId) {
|
|
59
|
+
return this.request(`/v1/runs/${encodeURIComponent(runId)}`);
|
|
60
|
+
}
|
|
61
|
+
async cancelRun(runId) {
|
|
62
|
+
await this.request(`/v1/runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" });
|
|
63
|
+
}
|
|
64
|
+
async respondToInterrupt(runId, interruptId, response) {
|
|
65
|
+
await this.request(`/v1/runs/${encodeURIComponent(runId)}/interrupts/${encodeURIComponent(interruptId)}/response`, { method: "POST", body: JSON.stringify({ response }) });
|
|
66
|
+
}
|
|
67
|
+
async *events(runId, options = {}) {
|
|
68
|
+
const response = await this.fetchRequest(this.url(`/v1/runs/${encodeURIComponent(runId)}/events`), { headers: this.headers(), signal: options.signal });
|
|
69
|
+
if (!response.ok || !response.body) {
|
|
70
|
+
throw await this.responseError(response);
|
|
71
|
+
}
|
|
72
|
+
const reader = response.body.getReader();
|
|
73
|
+
const decoder = new TextDecoder();
|
|
74
|
+
let buffer = "";
|
|
75
|
+
try {
|
|
76
|
+
while (true) {
|
|
77
|
+
const { value, done } = await reader.read();
|
|
78
|
+
buffer += decoder.decode(value, { stream: !done });
|
|
79
|
+
buffer = buffer.replace(/\r\n/g, "\n");
|
|
80
|
+
let boundary;
|
|
81
|
+
while ((boundary = buffer.indexOf("\n\n")) >= 0) {
|
|
82
|
+
const block = buffer.slice(0, boundary).replace(/\r/g, "");
|
|
83
|
+
buffer = buffer.slice(boundary + 2);
|
|
84
|
+
const data = block
|
|
85
|
+
.split("\n")
|
|
86
|
+
.filter((line) => line.startsWith("data:"))
|
|
87
|
+
.map((line) => line.slice(5).trimStart())
|
|
88
|
+
.join("\n");
|
|
89
|
+
if (!data)
|
|
90
|
+
continue;
|
|
91
|
+
const event = JSON.parse(data);
|
|
92
|
+
if (event.protocol_version !== OPENAGENT_HARNESS_PROTOCOL_VERSION) {
|
|
93
|
+
throw new OpenAgentHarnessError(`OpenAgent event protocol mismatch: ${event.protocol_version}`);
|
|
94
|
+
}
|
|
95
|
+
yield event;
|
|
96
|
+
}
|
|
97
|
+
if (done)
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
await reader.cancel().catch(() => undefined);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async runToCompletion(sessionId, input, options = {}) {
|
|
106
|
+
const accepted = await this.createRun(sessionId, input);
|
|
107
|
+
for await (const event of this.events(accepted.run_id, options)) {
|
|
108
|
+
if (["completed", "cancelled", "failed"].includes(event.data.status)) {
|
|
109
|
+
return event.data;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return this.getRun(accepted.run_id);
|
|
113
|
+
}
|
|
114
|
+
async request(path, init = {}) {
|
|
115
|
+
const response = await this.fetchRequest(this.url(path), {
|
|
116
|
+
...init,
|
|
117
|
+
headers: {
|
|
118
|
+
...this.headers(),
|
|
119
|
+
...(init.body ? { "content-type": "application/json" } : {}),
|
|
120
|
+
...init.headers,
|
|
121
|
+
},
|
|
122
|
+
});
|
|
123
|
+
if (!response.ok)
|
|
124
|
+
throw await this.responseError(response);
|
|
125
|
+
if (response.status === 204)
|
|
126
|
+
return undefined;
|
|
127
|
+
return response.json();
|
|
128
|
+
}
|
|
129
|
+
headers() {
|
|
130
|
+
return { authorization: `Bearer ${this.token}` };
|
|
131
|
+
}
|
|
132
|
+
url(path) {
|
|
133
|
+
return `${this.endpoint}${path}`;
|
|
134
|
+
}
|
|
135
|
+
async responseError(response) {
|
|
136
|
+
const payload = (await response.json().catch(() => null));
|
|
137
|
+
return new OpenAgentHarnessError(payload?.error ?? `${response.status} ${response.statusText}`, response.status);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC5E,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC5E,cAAc,YAAY,CAAC"}
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ChildProcessWithoutNullStreams } from "node:child_process";
|
|
2
|
+
import { OpenAgentHarnessClient } from "./client.js";
|
|
3
|
+
export interface SpawnOpenAgentOptions {
|
|
4
|
+
binaryPath?: string;
|
|
5
|
+
workspace: string;
|
|
6
|
+
listen?: string;
|
|
7
|
+
env?: NodeJS.ProcessEnv;
|
|
8
|
+
startupTimeoutMs?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SpawnedOpenAgent {
|
|
11
|
+
client: OpenAgentHarnessClient;
|
|
12
|
+
endpoint: string;
|
|
13
|
+
/** Process-scoped credential. Keep it out of logs and untrusted child processes. */
|
|
14
|
+
token: string;
|
|
15
|
+
process: ChildProcessWithoutNullStreams;
|
|
16
|
+
stop(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
export declare function spawnOpenAgent(options: SpawnOpenAgentOptions): Promise<SpawnedOpenAgent>;
|
|
19
|
+
//# sourceMappingURL=node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,8BAA8B,CAAC;IACxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAUD,wBAAsB,cAAc,CAClC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAyE3B"}
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { createInterface } from "node:readline";
|
|
4
|
+
import { OpenAgentHarnessClient } from "./client.js";
|
|
5
|
+
export async function spawnOpenAgent(options) {
|
|
6
|
+
const binaryPath = options.binaryPath ?? "openagent-server";
|
|
7
|
+
const token = randomBytes(32).toString("hex");
|
|
8
|
+
const tokenEnv = `OPENAGENT_HARNESS_TOKEN_${process.pid}_${Date.now()}`;
|
|
9
|
+
const child = spawn(binaryPath, [
|
|
10
|
+
"--workspace",
|
|
11
|
+
options.workspace,
|
|
12
|
+
"--listen",
|
|
13
|
+
options.listen ?? "127.0.0.1:0",
|
|
14
|
+
"--token-env",
|
|
15
|
+
tokenEnv,
|
|
16
|
+
"--output",
|
|
17
|
+
"json",
|
|
18
|
+
], {
|
|
19
|
+
env: { ...process.env, ...options.env, [tokenEnv]: token },
|
|
20
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
21
|
+
windowsHide: true,
|
|
22
|
+
});
|
|
23
|
+
const timeoutMs = options.startupTimeoutMs ?? 30_000;
|
|
24
|
+
const ready = await new Promise((resolve, reject) => {
|
|
25
|
+
const timeout = setTimeout(() => {
|
|
26
|
+
child.kill();
|
|
27
|
+
reject(new Error(`OpenAgent server did not become ready within ${timeoutMs}ms`));
|
|
28
|
+
}, timeoutMs);
|
|
29
|
+
const lines = createInterface({ input: child.stdout });
|
|
30
|
+
const fail = (error) => {
|
|
31
|
+
clearTimeout(timeout);
|
|
32
|
+
lines.close();
|
|
33
|
+
reject(error);
|
|
34
|
+
};
|
|
35
|
+
child.once("error", fail);
|
|
36
|
+
child.once("exit", (code) => fail(new Error(`OpenAgent server exited before ready (${code})`)));
|
|
37
|
+
lines.on("line", (line) => {
|
|
38
|
+
try {
|
|
39
|
+
const message = JSON.parse(line);
|
|
40
|
+
if (message.type !== "ready")
|
|
41
|
+
return;
|
|
42
|
+
clearTimeout(timeout);
|
|
43
|
+
child.removeListener("error", fail);
|
|
44
|
+
lines.close();
|
|
45
|
+
resolve(message);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Tracing output may precede the machine-readable ready message.
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
const stop = async () => {
|
|
53
|
+
if (child.exitCode !== null)
|
|
54
|
+
return;
|
|
55
|
+
child.kill("SIGTERM");
|
|
56
|
+
await new Promise((resolve) => {
|
|
57
|
+
const timeout = setTimeout(() => {
|
|
58
|
+
child.kill("SIGKILL");
|
|
59
|
+
resolve();
|
|
60
|
+
}, 5_000);
|
|
61
|
+
child.once("exit", () => {
|
|
62
|
+
clearTimeout(timeout);
|
|
63
|
+
resolve();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
return {
|
|
68
|
+
client: new OpenAgentHarnessClient({ endpoint: ready.endpoint, token }),
|
|
69
|
+
endpoint: ready.endpoint,
|
|
70
|
+
token,
|
|
71
|
+
process: child,
|
|
72
|
+
stop,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export declare const OPENAGENT_HARNESS_PROTOCOL_VERSION = 2;
|
|
2
|
+
export interface HarnessCapabilities {
|
|
3
|
+
protocol_version: number;
|
|
4
|
+
server_version: string;
|
|
5
|
+
capabilities: string[];
|
|
6
|
+
}
|
|
7
|
+
export interface HarnessWorkspace {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
}
|
|
11
|
+
export interface HarnessSession {
|
|
12
|
+
session_id: string;
|
|
13
|
+
title?: string | null;
|
|
14
|
+
status?: "idle" | "running" | "interrupted";
|
|
15
|
+
}
|
|
16
|
+
export interface ModelBinding {
|
|
17
|
+
provider_id: string;
|
|
18
|
+
model: string;
|
|
19
|
+
}
|
|
20
|
+
export interface CreateRunRequest {
|
|
21
|
+
input: string;
|
|
22
|
+
attachments?: string[];
|
|
23
|
+
model?: ModelBinding;
|
|
24
|
+
idempotencyKey?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface HarnessRunAccepted {
|
|
27
|
+
run_id: string;
|
|
28
|
+
session_id: string;
|
|
29
|
+
status: "accepted";
|
|
30
|
+
}
|
|
31
|
+
export type HarnessRunStatus = "accepted" | "running" | "interrupted" | "completed" | "cancelled" | "failed";
|
|
32
|
+
export interface HarnessMessage {
|
|
33
|
+
id: string;
|
|
34
|
+
role: "user" | "assistant" | string;
|
|
35
|
+
text: string;
|
|
36
|
+
status: "completed" | "aborted";
|
|
37
|
+
timestamp: number;
|
|
38
|
+
}
|
|
39
|
+
export interface HarnessInterrupt {
|
|
40
|
+
id: string;
|
|
41
|
+
kind: "ask_user" | "tool_approval" | "render_mermaid" | string;
|
|
42
|
+
tool_name: string;
|
|
43
|
+
arguments: unknown;
|
|
44
|
+
fields: unknown[];
|
|
45
|
+
}
|
|
46
|
+
export interface HarnessRunState {
|
|
47
|
+
run_id: string;
|
|
48
|
+
session_id: string;
|
|
49
|
+
status: HarnessRunStatus;
|
|
50
|
+
checkpoint_id?: string | null;
|
|
51
|
+
messages: HarnessMessage[];
|
|
52
|
+
interrupts: HarnessInterrupt[];
|
|
53
|
+
created_at: number;
|
|
54
|
+
}
|
|
55
|
+
export interface HarnessEventEnvelope {
|
|
56
|
+
protocol_version: number;
|
|
57
|
+
run_id: string;
|
|
58
|
+
sequence: number;
|
|
59
|
+
event_type: "run.state";
|
|
60
|
+
data: HarnessRunState;
|
|
61
|
+
}
|
|
62
|
+
export interface UploadedAttachment {
|
|
63
|
+
path: string;
|
|
64
|
+
name: string;
|
|
65
|
+
kind: "image" | "document";
|
|
66
|
+
mime_type: string;
|
|
67
|
+
}
|
|
68
|
+
export interface HarnessClientOptions {
|
|
69
|
+
endpoint: string;
|
|
70
|
+
token: string;
|
|
71
|
+
fetch?: HarnessFetch;
|
|
72
|
+
}
|
|
73
|
+
export type HarnessFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
74
|
+
export interface RunEventOptions {
|
|
75
|
+
signal?: AbortSignal;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kCAAkC,IAAI,CAAC;AAEpD,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;CAC7C;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,SAAS,GACT,aAAa,GACb,WAAW,GACX,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,GAAG,eAAe,GAAG,gBAAgB,GAAG,MAAM,CAAC;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,gBAAgB,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,WAAW,CAAC;IACxB,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAE/F,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,CAAC"}
|
package/openapi.yaml
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
openapi: 3.1.0
|
|
2
|
+
info:
|
|
3
|
+
title: OpenAgent Harness API
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
description: >-
|
|
6
|
+
Behavior-free public contract for a private OpenAgent runtime process.
|
|
7
|
+
All endpoints require a process-scoped Bearer token and are served only on
|
|
8
|
+
loopback interfaces.
|
|
9
|
+
servers:
|
|
10
|
+
- url: http://127.0.0.1:{port}
|
|
11
|
+
variables:
|
|
12
|
+
port:
|
|
13
|
+
default: "32123"
|
|
14
|
+
security:
|
|
15
|
+
- bearerAuth: []
|
|
16
|
+
paths:
|
|
17
|
+
/v1/capabilities:
|
|
18
|
+
get:
|
|
19
|
+
operationId: getCapabilities
|
|
20
|
+
responses:
|
|
21
|
+
"200":
|
|
22
|
+
description: Supported protocol and runtime capabilities
|
|
23
|
+
content:
|
|
24
|
+
application/json:
|
|
25
|
+
schema:
|
|
26
|
+
$ref: "#/components/schemas/Capabilities"
|
|
27
|
+
/v1/workspaces:
|
|
28
|
+
get:
|
|
29
|
+
operationId: listWorkspaces
|
|
30
|
+
responses:
|
|
31
|
+
"200":
|
|
32
|
+
description: Workspaces authorized when the daemon started
|
|
33
|
+
content:
|
|
34
|
+
application/json:
|
|
35
|
+
schema:
|
|
36
|
+
type: array
|
|
37
|
+
items:
|
|
38
|
+
$ref: "#/components/schemas/Workspace"
|
|
39
|
+
/v1/attachments:
|
|
40
|
+
post:
|
|
41
|
+
operationId: uploadAttachment
|
|
42
|
+
requestBody:
|
|
43
|
+
required: true
|
|
44
|
+
content:
|
|
45
|
+
application/json:
|
|
46
|
+
schema:
|
|
47
|
+
type: object
|
|
48
|
+
required: [name, content_base64]
|
|
49
|
+
properties:
|
|
50
|
+
name: { type: string, maxLength: 255 }
|
|
51
|
+
content_base64: { type: string }
|
|
52
|
+
responses:
|
|
53
|
+
"200":
|
|
54
|
+
description: Stored attachment locator
|
|
55
|
+
content:
|
|
56
|
+
application/json:
|
|
57
|
+
schema:
|
|
58
|
+
$ref: "#/components/schemas/Attachment"
|
|
59
|
+
/v1/sessions:
|
|
60
|
+
post:
|
|
61
|
+
operationId: createSession
|
|
62
|
+
requestBody:
|
|
63
|
+
required: true
|
|
64
|
+
content:
|
|
65
|
+
application/json:
|
|
66
|
+
schema:
|
|
67
|
+
type: object
|
|
68
|
+
required: [workspace_id]
|
|
69
|
+
properties:
|
|
70
|
+
workspace_id: { type: string }
|
|
71
|
+
role_id: { type: [string, "null"] }
|
|
72
|
+
responses:
|
|
73
|
+
"201":
|
|
74
|
+
description: Created harness session
|
|
75
|
+
content:
|
|
76
|
+
application/json:
|
|
77
|
+
schema:
|
|
78
|
+
$ref: "#/components/schemas/Session"
|
|
79
|
+
/v1/sessions/{session_id}:
|
|
80
|
+
parameters:
|
|
81
|
+
- $ref: "#/components/parameters/SessionId"
|
|
82
|
+
get:
|
|
83
|
+
operationId: getSession
|
|
84
|
+
responses:
|
|
85
|
+
"200":
|
|
86
|
+
description: Session state without private transcript records
|
|
87
|
+
content:
|
|
88
|
+
application/json:
|
|
89
|
+
schema:
|
|
90
|
+
$ref: "#/components/schemas/SessionState"
|
|
91
|
+
delete:
|
|
92
|
+
operationId: deleteSession
|
|
93
|
+
responses:
|
|
94
|
+
"204": { description: Session deleted }
|
|
95
|
+
/v1/sessions/{session_id}/runs:
|
|
96
|
+
parameters:
|
|
97
|
+
- $ref: "#/components/parameters/SessionId"
|
|
98
|
+
post:
|
|
99
|
+
operationId: createRun
|
|
100
|
+
requestBody:
|
|
101
|
+
required: true
|
|
102
|
+
content:
|
|
103
|
+
application/json:
|
|
104
|
+
schema:
|
|
105
|
+
$ref: "#/components/schemas/CreateRun"
|
|
106
|
+
responses:
|
|
107
|
+
"202":
|
|
108
|
+
description: Run accepted
|
|
109
|
+
content:
|
|
110
|
+
application/json:
|
|
111
|
+
schema:
|
|
112
|
+
$ref: "#/components/schemas/RunAccepted"
|
|
113
|
+
/v1/runs/{run_id}:
|
|
114
|
+
parameters:
|
|
115
|
+
- $ref: "#/components/parameters/RunId"
|
|
116
|
+
get:
|
|
117
|
+
operationId: getRun
|
|
118
|
+
responses:
|
|
119
|
+
"200":
|
|
120
|
+
description: Public projection of one run
|
|
121
|
+
content:
|
|
122
|
+
application/json:
|
|
123
|
+
schema:
|
|
124
|
+
$ref: "#/components/schemas/RunState"
|
|
125
|
+
/v1/runs/{run_id}/events:
|
|
126
|
+
parameters:
|
|
127
|
+
- $ref: "#/components/parameters/RunId"
|
|
128
|
+
get:
|
|
129
|
+
operationId: streamRunEvents
|
|
130
|
+
responses:
|
|
131
|
+
"200":
|
|
132
|
+
description: SSE stream of run.state envelopes
|
|
133
|
+
content:
|
|
134
|
+
text/event-stream:
|
|
135
|
+
schema:
|
|
136
|
+
$ref: "#/components/schemas/EventEnvelope"
|
|
137
|
+
/v1/runs/{run_id}/cancel:
|
|
138
|
+
parameters:
|
|
139
|
+
- $ref: "#/components/parameters/RunId"
|
|
140
|
+
post:
|
|
141
|
+
operationId: cancelRun
|
|
142
|
+
responses:
|
|
143
|
+
"202": { description: Cancellation accepted }
|
|
144
|
+
/v1/runs/{run_id}/interrupts/{interrupt_id}/response:
|
|
145
|
+
parameters:
|
|
146
|
+
- $ref: "#/components/parameters/RunId"
|
|
147
|
+
- name: interrupt_id
|
|
148
|
+
in: path
|
|
149
|
+
required: true
|
|
150
|
+
schema: { type: string }
|
|
151
|
+
post:
|
|
152
|
+
operationId: respondToInterrupt
|
|
153
|
+
requestBody:
|
|
154
|
+
required: true
|
|
155
|
+
content:
|
|
156
|
+
application/json:
|
|
157
|
+
schema:
|
|
158
|
+
type: object
|
|
159
|
+
required: [response]
|
|
160
|
+
properties:
|
|
161
|
+
response: {}
|
|
162
|
+
responses:
|
|
163
|
+
"202": { description: Response accepted }
|
|
164
|
+
components:
|
|
165
|
+
securitySchemes:
|
|
166
|
+
bearerAuth:
|
|
167
|
+
type: http
|
|
168
|
+
scheme: bearer
|
|
169
|
+
parameters:
|
|
170
|
+
SessionId:
|
|
171
|
+
name: session_id
|
|
172
|
+
in: path
|
|
173
|
+
required: true
|
|
174
|
+
schema: { type: string, format: uuid }
|
|
175
|
+
RunId:
|
|
176
|
+
name: run_id
|
|
177
|
+
in: path
|
|
178
|
+
required: true
|
|
179
|
+
schema: { type: string, format: uuid }
|
|
180
|
+
schemas:
|
|
181
|
+
Capabilities:
|
|
182
|
+
type: object
|
|
183
|
+
required: [protocol_version, server_version, capabilities]
|
|
184
|
+
properties:
|
|
185
|
+
protocol_version: { type: integer, const: 2 }
|
|
186
|
+
server_version: { type: string }
|
|
187
|
+
capabilities:
|
|
188
|
+
type: array
|
|
189
|
+
items: { type: string }
|
|
190
|
+
Workspace:
|
|
191
|
+
type: object
|
|
192
|
+
required: [id, name]
|
|
193
|
+
properties:
|
|
194
|
+
id: { type: string }
|
|
195
|
+
name: { type: string }
|
|
196
|
+
Session:
|
|
197
|
+
type: object
|
|
198
|
+
required: [session_id]
|
|
199
|
+
properties:
|
|
200
|
+
session_id: { type: string, format: uuid }
|
|
201
|
+
SessionState:
|
|
202
|
+
allOf:
|
|
203
|
+
- $ref: "#/components/schemas/Session"
|
|
204
|
+
- type: object
|
|
205
|
+
required: [status]
|
|
206
|
+
properties:
|
|
207
|
+
title: { type: [string, "null"] }
|
|
208
|
+
status: { enum: [idle, running, interrupted] }
|
|
209
|
+
ModelBinding:
|
|
210
|
+
type: object
|
|
211
|
+
required: [provider_id, model]
|
|
212
|
+
properties:
|
|
213
|
+
provider_id: { type: string }
|
|
214
|
+
model: { type: string }
|
|
215
|
+
CreateRun:
|
|
216
|
+
type: object
|
|
217
|
+
required: [input]
|
|
218
|
+
properties:
|
|
219
|
+
input: { type: string, maxLength: 65536 }
|
|
220
|
+
attachments:
|
|
221
|
+
type: array
|
|
222
|
+
maxItems: 8
|
|
223
|
+
items: { type: string }
|
|
224
|
+
model:
|
|
225
|
+
$ref: "#/components/schemas/ModelBinding"
|
|
226
|
+
idempotency_key: { type: string, minLength: 1, maxLength: 128 }
|
|
227
|
+
RunAccepted:
|
|
228
|
+
type: object
|
|
229
|
+
required: [run_id, session_id, status]
|
|
230
|
+
properties:
|
|
231
|
+
run_id: { type: string, format: uuid }
|
|
232
|
+
session_id: { type: string, format: uuid }
|
|
233
|
+
status: { const: accepted }
|
|
234
|
+
Message:
|
|
235
|
+
type: object
|
|
236
|
+
required: [id, role, text, status, timestamp]
|
|
237
|
+
properties:
|
|
238
|
+
id: { type: string }
|
|
239
|
+
role: { type: string }
|
|
240
|
+
text: { type: string }
|
|
241
|
+
status: { enum: [completed, aborted] }
|
|
242
|
+
timestamp: { type: integer }
|
|
243
|
+
Interrupt:
|
|
244
|
+
type: object
|
|
245
|
+
required: [id, kind, tool_name, arguments, fields]
|
|
246
|
+
properties:
|
|
247
|
+
id: { type: string }
|
|
248
|
+
kind: { type: string }
|
|
249
|
+
tool_name: { type: string }
|
|
250
|
+
arguments: {}
|
|
251
|
+
fields:
|
|
252
|
+
type: array
|
|
253
|
+
items: {}
|
|
254
|
+
RunState:
|
|
255
|
+
type: object
|
|
256
|
+
required: [run_id, session_id, status, messages, interrupts, created_at]
|
|
257
|
+
properties:
|
|
258
|
+
run_id: { type: string, format: uuid }
|
|
259
|
+
session_id: { type: string, format: uuid }
|
|
260
|
+
status:
|
|
261
|
+
enum: [accepted, running, interrupted, completed, cancelled, failed]
|
|
262
|
+
checkpoint_id: { type: [string, "null"] }
|
|
263
|
+
messages:
|
|
264
|
+
type: array
|
|
265
|
+
items:
|
|
266
|
+
$ref: "#/components/schemas/Message"
|
|
267
|
+
interrupts:
|
|
268
|
+
type: array
|
|
269
|
+
items:
|
|
270
|
+
$ref: "#/components/schemas/Interrupt"
|
|
271
|
+
created_at: { type: integer }
|
|
272
|
+
Attachment:
|
|
273
|
+
type: object
|
|
274
|
+
required: [path, name, kind, mime_type]
|
|
275
|
+
properties:
|
|
276
|
+
path: { type: string }
|
|
277
|
+
name: { type: string }
|
|
278
|
+
kind: { enum: [image, document] }
|
|
279
|
+
mime_type: { type: string }
|
|
280
|
+
EventEnvelope:
|
|
281
|
+
type: object
|
|
282
|
+
required: [protocol_version, run_id, sequence, event_type, data]
|
|
283
|
+
properties:
|
|
284
|
+
protocol_version: { type: integer, const: 2 }
|
|
285
|
+
run_id: { type: string, format: uuid }
|
|
286
|
+
sequence: { type: integer, minimum: 1 }
|
|
287
|
+
event_type: { const: run.state }
|
|
288
|
+
data:
|
|
289
|
+
$ref: "#/components/schemas/RunState"
|
|
290
|
+
Error:
|
|
291
|
+
type: object
|
|
292
|
+
required: [error]
|
|
293
|
+
properties:
|
|
294
|
+
error: { type: string }
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bang404/openagent-harness",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Thin client for the private OpenAgent harness runtime",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/BANG404/openagent-sdk.git",
|
|
9
|
+
"directory": "harness-typescript"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE",
|
|
16
|
+
"openapi.yaml"
|
|
17
|
+
],
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./node": {
|
|
24
|
+
"types": "./dist/node.d.ts",
|
|
25
|
+
"import": "./dist/node.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc -p tsconfig.build.json",
|
|
30
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
31
|
+
"check:openapi": "bun scripts/verify-openapi.ts",
|
|
32
|
+
"test": "bun test",
|
|
33
|
+
"prepack": "bun run build"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/bun": "latest",
|
|
40
|
+
"@types/node": "^24.0.0",
|
|
41
|
+
"typescript": "~5.6.2"
|
|
42
|
+
}
|
|
43
|
+
}
|