neoagent 2.3.1-beta.103 → 2.3.1-beta.105

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/lib/manager.js CHANGED
@@ -797,7 +797,7 @@ async function cmdLoginClaudeCode() {
797
797
  const data = JSON.parse(raw);
798
798
  const token = data?.claudeAiOauthTokens?.accessToken;
799
799
  if (token) {
800
- upsertEnvValue('CLAUDE_CODE_ACCESS_TOKEN', token);
800
+ upsertEnvValue('CLAUDE_CODE_OAUTH_TOKEN', token);
801
801
  logOk('Imported access token from Claude CLI credentials store');
802
802
  logInfo('Restarting NeoAgent to apply credentials...');
803
803
  cmdRestart();
@@ -806,13 +806,34 @@ async function cmdLoginClaudeCode() {
806
806
  } catch { }
807
807
  }
808
808
 
809
- // Fall back to browser-based PKCE OAuth flow
809
+ // Browser-based PKCE OAuth flow.
810
+ // client_id is the metadata URL per claude.ai's dynamic client registration.
811
+ // Redirect URIs registered: http://localhost/callback and http://127.0.0.1/callback (port 80).
812
+ // Per RFC 8252 §7.3, servers SHOULD allow any loopback port — we try high ports first
813
+ // and fall back to 80 if everything else is occupied.
810
814
  const http = require('http');
811
815
  const { URL: NodeURL } = require('url');
816
+ const net = require('net');
812
817
 
813
- const clientId = '9d1c250a-e61b-48f7-87a4-b8a14c8a8f5e';
814
- const redirectPort = 54321;
815
- const redirectUri = `http://localhost:${redirectPort}/callback`;
818
+ const clientId = '9d1c250a-e61b-44d9-88ed-5944d1962f5e';
819
+ const SCOPES = 'user:inference user:profile org:create_api_key user:sessions:claude_code user:mcp_servers';
820
+
821
+ // Find a free port (prefer high ports to avoid permission issues; fall back to 80)
822
+ const preferredPorts = [65432, 58080, 54321, 49152, 80];
823
+ let redirectPort = null;
824
+
825
+ for (const p of preferredPorts) {
826
+ const free = await new Promise((res) => {
827
+ const probe = net.createServer();
828
+ probe.listen(p, '127.0.0.1', () => { probe.close(() => res(true)); });
829
+ probe.on('error', () => res(false));
830
+ });
831
+ if (free) { redirectPort = p; break; }
832
+ }
833
+
834
+ if (!redirectPort) throw new Error('Could not find a free local port for the OAuth callback.');
835
+
836
+ const redirectUri = `http://127.0.0.1${redirectPort === 80 ? '' : `:${redirectPort}`}/callback`;
816
837
 
817
838
  // Generate PKCE verifier and challenge
818
839
  const codeVerifier = crypto.randomBytes(48).toString('base64url');
@@ -823,11 +844,11 @@ async function cmdLoginClaudeCode() {
823
844
 
824
845
  const state = crypto.randomBytes(16).toString('hex');
825
846
 
826
- const authUrl = new URL('https://claude.ai/oauth/authorize');
847
+ const authUrl = new URL('https://platform.claude.com/oauth/authorize');
827
848
  authUrl.searchParams.set('response_type', 'code');
828
849
  authUrl.searchParams.set('client_id', clientId);
829
850
  authUrl.searchParams.set('redirect_uri', redirectUri);
830
- authUrl.searchParams.set('scope', 'openid profile email offline_access');
851
+ authUrl.searchParams.set('scope', SCOPES);
831
852
  authUrl.searchParams.set('code_challenge', codeChallenge);
832
853
  authUrl.searchParams.set('code_challenge_method', 'S256');
833
854
  authUrl.searchParams.set('state', state);
@@ -851,7 +872,7 @@ async function cmdLoginClaudeCode() {
851
872
 
852
873
  const server = http.createServer((req, res) => {
853
874
  try {
854
- const reqUrl = new NodeURL(req.url, `http://localhost:${redirectPort}`);
875
+ const reqUrl = new NodeURL(req.url, redirectUri);
855
876
  const code = reqUrl.searchParams.get('code');
856
877
  const returnedState = reqUrl.searchParams.get('state');
857
878
  const error = reqUrl.searchParams.get('error');
@@ -897,7 +918,7 @@ async function cmdLoginClaudeCode() {
897
918
  });
898
919
 
899
920
  logInfo('Exchanging authorization code for access token...');
900
- const tokenRes = await fetch('https://claude.ai/api/oauth/token', {
921
+ const tokenRes = await fetch('https://platform.claude.com/v1/oauth/token', {
901
922
  method: 'POST',
902
923
  headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
903
924
  body: JSON.stringify({
@@ -920,11 +941,11 @@ async function cmdLoginClaudeCode() {
920
941
  throw new Error('Token exchange succeeded but no access_token was returned.');
921
942
  }
922
943
 
923
- upsertEnvValue('CLAUDE_CODE_ACCESS_TOKEN', accessToken);
944
+ upsertEnvValue('CLAUDE_CODE_OAUTH_TOKEN', accessToken);
924
945
  if (tokenData.refresh_token) {
925
946
  upsertEnvValue('CLAUDE_CODE_REFRESH_TOKEN', tokenData.refresh_token);
926
947
  }
927
- logOk('Saved Claude Code access token to .env');
948
+ logOk('Saved Claude Code OAuth token to .env');
928
949
  logInfo('Restarting NeoAgent to apply credentials...');
929
950
  cmdRestart();
930
951
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.3.1-beta.103",
3
+ "version": "2.3.1-beta.105",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -1 +1 @@
1
- 11c4133ebb724b223b80ad380661a4c1
1
+ 338e1871f3b43cdb434b7f44e7bb3256
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"42d3d75a56efe1a2e9902f52dc8006099c45d9
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "1865794536" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "4244290377" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });
@@ -129338,7 +129338,7 @@ r===$&&A.b()
129338
129338
  o.push(A.ii(p,A.iY(!1,new A.a3(B.tM,A.dT(new A.cI(B.he,new A.a5V(r,p),p),p,p),p),!1,B.I,!0),p,p,0,0,0,p))}r=!1
129339
129339
  if(!s.ay)if(!s.ch){r=s.e
129340
129340
  r===$&&A.b()
129341
- r=B.b.t("mpacm3gu-abb7f02").length!==0&&r.b}if(r){r=s.d
129341
+ r=B.b.t("mpad8vys-1c837fe").length!==0&&r.b}if(r){r=s.d
129342
129342
  r===$&&A.b()
129343
129343
  r=r.ag&&!r.V?84:0
129344
129344
  q=s.e
@@ -134146,7 +134146,7 @@ $S:236}
134146
134146
  A.Ys.prototype={}
134147
134147
  A.Rr.prototype={
134148
134148
  mT(a){var s=this
134149
- if(B.b.t("mpacm3gu-abb7f02").length===0||s.a!=null)return
134149
+ if(B.b.t("mpad8vys-1c837fe").length===0||s.a!=null)return
134150
134150
  s.A5()
134151
134151
  s.a=A.q1(B.PP,new A.b58(s))},
134152
134152
  A5(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f
@@ -134164,7 +134164,7 @@ if(!t.f.b(k)){s=1
134164
134164
  break}i=J.Z(k,"buildId")
134165
134165
  h=i==null?null:B.b.t(J.r(i))
134166
134166
  j=h==null?"":h
134167
- if(J.bm(j)===0||J.d(j,"mpacm3gu-abb7f02")){s=1
134167
+ if(J.bm(j)===0||J.d(j,"mpad8vys-1c837fe")){s=1
134168
134168
  break}n.b=!0
134169
134169
  n.D()
134170
134170
  p=2
@@ -134181,7 +134181,7 @@ case 2:return A.i(o.at(-1),r)}})
134181
134181
  return A.k($async$A5,r)},
134182
134182
  vb(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1
134183
134183
  var $async$vb=A.h(function(a2,a3){if(a2===1){o.push(a3)
134184
- s=p}for(;;)switch(s){case 0:if(B.b.t("mpacm3gu-abb7f02").length===0||n.c){s=1
134184
+ s=p}for(;;)switch(s){case 0:if(B.b.t("mpad8vys-1c837fe").length===0||n.c){s=1
134185
134185
  break}n.c=!0
134186
134186
  n.D()
134187
134187
  p=4
@@ -33,7 +33,7 @@ class ClaudeCodeProvider extends AnthropicProvider {
33
33
  'claude-haiku-4-5-20251001': 200000,
34
34
  };
35
35
 
36
- const authToken = config.apiKey || process.env.CLAUDE_CODE_ACCESS_TOKEN || readClaudeCliToken();
36
+ const authToken = config.apiKey || process.env.CLAUDE_CODE_OAUTH_TOKEN || readClaudeCliToken();
37
37
  if (!authToken) {
38
38
  console.warn('[ClaudeCode] No access token. Run `neoagent login claude-code` to authenticate.');
39
39
  }
@@ -83,7 +83,7 @@ const AI_PROVIDER_DEFINITIONS = Object.freeze({
83
83
  id: 'claude-code',
84
84
  label: 'Claude Code',
85
85
  description: 'Claude models via Claude Code subscription. Login with `neoagent login claude-code`.',
86
- envKey: 'CLAUDE_CODE_ACCESS_TOKEN',
86
+ envKey: 'CLAUDE_CODE_OAUTH_TOKEN',
87
87
  supportsApiKey: true,
88
88
  supportsBaseUrl: false,
89
89
  defaultEnabled: false,