kumo-cli 1.1.0 → 1.2.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 (96) hide show
  1. package/README.md +140 -131
  2. package/dist/auth/credentialsStore.js +19 -6
  3. package/dist/auth/credentialsStore.js.map +1 -1
  4. package/dist/claude/conversation.js +272 -0
  5. package/dist/claude/conversation.js.map +1 -0
  6. package/dist/claude/transcriptParser.js +98 -93
  7. package/dist/claude/transcriptParser.js.map +1 -1
  8. package/dist/commands/cliArgs.js +1 -0
  9. package/dist/commands/cliArgs.js.map +1 -1
  10. package/dist/core/config.js +0 -5
  11. package/dist/core/config.js.map +1 -1
  12. package/dist/core/logger.js +47 -6
  13. package/dist/core/logger.js.map +1 -1
  14. package/dist/core/projectFileWatcher.js +100 -36
  15. package/dist/core/projectFileWatcher.js.map +1 -1
  16. package/dist/engine/claudeArgs.js +4 -0
  17. package/dist/engine/claudeArgs.js.map +1 -1
  18. package/dist/engine/claudeBinary.js +14 -5
  19. package/dist/engine/claudeBinary.js.map +1 -1
  20. package/dist/engine/claudeConfig.js +20 -6
  21. package/dist/engine/claudeConfig.js.map +1 -1
  22. package/dist/engine/claudeLogin.js +76 -0
  23. package/dist/engine/claudeLogin.js.map +1 -0
  24. package/dist/engine/controlChannel.js +13 -1
  25. package/dist/engine/controlChannel.js.map +1 -1
  26. package/dist/engine/liveTranscript.js +70 -21
  27. package/dist/engine/liveTranscript.js.map +1 -1
  28. package/dist/engine/ndjson.js +15 -10
  29. package/dist/engine/ndjson.js.map +1 -1
  30. package/dist/engine/permissions.js +5 -2
  31. package/dist/engine/permissions.js.map +1 -1
  32. package/dist/engine/probePool.js +51 -0
  33. package/dist/engine/probePool.js.map +1 -0
  34. package/dist/engine/processTree.js +45 -0
  35. package/dist/engine/processTree.js.map +1 -0
  36. package/dist/engine/remoteConfig.js +17 -0
  37. package/dist/engine/remoteConfig.js.map +1 -0
  38. package/dist/engine/sessionManager.js +99 -84
  39. package/dist/engine/sessionManager.js.map +1 -1
  40. package/dist/engine/settingsCommands.js +56 -0
  41. package/dist/engine/settingsCommands.js.map +1 -1
  42. package/dist/engine/streamSession.js +59 -66
  43. package/dist/engine/streamSession.js.map +1 -1
  44. package/dist/engine/taskTracker.js +1 -1
  45. package/dist/engine/taskTracker.js.map +1 -1
  46. package/dist/engine/toolLabels.js +32 -0
  47. package/dist/engine/toolLabels.js.map +1 -0
  48. package/dist/handlers/controlRequest.js +17 -0
  49. package/dist/handlers/controlRequest.js.map +1 -0
  50. package/dist/handlers/fileHandlers.js +12 -0
  51. package/dist/handlers/fileHandlers.js.map +1 -1
  52. package/dist/handlers/messageRouter.js +8 -1
  53. package/dist/handlers/messageRouter.js.map +1 -1
  54. package/dist/handlers/promptImages.js +0 -55
  55. package/dist/handlers/promptImages.js.map +1 -1
  56. package/dist/handlers/runtimeHandlers.js +51 -151
  57. package/dist/handlers/runtimeHandlers.js.map +1 -1
  58. package/dist/handlers/sessionHandlers.js +48 -14
  59. package/dist/handlers/sessionHandlers.js.map +1 -1
  60. package/dist/handlers/terminalHandlers.js +9 -2
  61. package/dist/handlers/terminalHandlers.js.map +1 -1
  62. package/dist/http/httpClient.js +6 -0
  63. package/dist/http/httpClient.js.map +1 -1
  64. package/dist/index.js +58 -16
  65. package/dist/index.js.map +1 -1
  66. package/dist/pty/terminalManager.js +58 -11
  67. package/dist/pty/terminalManager.js.map +1 -1
  68. package/dist/services/bootstrapService.js +17 -1
  69. package/dist/services/bootstrapService.js.map +1 -1
  70. package/dist/services/claudeAdapterProxy.js +68 -21
  71. package/dist/services/claudeAdapterProxy.js.map +1 -1
  72. package/dist/services/cliRuntime.js +5 -5
  73. package/dist/services/cliRuntime.js.map +1 -1
  74. package/dist/services/fileService.js +50 -24
  75. package/dist/services/fileService.js.map +1 -1
  76. package/dist/services/forkService.js +1 -1
  77. package/dist/services/forkService.js.map +1 -1
  78. package/dist/services/modelService.js +62 -18
  79. package/dist/services/modelService.js.map +1 -1
  80. package/dist/services/pairingService.js +21 -15
  81. package/dist/services/pairingService.js.map +1 -1
  82. package/dist/services/sessionService.js +204 -85
  83. package/dist/services/sessionService.js.map +1 -1
  84. package/dist/services/tunnelHelpers.js +9 -5
  85. package/dist/services/tunnelHelpers.js.map +1 -1
  86. package/dist/services/tunnelService.js +17 -0
  87. package/dist/services/tunnelService.js.map +1 -1
  88. package/dist/transport/wsClient.js +60 -38
  89. package/dist/transport/wsClient.js.map +1 -1
  90. package/dist/utils/json.js +7 -0
  91. package/dist/utils/json.js.map +1 -0
  92. package/dist/utils/localHost.js +17 -0
  93. package/dist/utils/localHost.js.map +1 -0
  94. package/dist/utils/safePath.js +51 -20
  95. package/dist/utils/safePath.js.map +1 -1
  96. package/package.json +62 -62
@@ -32,8 +32,15 @@ export function createTerminalHandlers() {
32
32
  log(`[terminal] closed: ${terminalId}`);
33
33
  }
34
34
  },
35
- terminal_list: (_msg, ctx) => {
36
- ctx.send({ type: 'terminal_list', terminals: ctx.terminals.list() });
35
+ // replay: an app back on screen redraws each terminal from its recent output
36
+ terminal_list: (msg, ctx) => {
37
+ const terminals = ctx.terminals.list();
38
+ ctx.send({ type: 'terminal_list', terminals });
39
+ if (msg['replay'] !== true)
40
+ return;
41
+ for (const terminalId of terminals) {
42
+ ctx.send({ type: 'terminal_output', terminalId, data: ctx.terminals.recentOutput(terminalId), replace: true });
43
+ }
37
44
  },
38
45
  };
39
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"terminalHandlers.js","sourceRoot":"","sources":["../../src/handlers/terminalHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAGxC,uEAAuE;AACvE,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAI,GAAG,CAAC,MAAM,CAAY,IAAI,GAAG,CAAC;YAC5C,MAAM,IAAI,GAAI,GAAG,CAAC,MAAM,CAAY,IAAI,EAAE,CAAC;YAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAuB,CAAC;YAC7C,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YACzD,GAAG,CAAC,uBAAuB,UAAU,EAAE,CAAC,CAAC;YACzC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAW,CAAC;YAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAW,CAAC;YACnC,IAAI,UAAU,IAAI,IAAI;gBAAE,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAChE,CAAC;QACD,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAW,CAAC;YAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAW,CAAC;YACnC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAW,CAAC;YACnC,IAAI,UAAU,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBAC/B,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC7C,GAAG,CAAC,qBAAqB,UAAU,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QACD,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAW,CAAC;YAC/C,IAAI,UAAU,EAAE,CAAC;gBACf,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAChC,GAAG,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QACD,aAAa,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"terminalHandlers.js","sourceRoot":"","sources":["../../src/handlers/terminalHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAGxC,uEAAuE;AACvE,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAI,GAAG,CAAC,MAAM,CAAY,IAAI,GAAG,CAAC;YAC5C,MAAM,IAAI,GAAI,GAAG,CAAC,MAAM,CAAY,IAAI,EAAE,CAAC;YAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAuB,CAAC;YAC7C,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YACzD,GAAG,CAAC,uBAAuB,UAAU,EAAE,CAAC,CAAC;YACzC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAW,CAAC;YAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAW,CAAC;YACnC,IAAI,UAAU,IAAI,IAAI;gBAAE,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAChE,CAAC;QACD,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAW,CAAC;YAC/C,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAW,CAAC;YACnC,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAW,CAAC;YACnC,IAAI,UAAU,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBAC/B,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC7C,GAAG,CAAC,qBAAqB,UAAU,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QACD,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC3B,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAW,CAAC;YAC/C,IAAI,UAAU,EAAE,CAAC;gBACf,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAChC,GAAG,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QACD,6EAA6E;QAC7E,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;YACvC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;YAC/C,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI;gBAAE,OAAO;YACnC,KAAK,MAAM,UAAU,IAAI,SAAS,EAAE,CAAC;gBACnC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACjH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,5 +1,8 @@
1
1
  import http from 'node:http';
2
2
  import https from 'node:https';
3
+ // a server that stops answering (a half-open connection) fails the request instead of
4
+ // hanging the spawn or startup waiting on it
5
+ const REQUEST_TIMEOUT_MS = 10_000;
3
6
  // unified http request with optional bearer auth and json body. parses json when possible.
4
7
  export function httpRequest(method, url, opts = {}) {
5
8
  return new Promise((resolve, reject) => {
@@ -21,6 +24,8 @@ export function httpRequest(method, url, opts = {}) {
21
24
  method,
22
25
  headers,
23
26
  }, (res) => {
27
+ // decode as a stream, so a character split across chunks stays whole
28
+ res.setEncoding('utf8');
24
29
  let raw = '';
25
30
  res.on('data', (chunk) => { raw += chunk; });
26
31
  res.on('end', () => {
@@ -32,6 +37,7 @@ export function httpRequest(method, url, opts = {}) {
32
37
  }
33
38
  });
34
39
  });
40
+ req.setTimeout(opts.timeoutMs ?? REQUEST_TIMEOUT_MS, () => req.destroy(new Error(`request timed out: ${method} ${urlObj.pathname}`)));
35
41
  req.on('error', reject);
36
42
  if (payload)
37
43
  req.write(payload);
@@ -1 +1 @@
1
- {"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../../src/http/httpClient.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,YAAY,CAAC;AAa/B,2FAA2F;AAC3F,MAAM,UAAU,WAAW,CACzB,MAAyC,EACzC,GAAW,EACX,OAA2B,EAAE;IAE7B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;QAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClE,MAAM,OAAO,GAA2B,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;QACpE,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,OAAO,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;QAClE,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC;YAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,IAAI,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM;YACrC,MAAM;YACN,OAAO;SACR,EAAE,CAAC,GAAG,EAAE,EAAE;YACT,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC;oBAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAAC,CAAC;gBACxE,MAAM,CAAC;oBAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;gBAAC,CAAC;YAChE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,IAAI,OAAO;YAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChC,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"httpClient.js","sourceRoot":"","sources":["../../src/http/httpClient.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,YAAY,CAAC;AAc/B,sFAAsF;AACtF,6CAA6C;AAC7C,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,2FAA2F;AAC3F,MAAM,UAAU,WAAW,CACzB,MAAyC,EACzC,GAAW,EACX,OAA2B,EAAE;IAE7B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;QAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClE,MAAM,OAAO,GAA2B,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;QACpE,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;YAC7C,OAAO,CAAC,gBAAgB,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;QAClE,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC;YAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,IAAI,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM;YACrC,MAAM;YACN,OAAO;SACR,EAAE,CAAC,GAAG,EAAE,EAAE;YACT,qEAAqE;YACrE,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACxB,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI,CAAC;oBAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAAC,CAAC;gBACxE,MAAM,CAAC;oBAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;gBAAC,CAAC;YAChE,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,IAAI,kBAAkB,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,sBAAsB,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;QACtI,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxB,IAAI,OAAO;YAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAChC,GAAG,CAAC,GAAG,EAAE,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/index.js CHANGED
@@ -5,21 +5,35 @@ import { loadDotEnv } from './core/loadDotEnv.js';
5
5
  import { log } from './core/logger.js';
6
6
  import { ProjectFileWatcher } from './core/projectFileWatcher.js';
7
7
  import { SessionManager } from './engine/sessionManager.js';
8
+ import { allowRemoteUserConfig } from './engine/remoteConfig.js';
9
+ import { SERVER_HTTP, SERVER_WS } from './core/config.js';
10
+ import { isCleartextRemote } from './utils/localHost.js';
8
11
  import { ModelService } from './services/modelService.js';
9
12
  import { EffortService } from './services/effortService.js';
10
13
  import { printBanner } from './services/pairingService.js';
11
14
  import { resolveActiveCredentials } from './services/bootstrapService.js';
12
15
  import { createSpawnSpecFactory, createWsOpenHandler, resolveLaunchConfig } from './services/cliRuntime.js';
13
16
  import { WsClient } from './transport/wsClient.js';
17
+ import { resolveClaudeCommand } from './engine/claudeBinary.js';
14
18
  import { createMessageRouter } from './handlers/messageRouter.js';
15
19
  import { chooseAgent } from './commands/agentPrompt.js';
16
20
  import { extractEnvFileArg, parseCommand, printHelp } from './commands/cliArgs.js';
21
+ // sessions get this long to close on ctrl+c before the cli exits anyway
22
+ const SHUTDOWN_DEADLINE_MS = 5000;
17
23
  const { envFilePath, cliArgs: bootArgs } = extractEnvFileArg(process.argv.slice(2));
18
24
  if (envFilePath) {
19
25
  loadDotEnv(envFilePath);
20
26
  }
21
27
  let activeCredentials = null;
22
- let pairedResolved = false;
28
+ // last resort: one bad callback (a watcher, a socket) must not take every claude session and
29
+ // terminal down with it
30
+ process.on('uncaughtException', (error) => {
31
+ log(`[fatal] uncaught exception: ${error.stack ?? error}`);
32
+ console.error(`[kumo-cli] unexpected error: ${error.message}`);
33
+ });
34
+ process.on('unhandledRejection', (reason) => {
35
+ log(`[fatal] unhandled rejection: ${reason instanceof Error ? reason.stack : String(reason)}`);
36
+ });
23
37
  async function main() {
24
38
  const command = parseCommand(bootArgs);
25
39
  if (command.action === 'help') {
@@ -40,9 +54,16 @@ async function main() {
40
54
  return;
41
55
  }
42
56
  const launch = resolveLaunchConfig(command.args);
57
+ allowRemoteUserConfig(launch.allowRemoteConfig);
43
58
  printBanner();
59
+ if (isCleartextRemote(SERVER_HTTP()) || isCleartextRemote(SERVER_WS())) {
60
+ console.warn('\x1b[33m[kumo-cli] warning: the backend url is not https/wss, so the device token and everything relayed travel in the clear\x1b[0m');
61
+ }
44
62
  let ws;
45
63
  const send = (data) => ws.send(data);
64
+ // whether an app shows this cli's output; while none does, the live transcript is held back
65
+ // (the app reloads the history page when it comes back)
66
+ let watched = true;
46
67
  const fileWatcher = new ProjectFileWatcher(send);
47
68
  const model = new ModelService();
48
69
  const effort = new EffortService();
@@ -52,8 +73,12 @@ async function main() {
52
73
  send({ type: 'terminal_closed', terminalId, exitCode });
53
74
  });
54
75
  const sessions = new SessionManager({
55
- // cli_status from a session carries no effort/cwd; fill them so the backend keeps them
56
- emit: (msg) => send(msg['type'] === 'cli_status' ? { effort: effort.getEffective(), workingDir: process.cwd(), ...msg } : msg),
76
+ emit: (msg) => {
77
+ if (!watched && msg['type'] === 'transcript')
78
+ return;
79
+ // cli_status from a session carries no effort; fill it so the backend keeps it
80
+ send(msg['type'] === 'cli_status' ? { effort: effort.getEffective(), ...msg } : msg);
81
+ },
57
82
  spawnSpec: createSpawnSpecFactory({
58
83
  model,
59
84
  effort,
@@ -66,10 +91,13 @@ async function main() {
66
91
  });
67
92
  let shuttingDown = false;
68
93
  const shutdown = (code) => {
94
+ // a second ctrl+c means now, whatever is still closing
69
95
  if (shuttingDown)
70
- return;
96
+ process.exit(code);
71
97
  shuttingDown = true;
72
- console.log('\n[kumo-cli] closing claude sessions...');
98
+ console.log('\n[kumo-cli] closing claude sessions... (ctrl+c again to quit now)');
99
+ // a session stuck starting must not keep the cli from exiting
100
+ setTimeout(() => process.exit(code), SHUTDOWN_DEADLINE_MS).unref();
73
101
  void Promise.allSettled([sessions.closeAll(), model.dispose()]).finally(() => {
74
102
  ws?.close();
75
103
  process.exit(code);
@@ -89,28 +117,42 @@ async function main() {
89
117
  process.exit(1);
90
118
  }
91
119
  console.log(`\x1b[32m✓ Connected as ${activeCredentials.user?.email ?? activeCredentials.user?.id ?? 'device'}\x1b[0m`);
120
+ if (launch.allowRemoteConfig)
121
+ console.log('[kumo-cli] the app may change user-wide hooks, permission rules and mcp servers');
92
122
  console.log(`[kumo-cli] claude sessions run on demand (permission mode: ${launch.permissionMode}). press ctrl+c to quit.\n`);
93
123
  const router = createMessageRouter({
94
124
  send,
95
- sessions, model, effort, terminals,
96
- onPaired: () => {
97
- if (pairedResolved)
98
- return;
99
- pairedResolved = true;
100
- fileWatcher.restart();
125
+ sessions, effort, terminals,
126
+ files: fileWatcher,
127
+ onAppPresence: (watching) => {
128
+ log(`[presence] app ${watching ? 'on screen' : 'away'}`);
129
+ watched = watching;
130
+ terminals.setLive(watching);
131
+ if (!watching)
132
+ fileWatcher.stop();
133
+ },
134
+ onAuthError: () => {
135
+ ws.close();
136
+ shutdown(1);
101
137
  },
102
- onAuthError: () => { ws.close(); },
103
138
  });
104
139
  ws = new WsClient(createWsOpenHandler({
105
140
  send,
106
141
  credentials: () => activeCredentials,
107
142
  liveSessionIds: () => sessions.liveSessionIds(),
108
143
  effort: () => effort.getEffective(),
109
- restartWatcher: () => fileWatcher.restart(),
110
144
  refreshAuth: () => sessions.refreshAuth(),
111
- }), router, () => {
112
- fileWatcher.stop();
113
- });
145
+ }), router,
146
+ // the app subscribes again after a reconnect
147
+ () => fileWatcher.stop());
148
+ // find (or install) claude now: a first-run npm install, run synchronously, would otherwise
149
+ // freeze the open socket's heartbeats for its whole length
150
+ try {
151
+ resolveClaudeCommand();
152
+ }
153
+ catch (error) {
154
+ console.warn(`[kumo-cli] ${error.message}`);
155
+ }
114
156
  ws.connect();
115
157
  }
116
158
  main().catch((err) => {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -2,34 +2,62 @@ import * as pty from 'node-pty';
2
2
  import os from 'node:os';
3
3
  import { randomUUID } from 'node:crypto';
4
4
  import { safeCwd } from '../utils/safePath.js';
5
+ // pty output is coalesced into one frame per window instead of one frame per chunk
6
+ const OUTPUT_FLUSH_MS = 30;
7
+ const RECENT_OUTPUT_CHARS = 256 * 1024;
8
+ const clamp = (value, min, max) => Math.min(Math.max(Math.trunc(value), min), max);
9
+ const clampSize = (cols, rows) => ({ cols: clamp(cols, 20, 300), rows: clamp(rows, 5, 100) });
5
10
  // manages multiple user-facing shell sessions backed by node-pty
6
11
  export class TerminalManager {
7
12
  onData;
8
13
  onExit;
9
14
  terminals = new Map();
15
+ // output only streams while an app shows it; otherwise it just piles up in `recent`
16
+ live = true;
10
17
  constructor(onData, onExit) {
11
18
  this.onData = onData;
12
19
  this.onExit = onExit;
13
20
  }
14
- create(cols = 120, rows = 30, cwd) {
21
+ create(cols, rows, cwd) {
15
22
  const id = randomUUID();
16
23
  const shell = os.platform() === 'win32' ? 'cmd.exe' : process.env.SHELL || '/bin/bash';
17
- const safeCols = Math.min(Math.max(Math.trunc(cols), 20), 300);
18
- const safeRows = Math.min(Math.max(Math.trunc(rows), 5), 100);
19
24
  const child = pty.spawn(shell, [], {
20
25
  name: 'xterm-256color',
21
- cols: safeCols, rows: safeRows,
26
+ ...clampSize(cols, rows),
22
27
  cwd: safeCwd(cwd),
23
28
  env: process.env,
24
29
  });
25
- child.onData((data) => this.onData(id, data));
30
+ const session = { id, pty: child, pending: '', flushTimer: null, recent: [], recentChars: 0 };
31
+ child.onData((data) => {
32
+ this.remember(session, data);
33
+ if (!this.live)
34
+ return;
35
+ session.pending += data;
36
+ session.flushTimer ??= setTimeout(() => this.flush(session), OUTPUT_FLUSH_MS);
37
+ });
26
38
  child.onExit(({ exitCode }) => {
39
+ this.flush(session);
27
40
  this.terminals.delete(id);
28
41
  this.onExit(id, exitCode);
29
42
  });
30
- this.terminals.set(id, { id, pty: child, cols: safeCols, rows: safeRows });
43
+ this.terminals.set(id, session);
31
44
  return id;
32
45
  }
46
+ setLive(live) {
47
+ this.live = live;
48
+ if (live)
49
+ return;
50
+ for (const session of this.terminals.values()) {
51
+ if (session.flushTimer)
52
+ clearTimeout(session.flushTimer);
53
+ session.flushTimer = null;
54
+ session.pending = '';
55
+ }
56
+ }
57
+ recentOutput(id) {
58
+ const session = this.terminals.get(id);
59
+ return session ? session.recent.join('').slice(-RECENT_OUTPUT_CHARS) : '';
60
+ }
33
61
  write(id, data) {
34
62
  const session = this.terminals.get(id);
35
63
  if (!session)
@@ -42,11 +70,8 @@ export class TerminalManager {
42
70
  if (!session)
43
71
  return false;
44
72
  try {
45
- const safeCols = Math.min(Math.max(Math.trunc(cols), 20), 300);
46
- const safeRows = Math.min(Math.max(Math.trunc(rows), 5), 100);
47
- session.pty.resize(safeCols, safeRows);
48
- session.cols = safeCols;
49
- session.rows = safeRows;
73
+ const size = clampSize(cols, rows);
74
+ session.pty.resize(size.cols, size.rows);
50
75
  return true;
51
76
  }
52
77
  catch {
@@ -57,6 +82,8 @@ export class TerminalManager {
57
82
  const session = this.terminals.get(id);
58
83
  if (!session)
59
84
  return false;
85
+ if (session.flushTimer)
86
+ clearTimeout(session.flushTimer);
60
87
  try {
61
88
  session.pty.kill();
62
89
  }
@@ -67,5 +94,25 @@ export class TerminalManager {
67
94
  list() {
68
95
  return Array.from(this.terminals.keys());
69
96
  }
97
+ // keep the chunks, dropping whole old ones once they hold twice what a replay needs
98
+ remember(session, data) {
99
+ session.recent.push(data);
100
+ session.recentChars += data.length;
101
+ if (session.recentChars <= 2 * RECENT_OUTPUT_CHARS)
102
+ return;
103
+ while (session.recentChars - session.recent[0].length >= RECENT_OUTPUT_CHARS) {
104
+ session.recentChars -= session.recent.shift().length;
105
+ }
106
+ }
107
+ flush(session) {
108
+ if (session.flushTimer)
109
+ clearTimeout(session.flushTimer);
110
+ session.flushTimer = null;
111
+ if (!session.pending)
112
+ return;
113
+ const data = session.pending;
114
+ session.pending = '';
115
+ this.onData(session.id, data);
116
+ }
70
117
  }
71
118
  //# sourceMappingURL=terminalManager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminalManager.js","sourceRoot":"","sources":["../../src/pty/terminalManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"terminalManager.js","sourceRoot":"","sources":["../../src/pty/terminalManager.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,22 @@ export async function ensureBackendReachableOrThrow() {
7
7
  return;
8
8
  throw new Error(`[kumo-cli] cannot reach backend at ${SERVER_HTTP()}. check KUMO_SERVER_URL and that the server is running.`);
9
9
  }
10
+ const VERIFY_ATTEMPTS = 3;
11
+ // a passing backend hiccup gets a few tries; past that the cli stops with the token kept
12
+ async function verifyWithRetry(creds, delayMs = 2000) {
13
+ for (let attempt = 1;; attempt++) {
14
+ try {
15
+ return await verifyCredentials(creds);
16
+ }
17
+ catch (error) {
18
+ if (attempt >= VERIFY_ATTEMPTS) {
19
+ throw new Error(`[kumo-cli] could not check the saved device token (${error.message}). it is kept; try again in a moment.`);
20
+ }
21
+ console.warn(`[kumo-cli] backend not ready (${error.message}), retrying...`);
22
+ await new Promise((resolve) => setTimeout(resolve, delayMs * attempt));
23
+ }
24
+ }
25
+ }
10
26
  // restore cached credentials when possible, otherwise fall back to a fresh pairing flow
11
27
  export async function resolveActiveCredentials() {
12
28
  await ensureBackendReachableOrThrow();
@@ -15,7 +31,7 @@ export async function resolveActiveCredentials() {
15
31
  return pairFlow();
16
32
  }
17
33
  ensureDeviceUuid(activeCredentials.deviceUuid);
18
- const verified = await verifyCredentials(activeCredentials);
34
+ const verified = await verifyWithRetry(activeCredentials);
19
35
  if (!verified) {
20
36
  console.warn('[kumo-cli] cached device token was revoked or deleted, clearing credentials and re-pairing with the existing device identity...');
21
37
  clearCredentials();
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrapService.js","sourceRoot":"","sources":["../../src/services/bootstrapService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,kBAAkB,GAEnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzF,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,6BAA6B;IACjD,IAAI,MAAM,qBAAqB,EAAE;QAAE,OAAO;IAC1C,MAAM,IAAI,KAAK,CAAC,sCAAsC,WAAW,EAAE,yDAAyD,CAAC,CAAC;AAChI,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,MAAM,6BAA6B,EAAE,CAAC;IAEtC,IAAI,iBAAiB,GAAG,eAAe,EAAE,CAAC;IAC1C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,gBAAgB,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,iIAAiI,CAAC,CAAC;QAChJ,gBAAgB,EAAE,CAAC;QACnB,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,kBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"bootstrapService.js","sourceRoot":"","sources":["../../src/services/bootstrapService.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,kBAAkB,GAEnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzF,0DAA0D;AAC1D,MAAM,CAAC,KAAK,UAAU,6BAA6B;IACjD,IAAI,MAAM,qBAAqB,EAAE;QAAE,OAAO;IAC1C,MAAM,IAAI,KAAK,CAAC,sCAAsC,WAAW,EAAE,yDAAyD,CAAC,CAAC;AAChI,CAAC;AAED,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,yFAAyF;AACzF,KAAK,UAAU,eAAe,CAAC,KAAsB,EAAE,OAAO,GAAG,IAAI;IACnE,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,OAAO,MAAM,iBAAiB,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,IAAI,eAAe,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,sDAAuD,KAAe,CAAC,OAAO,uCAAuC,CAAC,CAAC;YACzI,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,iCAAkC,KAAe,CAAC,OAAO,gBAAgB,CAAC,CAAC;YACxF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;AACH,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,MAAM,6BAA6B,EAAE,CAAC;IAEtC,IAAI,iBAAiB,GAAG,eAAe,EAAE,CAAC;IAC1C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,gBAAgB,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,iBAAiB,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,iIAAiI,CAAC,CAAC;QAChJ,gBAAgB,EAAE,CAAC;QACnB,OAAO,QAAQ,EAAE,CAAC;IACpB,CAAC;IAED,kBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxC,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC1B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1,24 +1,53 @@
1
- import net from 'node:net';
1
+ import { randomBytes } from 'node:crypto';
2
2
  import Fastify from 'fastify';
3
3
  import OpenAI from 'openai';
4
4
  import { convertRequestToOpenAI, convertResponseToAnthropic, createErrorResponse, } from 'claude-adapter';
5
5
  import { streamXmlOpenAIToAnthropic } from 'claude-adapter/dist/converters/xmlStreaming.js';
6
6
  // local Anthropic-compatible proxy that forwards to OpenAI chat/completions upstream
7
- // bypasses claude-adapter's strict validation to support all Claude Code message roles
7
+ // bypasses claude-adapter's strict validation to support all Claude Code message roles.
8
+ // it spends the provider key, so only a caller holding its random token (the claude it was
9
+ // started for) and naming it by its loopback host gets through
8
10
  export class ClaudeAdapterProxy {
9
11
  app = null;
10
12
  key = null;
11
13
  url = null;
14
+ secret = null;
15
+ // starts and stops run one at a time, so two spawns never leave a second server behind
16
+ queue = Promise.resolve();
17
+ // the bearer token claude must send (ANTHROPIC_AUTH_TOKEN)
18
+ get token() { return this.secret; }
12
19
  // start or reuse a local proxy for OpenAI chat completions
13
- async start(config) {
20
+ start(config) {
21
+ return this.serial(() => this.startNow(config));
22
+ }
23
+ // stop the current adapter proxy if one is running
24
+ stop() {
25
+ return this.serial(() => this.stopNow());
26
+ }
27
+ serial(run) {
28
+ const next = this.queue.then(run);
29
+ this.queue = next.catch(() => undefined);
30
+ return next;
31
+ }
32
+ async startNow(config) {
14
33
  const key = `${config.baseURL}|${config.apiKey}|${config.model}`;
15
34
  if (this.app && this.key === key && this.url)
16
35
  return this.url;
17
- await this.stop();
18
- const port = await findAvailablePort();
36
+ await this.stopNow();
19
37
  const upstreamBaseUrl = config.baseURL.replace(/\/chat\/completions\/?$/i, '');
20
38
  const openai = new OpenAI({ baseURL: upstreamBaseUrl, apiKey: config.apiKey });
21
39
  const app = Fastify({ logger: false });
40
+ const secret = randomBytes(24).toString('hex');
41
+ let port = 0;
42
+ app.addHook('onRequest', async (request, reply) => {
43
+ const host = request.headers.host ?? '';
44
+ const auth = request.headers.authorization ?? '';
45
+ const apiKey = request.headers['x-api-key'];
46
+ const allowedHost = host === `127.0.0.1:${port}` || host === `localhost:${port}`;
47
+ if (!allowedHost || (auth !== `Bearer ${secret}` && apiKey !== secret)) {
48
+ return reply.code(401).send({ type: 'error', error: { type: 'authentication_error', message: 'unauthorized' } });
49
+ }
50
+ });
22
51
  app.post('/v1/messages', async (request, reply) => {
23
52
  try {
24
53
  const body = request.body;
@@ -29,7 +58,8 @@ export class ClaudeAdapterProxy {
29
58
  stripAdapterBranding(openaiRequest.messages);
30
59
  if (isStreaming) {
31
60
  const stream = await openai.chat.completions.create({ ...openaiRequest, stream: true });
32
- await streamXmlOpenAIToAnthropic(stream, reply, body.model, upstreamBaseUrl);
61
+ const counted = reportPromptTokens(stream, reply.raw);
62
+ await streamXmlOpenAIToAnthropic(counted, reply, body.model, upstreamBaseUrl);
33
63
  }
34
64
  else {
35
65
  const response = await openai.chat.completions.create({ ...openaiRequest, stream: false });
@@ -42,23 +72,52 @@ export class ClaudeAdapterProxy {
42
72
  reply.code(errResp.status).send({ error: errResp.error });
43
73
  }
44
74
  });
45
- await app.listen({ port, host: '127.0.0.1' });
75
+ // port 0: the os picks a free port at bind time, no check-then-bind race
76
+ await app.listen({ port: 0, host: '127.0.0.1' });
77
+ port = app.server.address().port;
46
78
  this.app = app;
47
79
  this.key = key;
80
+ this.secret = secret;
48
81
  this.url = `http://127.0.0.1:${port}`;
49
82
  return this.url;
50
83
  }
51
- // stop the current adapter proxy if one is running
52
- async stop() {
84
+ async stopNow() {
53
85
  if (!this.app)
54
86
  return;
55
87
  const app = this.app;
56
88
  this.app = null;
57
89
  this.key = null;
58
90
  this.url = null;
91
+ this.secret = null;
59
92
  await app.close().catch(() => undefined);
60
93
  }
61
94
  }
95
+ // the prompt's tokens only come with the stream's last chunk: claude-adapter has sent message_start
96
+ // with 0 by then, and its message_delta leaves them out. they go into that message_delta, so claude
97
+ // knows how big each turn was (and when to compact) instead of reading 0
98
+ function reportPromptTokens(stream, raw) {
99
+ let prompt;
100
+ let cached = 0;
101
+ const write = raw.write.bind(raw);
102
+ raw.write = ((chunk, ...rest) => {
103
+ if (prompt !== undefined && typeof chunk === 'string' && chunk.startsWith('data: ') && chunk.includes('"message_delta"')) {
104
+ const event = JSON.parse(chunk.slice('data: '.length));
105
+ // anthropic counts cache reads apart from the input, openai inside it
106
+ event.usage = { ...event.usage, input_tokens: Math.max(prompt - cached, 0), cache_read_input_tokens: cached };
107
+ chunk = `data: ${JSON.stringify(event)}\n\n`;
108
+ }
109
+ return write(chunk, ...rest);
110
+ });
111
+ return (async function* () {
112
+ for await (const chunk of stream) {
113
+ if (chunk?.usage) {
114
+ prompt = chunk.usage.prompt_tokens ?? 0;
115
+ cached = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;
116
+ }
117
+ yield chunk;
118
+ }
119
+ })();
120
+ }
62
121
  // replace Claude Code identifier before claude-adapter can inject its own branding
63
122
  function normalizeSystemBranding(body) {
64
123
  const CLAUDE_IDENTIFIER = "You are Claude Code, Anthropic's official CLI for Claude.";
@@ -89,16 +148,4 @@ function stripAdapterBranding(messages) {
89
148
  }
90
149
  }
91
150
  }
92
- // ask the OS for a currently free local TCP port
93
- async function findAvailablePort() {
94
- return new Promise((resolve, reject) => {
95
- const server = net.createServer();
96
- server.once('error', reject);
97
- server.listen(0, '127.0.0.1', () => {
98
- const address = server.address();
99
- const port = typeof address === 'object' && address ? address.port : 0;
100
- server.close(() => resolve(port));
101
- });
102
- });
103
- }
104
151
  //# sourceMappingURL=claudeAdapterProxy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"claudeAdapterProxy.js","sourceRoot":"","sources":["../../src/services/claudeAdapterProxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"claudeAdapterProxy.js","sourceRoot":"","sources":["../../src/services/claudeAdapterProxy.ts"],"names":[],"mappings":"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"}