@runtypelabs/cli 2.59.0 → 2.59.2
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/dist/chunk-0-T9NWjH.js +3899 -0
- package/dist/chunk-0x7UKC1U.js +17 -0
- package/dist/chunk-2ySxXtcg.js +418 -0
- package/dist/chunk-3An_BRHv.js +501 -0
- package/dist/chunk-6uTxgdiY.js +16218 -0
- package/dist/chunk-87nRnNRG.js +1363 -0
- package/dist/chunk-B3wo8uRx.js +322 -0
- package/dist/chunk-BGp3ZdBy.js +560 -0
- package/dist/chunk-BJQv9Elp.js +107 -0
- package/dist/chunk-BOpO6xE-.js +6053 -0
- package/dist/chunk-BQXXCL8B.js +102 -0
- package/dist/chunk-BV-8isOd.js +34 -0
- package/dist/chunk-BVMhjGVe.js +826 -0
- package/dist/chunk-BW2fg46T.js +141 -0
- package/dist/chunk-BWJdY5Ag.js +36 -0
- package/dist/chunk-BYJOrLhh.js +302 -0
- package/dist/chunk-BYab8EVL.js +127 -0
- package/dist/chunk-BfEKvp7h.js +82 -0
- package/dist/chunk-BhgLSfH6.js +1123 -0
- package/dist/chunk-BirUxTtH.js +296 -0
- package/dist/chunk-BmB6UVZ9.js +1559 -0
- package/dist/chunk-BnWhIqW1.js +109 -0
- package/dist/chunk-Bpfnfk0t.js +123 -0
- package/dist/chunk-BrhgdnM3.js +108 -0
- package/dist/chunk-Bt0XAgX5.js +327 -0
- package/dist/chunk-Bu0FJr6S.js +84 -0
- package/dist/chunk-BvEoKpN3.js +255 -0
- package/dist/chunk-BxNJgYbE.js +28 -0
- package/dist/chunk-C1OFhd7F.js +6131 -0
- package/dist/chunk-C7e7WwbU.js +331 -0
- package/dist/chunk-CDTYP6bN.js +558 -0
- package/dist/chunk-CGDQoqDC.js +24 -0
- package/dist/chunk-CJraEBVd.js +127 -0
- package/dist/chunk-CQrNhOtv.js +40 -0
- package/dist/chunk-CW6AzBH6.js +128 -0
- package/dist/chunk-CXgL4w-9.js +317 -0
- package/dist/chunk-CZrqoPyf.js +233 -0
- package/dist/chunk-CcFCyqbB.js +83 -0
- package/dist/chunk-CdaIvO-y.js +485 -0
- package/dist/chunk-CehSXtgK.js +624 -0
- package/dist/chunk-Ciqkop65.js +218 -0
- package/dist/chunk-CoAWdSiE.js +43 -0
- package/dist/chunk-Crb4y7t4.js +830 -0
- package/dist/chunk-CrlqIfmb.js +337 -0
- package/dist/chunk-Cs4pwCQ-.js +324 -0
- package/dist/chunk-CwM_9y01.js +519 -0
- package/dist/chunk-CyRbIJg8.js +440 -0
- package/dist/chunk-D0OHsyMy.js +212 -0
- package/dist/chunk-D3y2bURs.js +1347 -0
- package/dist/chunk-D4_mJk03.js +2338 -0
- package/dist/chunk-D6C8rned.js +578 -0
- package/dist/chunk-D9ZbUnks.js +11 -0
- package/dist/chunk-DEPmLshX.js +834 -0
- package/dist/chunk-DFj1UPB2.js +330 -0
- package/dist/chunk-DGdFdZVf.js +197 -0
- package/dist/chunk-DGv7X9S_.js +63 -0
- package/dist/chunk-DJQ47WYZ.js +664 -0
- package/dist/chunk-DJw3O61j.js +1974 -0
- package/dist/chunk-DK4FbWVK.js +100 -0
- package/dist/chunk-DSRYhUus.js +993 -0
- package/dist/chunk-DajZ9Eg4.js +299 -0
- package/dist/chunk-Df4dunvU.js +195 -0
- package/dist/chunk-DjNTPhfO.js +481 -0
- package/dist/chunk-Dn8eaJuu.js +1042 -0
- package/dist/chunk-DwDWqSxM.js +637 -0
- package/dist/chunk-Dz7cEtxl.js +84 -0
- package/dist/chunk-E_0bgjrS.js +359 -0
- package/dist/chunk-KPYN2vUp.js +776 -0
- package/dist/chunk-KcqPQJBi.js +86 -0
- package/dist/chunk-N9H0JnoG.js +349 -0
- package/dist/chunk-NONFcXkn.js +728 -0
- package/dist/chunk-PrFjcpmH.js +256 -0
- package/dist/chunk-QSfNYiw9.js +11 -0
- package/dist/chunk-R265bzj9.js +226 -0
- package/dist/chunk-X9V_r6jM.js +166 -0
- package/dist/chunk-ZBtPUtyA.js +55 -0
- package/dist/chunk-ZCTfmOs7.js +4939 -0
- package/dist/chunk-h6oavj0t.js +97 -0
- package/dist/chunk-i7DwkvvD.js +42 -0
- package/dist/chunk-mG-4eZ6S.js +203 -0
- package/dist/chunk-o0ygUbCf.js +313 -0
- package/dist/chunk-ucu5lrDZ.js +5715 -0
- package/dist/index.js +11367 -73764
- package/package.json +6 -6
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { r as createCliClient } from "./chunk-BW2fg46T.js";
|
|
3
|
+
import { n as ensureAuth } from "./chunk-CJraEBVd.js";
|
|
4
|
+
import { a as printJson, t as apiErrorDetails } from "./chunk-CcFCyqbB.js";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import { existsSync, lstatSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
8
|
+
import { join, relative } from "node:path";
|
|
9
|
+
import { zipSync } from "fflate";
|
|
10
|
+
// src/commands/apps.ts
|
|
11
|
+
const appsCommand = new Command("apps").description("Manage Runtype Apps (hosted AI apps on *.runtype.run)");
|
|
12
|
+
const MANIFEST_FILENAME = "runtype.app.json";
|
|
13
|
+
/** Walk a directory into a zippable map of relative paths, skipping dotfiles. */
|
|
14
|
+
function collectBundleFiles(dir) {
|
|
15
|
+
const zippable = {};
|
|
16
|
+
const walk = (current) => {
|
|
17
|
+
for (const entry of readdirSync(current)) {
|
|
18
|
+
if (entry.startsWith(".")) continue;
|
|
19
|
+
const full = join(current, entry);
|
|
20
|
+
const stat = lstatSync(full);
|
|
21
|
+
if (stat.isSymbolicLink()) continue;
|
|
22
|
+
if (stat.isDirectory()) {
|
|
23
|
+
if (entry === "node_modules") continue;
|
|
24
|
+
walk(full);
|
|
25
|
+
} else zippable[relative(dir, full).split("\\").join("/")] = readFileSync(full);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
walk(dir);
|
|
29
|
+
return zippable;
|
|
30
|
+
}
|
|
31
|
+
function fail(message, jsonMode, code, cause) {
|
|
32
|
+
if (jsonMode) printJson({
|
|
33
|
+
status: "error",
|
|
34
|
+
error: message,
|
|
35
|
+
code,
|
|
36
|
+
details: apiErrorDetails(cause)
|
|
37
|
+
});
|
|
38
|
+
else console.error(chalk.red(message));
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const appsApi = {
|
|
42
|
+
list: (client) => client.get("/apps"),
|
|
43
|
+
create: (client, data) => client.post("/apps", data),
|
|
44
|
+
delete: (client, appId) => client.delete(`/apps/${appId}`),
|
|
45
|
+
listVersions: (client, appId) => client.get(`/apps/${appId}/versions`),
|
|
46
|
+
uploadVersion: (client, appId, zipBytes) => client.postBinary(`/apps/${appId}/versions`, zipBytes, "application/zip"),
|
|
47
|
+
activate: (client, appId, versionId) => client.post(`/apps/${appId}/activate`, { versionId })
|
|
48
|
+
};
|
|
49
|
+
appsCommand.command("list").description("List your apps").option("--json", "Structured JSON output").action(async (options, cmd) => {
|
|
50
|
+
const globals = cmd.optsWithGlobals();
|
|
51
|
+
const jsonMode = !!(options.json ?? globals.json);
|
|
52
|
+
const apiKey = await ensureAuth();
|
|
53
|
+
if (!apiKey) return;
|
|
54
|
+
const client = createCliClient(apiKey);
|
|
55
|
+
try {
|
|
56
|
+
const { data } = await appsApi.list(client);
|
|
57
|
+
if (jsonMode) {
|
|
58
|
+
printJson({ data });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (data.length === 0) {
|
|
62
|
+
console.log(chalk.yellow("No apps yet. Create one with `runtype apps create`."));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
for (const app of data) {
|
|
66
|
+
const status = app.status === "suspended" ? chalk.red("suspended") : chalk.green("active");
|
|
67
|
+
const serving = app.activeVersionId ? "" : chalk.dim(" (no active version)");
|
|
68
|
+
console.log(`${chalk.bold(app.name)} ${chalk.dim(app.id)}`);
|
|
69
|
+
console.log(` ${app.url} ${status} ${app.visibility}${serving}`);
|
|
70
|
+
}
|
|
71
|
+
} catch (error) {
|
|
72
|
+
fail(`Failed to list apps: ${error instanceof Error ? error.message : String(error)}`, jsonMode, "LIST_FAILED", error);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
appsCommand.command("create").description("Create an app (the hostname is {slug}-{shortId}.runtype.run)").requiredOption("-s, --slug <slug>", "Hostname slug (lowercase, must start with a letter)").requiredOption("-n, --name <name>", "Display name").option("-d, --description <text>", "Description").option("--visibility <visibility>", "public or unlisted (default unlisted)").option("--json", "Structured JSON output").action(async (options, cmd) => {
|
|
76
|
+
const globals = cmd.optsWithGlobals();
|
|
77
|
+
const jsonMode = !!(options.json ?? globals.json);
|
|
78
|
+
const apiKey = await ensureAuth();
|
|
79
|
+
if (!apiKey) return;
|
|
80
|
+
const client = createCliClient(apiKey);
|
|
81
|
+
try {
|
|
82
|
+
const app = await appsApi.create(client, {
|
|
83
|
+
slug: options.slug,
|
|
84
|
+
name: options.name,
|
|
85
|
+
description: options.description,
|
|
86
|
+
visibility: options.visibility
|
|
87
|
+
});
|
|
88
|
+
if (jsonMode) {
|
|
89
|
+
printJson(app);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
console.log(chalk.green(`Created ${app.name} (${app.id})`));
|
|
93
|
+
console.log(` ${app.url}`);
|
|
94
|
+
console.log(chalk.dim(" Deploy a bundle with `runtype apps deploy <dir> --app " + app.id + "`"));
|
|
95
|
+
} catch (error) {
|
|
96
|
+
fail(`Failed to create app: ${error instanceof Error ? error.message : String(error)}`, jsonMode, "CREATE_FAILED", error);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
appsCommand.command("deploy <dir>").description("Zip a bundle directory, upload it as a new version, and activate it").requiredOption("-a, --app <appId>", "The app id (app_...) to deploy to").option("--no-activate", "Upload without activating (what is served stays unchanged)").option("--json", "Structured JSON output").action(async (dir, options, cmd) => {
|
|
100
|
+
const globals = cmd.optsWithGlobals();
|
|
101
|
+
const jsonMode = !!(options.json ?? globals.json);
|
|
102
|
+
const apiKey = await ensureAuth();
|
|
103
|
+
if (!apiKey) return;
|
|
104
|
+
if (!existsSync(dir) || !statSync(dir).isDirectory()) fail(`Not a directory: ${dir}`, jsonMode, "INVALID_DIR");
|
|
105
|
+
let bundleFiles = {};
|
|
106
|
+
try {
|
|
107
|
+
bundleFiles = collectBundleFiles(dir);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
fail(`Failed to read ${dir}: ${error instanceof Error ? error.message : String(error)}`, jsonMode, "INVALID_DIR");
|
|
110
|
+
}
|
|
111
|
+
if (!bundleFiles["index.html"]) fail(`${dir} is missing index.html at its root (symlinked files are not bundled).`, jsonMode, "MISSING_INDEX");
|
|
112
|
+
if (!bundleFiles[MANIFEST_FILENAME]) fail(`${dir} is missing ${MANIFEST_FILENAME} at its root (symlinked files are not bundled). Every app bundle needs a manifest; see the build-runtype-app skill or the Runtype docs.`, jsonMode, "MISSING_MANIFEST");
|
|
113
|
+
const client = createCliClient(apiKey);
|
|
114
|
+
try {
|
|
115
|
+
const zipBytes = zipSync(bundleFiles);
|
|
116
|
+
if (!jsonMode) console.log(chalk.dim(`Uploading ${(zipBytes.byteLength / 1024).toFixed(1)} KB bundle...`));
|
|
117
|
+
const version = await appsApi.uploadVersion(client, options.app, zipBytes);
|
|
118
|
+
let app;
|
|
119
|
+
if (options.activate) try {
|
|
120
|
+
app = (await appsApi.activate(client, options.app, version.id)).app;
|
|
121
|
+
} catch (error) {
|
|
122
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
123
|
+
if (jsonMode) printJson({
|
|
124
|
+
status: "error",
|
|
125
|
+
error: `Activation failed: ${message}`,
|
|
126
|
+
code: "ACTIVATE_FAILED",
|
|
127
|
+
details: apiErrorDetails(error),
|
|
128
|
+
version,
|
|
129
|
+
activated: false
|
|
130
|
+
});
|
|
131
|
+
else {
|
|
132
|
+
console.error(chalk.red(`Uploaded version ${version.versionNumber}, but activation failed: ${message}`));
|
|
133
|
+
console.error(chalk.dim(` Retry with \`runtype apps activate ${options.app} ${version.id}\` (no re-upload needed).`));
|
|
134
|
+
}
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
if (jsonMode) {
|
|
138
|
+
printJson({
|
|
139
|
+
version,
|
|
140
|
+
app,
|
|
141
|
+
activated: options.activate
|
|
142
|
+
});
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
console.log(chalk.green(`Deployed version ${version.versionNumber} (${version.fileCount} files, ${(version.sizeBytes / 1024).toFixed(1)} KB)`));
|
|
146
|
+
if (app) console.log(` Live at ${chalk.bold(app.url)}`);
|
|
147
|
+
else console.log(chalk.dim(` Uploaded but not activated. Activate with \`runtype apps activate ${options.app} ${version.id}\``));
|
|
148
|
+
} catch (error) {
|
|
149
|
+
fail(`Deploy failed: ${error instanceof Error ? error.message : String(error)}`, jsonMode, "DEPLOY_FAILED", error);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
appsCommand.command("versions <appId>").description("List an app's versions, newest first").option("--json", "Structured JSON output").action(async (appId, options, cmd) => {
|
|
153
|
+
const globals = cmd.optsWithGlobals();
|
|
154
|
+
const jsonMode = !!(options.json ?? globals.json);
|
|
155
|
+
const apiKey = await ensureAuth();
|
|
156
|
+
if (!apiKey) return;
|
|
157
|
+
const client = createCliClient(apiKey);
|
|
158
|
+
try {
|
|
159
|
+
const { data } = await appsApi.listVersions(client, appId);
|
|
160
|
+
if (jsonMode) {
|
|
161
|
+
printJson({ data });
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (data.length === 0) {
|
|
165
|
+
console.log(chalk.yellow("No versions uploaded yet."));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
for (const version of data) {
|
|
169
|
+
const marker = version.status === "active" ? chalk.green(" (active)") : "";
|
|
170
|
+
console.log(`v${version.versionNumber} ${chalk.dim(version.id)} ${version.fileCount} files, ${(version.sizeBytes / 1024).toFixed(1)} KB${marker}`);
|
|
171
|
+
}
|
|
172
|
+
} catch (error) {
|
|
173
|
+
fail(`Failed to list versions: ${error instanceof Error ? error.message : String(error)}`, jsonMode, "VERSIONS_FAILED", error);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
appsCommand.command("activate <appId> <versionId>").description("Activate an uploaded version (deploy or rollback)").option("--json", "Structured JSON output").action(async (appId, versionId, options, cmd) => {
|
|
177
|
+
const globals = cmd.optsWithGlobals();
|
|
178
|
+
const jsonMode = !!(options.json ?? globals.json);
|
|
179
|
+
const apiKey = await ensureAuth();
|
|
180
|
+
if (!apiKey) return;
|
|
181
|
+
const client = createCliClient(apiKey);
|
|
182
|
+
try {
|
|
183
|
+
const { app, version } = await appsApi.activate(client, appId, versionId);
|
|
184
|
+
if (jsonMode) {
|
|
185
|
+
printJson({
|
|
186
|
+
app,
|
|
187
|
+
version
|
|
188
|
+
});
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
console.log(chalk.green(`Activated version ${version.versionNumber}`));
|
|
192
|
+
console.log(` Live at ${chalk.bold(app.url)}`);
|
|
193
|
+
} catch (error) {
|
|
194
|
+
fail(`Activation failed: ${error instanceof Error ? error.message : String(error)}`, jsonMode, "ACTIVATE_FAILED", error);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
appsCommand.command("delete <appId>").description("Permanently delete an app, its versions, and its hosting").option("--json", "Structured JSON output").action(async (appId, options, cmd) => {
|
|
198
|
+
const globals = cmd.optsWithGlobals();
|
|
199
|
+
const jsonMode = !!(options.json ?? globals.json);
|
|
200
|
+
const apiKey = await ensureAuth();
|
|
201
|
+
if (!apiKey) return;
|
|
202
|
+
const client = createCliClient(apiKey);
|
|
203
|
+
try {
|
|
204
|
+
await appsApi.delete(client, appId);
|
|
205
|
+
if (jsonMode) {
|
|
206
|
+
printJson({
|
|
207
|
+
status: "deleted",
|
|
208
|
+
appId
|
|
209
|
+
});
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
console.log(chalk.green(`Deleted ${appId}`));
|
|
213
|
+
} catch (error) {
|
|
214
|
+
fail(`Delete failed: ${error instanceof Error ? error.message : String(error)}`, jsonMode, "DELETE_FAILED", error);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
export { appsCommand };
|
|
218
|
+
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// src/ink/ui.ts
|
|
3
|
+
let React;
|
|
4
|
+
let useState;
|
|
5
|
+
let useEffect;
|
|
6
|
+
let render;
|
|
7
|
+
let Text;
|
|
8
|
+
let DataList;
|
|
9
|
+
let EntityCard;
|
|
10
|
+
let MutationResult;
|
|
11
|
+
let ConfirmPrompt;
|
|
12
|
+
let enterAltScreen;
|
|
13
|
+
let useMutationState;
|
|
14
|
+
let mutationResultProps;
|
|
15
|
+
let loading;
|
|
16
|
+
/**
|
|
17
|
+
* Load React, Ink and the shared screens behind this module's bindings. Commands import the
|
|
18
|
+
* bindings statically and stay cheap to load; `index.ts` awaits this before an action that can
|
|
19
|
+
* render runs.
|
|
20
|
+
*/
|
|
21
|
+
function loadUi() {
|
|
22
|
+
loading ??= Promise.all([
|
|
23
|
+
import("react"),
|
|
24
|
+
import("ink"),
|
|
25
|
+
import("./chunk-PrFjcpmH.js")
|
|
26
|
+
]).then(([react, ink, shared]) => {
|
|
27
|
+
React = react.default;
|
|
28
|
+
useState = react.useState;
|
|
29
|
+
useEffect = react.useEffect;
|
|
30
|
+
render = ink.render;
|
|
31
|
+
Text = ink.Text;
|
|
32
|
+
DataList = shared.DataList;
|
|
33
|
+
EntityCard = shared.EntityCard;
|
|
34
|
+
MutationResult = shared.MutationResult;
|
|
35
|
+
ConfirmPrompt = shared.ConfirmPrompt;
|
|
36
|
+
enterAltScreen = shared.enterAltScreen;
|
|
37
|
+
useMutationState = shared.useMutationState;
|
|
38
|
+
mutationResultProps = shared.mutationResultProps;
|
|
39
|
+
});
|
|
40
|
+
return loading;
|
|
41
|
+
}
|
|
42
|
+
export { ConfirmPrompt, DataList, EntityCard, MutationResult, React, Text, enterAltScreen, loadUi, mutationResultProps, render, useEffect, useMutationState, useState };
|
|
43
|
+
|