profclaw 0.0.1-beta.2 → 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/CHANGELOG.md +21 -38
- package/CONTRIBUTING.md +3 -5
- package/README.md +128 -63
- package/dist/chat/execution/tools/index.d.ts +1 -1
- package/dist/chat/execution/tools/index.js +41 -2
- package/dist/chat/providers/slack/index.d.ts +2 -2
- package/dist/cli/commands/models.js +39 -26
- package/dist/cli/commands/onboard.js +64 -79
- package/dist/cli/commands/setup.js +293 -90
- package/dist/cli/index.js +0 -6
- package/dist/cli/providers.d.ts +15 -0
- package/dist/cli/providers.js +41 -0
- package/dist/core/deployment.js +2 -0
- package/dist/providers/ai-sdk.js +26 -6
- package/dist/routes/channels.d.ts +12 -0
- package/dist/routes/channels.js +166 -0
- package/dist/server/route-loader.js +1 -0
- package/dist/server.js +115 -109
- package/package.json +1 -1
- package/skills/git-workflow/SKILL.md +3 -3
- package/ui/dist/assets/{ActivityView-DIPQSJ_d.js → ActivityView-BeshZXmE.js} +1 -1
- package/ui/dist/assets/{AgentList-CqyaYrcq.js → AgentList-QVHeldPi.js} +1 -1
- package/ui/dist/assets/{AnalyticsDashboard-C-mjuGHT.js → AnalyticsDashboard-C9R97dXE.js} +1 -1
- package/ui/dist/assets/{AreaChart-CfYWmbtr.js → AreaChart-B73gaiVQ.js} +1 -1
- package/ui/dist/assets/{CartesianChart-BaQ3It0c.js → CartesianChart-CXYL2R-A.js} +1 -1
- package/ui/dist/assets/{ChatView-DxxQy6pl.js → ChatView-qjZErlrp.js} +1 -1
- package/ui/dist/assets/{CostsDashboard-CDBBcGkg.js → CostsDashboard-O4DCLy1i.js} +1 -1
- package/ui/dist/assets/{EstimateSelect-CDjf5qKl.js → EstimateSelect-1hQf4Osk.js} +1 -1
- package/ui/dist/assets/{FloatingChatbot-CZHjvJIe.js → FloatingChatbot-BZBzrJxd.js} +1 -1
- package/ui/dist/assets/{InviteCodeManagement-DTm-IPTm.js → InviteCodeManagement-LEoGqYeA.js} +1 -1
- package/ui/dist/assets/{ProjectDetail-DlYUcOss.js → ProjectDetail--gPfvATB.js} +1 -1
- package/ui/dist/assets/{ProjectIcon-BMRpnM04.js → ProjectIcon-Chd_ofsw.js} +1 -1
- package/ui/dist/assets/{ProjectList-D85TN0i0.js → ProjectList-BvUfVB6c.js} +1 -1
- package/ui/dist/assets/{Settings-CgPqzUvj.js → Settings-1kaf7VHE.js} +1 -1
- package/ui/dist/assets/{StatusIndicator-yig0uZEA.js → StatusIndicator-pRfkNcdV.js} +1 -1
- package/ui/dist/assets/{SummaryDetail-CwLAfHgJ.js → SummaryDetail-DV3AmONk.js} +1 -1
- package/ui/dist/assets/{SummaryList-BvS5Idnu.js → SummaryList-B6kXiTxL.js} +1 -1
- package/ui/dist/assets/{TaskDetail-zarC1fOt.js → TaskDetail-CV6CzbOS.js} +1 -1
- package/ui/dist/assets/{TaskList-CyJq3ANE.js → TaskList-DL7brQKd.js} +1 -1
- package/ui/dist/assets/{TicketBoard-BlWr3-iH.js → TicketBoard-CrkkFj7C.js} +1 -1
- package/ui/dist/assets/{TicketDetail-DmqWKj2W.js → TicketDetail-hnnYclpD.js} +1 -1
- package/ui/dist/assets/{TicketList-Scj4pMWa.js → TicketList-CsDAyQCL.js} +1 -1
- package/ui/dist/assets/{UserManagement-BH7uG7dw.js → UserManagement-BGFQyTSr.js} +1 -1
- package/ui/dist/assets/{ViewSwitcher-3HzZUdWn.js → ViewSwitcher-CnL0OqA8.js} +1 -1
- package/ui/dist/assets/{alert-dialog-DWPb2IfQ.js → alert-dialog-SKM6Gjz4.js} +1 -1
- package/ui/dist/assets/{archive-CGck7gxR.js → archive-BsLa7brF.js} +1 -1
- package/ui/dist/assets/{badge-DEmc3Z_l.js → badge-CVHH1a-v.js} +1 -1
- package/ui/dist/assets/{brain-CfFdLVqb.js → brain-6o_RHVpe.js} +1 -1
- package/ui/dist/assets/{bug-DqSGPUUE.js → bug-CmZI7jqM.js} +1 -1
- package/ui/dist/assets/{calendar-BuZ4zbPW.js → calendar-Bf0t2B82.js} +1 -1
- package/ui/dist/assets/{chevron-up-DcJ4LL_N.js → chevron-up-CoUsOvZj.js} +1 -1
- package/ui/dist/assets/{circle-x-C78PNZjF.js → circle-x-Dgw11LgT.js} +1 -1
- package/ui/dist/assets/{constants-DhDjZe4P.js → constants-Q5Zivl-a.js} +1 -1
- package/ui/dist/assets/{cpu-Ck6AoG8c.js → cpu-DiPMQICV.js} +1 -1
- package/ui/dist/assets/{database-CA2w8Lvt.js → database-BwTfupDi.js} +1 -1
- package/ui/dist/assets/{dialog-BOdGWhgE.js → dialog-BUqN9Psj.js} +1 -1
- package/ui/dist/assets/{ellipsis-FhHKRbfl.js → ellipsis-UJx4Xnf6.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-CO0UqE4-.js → ellipsis-vertical-DoULYEKn.js} +1 -1
- package/ui/dist/assets/{file-code-ChnhYYj1.js → file-code-B2UrJLwi.js} +1 -1
- package/ui/dist/assets/{folder-open-CHwA1-ve.js → folder-open-BJi577JH.js} +1 -1
- package/ui/dist/assets/{funnel-ByEjRFNB.js → funnel-PkaD_HSR.js} +1 -1
- package/ui/dist/assets/{git-branch-GTOPQgU4.js → git-branch-C_K30am0.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-F5M84Kut.js → git-commit-horizontal-IT6ecxWQ.js} +1 -1
- package/ui/dist/assets/{globe-CQWfr7hT.js → globe-f-jjCa_g.js} +1 -1
- package/ui/dist/assets/{hash-nKC9gtLg.js → hash-DNEv8Elo.js} +1 -1
- package/ui/dist/assets/{history-DfFSA9xJ.js → history-BQSBo_1Q.js} +1 -1
- package/ui/dist/assets/{index-DHGvP9mp.js → index-BUmnwPQr.js} +1 -1
- package/ui/dist/assets/{index-Z4-RtZcs.js → index-BfF5G4Cw.js} +1 -1
- package/ui/dist/assets/{index-DeI8lKRR.js → index-C8N375c2.js} +1 -1
- package/ui/dist/assets/index-CuxnqVVz.css +1 -0
- package/ui/dist/assets/{index-Ca3vk7Gq.js → index-CzMM3QOk.js} +1 -1
- package/ui/dist/assets/{index--JkIxVXb.js → index-lJlNPFVJ.js} +3 -3
- package/ui/dist/assets/{index-a4Fxq0Hb.js → index-nS3EErDg.js} +1 -1
- package/ui/dist/assets/{layers-DFeLExSa.js → layers-jFqVrWMD.js} +1 -1
- package/ui/dist/assets/{layout-dashboard-WmgjMhWF.js → layout-dashboard-CcKt1hXw.js} +1 -1
- package/ui/dist/assets/{lightbulb-Bo8hEr7B.js → lightbulb-Jhp7FvbU.js} +1 -1
- package/ui/dist/assets/{link-2-YqrpQXBH.js → link-2-DdO7ostF.js} +1 -1
- package/ui/dist/assets/{markdown-renderer-Croje6Xe.js → markdown-renderer-n1ToC4XQ.js} +1 -1
- package/ui/dist/assets/{message-square-CD0H5hot.js → message-square-CBgH65X7.js} +1 -1
- package/ui/dist/assets/{pencil-DpFnj5dn.js → pencil-CYXCEPQh.js} +1 -1
- package/ui/dist/assets/{play-DVgea_jT.js → play-d1ONaH0-.js} +1 -1
- package/ui/dist/assets/{popover-JXecfWG5.js → popover-CrmZgoWu.js} +1 -1
- package/ui/dist/assets/{progress-C1ghf1Fu.js → progress-uv4SPkL5.js} +1 -1
- package/ui/dist/assets/{rocket-BFxPYGx9.js → rocket-DhvUetsk.js} +1 -1
- package/ui/dist/assets/{select-MADP8m6Q.js → select-CeQ8AHGy.js} +1 -1
- package/ui/dist/assets/{send-eYnW_7n-.js → send-P0r5D7td.js} +1 -1
- package/ui/dist/assets/{server-CPMaysH8.js → server-CVHTZB72.js} +1 -1
- package/ui/dist/assets/{settings-2-scXUOuE_.js → settings-2-ocj5uHGx.js} +1 -1
- package/ui/dist/assets/{sheet-r6NSOxi-.js → sheet-DuQExSho.js} +1 -1
- package/ui/dist/assets/{shield-check-PEr7nmVw.js → shield-check-DfVdE34l.js} +1 -1
- package/ui/dist/assets/{shield-off-CLtXio62.js → shield-off-8l0J6R-8.js} +1 -1
- package/ui/dist/assets/{skeleton-C9oEzNlU.js → skeleton-TFiFJ3nB.js} +1 -1
- package/ui/dist/assets/{smartphone-DusFfY0U.js → smartphone-77_g3SQn.js} +1 -1
- package/ui/dist/assets/{square-e1yxB2eR.js → square-Ckzsr3Rn.js} +1 -1
- package/ui/dist/assets/{switch-tNs0n-kz.js → switch-CAePkd6k.js} +1 -1
- package/ui/dist/assets/{table-CXxtLicg.js → table-ZjAZ7hkt.js} +1 -1
- package/ui/dist/assets/{tag-tAwMmQ9G.js → tag-C35mgoEv.js} +1 -1
- package/ui/dist/assets/{textarea-BjiEeIWh.js → textarea-DsVPnSgR.js} +1 -1
- package/ui/dist/assets/{timer-Vel1N3RP.js → timer-DHJBS2w1.js} +1 -1
- package/ui/dist/assets/{tooltip-ZMwtfr1J.js → tooltip-BYmQ331W.js} +1 -1
- package/ui/dist/assets/{trash-2-eM-CNwsZ.js → trash-2-keO5tKPE.js} +1 -1
- package/ui/dist/assets/{trending-up-BGafmjRo.js → trending-up-BBv8KbrY.js} +1 -1
- package/ui/dist/assets/{wand-sparkles-DPvcd9Pi.js → wand-sparkles-BusQ52ZK.js} +1 -1
- package/ui/dist/assets/{wrench-B8s3zYVV.js → wrench-02YaOSiK.js} +1 -1
- package/ui/dist/index.html +2 -2
- package/dist/chat/auto-reply.d.ts +0 -90
- package/dist/chat/auto-reply.js +0 -272
- package/dist/chat/execution/pty.d.ts +0 -92
- package/dist/chat/execution/pty.js +0 -285
- package/dist/chat/execution/tools/glinr-ops.d.ts +0 -202
- package/dist/chat/execution/tools/glinr-ops.js +0 -694
- package/dist/cli/commands/browser.d.ts +0 -3
- package/dist/cli/commands/browser.js +0 -138
- package/dist/cli/commands/canvas.d.ts +0 -3
- package/dist/cli/commands/canvas.js +0 -155
- package/dist/cli/commands/nodes.d.ts +0 -3
- package/dist/cli/commands/nodes.js +0 -193
- package/dist/diagnostics/exporters.d.ts +0 -21
- package/dist/diagnostics/exporters.js +0 -138
- package/dist/diagnostics/index.d.ts +0 -10
- package/dist/diagnostics/index.js +0 -9
- package/dist/diagnostics/middleware.d.ts +0 -12
- package/dist/diagnostics/middleware.js +0 -58
- package/dist/diagnostics/tracer.d.ts +0 -133
- package/dist/diagnostics/tracer.js +0 -257
- package/dist/discovery/index.d.ts +0 -8
- package/dist/discovery/index.js +0 -7
- package/dist/discovery/mdns.d.ts +0 -40
- package/dist/discovery/mdns.js +0 -249
- package/dist/plugins/registry.d.ts +0 -122
- package/dist/plugins/registry.js +0 -352
- package/dist/plugins/sandbox.d.ts +0 -77
- package/dist/plugins/sandbox.js +0 -287
- package/dist/plugins/search/brave.d.ts +0 -9
- package/dist/plugins/search/brave.js +0 -157
- package/dist/plugins/search/duckduckgo.d.ts +0 -9
- package/dist/plugins/search/duckduckgo.js +0 -171
- package/dist/plugins/search/index.d.ts +0 -13
- package/dist/plugins/search/index.js +0 -23
- package/dist/plugins/search/searxng.d.ts +0 -9
- package/dist/plugins/search/searxng.js +0 -170
- package/dist/plugins/search/serper.d.ts +0 -9
- package/dist/plugins/search/serper.js +0 -135
- package/dist/plugins/search/tavily.d.ts +0 -9
- package/dist/plugins/search/tavily.js +0 -146
- package/dist/providers/adapters/anthropic.d.ts +0 -26
- package/dist/providers/adapters/anthropic.js +0 -306
- package/dist/providers/adapters/base.d.ts +0 -53
- package/dist/providers/adapters/base.js +0 -99
- package/dist/providers/adapters/ollama.d.ts +0 -30
- package/dist/providers/adapters/ollama.js +0 -292
- package/dist/utils/ai-cache.d.ts +0 -72
- package/dist/utils/ai-cache.js +0 -204
- package/dist/utils/file-lock.d.ts +0 -85
- package/dist/utils/file-lock.js +0 -204
- package/ui/dist/assets/index-WclMPci1.css +0 -1
|
@@ -16,6 +16,14 @@ import { existsSync, writeFileSync, readFileSync } from 'node:fs';
|
|
|
16
16
|
import { join } from 'node:path';
|
|
17
17
|
import { execSync } from 'node:child_process';
|
|
18
18
|
import { success, error, info, warn, spinner } from '../utils/output.js';
|
|
19
|
+
import { PROVIDER_CATALOG, PROVIDER_ENV_KEYS } from '../providers.js';
|
|
20
|
+
/** Render a step header with progress bar. */
|
|
21
|
+
function stepHeader(step, total, title) {
|
|
22
|
+
const barLen = 20;
|
|
23
|
+
const filled = Math.round((step / total) * barLen);
|
|
24
|
+
const bar = chalk.cyan('━'.repeat(filled)) + chalk.dim('━'.repeat(barLen - filled));
|
|
25
|
+
console.log(`\n ${bar} ${chalk.dim(`${step}/${total}`)} ${chalk.bold.white(title)}\n`);
|
|
26
|
+
}
|
|
19
27
|
const DETECT_TIMEOUT_MS = 5000;
|
|
20
28
|
/** Wrap a detection check with a timeout so a hung service doesn't block onboarding. */
|
|
21
29
|
async function withTimeout(promise, fallback, timeoutMs = DETECT_TIMEOUT_MS) {
|
|
@@ -146,7 +154,7 @@ async function runInteractive() {
|
|
|
146
154
|
console.log(chalk.cyan(banner));
|
|
147
155
|
console.log(chalk.dim(' Onboarding Wizard\n'));
|
|
148
156
|
// Step 1: Detect environment
|
|
149
|
-
|
|
157
|
+
stepHeader(1, 6, 'Environment Detection');
|
|
150
158
|
const spin = spinner('Scanning environment...');
|
|
151
159
|
spin.start();
|
|
152
160
|
const env = await detectEnvironment();
|
|
@@ -220,8 +228,8 @@ async function runInteractive() {
|
|
|
220
228
|
const recommended = recommendMode(env);
|
|
221
229
|
console.log('');
|
|
222
230
|
console.log(` ${chalk.cyan('Recommended mode:')} ${chalk.bold(recommended)}`);
|
|
223
|
-
// Step 2: Choose mode
|
|
224
|
-
|
|
231
|
+
// Step 2: Choose mode
|
|
232
|
+
stepHeader(2, 6, 'Deployment Mode');
|
|
225
233
|
let mode;
|
|
226
234
|
try {
|
|
227
235
|
mode = await select({
|
|
@@ -252,47 +260,25 @@ async function runInteractive() {
|
|
|
252
260
|
process.exit(0);
|
|
253
261
|
}
|
|
254
262
|
success(`Mode: ${mode}`);
|
|
255
|
-
// Step 3: AI Provider
|
|
256
|
-
|
|
263
|
+
// Step 3: AI Provider
|
|
264
|
+
stepHeader(3, 6, 'AI Provider');
|
|
257
265
|
let anthropicKey;
|
|
258
266
|
let openaiKey;
|
|
259
267
|
let ollamaUrl;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
268
|
+
// Check all provider env vars (not just Anthropic/OpenAI)
|
|
269
|
+
let detectedProviderName = null;
|
|
270
|
+
for (const p of PROVIDER_CATALOG) {
|
|
271
|
+
const val = process.env[p.envVar];
|
|
272
|
+
if (val && val !== '' && !val.startsWith('sk-ant-xxxx') && !val.startsWith('sk-xxxx')) {
|
|
273
|
+
detectedProviderName = p.name;
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (detectedProviderName) {
|
|
278
|
+
info(`AI provider already configured from environment (${detectedProviderName}).`);
|
|
264
279
|
}
|
|
265
280
|
else {
|
|
266
|
-
|
|
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
|
-
];
|
|
281
|
+
const providers = PROVIDER_CATALOG;
|
|
296
282
|
// Check which providers have keys in env
|
|
297
283
|
const detected = new Set();
|
|
298
284
|
for (const p of providers) {
|
|
@@ -306,6 +292,7 @@ async function runInteractive() {
|
|
|
306
292
|
try {
|
|
307
293
|
chosenProvider = await search({
|
|
308
294
|
message: 'Select AI provider (type to filter, arrows to navigate)',
|
|
295
|
+
pageSize: 15,
|
|
309
296
|
source: (term) => {
|
|
310
297
|
const results = [];
|
|
311
298
|
const filter = (term || '').toLowerCase();
|
|
@@ -405,16 +392,25 @@ async function runInteractive() {
|
|
|
405
392
|
info('AI provider skipped. Configure later: profclaw provider');
|
|
406
393
|
}
|
|
407
394
|
}
|
|
395
|
+
// Collect extra env vars that were set during provider selection
|
|
396
|
+
const extraEnvVars = {};
|
|
397
|
+
if (!anthropicKey && !openaiKey && !ollamaUrl) {
|
|
398
|
+
for (const key of PROVIDER_ENV_KEYS) {
|
|
399
|
+
if (process.env[key])
|
|
400
|
+
extraEnvVars[key] = process.env[key];
|
|
401
|
+
}
|
|
402
|
+
}
|
|
408
403
|
// Step 4: Generate .env
|
|
409
|
-
|
|
404
|
+
stepHeader(4, 6, 'Configuration');
|
|
405
|
+
const envPath = join(process.cwd(), '.env');
|
|
410
406
|
if (!env.existingEnv) {
|
|
411
407
|
const envContent = generateEnvFile({
|
|
412
408
|
mode,
|
|
413
409
|
anthropicKey,
|
|
414
410
|
openaiKey,
|
|
415
411
|
ollamaUrl,
|
|
412
|
+
extraEnvVars,
|
|
416
413
|
});
|
|
417
|
-
const envPath = join(process.cwd(), '.env');
|
|
418
414
|
try {
|
|
419
415
|
writeFileSync(envPath, envContent, { mode: 0o600 });
|
|
420
416
|
success('.env file created.');
|
|
@@ -425,60 +421,49 @@ async function runInteractive() {
|
|
|
425
421
|
}
|
|
426
422
|
}
|
|
427
423
|
else {
|
|
428
|
-
info('.env file already exists. Updating PROFCLAW_MODE...');
|
|
429
|
-
const envPath = join(process.cwd(), '.env');
|
|
430
424
|
let content = readFileSync(envPath, 'utf-8');
|
|
425
|
+
// Update mode
|
|
431
426
|
if (content.includes('PROFCLAW_MODE=')) {
|
|
432
427
|
content = content.replace(/PROFCLAW_MODE=\w+/, `PROFCLAW_MODE=${mode}`);
|
|
433
428
|
}
|
|
434
429
|
else {
|
|
435
430
|
content += `\nPROFCLAW_MODE=${mode}\n`;
|
|
436
431
|
}
|
|
432
|
+
// Add provider keys to existing .env
|
|
433
|
+
const keysToWrite = { ...extraEnvVars };
|
|
434
|
+
if (anthropicKey)
|
|
435
|
+
keysToWrite['ANTHROPIC_API_KEY'] = anthropicKey;
|
|
436
|
+
if (openaiKey)
|
|
437
|
+
keysToWrite['OPENAI_API_KEY'] = openaiKey;
|
|
438
|
+
if (ollamaUrl)
|
|
439
|
+
keysToWrite['OLLAMA_BASE_URL'] = ollamaUrl;
|
|
440
|
+
for (const [key, value] of Object.entries(keysToWrite)) {
|
|
441
|
+
if (content.includes(`${key}=`)) {
|
|
442
|
+
content = content.replace(new RegExp(`${key}=.*`), `${key}=${value}`);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
content += `${key}=${value}\n`;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
437
448
|
writeFileSync(envPath, content);
|
|
438
|
-
|
|
449
|
+
const keyCount = Object.keys(keysToWrite).length;
|
|
450
|
+
if (keyCount > 0) {
|
|
451
|
+
success(`PROFCLAW_MODE=${mode} + ${keyCount} provider key(s) saved to .env`);
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
success(`PROFCLAW_MODE=${mode} set in .env`);
|
|
455
|
+
}
|
|
439
456
|
}
|
|
440
|
-
//
|
|
441
|
-
|
|
442
|
-
info('Launching setup wizard for admin account and provider configuration...\n');
|
|
457
|
+
// Steps 5-6: Delegate to setup wizard for admin account + registration
|
|
458
|
+
// Setup continues the step numbering (5/6, 6/6) and shows summary + server start
|
|
443
459
|
try {
|
|
444
460
|
const { setupCommand } = await import('./setup.js');
|
|
445
461
|
const setupCmd = setupCommand();
|
|
446
|
-
await setupCmd.parseAsync(['node', 'setup']);
|
|
462
|
+
await setupCmd.parseAsync(['node', 'setup', '--from-onboard']);
|
|
447
463
|
}
|
|
448
464
|
catch (err) {
|
|
449
465
|
error(`Setup wizard failed: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
|
450
466
|
info('You can run it again later: profclaw setup');
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
// Step 6: Post-setup validation
|
|
454
|
-
console.log(chalk.bold.white('\n Step 6: Validation\n'));
|
|
455
|
-
const postSpin = spinner('Validating installation...');
|
|
456
|
-
postSpin.start();
|
|
457
|
-
const checks = [];
|
|
458
|
-
// Check .env exists
|
|
459
|
-
const envExists = existsSync(join(process.cwd(), '.env'));
|
|
460
|
-
checks.push({ label: '.env file', ok: envExists });
|
|
461
|
-
// Check config exists
|
|
462
|
-
const configExists = existsSync(join(process.cwd(), 'config', 'settings.yml'));
|
|
463
|
-
checks.push({ label: 'config/settings.yml', ok: configExists });
|
|
464
|
-
// Check database was created
|
|
465
|
-
const dbExists = existsSync(join(process.cwd(), 'data', 'profclaw.db'));
|
|
466
|
-
checks.push({ label: 'Database', ok: dbExists });
|
|
467
|
-
postSpin.stop();
|
|
468
|
-
for (const check of checks) {
|
|
469
|
-
const icon = check.ok ? chalk.green(' +') : chalk.red(' -');
|
|
470
|
-
console.log(`${icon} ${check.label}: ${check.ok ? 'OK' : 'missing'}`);
|
|
471
|
-
}
|
|
472
|
-
const allPassed = checks.every((c) => c.ok);
|
|
473
|
-
if (allPassed) {
|
|
474
|
-
console.log('');
|
|
475
|
-
success('Onboarding complete! Start the server:');
|
|
476
|
-
console.log(`\n ${chalk.cyan.bold('profclaw serve')}\n`);
|
|
477
|
-
}
|
|
478
|
-
else {
|
|
479
|
-
console.log('');
|
|
480
|
-
warn('Some checks did not pass. You may need to run setup again:');
|
|
481
|
-
console.log(`\n ${chalk.cyan('profclaw setup')}\n`);
|
|
482
467
|
}
|
|
483
468
|
}
|
|
484
469
|
// Non-Interactive Onboarding
|