@kisev/skills-opencode 2.2.3 → 2.3.1
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 +31 -204
- package/README.ru.md +31 -205
- package/dist/agent-profiles.js +5 -5
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.js +2 -1
- package/dist/cli-output.js +4 -3
- package/dist/cli.js +421 -20
- package/dist/doctor.js +2 -10
- package/dist/installer.js +4 -3
- package/dist/package-metadata.d.ts +4 -0
- package/dist/package-metadata.js +42 -0
- package/dist/registry.js +2 -1
- package/dist/terminal-wizard.d.ts +1 -0
- package/dist/terminal-wizard.js +120 -8
- package/package.json +2 -1
package/dist/terminal-wizard.js
CHANGED
|
@@ -3,22 +3,41 @@ function parseKey(buffer) {
|
|
|
3
3
|
const seq = buffer.toString();
|
|
4
4
|
if (seq === "\r" || seq === "\n")
|
|
5
5
|
return { name: "return", sequence: seq };
|
|
6
|
+
if (seq === " ")
|
|
7
|
+
return { name: "space", sequence: seq };
|
|
8
|
+
if (seq === "a" || seq === "A")
|
|
9
|
+
return { name: "all", sequence: seq };
|
|
10
|
+
if (seq === "n" || seq === "N")
|
|
11
|
+
return { name: "none", sequence: seq };
|
|
6
12
|
if (seq === "\x03")
|
|
7
13
|
return { name: "ctrl+c", sequence: seq };
|
|
8
14
|
if (seq === "\x04")
|
|
9
15
|
return { name: "ctrl+d", sequence: seq };
|
|
10
16
|
if (seq === "\x1b" || seq === "\x1b\x1b" || seq === "\x1b\x1b\x1b")
|
|
11
17
|
return { name: "escape", sequence: seq };
|
|
12
|
-
if (seq === "\x1b[A" || seq === "\x1b[OA")
|
|
18
|
+
if (seq === "\x1b[A" || seq === "\x1bOA" || seq === "\x1b[OA")
|
|
13
19
|
return { name: "up", sequence: seq };
|
|
14
|
-
if (seq === "\x1b[B" || seq === "\x1b[OB")
|
|
20
|
+
if (seq === "\x1b[B" || seq === "\x1bOB" || seq === "\x1b[OB")
|
|
15
21
|
return { name: "down", sequence: seq };
|
|
16
|
-
if (seq === "\x1b[C" || seq === "\x1b[OC")
|
|
22
|
+
if (seq === "\x1b[C" || seq === "\x1bOC" || seq === "\x1b[OC")
|
|
17
23
|
return { name: "right", sequence: seq };
|
|
18
|
-
if (seq === "\x1b[D" || seq === "\x1b[OD")
|
|
24
|
+
if (seq === "\x1b[D" || seq === "\x1bOD" || seq === "\x1b[OD")
|
|
19
25
|
return { name: "left", sequence: seq };
|
|
20
26
|
return { name: "unknown", sequence: seq };
|
|
21
27
|
}
|
|
28
|
+
function nextSequence(remaining) {
|
|
29
|
+
if (remaining.startsWith("\x1b[O"))
|
|
30
|
+
return remaining.slice(0, 4);
|
|
31
|
+
if (remaining.startsWith("\x1b[") || remaining.startsWith("\x1bO"))
|
|
32
|
+
return remaining.slice(0, 3);
|
|
33
|
+
return remaining[0];
|
|
34
|
+
}
|
|
35
|
+
function validateOptions(options) {
|
|
36
|
+
if (options.length === 0)
|
|
37
|
+
throw new InstallerError("invalid_input", "Interactive selector requires at least one option");
|
|
38
|
+
if (new Set(options).size !== options.length)
|
|
39
|
+
throw new InstallerError("invalid_input", "Interactive selector options must be unique");
|
|
40
|
+
}
|
|
22
41
|
function clearLines(stderr, count) {
|
|
23
42
|
for (let i = 0; i < count; i++) {
|
|
24
43
|
stderr.write("\x1b[A\x1b[K");
|
|
@@ -28,10 +47,12 @@ export async function selectOption(label, options, stdin = process.stdin, stderr
|
|
|
28
47
|
if (!stdin.isTTY || !stderr.isTTY) {
|
|
29
48
|
throw new InstallerError("terminal_required", "This operation requires an interactive terminal");
|
|
30
49
|
}
|
|
50
|
+
validateOptions(options);
|
|
31
51
|
let selected = Math.max(0, Math.min(initial, options.length - 1));
|
|
32
|
-
const lineCount = options.length +
|
|
52
|
+
const lineCount = options.length + 2;
|
|
33
53
|
function render() {
|
|
34
|
-
stderr.write(
|
|
54
|
+
stderr.write(`? ${label}\n`);
|
|
55
|
+
stderr.write(" Up/Down move | Enter select | Esc cancel\n");
|
|
35
56
|
for (let i = 0; i < options.length; i++) {
|
|
36
57
|
const cursor = i === selected ? "> " : " ";
|
|
37
58
|
stderr.write(`${cursor}${options[i]}\n`);
|
|
@@ -49,7 +70,7 @@ export async function selectOption(label, options, stdin = process.stdin, stderr
|
|
|
49
70
|
function onData(data) {
|
|
50
71
|
let remaining = data.toString();
|
|
51
72
|
while (remaining) {
|
|
52
|
-
const sequence =
|
|
73
|
+
const sequence = nextSequence(remaining);
|
|
53
74
|
remaining = remaining.slice(sequence.length);
|
|
54
75
|
const key = parseKey(Buffer.from(sequence));
|
|
55
76
|
if (key.name === "ctrl+c" || key.name === "ctrl+d" || key.name === "escape") {
|
|
@@ -79,11 +100,102 @@ export async function selectOption(label, options, stdin = process.stdin, stderr
|
|
|
79
100
|
stdin.on("data", onData);
|
|
80
101
|
});
|
|
81
102
|
}
|
|
103
|
+
export async function selectOptions(label, options, initialSelected = [], stdin = process.stdin, stderr = process.stderr) {
|
|
104
|
+
if (!stdin.isTTY || !stderr.isTTY) {
|
|
105
|
+
throw new InstallerError("terminal_required", "This operation requires an interactive terminal");
|
|
106
|
+
}
|
|
107
|
+
validateOptions(options);
|
|
108
|
+
const allowed = new Set(options);
|
|
109
|
+
for (const value of initialSelected) {
|
|
110
|
+
if (!allowed.has(value))
|
|
111
|
+
throw new InstallerError("invalid_input", `Unknown initial selector option: ${value}`);
|
|
112
|
+
}
|
|
113
|
+
const selected = new Set(initialSelected);
|
|
114
|
+
let active = 0;
|
|
115
|
+
const lineCount = options.length + 3;
|
|
116
|
+
function render() {
|
|
117
|
+
stderr.write(`? ${label}\n`);
|
|
118
|
+
stderr.write(" Up/Down move | Space toggle | A all | N none | Enter confirm | Esc cancel\n");
|
|
119
|
+
for (let index = 0; index < options.length; index += 1) {
|
|
120
|
+
const cursor = index === active ? "> " : " ";
|
|
121
|
+
const marker = selected.has(options[index]) ? "[x]" : "[ ]";
|
|
122
|
+
stderr.write(`${cursor}${marker} ${options[index]}\n`);
|
|
123
|
+
}
|
|
124
|
+
stderr.write(` Selected ${selected.size}/${options.length}\n`);
|
|
125
|
+
}
|
|
126
|
+
render();
|
|
127
|
+
return new Promise((resolve) => {
|
|
128
|
+
stdin.setRawMode(true);
|
|
129
|
+
stdin.resume();
|
|
130
|
+
function cleanup() {
|
|
131
|
+
stdin.setRawMode(false);
|
|
132
|
+
stdin.pause();
|
|
133
|
+
stdin.removeListener("data", onData);
|
|
134
|
+
}
|
|
135
|
+
function finish(value) {
|
|
136
|
+
cleanup();
|
|
137
|
+
clearLines(stderr, lineCount);
|
|
138
|
+
resolve(value);
|
|
139
|
+
}
|
|
140
|
+
function redraw(update) {
|
|
141
|
+
clearLines(stderr, lineCount);
|
|
142
|
+
update();
|
|
143
|
+
render();
|
|
144
|
+
}
|
|
145
|
+
function onData(data) {
|
|
146
|
+
let remaining = data.toString();
|
|
147
|
+
while (remaining) {
|
|
148
|
+
const sequence = nextSequence(remaining);
|
|
149
|
+
remaining = remaining.slice(sequence.length);
|
|
150
|
+
const key = parseKey(Buffer.from(sequence));
|
|
151
|
+
if (key.name === "ctrl+c" || key.name === "ctrl+d" || key.name === "escape") {
|
|
152
|
+
finish(null);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (key.name === "return") {
|
|
156
|
+
finish(options.filter((option) => selected.has(option)));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (key.name === "up") {
|
|
160
|
+
redraw(() => {
|
|
161
|
+
active = (active - 1 + options.length) % options.length;
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
else if (key.name === "down") {
|
|
165
|
+
redraw(() => {
|
|
166
|
+
active = (active + 1) % options.length;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
else if (key.name === "space") {
|
|
170
|
+
redraw(() => {
|
|
171
|
+
const option = options[active];
|
|
172
|
+
if (selected.has(option))
|
|
173
|
+
selected.delete(option);
|
|
174
|
+
else
|
|
175
|
+
selected.add(option);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
else if (key.name === "all") {
|
|
179
|
+
redraw(() => {
|
|
180
|
+
for (const option of options)
|
|
181
|
+
selected.add(option);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
else if (key.name === "none") {
|
|
185
|
+
redraw(() => selected.clear());
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
stdin.on("data", onData);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
82
192
|
export async function promptText(label, stdin = process.stdin, stderr = process.stderr) {
|
|
83
193
|
if (!stdin.isTTY || !stderr.isTTY) {
|
|
84
194
|
throw new InstallerError("terminal_required", "This operation requires an interactive terminal");
|
|
85
195
|
}
|
|
86
|
-
stderr.write(
|
|
196
|
+
stderr.write(`? ${label}\n`);
|
|
197
|
+
stderr.write(" Type a value | Enter confirm | Esc cancel\n");
|
|
198
|
+
stderr.write("> ");
|
|
87
199
|
return new Promise((resolve) => {
|
|
88
200
|
let buffer = "";
|
|
89
201
|
stdin.setRawMode(true);
|
package/package.json
CHANGED