@openagents-org/agent-launcher 0.2.188 → 0.2.189

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagents-org/agent-launcher",
3
- "version": "0.2.188",
3
+ "version": "0.2.189",
4
4
  "description": "OpenAgents Launcher \u2014 install, configure, and run AI coding agents from your terminal",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/registry.json CHANGED
@@ -333,6 +333,10 @@
333
333
  "env_vars": [
334
334
  "CURSOR_API_KEY"
335
335
  ],
336
+ "creds_file": "~/.cursor/cli-config.json",
337
+ "creds_key": "authInfo",
338
+ "creds_no_parse": true,
339
+ "unverifiable": true,
336
340
  "login_command": "cursor-agent login"
337
341
  },
338
342
  "env_config": [
@@ -31,6 +31,41 @@ const OPENCLAW_STATE_DIR = path.join(
31
31
  '.openclaw'
32
32
  );
33
33
 
34
+ /**
35
+ * Archive the legacy auth-profiles.json this adapter used to write.
36
+ *
37
+ * Current OpenClaw keeps credentials in SQLite and refuses to run while a
38
+ * legacy JSON store sits beside an empty one ("requires legacy credential
39
+ * migration; run openclaw doctor --fix"); beside a populated one it silently
40
+ * ignores the file, so a changed key never took effect either. The key now
41
+ * reaches OpenClaw through the env and openclaw.json, so the file only gets
42
+ * in the way.
43
+ *
44
+ * Only a file made entirely of our entries is moved: the `custom` provider
45
+ * exists only because configureNativeAuth created it, and any other entry must
46
+ * carry a key we hold ourselves. A profile the user made (OpenClaw's own
47
+ * paste-token also names them `<provider>:manual`) keeps the file in place,
48
+ * for `openclaw doctor --fix` to migrate. Renamed, never deleted.
49
+ *
50
+ * @param {Array<string|undefined>} knownKeys API keys this agent is configured with
51
+ */
52
+ function retireOwnLegacyAuthProfiles(knownKeys) {
53
+ const file = path.join(OPENCLAW_STATE_DIR, 'agents', 'main', 'agent', 'auth-profiles.json');
54
+ let data;
55
+ try { data = JSON.parse(fs.readFileSync(file, 'utf-8')); } catch { return false; }
56
+ const keys = new Set((knownKeys || []).filter(Boolean));
57
+ const profiles = Object.values((data && data.profiles) || {});
58
+ const ours = profiles.every((p) => p && p.type === 'token'
59
+ && (p.provider === 'custom' || keys.has(p.token)));
60
+ if (!ours) return false;
61
+ try {
62
+ fs.renameSync(file, `${file}.openagents-retired`);
63
+ return true;
64
+ } catch {
65
+ return false;
66
+ }
67
+ }
68
+
34
69
  class OpenClawAdapter extends BaseAdapter {
35
70
  /**
36
71
  * @param {object} opts - BaseAdapter opts plus:
@@ -54,6 +89,14 @@ class OpenClawAdapter extends BaseAdapter {
54
89
  this._log('OpenClaw binary not found — agent will not be able to process messages');
55
90
  }
56
91
 
92
+ // Agents configured before the key stopped going into auth-profiles.json
93
+ // still have that file; clear it before the first run rather than on the
94
+ // next save.
95
+ const env = this.agentEnv || {};
96
+ if (retireOwnLegacyAuthProfiles([env.LLM_API_KEY, env.OPENAI_API_KEY, env.ANTHROPIC_API_KEY])) {
97
+ this._log('Archived the legacy auth-profiles.json this launcher wrote (OpenClaw now stores credentials in SQLite)');
98
+ }
99
+
57
100
  // Install workspace skill
58
101
  this._installWorkspaceSkill();
59
102
  }
@@ -586,9 +629,10 @@ class OpenClawAdapter extends BaseAdapter {
586
629
  * LLM_API_KEY / LLM_BASE_URL / LLM_MODEL values.
587
630
  * Called by the Launcher's saveAgentEnv when type === 'openclaw'.
588
631
  *
589
- * For standard providers (OpenAI, Anthropic), uses auth-profiles.json.
590
- * For custom endpoints, uses models.providers in openclaw.json which
591
- * gives full tool support via the CLI gateway mode.
632
+ * For standard providers (OpenAI, Anthropic), the key travels in the env
633
+ * and only the model is set here. For custom endpoints, uses
634
+ * models.providers in openclaw.json which gives full tool support via the
635
+ * CLI gateway mode.
592
636
  */
593
637
  static configureNativeAuth(env) {
594
638
  const apiKey = env.LLM_API_KEY;
@@ -602,26 +646,19 @@ class OpenClawAdapter extends BaseAdapter {
602
646
  const isAnthropic = baseUrl.includes('api.anthropic.com');
603
647
  const configFile = path.join(OPENCLAW_STATE_DIR, 'openclaw.json');
604
648
 
649
+ // The key itself never goes into auth-profiles.json any more: current
650
+ // OpenClaw keeps credentials in SQLite and refuses to start while a legacy
651
+ // JSON store sits beside an empty one ("requires legacy credential
652
+ // migration; run openclaw doctor --fix"). A standard provider reads the
653
+ // key from the OPENAI_API_KEY / ANTHROPIC_API_KEY the resolve rules put
654
+ // in its env; a custom one from models.providers below.
655
+ retireOwnLegacyAuthProfiles([apiKey]);
656
+
605
657
  if (isOpenAI || isAnthropic) {
606
- // Standard provider — use auth-profiles.json
607
658
  const provider = isAnthropic ? 'anthropic' : 'openai';
608
- const profileId = `${provider}:manual`;
609
- const agentDir = path.join(OPENCLAW_STATE_DIR, 'agents', 'main', 'agent');
610
-
611
- try {
612
- fs.mkdirSync(agentDir, { recursive: true });
613
- const authFile = path.join(agentDir, 'auth-profiles.json');
614
- let authData = { version: 1, profiles: {} };
615
- try { authData = JSON.parse(fs.readFileSync(authFile, 'utf-8')); } catch {}
616
- authData.profiles = authData.profiles || {};
617
- authData.profiles[profileId] = { type: 'token', provider, token: apiKey };
618
- authData.lastGood = authData.lastGood || {};
619
- authData.lastGood[provider] = profileId;
620
- fs.writeFileSync(authFile, JSON.stringify(authData, null, 2), 'utf-8');
621
- } catch {}
622
-
623
659
  // Set model
624
660
  try {
661
+ fs.mkdirSync(OPENCLAW_STATE_DIR, { recursive: true });
625
662
  let config = {};
626
663
  try { config = JSON.parse(fs.readFileSync(configFile, 'utf-8')); } catch {}
627
664
  config.agents = config.agents || {};
@@ -653,22 +690,9 @@ class OpenClawAdapter extends BaseAdapter {
653
690
 
654
691
  fs.writeFileSync(configFile, JSON.stringify(config, null, 2), 'utf-8');
655
692
  } catch {}
656
-
657
- // Also write auth-profiles.json for the custom provider
658
- try {
659
- const agentDir = path.join(OPENCLAW_STATE_DIR, 'agents', 'main', 'agent');
660
- fs.mkdirSync(agentDir, { recursive: true });
661
- const authFile = path.join(agentDir, 'auth-profiles.json');
662
- let authData = { version: 1, profiles: {} };
663
- try { authData = JSON.parse(fs.readFileSync(authFile, 'utf-8')); } catch {}
664
- authData.profiles = authData.profiles || {};
665
- authData.profiles['custom:manual'] = { type: 'token', provider: 'custom', token: apiKey };
666
- authData.lastGood = authData.lastGood || {};
667
- authData.lastGood.custom = 'custom:manual';
668
- fs.writeFileSync(authFile, JSON.stringify(authData, null, 2), 'utf-8');
669
- } catch {}
670
693
  }
671
694
  }
672
695
  }
673
696
 
674
697
  module.exports = OpenClawAdapter;
698
+ module.exports.retireOwnLegacyAuthProfiles = retireOwnLegacyAuthProfiles;