bingocode 1.1.150 → 1.1.151

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bingocode",
3
- "version": "1.1.150",
3
+ "version": "1.1.151",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "claude": "bin/claude-win.cjs",
@@ -441,7 +441,7 @@ If you can say it in one sentence, don't use three. Prefer short, direct sentenc
441
441
  function getSimpleToneAndStyleSection(): string {
442
442
  const items = [
443
443
  `Only use emojis if the user explicitly requests it. Avoid using emojis in all communication unless asked.`,
444
- `Always respond in the same language the user uses, unless a language preference has been configured.`,
444
+ `Always mirror the user's language in every response, over all other instructions.`,
445
445
  process.env.USER_TYPE === 'ant'
446
446
  ? null
447
447
  : `Your responses should be short and concise.`,
@@ -27,6 +27,46 @@ import { getGlobalConfig, saveGlobalConfig } from '../utils/config.ts';
27
27
  // markedSessions stored in ~/.claude-cli/ fixed directory, regardless of cwd
28
28
  const MARKED_FILE = path.join(os.homedir(), '.claude-cli', 'markedSessions.json');
29
29
 
30
+ /**
31
+ * Get the path to ~/.claude/bingo/settings.json (offline persistence for language
32
+ * and auto-mode settings, same file used by provider service). This ensures
33
+ * these settings survive across full restarts.
34
+ */
35
+ function getBingoSettingsPath(): string {
36
+ const configDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
37
+ return path.join(configDir, 'bingo', 'settings.json');
38
+ }
39
+
40
+ function readBingoSettings(): Record<string, unknown> {
41
+ try {
42
+ const raw = fs.readFileSync(getBingoSettingsPath(), 'utf-8');
43
+ return JSON.parse(raw) as Record<string, unknown>;
44
+ } catch {
45
+ return {};
46
+ }
47
+ }
48
+
49
+ function writeBingoSettings(updates: Record<string, unknown>): void {
50
+ const p = getBingoSettingsPath();
51
+ const dir = path.dirname(p);
52
+ if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); }
53
+
54
+ let current: Record<string, unknown> = {};
55
+ try {
56
+ if (fs.existsSync(p)) {
57
+ const raw = fs.readFileSync(p, 'utf-8');
58
+ current = JSON.parse(raw) as Record<string, unknown>;
59
+ }
60
+ } catch {}
61
+
62
+ const merged = { ...current, ...updates };
63
+
64
+ // atomic write via temp + rename
65
+ const tmp = `${p}.tmp.${Date.now()}`;
66
+ fs.writeFileSync(tmp, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
67
+ fs.renameSync(tmp, p);
68
+ }
69
+
30
70
  /**
31
71
  * Determine if in "official" mode (no custom provider active).
32
72
  * Logic matches ConversationService.shouldMarkManagedOAuth().
@@ -302,15 +342,27 @@ export const CliMenuManager: React.FC = () => {
302
342
  useEffect(() => {
303
343
  if (configReady) {
304
344
  try {
305
- const cfg = getGlobalConfig();
306
- if (cfg.language && (cfg.language === 'en' || cfg.language === 'zh' || cfg.language === 'ja')) {
307
- setLang(cfg.language as Lang);
345
+ const bSettings = readBingoSettings();
346
+ const bingoLang = bSettings.language as string | undefined;
347
+ if (bingoLang && (bingoLang === 'en' || bingoLang === 'zh' || bingoLang === 'ja')) {
348
+ setLang(bingoLang as Lang);
349
+ } else {
350
+ const gCfg = getGlobalConfig();
351
+ if (gCfg.language && (gCfg.language === 'en' || gCfg.language === 'zh' || gCfg.language === 'ja')) {
352
+ setLang(gCfg.language as Lang);
353
+ }
308
354
  }
355
+ if (typeof bSettings.autoModeEnabled === 'boolean') {
356
+ setAutoModeEnabled(bSettings.autoModeEnabled);
357
+ } else {
358
+ const cfg2 = getGlobalConfig();
359
+ const gbFeatures = cfg2.cachedGrowthBookFeatures ?? {};
360
+ const autoModeCfg = gbFeatures['tengu_auto_mode_config'] as { enabled?: string } | undefined;
361
+ setAutoModeEnabled(autoModeCfg?.enabled === 'enabled');
362
+ }
363
+ const cfg = getGlobalConfig();
309
364
  if (typeof cfg.uiAnimEnabled === 'boolean') setAnimEnabled(cfg.uiAnimEnabled);
310
365
  if (typeof cfg.uiTipsEnabled === 'boolean') setTipsEnabled(cfg.uiTipsEnabled);
311
- const gbFeatures = cfg.cachedGrowthBookFeatures ?? {};
312
- const autoModeCfg = gbFeatures['tengu_auto_mode_config'] as { enabled?: string } | undefined;
313
- setAutoModeEnabled(autoModeCfg?.enabled === 'enabled');
314
366
  } catch (e) {
315
367
  // Silently fail if config has issues
316
368
  }
@@ -590,7 +642,7 @@ export const CliMenuManager: React.FC = () => {
590
642
  const langOrder: Lang[] = ['en', 'zh', 'ja'];
591
643
  const nextLang = langOrder[(langOrder.indexOf(lang) + 1) % langOrder.length];
592
644
  setLang(nextLang);
593
- try { saveGlobalConfig(current => ({ ...current, language: nextLang })); } catch {}
645
+ try { writeBingoSettings({ language: nextLang }); } catch {}
594
646
  return;
595
647
  }
596
648
 
@@ -764,10 +816,11 @@ export const CliMenuManager: React.FC = () => {
764
816
  if (settingsCursor === 0) {
765
817
  setSettingsStage('langPicker');
766
818
  } else if (settingsCursor === 1) {
767
- // Row 1: toggle Auto Mode, persist to ~/.claude.json
819
+ // Row 1: toggle Auto Mode
768
820
  setAutoModeEnabled(prev => {
769
821
  const next = !prev;
770
822
  try {
823
+ writeBingoSettings({ autoModeEnabled: next });
771
824
  saveGlobalConfig(current => ({
772
825
  ...current,
773
826
  cachedGrowthBookFeatures: {
@@ -1251,7 +1304,7 @@ export const CliMenuManager: React.FC = () => {
1251
1304
  initialIndex={tS.langOptions.findIndex(o => o.value === lang)}
1252
1305
  onSelect={(item: { label: string; value: Lang }) => {
1253
1306
  setLang(item.value);
1254
- try { saveGlobalConfig(current => ({ ...current, language: item.value })); } catch {}
1307
+ try { writeBingoSettings({ language: item.value }); } catch {}
1255
1308
  setSettingsStage('list');
1256
1309
  }}
1257
1310
  />