nosana-mcp 0.2.0

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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -0
  3. package/dist/cli/commands/account.d.ts +7 -0
  4. package/dist/cli/commands/account.js +108 -0
  5. package/dist/cli/commands/account.js.map +1 -0
  6. package/dist/cli/commands/deploy.d.ts +3 -0
  7. package/dist/cli/commands/deploy.js +311 -0
  8. package/dist/cli/commands/deploy.js.map +1 -0
  9. package/dist/cli/commands/gpus.d.ts +3 -0
  10. package/dist/cli/commands/gpus.js +38 -0
  11. package/dist/cli/commands/gpus.js.map +1 -0
  12. package/dist/cli/commands/job.d.ts +3 -0
  13. package/dist/cli/commands/job.js +31 -0
  14. package/dist/cli/commands/job.js.map +1 -0
  15. package/dist/cli/commands/run.d.ts +33 -0
  16. package/dist/cli/commands/run.js +365 -0
  17. package/dist/cli/commands/run.js.map +1 -0
  18. package/dist/cli/commands/templates.d.ts +3 -0
  19. package/dist/cli/commands/templates.js +115 -0
  20. package/dist/cli/commands/templates.js.map +1 -0
  21. package/dist/cli/index.d.ts +2 -0
  22. package/dist/cli/index.js +45 -0
  23. package/dist/cli/index.js.map +1 -0
  24. package/dist/core/client.d.ts +23 -0
  25. package/dist/core/client.js +38 -0
  26. package/dist/core/client.js.map +1 -0
  27. package/dist/core/config.d.ts +18 -0
  28. package/dist/core/config.js +52 -0
  29. package/dist/core/config.js.map +1 -0
  30. package/dist/core/credits.d.ts +9 -0
  31. package/dist/core/credits.js +9 -0
  32. package/dist/core/credits.js.map +1 -0
  33. package/dist/core/deploy.d.ts +146 -0
  34. package/dist/core/deploy.js +400 -0
  35. package/dist/core/deploy.js.map +1 -0
  36. package/dist/core/format.d.ts +25 -0
  37. package/dist/core/format.js +144 -0
  38. package/dist/core/format.js.map +1 -0
  39. package/dist/core/markets.d.ts +74 -0
  40. package/dist/core/markets.js +146 -0
  41. package/dist/core/markets.js.map +1 -0
  42. package/dist/core/templates.d.ts +61 -0
  43. package/dist/core/templates.js +190 -0
  44. package/dist/core/templates.js.map +1 -0
  45. package/dist/mcp/index.d.ts +2 -0
  46. package/dist/mcp/index.js +73 -0
  47. package/dist/mcp/index.js.map +1 -0
  48. package/dist/mcp/tools.d.ts +52 -0
  49. package/dist/mcp/tools.js +994 -0
  50. package/dist/mcp/tools.js.map +1 -0
  51. package/docs/CLI.md +144 -0
  52. package/docs/COST.md +32 -0
  53. package/docs/MINIMAX-H3.md +79 -0
  54. package/examples/hello-world.json +18 -0
  55. package/examples/minimax-h3-i2v-32gb.json +56 -0
  56. package/package.json +66 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Swatantra Sohni
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # Nosana MCP
2
+
3
+ **Let your AI agent rent a GPU and deploy models on [Nosana](https://nosana.com).**
4
+ Nosana MCP is a [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude Code, Claude Desktop, Cursor, Codex, OpenClaw and any other MCP client the tools to browse Nosana's ready-to-run templates (MiniMax H3 video, Qwen and Gemma LLMs, ComfyUI, Jupyter, VS Code), compare GPU markets by live price and availability, estimate the cost, deploy, and hand back the running endpoint. Everything is paid with Nosana account credits through a single API key. No wallet, no tokens.
5
+
6
+ > "Deploy MiniMax H3 on an RTX 5090 and give me the ComfyUI link."
7
+ > The agent checks your credits, picks the 32 GB variant, shows you the price (about 0.40 credits per hour on a 5090), waits for your yes, deploys, polls until ComfyUI answers, and returns the URL. When you are done: "stop it".
8
+
9
+ A companion CLI, `nosana-deploy`, ships in the same package for humans, scripts and CI. See [docs/CLI.md](docs/CLI.md).
10
+
11
+ ## Quick start
12
+
13
+ ### 1. Credits and an API key
14
+
15
+ 1. Sign in at [deploy.nosana.com](https://deploy.nosana.com).
16
+ 2. **Billing**: add credits with a card or crypto.
17
+ 3. **Account > API Keys > Create Key**. Copy it once.
18
+
19
+ ### 2. Add the server to your client
20
+
21
+ Claude Code:
22
+
23
+ ```bash
24
+ claude mcp add nosana --env NOSANA_API_KEY=nos_your_key -- npx -y nosana-mcp
25
+ ```
26
+
27
+ Claude Desktop, Cursor, Windsurf and most other clients take the same JSON:
28
+
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "nosana": {
33
+ "command": "npx",
34
+ "args": ["-y", "nosana-mcp"],
35
+ "env": { "NOSANA_API_KEY": "nos_your_key" }
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ Codex CLI:
42
+
43
+ ```bash
44
+ codex mcp add nosana --env NOSANA_API_KEY=nos_your_key -- npx -y nosana-mcp
45
+ ```
46
+
47
+ Running from a clone instead of npm:
48
+
49
+ ```bash
50
+ git clone https://github.com/SohniSwatantra/nosana-mcp.git && cd nosana-mcp
51
+ npm install && npm run build
52
+ # then point your client at: node /absolute/path/to/nosana-mcp/dist/mcp/index.js
53
+ ```
54
+
55
+ Instead of the environment variable you can run `nosana-deploy login` once; the server also reads the key that command stores in `~/.config/nosana-deploy/config.json`.
56
+
57
+ ### 3. Ask
58
+
59
+ - "Deploy Qwen 3.6 27B on the cheapest idle GPU and give me the OpenAI-compatible URL."
60
+ - "Deploy MiniMax H3 image-to-video. If no 5090 is idle, show me the alternatives."
61
+ - "What is running right now and what does it cost per hour?" / "Stop everything."
62
+
63
+ The agent must show you the estimate and get a yes before it can call `create_deployment`. Bundled prompts: `deploy_template`, `deploy_llm`, `deploy_comfy`, `deploy_minimax_h3`, `stop_when_done`.
64
+
65
+ After adding or changing the server configuration, restart the client or reconnect its MCP servers (Claude Code: `/mcp`); tools are discovered at session start.
66
+
67
+ ## Tools
68
+
69
+ Every tool returns one JSON object, both as text and as MCP `structuredContent`: `{ok, message, next_tool, next_args, ...}`. `ok` is false only when the tool itself failed; deployment outcomes live in `outcome`. Agents never have to parse prose.
70
+
71
+ | Tool | What it does | Spends credits |
72
+ |---|---|---|
73
+ | `doctor` | Checks the key, credits and every Nosana API; returns the exact fix (install command, restart hint). | no |
74
+ | `get_balance` | Assigned, reserved, settled and available credits. | no |
75
+ | `list_templates` / `get_template` | Catalog with kind (comfyui, llm, notebook, ide), VRAM from the template itself, variants, hardware notes, typical boot time. | no |
76
+ | `list_gpus` | Markets in buyer buckets: `ready_now` (fits, idle host), `fits_but_queued`, `idle_with_risk`, `unsupported`. Prices per hour include the fee and match the dashboard. | no |
77
+ | `recommend_plan` | One call from a workload ("minimax-h3/i2v-32gb", "qwen3-6-27b", "gemma3 12b", or a job definition) to the cheapest ready GPU, cost, similar deployments already running, and exact `create_deployment` arguments. Never picks a queued or unsupported GPU by itself. | no |
78
+ | `estimate_deployment` | Dry run of `create_deployment` with the same arguments, including `gpu: "auto"`. | no |
79
+ | `create_deployment` | Creates and starts. Needs `confirm=true`. Refuses to queue without `accept_queue`, to duplicate a running workload without `allow_duplicate`, and to use unfit hardware or overspend without `force`. | **yes** |
80
+ | `wait_for_deployment` | Watches up to 45 s per call (MCP clients time out at 60 s). Returns `online` with URLs and usage, `completed` with logs, `stopped` (user or timeout, not an error), `failed` with the scheduler error, or `pending` with phase (`queued`, `starting`, `initializing`), elapsed time and `poll_after_seconds`. | no |
81
+ | `get_deployment` / `list_deployments` | Status, phase, endpoints with a real readiness probe, price per hour, recent jobs and events. | no |
82
+ | `get_endpoint_usage` | How to use the running service: ComfyUI `/prompt` API, OpenAI-compatible base URL for Ollama/vLLM (`/v1/models`, `/v1/chat/completions`), Jupyter/VS Code URL, raw ports for custom jobs. | no |
83
+ | `get_job_result` / `get_deployment_events` | Logs and the scheduler's event log. | no |
84
+ | `stop_deployment` | Stops jobs; billing stops with them. | ends spending |
85
+ | `start_deployment` / `extend_deployment` | Restart a stopped deployment (needs `confirm=true`) or change its timeout. | yes |
86
+
87
+ Resources: `nosana://templates`, `nosana://gpus`. Prompts: `deploy_template`, `deploy_llm`, `deploy_comfy`, `deploy_minimax_h3`, `stop_when_done`.
88
+
89
+ ### The happy path an agent follows
90
+
91
+ ```
92
+ recommend_plan("qwen3-6-27b") -> ready_now GPU, cost, create_args
93
+ create_deployment(create_args, confirm=true) after the user says yes
94
+ wait_for_deployment(id) x N -> pending(phase) ... online
95
+ get_endpoint_usage(id) -> OPENAI_BASE_URL, /v1/models, curl example
96
+ stop_deployment(id) when the user is done
97
+ ```
98
+
99
+ ## Guard rails built in
100
+
101
+ - **Confirmation before spending.** `create_deployment` and `start_deployment` do nothing without `confirm=true`; their descriptions tell the agent to show the estimate first, and MCP annotations mark them non-read-only so clients prompt for approval.
102
+ - **No silent queueing.** With `gpu: "auto"` only a GPU that fits *and* has an idle host is chosen. If none is ready, the response lists `fits_but_queued` and `idle_with_risk` and asks for a decision (`accept_queue` or `force`). Unsupported hardware (a non-Blackwell card for MiniMax H3) is never offered, because it would download 45 GB of weights and then fail.
103
+ - **No accidental duplicates.** Creating a workload that is already running is refused unless `allow_duplicate=true`.
104
+ - **60-minute minimum.** Nosana only schedules credit-paid jobs of 3600 seconds or more; shorter values are rejected before anything is created. Workloads that download weights default to 120 minutes.
105
+ - **Real readiness.** Nosana marks an endpoint online when the host tunnel is up while the container may still be loading. The server probes the service itself (`/` for web UIs, `/api/tags` or `/v1/models` for LLMs) before reporting `online`.
106
+ - **Stopped is not failed.** A deployment stopped by the user or its timeout reports `outcome: "stopped"`, so agents do not "fix" it by restarting and paying the boot again.
107
+ - **Fail fast, retry the transient.** Repeated scheduler errors end the wait with the error text; transient 5xx and network blips are retried with backoff.
108
+ - **Short calls.** No tool blocks longer than 45 seconds. Pending results carry `poll_after_seconds` and `next_args` so the agent can loop safely.
109
+
110
+ ## Costs to expect
111
+
112
+ Prices come from the live market list and include the network fee, so they match deploy.nosana.com. Every plan and every online result carries `usd_per_hour`, `estimated_credits`, `boot_minutes_typical` and the billing rules (idle time bills, there is no pause, stopping ends billing, restarting pays the boot again). See [docs/COST.md](docs/COST.md) for numbers from real runs.
113
+
114
+ ## Development
115
+
116
+ ```bash
117
+ npm install
118
+ npm run build
119
+ npm run test:mcp # read-only smoke test with assertions against the live API (needs NOSANA_API_KEY)
120
+ SMOKE_DEPLOY=1 npm run test:mcp # also deploys hello-world once (about 0.05 credits)
121
+ npm run inspect # MCP Inspector UI against the built server
122
+ ```
123
+
124
+ Layout: `src/core` (Nosana Kit wrappers: templates, markets, deployments, cost, readiness), `src/mcp` (server and tools), `src/cli` (the `nosana-deploy` command). Both surfaces share the core, so a fix in one place fixes both.
125
+
126
+ ## License
127
+
128
+ MIT. Not affiliated with Nosana; built on the public `@nosana/kit` SDK and API.
@@ -0,0 +1,7 @@
1
+ import type { Command } from 'commander';
2
+ import { type CreditsBalance, type GlobalOptions } from '../../core/client.js';
3
+ import { availableCredits } from '../../core/credits.js';
4
+ export { availableCredits };
5
+ export declare function balanceTable(balance: CreditsBalance): string;
6
+ export declare function loginInteractive(options: GlobalOptions, provided?: string): Promise<string>;
7
+ export declare function registerAccountCommands(program: Command, globals: () => GlobalOptions): void;
@@ -0,0 +1,108 @@
1
+ import { password } from '@inquirer/prompts';
2
+ import { CliError, createClient } from '../../core/client.js';
3
+ import { CONFIG_FILE, clearConfig, isInteractive, maskKey, readConfig, resolveApiKey, writeConfig } from '../../core/config.js';
4
+ import { formatError, pageSize, printJson, sym, table, withTimeout } from '../../core/format.js';
5
+ import { availableCredits, summarizeBalance } from '../../core/credits.js';
6
+ export { availableCredits };
7
+ export function balanceTable(balance) {
8
+ const b = summarizeBalance(balance);
9
+ return table(['Assigned', 'Reserved', 'Settled', 'Available'], [[b.assigned.toFixed(3), b.reserved.toFixed(3), b.settled.toFixed(3), b.available.toFixed(3)]]);
10
+ }
11
+ export async function loginInteractive(options, provided) {
12
+ let key = provided?.trim();
13
+ if (!key) {
14
+ if (!isInteractive())
15
+ throw new CliError('Pass --key <apiKey> or set NOSANA_API_KEY when not running in a terminal.', 2);
16
+ console.log('Create an API key at https://deploy.nosana.com (Account > API Keys) and paste it below.');
17
+ key = (await password({ message: 'Nosana API key', mask: '*' })).trim();
18
+ }
19
+ if (!key)
20
+ throw new CliError('Empty API key.', 2);
21
+ const client = createClient(options, key);
22
+ let balance;
23
+ try {
24
+ balance = await client.api.credits.balance();
25
+ }
26
+ catch (error) {
27
+ throw new CliError(`Nosana rejected the API key: ${formatError(error)}`);
28
+ }
29
+ writeConfig({ ...readConfig(), apiKey: key, network: options.network });
30
+ console.log(`${sym.ok} API key ${maskKey(key)} verified and saved to ${CONFIG_FILE}`);
31
+ console.log(balanceTable(balance));
32
+ return key;
33
+ }
34
+ export function registerAccountCommands(program, globals) {
35
+ program
36
+ .command('login')
37
+ .description('Verify a Nosana API key and store it in ~/.config/nosana-deploy/config.json.')
38
+ .option('--key <apiKey>', 'API key (prompted when omitted)')
39
+ .action(async (cmd) => {
40
+ const options = globals();
41
+ await loginInteractive(options, cmd.key ?? options.apiKey);
42
+ });
43
+ program
44
+ .command('logout')
45
+ .description('Remove the stored API key.')
46
+ .action(() => {
47
+ console.log(clearConfig() ? `${sym.ok} Removed ${CONFIG_FILE}` : `${sym.info} No stored credentials at ${CONFIG_FILE}`);
48
+ });
49
+ program
50
+ .command('balance')
51
+ .description('Show the credit balance of the account behind the API key.')
52
+ .action(async () => {
53
+ const options = globals();
54
+ const client = createClient(options);
55
+ const balance = await client.api.credits.balance();
56
+ if (options.json) {
57
+ printJson({ ...balance, availableCredits: availableCredits(balance) });
58
+ return;
59
+ }
60
+ console.log(balanceTable(balance));
61
+ console.log(`\nTop up at https://deploy.nosana.com (Billing) with a card or crypto.`);
62
+ });
63
+ program
64
+ .command('doctor')
65
+ .description('Check Node.js, the API key, and connectivity to every Nosana API this CLI uses.')
66
+ .action(async () => {
67
+ const options = globals();
68
+ const checks = [];
69
+ const run = async (name, critical, fn) => {
70
+ try {
71
+ checks.push({ name, ok: true, detail: await fn(), critical });
72
+ }
73
+ catch (error) {
74
+ checks.push({ name, ok: false, detail: formatError(error), critical });
75
+ }
76
+ };
77
+ const major = Number(process.versions.node.split('.')[0]);
78
+ checks.push({ name: 'Node.js', ok: major >= 20, detail: `v${process.versions.node}${major >= 20 ? '' : ' (need 20 or newer)'}`, critical: true });
79
+ const resolved = resolveApiKey(options.apiKey);
80
+ checks.push({
81
+ name: 'API key',
82
+ ok: Boolean(resolved),
83
+ detail: resolved ? `${maskKey(resolved.key)} (from ${resolved.source})` : 'missing: run `nosana-deploy login`',
84
+ critical: true,
85
+ });
86
+ if (resolved) {
87
+ const client = createClient(options, resolved.key);
88
+ await run('Credits API', true, async () => `${availableCredits(await client.api.credits.balance()).toFixed(3)} credits available`);
89
+ await run('Markets API', true, async () => `${(await client.api.markets.list()).length} GPU markets`);
90
+ await run('Templates API', true, async () => `${(await client.api.templates.list()).length} templates`);
91
+ await run('Host availability', false, async () => `${(await client.api.hosts.getQueuedNodes()).length} idle hosts network-wide`);
92
+ await run('Deployments API', true, async () => `${(await client.api.deployments.list({ limit: pageSize(10) })).total_items} deployments on this account`);
93
+ await run('Solana RPC (optional, for --queue)', false, async () => `${(await withTimeout(client.jobs.markets(), 15_000, 'RPC read')).length} on-chain markets`);
94
+ }
95
+ if (options.json) {
96
+ printJson(checks);
97
+ }
98
+ else {
99
+ for (const check of checks) {
100
+ const marker = check.ok ? sym.ok : check.critical ? sym.err : sym.warn;
101
+ console.log(`${marker} ${check.name.padEnd(36)} ${check.detail}`);
102
+ }
103
+ }
104
+ if (checks.some((c) => !c.ok && c.critical))
105
+ throw new CliError('Some critical checks failed.');
106
+ });
107
+ }
108
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/cli/commands/account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import { type GlobalOptions } from '../../core/client.js';
3
+ export declare function registerDeployCommands(program: Command, globals: () => GlobalOptions): void;
@@ -0,0 +1,311 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { confirm } from '@inquirer/prompts';
4
+ import { validateJobDefinition } from '@nosana/kit';
5
+ import pc from 'picocolors';
6
+ import { CliError, createClient } from '../../core/client.js';
7
+ import { isInteractive } from '../../core/config.js';
8
+ import { dashboardUrl, deploymentsTable, explorerJobUrl, formatJobResult, normalizeJobState, summarizeDeployment, waitForDeployment } from '../../core/deploy.js';
9
+ import { fmtDate, pageSize, parseIntStrict, printJson, short, sleep, statusColor, sym, table } from '../../core/format.js';
10
+ import { addDeployFlags, DEFAULT_WAIT_MINUTES, runDeployFlow } from './run.js';
11
+ const DELETABLE_STATUSES = new Set(['STOPPED', 'ERROR', 'INSUFFICIENT_FUNDS', 'ARCHIVED']);
12
+ async function confirmDestructive(action, id, yes) {
13
+ if (yes)
14
+ return;
15
+ if (!isInteractive())
16
+ throw new CliError(`Add --yes to ${action} ${id} without a prompt.`, 2);
17
+ const ok = await confirm({ message: `Really ${action} deployment ${id}?`, default: false });
18
+ if (!ok)
19
+ throw new CliError('Aborted.', 130);
20
+ }
21
+ async function watch(client, id, minutes, options) {
22
+ console.log(`Watching ${id} for up to ${minutes} min. Ctrl+C only stops watching.`);
23
+ const outcome = await waitForDeployment(client, id, { timeoutMinutes: minutes, network: options.network, quiet: Boolean(options.json) });
24
+ const dep = outcome.deployment;
25
+ if (options.json) {
26
+ printJson({ outcome: outcome.kind, deployment: dep.id, status: dep.status, endpoints: dep.endpoints, ...(outcome.kind === 'online' ? { readyUrls: outcome.readyUrls } : {}) });
27
+ }
28
+ else {
29
+ console.log();
30
+ if (outcome.kind === 'online') {
31
+ console.log(`${sym.ok} Online and answering:`);
32
+ for (const e of dep.endpoints.filter((x) => outcome.readyUrls.includes(x.url)))
33
+ console.log(` ${e.url} (${e.opId}:${e.port})`);
34
+ }
35
+ else if (outcome.kind === 'completed') {
36
+ console.log(`${sym.ok} Job ${outcome.job} completed. ${explorerJobUrl(outcome.job, options.network)}`);
37
+ try {
38
+ for (const line of formatJobResult((await dep.getJob(outcome.job)).jobResult))
39
+ console.log(` ${line}`);
40
+ }
41
+ catch {
42
+ /* results may lag */
43
+ }
44
+ }
45
+ else if (outcome.kind === 'stopped') {
46
+ console.log(`${sym.warn} Deployment is ${statusColor(dep.status)}: stopped by you or by its timeout, not failed.`);
47
+ }
48
+ else if (outcome.kind === 'failed') {
49
+ if (outcome.error)
50
+ console.log(`${sym.err} Scheduler error: ${outcome.error}`);
51
+ console.log(`${sym.err} Deployment is ${statusColor(outcome.reason)}. See: nosana-deploy deploy events ${dep.id}${outcome.error ? ` and stop it with: nosana-deploy deploy stop ${dep.id}` : ''}`);
52
+ }
53
+ else {
54
+ console.log(`${sym.warn} Watch window elapsed; deployment status is ${statusColor(dep.status)}. Run the command again to keep watching.`);
55
+ }
56
+ }
57
+ if (outcome.kind === 'failed')
58
+ throw new CliError(`Deployment ${dep.id} is ${dep.status}.`);
59
+ }
60
+ export function registerDeployCommands(program, globals) {
61
+ const deploy = program.command('deploy').alias('deployments').description('Create and manage deployments (the same objects you see on deploy.nosana.com).');
62
+ addDeployFlags(deploy
63
+ .command('create')
64
+ .description('Create a deployment from flags (non-interactive). Add --start to start it and --yes to skip the confirmation.'), { start: false }).action(async (flags) => runDeployFlow(globals(), flags, false, { start: false }));
65
+ deploy
66
+ .command('list', { isDefault: true })
67
+ .description('List deployments on this account.')
68
+ .option('--limit <count>', 'Page size (10, 20, 50 or 100)', '20')
69
+ .option('--status <status>', 'Filter by status, e.g. RUNNING or STOPPED,ERROR')
70
+ .option('--search <text>', 'Filter by partial id or name')
71
+ .action(async (cmd) => {
72
+ const options = globals();
73
+ const client = createClient(options);
74
+ const result = await client.api.deployments.list({
75
+ limit: pageSize(parseIntStrict(cmd.limit, '--limit')),
76
+ ...(cmd.status ? { status: cmd.status.toUpperCase() } : {}),
77
+ ...(cmd.search ? { search: cmd.search } : {}),
78
+ });
79
+ const deployments = result.deployments;
80
+ if (options.json) {
81
+ printJson({ total_items: result.total_items, deployments });
82
+ return;
83
+ }
84
+ if (!deployments.length) {
85
+ console.log('No deployments found. Create one with `nosana-deploy run`.');
86
+ return;
87
+ }
88
+ console.log(deploymentsTable(deployments));
89
+ console.log(`\n${deployments.length} of ${result.total_items} deployments shown.`);
90
+ });
91
+ deploy
92
+ .command('get')
93
+ .alias('show')
94
+ .description('Show one deployment with its endpoints.')
95
+ .argument('<id>', 'Deployment id')
96
+ .action(async (id) => {
97
+ const options = globals();
98
+ const dep = (await createClient(options).api.deployments.get(id));
99
+ if (options.json)
100
+ printJson(dep);
101
+ else
102
+ console.log(summarizeDeployment(dep, options.network).join('\n'));
103
+ });
104
+ deploy
105
+ .command('start')
106
+ .description('Start a draft or stopped deployment.')
107
+ .argument('<id>', 'Deployment id')
108
+ .option('--wait', 'Watch until the workload is online or the job completes')
109
+ .option('--wait-timeout <minutes>', 'How long to watch', String(DEFAULT_WAIT_MINUTES))
110
+ .action(async (id, cmd) => {
111
+ const options = globals();
112
+ const client = createClient(options);
113
+ const dep = (await client.api.deployments.get(id));
114
+ await dep.start();
115
+ console.log(`${sym.ok} Started ${id}. Dashboard: ${dashboardUrl(id, options.network)}`);
116
+ if (cmd.wait)
117
+ await watch(client, id, parseIntStrict(cmd.waitTimeout, '--wait-timeout'), options);
118
+ });
119
+ deploy
120
+ .command('stop')
121
+ .description('Stop a deployment and its running jobs (billing stops with them).')
122
+ .argument('<id>', 'Deployment id')
123
+ .action(async (id) => {
124
+ const options = globals();
125
+ const client = createClient(options);
126
+ const dep = (await client.api.deployments.get(id));
127
+ await dep.stop();
128
+ const after = (await client.api.deployments.get(id));
129
+ if (options.json)
130
+ printJson({ id, status: after.status });
131
+ else
132
+ console.log(`${sym.ok} Stop requested for ${id}; status is now ${statusColor(after.status)}.`);
133
+ });
134
+ deploy
135
+ .command('watch')
136
+ .description('Follow a deployment until its endpoint is online or its job completes.')
137
+ .argument('<id>', 'Deployment id')
138
+ .option('--wait-timeout <minutes>', 'How long to watch', String(DEFAULT_WAIT_MINUTES))
139
+ .action(async (id, cmd) => {
140
+ const options = globals();
141
+ await watch(createClient(options), id, parseIntStrict(cmd.waitTimeout, '--wait-timeout'), options);
142
+ });
143
+ deploy
144
+ .command('jobs')
145
+ .description('List the jobs a deployment has run.')
146
+ .argument('<id>', 'Deployment id')
147
+ .option('--limit <count>', 'Page size', '20')
148
+ .action(async (id, cmd) => {
149
+ const options = globals();
150
+ const dep = (await createClient(options).api.deployments.get(id));
151
+ const result = await dep.getJobs({ limit: pageSize(parseIntStrict(cmd.limit, '--limit')) });
152
+ const jobs = result.jobs;
153
+ if (options.json) {
154
+ printJson(result.jobs);
155
+ return;
156
+ }
157
+ if (!jobs.length) {
158
+ console.log('No jobs yet.');
159
+ return;
160
+ }
161
+ console.log(table(['Job', 'State', 'Host', 'Rev', 'Created', 'Started'], jobs.map((j) => [j.job, statusColor(normalizeJobState(j.state)), j.node ? short(j.node, 6) : '-', String(j.revision ?? '-'), fmtDate(j.created_at), j.time_start ? fmtDate(j.time_start) : '-'])));
162
+ });
163
+ deploy
164
+ .command('events')
165
+ .description('Show the deployment event log (scheduling, starts, stops, errors).')
166
+ .argument('<id>', 'Deployment id')
167
+ .option('--limit <count>', 'Page size', '50')
168
+ .action(async (id, cmd) => {
169
+ const options = globals();
170
+ const dep = (await createClient(options).api.deployments.get(id));
171
+ const result = await dep.getEvents({ limit: pageSize(parseIntStrict(cmd.limit, '--limit')), sort_order: 'desc' });
172
+ const events = result.events;
173
+ if (options.json) {
174
+ printJson(result.events);
175
+ return;
176
+ }
177
+ if (!events.length) {
178
+ console.log('No events yet.');
179
+ return;
180
+ }
181
+ for (const e of [...events].reverse())
182
+ console.log(`${pc.dim(fmtDate(e.created_at))} ${pc.bold(e.type ?? e.event ?? '')} ${e.message ?? ''}`);
183
+ });
184
+ deploy
185
+ .command('result')
186
+ .description('Print the logs/results of a deployment job (latest job by default).')
187
+ .argument('<id>', 'Deployment id')
188
+ .option('--job <address>', 'Specific job address')
189
+ .action(async (id, cmd) => {
190
+ const options = globals();
191
+ const dep = (await createClient(options).api.deployments.get(id));
192
+ let jobAddress = cmd.job;
193
+ if (!jobAddress) {
194
+ const jobs = (await dep.getJobs({ limit: 10 })).jobs;
195
+ if (!jobs.length)
196
+ throw new CliError('This deployment has not run any job yet.');
197
+ jobAddress = jobs[0].job;
198
+ }
199
+ const job = await dep.getJob(jobAddress);
200
+ if (options.json) {
201
+ printJson(job);
202
+ return;
203
+ }
204
+ console.log(`Job ${jobAddress} state ${statusColor(normalizeJobState(job.state))} host ${job.node ?? '-'} ${explorerJobUrl(jobAddress, options.network)}`);
205
+ for (const line of formatJobResult(job.jobResult))
206
+ console.log(line);
207
+ });
208
+ deploy
209
+ .command('extend')
210
+ .description('Change the timeout (minutes) of a deployment.')
211
+ .argument('<id>', 'Deployment id')
212
+ .requiredOption('--timeout <minutes>', 'New timeout in minutes')
213
+ .action(async (id, cmd) => {
214
+ const options = globals();
215
+ const dep = (await createClient(options).api.deployments.get(id));
216
+ await dep.updateTimeout(parseIntStrict(cmd.timeout, '--timeout'));
217
+ console.log(`${sym.ok} Timeout of ${id} set to ${cmd.timeout} min.`);
218
+ });
219
+ deploy
220
+ .command('scale')
221
+ .description('Change the replica count of a deployment.')
222
+ .argument('<id>', 'Deployment id')
223
+ .requiredOption('--replicas <count>', 'New replica count')
224
+ .action(async (id, cmd) => {
225
+ const options = globals();
226
+ const dep = (await createClient(options).api.deployments.get(id));
227
+ await dep.updateReplicaCount(parseIntStrict(cmd.replicas, '--replicas'));
228
+ console.log(`${sym.ok} Replicas of ${id} set to ${cmd.replicas}.`);
229
+ });
230
+ deploy
231
+ .command('rename')
232
+ .description('Rename a deployment.')
233
+ .argument('<id>', 'Deployment id')
234
+ .requiredOption('--name <name>', 'New name')
235
+ .action(async (id, cmd) => {
236
+ const options = globals();
237
+ const dep = (await createClient(options).api.deployments.get(id));
238
+ await dep.updateName(cmd.name);
239
+ console.log(`${sym.ok} Renamed ${id} to "${cmd.name}".`);
240
+ });
241
+ deploy
242
+ .command('revision')
243
+ .description('Upload a new job definition revision and make it active.')
244
+ .argument('<id>', 'Deployment id')
245
+ .requiredOption('-f, --file <path>', 'Job definition JSON')
246
+ .action(async (id, cmd) => {
247
+ const options = globals();
248
+ const parsed = JSON.parse(fs.readFileSync(path.resolve(cmd.file), 'utf8'));
249
+ const validation = validateJobDefinition(parsed);
250
+ if (!validation.success)
251
+ throw new CliError(`Invalid job definition:\n${JSON.stringify(validation.errors, null, 2)}`, 2);
252
+ const client = createClient(options);
253
+ const dep = (await client.api.deployments.get(id));
254
+ await dep.createRevision(parsed);
255
+ const after = (await client.api.deployments.get(id));
256
+ console.log(`${sym.ok} New revision uploaded; active revision is now ${after.active_revision}. Restart the deployment to roll it out.`);
257
+ });
258
+ deploy
259
+ .command('auth-header')
260
+ .description('Print the Authorization header that grants access to a confidential deployment endpoint.')
261
+ .argument('<id>', 'Deployment id')
262
+ .action(async (id) => {
263
+ const options = globals();
264
+ const dep = (await createClient(options).api.deployments.get(id));
265
+ const header = await dep.generateAuthHeader();
266
+ if (options.json)
267
+ printJson({ id, authorization: header });
268
+ else
269
+ console.log(`Authorization: ${header}`);
270
+ });
271
+ deploy
272
+ .command('archive')
273
+ .description('Archive a stopped deployment (hides it from the list).')
274
+ .argument('<id>', 'Deployment id')
275
+ .option('-y, --yes', 'Skip confirmation')
276
+ .action(async (id, cmd) => {
277
+ const options = globals();
278
+ const dep = (await createClient(options).api.deployments.get(id));
279
+ await confirmDestructive('archive', id, cmd.yes);
280
+ await dep.archive();
281
+ console.log(`${sym.ok} Archived ${id}.`);
282
+ });
283
+ deploy
284
+ .command('delete')
285
+ .description('Delete a deployment permanently (stops it first if it is still running; drafts must be started and stopped once).')
286
+ .argument('<id>', 'Deployment id')
287
+ .option('-y, --yes', 'Skip confirmation')
288
+ .action(async (id, cmd) => {
289
+ const options = globals();
290
+ const client = createClient(options);
291
+ let dep = (await client.api.deployments.get(id));
292
+ await confirmDestructive('delete', id, cmd.yes);
293
+ if (dep.status === 'DRAFT') {
294
+ throw new CliError(`${id} is a DRAFT. The Nosana API refuses to stop, archive or delete drafts. Start it and stop it first (\`deploy start ${id}\`, then \`deploy stop ${id}\`), or remove it on deploy.nosana.com.`);
295
+ }
296
+ if (!DELETABLE_STATUSES.has(dep.status)) {
297
+ await dep.stop();
298
+ for (let attempt = 0; attempt < 12 && !DELETABLE_STATUSES.has(dep.status); attempt += 1) {
299
+ await sleep(5000);
300
+ dep = (await client.api.deployments.get(id));
301
+ }
302
+ if (!DELETABLE_STATUSES.has(dep.status)) {
303
+ throw new CliError(`${id} is still ${dep.status}; wait for it to stop, then run delete again.`);
304
+ }
305
+ console.log(`${sym.ok} Stopped ${id}.`);
306
+ }
307
+ await dep.delete();
308
+ console.log(`${sym.ok} Deleted ${id}.`);
309
+ });
310
+ }
311
+ //# sourceMappingURL=deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../../src/cli/commands/deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import { type GlobalOptions } from '../../core/client.js';
3
+ export declare function registerGpuCommands(program: Command, globals: () => GlobalOptions): void;