lazyclaw 3.99.4 → 3.99.5
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/cli.mjs +65 -6
- package/package.json +1 -1
- package/providers/registry.mjs +10 -5
package/cli.mjs
CHANGED
|
@@ -1457,10 +1457,10 @@ async function _pickProviderInteractive() {
|
|
|
1457
1457
|
});
|
|
1458
1458
|
return { provider: ans || providers[0], model: null };
|
|
1459
1459
|
}
|
|
1460
|
-
// Default cursor:
|
|
1461
|
-
//
|
|
1462
|
-
|
|
1463
|
-
|
|
1460
|
+
// Default cursor: lands on item 0 (= the first row from PROVIDERS
|
|
1461
|
+
// insertion order, which registry.mjs deliberately curates as the
|
|
1462
|
+
// most user-familiar vendor — gemini at the time of writing).
|
|
1463
|
+
let idx = 0;
|
|
1464
1464
|
|
|
1465
1465
|
const readline = await import('node:readline');
|
|
1466
1466
|
readline.emitKeypressEvents(process.stdin);
|
|
@@ -3082,10 +3082,69 @@ function parseArgs(argv) {
|
|
|
3082
3082
|
// so chat / agent / etc. behave bit-identically to typing them
|
|
3083
3083
|
// directly. Non-TTY (piped, scripted) callers still see the
|
|
3084
3084
|
// classic "Usage: …" line so automation isn't surprised.
|
|
3085
|
+
// First-run welcome panel + delegated onboard. Drawn once before the
|
|
3086
|
+
// main launcher menu when the config has no provider yet. Walks the
|
|
3087
|
+
// user through the same arrow-key picker that `lazyclaw onboard`
|
|
3088
|
+
// uses; on success the launcher continues, on cancel the launcher
|
|
3089
|
+
// exits politely instead of dropping into a menu where every option
|
|
3090
|
+
// would error.
|
|
3091
|
+
async function _runFirstTimeOnboard() {
|
|
3092
|
+
const accent = (s) => `\x1b[38;5;208m${s}\x1b[0m`;
|
|
3093
|
+
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
3094
|
+
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
3095
|
+
process.stdout.write('\x1b[2J\x1b[H');
|
|
3096
|
+
const banner = [
|
|
3097
|
+
accent(' ╭──────────────────────────────╮'),
|
|
3098
|
+
accent(' │ _ │'),
|
|
3099
|
+
accent(' │ | |__ _ _____ _ _ │'),
|
|
3100
|
+
accent(' │ | / _` |_ / || | \'_| │'),
|
|
3101
|
+
accent(' │ |_\\__,_/__\\_, |_| │'),
|
|
3102
|
+
accent(' │ LazyClaw |__/ ' + (readVersionFromRepo() || '').padEnd(10) + ' │'),
|
|
3103
|
+
accent(' ╰──────────────────────────────╯'),
|
|
3104
|
+
];
|
|
3105
|
+
banner.forEach((l) => process.stdout.write(l + '\n'));
|
|
3106
|
+
process.stdout.write('\n');
|
|
3107
|
+
process.stdout.write(` ${bold('👋 Welcome — first-time setup')}\n\n`);
|
|
3108
|
+
process.stdout.write(` ${dim('No provider configured yet at')} ${configPath()}\n`);
|
|
3109
|
+
process.stdout.write(` ${dim('Pick a provider + model below; LazyClaw stores it in ~/.lazyclaw/config.json.')}\n\n`);
|
|
3110
|
+
process.stdout.write(` ${dim('Quick rule of thumb:')}\n`);
|
|
3111
|
+
process.stdout.write(` ${dim(' · gemini / openai / anthropic — need an API key (sk-... / paste during setup)')}\n`);
|
|
3112
|
+
process.stdout.write(` ${dim(' · claude-cli / ollama — keyless (use your existing Claude Code login or local Ollama)')}\n`);
|
|
3113
|
+
process.stdout.write(` ${dim(' · mock — offline echo, only useful for testing')}\n\n`);
|
|
3114
|
+
process.stdout.write(` ${dim('Press Enter to open the picker · Ctrl+C to abort.')}\n`);
|
|
3115
|
+
await _quickPrompt(' ▶ ');
|
|
3116
|
+
// Delegate to the real onboard flow with --pick so the picker UI
|
|
3117
|
+
// fires regardless of how this entry point was reached. cmdOnboard
|
|
3118
|
+
// owns config writing.
|
|
3119
|
+
try {
|
|
3120
|
+
await cmdOnboard({ pick: true });
|
|
3121
|
+
} catch (e) {
|
|
3122
|
+
process.stderr.write(`onboard error: ${e?.message || e}\n`);
|
|
3123
|
+
}
|
|
3124
|
+
process.stdout.write('\n');
|
|
3125
|
+
}
|
|
3126
|
+
|
|
3085
3127
|
async function cmdLauncher() {
|
|
3086
3128
|
await ensureRegistry();
|
|
3087
|
-
|
|
3088
|
-
|
|
3129
|
+
let cfg = readConfig();
|
|
3130
|
+
// First-run guard: a fresh install has no `provider` set, so any
|
|
3131
|
+
// menu pick that calls a provider (Chat / Agent / Doctor / etc.)
|
|
3132
|
+
// would error halfway through with a confusing "missing api key"
|
|
3133
|
+
// or "unknown provider". Detect that state up front and walk the
|
|
3134
|
+
// user through onboard before showing the menu — once they've
|
|
3135
|
+
// picked, re-read the config and continue normally.
|
|
3136
|
+
if (!cfg.provider) {
|
|
3137
|
+
await _runFirstTimeOnboard();
|
|
3138
|
+
cfg = readConfig();
|
|
3139
|
+
// If they cancelled / aborted onboard we still don't have a
|
|
3140
|
+
// provider — drop straight out instead of showing a menu where
|
|
3141
|
+
// every item leads to the same error.
|
|
3142
|
+
if (!cfg.provider) {
|
|
3143
|
+
process.stdout.write('\n Setup not completed — exiting.\n Run `lazyclaw onboard` when ready, then try `lazyclaw` again.\n\n');
|
|
3144
|
+
process.exit(0);
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
3147
|
+
const provider = cfg.provider;
|
|
3089
3148
|
const model = cfg.model || '(default)';
|
|
3090
3149
|
const items = [
|
|
3091
3150
|
{ id: 'chat', label: 'Chat', desc: 'interactive REPL with the configured provider', argv: ['chat'] },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lazyclaw",
|
|
3
|
-
"version": "3.99.
|
|
3
|
+
"version": "3.99.5",
|
|
4
4
|
"description": "Lazy, elegant terminal CLI for chatting with Claude / OpenAI / Gemini / Ollama and orchestrating multi-step LLM workflows. Banner-on-launch, slash-command ghost autocomplete, persistent sessions, local HTTP gateway.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
package/providers/registry.mjs
CHANGED
|
@@ -50,15 +50,20 @@ export const mockProvider = {
|
|
|
50
50
|
|
|
51
51
|
export { anthropicProvider, openaiProvider, ollamaProvider, geminiProvider, claudeCliProvider };
|
|
52
52
|
|
|
53
|
+
// Insertion order is the picker order. The list goes first-to-last in
|
|
54
|
+
// rough "user-familiar / popular" order so a first-time onboard lands
|
|
55
|
+
// the cursor on a vendor most users recognise. v3.99.5 reordered per
|
|
56
|
+
// user feedback ("gemini, codex 이런거 먼저 나오게끔").
|
|
53
57
|
export const PROVIDERS = {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
//
|
|
58
|
+
// Tier 1 — popular / brand-name vendors users come in looking for.
|
|
59
|
+
gemini: geminiProvider,
|
|
60
|
+
openai: openaiProvider, // surfaces gpt-5-codex / gpt-5 / o3-pro etc.
|
|
61
|
+
// Tier 2 — Claude. CLI variant first because it's keyless.
|
|
57
62
|
'claude-cli': claudeCliProvider,
|
|
58
63
|
anthropic: anthropicProvider,
|
|
59
|
-
|
|
60
|
-
gemini: geminiProvider,
|
|
64
|
+
// Tier 3 — local + dev/test.
|
|
61
65
|
ollama: ollamaProvider,
|
|
66
|
+
mock: mockProvider,
|
|
62
67
|
};
|
|
63
68
|
|
|
64
69
|
// Static metadata for `lazyclaw providers list/info`. Kept next to PROVIDERS
|