@testany/hephos 0.3.17 → 0.4.0-dev.3

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 (82) hide show
  1. package/README.md +29 -0
  2. package/out/auth/AuthConfig.d.ts +54 -0
  3. package/out/auth/AuthConfig.d.ts.map +1 -0
  4. package/out/auth/AuthConfig.js +70 -0
  5. package/out/auth/AuthConfig.js.map +1 -0
  6. package/out/auth/AuthService.d.ts +74 -0
  7. package/out/auth/AuthService.d.ts.map +1 -0
  8. package/out/auth/AuthService.js +275 -0
  9. package/out/auth/AuthService.js.map +1 -0
  10. package/out/auth/CallbackServer.d.ts +15 -0
  11. package/out/auth/CallbackServer.d.ts.map +1 -0
  12. package/out/auth/CallbackServer.js +277 -0
  13. package/out/auth/CallbackServer.js.map +1 -0
  14. package/out/auth/TokenCache.d.ts +81 -0
  15. package/out/auth/TokenCache.d.ts.map +1 -0
  16. package/out/auth/TokenCache.js +191 -0
  17. package/out/auth/TokenCache.js.map +1 -0
  18. package/out/auth/index.d.ts +11 -0
  19. package/out/auth/index.d.ts.map +1 -0
  20. package/out/auth/index.js +13 -0
  21. package/out/auth/index.js.map +1 -0
  22. package/out/auth/types.d.ts +75 -0
  23. package/out/auth/types.d.ts.map +1 -0
  24. package/out/auth/types.js +15 -0
  25. package/out/auth/types.js.map +1 -0
  26. package/out/cli.d.ts.map +1 -1
  27. package/out/cli.js +223 -33
  28. package/out/cli.js.map +1 -1
  29. package/out/repl/ReplModeInk.d.ts +1 -0
  30. package/out/repl/ReplModeInk.d.ts.map +1 -1
  31. package/out/repl/ReplModeInk.js +124 -5
  32. package/out/repl/ReplModeInk.js.map +1 -1
  33. package/out/secure-config/BaseDirResolver.d.ts +5 -0
  34. package/out/secure-config/BaseDirResolver.d.ts.map +1 -0
  35. package/out/secure-config/BaseDirResolver.js +20 -0
  36. package/out/secure-config/BaseDirResolver.js.map +1 -0
  37. package/out/secure-config/DeviceKeyService.d.ts +13 -0
  38. package/out/secure-config/DeviceKeyService.d.ts.map +1 -0
  39. package/out/secure-config/DeviceKeyService.js +51 -0
  40. package/out/secure-config/DeviceKeyService.js.map +1 -0
  41. package/out/secure-config/DeviceStore.d.ts +13 -0
  42. package/out/secure-config/DeviceStore.d.ts.map +1 -0
  43. package/out/secure-config/DeviceStore.js +39 -0
  44. package/out/secure-config/DeviceStore.js.map +1 -0
  45. package/out/secure-config/InstructionNormalizer.d.ts +5 -0
  46. package/out/secure-config/InstructionNormalizer.d.ts.map +1 -0
  47. package/out/secure-config/InstructionNormalizer.js +20 -0
  48. package/out/secure-config/InstructionNormalizer.js.map +1 -0
  49. package/out/secure-config/KeysetService.d.ts +15 -0
  50. package/out/secure-config/KeysetService.d.ts.map +1 -0
  51. package/out/secure-config/KeysetService.js +88 -0
  52. package/out/secure-config/KeysetService.js.map +1 -0
  53. package/out/secure-config/SCPService.d.ts +14 -0
  54. package/out/secure-config/SCPService.d.ts.map +1 -0
  55. package/out/secure-config/SCPService.js +79 -0
  56. package/out/secure-config/SCPService.js.map +1 -0
  57. package/out/secure-config/SecureConfigClient.d.ts +30 -0
  58. package/out/secure-config/SecureConfigClient.d.ts.map +1 -0
  59. package/out/secure-config/SecureConfigClient.js +81 -0
  60. package/out/secure-config/SecureConfigClient.js.map +1 -0
  61. package/out/secure-config/errors.d.ts +8 -0
  62. package/out/secure-config/errors.d.ts.map +1 -0
  63. package/out/secure-config/errors.js +20 -0
  64. package/out/secure-config/errors.js.map +1 -0
  65. package/out/secure-config/index.d.ts +11 -0
  66. package/out/secure-config/index.d.ts.map +1 -0
  67. package/out/secure-config/index.js +11 -0
  68. package/out/secure-config/index.js.map +1 -0
  69. package/out/secure-config/rootKey.d.ts +3 -0
  70. package/out/secure-config/rootKey.d.ts.map +1 -0
  71. package/out/secure-config/rootKey.js +57 -0
  72. package/out/secure-config/rootKey.js.map +1 -0
  73. package/out/secure-config/signatureUtils.d.ts +3 -0
  74. package/out/secure-config/signatureUtils.d.ts.map +1 -0
  75. package/out/secure-config/signatureUtils.js +23 -0
  76. package/out/secure-config/signatureUtils.js.map +1 -0
  77. package/out/secure-config/types.d.ts +79 -0
  78. package/out/secure-config/types.d.ts.map +1 -0
  79. package/out/secure-config/types.js +2 -0
  80. package/out/secure-config/types.js.map +1 -0
  81. package/package.json +2 -2
  82. package/patches/ink-text-input+6.0.0.patch +176 -2
@@ -4,7 +4,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
4
4
  */
5
5
  import { useState, useEffect, useRef, useMemo } from 'react';
6
6
  import { render, Box, Text, useInput, useApp, Static, useStdout } from 'ink';
7
- import TextInput from 'ink-text-input';
7
+ import TextInput, { getLineInfo } from 'ink-text-input';
8
8
  import * as fs from 'fs';
9
9
  import { watch } from 'fs';
10
10
  import * as path from 'path';
@@ -27,6 +27,7 @@ import { QueueDisplay } from './components/QueueDisplay.js';
27
27
  import { TipsBar } from './components/TipsBar.js';
28
28
  import { HistoryOverlay } from './components/HistoryOverlay.js';
29
29
  import { useHistory } from './hooks/useHistory.js';
30
+ import { AuthService, isValidRegion, AUTH_CONFIG, tokenCache, AuthError } from '../auth/index.js';
30
31
  // Read version from package.json
31
32
  const __filename = fileURLToPath(import.meta.url);
32
33
  const __dirname = path.dirname(__filename);
@@ -38,11 +39,18 @@ const commands = [
38
39
  { name: '/status', desc: 'Check installed AI CLI tools' },
39
40
  { name: '/agents', desc: 'Manage registered AI agents' },
40
41
  { name: '/team', desc: 'Manage team configurations' },
42
+ { name: '/login', desc: 'Login to HephOS cloud' },
41
43
  { name: '/tips', desc: 'Toggle syntax tips in conversation mode' },
42
44
  { name: '/clear', desc: 'Clear the screen' },
43
45
  { name: '/exit', desc: 'Exit the application' },
44
46
  { name: '/quit', desc: 'Same as /exit' },
45
47
  ];
48
+ const loginCommands = [
49
+ { name: '/login cn', desc: 'Login to China Region' },
50
+ { name: '/login us', desc: 'Login to International Region' },
51
+ { name: '/login status', desc: 'Show authentication status' },
52
+ { name: '/login logout', desc: 'Logout from current region' },
53
+ ];
46
54
  const teamCommands = [
47
55
  { name: '/team create', desc: 'Create a new team configuration' },
48
56
  { name: '/team list', desc: 'List all team configurations' },
@@ -60,7 +68,11 @@ const agentsCommands = [
60
68
  ];
61
69
  // 欢迎界面组件
62
70
  function WelcomeScreen() {
63
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 0, flexDirection: "column", children: [_jsx(Logo, {}), _jsx(Text, { dimColor: true, children: "Multi-AI Conversation Orchestrator" }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " CLI version " }), _jsx(Text, { color: "white", children: VERSION })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " Core version " }), _jsx(Text, { color: "white", children: CORE_VERSION })] })] }), _jsxs(Text, { dimColor: true, children: [" built by ", _jsx(Text, { color: "cyan", children: "TestAny.io" })] }), _jsxs(Text, { dimColor: true, children: [" Type ", _jsx(Text, { color: "green", children: "/help" }), " for available commands"] }), _jsxs(Text, { dimColor: true, children: [" Type ", _jsx(Text, { color: "green", children: "/exit" }), " to quit"] })] }));
71
+ // Check login status
72
+ const activeRegion = tokenCache.getActiveRegion();
73
+ const userInfo = activeRegion ? tokenCache.getUserInfo(activeRegion) : null;
74
+ const isLoggedIn = activeRegion && tokenCache.isValid(activeRegion);
75
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 0, flexDirection: "column", children: [_jsx(Logo, {}), _jsx(Text, { dimColor: true, children: "Multi-AI Conversation Orchestrator" }), _jsx(Text, { children: " " }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " CLI version " }), _jsx(Text, { color: "white", children: VERSION })] }), _jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " Core version " }), _jsx(Text, { color: "white", children: CORE_VERSION })] }), isLoggedIn && userInfo && (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: " Logged in " }), _jsxs(Text, { color: "green", children: ["HephOS ", activeRegion.toUpperCase()] }), _jsx(Text, { dimColor: true, children: " as " }), _jsx(Text, { color: "white", children: userInfo.email || userInfo.name || 'unknown' })] }))] }), _jsxs(Text, { dimColor: true, children: [" built by ", _jsx(Text, { color: "cyan", children: "TestAny.io" })] }), _jsxs(Text, { dimColor: true, children: [" Type ", _jsx(Text, { color: "green", children: "/login" }), " to login"] }), _jsxs(Text, { dimColor: true, children: [" Type ", _jsx(Text, { color: "green", children: "/help" }), " for available commands"] }), _jsxs(Text, { dimColor: true, children: [" Type ", _jsx(Text, { color: "green", children: "/exit" }), " to quit"] })] }));
64
76
  }
65
77
  // 更新通知组件
66
78
  function UpdateNotification({ versionInfo }) {
@@ -213,10 +225,11 @@ function SelectView({ title, options, selectedIndex, multiSelect, selectedItems
213
225
  return (_jsx(Box, { children: _jsxs(Text, { color: isSelected ? 'green' : 'gray', bold: isSelected, children: [isSelected ? '▶ ' : ' ', multiSelect ? (isChecked ? '☑' : '☐') : '', ' ', option] }) }, idx));
214
226
  }) }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { dimColor: true, children: "Use " }), _jsx(Text, { color: "yellow", children: "\u2191\u2193" }), _jsx(Text, { dimColor: true, children: " to navigate, " }), multiSelect && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "yellow", children: "Space" }), _jsx(Text, { dimColor: true, children: " to toggle, " })] })), _jsx(Text, { color: "yellow", children: "Enter" }), _jsx(Text, { dimColor: true, children: " to confirm" })] })] }));
215
227
  }
216
- function App({ registryPath, debug = false, proxyUrl }) {
228
+ function App({ registryPath, debug = false, proxyUrl, autoDeployConfigPath }) {
217
229
  const { stdout } = useStdout();
218
230
  const terminalWidth = stdout?.columns || 80;
219
231
  const [input, setInput] = useState('');
232
+ const [cursorOffset, setCursorOffset] = useState(0);
220
233
  // Initialize output with WelcomeScreen as first item - it will be rendered once via Static
221
234
  const [output, setOutput] = useState([_jsx(WelcomeScreen, {}, "welcome")]);
222
235
  const [currentConfig, setCurrentConfig] = useState(null);
@@ -232,6 +245,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
232
245
  const [isExiting, setIsExiting] = useState(false);
233
246
  const [queueState, setQueueState] = useState(null);
234
247
  const [showTips, setShowTips] = useState(true); // Tips bar visibility (default: on)
248
+ const autoDeployOnceRef = useRef(false);
235
249
  // Command history management
236
250
  const history = useHistory();
237
251
  // Track previous queue size to detect DROP-triggered clears
@@ -726,6 +740,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
726
740
  const result = history.searchBackward();
727
741
  if (result !== null) {
728
742
  setInput(result);
743
+ setCursorOffset(result.length);
729
744
  }
730
745
  }
731
746
  else {
@@ -741,6 +756,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
741
756
  const result = history.searchForward();
742
757
  if (result !== null) {
743
758
  setInput(result);
759
+ setCursorOffset(result.length);
744
760
  }
745
761
  return;
746
762
  }
@@ -754,6 +770,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
754
770
  const result = history.searchBackward();
755
771
  if (result !== null) {
756
772
  setInput(result);
773
+ setCursorOffset(result.length);
757
774
  }
758
775
  return;
759
776
  }
@@ -761,6 +778,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
761
778
  const historyEntry = history.navigateUp(input, historyMode);
762
779
  if (historyEntry !== null) {
763
780
  setInput(historyEntry);
781
+ setCursorOffset(historyEntry.length); // Reset cursor to end
764
782
  }
765
783
  return;
766
784
  }
@@ -774,6 +792,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
774
792
  const result = history.searchForward();
775
793
  if (result !== null) {
776
794
  setInput(result);
795
+ setCursorOffset(result.length);
777
796
  }
778
797
  return;
779
798
  }
@@ -781,6 +800,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
781
800
  const historyEntry = history.navigateDown(historyMode);
782
801
  if (historyEntry !== null) {
783
802
  setInput(historyEntry);
803
+ setCursorOffset(historyEntry.length); // Reset cursor to end
784
804
  }
785
805
  return;
786
806
  }
@@ -882,6 +902,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
882
902
  const historyEntry = history.jumpUp(input, historyMode);
883
903
  if (historyEntry !== null) {
884
904
  setInput(historyEntry);
905
+ setCursorOffset(historyEntry.length); // Reset cursor to end
885
906
  }
886
907
  return;
887
908
  }
@@ -894,17 +915,24 @@ function App({ registryPath, debug = false, proxyUrl }) {
894
915
  const historyEntry = history.jumpDown(historyMode);
895
916
  if (historyEntry !== null) {
896
917
  setInput(historyEntry);
918
+ setCursorOffset(historyEntry.length); // Reset cursor to end
897
919
  }
898
920
  return;
899
921
  }
900
922
  }
901
923
  // 处理不同模式下的上下键导航
902
924
  if (key.upArrow) {
925
+ // Multi-line input: if cursor is not on first line, let TextInput handle it
926
+ const lineInfo = getLineInfo(input, cursorOffset);
927
+ if (!lineInfo.isFirstLine) {
928
+ return; // Let TextInput handle line navigation
929
+ }
903
930
  // Search mode takes priority - navigate search results
904
931
  if (history.searchMode) {
905
932
  const result = history.searchBackward();
906
933
  if (result !== null) {
907
934
  setInput(result);
935
+ setCursorOffset(result.length);
908
936
  }
909
937
  return;
910
938
  }
@@ -914,6 +942,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
914
942
  const historyEntry = history.navigateUp(input, 'normal');
915
943
  if (historyEntry !== null) {
916
944
  setInput(historyEntry);
945
+ setCursorOffset(historyEntry.length); // Reset cursor to end
917
946
  }
918
947
  return;
919
948
  }
@@ -928,6 +957,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
928
957
  const historyEntry = history.navigateUp(input, 'normal');
929
958
  if (historyEntry !== null) {
930
959
  setInput(historyEntry);
960
+ setCursorOffset(historyEntry.length); // Reset cursor to end
931
961
  }
932
962
  return;
933
963
  }
@@ -936,6 +966,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
936
966
  const historyEntry = history.navigateUp(input, 'conversation');
937
967
  if (historyEntry !== null) {
938
968
  setInput(historyEntry);
969
+ setCursorOffset(historyEntry.length); // Reset cursor to end
939
970
  }
940
971
  return;
941
972
  }
@@ -949,11 +980,17 @@ function App({ registryPath, debug = false, proxyUrl }) {
949
980
  }
950
981
  }
951
982
  if (key.downArrow) {
983
+ // Multi-line input: if cursor is not on last line, let TextInput handle it
984
+ const lineInfo = getLineInfo(input, cursorOffset);
985
+ if (!lineInfo.isLastLine) {
986
+ return; // Let TextInput handle line navigation
987
+ }
952
988
  // Search mode takes priority - navigate search results
953
989
  if (history.searchMode) {
954
990
  const result = history.searchForward();
955
991
  if (result !== null) {
956
992
  setInput(result);
993
+ setCursorOffset(result.length);
957
994
  }
958
995
  return;
959
996
  }
@@ -963,6 +1000,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
963
1000
  const historyEntry = history.navigateDown('normal');
964
1001
  if (historyEntry !== null) {
965
1002
  setInput(historyEntry);
1003
+ setCursorOffset(historyEntry.length); // Reset cursor to end
966
1004
  }
967
1005
  return;
968
1006
  }
@@ -983,6 +1021,7 @@ function App({ registryPath, debug = false, proxyUrl }) {
983
1021
  const historyEntry = history.navigateDown('conversation');
984
1022
  if (historyEntry !== null) {
985
1023
  setInput(historyEntry);
1024
+ setCursorOffset(historyEntry.length); // Reset cursor to end
986
1025
  }
987
1026
  }
988
1027
  return;
@@ -1139,6 +1178,9 @@ function App({ registryPath, debug = false, proxyUrl }) {
1139
1178
  case '/agents':
1140
1179
  handleAgentsCommand(args);
1141
1180
  break;
1181
+ case '/login':
1182
+ await handleLoginCommand(args);
1183
+ break;
1142
1184
  case '/tips':
1143
1185
  if (args[0] === 'off') {
1144
1186
  setShowTips(false);
@@ -1202,6 +1244,71 @@ function App({ registryPath, debug = false, proxyUrl }) {
1202
1244
  }
1203
1245
  }
1204
1246
  };
1247
+ // Handle /login command
1248
+ const handleLoginCommand = async (args) => {
1249
+ if (args.length === 0) {
1250
+ // Show login help/region selection
1251
+ appendOutput(_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", children: "Login to HephOS Cloud" }), _jsx(Text, { dimColor: true, children: "Usage: /login <region> | /login status | /login logout" }), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "Available regions:" }), _jsxs(Text, { children: [" cn - ", AUTH_CONFIG.cn.displayName] }), _jsxs(Text, { children: [" us - ", AUTH_CONFIG.us.displayName] }), _jsx(Text, { children: " " }), _jsx(Text, { dimColor: true, children: "Commands:" }), _jsx(Text, { children: " /login cn - Login to CN region" }), _jsx(Text, { children: " /login us - Login to US region" }), _jsx(Text, { children: " /login status - Show authentication status" }), _jsx(Text, { children: " /login logout - Logout from current region" })] }, `login-help-${getNextKey()}`));
1252
+ return;
1253
+ }
1254
+ const subcommand = args[0].toLowerCase();
1255
+ if (subcommand === 'status') {
1256
+ // Show auth status
1257
+ const activeRegion = tokenCache.getActiveRegion();
1258
+ appendOutput(_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "cyan", children: "HephOS Authentication Status" }), _jsx(Text, { children: " " }), ['cn', 'us'].map(region => {
1259
+ const config = AUTH_CONFIG[region];
1260
+ const isValid = tokenCache.isValid(region);
1261
+ const userInfo = tokenCache.getUserInfo(region);
1262
+ const isActive = activeRegion === region;
1263
+ return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { children: [config.displayName, isActive && _jsx(Text, { color: "cyan", children: " (active)" })] }), _jsxs(Text, { children: [' Status: ', isValid
1264
+ ? _jsx(Text, { color: "green", children: "\u2713 Logged in" })
1265
+ : _jsx(Text, { dimColor: true, children: "\u2717 Not logged in" })] }), userInfo && (_jsxs(_Fragment, { children: [_jsxs(Text, { dimColor: true, children: [" Email: ", userInfo.email || 'N/A'] }), _jsxs(Text, { dimColor: true, children: [" User ID: ", userInfo.sub] })] }))] }, region));
1266
+ }), _jsxs(Text, { dimColor: true, children: ["Token cache: ", tokenCache.getCachePath()] })] }, `auth-status-${getNextKey()}`));
1267
+ return;
1268
+ }
1269
+ if (subcommand === 'logout') {
1270
+ const region = args[1]?.toLowerCase();
1271
+ const targetRegion = region && isValidRegion(region) ? region : tokenCache.getActiveRegion();
1272
+ if (!targetRegion) {
1273
+ appendOutput(_jsx(Text, { color: "yellow", children: "No active session to logout from." }, `logout-none-${getNextKey()}`));
1274
+ return;
1275
+ }
1276
+ const config = AUTH_CONFIG[targetRegion];
1277
+ appendOutput(_jsxs(Text, { dimColor: true, children: ["Logging out from ", config.displayName, "..."] }, `logout-msg-${getNextKey()}`));
1278
+ try {
1279
+ const authService = new AuthService(targetRegion);
1280
+ await authService.logout();
1281
+ appendOutput(_jsx(Text, { color: "green", children: "\u2713 Logged out successfully." }, `logout-ok-${getNextKey()}`));
1282
+ }
1283
+ catch (err) {
1284
+ tokenCache.clear(targetRegion);
1285
+ appendOutput(_jsx(Text, { color: "yellow", children: "Local tokens cleared." }, `logout-warn-${getNextKey()}`));
1286
+ }
1287
+ return;
1288
+ }
1289
+ // Login to a region
1290
+ if (!isValidRegion(subcommand)) {
1291
+ appendOutput(_jsxs(Text, { color: "red", children: ["Invalid region \"", subcommand, "\". Use 'cn' or 'us'."] }, `login-invalid-${getNextKey()}`));
1292
+ return;
1293
+ }
1294
+ const region = subcommand;
1295
+ const config = AUTH_CONFIG[region];
1296
+ appendOutput(_jsxs(Text, { color: "cyan", children: ["\uD83D\uDD10 Opening browser for HephOS login (", config.displayName, ")..."] }, `login-start-${getNextKey()}`));
1297
+ appendOutput(_jsx(Text, { dimColor: true, children: " Complete login in your browser to continue." }, `login-hint-${getNextKey()}`));
1298
+ try {
1299
+ const authService = new AuthService(region);
1300
+ const result = await authService.login();
1301
+ appendOutput(_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "green", children: "\u2713 Login successful!" }), _jsxs(Text, { bold: true, children: [" Welcome, ", result.userInfo.email || result.userInfo.name || result.userInfo.sub] }), _jsxs(Text, { dimColor: true, children: [" Token cached at: ", tokenCache.getCachePath()] })] }, `login-success-${getNextKey()}`));
1302
+ }
1303
+ catch (err) {
1304
+ if (err instanceof AuthError) {
1305
+ appendOutput(_jsxs(Text, { color: "red", children: ["\u2717 Login failed: ", err.message] }, `login-error-${getNextKey()}`));
1306
+ }
1307
+ else {
1308
+ appendOutput(_jsxs(Text, { color: "red", children: ["\u2717 Login failed: ", err instanceof Error ? err.message : String(err)] }, `login-error-${getNextKey()}`));
1309
+ }
1310
+ }
1311
+ };
1205
1312
  const handleTeamCommand = (args) => {
1206
1313
  if (args.length === 0) {
1207
1314
  appendOutput(_jsx(TeamMenuHelp, {}, `team-help-${getNextKey()}`));
@@ -1562,6 +1669,18 @@ function App({ registryPath, debug = false, proxyUrl }) {
1562
1669
  return null;
1563
1670
  }
1564
1671
  };
1672
+ useEffect(() => {
1673
+ if (!autoDeployConfigPath || autoDeployOnceRef.current)
1674
+ return;
1675
+ autoDeployOnceRef.current = true;
1676
+ const config = loadConfig(autoDeployConfigPath);
1677
+ if (config) {
1678
+ checkAndPromptRestore(config);
1679
+ }
1680
+ else {
1681
+ appendOutput(_jsxs(Text, { color: "red", children: ["\u2717 Failed to load config for auto deploy: ", autoDeployConfigPath] }, `auto-deploy-fail-${getNextKey()}`));
1682
+ }
1683
+ }, [autoDeployConfigPath]);
1565
1684
  const initializeAndDeployTeam = async (config) => {
1566
1685
  try {
1567
1686
  // Reset queue state tracking to avoid false "Queue cleared" on new session
@@ -1872,10 +1991,10 @@ function App({ registryPath, debug = false, proxyUrl }) {
1872
1991
  history.exitHistory();
1873
1992
  }
1874
1993
  setInput(val);
1875
- }, onSubmit: handleInputSubmit, placeholder: " " })] }), _jsx(Text, { color: mode === 'conversation' ? 'green' : 'cyan', dimColor: true, children: '─'.repeat(terminalWidth - 4) })] })), !isExiting && (mode === 'normal' || mode === 'conversation') && (history.isActive || history.searchMode) && (_jsx(HistoryOverlay, { visible: true, entries: history.entries, currentIndex: history.currentIndex, activeMode: history.activeMode, searchMode: history.searchMode, searchQuery: history.searchQuery, terminalWidth: terminalWidth })), !isExiting && mode === 'normal' && !history.isActive && !history.searchMode && _jsx(CommandHints, { input: input, selectedIndex: selectedIndex }), !isExiting && mode === 'conversation' && !history.isActive && !history.searchMode && (_jsx(TipsBar, { visible: showTips, terminalWidth: terminalWidth }))] }));
1994
+ }, onSubmit: handleInputSubmit, onCursorChange: setCursorOffset, placeholder: " " })] }), _jsx(Text, { color: mode === 'conversation' ? 'green' : 'cyan', dimColor: true, children: '─'.repeat(terminalWidth - 4) })] })), !isExiting && (mode === 'normal' || mode === 'conversation') && (history.isActive || history.searchMode) && (_jsx(HistoryOverlay, { visible: true, entries: history.entries, currentIndex: history.currentIndex, activeMode: history.activeMode, searchMode: history.searchMode, searchQuery: history.searchQuery, terminalWidth: terminalWidth })), !isExiting && mode === 'normal' && !history.isActive && !history.searchMode && _jsx(CommandHints, { input: input, selectedIndex: selectedIndex }), !isExiting && mode === 'conversation' && !history.isActive && !history.searchMode && (_jsx(TipsBar, { visible: showTips, terminalWidth: terminalWidth }))] }));
1876
1995
  }
1877
1996
  export function startReplInk(registryPath, options = {}) {
1878
- render(_jsx(App, { registryPath: registryPath, debug: options.debug, proxyUrl: options.proxyUrl }), {
1997
+ render(_jsx(App, { registryPath: registryPath, debug: options.debug, proxyUrl: options.proxyUrl, autoDeployConfigPath: options.autoDeployConfigPath }), {
1879
1998
  // Don't use alternateBuffer - it prevents scrolling for long agent outputs
1880
1999
  // Trade-off: long input lines may cause duplicate prompts, but scrolling works
1881
2000
  incrementalRendering: true