@miosa/cli 1.0.90 → 1.0.92
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 +12 -4
- package/README.md +20 -57
- package/dist/bin/miosa.js +0 -2
- package/dist/bin/miosa.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +21 -2
- package/dist/client.js.map +1 -1
- package/dist/commands/agent.js +2 -2
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/capabilities.d.ts.map +1 -1
- package/dist/commands/capabilities.js +59 -86
- package/dist/commands/capabilities.js.map +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +1 -12
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/computers.d.ts.map +1 -1
- package/dist/commands/computers.js +95 -96
- package/dist/commands/computers.js.map +1 -1
- package/dist/commands/connectors.d.ts.map +1 -1
- package/dist/commands/connectors.js +1 -509
- package/dist/commands/connectors.js.map +1 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +0 -147
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/devices.d.ts.map +1 -1
- package/dist/commands/devices.js +41 -416
- package/dist/commands/devices.js.map +1 -1
- package/dist/commands/doctor.d.ts +0 -7
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +23 -28
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/machines.d.ts +3 -0
- package/dist/commands/machines.d.ts.map +1 -0
- package/dist/commands/machines.js +29 -0
- package/dist/commands/machines.js.map +1 -0
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +8 -106
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/sandbox.d.ts.map +1 -1
- package/dist/commands/sandbox.js +51 -187
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/templates.d.ts.map +1 -1
- package/dist/commands/templates.js +19 -30
- package/dist/commands/templates.js.map +1 -1
- package/dist/commands/webhooks.d.ts.map +1 -1
- package/dist/commands/webhooks.js +0 -5
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/commands/workspaces.d.ts.map +1 -1
- package/dist/commands/workspaces.js +0 -47
- package/dist/commands/workspaces.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/sandbox.js
CHANGED
|
@@ -104,9 +104,8 @@ export function register(program) {
|
|
|
104
104
|
console.log(JSON.stringify(data, null, 2));
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
: (unwrap(await client().apiGet(apiPath(`/sandboxes/${enc(id)}`))) ?? {});
|
|
107
|
+
const raw = unwrap(await client().apiGet(apiPath(`/sandboxes/${enc(id)}`)));
|
|
108
|
+
const sb = (raw ?? {});
|
|
110
109
|
printBanner({ subtitle: "Sandbox" });
|
|
111
110
|
const rows = [
|
|
112
111
|
{ label: "ID", value: chalk.bold(str(sb["id"])), icon: icon.info },
|
|
@@ -143,23 +142,6 @@ export function register(program) {
|
|
|
143
142
|
value: chalk.cyan(str(sb["public_url"])),
|
|
144
143
|
});
|
|
145
144
|
}
|
|
146
|
-
const preview = asRecord(sb["preview"]);
|
|
147
|
-
if (preview?.["url"]) {
|
|
148
|
-
rows.push({
|
|
149
|
-
label: "Preview URL",
|
|
150
|
-
value: chalk.cyan(str(preview["url"])),
|
|
151
|
-
});
|
|
152
|
-
rows.push({
|
|
153
|
-
label: "URL class",
|
|
154
|
-
value: str(preview["url_class"] ?? "temporary_preview"),
|
|
155
|
-
});
|
|
156
|
-
rows.push({
|
|
157
|
-
label: "Embeddable",
|
|
158
|
-
value: preview["stable_for_embedding"] === true
|
|
159
|
-
? chalk.green("yes")
|
|
160
|
-
: chalk.yellow("temporary"),
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
145
|
if (sb["created_at"]) {
|
|
164
146
|
rows.push({
|
|
165
147
|
label: "Created",
|
|
@@ -391,12 +373,14 @@ export function register(program) {
|
|
|
391
373
|
}
|
|
392
374
|
}));
|
|
393
375
|
registerSandboxConnectorCommands(sandbox);
|
|
394
|
-
// prompt — invoke an in-Sandbox AI agent CLI
|
|
395
|
-
//
|
|
376
|
+
// prompt — invoke an in-Sandbox AI agent CLI (mirrors `box prompt`).
|
|
377
|
+
// Implemented through Agent Runs so callers get a stable run response while
|
|
378
|
+
// execution still happens inside the remote filesystem.
|
|
396
379
|
sandbox
|
|
397
380
|
.command("prompt <sandbox-id> <instruction...>")
|
|
398
|
-
.description("Run an in-Sandbox AI agent with the given instruction")
|
|
399
|
-
.option("--provider <name>", "
|
|
381
|
+
.description("Run an in-Sandbox AI agent runtime with the given instruction")
|
|
382
|
+
.option("--provider <name>", "Agent runtime: claude (default), claude-code, codex, pi, hermes, osa, custom")
|
|
383
|
+
.option("--runtime-command <command>", "Executable command for --provider custom, e.g. 'hermes-agent run'")
|
|
400
384
|
.option("--model <name>", "Provider-specific model name")
|
|
401
385
|
.option("--connector <uid>", "MIOSA Connect connector UID to preflight before running the agent")
|
|
402
386
|
.option("--preflight", "Verify the Sandbox has the requested provider connector before exec")
|
|
@@ -411,17 +395,13 @@ export function register(program) {
|
|
|
411
395
|
.option("--json", "Output as JSON")
|
|
412
396
|
.action((id, words, opts) => runAction(async () => {
|
|
413
397
|
const provider = opts.provider ?? "claude";
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
"claude-code",
|
|
417
|
-
"codex",
|
|
418
|
-
"hermes",
|
|
419
|
-
"osa",
|
|
420
|
-
"pi",
|
|
421
|
-
];
|
|
422
|
-
if (!allowedProviders.includes(provider)) {
|
|
398
|
+
if (!isSupportedPromptProvider(provider)) {
|
|
399
|
+
const allowedProviders = supportedPromptProviders();
|
|
423
400
|
throw new Error(`Unsupported provider "${provider}". Use: ${allowedProviders.join(", ")}`);
|
|
424
401
|
}
|
|
402
|
+
if (opts.runtimeCommand && provider !== "custom") {
|
|
403
|
+
throw new Error("--runtime-command can only be used with --provider custom");
|
|
404
|
+
}
|
|
425
405
|
if (opts.connector || opts.preflight) {
|
|
426
406
|
await preflightSandboxConnector(id, {
|
|
427
407
|
provider,
|
|
@@ -437,6 +417,8 @@ export function register(program) {
|
|
|
437
417
|
provider,
|
|
438
418
|
prompt: instruction,
|
|
439
419
|
};
|
|
420
|
+
if (opts.runtimeCommand)
|
|
421
|
+
body["command"] = opts.runtimeCommand;
|
|
440
422
|
if (opts.model)
|
|
441
423
|
body["model"] = opts.model;
|
|
442
424
|
if (opts.cwd)
|
|
@@ -686,7 +668,6 @@ export function register(program) {
|
|
|
686
668
|
.option("--sandbox <id>", "Existing sandbox ID. Creates one when omitted")
|
|
687
669
|
.option("--template <template>", "Template for new sandbox", "miosa-sandbox")
|
|
688
670
|
.option("--name <name>", "Name for a new sandbox")
|
|
689
|
-
.option("--always-on", "Create a new sandbox that keeps running instead of timing out")
|
|
690
671
|
.option("--port <port>", "Preview port", parseIntegerOption)
|
|
691
672
|
.option("--publish-port <port>", "Alias for --port", parseIntegerOption)
|
|
692
673
|
.option("--start <command>", "Start command to run inside /workspace")
|
|
@@ -696,13 +677,6 @@ export function register(program) {
|
|
|
696
677
|
.option("--revision <revision>", "Git revision/branch for --source git:...")
|
|
697
678
|
.option("--depth <n>", "Git clone depth for --source git:...", parseIntegerOption)
|
|
698
679
|
.option("--wait", "Wait until the public preview returns a good HTTP status")
|
|
699
|
-
.option("--publish", "Publish the workspace to a durable deployment after preview succeeds")
|
|
700
|
-
.option("--slug <slug>", "Deployment slug to use with --publish")
|
|
701
|
-
.option("--static", "Publish as a static deployment when using --publish")
|
|
702
|
-
.option("--deployment-type <type>", "Deployment runtime type for --publish: miosa_deploy, docker_deploy, dynamic, static")
|
|
703
|
-
.option("--domain <domain>", "Custom domain to attach when using --publish")
|
|
704
|
-
.option("--build-command <cmd>", "Build command to run before publish")
|
|
705
|
-
.option("--run-command <cmd>", "Run command for durable dynamic publish")
|
|
706
680
|
.option("--timeout <duration>", "Wait timeout, e.g. 180s or 3m", parseDurationSec, 180)
|
|
707
681
|
.option("--probe-path <path>", "HTTP path to probe")
|
|
708
682
|
.option("--json", "Output as JSON")
|
|
@@ -717,16 +691,10 @@ export function register(program) {
|
|
|
717
691
|
console.log(` ${chalk.bold("Sandbox")} ${result.sandbox_id}`);
|
|
718
692
|
console.log(` ${chalk.bold("Port")} ${result.port}`);
|
|
719
693
|
console.log(` ${chalk.bold("Preview")} ${chalk.cyan(result.preview_url)}`);
|
|
720
|
-
if (result.deployment?.url) {
|
|
721
|
-
console.log(` ${chalk.bold("Durable")} ${chalk.cyan(result.deployment.url)}`);
|
|
722
|
-
}
|
|
723
694
|
console.log(` ${chalk.bold("Ready")} ${result.preview_ready
|
|
724
695
|
? chalk.green("yes")
|
|
725
696
|
: chalk.yellow("not verified")}`);
|
|
726
697
|
console.log();
|
|
727
|
-
console.log(chalk.yellow(" This is a timed sandbox preview. Persistent keeps disk; always-on keeps the app running."));
|
|
728
|
-
console.log(chalk.dim(` For a durable client link, publish it: miosa sandbox publish ${result.sandbox_id} --path /workspace --slug <slug> --wait`));
|
|
729
|
-
console.log();
|
|
730
698
|
}
|
|
731
699
|
catch (err) {
|
|
732
700
|
handleSandboxDeployError(err, opts);
|
|
@@ -751,7 +719,6 @@ export function register(program) {
|
|
|
751
719
|
return;
|
|
752
720
|
}
|
|
753
721
|
console.log(result.url);
|
|
754
|
-
printPreviewContractHint(result);
|
|
755
722
|
if (!result.ready) {
|
|
756
723
|
console.error(chalk.yellow(`Preview route created but not verified yet (${result.error ?? result.status ?? "pending"}).`));
|
|
757
724
|
}
|
|
@@ -1829,9 +1796,6 @@ async function showSandboxWithPreview(sandboxId, port, probePath) {
|
|
|
1829
1796
|
catch (err) {
|
|
1830
1797
|
preview = {
|
|
1831
1798
|
url: "",
|
|
1832
|
-
url_class: "temporary_preview",
|
|
1833
|
-
stable_for_embedding: false,
|
|
1834
|
-
recommended_next_action: "create_alias_or_publish",
|
|
1835
1799
|
ready: false,
|
|
1836
1800
|
status: null,
|
|
1837
1801
|
latency_ms: null,
|
|
@@ -1844,10 +1808,6 @@ async function showSandboxWithPreview(sandboxId, port, probePath) {
|
|
|
1844
1808
|
preview: {
|
|
1845
1809
|
url: preview?.url || null,
|
|
1846
1810
|
port,
|
|
1847
|
-
url_info: preview?.url_info ?? null,
|
|
1848
|
-
url_class: preview?.url_class ?? "temporary_preview",
|
|
1849
|
-
stable_for_embedding: preview?.stable_for_embedding ?? false,
|
|
1850
|
-
recommended_next_action: preview?.recommended_next_action ?? "create_alias_or_publish",
|
|
1851
1811
|
route_ready: Boolean(preview?.url),
|
|
1852
1812
|
tls_ready: preview?.ready ?? false,
|
|
1853
1813
|
last_status: preview?.status ?? null,
|
|
@@ -1870,28 +1830,12 @@ async function previewSandbox(sandboxId, port, opts) {
|
|
|
1870
1830
|
: await probePublicPreview(url, opts.probePath);
|
|
1871
1831
|
return {
|
|
1872
1832
|
url,
|
|
1873
|
-
url_class: stringField(exposed, "url_class") ??
|
|
1874
|
-
stringField(exposed, "class") ??
|
|
1875
|
-
"temporary_preview",
|
|
1876
|
-
stable_for_embedding: booleanField(exposed, "stable_for_embedding") ?? false,
|
|
1877
|
-
recommended_next_action: stringField(exposed, "recommended_next_action") ??
|
|
1878
|
-
"create_alias_or_publish",
|
|
1879
|
-
url_info: objectField(exposed, "url_info") ?? undefined,
|
|
1880
1833
|
ready: edge.ok,
|
|
1881
1834
|
status: edge.status,
|
|
1882
1835
|
latency_ms: edge.latency_ms ?? null,
|
|
1883
1836
|
error: edge.error,
|
|
1884
1837
|
};
|
|
1885
1838
|
}
|
|
1886
|
-
function printPreviewContractHint(result) {
|
|
1887
|
-
const urlClass = result.url_class ?? "temporary_preview";
|
|
1888
|
-
if (result.stable_for_embedding === true) {
|
|
1889
|
-
console.error(chalk.dim(`URL class: ${urlClass}, stable for embedding.`));
|
|
1890
|
-
return;
|
|
1891
|
-
}
|
|
1892
|
-
console.error(chalk.yellow(`URL class: ${urlClass}, temporary preview.`));
|
|
1893
|
-
console.error(chalk.dim(`For durable client use, next action: ${result.recommended_next_action ?? "create_alias_or_publish"}.`));
|
|
1894
|
-
}
|
|
1895
1839
|
async function waitSandboxReady(sandboxId, port, probePath, timeoutSec) {
|
|
1896
1840
|
const c = client();
|
|
1897
1841
|
await waitForSandboxRunning(c, sandboxId, Math.min(timeoutSec, 120));
|
|
@@ -2007,7 +1951,6 @@ async function deploySandbox(localDir, opts) {
|
|
|
2007
1951
|
source: opts.source,
|
|
2008
1952
|
revision: opts.revision,
|
|
2009
1953
|
depth: opts.depth,
|
|
2010
|
-
alwaysOn: opts.alwaysOn,
|
|
2011
1954
|
});
|
|
2012
1955
|
}
|
|
2013
1956
|
deployStep(opts, "Waiting for sandbox");
|
|
@@ -2048,53 +1991,20 @@ async function deploySandbox(localDir, opts) {
|
|
|
2048
1991
|
const internal = await waitForInternalHttp(c, sandboxId, resolvedPort, resolvedProbePath, Math.min(opts.timeout, 60));
|
|
2049
1992
|
deployStep(opts, "Creating public preview route");
|
|
2050
1993
|
const exposed = await c.apiPost(apiPath(`/sandboxes/${enc(sandboxId)}/expose`), { port: resolvedPort, title: "app preview" });
|
|
2051
|
-
const
|
|
2052
|
-
const previewUrl = extractUrl(exposeData);
|
|
1994
|
+
const previewUrl = extractUrl(unwrap(exposed));
|
|
2053
1995
|
if (!previewUrl) {
|
|
2054
1996
|
throw new UserError("Sandbox expose did not return a preview URL.");
|
|
2055
1997
|
}
|
|
2056
|
-
const previewUrlInfo = objectField(exposeData, "url_info") ?? undefined;
|
|
2057
|
-
const previewUrlClass = stringField(exposeData, "url_class") ??
|
|
2058
|
-
stringField(exposeData, "class") ??
|
|
2059
|
-
"temporary_preview";
|
|
2060
|
-
const stableForEmbedding = booleanField(exposeData, "stable_for_embedding") ?? false;
|
|
2061
|
-
const recommendedNextAction = stringField(exposeData, "recommended_next_action") ??
|
|
2062
|
-
"create_alias_or_publish";
|
|
2063
1998
|
if (opts.wait)
|
|
2064
1999
|
deployStep(opts, "Checking public preview readiness");
|
|
2065
2000
|
const edge = opts.wait
|
|
2066
2001
|
? await waitForPublicPreview(previewUrl, resolvedProbePath, opts.timeout)
|
|
2067
2002
|
: { ok: false, status: null };
|
|
2068
|
-
const deployment = opts.publish
|
|
2069
|
-
? await publishSandbox(sandboxId, {
|
|
2070
|
-
path: remoteWorkdir,
|
|
2071
|
-
name: opts.name,
|
|
2072
|
-
slug: opts.slug,
|
|
2073
|
-
environment: "production",
|
|
2074
|
-
buildCommand: opts.buildCommand,
|
|
2075
|
-
runCommand: opts.runCommand,
|
|
2076
|
-
domain: opts.domain,
|
|
2077
|
-
deploymentType: opts.static
|
|
2078
|
-
? "static"
|
|
2079
|
-
: (opts.deploymentType ?? "dynamic"),
|
|
2080
|
-
port: resolvedPort,
|
|
2081
|
-
wait: opts.wait,
|
|
2082
|
-
timeout: opts.timeout,
|
|
2083
|
-
json: opts.json,
|
|
2084
|
-
})
|
|
2085
|
-
: null;
|
|
2086
2003
|
return {
|
|
2087
2004
|
sandbox_id: sandboxId,
|
|
2088
2005
|
port: resolvedPort,
|
|
2089
2006
|
preview_url: previewUrl,
|
|
2090
|
-
preview_url_info: previewUrlInfo,
|
|
2091
|
-
preview_url_class: previewUrlClass,
|
|
2092
|
-
stable_for_embedding: stableForEmbedding,
|
|
2093
|
-
recommended_next_action: recommendedNextAction,
|
|
2094
2007
|
preview_ready: edge.ok,
|
|
2095
|
-
persistent: true,
|
|
2096
|
-
always_on: Boolean(opts.alwaysOn),
|
|
2097
|
-
deployment,
|
|
2098
2008
|
internal_status: internal.status,
|
|
2099
2009
|
edge_status: edge.status,
|
|
2100
2010
|
latency_ms: edge.latency_ms ?? null,
|
|
@@ -2203,25 +2113,6 @@ async function publishSandbox(sandboxId, opts) {
|
|
|
2203
2113
|
extractUrl(deployment) ??
|
|
2204
2114
|
stringField(data, "url") ??
|
|
2205
2115
|
null;
|
|
2206
|
-
let urlInfo = objectField(response, "url_info") ??
|
|
2207
|
-
objectField(deployment, "url_info") ??
|
|
2208
|
-
objectField(data, "url_info") ??
|
|
2209
|
-
null;
|
|
2210
|
-
let urlClass = stringField(response, "url_class") ??
|
|
2211
|
-
stringField(response, "class") ??
|
|
2212
|
-
stringField(deployment, "url_class") ??
|
|
2213
|
-
stringField(deployment, "class") ??
|
|
2214
|
-
stringField(data, "url_class") ??
|
|
2215
|
-
stringField(data, "class") ??
|
|
2216
|
-
"durable_deployment";
|
|
2217
|
-
let stableForEmbedding = booleanField(response, "stable_for_embedding") ??
|
|
2218
|
-
booleanField(deployment, "stable_for_embedding") ??
|
|
2219
|
-
booleanField(data, "stable_for_embedding") ??
|
|
2220
|
-
true;
|
|
2221
|
-
let recommendedNextAction = stringField(response, "recommended_next_action") ??
|
|
2222
|
-
stringField(deployment, "recommended_next_action") ??
|
|
2223
|
-
stringField(data, "recommended_next_action") ??
|
|
2224
|
-
"attach_custom_domain";
|
|
2225
2116
|
let deploymentProduct = stringField(response, "deployment_product") ??
|
|
2226
2117
|
stringField(data, "deployment_product") ??
|
|
2227
2118
|
stringField(deployment, "deployment_product") ??
|
|
@@ -2237,15 +2128,6 @@ async function publishSandbox(sandboxId, opts) {
|
|
|
2237
2128
|
const waited = await waitForDeploymentReady(c, deploymentId, opts.timeout);
|
|
2238
2129
|
state = stringField(waited, "state") ?? state;
|
|
2239
2130
|
url = extractUrl(waited) ?? url;
|
|
2240
|
-
urlInfo = objectField(waited, "url_info") ?? urlInfo;
|
|
2241
|
-
urlClass =
|
|
2242
|
-
stringField(waited, "url_class") ??
|
|
2243
|
-
stringField(waited, "class") ??
|
|
2244
|
-
urlClass;
|
|
2245
|
-
stableForEmbedding =
|
|
2246
|
-
booleanField(waited, "stable_for_embedding") ?? stableForEmbedding;
|
|
2247
|
-
recommendedNextAction =
|
|
2248
|
-
stringField(waited, "recommended_next_action") ?? recommendedNextAction;
|
|
2249
2131
|
deploymentProduct =
|
|
2250
2132
|
stringField(waited, "deployment_product") ??
|
|
2251
2133
|
stringField(asRecord(waited["metadata"]), "deployment_product") ??
|
|
@@ -2257,11 +2139,6 @@ async function publishSandbox(sandboxId, opts) {
|
|
|
2257
2139
|
response["state"] = state;
|
|
2258
2140
|
if (url)
|
|
2259
2141
|
response["url"] = url;
|
|
2260
|
-
if (urlInfo)
|
|
2261
|
-
response["url_info"] = urlInfo;
|
|
2262
|
-
response["url_class"] = urlClass;
|
|
2263
|
-
response["stable_for_embedding"] = stableForEmbedding;
|
|
2264
|
-
response["recommended_next_action"] = recommendedNextAction;
|
|
2265
2142
|
data["deployment"] = waited;
|
|
2266
2143
|
data["promotion_pending"] = false;
|
|
2267
2144
|
data["app_consistency_pending"] = false;
|
|
@@ -2283,10 +2160,6 @@ async function publishSandbox(sandboxId, opts) {
|
|
|
2283
2160
|
release_id: releaseId,
|
|
2284
2161
|
version_id: versionId,
|
|
2285
2162
|
url,
|
|
2286
|
-
url_info: urlInfo ?? undefined,
|
|
2287
|
-
url_class: urlClass,
|
|
2288
|
-
stable_for_embedding: stableForEmbedding,
|
|
2289
|
-
recommended_next_action: recommendedNextAction,
|
|
2290
2163
|
state,
|
|
2291
2164
|
deployment_product: deploymentProduct,
|
|
2292
2165
|
docker_deploy_host_id: dockerDeployHostId,
|
|
@@ -2311,7 +2184,7 @@ async function waitForDeploymentReady(c, deploymentId, timeoutSec) {
|
|
|
2311
2184
|
await sleep(2000);
|
|
2312
2185
|
}
|
|
2313
2186
|
const lastState = last ? String(last["state"] ?? "unknown") : "unknown";
|
|
2314
|
-
throw new UserError(`Deployment still building after ${timeoutSec}s — it may still finish. Re-check with \`miosa
|
|
2187
|
+
throw new UserError(`Deployment still building after ${timeoutSec}s — it may still finish. Re-check with \`miosa sandbox show ${deploymentId}\` or \`miosa deploy logs\`.`, `Last state: ${lastState}`);
|
|
2315
2188
|
}
|
|
2316
2189
|
function parsePublishDatabase(value) {
|
|
2317
2190
|
if (!value)
|
|
@@ -2349,12 +2222,6 @@ async function doctorSandbox(sandboxId, port, probePath) {
|
|
|
2349
2222
|
exposeData = { error: err instanceof Error ? err.message : String(err) };
|
|
2350
2223
|
}
|
|
2351
2224
|
const previewUrl = extractUrl(exposeData);
|
|
2352
|
-
const urlClass = stringField(exposeData, "url_class") ??
|
|
2353
|
-
stringField(exposeData, "class") ??
|
|
2354
|
-
"temporary_preview";
|
|
2355
|
-
const stableForEmbedding = booleanField(exposeData, "stable_for_embedding") ?? false;
|
|
2356
|
-
const recommendedNextAction = stringField(exposeData, "recommended_next_action") ??
|
|
2357
|
-
"create_alias_or_publish";
|
|
2358
2225
|
const edge = previewUrl
|
|
2359
2226
|
? await probePublicPreview(previewUrl, probePath)
|
|
2360
2227
|
: { ok: false, status: null, error: "No preview URL returned" };
|
|
@@ -2372,10 +2239,6 @@ async function doctorSandbox(sandboxId, port, probePath) {
|
|
|
2372
2239
|
edge_probe: edge,
|
|
2373
2240
|
preview_ready: edge.ok,
|
|
2374
2241
|
preview_url: previewUrl,
|
|
2375
|
-
url_info: objectField(exposeData, "url_info") ?? null,
|
|
2376
|
-
url_class: urlClass,
|
|
2377
|
-
stable_for_embedding: stableForEmbedding,
|
|
2378
|
-
recommended_next_action: recommendedNextAction,
|
|
2379
2242
|
expose: exposeData,
|
|
2380
2243
|
};
|
|
2381
2244
|
}
|
|
@@ -2391,8 +2254,6 @@ function renderDoctorReport(report) {
|
|
|
2391
2254
|
console.log(` ${chalk.bold("Preview ready")} ${report["preview_ready"] ? chalk.green("yes") : chalk.red("no")}`);
|
|
2392
2255
|
if (report["preview_url"]) {
|
|
2393
2256
|
console.log(` ${chalk.bold("Preview URL")} ${chalk.cyan(String(report["preview_url"]))}`);
|
|
2394
|
-
console.log(` ${chalk.bold("URL class")} ${report["url_class"]}`);
|
|
2395
|
-
console.log(` ${chalk.bold("Embeddable")} ${report["stable_for_embedding"] === true ? chalk.green("yes") : chalk.yellow("temporary")}`);
|
|
2396
2257
|
}
|
|
2397
2258
|
console.log();
|
|
2398
2259
|
if (!report["preview_ready"]) {
|
|
@@ -2588,8 +2449,6 @@ async function createSandboxForDeploy(c, template, name, source) {
|
|
|
2588
2449
|
const body = { template_id: template };
|
|
2589
2450
|
if (name)
|
|
2590
2451
|
body["name"] = name;
|
|
2591
|
-
if (source?.alwaysOn)
|
|
2592
|
-
body["always_on"] = true;
|
|
2593
2452
|
if (source?.source)
|
|
2594
2453
|
body["source"] = source.source;
|
|
2595
2454
|
if (source?.revision)
|
|
@@ -2860,8 +2719,6 @@ function recoveryCommandForSandboxDeploy(sandboxId, opts, localDir) {
|
|
|
2860
2719
|
parts.push("--port", String(opts.port));
|
|
2861
2720
|
if (opts.publishPort != null)
|
|
2862
2721
|
parts.push("--publish-port", String(opts.publishPort));
|
|
2863
|
-
if (opts.alwaysOn)
|
|
2864
|
-
parts.push("--always-on");
|
|
2865
2722
|
if (opts.installCommand)
|
|
2866
2723
|
parts.push("--install-command", shellQuote(opts.installCommand));
|
|
2867
2724
|
if (opts.install === false)
|
|
@@ -3217,29 +3074,11 @@ function extractUrl(value) {
|
|
|
3217
3074
|
return null;
|
|
3218
3075
|
const row = value;
|
|
3219
3076
|
for (const key of ["url", "preview_url", "public_url"]) {
|
|
3220
|
-
if (typeof row[key] === "string" && row[key])
|
|
3221
|
-
return
|
|
3222
|
-
}
|
|
3077
|
+
if (typeof row[key] === "string" && row[key])
|
|
3078
|
+
return row[key];
|
|
3223
3079
|
}
|
|
3224
3080
|
return null;
|
|
3225
3081
|
}
|
|
3226
|
-
function normalizePreviewUrl(url) {
|
|
3227
|
-
try {
|
|
3228
|
-
const parsed = new URL(url);
|
|
3229
|
-
parsed.hostname = parsed.hostname.replace(".sandbox.sandbox.preview.", ".sandbox.preview.");
|
|
3230
|
-
const normalized = parsed.toString();
|
|
3231
|
-
if (parsed.pathname === "/" &&
|
|
3232
|
-
!parsed.search &&
|
|
3233
|
-
!parsed.hash &&
|
|
3234
|
-
!url.endsWith("/")) {
|
|
3235
|
-
return normalized.replace(/\/$/, "");
|
|
3236
|
-
}
|
|
3237
|
-
return normalized;
|
|
3238
|
-
}
|
|
3239
|
-
catch {
|
|
3240
|
-
return url.replace(".sandbox.sandbox.preview.", ".sandbox.preview.");
|
|
3241
|
-
}
|
|
3242
|
-
}
|
|
3243
3082
|
function asRecord(value) {
|
|
3244
3083
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
3245
3084
|
return null;
|
|
@@ -3249,13 +3088,6 @@ function stringField(row, key) {
|
|
|
3249
3088
|
const value = row?.[key];
|
|
3250
3089
|
return typeof value === "string" && value.length > 0 ? value : null;
|
|
3251
3090
|
}
|
|
3252
|
-
function booleanField(row, key) {
|
|
3253
|
-
const value = row?.[key];
|
|
3254
|
-
return typeof value === "boolean" ? value : null;
|
|
3255
|
-
}
|
|
3256
|
-
function objectField(row, key) {
|
|
3257
|
-
return asRecord(row?.[key]);
|
|
3258
|
-
}
|
|
3259
3091
|
function isSandboxTarget(value) {
|
|
3260
3092
|
const idx = value.indexOf(":");
|
|
3261
3093
|
if (idx <= 0)
|
|
@@ -3370,6 +3202,38 @@ function commandInCwd(command, cwd) {
|
|
|
3370
3202
|
return command;
|
|
3371
3203
|
return `cd ${shellQuote(cwd)} && ${command}`;
|
|
3372
3204
|
}
|
|
3205
|
+
function supportedPromptProviders() {
|
|
3206
|
+
return [
|
|
3207
|
+
"claude",
|
|
3208
|
+
"claude-code",
|
|
3209
|
+
"codex",
|
|
3210
|
+
"pi",
|
|
3211
|
+
"hermes",
|
|
3212
|
+
"osa",
|
|
3213
|
+
"custom",
|
|
3214
|
+
];
|
|
3215
|
+
}
|
|
3216
|
+
function runtimeCommandForProvider(provider, runtimeCommand) {
|
|
3217
|
+
const normalized = provider.trim().toLowerCase();
|
|
3218
|
+
if (normalized === "custom") {
|
|
3219
|
+
if (!runtimeCommand?.trim()) {
|
|
3220
|
+
throw new Error("--provider custom requires --runtime-command, e.g. --runtime-command 'hermes-agent run'");
|
|
3221
|
+
}
|
|
3222
|
+
return runtimeCommand.trim();
|
|
3223
|
+
}
|
|
3224
|
+
const builtIns = {
|
|
3225
|
+
claude: "claude",
|
|
3226
|
+
"claude-code": "claude",
|
|
3227
|
+
codex: "codex",
|
|
3228
|
+
pi: "pi",
|
|
3229
|
+
hermes: "hermes",
|
|
3230
|
+
osa: "osa",
|
|
3231
|
+
};
|
|
3232
|
+
return builtIns[normalized] ?? null;
|
|
3233
|
+
}
|
|
3234
|
+
function isSupportedPromptProvider(provider) {
|
|
3235
|
+
return supportedPromptProviders().includes(provider.trim().toLowerCase());
|
|
3236
|
+
}
|
|
3373
3237
|
function backgroundCommand(command) {
|
|
3374
3238
|
if (!command.trim())
|
|
3375
3239
|
return command;
|