profclaw 0.0.1-beta.1 → 0.0.1-beta.2
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/dist/adapters/openclaw.js +1 -1
- package/dist/agents/executor.js +38 -6
- package/dist/auth/auth-service.js +8 -6
- package/dist/auth/device-identity.js +7 -5
- package/dist/auth/github-oauth.js +3 -1
- package/dist/auth/pairing-codes.js +6 -4
- package/dist/browser/service.js +5 -3
- package/dist/chat/execution/guardrails.js +3 -1
- package/dist/chat/execution/workflows/executor.js +4 -2
- package/dist/chat/memory.js +3 -1
- package/dist/chat/proactive/index.js +13 -11
- package/dist/chat/tools.js +8 -7
- package/dist/cli/commands/auth.js +22 -13
- package/dist/cli/commands/onboard.js +248 -59
- package/dist/cli/commands/setup.js +180 -104
- package/dist/cron/issue-poller.js +1 -1
- package/dist/hooks/agent-webhook.js +10 -7
- package/dist/hooks/prompt-submit.js +5 -6
- package/dist/hooks/session-end.js +10 -6
- package/dist/hooks/tool-use.js +9 -6
- package/dist/integrations/github-ticket-sync.js +8 -6
- package/dist/integrations/github.js +8 -6
- package/dist/integrations/jira.js +5 -3
- package/dist/mcp/server.js +12 -9
- package/dist/memory/experience-store.js +15 -14
- package/dist/notifications/slack.js +4 -2
- package/dist/providers/types.d.ts +2 -2
- package/dist/queue/failure-handler.js +15 -13
- package/dist/queue/index.js +6 -4
- package/dist/queue/memory-queue.js +23 -27
- package/dist/queue/task-queue.js +18 -22
- package/dist/routes/agents.js +3 -1
- package/dist/routes/auth.js +11 -9
- package/dist/routes/devices.js +17 -15
- package/dist/routes/gateway.js +3 -1
- package/dist/routes/hooks.js +7 -5
- package/dist/routes/import.js +10 -8
- package/dist/routes/labels.js +11 -9
- package/dist/routes/oobe.js +8 -6
- package/dist/routes/openapi.js +1 -1
- package/dist/routes/projects.js +27 -25
- package/dist/routes/settings.js +7 -5
- package/dist/routes/setup.js +12 -11
- package/dist/routes/slack.js +28 -27
- package/dist/routes/stats.js +6 -4
- package/dist/routes/summaries.js +4 -3
- package/dist/routes/sync.js +7 -5
- package/dist/routes/tasks.js +10 -8
- package/dist/routes/tickets.js +26 -26
- package/dist/routes/tokens.js +5 -3
- package/dist/routes/users.js +14 -12
- package/dist/routes/webhooks.js +5 -3
- package/dist/settings/index.js +3 -1
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.js +9 -4
- package/dist/storage/libsql.js +29 -21
- package/dist/storage/schema.d.ts +107 -46
- package/dist/summaries/storage.js +3 -1
- package/dist/tickets/index.js +10 -8
- package/dist/utils/circuit-breaker.js +10 -5
- package/dist/utils/logger.d.ts +5 -1
- package/dist/utils/logger.js +23 -7
- package/package.json +4 -3
- package/ui/dist/assets/{ActivityView-CkPgKhwm.js → ActivityView-DIPQSJ_d.js} +1 -1
- package/ui/dist/assets/{AgentList-C3SVdeEz.js → AgentList-CqyaYrcq.js} +1 -1
- package/ui/dist/assets/{AnalyticsDashboard-DVU--vlP.js → AnalyticsDashboard-C-mjuGHT.js} +1 -1
- package/ui/dist/assets/{AreaChart-B5qMEGWj.js → AreaChart-CfYWmbtr.js} +1 -1
- package/ui/dist/assets/{CartesianChart-B50bcUJi.js → CartesianChart-BaQ3It0c.js} +1 -1
- package/ui/dist/assets/{ChatView-BZFJs7w_.js → ChatView-DxxQy6pl.js} +1 -1
- package/ui/dist/assets/CostsDashboard-CDBBcGkg.js +1 -0
- package/ui/dist/assets/{EstimateSelect-CLpB4NQO.js → EstimateSelect-CDjf5qKl.js} +1 -1
- package/ui/dist/assets/{FloatingChatbot-CBzBY9a0.js → FloatingChatbot-CZHjvJIe.js} +1 -1
- package/ui/dist/assets/{InviteCodeManagement-DsbdPa6W.js → InviteCodeManagement-DTm-IPTm.js} +1 -1
- package/ui/dist/assets/{ProjectDetail-BEM3tFXg.js → ProjectDetail-DlYUcOss.js} +1 -1
- package/ui/dist/assets/{ProjectIcon-CN1FmFAk.js → ProjectIcon-BMRpnM04.js} +1 -1
- package/ui/dist/assets/{ProjectList-DSDaNhxQ.js → ProjectList-D85TN0i0.js} +1 -1
- package/ui/dist/assets/{Settings-dPVcqC_d.js → Settings-CgPqzUvj.js} +3 -3
- package/ui/dist/assets/{StatusIndicator-DA3NAo_b.js → StatusIndicator-yig0uZEA.js} +1 -1
- package/ui/dist/assets/{SummaryDetail-Bjnf9lT8.js → SummaryDetail-CwLAfHgJ.js} +1 -1
- package/ui/dist/assets/{SummaryList-ENwKDBKW.js → SummaryList-BvS5Idnu.js} +1 -1
- package/ui/dist/assets/{TaskDetail-DnwG6MzB.js → TaskDetail-zarC1fOt.js} +1 -1
- package/ui/dist/assets/{TaskList-D9Ug_HiV.js → TaskList-CyJq3ANE.js} +1 -1
- package/ui/dist/assets/{TicketBoard-CviH1571.js → TicketBoard-BlWr3-iH.js} +1 -1
- package/ui/dist/assets/{TicketDetail-8Jk8O-33.js → TicketDetail-DmqWKj2W.js} +1 -1
- package/ui/dist/assets/{TicketList-B-iV4rRA.js → TicketList-Scj4pMWa.js} +1 -1
- package/ui/dist/assets/{UserManagement-CPZ8s7s2.js → UserManagement-BH7uG7dw.js} +1 -1
- package/ui/dist/assets/{ViewSwitcher-BUyOOWDI.js → ViewSwitcher-3HzZUdWn.js} +1 -1
- package/ui/dist/assets/{alert-dialog-BOmnTkN-.js → alert-dialog-DWPb2IfQ.js} +1 -1
- package/ui/dist/assets/{archive-D5my9zOG.js → archive-CGck7gxR.js} +1 -1
- package/ui/dist/assets/{badge-B4ov81_m.js → badge-DEmc3Z_l.js} +1 -1
- package/ui/dist/assets/{brain-C53ElFLD.js → brain-CfFdLVqb.js} +1 -1
- package/ui/dist/assets/{bug-D0TJoCYn.js → bug-DqSGPUUE.js} +1 -1
- package/ui/dist/assets/{calendar-BkWIhKa1.js → calendar-BuZ4zbPW.js} +1 -1
- package/ui/dist/assets/{chevron-up-BRTtndUZ.js → chevron-up-DcJ4LL_N.js} +1 -1
- package/ui/dist/assets/{circle-x-BN89YhbS.js → circle-x-C78PNZjF.js} +1 -1
- package/ui/dist/assets/{constants-fc7TFI7u.js → constants-DhDjZe4P.js} +1 -1
- package/ui/dist/assets/{cpu-B41x1-vV.js → cpu-Ck6AoG8c.js} +1 -1
- package/ui/dist/assets/{database-D9Cnfmzj.js → database-CA2w8Lvt.js} +1 -1
- package/ui/dist/assets/{dialog-DrWB4EYD.js → dialog-BOdGWhgE.js} +1 -1
- package/ui/dist/assets/{ellipsis-NuUWekvu.js → ellipsis-FhHKRbfl.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-BueMfuCw.js → ellipsis-vertical-CO0UqE4-.js} +1 -1
- package/ui/dist/assets/{file-code-HR9829Jc.js → file-code-ChnhYYj1.js} +1 -1
- package/ui/dist/assets/{folder-open-C_7oYEqe.js → folder-open-CHwA1-ve.js} +1 -1
- package/ui/dist/assets/{funnel-B5gmNXGf.js → funnel-ByEjRFNB.js} +1 -1
- package/ui/dist/assets/{git-branch-BRMiJmV3.js → git-branch-GTOPQgU4.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-CXOUQeJI.js → git-commit-horizontal-F5M84Kut.js} +1 -1
- package/ui/dist/assets/{globe-CCspjvus.js → globe-CQWfr7hT.js} +1 -1
- package/ui/dist/assets/{hash-g3102kPC.js → hash-nKC9gtLg.js} +1 -1
- package/ui/dist/assets/{history-CNqcBBrV.js → history-DfFSA9xJ.js} +1 -1
- package/ui/dist/assets/{index-kb4AJXUB.js → index--JkIxVXb.js} +3 -3
- package/ui/dist/assets/index-Ca3vk7Gq.js +1 -0
- package/ui/dist/assets/{index-C9jNQXzL.js → index-DHGvP9mp.js} +1 -1
- package/ui/dist/assets/index-DeI8lKRR.js +1 -0
- package/ui/dist/assets/{index-DURTouJI.js → index-Z4-RtZcs.js} +1 -1
- package/ui/dist/assets/{index-CEZ6R2Uw.js → index-a4Fxq0Hb.js} +1 -1
- package/ui/dist/assets/{layers-CLXiHN6o.js → layers-DFeLExSa.js} +1 -1
- package/ui/dist/assets/{layout-dashboard-B07MFhBs.js → layout-dashboard-WmgjMhWF.js} +1 -1
- package/ui/dist/assets/{lightbulb-B2dgG5ks.js → lightbulb-Bo8hEr7B.js} +1 -1
- package/ui/dist/assets/{link-2-BxNmr9hL.js → link-2-YqrpQXBH.js} +1 -1
- package/ui/dist/assets/{markdown-renderer-CjU6hBcW.js → markdown-renderer-Croje6Xe.js} +1 -1
- package/ui/dist/assets/{message-square-Bf2-CVbt.js → message-square-CD0H5hot.js} +1 -1
- package/ui/dist/assets/{pencil-D096Ey62.js → pencil-DpFnj5dn.js} +1 -1
- package/ui/dist/assets/{play-DfdcSI3x.js → play-DVgea_jT.js} +1 -1
- package/ui/dist/assets/{popover-BV0QJDQq.js → popover-JXecfWG5.js} +1 -1
- package/ui/dist/assets/{progress-DjPEDJfI.js → progress-C1ghf1Fu.js} +1 -1
- package/ui/dist/assets/{rocket-CPsTc-5G.js → rocket-BFxPYGx9.js} +1 -1
- package/ui/dist/assets/{select-LsO16slr.js → select-MADP8m6Q.js} +1 -1
- package/ui/dist/assets/{send-BDYBZDUZ.js → send-eYnW_7n-.js} +1 -1
- package/ui/dist/assets/{server-B3k6noce.js → server-CPMaysH8.js} +1 -1
- package/ui/dist/assets/{settings-2-Cu4xTjhG.js → settings-2-scXUOuE_.js} +1 -1
- package/ui/dist/assets/{sheet-BScLnPKX.js → sheet-r6NSOxi-.js} +1 -1
- package/ui/dist/assets/{shield-check-CQqkwufI.js → shield-check-PEr7nmVw.js} +1 -1
- package/ui/dist/assets/{shield-off-ZFruH9KO.js → shield-off-CLtXio62.js} +1 -1
- package/ui/dist/assets/{skeleton-CtkIA_MU.js → skeleton-C9oEzNlU.js} +1 -1
- package/ui/dist/assets/{smartphone-DnoksVkc.js → smartphone-DusFfY0U.js} +1 -1
- package/ui/dist/assets/{square-uD9ZHMfW.js → square-e1yxB2eR.js} +1 -1
- package/ui/dist/assets/{switch-MQPnwGJK.js → switch-tNs0n-kz.js} +1 -1
- package/ui/dist/assets/{table-B8cqlywA.js → table-CXxtLicg.js} +1 -1
- package/ui/dist/assets/{tag-wEJQRWlV.js → tag-tAwMmQ9G.js} +1 -1
- package/ui/dist/assets/{textarea-D5LJCOGl.js → textarea-BjiEeIWh.js} +1 -1
- package/ui/dist/assets/{timer-mbGHegmr.js → timer-Vel1N3RP.js} +1 -1
- package/ui/dist/assets/{tooltip-Df1CunSp.js → tooltip-ZMwtfr1J.js} +1 -1
- package/ui/dist/assets/{trash-2-B4oAXsX-.js → trash-2-eM-CNwsZ.js} +1 -1
- package/ui/dist/assets/{trending-up-BGWxvlmZ.js → trending-up-BGafmjRo.js} +1 -1
- package/ui/dist/assets/{wand-sparkles-CZy4xvL3.js → wand-sparkles-DPvcd9Pi.js} +1 -1
- package/ui/dist/assets/{wrench-ByZkjO6m.js → wrench-B8s3zYVV.js} +1 -1
- package/ui/dist/index.html +1 -1
- package/ui/dist/assets/CostsDashboard-ChfH8BlG.js +0 -1
- package/ui/dist/assets/index-27mTPKuh.js +0 -1
- package/ui/dist/assets/index-BMx3fH-e.js +0 -1
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { Command } from 'commander';
|
|
12
12
|
import chalk from 'chalk';
|
|
13
13
|
import figlet from 'figlet';
|
|
14
|
-
import {
|
|
14
|
+
import { select, search, input, Separator } from '@inquirer/prompts';
|
|
15
15
|
import { existsSync, writeFileSync, readFileSync } from 'node:fs';
|
|
16
16
|
import { join } from 'node:path';
|
|
17
17
|
import { execSync } from 'node:child_process';
|
|
@@ -125,6 +125,14 @@ function generateEnvFile(opts) {
|
|
|
125
125
|
lines.push(`OLLAMA_BASE_URL=${opts.ollamaUrl}`);
|
|
126
126
|
lines.push('');
|
|
127
127
|
}
|
|
128
|
+
// Write any extra env vars from selected providers
|
|
129
|
+
if (opts.extraEnvVars) {
|
|
130
|
+
for (const [key, value] of Object.entries(opts.extraEnvVars)) {
|
|
131
|
+
lines.push(`${key}=${value}`);
|
|
132
|
+
}
|
|
133
|
+
if (Object.keys(opts.extraEnvVars).length > 0)
|
|
134
|
+
lines.push('');
|
|
135
|
+
}
|
|
128
136
|
if (opts.mode === 'pro') {
|
|
129
137
|
lines.push('# Redis (required for pro mode)');
|
|
130
138
|
lines.push('REDIS_URL=redis://localhost:6379');
|
|
@@ -133,24 +141,6 @@ function generateEnvFile(opts) {
|
|
|
133
141
|
return lines.join('\n');
|
|
134
142
|
}
|
|
135
143
|
// Interactive Onboarding
|
|
136
|
-
async function prompt(rl, question) {
|
|
137
|
-
const answer = await rl.question(chalk.bold(question));
|
|
138
|
-
return answer.trim();
|
|
139
|
-
}
|
|
140
|
-
async function promptChoice(rl, question, options) {
|
|
141
|
-
console.log('');
|
|
142
|
-
console.log(chalk.bold(question));
|
|
143
|
-
for (const opt of options) {
|
|
144
|
-
console.log(` ${chalk.cyan(opt.key)}) ${opt.label}`);
|
|
145
|
-
}
|
|
146
|
-
const validKeys = options.map(o => o.key);
|
|
147
|
-
while (true) {
|
|
148
|
-
const answer = await prompt(rl, `Choice [${validKeys.join('/')}]: `);
|
|
149
|
-
if (validKeys.includes(answer))
|
|
150
|
-
return answer;
|
|
151
|
-
console.log(chalk.red(` Invalid choice. Options: ${validKeys.join(', ')}`));
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
144
|
async function runInteractive() {
|
|
155
145
|
const banner = figlet.textSync('profClaw', { font: 'Standard' });
|
|
156
146
|
console.log(chalk.cyan(banner));
|
|
@@ -161,58 +151,258 @@ async function runInteractive() {
|
|
|
161
151
|
spin.start();
|
|
162
152
|
const env = await detectEnvironment();
|
|
163
153
|
spin.stop();
|
|
164
|
-
|
|
165
|
-
console.log(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
154
|
+
// Helpers for display
|
|
155
|
+
const ok = (label, value) => console.log(` ${chalk.green('+')} ${chalk.white(label.padEnd(14))} ${value}`);
|
|
156
|
+
const no = (label, value, hint) => {
|
|
157
|
+
console.log(` ${chalk.yellow('~')} ${chalk.dim(label.padEnd(14))} ${chalk.dim(value)}`);
|
|
158
|
+
if (hint)
|
|
159
|
+
console.log(` ${chalk.dim('\u2514')} ${chalk.yellow(hint)}`);
|
|
160
|
+
};
|
|
161
|
+
const ramGb = (env.totalMemoryMb / 1024).toFixed(0);
|
|
162
|
+
const ramBar = (() => {
|
|
163
|
+
const total = 16; // bar width
|
|
164
|
+
const filled = Math.min(total, Math.round((env.totalMemoryMb / 65536) * total));
|
|
165
|
+
return chalk.green('\u2588'.repeat(filled)) + chalk.dim('\u2591'.repeat(total - filled));
|
|
166
|
+
})();
|
|
167
|
+
const ramWarn = env.totalMemoryMb < 512
|
|
168
|
+
? chalk.red(' (low - pico mode recommended)')
|
|
169
|
+
: env.totalMemoryMb < 2048
|
|
170
|
+
? chalk.yellow(' (limited - mini mode recommended)')
|
|
171
|
+
: '';
|
|
172
|
+
// -- System --
|
|
173
|
+
console.log('');
|
|
174
|
+
console.log(` ${chalk.bold.cyan('System')}`);
|
|
175
|
+
ok('OS', `${env.os} (${env.arch})`);
|
|
176
|
+
ok('Node', env.nodeVersion);
|
|
177
|
+
ok('RAM', `${ramGb} GB ${ramBar}${ramWarn}`);
|
|
178
|
+
if (env.isDocker) {
|
|
179
|
+
ok('Docker', 'Running in container');
|
|
180
|
+
}
|
|
181
|
+
// -- Services --
|
|
182
|
+
console.log('');
|
|
183
|
+
console.log(` ${chalk.bold.cyan('Services')}`);
|
|
184
|
+
if (env.hasRedis) {
|
|
185
|
+
ok('Redis', chalk.green('connected'));
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
no('Redis', 'not found (optional)', 'Install: brew install redis | docker run -d -p 6379:6379 redis:alpine');
|
|
189
|
+
}
|
|
190
|
+
if (env.hasOllama) {
|
|
191
|
+
ok('Ollama', chalk.green('running') + ' (free local AI)');
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
no('Ollama', 'not running (optional)', 'Install: brew install ollama && ollama serve | https://ollama.com/download');
|
|
195
|
+
}
|
|
196
|
+
// -- Tools --
|
|
197
|
+
console.log('');
|
|
198
|
+
console.log(` ${chalk.bold.cyan('Tools')}`);
|
|
199
|
+
if (env.hasClaude) {
|
|
200
|
+
ok('Claude CLI', 'found');
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
no('Claude CLI', 'not found (optional)', 'Install: npm install -g @anthropic-ai/claude-code');
|
|
204
|
+
}
|
|
205
|
+
if (env.hasGit) {
|
|
206
|
+
ok('Git', 'found');
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
no('Git', 'not found', 'Install: brew install git | https://git-scm.com/downloads');
|
|
210
|
+
}
|
|
211
|
+
// -- Existing Data --
|
|
212
|
+
if (env.existingEnv || env.existingDb) {
|
|
213
|
+
console.log('');
|
|
214
|
+
console.log(` ${chalk.bold.cyan('Existing Data')}`);
|
|
215
|
+
if (env.existingEnv)
|
|
216
|
+
ok('.env', 'found');
|
|
217
|
+
if (env.existingDb)
|
|
218
|
+
ok('Database', 'found');
|
|
219
|
+
}
|
|
173
220
|
const recommended = recommendMode(env);
|
|
174
|
-
console.log(
|
|
175
|
-
|
|
176
|
-
// Step 2: Choose mode
|
|
221
|
+
console.log('');
|
|
222
|
+
console.log(` ${chalk.cyan('Recommended mode:')} ${chalk.bold(recommended)}`);
|
|
223
|
+
// Step 2: Choose mode (arrow keys)
|
|
177
224
|
console.log(chalk.bold.white('\n Step 2: Deployment Mode\n'));
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
225
|
+
let mode;
|
|
226
|
+
try {
|
|
227
|
+
mode = await select({
|
|
228
|
+
message: 'Select deployment mode',
|
|
229
|
+
default: recommended,
|
|
230
|
+
choices: [
|
|
231
|
+
{
|
|
232
|
+
name: `Pico - Agent + tools only, ~50MB RAM${recommended === 'pico' ? chalk.green(' (recommended)') : ''}`,
|
|
233
|
+
value: 'pico',
|
|
234
|
+
description: 'Minimal footprint. CLI agent, tool execution, no web UI.',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
name: `Mini - Dashboard, cron, integrations, ~150MB RAM${recommended === 'mini' ? chalk.green(' (recommended)') : ''}`,
|
|
238
|
+
value: 'mini',
|
|
239
|
+
description: 'Web dashboard, scheduled jobs, GitHub/Jira/Linear webhooks.',
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
name: `Pro - Everything, Redis required, ~300MB RAM${recommended === 'pro' ? chalk.green(' (recommended)') : ''}`,
|
|
243
|
+
value: 'pro',
|
|
244
|
+
description: 'BullMQ queues, plugins, sync engine, multi-agent orchestration.',
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
theme: { prefix: ' ', style: { highlight: (text) => chalk.cyan.bold(text) } },
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
console.log(chalk.dim('\n Cancelled.'));
|
|
252
|
+
process.exit(0);
|
|
253
|
+
}
|
|
184
254
|
success(`Mode: ${mode}`);
|
|
185
|
-
// Step 3: AI Provider
|
|
255
|
+
// Step 3: AI Provider (searchable list)
|
|
186
256
|
console.log(chalk.bold.white('\n Step 3: AI Provider\n'));
|
|
187
257
|
let anthropicKey;
|
|
188
258
|
let openaiKey;
|
|
189
259
|
let ollamaUrl;
|
|
190
260
|
const hasExistingProvider = !!process.env.ANTHROPIC_API_KEY || !!process.env.OPENAI_API_KEY;
|
|
191
261
|
if (hasExistingProvider) {
|
|
192
|
-
|
|
262
|
+
const which = process.env.ANTHROPIC_API_KEY ? 'Anthropic' : 'OpenAI';
|
|
263
|
+
info(`AI provider already configured from environment (${which}).`);
|
|
193
264
|
}
|
|
194
265
|
else {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
{ key: '
|
|
198
|
-
{ key: '
|
|
199
|
-
{ key: '
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
266
|
+
// Provider catalog
|
|
267
|
+
const providers = [
|
|
268
|
+
{ key: 'anthropic', name: 'Anthropic', models: 'Claude 4.x, 3.5 Sonnet', envVar: 'ANTHROPIC_API_KEY', category: 'Popular', tag: 'recommended' },
|
|
269
|
+
{ key: 'openai', name: 'OpenAI', models: 'GPT-4o, o1, o3', envVar: 'OPENAI_API_KEY', category: 'Popular', tag: '' },
|
|
270
|
+
{ key: 'google', name: 'Google AI', models: 'Gemini 2.x, Flash', envVar: 'GOOGLE_GENERATIVE_AI_API_KEY', category: 'Popular', tag: '' },
|
|
271
|
+
{ key: 'ollama', name: 'Ollama', models: 'Llama, Mistral, Qwen', envVar: 'OLLAMA_BASE_URL', category: 'Popular', tag: env.hasOllama ? 'detected' : 'free, local' },
|
|
272
|
+
{ key: 'groq', name: 'Groq', models: 'Llama, Mixtral', envVar: 'GROQ_API_KEY', category: 'Fast Inference', tag: 'fast' },
|
|
273
|
+
{ key: 'cerebras', name: 'Cerebras', models: 'Llama 3.3 70B', envVar: 'CEREBRAS_API_KEY', category: 'Fast Inference', tag: 'fast' },
|
|
274
|
+
{ key: 'fireworks', name: 'Fireworks', models: 'Llama, Mixtral', envVar: 'FIREWORKS_API_KEY', category: 'Fast Inference', tag: '' },
|
|
275
|
+
{ key: 'together', name: 'Together', models: 'Open models', envVar: 'TOGETHER_API_KEY', category: 'Fast Inference', tag: '' },
|
|
276
|
+
{ key: 'azure', name: 'Azure OpenAI', models: 'GPT-4o', envVar: 'AZURE_OPENAI_API_KEY', category: 'Enterprise', tag: 'enterprise' },
|
|
277
|
+
{ key: 'bedrock', name: 'AWS Bedrock', models: 'Claude, Titan, Llama', envVar: 'AWS_ACCESS_KEY_ID', category: 'Enterprise', tag: 'enterprise' },
|
|
278
|
+
{ key: 'watsonx', name: 'IBM Watsonx', models: 'Granite, Llama', envVar: 'WATSONX_API_KEY', category: 'Enterprise', tag: 'enterprise' },
|
|
279
|
+
{ key: 'deepseek', name: 'DeepSeek', models: 'V3, R1 (reasoning)', envVar: 'DEEPSEEK_API_KEY', category: 'More Providers', tag: '' },
|
|
280
|
+
{ key: 'mistral', name: 'Mistral', models: 'Large, Codestral', envVar: 'MISTRAL_API_KEY', category: 'More Providers', tag: '' },
|
|
281
|
+
{ key: 'xai', name: 'xAI', models: 'Grok', envVar: 'XAI_API_KEY', category: 'More Providers', tag: '' },
|
|
282
|
+
{ key: 'perplexity', name: 'Perplexity', models: 'Sonar (search)', envVar: 'PERPLEXITY_API_KEY', category: 'More Providers', tag: 'search' },
|
|
283
|
+
{ key: 'cohere', name: 'Cohere', models: 'Command R+', envVar: 'COHERE_API_KEY', category: 'More Providers', tag: '' },
|
|
284
|
+
{ key: 'openrouter', name: 'OpenRouter', models: 'Any model (proxy)', envVar: 'OPENROUTER_API_KEY', category: 'Aggregators', tag: 'multi-model' },
|
|
285
|
+
{ key: 'replicate', name: 'Replicate', models: 'Open-source models', envVar: 'REPLICATE_API_TOKEN', category: 'Aggregators', tag: '' },
|
|
286
|
+
{ key: 'github-models', name: 'GitHub Models', models: 'Azure-backed', envVar: 'GITHUB_TOKEN', category: 'Aggregators', tag: '' },
|
|
287
|
+
{ key: 'huggingface', name: 'HuggingFace', models: 'Inference API', envVar: 'HF_TOKEN', category: 'Aggregators', tag: '' },
|
|
288
|
+
{ key: 'nvidia-nim', name: 'NVIDIA NIM', models: 'Llama, Nemotron', envVar: 'NVIDIA_NIM_API_KEY', category: 'Aggregators', tag: '' },
|
|
289
|
+
{ key: 'zhipu', name: 'Zhipu AI', models: 'GLM-4, GLM-5', envVar: 'ZHIPU_API_KEY', category: 'Asia', tag: '' },
|
|
290
|
+
{ key: 'moonshot', name: 'Moonshot', models: 'Kimi (128K context)', envVar: 'MOONSHOT_API_KEY', category: 'Asia', tag: '' },
|
|
291
|
+
{ key: 'qwen', name: 'Qwen', models: 'Qwen Max, Plus', envVar: 'QWEN_API_KEY', category: 'Asia', tag: '' },
|
|
292
|
+
{ key: 'minimax', name: 'MiniMax', models: 'abab series', envVar: 'MINIMAX_API_KEY', category: 'Asia', tag: '' },
|
|
293
|
+
{ key: 'volcengine', name: 'Volcengine', models: 'Doubao (Bytedance)', envVar: 'VOLCENGINE_API_KEY', category: 'Asia', tag: '' },
|
|
294
|
+
{ key: 'qianfan', name: 'Qianfan', models: 'ERNIE (Baidu)', envVar: 'QIANFAN_API_KEY', category: 'Asia', tag: '' },
|
|
295
|
+
];
|
|
296
|
+
// Check which providers have keys in env
|
|
297
|
+
const detected = new Set();
|
|
298
|
+
for (const p of providers) {
|
|
299
|
+
if (process.env[p.envVar])
|
|
300
|
+
detected.add(p.key);
|
|
301
|
+
}
|
|
302
|
+
if (env.hasOllama)
|
|
303
|
+
detected.add('ollama');
|
|
304
|
+
// Build searchable choices grouped by category
|
|
305
|
+
let chosenProvider;
|
|
306
|
+
try {
|
|
307
|
+
chosenProvider = await search({
|
|
308
|
+
message: 'Select AI provider (type to filter, arrows to navigate)',
|
|
309
|
+
source: (term) => {
|
|
310
|
+
const results = [];
|
|
311
|
+
const filter = (term || '').toLowerCase();
|
|
312
|
+
let lastCategory = '';
|
|
313
|
+
for (const p of providers) {
|
|
314
|
+
// Filter by name, key, models, category, or tag
|
|
315
|
+
if (filter && ![p.name, p.key, p.models, p.category, p.tag]
|
|
316
|
+
.some(s => s.toLowerCase().includes(filter))) {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
// Add category separator
|
|
320
|
+
if (p.category !== lastCategory) {
|
|
321
|
+
if (results.length > 0)
|
|
322
|
+
results.push(new Separator());
|
|
323
|
+
results.push(new Separator(chalk.bold.cyan(` ${p.category} `)));
|
|
324
|
+
lastCategory = p.category;
|
|
325
|
+
}
|
|
326
|
+
const det = detected.has(p.key) ? chalk.green(' *') : '';
|
|
327
|
+
const tag = p.tag ? ` ${chalk.dim(`[${p.tag}]`)}` : '';
|
|
328
|
+
results.push({
|
|
329
|
+
name: `${p.name.padEnd(16)} ${chalk.dim(p.models)}${tag}${det}`,
|
|
330
|
+
value: p.key,
|
|
331
|
+
description: `${p.envVar}`,
|
|
332
|
+
short: p.name,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
// Always add skip option at the end
|
|
336
|
+
if (!filter || 'skip'.includes(filter)) {
|
|
337
|
+
results.push(new Separator());
|
|
338
|
+
results.push({
|
|
339
|
+
name: chalk.dim('Skip for now'),
|
|
340
|
+
value: 'skip',
|
|
341
|
+
description: 'Configure later with: profclaw provider',
|
|
342
|
+
short: 'Skip',
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
return results;
|
|
346
|
+
},
|
|
347
|
+
theme: { prefix: ' ', style: { highlight: (text) => chalk.cyan.bold(text) } },
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
console.log(chalk.dim('\n Cancelled.'));
|
|
352
|
+
process.exit(0);
|
|
205
353
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
354
|
+
if (chosenProvider !== 'skip') {
|
|
355
|
+
const chosen = providers.find(p => p.key === chosenProvider);
|
|
356
|
+
console.log(`\n ${chalk.bold(chosen.name)} selected`);
|
|
357
|
+
console.log(chalk.dim(` Env var: ${chosen.envVar}`));
|
|
358
|
+
if (chosen.key === 'ollama') {
|
|
359
|
+
if (env.hasOllama) {
|
|
360
|
+
ollamaUrl = process.env.OLLAMA_BASE_URL || 'http://localhost:11434';
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
try {
|
|
364
|
+
ollamaUrl = await input({
|
|
365
|
+
message: 'Ollama URL',
|
|
366
|
+
default: 'http://localhost:11434',
|
|
367
|
+
theme: { prefix: ' ' },
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
catch {
|
|
371
|
+
ollamaUrl = 'http://localhost:11434';
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
success(`Ollama: ${ollamaUrl}`);
|
|
375
|
+
}
|
|
376
|
+
else if (detected.has(chosen.key)) {
|
|
377
|
+
success(`${chosen.name} already configured from ${chosen.envVar}`);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
try {
|
|
381
|
+
const keyInput = await input({
|
|
382
|
+
message: chosen.envVar,
|
|
383
|
+
theme: { prefix: ' ' },
|
|
384
|
+
});
|
|
385
|
+
if (keyInput) {
|
|
386
|
+
if (chosen.key === 'anthropic')
|
|
387
|
+
anthropicKey = keyInput;
|
|
388
|
+
else if (chosen.key === 'openai')
|
|
389
|
+
openaiKey = keyInput;
|
|
390
|
+
else {
|
|
391
|
+
process.env[chosen.envVar] = keyInput;
|
|
392
|
+
}
|
|
393
|
+
success(`${chosen.name} configured.`);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
warn('No key provided, skipping.');
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
catch {
|
|
400
|
+
warn('Input cancelled, skipping provider.');
|
|
401
|
+
}
|
|
402
|
+
}
|
|
210
403
|
}
|
|
211
|
-
else
|
|
212
|
-
|
|
213
|
-
? (process.env.OLLAMA_BASE_URL || 'http://localhost:11434')
|
|
214
|
-
: await prompt(rl, ' Ollama URL [http://localhost:11434]: ') || 'http://localhost:11434';
|
|
215
|
-
success(`Ollama: ${ollamaUrl}`);
|
|
404
|
+
else {
|
|
405
|
+
info('AI provider skipped. Configure later: profclaw provider');
|
|
216
406
|
}
|
|
217
407
|
}
|
|
218
408
|
// Step 4: Generate .env
|
|
@@ -247,7 +437,6 @@ async function runInteractive() {
|
|
|
247
437
|
writeFileSync(envPath, content);
|
|
248
438
|
success(`PROFCLAW_MODE=${mode} set in .env`);
|
|
249
439
|
}
|
|
250
|
-
rl.close();
|
|
251
440
|
// Step 5: Run setup wizard
|
|
252
441
|
console.log(chalk.bold.white('\n Step 5: Setup\n'));
|
|
253
442
|
info('Launching setup wizard for admin account and provider configuration...\n');
|