zyrouter 0.1.3 → 0.1.4
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 +1 -1
- package/lib/main.mjs +5 -3
- package/lib/ui.mjs +8 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ to `~/.zyrouter/backups/`, writes the ZyRouter settings, and sends one small tes
|
|
|
11
11
|
|
|
12
12
|
| Tool | File it writes |
|
|
13
13
|
| --- | --- |
|
|
14
|
-
| Codex (CLI
|
|
14
|
+
| Codex (CLI, VS Code & App) | `~/.codex/config.toml` and the `ZYROUTER_API_KEY` user environment variable |
|
|
15
15
|
| Claude Code | `~/.claude/settings.json` |
|
|
16
16
|
| OpenCode | `~/.config/opencode/opencode.json` (key written in the file); an existing ZyRouter entry in `~/.local/share/opencode/auth.json` is updated too |
|
|
17
17
|
| OpenClaw | `~/.openclaw/openclaw.json` |
|
package/lib/main.mjs
CHANGED
|
@@ -42,7 +42,7 @@ function toolCatalog(ctx) {
|
|
|
42
42
|
return [
|
|
43
43
|
{
|
|
44
44
|
id: "codex",
|
|
45
|
-
name: "Codex (CLI
|
|
45
|
+
name: "Codex (CLI, VS Code & App)",
|
|
46
46
|
protocol: "responses",
|
|
47
47
|
// Many Codex users sign in with ChatGPT; switching it to ZyRouter must be picked, not pressed through with Enter.
|
|
48
48
|
optIn: true,
|
|
@@ -294,11 +294,13 @@ export async function run(argv, overrides = {}) {
|
|
|
294
294
|
const unknown = wanted.filter((id) => !tools.some((tool) => tool.id === id));
|
|
295
295
|
if (unknown.length) throw new Error(`Aplikasi tidak dikenal: ${unknown.join(", ")}. Pilihan: ${tools.map((tool) => tool.id).join(", ")}`);
|
|
296
296
|
} else if (canAsk && ctx.tty) {
|
|
297
|
+
// Nothing starts checked: a pre-checked app would be written instead of the one the cursor is on.
|
|
297
298
|
const ids = await pickFromMenu(ctx, {
|
|
298
299
|
title: "Pilih aplikasi yang mau diatur",
|
|
299
|
-
hint: "↑↓ pindah · spasi centang · a semua · enter lanjut",
|
|
300
|
+
hint: "↑↓ pindah · spasi centang banyak · a semua · enter lanjut",
|
|
300
301
|
multi: true,
|
|
301
|
-
|
|
302
|
+
initialValue: (preselected[0] || detected[0])?.id,
|
|
303
|
+
rows: tools.map((tool) => ({ label: tool.name, value: tool.id, note: toolNote(tool) })),
|
|
302
304
|
});
|
|
303
305
|
selected = tools.filter((tool) => ids.includes(tool.id));
|
|
304
306
|
} else if (canAsk) {
|
package/lib/ui.mjs
CHANGED
|
@@ -105,9 +105,14 @@ export async function readSecret(ctx, label) {
|
|
|
105
105
|
return result.trim();
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
/** What Enter applies in a multi menu: the checked rows, or the row under the cursor when none is checked. */
|
|
109
|
+
function multiMenuResult(items, checked, cursor) {
|
|
110
|
+
return checked.size ? items.filter((item) => checked.has(item.value)) : [items[cursor]];
|
|
111
|
+
}
|
|
112
|
+
|
|
108
113
|
/**
|
|
109
114
|
* Arrow-key menu. `rows` mixes { header } lines with { label, value, note, checked } items.
|
|
110
|
-
* Single choice returns a value; multi choice returns the checked values.
|
|
115
|
+
* Single choice returns a value; multi choice returns the checked values, or the highlighted one if none is checked.
|
|
111
116
|
*/
|
|
112
117
|
export async function pickFromMenu(ctx, { title, hint, rows, multi = false, initialValue }) {
|
|
113
118
|
const { style } = ctx;
|
|
@@ -137,6 +142,7 @@ export async function pickFromMenu(ctx, { title, hint, rows, multi = false, init
|
|
|
137
142
|
lines.push(` ${pointer} ${box}${label}${row.note ? ` ${style.gray(row.note)}` : ""}`);
|
|
138
143
|
}
|
|
139
144
|
if (start + height < rows.length) lines.push(style.gray(" ↓ lainnya"));
|
|
145
|
+
if (multi) lines.push(` ${style.gray("Enter akan mengatur:")} ${style.bold(multiMenuResult(items, checked, cursor).map((item) => item.label).join(", "))}`);
|
|
140
146
|
if (drawn) process.stdout.write(`\x1b[${drawn}A\x1b[0J`);
|
|
141
147
|
process.stdout.write(`${lines.join("\n")}\n`);
|
|
142
148
|
drawn = lines.length;
|
|
@@ -155,7 +161,7 @@ export async function pickFromMenu(ctx, { title, hint, rows, multi = false, init
|
|
|
155
161
|
if (checked.size === items.length) checked.clear();
|
|
156
162
|
else items.forEach((item) => checked.add(item.value));
|
|
157
163
|
} else if (key.name === "return" || key.name === "enter") {
|
|
158
|
-
return done(multi ? items
|
|
164
|
+
return done(multi ? multiMenuResult(items, checked, cursor).map((item) => item.value) : items[cursor].value);
|
|
159
165
|
}
|
|
160
166
|
render();
|
|
161
167
|
});
|