trellis
Version:
Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications
107 lines (105 loc) • 3.34 kB
JavaScript
import {
deploy
} from "../chunk-YMMGVZKS.js";
import {
DeployNameError
} from "../chunk-3XCOAP6G.js";
import "../chunk-HQD7LBM4.js";
import {
roomMcpPathForUrl
} from "../chunk-YC5I32PS.js";
import "../chunk-UZRUP7QW.js";
import {
configPath
} from "../chunk-JA7AIHRK.js";
import "../chunk-2ESYSVXG.js";
// src/cli/deploy-cli.ts
import chalk from "chalk";
function printDeploySuccess(result, configDir, stub) {
console.log("");
console.log(
chalk.green(
stub ? "\u2713 Stub deploy \u2014 config written (no Sprite provisioned)" : "\u2713 TurtleDB room deployed"
)
);
console.log(chalk.dim(` Name: ${result.name}`));
console.log(chalk.dim(` URL: ${result.url}`));
console.log(chalk.dim(` API key: ${result.apiKey}`));
console.log(chalk.dim(` Config: ${configPath(configDir)}`));
console.log("");
const base = result.url.replace(/\/$/, "");
const mcpPath = roomMcpPathForUrl(base);
const mcpUrl = `${base}${mcpPath}`;
console.log(chalk.dim(` Health: curl ${result.url}/health`));
console.log(chalk.dim(` MCP: ${mcpUrl}`));
if (mcpPath !== "/mcp") {
console.log(chalk.dim(` (Sprites reserves /mcp \u2014 use ${mcpPath} on *.sprites.app)`));
}
console.log(chalk.dim(` Gateway: ${base}/gateway/mcp`));
console.log("");
console.log(chalk.bold("Cursor MCP (remote):"));
console.log(
chalk.cyan(
` { "url": "${mcpUrl}", "headers": { "Authorization": "Bearer ${result.apiKey}" } }`
)
);
console.log("");
console.log(chalk.bold("Claude Desktop (stdio bridge):"));
console.log(
chalk.cyan(
` npx trellis mcp bridge --room ${result.url} --api-key ${result.apiKey}`
)
);
console.log("");
console.log(chalk.bold("SDK:"));
console.log(chalk.cyan(` import { TrellisDb } from 'trellis/client';`));
console.log(
chalk.cyan(
` const db = new TrellisDb({ url: '${result.url}', apiKey: '${result.apiKey}' });`
)
);
}
async function runDeployCli(opts) {
const configDir = opts.configDir ?? ".";
const port = opts.port === void 0 ? void 0 : typeof opts.port === "string" ? parseInt(opts.port, 10) : opts.port;
const { readConfig } = await import("../config-KMY6RRK3.js");
const config = readConfig(configDir);
const label = opts.stub ? "Stub deploy" : "Deploying to Sprites";
console.log(chalk.bold(`${label}: ${opts.name}...`));
try {
const result = await deploy({
name: opts.name,
dbPath: config?.dbPath,
apiKey: opts.key,
jwtSecret: opts.jwtSecret,
port,
configDir,
stub: !!opts.stub,
onProgress: (msg) => console.log(chalk.dim(` ${msg}`))
});
printDeploySuccess(result, configDir, !!opts.stub);
if (!opts.stub) {
try {
const { trackSprite } = await import("../vm-config-YZRJ3KUB.js");
trackSprite(result.name, {
url: result.url,
hasTrellis: true,
apiKey: result.apiKey
});
} catch {
}
}
} catch (err) {
if (err instanceof DeployNameError) {
console.error(chalk.red(`Invalid name: ${err.message}`));
process.exit(1);
}
const message = err instanceof Error ? err.message : String(err);
console.error(chalk.red(`Deploy failed: ${message}`));
process.exit(1);
}
}
export {
printDeploySuccess,
runDeployCli
};