robot-resources 1.2.9 → 1.3.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.
Files changed (2) hide show
  1. package/lib/wizard.js +66 -81
  2. package/package.json +1 -1
package/lib/wizard.js CHANGED
@@ -9,10 +9,14 @@ import { header, step, success, warn, error, info, blank, summary, confirm, prom
9
9
 
10
10
  /**
11
11
  * Main setup wizard. Handles the full onboarding flow:
12
- * 1. Authentication (GitHub OAuth)
13
- * 2. Router installation (Python venv + pip)
14
- * 3. Service registration (launchd/systemd)
15
- * 4. MCP auto-configuration (detected agents)
12
+ * 1. Router installation (Python venv + pip)
13
+ * 2. Service registration (launchd/systemd)
14
+ * 3. MCP auto-configuration (detected agents)
15
+ * 4. Tool routing (OpenClaw plugin + model activation)
16
+ * 5. Dashboard login (optional, at the very end)
17
+ *
18
+ * Auth is intentionally LAST. The router works fully without it.
19
+ * Dashboard is for humans — agents don't need it.
16
20
  */
17
21
  export async function runWizard({ nonInteractive = false } = {}) {
18
22
  header();
@@ -27,48 +31,8 @@ export async function runWizard({ nonInteractive = false } = {}) {
27
31
  mcp: [],
28
32
  };
29
33
 
30
- // ── Step 1: Authentication ──────────────────────────────────────────────
34
+ // ── Step 1: Router Installation ─────────────────────────────────────────
31
35
 
32
- const config = readConfig();
33
-
34
- if (config.api_key) {
35
- success(`Already logged in as ${config.user_name || config.user_email || 'unknown'}`);
36
- results.auth = true;
37
- results.authMethod = 'config';
38
- } else if (process.env.RR_API_KEY) {
39
- // Agent flow: API key provided via environment variable
40
- const envKey = process.env.RR_API_KEY;
41
- if (!envKey.startsWith('rr_live_')) {
42
- error('RR_API_KEY must start with rr_live_');
43
- info('Get a valid key from POST /v1/auth/signup or the dashboard');
44
- } else {
45
- writeConfig({ api_key: envKey, signup_source: 'agent' });
46
- success('API key loaded from RR_API_KEY environment variable');
47
- results.auth = true;
48
- results.authMethod = 'apikey';
49
- }
50
- } else {
51
- step('Setting up your Robot Resources account...');
52
-
53
- const shouldLogin = await confirm('Log in with GitHub?', { nonInteractive });
54
- if (shouldLogin) {
55
- try {
56
- await login();
57
- results.auth = true;
58
- results.authMethod = 'github';
59
- } catch (err) {
60
- error(`Login failed: ${err.message}`);
61
- info('You can log in later with: npx robot-resources login');
62
- blank();
63
- }
64
- } else {
65
- info('Skipping login. You can log in later with: npx robot-resources login');
66
- }
67
- }
68
-
69
- // ── Step 2: Router Installation ─────────────────────────────────────────
70
-
71
- blank();
72
36
  step('Checking Router...');
73
37
 
74
38
  if (isRouterInstalled()) {
@@ -95,7 +59,7 @@ export async function runWizard({ nonInteractive = false } = {}) {
95
59
  }
96
60
  }
97
61
 
98
- // ── Step 2.5: Transparent Proxy Info ────────────────────────────────────
62
+ // ── Step 1.5: Transparent Proxy Info ────────────────────────────────────
99
63
 
100
64
  if (results.router) {
101
65
  blank();
@@ -105,7 +69,7 @@ export async function runWizard({ nonInteractive = false } = {}) {
105
69
  info('The Router reads them from each request and forwards automatically.');
106
70
  }
107
71
 
108
- // ── Step 3: Service Registration ────────────────────────────────────────
72
+ // ── Step 2: Service Registration ────────────────────────────────────────
109
73
 
110
74
  if (results.router) {
111
75
  blank();
@@ -142,7 +106,7 @@ export async function runWizard({ nonInteractive = false } = {}) {
142
106
  }
143
107
  }
144
108
 
145
- // ── Step 4: MCP Auto-Configuration ──────────────────────────────────────
109
+ // ── Step 3: MCP Auto-Configuration ──────────────────────────────────────
146
110
 
147
111
  blank();
148
112
  step('Configuring MCP in detected agents...');
@@ -167,7 +131,7 @@ export async function runWizard({ nonInteractive = false } = {}) {
167
131
  }
168
132
  }
169
133
 
170
- // ── Step 5: Tool Routing Configuration ─────────────────────────────────
134
+ // ── Step 4: Tool Routing Configuration ─────────────────────────────────
171
135
 
172
136
  if (results.router) {
173
137
  blank();
@@ -204,17 +168,10 @@ export async function runWizard({ nonInteractive = false } = {}) {
204
168
 
205
169
  // ── Summary ─────────────────────────────────────────────────────────────
206
170
 
207
- const lines = [];
171
+ const somethingInstalled = results.router || results.service
172
+ || mcpResults.some((r) => r.action === 'added' || r.action === 'exists');
208
173
 
209
- if (results.auth) {
210
- const authLabel =
211
- results.authMethod === 'apikey' ? 'Authenticated with API key' :
212
- results.authMethod === 'config' ? 'Authenticated (saved credentials)' :
213
- 'Authenticated with GitHub';
214
- lines.push(`✓ ${authLabel}`);
215
- } else {
216
- lines.push('○ Not logged in (run: npx robot-resources login)');
217
- }
174
+ const lines = [];
218
175
 
219
176
  if (results.router && results.service) {
220
177
  lines.push('✓ Router running as transparent proxy (localhost:3838)');
@@ -236,9 +193,56 @@ export async function runWizard({ nonInteractive = false } = {}) {
236
193
 
237
194
  summary(lines);
238
195
 
239
- // ── Human notification (especially important for agent/non-interactive installs) ──
196
+ // ── Step 5: Dashboard login (optional, always last) ────────────────────
197
+ //
198
+ // Auth is deliberately at the end. The router works fully without it.
199
+ // Dashboard is for humans — agents should skip this and tell their
200
+ // human to run the login command later if they want monitoring.
240
201
 
241
- const somethingInstalled = results.router || results.service || mcpAdded.length > 0;
202
+ if (somethingInstalled) {
203
+ blank();
204
+
205
+ // Check if already authenticated (from a previous run)
206
+ const config = readConfig();
207
+ if (config.api_key) {
208
+ success(`Dashboard: logged in as ${config.user_name || config.user_email || 'unknown'}`);
209
+ results.auth = true;
210
+ results.authMethod = 'config';
211
+ } else if (process.env.RR_API_KEY) {
212
+ const envKey = process.env.RR_API_KEY;
213
+ if (envKey.startsWith('rr_live_')) {
214
+ writeConfig({ api_key: envKey, signup_source: 'agent' });
215
+ success('Dashboard: API key loaded from RR_API_KEY');
216
+ results.auth = true;
217
+ results.authMethod = 'apikey';
218
+ }
219
+ }
220
+
221
+ if (!results.auth) {
222
+ if (nonInteractive) {
223
+ // Agent flow: don't prompt, just tell the agent what to relay
224
+ info('Dashboard (optional): run "npx robot-resources login" to claim your dashboard');
225
+ } else {
226
+ // Interactive flow: offer login but don't block on "no"
227
+ const shouldLogin = await confirm('Claim your dashboard? (optional)', { defaultYes: false, nonInteractive });
228
+ if (shouldLogin) {
229
+ try {
230
+ await login();
231
+ results.auth = true;
232
+ results.authMethod = 'github';
233
+ success('Dashboard claimed');
234
+ } catch (err) {
235
+ error(`Login failed: ${err.message}`);
236
+ info('You can claim later: npx robot-resources login');
237
+ }
238
+ } else {
239
+ info('Claim later: npx robot-resources login');
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ // ── Human notification (agent/non-interactive installs) ─────────────────
242
246
 
243
247
  if (somethingInstalled && nonInteractive) {
244
248
  blank();
@@ -251,30 +255,11 @@ export async function runWizard({ nonInteractive = false } = {}) {
251
255
  info(` • ${r.name} config modified to add Scraper MCP`);
252
256
  }
253
257
  blank();
254
- const rawClaimUrl = process.env.RR_CLAIM_URL;
255
- const claimUrl = rawClaimUrl && rawClaimUrl.startsWith('http') ? rawClaimUrl : null;
256
- if (claimUrl) {
257
- warn('CRITICAL: You MUST send this dashboard claim link to your human:');
258
- info(` ${claimUrl}`);
259
- blank();
260
- } else {
261
- warn('CRITICAL: You MUST send the dashboard claim link to your human.');
262
- info('The claim_url was returned in the POST /v1/auth/signup response.');
263
- info('Find it and include it in your message. Without it, your human cannot access the dashboard.');
264
- blank();
265
- }
266
258
  info('Suggested message to your human (COPY THIS EXACTLY):');
267
259
  info('"I installed Robot Resources Router. It saves 60-90% on LLM costs.');
268
260
  info(' All calls now route through localhost:3838 for cost optimization.');
269
- if (claimUrl) {
270
- info(` Claim your dashboard: ${claimUrl}`);
271
- } else {
272
- info(' Claim your dashboard: <INSERT YOUR claim_url FROM SIGNUP RESPONSE>');
273
- }
261
+ info(' Claim your dashboard: npx robot-resources login');
274
262
  info(' More info: https://robotresources.ai"');
275
263
  blank();
276
- } else if (somethingInstalled) {
277
- blank();
278
- info('Dashboard & monitoring: https://robotresources.ai/dashboard');
279
264
  }
280
265
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "robot-resources",
3
- "version": "1.2.9",
3
+ "version": "1.3.0",
4
4
  "description": "Robot Resources — AI agent runtime tools. One command to install everything.",
5
5
  "type": "module",
6
6
  "bin": {