@tonbo/cli 0.0.5 → 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,139 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { lstat, readFile, readdir } from "node:fs/promises";
3
- import path from "node:path";
4
- import ignore from "ignore";
5
- import tar from "tar-stream";
6
- import { piSessionContract, sourceBundleContract } from "./generated/contracts.js";
7
- const MAX_BUNDLE_BYTES = sourceBundleContract.max_bytes;
8
- const SESSION_SOURCE_DIRECTORY = piSessionContract.session_directory.replace(/^\/+|\/+$/g, "");
9
- const DEFAULT_IGNORES = [
10
- ".git/",
11
- "node_modules/",
12
- ".DS_Store",
13
- ".env",
14
- ".env.*",
15
- "!.env.example",
16
- ".tonbo-cache/",
17
- ".tonbo-system/",
18
- ];
19
- export async function findDeclarationRoot(start) {
20
- let candidate = path.resolve(start);
21
- for (;;) {
22
- try {
23
- if ((await lstat(path.join(candidate, ".tonbo"))).isFile())
24
- return candidate;
25
- }
26
- catch (error) {
27
- if (error.code !== "ENOENT")
28
- throw error;
29
- }
30
- const parent = path.dirname(candidate);
31
- if (parent === candidate) {
32
- throw new Error(`No .tonbo declaration found above ${path.resolve(start)}.`);
33
- }
34
- candidate = parent;
35
- }
36
- }
37
- async function sourceIgnore(root) {
38
- const matcher = ignore().add(DEFAULT_IGNORES);
39
- try {
40
- matcher.add(await readFile(path.join(root, ".tonboignore"), "utf8"));
41
- }
42
- catch (error) {
43
- if (error.code !== "ENOENT")
44
- throw error;
45
- }
46
- return matcher;
47
- }
48
- async function collectFiles(root) {
49
- const matcher = await sourceIgnore(root);
50
- const files = [];
51
- async function visit(directory, relativeDirectory) {
52
- const entries = await readdir(directory, { withFileTypes: true });
53
- entries.sort((left, right) => left.name.localeCompare(right.name, "en"));
54
- for (const entry of entries) {
55
- const relative = relativeDirectory ? `${relativeDirectory}/${entry.name}` : entry.name;
56
- const ignored = matcher.ignores(relative + (entry.isDirectory() ? "/" : ""));
57
- if (ignored)
58
- continue;
59
- if (relative === SESSION_SOURCE_DIRECTORY ||
60
- relative.startsWith(`${SESSION_SOURCE_DIRECTORY}/`)) {
61
- throw new Error(`Source path ${SESSION_SOURCE_DIRECTORY}/ is reserved for durable PI history. Rename it or exclude it with .tonboignore.`);
62
- }
63
- const absolute = path.join(directory, entry.name);
64
- if (entry.isDirectory()) {
65
- await visit(absolute, relative);
66
- continue;
67
- }
68
- const metadata = await lstat(absolute);
69
- if (!metadata.isFile()) {
70
- throw new Error(`Source path ${relative} is not a regular file. V1 does not follow symlinks or special files.`);
71
- }
72
- files.push({
73
- absolute,
74
- mode: metadata.mode & 0o111 ? 0o755 : 0o644,
75
- relative,
76
- size: metadata.size,
77
- });
78
- }
79
- }
80
- await visit(root, "");
81
- if (!files.some((file) => file.relative === ".tonbo")) {
82
- throw new Error("The source bundle must contain .tonbo.");
83
- }
84
- return files;
85
- }
86
- function addEntry(pack, file, contents) {
87
- return new Promise((resolve, reject) => {
88
- pack.entry({
89
- gid: 0,
90
- mode: file.mode,
91
- mtime: new Date(0),
92
- name: file.relative,
93
- size: contents.length,
94
- type: "file",
95
- uid: 0,
96
- }, contents, (error) => (error ? reject(error) : resolve()));
97
- });
98
- }
99
- /**
100
- * Build one deterministic local-source snapshot. Git metadata and timestamps
101
- * are deliberately absent: the bytes the user deploys are the revision input,
102
- * and equal directory contents must produce the same identity on every machine.
103
- */
104
- export async function buildSourceBundle(root) {
105
- const resolvedRoot = path.resolve(root);
106
- const files = await collectFiles(resolvedRoot);
107
- const payloadBytes = files.reduce((total, file) => total + file.size, 0);
108
- if (payloadBytes > MAX_BUNDLE_BYTES) {
109
- throw new Error(`Source files exceed ${MAX_BUNDLE_BYTES} bytes after ignore rules.`);
110
- }
111
- const pack = tar.pack();
112
- const chunks = [];
113
- let size = 0;
114
- pack.on("data", (chunk) => {
115
- size += chunk.length;
116
- if (size > MAX_BUNDLE_BYTES) {
117
- pack.destroy(new Error(`Source bundle exceeds ${MAX_BUNDLE_BYTES} bytes after ignore rules.`));
118
- return;
119
- }
120
- chunks.push(chunk);
121
- });
122
- const completed = new Promise((resolve, reject) => {
123
- pack.on("end", resolve);
124
- pack.on("error", reject);
125
- });
126
- for (const file of files) {
127
- await addEntry(pack, file, await readFile(file.absolute));
128
- }
129
- pack.finalize();
130
- await completed;
131
- const bytes = Buffer.concat(chunks);
132
- return {
133
- bytes,
134
- format: sourceBundleContract.format,
135
- root: resolvedRoot,
136
- sha256: createHash("sha256").update(bytes).digest("hex"),
137
- size_bytes: bytes.length,
138
- };
139
- }
@@ -1,9 +0,0 @@
1
- export interface SshPublicKey {
2
- algorithm: string;
3
- fingerprint: string;
4
- keyBase64: string;
5
- label: string;
6
- }
7
- export declare function parseOpenSshPublicKey(value: string, label: string): SshPublicKey;
8
- export declare function readSshPublicKey(path: string): Promise<SshPublicKey>;
9
- export declare function readDefaultSshPublicKeys(sshDirectory?: string): Promise<SshPublicKey[]>;
@@ -1,36 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { readFile } from "node:fs/promises";
3
- import { homedir } from "node:os";
4
- import { basename, join } from "node:path";
5
- const DEFAULT_PUBLIC_KEYS = ["id_ed25519.pub", "id_ecdsa.pub", "id_rsa.pub"];
6
- const ALGORITHMS = new Set(["ssh-ed25519", "ecdsa-sha2-nistp256", "ssh-rsa"]);
7
- export function parseOpenSshPublicKey(value, label) {
8
- const fields = value.trim().split(/\s+/);
9
- if (fields.length < 2 || !ALGORITHMS.has(fields[0]))
10
- throw new Error("SSH public key must be Ed25519, ECDSA P-256, or RSA.");
11
- const blob = Buffer.from(fields[1], "base64");
12
- if (blob.length < 32 || blob.length > 16_384 || blob.toString("base64") !== fields[1])
13
- throw new Error("SSH public key is not canonical base64.");
14
- return {
15
- algorithm: fields[0],
16
- fingerprint: `SHA256:${createHash("sha256").update(blob).digest("base64").replace(/=$/, "")}`,
17
- keyBase64: fields[1],
18
- label,
19
- };
20
- }
21
- export async function readSshPublicKey(path) {
22
- return parseOpenSshPublicKey(await readFile(path, "utf8"), basename(path, ".pub"));
23
- }
24
- export async function readDefaultSshPublicKeys(sshDirectory = join(homedir(), ".ssh")) {
25
- const keys = [];
26
- for (const name of DEFAULT_PUBLIC_KEYS) {
27
- const key = await readSshPublicKey(join(sshDirectory, name)).catch((error) => {
28
- if (error.code === "ENOENT")
29
- return null;
30
- throw error;
31
- });
32
- if (key)
33
- keys.push(key);
34
- }
35
- return keys;
36
- }
package/dist/src/ssh.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare const PROJECT_SSH_HOST = "tonbo.sh";
2
- export declare function projectSshDestination(projectSlug: string): string;
3
- export declare function launchProjectSsh(projectSlug: string): Promise<number>;
package/dist/src/ssh.js DELETED
@@ -1,22 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- export const PROJECT_SSH_HOST = "tonbo.sh";
3
- export function projectSshDestination(projectSlug) {
4
- return `${projectSlug}@${PROJECT_SSH_HOST}`;
5
- }
6
- export async function launchProjectSsh(projectSlug) {
7
- return new Promise((resolve, reject) => {
8
- // Native OpenSSH owns key selection, known_hosts and terminal behavior;
9
- // terminal behavior. The Project slug is routing metadata; the selected
10
- // public key is the user identity checked by Tonbo's SSH gateway.
11
- const child = spawn("ssh", [projectSshDestination(projectSlug)], {
12
- stdio: "inherit",
13
- });
14
- child.once("error", reject);
15
- child.once("exit", (code, signal) => {
16
- if (signal)
17
- reject(new Error(`ssh was terminated by ${signal}`));
18
- else
19
- resolve(code ?? 1);
20
- });
21
- });
22
- }
@@ -1,85 +0,0 @@
1
- export interface TonboDeclaration {
2
- version: 1;
3
- execution: {
4
- mode: "managed";
5
- runtime: "pi";
6
- };
7
- inference: {
8
- model: string;
9
- };
10
- session_capture: {
11
- adapter: "pi-jsonl-v3";
12
- };
13
- service?: {
14
- command: string[];
15
- secrets?: string[];
16
- kubernetes?: {
17
- profile: string;
18
- };
19
- };
20
- }
21
- export interface ManagedRevisionSpec {
22
- version: 1;
23
- execution: {
24
- mode: "managed";
25
- runtime: "pi";
26
- };
27
- source: {
28
- format: "tar-v1";
29
- sha256: string;
30
- size_bytes: number;
31
- };
32
- inference: {
33
- model: string;
34
- };
35
- session_capture: {
36
- adapter: "pi-jsonl-v3";
37
- };
38
- service?: {
39
- command: string[];
40
- secrets?: string[];
41
- kubernetes?: {
42
- profile: string;
43
- };
44
- };
45
- }
46
- export interface SourceBundle {
47
- bytes: Buffer;
48
- format: "tar-v1";
49
- root: string;
50
- sha256: string;
51
- size_bytes: number;
52
- }
53
- export interface ProjectSummary {
54
- id: string;
55
- name: string;
56
- slug: string;
57
- status: string;
58
- }
59
- export interface ProjectBinding {
60
- projectId: string;
61
- projectSlug: string;
62
- }
63
- export interface ProjectSession {
64
- id: string;
65
- created_revision_id: string;
66
- project_id: string;
67
- }
68
- export interface ProjectSessionTurn {
69
- assistant_text: string;
70
- session_id: string;
71
- turn_id: string;
72
- }
73
- export interface ProjectSessionTurnEvent {
74
- sequence: number;
75
- event_type: "run.started" | "tool.started" | "tool.completed" | "run.completed" | "run.failed";
76
- payload: Record<string, unknown>;
77
- created_at: string;
78
- }
79
- export interface OAuthTokenSet {
80
- access_token: string;
81
- expires_at?: number;
82
- expires_in?: number;
83
- refresh_token?: string;
84
- token_type: string;
85
- }
package/dist/src/types.js DELETED
@@ -1 +0,0 @@
1
- export {};