workstation.md 0.1.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/workstation.d.ts +14 -0
- package/bin/workstation.js +78 -0
- package/package.json +24 -0
- package/src/workstation.ts +96 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
declare const API_URL: string;
|
|
3
|
+
interface WorkstationInfo {
|
|
4
|
+
id: string;
|
|
5
|
+
host: string;
|
|
6
|
+
port: number;
|
|
7
|
+
web: string;
|
|
8
|
+
}
|
|
9
|
+
declare function apiRequest(path: string, options?: RequestInit): Promise<any>;
|
|
10
|
+
declare function create(args: string[]): Promise<void>;
|
|
11
|
+
declare function destroy(wsId: string): Promise<void>;
|
|
12
|
+
declare function list(): Promise<void>;
|
|
13
|
+
declare function usage(): void;
|
|
14
|
+
declare function main(): Promise<void>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
const API_URL = process.env.WORKSTATION_API_URL || "https://api.workstation.md";
|
|
4
|
+
async function apiRequest(path, options = {}) {
|
|
5
|
+
const res = await fetch(`${API_URL}${path}`, {
|
|
6
|
+
...options,
|
|
7
|
+
headers: {
|
|
8
|
+
"Content-Type": "application/json",
|
|
9
|
+
...options.headers,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
if (!res.ok) {
|
|
13
|
+
const text = await res.text();
|
|
14
|
+
console.error(`Error: ${res.status} ${text}`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
return res.json();
|
|
18
|
+
}
|
|
19
|
+
async function create(args) {
|
|
20
|
+
let pubkey;
|
|
21
|
+
for (let i = 0; i < args.length; i++) {
|
|
22
|
+
if (args[i] === "--pubkey" && args[i + 1]) {
|
|
23
|
+
pubkey = args[i + 1];
|
|
24
|
+
i++;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (!pubkey) {
|
|
28
|
+
console.error("Usage: workstation create --pubkey <public_key>");
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const info = await apiRequest("/create", {
|
|
32
|
+
method: "POST",
|
|
33
|
+
body: JSON.stringify({ pubkey }),
|
|
34
|
+
});
|
|
35
|
+
console.log(JSON.stringify(info, null, 2));
|
|
36
|
+
}
|
|
37
|
+
async function destroy(wsId) {
|
|
38
|
+
const result = await apiRequest(`/${wsId}`, { method: "DELETE" });
|
|
39
|
+
console.log(JSON.stringify(result, null, 2));
|
|
40
|
+
}
|
|
41
|
+
async function list() {
|
|
42
|
+
const items = await apiRequest("/list");
|
|
43
|
+
if (items.length === 0) {
|
|
44
|
+
console.log("No active workstations.");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
for (const ws of items) {
|
|
48
|
+
console.log(`${ws.id}\tssh -p ${ws.port} root@${ws.host}\t${ws.web}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function usage() {
|
|
52
|
+
console.log(`Usage:
|
|
53
|
+
workstation create --pubkey <public_key> Create a new workstation
|
|
54
|
+
workstation <id> destroy Destroy a workstation
|
|
55
|
+
workstation list List active workstations`);
|
|
56
|
+
}
|
|
57
|
+
async function main() {
|
|
58
|
+
const args = process.argv.slice(2);
|
|
59
|
+
if (args.length === 0) {
|
|
60
|
+
usage();
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
const command = args[0];
|
|
64
|
+
if (command === "create") {
|
|
65
|
+
await create(args.slice(1));
|
|
66
|
+
}
|
|
67
|
+
else if (command === "list") {
|
|
68
|
+
await list();
|
|
69
|
+
}
|
|
70
|
+
else if (args.length >= 2 && args[1] === "destroy") {
|
|
71
|
+
await destroy(command);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
usage();
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "workstation.md",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Cloud Linux workstations for AI agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"workstation": "./bin/workstation.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "tsc --watch"
|
|
12
|
+
},
|
|
13
|
+
"keywords": ["ai", "agent", "workstation", "cloud", "ssh"],
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/workstation-md/workstation-cli"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"typescript": "^5.5.0",
|
|
22
|
+
"@types/node": "^20.14.0"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const API_URL = process.env.WORKSTATION_API_URL || "https://api.workstation.md";
|
|
4
|
+
|
|
5
|
+
interface WorkstationInfo {
|
|
6
|
+
id: string;
|
|
7
|
+
host: string;
|
|
8
|
+
port: number;
|
|
9
|
+
web: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async function apiRequest(path: string, options: RequestInit = {}): Promise<any> {
|
|
13
|
+
const res = await fetch(`${API_URL}${path}`, {
|
|
14
|
+
...options,
|
|
15
|
+
headers: {
|
|
16
|
+
"Content-Type": "application/json",
|
|
17
|
+
...options.headers,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
if (!res.ok) {
|
|
21
|
+
const text = await res.text();
|
|
22
|
+
console.error(`Error: ${res.status} ${text}`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
return res.json();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function create(args: string[]) {
|
|
29
|
+
let pubkey: string | undefined;
|
|
30
|
+
|
|
31
|
+
for (let i = 0; i < args.length; i++) {
|
|
32
|
+
if (args[i] === "--pubkey" && args[i + 1]) {
|
|
33
|
+
pubkey = args[i + 1];
|
|
34
|
+
i++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!pubkey) {
|
|
39
|
+
console.error("Usage: workstation create --pubkey <public_key>");
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const info: WorkstationInfo = await apiRequest("/create", {
|
|
44
|
+
method: "POST",
|
|
45
|
+
body: JSON.stringify({ pubkey }),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
console.log(JSON.stringify(info, null, 2));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function destroy(wsId: string) {
|
|
52
|
+
const result = await apiRequest(`/${wsId}`, { method: "DELETE" });
|
|
53
|
+
console.log(JSON.stringify(result, null, 2));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function list() {
|
|
57
|
+
const items: WorkstationInfo[] = await apiRequest("/list");
|
|
58
|
+
if (items.length === 0) {
|
|
59
|
+
console.log("No active workstations.");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
for (const ws of items) {
|
|
63
|
+
console.log(`${ws.id}\tssh -p ${ws.port} root@${ws.host}\t${ws.web}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function usage() {
|
|
68
|
+
console.log(`Usage:
|
|
69
|
+
workstation create --pubkey <public_key> Create a new workstation
|
|
70
|
+
workstation <id> destroy Destroy a workstation
|
|
71
|
+
workstation list List active workstations`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function main() {
|
|
75
|
+
const args = process.argv.slice(2);
|
|
76
|
+
|
|
77
|
+
if (args.length === 0) {
|
|
78
|
+
usage();
|
|
79
|
+
process.exit(0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const command = args[0];
|
|
83
|
+
|
|
84
|
+
if (command === "create") {
|
|
85
|
+
await create(args.slice(1));
|
|
86
|
+
} else if (command === "list") {
|
|
87
|
+
await list();
|
|
88
|
+
} else if (args.length >= 2 && args[1] === "destroy") {
|
|
89
|
+
await destroy(command);
|
|
90
|
+
} else {
|
|
91
|
+
usage();
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
main();
|
package/tsconfig.json
ADDED