@tonbo/cli 0.0.6 → 0.0.7

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.
@@ -1,90 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { chmod, lstat, mkdir, open, readFile, rename, rm } from "node:fs/promises";
3
- import path from "node:path";
4
- import { defaultConfigDirectory } from "./config.js";
5
- /**
6
- * Human OAuth credentials live beside the CLI config, never in an Agent
7
- * directory. The file is private and atomically replaced so a crash cannot
8
- * leave a partially rotated refresh token. Symlinks are refused because this
9
- * path contains bearer credentials and must not redirect writes elsewhere.
10
- */
11
- export class FileCredentialStore {
12
- filename;
13
- constructor(filename = path.join(defaultConfigDirectory(), "credentials.json")) {
14
- this.filename = filename;
15
- }
16
- async load() {
17
- try {
18
- await assertPrivateRegularFile(this.filename);
19
- const parsed = JSON.parse(await readFile(this.filename, "utf8"));
20
- if (!isOAuthTokenSet(parsed))
21
- throw new Error("invalid token set");
22
- return parsed;
23
- }
24
- catch (error) {
25
- if (error.code === "ENOENT")
26
- return null;
27
- throw new Error(`Could not read Tonbo credentials at ${this.filename}.`, { cause: error });
28
- }
29
- }
30
- async save(tokens) {
31
- if (!isOAuthTokenSet(tokens))
32
- throw new Error("Refusing to store a malformed Tonbo token set.");
33
- const directory = path.dirname(this.filename);
34
- await mkdir(directory, { mode: 0o700, recursive: true });
35
- await preparePrivateDirectory(directory);
36
- await assertExistingDestinationIsSafe(this.filename);
37
- const temporary = path.join(directory, `.${path.basename(this.filename)}.${process.pid}.${randomUUID()}.tmp`);
38
- let handle = null;
39
- try {
40
- handle = await open(temporary, "wx", 0o600);
41
- await handle.writeFile(`${JSON.stringify(tokens, null, 2)}\n`, "utf8");
42
- await handle.sync();
43
- await handle.close();
44
- handle = null;
45
- if (process.platform !== "win32")
46
- await chmod(temporary, 0o600);
47
- await rename(temporary, this.filename);
48
- }
49
- catch (error) {
50
- await handle?.close().catch(() => undefined);
51
- await rm(temporary, { force: true }).catch(() => undefined);
52
- throw new Error(`Could not store Tonbo credentials at ${this.filename}.`, { cause: error });
53
- }
54
- }
55
- }
56
- function isOAuthTokenSet(value) {
57
- if (!value || typeof value !== "object" || Array.isArray(value))
58
- return false;
59
- const token = value;
60
- return (typeof token.access_token === "string" &&
61
- token.access_token.length > 0 &&
62
- (token.refresh_token === undefined || typeof token.refresh_token === "string") &&
63
- (token.expires_at === undefined ||
64
- (Number.isInteger(token.expires_at) && (token.expires_at ?? 0) > 0)));
65
- }
66
- async function preparePrivateDirectory(directory) {
67
- const stat = await lstat(directory);
68
- if (stat.isSymbolicLink() || !stat.isDirectory())
69
- throw new Error("Tonbo config directory must be a real directory.");
70
- if (process.platform !== "win32")
71
- await chmod(directory, 0o700);
72
- }
73
- async function assertExistingDestinationIsSafe(filename) {
74
- try {
75
- const stat = await lstat(filename);
76
- if (stat.isSymbolicLink() || !stat.isFile())
77
- throw new Error("Tonbo credential path must be a regular file.");
78
- }
79
- catch (error) {
80
- if (error.code !== "ENOENT")
81
- throw error;
82
- }
83
- }
84
- async function assertPrivateRegularFile(filename) {
85
- const stat = await lstat(filename);
86
- if (stat.isSymbolicLink() || !stat.isFile())
87
- throw new Error("Tonbo credential path must be a regular file.");
88
- if (process.platform !== "win32" && (stat.mode & 0o077) !== 0)
89
- throw new Error("Tonbo credential file must have mode 0600.");
90
- }
@@ -1,10 +0,0 @@
1
- import { parseDeclaration } from "./contracts.js";
2
- import type { ManagedRevisionSpec, SourceBundle, TonboDeclaration } from "./types.js";
3
- export declare const DECLARATION_FILENAME = ".tonbo";
4
- export declare const DEFAULT_INFERENCE_MODEL = "claude-sonnet-4-5";
5
- export declare function createDeclaration(model?: string, driver?: TonboDeclaration["agent"]["driver"], buildCommand?: string[]): TonboDeclaration;
6
- export declare function renderDeclaration(declaration: TonboDeclaration): string;
7
- export declare function declarationExists(root: string): Promise<boolean>;
8
- export declare function saveDeclaration(root: string, declaration: TonboDeclaration, overwrite: boolean): Promise<void>;
9
- export declare function loadDeclaration(declarationRoot: string): Promise<TonboDeclaration>;
10
- export declare function buildRevision(declaration: ReturnType<typeof parseDeclaration>, source: SourceBundle): ManagedRevisionSpec;
@@ -1,97 +0,0 @@
1
- import { randomUUID } from "node:crypto";
2
- import { lstat, open, readFile, rename, rm } from "node:fs/promises";
3
- import path from "node:path";
4
- import { parse, stringify } from "smol-toml";
5
- import { assertManagedRevision, parseDeclaration } from "./contracts.js";
6
- export const DECLARATION_FILENAME = ".tonbo";
7
- export const DEFAULT_INFERENCE_MODEL = "claude-sonnet-4-5";
8
- export function createDeclaration(model = DEFAULT_INFERENCE_MODEL, driver = { kind: "native" }, buildCommand) {
9
- return parseDeclaration({
10
- version: 1,
11
- agent: { runtime: "pi", driver },
12
- inference: { model: model.trim() },
13
- ...(buildCommand ? { build: { command: buildCommand } } : {}),
14
- });
15
- }
16
- export function renderDeclaration(declaration) {
17
- return `# Tonbo Project Agent configuration.\n${stringify(declaration)}`;
18
- }
19
- export async function declarationExists(root) {
20
- const filename = path.join(root, DECLARATION_FILENAME);
21
- try {
22
- const metadata = await lstat(filename);
23
- if (metadata.isSymbolicLink() || !metadata.isFile())
24
- throw new Error(`${filename} must be a regular file.`);
25
- return true;
26
- }
27
- catch (error) {
28
- if (error.code === "ENOENT")
29
- return false;
30
- throw error;
31
- }
32
- }
33
- export async function saveDeclaration(root, declaration, overwrite) {
34
- const filename = path.join(root, DECLARATION_FILENAME);
35
- const exists = await declarationExists(root);
36
- if (exists && !overwrite)
37
- throw new Error(`${DECLARATION_FILENAME} already exists. Pass --force to replace it.`);
38
- const contents = renderDeclaration(declaration);
39
- if (!overwrite) {
40
- const handle = await open(filename, "wx", 0o644).catch((error) => {
41
- if (error.code === "EEXIST")
42
- throw new Error(`${DECLARATION_FILENAME} already exists. Pass --force to replace it.`);
43
- throw error;
44
- });
45
- try {
46
- await handle.writeFile(contents, "utf8");
47
- await handle.sync();
48
- }
49
- finally {
50
- await handle.close();
51
- }
52
- return;
53
- }
54
- const temporary = path.join(root, `.${DECLARATION_FILENAME}.${process.pid}.${randomUUID()}.tmp`);
55
- let handle;
56
- try {
57
- handle = await open(temporary, "wx", 0o644);
58
- await handle.writeFile(contents, "utf8");
59
- await handle.sync();
60
- await handle.close();
61
- handle = undefined;
62
- await rename(temporary, filename);
63
- }
64
- catch (error) {
65
- await handle?.close().catch(() => undefined);
66
- await rm(temporary, { force: true }).catch(() => undefined);
67
- throw error;
68
- }
69
- }
70
- export async function loadDeclaration(declarationRoot) {
71
- const filename = path.join(declarationRoot, DECLARATION_FILENAME);
72
- let parsed;
73
- try {
74
- parsed = parse(await readFile(filename, "utf8"));
75
- }
76
- catch (error) {
77
- if (error.code === "ENOENT")
78
- throw new Error(`No ${DECLARATION_FILENAME} declaration found at ${filename}.`);
79
- throw new Error(`Could not read ${filename} as TOML.`, { cause: error });
80
- }
81
- return parseDeclaration(parsed);
82
- }
83
- export function buildRevision(declaration, source) {
84
- const spec = {
85
- version: 1,
86
- agent: declaration.agent,
87
- source: {
88
- format: source.format,
89
- sha256: source.sha256,
90
- size_bytes: source.size_bytes,
91
- },
92
- inference: declaration.inference,
93
- ...(declaration.service ? { service: declaration.service } : {}),
94
- };
95
- assertManagedRevision(spec);
96
- return spec;
97
- }
@@ -1,221 +0,0 @@
1
- export declare const piAgentSchema: {
2
- readonly $schema: "https://json-schema.org/draft/2020-12/schema";
3
- readonly $id: "https://contracts.tonbo.dev/agents/pi-agent-v1.schema.json";
4
- readonly title: "PI Agent v1";
5
- readonly type: "object";
6
- readonly additionalProperties: false;
7
- readonly required: readonly ["runtime", "driver"];
8
- readonly properties: {
9
- readonly runtime: {
10
- readonly const: "pi";
11
- };
12
- readonly secrets: {
13
- readonly type: "array";
14
- readonly maxItems: 32;
15
- readonly uniqueItems: true;
16
- readonly items: {
17
- readonly type: "string";
18
- readonly pattern: "^[A-Z_][A-Z0-9_]{0,127}$";
19
- };
20
- };
21
- readonly driver: {
22
- readonly oneOf: readonly [{
23
- readonly type: "object";
24
- readonly additionalProperties: false;
25
- readonly required: readonly ["kind"];
26
- readonly properties: {
27
- readonly kind: {
28
- readonly const: "native";
29
- };
30
- };
31
- }, {
32
- readonly type: "object";
33
- readonly additionalProperties: false;
34
- readonly required: readonly ["kind", "protocol", "command"];
35
- readonly properties: {
36
- readonly kind: {
37
- readonly const: "command";
38
- };
39
- readonly protocol: {
40
- readonly const: "pi-rpc-v1";
41
- };
42
- readonly command: {
43
- readonly type: "array";
44
- readonly minItems: 1;
45
- readonly maxItems: 64;
46
- readonly items: {
47
- readonly type: "string";
48
- readonly minLength: 1;
49
- readonly maxLength: 1024;
50
- };
51
- };
52
- };
53
- }];
54
- };
55
- };
56
- };
57
- export declare const projectServiceSchema: {
58
- readonly $schema: "https://json-schema.org/draft/2020-12/schema";
59
- readonly $id: "https://contracts.tonbo.dev/agents/project-service-v1.schema.json";
60
- readonly title: "Tonbo Project application service v1";
61
- readonly type: "object";
62
- readonly additionalProperties: false;
63
- readonly required: readonly ["command"];
64
- readonly properties: {
65
- readonly command: {
66
- readonly type: "array";
67
- readonly minItems: 1;
68
- readonly maxItems: 64;
69
- readonly items: {
70
- readonly type: "string";
71
- readonly minLength: 1;
72
- readonly maxLength: 4096;
73
- };
74
- };
75
- readonly secrets: {
76
- readonly type: "array";
77
- readonly maxItems: 32;
78
- readonly uniqueItems: true;
79
- readonly items: {
80
- readonly type: "string";
81
- readonly pattern: "^[A-Z_][A-Z0-9_]{0,127}$";
82
- };
83
- };
84
- readonly kubernetes: {
85
- readonly $ref: "https://contracts.tonbo.dev/agents/kubernetes-profiles-v1.schema.json#/$defs/request";
86
- };
87
- };
88
- };
89
- export declare const kubernetesProfilesSchema: {
90
- readonly $schema: "https://json-schema.org/draft/2020-12/schema";
91
- readonly $id: "https://contracts.tonbo.dev/agents/kubernetes-profiles-v1.schema.json";
92
- readonly title: "Tonbo managed Kubernetes profiles v1";
93
- readonly $defs: {
94
- readonly request: {
95
- readonly type: "object";
96
- readonly additionalProperties: false;
97
- readonly required: readonly ["profile"];
98
- readonly properties: {
99
- readonly profile: false;
100
- };
101
- };
102
- };
103
- readonly "x-tonbo-profiles": {};
104
- };
105
- export declare const declarationSchema: {
106
- readonly $schema: "https://json-schema.org/draft/2020-12/schema";
107
- readonly $id: "https://contracts.tonbo.dev/agents/tonbo-declaration-v1.schema.json";
108
- readonly title: "Tonbo Project Agent declaration v1";
109
- readonly type: "object";
110
- readonly additionalProperties: false;
111
- readonly required: readonly ["version", "agent"];
112
- readonly properties: {
113
- readonly version: {
114
- readonly const: 1;
115
- };
116
- readonly agent: {
117
- readonly $ref: "https://contracts.tonbo.dev/agents/pi-agent-v1.schema.json";
118
- };
119
- readonly inference: {
120
- readonly type: "object";
121
- readonly additionalProperties: false;
122
- readonly default: {
123
- readonly model: "claude-sonnet-4-5";
124
- };
125
- readonly required: readonly ["model"];
126
- readonly properties: {
127
- readonly model: {
128
- readonly type: "string";
129
- readonly minLength: 1;
130
- readonly maxLength: 160;
131
- };
132
- };
133
- };
134
- readonly build: {
135
- readonly type: "object";
136
- readonly additionalProperties: false;
137
- readonly required: readonly ["command"];
138
- readonly properties: {
139
- readonly command: {
140
- readonly type: "array";
141
- readonly minItems: 1;
142
- readonly maxItems: 64;
143
- readonly items: {
144
- readonly type: "string";
145
- readonly minLength: 1;
146
- readonly maxLength: 1024;
147
- };
148
- };
149
- };
150
- };
151
- readonly service: {
152
- readonly $ref: "https://contracts.tonbo.dev/agents/project-service-v1.schema.json";
153
- };
154
- };
155
- };
156
- export declare const revisionSchema: {
157
- readonly $schema: "https://json-schema.org/draft/2020-12/schema";
158
- readonly $id: "https://contracts.tonbo.dev/agents/managed-revision-v1.schema.json";
159
- readonly title: "Managed Project revision v1";
160
- readonly type: "object";
161
- readonly additionalProperties: false;
162
- readonly required: readonly ["version", "agent", "source", "inference"];
163
- readonly properties: {
164
- readonly version: {
165
- readonly const: 1;
166
- };
167
- readonly agent: {
168
- readonly $ref: "https://contracts.tonbo.dev/agents/pi-agent-v1.schema.json";
169
- };
170
- readonly source: {
171
- readonly type: "object";
172
- readonly additionalProperties: false;
173
- readonly required: readonly ["format", "sha256", "size_bytes"];
174
- readonly properties: {
175
- readonly format: {
176
- readonly const: "tar-v1";
177
- };
178
- readonly sha256: {
179
- readonly type: "string";
180
- readonly pattern: "^[0-9a-f]{64}$";
181
- };
182
- readonly size_bytes: {
183
- readonly type: "integer";
184
- readonly minimum: 1;
185
- readonly maximum: 67108864;
186
- };
187
- };
188
- };
189
- readonly inference: {
190
- readonly type: "object";
191
- readonly additionalProperties: false;
192
- readonly required: readonly ["model"];
193
- readonly properties: {
194
- readonly model: {
195
- readonly type: "string";
196
- readonly minLength: 1;
197
- readonly maxLength: 160;
198
- };
199
- };
200
- };
201
- readonly service: {
202
- readonly $ref: "https://contracts.tonbo.dev/agents/project-service-v1.schema.json";
203
- };
204
- };
205
- };
206
- export declare const sourceBundleContract: {
207
- readonly version: 1;
208
- readonly format: "tar-v1";
209
- readonly bucket: "agent-source-bundles";
210
- readonly content_type: "application/vnd.tonbo.source+tar";
211
- readonly max_bytes: 67108864;
212
- };
213
- export declare const piSessionContract: {
214
- readonly version: 1;
215
- readonly adapter: "pi-jsonl-v3";
216
- readonly format_version: 3;
217
- readonly durable_completion_timeout_seconds: 30;
218
- readonly session_directory: "/sessions";
219
- readonly path_template: "/sessions/{session_id}.jsonl";
220
- readonly preflight_command: readonly ["/usr/local/bin/artifacts", "runtime", "session-preflight"];
221
- };
@@ -1,261 +0,0 @@
1
- // Generated from contracts/agents/pi-agent-v1.schema.json and contracts/agents/project-service-v1.schema.json and contracts/agents/kubernetes-profiles-v1.schema.json and contracts/agents/tonbo-declaration-v1.schema.json and contracts/agents/managed-revision-v1.schema.json and contracts/agents/source-bundle-v1.json and contracts/agents/pi-session-v1.json.
2
- // Run pnpm generate:contracts after changing a canonical Agent contract.
3
- export const piAgentSchema = {
4
- "$schema": "https://json-schema.org/draft/2020-12/schema",
5
- "$id": "https://contracts.tonbo.dev/agents/pi-agent-v1.schema.json",
6
- "title": "PI Agent v1",
7
- "type": "object",
8
- "additionalProperties": false,
9
- "required": [
10
- "runtime",
11
- "driver"
12
- ],
13
- "properties": {
14
- "runtime": {
15
- "const": "pi"
16
- },
17
- "secrets": {
18
- "type": "array",
19
- "maxItems": 32,
20
- "uniqueItems": true,
21
- "items": {
22
- "type": "string",
23
- "pattern": "^[A-Z_][A-Z0-9_]{0,127}$"
24
- }
25
- },
26
- "driver": {
27
- "oneOf": [
28
- {
29
- "type": "object",
30
- "additionalProperties": false,
31
- "required": [
32
- "kind"
33
- ],
34
- "properties": {
35
- "kind": {
36
- "const": "native"
37
- }
38
- }
39
- },
40
- {
41
- "type": "object",
42
- "additionalProperties": false,
43
- "required": [
44
- "kind",
45
- "protocol",
46
- "command"
47
- ],
48
- "properties": {
49
- "kind": {
50
- "const": "command"
51
- },
52
- "protocol": {
53
- "const": "pi-rpc-v1"
54
- },
55
- "command": {
56
- "type": "array",
57
- "minItems": 1,
58
- "maxItems": 64,
59
- "items": {
60
- "type": "string",
61
- "minLength": 1,
62
- "maxLength": 1024
63
- }
64
- }
65
- }
66
- }
67
- ]
68
- }
69
- }
70
- };
71
- export const projectServiceSchema = {
72
- "$schema": "https://json-schema.org/draft/2020-12/schema",
73
- "$id": "https://contracts.tonbo.dev/agents/project-service-v1.schema.json",
74
- "title": "Tonbo Project application service v1",
75
- "type": "object",
76
- "additionalProperties": false,
77
- "required": [
78
- "command"
79
- ],
80
- "properties": {
81
- "command": {
82
- "type": "array",
83
- "minItems": 1,
84
- "maxItems": 64,
85
- "items": {
86
- "type": "string",
87
- "minLength": 1,
88
- "maxLength": 4096
89
- }
90
- },
91
- "secrets": {
92
- "type": "array",
93
- "maxItems": 32,
94
- "uniqueItems": true,
95
- "items": {
96
- "type": "string",
97
- "pattern": "^[A-Z_][A-Z0-9_]{0,127}$"
98
- }
99
- },
100
- "kubernetes": {
101
- "$ref": "https://contracts.tonbo.dev/agents/kubernetes-profiles-v1.schema.json#/$defs/request"
102
- }
103
- }
104
- };
105
- export const kubernetesProfilesSchema = {
106
- "$schema": "https://json-schema.org/draft/2020-12/schema",
107
- "$id": "https://contracts.tonbo.dev/agents/kubernetes-profiles-v1.schema.json",
108
- "title": "Tonbo managed Kubernetes profiles v1",
109
- "$defs": {
110
- "request": {
111
- "type": "object",
112
- "additionalProperties": false,
113
- "required": [
114
- "profile"
115
- ],
116
- "properties": {
117
- "profile": false
118
- }
119
- }
120
- },
121
- "x-tonbo-profiles": {}
122
- };
123
- export const declarationSchema = {
124
- "$schema": "https://json-schema.org/draft/2020-12/schema",
125
- "$id": "https://contracts.tonbo.dev/agents/tonbo-declaration-v1.schema.json",
126
- "title": "Tonbo Project Agent declaration v1",
127
- "type": "object",
128
- "additionalProperties": false,
129
- "required": [
130
- "version",
131
- "agent"
132
- ],
133
- "properties": {
134
- "version": {
135
- "const": 1
136
- },
137
- "agent": {
138
- "$ref": "https://contracts.tonbo.dev/agents/pi-agent-v1.schema.json"
139
- },
140
- "inference": {
141
- "type": "object",
142
- "additionalProperties": false,
143
- "default": {
144
- "model": "claude-sonnet-4-5"
145
- },
146
- "required": [
147
- "model"
148
- ],
149
- "properties": {
150
- "model": {
151
- "type": "string",
152
- "minLength": 1,
153
- "maxLength": 160
154
- }
155
- }
156
- },
157
- "build": {
158
- "type": "object",
159
- "additionalProperties": false,
160
- "required": [
161
- "command"
162
- ],
163
- "properties": {
164
- "command": {
165
- "type": "array",
166
- "minItems": 1,
167
- "maxItems": 64,
168
- "items": {
169
- "type": "string",
170
- "minLength": 1,
171
- "maxLength": 1024
172
- }
173
- }
174
- }
175
- },
176
- "service": {
177
- "$ref": "https://contracts.tonbo.dev/agents/project-service-v1.schema.json"
178
- }
179
- }
180
- };
181
- export const revisionSchema = {
182
- "$schema": "https://json-schema.org/draft/2020-12/schema",
183
- "$id": "https://contracts.tonbo.dev/agents/managed-revision-v1.schema.json",
184
- "title": "Managed Project revision v1",
185
- "type": "object",
186
- "additionalProperties": false,
187
- "required": [
188
- "version",
189
- "agent",
190
- "source",
191
- "inference"
192
- ],
193
- "properties": {
194
- "version": {
195
- "const": 1
196
- },
197
- "agent": {
198
- "$ref": "https://contracts.tonbo.dev/agents/pi-agent-v1.schema.json"
199
- },
200
- "source": {
201
- "type": "object",
202
- "additionalProperties": false,
203
- "required": [
204
- "format",
205
- "sha256",
206
- "size_bytes"
207
- ],
208
- "properties": {
209
- "format": {
210
- "const": "tar-v1"
211
- },
212
- "sha256": {
213
- "type": "string",
214
- "pattern": "^[0-9a-f]{64}$"
215
- },
216
- "size_bytes": {
217
- "type": "integer",
218
- "minimum": 1,
219
- "maximum": 67108864
220
- }
221
- }
222
- },
223
- "inference": {
224
- "type": "object",
225
- "additionalProperties": false,
226
- "required": [
227
- "model"
228
- ],
229
- "properties": {
230
- "model": {
231
- "type": "string",
232
- "minLength": 1,
233
- "maxLength": 160
234
- }
235
- }
236
- },
237
- "service": {
238
- "$ref": "https://contracts.tonbo.dev/agents/project-service-v1.schema.json"
239
- }
240
- }
241
- };
242
- export const sourceBundleContract = {
243
- "version": 1,
244
- "format": "tar-v1",
245
- "bucket": "agent-source-bundles",
246
- "content_type": "application/vnd.tonbo.source+tar",
247
- "max_bytes": 67108864
248
- };
249
- export const piSessionContract = {
250
- "version": 1,
251
- "adapter": "pi-jsonl-v3",
252
- "format_version": 3,
253
- "durable_completion_timeout_seconds": 30,
254
- "session_directory": "/sessions",
255
- "path_template": "/sessions/{session_id}.jsonl",
256
- "preflight_command": [
257
- "/usr/local/bin/artifacts",
258
- "runtime",
259
- "session-preflight"
260
- ]
261
- };
@@ -1,6 +0,0 @@
1
- export declare class HttpError extends Error {
2
- readonly status: number;
3
- readonly body: unknown;
4
- constructor(message: string, status: number, body: unknown);
5
- }
6
- export declare function requestJson<T>(fetcher: typeof fetch, url: string, init?: RequestInit): Promise<T>;