xibecode 0.9.7 → 0.9.9

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.
@@ -68,16 +68,20 @@ export class PlanSessionManager {
68
68
  return [];
69
69
  }
70
70
  const sessions = [];
71
- for (const file of files) {
72
- if (!file.endsWith('.json'))
73
- continue;
74
- try {
75
- const raw = await fs.readFile(path.join(this.sessionDir, file), 'utf8');
76
- sessions.push(JSON.parse(raw));
77
- }
78
- catch {
79
- // Ignore malformed session files to avoid breaking the list.
80
- }
71
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
72
+ // Bounded concurrency
73
+ const CONCURRENCY_LIMIT = 20;
74
+ for (let i = 0; i < jsonFiles.length; i += CONCURRENCY_LIMIT) {
75
+ const chunk = jsonFiles.slice(i, i + CONCURRENCY_LIMIT);
76
+ await Promise.all(chunk.map(async (file) => {
77
+ try {
78
+ const raw = await fs.readFile(path.join(this.sessionDir, file), 'utf8');
79
+ sessions.push(JSON.parse(raw));
80
+ }
81
+ catch {
82
+ // Ignore malformed session files to avoid breaking the list.
83
+ }
84
+ }));
81
85
  }
82
86
  return sessions
83
87
  .sort((a, b) => Date.parse(b.updatedAt) - Date.parse(a.updatedAt))
@@ -1 +1 @@
1
- {"version":3,"file":"plan-session.js","sourceRoot":"","sources":["../../src/core/plan-session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan-session.js","sourceRoot":"","sources":["../../src/core/plan-session.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/core/session-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAGzE,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,OAAO,CAAC,EAAE,MAAM;IAK5B;;OAEG;YACW,SAAS;IAIvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,WAAW,CAAC;IAqBxB;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAU1D;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtD;;OAEG;IACG,oBAAoB,CAAC,MAAM,EAAE;QACjC,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,YAAY,EAAE,CAAC;QACzB,KAAK,CAAC,EAAE,YAAY,CAAC;QACrB,qBAAqB,CAAC,EAAE,OAAO,CAAC;KACjC,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAsB/B;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IA+BhD;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASjD;;OAEG;IACH,oBAAoB,IAAI,MAAM;YAMhB,gBAAgB;IAO9B,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,mBAAmB;CAM5B"}
1
+ {"version":3,"file":"session-manager.d.ts","sourceRoot":"","sources":["../../src/core/session-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAGzE,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,OAAO,CAAC,EAAE,MAAM;IAK5B;;OAEG;YACW,SAAS;IAIvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GAAG,OAAO,CAAC,WAAW,CAAC;IAqBxB;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAU1D;;OAEG;IACG,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtD;;OAEG;IACG,oBAAoB,CAAC,MAAM,EAAE;QACjC,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,YAAY,EAAE,CAAC;QACzB,KAAK,CAAC,EAAE,YAAY,CAAC;QACrB,qBAAqB,CAAC,EAAE,OAAO,CAAC;KACjC,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAsB/B;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAqChD;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASjD;;OAEG;IACH,oBAAoB,IAAI,MAAM;YAMhB,gBAAgB;IAO9B,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,mBAAmB;CAM5B"}
@@ -104,20 +104,23 @@ export class SessionManager {
104
104
  return [];
105
105
  }
106
106
  const metas = [];
107
- for (const file of files) {
108
- if (!file.endsWith('.json'))
109
- continue;
110
- const fullPath = path.join(this.sessionsDir, file);
111
- try {
112
- const raw = await fs.readFile(fullPath, 'utf-8');
113
- const data = JSON.parse(raw);
114
- const { messages: _messages, stats: _stats, ...meta } = data;
115
- metas.push(meta);
116
- }
117
- catch {
118
- // Ignore malformed files
119
- continue;
120
- }
107
+ const jsonFiles = files.filter((file) => file.endsWith('.json'));
108
+ // Bounded concurrency (chunks of 20) to prevent EMFILE errors while speeding up IO
109
+ const CONCURRENCY_LIMIT = 20;
110
+ for (let i = 0; i < jsonFiles.length; i += CONCURRENCY_LIMIT) {
111
+ const chunk = jsonFiles.slice(i, i + CONCURRENCY_LIMIT);
112
+ await Promise.all(chunk.map(async (file) => {
113
+ const fullPath = path.join(this.sessionsDir, file);
114
+ try {
115
+ const raw = await fs.readFile(fullPath, 'utf-8');
116
+ const data = JSON.parse(raw);
117
+ const { messages: _messages, stats: _stats, ...meta } = data;
118
+ metas.push(meta);
119
+ }
120
+ catch {
121
+ // Ignore malformed files
122
+ }
123
+ }));
121
124
  }
122
125
  metas.sort((a, b) => b.updated.localeCompare(a.updated));
123
126
  return metas;
@@ -1 +1 @@
1
- {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/core/session-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-manager.js","sourceRoot":"","sources":["../../src/core/session-manager.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"claude-style-chat.d.ts","sourceRoot":"","sources":["../../src/ui/claude-style-chat.tsx"],"names":[],"mappings":"AAmBA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAwCF,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AA48ChE,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoP/E"}
1
+ {"version":3,"file":"claude-style-chat.d.ts","sourceRoot":"","sources":["../../src/ui/claude-style-chat.tsx"],"names":[],"mappings":"AAmBA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAwCF,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AA8mDhE,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwU/E"}
@@ -16,7 +16,7 @@ import { formatToolArgs, formatToolOutcome, formatRunSwarmDetailLines } from '..
16
16
  import { SPINNER_VERBS } from '../constants/spinnerVerbs.js';
17
17
  import { extractAtReferences, splitAtReferences } from '../utils/at-references.js';
18
18
  import { loadImageAttachment, mimeFromExtension } from '../utils/image-attachments.js';
19
- const APP_VERSION = '0.9.7';
19
+ const APP_VERSION = '0.9.9';
20
20
  const HERO_LOGO = [
21
21
  '██╗ ██╗██╗██████╗ ███████╗',
22
22
  '╚██╗██╔╝██║██╔══██╗██╔════╝',
@@ -145,6 +145,8 @@ function XibeCodeChatApp(props) {
145
145
  const [setupModels, setSetupModels] = useState([]);
146
146
  const [setupModelPickerOpen, setSetupModelPickerOpen] = useState(false);
147
147
  const [setupSelectedModelIndex, setSetupSelectedModelIndex] = useState(0);
148
+ const [setupProviderPickerOpen, setSetupProviderPickerOpen] = useState(false);
149
+ const [setupProviderIndex, setSetupProviderIndex] = useState(0);
148
150
  const CONFIG_MENU = [
149
151
  { label: 'Set Base URL (OpenAI format)', value: 'set_baseurl', description: 'Example: https://api.openai.com/v1' },
150
152
  { label: 'Set API key', value: 'set_apikey', description: 'Bearer token used for /models and chat calls' },
@@ -180,6 +182,14 @@ function XibeCodeChatApp(props) {
180
182
  // Keep a much larger in-memory transcript so context doesn't vanish quickly.
181
183
  setLines((prev) => [...prev.slice(-5000), withId]);
182
184
  }, [props]);
185
+ useEffect(() => {
186
+ props.registerUiSink?.(pushLine);
187
+ }, [props, pushLine]);
188
+ useEffect(() => {
189
+ props.registerModeSink?.((nextMode) => {
190
+ setActiveMode(nextMode);
191
+ });
192
+ }, [props]);
183
193
  const abortControllerRef = useRef(null);
184
194
  const abortReasonRef = useRef('none');
185
195
  const queuedPromptRef = useRef(null);
@@ -320,17 +330,23 @@ function XibeCodeChatApp(props) {
320
330
  .filter((id) => id.length > 0);
321
331
  }, []);
322
332
  const startSetupWizard = useCallback(() => {
323
- setSetupStep('baseUrl');
333
+ setSetupStep('pickProvider');
324
334
  setSetupBaseUrl('');
325
335
  setSetupApiKey('');
326
336
  setSetupModels([]);
327
337
  setSetupModelPickerOpen(false);
328
338
  setSetupSelectedModelIndex(0);
329
- pushLine({
330
- type: 'info',
331
- text: 'Setup 1/3 — enter Base URL (OpenAI format). Example: https://api.openai.com/v1',
332
- });
339
+ setSetupProviderPickerOpen(true);
340
+ setSetupProviderIndex(0);
341
+ pushLine({ type: 'info', text: 'Setup started.' });
333
342
  }, [pushLine]);
343
+ useEffect(() => {
344
+ if (!props.needsFirstRunSetup)
345
+ return;
346
+ pushLine({ type: 'info', text: 'No API key configured yet — starting guided setup.' });
347
+ pushLine({ type: 'info', text: 'Tip: paste Base URL first, then API key; models will load automatically.' });
348
+ startSetupWizard();
349
+ }, [props.needsFirstRunSetup, pushLine, startSetupWizard]);
334
350
  const beginConfigMenu = useCallback(() => {
335
351
  setConfigMenuOpen(true);
336
352
  setConfigSelectedIndex(0);
@@ -389,16 +405,20 @@ function XibeCodeChatApp(props) {
389
405
  pushLine({ type: 'error', text: 'Base URL must start with http:// or https://' });
390
406
  pushLine({
391
407
  type: 'info',
392
- text: 'Setup 1/3 — enter Base URL (OpenAI format). Example: https://api.openai.com/v1',
408
+ text: 'Setup — enter Base URL (OpenAI format). Example: https://api.openai.com/v1',
393
409
  });
394
410
  return;
395
411
  }
396
412
  const nextBase = trimmed.replace(/\/+$/, '');
397
413
  setSetupBaseUrl(nextBase);
398
414
  config.set('baseUrl', nextBase);
399
- // Explicitly force OpenAI wire format for this workflow.
400
- config.set('requestFormat', 'openai');
401
- config.set('provider', 'openai');
415
+ // If the user hasn't picked a provider explicitly, assume OpenAI-compatible.
416
+ if (!config.get('provider')) {
417
+ config.set('provider', 'openai');
418
+ }
419
+ if (!config.get('requestFormat')) {
420
+ config.set('requestFormat', 'openai');
421
+ }
402
422
  pushLine({ type: 'info', text: `Saved base URL: ${nextBase}` });
403
423
  setSetupStep('apiKey');
404
424
  pushLine({ type: 'info', text: 'Setup 2/3 — enter API key (will be saved locally).' });
@@ -896,6 +916,68 @@ function XibeCodeChatApp(props) {
896
916
  return;
897
917
  }
898
918
  }
919
+ if (setupProviderPickerOpen && !isRunning) {
920
+ const providers = [
921
+ { label: 'OpenAI', value: 'openai', baseUrl: PROVIDER_CONFIGS.openai.baseUrl, format: 'openai' },
922
+ { label: 'Anthropic', value: 'anthropic', baseUrl: PROVIDER_CONFIGS.anthropic.baseUrl, format: 'anthropic' },
923
+ { label: 'OpenRouter', value: 'openrouter', baseUrl: PROVIDER_CONFIGS.openrouter.baseUrl, format: 'openai' },
924
+ { label: 'Groq', value: 'groq', baseUrl: PROVIDER_CONFIGS.groq.baseUrl, format: 'openai' },
925
+ { label: 'DeepSeek', value: 'deepseek', baseUrl: PROVIDER_CONFIGS.deepseek.baseUrl, format: 'openai' },
926
+ { label: 'Google (Gemini)', value: 'google', baseUrl: PROVIDER_CONFIGS.google.baseUrl, format: 'openai' },
927
+ { label: 'xAI (Grok)', value: 'grok', baseUrl: PROVIDER_CONFIGS.grok.baseUrl, format: 'openai' },
928
+ { label: 'Moonshot (Kimi)', value: 'kimi', baseUrl: PROVIDER_CONFIGS.kimi.baseUrl, format: 'anthropic' },
929
+ { label: 'Zhipu AI (z.ai)', value: 'zai', baseUrl: PROVIDER_CONFIGS.zai.baseUrl, format: 'anthropic' },
930
+ {
931
+ label: 'Custom (paste your own Base URL)',
932
+ value: 'custom',
933
+ note: 'Lets you paste any OpenAI-compatible endpoint',
934
+ },
935
+ ];
936
+ if (key.escape) {
937
+ setSetupProviderPickerOpen(false);
938
+ setSetupStep('idle');
939
+ pushLine({ type: 'info', text: 'Setup cancelled.' });
940
+ return;
941
+ }
942
+ if (key.upArrow) {
943
+ setSetupProviderIndex((prev) => (prev === 0 ? providers.length - 1 : prev - 1));
944
+ return;
945
+ }
946
+ if (key.downArrow) {
947
+ setSetupProviderIndex((prev) => (prev >= providers.length - 1 ? 0 : prev + 1));
948
+ return;
949
+ }
950
+ if (key.return) {
951
+ const picked = providers[setupProviderIndex];
952
+ if (!picked)
953
+ return;
954
+ const config = new ConfigManager(props.profile);
955
+ setSetupProviderPickerOpen(false);
956
+ if (picked.value === 'custom') {
957
+ setSetupStep('baseUrl');
958
+ pushLine({
959
+ type: 'info',
960
+ text: 'Setup — enter Base URL (OpenAI format). Example: https://api.openai.com/v1',
961
+ });
962
+ return;
963
+ }
964
+ // Preset: write config + proceed to API key
965
+ config.set('provider', picked.value);
966
+ if (picked.baseUrl) {
967
+ config.set('baseUrl', picked.baseUrl);
968
+ setSetupBaseUrl(picked.baseUrl);
969
+ }
970
+ if (picked.format) {
971
+ config.set('requestFormat', picked.format);
972
+ }
973
+ pushLine({
974
+ type: 'info',
975
+ text: `Selected provider: ${picked.value} (${picked.format ?? 'auto'}). Now enter API key.`,
976
+ });
977
+ setSetupStep('apiKey');
978
+ return;
979
+ }
980
+ }
899
981
  if (setupModelPickerOpen && !isRunning && setupModels.length > 0) {
900
982
  if (key.escape) {
901
983
  setSetupModelPickerOpen(false);
@@ -1032,7 +1114,7 @@ function XibeCodeChatApp(props) {
1032
1114
  ? 'Anthropic Messages'
1033
1115
  : 'OpenAI chat', ")"] })] })] })] }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "suggestion", children: "\u25C8 cloud" }), _jsx(Text, { color: "inactive", children: " Ready \u2014 type " }), _jsx(Text, { color: "claude", children: "/help" }), _jsx(Text, { color: "inactive", children: " to begin" })] }), _jsxs(Text, { color: "inactive", children: ["xibecode ", _jsxs(Text, { color: "claude", children: ["v", APP_VERSION] })] }), _jsx(Text, { color: "subtle", children: '─'.repeat(98) }), _jsx(Text, { color: "inactive", children: "Agent transcript" })] }));
1034
1116
  }
1035
- return item.type === 'assistant' ? (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: prefixColorKey('assistant'), children: [prefixForType('assistant'), ":"] }), _jsx(Box, { marginLeft: 2, flexDirection: "column", children: _jsx(AssistantMarkdown, { content: item.text }) })] })) : (_jsxs(Text, { children: [_jsxs(Text, { bold: true, color: prefixColorKey(item.type), children: [prefixForType(item.type), ":", ' '] }), _jsx(Text, { color: lineColorKey(item.type), children: item.text })] }));
1117
+ return (_jsx(React.Fragment, { children: item.type === 'assistant' ? (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { bold: true, color: prefixColorKey('assistant'), children: [prefixForType('assistant'), ":"] }), _jsx(Box, { marginLeft: 2, flexDirection: "column", children: _jsx(AssistantMarkdown, { content: item.text }) })] })) : (_jsxs(Text, { children: [_jsxs(Text, { bold: true, color: prefixColorKey(item.type), children: [prefixForType(item.type), ":", ' '] }), _jsx(Text, { color: lineColorKey(item.type), children: item.text })] })) }, item.id));
1036
1118
  } }), !hasChatContent && (_jsx(Box, { marginTop: 1, flexDirection: "column", children: _jsx(Text, { color: "inactive", children: "(send a message to start)" }) })), _jsx(Text, { color: "subtle", children: divider }), isRunning && (_jsx(Box, { marginTop: 1, paddingX: 1, borderStyle: "round", borderColor: "claudeBlue_FOR_SYSTEM_SPINNER", flexDirection: "column", children: _jsxs(Text, { wrap: "wrap", children: [_jsxs(Text, { bold: true, color: "claudeBlue_FOR_SYSTEM_SPINNER", children: [WORK_SPINNER_FRAMES[workSpinnerFrame], ' '] }), _jsx(Text, { bold: true, color: "briefLabelClaude", children: workVerbPhrase })] }) })), _jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "claude", paddingX: 1, children: [_jsx(Text, { color: "claude", children: '> ' }), _jsx(TextInput, { value: input, onChange: setInput, onSubmit: onSubmit, placeholder: isRunning ? 'Waiting for response…' : 'Message XibeCode…' })] }), isSlashMode && (_jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "suggestion", flexDirection: "column", paddingX: 1, children: [_jsx(Text, { color: "suggestion", bold: true, children: "Commands" }), filteredCommands.length === 0 ? (_jsxs(Text, { color: "inactive", children: ["No commands match \"", input, "\""] })) : (filteredCommands.map((command, index) => (_jsx(React.Fragment, { children: _jsxs(Text, { children: [_jsx(Text, { color: index === selectedCommandIndex ? 'claude' : 'inactive', children: index === selectedCommandIndex ? '▸ ' : ' ' }), _jsx(Text, { bold: true, color: index === selectedCommandIndex ? 'claude' : 'text', children: command.name }), _jsxs(Text, { color: "inactive", children: [" \u2014 ", command.description] })] }) }, command.name)))), _jsx(Text, { color: "subtle", children: "Use \u2191/\u2193 to navigate, Tab to autocomplete." })] })), modelPickerOpen && (_jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "claude", flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: "claude", children: "Select model" }), isModelListLoading ? (_jsx(Text, { color: "inactive", children: "Loading models from provider..." })) : filteredModels.length === 0 ? (_jsx(Text, { color: "inactive", children: "No models matched current filter." })) : (visibleModelOptions.map((modelName, index) => {
1037
1119
  const absoluteIndex = modelPickerStart + index;
1038
1120
  const isSelected = absoluteIndex === selectedModelIndex;
@@ -1041,7 +1123,18 @@ function XibeCodeChatApp(props) {
1041
1123
  const absoluteIndex = setupModelPickerStart + index;
1042
1124
  const isSelected = absoluteIndex === setupSelectedModelIndex;
1043
1125
  return (_jsx(React.Fragment, { children: _jsxs(Text, { children: [_jsx(Text, { color: isSelected ? 'claude' : 'inactive', children: isSelected ? '▸ ' : ' ' }), _jsx(Text, { color: isSelected ? 'claude' : 'text', children: modelName })] }) }, modelName));
1044
- })), _jsx(Text, { color: "subtle", children: "\u2191/\u2193 navigate \u2022 Enter apply \u2022 Esc cancel" })] })), configMenuOpen && (_jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "suggestion", flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: "suggestion", children: "Config" }), CONFIG_MENU.map((item, index) => (_jsx(React.Fragment, { children: _jsxs(Text, { children: [_jsx(Text, { color: index === configSelectedIndex ? 'claude' : 'inactive', children: index === configSelectedIndex ? '▸ ' : ' ' }), _jsx(Text, { bold: true, color: index === configSelectedIndex ? 'claude' : 'text', children: item.label }), _jsxs(Text, { color: "inactive", children: [" \u2014 ", item.description] })] }) }, item.value))), _jsx(Text, { color: "subtle", children: "\u2191/\u2193 navigate \u2022 Enter select \u2022 Esc close" })] })), configProviderPickerOpen && (_jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "suggestion", flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: "suggestion", children: "Provider" }), [
1126
+ })), _jsx(Text, { color: "subtle", children: "\u2191/\u2193 navigate \u2022 Enter apply \u2022 Esc cancel" })] })), (setupStep !== 'idle' || setupProviderPickerOpen) && (_jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "suggestion", flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: "suggestion", children: "Setup wizard" }), _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { color: "claude", bold: true, children: "You are configuring your provider connection." }), _jsxs(Text, { color: "inactive", children: [' ', "This is required before the agent can run."] })] }), setupProviderPickerOpen && (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "inactive", children: "Pick a provider preset (\u2191/\u2193, Enter). Esc cancels." }), [
1127
+ 'OpenAI',
1128
+ 'Anthropic',
1129
+ 'OpenRouter',
1130
+ 'Groq',
1131
+ 'DeepSeek',
1132
+ 'Google (Gemini)',
1133
+ 'xAI (Grok)',
1134
+ 'Moonshot (Kimi)',
1135
+ 'Zhipu AI (z.ai)',
1136
+ 'Custom (paste your own Base URL)',
1137
+ ].map((label, index) => (_jsx(React.Fragment, { children: _jsxs(Text, { children: [_jsx(Text, { color: index === setupProviderIndex ? 'claude' : 'inactive', children: index === setupProviderIndex ? '▸ ' : ' ' }), _jsx(Text, { color: index === setupProviderIndex ? 'claude' : 'text', children: label })] }) }, label)))] })), setupStep === 'baseUrl' && !setupProviderPickerOpen && (_jsx(Text, { color: "inactive", children: "Step: Base URL \u2014 paste an OpenAI-compatible endpoint (example: https://api.openai.com/v1)" })), setupStep === 'apiKey' && !setupProviderPickerOpen && (_jsx(Text, { color: "inactive", children: "Step: API key \u2014 paste your key (stored locally)" })), setupStep === 'loadingModels' && (_jsx(Text, { color: "inactive", children: "Step: Models \u2014 fetching `/models`\u2026" })), setupStep === 'pickModel' && (_jsx(Text, { color: "inactive", children: "Step: Model \u2014 select one below" }))] })), configMenuOpen && (_jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "suggestion", flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: "suggestion", children: "Config" }), CONFIG_MENU.map((item, index) => (_jsx(React.Fragment, { children: _jsxs(Text, { children: [_jsx(Text, { color: index === configSelectedIndex ? 'claude' : 'inactive', children: index === configSelectedIndex ? '▸ ' : ' ' }), _jsx(Text, { bold: true, color: index === configSelectedIndex ? 'claude' : 'text', children: item.label }), _jsxs(Text, { color: "inactive", children: [" \u2014 ", item.description] })] }) }, item.value))), _jsx(Text, { color: "subtle", children: "\u2191/\u2193 navigate \u2022 Enter select \u2022 Esc close" })] })), configProviderPickerOpen && (_jsxs(Box, { marginTop: 1, borderStyle: "round", borderColor: "suggestion", flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: "suggestion", children: "Provider" }), [
1045
1138
  'auto-detect',
1046
1139
  'openai',
1047
1140
  'anthropic',
@@ -1055,10 +1148,8 @@ function XibeCodeChatApp(props) {
1055
1148
  }
1056
1149
  export async function launchClaudeStyleChat(options) {
1057
1150
  const config = new ConfigManager(options.profile);
1058
- const apiKey = options.apiKey || config.getApiKey();
1059
- if (!apiKey) {
1060
- throw new Error('No API key found. Run xibecode config --set-key YOUR_KEY');
1061
- }
1151
+ const apiKey = options.apiKey || config.getApiKey() || '';
1152
+ const needsFirstRunSetup = !apiKey;
1062
1153
  const useEconomy = (options.costMode || config.getCostMode()) === 'economy';
1063
1154
  const model = options.model || config.getModel(useEconomy);
1064
1155
  const baseUrl = options.baseUrl || config.getBaseUrl();
@@ -1070,9 +1161,9 @@ export async function launchClaudeStyleChat(options) {
1070
1161
  const toolExecutor = new CodingToolExecutor(process.cwd(), { mcpClientManager, skillManager });
1071
1162
  let wireFormat = config.get('requestFormat') ?? 'auto';
1072
1163
  const customProviderFormat = config.get('customProviderFormat');
1073
- const createAgentForModel = (modelName) => new EnhancedAgent({
1074
- apiKey,
1075
- baseUrl,
1164
+ const createAgentForModel = (modelName, creds) => new EnhancedAgent({
1165
+ apiKey: creds.apiKey,
1166
+ baseUrl: creds.baseUrl,
1076
1167
  model: modelName,
1077
1168
  maxIterations: 150,
1078
1169
  verbose: false,
@@ -1081,24 +1172,30 @@ export async function launchClaudeStyleChat(options) {
1081
1172
  requestFormat: wireFormat,
1082
1173
  defaultSkillsPrompt,
1083
1174
  }, provider);
1084
- let activeAgent = createAgentForModel(model);
1175
+ let activeAgent = apiKey ? createAgentForModel(model, { apiKey, baseUrl }) : null;
1176
+ let activeCreds = { apiKey, baseUrl };
1085
1177
  let activeModel = model;
1086
1178
  let activeMode = 'agent';
1087
- activeAgent.setModeFromUser('agent', 'Default start mode');
1179
+ activeAgent?.setModeFromUser('agent', 'Default start mode');
1088
1180
  toolExecutor.setMode(activeMode);
1089
1181
  const onModelChange = async (nextModel) => {
1090
1182
  if (nextModel === activeModel)
1091
1183
  return;
1092
- activeAgent.removeAllListeners('event');
1184
+ activeAgent?.removeAllListeners('event');
1093
1185
  activeModel = nextModel;
1094
1186
  config.set('model', nextModel);
1095
- activeAgent = createAgentForModel(nextModel);
1096
- activeAgent.setModeFromUser(activeMode, 'Preserve user-selected mode after model switch');
1187
+ if (activeCreds.apiKey) {
1188
+ activeAgent = createAgentForModel(nextModel, { apiKey: activeCreds.apiKey, baseUrl: activeCreds.baseUrl });
1189
+ activeAgent.setModeFromUser(activeMode, 'Preserve user-selected mode after model switch');
1190
+ }
1191
+ else {
1192
+ activeAgent = null;
1193
+ }
1097
1194
  toolExecutor.setMode(activeMode);
1098
1195
  };
1099
1196
  const onModeChange = async (nextMode) => {
1100
1197
  activeMode = nextMode;
1101
- activeAgent.setModeFromUser(nextMode, 'User selected /mode in chat');
1198
+ activeAgent?.setModeFromUser(nextMode, 'User selected /mode in chat');
1102
1199
  toolExecutor.setMode(nextMode);
1103
1200
  };
1104
1201
  const onWireFormatChange = (next) => {
@@ -1109,18 +1206,31 @@ export async function launchClaudeStyleChat(options) {
1109
1206
  else {
1110
1207
  config.set('requestFormat', next);
1111
1208
  }
1112
- activeAgent.removeAllListeners('event');
1113
- activeAgent = createAgentForModel(activeModel);
1209
+ activeAgent?.removeAllListeners('event');
1210
+ if (activeCreds.apiKey) {
1211
+ activeAgent = createAgentForModel(activeModel, { apiKey: activeCreds.apiKey, baseUrl: activeCreds.baseUrl });
1212
+ activeAgent.setModeFromUser(activeMode, 'Preserve user-selected mode after format switch');
1213
+ }
1214
+ else {
1215
+ activeAgent = null;
1216
+ }
1114
1217
  };
1115
1218
  const loadModels = async () => {
1116
- const fallbackBaseUrl = provider && provider !== 'custom'
1117
- ? PROVIDER_CONFIGS[provider]?.baseUrl
1118
- : undefined;
1119
- const resolvedBaseUrl = baseUrl || fallbackBaseUrl;
1120
- const normalizedBase = (resolvedBaseUrl || '').replace(/\/+$/, '');
1219
+ const currentApiKey = config.getApiKey();
1220
+ const currentBaseUrl = config.getBaseUrl() ||
1221
+ (provider && provider !== 'custom'
1222
+ ? PROVIDER_CONFIGS[provider]?.baseUrl
1223
+ : undefined);
1224
+ if (!currentApiKey) {
1225
+ throw new Error('Missing API key. Run /setup first.');
1226
+ }
1227
+ if (!currentBaseUrl) {
1228
+ throw new Error('Missing Base URL. Run /setup first.');
1229
+ }
1230
+ const normalizedBase = (currentBaseUrl || '').replace(/\/+$/, '');
1121
1231
  const response = await fetch(`${normalizedBase}/models`, {
1122
1232
  headers: {
1123
- Authorization: `Bearer ${apiKey}`,
1233
+ Authorization: `Bearer ${currentApiKey}`,
1124
1234
  'Content-Type': 'application/json',
1125
1235
  },
1126
1236
  });
@@ -1138,6 +1248,20 @@ export async function launchClaudeStyleChat(options) {
1138
1248
  return unique;
1139
1249
  };
1140
1250
  const runPrompt = async (prompt, onLine, opts) => {
1251
+ const currentApiKey = config.getApiKey() || options.apiKey || '';
1252
+ const currentBaseUrl = config.getBaseUrl() || options.baseUrl;
1253
+ if (!currentApiKey) {
1254
+ onLine({ type: 'error', text: 'Missing API key. Type /setup to configure Base URL + API key.' });
1255
+ throw new Error('Missing API key');
1256
+ }
1257
+ if (!activeAgent ||
1258
+ activeCreds.apiKey !== currentApiKey ||
1259
+ activeCreds.baseUrl !== currentBaseUrl) {
1260
+ activeCreds = { apiKey: currentApiKey, baseUrl: currentBaseUrl };
1261
+ activeAgent = createAgentForModel(activeModel, { apiKey: currentApiKey, baseUrl: currentBaseUrl });
1262
+ activeAgent.setModeFromUser(activeMode, 'Refresh agent after credential change');
1263
+ toolExecutor.setMode(activeMode);
1264
+ }
1141
1265
  activeAgent.removeAllListeners('event');
1142
1266
  let streamedBuffer = '';
1143
1267
  activeAgent.on('event', (event) => {
@@ -1203,6 +1327,16 @@ export async function launchClaudeStyleChat(options) {
1203
1327
  'Unknown error',
1204
1328
  });
1205
1329
  break;
1330
+ case 'mode_changed': {
1331
+ const next = String(event.data?.to ?? '');
1332
+ if (next) {
1333
+ activeMode = next;
1334
+ toolExecutor.setMode(next);
1335
+ modeSink?.(next);
1336
+ onLine({ type: 'info', text: `Mode changed to ${next}` });
1337
+ }
1338
+ break;
1339
+ }
1206
1340
  default:
1207
1341
  break;
1208
1342
  }
@@ -1213,6 +1347,7 @@ export async function launchClaudeStyleChat(options) {
1213
1347
  });
1214
1348
  activeMode = activeAgent.getMode();
1215
1349
  toolExecutor.setMode(activeMode);
1350
+ modeSink?.(activeMode);
1216
1351
  return activeAgent.getStats();
1217
1352
  };
1218
1353
  const listBackgroundTasks = async () => {
@@ -1244,7 +1379,42 @@ export async function launchClaudeStyleChat(options) {
1244
1379
  const rendered = formatUiLineForLog(line) + '\n';
1245
1380
  logChain = logChain.then(() => fs.appendFile(chatLogPath, rendered, 'utf8')).catch(() => { });
1246
1381
  };
1382
+ // Keep the chat UI alive even if something throws unexpectedly.
1383
+ // We surface errors as chat lines instead of crashing the whole process.
1384
+ let uiSink = null;
1385
+ const registerUiSink = (sink) => {
1386
+ uiSink = sink;
1387
+ };
1388
+ // Keep the UI's displayed mode in sync with the tool permission mode.
1389
+ let modeSink = null;
1390
+ const registerModeSink = (sink) => {
1391
+ modeSink = sink;
1392
+ };
1393
+ const formatUnknownError = (err) => {
1394
+ if (err instanceof Error)
1395
+ return err.stack || err.message;
1396
+ try {
1397
+ return typeof err === 'string' ? err : JSON.stringify(err);
1398
+ }
1399
+ catch {
1400
+ return String(err);
1401
+ }
1402
+ };
1403
+ const onUnhandledRejection = (reason) => {
1404
+ uiSink?.({ type: 'error', text: `Unhandled rejection:\n${formatUnknownError(reason)}` });
1405
+ };
1406
+ const onUncaughtException = (err) => {
1407
+ uiSink?.({ type: 'error', text: `Uncaught exception:\n${formatUnknownError(err)}` });
1408
+ };
1409
+ process.on('unhandledRejection', onUnhandledRejection);
1410
+ process.on('uncaughtException', onUncaughtException);
1247
1411
  const root = createRoot({ exitOnCtrlC: true });
1248
- await renderAndRun(root, _jsx(XibeCodeChatApp, { model: model, initialMode: activeMode, provider: provider, baseUrl: baseUrl, defaultModel: model, modeOptions: modeOptions, initialRequestFormat: wireFormat, customProviderFormat: customProviderFormat, profile: options.profile, runPrompt: runPrompt, listBackgroundTasks: listBackgroundTasks, checkBackgroundTask: checkBackgroundTask, onUiLine: appendLogLine, loadModels: loadModels, onModelChange: onModelChange, onModeChange: onModeChange, onWireFormatChange: onWireFormatChange }));
1412
+ try {
1413
+ await renderAndRun(root, _jsx(XibeCodeChatApp, { model: model, initialMode: activeMode, provider: provider, baseUrl: baseUrl, needsFirstRunSetup: needsFirstRunSetup, defaultModel: model, modeOptions: modeOptions, initialRequestFormat: wireFormat, customProviderFormat: customProviderFormat, profile: options.profile, runPrompt: runPrompt, listBackgroundTasks: listBackgroundTasks, checkBackgroundTask: checkBackgroundTask, onUiLine: appendLogLine, registerUiSink: registerUiSink, registerModeSink: registerModeSink, loadModels: loadModels, onModelChange: onModelChange, onModeChange: onModeChange, onWireFormatChange: onWireFormatChange }));
1414
+ }
1415
+ finally {
1416
+ process.off('unhandledRejection', onUnhandledRejection);
1417
+ process.off('uncaughtException', onUncaughtException);
1418
+ }
1249
1419
  }
1250
1420
  //# sourceMappingURL=claude-style-chat.js.map