mirror of
https://github.com/trycua/computer.git
synced 2026-05-05 06:31:06 -05:00
Merge pull request #579 from sarinali/feat/new-usecase-connections-extraction
Post Event Contact Usecase
This commit is contained in:
@@ -4,9 +4,9 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
version:
|
version:
|
||||||
description: 'Version to publish (default: from package.json)'
|
description: "Version to publish (default: from package.json)"
|
||||||
required: false
|
required: false
|
||||||
default: ''
|
default: ""
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-and-publish:
|
build-and-publish:
|
||||||
@@ -14,25 +14,25 @@ jobs:
|
|||||||
id-token: write
|
id-token: write
|
||||||
contents: write
|
contents: write
|
||||||
packages: write
|
packages: write
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- target: bun-linux-x64
|
- target: bun-linux-x64
|
||||||
ext: ''
|
ext: ""
|
||||||
binary_name: cua-linux-x64
|
binary_name: cua-linux-x64
|
||||||
- target: bun-darwin-x64
|
- target: bun-darwin-x64
|
||||||
ext: ''
|
ext: ""
|
||||||
binary_name: cua-darwin-x64
|
binary_name: cua-darwin-x64
|
||||||
- target: bun-darwin-arm64
|
- target: bun-darwin-arm64
|
||||||
ext: ''
|
ext: ""
|
||||||
binary_name: cua-darwin-arm64
|
binary_name: cua-darwin-arm64
|
||||||
- target: bun-windows-x64
|
- target: bun-windows-x64
|
||||||
ext: '.exe'
|
ext: ".exe"
|
||||||
binary_name: cua-windows-x64
|
binary_name: cua-windows-x64
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -140,7 +140,7 @@ jobs:
|
|||||||
```bash
|
```bash
|
||||||
# For Linux/macOS
|
# For Linux/macOS
|
||||||
curl -fsSL https://cua.ai/cli/install.sh | sh
|
curl -fsSL https://cua.ai/cli/install.sh | sh
|
||||||
|
|
||||||
# For Windows (PowerShell)
|
# For Windows (PowerShell)
|
||||||
irm https://cua.ai/cli/install.ps1 | iex
|
irm https://cua.ai/cli/install.ps1 | iex
|
||||||
```
|
```
|
||||||
@@ -149,7 +149,7 @@ jobs:
|
|||||||
```bash
|
```bash
|
||||||
# Using bun
|
# Using bun
|
||||||
bun add -g @trycua/cli
|
bun add -g @trycua/cli
|
||||||
|
|
||||||
# Or using npm
|
# Or using npm
|
||||||
npm install -g @trycua/cli
|
npm install -g @trycua/cli
|
||||||
```
|
```
|
||||||
@@ -209,4 +209,4 @@ jobs:
|
|||||||
asset_name: cua-windows-x64.exe
|
asset_name: cua-windows-x64.exe
|
||||||
asset_content_type: application/octet-stream
|
asset_content_type: application/octet-stream
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"title": "Cookbook",
|
"title": "Cookbook",
|
||||||
"description": "Real-world examples of building with Cua",
|
"description": "Real-world examples of building with Cua",
|
||||||
"pages": ["form-filling"]
|
"pages": ["form-filling", "post-event-contact-export"]
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -11,11 +11,12 @@ export function registerVmCommands(y: Argv) {
|
|||||||
.command(
|
.command(
|
||||||
['list', 'ls', 'ps'],
|
['list', 'ls', 'ps'],
|
||||||
'List sandboxes',
|
'List sandboxes',
|
||||||
(y) => y.option('show-passwords', {
|
(y) =>
|
||||||
type: 'boolean',
|
y.option('show-passwords', {
|
||||||
default: false,
|
type: 'boolean',
|
||||||
describe: 'Show sandbox passwords in output'
|
default: false,
|
||||||
}),
|
describe: 'Show sandbox passwords in output',
|
||||||
|
}),
|
||||||
async (argv: Record<string, unknown>) => {
|
async (argv: Record<string, unknown>) => {
|
||||||
const token = await ensureApiKeyInteractive();
|
const token = await ensureApiKeyInteractive();
|
||||||
const res = await http('/v1/vms', { token });
|
const res = await http('/v1/vms', { token });
|
||||||
@@ -34,284 +35,283 @@ export function registerVmCommands(y: Argv) {
|
|||||||
)
|
)
|
||||||
.command(
|
.command(
|
||||||
'create',
|
'create',
|
||||||
'Create a new sandbox',
|
'Create a new sandbox',
|
||||||
(y) =>
|
(y) =>
|
||||||
y
|
y
|
||||||
.option('os', {
|
.option('os', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
choices: ['linux', 'windows', 'macos'],
|
choices: ['linux', 'windows', 'macos'],
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
describe: 'Operating system',
|
describe: 'Operating system',
|
||||||
})
|
})
|
||||||
.option('configuration', {
|
.option('configuration', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
choices: ['small', 'medium', 'large'],
|
choices: ['small', 'medium', 'large'],
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
describe: 'Sandbox size configuration',
|
describe: 'Sandbox size configuration',
|
||||||
})
|
})
|
||||||
.option('region', {
|
.option('region', {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
choices: [
|
choices: [
|
||||||
'north-america',
|
'north-america',
|
||||||
'europe',
|
'europe',
|
||||||
'asia-pacific',
|
'asia-pacific',
|
||||||
'south-america',
|
'south-america',
|
||||||
],
|
],
|
||||||
demandOption: true,
|
demandOption: true,
|
||||||
describe: 'Sandbox region',
|
describe: 'Sandbox region',
|
||||||
}),
|
}),
|
||||||
async (argv: Record<string, unknown>) => {
|
async (argv: Record<string, unknown>) => {
|
||||||
const token = await ensureApiKeyInteractive();
|
const token = await ensureApiKeyInteractive();
|
||||||
const { os, configuration, region } = argv as {
|
const { os, configuration, region } = argv as {
|
||||||
os: string;
|
os: string;
|
||||||
configuration: string;
|
configuration: string;
|
||||||
region: string;
|
region: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = await http('/v1/vms', {
|
const res = await http('/v1/vms', {
|
||||||
token,
|
token,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: { os, configuration, region },
|
body: { os, configuration, region },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status === 401) {
|
if (res.status === 401) {
|
||||||
clearApiKey();
|
clearApiKey();
|
||||||
console.error("Unauthorized. Try 'cua login' again.");
|
console.error("Unauthorized. Try 'cua login' again.");
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.status === 400) {
|
|
||||||
console.error('Invalid request or unsupported configuration');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.status === 500) {
|
|
||||||
console.error('Internal server error');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.status === 200) {
|
|
||||||
// Sandbox ready immediately
|
|
||||||
const data = (await res.json()) as {
|
|
||||||
status: string;
|
|
||||||
name: string;
|
|
||||||
password: string;
|
|
||||||
host: string;
|
|
||||||
};
|
|
||||||
console.log(`Sandbox created and ready: ${data.name}`);
|
|
||||||
console.log(`Password: ${data.password}`);
|
|
||||||
console.log(`Host: ${data.host}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.status === 202) {
|
|
||||||
// Sandbox provisioning started
|
|
||||||
const data = (await res.json()) as {
|
|
||||||
status: string;
|
|
||||||
name: string;
|
|
||||||
job_id: string;
|
|
||||||
};
|
|
||||||
console.log(`Sandbox provisioning started: ${data.name}`);
|
|
||||||
console.log(`Job ID: ${data.job_id}`);
|
|
||||||
console.log("Use 'cua list' to monitor provisioning progress");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error(`Unexpected status: ${res.status}`);
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
if (res.status === 400) {
|
||||||
|
console.error('Invalid request or unsupported configuration');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === 500) {
|
||||||
|
console.error('Internal server error');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === 200) {
|
||||||
|
// Sandbox ready immediately
|
||||||
|
const data = (await res.json()) as {
|
||||||
|
status: string;
|
||||||
|
name: string;
|
||||||
|
password: string;
|
||||||
|
host: string;
|
||||||
|
};
|
||||||
|
console.log(`Sandbox created and ready: ${data.name}`);
|
||||||
|
console.log(`Password: ${data.password}`);
|
||||||
|
console.log(`Host: ${data.host}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.status === 202) {
|
||||||
|
// Sandbox provisioning started
|
||||||
|
const data = (await res.json()) as {
|
||||||
|
status: string;
|
||||||
|
name: string;
|
||||||
|
job_id: string;
|
||||||
|
};
|
||||||
|
console.log(`Sandbox provisioning started: ${data.name}`);
|
||||||
|
console.log(`Job ID: ${data.job_id}`);
|
||||||
|
console.log("Use 'cua list' to monitor provisioning progress");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(`Unexpected status: ${res.status}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
)
|
||||||
.command(
|
.command(
|
||||||
'delete <name>',
|
'delete <name>',
|
||||||
'Delete a sandbox',
|
'Delete a sandbox',
|
||||||
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
||||||
async (argv: Record<string, unknown>) => {
|
async (argv: Record<string, unknown>) => {
|
||||||
const token = await ensureApiKeyInteractive();
|
const token = await ensureApiKeyInteractive();
|
||||||
const name = String((argv as any).name);
|
const name = String((argv as any).name);
|
||||||
const res = await http(`/v1/vms/${encodeURIComponent(name)}`, {
|
const res = await http(`/v1/vms/${encodeURIComponent(name)}`, {
|
||||||
token,
|
token,
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status === 202) {
|
if (res.status === 202) {
|
||||||
const body = (await res.json().catch(() => ({}))) as {
|
const body = (await res.json().catch(() => ({}))) as {
|
||||||
status?: string;
|
status?: string;
|
||||||
};
|
};
|
||||||
console.log(`Sandbox deletion initiated: ${body.status ?? 'deleting'}`);
|
console.log(
|
||||||
return;
|
`Sandbox deletion initiated: ${body.status ?? 'deleting'}`
|
||||||
}
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (res.status === 404) {
|
if (res.status === 404) {
|
||||||
console.error('Sandbox not found or not owned by you');
|
console.error('Sandbox not found or not owned by you');
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res.status === 401) {
|
|
||||||
clearApiKey();
|
|
||||||
console.error("Unauthorized. Try 'cua login' again.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error(`Unexpected status: ${res.status}`);
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
if (res.status === 401) {
|
||||||
|
clearApiKey();
|
||||||
|
console.error("Unauthorized. Try 'cua login' again.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(`Unexpected status: ${res.status}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
)
|
||||||
.command(
|
.command(
|
||||||
'start <name>',
|
'start <name>',
|
||||||
'Start a sandbox',
|
'Start a sandbox',
|
||||||
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
||||||
async (argv: Record<string, unknown>) => {
|
async (argv: Record<string, unknown>) => {
|
||||||
const token = await ensureApiKeyInteractive();
|
const token = await ensureApiKeyInteractive();
|
||||||
const name = String((argv as any).name);
|
const name = String((argv as any).name);
|
||||||
const res = await http(`/v1/vms/${encodeURIComponent(name)}/start`, {
|
const res = await http(`/v1/vms/${encodeURIComponent(name)}/start`, {
|
||||||
token,
|
token,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
});
|
});
|
||||||
if (res.status === 204) {
|
if (res.status === 204) {
|
||||||
console.log('Start accepted');
|
console.log('Start accepted');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (res.status === 404) {
|
if (res.status === 404) {
|
||||||
console.error('Sandbox not found');
|
console.error('Sandbox not found');
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
if (res.status === 401) {
|
|
||||||
clearApiKey();
|
|
||||||
console.error("Unauthorized. Try 'cua login' again.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
console.error(`Unexpected status: ${res.status}`);
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
)
|
if (res.status === 401) {
|
||||||
|
clearApiKey();
|
||||||
|
console.error("Unauthorized. Try 'cua login' again.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.error(`Unexpected status: ${res.status}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
)
|
||||||
.command(
|
.command(
|
||||||
'stop <name>',
|
'stop <name>',
|
||||||
'Stop a sandbox',
|
'Stop a sandbox',
|
||||||
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
||||||
async (argv: Record<string, unknown>) => {
|
async (argv: Record<string, unknown>) => {
|
||||||
const token = await ensureApiKeyInteractive();
|
const token = await ensureApiKeyInteractive();
|
||||||
const name = String((argv as any).name);
|
const name = String((argv as any).name);
|
||||||
const res = await http(`/v1/vms/${encodeURIComponent(name)}/stop`, {
|
const res = await http(`/v1/vms/${encodeURIComponent(name)}/stop`, {
|
||||||
token,
|
token,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
});
|
});
|
||||||
if (res.status === 202) {
|
if (res.status === 202) {
|
||||||
const body = (await res.json().catch(() => ({}))) as {
|
const body = (await res.json().catch(() => ({}))) as {
|
||||||
status?: string;
|
status?: string;
|
||||||
};
|
};
|
||||||
console.log(body.status ?? 'stopping');
|
console.log(body.status ?? 'stopping');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (res.status === 404) {
|
if (res.status === 404) {
|
||||||
console.error('Sandbox not found');
|
console.error('Sandbox not found');
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
if (res.status === 401) {
|
|
||||||
clearApiKey();
|
|
||||||
console.error("Unauthorized. Try 'cua login' again.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
console.error(`Unexpected status: ${res.status}`);
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
)
|
if (res.status === 401) {
|
||||||
|
clearApiKey();
|
||||||
|
console.error("Unauthorized. Try 'cua login' again.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.error(`Unexpected status: ${res.status}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
)
|
||||||
.command(
|
.command(
|
||||||
'restart <name>',
|
'restart <name>',
|
||||||
'Restart a sandbox',
|
'Restart a sandbox',
|
||||||
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
||||||
async (argv: Record<string, unknown>) => {
|
async (argv: Record<string, unknown>) => {
|
||||||
const token = await ensureApiKeyInteractive();
|
const token = await ensureApiKeyInteractive();
|
||||||
const name = String((argv as any).name);
|
const name = String((argv as any).name);
|
||||||
const res = await http(
|
const res = await http(`/v1/vms/${encodeURIComponent(name)}/restart`, {
|
||||||
`/v1/vms/${encodeURIComponent(name)}/restart`,
|
token,
|
||||||
{
|
method: 'POST',
|
||||||
token,
|
});
|
||||||
method: 'POST',
|
if (res.status === 202) {
|
||||||
}
|
const body = (await res.json().catch(() => ({}))) as {
|
||||||
);
|
status?: string;
|
||||||
if (res.status === 202) {
|
};
|
||||||
const body = (await res.json().catch(() => ({}))) as {
|
console.log(body.status ?? 'restarting');
|
||||||
status?: string;
|
return;
|
||||||
};
|
}
|
||||||
console.log(body.status ?? 'restarting');
|
if (res.status === 404) {
|
||||||
return;
|
console.error('Sandbox not found');
|
||||||
}
|
|
||||||
if (res.status === 404) {
|
|
||||||
console.error('Sandbox not found');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
if (res.status === 401) {
|
|
||||||
clearApiKey();
|
|
||||||
console.error("Unauthorized. Try 'cua login' again.");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
console.error(`Unexpected status: ${res.status}`);
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
)
|
if (res.status === 401) {
|
||||||
|
clearApiKey();
|
||||||
|
console.error("Unauthorized. Try 'cua login' again.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
console.error(`Unexpected status: ${res.status}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
)
|
||||||
.command(
|
.command(
|
||||||
'open <name>',
|
'open <name>',
|
||||||
'Open NoVNC for a sandbox in your browser',
|
'Open NoVNC for a sandbox in your browser',
|
||||||
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
(y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
||||||
async (argv: Record<string, unknown>) => {
|
async (argv: Record<string, unknown>) => {
|
||||||
const token = await ensureApiKeyInteractive();
|
const token = await ensureApiKeyInteractive();
|
||||||
const name = String((argv as any).name);
|
const name = String((argv as any).name);
|
||||||
const listRes = await http('/v1/vms', { token });
|
const listRes = await http('/v1/vms', { token });
|
||||||
if (listRes.status === 401) {
|
if (listRes.status === 401) {
|
||||||
clearApiKey();
|
clearApiKey();
|
||||||
console.error("Unauthorized. Try 'cua login' again.");
|
console.error("Unauthorized. Try 'cua login' again.");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
|
||||||
if (!listRes.ok) {
|
|
||||||
console.error(`Request failed: ${listRes.status}`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
const vms = (await listRes.json()) as VmItem[];
|
|
||||||
const vm = vms.find((v) => v.name === name);
|
|
||||||
if (!vm) {
|
|
||||||
console.error('Sandbox not found');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
const host =
|
|
||||||
vm.host && vm.host.length
|
|
||||||
? vm.host
|
|
||||||
: `${vm.name}.containers.cloud.trycua.com`;
|
|
||||||
const url = `https://${host}/vnc.html?autoconnect=true&password=${encodeURIComponent(vm.password)}`;
|
|
||||||
console.log(`Opening NoVNC: ${url}`);
|
|
||||||
await openInBrowser(url);
|
|
||||||
}
|
}
|
||||||
)
|
if (!listRes.ok) {
|
||||||
// .command(
|
console.error(`Request failed: ${listRes.status}`);
|
||||||
// 'chat <name>',
|
process.exit(1);
|
||||||
// 'Open CUA playground for a sandbox',
|
}
|
||||||
// (y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
const vms = (await listRes.json()) as VmItem[];
|
||||||
// async (argv: Record<string, unknown>) => {
|
const vm = vms.find((v) => v.name === name);
|
||||||
// const token = await ensureApiKeyInteractive();
|
if (!vm) {
|
||||||
// const name = String((argv as any).name);
|
console.error('Sandbox not found');
|
||||||
// const listRes = await http('/v1/vms', { token });
|
process.exit(1);
|
||||||
// if (listRes.status === 401) {
|
}
|
||||||
// clearApiKey();
|
const host =
|
||||||
// console.error("Unauthorized. Try 'cua login' again.");
|
vm.host && vm.host.length
|
||||||
// process.exit(1);
|
? vm.host
|
||||||
// }
|
: `${vm.name}.containers.cloud.trycua.com`;
|
||||||
// if (!listRes.ok) {
|
const url = `https://${host}/vnc.html?autoconnect=true&password=${encodeURIComponent(vm.password)}`;
|
||||||
// console.error(`Request failed: ${listRes.status}`);
|
console.log(`Opening NoVNC: ${url}`);
|
||||||
// process.exit(1);
|
await openInBrowser(url);
|
||||||
// }
|
}
|
||||||
// const vms = (await listRes.json()) as VmItem[];
|
);
|
||||||
// const vm = vms.find((v) => v.name === name);
|
// .command(
|
||||||
// if (!vm) {
|
// 'chat <name>',
|
||||||
// console.error('Sandbox not found');
|
// 'Open CUA playground for a sandbox',
|
||||||
// process.exit(1);
|
// (y) => y.positional('name', { type: 'string', describe: 'Sandbox name' }),
|
||||||
// }
|
// async (argv: Record<string, unknown>) => {
|
||||||
// const host =
|
// const token = await ensureApiKeyInteractive();
|
||||||
// vm.host && vm.host.length
|
// const name = String((argv as any).name);
|
||||||
// ? vm.host
|
// const listRes = await http('/v1/vms', { token });
|
||||||
// : `${vm.name}.containers.cloud.trycua.com`;
|
// if (listRes.status === 401) {
|
||||||
// const base = WEBSITE_URL.replace(/\/$/, '');
|
// clearApiKey();
|
||||||
// const url = `${base}/dashboard/playground?host=${encodeURIComponent(host)}&id=${encodeURIComponent(vm.name)}&name=${encodeURIComponent(vm.name)}&vnc_password=${encodeURIComponent(vm.password)}&fullscreen=true`;
|
// console.error("Unauthorized. Try 'cua login' again.");
|
||||||
// console.log(`Opening Playground: ${url}`);
|
// process.exit(1);
|
||||||
// await openInBrowser(url);
|
// }
|
||||||
// }
|
// if (!listRes.ok) {
|
||||||
// );
|
// console.error(`Request failed: ${listRes.status}`);
|
||||||
|
// process.exit(1);
|
||||||
|
// }
|
||||||
|
// const vms = (await listRes.json()) as VmItem[];
|
||||||
|
// const vm = vms.find((v) => v.name === name);
|
||||||
|
// if (!vm) {
|
||||||
|
// console.error('Sandbox not found');
|
||||||
|
// process.exit(1);
|
||||||
|
// }
|
||||||
|
// const host =
|
||||||
|
// vm.host && vm.host.length
|
||||||
|
// ? vm.host
|
||||||
|
// : `${vm.name}.containers.cloud.trycua.com`;
|
||||||
|
// const base = WEBSITE_URL.replace(/\/$/, '');
|
||||||
|
// const url = `${base}/dashboard/playground?host=${encodeURIComponent(host)}&id=${encodeURIComponent(vm.name)}&name=${encodeURIComponent(vm.name)}&vnc_password=${encodeURIComponent(vm.password)}&fullscreen=true`;
|
||||||
|
// console.log(`Opening Playground: ${url}`);
|
||||||
|
// await openInBrowser(url);
|
||||||
|
// }
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,28 +26,29 @@ export type VmItem = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export function printVmList(items: VmItem[], showPasswords: boolean = false) {
|
export function printVmList(items: VmItem[], showPasswords: boolean = false) {
|
||||||
const headers = showPasswords
|
const headers = showPasswords
|
||||||
? ['NAME', 'STATUS', 'PASSWORD', 'HOST']
|
? ['NAME', 'STATUS', 'PASSWORD', 'HOST']
|
||||||
: ['NAME', 'STATUS', 'HOST'];
|
: ['NAME', 'STATUS', 'HOST'];
|
||||||
|
|
||||||
const rows: string[][] = [
|
const rows: string[][] = [
|
||||||
headers,
|
headers,
|
||||||
...items.map((v) => showPasswords
|
...items.map((v) =>
|
||||||
? [v.name, String(v.status), v.password, v.host || '']
|
showPasswords
|
||||||
: [v.name, String(v.status), v.host || '']
|
? [v.name, String(v.status), v.password, v.host || '']
|
||||||
|
: [v.name, String(v.status), v.host || '']
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
const numCols = headers.length;
|
const numCols = headers.length;
|
||||||
const widths: number[] = new Array(numCols).fill(0);
|
const widths: number[] = new Array(numCols).fill(0);
|
||||||
|
|
||||||
for (const r of rows)
|
for (const r of rows)
|
||||||
for (let i = 0; i < numCols; i++)
|
for (let i = 0; i < numCols; i++)
|
||||||
widths[i] = Math.max(widths[i] ?? 0, (r[i] ?? '').length);
|
widths[i] = Math.max(widths[i] ?? 0, (r[i] ?? '').length);
|
||||||
|
|
||||||
for (const r of rows)
|
for (const r of rows)
|
||||||
console.log(r.map((c, i) => (c ?? '').padEnd(widths[i] ?? 0)).join(' '));
|
console.log(r.map((c, i) => (c ?? '').padEnd(widths[i] ?? 0)).join(' '));
|
||||||
|
|
||||||
if (items.length === 0) console.log('No VMs found');
|
if (items.length === 0) console.log('No VMs found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user