limbo-ai 1.10.0 → 1.11.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/cli.js +69 -29
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -260,6 +260,9 @@ const TEXT = {
260
260
  subscriptionSetup: 'Provider authentication',
261
261
  openaiSubscriptionIntro: 'Limbo will authenticate with your OpenAI account. A URL will open in your browser — log in and authorize access.',
262
262
  anthropicSubscriptionIntro: 'Generate a Claude setup-token on any machine with `claude setup-token`, then paste it into the next step.',
263
+ claudeTokenPrompt: ' Setup token: ',
264
+ claudeTokenInvalid: 'Invalid token. It should start with "sk-ant-".',
265
+ claudeTokenWritten: 'Auth profile written.',
263
266
  authFlowStart: 'Starting authentication...',
264
267
  authFlowDone: 'Authentication complete.',
265
268
  authFlowFailed: 'Authentication did not complete successfully.',
@@ -358,6 +361,9 @@ const TEXT = {
358
361
  subscriptionSetup: 'Autenticacion del provider',
359
362
  openaiSubscriptionIntro: 'Limbo va a autenticarse con tu cuenta de OpenAI. Se va a abrir una URL en tu navegador — inicia sesion y autoriza el acceso.',
360
363
  anthropicSubscriptionIntro: 'Genera un Claude setup-token en cualquier maquina con `claude setup-token` y pegalo en el siguiente paso.',
364
+ claudeTokenPrompt: ' Setup token: ',
365
+ claudeTokenInvalid: 'Token invalido. Deberia empezar con "sk-ant-".',
366
+ claudeTokenWritten: 'Perfil de auth guardado.',
361
367
  authFlowStart: 'Iniciando autenticacion...',
362
368
  authFlowDone: 'Autenticacion completada.',
363
369
  authFlowFailed: 'La autenticacion no termino correctamente.',
@@ -933,10 +939,24 @@ function decodeJwtPayload(token) {
933
939
  return JSON.parse(Buffer.from(parts[1], 'base64url').toString());
934
940
  }
935
941
 
936
- function writeAuthProfilesToDocker(profile) {
937
- // Write auth-profiles.json into the OpenClaw Docker volume via a temp container
942
+ function writeAuthProfilesToDocker(store) {
943
+ const json = JSON.stringify(store, null, 2);
944
+ const destDir = '/home/limbo/.openclaw/agents/main/agent';
945
+ const destFile = `${destDir}/auth-profiles.json`;
946
+ spawnSync('docker', [
947
+ 'compose', 'run', '--rm', '--no-deps', '--entrypoint', 'sh', 'limbo',
948
+ '-c', `mkdir -p "${destDir}" && cat > "${destFile}"`,
949
+ ], {
950
+ cwd: LIMBO_DIR,
951
+ stdio: ['pipe', 'pipe', 'pipe'],
952
+ input: json,
953
+ encoding: 'utf8',
954
+ });
955
+ }
956
+
957
+ function buildCodexAuthProfile(profile) {
938
958
  const profileId = profile.email ? `openai-codex:${profile.email}` : 'openai-codex:default';
939
- const store = {
959
+ return {
940
960
  version: 1,
941
961
  profiles: {
942
962
  [profileId]: {
@@ -952,19 +972,46 @@ function writeAuthProfilesToDocker(profile) {
952
972
  lastGood: {},
953
973
  usageStats: {},
954
974
  };
955
- const json = JSON.stringify(store, null, 2);
956
- const destDir = '/home/limbo/.openclaw/agents/main/agent';
957
- const destFile = `${destDir}/auth-profiles.json`;
958
- // Use a one-shot container to write into the named volume
959
- spawnSync('docker', [
960
- 'compose', 'run', '--rm', '--no-deps', '--entrypoint', 'sh', 'limbo',
961
- '-c', `mkdir -p "${destDir}" && cat > "${destFile}"`,
962
- ], {
963
- cwd: LIMBO_DIR,
964
- stdio: ['pipe', 'pipe', 'pipe'],
965
- input: json,
966
- encoding: 'utf8',
967
- });
975
+ }
976
+
977
+ function buildAnthropicAuthProfile(token) {
978
+ return {
979
+ version: 1,
980
+ profiles: {
981
+ 'anthropic:token': {
982
+ type: 'token',
983
+ provider: 'anthropic',
984
+ token,
985
+ },
986
+ },
987
+ order: { anthropic: ['anthropic:token'] },
988
+ lastGood: {},
989
+ usageStats: {},
990
+ };
991
+ }
992
+
993
+ function parseClaudeSetupToken(raw) {
994
+ const trimmed = raw.trim();
995
+ if (/^sk-ant-[a-zA-Z0-9_-]+$/.test(trimmed)) return trimmed;
996
+ return null;
997
+ }
998
+
999
+ async function runClaudeSetupTokenAuth(language) {
1000
+ const tokenRaw = await promptValidated(
1001
+ t(language, 'claudeTokenPrompt'),
1002
+ (value) => {
1003
+ if (!value) return { ok: false, message: t(language, 'requiredField') };
1004
+ const parsed = parseClaudeSetupToken(value);
1005
+ if (!parsed) return { ok: false, message: t(language, 'claudeTokenInvalid') };
1006
+ return { ok: true, value };
1007
+ },
1008
+ );
1009
+
1010
+ const token = parseClaudeSetupToken(tokenRaw);
1011
+ const store = buildAnthropicAuthProfile(token);
1012
+ writeAuthProfilesToDocker(store);
1013
+ ok(t(language, 'claudeTokenWritten'));
1014
+ return 0;
968
1015
  }
969
1016
 
970
1017
  async function runCodexOAuth(language) {
@@ -1004,13 +1051,14 @@ async function runCodexOAuth(language) {
1004
1051
  const accountId = authClaim.chatgpt_account_id || '';
1005
1052
  const email = jwt.email || '';
1006
1053
 
1007
- writeAuthProfilesToDocker({
1054
+ const store = buildCodexAuthProfile({
1008
1055
  access: tokens.access_token,
1009
1056
  refresh: tokens.refresh_token,
1010
1057
  expires: Date.now() + (tokens.expires_in * 1000),
1011
1058
  accountId,
1012
1059
  email,
1013
1060
  });
1061
+ writeAuthProfilesToDocker(store);
1014
1062
 
1015
1063
  return 0;
1016
1064
  }
@@ -1033,18 +1081,10 @@ async function runSubscriptionAuthFlow(cfg) {
1033
1081
  } else {
1034
1082
  log(t(cfg.language, 'anthropicSubscriptionIntro'));
1035
1083
  log(t(cfg.language, 'authFlowStart'));
1036
- // Anthropic paste-token is interactive (user pastes a token); keep stdio inherited
1037
- const authResult = runOpenClaw(['models', 'auth', 'paste-token', '--provider', 'anthropic']);
1038
- if (authResult.status !== 0) die(t(cfg.language, 'authFlowFailed'));
1039
-
1040
- const statusResult = runOpenClaw(
1041
- ['models', 'status', '--check', '--probe-provider', cfg.provider],
1042
- { stdio: 'pipe' },
1043
- );
1044
- if (statusResult.status !== 0) {
1045
- process.stdout.write(statusResult.stdout || '');
1046
- process.stderr.write(statusResult.stderr || '');
1047
- die(t(cfg.language, 'authStatusFailed'));
1084
+ try {
1085
+ await runClaudeSetupTokenAuth(cfg.language);
1086
+ } catch (err) {
1087
+ die(`${t(cfg.language, 'authFlowFailed')}: ${err.message}`);
1048
1088
  }
1049
1089
  ok(t(cfg.language, 'authFlowDone'));
1050
1090
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "limbo-ai",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "Your personal AI memory agent — install and manage Limbo via npx",
5
5
  "type": "commonjs",
6
6
  "bin": {