@managoat/fountain-sdk 1.25.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/CHANGELOG.md +653 -0
- package/LICENSE +202 -0
- package/README.md +445 -0
- package/dist/client.d.ts +190 -0
- package/dist/client.js +225 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +49 -0
- package/dist/config.js +87 -0
- package/dist/config.js.map +1 -0
- package/dist/conversation.d.ts +100 -0
- package/dist/conversation.js +189 -0
- package/dist/conversation.js.map +1 -0
- package/dist/errors.d.ts +102 -0
- package/dist/errors.js +197 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/openapi.d.ts +16654 -0
- package/dist/generated/openapi.js +6 -0
- package/dist/generated/openapi.js.map +1 -0
- package/dist/http.d.ts +37 -0
- package/dist/http.js +129 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +2 -0
- package/dist/node.js +21 -0
- package/dist/node.js.map +1 -0
- package/dist/queue.d.ts +25 -0
- package/dist/queue.js +64 -0
- package/dist/queue.js.map +1 -0
- package/dist/resolve.d.ts +29 -0
- package/dist/resolve.js +89 -0
- package/dist/resolve.js.map +1 -0
- package/dist/resources.d.ts +126 -0
- package/dist/resources.js +206 -0
- package/dist/resources.js.map +1 -0
- package/dist/run.d.ts +81 -0
- package/dist/run.js +247 -0
- package/dist/run.js.map +1 -0
- package/dist/schemas.d.ts +90 -0
- package/dist/schemas.js +2 -0
- package/dist/schemas.js.map +1 -0
- package/dist/sse.d.ts +58 -0
- package/dist/sse.js +219 -0
- package/dist/sse.js.map +1 -0
- package/dist/team.d.ts +90 -0
- package/dist/team.js +183 -0
- package/dist/team.js.map +1 -0
- package/dist/turn.d.ts +46 -0
- package/dist/turn.js +205 -0
- package/dist/turn.js.map +1 -0
- package/dist/types.d.ts +144 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +61 -0
package/dist/turn.js
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
const TERMINAL_TURN_STATES = new Set(["done", "failed", "interrupted"]);
|
|
2
|
+
/**
|
|
3
|
+
* Folds the log feed into one turn's answer.
|
|
4
|
+
*
|
|
5
|
+
* The feed carries every turn of the conversation and every stream of each
|
|
6
|
+
* turn, so "what did the agent just say" is a filtering problem, not a
|
|
7
|
+
* concatenation one. This class is the filter:
|
|
8
|
+
*
|
|
9
|
+
* - a `stage`/`turn` event opens and closes the turn we are following, and
|
|
10
|
+
* is the only thing that says how it ended;
|
|
11
|
+
* - `output` events carry server-parsed `blocks`; only `text` is the answer,
|
|
12
|
+
* `tool_use` is noise worth naming, `thinking` is neither;
|
|
13
|
+
* - text that follows a tool call is a new message, so it gets a paragraph
|
|
14
|
+
* break — the rule that stops a transcript reading as one run-on sentence.
|
|
15
|
+
*
|
|
16
|
+
* The joining rules are ported from the Hermes plugin, which learned them
|
|
17
|
+
* against real runtimes: ACP streams one message as chunks that join with
|
|
18
|
+
* nothing, while a legacy stdout row is a whole message and joins as a
|
|
19
|
+
* paragraph.
|
|
20
|
+
*/
|
|
21
|
+
export class TurnFollower {
|
|
22
|
+
turnNumber;
|
|
23
|
+
turnId = null;
|
|
24
|
+
started = false;
|
|
25
|
+
state = null;
|
|
26
|
+
exitCode = null;
|
|
27
|
+
reason = null;
|
|
28
|
+
chunks = [];
|
|
29
|
+
tools = [];
|
|
30
|
+
breakBeforeText = false;
|
|
31
|
+
constructor(turnNumber, turnId = null) {
|
|
32
|
+
this.turnNumber = turnNumber;
|
|
33
|
+
this.turnId = turnId;
|
|
34
|
+
}
|
|
35
|
+
get text() {
|
|
36
|
+
return this.chunks.join("").trim();
|
|
37
|
+
}
|
|
38
|
+
get toolsUsed() {
|
|
39
|
+
return [...this.tools];
|
|
40
|
+
}
|
|
41
|
+
get finished() {
|
|
42
|
+
return this.state !== null;
|
|
43
|
+
}
|
|
44
|
+
/** Fold one event in, and report what a streaming caller should be told. */
|
|
45
|
+
apply(event) {
|
|
46
|
+
if (event.kind === "stage")
|
|
47
|
+
return this.applyStage(event);
|
|
48
|
+
if (event.kind !== "output")
|
|
49
|
+
return [];
|
|
50
|
+
return this.applyOutput(event);
|
|
51
|
+
}
|
|
52
|
+
applyStage(event) {
|
|
53
|
+
if (event.stage !== "turn")
|
|
54
|
+
return [];
|
|
55
|
+
const meta = parseJson(event.data) ?? {};
|
|
56
|
+
if (!this.matchesTurn(meta))
|
|
57
|
+
return [];
|
|
58
|
+
if (event.state === "started") {
|
|
59
|
+
this.started = true;
|
|
60
|
+
this.turnId = asString(meta.turn_id) ?? this.turnId;
|
|
61
|
+
return [{ type: "turn-start", turnNumber: this.turnNumber, turnId: this.turnId }];
|
|
62
|
+
}
|
|
63
|
+
if (event.state && TERMINAL_TURN_STATES.has(event.state)) {
|
|
64
|
+
this.state = event.state;
|
|
65
|
+
this.turnId = this.turnId ?? asString(meta.turn_id);
|
|
66
|
+
if (typeof meta.exit_code === "number")
|
|
67
|
+
this.exitCode = meta.exit_code;
|
|
68
|
+
const reason = asString(meta.reason) ?? asString(meta.stop_reason);
|
|
69
|
+
if (reason)
|
|
70
|
+
this.reason = reason;
|
|
71
|
+
return [
|
|
72
|
+
{ type: "turn-end", state: this.state, exitCode: this.exitCode, reason: this.reason },
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
matchesTurn(meta) {
|
|
78
|
+
if (this.turnId && asString(meta.turn_id) === this.turnId)
|
|
79
|
+
return true;
|
|
80
|
+
return meta.turn_number === this.turnNumber;
|
|
81
|
+
}
|
|
82
|
+
applyOutput(event) {
|
|
83
|
+
const turnId = asString(event.turn_id);
|
|
84
|
+
// A different turn's output — history, or a turn someone else started.
|
|
85
|
+
if (this.turnId && turnId && turnId !== this.turnId)
|
|
86
|
+
return [];
|
|
87
|
+
// Output from before our turn opened is the tail of an older one.
|
|
88
|
+
if (!this.started && !this.turnId)
|
|
89
|
+
return [];
|
|
90
|
+
const acp = event.stream === "acp";
|
|
91
|
+
const out = [];
|
|
92
|
+
for (const block of event.blocks ?? []) {
|
|
93
|
+
out.push({ type: "block", block, event });
|
|
94
|
+
out.push(...this.applyBlock(block, acp));
|
|
95
|
+
}
|
|
96
|
+
return out;
|
|
97
|
+
}
|
|
98
|
+
applyBlock(block, acp) {
|
|
99
|
+
const body = block.body ?? "";
|
|
100
|
+
if (block.kind === "text") {
|
|
101
|
+
if (!body)
|
|
102
|
+
return [];
|
|
103
|
+
const prefix = this.paragraphBreak(acp);
|
|
104
|
+
if (prefix)
|
|
105
|
+
this.chunks.push(prefix);
|
|
106
|
+
this.chunks.push(body);
|
|
107
|
+
this.breakBeforeText = false;
|
|
108
|
+
return [{ type: "text", text: prefix + body }];
|
|
109
|
+
}
|
|
110
|
+
if (block.kind === "thinking") {
|
|
111
|
+
return body ? [{ type: "thinking", text: body }] : [];
|
|
112
|
+
}
|
|
113
|
+
// `raw` and `init` are transport bookkeeping: not output, and not a break.
|
|
114
|
+
if (block.kind === "raw" || block.kind === "init")
|
|
115
|
+
return [];
|
|
116
|
+
this.breakBeforeText = true;
|
|
117
|
+
// The turn is now blocked until somebody answers. Surface it as its own
|
|
118
|
+
// event rather than a bare block, because a caller that does not handle it
|
|
119
|
+
// loses the tool call to the server's deny-on-timeout.
|
|
120
|
+
if (block.kind === "permission_request") {
|
|
121
|
+
const request = toPermissionRequest(block);
|
|
122
|
+
return request ? [{ type: "permission", request, block }] : [];
|
|
123
|
+
}
|
|
124
|
+
if (block.kind === "tool_use") {
|
|
125
|
+
const name = asString(block.name);
|
|
126
|
+
if (!name)
|
|
127
|
+
return [];
|
|
128
|
+
if (!this.tools.includes(name))
|
|
129
|
+
this.tools.push(name);
|
|
130
|
+
return [{ type: "tool", name, block }];
|
|
131
|
+
}
|
|
132
|
+
// A `result` block is the answer only when the runtime said nothing else.
|
|
133
|
+
if (block.kind === "result" && !this.chunks.length && body) {
|
|
134
|
+
this.chunks.push(body);
|
|
135
|
+
return [{ type: "text", text: body }];
|
|
136
|
+
}
|
|
137
|
+
if (block.kind === "error" && body) {
|
|
138
|
+
const text = `\n[error] ${body}\n`;
|
|
139
|
+
this.chunks.push(text);
|
|
140
|
+
return [{ type: "text", text }];
|
|
141
|
+
}
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* ACP chunks are pieces of one message and join with nothing; anything after
|
|
146
|
+
* a tool call is a new message. A legacy row is a whole message either way.
|
|
147
|
+
*/
|
|
148
|
+
paragraphBreak(acp) {
|
|
149
|
+
if (!this.chunks.length)
|
|
150
|
+
return "";
|
|
151
|
+
if (acp && !this.breakBeforeText)
|
|
152
|
+
return "";
|
|
153
|
+
const last = this.chunks[this.chunks.length - 1] ?? "";
|
|
154
|
+
return last.endsWith("\n") ? "" : "\n\n";
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Read a `permission_request` block into something answerable.
|
|
159
|
+
*
|
|
160
|
+
* No `request_id` means there is nothing a caller could send back, and an
|
|
161
|
+
* empty `options` list means there is nothing they could choose — either way
|
|
162
|
+
* the block is a notice, not a question, so it is dropped rather than handed
|
|
163
|
+
* over as a request that cannot be answered.
|
|
164
|
+
*/
|
|
165
|
+
function toPermissionRequest(block) {
|
|
166
|
+
const requestId = asString(block.request_id);
|
|
167
|
+
if (!requestId)
|
|
168
|
+
return null;
|
|
169
|
+
const options = [];
|
|
170
|
+
for (const raw of block.options ?? []) {
|
|
171
|
+
if (!raw || typeof raw !== "object")
|
|
172
|
+
continue;
|
|
173
|
+
const option = raw;
|
|
174
|
+
const optionId = asString(option.optionId) ?? asString(option.option_id);
|
|
175
|
+
if (!optionId)
|
|
176
|
+
continue;
|
|
177
|
+
options.push({ ...option, optionId });
|
|
178
|
+
}
|
|
179
|
+
if (!options.length)
|
|
180
|
+
return null;
|
|
181
|
+
return {
|
|
182
|
+
requestId,
|
|
183
|
+
summary: asString(block.summary) ?? asString(block.body),
|
|
184
|
+
toolName: asString(block.name),
|
|
185
|
+
toolId: asString(block.tool_id),
|
|
186
|
+
options,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function parseJson(raw) {
|
|
190
|
+
if (raw && typeof raw === "object")
|
|
191
|
+
return raw;
|
|
192
|
+
if (typeof raw !== "string" || !raw.trim())
|
|
193
|
+
return null;
|
|
194
|
+
try {
|
|
195
|
+
const parsed = JSON.parse(raw);
|
|
196
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function asString(value) {
|
|
203
|
+
return typeof value === "string" && value ? value : null;
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=turn.js.map
|
package/dist/turn.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn.js","sourceRoot":"","sources":["../src/turn.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SDK's own vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* Anything the API defines comes from `schemas.ts`, which is generated from
|
|
5
|
+
* the OpenAPI document — so it cannot drift. What is left here is what a spec
|
|
6
|
+
* cannot say: that many log events fold into one *turn*, that a run can be
|
|
7
|
+
* awaited or streamed, and how a turn ended.
|
|
8
|
+
*/
|
|
9
|
+
export type { Agent, AgentInput, AgentPatch, AuthMe, Block, Catalog, Connection, ConnectionProvider, ConnectionProviderInput, ConnectionProviderPatch, ConversationRecord, ConversationTreeNode, Environment, EnvironmentInput, EnvironmentPatch, ImageInput, LogEvent, Repository, Runner, SandboxDiff, SandboxEntry, SandboxFile, SandboxListing, SandboxRecord, Schedule, ScheduleInput, SchedulePatch, SearchHit, Secret, TeamAddInput, TeamCommsStatus, Teammate, TeammateContact, Turn, Vault, VaultInput, VaultPatch, VaultSecret, VaultSecretMetadataPatch, } from "./schemas.ts";
|
|
10
|
+
import type { Agent, Block, ConversationRecord, LogEvent } from "./schemas.ts";
|
|
11
|
+
/** The agent runtimes Fountain can start. */
|
|
12
|
+
export type Runtime = NonNullable<Agent["runtime"]>;
|
|
13
|
+
/** Sandbox backends. `null` on an agent means "the instance default". */
|
|
14
|
+
export type SandboxProvider = NonNullable<Agent["sandbox_provider"]>;
|
|
15
|
+
/** A conversation's lifecycle status. */
|
|
16
|
+
export type ConversationStatus = ConversationRecord["status"];
|
|
17
|
+
/**
|
|
18
|
+
* A skill given to an agent — either written into the sandbox verbatim, or
|
|
19
|
+
* installed from GitHub. Exactly one of `content` or `source` per entry; the
|
|
20
|
+
* spec cannot express that, so this narrows what the generated type allows.
|
|
21
|
+
*/
|
|
22
|
+
export type SkillInput = {
|
|
23
|
+
name: string;
|
|
24
|
+
content: string;
|
|
25
|
+
source?: never;
|
|
26
|
+
ref?: never;
|
|
27
|
+
} | {
|
|
28
|
+
source: string;
|
|
29
|
+
ref?: string;
|
|
30
|
+
name?: string;
|
|
31
|
+
content?: never;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* A log event off `/api/team/stream`, which multiplexes every teammate's
|
|
35
|
+
* conversation onto one connection and labels each payload with the two ids a
|
|
36
|
+
* roster routes on. Both are absent on a single-conversation stream, and on
|
|
37
|
+
* the `team` / `schedule` notices the same endpoint interleaves.
|
|
38
|
+
*/
|
|
39
|
+
export interface TeamEvent extends LogEvent {
|
|
40
|
+
conversation_id?: string;
|
|
41
|
+
agent_id?: string;
|
|
42
|
+
}
|
|
43
|
+
/** The log-event streams a conversation carries. */
|
|
44
|
+
export type Stream = "stdout" | "stderr" | "acp" | "stage";
|
|
45
|
+
/**
|
|
46
|
+
* One choice an agent offered when it asked permission. `optionId` is what an
|
|
47
|
+
* answer sends back; `kind` is the vocabulary a UI can render without reading
|
|
48
|
+
* the label (`allow_once`, `allow_always`, `reject_once`, `reject_always`, …).
|
|
49
|
+
* Runtimes may add fields, so the rest is left open.
|
|
50
|
+
*/
|
|
51
|
+
export interface PermissionOption {
|
|
52
|
+
optionId: string;
|
|
53
|
+
kind?: string;
|
|
54
|
+
name?: string;
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The agent is holding a tool call, waiting to be told whether to run it.
|
|
59
|
+
*
|
|
60
|
+
* Only agents with an `ask` entry in `permission_policy` produce these; the
|
|
61
|
+
* default is `auto_allow` and never asks. Nothing else in the turn advances
|
|
62
|
+
* until this is answered, and if nobody answers before the server's timeout it
|
|
63
|
+
* is denied — so a caller that ignores these on an `ask` agent gets a turn that
|
|
64
|
+
* does less than it was told to, not an error.
|
|
65
|
+
*/
|
|
66
|
+
export interface PermissionRequest {
|
|
67
|
+
/** Pass this to `answer`. */
|
|
68
|
+
requestId: string;
|
|
69
|
+
/** What the agent wants to do, in the runtime's words. */
|
|
70
|
+
summary: string | null;
|
|
71
|
+
/** The tool it is asking about. Claude titles this with the command itself. */
|
|
72
|
+
toolName: string | null;
|
|
73
|
+
toolId: string | null;
|
|
74
|
+
/** The choices the agent offered, in its order. Answer with one of these. */
|
|
75
|
+
options: PermissionOption[];
|
|
76
|
+
}
|
|
77
|
+
/** How a turn ended. `timeout` means the SDK stopped waiting, not that the agent did. */
|
|
78
|
+
export type TurnState = "done" | "failed" | "interrupted" | "timeout";
|
|
79
|
+
/** What a run emits while it works. */
|
|
80
|
+
export type RunEvent = {
|
|
81
|
+
type: "conversation";
|
|
82
|
+
conversationId: string;
|
|
83
|
+
conversation: ConversationRecord;
|
|
84
|
+
url: string;
|
|
85
|
+
} | {
|
|
86
|
+
type: "turn-start";
|
|
87
|
+
turnNumber: number;
|
|
88
|
+
turnId: string | null;
|
|
89
|
+
} | {
|
|
90
|
+
type: "text";
|
|
91
|
+
text: string;
|
|
92
|
+
} | {
|
|
93
|
+
type: "thinking";
|
|
94
|
+
text: string;
|
|
95
|
+
} | {
|
|
96
|
+
type: "tool";
|
|
97
|
+
name: string;
|
|
98
|
+
block: Block;
|
|
99
|
+
} | {
|
|
100
|
+
type: "permission";
|
|
101
|
+
request: PermissionRequest;
|
|
102
|
+
block: Block;
|
|
103
|
+
} | {
|
|
104
|
+
type: "block";
|
|
105
|
+
block: Block;
|
|
106
|
+
event: LogEvent;
|
|
107
|
+
} | {
|
|
108
|
+
type: "event";
|
|
109
|
+
event: LogEvent;
|
|
110
|
+
} | {
|
|
111
|
+
type: "turn-end";
|
|
112
|
+
state: TurnState;
|
|
113
|
+
exitCode: number | null;
|
|
114
|
+
reason: string | null;
|
|
115
|
+
};
|
|
116
|
+
/** The finished turn. */
|
|
117
|
+
export interface RunResult {
|
|
118
|
+
/** The conversation the turn ran in. Keep it: the sandbox is still there. */
|
|
119
|
+
conversationId: string;
|
|
120
|
+
/** Where a human watches it. */
|
|
121
|
+
url: string;
|
|
122
|
+
/** Which turn this was — 1 for a fresh `run`, 2+ for a `send`. */
|
|
123
|
+
turnNumber: number;
|
|
124
|
+
/** Everything the agent said, tool noise removed. */
|
|
125
|
+
text: string;
|
|
126
|
+
/** Tool names the agent used, in the order it first used each. */
|
|
127
|
+
toolsUsed: string[];
|
|
128
|
+
/** How the turn ended. */
|
|
129
|
+
state: TurnState;
|
|
130
|
+
/** The runtime's exit code when it reported one. */
|
|
131
|
+
exitCode: number | null;
|
|
132
|
+
/** Why it stopped, when the runtime said. */
|
|
133
|
+
reason: string | null;
|
|
134
|
+
/** The conversation's status when the turn ended. */
|
|
135
|
+
status: string | null;
|
|
136
|
+
/** Every log event consumed, when `collectEvents` was set. */
|
|
137
|
+
events?: LogEvent[];
|
|
138
|
+
}
|
|
139
|
+
/** A named thing an agent can be given: an environment or a vault. */
|
|
140
|
+
export interface NamedResource {
|
|
141
|
+
id: string;
|
|
142
|
+
name: string;
|
|
143
|
+
[key: string]: unknown;
|
|
144
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@managoat/fountain-sdk",
|
|
3
|
+
"version": "1.25.0",
|
|
4
|
+
"description": "Run a coding agent on a real computer, with your repos and your credentials, in one call.",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=20.19"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/managoat/fountain.git",
|
|
16
|
+
"directory": "sdk/typescript"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/managoat/fountain/tree/main/sdk/typescript",
|
|
19
|
+
"keywords": [
|
|
20
|
+
"fountain",
|
|
21
|
+
"agent",
|
|
22
|
+
"sandbox",
|
|
23
|
+
"coding-agent",
|
|
24
|
+
"acp",
|
|
25
|
+
"sdk"
|
|
26
|
+
],
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"node": "./dist/node.js",
|
|
31
|
+
"browser": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./browser": {
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist",
|
|
41
|
+
"README.md",
|
|
42
|
+
"CHANGELOG.md"
|
|
43
|
+
],
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc -p tsconfig.build.json",
|
|
46
|
+
"generate": "openapi-typescript ${FOUNTAIN_OPENAPI:-../../dist/openapi.json} -o src/generated/openapi.ts",
|
|
47
|
+
"verify-contract": "node scripts/verify-contract.mjs",
|
|
48
|
+
"conformance": "node --test test/conformance.test.ts",
|
|
49
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
50
|
+
"test": "node --test test/*.test.ts",
|
|
51
|
+
"prepublishOnly": "node scripts/ci-publishes.mjs && npm run typecheck && npm test && npm run build"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/node": "^26.4.0",
|
|
55
|
+
"openapi-typescript": "^7.13.0",
|
|
56
|
+
"typescript": "^5.7.0"
|
|
57
|
+
},
|
|
58
|
+
"browser": {
|
|
59
|
+
"./dist/node.js": "./dist/index.js"
|
|
60
|
+
}
|
|
61
|
+
}
|