noiton 1.0.0 โ 2.0.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 +46 -31
- package/package.json +25 -8
- package/src/commands/change.js +44 -54
- package/src/commands/init.js +266 -43
- package/src/commands/refresh.js +59 -47
- package/src/commands/remove.js +46 -22
- package/src/commands/status.js +58 -31
- package/src/constants.js +31 -17
- package/src/index.js +21 -10
- package/src/lib/agents/aider.js +141 -0
- package/src/lib/agents/cline.js +128 -0
- package/src/lib/agents/hermes.js +156 -0
- package/src/lib/agents/index.js +82 -0
- package/src/lib/agents/kilo.js +140 -0
- package/src/lib/agents/kimi.js +149 -0
- package/src/lib/agents/openclaw.js +155 -0
- package/src/lib/agents/opencode.js +177 -0
- package/src/lib/detect.js +286 -0
- package/src/lib/install.js +210 -0
- package/src/messages.js +169 -0
- package/src/octopus.js +272 -0
- package/src/ui.js +196 -0
package/src/ui.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NOITON UI - visual helpers for the terminal
|
|
3
|
+
*
|
|
4
|
+
* Provides: banner, boxes, spinners, progress, dividers, status lines.
|
|
5
|
+
* Uses picocolors (lightweight) + ora (spinners) + boxen (boxes).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import picocolors from "picocolors";
|
|
9
|
+
import ora from "ora";
|
|
10
|
+
import boxen from "boxen";
|
|
11
|
+
import { VERSION, c } from "./constants.js";
|
|
12
|
+
import { octopusHappy, octopusCurious, octopusDancing, octopusSad, octopusSleeping, octopusWorking, octopusLogo, brandGradient } from "./octopus.js";
|
|
13
|
+
|
|
14
|
+
// ============= BANNER =============
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Print the main NOITON banner with octopus mascot.
|
|
18
|
+
* @param {"happy"|"curious"|"dancing"|"sad"|"sleeping"|"working"} mood
|
|
19
|
+
*/
|
|
20
|
+
export function printBanner(mood = "happy") {
|
|
21
|
+
const octopus = {
|
|
22
|
+
happy: octopusHappy,
|
|
23
|
+
curious: octopusCurious,
|
|
24
|
+
dancing: octopusDancing,
|
|
25
|
+
sad: octopusSad,
|
|
26
|
+
sleeping: octopusSleeping,
|
|
27
|
+
working: octopusWorking,
|
|
28
|
+
}[mood] || octopusHappy;
|
|
29
|
+
|
|
30
|
+
console.log();
|
|
31
|
+
console.log(octopus());
|
|
32
|
+
console.log(brandGradient(` N O I T O N v${VERSION}`));
|
|
33
|
+
console.log(c.dim(` ๐ Universal AI Agent Connector ๐`));
|
|
34
|
+
console.log();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ============= BOXES =============
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Print a message inside a colored box.
|
|
41
|
+
* @param {string} text
|
|
42
|
+
* @param {"info"|"success"|"warning"|"error"|"purple"} style
|
|
43
|
+
*/
|
|
44
|
+
export function box(text, style = "info") {
|
|
45
|
+
const styles = {
|
|
46
|
+
info: { borderColor: "cyan", title: " โน๏ธ " },
|
|
47
|
+
success: { borderColor: "green", title: " โ
" },
|
|
48
|
+
warning: { borderColor: "yellow", title: " โ ๏ธ " },
|
|
49
|
+
error: { borderColor: "red", title: " โ " },
|
|
50
|
+
purple: { borderColor: "magenta", title: " ๐ " },
|
|
51
|
+
};
|
|
52
|
+
const s = styles[style] || styles.info;
|
|
53
|
+
console.log(
|
|
54
|
+
boxen(text, {
|
|
55
|
+
padding: 1,
|
|
56
|
+
margin: { top: 0, bottom: 0, left: 2, right: 2 },
|
|
57
|
+
borderStyle: "round",
|
|
58
|
+
borderColor: s.borderColor,
|
|
59
|
+
title: s.title,
|
|
60
|
+
titleAlignment: "left",
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ============= SPINNER =============
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Create and start a spinner with a NOITON-flavored message.
|
|
69
|
+
* @param {string} text
|
|
70
|
+
* @returns {ora.Spinner} spinner instance
|
|
71
|
+
*/
|
|
72
|
+
export function spinner(text) {
|
|
73
|
+
return ora({
|
|
74
|
+
text,
|
|
75
|
+
spinner: "dots",
|
|
76
|
+
color: "magenta",
|
|
77
|
+
}).start();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ============= DIVIDER =============
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Print a horizontal divider line.
|
|
84
|
+
*/
|
|
85
|
+
export function divider(char = "โ", len = 56) {
|
|
86
|
+
console.log(c.gray(char.repeat(len)));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ============= STATUS LINES =============
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Print a success status line.
|
|
93
|
+
* @param {string} msg
|
|
94
|
+
*/
|
|
95
|
+
export function ok(msg) {
|
|
96
|
+
console.log(` ${c.green("โ")} ${msg}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Print a warning status line.
|
|
101
|
+
* @param {string} msg
|
|
102
|
+
*/
|
|
103
|
+
export function warn(msg) {
|
|
104
|
+
console.log(` ${c.yellow("โ ")} ${msg}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Print an error status line.
|
|
109
|
+
* @param {string} msg
|
|
110
|
+
*/
|
|
111
|
+
export function fail(msg) {
|
|
112
|
+
console.log(` ${c.red("โ")} ${msg}`);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Print an info status line.
|
|
117
|
+
* @param {string} msg
|
|
118
|
+
*/
|
|
119
|
+
export function info(msg) {
|
|
120
|
+
console.log(` ${c.cyan("โน")} ${msg}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Print a dim/secondary line.
|
|
125
|
+
* @param {string} msg
|
|
126
|
+
*/
|
|
127
|
+
export function dim(msg) {
|
|
128
|
+
console.log(` ${c.dim(msg)}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Print a step header.
|
|
133
|
+
* @param {number} n - step number
|
|
134
|
+
* @param {string} title
|
|
135
|
+
*/
|
|
136
|
+
export function step(n, title) {
|
|
137
|
+
console.log();
|
|
138
|
+
console.log(c.bold(c.purple(` โธ Passo ${n}: ${title}`)));
|
|
139
|
+
divider("ยท");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ============= CHECKLIST =============
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Print a checklist of items with check/cross marks.
|
|
146
|
+
* @param {Array<{label: string, ok: boolean, detail?: string}>} items
|
|
147
|
+
*/
|
|
148
|
+
export function checklist(items) {
|
|
149
|
+
for (const item of items) {
|
|
150
|
+
const mark = item.ok ? c.green("โ") : c.gray("โ");
|
|
151
|
+
const label = item.ok ? c.white(item.label) : c.gray(item.label);
|
|
152
|
+
const detail = item.detail ? c.dim(` ${item.detail}`) : "";
|
|
153
|
+
console.log(` ${mark} ${label}${detail}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ============= PROGRESS =============
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Run an async task with a spinner, then show success/fail.
|
|
161
|
+
* @param {string} message - spinner text
|
|
162
|
+
* @param {Function} fn - async function to run
|
|
163
|
+
* @param {string} successMsg - message on success
|
|
164
|
+
* @returns {Promise<any>} result of fn
|
|
165
|
+
*/
|
|
166
|
+
export async function withSpinner(message, fn, successMsg) {
|
|
167
|
+
const s = spinner(message);
|
|
168
|
+
try {
|
|
169
|
+
const result = await fn();
|
|
170
|
+
s.succeed(successMsg || message);
|
|
171
|
+
return result;
|
|
172
|
+
} catch (err) {
|
|
173
|
+
s.fail(`${message} - ${err.message}`);
|
|
174
|
+
throw err;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ============= CLEAR =============
|
|
179
|
+
|
|
180
|
+
export function clear() {
|
|
181
|
+
process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ============= HEADER (small) =============
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Print a small inline header (no octopus) for sub-commands.
|
|
188
|
+
*/
|
|
189
|
+
export function printHeader(title) {
|
|
190
|
+
console.log();
|
|
191
|
+
console.log(c.bold(c.purple(` ๐ NOITON `)) + c.dim(` v${VERSION} `));
|
|
192
|
+
console.log(c.gray(` ${"โ".repeat(title.length + 4)}`));
|
|
193
|
+
console.log(c.bold(` ${title}`));
|
|
194
|
+
console.log(c.gray(` ${"โ".repeat(title.length + 4)}`));
|
|
195
|
+
console.log();
|
|
196
|
+
}
|