@castari/cli 0.1.10 → 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.
- package/bin/cast.js +2 -0
- package/dist/commands/agents.d.ts +6 -0
- package/dist/commands/agents.d.ts.map +1 -0
- package/dist/commands/agents.js +174 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/apikey.d.ts +6 -0
- package/dist/commands/apikey.d.ts.map +1 -0
- package/dist/commands/apikey.js +57 -0
- package/dist/commands/apikey.js.map +1 -0
- package/dist/commands/deploy.d.ts +3 -3
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +24 -64
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/invoke.d.ts +3 -0
- package/dist/commands/invoke.d.ts.map +1 -0
- package/dist/commands/invoke.js +50 -0
- package/dist/commands/invoke.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +123 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +16 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/secrets.d.ts +6 -0
- package/dist/commands/secrets.d.ts.map +1 -0
- package/dist/commands/secrets.js +90 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/stop.d.ts +3 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +25 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/usage.d.ts +3 -0
- package/dist/commands/usage.d.ts.map +1 -0
- package/dist/commands/usage.js +76 -0
- package/dist/commands/usage.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +27 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -34
- package/dist/index.js.map +1 -0
- package/dist/utils/errors.d.ts +6 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +42 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/output.d.ts +45 -0
- package/dist/utils/output.d.ts.map +1 -0
- package/dist/utils/output.js +75 -0
- package/dist/utils/output.js.map +1 -0
- package/package.json +55 -35
- package/LICENSE +0 -21
- package/README.md +0 -131
- package/dist/commands/client-id.d.ts +0 -1
- package/dist/commands/client-id.js +0 -25
- package/dist/commands/dev.d.ts +0 -1
- package/dist/commands/dev.js +0 -17
- package/dist/commands/generate-secrets.d.ts +0 -1
- package/dist/commands/generate-secrets.js +0 -60
- package/dist/commands/init.d.ts +0 -5
- package/dist/commands/init.js +0 -883
- package/dist/commands/start.d.ts +0 -5
- package/dist/commands/start.js +0 -100
- package/dist/utils/client-auth.d.ts +0 -11
- package/dist/utils/client-auth.js +0 -21
- package/dist/utils/client-id.d.ts +0 -10
- package/dist/utils/client-id.js +0 -36
package/bin/cast.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwLpC;;GAEG;AACH,eAAO,MAAM,aAAa,SAKE,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { CastariClient } from '@castari/sdk';
|
|
6
|
+
import { hint, keyValue, blank, formatDate, info } from '../utils/output.js';
|
|
7
|
+
import { handleError } from '../utils/errors.js';
|
|
8
|
+
/**
|
|
9
|
+
* Format agent status with color
|
|
10
|
+
*/
|
|
11
|
+
function formatStatus(status) {
|
|
12
|
+
switch (status) {
|
|
13
|
+
case 'active':
|
|
14
|
+
return chalk.green(status);
|
|
15
|
+
case 'deploying':
|
|
16
|
+
return chalk.yellow(status);
|
|
17
|
+
case 'pending':
|
|
18
|
+
return chalk.blue(status);
|
|
19
|
+
case 'stopped':
|
|
20
|
+
return chalk.gray(status);
|
|
21
|
+
case 'failed':
|
|
22
|
+
return chalk.red(status);
|
|
23
|
+
default:
|
|
24
|
+
return status;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* cast agents list
|
|
29
|
+
*/
|
|
30
|
+
const listCommand = new Command('list')
|
|
31
|
+
.description('List all agents')
|
|
32
|
+
.action(async () => {
|
|
33
|
+
const spinner = ora('Fetching agents...').start();
|
|
34
|
+
try {
|
|
35
|
+
const client = new CastariClient();
|
|
36
|
+
await client.ensureAuthenticated();
|
|
37
|
+
const agents = await client.agents.list();
|
|
38
|
+
spinner.stop();
|
|
39
|
+
if (agents.length === 0) {
|
|
40
|
+
info('No agents found');
|
|
41
|
+
hint("Create one with 'cast agents create <name> <git-url>'");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const table = new Table({
|
|
45
|
+
head: [
|
|
46
|
+
chalk.white('Slug'),
|
|
47
|
+
chalk.white('Name'),
|
|
48
|
+
chalk.white('Status'),
|
|
49
|
+
chalk.white('Created'),
|
|
50
|
+
],
|
|
51
|
+
style: {
|
|
52
|
+
head: [],
|
|
53
|
+
border: [],
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
for (const agent of agents) {
|
|
57
|
+
table.push([
|
|
58
|
+
agent.slug,
|
|
59
|
+
agent.name,
|
|
60
|
+
formatStatus(agent.status),
|
|
61
|
+
formatDate(agent.created_at),
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
console.log(table.toString());
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
spinner.fail('Failed to list agents');
|
|
68
|
+
handleError(err);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
/**
|
|
72
|
+
* cast agents create <name> <git-url>
|
|
73
|
+
*/
|
|
74
|
+
const createCommand = new Command('create')
|
|
75
|
+
.description('Create a new agent')
|
|
76
|
+
.argument('<name>', 'Agent name')
|
|
77
|
+
.argument('<git-url>', 'Git repository URL')
|
|
78
|
+
.option('--slug <slug>', 'Custom slug (default: auto-generated from name)')
|
|
79
|
+
.action(async (name, gitUrl, options) => {
|
|
80
|
+
const spinner = ora('Creating agent...').start();
|
|
81
|
+
try {
|
|
82
|
+
const client = new CastariClient();
|
|
83
|
+
await client.ensureAuthenticated();
|
|
84
|
+
const agent = await client.agents.create({
|
|
85
|
+
name,
|
|
86
|
+
gitRepoUrl: gitUrl,
|
|
87
|
+
slug: options.slug,
|
|
88
|
+
});
|
|
89
|
+
spinner.succeed(`Agent '${agent.name}' created!`);
|
|
90
|
+
blank();
|
|
91
|
+
keyValue('Slug', agent.slug);
|
|
92
|
+
keyValue('Git URL', agent.git_repo_url);
|
|
93
|
+
keyValue('Status', agent.status);
|
|
94
|
+
blank();
|
|
95
|
+
hint(`Deploy with: cast deploy ${agent.slug}`);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
spinner.fail('Failed to create agent');
|
|
99
|
+
handleError(err);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
/**
|
|
103
|
+
* cast agents get <slug>
|
|
104
|
+
*/
|
|
105
|
+
const getCommand = new Command('get')
|
|
106
|
+
.description('Get agent details')
|
|
107
|
+
.argument('<slug>', 'Agent slug')
|
|
108
|
+
.action(async (slug) => {
|
|
109
|
+
const spinner = ora('Fetching agent...').start();
|
|
110
|
+
try {
|
|
111
|
+
const client = new CastariClient();
|
|
112
|
+
await client.ensureAuthenticated();
|
|
113
|
+
const agent = await client.agents.get(slug);
|
|
114
|
+
spinner.stop();
|
|
115
|
+
blank();
|
|
116
|
+
keyValue('Name', agent.name);
|
|
117
|
+
keyValue('Slug', agent.slug);
|
|
118
|
+
keyValue('Git URL', agent.git_repo_url);
|
|
119
|
+
keyValue('Status', formatStatus(agent.status));
|
|
120
|
+
keyValue('Sandbox ID', agent.sandbox_id ?? undefined);
|
|
121
|
+
keyValue('Created', formatDate(agent.created_at));
|
|
122
|
+
keyValue('Updated', formatDate(agent.updated_at));
|
|
123
|
+
blank();
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
spinner.fail('Failed to get agent');
|
|
127
|
+
handleError(err);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
/**
|
|
131
|
+
* cast agents delete <slug>
|
|
132
|
+
*/
|
|
133
|
+
const deleteCommand = new Command('delete')
|
|
134
|
+
.description('Delete an agent')
|
|
135
|
+
.argument('<slug>', 'Agent slug')
|
|
136
|
+
.option('-f, --force', 'Skip confirmation')
|
|
137
|
+
.action(async (slug, options) => {
|
|
138
|
+
try {
|
|
139
|
+
const client = new CastariClient();
|
|
140
|
+
await client.ensureAuthenticated();
|
|
141
|
+
// Confirm deletion unless --force is used
|
|
142
|
+
if (!options.force) {
|
|
143
|
+
const readline = await import('node:readline');
|
|
144
|
+
const rl = readline.createInterface({
|
|
145
|
+
input: process.stdin,
|
|
146
|
+
output: process.stdout,
|
|
147
|
+
});
|
|
148
|
+
const answer = await new Promise((resolve) => {
|
|
149
|
+
rl.question(chalk.yellow(`Are you sure you want to delete agent '${slug}'? [y/N] `), resolve);
|
|
150
|
+
});
|
|
151
|
+
rl.close();
|
|
152
|
+
if (answer.toLowerCase() !== 'y' && answer.toLowerCase() !== 'yes') {
|
|
153
|
+
info('Deletion cancelled');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const spinner = ora('Deleting agent...').start();
|
|
158
|
+
await client.agents.delete(slug);
|
|
159
|
+
spinner.succeed(`Agent '${slug}' deleted`);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
handleError(err);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
/**
|
|
166
|
+
* cast agents
|
|
167
|
+
*/
|
|
168
|
+
export const agentsCommand = new Command('agents')
|
|
169
|
+
.description('Manage agents')
|
|
170
|
+
.addCommand(listCommand)
|
|
171
|
+
.addCommand(createCommand)
|
|
172
|
+
.addCommand(getCommand)
|
|
173
|
+
.addCommand(deleteCommand);
|
|
174
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apikey.d.ts","sourceRoot":"","sources":["../../src/commands/apikey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAsDpC;;GAEG;AACH,eAAO,MAAM,aAAa,SAGE,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { CastariClient } from '@castari/sdk';
|
|
5
|
+
import { info, blank, keyValue } from '../utils/output.js';
|
|
6
|
+
import { handleError } from '../utils/errors.js';
|
|
7
|
+
/**
|
|
8
|
+
* cast apikey create
|
|
9
|
+
*/
|
|
10
|
+
const createCommand = new Command('create')
|
|
11
|
+
.description('Create a new API key (only one per user)')
|
|
12
|
+
.action(async () => {
|
|
13
|
+
const spinner = ora('Creating API key...').start();
|
|
14
|
+
try {
|
|
15
|
+
const client = new CastariClient();
|
|
16
|
+
await client.ensureAuthenticated();
|
|
17
|
+
const result = await client.auth.createApiKey();
|
|
18
|
+
spinner.succeed('API key created!');
|
|
19
|
+
blank();
|
|
20
|
+
console.log(chalk.yellow('⚠ Save this key - it will only be shown once!'));
|
|
21
|
+
blank();
|
|
22
|
+
keyValue('API Key', chalk.green(result.api_key));
|
|
23
|
+
keyValue('Prefix', result.prefix);
|
|
24
|
+
blank();
|
|
25
|
+
info('Use with: CASTARI_API_KEY=<key> cast <command>');
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
spinner.fail('Failed to create API key');
|
|
29
|
+
handleError(err);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* cast apikey revoke
|
|
34
|
+
*/
|
|
35
|
+
const revokeCommand = new Command('revoke')
|
|
36
|
+
.description('Revoke your API key')
|
|
37
|
+
.action(async () => {
|
|
38
|
+
const spinner = ora('Revoking API key...').start();
|
|
39
|
+
try {
|
|
40
|
+
const client = new CastariClient();
|
|
41
|
+
await client.ensureAuthenticated();
|
|
42
|
+
await client.auth.revokeApiKey();
|
|
43
|
+
spinner.succeed('API key revoked');
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
spinner.fail('Failed to revoke API key');
|
|
47
|
+
handleError(err);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
/**
|
|
51
|
+
* cast apikey
|
|
52
|
+
*/
|
|
53
|
+
export const apikeyCommand = new Command('apikey')
|
|
54
|
+
.description('Manage API keys')
|
|
55
|
+
.addCommand(createCommand)
|
|
56
|
+
.addCommand(revokeCommand);
|
|
57
|
+
//# sourceMappingURL=apikey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apikey.js","sourceRoot":"","sources":["../../src/commands/apikey.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAW,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;GAEG;AACH,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KACxC,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,OAAO,GAAG,GAAG,CAAC,qBAAqB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,MAAM,CAAC,mBAAmB,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAEhD,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACpC,KAAK,EAAE,CAAC;QACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,+CAA+C,CAAC,CAAC,CAAC;QAC3E,KAAK,EAAE,CAAC;QACR,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAClC,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,gDAAgD,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACzC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL;;GAEG;AACH,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KACxC,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,OAAO,GAAG,GAAG,CAAC,qBAAqB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,MAAM,CAAC,mBAAmB,EAAE,CAAC;QACnC,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QAEjC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACzC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,iBAAiB,CAAC;KAC9B,UAAU,CAAC,aAAa,CAAC;KACzB,UAAU,CAAC,aAAa,CAAC,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export declare const deployCommand: Command;
|
|
3
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,aAAa,SAuBtB,CAAC"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,69 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import ora from 'ora';
|
|
2
3
|
import chalk from 'chalk';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const pkg = JSON.parse(await readFile('package.json', 'utf-8'));
|
|
12
|
-
snapshotName = pkg.name;
|
|
13
|
-
}
|
|
14
|
-
catch (e) {
|
|
15
|
-
console.warn(chalk.yellow('Warning: Could not read package.json. Using default name.'));
|
|
16
|
-
snapshotName = 'castari-agent';
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
if (!snapshotName) {
|
|
20
|
-
console.error(chalk.red('Error: Snapshot name is required (via --snapshot or package.json name).'));
|
|
21
|
-
process.exit(1);
|
|
22
|
-
}
|
|
23
|
-
console.log(chalk.blue(`📦 Packaging source code...`));
|
|
24
|
-
const zip = new AdmZip();
|
|
25
|
-
const projectRoot = process.cwd();
|
|
26
|
-
// Add local files, respecting a simple ignore list for now
|
|
27
|
-
// Ideally we'd parse .gitignore, but for MVP let's just ignore common heavy folders
|
|
28
|
-
const ignoreList = ['node_modules', '.git', 'dist', '.env'];
|
|
29
|
-
zip.addLocalFolder(projectRoot, undefined, (filename) => {
|
|
30
|
-
// Simple filter: return false to exclude
|
|
31
|
-
// filename is the relative path in the zip? No, it seems to be the absolute path or filename.
|
|
32
|
-
// AdmZip filter is a bit tricky. Let's assume it passes the name.
|
|
33
|
-
// Actually addLocalFolder filter takes a RegExp or function.
|
|
34
|
-
// If function: (filename: string) => boolean.
|
|
35
|
-
// Note: filename passed to filter is usually the relative path.
|
|
36
|
-
// Let's try to be safe and just add everything except node_modules at the root.
|
|
37
|
-
// Actually, addLocalFolder adds everything.
|
|
38
|
-
// We might want to use addLocalFile loop or similar if we want strict control.
|
|
39
|
-
// But let's try the filter.
|
|
40
|
-
return !ignoreList.some(ignore => filename.includes(ignore));
|
|
41
|
-
});
|
|
42
|
-
const zipBuffer = zip.toBuffer();
|
|
43
|
-
console.log(chalk.blue(`🚀 Uploading to Castari Platform...`));
|
|
44
|
-
const platformUrl = process.env.CASTARI_PLATFORM_URL || 'https://castari-api-12511-04c55b73-g4p2s9om.onporter.run';
|
|
45
|
-
const formData = new FormData();
|
|
46
|
-
formData.append('file', new Blob([zipBuffer]), 'source.zip');
|
|
47
|
-
formData.append('snapshot', snapshotName);
|
|
48
|
-
formData.append('clientId', clientId);
|
|
4
|
+
import { CastariClient } from '@castari/sdk';
|
|
5
|
+
import { keyValue, blank, hint } from '../utils/output.js';
|
|
6
|
+
import { handleError } from '../utils/errors.js';
|
|
7
|
+
export const deployCommand = new Command('deploy')
|
|
8
|
+
.description('Deploy an agent')
|
|
9
|
+
.argument('<slug>', 'Agent slug')
|
|
10
|
+
.action(async (slug) => {
|
|
11
|
+
const spinner = ora(`Deploying ${slug}...`).start();
|
|
49
12
|
try {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
throw new Error(`Platform error (${response.status}): ${errorText}`);
|
|
61
|
-
}
|
|
62
|
-
const result = await response.json();
|
|
63
|
-
console.log(chalk.green(`✅ Snapshot "${result.snapshot}" created successfully for client ${clientId}`));
|
|
13
|
+
const client = new CastariClient();
|
|
14
|
+
await client.ensureAuthenticated();
|
|
15
|
+
spinner.text = `Deploying ${slug}... (this may take a minute)`;
|
|
16
|
+
const agent = await client.agents.deploy(slug);
|
|
17
|
+
spinner.succeed(`Agent '${slug}' deployed!`);
|
|
18
|
+
blank();
|
|
19
|
+
keyValue('Status', chalk.green(agent.status));
|
|
20
|
+
keyValue('Sandbox ID', agent.sandbox_id ?? undefined);
|
|
21
|
+
blank();
|
|
22
|
+
hint(`Invoke with: cast invoke ${slug} "your prompt here"`);
|
|
64
23
|
}
|
|
65
24
|
catch (err) {
|
|
66
|
-
|
|
67
|
-
|
|
25
|
+
spinner.fail('Deployment failed');
|
|
26
|
+
handleError(err);
|
|
68
27
|
}
|
|
69
|
-
}
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAW,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,iBAAiB,CAAC;KAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;KAChC,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;IAC7B,MAAM,OAAO,GAAG,GAAG,CAAC,aAAa,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAEnC,OAAO,CAAC,IAAI,GAAG,aAAa,IAAI,8BAA8B,CAAC;QAC/D,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAE/C,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,aAAa,CAAC,CAAC;QAC7C,KAAK,EAAE,CAAC;QACR,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC;QACtD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,4BAA4B,IAAI,qBAAqB,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAClC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/commands/invoke.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,aAAa,SAiDtB,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { CastariClient } from '@castari/sdk';
|
|
6
|
+
import { blank, formatNumber, formatCost } from '../utils/output.js';
|
|
7
|
+
import { handleError } from '../utils/errors.js';
|
|
8
|
+
export const invokeCommand = new Command('invoke')
|
|
9
|
+
.description('Invoke an agent with a prompt')
|
|
10
|
+
.argument('<slug>', 'Agent slug')
|
|
11
|
+
.argument('[prompt]', 'Prompt to send to the agent')
|
|
12
|
+
.option('-i, --input <file>', 'Read prompt from file')
|
|
13
|
+
.action(async (slug, promptArg, options) => {
|
|
14
|
+
try {
|
|
15
|
+
// Get prompt from argument or file
|
|
16
|
+
let prompt;
|
|
17
|
+
if (options?.input) {
|
|
18
|
+
prompt = await readFile(options.input, 'utf-8');
|
|
19
|
+
}
|
|
20
|
+
else if (promptArg) {
|
|
21
|
+
prompt = promptArg;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.error(chalk.red('Error: Either a prompt or --input <file> is required'));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const spinner = ora(`Invoking ${slug}...`).start();
|
|
28
|
+
const client = new CastariClient();
|
|
29
|
+
await client.ensureAuthenticated();
|
|
30
|
+
spinner.text = `Invoking ${slug}... (this may take a while)`;
|
|
31
|
+
const result = await client.agents.invoke(slug, { prompt });
|
|
32
|
+
spinner.stop();
|
|
33
|
+
blank();
|
|
34
|
+
// Print the response
|
|
35
|
+
console.log(result.response_content);
|
|
36
|
+
// Print usage stats
|
|
37
|
+
blank();
|
|
38
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
39
|
+
console.log(chalk.gray(`Tokens: ${formatNumber(result.input_tokens)} in / ${formatNumber(result.output_tokens)} out`));
|
|
40
|
+
const cost = typeof result.total_cost_usd === 'string'
|
|
41
|
+
? parseFloat(result.total_cost_usd)
|
|
42
|
+
: result.total_cost_usd;
|
|
43
|
+
console.log(chalk.gray(`Cost: ${formatCost(cost)}`));
|
|
44
|
+
console.log(chalk.gray(`Duration: ${(result.duration_ms / 1000).toFixed(1)}s`));
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
handleError(err);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=invoke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../src/commands/invoke.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiGpC,eAAO,MAAM,YAAY,SA2CrB,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import open from 'open';
|
|
4
|
+
import { createServer } from 'node:http';
|
|
5
|
+
import { saveCredentials, CastariClient, getApiUrl } from '@castari/sdk';
|
|
6
|
+
import { info } from '../utils/output.js';
|
|
7
|
+
import { handleError } from '../utils/errors.js';
|
|
8
|
+
/**
|
|
9
|
+
* Find an available port for the local callback server
|
|
10
|
+
*/
|
|
11
|
+
async function findAvailablePort() {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const server = createServer();
|
|
14
|
+
server.listen(0, () => {
|
|
15
|
+
const address = server.address();
|
|
16
|
+
if (address && typeof address === 'object') {
|
|
17
|
+
const port = address.port;
|
|
18
|
+
server.close(() => resolve(port));
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
reject(new Error('Failed to find available port'));
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
server.on('error', reject);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start a local server to receive the OAuth callback
|
|
29
|
+
*/
|
|
30
|
+
async function startCallbackServer(port) {
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
const timeout = setTimeout(() => {
|
|
33
|
+
server.close();
|
|
34
|
+
reject(new Error('Login timed out. Please try again.'));
|
|
35
|
+
}, 120000); // 2 minute timeout
|
|
36
|
+
const server = createServer((req, res) => {
|
|
37
|
+
const url = new URL(req.url || '/', `http://localhost:${port}`);
|
|
38
|
+
if (url.pathname === '/callback') {
|
|
39
|
+
const token = url.searchParams.get('token');
|
|
40
|
+
const errorParam = url.searchParams.get('error');
|
|
41
|
+
if (errorParam) {
|
|
42
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
43
|
+
res.end(`
|
|
44
|
+
<html>
|
|
45
|
+
<body style="font-family: system-ui; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0;">
|
|
46
|
+
<div style="text-align: center;">
|
|
47
|
+
<h1 style="color: #e53e3e;">Login Failed</h1>
|
|
48
|
+
<p>${errorParam}</p>
|
|
49
|
+
<p>You can close this window.</p>
|
|
50
|
+
</div>
|
|
51
|
+
</body>
|
|
52
|
+
</html>
|
|
53
|
+
`);
|
|
54
|
+
clearTimeout(timeout);
|
|
55
|
+
server.close();
|
|
56
|
+
reject(new Error(errorParam));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (token) {
|
|
60
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
61
|
+
res.end(`
|
|
62
|
+
<html>
|
|
63
|
+
<body style="font-family: system-ui; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0;">
|
|
64
|
+
<div style="text-align: center;">
|
|
65
|
+
<h1 style="color: #38a169;">Login Successful!</h1>
|
|
66
|
+
<p>You can close this window and return to the terminal.</p>
|
|
67
|
+
</div>
|
|
68
|
+
</body>
|
|
69
|
+
</html>
|
|
70
|
+
`);
|
|
71
|
+
clearTimeout(timeout);
|
|
72
|
+
server.close();
|
|
73
|
+
resolve(token);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
res.writeHead(404);
|
|
78
|
+
res.end('Not found');
|
|
79
|
+
});
|
|
80
|
+
server.listen(port, () => {
|
|
81
|
+
// Server is ready
|
|
82
|
+
});
|
|
83
|
+
server.on('error', (err) => {
|
|
84
|
+
clearTimeout(timeout);
|
|
85
|
+
reject(err);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export const loginCommand = new Command('login')
|
|
90
|
+
.description('Authenticate with Castari')
|
|
91
|
+
.action(async () => {
|
|
92
|
+
const spinner = ora('Preparing authentication...').start();
|
|
93
|
+
try {
|
|
94
|
+
// Find an available port for the callback
|
|
95
|
+
const port = await findAvailablePort();
|
|
96
|
+
spinner.text = 'Starting authentication server...';
|
|
97
|
+
// Get the API URL
|
|
98
|
+
const apiUrl = await getApiUrl();
|
|
99
|
+
const authUrl = `${apiUrl}/api/v1/auth/cli/login?port=${port}`;
|
|
100
|
+
// Start the callback server
|
|
101
|
+
const tokenPromise = startCallbackServer(port);
|
|
102
|
+
spinner.stop();
|
|
103
|
+
info(`Opening browser for authentication...`);
|
|
104
|
+
info(`If the browser doesn't open, visit: ${authUrl}`);
|
|
105
|
+
// Open the browser
|
|
106
|
+
await open(authUrl);
|
|
107
|
+
spinner.start('Waiting for authentication...');
|
|
108
|
+
// Wait for the callback
|
|
109
|
+
const token = await tokenPromise;
|
|
110
|
+
spinner.text = 'Saving credentials...';
|
|
111
|
+
// Save the token
|
|
112
|
+
await saveCredentials({ token });
|
|
113
|
+
// Verify the token works by getting user info
|
|
114
|
+
const client = new CastariClient({ token });
|
|
115
|
+
const user = await client.auth.me();
|
|
116
|
+
spinner.succeed(`Logged in as ${user.email}`);
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
spinner.fail('Login failed');
|
|
120
|
+
handleError(err);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAkB,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;GAEG;AACH,KAAK,UAAU,iBAAiB;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE;YACpB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;gBAC1B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;YACrD,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,mBAAmB,CAAC,IAAY;IAC7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAC1D,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,mBAAmB;QAE/B,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACvC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;YAEhE,IAAI,GAAG,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC5C,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAEjD,IAAI,UAAU,EAAE,CAAC;oBACf,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;oBACpD,GAAG,CAAC,GAAG,CAAC;;;;;uBAKK,UAAU;;;;;WAKtB,CAAC,CAAC;oBACH,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;oBAC9B,OAAO;gBACT,CAAC;gBAED,IAAI,KAAK,EAAE,CAAC;oBACV,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;oBACpD,GAAG,CAAC,GAAG,CAAC;;;;;;;;;WASP,CAAC,CAAC;oBACH,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,MAAM,CAAC,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,CAAC;oBACf,OAAO;gBACT,CAAC;YACH,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;YACvB,kBAAkB;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,YAAY,CAAC,OAAO,CAAC,CAAC;YACtB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,2BAA2B,CAAC;KACxC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,OAAO,GAAG,GAAG,CAAC,6BAA6B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE3D,IAAI,CAAC;QACH,0CAA0C;QAC1C,MAAM,IAAI,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACvC,OAAO,CAAC,IAAI,GAAG,mCAAmC,CAAC;QAEnD,kBAAkB;QAClB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,GAAG,MAAM,+BAA+B,IAAI,EAAE,CAAC;QAE/D,4BAA4B;QAC5B,MAAM,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAE/C,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,IAAI,CAAC,uCAAuC,CAAC,CAAC;QAC9C,IAAI,CAAC,uCAAuC,OAAO,EAAE,CAAC,CAAC;QAEvD,mBAAmB;QACnB,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpB,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAE/C,wBAAwB;QACxB,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC;QAEjC,OAAO,CAAC,IAAI,GAAG,uBAAuB,CAAC;QAEvC,iBAAiB;QACjB,MAAM,eAAe,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAEjC,8CAA8C;QAC9C,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QAEpC,OAAO,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7B,WAAW,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SAStB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { clearCredentials } from '@castari/sdk';
|
|
3
|
+
import { success } from '../utils/output.js';
|
|
4
|
+
import { handleError } from '../utils/errors.js';
|
|
5
|
+
export const logoutCommand = new Command('logout')
|
|
6
|
+
.description('Clear stored credentials')
|
|
7
|
+
.action(async () => {
|
|
8
|
+
try {
|
|
9
|
+
await clearCredentials();
|
|
10
|
+
success('Logged out successfully');
|
|
11
|
+
}
|
|
12
|
+
catch (err) {
|
|
13
|
+
handleError(err);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,0BAA0B,CAAC;KACvC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,gBAAgB,EAAE,CAAC;QACzB,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,WAAW,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/commands/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6FpC;;GAEG;AACH,eAAO,MAAM,cAAc,SAIC,CAAC"}
|