aemeathcli 1.0.10 → 1.0.12

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 (184) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +66 -54
  3. package/dist/App-JQ622M66.js +4431 -0
  4. package/dist/App-JQ622M66.js.map +1 -0
  5. package/dist/agent-store/architect.md +32 -0
  6. package/dist/agent-store/debugger.md +32 -0
  7. package/dist/agent-store/developer.md +29 -0
  8. package/dist/agent-store/documenter.md +30 -0
  9. package/dist/agent-store/researcher.md +31 -0
  10. package/dist/agent-store/reviewer.md +28 -0
  11. package/dist/agent-store/supervisor.md +37 -0
  12. package/dist/agent-store/tester.md +30 -0
  13. package/dist/api-key-fallback-RJLPM3KH.js +11 -0
  14. package/dist/{api-key-fallback-YQQBOQIL.js.map → api-key-fallback-RJLPM3KH.js.map} +1 -1
  15. package/dist/auth-status-JQJOKUPF.js +13 -0
  16. package/dist/auth-status-JQJOKUPF.js.map +1 -0
  17. package/dist/{chunk-RWCNNAL7.js → chunk-2KMA5RBC.js} +25 -48
  18. package/dist/chunk-2KMA5RBC.js.map +1 -0
  19. package/dist/{chunk-CYQNBB25.js → chunk-2Y7TR6BS.js} +28 -5
  20. package/dist/chunk-2Y7TR6BS.js.map +1 -0
  21. package/dist/{chunk-DAHGLHNR.js → chunk-2ZYK5IJG.js} +6 -141
  22. package/dist/chunk-2ZYK5IJG.js.map +1 -0
  23. package/dist/chunk-36RXCZOV.js +88 -0
  24. package/dist/chunk-36RXCZOV.js.map +1 -0
  25. package/dist/{chunk-DMBPX3RG.js → chunk-7EBLXPL4.js} +9 -9
  26. package/dist/{chunk-DMBPX3RG.js.map → chunk-7EBLXPL4.js.map} +1 -1
  27. package/dist/chunk-BIMQL4AG.js +186 -0
  28. package/dist/chunk-BIMQL4AG.js.map +1 -0
  29. package/dist/{chunk-NBR3GHMT.js → chunk-D275MCIH.js} +39 -7
  30. package/dist/chunk-D275MCIH.js.map +1 -0
  31. package/dist/{chunk-Y5XVD2CD.js → chunk-FFS4T7BZ.js} +109 -82
  32. package/dist/chunk-FFS4T7BZ.js.map +1 -0
  33. package/dist/{chunk-CARHU3DO.js → chunk-GXAJGP2T.js} +64 -16
  34. package/dist/chunk-GXAJGP2T.js.map +1 -0
  35. package/dist/{chunk-I5PZ4JTS.js → chunk-HESQLCLU.js} +4 -4
  36. package/dist/{chunk-I5PZ4JTS.js.map → chunk-HESQLCLU.js.map} +1 -1
  37. package/dist/{chunk-JAXXTYID.js → chunk-IR5HLBMH.js} +2 -2
  38. package/dist/{chunk-JAXXTYID.js.map → chunk-IR5HLBMH.js.map} +1 -1
  39. package/dist/{chunk-MFBHNWGV.js → chunk-K2FCMRXH.js} +11 -19
  40. package/dist/chunk-K2FCMRXH.js.map +1 -0
  41. package/dist/{chunk-H66O5Z2V.js → chunk-KIC7UI5U.js} +41 -6
  42. package/dist/chunk-KIC7UI5U.js.map +1 -0
  43. package/dist/{chunk-MXZSI3AY.js → chunk-KMOAJRDE.js} +42 -10
  44. package/dist/chunk-KMOAJRDE.js.map +1 -0
  45. package/dist/chunk-LQBALETG.js +71 -0
  46. package/dist/chunk-LQBALETG.js.map +1 -0
  47. package/dist/chunk-M3FPQSRU.js +12 -0
  48. package/dist/chunk-M3FPQSRU.js.map +1 -0
  49. package/dist/chunk-NQEUK763.js +26 -0
  50. package/dist/chunk-NQEUK763.js.map +1 -0
  51. package/dist/chunk-OPWAFS6Y.js +38 -0
  52. package/dist/chunk-OPWAFS6Y.js.map +1 -0
  53. package/dist/{chunk-6PDJ45T4.js → chunk-PS4WEFW6.js} +50 -25
  54. package/dist/chunk-PS4WEFW6.js.map +1 -0
  55. package/dist/{chunk-HMJRPNPZ.js → chunk-QK7TKNHV.js} +93 -21
  56. package/dist/chunk-QK7TKNHV.js.map +1 -0
  57. package/dist/{chunk-LSOYPSAT.js → chunk-RADJSEG5.js} +4 -4
  58. package/dist/chunk-RADJSEG5.js.map +1 -0
  59. package/dist/{chunk-4IJD72YB.js → chunk-SNWPI6XJ.js} +7 -7
  60. package/dist/chunk-SNWPI6XJ.js.map +1 -0
  61. package/dist/{chunk-TEVZS4FA.js → chunk-UM7MSLOV.js} +16 -9
  62. package/dist/chunk-UM7MSLOV.js.map +1 -0
  63. package/dist/chunk-VNZ3YTQD.js +232 -0
  64. package/dist/chunk-VNZ3YTQD.js.map +1 -0
  65. package/dist/{chunk-IYW62KKR.js → chunk-WXIN65UG.js} +66 -23
  66. package/dist/chunk-WXIN65UG.js.map +1 -0
  67. package/dist/chunk-XEXWX7C7.js +241 -0
  68. package/dist/chunk-XEXWX7C7.js.map +1 -0
  69. package/dist/{chunk-CGEV3ARR.js → chunk-YCCYXDW7.js} +3 -3
  70. package/dist/chunk-YCCYXDW7.js.map +1 -0
  71. package/dist/chunk-YPQ2MLAV.js +140 -0
  72. package/dist/chunk-YPQ2MLAV.js.map +1 -0
  73. package/dist/chunk-ZCOVMVK4.js +26 -0
  74. package/dist/chunk-ZCOVMVK4.js.map +1 -0
  75. package/dist/{claude-login-5WELXPKT.js → claude-login-AIFIWTYF.js} +9 -9
  76. package/dist/{claude-login-5WELXPKT.js.map → claude-login-AIFIWTYF.js.map} +1 -1
  77. package/dist/cli.js +370 -171
  78. package/dist/cli.js.map +1 -1
  79. package/dist/{codex-login-GZIFXUWD.js → codex-login-LW5X7GAM.js} +10 -10
  80. package/dist/codex-login-LW5X7GAM.js.map +1 -0
  81. package/dist/config-store-NF56VHFU.js +7 -0
  82. package/dist/{config-store-W6FBCQAQ.js.map → config-store-NF56VHFU.js.map} +1 -1
  83. package/dist/conversation-store-7GRDQZD2.js +4 -0
  84. package/dist/conversation-store-7GRDQZD2.js.map +1 -0
  85. package/dist/detect-providers-QICJ5U3R.js +4 -0
  86. package/dist/detect-providers-QICJ5U3R.js.map +1 -0
  87. package/dist/executor-FTABX2AW.js +4 -0
  88. package/dist/{executor-6RIKIGXK.js.map → executor-FTABX2AW.js.map} +1 -1
  89. package/dist/first-run-ADROZVYF.js +230 -0
  90. package/dist/first-run-ADROZVYF.js.map +1 -0
  91. package/dist/{gemini-login-AZGL3CE7.js → gemini-login-TST454MX.js} +9 -9
  92. package/dist/{gemini-login-AZGL3CE7.js.map → gemini-login-TST454MX.js.map} +1 -1
  93. package/dist/index.d.ts +46 -70
  94. package/dist/index.js +79 -468
  95. package/dist/index.js.map +1 -1
  96. package/dist/input-history-BEICE7PT.js +57 -0
  97. package/dist/input-history-BEICE7PT.js.map +1 -0
  98. package/dist/kimi-adapter-7FYOAKOI.js +6 -0
  99. package/dist/{kimi-adapter-JN4HFFHU.js.map → kimi-adapter-7FYOAKOI.js.map} +1 -1
  100. package/dist/{kimi-login-6LUWB7P6.js → kimi-login-3IGVOBJI.js} +9 -9
  101. package/dist/{kimi-login-6LUWB7P6.js.map → kimi-login-3IGVOBJI.js.map} +1 -1
  102. package/dist/logger-KGHUQ4VE.js +3 -0
  103. package/dist/logger-KGHUQ4VE.js.map +1 -0
  104. package/dist/model-discovery-AAJDHRFO.js +6 -0
  105. package/dist/model-discovery-AAJDHRFO.js.map +1 -0
  106. package/dist/native-cli-adapters-CLONTZOA.js +8 -0
  107. package/dist/{native-cli-adapters-OLW3XX57.js.map → native-cli-adapters-CLONTZOA.js.map} +1 -1
  108. package/dist/ollama-adapter-2N5OQIEV.js +5 -0
  109. package/dist/{ollama-adapter-OJQ3FKWK.js.map → ollama-adapter-2N5OQIEV.js.map} +1 -1
  110. package/dist/pathResolver-UVAB2FCW.js +3 -0
  111. package/dist/pathResolver-UVAB2FCW.js.map +1 -0
  112. package/dist/profile-loader-EMLV4J7S.js +162 -0
  113. package/dist/profile-loader-EMLV4J7S.js.map +1 -0
  114. package/dist/registry-LRURZVUL.js +5 -0
  115. package/dist/{registry-AZ2LOHHJ.js.map → registry-LRURZVUL.js.map} +1 -1
  116. package/dist/registry-MVNSXCEF.js +6 -0
  117. package/dist/{registry-H7B3AHPQ.js.map → registry-MVNSXCEF.js.map} +1 -1
  118. package/dist/server-manager-THGZBBZB.js +5 -0
  119. package/dist/{server-manager-PTGBHCLS.js.map → server-manager-THGZBBZB.js.map} +1 -1
  120. package/dist/session-manager-X3DXT53M.js +12 -0
  121. package/dist/{session-manager-XOMDMC77.js.map → session-manager-X3DXT53M.js.map} +1 -1
  122. package/dist/skills/built-in/code-review/SKILL.md +85 -0
  123. package/dist/skills/built-in/commit/SKILL.md +83 -0
  124. package/dist/skills/built-in/debug/SKILL.md +119 -0
  125. package/dist/skills/built-in/plan/SKILL.md +123 -0
  126. package/dist/skills/built-in/refactor/SKILL.md +132 -0
  127. package/dist/skills/built-in/test/SKILL.md +128 -0
  128. package/dist/sqlite-store-7OECRTXM.js +5 -0
  129. package/dist/sqlite-store-7OECRTXM.js.map +1 -0
  130. package/dist/team-manager-2VSMALAA.js +11 -0
  131. package/dist/{team-manager-HC4XGCFY.js.map → team-manager-2VSMALAA.js.map} +1 -1
  132. package/dist/team-state-HZNVMQHT.js +3 -0
  133. package/dist/team-state-HZNVMQHT.js.map +1 -0
  134. package/dist/tmux-manager-57QCUVHU.js +6 -0
  135. package/dist/{tmux-manager-GPYZ3WQH.js.map → tmux-manager-57QCUVHU.js.map} +1 -1
  136. package/dist/tools-KWFSYT56.js +6 -0
  137. package/dist/{tools-TSMXMHIF.js.map → tools-KWFSYT56.js.map} +1 -1
  138. package/package.json +11 -11
  139. package/dist/App-FKRSMFMB.js +0 -2789
  140. package/dist/App-FKRSMFMB.js.map +0 -1
  141. package/dist/api-key-fallback-YQQBOQIL.js +0 -11
  142. package/dist/chunk-4IJD72YB.js.map +0 -1
  143. package/dist/chunk-6PDJ45T4.js.map +0 -1
  144. package/dist/chunk-CARHU3DO.js.map +0 -1
  145. package/dist/chunk-CGEV3ARR.js.map +0 -1
  146. package/dist/chunk-CS5X3BWX.js +0 -27
  147. package/dist/chunk-CS5X3BWX.js.map +0 -1
  148. package/dist/chunk-CYQNBB25.js.map +0 -1
  149. package/dist/chunk-DAHGLHNR.js.map +0 -1
  150. package/dist/chunk-H66O5Z2V.js.map +0 -1
  151. package/dist/chunk-HMJRPNPZ.js.map +0 -1
  152. package/dist/chunk-IYW62KKR.js.map +0 -1
  153. package/dist/chunk-LSOYPSAT.js.map +0 -1
  154. package/dist/chunk-MFBHNWGV.js.map +0 -1
  155. package/dist/chunk-MXZSI3AY.js.map +0 -1
  156. package/dist/chunk-NBR3GHMT.js.map +0 -1
  157. package/dist/chunk-RWCNNAL7.js.map +0 -1
  158. package/dist/chunk-TEVZS4FA.js.map +0 -1
  159. package/dist/chunk-UY2SYSEZ.js +0 -211
  160. package/dist/chunk-UY2SYSEZ.js.map +0 -1
  161. package/dist/chunk-WAHVZH7V.js +0 -260
  162. package/dist/chunk-WAHVZH7V.js.map +0 -1
  163. package/dist/chunk-WPP3PEDE.js +0 -234
  164. package/dist/chunk-WPP3PEDE.js.map +0 -1
  165. package/dist/chunk-Y5XVD2CD.js.map +0 -1
  166. package/dist/claude-adapter-QMLFMSP3.js +0 -6
  167. package/dist/claude-adapter-QMLFMSP3.js.map +0 -1
  168. package/dist/codex-login-GZIFXUWD.js.map +0 -1
  169. package/dist/config-store-W6FBCQAQ.js +0 -6
  170. package/dist/executor-6RIKIGXK.js +0 -4
  171. package/dist/gemini-adapter-6JIHZ7WI.js +0 -6
  172. package/dist/gemini-adapter-6JIHZ7WI.js.map +0 -1
  173. package/dist/kimi-adapter-JN4HFFHU.js +0 -6
  174. package/dist/native-cli-adapters-OLW3XX57.js +0 -6
  175. package/dist/ollama-adapter-OJQ3FKWK.js +0 -6
  176. package/dist/openai-adapter-XU46EN7B.js +0 -6
  177. package/dist/openai-adapter-XU46EN7B.js.map +0 -1
  178. package/dist/registry-AZ2LOHHJ.js +0 -6
  179. package/dist/registry-H7B3AHPQ.js +0 -5
  180. package/dist/server-manager-PTGBHCLS.js +0 -5
  181. package/dist/session-manager-XOMDMC77.js +0 -12
  182. package/dist/team-manager-HC4XGCFY.js +0 -11
  183. package/dist/tmux-manager-GPYZ3WQH.js +0 -6
  184. package/dist/tools-TSMXMHIF.js +0 -6
@@ -0,0 +1,230 @@
1
+ import { detectInstalledProviders } from './chunk-NQEUK763.js';
2
+ import { CLI_PROVIDER_ORDER, getCliProviderEntry } from './chunk-LQBALETG.js';
3
+ import { ConfigStore } from './chunk-WXIN65UG.js';
4
+ import './chunk-M3FPQSRU.js';
5
+ import { PACKAGE_VERSION, DEFAULT_CONFIG } from './chunk-2Y7TR6BS.js';
6
+ import './chunk-IR5HLBMH.js';
7
+ import { getConfigPath } from './chunk-D275MCIH.js';
8
+ import { existsSync } from 'fs';
9
+ import pc from 'picocolors';
10
+
11
+ function hasGlobalConfig() {
12
+ return existsSync(getConfigPath());
13
+ }
14
+ function isInteractiveTerminal() {
15
+ return process.stdin.isTTY && process.stdout.isTTY;
16
+ }
17
+ function createInitialConfig() {
18
+ return {
19
+ ...DEFAULT_CONFIG,
20
+ version: PACKAGE_VERSION
21
+ };
22
+ }
23
+ function ensureDefaultConfig() {
24
+ const store = new ConfigStore();
25
+ const configPath = getConfigPath();
26
+ if (hasGlobalConfig()) {
27
+ return {
28
+ configPath,
29
+ created: false,
30
+ config: store.loadGlobal()
31
+ };
32
+ }
33
+ const config = createInitialConfig();
34
+ store.saveGlobal(config);
35
+ return {
36
+ configPath,
37
+ created: true,
38
+ config
39
+ };
40
+ }
41
+ async function createFirstRunLogin(provider) {
42
+ switch (provider) {
43
+ case "claude": {
44
+ const { ClaudeLogin } = await import('./claude-login-AIFIWTYF.js');
45
+ return new ClaudeLogin();
46
+ }
47
+ case "codex": {
48
+ const { CodexLogin } = await import('./codex-login-LW5X7GAM.js');
49
+ return new CodexLogin();
50
+ }
51
+ case "gemini": {
52
+ const { GeminiLogin } = await import('./gemini-login-TST454MX.js');
53
+ return new GeminiLogin();
54
+ }
55
+ case "kimi": {
56
+ const { KimiLogin } = await import('./kimi-login-3IGVOBJI.js');
57
+ return new KimiLogin();
58
+ }
59
+ }
60
+ }
61
+ function writeWelcomeBanner() {
62
+ process.stdout.write(
63
+ [
64
+ "",
65
+ pc.cyan(" \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557"),
66
+ pc.cyan(" \u2551 Welcome to AemeathCLI \u2551"),
67
+ pc.cyan(` \u2551 Multi-Model CLI Coding Tool v${PACKAGE_VERSION.padEnd(10)} \u2551`),
68
+ pc.cyan(" \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D"),
69
+ "",
70
+ " Let's get you set up:",
71
+ ""
72
+ ].join("\n")
73
+ );
74
+ }
75
+ async function runFirstRunSetup(options = {}) {
76
+ const configPath = getConfigPath();
77
+ if (hasGlobalConfig() && !options.force) {
78
+ const store2 = new ConfigStore();
79
+ return {
80
+ configPath,
81
+ created: false,
82
+ config: store2.loadGlobal()
83
+ };
84
+ }
85
+ const store = new ConfigStore();
86
+ const config = createInitialConfig();
87
+ const detectedProviders = detectInstalledProviders();
88
+ if (options.defaults || !isInteractiveTerminal()) {
89
+ const defaultPrimaryMasterProvider = detectedProviders[0];
90
+ const configWithDefaults = {
91
+ ...config,
92
+ swarm: {
93
+ onboardingComplete: true,
94
+ detectedProviders,
95
+ primaryMasterProvider: defaultPrimaryMasterProvider,
96
+ fallbackMasterProviders: detectedProviders.slice(1)
97
+ }
98
+ };
99
+ store.saveGlobal(configWithDefaults);
100
+ const modeLabel = options.defaults ? "defaults" : "non-interactive defaults";
101
+ process.stdout.write(
102
+ `${pc.green("\u2713")} Saved ${modeLabel} to ${pc.cyan(configPath)}
103
+ `
104
+ );
105
+ return {
106
+ configPath,
107
+ created: true,
108
+ config: configWithDefaults
109
+ };
110
+ }
111
+ const { checkbox, confirm, select } = await import('@inquirer/prompts');
112
+ writeWelcomeBanner();
113
+ const detectedLines = CLI_PROVIDER_ORDER.map((provider) => {
114
+ const entry = getCliProviderEntry(provider);
115
+ const installed = detectedProviders.includes(provider);
116
+ return ` ${installed ? pc.green("\u2713") : pc.dim("\u25CB")} ${entry.label} \u2014 ${installed ? "installed" : "not detected"}`;
117
+ });
118
+ process.stdout.write(`${detectedLines.join("\n")}
119
+
120
+ `);
121
+ const loginChoices = CLI_PROVIDER_ORDER.map((provider) => {
122
+ const entry = getCliProviderEntry(provider);
123
+ if (entry.loginProvider === void 0) {
124
+ return void 0;
125
+ }
126
+ const installed = detectedProviders.includes(provider);
127
+ return {
128
+ name: `${entry.label}${installed ? "" : " (not detected, login only)"}`,
129
+ value: entry.loginProvider,
130
+ checked: installed && provider !== "kimi-cli"
131
+ };
132
+ }).filter((choice) => choice !== void 0);
133
+ const selectedLoginProviders = await checkbox({
134
+ message: "Which providers should be authenticated during setup?",
135
+ choices: loginChoices
136
+ });
137
+ for (const provider of selectedLoginProviders) {
138
+ process.stdout.write(pc.cyan(` Logging in to ${provider}...
139
+ `));
140
+ try {
141
+ const login = await createFirstRunLogin(provider);
142
+ await login.login();
143
+ process.stdout.write(pc.green(` \u2713 ${provider} \u2014 Logged in successfully
144
+ `));
145
+ } catch (error) {
146
+ const message = error instanceof Error ? error.message : String(error);
147
+ process.stdout.write(pc.yellow(` ! ${provider} \u2014 Login skipped: ${message}
148
+ `));
149
+ }
150
+ }
151
+ if (detectedProviders.includes("ollama")) {
152
+ process.stdout.write(pc.green(" \u2713 ollama \u2014 Local agent runtime detected\n"));
153
+ }
154
+ let primaryMasterProvider;
155
+ let fallbackMasterProviders = [];
156
+ if (detectedProviders.length > 0) {
157
+ primaryMasterProvider = await select({
158
+ message: "Choose the primary master agent provider for swarm orchestration:",
159
+ choices: detectedProviders.map((provider) => ({
160
+ name: `${getCliProviderEntry(provider).label} \u2014 ${getCliProviderEntry(provider).description}`,
161
+ value: provider
162
+ }))
163
+ });
164
+ const remainingProviders = detectedProviders.filter(
165
+ (provider) => provider !== primaryMasterProvider
166
+ );
167
+ if (remainingProviders.length > 0) {
168
+ fallbackMasterProviders = await checkbox({
169
+ message: "Select optional fallback master-agent providers:",
170
+ choices: remainingProviders.map((provider) => ({
171
+ name: `${getCliProviderEntry(provider).label} \u2014 ${getCliProviderEntry(provider).description}`,
172
+ value: provider
173
+ }))
174
+ });
175
+ }
176
+ } else {
177
+ process.stdout.write(
178
+ `${pc.yellow(" !")} No supported native agent CLIs were detected. You can still use direct chat, but swarm orchestration will stay limited until one is installed.
179
+ `
180
+ );
181
+ }
182
+ const keepRoleDefaults = await confirm({
183
+ message: "Keep the recommended role-routing defaults?",
184
+ default: true
185
+ });
186
+ const configuredProviders = {
187
+ ...config.providers
188
+ };
189
+ for (const provider of detectedProviders) {
190
+ const entry = getCliProviderEntry(provider);
191
+ configuredProviders[entry.provider] = {
192
+ ...configuredProviders[entry.provider],
193
+ enabled: true
194
+ };
195
+ }
196
+ const finalConfig = {
197
+ ...config,
198
+ roles: keepRoleDefaults ? DEFAULT_CONFIG.roles : config.roles,
199
+ providers: configuredProviders,
200
+ swarm: {
201
+ onboardingComplete: true,
202
+ detectedProviders,
203
+ primaryMasterProvider,
204
+ fallbackMasterProviders
205
+ }
206
+ };
207
+ store.saveGlobal(finalConfig);
208
+ process.stdout.write(
209
+ [
210
+ "",
211
+ ` ${pc.green("\u2713")} Configuration saved to ${pc.cyan(configPath)}`,
212
+ "",
213
+ ` Swarm primary: ${primaryMasterProvider ? getCliProviderEntry(primaryMasterProvider).label : "not set"}`,
214
+ ` Swarm fallbacks: ${fallbackMasterProviders.length > 0 ? fallbackMasterProviders.map(getCliProviderEntry).map((entry) => entry.label).join(", ") : "none"}`,
215
+ "",
216
+ " Ready. Start with `aemeathcli` or `ac`.",
217
+ " Use Shift+Tab inside the TUI to switch between swarm, guided edits, and direct chat.",
218
+ ""
219
+ ].join("\n")
220
+ );
221
+ return {
222
+ configPath,
223
+ created: true,
224
+ config: finalConfig
225
+ };
226
+ }
227
+
228
+ export { createInitialConfig, ensureDefaultConfig, hasGlobalConfig, isInteractiveTerminal, runFirstRunSetup };
229
+ //# sourceMappingURL=first-run-ADROZVYF.js.map
230
+ //# sourceMappingURL=first-run-ADROZVYF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/setup/first-run.ts"],"names":["store"],"mappings":"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","file":"first-run-ADROZVYF.js","sourcesContent":["import { existsSync } from \"node:fs\";\n\nimport pc from \"picocolors\";\n\nimport type { CliProviderType } from \"../../orchestrator/constants.js\";\nimport { CLI_PROVIDER_ORDER, getCliProviderEntry, type LoginProvider } from \"../../orchestrator/utils/provider-catalog.js\";\nimport { detectInstalledProviders } from \"../../orchestrator/utils/detect-providers.js\";\nimport { ConfigStore } from \"../../storage/config-store.js\";\nimport { DEFAULT_CONFIG, type IGlobalConfig } from \"../../types/config.js\";\nimport { getConfigPath } from \"../../utils/pathResolver.js\";\nimport { PACKAGE_VERSION } from \"../../version.js\";\n\ninterface IFirstRunLogin {\n login(): Promise<unknown>;\n}\n\nexport interface FirstRunSetupOptions {\n readonly defaults?: boolean;\n readonly force?: boolean;\n}\n\nexport interface FirstRunSetupResult {\n readonly configPath: string;\n readonly created: boolean;\n readonly config: IGlobalConfig;\n}\n\nexport function hasGlobalConfig(): boolean {\n return existsSync(getConfigPath());\n}\n\nexport function isInteractiveTerminal(): boolean {\n return process.stdin.isTTY && process.stdout.isTTY;\n}\n\nexport function createInitialConfig(): IGlobalConfig {\n return {\n ...DEFAULT_CONFIG,\n version: PACKAGE_VERSION,\n };\n}\n\nexport function ensureDefaultConfig(): FirstRunSetupResult {\n const store = new ConfigStore();\n const configPath = getConfigPath();\n\n if (hasGlobalConfig()) {\n return {\n configPath,\n created: false,\n config: store.loadGlobal(),\n };\n }\n\n const config = createInitialConfig();\n store.saveGlobal(config);\n\n return {\n configPath,\n created: true,\n config,\n };\n}\n\nasync function createFirstRunLogin(provider: LoginProvider): Promise<IFirstRunLogin> {\n switch (provider) {\n case \"claude\": {\n const { ClaudeLogin } = await import(\"../../auth/providers/claude-login.js\");\n return new ClaudeLogin();\n }\n case \"codex\": {\n const { CodexLogin } = await import(\"../../auth/providers/codex-login.js\");\n return new CodexLogin();\n }\n case \"gemini\": {\n const { GeminiLogin } = await import(\"../../auth/providers/gemini-login.js\");\n return new GeminiLogin();\n }\n case \"kimi\": {\n const { KimiLogin } = await import(\"../../auth/providers/kimi-login.js\");\n return new KimiLogin();\n }\n }\n}\n\nfunction writeWelcomeBanner(): void {\n process.stdout.write(\n [\n \"\",\n pc.cyan(\" ╔══════════════════════════════════════════════╗\"),\n pc.cyan(\" ║ Welcome to AemeathCLI ║\"),\n pc.cyan(` ║ Multi-Model CLI Coding Tool v${PACKAGE_VERSION.padEnd(10)} ║`),\n pc.cyan(\" ╚══════════════════════════════════════════════╝\"),\n \"\",\n \" Let's get you set up:\",\n \"\",\n ].join(\"\\n\"),\n );\n}\n\nexport async function runFirstRunSetup(\n options: FirstRunSetupOptions = {},\n): Promise<FirstRunSetupResult> {\n const configPath = getConfigPath();\n if (hasGlobalConfig() && !options.force) {\n const store = new ConfigStore();\n return {\n configPath,\n created: false,\n config: store.loadGlobal(),\n };\n }\n\n const store = new ConfigStore();\n const config = createInitialConfig();\n const detectedProviders = detectInstalledProviders();\n\n if (options.defaults || !isInteractiveTerminal()) {\n const defaultPrimaryMasterProvider = detectedProviders[0];\n const configWithDefaults: IGlobalConfig = {\n ...config,\n swarm: {\n onboardingComplete: true,\n detectedProviders,\n primaryMasterProvider: defaultPrimaryMasterProvider,\n fallbackMasterProviders: detectedProviders.slice(1),\n },\n };\n store.saveGlobal(configWithDefaults);\n\n const modeLabel = options.defaults ? \"defaults\" : \"non-interactive defaults\";\n process.stdout.write(\n `${pc.green(\"✓\")} Saved ${modeLabel} to ${pc.cyan(configPath)}\\n`,\n );\n\n return {\n configPath,\n created: true,\n config: configWithDefaults,\n };\n }\n\n const { checkbox, confirm, select } = await import(\"@inquirer/prompts\");\n\n writeWelcomeBanner();\n\n const detectedLines = CLI_PROVIDER_ORDER.map((provider) => {\n const entry = getCliProviderEntry(provider);\n const installed = detectedProviders.includes(provider);\n return ` ${installed ? pc.green(\"✓\") : pc.dim(\"○\")} ${entry.label} — ${installed ? \"installed\" : \"not detected\"}`;\n });\n process.stdout.write(`${detectedLines.join(\"\\n\")}\\n\\n`);\n\n const loginChoices = CLI_PROVIDER_ORDER\n .map((provider) => {\n const entry = getCliProviderEntry(provider);\n if (entry.loginProvider === undefined) {\n return undefined;\n }\n\n const installed = detectedProviders.includes(provider);\n return {\n name: `${entry.label}${installed ? \"\" : \" (not detected, login only)\"}`,\n value: entry.loginProvider,\n checked: installed && provider !== \"kimi-cli\",\n };\n })\n .filter((choice): choice is { name: string; value: LoginProvider; checked: boolean } => choice !== undefined);\n\n const selectedLoginProviders = await checkbox<LoginProvider>({\n message: \"Which providers should be authenticated during setup?\",\n choices: loginChoices,\n });\n\n for (const provider of selectedLoginProviders) {\n process.stdout.write(pc.cyan(` Logging in to ${provider}...\\n`));\n try {\n const login = await createFirstRunLogin(provider);\n await login.login();\n process.stdout.write(pc.green(` ✓ ${provider} — Logged in successfully\\n`));\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n process.stdout.write(pc.yellow(` ! ${provider} — Login skipped: ${message}\\n`));\n }\n }\n\n if (detectedProviders.includes(\"ollama\")) {\n process.stdout.write(pc.green(\" ✓ ollama — Local agent runtime detected\\n\"));\n }\n\n let primaryMasterProvider: CliProviderType | undefined;\n let fallbackMasterProviders: CliProviderType[] = [];\n\n if (detectedProviders.length > 0) {\n primaryMasterProvider = await select<CliProviderType>({\n message: \"Choose the primary master agent provider for swarm orchestration:\",\n choices: detectedProviders.map((provider) => ({\n name: `${getCliProviderEntry(provider).label} — ${getCliProviderEntry(provider).description}`,\n value: provider,\n })),\n });\n\n const remainingProviders = detectedProviders.filter(\n (provider) => provider !== primaryMasterProvider,\n );\n\n if (remainingProviders.length > 0) {\n fallbackMasterProviders = await checkbox<CliProviderType>({\n message: \"Select optional fallback master-agent providers:\",\n choices: remainingProviders.map((provider) => ({\n name: `${getCliProviderEntry(provider).label} — ${getCliProviderEntry(provider).description}`,\n value: provider,\n })),\n });\n }\n } else {\n process.stdout.write(\n `${pc.yellow(\" !\")} No supported native agent CLIs were detected. You can still use direct chat, but swarm orchestration will stay limited until one is installed.\\n`,\n );\n }\n\n const keepRoleDefaults = await confirm({\n message: \"Keep the recommended role-routing defaults?\",\n default: true,\n });\n\n const configuredProviders: IGlobalConfig[\"providers\"] = {\n ...config.providers,\n };\n for (const provider of detectedProviders) {\n const entry = getCliProviderEntry(provider);\n configuredProviders[entry.provider] = {\n ...configuredProviders[entry.provider],\n enabled: true,\n };\n }\n\n const finalConfig: IGlobalConfig = {\n ...config,\n roles: keepRoleDefaults ? DEFAULT_CONFIG.roles : config.roles,\n providers: configuredProviders,\n swarm: {\n onboardingComplete: true,\n detectedProviders,\n primaryMasterProvider,\n fallbackMasterProviders,\n },\n };\n\n store.saveGlobal(finalConfig);\n\n process.stdout.write(\n [\n \"\",\n ` ${pc.green(\"✓\")} Configuration saved to ${pc.cyan(configPath)}`,\n \"\",\n ` Swarm primary: ${primaryMasterProvider ? getCliProviderEntry(primaryMasterProvider).label : \"not set\"}`,\n ` Swarm fallbacks: ${fallbackMasterProviders.length > 0 ? fallbackMasterProviders.map(getCliProviderEntry).map((entry) => entry.label).join(\", \") : \"none\"}`,\n \"\",\n \" Ready. Start with `aemeathcli` or `ac`.\",\n \" Use Shift+Tab inside the TUI to switch between swarm, guided edits, and direct chat.\",\n \"\",\n ].join(\"\\n\"),\n );\n\n return {\n configPath,\n created: true,\n config: finalConfig,\n };\n}\n"]}
@@ -1,11 +1,11 @@
1
- import { CredentialStore } from './chunk-4IJD72YB.js';
2
- import './chunk-CGEV3ARR.js';
3
- import './chunk-CYQNBB25.js';
4
- import './chunk-NBR3GHMT.js';
5
- import './chunk-CS5X3BWX.js';
6
- import './chunk-HCIHOHLX.js';
1
+ import { CredentialStore } from './chunk-SNWPI6XJ.js';
2
+ import './chunk-YCCYXDW7.js';
3
+ import './chunk-OPWAFS6Y.js';
7
4
  import { AuthenticationError } from './chunk-ZGOHARPV.js';
8
- import { logger } from './chunk-JAXXTYID.js';
5
+ import './chunk-HCIHOHLX.js';
6
+ import './chunk-2Y7TR6BS.js';
7
+ import { logger } from './chunk-IR5HLBMH.js';
8
+ import './chunk-D275MCIH.js';
9
9
  import { statSync, existsSync, readFileSync } from 'fs';
10
10
  import { join } from 'path';
11
11
  import { homedir } from 'os';
@@ -229,5 +229,5 @@ var GeminiLogin = class {
229
229
  };
230
230
 
231
231
  export { GeminiLogin };
232
- //# sourceMappingURL=gemini-login-AZGL3CE7.js.map
233
- //# sourceMappingURL=gemini-login-AZGL3CE7.js.map
232
+ //# sourceMappingURL=gemini-login-TST454MX.js.map
233
+ //# sourceMappingURL=gemini-login-TST454MX.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth/providers/gemini-login.ts"],"names":[],"mappings":"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","file":"gemini-login-AZGL3CE7.js","sourcesContent":["/**\n * Gemini (Google) delegated authentication\n * Reads cached credentials from ~/.gemini/oauth_creds.json (shared with the Gemini CLI).\n * If not authenticated, opens a new terminal window running `gemini` for interactive login,\n * then polls for credentials to appear.\n */\n\nimport { readFileSync, existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { execa } from \"execa\";\nimport type { ICredential } from \"../../types/index.js\";\nimport { AuthenticationError } from \"../../types/index.js\";\nimport { CredentialStore } from \"../credential-store.js\";\nimport { logger } from \"../../utils/index.js\";\n\n// ── Gemini CLI Token Paths ──────────────────────────────────────────────\n\nconst CLI_COMMAND = \"gemini\";\nconst LOGIN_POLL_INTERVAL_MS = 2_000;\nconst LOGIN_POLL_TIMEOUT_MS = 120_000;\n\nfunction getGeminiHome(): string {\n return process.env[\"GEMINI_HOME\"] ?? join(homedir(), \".gemini\");\n}\n\nfunction getOAuthCredsPath(): string {\n return join(getGeminiHome(), \"oauth_creds.json\");\n}\n\nfunction getGoogleAccountsPath(): string {\n return join(getGeminiHome(), \"google_accounts.json\");\n}\n\n// ── Read existing tokens from Gemini CLI cache ──────────────────────────\n\ninterface IGeminiOAuthCreds {\n readonly access_token?: string;\n readonly scope?: string;\n readonly token_type?: string;\n readonly id_token?: string;\n readonly expiry_date?: number;\n readonly refresh_token?: string;\n}\n\ninterface IGoogleAccounts {\n readonly active?: string;\n}\n\nfunction readOAuthCreds(): IGeminiOAuthCreds | undefined {\n const credsPath = getOAuthCredsPath();\n if (!existsSync(credsPath)) return undefined;\n try {\n return JSON.parse(readFileSync(credsPath, \"utf-8\")) as IGeminiOAuthCreds;\n } catch {\n return undefined;\n }\n}\n\nfunction readGoogleAccounts(): IGoogleAccounts | undefined {\n const accountsPath = getGoogleAccountsPath();\n if (!existsSync(accountsPath)) return undefined;\n try {\n return JSON.parse(readFileSync(accountsPath, \"utf-8\")) as IGoogleAccounts;\n } catch {\n return undefined;\n }\n}\n\nfunction getCredsMtime(): number {\n const credsPath = getOAuthCredsPath();\n try {\n return statSync(credsPath).mtimeMs;\n } catch {\n return 0;\n }\n}\n\nfunction extractEmailFromIdToken(idToken: string): string | undefined {\n try {\n const payload = idToken.split(\".\")[1];\n if (!payload) return undefined;\n const decoded = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf8\")) as { email?: string };\n return decoded.email;\n } catch {\n return undefined;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ── Open a new terminal window cross-platform ───────────────────────────\n\nasync function openTerminalWithGemini(): Promise<void> {\n const platform = process.platform;\n\n if (platform === \"win32\") {\n // Windows: open a new PowerShell window running gemini\n await execa(\"cmd\", [\"/c\", \"start\", \"powershell\", \"-NoExit\", \"-Command\", \"gemini\"], {\n stdin: \"ignore\",\n stdout: \"ignore\",\n stderr: \"ignore\",\n });\n } else if (platform === \"darwin\") {\n // macOS: open a new Terminal.app window running gemini\n await execa(\"osascript\", [\n \"-e\",\n 'tell application \"Terminal\" to do script \"gemini\"',\n \"-e\",\n 'tell application \"Terminal\" to activate',\n ], {\n stdin: \"ignore\",\n stdout: \"ignore\",\n stderr: \"ignore\",\n });\n } else {\n // Linux: try common terminal emulators\n const terminals = [\n { cmd: \"gnome-terminal\", args: [\"--\", \"gemini\"] },\n { cmd: \"konsole\", args: [\"-e\", \"gemini\"] },\n { cmd: \"xfce4-terminal\", args: [\"-e\", \"gemini\"] },\n { cmd: \"xterm\", args: [\"-e\", \"gemini\"] },\n ];\n\n for (const terminal of terminals) {\n try {\n await execa(terminal.cmd, terminal.args, {\n stdin: \"ignore\",\n stdout: \"ignore\",\n stderr: \"ignore\",\n detached: true,\n });\n return;\n } catch {\n // Try next terminal\n }\n }\n\n throw new Error(\"Could not find a terminal emulator. Please run `gemini` manually in a separate terminal.\");\n }\n}\n\n// ── GeminiLogin Class ───────────────────────────────────────────────────\n\nexport class GeminiLogin {\n private readonly credentialStore: CredentialStore;\n\n constructor(store?: CredentialStore) {\n this.credentialStore = store ?? new CredentialStore();\n }\n\n /**\n * Attempt to import credentials from the Gemini CLI cache.\n * If not found, opens a new terminal window running `gemini` for interactive\n * login, then polls for credentials to appear in ~/.gemini/oauth_creds.json.\n */\n async login(): Promise<ICredential> {\n // Try importing existing credentials from Gemini CLI's cache\n const existing = this.readCachedCredential();\n if (existing) {\n const isExpired = existing.expiresAt ? new Date() > existing.expiresAt : false;\n if (!isExpired) {\n logger.info(\"Found existing Gemini CLI credentials in ~/.gemini/oauth_creds.json\");\n await this.credentialStore.set(\"google\", existing);\n return existing;\n }\n }\n\n // Check if the CLI is installed\n const cliAvailable = await this.isCliAvailable();\n\n if (!cliAvailable) {\n throw new AuthenticationError(\n \"google\",\n \"Gemini CLI not found. Install it first:\\n\" +\n \" npm install -g @google/gemini-cli\\n\" +\n \"Then retry /login.\",\n );\n }\n\n // Record the current mtime so we can detect new credentials\n const beforeMtime = getCredsMtime();\n\n // Open a new terminal window running gemini for interactive login\n logger.info(\"Opening new terminal window for Gemini login\");\n try {\n await openTerminalWithGemini();\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new AuthenticationError(\"google\", msg);\n }\n\n // Poll for credentials to appear (user authenticates in the other window)\n const credential = await this.pollForCredentials(beforeMtime);\n if (!credential) {\n throw new AuthenticationError(\n \"google\",\n \"Login timed out. Please complete authentication in the Gemini terminal, then retry /login.\",\n );\n }\n\n await this.credentialStore.set(\"google\", credential);\n logger.info(\"Gemini credentials imported successfully\");\n return credential;\n }\n\n async logout(): Promise<void> {\n await this.credentialStore.delete(\"google\");\n logger.info(\"Google session revoked from AemeathCLI\");\n }\n\n async isLoggedIn(): Promise<boolean> {\n const credential = this.readCachedCredential();\n if (!credential) return false;\n if (credential.expiresAt && new Date() > credential.expiresAt && credential.refreshToken === undefined) {\n return false;\n }\n\n await this.credentialStore.set(\"google\", credential);\n return true;\n }\n\n async getStatus(): Promise<{ loggedIn: boolean; email?: string | undefined; plan?: string | undefined }> {\n const loggedIn = await this.isLoggedIn();\n if (!loggedIn) return { loggedIn: false };\n\n const credential = await this.credentialStore.get(\"google\");\n if (!credential) return { loggedIn: false };\n\n return {\n loggedIn: true,\n ...(credential.email !== undefined ? { email: credential.email } : {}),\n plan: \"Google AI\",\n };\n }\n\n async getCachedCredential(): Promise<ICredential | undefined> {\n const credential = this.readCachedCredential();\n if (credential) {\n await this.credentialStore.set(\"google\", credential);\n }\n return credential;\n }\n\n // ── Internal ──────────────────────────────────────────────────────────\n\n private readCachedCredential(): ICredential | undefined {\n const oauthCreds = readOAuthCreds();\n if (!oauthCreds?.access_token) return undefined;\n\n let email: string | undefined;\n const accounts = readGoogleAccounts();\n if (accounts?.active) {\n email = accounts.active;\n } else if (oauthCreds.id_token) {\n email = extractEmailFromIdToken(oauthCreds.id_token);\n }\n\n const expiresAt = oauthCreds.expiry_date ? new Date(oauthCreds.expiry_date) : undefined;\n\n return {\n provider: \"google\",\n method: \"native_login\",\n token: oauthCreds.access_token,\n ...(oauthCreds.refresh_token !== undefined ? { refreshToken: oauthCreds.refresh_token } : {}),\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n ...(email !== undefined ? { email } : {}),\n plan: \"Google AI\",\n };\n }\n\n /**\n * Poll for new credentials to appear in ~/.gemini/oauth_creds.json.\n * Detects new credentials by checking if the file mtime changed from beforeMtime.\n */\n private async pollForCredentials(beforeMtime: number): Promise<ICredential | undefined> {\n const deadline = Date.now() + LOGIN_POLL_TIMEOUT_MS;\n\n while (Date.now() < deadline) {\n await sleep(LOGIN_POLL_INTERVAL_MS);\n\n const currentMtime = getCredsMtime();\n if (currentMtime > beforeMtime) {\n const credential = this.readCachedCredential();\n if (credential) return credential;\n }\n }\n\n // One final check\n return this.readCachedCredential() ?? undefined;\n }\n\n private async isCliAvailable(): Promise<boolean> {\n try {\n await execa(CLI_COMMAND, [\"--version\"], { timeout: 5000, stdin: \"ignore\", stdout: \"ignore\", stderr: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/auth/providers/gemini-login.ts"],"names":[],"mappings":"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","file":"gemini-login-TST454MX.js","sourcesContent":["/**\n * Gemini (Google) delegated authentication\n * Reads cached credentials from ~/.gemini/oauth_creds.json (shared with the Gemini CLI).\n * If not authenticated, opens a new terminal window running `gemini` for interactive login,\n * then polls for credentials to appear.\n */\n\nimport { readFileSync, existsSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { execa } from \"execa\";\nimport type { ICredential } from \"../../types/index.js\";\nimport { AuthenticationError } from \"../../types/index.js\";\nimport { CredentialStore } from \"../credential-store.js\";\nimport { logger } from \"../../utils/index.js\";\n\n// ── Gemini CLI Token Paths ──────────────────────────────────────────────\n\nconst CLI_COMMAND = \"gemini\";\nconst LOGIN_POLL_INTERVAL_MS = 2_000;\nconst LOGIN_POLL_TIMEOUT_MS = 120_000;\n\nfunction getGeminiHome(): string {\n return process.env[\"GEMINI_HOME\"] ?? join(homedir(), \".gemini\");\n}\n\nfunction getOAuthCredsPath(): string {\n return join(getGeminiHome(), \"oauth_creds.json\");\n}\n\nfunction getGoogleAccountsPath(): string {\n return join(getGeminiHome(), \"google_accounts.json\");\n}\n\n// ── Read existing tokens from Gemini CLI cache ──────────────────────────\n\ninterface IGeminiOAuthCreds {\n readonly access_token?: string;\n readonly scope?: string;\n readonly token_type?: string;\n readonly id_token?: string;\n readonly expiry_date?: number;\n readonly refresh_token?: string;\n}\n\ninterface IGoogleAccounts {\n readonly active?: string;\n}\n\nfunction readOAuthCreds(): IGeminiOAuthCreds | undefined {\n const credsPath = getOAuthCredsPath();\n if (!existsSync(credsPath)) return undefined;\n try {\n return JSON.parse(readFileSync(credsPath, \"utf-8\")) as IGeminiOAuthCreds;\n } catch {\n return undefined;\n }\n}\n\nfunction readGoogleAccounts(): IGoogleAccounts | undefined {\n const accountsPath = getGoogleAccountsPath();\n if (!existsSync(accountsPath)) return undefined;\n try {\n return JSON.parse(readFileSync(accountsPath, \"utf-8\")) as IGoogleAccounts;\n } catch {\n return undefined;\n }\n}\n\nfunction getCredsMtime(): number {\n const credsPath = getOAuthCredsPath();\n try {\n return statSync(credsPath).mtimeMs;\n } catch {\n return 0;\n }\n}\n\nfunction extractEmailFromIdToken(idToken: string): string | undefined {\n try {\n const payload = idToken.split(\".\")[1];\n if (!payload) return undefined;\n const decoded = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf8\")) as { email?: string };\n return decoded.email;\n } catch {\n return undefined;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ── Open a new terminal window cross-platform ───────────────────────────\n\nasync function openTerminalWithGemini(): Promise<void> {\n const platform = process.platform;\n\n if (platform === \"win32\") {\n // Windows: open a new PowerShell window running gemini\n await execa(\"cmd\", [\"/c\", \"start\", \"powershell\", \"-NoExit\", \"-Command\", \"gemini\"], {\n stdin: \"ignore\",\n stdout: \"ignore\",\n stderr: \"ignore\",\n });\n } else if (platform === \"darwin\") {\n // macOS: open a new Terminal.app window running gemini\n await execa(\"osascript\", [\n \"-e\",\n 'tell application \"Terminal\" to do script \"gemini\"',\n \"-e\",\n 'tell application \"Terminal\" to activate',\n ], {\n stdin: \"ignore\",\n stdout: \"ignore\",\n stderr: \"ignore\",\n });\n } else {\n // Linux: try common terminal emulators\n const terminals = [\n { cmd: \"gnome-terminal\", args: [\"--\", \"gemini\"] },\n { cmd: \"konsole\", args: [\"-e\", \"gemini\"] },\n { cmd: \"xfce4-terminal\", args: [\"-e\", \"gemini\"] },\n { cmd: \"xterm\", args: [\"-e\", \"gemini\"] },\n ];\n\n for (const terminal of terminals) {\n try {\n await execa(terminal.cmd, terminal.args, {\n stdin: \"ignore\",\n stdout: \"ignore\",\n stderr: \"ignore\",\n detached: true,\n });\n return;\n } catch {\n // Try next terminal\n }\n }\n\n throw new Error(\"Could not find a terminal emulator. Please run `gemini` manually in a separate terminal.\");\n }\n}\n\n// ── GeminiLogin Class ───────────────────────────────────────────────────\n\nexport class GeminiLogin {\n private readonly credentialStore: CredentialStore;\n\n constructor(store?: CredentialStore) {\n this.credentialStore = store ?? new CredentialStore();\n }\n\n /**\n * Attempt to import credentials from the Gemini CLI cache.\n * If not found, opens a new terminal window running `gemini` for interactive\n * login, then polls for credentials to appear in ~/.gemini/oauth_creds.json.\n */\n async login(): Promise<ICredential> {\n // Try importing existing credentials from Gemini CLI's cache\n const existing = this.readCachedCredential();\n if (existing) {\n const isExpired = existing.expiresAt ? new Date() > existing.expiresAt : false;\n if (!isExpired) {\n logger.info(\"Found existing Gemini CLI credentials in ~/.gemini/oauth_creds.json\");\n await this.credentialStore.set(\"google\", existing);\n return existing;\n }\n }\n\n // Check if the CLI is installed\n const cliAvailable = await this.isCliAvailable();\n\n if (!cliAvailable) {\n throw new AuthenticationError(\n \"google\",\n \"Gemini CLI not found. Install it first:\\n\" +\n \" npm install -g @google/gemini-cli\\n\" +\n \"Then retry /login.\",\n );\n }\n\n // Record the current mtime so we can detect new credentials\n const beforeMtime = getCredsMtime();\n\n // Open a new terminal window running gemini for interactive login\n logger.info(\"Opening new terminal window for Gemini login\");\n try {\n await openTerminalWithGemini();\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new AuthenticationError(\"google\", msg);\n }\n\n // Poll for credentials to appear (user authenticates in the other window)\n const credential = await this.pollForCredentials(beforeMtime);\n if (!credential) {\n throw new AuthenticationError(\n \"google\",\n \"Login timed out. Please complete authentication in the Gemini terminal, then retry /login.\",\n );\n }\n\n await this.credentialStore.set(\"google\", credential);\n logger.info(\"Gemini credentials imported successfully\");\n return credential;\n }\n\n async logout(): Promise<void> {\n await this.credentialStore.delete(\"google\");\n logger.info(\"Google session revoked from AemeathCLI\");\n }\n\n async isLoggedIn(): Promise<boolean> {\n const credential = this.readCachedCredential();\n if (!credential) return false;\n if (credential.expiresAt && new Date() > credential.expiresAt && credential.refreshToken === undefined) {\n return false;\n }\n\n await this.credentialStore.set(\"google\", credential);\n return true;\n }\n\n async getStatus(): Promise<{ loggedIn: boolean; email?: string | undefined; plan?: string | undefined }> {\n const loggedIn = await this.isLoggedIn();\n if (!loggedIn) return { loggedIn: false };\n\n const credential = await this.credentialStore.get(\"google\");\n if (!credential) return { loggedIn: false };\n\n return {\n loggedIn: true,\n ...(credential.email !== undefined ? { email: credential.email } : {}),\n plan: \"Google AI\",\n };\n }\n\n async getCachedCredential(): Promise<ICredential | undefined> {\n const credential = this.readCachedCredential();\n if (credential) {\n await this.credentialStore.set(\"google\", credential);\n }\n return credential;\n }\n\n // ── Internal ──────────────────────────────────────────────────────────\n\n private readCachedCredential(): ICredential | undefined {\n const oauthCreds = readOAuthCreds();\n if (!oauthCreds?.access_token) return undefined;\n\n let email: string | undefined;\n const accounts = readGoogleAccounts();\n if (accounts?.active) {\n email = accounts.active;\n } else if (oauthCreds.id_token) {\n email = extractEmailFromIdToken(oauthCreds.id_token);\n }\n\n const expiresAt = oauthCreds.expiry_date ? new Date(oauthCreds.expiry_date) : undefined;\n\n return {\n provider: \"google\",\n method: \"native_login\",\n token: oauthCreds.access_token,\n ...(oauthCreds.refresh_token !== undefined ? { refreshToken: oauthCreds.refresh_token } : {}),\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n ...(email !== undefined ? { email } : {}),\n plan: \"Google AI\",\n };\n }\n\n /**\n * Poll for new credentials to appear in ~/.gemini/oauth_creds.json.\n * Detects new credentials by checking if the file mtime changed from beforeMtime.\n */\n private async pollForCredentials(beforeMtime: number): Promise<ICredential | undefined> {\n const deadline = Date.now() + LOGIN_POLL_TIMEOUT_MS;\n\n while (Date.now() < deadline) {\n await sleep(LOGIN_POLL_INTERVAL_MS);\n\n const currentMtime = getCredsMtime();\n if (currentMtime > beforeMtime) {\n const credential = this.readCachedCredential();\n if (credential) return credential;\n }\n }\n\n // One final check\n return this.readCachedCredential() ?? undefined;\n }\n\n private async isCliAvailable(): Promise<boolean> {\n try {\n await execa(CLI_COMMAND, [\"--version\"], { timeout: 5000, stdin: \"ignore\", stdout: \"ignore\", stderr: \"ignore\" });\n return true;\n } catch {\n return false;\n }\n }\n}\n"]}