reasonix 0.51.0 → 0.52.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 (143) hide show
  1. package/dashboard/dist/app.css +1 -1
  2. package/dashboard/dist/app.js +3 -3
  3. package/dashboard/dist/app.js.map +1 -1
  4. package/dist/cli/{acp-XEUHGG7X.js → acp-NEUYWGUU.js} +26 -26
  5. package/dist/cli/chat-QA6IVFJD.js +49 -0
  6. package/dist/cli/{chunk-HGK57NBN.js → chunk-2W4F3RIZ.js} +2 -2
  7. package/dist/cli/{chunk-UO6E7FN3.js → chunk-3OXD5CBM.js} +32756 -31192
  8. package/dist/cli/chunk-3OXD5CBM.js.map +1 -0
  9. package/dist/cli/{chunk-UMZ6KHTS.js → chunk-5YLEKX2V.js} +2 -2
  10. package/dist/cli/{chunk-BA5R6BAE.js → chunk-6QBUXA73.js} +2 -2
  11. package/dist/cli/chunk-77JIQ7SL.js +40 -0
  12. package/dist/cli/chunk-77JIQ7SL.js.map +1 -0
  13. package/dist/cli/{chunk-6XWXIVQ3.js → chunk-AMSK3ZLB.js} +2 -2
  14. package/dist/cli/chunk-AMSK3ZLB.js.map +1 -0
  15. package/dist/cli/{chunk-A5PBEIJ7.js → chunk-AOYUW3HR.js} +37 -4
  16. package/dist/cli/chunk-AOYUW3HR.js.map +1 -0
  17. package/dist/cli/{chunk-3YRTIWFX.js → chunk-ARBGTNHM.js} +2 -2
  18. package/dist/cli/{chunk-3BTK5BHI.js → chunk-B4MOGWHW.js} +2 -2
  19. package/dist/cli/{chunk-5AIDYVH2.js → chunk-CFJY64UA.js} +2 -2
  20. package/dist/cli/{chunk-SBHF5NWD.js → chunk-CGVW5W7N.js} +14 -14
  21. package/dist/cli/{chunk-SBHF5NWD.js.map → chunk-CGVW5W7N.js.map} +1 -1
  22. package/dist/cli/{chunk-DVD67FXQ.js → chunk-CLHMV6OL.js} +568 -66
  23. package/dist/cli/chunk-CLHMV6OL.js.map +1 -0
  24. package/dist/cli/{chunk-2WUEAI2I.js → chunk-CPCUMMSR.js} +3 -3
  25. package/dist/cli/{chunk-JHWQDJZA.js → chunk-CTRM32BP.js} +2 -2
  26. package/dist/cli/{chunk-544J4PXD.js → chunk-D6WRFR6V.js} +5 -5
  27. package/dist/cli/{chunk-N4SEBLU4.js → chunk-DLTE4GBY.js} +3 -3
  28. package/dist/cli/{chunk-NRROJXXT.js → chunk-FY5UERSG.js} +9 -9
  29. package/dist/cli/{chunk-C2MRSJTV.js → chunk-GFJJEW3Z.js} +18 -10
  30. package/dist/cli/chunk-GFJJEW3Z.js.map +1 -0
  31. package/dist/cli/{chunk-R6KIHEF3.js → chunk-GNRKXRRE.js} +743 -660
  32. package/dist/cli/chunk-GNRKXRRE.js.map +1 -0
  33. package/dist/cli/{chunk-SXSAWOB7.js → chunk-HI6THNAZ.js} +19 -17
  34. package/dist/cli/chunk-HI6THNAZ.js.map +1 -0
  35. package/dist/cli/{chunk-K4YQFULP.js → chunk-HNZ4727T.js} +15 -15
  36. package/dist/cli/chunk-I3NE5S63.js +54 -0
  37. package/dist/cli/{chunk-EAMXOWUW.js.map → chunk-I3NE5S63.js.map} +1 -1
  38. package/dist/cli/{chunk-FEZK652I.js → chunk-MVLPXZAA.js} +834 -10
  39. package/dist/cli/chunk-MVLPXZAA.js.map +1 -0
  40. package/dist/cli/{chunk-36BM7INR.js → chunk-MW64SQUE.js} +2 -2
  41. package/dist/cli/{chunk-Z3MKG7MQ.js → chunk-OMNRXZNA.js} +2 -2
  42. package/dist/cli/{chunk-7YPMTE3U.js → chunk-RCC73DWQ.js} +5 -9
  43. package/dist/cli/chunk-RCC73DWQ.js.map +1 -0
  44. package/dist/cli/{chunk-2HVTBFCI.js → chunk-RHQOGG43.js} +5 -3
  45. package/dist/cli/chunk-RHQOGG43.js.map +1 -0
  46. package/dist/cli/{chunk-EWVFGYT6.js → chunk-VVPV5HU6.js} +2 -2
  47. package/dist/cli/{chunk-7YB26OQO.js → chunk-WPY7AFS6.js} +2 -2
  48. package/dist/cli/{chunk-BM6BBFAV.js → chunk-XBYHNZ5Z.js} +2 -2
  49. package/dist/cli/{chunk-WPOKBW5E.js → chunk-XNMXVL6C.js} +2 -2
  50. package/dist/cli/{chunk-SVD4UPRQ.js → chunk-XUZHBQSM.js} +2 -2
  51. package/dist/cli/{chunk-Q46B3Z7H.js → chunk-YMYX6QTC.js} +8 -5
  52. package/dist/cli/{chunk-Q46B3Z7H.js.map → chunk-YMYX6QTC.js.map} +1 -1
  53. package/dist/cli/{chunk-K3QJ3GKI.js → chunk-Z663GVUB.js} +3 -3
  54. package/dist/cli/{code-BMXLBC7D.js → code-WN6D4VZO.js} +35 -36
  55. package/dist/cli/{code-BMXLBC7D.js.map → code-WN6D4VZO.js.map} +1 -1
  56. package/dist/cli/{commands-E4RZXMF6.js → commands-DHETOY7O.js} +4 -4
  57. package/dist/cli/{commit-KSRQ64IL.js → commit-BBUYAKZV.js} +3 -3
  58. package/dist/cli/{config-QNDONOTU.js → config-KV7VV5LG.js} +4 -2
  59. package/dist/cli/{desktop-H3ZHIMDA.js → desktop-LJVXWXNF.js} +557 -70
  60. package/dist/cli/desktop-LJVXWXNF.js.map +1 -0
  61. package/dist/cli/diff-2JHMQAHI.js +165 -0
  62. package/dist/cli/{diff-I4PYI43W.js.map → diff-2JHMQAHI.js.map} +1 -1
  63. package/dist/cli/{doctor-Y2E4MY2F.js → doctor-GI5LOEZL.js} +11 -11
  64. package/dist/cli/{events-47HOT7ZA.js → events-LBKMLFM4.js} +5 -5
  65. package/dist/cli/index.js +40 -39
  66. package/dist/cli/index.js.map +1 -1
  67. package/dist/cli/{mcp-76DK63ZB.js → mcp-DKEJK5ND.js} +3 -3
  68. package/dist/cli/{mcp-browse-SDNUGO74.js → mcp-browse-V7KWDY32.js} +15 -15
  69. package/dist/cli/{mcp-browse-SDNUGO74.js.map → mcp-browse-V7KWDY32.js.map} +1 -1
  70. package/dist/cli/{mcp-inspect-BL5DEO5M.js → mcp-inspect-MTABNHVM.js} +5 -5
  71. package/dist/cli/{prompt-JLATI3P7.js → prompt-ATI7DKHF.js} +5 -5
  72. package/dist/cli/{prune-sessions-WHZDFUKD.js → prune-sessions-YQQSZTZS.js} +4 -4
  73. package/dist/cli/{replay-MHXS7C7Z.js → replay-ZJQ4I4CJ.js} +30 -30
  74. package/dist/cli/{replay-MHXS7C7Z.js.map → replay-ZJQ4I4CJ.js.map} +1 -1
  75. package/dist/cli/{run-SXNCPRJE.js → run-HFPRNWJY.js} +22 -22
  76. package/dist/cli/{server-GEHOE6CO.js → server-UHKO2VVM.js} +23 -23
  77. package/dist/cli/{sessions-EPBFYISL.js → sessions-IQEWWUH3.js} +16 -16
  78. package/dist/cli/setup-5BYKCL62.js +502 -0
  79. package/dist/cli/setup-5BYKCL62.js.map +1 -0
  80. package/dist/cli/{stats-4WB4XHBP.js → stats-OFCGOQMZ.js} +6 -6
  81. package/dist/cli/{version-4SP3DLLH.js → version-EODUFAAI.js} +16 -16
  82. package/dist/index.d.ts +12 -1
  83. package/dist/index.js +613 -78
  84. package/dist/index.js.map +1 -1
  85. package/package.json +21 -3
  86. package/dist/cli/chat-NJ2Q5KHG.js +0 -50
  87. package/dist/cli/chunk-2HVTBFCI.js.map +0 -1
  88. package/dist/cli/chunk-5BBC6YMV.js +0 -832
  89. package/dist/cli/chunk-5BBC6YMV.js.map +0 -1
  90. package/dist/cli/chunk-6XWXIVQ3.js.map +0 -1
  91. package/dist/cli/chunk-7YPMTE3U.js.map +0 -1
  92. package/dist/cli/chunk-A5PBEIJ7.js.map +0 -1
  93. package/dist/cli/chunk-C2MRSJTV.js.map +0 -1
  94. package/dist/cli/chunk-DVD67FXQ.js.map +0 -1
  95. package/dist/cli/chunk-EAMXOWUW.js +0 -54
  96. package/dist/cli/chunk-FEZK652I.js.map +0 -1
  97. package/dist/cli/chunk-R6KIHEF3.js.map +0 -1
  98. package/dist/cli/chunk-SXSAWOB7.js.map +0 -1
  99. package/dist/cli/chunk-UO6E7FN3.js.map +0 -1
  100. package/dist/cli/chunk-UPW544V3.js +0 -96
  101. package/dist/cli/chunk-UPW544V3.js.map +0 -1
  102. package/dist/cli/desktop-H3ZHIMDA.js.map +0 -1
  103. package/dist/cli/devtools-HW3WDT3Q.js +0 -91
  104. package/dist/cli/devtools-HW3WDT3Q.js.map +0 -1
  105. package/dist/cli/diff-I4PYI43W.js +0 -165
  106. package/dist/cli/setup-IW2XR5XI.js +0 -593
  107. package/dist/cli/setup-IW2XR5XI.js.map +0 -1
  108. /package/dist/cli/{acp-XEUHGG7X.js.map → acp-NEUYWGUU.js.map} +0 -0
  109. /package/dist/cli/{chat-NJ2Q5KHG.js.map → chat-QA6IVFJD.js.map} +0 -0
  110. /package/dist/cli/{chunk-HGK57NBN.js.map → chunk-2W4F3RIZ.js.map} +0 -0
  111. /package/dist/cli/{chunk-UMZ6KHTS.js.map → chunk-5YLEKX2V.js.map} +0 -0
  112. /package/dist/cli/{chunk-BA5R6BAE.js.map → chunk-6QBUXA73.js.map} +0 -0
  113. /package/dist/cli/{chunk-3YRTIWFX.js.map → chunk-ARBGTNHM.js.map} +0 -0
  114. /package/dist/cli/{chunk-3BTK5BHI.js.map → chunk-B4MOGWHW.js.map} +0 -0
  115. /package/dist/cli/{chunk-5AIDYVH2.js.map → chunk-CFJY64UA.js.map} +0 -0
  116. /package/dist/cli/{chunk-2WUEAI2I.js.map → chunk-CPCUMMSR.js.map} +0 -0
  117. /package/dist/cli/{chunk-JHWQDJZA.js.map → chunk-CTRM32BP.js.map} +0 -0
  118. /package/dist/cli/{chunk-544J4PXD.js.map → chunk-D6WRFR6V.js.map} +0 -0
  119. /package/dist/cli/{chunk-N4SEBLU4.js.map → chunk-DLTE4GBY.js.map} +0 -0
  120. /package/dist/cli/{chunk-NRROJXXT.js.map → chunk-FY5UERSG.js.map} +0 -0
  121. /package/dist/cli/{chunk-K4YQFULP.js.map → chunk-HNZ4727T.js.map} +0 -0
  122. /package/dist/cli/{chunk-36BM7INR.js.map → chunk-MW64SQUE.js.map} +0 -0
  123. /package/dist/cli/{chunk-Z3MKG7MQ.js.map → chunk-OMNRXZNA.js.map} +0 -0
  124. /package/dist/cli/{chunk-EWVFGYT6.js.map → chunk-VVPV5HU6.js.map} +0 -0
  125. /package/dist/cli/{chunk-7YB26OQO.js.map → chunk-WPY7AFS6.js.map} +0 -0
  126. /package/dist/cli/{chunk-BM6BBFAV.js.map → chunk-XBYHNZ5Z.js.map} +0 -0
  127. /package/dist/cli/{chunk-WPOKBW5E.js.map → chunk-XNMXVL6C.js.map} +0 -0
  128. /package/dist/cli/{chunk-SVD4UPRQ.js.map → chunk-XUZHBQSM.js.map} +0 -0
  129. /package/dist/cli/{chunk-K3QJ3GKI.js.map → chunk-Z663GVUB.js.map} +0 -0
  130. /package/dist/cli/{commands-E4RZXMF6.js.map → commands-DHETOY7O.js.map} +0 -0
  131. /package/dist/cli/{commit-KSRQ64IL.js.map → commit-BBUYAKZV.js.map} +0 -0
  132. /package/dist/cli/{config-QNDONOTU.js.map → config-KV7VV5LG.js.map} +0 -0
  133. /package/dist/cli/{doctor-Y2E4MY2F.js.map → doctor-GI5LOEZL.js.map} +0 -0
  134. /package/dist/cli/{events-47HOT7ZA.js.map → events-LBKMLFM4.js.map} +0 -0
  135. /package/dist/cli/{mcp-76DK63ZB.js.map → mcp-DKEJK5ND.js.map} +0 -0
  136. /package/dist/cli/{mcp-inspect-BL5DEO5M.js.map → mcp-inspect-MTABNHVM.js.map} +0 -0
  137. /package/dist/cli/{prompt-JLATI3P7.js.map → prompt-ATI7DKHF.js.map} +0 -0
  138. /package/dist/cli/{prune-sessions-WHZDFUKD.js.map → prune-sessions-YQQSZTZS.js.map} +0 -0
  139. /package/dist/cli/{run-SXNCPRJE.js.map → run-HFPRNWJY.js.map} +0 -0
  140. /package/dist/cli/{server-GEHOE6CO.js.map → server-UHKO2VVM.js.map} +0 -0
  141. /package/dist/cli/{sessions-EPBFYISL.js.map → sessions-IQEWWUH3.js.map} +0 -0
  142. /package/dist/cli/{stats-4WB4XHBP.js.map → stats-OFCGOQMZ.js.map} +0 -0
  143. /package/dist/cli/{version-4SP3DLLH.js.map → version-EODUFAAI.js.map} +0 -0
@@ -1,593 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
- import {
4
- MultiSelect,
5
- SingleSelect
6
- } from "./chunk-SBHF5NWD.js";
7
- import {
8
- ThemeProvider,
9
- useTheme
10
- } from "./chunk-2HVTBFCI.js";
11
- import {
12
- Box_default,
13
- Text,
14
- render_default,
15
- require_react,
16
- source_default,
17
- use_app_default,
18
- use_input_default
19
- } from "./chunk-UO6E7FN3.js";
20
- import {
21
- MCP_CATALOG
22
- } from "./chunk-PLHAZOLZ.js";
23
- import {
24
- loadDotenv
25
- } from "./chunk-2UQP6H6T.js";
26
- import {
27
- detectSystemLanguage,
28
- getLanguage,
29
- getSupportedLanguages,
30
- notifyLanguageChange,
31
- onLanguageChange,
32
- setLanguage,
33
- t
34
- } from "./chunk-DVD67FXQ.js";
35
- import {
36
- defaultConfigPath,
37
- isPlausibleKey,
38
- listThemeNames,
39
- loadApiKey,
40
- loadBaseUrl,
41
- loadTheme,
42
- readConfig,
43
- redactKey,
44
- resolveThemePreference,
45
- writeConfig
46
- } from "./chunk-A5PBEIJ7.js";
47
- import {
48
- __toESM
49
- } from "./chunk-TUK7OWJA.js";
50
-
51
- // src/cli/commands/setup.tsx
52
- var import_react3 = __toESM(require_react(), 1);
53
-
54
- // src/cli/ui/Wizard.tsx
55
- import { mkdirSync, statSync } from "fs";
56
-
57
- // node_modules/ink-text-input/build/index.js
58
- var import_react = __toESM(require_react(), 1);
59
- function TextInput({ value: originalValue, placeholder = "", focus = true, mask, highlightPastedText = false, showCursor = true, onChange, onSubmit }) {
60
- const [state, setState] = (0, import_react.useState)({
61
- cursorOffset: (originalValue || "").length,
62
- cursorWidth: 0
63
- });
64
- const { cursorOffset, cursorWidth } = state;
65
- (0, import_react.useEffect)(() => {
66
- setState((previousState) => {
67
- if (!focus || !showCursor) {
68
- return previousState;
69
- }
70
- const newValue = originalValue || "";
71
- if (previousState.cursorOffset > newValue.length - 1) {
72
- return {
73
- cursorOffset: newValue.length,
74
- cursorWidth: 0
75
- };
76
- }
77
- return previousState;
78
- });
79
- }, [originalValue, focus, showCursor]);
80
- const cursorActualWidth = highlightPastedText ? cursorWidth : 0;
81
- const value = mask ? mask.repeat(originalValue.length) : originalValue;
82
- let renderedValue = value;
83
- let renderedPlaceholder = placeholder ? source_default.grey(placeholder) : void 0;
84
- if (showCursor && focus) {
85
- renderedPlaceholder = placeholder.length > 0 ? source_default.inverse(placeholder[0]) + source_default.grey(placeholder.slice(1)) : source_default.inverse(" ");
86
- renderedValue = value.length > 0 ? "" : source_default.inverse(" ");
87
- let i = 0;
88
- for (const char of value) {
89
- renderedValue += i >= cursorOffset - cursorActualWidth && i <= cursorOffset ? source_default.inverse(char) : char;
90
- i++;
91
- }
92
- if (value.length > 0 && cursorOffset === value.length) {
93
- renderedValue += source_default.inverse(" ");
94
- }
95
- }
96
- use_input_default((input, key) => {
97
- if (key.upArrow || key.downArrow || key.ctrl && input === "c" || key.tab || key.shift && key.tab) {
98
- return;
99
- }
100
- if (key.return) {
101
- if (onSubmit) {
102
- onSubmit(originalValue);
103
- }
104
- return;
105
- }
106
- let nextCursorOffset = cursorOffset;
107
- let nextValue = originalValue;
108
- let nextCursorWidth = 0;
109
- if (key.leftArrow) {
110
- if (showCursor) {
111
- nextCursorOffset--;
112
- }
113
- } else if (key.rightArrow) {
114
- if (showCursor) {
115
- nextCursorOffset++;
116
- }
117
- } else if (key.backspace || key.delete) {
118
- if (cursorOffset > 0) {
119
- nextValue = originalValue.slice(0, cursorOffset - 1) + originalValue.slice(cursorOffset, originalValue.length);
120
- nextCursorOffset--;
121
- }
122
- } else {
123
- nextValue = originalValue.slice(0, cursorOffset) + input + originalValue.slice(cursorOffset, originalValue.length);
124
- nextCursorOffset += input.length;
125
- if (input.length > 1) {
126
- nextCursorWidth = input.length;
127
- }
128
- }
129
- if (cursorOffset < 0) {
130
- nextCursorOffset = 0;
131
- }
132
- if (cursorOffset > originalValue.length) {
133
- nextCursorOffset = originalValue.length;
134
- }
135
- setState({
136
- cursorOffset: nextCursorOffset,
137
- cursorWidth: nextCursorWidth
138
- });
139
- if (nextValue !== originalValue) {
140
- onChange(nextValue);
141
- }
142
- }, { isActive: focus });
143
- return import_react.default.createElement(Text, null, placeholder ? value.length > 0 ? renderedValue : renderedPlaceholder : renderedValue);
144
- }
145
- var build_default = TextInput;
146
-
147
- // src/cli/ui/Wizard.tsx
148
- var import_react2 = __toESM(require_react(), 1);
149
- var CATALOG_BY_NAME = new Map(MCP_CATALOG.map((e) => [e.name, e]));
150
- var LANGUAGE_LABELS = {
151
- EN: "English",
152
- "zh-CN": "\u7B80\u4F53\u4E2D\u6587",
153
- de: "Deutsch"
154
- };
155
- function Wizard({
156
- onComplete,
157
- onCancel,
158
- existingApiKey,
159
- forceApiKeyStep = false,
160
- validateApiKey = validateDeepSeekApiKey,
161
- initial
162
- }) {
163
- const { exit } = use_app_default();
164
- const [, setLanguageVersion] = (0, import_react2.useState)(0);
165
- (0, import_react2.useEffect)(() => onLanguageChange(() => setLanguageVersion((v) => v + 1)), []);
166
- const [previewTheme, setPreviewTheme] = (0, import_react2.useState)(
167
- () => resolveThemePreference(initial?.theme ?? loadTheme(), process.env.REASONIX_THEME)
168
- );
169
- const [step, setStep] = (0, import_react2.useState)("language");
170
- const [data, setData] = (0, import_react2.useState)(() => ({
171
- language: getLanguage(),
172
- theme: resolveThemePreference(initial?.theme ?? loadTheme(), process.env.REASONIX_THEME),
173
- apiKey: existingApiKey ?? "",
174
- selectedCatalog: deriveInitialCatalog(initial?.mcp ?? []),
175
- catalogArgs: {}
176
- }));
177
- const [error, setError] = (0, import_react2.useState)(null);
178
- use_input_default((_input, key) => {
179
- if (key.escape && step !== "saved" && onCancel) onCancel();
180
- });
181
- const content = (() => {
182
- if (step === "language") {
183
- return /* @__PURE__ */ import_react2.default.createElement(
184
- LanguageStep,
185
- {
186
- initialValue: data.language,
187
- onSubmit: (lang) => {
188
- setLanguage(lang);
189
- notifyLanguageChange();
190
- setData((d) => ({ ...d, language: lang }));
191
- setStep("theme");
192
- }
193
- }
194
- );
195
- }
196
- if (step === "theme") {
197
- return /* @__PURE__ */ import_react2.default.createElement(
198
- ThemeStep,
199
- {
200
- initialValue: data.theme,
201
- onPreview: setPreviewTheme,
202
- onSubmit: (theme) => {
203
- setData((d) => ({ ...d, theme }));
204
- setStep(existingApiKey && !forceApiKeyStep ? "mcp" : "apiKey");
205
- }
206
- }
207
- );
208
- }
209
- if (step === "apiKey") {
210
- return /* @__PURE__ */ import_react2.default.createElement(
211
- ApiKeyStep,
212
- {
213
- initialValue: data.apiKey,
214
- validateApiKey,
215
- onSubmit: (key) => {
216
- setData((d) => ({ ...d, apiKey: key }));
217
- setError(null);
218
- setStep("mcp");
219
- },
220
- error,
221
- onError: setError
222
- }
223
- );
224
- }
225
- if (step === "mcp") {
226
- return /* @__PURE__ */ import_react2.default.createElement(StepFrame, { title: t("wizard.mcpTitle"), step: 1, total: 2 }, /* @__PURE__ */ import_react2.default.createElement(
227
- MultiSelect,
228
- {
229
- items: mcpItems(),
230
- initialSelected: data.selectedCatalog,
231
- onSubmit: (selected) => {
232
- setData((d) => ({ ...d, selectedCatalog: selected }));
233
- const needsArgs = selected.some((name) => CATALOG_BY_NAME.get(name)?.userArgs);
234
- setStep(needsArgs ? "mcpArgs" : "review");
235
- },
236
- footer: t("wizard.mcpFooterMulti")
237
- }
238
- ));
239
- }
240
- if (step === "mcpArgs") {
241
- const pending = data.selectedCatalog.filter((name) => {
242
- const entry2 = CATALOG_BY_NAME.get(name);
243
- return entry2?.userArgs && !data.catalogArgs[name];
244
- });
245
- if (pending.length === 0) {
246
- setStep("review");
247
- return null;
248
- }
249
- const currentName = pending[0];
250
- const entry = CATALOG_BY_NAME.get(currentName);
251
- return /* @__PURE__ */ import_react2.default.createElement(
252
- McpArgsStep,
253
- {
254
- entry,
255
- error,
256
- onSubmit: (value) => {
257
- setData((d) => ({
258
- ...d,
259
- catalogArgs: { ...d.catalogArgs, [currentName]: value }
260
- }));
261
- setError(null);
262
- },
263
- onError: setError
264
- }
265
- );
266
- }
267
- if (step === "review") {
268
- const specs = data.selectedCatalog.map((name) => buildSpec(name, data.catalogArgs));
269
- return /* @__PURE__ */ import_react2.default.createElement(StepFrame, { title: t("wizard.reviewTitle"), step: 2, total: 2 }, /* @__PURE__ */ import_react2.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react2.default.createElement(
270
- SummaryLine,
271
- {
272
- label: t("wizard.reviewLabelLanguage"),
273
- value: LANGUAGE_LABELS[data.language]
274
- }
275
- ), /* @__PURE__ */ import_react2.default.createElement(SummaryLine, { label: t("wizard.reviewLabelApiKey"), value: redactKey(data.apiKey) }), /* @__PURE__ */ import_react2.default.createElement(SummaryLine, { label: t("wizard.reviewLabelTheme"), value: data.theme }), /* @__PURE__ */ import_react2.default.createElement(
276
- SummaryLine,
277
- {
278
- label: t("wizard.reviewLabelMcp"),
279
- value: specs.length === 0 ? t("wizard.reviewMcpNone") : t("wizard.reviewMcpServers", { count: specs.length })
280
- }
281
- ), specs.map((spec, i) => (
282
- // biome-ignore lint/suspicious/noArrayIndexKey: review-only render, order fixed
283
- /* @__PURE__ */ import_react2.default.createElement(Box_default, { key: i, paddingLeft: 14 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, "\xB7 ", spec))
284
- )), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, null, t("wizard.reviewSavesTo", { path: defaultConfigPath() }))), error ? /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { color: "red" }, error)) : null, /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.reviewFooter")))), /* @__PURE__ */ import_react2.default.createElement(
285
- ReviewConfirm,
286
- {
287
- onConfirm: () => {
288
- try {
289
- const specsNow = data.selectedCatalog.map(
290
- (name) => buildSpec(name, data.catalogArgs)
291
- );
292
- const prev = readConfig();
293
- const next = {
294
- ...prev,
295
- apiKey: data.apiKey,
296
- theme: data.theme,
297
- mcp: specsNow,
298
- setupCompleted: true
299
- };
300
- writeConfig(next);
301
- setStep("saved");
302
- onComplete(next);
303
- } catch (e) {
304
- setError(t("wizard.reviewSaveError", { message: e.message }));
305
- }
306
- }
307
- }
308
- ));
309
- }
310
- return /* @__PURE__ */ import_react2.default.createElement(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "green", paddingX: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true, color: "green" }, t("wizard.savedTitle")), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, null, t("ui.welcome"))), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.savedShellHint"))), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.savedFooter"))), /* @__PURE__ */ import_react2.default.createElement(ExitOnEnter, { onExit: exit }));
311
- })();
312
- return /* @__PURE__ */ import_react2.default.createElement(ThemeProvider, { name: previewTheme }, content);
313
- }
314
- var THEME_NAMES = listThemeNames();
315
- function ThemeStep({
316
- initialValue,
317
- onPreview,
318
- onSubmit
319
- }) {
320
- const initialIndex = Math.max(0, THEME_NAMES.indexOf(initialValue));
321
- const [index, setIndex] = (0, import_react2.useState)(initialIndex);
322
- const theme = useTheme();
323
- use_input_default((_input, key) => {
324
- if (key.upArrow) {
325
- const next = (index - 1 + THEME_NAMES.length) % THEME_NAMES.length;
326
- setIndex(next);
327
- onPreview(THEME_NAMES[next]);
328
- } else if (key.downArrow) {
329
- const next = (index + 1) % THEME_NAMES.length;
330
- setIndex(next);
331
- onPreview(THEME_NAMES[next]);
332
- } else if (key.return) {
333
- onSubmit(THEME_NAMES[index]);
334
- }
335
- });
336
- return /* @__PURE__ */ import_react2.default.createElement(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: theme.tone.brand, paddingX: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true, color: theme.tone.brand }, t("wizard.themeTitle")), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.themeSubtitle"))), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1, flexDirection: "column" }, THEME_NAMES.map((name, i) => /* @__PURE__ */ import_react2.default.createElement(Box_default, { key: name }, /* @__PURE__ */ import_react2.default.createElement(Text, { color: i === index ? theme.tone.brand : void 0 }, i === index ? "\u25B8 " : " "), /* @__PURE__ */ import_react2.default.createElement(Text, { bold: i === index, color: i === index ? theme.fg.strong : theme.fg.body }, name), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.fg.meta }, " \u2014 "), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.fg.meta }, t(`wizard.themeCaption.${name}`))))), /* @__PURE__ */ import_react2.default.createElement(
337
- Box_default,
338
- {
339
- marginTop: 1,
340
- flexDirection: "column",
341
- borderStyle: "round",
342
- borderColor: theme.fg.faint,
343
- paddingX: 1
344
- },
345
- /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.fg.meta }, t("wizard.themeSampleHeading")),
346
- /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.tone.accent }, "\u25C6 "), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.tone.accent }, t("wizard.themeSampleReasoning"))),
347
- /* @__PURE__ */ import_react2.default.createElement(Box_default, null, /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.tone.info }, "\u25A3 "), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.fg.body }, "fs.readFile("), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.tone.ok }, '"main.ts"'), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.fg.body }, ")")),
348
- /* @__PURE__ */ import_react2.default.createElement(Box_default, null, /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.fg.meta }, "~/project/main.ts:42")),
349
- /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.tone.ok }, "ok"), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.fg.faint }, " \xB7 "), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.tone.warn }, "warn"), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.fg.faint }, " \xB7 "), /* @__PURE__ */ import_react2.default.createElement(Text, { color: theme.tone.err }, "err"))
350
- ), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.themeFooter"))));
351
- }
352
- function LanguageStep({
353
- initialValue,
354
- onSubmit
355
- }) {
356
- const items = getSupportedLanguages().map((code) => ({
357
- value: code,
358
- label: LANGUAGE_LABELS[code],
359
- hint: code === detectSystemLanguage() ? "(detected)" : void 0
360
- }));
361
- return /* @__PURE__ */ import_react2.default.createElement(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true, color: "cyan" }, t("wizard.languageTitle")), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.languageSubtitle"))), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(
362
- SingleSelect,
363
- {
364
- items,
365
- initialValue,
366
- onSubmit,
367
- footer: t("wizard.selectFooter")
368
- }
369
- )));
370
- }
371
- function ApiKeyStep({
372
- initialValue,
373
- validateApiKey,
374
- onSubmit,
375
- error,
376
- onError
377
- }) {
378
- const [value, setValue] = (0, import_react2.useState)("");
379
- const [checking, setChecking] = (0, import_react2.useState)(false);
380
- return /* @__PURE__ */ import_react2.default.createElement(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true, color: "cyan" }, t("wizard.welcomeTitle")), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, null, t("wizard.apiKeyPrompt"))), /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.apiKeyGetOne")), /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.apiKeySavedLocally", { path: defaultConfigPath() })), initialValue ? /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.apiKeyPreview", { redacted: redactKey(initialValue) })) : null, /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true, color: "cyan" }, t("wizard.apiKeyInputLabel")), /* @__PURE__ */ import_react2.default.createElement(
381
- build_default,
382
- {
383
- value,
384
- onChange: setValue,
385
- onSubmit: (raw) => {
386
- const trimmed = raw.trim() || initialValue?.trim() || "";
387
- if (!isPlausibleKey(trimmed)) {
388
- onError(t("wizard.apiKeyInvalid"));
389
- setValue("");
390
- return;
391
- }
392
- setChecking(true);
393
- onError(null);
394
- void validateApiKey(trimmed).then((result) => {
395
- setChecking(false);
396
- if (!result.ok) {
397
- onError(
398
- result.reason === "rejected" ? t("wizard.apiKeyRejected") : t("wizard.apiKeyCheckFailed", { message: result.message ?? "unknown" })
399
- );
400
- setValue("");
401
- return;
402
- }
403
- onSubmit(trimmed);
404
- });
405
- },
406
- mask: "\u2022",
407
- placeholder: "sk-..."
408
- }
409
- )), checking ? /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { color: "yellow" }, t("wizard.apiKeyChecking"))) : error ? /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { color: "red" }, error)) : value ? /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.apiKeyPreview", { redacted: redactKey(value) }))) : null);
410
- }
411
- async function validateDeepSeekApiKey(apiKey, opts = {}) {
412
- const fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);
413
- let baseUrl = opts.baseUrl ?? loadBaseUrl() ?? "https://api.deepseek.com";
414
- while (baseUrl.endsWith("/")) baseUrl = baseUrl.slice(0, -1);
415
- const ctrl = new AbortController();
416
- const timer = setTimeout(() => ctrl.abort(), opts.timeoutMs ?? 1e4);
417
- try {
418
- const resp = await fetchImpl(`${baseUrl}/models`, {
419
- method: "GET",
420
- headers: { Authorization: `Bearer ${apiKey}` },
421
- signal: ctrl.signal
422
- });
423
- if (resp.ok) return { ok: true };
424
- if (resp.status === 401 || resp.status === 403) return { ok: false, reason: "rejected" };
425
- return { ok: false, reason: "failed", message: `HTTP ${resp.status}` };
426
- } catch (e) {
427
- return { ok: false, reason: "failed", message: e.message };
428
- } finally {
429
- clearTimeout(timer);
430
- }
431
- }
432
- function McpArgsStep({
433
- entry,
434
- error,
435
- onSubmit,
436
- onError
437
- }) {
438
- const [value, setValue] = (0, import_react2.useState)("");
439
- const [pendingCreate, setPendingCreate] = (0, import_react2.useState)(null);
440
- use_input_default((input, key) => {
441
- if (!pendingCreate) return;
442
- const ch = input.toLowerCase();
443
- if (ch === "y" || key.return) {
444
- try {
445
- mkdirSync(pendingCreate, { recursive: true });
446
- const created = pendingCreate;
447
- setPendingCreate(null);
448
- setValue("");
449
- onError(null);
450
- onSubmit(created);
451
- } catch (e) {
452
- onError(
453
- t("wizard.mcpArgsDirCreateFailed", {
454
- path: pendingCreate,
455
- message: e.message
456
- })
457
- );
458
- setPendingCreate(null);
459
- }
460
- } else if (ch === "n" || key.escape) {
461
- setPendingCreate(null);
462
- onError(null);
463
- }
464
- });
465
- if (pendingCreate) {
466
- return /* @__PURE__ */ import_react2.default.createElement(StepFrame, { title: t("wizard.mcpArgsTitle", { name: entry.name }), step: 2, total: 3 }, /* @__PURE__ */ import_react2.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react2.default.createElement(Text, null, t("wizard.mcpArgsDirMissing", { path: pendingCreate })), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.mcpArgsDirCreateHint"))), error ? /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { color: "red" }, error)) : null));
467
- }
468
- return /* @__PURE__ */ import_react2.default.createElement(StepFrame, { title: t("wizard.mcpArgsTitle", { name: entry.name }), step: 2, total: 3 }, /* @__PURE__ */ import_react2.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react2.default.createElement(Text, null, entry.summary), entry.note ? /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, entry.note)) : null, /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, null, t("wizard.mcpArgsRequiredParam")), /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true }, entry.userArgs)), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true, color: "cyan" }, entry.userArgs, " \u203A "), /* @__PURE__ */ import_react2.default.createElement(
469
- build_default,
470
- {
471
- value,
472
- onChange: setValue,
473
- onSubmit: (raw) => {
474
- const trimmed = raw.trim();
475
- if (!trimmed) {
476
- onError(t("wizard.mcpArgsEmpty", { name: entry.name }));
477
- return;
478
- }
479
- if (entry.name === "filesystem") {
480
- const check = checkFilesystemPath(trimmed);
481
- if (check.kind === "missing") {
482
- setPendingCreate(trimmed);
483
- return;
484
- }
485
- if (check.kind === "not-a-dir") {
486
- onError(t("wizard.mcpArgsNotADir", { path: trimmed }));
487
- return;
488
- }
489
- }
490
- onSubmit(trimmed);
491
- setValue("");
492
- },
493
- placeholder: placeholderFor(entry)
494
- }
495
- )), error ? /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react2.default.createElement(Text, { color: "red" }, error)) : null));
496
- }
497
- function checkFilesystemPath(p) {
498
- try {
499
- return { kind: statSync(p).isDirectory() ? "ok" : "not-a-dir" };
500
- } catch {
501
- return { kind: "missing" };
502
- }
503
- }
504
- function ReviewConfirm({ onConfirm }) {
505
- use_input_default((_i, key) => {
506
- if (key.return) onConfirm();
507
- });
508
- return null;
509
- }
510
- function ExitOnEnter({ onExit }) {
511
- use_input_default((_i, key) => {
512
- if (key.return) onExit();
513
- });
514
- return null;
515
- }
516
- function StepFrame({
517
- title,
518
- step,
519
- total,
520
- children
521
- }) {
522
- return /* @__PURE__ */ import_react2.default.createElement(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ import_react2.default.createElement(Box_default, null, /* @__PURE__ */ import_react2.default.createElement(Text, { dimColor: true }, t("wizard.stepCounter", { step, total })), /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true, color: "cyan" }, title)), /* @__PURE__ */ import_react2.default.createElement(Box_default, { marginTop: 1, flexDirection: "column" }, children));
523
- }
524
- function SummaryLine({ label, value }) {
525
- return /* @__PURE__ */ import_react2.default.createElement(Box_default, null, /* @__PURE__ */ import_react2.default.createElement(Text, null, label.padEnd(12)), /* @__PURE__ */ import_react2.default.createElement(Text, { bold: true }, value));
526
- }
527
- function mcpItems() {
528
- return MCP_CATALOG.map((entry) => {
529
- const hintParts = [entry.summary];
530
- if (entry.userArgs) hintParts.push(t("wizard.mcpUserArgsHint", { arg: entry.userArgs }));
531
- if (entry.note) hintParts.push(entry.note);
532
- return {
533
- value: entry.name,
534
- label: entry.name,
535
- hint: hintParts.join(" \xB7 ")
536
- };
537
- });
538
- }
539
- function placeholderFor(entry) {
540
- if (entry.name === "filesystem") return "e.g. /tmp/reasonix-sandbox";
541
- if (entry.name === "sqlite") return "e.g. ./notes.sqlite";
542
- return entry.userArgs ?? "";
543
- }
544
- function deriveInitialCatalog(existingSpecs) {
545
- const packageToName = new Map(MCP_CATALOG.map((e) => [e.package, e.name]));
546
- const out = [];
547
- for (const spec of existingSpecs) {
548
- for (const [pkg, name] of packageToName) {
549
- if (spec.includes(pkg)) {
550
- out.push(name);
551
- break;
552
- }
553
- }
554
- }
555
- return out;
556
- }
557
- function buildSpec(name, argsByName) {
558
- const entry = CATALOG_BY_NAME.get(name);
559
- if (!entry) return name;
560
- const userArg = entry.userArgs ? argsByName[name] : void 0;
561
- const tail = userArg ? ` ${quoteIfNeeded(userArg)}` : "";
562
- return `${entry.name}=npx -y ${entry.package}${tail}`;
563
- }
564
- function quoteIfNeeded(s) {
565
- return /\s|"/.test(s) ? `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"` : s;
566
- }
567
-
568
- // src/cli/commands/setup.tsx
569
- async function setupCommand(opts = {}) {
570
- loadDotenv();
571
- const existingKey = loadApiKey();
572
- const existing = readConfig();
573
- const { waitUntilExit, unmount } = render_default(
574
- /* @__PURE__ */ import_react3.default.createElement(
575
- Wizard,
576
- {
577
- existingApiKey: existingKey,
578
- initial: { mcp: existing.mcp, theme: existing.theme },
579
- forceApiKeyStep: opts.forceKeyStep,
580
- onComplete: () => void 0,
581
- onCancel: () => {
582
- unmount();
583
- }
584
- }
585
- ),
586
- { exitOnCtrlC: true, patchConsole: false }
587
- );
588
- await waitUntilExit();
589
- }
590
- export {
591
- setupCommand
592
- };
593
- //# sourceMappingURL=setup-IW2XR5XI.js.map