swarmlancer-cli 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/README.md +15 -0
- package/dist/agent.d.ts +13 -0
- package/dist/agent.js +202 -0
- package/dist/app.d.ts +4 -0
- package/dist/app.js +496 -0
- package/dist/config.d.ts +49 -0
- package/dist/config.js +175 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +129 -0
- package/dist/inference.d.ts +13 -0
- package/dist/inference.js +105 -0
- package/dist/login.d.ts +1 -0
- package/dist/login.js +57 -0
- package/dist/screening.d.ts +22 -0
- package/dist/screening.js +101 -0
- package/dist/screens/agent-config.d.ts +14 -0
- package/dist/screens/agent-config.js +64 -0
- package/dist/screens/agent-editor.d.ts +13 -0
- package/dist/screens/agent-editor.js +64 -0
- package/dist/screens/agent-list.d.ts +22 -0
- package/dist/screens/agent-list.js +73 -0
- package/dist/screens/agent-picker.d.ts +15 -0
- package/dist/screens/agent-picker.js +51 -0
- package/dist/screens/agent-running.d.ts +20 -0
- package/dist/screens/agent-running.js +68 -0
- package/dist/screens/banner.d.ts +6 -0
- package/dist/screens/banner.js +27 -0
- package/dist/screens/dashboard.d.ts +16 -0
- package/dist/screens/dashboard.js +59 -0
- package/dist/screens/discovery-settings.d.ts +17 -0
- package/dist/screens/discovery-settings.js +189 -0
- package/dist/screens/message.d.ts +15 -0
- package/dist/screens/message.js +39 -0
- package/dist/screens/model-picker.d.ts +14 -0
- package/dist/screens/model-picker.js +49 -0
- package/dist/screens/name-editor.d.ts +15 -0
- package/dist/screens/name-editor.js +67 -0
- package/dist/screens/session-goal.d.ts +13 -0
- package/dist/screens/session-goal.js +61 -0
- package/dist/screens/settings.d.ts +15 -0
- package/dist/screens/settings.js +126 -0
- package/dist/screens/setup-wizard.d.ts +20 -0
- package/dist/screens/setup-wizard.js +120 -0
- package/dist/screens/status-panel.d.ts +15 -0
- package/dist/screens/status-panel.js +37 -0
- package/dist/theme.d.ts +42 -0
- package/dist/theme.js +56 -0
- package/package.json +49 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { SelectList, truncateToWidth, } from "@mariozechner/pi-tui";
|
|
2
|
+
import { colors, theme } from "../theme.js";
|
|
3
|
+
export class SetupWizardScreen {
|
|
4
|
+
tui;
|
|
5
|
+
steps;
|
|
6
|
+
cachedRender;
|
|
7
|
+
// For confirmation prompts
|
|
8
|
+
promptActive = false;
|
|
9
|
+
promptText = "";
|
|
10
|
+
promptList;
|
|
11
|
+
promptResolve;
|
|
12
|
+
constructor(tui) {
|
|
13
|
+
this.tui = tui;
|
|
14
|
+
this.steps = [
|
|
15
|
+
{ label: "Authentication", status: "pending" },
|
|
16
|
+
{ label: "Model detection", status: "pending" },
|
|
17
|
+
{ label: "Agents", status: "pending" },
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
setStep(index, status, detail) {
|
|
21
|
+
this.steps[index].status = status;
|
|
22
|
+
if (detail !== undefined)
|
|
23
|
+
this.steps[index].detail = detail;
|
|
24
|
+
this.cachedRender = undefined;
|
|
25
|
+
this.tui.requestRender();
|
|
26
|
+
}
|
|
27
|
+
/** Show a yes/no prompt and return the user's choice */
|
|
28
|
+
askConfirm(question) {
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
this.promptActive = true;
|
|
31
|
+
this.promptText = question;
|
|
32
|
+
this.promptResolve = resolve;
|
|
33
|
+
const items = [
|
|
34
|
+
{ value: "yes", label: "Yes" },
|
|
35
|
+
{ value: "no", label: "Later" },
|
|
36
|
+
];
|
|
37
|
+
this.promptList = new SelectList(items, 2, {
|
|
38
|
+
selectedPrefix: (t) => theme.accent(t),
|
|
39
|
+
selectedText: (t) => theme.accent(t),
|
|
40
|
+
description: (t) => colors.gray(t),
|
|
41
|
+
scrollInfo: (t) => colors.gray(t),
|
|
42
|
+
noMatch: (t) => colors.yellow(t),
|
|
43
|
+
});
|
|
44
|
+
this.promptList.onSelect = (item) => {
|
|
45
|
+
this.promptActive = false;
|
|
46
|
+
this.promptList = undefined;
|
|
47
|
+
this.cachedRender = undefined;
|
|
48
|
+
this.tui.requestRender();
|
|
49
|
+
resolve(item.value === "yes");
|
|
50
|
+
};
|
|
51
|
+
this.promptList.onCancel = () => {
|
|
52
|
+
this.promptActive = false;
|
|
53
|
+
this.promptList = undefined;
|
|
54
|
+
this.cachedRender = undefined;
|
|
55
|
+
this.tui.requestRender();
|
|
56
|
+
resolve(false);
|
|
57
|
+
};
|
|
58
|
+
this.cachedRender = undefined;
|
|
59
|
+
this.tui.requestRender();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
handleInput(data) {
|
|
63
|
+
if (this.promptActive && this.promptList) {
|
|
64
|
+
this.promptList.handleInput(data);
|
|
65
|
+
this.cachedRender = undefined;
|
|
66
|
+
this.tui.requestRender();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
render(width) {
|
|
70
|
+
if (this.cachedRender)
|
|
71
|
+
return this.cachedRender;
|
|
72
|
+
const lines = [];
|
|
73
|
+
// Steps
|
|
74
|
+
for (let si = 0; si < this.steps.length; si++) {
|
|
75
|
+
const step = this.steps[si];
|
|
76
|
+
let icon;
|
|
77
|
+
let line;
|
|
78
|
+
switch (step.status) {
|
|
79
|
+
case "pending":
|
|
80
|
+
icon = colors.gray("○");
|
|
81
|
+
line = colors.gray(step.label);
|
|
82
|
+
break;
|
|
83
|
+
case "running":
|
|
84
|
+
icon = colors.cyan("◉");
|
|
85
|
+
line = colors.cyan(step.label + "...");
|
|
86
|
+
break;
|
|
87
|
+
case "done":
|
|
88
|
+
icon = colors.green("✓");
|
|
89
|
+
line = colors.green(step.label);
|
|
90
|
+
break;
|
|
91
|
+
case "failed":
|
|
92
|
+
icon = colors.red("✗");
|
|
93
|
+
line = colors.red(step.label);
|
|
94
|
+
break;
|
|
95
|
+
case "skipped":
|
|
96
|
+
icon = colors.yellow("⊘");
|
|
97
|
+
line = colors.yellow(step.label);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
lines.push(truncateToWidth(` ${icon} ${line}`, width));
|
|
101
|
+
if (step.detail) {
|
|
102
|
+
lines.push(truncateToWidth(` ${colors.gray(step.detail)}`, width));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Prompt
|
|
106
|
+
if (this.promptActive && this.promptList) {
|
|
107
|
+
lines.push("");
|
|
108
|
+
lines.push(truncateToWidth(` ${colors.bold(this.promptText)}`, width));
|
|
109
|
+
lines.push("");
|
|
110
|
+
for (const pLine of this.promptList.render(width - 2)) {
|
|
111
|
+
lines.push(truncateToWidth(` ${pLine}`, width));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
this.cachedRender = lines;
|
|
115
|
+
return lines;
|
|
116
|
+
}
|
|
117
|
+
invalidate() {
|
|
118
|
+
this.cachedRender = undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Container } from "@mariozechner/pi-tui";
|
|
2
|
+
import type { Model, Api } from "@mariozechner/pi-ai";
|
|
3
|
+
export interface StatusInfo {
|
|
4
|
+
loggedIn: boolean;
|
|
5
|
+
model: Model<Api> | undefined;
|
|
6
|
+
agentCount: number;
|
|
7
|
+
serverUrl: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class StatusPanel extends Container {
|
|
10
|
+
private info;
|
|
11
|
+
constructor(info: StatusInfo);
|
|
12
|
+
update(info: Partial<StatusInfo>): void;
|
|
13
|
+
private rebuild;
|
|
14
|
+
invalidate(): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Container, Text } from "@mariozechner/pi-tui";
|
|
2
|
+
import { colors, theme } from "../theme.js";
|
|
3
|
+
export class StatusPanel extends Container {
|
|
4
|
+
info;
|
|
5
|
+
constructor(info) {
|
|
6
|
+
super();
|
|
7
|
+
this.info = info;
|
|
8
|
+
this.rebuild();
|
|
9
|
+
}
|
|
10
|
+
update(info) {
|
|
11
|
+
Object.assign(this.info, info);
|
|
12
|
+
this.rebuild();
|
|
13
|
+
}
|
|
14
|
+
rebuild() {
|
|
15
|
+
this.clear();
|
|
16
|
+
const line = (label, value, ok) => {
|
|
17
|
+
const icon = ok ? colors.green("✓") : colors.red("✗");
|
|
18
|
+
const labelStr = colors.gray(label.padEnd(10));
|
|
19
|
+
return ` ${icon} ${labelStr} ${value}`;
|
|
20
|
+
};
|
|
21
|
+
this.addChild(new Text(theme.border("─".repeat(50)), 0, 0));
|
|
22
|
+
this.addChild(new Text(line("Auth", this.info.loggedIn ? "logged in" : "not logged in", this.info.loggedIn), 0, 0));
|
|
23
|
+
this.addChild(new Text(line("Model", this.info.model
|
|
24
|
+
? `${this.info.model.provider}/${this.info.model.id}`
|
|
25
|
+
: "(not detected)", !!this.info.model), 0, 0));
|
|
26
|
+
const agentStr = this.info.agentCount === 0
|
|
27
|
+
? "none — create one in Manage agents"
|
|
28
|
+
: `${this.info.agentCount} agent${this.info.agentCount === 1 ? "" : "s"}`;
|
|
29
|
+
this.addChild(new Text(line("Agents", agentStr, this.info.agentCount > 0), 0, 0));
|
|
30
|
+
this.addChild(new Text(line("Server", this.info.serverUrl, true), 0, 0));
|
|
31
|
+
this.addChild(new Text(theme.border("─".repeat(50)), 0, 0));
|
|
32
|
+
}
|
|
33
|
+
invalidate() {
|
|
34
|
+
super.invalidate();
|
|
35
|
+
this.rebuild();
|
|
36
|
+
}
|
|
37
|
+
}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export declare const colors: {
|
|
2
|
+
reset: string;
|
|
3
|
+
bold: (s: string) => string;
|
|
4
|
+
dim: (s: string) => string;
|
|
5
|
+
italic: (s: string) => string;
|
|
6
|
+
cyan: (s: string) => string;
|
|
7
|
+
green: (s: string) => string;
|
|
8
|
+
red: (s: string) => string;
|
|
9
|
+
yellow: (s: string) => string;
|
|
10
|
+
magenta: (s: string) => string;
|
|
11
|
+
blue: (s: string) => string;
|
|
12
|
+
white: (s: string) => string;
|
|
13
|
+
gray: (s: string) => string;
|
|
14
|
+
brightCyan: (s: string) => string;
|
|
15
|
+
brightGreen: (s: string) => string;
|
|
16
|
+
brightYellow: (s: string) => string;
|
|
17
|
+
brightWhite: (s: string) => string;
|
|
18
|
+
lime: (s: string) => string;
|
|
19
|
+
limeBold: (s: string) => string;
|
|
20
|
+
bgLime: (s: string) => string;
|
|
21
|
+
bgGray: (s: string) => string;
|
|
22
|
+
bgCyan: (s: string) => string;
|
|
23
|
+
bgBlue: (s: string) => string;
|
|
24
|
+
inverse: (s: string) => string;
|
|
25
|
+
};
|
|
26
|
+
export declare const theme: {
|
|
27
|
+
accent: (s: string) => string;
|
|
28
|
+
success: (s: string) => string;
|
|
29
|
+
error: (s: string) => string;
|
|
30
|
+
warning: (s: string) => string;
|
|
31
|
+
muted: (s: string) => string;
|
|
32
|
+
highlight: (s: string) => string;
|
|
33
|
+
border: (s: string) => string;
|
|
34
|
+
title: (s: string) => string;
|
|
35
|
+
subtitle: (s: string) => string;
|
|
36
|
+
status: {
|
|
37
|
+
ok: (s: string) => string;
|
|
38
|
+
fail: (s: string) => string;
|
|
39
|
+
warn: (s: string) => string;
|
|
40
|
+
info: (s: string) => string;
|
|
41
|
+
};
|
|
42
|
+
};
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// ANSI color helpers for standalone TUI (no pi theme system)
|
|
2
|
+
const ESC = "\x1b[";
|
|
3
|
+
// Logo color: #C8F135 (RGB 200, 241, 53) — lime green from the Swarmlancer logo
|
|
4
|
+
const LIME_FG = `${ESC}38;2;200;241;53m`;
|
|
5
|
+
const LIME_BG = `${ESC}48;2;200;241;53m`;
|
|
6
|
+
const DARK_FG = `${ESC}38;2;26;26;26m`;
|
|
7
|
+
const RESET = `${ESC}0m`;
|
|
8
|
+
export const colors = {
|
|
9
|
+
reset: `${ESC}0m`,
|
|
10
|
+
// Foreground
|
|
11
|
+
bold: (s) => `${ESC}1m${s}${ESC}22m`,
|
|
12
|
+
dim: (s) => `${ESC}2m${s}${ESC}22m`,
|
|
13
|
+
italic: (s) => `${ESC}3m${s}${ESC}23m`,
|
|
14
|
+
// Named colors
|
|
15
|
+
cyan: (s) => `${ESC}36m${s}${ESC}39m`,
|
|
16
|
+
green: (s) => `${ESC}32m${s}${ESC}39m`,
|
|
17
|
+
red: (s) => `${ESC}31m${s}${ESC}39m`,
|
|
18
|
+
yellow: (s) => `${ESC}33m${s}${ESC}39m`,
|
|
19
|
+
magenta: (s) => `${ESC}35m${s}${ESC}39m`,
|
|
20
|
+
blue: (s) => `${ESC}34m${s}${ESC}39m`,
|
|
21
|
+
white: (s) => `${ESC}37m${s}${ESC}39m`,
|
|
22
|
+
gray: (s) => `${ESC}90m${s}${ESC}39m`,
|
|
23
|
+
// Bright
|
|
24
|
+
brightCyan: (s) => `${ESC}96m${s}${ESC}39m`,
|
|
25
|
+
brightGreen: (s) => `${ESC}92m${s}${ESC}39m`,
|
|
26
|
+
brightYellow: (s) => `${ESC}93m${s}${ESC}39m`,
|
|
27
|
+
brightWhite: (s) => `${ESC}97m${s}${ESC}39m`,
|
|
28
|
+
// Logo lime green — #C8F135
|
|
29
|
+
lime: (s) => `${LIME_FG}${s}${ESC}39m`,
|
|
30
|
+
limeBold: (s) => `${LIME_FG}${ESC}1m${s}${ESC}22m${ESC}39m`,
|
|
31
|
+
bgLime: (s) => `${LIME_BG}${DARK_FG}${s}${RESET}`,
|
|
32
|
+
// Background
|
|
33
|
+
bgGray: (s) => `${ESC}48;5;236m${s}${ESC}49m`,
|
|
34
|
+
bgCyan: (s) => `${ESC}46m${s}${ESC}49m`,
|
|
35
|
+
bgBlue: (s) => `${ESC}44m${s}${ESC}49m`,
|
|
36
|
+
// Inverse
|
|
37
|
+
inverse: (s) => `${ESC}7m${s}${ESC}27m`,
|
|
38
|
+
};
|
|
39
|
+
// Semantic aliases — accent is now the logo lime green
|
|
40
|
+
export const theme = {
|
|
41
|
+
accent: colors.lime,
|
|
42
|
+
success: colors.green,
|
|
43
|
+
error: colors.red,
|
|
44
|
+
warning: colors.yellow,
|
|
45
|
+
muted: colors.gray,
|
|
46
|
+
highlight: colors.limeBold,
|
|
47
|
+
border: colors.lime,
|
|
48
|
+
title: (s) => colors.bold(colors.lime(s)),
|
|
49
|
+
subtitle: (s) => colors.bold(colors.white(s)),
|
|
50
|
+
status: {
|
|
51
|
+
ok: (s) => colors.green(`✓ ${s}`),
|
|
52
|
+
fail: (s) => colors.red(`✗ ${s}`),
|
|
53
|
+
warn: (s) => colors.yellow(`⚠ ${s}`),
|
|
54
|
+
info: (s) => colors.lime(`▸ ${s}`),
|
|
55
|
+
},
|
|
56
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "swarmlancer-cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Swarmlancer CLI — let the swarm begin. Connect your AI agent to a network of other agents.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"swarmlancer": "dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc -p tsconfig.build.json",
|
|
16
|
+
"prepublishOnly": "rm -rf dist && npm run build",
|
|
17
|
+
"start": "bun run src/index.ts start",
|
|
18
|
+
"dev": "bun run src/index.ts"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"ai",
|
|
22
|
+
"agent",
|
|
23
|
+
"networking",
|
|
24
|
+
"cli",
|
|
25
|
+
"llm",
|
|
26
|
+
"autonomous"
|
|
27
|
+
],
|
|
28
|
+
"author": "nevertypeit",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/nevertypeit/swarmlancer-cli"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://swarmlancer.com",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^25.5.0",
|
|
40
|
+
"@types/ws": "^8.18.1",
|
|
41
|
+
"typescript": "^5.8.0"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@mariozechner/pi-coding-agent": "^0.58.4",
|
|
45
|
+
"@mariozechner/pi-tui": "^0.58.4",
|
|
46
|
+
"open": "^11.0.0",
|
|
47
|
+
"ws": "^8.19.0"
|
|
48
|
+
}
|
|
49
|
+
}
|