offsite 0.0.12 → 0.0.13

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 (81) hide show
  1. package/apps/server/dist/main.mjs +157 -83
  2. package/apps/server/dist/main.mjs.map +1 -1
  3. package/apps/web/dist/assets/{angular-html-DNGrmdhg.js → angular-html-CtL9u31h.js} +1 -1
  4. package/apps/web/dist/assets/{angular-ts-D4hBqsOh.js → angular-ts-D4IFBcAh.js} +1 -1
  5. package/apps/web/dist/assets/{apl-CYvdPOPE.js → apl-CqnJhScR.js} +1 -1
  6. package/apps/web/dist/assets/{astro-BqtVnRyx.js → astro-Dn1_avL_.js} +1 -1
  7. package/apps/web/dist/assets/{blade-BPJV2sdT.js → blade-BKSa6Bs3.js} +1 -1
  8. package/apps/web/dist/assets/{c-CBQDE6Uf.js → c-C8sbMt_8.js} +1 -1
  9. package/apps/web/dist/assets/{chapel-BHOESU2p.js → chapel-BWxXvR2-.js} +1 -1
  10. package/apps/web/dist/assets/{cobol-CMpvzrel.js → cobol-DNoVp--S.js} +1 -1
  11. package/apps/web/dist/assets/{coffee-Bv27C06e.js → coffee-m1P3e2U1.js} +1 -1
  12. package/apps/web/dist/assets/{cpp-MTwxWDTP.js → cpp-CDvshXRJ.js} +1 -1
  13. package/apps/web/dist/assets/{crystal-CI5fSUCy.js → crystal-C4b65AQe.js} +1 -1
  14. package/apps/web/dist/assets/{css-BW8DHcmj.js → css-CqQV9eEE.js} +1 -1
  15. package/apps/web/dist/assets/{edge-C2HOl06F.js → edge-CEdbZQ1U.js} +1 -1
  16. package/apps/web/dist/assets/{elixir-OV4G1_r7.js → elixir-CYDX6OgA.js} +1 -1
  17. package/apps/web/dist/assets/{elm-BF0pK-yg.js → elm-10RuU89D.js} +1 -1
  18. package/apps/web/dist/assets/{erb-DFQCtOmK.js → erb-BiMfBUaM.js} +1 -1
  19. package/apps/web/dist/assets/{git-rebase-C9nAAu5A.js → git-rebase-D4Se-3SO.js} +1 -1
  20. package/apps/web/dist/assets/{glimmer-js-B9gnYdT1.js → glimmer-js-sKOVTqrH.js} +1 -1
  21. package/apps/web/dist/assets/{glimmer-ts-BkG38Inm.js → glimmer-ts-DWMGXcHA.js} +1 -1
  22. package/apps/web/dist/assets/{glsl-wwo6dKBr.js → glsl-6ltM2JGZ.js} +1 -1
  23. package/apps/web/dist/assets/{graphql-tQJRbYuy.js → graphql-DwyBbitO.js} +1 -1
  24. package/apps/web/dist/assets/{hack-C9e9oyUG.js → hack-DKDbxv34.js} +1 -1
  25. package/apps/web/dist/assets/{haml-CTolMb7J.js → haml-Bsfivw5f.js} +1 -1
  26. package/apps/web/dist/assets/{handlebars-CrJTM5vD.js → handlebars-B3HW0h8N.js} +1 -1
  27. package/apps/web/dist/assets/{html-Be6zOrn3.js → html-D9EhGmAq.js} +1 -1
  28. package/apps/web/dist/assets/{html-derivative-10Bvy_Et.js → html-derivative-Cs1eIi3k.js} +1 -1
  29. package/apps/web/dist/assets/{http-GZlGWwa-.js → http-BG4vxnc2.js} +1 -1
  30. package/apps/web/dist/assets/{hurl-DEYfhn1R.js → hurl-OIF0UEfX.js} +1 -1
  31. package/apps/web/dist/assets/{index-CiQ326rG.js → index-CEx2Hw3M.js} +143 -143
  32. package/apps/web/dist/assets/{java-BsFb26JS.js → java-2iLSH1xc.js} +1 -1
  33. package/apps/web/dist/assets/{javascript-DDLm5bzW.js → javascript-Di7CdqTh.js} +1 -1
  34. package/apps/web/dist/assets/{jinja-NBeNjUXf.js → jinja-2mjIAN_z.js} +1 -1
  35. package/apps/web/dist/assets/{jison-DKz4RK3A.js → jison-Ciw1rqtP.js} +1 -1
  36. package/apps/web/dist/assets/{json-Bg4r8xCd.js → json-D7Dp9EFU.js} +1 -1
  37. package/apps/web/dist/assets/{jsx-BMnPLKsa.js → jsx-WEelr3xJ.js} +1 -1
  38. package/apps/web/dist/assets/{julia-Wll5K4al.js → julia-DL3m48KZ.js} +1 -1
  39. package/apps/web/dist/assets/{just-BLn1iI69.js → just-B-5HaJEz.js} +1 -1
  40. package/apps/web/dist/assets/{latex-D15HRF2E.js → latex-DKmfapvy.js} +1 -1
  41. package/apps/web/dist/assets/{liquid-COHkGI02.js → liquid-Bqxp18sH.js} +1 -1
  42. package/apps/web/dist/assets/{lua-CkbAAxOH.js → lua-BSLGBVbN.js} +1 -1
  43. package/apps/web/dist/assets/{marko-Dmgo6IU5.js → marko-yLzCBGNR.js} +1 -1
  44. package/apps/web/dist/assets/{mdc-D_OV_cCt.js → mdc-DSGSIXIk.js} +1 -1
  45. package/apps/web/dist/assets/{nginx-ADn2lIMW.js → nginx-BF1hRuVH.js} +1 -1
  46. package/apps/web/dist/assets/{nim-C6zTq4FI.js → nim-kAH67IJv.js} +1 -1
  47. package/apps/web/dist/assets/{org-D9XGvcFV.js → org-DCuW6Ito.js} +1 -1
  48. package/apps/web/dist/assets/{perl-B7-K-xLH.js → perl-ChYkJruC.js} +1 -1
  49. package/apps/web/dist/assets/{php-CO9ZzQRp.js → php-Dy0o5CHL.js} +1 -1
  50. package/apps/web/dist/assets/{pug-BaAyPwTO.js → pug-C-vFGcyR.js} +1 -1
  51. package/apps/web/dist/assets/{qml-Cp3pyCa-.js → qml-Bbhsm3bz.js} +1 -1
  52. package/apps/web/dist/assets/{r-CT05_vfW.js → r-D6AOSU_n.js} +1 -1
  53. package/apps/web/dist/assets/{razor-D5rHsTSp.js → razor-CsDTm1QE.js} +1 -1
  54. package/apps/web/dist/assets/{regexp-D6kzd_X5.js → regexp-Cxw4Sy2X.js} +1 -1
  55. package/apps/web/dist/assets/{rst-AkFwrhnR.js → rst-BdEa7eTr.js} +1 -1
  56. package/apps/web/dist/assets/{ruby-LNJDVfMG.js → ruby-CrX6uYJq.js} +1 -1
  57. package/apps/web/dist/assets/{sas-C8o3xi__.js → sas-Dq1DiCgf.js} +1 -1
  58. package/apps/web/dist/assets/{scss-Ch7Tact0.js → scss-Cq-_Yezx.js} +1 -1
  59. package/apps/web/dist/assets/{shellscript-CN-vf6fZ.js → shellscript-N1TdW_Vo.js} +1 -1
  60. package/apps/web/dist/assets/{shellsession-CxId-awN.js → shellsession-DGy-5gMa.js} +1 -1
  61. package/apps/web/dist/assets/{soy-PXtFJtGw.js → soy-BZmv_HHk.js} +1 -1
  62. package/apps/web/dist/assets/{sql-B7js2_Lu.js → sql-B0TfXN6P.js} +1 -1
  63. package/apps/web/dist/assets/{stata-C0Zwsf36.js → stata-D0cL92SE.js} +1 -1
  64. package/apps/web/dist/assets/{surrealql-DawzxLLe.js → surrealql-B9RWrsWf.js} +1 -1
  65. package/apps/web/dist/assets/{svelte-CbCoXemF.js → svelte-Erfh9F_0.js} +1 -1
  66. package/apps/web/dist/assets/{templ-CQyn0W4C.js → templ-C1hdk1C3.js} +1 -1
  67. package/apps/web/dist/assets/{tex-FeZKQwyK.js → tex-B6y5Z0Oe.js} +1 -1
  68. package/apps/web/dist/assets/{ts-tags-KsJvoinT.js → ts-tags-B8Q3bBJx.js} +1 -1
  69. package/apps/web/dist/assets/{tsx-Cw6pGPeZ.js → tsx-CA2zlxVX.js} +1 -1
  70. package/apps/web/dist/assets/{twig-Cj9MLPms.js → twig-xr1-p8qn.js} +1 -1
  71. package/apps/web/dist/assets/{typescript-DwZR66Da.js → typescript-Bdd7ljtG.js} +1 -1
  72. package/apps/web/dist/assets/{typst--K-bHYFW.js → typst-BGU6c2s1.js} +1 -1
  73. package/apps/web/dist/assets/{vue-BrB0TrD_.js → vue-CxnbGcMK.js} +1 -1
  74. package/apps/web/dist/assets/{vue-html-BgNSGBvl.js → vue-html-D3pkBH4b.js} +1 -1
  75. package/apps/web/dist/assets/{vue-vine-C2qLo1pd.js → vue-vine-0adNns8e.js} +1 -1
  76. package/apps/web/dist/assets/{xml-DzdlZG_g.js → xml-Bf5yulh9.js} +1 -1
  77. package/apps/web/dist/assets/{xsl-D3HxAJEY.js → xsl-DnGCH2C6.js} +1 -1
  78. package/apps/web/dist/assets/{yaml-SX7TQG-a.js → yaml-ALFPjwWA.js} +1 -1
  79. package/apps/web/dist/index.html +1 -1
  80. package/apps/web/dist/sw.js +1 -1
  81. package/package.json +1 -1
@@ -788,58 +788,31 @@ const modelSetting = z.strictObject({
788
788
  hidden: z.boolean(),
789
789
  effort: z.string().nullable()
790
790
  });
791
+ const posixDir = z.string().refine((value) => path.posix.isAbsolute(value), "must be an absolute path").nullable().default(null);
792
+ const platformDirs = z.strictObject({
793
+ macos: posixDir,
794
+ linux: posixDir,
795
+ windows: z.string().refine((value) => path.win32.isAbsolute(value), "must be an absolute path").nullable().default(null)
796
+ }).prefault({});
797
+ function accountSchema(provider) {
798
+ return z.strictObject({
799
+ id: z.string(),
800
+ provider: z.literal(provider),
801
+ name: z.string(),
802
+ configDir: platformDirs,
803
+ enabled: z.boolean().default(true),
804
+ hiddenModels: z.record(z.string(), z.boolean()).default({})
805
+ });
806
+ }
791
807
  const configSchema = z.strictObject({
792
- claudeBaseDir: z.string().refine((value) => path.isAbsolute(value), "must be an absolute path").default(path.join(os.homedir(), ".claude")),
808
+ claudeBaseDir: platformDirs,
809
+ claudeAccounts: z.array(accountSchema("claude")).default([]),
810
+ codexAccounts: z.array(accountSchema("codex")).default([]),
793
811
  enabledProviders: z.strictObject({
794
812
  claude: z.boolean().default(true),
795
813
  codex: z.boolean().default(true),
796
814
  opencode: z.boolean().default(true)
797
815
  }).prefault({}),
798
- composer: z.strictObject({
799
- provider: z.enum([
800
- "claude",
801
- "codex",
802
- "opencode"
803
- ]).default("claude"),
804
- claude: z.strictObject({
805
- accountId: z.string().nullable().default(null),
806
- model: z.string().nullable().default(null),
807
- effort: z.enum([
808
- "low",
809
- "medium",
810
- "high",
811
- "xhigh",
812
- "max"
813
- ]).nullable().default(null),
814
- mode: z.enum([
815
- "default",
816
- "acceptEdits",
817
- "bypassPermissions",
818
- "plan",
819
- "dontAsk",
820
- "auto"
821
- ]).nullable().default("bypassPermissions"),
822
- plan: z.boolean().default(false)
823
- }).prefault({}),
824
- codex: z.strictObject({
825
- accountId: z.string().nullable().default(null),
826
- model: z.string().nullable().default(null),
827
- effort: z.string().nullable().default(null),
828
- mode: z.enum([
829
- "read-only",
830
- "auto",
831
- "full-access"
832
- ]).nullable().default("auto"),
833
- plan: z.boolean().default(false)
834
- }).prefault({}),
835
- opencode: z.strictObject({
836
- accountId: z.null().default(null),
837
- model: z.string().nullable().default(null),
838
- effort: z.string().nullable().default(null),
839
- mode: z.string().nullable().default(null),
840
- plan: z.boolean().default(false)
841
- }).prefault({})
842
- }).prefault({}),
843
816
  commitMessage: z.strictObject({
844
817
  provider: z.enum([
845
818
  "claude",
@@ -876,13 +849,16 @@ const configSchema = z.strictObject({
876
849
  }).prefault({})
877
850
  }).prefault({})
878
851
  });
879
- const defaults = configSchema.parse({});
852
+ const defaults$1 = configSchema.parse({});
880
853
  function platform() {
881
854
  if (process.platform === "darwin") return "macos";
882
855
  if (process.platform === "linux") return "linux";
883
856
  if (process.platform === "win32") return "windows";
884
857
  throw new Error(`unsupported platform ${process.platform}`);
885
858
  }
859
+ function claudeBaseDir() {
860
+ return readConfig().claudeBaseDir[platform()] ?? path.join(os.homedir(), ".claude");
861
+ }
886
862
  function defaultShell() {
887
863
  if (process.platform === "win32") return process.env.COMSPEC ?? "cmd.exe";
888
864
  return os.userInfo().shell ?? "/bin/sh";
@@ -890,9 +866,10 @@ function defaultShell() {
890
866
  function configInfo() {
891
867
  return {
892
868
  config: readConfig(),
893
- defaults,
869
+ defaults: defaults$1,
894
870
  platform: platform(),
895
- defaultShell: defaultShell()
871
+ defaultShell: defaultShell(),
872
+ defaultClaudeBaseDir: path.join(os.homedir(), ".claude")
896
873
  };
897
874
  }
898
875
  function readConfig() {
@@ -901,13 +878,13 @@ function readConfig() {
901
878
  user = readJson("config.json");
902
879
  } catch (error) {
903
880
  console.warn(`invalid ${configFile}, using the default config: ${error}`);
904
- return structuredClone(defaults);
881
+ return structuredClone(defaults$1);
905
882
  }
906
- if (user === null) return structuredClone(defaults);
883
+ if (user === null) return structuredClone(defaults$1);
907
884
  const result = configSchema.safeParse(user);
908
885
  if (!result.success) {
909
886
  console.warn(`invalid ${configFile}, using the default config:\n${z.prettifyError(result.error)}`);
910
- return structuredClone(defaults);
887
+ return structuredClone(defaults$1);
911
888
  }
912
889
  return result.data;
913
890
  }
@@ -915,7 +892,7 @@ function saveConfig(value) {
915
892
  const result = configSchema.safeParse(value);
916
893
  if (!result.success) throw new Error(z.prettifyError(result.error));
917
894
  writeJson("config.json", result.data);
918
- process.env.CLAUDE_CONFIG_DIR = result.data.claudeBaseDir;
895
+ process.env.CLAUDE_CONFIG_DIR = claudeBaseDir();
919
896
  broadcast({
920
897
  type: "config",
921
898
  config: result.data
@@ -2723,7 +2700,7 @@ async function find(provider, paths) {
2723
2700
  }
2724
2701
  function watchSessions() {
2725
2702
  for (const watcher of watchers) watcher.close();
2726
- watchers = [["claude", path.join(readConfig().claudeBaseDir, "projects")], ["codex", path.join(codexBaseDir, "sessions")]].flatMap(([provider, dir]) => {
2703
+ watchers = [["claude", path.join(claudeBaseDir(), "projects")], ["codex", path.join(codexBaseDir, "sessions")]].flatMap(([provider, dir]) => {
2727
2704
  if (!readConfig().enabledProviders[provider]) return [];
2728
2705
  try {
2729
2706
  const watcher = watch(dir, { recursive: true }, () => refreshSessions(provider));
@@ -2919,14 +2896,15 @@ function providerName(provider) {
2919
2896
  return providerNames[provider];
2920
2897
  }
2921
2898
  function storedAccounts() {
2922
- return (readJson("accounts.json") ?? []).map((item) => ({
2923
- id: item.id,
2924
- provider: item.provider,
2925
- name: item.name,
2926
- configDir: item.configDir,
2927
- enabled: item.enabled ?? true,
2928
- hiddenModels: item.hiddenModels ?? {}
2929
- }));
2899
+ const config = readConfig();
2900
+ return [...config.claudeAccounts, ...config.codexAccounts].flatMap((item) => {
2901
+ const configDir = item.configDir[platform()];
2902
+ if (configDir === null) return [];
2903
+ return [{
2904
+ ...item,
2905
+ configDir
2906
+ }];
2907
+ });
2930
2908
  }
2931
2909
  function assertEnabled(provider, accountId) {
2932
2910
  if (!readConfig().enabledProviders[provider]) throw new Error(`${providerName(provider)} is disabled in Settings`);
@@ -3025,29 +3003,50 @@ function providerCapabilities(provider, accountId, cwd) {
3025
3003
  }
3026
3004
  }
3027
3005
  function addAccount(provider, name, configDir) {
3028
- saveAccounts([...storedAccounts(), {
3029
- id: randomUUID(),
3030
- provider,
3031
- ...validAccount(name, configDir),
3032
- enabled: true,
3033
- hiddenModels: {}
3034
- }]);
3006
+ const account = validAccount(name, configDir);
3007
+ const config = readConfig();
3008
+ const key = `${provider}Accounts`;
3009
+ saveConfig({
3010
+ ...config,
3011
+ [key]: [...config[key], {
3012
+ id: randomUUID(),
3013
+ provider,
3014
+ name: account.name,
3015
+ configDir: { [platform()]: account.configDir },
3016
+ enabled: true,
3017
+ hiddenModels: {}
3018
+ }]
3019
+ });
3035
3020
  }
3036
3021
  async function updateAccount(update) {
3037
3022
  const before = storedAccounts().find((item) => item.id === update.id);
3038
3023
  if (before === void 0) throw new Error("That account was removed");
3039
3024
  const account = validAccount(update.name, update.configDir);
3040
- saveAccounts(storedAccounts().map((item) => item.id === update.id ? {
3041
- ...item,
3042
- ...account,
3043
- enabled: update.enabled,
3044
- hiddenModels: update.hiddenModels
3045
- } : item));
3025
+ const config = readConfig();
3026
+ const key = `${before.provider}Accounts`;
3027
+ saveConfig({
3028
+ ...config,
3029
+ [key]: config[key].map((item) => item.id === update.id ? {
3030
+ ...item,
3031
+ name: account.name,
3032
+ configDir: {
3033
+ ...item.configDir,
3034
+ [platform()]: account.configDir
3035
+ },
3036
+ enabled: update.enabled,
3037
+ hiddenModels: update.hiddenModels
3038
+ } : item)
3039
+ });
3046
3040
  forgetClaude(update.id);
3047
3041
  if (before.enabled && !update.enabled) await stopAccount(before);
3048
3042
  }
3049
3043
  function removeAccount(id) {
3050
- saveAccounts(storedAccounts().filter((item) => item.id !== id));
3044
+ const config = readConfig();
3045
+ saveConfig({
3046
+ ...config,
3047
+ claudeAccounts: config.claudeAccounts.filter((item) => item.id !== id),
3048
+ codexAccounts: config.codexAccounts.filter((item) => item.id !== id)
3049
+ });
3051
3050
  forgetClaude(id);
3052
3051
  }
3053
3052
  function validAccount(name, configDir) {
@@ -3063,9 +3062,6 @@ function validAccount(name, configDir) {
3063
3062
  };
3064
3063
  throw new Error("Use an absolute config directory or one starting with ~/");
3065
3064
  }
3066
- function saveAccounts(items) {
3067
- writeJson("accounts.json", items);
3068
- }
3069
3065
  //#endregion
3070
3066
  //#region src/lib/claude/claude.ts
3071
3067
  const efforts = [
@@ -3239,7 +3235,7 @@ async function recordUsage(accountId, probe) {
3239
3235
  }
3240
3236
  }
3241
3237
  function isLinked(configDir) {
3242
- const base = readConfig().claudeBaseDir;
3238
+ const base = claudeBaseDir();
3243
3239
  try {
3244
3240
  if (realpathSync(configDir) === realpathSync(base)) return true;
3245
3241
  return realpathSync(path.join(configDir, "projects")) === realpathSync(path.join(base, "projects"));
@@ -3695,7 +3691,7 @@ function text$1(value) {
3695
3691
  //#endregion
3696
3692
  //#region src/lib/claude/history.ts
3697
3693
  async function sessionFile(sessionId) {
3698
- const projectsDir = path.join(readConfig().claudeBaseDir, "projects");
3694
+ const projectsDir = path.join(claudeBaseDir(), "projects");
3699
3695
  for (const dir of await readdir(projectsDir)) {
3700
3696
  const file = path.join(projectsDir, dir, `${sessionId}.jsonl`);
3701
3697
  try {
@@ -5624,6 +5620,81 @@ function send(connection, event) {
5624
5620
  });
5625
5621
  }
5626
5622
  //#endregion
5623
+ //#region src/storage/state.ts
5624
+ const stateFile = path.join(home, "state.json");
5625
+ const stateSchema = z.strictObject({ composer: z.strictObject({
5626
+ provider: z.enum([
5627
+ "claude",
5628
+ "codex",
5629
+ "opencode"
5630
+ ]).default("claude"),
5631
+ claude: z.strictObject({
5632
+ accountId: z.string().nullable().default(null),
5633
+ model: z.string().nullable().default(null),
5634
+ effort: z.enum([
5635
+ "low",
5636
+ "medium",
5637
+ "high",
5638
+ "xhigh",
5639
+ "max"
5640
+ ]).nullable().default(null),
5641
+ mode: z.enum([
5642
+ "default",
5643
+ "acceptEdits",
5644
+ "bypassPermissions",
5645
+ "plan",
5646
+ "dontAsk",
5647
+ "auto"
5648
+ ]).nullable().default("bypassPermissions"),
5649
+ plan: z.boolean().default(false)
5650
+ }).prefault({}),
5651
+ codex: z.strictObject({
5652
+ accountId: z.string().nullable().default(null),
5653
+ model: z.string().nullable().default(null),
5654
+ effort: z.string().nullable().default(null),
5655
+ mode: z.enum([
5656
+ "read-only",
5657
+ "auto",
5658
+ "full-access"
5659
+ ]).nullable().default("auto"),
5660
+ plan: z.boolean().default(false)
5661
+ }).prefault({}),
5662
+ opencode: z.strictObject({
5663
+ accountId: z.null().default(null),
5664
+ model: z.string().nullable().default(null),
5665
+ effort: z.string().nullable().default(null),
5666
+ mode: z.string().nullable().default(null),
5667
+ plan: z.boolean().default(false)
5668
+ }).prefault({})
5669
+ }).prefault({}) });
5670
+ const defaults = stateSchema.parse({});
5671
+ function readComposer() {
5672
+ let user;
5673
+ try {
5674
+ user = readJson("state.json");
5675
+ } catch (error) {
5676
+ console.warn(`invalid ${stateFile}, using the default state: ${error}`);
5677
+ return structuredClone(defaults.composer);
5678
+ }
5679
+ if (user === null) return structuredClone(defaults.composer);
5680
+ const result = stateSchema.safeParse(user);
5681
+ if (!result.success) {
5682
+ console.warn(`invalid ${stateFile}, using the default state:\n${z.prettifyError(result.error)}`);
5683
+ return structuredClone(defaults.composer);
5684
+ }
5685
+ return result.data.composer;
5686
+ }
5687
+ function saveComposer(value) {
5688
+ const result = stateSchema.safeParse({ composer: value });
5689
+ if (!result.success) throw new Error(z.prettifyError(result.error));
5690
+ writeJson("state.json", result.data);
5691
+ broadcast({
5692
+ type: "composer",
5693
+ composer: result.data.composer
5694
+ });
5695
+ return result.data.composer;
5696
+ }
5697
+ //#endregion
5627
5698
  //#region src/api/socket.ts
5628
5699
  const handlers = {
5629
5700
  ping: () => null,
@@ -5631,6 +5702,7 @@ const handlers = {
5631
5702
  refreshAll();
5632
5703
  return {
5633
5704
  ...configInfo(),
5705
+ composer: readComposer(),
5634
5706
  hostname: os.hostname(),
5635
5707
  projects: projects$1(),
5636
5708
  sessions: sessions(),
@@ -5639,6 +5711,8 @@ const handlers = {
5639
5711
  };
5640
5712
  },
5641
5713
  "config.get": () => configInfo(),
5714
+ "composer.get": () => readComposer(),
5715
+ "composer.save": (params) => saveComposer(params),
5642
5716
  "config.save": async (params) => {
5643
5717
  const before = readConfig();
5644
5718
  const saved = saveConfig(params);
@@ -5647,7 +5721,7 @@ const handlers = {
5647
5721
  "codex",
5648
5722
  "opencode"
5649
5723
  ]) if (before.enabledProviders[provider] && !saved.enabledProviders[provider]) await stopProvider(provider);
5650
- if (saved.claudeBaseDir === before.claudeBaseDir && JSON.stringify(saved.enabledProviders) === JSON.stringify(before.enabledProviders)) return saved;
5724
+ if (JSON.stringify(saved.claudeBaseDir) === JSON.stringify(before.claudeBaseDir) && JSON.stringify(saved.enabledProviders) === JSON.stringify(before.enabledProviders)) return saved;
5651
5725
  watchSessions();
5652
5726
  refreshAll();
5653
5727
  publishAccounts();
@@ -5907,7 +5981,7 @@ if (args.command === "unpair") {
5907
5981
  process.exit(0);
5908
5982
  }
5909
5983
  lockHome();
5910
- process.env.CLAUDE_CONFIG_DIR = readConfig().claudeBaseDir;
5984
+ process.env.CLAUDE_CONFIG_DIR = claudeBaseDir();
5911
5985
  watchSessions();
5912
5986
  refreshAll();
5913
5987
  if (findClaude() === null) {