limbo-ai 1.9.0 → 1.9.2

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 +20 -16
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -256,6 +256,7 @@ const TEXT = {
256
256
  anthropicSubscriptionIntro: 'Generate a Claude setup-token on any machine with `claude setup-token`, then paste it into the next step.',
257
257
  authFlowStart: 'Starting authentication...',
258
258
  authFlowDone: 'Authentication complete.',
259
+ modelConnected: (model) => `Model connected: ${model}`,
259
260
  authFlowFailed: 'Authentication did not complete successfully.',
260
261
  authStatusFailed: 'Provider auth is still missing or invalid. Try running with --reconfigure.',
261
262
  configFlowStart: 'Applying configuration...',
@@ -348,6 +349,7 @@ const TEXT = {
348
349
  anthropicSubscriptionIntro: 'Genera un Claude setup-token en cualquier maquina con `claude setup-token` y pegalo en el siguiente paso.',
349
350
  authFlowStart: 'Iniciando autenticacion...',
350
351
  authFlowDone: 'Autenticacion completada.',
352
+ modelConnected: (model) => `Modelo conectado: ${model}`,
351
353
  authFlowFailed: 'La autenticacion no termino correctamente.',
352
354
  authStatusFailed: 'La autenticacion del provider sigue siendo invalida o no esta configurada. Proba con --reconfigure.',
353
355
  configFlowStart: 'Aplicando configuracion...',
@@ -809,8 +811,12 @@ function applyOpenClawConfig(cfg) {
809
811
  ok(t(cfg.language, 'configFlowDone'));
810
812
  }
811
813
 
814
+ // Strip ANSI escape sequences so URL/text matching works on TTY output.
815
+ const stripAnsi = (str) => str.replace(/\x1b\[[0-9;]*[A-Za-z]/g, '').replace(/\r/g, '');
816
+
812
817
  // Spawn OpenClaw auth with filtered output: extract OAuth URLs, suppress branding.
813
- // Uses async spawn so URLs appear in real-time (spawnSync would buffer until exit).
818
+ // --tty is required so openclaw sees a TTY inside the container and runs the auth wizard.
819
+ // We pipe stdout/stderr to filter content while the container gets a proper PTY allocation.
814
820
  function streamFilteredAuth(dockerArgs) {
815
821
  return new Promise((resolve) => {
816
822
  const proc = spawn('docker', dockerArgs, {
@@ -824,25 +830,22 @@ function streamFilteredAuth(dockerArgs) {
824
830
 
825
831
  const handleData = (data) => {
826
832
  buf += data.toString();
827
- const lines = buf.split('\n');
833
+ // Split on \r\n, \n, or bare \r — TUIs use carriage returns for in-place redraws
834
+ const lines = buf.split(/\r?\n|\r/);
828
835
  buf = lines.pop(); // hold incomplete last line
829
836
  for (const line of lines) emitLine(line);
830
837
  };
831
838
 
832
- const emitLine = (line) => {
839
+ const emitLine = (rawLine) => {
840
+ const line = stripAnsi(rawLine);
833
841
  const urls = line.match(urlRe) || [];
834
- if (urls.length > 0) {
835
- for (const url of urls) {
836
- if (!seenUrls.has(url)) {
837
- seenUrls.add(url);
838
- console.log(`\n ${c.cyan}${c.bold}→ ${url}${c.reset}\n`);
839
- }
842
+ // Whitelist-only: only emit URLs — everything else is branding or TUI chrome
843
+ for (const url of urls) {
844
+ if (!seenUrls.has(url)) {
845
+ seenUrls.add(url);
846
+ console.log(`\n ${c.cyan}${c.bold}→ ${url}${c.reset}\n`);
840
847
  }
841
- return;
842
848
  }
843
- // Suppress lines that only contain internal gateway/runtime branding
844
- if (/openclaw/i.test(line)) return;
845
- if (line.trim()) console.log(` ${line}`);
846
849
  };
847
850
 
848
851
  proc.stdout.on('data', handleData);
@@ -870,8 +873,9 @@ async function runSubscriptionAuthFlow(cfg) {
870
873
 
871
874
  let exitCode;
872
875
  if (cfg.providerFamily === 'openai') {
873
- // Stream output and extract OAuth URL so the user never sees "openclaw"
874
- exitCode = await streamFilteredAuth(['compose', 'run', '--rm', '--entrypoint', 'openclaw', 'limbo', ...authArgs]);
876
+ // --tty allocates a PTY inside the container so openclaw's auth wizard runs correctly.
877
+ // We still pipe stdout/stderr to filter out branding and highlight the OAuth URL.
878
+ exitCode = await streamFilteredAuth(['compose', 'run', '--tty', '--rm', '--entrypoint', 'openclaw', 'limbo', ...authArgs]);
875
879
  } else {
876
880
  // Anthropic paste-token is interactive (user pastes a token); keep stdio inherited
877
881
  const authResult = runOpenClaw(authArgs);
@@ -891,7 +895,7 @@ async function runSubscriptionAuthFlow(cfg) {
891
895
  die(t(cfg.language, 'authStatusFailed'));
892
896
  }
893
897
 
894
- ok(t(cfg.language, 'authFlowDone'));
898
+ ok(t(cfg.language, 'modelConnected', `${cfg.provider}/${cfg.modelName}`));
895
899
  }
896
900
 
897
901
  function printSuccess(cfg, gatewayToken) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "limbo-ai",
3
- "version": "1.9.0",
3
+ "version": "1.9.2",
4
4
  "description": "Your personal AI memory agent — install and manage Limbo via npx",
5
5
  "type": "commonjs",
6
6
  "bin": {