@openacp/cli 2026.403.1 → 2026.403.3

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/dist/cli.js CHANGED
@@ -6925,22 +6925,22 @@ __export(config_registry_exports, {
6925
6925
  });
6926
6926
  import * as fs18 from "fs";
6927
6927
  import * as path22 from "path";
6928
- function getFieldDef(path68) {
6929
- return CONFIG_REGISTRY.find((f) => f.path === path68);
6928
+ function getFieldDef(path69) {
6929
+ return CONFIG_REGISTRY.find((f) => f.path === path69);
6930
6930
  }
6931
6931
  function getSafeFields() {
6932
6932
  return CONFIG_REGISTRY.filter((f) => f.scope === "safe");
6933
6933
  }
6934
- function isHotReloadable(path68) {
6935
- const def = getFieldDef(path68);
6934
+ function isHotReloadable(path69) {
6935
+ const def = getFieldDef(path69);
6936
6936
  return def?.hotReload ?? false;
6937
6937
  }
6938
6938
  function resolveOptions(def, config) {
6939
6939
  if (!def.options) return void 0;
6940
6940
  return typeof def.options === "function" ? def.options(config) : def.options;
6941
6941
  }
6942
- function getConfigValue(config, path68) {
6943
- const parts = path68.split(".");
6942
+ function getConfigValue(config, path69) {
6943
+ const parts = path69.split(".");
6944
6944
  let current = config;
6945
6945
  for (const part of parts) {
6946
6946
  if (current && typeof current === "object" && part in current) {
@@ -10666,8 +10666,8 @@ function formatToolSummary(name, rawInput, displaySummary) {
10666
10666
  }
10667
10667
  if (lowerName === "grep") {
10668
10668
  const pattern = args2.pattern ?? "";
10669
- const path68 = args2.path ?? "";
10670
- return pattern ? `\u{1F50D} Grep "${pattern}"${path68 ? ` in ${path68}` : ""}` : `\u{1F527} ${name}`;
10669
+ const path69 = args2.path ?? "";
10670
+ return pattern ? `\u{1F50D} Grep "${pattern}"${path69 ? ` in ${path69}` : ""}` : `\u{1F527} ${name}`;
10671
10671
  }
10672
10672
  if (lowerName === "glob") {
10673
10673
  const pattern = args2.pattern ?? "";
@@ -10703,8 +10703,8 @@ function formatToolTitle(name, rawInput, displayTitle) {
10703
10703
  }
10704
10704
  if (lowerName === "grep") {
10705
10705
  const pattern = args2.pattern ?? "";
10706
- const path68 = args2.path ?? "";
10707
- return pattern ? `"${pattern}"${path68 ? ` in ${path68}` : ""}` : name;
10706
+ const path69 = args2.path ?? "";
10707
+ return pattern ? `"${pattern}"${path69 ? ` in ${path69}` : ""}` : name;
10708
10708
  }
10709
10709
  if (lowerName === "glob") {
10710
10710
  return String(args2.pattern ?? name);
@@ -12847,7 +12847,115 @@ var init_agents3 = __esm({
12847
12847
  }
12848
12848
  });
12849
12849
 
12850
+ // src/core/plugin/settings-manager.ts
12851
+ var settings_manager_exports = {};
12852
+ __export(settings_manager_exports, {
12853
+ SettingsManager: () => SettingsManager
12854
+ });
12855
+ import fs26 from "fs";
12856
+ import path30 from "path";
12857
+ var SettingsManager, SettingsAPIImpl;
12858
+ var init_settings_manager = __esm({
12859
+ "src/core/plugin/settings-manager.ts"() {
12860
+ "use strict";
12861
+ SettingsManager = class {
12862
+ constructor(basePath) {
12863
+ this.basePath = basePath;
12864
+ }
12865
+ getBasePath() {
12866
+ return this.basePath;
12867
+ }
12868
+ createAPI(pluginName) {
12869
+ const settingsPath = this.getSettingsPath(pluginName);
12870
+ return new SettingsAPIImpl(settingsPath);
12871
+ }
12872
+ async loadSettings(pluginName) {
12873
+ const settingsPath = this.getSettingsPath(pluginName);
12874
+ try {
12875
+ const content = fs26.readFileSync(settingsPath, "utf-8");
12876
+ return JSON.parse(content);
12877
+ } catch {
12878
+ return {};
12879
+ }
12880
+ }
12881
+ validateSettings(_pluginName, settings, schema) {
12882
+ if (!schema) return { valid: true };
12883
+ const result = schema.safeParse(settings);
12884
+ if (result.success) return { valid: true };
12885
+ return {
12886
+ valid: false,
12887
+ errors: result.error.errors.map(
12888
+ (e) => `${e.path.join(".")}: ${e.message}`
12889
+ )
12890
+ };
12891
+ }
12892
+ getSettingsPath(pluginName) {
12893
+ return path30.join(this.basePath, pluginName, "settings.json");
12894
+ }
12895
+ async getPluginSettings(pluginName) {
12896
+ return this.loadSettings(pluginName);
12897
+ }
12898
+ async updatePluginSettings(pluginName, updates) {
12899
+ const api = this.createAPI(pluginName);
12900
+ const current = await api.getAll();
12901
+ await api.setAll({ ...current, ...updates });
12902
+ }
12903
+ };
12904
+ SettingsAPIImpl = class {
12905
+ constructor(settingsPath) {
12906
+ this.settingsPath = settingsPath;
12907
+ }
12908
+ cache = null;
12909
+ readFile() {
12910
+ if (this.cache !== null) return this.cache;
12911
+ try {
12912
+ const content = fs26.readFileSync(this.settingsPath, "utf-8");
12913
+ this.cache = JSON.parse(content);
12914
+ return this.cache;
12915
+ } catch {
12916
+ this.cache = {};
12917
+ return this.cache;
12918
+ }
12919
+ }
12920
+ writeFile(data) {
12921
+ const dir = path30.dirname(this.settingsPath);
12922
+ fs26.mkdirSync(dir, { recursive: true });
12923
+ fs26.writeFileSync(this.settingsPath, JSON.stringify(data, null, 2));
12924
+ this.cache = data;
12925
+ }
12926
+ async get(key) {
12927
+ const data = this.readFile();
12928
+ return data[key];
12929
+ }
12930
+ async set(key, value) {
12931
+ const data = this.readFile();
12932
+ data[key] = value;
12933
+ this.writeFile(data);
12934
+ }
12935
+ async getAll() {
12936
+ return { ...this.readFile() };
12937
+ }
12938
+ async setAll(settings) {
12939
+ this.writeFile({ ...settings });
12940
+ }
12941
+ async delete(key) {
12942
+ const data = this.readFile();
12943
+ delete data[key];
12944
+ this.writeFile(data);
12945
+ }
12946
+ async clear() {
12947
+ this.writeFile({});
12948
+ }
12949
+ async has(key) {
12950
+ const data = this.readFile();
12951
+ return key in data;
12952
+ }
12953
+ };
12954
+ }
12955
+ });
12956
+
12850
12957
  // src/core/doctor/checks/telegram.ts
12958
+ import * as path31 from "path";
12851
12959
  var BOT_TOKEN_REGEX, telegramCheck;
12852
12960
  var init_telegram = __esm({
12853
12961
  "src/core/doctor/checks/telegram.ts"() {
@@ -12862,13 +12970,16 @@ var init_telegram = __esm({
12862
12970
  results.push({ status: "fail", message: "Cannot check Telegram \u2014 config not loaded" });
12863
12971
  return results;
12864
12972
  }
12865
- const tgConfig = ctx.config.channels.telegram;
12866
- if (!tgConfig || !tgConfig.enabled) {
12867
- results.push({ status: "pass", message: "Telegram not enabled (skipped)" });
12973
+ const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
12974
+ const sm = new SettingsManager2(path31.join(ctx.pluginsDir, "data"));
12975
+ const ps = await sm.loadSettings("@openacp/telegram");
12976
+ const legacyCh = ctx.config.channels.telegram;
12977
+ const botToken = ps.botToken ?? legacyCh?.botToken;
12978
+ const chatId = ps.chatId ?? legacyCh?.chatId;
12979
+ if (!botToken && !chatId) {
12980
+ results.push({ status: "pass", message: "Telegram not configured (skipped)" });
12868
12981
  return results;
12869
12982
  }
12870
- const botToken = tgConfig.botToken;
12871
- const chatId = tgConfig.chatId;
12872
12983
  if (!botToken || !BOT_TOKEN_REGEX.test(botToken)) {
12873
12984
  results.push({ status: "fail", message: "Bot token format invalid" });
12874
12985
  return results;
@@ -12944,7 +13055,7 @@ var init_telegram = __esm({
12944
13055
  });
12945
13056
 
12946
13057
  // src/core/doctor/checks/storage.ts
12947
- import * as fs26 from "fs";
13058
+ import * as fs27 from "fs";
12948
13059
  var storageCheck;
12949
13060
  var init_storage = __esm({
12950
13061
  "src/core/doctor/checks/storage.ts"() {
@@ -12954,28 +13065,28 @@ var init_storage = __esm({
12954
13065
  order: 4,
12955
13066
  async run(ctx) {
12956
13067
  const results = [];
12957
- if (!fs26.existsSync(ctx.dataDir)) {
13068
+ if (!fs27.existsSync(ctx.dataDir)) {
12958
13069
  results.push({
12959
13070
  status: "fail",
12960
13071
  message: "Data directory ~/.openacp does not exist",
12961
13072
  fixable: true,
12962
13073
  fixRisk: "safe",
12963
13074
  fix: async () => {
12964
- fs26.mkdirSync(ctx.dataDir, { recursive: true });
13075
+ fs27.mkdirSync(ctx.dataDir, { recursive: true });
12965
13076
  return { success: true, message: "created directory" };
12966
13077
  }
12967
13078
  });
12968
13079
  } else {
12969
13080
  try {
12970
- fs26.accessSync(ctx.dataDir, fs26.constants.W_OK);
13081
+ fs27.accessSync(ctx.dataDir, fs27.constants.W_OK);
12971
13082
  results.push({ status: "pass", message: "Data directory exists and writable" });
12972
13083
  } catch {
12973
13084
  results.push({ status: "fail", message: "Data directory not writable" });
12974
13085
  }
12975
13086
  }
12976
- if (fs26.existsSync(ctx.sessionsPath)) {
13087
+ if (fs27.existsSync(ctx.sessionsPath)) {
12977
13088
  try {
12978
- const content = fs26.readFileSync(ctx.sessionsPath, "utf-8");
13089
+ const content = fs27.readFileSync(ctx.sessionsPath, "utf-8");
12979
13090
  const data = JSON.parse(content);
12980
13091
  if (typeof data === "object" && data !== null && "sessions" in data) {
12981
13092
  results.push({ status: "pass", message: "Sessions file valid" });
@@ -12986,7 +13097,7 @@ var init_storage = __esm({
12986
13097
  fixable: true,
12987
13098
  fixRisk: "risky",
12988
13099
  fix: async () => {
12989
- fs26.writeFileSync(ctx.sessionsPath, JSON.stringify({ version: 1, sessions: {} }, null, 2));
13100
+ fs27.writeFileSync(ctx.sessionsPath, JSON.stringify({ version: 1, sessions: {} }, null, 2));
12990
13101
  return { success: true, message: "reset sessions file" };
12991
13102
  }
12992
13103
  });
@@ -12998,7 +13109,7 @@ var init_storage = __esm({
12998
13109
  fixable: true,
12999
13110
  fixRisk: "risky",
13000
13111
  fix: async () => {
13001
- fs26.writeFileSync(ctx.sessionsPath, JSON.stringify({ version: 1, sessions: {} }, null, 2));
13112
+ fs27.writeFileSync(ctx.sessionsPath, JSON.stringify({ version: 1, sessions: {} }, null, 2));
13002
13113
  return { success: true, message: "reset sessions file" };
13003
13114
  }
13004
13115
  });
@@ -13006,20 +13117,20 @@ var init_storage = __esm({
13006
13117
  } else {
13007
13118
  results.push({ status: "pass", message: "Sessions file not present yet (created on first session)" });
13008
13119
  }
13009
- if (!fs26.existsSync(ctx.logsDir)) {
13120
+ if (!fs27.existsSync(ctx.logsDir)) {
13010
13121
  results.push({
13011
13122
  status: "warn",
13012
13123
  message: "Log directory does not exist",
13013
13124
  fixable: true,
13014
13125
  fixRisk: "safe",
13015
13126
  fix: async () => {
13016
- fs26.mkdirSync(ctx.logsDir, { recursive: true });
13127
+ fs27.mkdirSync(ctx.logsDir, { recursive: true });
13017
13128
  return { success: true, message: "created log directory" };
13018
13129
  }
13019
13130
  });
13020
13131
  } else {
13021
13132
  try {
13022
- fs26.accessSync(ctx.logsDir, fs26.constants.W_OK);
13133
+ fs27.accessSync(ctx.logsDir, fs27.constants.W_OK);
13023
13134
  results.push({ status: "pass", message: "Log directory exists and writable" });
13024
13135
  } catch {
13025
13136
  results.push({ status: "fail", message: "Log directory not writable" });
@@ -13032,7 +13143,7 @@ var init_storage = __esm({
13032
13143
  });
13033
13144
 
13034
13145
  // src/core/doctor/checks/workspace.ts
13035
- import * as fs27 from "fs";
13146
+ import * as fs28 from "fs";
13036
13147
  var workspaceCheck;
13037
13148
  var init_workspace2 = __esm({
13038
13149
  "src/core/doctor/checks/workspace.ts"() {
@@ -13048,20 +13159,20 @@ var init_workspace2 = __esm({
13048
13159
  return results;
13049
13160
  }
13050
13161
  const baseDir = expandHome3(ctx.config.workspace.baseDir);
13051
- if (!fs27.existsSync(baseDir)) {
13162
+ if (!fs28.existsSync(baseDir)) {
13052
13163
  results.push({
13053
13164
  status: "warn",
13054
13165
  message: `Workspace directory does not exist: ${baseDir}`,
13055
13166
  fixable: true,
13056
13167
  fixRisk: "safe",
13057
13168
  fix: async () => {
13058
- fs27.mkdirSync(baseDir, { recursive: true });
13169
+ fs28.mkdirSync(baseDir, { recursive: true });
13059
13170
  return { success: true, message: "created directory" };
13060
13171
  }
13061
13172
  });
13062
13173
  } else {
13063
13174
  try {
13064
- fs27.accessSync(baseDir, fs27.constants.W_OK);
13175
+ fs28.accessSync(baseDir, fs28.constants.W_OK);
13065
13176
  results.push({ status: "pass", message: `Workspace directory exists: ${baseDir}` });
13066
13177
  } catch {
13067
13178
  results.push({ status: "fail", message: `Workspace directory not writable: ${baseDir}` });
@@ -13074,8 +13185,8 @@ var init_workspace2 = __esm({
13074
13185
  });
13075
13186
 
13076
13187
  // src/core/doctor/checks/plugins.ts
13077
- import * as fs28 from "fs";
13078
- import * as path30 from "path";
13188
+ import * as fs29 from "fs";
13189
+ import * as path32 from "path";
13079
13190
  var pluginsCheck;
13080
13191
  var init_plugins2 = __esm({
13081
13192
  "src/core/doctor/checks/plugins.ts"() {
@@ -13085,16 +13196,16 @@ var init_plugins2 = __esm({
13085
13196
  order: 6,
13086
13197
  async run(ctx) {
13087
13198
  const results = [];
13088
- if (!fs28.existsSync(ctx.pluginsDir)) {
13199
+ if (!fs29.existsSync(ctx.pluginsDir)) {
13089
13200
  results.push({
13090
13201
  status: "warn",
13091
13202
  message: "Plugins directory does not exist",
13092
13203
  fixable: true,
13093
13204
  fixRisk: "safe",
13094
13205
  fix: async () => {
13095
- fs28.mkdirSync(ctx.pluginsDir, { recursive: true });
13096
- fs28.writeFileSync(
13097
- path30.join(ctx.pluginsDir, "package.json"),
13206
+ fs29.mkdirSync(ctx.pluginsDir, { recursive: true });
13207
+ fs29.writeFileSync(
13208
+ path32.join(ctx.pluginsDir, "package.json"),
13098
13209
  JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2)
13099
13210
  );
13100
13211
  return { success: true, message: "initialized plugins directory" };
@@ -13103,15 +13214,15 @@ var init_plugins2 = __esm({
13103
13214
  return results;
13104
13215
  }
13105
13216
  results.push({ status: "pass", message: "Plugins directory exists" });
13106
- const pkgPath = path30.join(ctx.pluginsDir, "package.json");
13107
- if (!fs28.existsSync(pkgPath)) {
13217
+ const pkgPath = path32.join(ctx.pluginsDir, "package.json");
13218
+ if (!fs29.existsSync(pkgPath)) {
13108
13219
  results.push({
13109
13220
  status: "warn",
13110
13221
  message: "Plugins package.json missing",
13111
13222
  fixable: true,
13112
13223
  fixRisk: "safe",
13113
13224
  fix: async () => {
13114
- fs28.writeFileSync(
13225
+ fs29.writeFileSync(
13115
13226
  pkgPath,
13116
13227
  JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2)
13117
13228
  );
@@ -13121,7 +13232,7 @@ var init_plugins2 = __esm({
13121
13232
  return results;
13122
13233
  }
13123
13234
  try {
13124
- const pkg = JSON.parse(fs28.readFileSync(pkgPath, "utf-8"));
13235
+ const pkg = JSON.parse(fs29.readFileSync(pkgPath, "utf-8"));
13125
13236
  const deps = pkg.dependencies || {};
13126
13237
  const count = Object.keys(deps).length;
13127
13238
  results.push({ status: "pass", message: `Plugins package.json valid (${count} plugins)` });
@@ -13132,7 +13243,7 @@ var init_plugins2 = __esm({
13132
13243
  fixable: true,
13133
13244
  fixRisk: "risky",
13134
13245
  fix: async () => {
13135
- fs28.writeFileSync(
13246
+ fs29.writeFileSync(
13136
13247
  pkgPath,
13137
13248
  JSON.stringify({ name: "openacp-plugins", private: true, dependencies: {} }, null, 2)
13138
13249
  );
@@ -13147,7 +13258,7 @@ var init_plugins2 = __esm({
13147
13258
  });
13148
13259
 
13149
13260
  // src/core/doctor/checks/daemon.ts
13150
- import * as fs29 from "fs";
13261
+ import * as fs30 from "fs";
13151
13262
  import * as net from "net";
13152
13263
  function isProcessAlive(pid) {
13153
13264
  try {
@@ -13177,8 +13288,8 @@ var init_daemon = __esm({
13177
13288
  order: 7,
13178
13289
  async run(ctx) {
13179
13290
  const results = [];
13180
- if (fs29.existsSync(ctx.pidPath)) {
13181
- const content = fs29.readFileSync(ctx.pidPath, "utf-8").trim();
13291
+ if (fs30.existsSync(ctx.pidPath)) {
13292
+ const content = fs30.readFileSync(ctx.pidPath, "utf-8").trim();
13182
13293
  const pid = parseInt(content, 10);
13183
13294
  if (isNaN(pid)) {
13184
13295
  results.push({
@@ -13187,7 +13298,7 @@ var init_daemon = __esm({
13187
13298
  fixable: true,
13188
13299
  fixRisk: "safe",
13189
13300
  fix: async () => {
13190
- fs29.unlinkSync(ctx.pidPath);
13301
+ fs30.unlinkSync(ctx.pidPath);
13191
13302
  return { success: true, message: "removed invalid PID file" };
13192
13303
  }
13193
13304
  });
@@ -13198,7 +13309,7 @@ var init_daemon = __esm({
13198
13309
  fixable: true,
13199
13310
  fixRisk: "safe",
13200
13311
  fix: async () => {
13201
- fs29.unlinkSync(ctx.pidPath);
13312
+ fs30.unlinkSync(ctx.pidPath);
13202
13313
  return { success: true, message: "removed stale PID file" };
13203
13314
  }
13204
13315
  });
@@ -13206,8 +13317,8 @@ var init_daemon = __esm({
13206
13317
  results.push({ status: "pass", message: `Daemon running (PID ${pid})` });
13207
13318
  }
13208
13319
  }
13209
- if (fs29.existsSync(ctx.portFilePath)) {
13210
- const content = fs29.readFileSync(ctx.portFilePath, "utf-8").trim();
13320
+ if (fs30.existsSync(ctx.portFilePath)) {
13321
+ const content = fs30.readFileSync(ctx.portFilePath, "utf-8").trim();
13211
13322
  const port = parseInt(content, 10);
13212
13323
  if (isNaN(port)) {
13213
13324
  results.push({
@@ -13216,7 +13327,7 @@ var init_daemon = __esm({
13216
13327
  fixable: true,
13217
13328
  fixRisk: "safe",
13218
13329
  fix: async () => {
13219
- fs29.unlinkSync(ctx.portFilePath);
13330
+ fs30.unlinkSync(ctx.portFilePath);
13220
13331
  return { success: true, message: "removed invalid port file" };
13221
13332
  }
13222
13333
  });
@@ -13228,8 +13339,8 @@ var init_daemon = __esm({
13228
13339
  const apiPort = ctx.config.api.port;
13229
13340
  const inUse = await checkPortInUse(apiPort);
13230
13341
  if (inUse) {
13231
- if (fs29.existsSync(ctx.pidPath)) {
13232
- const pid = parseInt(fs29.readFileSync(ctx.pidPath, "utf-8").trim(), 10);
13342
+ if (fs30.existsSync(ctx.pidPath)) {
13343
+ const pid = parseInt(fs30.readFileSync(ctx.pidPath, "utf-8").trim(), 10);
13233
13344
  if (!isNaN(pid) && isProcessAlive(pid)) {
13234
13345
  results.push({ status: "pass", message: `API port ${apiPort} in use by OpenACP daemon` });
13235
13346
  } else {
@@ -13249,8 +13360,8 @@ var init_daemon = __esm({
13249
13360
  });
13250
13361
 
13251
13362
  // src/core/doctor/checks/tunnel.ts
13252
- import * as fs30 from "fs";
13253
- import * as path31 from "path";
13363
+ import * as fs31 from "fs";
13364
+ import * as path33 from "path";
13254
13365
  import * as os13 from "os";
13255
13366
  import { execFileSync as execFileSync4 } from "child_process";
13256
13367
  var tunnelCheck;
@@ -13274,9 +13385,9 @@ var init_tunnel3 = __esm({
13274
13385
  results.push({ status: "pass", message: `Tunnel provider: ${provider}` });
13275
13386
  if (provider === "cloudflare") {
13276
13387
  const binName = os13.platform() === "win32" ? "cloudflared.exe" : "cloudflared";
13277
- const binPath = path31.join(ctx.dataDir, "bin", binName);
13388
+ const binPath = path33.join(ctx.dataDir, "bin", binName);
13278
13389
  let found = false;
13279
- if (fs30.existsSync(binPath)) {
13390
+ if (fs31.existsSync(binPath)) {
13280
13391
  found = true;
13281
13392
  } else {
13282
13393
  try {
@@ -13322,8 +13433,8 @@ var doctor_exports = {};
13322
13433
  __export(doctor_exports, {
13323
13434
  DoctorEngine: () => DoctorEngine
13324
13435
  });
13325
- import * as fs31 from "fs";
13326
- import * as path32 from "path";
13436
+ import * as fs32 from "fs";
13437
+ import * as path34 from "path";
13327
13438
  var ALL_CHECKS, CHECK_TIMEOUT_MS, DoctorEngine;
13328
13439
  var init_doctor = __esm({
13329
13440
  "src/core/doctor/index.ts"() {
@@ -13405,27 +13516,27 @@ var init_doctor = __esm({
13405
13516
  }
13406
13517
  async buildContext() {
13407
13518
  const dataDir = this.dataDir;
13408
- const configPath = process.env.OPENACP_CONFIG_PATH || path32.join(dataDir, "config.json");
13519
+ const configPath = process.env.OPENACP_CONFIG_PATH || path34.join(dataDir, "config.json");
13409
13520
  let config = null;
13410
13521
  let rawConfig = null;
13411
13522
  try {
13412
- const content = fs31.readFileSync(configPath, "utf-8");
13523
+ const content = fs32.readFileSync(configPath, "utf-8");
13413
13524
  rawConfig = JSON.parse(content);
13414
13525
  const cm = new ConfigManager(configPath);
13415
13526
  await cm.load();
13416
13527
  config = cm.get();
13417
13528
  } catch {
13418
13529
  }
13419
- const logsDir = config ? expandHome3(config.logging.logDir) : path32.join(dataDir, "logs");
13530
+ const logsDir = config ? expandHome3(config.logging.logDir) : path34.join(dataDir, "logs");
13420
13531
  return {
13421
13532
  config,
13422
13533
  rawConfig,
13423
13534
  configPath,
13424
13535
  dataDir,
13425
- sessionsPath: path32.join(dataDir, "sessions.json"),
13426
- pidPath: path32.join(dataDir, "openacp.pid"),
13427
- portFilePath: path32.join(dataDir, "api.port"),
13428
- pluginsDir: path32.join(dataDir, "plugins"),
13536
+ sessionsPath: path34.join(dataDir, "sessions.json"),
13537
+ pidPath: path34.join(dataDir, "openacp.pid"),
13538
+ portFilePath: path34.join(dataDir, "api.port"),
13539
+ pluginsDir: path34.join(dataDir, "plugins"),
13429
13540
  logsDir
13430
13541
  };
13431
13542
  }
@@ -17162,113 +17273,6 @@ var init_core_plugins = __esm({
17162
17273
  }
17163
17274
  });
17164
17275
 
17165
- // src/core/plugin/settings-manager.ts
17166
- var settings_manager_exports = {};
17167
- __export(settings_manager_exports, {
17168
- SettingsManager: () => SettingsManager
17169
- });
17170
- import fs32 from "fs";
17171
- import path33 from "path";
17172
- var SettingsManager, SettingsAPIImpl;
17173
- var init_settings_manager = __esm({
17174
- "src/core/plugin/settings-manager.ts"() {
17175
- "use strict";
17176
- SettingsManager = class {
17177
- constructor(basePath) {
17178
- this.basePath = basePath;
17179
- }
17180
- getBasePath() {
17181
- return this.basePath;
17182
- }
17183
- createAPI(pluginName) {
17184
- const settingsPath = this.getSettingsPath(pluginName);
17185
- return new SettingsAPIImpl(settingsPath);
17186
- }
17187
- async loadSettings(pluginName) {
17188
- const settingsPath = this.getSettingsPath(pluginName);
17189
- try {
17190
- const content = fs32.readFileSync(settingsPath, "utf-8");
17191
- return JSON.parse(content);
17192
- } catch {
17193
- return {};
17194
- }
17195
- }
17196
- validateSettings(_pluginName, settings, schema) {
17197
- if (!schema) return { valid: true };
17198
- const result = schema.safeParse(settings);
17199
- if (result.success) return { valid: true };
17200
- return {
17201
- valid: false,
17202
- errors: result.error.errors.map(
17203
- (e) => `${e.path.join(".")}: ${e.message}`
17204
- )
17205
- };
17206
- }
17207
- getSettingsPath(pluginName) {
17208
- return path33.join(this.basePath, pluginName, "settings.json");
17209
- }
17210
- async getPluginSettings(pluginName) {
17211
- return this.loadSettings(pluginName);
17212
- }
17213
- async updatePluginSettings(pluginName, updates) {
17214
- const api = this.createAPI(pluginName);
17215
- const current = await api.getAll();
17216
- await api.setAll({ ...current, ...updates });
17217
- }
17218
- };
17219
- SettingsAPIImpl = class {
17220
- constructor(settingsPath) {
17221
- this.settingsPath = settingsPath;
17222
- }
17223
- cache = null;
17224
- readFile() {
17225
- if (this.cache !== null) return this.cache;
17226
- try {
17227
- const content = fs32.readFileSync(this.settingsPath, "utf-8");
17228
- this.cache = JSON.parse(content);
17229
- return this.cache;
17230
- } catch {
17231
- this.cache = {};
17232
- return this.cache;
17233
- }
17234
- }
17235
- writeFile(data) {
17236
- const dir = path33.dirname(this.settingsPath);
17237
- fs32.mkdirSync(dir, { recursive: true });
17238
- fs32.writeFileSync(this.settingsPath, JSON.stringify(data, null, 2));
17239
- this.cache = data;
17240
- }
17241
- async get(key) {
17242
- const data = this.readFile();
17243
- return data[key];
17244
- }
17245
- async set(key, value) {
17246
- const data = this.readFile();
17247
- data[key] = value;
17248
- this.writeFile(data);
17249
- }
17250
- async getAll() {
17251
- return { ...this.readFile() };
17252
- }
17253
- async setAll(settings) {
17254
- this.writeFile({ ...settings });
17255
- }
17256
- async delete(key) {
17257
- const data = this.readFile();
17258
- delete data[key];
17259
- this.writeFile(data);
17260
- }
17261
- async clear() {
17262
- this.writeFile({});
17263
- }
17264
- async has(key) {
17265
- const data = this.readFile();
17266
- return key in data;
17267
- }
17268
- };
17269
- }
17270
- });
17271
-
17272
17276
  // src/core/plugin/terminal-io.ts
17273
17277
  import * as clack from "@clack/prompts";
17274
17278
  function isCancel(value) {
@@ -17332,10 +17336,10 @@ var install_context_exports = {};
17332
17336
  __export(install_context_exports, {
17333
17337
  createInstallContext: () => createInstallContext
17334
17338
  });
17335
- import path34 from "path";
17339
+ import path35 from "path";
17336
17340
  function createInstallContext(opts) {
17337
17341
  const { pluginName, settingsManager, basePath, legacyConfig, instanceRoot } = opts;
17338
- const dataDir = path34.join(basePath, pluginName, "data");
17342
+ const dataDir = path35.join(basePath, pluginName, "data");
17339
17343
  return {
17340
17344
  pluginName,
17341
17345
  terminal: createTerminalIO(),
@@ -17363,13 +17367,13 @@ __export(api_client_exports, {
17363
17367
  removeStalePortFile: () => removeStalePortFile
17364
17368
  });
17365
17369
  import * as fs33 from "fs";
17366
- import * as path35 from "path";
17370
+ import * as path36 from "path";
17367
17371
  import * as os14 from "os";
17368
17372
  function defaultPortFile(root) {
17369
- return path35.join(root ?? DEFAULT_ROOT, "api.port");
17373
+ return path36.join(root ?? DEFAULT_ROOT, "api.port");
17370
17374
  }
17371
17375
  function defaultSecretFile(root) {
17372
- return path35.join(root ?? DEFAULT_ROOT, "api-secret");
17376
+ return path36.join(root ?? DEFAULT_ROOT, "api-secret");
17373
17377
  }
17374
17378
  function readApiPort(portFilePath, instanceRoot) {
17375
17379
  const filePath = portFilePath ?? defaultPortFile(instanceRoot);
@@ -17409,7 +17413,7 @@ var DEFAULT_ROOT;
17409
17413
  var init_api_client = __esm({
17410
17414
  "src/cli/api-client.ts"() {
17411
17415
  "use strict";
17412
- DEFAULT_ROOT = path35.join(os14.homedir(), ".openacp");
17416
+ DEFAULT_ROOT = path36.join(os14.homedir(), ".openacp");
17413
17417
  }
17414
17418
  });
17415
17419
 
@@ -17457,7 +17461,7 @@ var init_suggest = __esm({
17457
17461
 
17458
17462
  // src/cli/instance-hint.ts
17459
17463
  import fs34 from "fs";
17460
- import path36 from "path";
17464
+ import path37 from "path";
17461
17465
  import os15 from "os";
17462
17466
  function printInstanceHint(root) {
17463
17467
  const globalRoot = getGlobalRoot();
@@ -17466,7 +17470,7 @@ function printInstanceHint(root) {
17466
17470
  const label = isGlobal ? "global" : "local";
17467
17471
  console.log(` Workspace: ${label} \u2014 ${displayPath}`);
17468
17472
  if (isGlobal) {
17469
- const localRoot = path36.join(process.cwd(), ".openacp");
17473
+ const localRoot = path37.join(process.cwd(), ".openacp");
17470
17474
  if (fs34.existsSync(localRoot)) {
17471
17475
  console.log(` \x1B[2mhint: local workspace exists in current directory \u2014 use --local to use it\x1B[0m`);
17472
17476
  }
@@ -17498,22 +17502,22 @@ __export(daemon_exports, {
17498
17502
  });
17499
17503
  import { spawn as spawn6 } from "child_process";
17500
17504
  import * as fs35 from "fs";
17501
- import * as path37 from "path";
17505
+ import * as path38 from "path";
17502
17506
  import * as os16 from "os";
17503
17507
  function getPidPath(root) {
17504
17508
  const base = root ?? DEFAULT_ROOT2;
17505
- return path37.join(base, "openacp.pid");
17509
+ return path38.join(base, "openacp.pid");
17506
17510
  }
17507
17511
  function getLogDir(root) {
17508
17512
  const base = root ?? DEFAULT_ROOT2;
17509
- return path37.join(base, "logs");
17513
+ return path38.join(base, "logs");
17510
17514
  }
17511
17515
  function getRunningMarker(root) {
17512
17516
  const base = root ?? DEFAULT_ROOT2;
17513
- return path37.join(base, "running");
17517
+ return path38.join(base, "running");
17514
17518
  }
17515
17519
  function writePidFile(pidPath, pid) {
17516
- const dir = path37.dirname(pidPath);
17520
+ const dir = path38.dirname(pidPath);
17517
17521
  fs35.mkdirSync(dir, { recursive: true });
17518
17522
  fs35.writeFileSync(pidPath, String(pid));
17519
17523
  }
@@ -17562,8 +17566,8 @@ function startDaemon(pidPath = getPidPath(), logDir2, instanceRoot) {
17562
17566
  }
17563
17567
  const resolvedLogDir = logDir2 ? expandHome3(logDir2) : getLogDir(instanceRoot);
17564
17568
  fs35.mkdirSync(resolvedLogDir, { recursive: true });
17565
- const logFile = path37.join(resolvedLogDir, "openacp.log");
17566
- const cliPath = path37.resolve(process.argv[1]);
17569
+ const logFile = path38.join(resolvedLogDir, "openacp.log");
17570
+ const cliPath = path38.resolve(process.argv[1]);
17567
17571
  const nodePath = process.execPath;
17568
17572
  const out = fs35.openSync(logFile, "a");
17569
17573
  const err = fs35.openSync(logFile, "a");
@@ -17647,7 +17651,7 @@ async function stopDaemon(pidPath = getPidPath(), instanceRoot) {
17647
17651
  }
17648
17652
  function markRunning(root) {
17649
17653
  const marker = getRunningMarker(root);
17650
- fs35.mkdirSync(path37.dirname(marker), { recursive: true });
17654
+ fs35.mkdirSync(path38.dirname(marker), { recursive: true });
17651
17655
  fs35.writeFileSync(marker, "");
17652
17656
  }
17653
17657
  function clearRunning(root) {
@@ -17664,7 +17668,7 @@ var init_daemon2 = __esm({
17664
17668
  "src/cli/daemon.ts"() {
17665
17669
  "use strict";
17666
17670
  init_config2();
17667
- DEFAULT_ROOT2 = path37.join(os16.homedir(), ".openacp");
17671
+ DEFAULT_ROOT2 = path38.join(os16.homedir(), ".openacp");
17668
17672
  }
17669
17673
  });
17670
17674
 
@@ -17673,12 +17677,12 @@ var stop_exports = {};
17673
17677
  __export(stop_exports, {
17674
17678
  cmdStop: () => cmdStop
17675
17679
  });
17676
- import path39 from "path";
17680
+ import path40 from "path";
17677
17681
  import os18 from "os";
17678
17682
  async function cmdStop(args2 = [], instanceRoot) {
17679
17683
  const json = isJsonMode(args2);
17680
17684
  if (json) await muteForJson();
17681
- const root = instanceRoot ?? path39.join(os18.homedir(), ".openacp");
17685
+ const root = instanceRoot ?? path40.join(os18.homedir(), ".openacp");
17682
17686
  if (!json && wantsHelp(args2)) {
17683
17687
  console.log(`
17684
17688
  \x1B[1mopenacp stop\x1B[0m \u2014 Stop the background daemon
@@ -18020,7 +18024,7 @@ var init_mcp_manager = __esm({
18020
18024
 
18021
18025
  // src/core/utils/debug-tracer.ts
18022
18026
  import fs37 from "fs";
18023
- import path40 from "path";
18027
+ import path41 from "path";
18024
18028
  function createDebugTracer(sessionId, workingDirectory) {
18025
18029
  if (!DEBUG_ENABLED) return null;
18026
18030
  return new DebugTracer(sessionId, workingDirectory);
@@ -18034,7 +18038,7 @@ var init_debug_tracer = __esm({
18034
18038
  constructor(sessionId, workingDirectory) {
18035
18039
  this.sessionId = sessionId;
18036
18040
  this.workingDirectory = workingDirectory;
18037
- this.logDir = path40.join(workingDirectory, ".log");
18041
+ this.logDir = path41.join(workingDirectory, ".log");
18038
18042
  }
18039
18043
  dirCreated = false;
18040
18044
  logDir;
@@ -18044,7 +18048,7 @@ var init_debug_tracer = __esm({
18044
18048
  fs37.mkdirSync(this.logDir, { recursive: true });
18045
18049
  this.dirCreated = true;
18046
18050
  }
18047
- const filePath = path40.join(this.logDir, `${this.sessionId}_${layer}.jsonl`);
18051
+ const filePath = path41.join(this.logDir, `${this.sessionId}_${layer}.jsonl`);
18048
18052
  const seen = /* @__PURE__ */ new WeakSet();
18049
18053
  const line = JSON.stringify({ ts: Date.now(), ...data }, (_key, value) => {
18050
18054
  if (typeof value === "object" && value !== null) {
@@ -18068,16 +18072,16 @@ var init_debug_tracer = __esm({
18068
18072
  import { spawn as spawn8, execFileSync as execFileSync5 } from "child_process";
18069
18073
  import { Transform } from "stream";
18070
18074
  import fs38 from "fs";
18071
- import path41 from "path";
18075
+ import path42 from "path";
18072
18076
  import { ClientSideConnection, ndJsonStream } from "@agentclientprotocol/sdk";
18073
18077
  import { PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
18074
18078
  function findPackageRoot(startDir) {
18075
18079
  let dir = startDir;
18076
- while (dir !== path41.dirname(dir)) {
18077
- if (fs38.existsSync(path41.join(dir, "package.json"))) {
18080
+ while (dir !== path42.dirname(dir)) {
18081
+ if (fs38.existsSync(path42.join(dir, "package.json"))) {
18078
18082
  return dir;
18079
18083
  }
18080
- dir = path41.dirname(dir);
18084
+ dir = path42.dirname(dir);
18081
18085
  }
18082
18086
  return startDir;
18083
18087
  }
@@ -18089,8 +18093,8 @@ function resolveAgentCommand(cmd) {
18089
18093
  }
18090
18094
  for (const root of searchRoots) {
18091
18095
  const packageDirs = [
18092
- path41.resolve(root, "node_modules", "@zed-industries", cmd, "dist", "index.js"),
18093
- path41.resolve(root, "node_modules", cmd, "dist", "index.js")
18096
+ path42.resolve(root, "node_modules", "@zed-industries", cmd, "dist", "index.js"),
18097
+ path42.resolve(root, "node_modules", cmd, "dist", "index.js")
18094
18098
  ];
18095
18099
  for (const jsPath of packageDirs) {
18096
18100
  if (fs38.existsSync(jsPath)) {
@@ -18099,7 +18103,7 @@ function resolveAgentCommand(cmd) {
18099
18103
  }
18100
18104
  }
18101
18105
  for (const root of searchRoots) {
18102
- const localBin = path41.resolve(root, "node_modules", ".bin", cmd);
18106
+ const localBin = path42.resolve(root, "node_modules", ".bin", cmd);
18103
18107
  if (fs38.existsSync(localBin)) {
18104
18108
  const content = fs38.readFileSync(localBin, "utf-8");
18105
18109
  if (content.startsWith("#!/usr/bin/env node")) {
@@ -18107,7 +18111,7 @@ function resolveAgentCommand(cmd) {
18107
18111
  }
18108
18112
  const match = content.match(/"([^"]+\.js)"/);
18109
18113
  if (match) {
18110
- const target = path41.resolve(path41.dirname(localBin), match[1]);
18114
+ const target = path42.resolve(path42.dirname(localBin), match[1]);
18111
18115
  if (fs38.existsSync(target)) {
18112
18116
  return { command: process.execPath, args: [target] };
18113
18117
  }
@@ -18508,7 +18512,7 @@ ${stderr}`
18508
18512
  writePath = result.path;
18509
18513
  writeContent = result.content;
18510
18514
  }
18511
- await fs38.promises.mkdir(path41.dirname(writePath), { recursive: true });
18515
+ await fs38.promises.mkdir(path42.dirname(writePath), { recursive: true });
18512
18516
  await fs38.promises.writeFile(writePath, writeContent, "utf-8");
18513
18517
  return {};
18514
18518
  },
@@ -20120,7 +20124,7 @@ var init_message_transformer = __esm({
20120
20124
 
20121
20125
  // src/core/sessions/session-store.ts
20122
20126
  import fs40 from "fs";
20123
- import path42 from "path";
20127
+ import path43 from "path";
20124
20128
  var log30, DEBOUNCE_MS2, JsonFileSessionStore;
20125
20129
  var init_session_store = __esm({
20126
20130
  "src/core/sessions/session-store.ts"() {
@@ -20196,7 +20200,7 @@ var init_session_store = __esm({
20196
20200
  version: 1,
20197
20201
  sessions: Object.fromEntries(this.records)
20198
20202
  };
20199
- const dir = path42.dirname(this.filePath);
20203
+ const dir = path43.dirname(this.filePath);
20200
20204
  if (!fs40.existsSync(dir)) fs40.mkdirSync(dir, { recursive: true });
20201
20205
  fs40.writeFileSync(this.filePath, JSON.stringify(data, null, 2));
20202
20206
  }
@@ -20771,7 +20775,7 @@ __export(agent_store_exports, {
20771
20775
  AgentStore: () => AgentStore
20772
20776
  });
20773
20777
  import * as fs41 from "fs";
20774
- import * as path43 from "path";
20778
+ import * as path44 from "path";
20775
20779
  import * as os19 from "os";
20776
20780
  import { z as z7 } from "zod";
20777
20781
  var log33, InstalledAgentSchema, AgentStoreSchema, AgentStore;
@@ -20800,7 +20804,7 @@ var init_agent_store = __esm({
20800
20804
  data = { version: 1, installed: {} };
20801
20805
  filePath;
20802
20806
  constructor(filePath) {
20803
- this.filePath = filePath ?? path43.join(os19.homedir(), ".openacp", "agents.json");
20807
+ this.filePath = filePath ?? path44.join(os19.homedir(), ".openacp", "agents.json");
20804
20808
  }
20805
20809
  load() {
20806
20810
  if (!fs41.existsSync(this.filePath)) {
@@ -20842,7 +20846,7 @@ var init_agent_store = __esm({
20842
20846
  return key in this.data.installed;
20843
20847
  }
20844
20848
  save() {
20845
- fs41.mkdirSync(path43.dirname(this.filePath), { recursive: true });
20849
+ fs41.mkdirSync(path44.dirname(this.filePath), { recursive: true });
20846
20850
  const tmpPath = this.filePath + ".tmp";
20847
20851
  fs41.writeFileSync(tmpPath, JSON.stringify(this.data, null, 2));
20848
20852
  fs41.renameSync(tmpPath, this.filePath);
@@ -20853,7 +20857,7 @@ var init_agent_store = __esm({
20853
20857
 
20854
20858
  // src/core/agents/agent-installer.ts
20855
20859
  import * as fs42 from "fs";
20856
- import * as path44 from "path";
20860
+ import * as path45 from "path";
20857
20861
  import * as os20 from "os";
20858
20862
  function getPlatformKey() {
20859
20863
  const platform2 = PLATFORM_MAP[process.platform] ?? process.platform;
@@ -20905,7 +20909,7 @@ function buildInstalledAgent(registryId, name, version, dist, binaryPath) {
20905
20909
  binaryPath: null
20906
20910
  };
20907
20911
  }
20908
- const absCmd = path44.resolve(binaryPath, dist.cmd);
20912
+ const absCmd = path45.resolve(binaryPath, dist.cmd);
20909
20913
  return {
20910
20914
  registryId,
20911
20915
  name,
@@ -20978,7 +20982,7 @@ Install it with: pip install uv`;
20978
20982
  return { ok: true, agentKey, setupSteps: setup?.setupSteps };
20979
20983
  }
20980
20984
  async function downloadAndExtract(agentId, archiveUrl, progress, agentsDir) {
20981
- const destDir = path44.join(agentsDir ?? DEFAULT_AGENTS_DIR, agentId);
20985
+ const destDir = path45.join(agentsDir ?? DEFAULT_AGENTS_DIR, agentId);
20982
20986
  fs42.mkdirSync(destDir, { recursive: true });
20983
20987
  await progress?.onStep("Downloading...");
20984
20988
  log34.info({ agentId, url: archiveUrl }, "Downloading agent binary");
@@ -21022,15 +21026,15 @@ function validateExtractedPaths(destDir) {
21022
21026
  for (const entry of entries) {
21023
21027
  const dirent = entry;
21024
21028
  const parentPath = dirent.parentPath ?? dirent.path ?? destDir;
21025
- const fullPath = path44.join(parentPath, entry.name);
21029
+ const fullPath = path45.join(parentPath, entry.name);
21026
21030
  let realPath;
21027
21031
  try {
21028
21032
  realPath = fs42.realpathSync(fullPath);
21029
21033
  } catch {
21030
21034
  const linkTarget = fs42.readlinkSync(fullPath);
21031
- realPath = path44.resolve(path44.dirname(fullPath), linkTarget);
21035
+ realPath = path45.resolve(path45.dirname(fullPath), linkTarget);
21032
21036
  }
21033
- if (!realPath.startsWith(realDest + path44.sep) && realPath !== realDest) {
21037
+ if (!realPath.startsWith(realDest + path45.sep) && realPath !== realDest) {
21034
21038
  fs42.rmSync(destDir, { recursive: true, force: true });
21035
21039
  throw new Error(`Archive contains unsafe path: ${entry.name}`);
21036
21040
  }
@@ -21038,7 +21042,7 @@ function validateExtractedPaths(destDir) {
21038
21042
  }
21039
21043
  async function extractTarGz(buffer, destDir) {
21040
21044
  const { execFileSync: execFileSync8 } = await import("child_process");
21041
- const tmpFile = path44.join(destDir, "_archive.tar.gz");
21045
+ const tmpFile = path45.join(destDir, "_archive.tar.gz");
21042
21046
  fs42.writeFileSync(tmpFile, buffer);
21043
21047
  try {
21044
21048
  execFileSync8("tar", ["xzf", tmpFile, "-C", destDir], { stdio: "pipe" });
@@ -21049,7 +21053,7 @@ async function extractTarGz(buffer, destDir) {
21049
21053
  }
21050
21054
  async function extractZip(buffer, destDir) {
21051
21055
  const { execFileSync: execFileSync8 } = await import("child_process");
21052
- const tmpFile = path44.join(destDir, "_archive.zip");
21056
+ const tmpFile = path45.join(destDir, "_archive.zip");
21053
21057
  fs42.writeFileSync(tmpFile, buffer);
21054
21058
  try {
21055
21059
  execFileSync8("unzip", ["-o", tmpFile, "-d", destDir], { stdio: "pipe" });
@@ -21074,7 +21078,7 @@ var init_agent_installer = __esm({
21074
21078
  init_log();
21075
21079
  init_agent_dependencies();
21076
21080
  log34 = createChildLogger({ module: "agent-installer" });
21077
- DEFAULT_AGENTS_DIR = path44.join(os20.homedir(), ".openacp", "agents");
21081
+ DEFAULT_AGENTS_DIR = path45.join(os20.homedir(), ".openacp", "agents");
21078
21082
  ARCH_MAP = {
21079
21083
  arm64: "aarch64",
21080
21084
  x64: "x86_64"
@@ -21093,7 +21097,7 @@ __export(agent_catalog_exports, {
21093
21097
  AgentCatalog: () => AgentCatalog
21094
21098
  });
21095
21099
  import * as fs43 from "fs";
21096
- import * as path45 from "path";
21100
+ import * as path46 from "path";
21097
21101
  import * as os21 from "os";
21098
21102
  var log35, REGISTRY_URL2, DEFAULT_TTL_HOURS, AgentCatalog;
21099
21103
  var init_agent_catalog = __esm({
@@ -21113,7 +21117,7 @@ var init_agent_catalog = __esm({
21113
21117
  agentsDir;
21114
21118
  constructor(store, cachePath, agentsDir) {
21115
21119
  this.store = store ?? new AgentStore();
21116
- this.cachePath = cachePath ?? path45.join(os21.homedir(), ".openacp", "registry-cache.json");
21120
+ this.cachePath = cachePath ?? path46.join(os21.homedir(), ".openacp", "registry-cache.json");
21117
21121
  this.agentsDir = agentsDir;
21118
21122
  }
21119
21123
  load() {
@@ -21134,7 +21138,7 @@ var init_agent_catalog = __esm({
21134
21138
  ttlHours: DEFAULT_TTL_HOURS,
21135
21139
  data
21136
21140
  };
21137
- fs43.mkdirSync(path45.dirname(this.cachePath), { recursive: true });
21141
+ fs43.mkdirSync(path46.dirname(this.cachePath), { recursive: true });
21138
21142
  fs43.writeFileSync(this.cachePath, JSON.stringify(cache, null, 2));
21139
21143
  log35.info({ count: this.registryAgents.length }, "Registry updated");
21140
21144
  } catch (err) {
@@ -21320,9 +21324,9 @@ var init_agent_catalog = __esm({
21320
21324
  }
21321
21325
  try {
21322
21326
  const candidates = [
21323
- path45.join(import.meta.dirname, "data", "registry-snapshot.json"),
21324
- path45.join(import.meta.dirname, "..", "data", "registry-snapshot.json"),
21325
- path45.join(import.meta.dirname, "..", "..", "data", "registry-snapshot.json")
21327
+ path46.join(import.meta.dirname, "data", "registry-snapshot.json"),
21328
+ path46.join(import.meta.dirname, "..", "data", "registry-snapshot.json"),
21329
+ path46.join(import.meta.dirname, "..", "..", "data", "registry-snapshot.json")
21326
21330
  ];
21327
21331
  for (const candidate of candidates) {
21328
21332
  if (fs43.existsSync(candidate)) {
@@ -21620,7 +21624,7 @@ var init_error_tracker = __esm({
21620
21624
 
21621
21625
  // src/core/plugin/plugin-storage.ts
21622
21626
  import fs44 from "fs";
21623
- import path46 from "path";
21627
+ import path47 from "path";
21624
21628
  var PluginStorageImpl;
21625
21629
  var init_plugin_storage = __esm({
21626
21630
  "src/core/plugin/plugin-storage.ts"() {
@@ -21630,8 +21634,8 @@ var init_plugin_storage = __esm({
21630
21634
  dataDir;
21631
21635
  writeChain = Promise.resolve();
21632
21636
  constructor(baseDir) {
21633
- this.dataDir = path46.join(baseDir, "data");
21634
- this.kvPath = path46.join(baseDir, "kv.json");
21637
+ this.dataDir = path47.join(baseDir, "data");
21638
+ this.kvPath = path47.join(baseDir, "kv.json");
21635
21639
  fs44.mkdirSync(baseDir, { recursive: true });
21636
21640
  }
21637
21641
  readKv() {
@@ -21677,7 +21681,7 @@ var init_plugin_storage = __esm({
21677
21681
  });
21678
21682
 
21679
21683
  // src/core/plugin/plugin-context.ts
21680
- import path47 from "path";
21684
+ import path48 from "path";
21681
21685
  import os22 from "os";
21682
21686
  function requirePermission(permissions, required, action) {
21683
21687
  if (!permissions.includes(required)) {
@@ -21697,7 +21701,7 @@ function createPluginContext(opts) {
21697
21701
  config,
21698
21702
  core
21699
21703
  } = opts;
21700
- const instanceRoot = opts.instanceRoot ?? path47.join(os22.homedir(), ".openacp");
21704
+ const instanceRoot = opts.instanceRoot ?? path48.join(os22.homedir(), ".openacp");
21701
21705
  const registeredListeners = [];
21702
21706
  const registeredCommands = [];
21703
21707
  const noopLog = {
@@ -22548,7 +22552,7 @@ var init_core_items = __esm({
22548
22552
  });
22549
22553
 
22550
22554
  // src/core/core.ts
22551
- import path48 from "path";
22555
+ import path49 from "path";
22552
22556
  import os23 from "os";
22553
22557
  var log39, OpenACPCore;
22554
22558
  var init_core = __esm({
@@ -22631,7 +22635,7 @@ var init_core = __esm({
22631
22635
  );
22632
22636
  this.agentCatalog.load();
22633
22637
  this.agentManager = new AgentManager(this.agentCatalog);
22634
- const storePath = ctx?.paths.sessions ?? path48.join(os23.homedir(), ".openacp", "sessions.json");
22638
+ const storePath = ctx?.paths.sessions ?? path49.join(os23.homedir(), ".openacp", "sessions.json");
22635
22639
  this.sessionStore = new JsonFileSessionStore(
22636
22640
  storePath,
22637
22641
  config.sessionStore.ttlDays
@@ -22655,7 +22659,7 @@ var init_core = __esm({
22655
22659
  sessions: this.sessionManager,
22656
22660
  config: this.configManager,
22657
22661
  core: this,
22658
- storagePath: ctx?.paths.pluginsData ?? path48.join(os23.homedir(), ".openacp", "plugins", "data"),
22662
+ storagePath: ctx?.paths.pluginsData ?? path49.join(os23.homedir(), ".openacp", "plugins", "data"),
22659
22663
  instanceRoot: ctx?.root,
22660
22664
  log: createChildLogger({ module: "plugin" })
22661
22665
  });
@@ -22716,7 +22720,7 @@ var init_core = __esm({
22716
22720
  );
22717
22721
  registerCoreMenuItems(this.menuRegistry);
22718
22722
  if (ctx?.root) {
22719
- this.assistantRegistry.setInstanceRoot(path48.dirname(ctx.root));
22723
+ this.assistantRegistry.setInstanceRoot(path49.dirname(ctx.root));
22720
22724
  }
22721
22725
  this.assistantRegistry.register(createSessionsSection(this));
22722
22726
  this.assistantRegistry.register(createAgentsSection(this));
@@ -24042,21 +24046,25 @@ async function printStartBanner() {
24042
24046
  console.log(`${c.dim} AI coding agents, anywhere. v${version}${c.reset}
24043
24047
  `);
24044
24048
  }
24045
- function summarizeConfig(config) {
24049
+ async function summarizeConfig(config, settingsManager) {
24046
24050
  const lines = [];
24051
+ const channelDefs = [
24052
+ { id: "telegram", label: "Telegram", pluginName: "@openacp/telegram", keys: ["botToken", "chatId"] },
24053
+ { id: "discord", label: "Discord", pluginName: "@openacp/adapter-discord", keys: ["guildId", "token"] }
24054
+ ];
24047
24055
  const channelStatuses = [];
24048
- for (const [id, meta] of Object.entries({
24049
- telegram: "Telegram",
24050
- discord: "Discord"
24051
- })) {
24052
- const ch = config.channels[id];
24053
- if (ch?.enabled) {
24054
- channelStatuses.push(`${meta} (enabled)`);
24055
- } else if (ch && Object.keys(ch).length > 1) {
24056
- channelStatuses.push(`${meta} (disabled)`);
24057
- } else {
24058
- channelStatuses.push(`${meta} (not configured)`);
24056
+ for (const def of channelDefs) {
24057
+ const legacyCh = config.channels[def.id];
24058
+ let configured = !!legacyCh && Object.keys(legacyCh).length > 1;
24059
+ let enabled = legacyCh?.enabled === true;
24060
+ if (settingsManager) {
24061
+ const ps = await settingsManager.loadSettings(def.pluginName);
24062
+ if (def.keys.some((k) => ps[k])) {
24063
+ configured = true;
24064
+ enabled = ps.enabled !== false;
24065
+ }
24059
24066
  }
24067
+ channelStatuses.push(`${def.label} (${enabled ? "enabled" : configured ? "disabled" : "not configured"})`);
24060
24068
  }
24061
24069
  lines.push(`Channels: ${channelStatuses.join(", ")}`);
24062
24070
  lines.push(`Default agent: ${config.defaultAgent}`);
@@ -24133,9 +24141,8 @@ async function setupAgents() {
24133
24141
  await catalog.refreshRegistryIfStale();
24134
24142
  if (!catalog.getInstalledAgent("claude")) {
24135
24143
  const claudeRegistry = catalog.findRegistryAgent("claude-acp");
24136
- if (claudeRegistry) {
24137
- await catalog.install("claude-acp");
24138
- } else {
24144
+ const installed2 = claudeRegistry ? await catalog.install("claude-acp") : null;
24145
+ if (!installed2?.ok) {
24139
24146
  const { AgentStore: AgentStore2 } = await Promise.resolve().then(() => (init_agent_store(), agent_store_exports));
24140
24147
  const store = new AgentStore2();
24141
24148
  store.load();
@@ -24273,7 +24280,7 @@ __export(autostart_exports, {
24273
24280
  });
24274
24281
  import { execFileSync as execFileSync7 } from "child_process";
24275
24282
  import * as fs45 from "fs";
24276
- import * as path49 from "path";
24283
+ import * as path50 from "path";
24277
24284
  import * as os24 from "os";
24278
24285
  function isAutoStartSupported() {
24279
24286
  return process.platform === "darwin" || process.platform === "linux";
@@ -24286,7 +24293,7 @@ function escapeSystemdValue(str) {
24286
24293
  return `"${escaped}"`;
24287
24294
  }
24288
24295
  function generateLaunchdPlist(nodePath, cliPath, logDir2) {
24289
- const logFile = path49.join(logDir2, "openacp.log");
24296
+ const logFile = path50.join(logDir2, "openacp.log");
24290
24297
  return `<?xml version="1.0" encoding="UTF-8"?>
24291
24298
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
24292
24299
  <plist version="1.0">
@@ -24331,12 +24338,12 @@ function installAutoStart(logDir2) {
24331
24338
  return { success: false, error: "Auto-start not supported on this platform" };
24332
24339
  }
24333
24340
  const nodePath = process.execPath;
24334
- const cliPath = path49.resolve(process.argv[1]);
24335
- const resolvedLogDir = logDir2.startsWith("~") ? path49.join(os24.homedir(), logDir2.slice(1)) : logDir2;
24341
+ const cliPath = path50.resolve(process.argv[1]);
24342
+ const resolvedLogDir = logDir2.startsWith("~") ? path50.join(os24.homedir(), logDir2.slice(1)) : logDir2;
24336
24343
  try {
24337
24344
  if (process.platform === "darwin") {
24338
24345
  const plist = generateLaunchdPlist(nodePath, cliPath, resolvedLogDir);
24339
- const dir = path49.dirname(LAUNCHD_PLIST_PATH);
24346
+ const dir = path50.dirname(LAUNCHD_PLIST_PATH);
24340
24347
  fs45.mkdirSync(dir, { recursive: true });
24341
24348
  fs45.writeFileSync(LAUNCHD_PLIST_PATH, plist);
24342
24349
  execFileSync7("launchctl", ["load", LAUNCHD_PLIST_PATH], { stdio: "pipe" });
@@ -24345,7 +24352,7 @@ function installAutoStart(logDir2) {
24345
24352
  }
24346
24353
  if (process.platform === "linux") {
24347
24354
  const unit = generateSystemdUnit(nodePath, cliPath);
24348
- const dir = path49.dirname(SYSTEMD_SERVICE_PATH);
24355
+ const dir = path50.dirname(SYSTEMD_SERVICE_PATH);
24349
24356
  fs45.mkdirSync(dir, { recursive: true });
24350
24357
  fs45.writeFileSync(SYSTEMD_SERVICE_PATH, unit);
24351
24358
  execFileSync7("systemctl", ["--user", "daemon-reload"], { stdio: "pipe" });
@@ -24411,8 +24418,8 @@ var init_autostart = __esm({
24411
24418
  init_log();
24412
24419
  log40 = createChildLogger({ module: "autostart" });
24413
24420
  LAUNCHD_LABEL = "com.openacp.daemon";
24414
- LAUNCHD_PLIST_PATH = path49.join(os24.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
24415
- SYSTEMD_SERVICE_PATH = path49.join(os24.homedir(), ".config", "systemd", "user", "openacp.service");
24421
+ LAUNCHD_PLIST_PATH = path50.join(os24.homedir(), "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
24422
+ SYSTEMD_SERVICE_PATH = path50.join(os24.homedir(), ".config", "systemd", "user", "openacp.service");
24416
24423
  }
24417
24424
  });
24418
24425
 
@@ -24531,27 +24538,44 @@ var init_setup_integrations = __esm({
24531
24538
  });
24532
24539
 
24533
24540
  // src/core/setup/setup-channels.ts
24534
- import * as path50 from "path";
24541
+ import * as path51 from "path";
24535
24542
  import * as clack7 from "@clack/prompts";
24536
- function getChannelStatuses(config) {
24543
+ async function getChannelStatuses(config, settingsManager) {
24537
24544
  const statuses = [];
24538
24545
  for (const [id, meta] of Object.entries(CHANNEL_META)) {
24539
24546
  const ch = config.channels[id];
24540
- const enabled = ch?.enabled === true;
24541
- const configured = !!ch && Object.keys(ch).length > 1;
24547
+ let configured = !!ch && Object.keys(ch).length > 1;
24548
+ let enabled = ch?.enabled === true;
24542
24549
  let hint;
24543
- if (id === "telegram" && ch?.botToken && typeof ch.botToken === "string" && ch.botToken !== "YOUR_BOT_TOKEN_HERE") {
24544
- hint = `Chat ID: ${ch.chatId}`;
24550
+ if (settingsManager && id === "telegram") {
24551
+ const ps = await settingsManager.loadSettings("@openacp/telegram");
24552
+ if (ps.botToken && ps.chatId) {
24553
+ configured = true;
24554
+ enabled = ps.enabled !== false;
24555
+ hint = `Chat ID: ${ps.chatId}`;
24556
+ }
24557
+ } else if (settingsManager && id === "discord") {
24558
+ const ps = await settingsManager.loadSettings("@openacp/adapter-discord");
24559
+ if (ps.guildId || ps.token) {
24560
+ configured = true;
24561
+ enabled = ps.enabled !== false;
24562
+ hint = ps.guildId ? `Guild: ${ps.guildId}` : void 0;
24563
+ }
24545
24564
  }
24546
- if (id === "discord" && ch?.guildId) {
24547
- hint = `Guild: ${ch.guildId}`;
24565
+ if (!hint) {
24566
+ if (id === "telegram" && ch?.botToken && typeof ch.botToken === "string" && ch.botToken !== "YOUR_BOT_TOKEN_HERE") {
24567
+ hint = `Chat ID: ${ch.chatId}`;
24568
+ }
24569
+ if (id === "discord" && ch?.guildId) {
24570
+ hint = `Guild: ${ch.guildId}`;
24571
+ }
24548
24572
  }
24549
24573
  statuses.push({ id, label: meta.label, configured, enabled, hint });
24550
24574
  }
24551
24575
  return statuses;
24552
24576
  }
24553
- function noteChannelStatus(config) {
24554
- const statuses = getChannelStatuses(config);
24577
+ async function noteChannelStatus(config, settingsManager) {
24578
+ const statuses = await getChannelStatuses(config, settingsManager);
24555
24579
  const lines = statuses.map((s) => {
24556
24580
  const status = s.enabled ? "enabled" : s.configured ? "disabled" : "not configured";
24557
24581
  const hintStr = s.hint ? ` \u2014 ${s.hint}` : "";
@@ -24576,7 +24600,7 @@ async function promptConfiguredAction(label) {
24576
24600
  })
24577
24601
  );
24578
24602
  }
24579
- async function configureViaPlugin(channelId) {
24603
+ async function configureViaPlugin(channelId, settingsManager) {
24580
24604
  const pluginMap = {
24581
24605
  telegram: { importPath: "../../plugins/telegram/index.js", name: "@openacp/telegram" }
24582
24606
  };
@@ -24595,24 +24619,27 @@ async function configureViaPlugin(channelId) {
24595
24619
  }
24596
24620
  }
24597
24621
  if (plugin2?.configure) {
24598
- const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
24599
24622
  const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
24600
- const basePath = path50.join(getGlobalRoot(), "plugins", "data");
24601
- const settingsManager = new SettingsManager2(basePath);
24623
+ let sm = settingsManager;
24624
+ if (!sm) {
24625
+ const { SettingsManager: SM } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
24626
+ const basePath = path51.join(getGlobalRoot(), "plugins", "data");
24627
+ sm = new SM(basePath);
24628
+ }
24602
24629
  const ctx = createInstallContext2({
24603
24630
  pluginName: plugin2.name,
24604
- settingsManager,
24605
- basePath
24631
+ settingsManager: sm,
24632
+ basePath: sm.getBasePath()
24606
24633
  });
24607
24634
  await plugin2.configure(ctx);
24608
24635
  }
24609
24636
  }
24610
- async function configureChannels(config) {
24637
+ async function configureChannels(config, settingsManager) {
24611
24638
  const next = structuredClone(config);
24612
24639
  let changed = false;
24613
- noteChannelStatus(next);
24640
+ await noteChannelStatus(next, settingsManager);
24614
24641
  while (true) {
24615
- const statuses = getChannelStatuses(next);
24642
+ const statuses = await getChannelStatuses(next, settingsManager);
24616
24643
  const options = statuses.map((s) => {
24617
24644
  const status = s.enabled ? "enabled" : s.configured ? "disabled" : "not configured";
24618
24645
  return {
@@ -24633,8 +24660,8 @@ async function configureChannels(config) {
24633
24660
  if (choice === "__done__") break;
24634
24661
  const channelId = choice;
24635
24662
  const meta = CHANNEL_META[channelId];
24636
- const existing = next.channels[channelId];
24637
- const isConfigured = !!existing && Object.keys(existing).length > 1;
24663
+ const statuses2 = await getChannelStatuses(next, settingsManager);
24664
+ const isConfigured = statuses2.find((s) => s.id === channelId)?.configured ?? false;
24638
24665
  if (isConfigured) {
24639
24666
  const action = await promptConfiguredAction(meta.label);
24640
24667
  if (action === "skip") continue;
@@ -24659,7 +24686,7 @@ async function configureChannels(config) {
24659
24686
  continue;
24660
24687
  }
24661
24688
  }
24662
- await configureViaPlugin(channelId);
24689
+ await configureViaPlugin(channelId, settingsManager);
24663
24690
  changed = true;
24664
24691
  }
24665
24692
  return { config: next, changed };
@@ -24679,11 +24706,11 @@ __export(instance_copy_exports, {
24679
24706
  copyInstance: () => copyInstance
24680
24707
  });
24681
24708
  import fs46 from "fs";
24682
- import path51 from "path";
24709
+ import path52 from "path";
24683
24710
  async function copyInstance(src, dst, opts) {
24684
24711
  const { inheritableKeys = {}, onProgress } = opts;
24685
24712
  fs46.mkdirSync(dst, { recursive: true });
24686
- const configSrc = path51.join(src, "config.json");
24713
+ const configSrc = path52.join(src, "config.json");
24687
24714
  if (fs46.existsSync(configSrc)) {
24688
24715
  onProgress?.("Configuration", "start");
24689
24716
  const config = JSON.parse(fs46.readFileSync(configSrc, "utf-8"));
@@ -24705,44 +24732,44 @@ async function copyInstance(src, dst, opts) {
24705
24732
  }
24706
24733
  }
24707
24734
  }
24708
- fs46.writeFileSync(path51.join(dst, "config.json"), JSON.stringify(config, null, 2));
24735
+ fs46.writeFileSync(path52.join(dst, "config.json"), JSON.stringify(config, null, 2));
24709
24736
  onProgress?.("Configuration", "done");
24710
24737
  }
24711
- const pluginsSrc = path51.join(src, "plugins.json");
24738
+ const pluginsSrc = path52.join(src, "plugins.json");
24712
24739
  if (fs46.existsSync(pluginsSrc)) {
24713
24740
  onProgress?.("Plugin list", "start");
24714
- fs46.copyFileSync(pluginsSrc, path51.join(dst, "plugins.json"));
24741
+ fs46.copyFileSync(pluginsSrc, path52.join(dst, "plugins.json"));
24715
24742
  onProgress?.("Plugin list", "done");
24716
24743
  }
24717
- const pluginsDir = path51.join(src, "plugins");
24744
+ const pluginsDir = path52.join(src, "plugins");
24718
24745
  if (fs46.existsSync(pluginsDir)) {
24719
24746
  onProgress?.("Plugins", "start");
24720
- const dstPlugins = path51.join(dst, "plugins");
24747
+ const dstPlugins = path52.join(dst, "plugins");
24721
24748
  fs46.mkdirSync(dstPlugins, { recursive: true });
24722
- const pkgJson = path51.join(pluginsDir, "package.json");
24723
- if (fs46.existsSync(pkgJson)) fs46.copyFileSync(pkgJson, path51.join(dstPlugins, "package.json"));
24724
- const nodeModules = path51.join(pluginsDir, "node_modules");
24725
- if (fs46.existsSync(nodeModules)) fs46.cpSync(nodeModules, path51.join(dstPlugins, "node_modules"), { recursive: true });
24749
+ const pkgJson = path52.join(pluginsDir, "package.json");
24750
+ if (fs46.existsSync(pkgJson)) fs46.copyFileSync(pkgJson, path52.join(dstPlugins, "package.json"));
24751
+ const nodeModules = path52.join(pluginsDir, "node_modules");
24752
+ if (fs46.existsSync(nodeModules)) fs46.cpSync(nodeModules, path52.join(dstPlugins, "node_modules"), { recursive: true });
24726
24753
  onProgress?.("Plugins", "done");
24727
24754
  }
24728
- const agentsJson = path51.join(src, "agents.json");
24755
+ const agentsJson = path52.join(src, "agents.json");
24729
24756
  if (fs46.existsSync(agentsJson)) {
24730
24757
  onProgress?.("Agents", "start");
24731
- fs46.copyFileSync(agentsJson, path51.join(dst, "agents.json"));
24732
- const agentsDir = path51.join(src, "agents");
24733
- if (fs46.existsSync(agentsDir)) fs46.cpSync(agentsDir, path51.join(dst, "agents"), { recursive: true });
24758
+ fs46.copyFileSync(agentsJson, path52.join(dst, "agents.json"));
24759
+ const agentsDir = path52.join(src, "agents");
24760
+ if (fs46.existsSync(agentsDir)) fs46.cpSync(agentsDir, path52.join(dst, "agents"), { recursive: true });
24734
24761
  onProgress?.("Agents", "done");
24735
24762
  }
24736
- const binDir = path51.join(src, "bin");
24763
+ const binDir = path52.join(src, "bin");
24737
24764
  if (fs46.existsSync(binDir)) {
24738
24765
  onProgress?.("Tools", "start");
24739
- fs46.cpSync(binDir, path51.join(dst, "bin"), { recursive: true });
24766
+ fs46.cpSync(binDir, path52.join(dst, "bin"), { recursive: true });
24740
24767
  onProgress?.("Tools", "done");
24741
24768
  }
24742
- const pluginDataSrc = path51.join(src, "plugins", "data");
24769
+ const pluginDataSrc = path52.join(src, "plugins", "data");
24743
24770
  if (fs46.existsSync(pluginDataSrc)) {
24744
24771
  onProgress?.("Preferences", "start");
24745
- copyPluginSettings(pluginDataSrc, path51.join(dst, "plugins", "data"), inheritableKeys);
24772
+ copyPluginSettings(pluginDataSrc, path52.join(dst, "plugins", "data"), inheritableKeys);
24746
24773
  onProgress?.("Preferences", "done");
24747
24774
  }
24748
24775
  }
@@ -24757,10 +24784,10 @@ function copyPluginSettings(srcData, dstData, inheritableKeys) {
24757
24784
  if (key in settings) filtered[key] = settings[key];
24758
24785
  }
24759
24786
  if (Object.keys(filtered).length > 0) {
24760
- const relative = path51.relative(srcData, path51.dirname(settingsPath));
24761
- const dstDir = path51.join(dstData, relative);
24787
+ const relative = path52.relative(srcData, path52.dirname(settingsPath));
24788
+ const dstDir = path52.join(dstData, relative);
24762
24789
  fs46.mkdirSync(dstDir, { recursive: true });
24763
- fs46.writeFileSync(path51.join(dstDir, "settings.json"), JSON.stringify(filtered, null, 2));
24790
+ fs46.writeFileSync(path52.join(dstDir, "settings.json"), JSON.stringify(filtered, null, 2));
24764
24791
  }
24765
24792
  } catch {
24766
24793
  }
@@ -24771,15 +24798,15 @@ function walkPluginDirs(base, cb) {
24771
24798
  for (const entry of fs46.readdirSync(base, { withFileTypes: true })) {
24772
24799
  if (!entry.isDirectory()) continue;
24773
24800
  if (entry.name.startsWith("@")) {
24774
- const scopeDir = path51.join(base, entry.name);
24801
+ const scopeDir = path52.join(base, entry.name);
24775
24802
  for (const sub of fs46.readdirSync(scopeDir, { withFileTypes: true })) {
24776
24803
  if (!sub.isDirectory()) continue;
24777
24804
  const pluginName = `${entry.name}/${sub.name}`;
24778
- const settingsPath = path51.join(scopeDir, sub.name, "settings.json");
24805
+ const settingsPath = path52.join(scopeDir, sub.name, "settings.json");
24779
24806
  if (fs46.existsSync(settingsPath)) cb(pluginName, settingsPath);
24780
24807
  }
24781
24808
  } else {
24782
- const settingsPath = path51.join(base, entry.name, "settings.json");
24809
+ const settingsPath = path52.join(base, entry.name, "settings.json");
24783
24810
  if (fs46.existsSync(settingsPath)) cb(entry.name, settingsPath);
24784
24811
  }
24785
24812
  }
@@ -24792,14 +24819,14 @@ var init_instance_copy = __esm({
24792
24819
 
24793
24820
  // src/core/setup/git-protect.ts
24794
24821
  import fs47 from "fs";
24795
- import path52 from "path";
24822
+ import path53 from "path";
24796
24823
  function protectLocalInstance(projectDir) {
24797
24824
  ensureGitignore(projectDir);
24798
24825
  ensureClaudeMd(projectDir);
24799
24826
  printSecurityWarning();
24800
24827
  }
24801
24828
  function ensureGitignore(projectDir) {
24802
- const gitignorePath = path52.join(projectDir, ".gitignore");
24829
+ const gitignorePath = path53.join(projectDir, ".gitignore");
24803
24830
  const entry = ".openacp";
24804
24831
  if (fs47.existsSync(gitignorePath)) {
24805
24832
  const content = fs47.readFileSync(gitignorePath, "utf-8");
@@ -24819,7 +24846,7 @@ ${entry}
24819
24846
  }
24820
24847
  }
24821
24848
  function ensureClaudeMd(projectDir) {
24822
- const claudeMdPath = path52.join(projectDir, "CLAUDE.md");
24849
+ const claudeMdPath = path53.join(projectDir, "CLAUDE.md");
24823
24850
  const marker = "## Local OpenACP Workspace";
24824
24851
  if (fs47.existsSync(claudeMdPath)) {
24825
24852
  const content = fs47.readFileSync(claudeMdPath, "utf-8");
@@ -24862,7 +24889,7 @@ var init_git_protect = __esm({
24862
24889
  });
24863
24890
 
24864
24891
  // src/core/setup/wizard.ts
24865
- import * as path53 from "path";
24892
+ import * as path54 from "path";
24866
24893
  import * as fs48 from "fs";
24867
24894
  import * as os25 from "os";
24868
24895
  import * as clack8 from "@clack/prompts";
@@ -24911,7 +24938,7 @@ async function runSetup(configManager, opts) {
24911
24938
  const isGlobal = instanceRoot === getGlobalRoot();
24912
24939
  let instanceName = opts?.instanceName;
24913
24940
  if (!instanceName) {
24914
- const defaultName = isGlobal ? "Global workspace" : path53.basename(path53.dirname(instanceRoot));
24941
+ const defaultName = isGlobal ? "Global workspace" : path54.basename(path54.dirname(instanceRoot));
24915
24942
  const locationHint = isGlobal ? "global (~/.openacp)" : `local (${instanceRoot.replace(/\/.openacp$/, "").replace(os25.homedir(), "~")})`;
24916
24943
  const nameResult = await clack8.text({
24917
24944
  message: `Name for this workspace (${locationHint})`,
@@ -24922,13 +24949,13 @@ async function runSetup(configManager, opts) {
24922
24949
  instanceName = nameResult.trim();
24923
24950
  }
24924
24951
  const globalRoot = getGlobalRoot();
24925
- const registryPath = path53.join(globalRoot, "instances.json");
24952
+ const registryPath = path54.join(globalRoot, "instances.json");
24926
24953
  const instanceRegistry = new InstanceRegistry(registryPath);
24927
24954
  await instanceRegistry.load();
24928
24955
  let didCopy = false;
24929
24956
  if (opts?.from) {
24930
- const fromRoot = path53.join(opts.from, ".openacp");
24931
- if (fs48.existsSync(path53.join(fromRoot, "config.json"))) {
24957
+ const fromRoot = path54.join(opts.from, ".openacp");
24958
+ if (fs48.existsSync(path54.join(fromRoot, "config.json"))) {
24932
24959
  const inheritableMap = buildInheritableKeysMap();
24933
24960
  await copyInstance(fromRoot, instanceRoot, { inheritableKeys: inheritableMap });
24934
24961
  didCopy = true;
@@ -24939,7 +24966,7 @@ async function runSetup(configManager, opts) {
24939
24966
  }
24940
24967
  if (!didCopy) {
24941
24968
  const existingInstances = instanceRegistry.list().filter(
24942
- (e) => fs48.existsSync(path53.join(e.root, "config.json")) && e.root !== instanceRoot
24969
+ (e) => fs48.existsSync(path54.join(e.root, "config.json")) && e.root !== instanceRoot
24943
24970
  );
24944
24971
  if (existingInstances.length > 0) {
24945
24972
  let singleLabel;
@@ -24947,7 +24974,7 @@ async function runSetup(configManager, opts) {
24947
24974
  const e = existingInstances[0];
24948
24975
  let name = e.id;
24949
24976
  try {
24950
- const cfg = JSON.parse(fs48.readFileSync(path53.join(e.root, "config.json"), "utf-8"));
24977
+ const cfg = JSON.parse(fs48.readFileSync(path54.join(e.root, "config.json"), "utf-8"));
24951
24978
  if (cfg.instanceName) name = cfg.instanceName;
24952
24979
  } catch {
24953
24980
  }
@@ -24972,7 +24999,7 @@ async function runSetup(configManager, opts) {
24972
24999
  options: existingInstances.map((e) => {
24973
25000
  let name = e.id;
24974
25001
  try {
24975
- const cfg = JSON.parse(fs48.readFileSync(path53.join(e.root, "config.json"), "utf-8"));
25002
+ const cfg = JSON.parse(fs48.readFileSync(path54.join(e.root, "config.json"), "utf-8"));
24976
25003
  if (cfg.instanceName) name = cfg.instanceName;
24977
25004
  } catch {
24978
25005
  }
@@ -25069,9 +25096,9 @@ async function runSetup(configManager, opts) {
25069
25096
  if (channelId.startsWith("official:")) {
25070
25097
  const npmPackage = channelId.slice("official:".length);
25071
25098
  const { execFileSync: execFileSync8 } = await import("child_process");
25072
- const pluginsDir = path53.join(instanceRoot, "plugins");
25073
- const nodeModulesDir = path53.join(pluginsDir, "node_modules");
25074
- const installedPath = path53.join(nodeModulesDir, npmPackage);
25099
+ const pluginsDir = path54.join(instanceRoot, "plugins");
25100
+ const nodeModulesDir = path54.join(pluginsDir, "node_modules");
25101
+ const installedPath = path54.join(nodeModulesDir, npmPackage);
25075
25102
  if (!fs48.existsSync(installedPath)) {
25076
25103
  try {
25077
25104
  clack8.log.step(`Installing ${npmPackage}...`);
@@ -25085,9 +25112,9 @@ async function runSetup(configManager, opts) {
25085
25112
  }
25086
25113
  }
25087
25114
  try {
25088
- const installedPkgPath = path53.join(nodeModulesDir, npmPackage, "package.json");
25115
+ const installedPkgPath = path54.join(nodeModulesDir, npmPackage, "package.json");
25089
25116
  const installedPkg = JSON.parse(fs48.readFileSync(installedPkgPath, "utf-8"));
25090
- const pluginModule = await import(path53.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
25117
+ const pluginModule = await import(path54.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
25091
25118
  const plugin2 = pluginModule.default;
25092
25119
  if (plugin2?.install) {
25093
25120
  const installCtx = createInstallContext2({
@@ -25117,8 +25144,8 @@ async function runSetup(configManager, opts) {
25117
25144
  if (channelId.startsWith("community:")) {
25118
25145
  const npmPackage = channelId.slice("community:".length);
25119
25146
  const { execFileSync: execFileSync8 } = await import("child_process");
25120
- const pluginsDir = path53.join(instanceRoot, "plugins");
25121
- const nodeModulesDir = path53.join(pluginsDir, "node_modules");
25147
+ const pluginsDir = path54.join(instanceRoot, "plugins");
25148
+ const nodeModulesDir = path54.join(pluginsDir, "node_modules");
25122
25149
  try {
25123
25150
  execFileSync8("npm", ["install", npmPackage, "--prefix", pluginsDir, "--save"], {
25124
25151
  stdio: "inherit",
@@ -25130,9 +25157,9 @@ async function runSetup(configManager, opts) {
25130
25157
  }
25131
25158
  try {
25132
25159
  const { readFileSync: readFileSync19 } = await import("fs");
25133
- const installedPkgPath = path53.join(nodeModulesDir, npmPackage, "package.json");
25160
+ const installedPkgPath = path54.join(nodeModulesDir, npmPackage, "package.json");
25134
25161
  const installedPkg = JSON.parse(readFileSync19(installedPkgPath, "utf-8"));
25135
- const pluginModule = await import(path53.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
25162
+ const pluginModule = await import(path54.join(nodeModulesDir, npmPackage, installedPkg.main ?? "dist/index.js"));
25136
25163
  const plugin2 = pluginModule.default;
25137
25164
  if (plugin2?.install) {
25138
25165
  const installCtx = createInstallContext2({
@@ -25187,7 +25214,7 @@ async function runSetup(configManager, opts) {
25187
25214
  security,
25188
25215
  logging: {
25189
25216
  level: "info",
25190
- logDir: path53.join(instanceRoot, "logs"),
25217
+ logDir: path54.join(instanceRoot, "logs"),
25191
25218
  maxFileSize: "10m",
25192
25219
  maxFiles: 7,
25193
25220
  sessionLogRetentionDays: 30
@@ -25239,9 +25266,9 @@ async function runSetup(configManager, opts) {
25239
25266
  instanceRegistry.register(id, instanceRoot);
25240
25267
  await instanceRegistry.save();
25241
25268
  }
25242
- const isLocal = instanceRoot !== path53.join(getGlobalRoot());
25269
+ const isLocal = instanceRoot !== path54.join(getGlobalRoot());
25243
25270
  if (isLocal) {
25244
- const projectDir = path53.dirname(instanceRoot);
25271
+ const projectDir = path54.dirname(instanceRoot);
25245
25272
  protectLocalInstance(projectDir);
25246
25273
  }
25247
25274
  clack8.outro(`Config saved to ${configManager.getConfigPath()}`);
@@ -25305,20 +25332,20 @@ async function selectSection(hasSelection) {
25305
25332
  })
25306
25333
  );
25307
25334
  }
25308
- async function runReconfigure(configManager) {
25335
+ async function runReconfigure(configManager, settingsManager) {
25309
25336
  await printStartBanner();
25310
25337
  clack8.intro("OpenACP \u2014 Reconfigure");
25311
25338
  try {
25312
25339
  await configManager.load();
25313
25340
  let config = configManager.get();
25314
- clack8.note(summarizeConfig(config), "Current configuration");
25341
+ clack8.note(await summarizeConfig(config, settingsManager), "Current configuration");
25315
25342
  let ranSection = false;
25316
25343
  while (true) {
25317
25344
  const choice = await selectSection(ranSection);
25318
25345
  if (choice === "__continue") break;
25319
25346
  ranSection = true;
25320
25347
  if (choice === "channels") {
25321
- const result = await configureChannels(config);
25348
+ const result = await configureChannels(config, settingsManager);
25322
25349
  if (result.changed) {
25323
25350
  config = { ...config, channels: result.config.channels };
25324
25351
  await configManager.writeNew(config);
@@ -25529,7 +25556,7 @@ __export(dev_loader_exports, {
25529
25556
  DevPluginLoader: () => DevPluginLoader
25530
25557
  });
25531
25558
  import fs49 from "fs";
25532
- import path54 from "path";
25559
+ import path55 from "path";
25533
25560
  var loadCounter, DevPluginLoader;
25534
25561
  var init_dev_loader = __esm({
25535
25562
  "src/core/plugin/dev-loader.ts"() {
@@ -25538,11 +25565,11 @@ var init_dev_loader = __esm({
25538
25565
  DevPluginLoader = class {
25539
25566
  pluginPath;
25540
25567
  constructor(pluginPath) {
25541
- this.pluginPath = path54.resolve(pluginPath);
25568
+ this.pluginPath = path55.resolve(pluginPath);
25542
25569
  }
25543
25570
  async load() {
25544
- const distIndex = path54.join(this.pluginPath, "dist", "index.js");
25545
- const srcIndex = path54.join(this.pluginPath, "src", "index.ts");
25571
+ const distIndex = path55.join(this.pluginPath, "dist", "index.js");
25572
+ const srcIndex = path55.join(this.pluginPath, "src", "index.ts");
25546
25573
  if (!fs49.existsSync(distIndex) && !fs49.existsSync(srcIndex)) {
25547
25574
  throw new Error(`Plugin not found at ${this.pluginPath}. Expected dist/index.js or src/index.ts`);
25548
25575
  }
@@ -25561,7 +25588,7 @@ var init_dev_loader = __esm({
25561
25588
  return this.pluginPath;
25562
25589
  }
25563
25590
  getDistPath() {
25564
- return path54.join(this.pluginPath, "dist");
25591
+ return path55.join(this.pluginPath, "dist");
25565
25592
  }
25566
25593
  };
25567
25594
  }
@@ -25573,13 +25600,13 @@ __export(main_exports, {
25573
25600
  RESTART_EXIT_CODE: () => RESTART_EXIT_CODE,
25574
25601
  startServer: () => startServer
25575
25602
  });
25576
- import path55 from "path";
25603
+ import path56 from "path";
25577
25604
  import { randomUUID as randomUUID3 } from "crypto";
25578
25605
  import fs50 from "fs";
25579
25606
  async function startServer(opts) {
25580
25607
  const globalRoot = getGlobalRoot();
25581
25608
  if (!opts?.instanceContext) {
25582
- const reg = new InstanceRegistry(path55.join(globalRoot, "instances.json"));
25609
+ const reg = new InstanceRegistry(path56.join(globalRoot, "instances.json"));
25583
25610
  reg.load();
25584
25611
  const entry = reg.getByRoot(globalRoot);
25585
25612
  opts = { ...opts, instanceContext: createInstanceContext({ id: entry?.id ?? randomUUID3(), root: globalRoot, isGlobal: true }) };
@@ -25664,22 +25691,22 @@ async function startServer(opts) {
25664
25691
  try {
25665
25692
  let modulePath;
25666
25693
  if (name.startsWith("/") || name.startsWith(".")) {
25667
- const resolved = path55.resolve(name);
25668
- const pkgPath = path55.join(resolved, "package.json");
25694
+ const resolved = path56.resolve(name);
25695
+ const pkgPath = path56.join(resolved, "package.json");
25669
25696
  const pkg = JSON.parse(await fs50.promises.readFile(pkgPath, "utf-8"));
25670
- modulePath = path55.join(resolved, pkg.main || "dist/index.js");
25697
+ modulePath = path56.join(resolved, pkg.main || "dist/index.js");
25671
25698
  } else {
25672
- const nodeModulesDir = path55.join(ctx.paths.plugins, "node_modules");
25673
- let pkgDir = path55.join(nodeModulesDir, name);
25674
- if (!fs50.existsSync(path55.join(pkgDir, "package.json"))) {
25699
+ const nodeModulesDir = path56.join(ctx.paths.plugins, "node_modules");
25700
+ let pkgDir = path56.join(nodeModulesDir, name);
25701
+ if (!fs50.existsSync(path56.join(pkgDir, "package.json"))) {
25675
25702
  let found = false;
25676
25703
  const scopes = fs50.existsSync(nodeModulesDir) ? fs50.readdirSync(nodeModulesDir).filter((d) => d.startsWith("@")) : [];
25677
25704
  for (const scope of scopes) {
25678
- const scopeDir = path55.join(nodeModulesDir, scope);
25705
+ const scopeDir = path56.join(nodeModulesDir, scope);
25679
25706
  const pkgs = fs50.readdirSync(scopeDir);
25680
25707
  for (const pkg2 of pkgs) {
25681
- const candidateDir = path55.join(scopeDir, pkg2);
25682
- const candidatePkgPath = path55.join(candidateDir, "package.json");
25708
+ const candidateDir = path56.join(scopeDir, pkg2);
25709
+ const candidatePkgPath = path56.join(candidateDir, "package.json");
25683
25710
  if (fs50.existsSync(candidatePkgPath)) {
25684
25711
  try {
25685
25712
  const candidatePkg = JSON.parse(fs50.readFileSync(candidatePkgPath, "utf-8"));
@@ -25696,9 +25723,9 @@ async function startServer(opts) {
25696
25723
  if (found) break;
25697
25724
  }
25698
25725
  }
25699
- const pkgJsonPath = path55.join(pkgDir, "package.json");
25726
+ const pkgJsonPath = path56.join(pkgDir, "package.json");
25700
25727
  const pkg = JSON.parse(await fs50.promises.readFile(pkgJsonPath, "utf-8"));
25701
- modulePath = path55.join(pkgDir, pkg.main || "dist/index.js");
25728
+ modulePath = path56.join(pkgDir, pkg.main || "dist/index.js");
25702
25729
  }
25703
25730
  log.debug({ plugin: name, modulePath }, "Loading community plugin");
25704
25731
  const mod = await import(modulePath);
@@ -25861,7 +25888,7 @@ async function startServer(opts) {
25861
25888
  await core.start();
25862
25889
  try {
25863
25890
  const globalRoot2 = getGlobalRoot();
25864
- const registryPath = path55.join(globalRoot2, "instances.json");
25891
+ const registryPath = path56.join(globalRoot2, "instances.json");
25865
25892
  const instanceReg = new InstanceRegistry(registryPath);
25866
25893
  await instanceReg.load();
25867
25894
  if (!instanceReg.getByRoot(ctx.root)) {
@@ -26024,13 +26051,13 @@ var restart_exports = {};
26024
26051
  __export(restart_exports, {
26025
26052
  cmdRestart: () => cmdRestart
26026
26053
  });
26027
- import path56 from "path";
26054
+ import path57 from "path";
26028
26055
  import os26 from "os";
26029
26056
  import { randomUUID as randomUUID4 } from "crypto";
26030
26057
  async function cmdRestart(args2 = [], instanceRoot) {
26031
26058
  const json = isJsonMode(args2);
26032
26059
  if (json) await muteForJson();
26033
- const root = instanceRoot ?? path56.join(os26.homedir(), ".openacp");
26060
+ const root = instanceRoot ?? path57.join(os26.homedir(), ".openacp");
26034
26061
  if (!json && wantsHelp(args2)) {
26035
26062
  console.log(`
26036
26063
  \x1B[1mopenacp restart\x1B[0m \u2014 Restart the background daemon
@@ -26078,7 +26105,7 @@ Stops the running daemon (if any) and starts a new one.
26078
26105
  printInstanceHint(root);
26079
26106
  console.log("Starting in foreground mode...");
26080
26107
  const { startServer: startServer2 } = await Promise.resolve().then(() => (init_main(), main_exports));
26081
- const reg = new InstanceRegistry(path56.join(getGlobalRoot(), "instances.json"));
26108
+ const reg = new InstanceRegistry(path57.join(getGlobalRoot(), "instances.json"));
26082
26109
  reg.load();
26083
26110
  const existingEntry = reg.getByRoot(root);
26084
26111
  const ctx = createInstanceContext({
@@ -26094,7 +26121,7 @@ Stops the running daemon (if any) and starts a new one.
26094
26121
  console.error(result.error);
26095
26122
  process.exit(1);
26096
26123
  }
26097
- if (json) jsonSuccess({ pid: result.pid, instanceId: path56.basename(root), dir: root });
26124
+ if (json) jsonSuccess({ pid: result.pid, instanceId: path57.basename(root), dir: root });
26098
26125
  printInstanceHint(root);
26099
26126
  console.log(`OpenACP daemon started (PID ${result.pid})`);
26100
26127
  }
@@ -26118,7 +26145,7 @@ __export(status_exports, {
26118
26145
  readInstanceInfo: () => readInstanceInfo
26119
26146
  });
26120
26147
  import fs51 from "fs";
26121
- import path57 from "path";
26148
+ import path58 from "path";
26122
26149
  import os27 from "os";
26123
26150
  async function cmdStatus(args2 = [], instanceRoot) {
26124
26151
  const json = isJsonMode(args2);
@@ -26136,7 +26163,7 @@ async function cmdStatus(args2 = [], instanceRoot) {
26136
26163
  await showSingleInstance(root, json);
26137
26164
  }
26138
26165
  async function showAllInstances(json = false) {
26139
- const registryPath = path57.join(getGlobalRoot(), "instances.json");
26166
+ const registryPath = path58.join(getGlobalRoot(), "instances.json");
26140
26167
  const registry = new InstanceRegistry(registryPath);
26141
26168
  await registry.load();
26142
26169
  const instances = registry.list();
@@ -26179,7 +26206,7 @@ async function showAllInstances(json = false) {
26179
26206
  console.log("");
26180
26207
  }
26181
26208
  async function showInstanceById(id, json = false) {
26182
- const registryPath = path57.join(getGlobalRoot(), "instances.json");
26209
+ const registryPath = path58.join(getGlobalRoot(), "instances.json");
26183
26210
  const registry = new InstanceRegistry(registryPath);
26184
26211
  await registry.load();
26185
26212
  const entry = registry.get(id);
@@ -26194,7 +26221,7 @@ async function showSingleInstance(root, json = false) {
26194
26221
  const info = readInstanceInfo(root);
26195
26222
  if (json) {
26196
26223
  jsonSuccess({
26197
- id: path57.basename(root),
26224
+ id: path58.basename(root),
26198
26225
  name: info.name,
26199
26226
  status: info.pid ? "online" : "offline",
26200
26227
  pid: info.pid,
@@ -26225,13 +26252,13 @@ function readInstanceInfo(root) {
26225
26252
  channels: []
26226
26253
  };
26227
26254
  try {
26228
- const config = JSON.parse(fs51.readFileSync(path57.join(root, "config.json"), "utf-8"));
26255
+ const config = JSON.parse(fs51.readFileSync(path58.join(root, "config.json"), "utf-8"));
26229
26256
  result.name = config.instanceName ?? null;
26230
26257
  result.runMode = config.runMode ?? null;
26231
26258
  } catch {
26232
26259
  }
26233
26260
  try {
26234
- const pid = parseInt(fs51.readFileSync(path57.join(root, "openacp.pid"), "utf-8").trim());
26261
+ const pid = parseInt(fs51.readFileSync(path58.join(root, "openacp.pid"), "utf-8").trim());
26235
26262
  if (!isNaN(pid)) {
26236
26263
  process.kill(pid, 0);
26237
26264
  result.pid = pid;
@@ -26239,19 +26266,19 @@ function readInstanceInfo(root) {
26239
26266
  } catch {
26240
26267
  }
26241
26268
  try {
26242
- const port = parseInt(fs51.readFileSync(path57.join(root, "api.port"), "utf-8").trim());
26269
+ const port = parseInt(fs51.readFileSync(path58.join(root, "api.port"), "utf-8").trim());
26243
26270
  if (!isNaN(port)) result.apiPort = port;
26244
26271
  } catch {
26245
26272
  }
26246
26273
  try {
26247
- const tunnels = JSON.parse(fs51.readFileSync(path57.join(root, "tunnels.json"), "utf-8"));
26274
+ const tunnels = JSON.parse(fs51.readFileSync(path58.join(root, "tunnels.json"), "utf-8"));
26248
26275
  const entries = Object.values(tunnels);
26249
26276
  const systemEntry = entries.find((t) => t.type === "system");
26250
26277
  if (systemEntry?.port) result.tunnelPort = systemEntry.port;
26251
26278
  } catch {
26252
26279
  }
26253
26280
  try {
26254
- const plugins = JSON.parse(fs51.readFileSync(path57.join(root, "plugins.json"), "utf-8"));
26281
+ const plugins = JSON.parse(fs51.readFileSync(path58.join(root, "plugins.json"), "utf-8"));
26255
26282
  const adapters = ["@openacp/telegram", "@openacp/discord", "@openacp/slack"];
26256
26283
  for (const name of adapters) {
26257
26284
  if (plugins.installed?.[name] && plugins.installed[name].enabled !== false) {
@@ -26335,7 +26362,7 @@ var config_editor_exports = {};
26335
26362
  __export(config_editor_exports, {
26336
26363
  runConfigEditor: () => runConfigEditor
26337
26364
  });
26338
- import * as path58 from "path";
26365
+ import * as path59 from "path";
26339
26366
  import * as clack9 from "@clack/prompts";
26340
26367
  async function select8(opts) {
26341
26368
  const result = await clack9.select({
@@ -26520,7 +26547,7 @@ async function editDiscord(_config, _updates) {
26520
26547
  const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
26521
26548
  const { getGlobalRoot: getGlobalRoot2 } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
26522
26549
  const root = getGlobalRoot2();
26523
- const basePath = path58.join(root, "plugins");
26550
+ const basePath = path59.join(root, "plugins", "data");
26524
26551
  const settingsManager = new SettingsManager2(basePath);
26525
26552
  const ctx = createInstallContext2({
26526
26553
  pluginName: plugin2.name,
@@ -26534,11 +26561,17 @@ async function editDiscord(_config, _updates) {
26534
26561
  }
26535
26562
  }
26536
26563
  async function editChannels(config, updates, settingsManager) {
26537
- const tgEnabled = config.channels?.telegram?.enabled !== false && config.channels?.telegram;
26538
- const dcEnabled = config.channels?.discord?.enabled !== false && config.channels?.discord;
26564
+ let tgConfigured = !!config.channels?.telegram;
26565
+ let dcConfigured = !!config.channels?.discord;
26566
+ if (settingsManager) {
26567
+ const tgPs = await settingsManager.loadSettings("@openacp/telegram");
26568
+ if (tgPs.botToken && tgPs.chatId) tgConfigured = true;
26569
+ const dcPs = await settingsManager.loadSettings("@openacp/adapter-discord");
26570
+ if (dcPs.guildId || dcPs.token) dcConfigured = true;
26571
+ }
26539
26572
  console.log(header("Channels"));
26540
- console.log(` Telegram : ${tgEnabled ? ok2("configured") : dim2("not configured")}`);
26541
- console.log(` Discord : ${dcEnabled ? ok2("configured") : dim2("not configured")}`);
26573
+ console.log(` Telegram : ${tgConfigured ? ok2("configured") : dim2("not configured")}`);
26574
+ console.log(` Discord : ${dcConfigured ? ok2("configured") : dim2("not configured")}`);
26542
26575
  console.log("");
26543
26576
  while (true) {
26544
26577
  const choice = await select8({
@@ -27035,17 +27068,17 @@ ${c2.cyan}${c2.bold}OpenACP Config Editor${c2.reset}`);
27035
27068
  async function sendConfigViaApi(port, updates) {
27036
27069
  const { apiCall: call } = await Promise.resolve().then(() => (init_api_client(), api_client_exports));
27037
27070
  const paths = flattenToPaths(updates);
27038
- for (const { path: path68, value } of paths) {
27071
+ for (const { path: path69, value } of paths) {
27039
27072
  const res = await call(port, "/api/config", {
27040
27073
  method: "PATCH",
27041
27074
  headers: { "Content-Type": "application/json" },
27042
- body: JSON.stringify({ path: path68, value })
27075
+ body: JSON.stringify({ path: path69, value })
27043
27076
  });
27044
27077
  const data = await res.json();
27045
27078
  if (!res.ok) {
27046
- console.log(warn2(`Failed to update ${path68}: ${data.error}`));
27079
+ console.log(warn2(`Failed to update ${path69}: ${data.error}`));
27047
27080
  } else if (data.needsRestart) {
27048
- console.log(warn2(`${path68} updated \u2014 restart required`));
27081
+ console.log(warn2(`${path69} updated \u2014 restart required`));
27049
27082
  }
27050
27083
  }
27051
27084
  }
@@ -27154,24 +27187,24 @@ __export(instance_prompt_exports, {
27154
27187
  promptForInstance: () => promptForInstance
27155
27188
  });
27156
27189
  import fs56 from "fs";
27157
- import path66 from "path";
27190
+ import path67 from "path";
27158
27191
  import os32 from "os";
27159
27192
  async function promptForInstance(opts) {
27160
27193
  const globalRoot = getGlobalRoot();
27161
- const globalConfigExists = fs56.existsSync(path66.join(globalRoot, "config.json"));
27194
+ const globalConfigExists = fs56.existsSync(path67.join(globalRoot, "config.json"));
27162
27195
  const cwd = process.cwd();
27163
- const localRoot = path66.join(cwd, ".openacp");
27196
+ const localRoot = path67.join(cwd, ".openacp");
27164
27197
  if (!globalConfigExists) return globalRoot;
27165
27198
  const isTTY = process.stdin.isTTY && process.stdout.isTTY;
27166
27199
  if (!isTTY) return globalRoot;
27167
- const registryPath = path66.join(globalRoot, "instances.json");
27200
+ const registryPath = path67.join(globalRoot, "instances.json");
27168
27201
  const registry = new InstanceRegistry(registryPath);
27169
27202
  registry.load();
27170
27203
  const instances = registry.list().filter((e) => fs56.existsSync(e.root));
27171
27204
  const instanceOptions = instances.map((e) => {
27172
27205
  let name = e.id;
27173
27206
  try {
27174
- const raw = fs56.readFileSync(path66.join(e.root, "config.json"), "utf-8");
27207
+ const raw = fs56.readFileSync(path67.join(e.root, "config.json"), "utf-8");
27175
27208
  const parsed = JSON.parse(raw);
27176
27209
  if (parsed.instanceName) name = parsed.instanceName;
27177
27210
  } catch {
@@ -27219,7 +27252,7 @@ var init_instance_prompt = __esm({
27219
27252
 
27220
27253
  // src/cli.ts
27221
27254
  import { setDefaultAutoSelectFamily } from "net";
27222
- import path67 from "path";
27255
+ import path68 from "path";
27223
27256
 
27224
27257
  // src/cli/commands/help.ts
27225
27258
  function printHelp() {
@@ -27459,10 +27492,10 @@ Shows all plugins registered in the plugin registry.
27459
27492
  return;
27460
27493
  }
27461
27494
  const os33 = await import("os");
27462
- const path68 = await import("path");
27495
+ const path69 = await import("path");
27463
27496
  const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
27464
- const root = instanceRoot ?? path68.join(os33.homedir(), ".openacp");
27465
- const registryPath = path68.join(root, "plugins.json");
27497
+ const root = instanceRoot ?? path69.join(os33.homedir(), ".openacp");
27498
+ const registryPath = path69.join(root, "plugins.json");
27466
27499
  const registry = new PluginRegistry2(registryPath);
27467
27500
  await registry.load();
27468
27501
  const plugins = registry.list();
@@ -27598,10 +27631,10 @@ async function cmdPlugin(args2 = [], instanceRoot) {
27598
27631
  async function setPluginEnabled(name, enabled, instanceRoot, json = false) {
27599
27632
  if (json) await muteForJson();
27600
27633
  const os33 = await import("os");
27601
- const path68 = await import("path");
27634
+ const path69 = await import("path");
27602
27635
  const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
27603
- const root = instanceRoot ?? path68.join(os33.homedir(), ".openacp");
27604
- const registryPath = path68.join(root, "plugins.json");
27636
+ const root = instanceRoot ?? path69.join(os33.homedir(), ".openacp");
27637
+ const registryPath = path69.join(root, "plugins.json");
27605
27638
  const registry = new PluginRegistry2(registryPath);
27606
27639
  await registry.load();
27607
27640
  const entry = registry.get(name);
@@ -27617,7 +27650,7 @@ async function setPluginEnabled(name, enabled, instanceRoot, json = false) {
27617
27650
  }
27618
27651
  async function configurePlugin(name, instanceRoot) {
27619
27652
  const os33 = await import("os");
27620
- const path68 = await import("path");
27653
+ const path69 = await import("path");
27621
27654
  const { corePlugins: corePlugins2 } = await Promise.resolve().then(() => (init_core_plugins(), core_plugins_exports));
27622
27655
  const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
27623
27656
  const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
@@ -27626,8 +27659,8 @@ async function configurePlugin(name, instanceRoot) {
27626
27659
  console.error(`Plugin "${name}" not found.`);
27627
27660
  process.exit(1);
27628
27661
  }
27629
- const root = instanceRoot ?? path68.join(os33.homedir(), ".openacp");
27630
- const basePath = path68.join(root, "plugins", "data");
27662
+ const root = instanceRoot ?? path69.join(os33.homedir(), ".openacp");
27663
+ const basePath = path69.join(root, "plugins", "data");
27631
27664
  const settingsManager = new SettingsManager2(basePath);
27632
27665
  const ctx = createInstallContext2({ pluginName: name, settingsManager, basePath });
27633
27666
  if (plugin2.configure) {
@@ -27641,13 +27674,13 @@ async function configurePlugin(name, instanceRoot) {
27641
27674
  async function installPlugin(input2, instanceRoot, json = false) {
27642
27675
  if (json) await muteForJson();
27643
27676
  const os33 = await import("os");
27644
- const path68 = await import("path");
27677
+ const path69 = await import("path");
27645
27678
  const { execFileSync: execFileSync8 } = await import("child_process");
27646
27679
  const { getCurrentVersion: getCurrentVersion2 } = await Promise.resolve().then(() => (init_version(), version_exports));
27647
27680
  const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
27648
27681
  const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
27649
27682
  const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
27650
- const root = instanceRoot ?? path68.join(os33.homedir(), ".openacp");
27683
+ const root = instanceRoot ?? path69.join(os33.homedir(), ".openacp");
27651
27684
  let pkgName;
27652
27685
  let pkgVersion;
27653
27686
  if (input2.startsWith("@")) {
@@ -27692,9 +27725,9 @@ async function installPlugin(input2, instanceRoot, json = false) {
27692
27725
  if (!json) console.log(`Installing ${installSpec}...`);
27693
27726
  const { corePlugins: corePlugins2 } = await Promise.resolve().then(() => (init_core_plugins(), core_plugins_exports));
27694
27727
  const builtinPlugin = corePlugins2.find((p2) => p2.name === pkgName);
27695
- const basePath = path68.join(root, "plugins", "data");
27728
+ const basePath = path69.join(root, "plugins", "data");
27696
27729
  const settingsManager = new SettingsManager2(basePath);
27697
- const registryPath = path68.join(root, "plugins.json");
27730
+ const registryPath = path69.join(root, "plugins.json");
27698
27731
  const pluginRegistry = new PluginRegistry2(registryPath);
27699
27732
  await pluginRegistry.load();
27700
27733
  if (builtinPlugin) {
@@ -27714,8 +27747,8 @@ async function installPlugin(input2, instanceRoot, json = false) {
27714
27747
  console.log(`\u2713 ${builtinPlugin.name} installed! Restart to activate.`);
27715
27748
  return;
27716
27749
  }
27717
- const pluginsDir = path68.join(root, "plugins");
27718
- const nodeModulesDir = path68.join(pluginsDir, "node_modules");
27750
+ const pluginsDir = path69.join(root, "plugins");
27751
+ const nodeModulesDir = path69.join(pluginsDir, "node_modules");
27719
27752
  try {
27720
27753
  execFileSync8("npm", ["install", installSpec, "--prefix", pluginsDir, "--save"], {
27721
27754
  stdio: json ? "pipe" : "inherit",
@@ -27729,8 +27762,8 @@ async function installPlugin(input2, instanceRoot, json = false) {
27729
27762
  const cliVersion = getCurrentVersion2();
27730
27763
  const isLocalPath = pkgName.startsWith("/") || pkgName.startsWith(".");
27731
27764
  try {
27732
- const pluginRoot = isLocalPath ? path68.resolve(pkgName) : path68.join(nodeModulesDir, pkgName);
27733
- const installedPkgPath = path68.join(pluginRoot, "package.json");
27765
+ const pluginRoot = isLocalPath ? path69.resolve(pkgName) : path69.join(nodeModulesDir, pkgName);
27766
+ const installedPkgPath = path69.join(pluginRoot, "package.json");
27734
27767
  const { readFileSync: readFileSync19 } = await import("fs");
27735
27768
  const installedPkg = JSON.parse(readFileSync19(installedPkgPath, "utf-8"));
27736
27769
  const minVersion = installedPkg.engines?.openacp?.replace(/[>=^~\s]/g, "");
@@ -27745,7 +27778,7 @@ async function installPlugin(input2, instanceRoot, json = false) {
27745
27778
  }
27746
27779
  }
27747
27780
  }
27748
- const pluginModule = await import(path68.join(pluginRoot, installedPkg.main ?? "dist/index.js"));
27781
+ const pluginModule = await import(path69.join(pluginRoot, installedPkg.main ?? "dist/index.js"));
27749
27782
  const plugin2 = pluginModule.default;
27750
27783
  if (plugin2?.install) {
27751
27784
  const ctx = createInstallContext2({ pluginName: plugin2.name ?? pkgName, settingsManager, basePath });
@@ -27776,11 +27809,11 @@ async function installPlugin(input2, instanceRoot, json = false) {
27776
27809
  async function uninstallPlugin(name, purge, instanceRoot, json = false) {
27777
27810
  if (json) await muteForJson();
27778
27811
  const os33 = await import("os");
27779
- const path68 = await import("path");
27812
+ const path69 = await import("path");
27780
27813
  const fs57 = await import("fs");
27781
27814
  const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
27782
- const root = instanceRoot ?? path68.join(os33.homedir(), ".openacp");
27783
- const registryPath = path68.join(root, "plugins.json");
27815
+ const root = instanceRoot ?? path69.join(os33.homedir(), ".openacp");
27816
+ const registryPath = path69.join(root, "plugins.json");
27784
27817
  const registry = new PluginRegistry2(registryPath);
27785
27818
  await registry.load();
27786
27819
  const entry = registry.get(name);
@@ -27800,7 +27833,7 @@ async function uninstallPlugin(name, purge, instanceRoot, json = false) {
27800
27833
  if (plugin2?.uninstall) {
27801
27834
  const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
27802
27835
  const { createInstallContext: createInstallContext2 } = await Promise.resolve().then(() => (init_install_context(), install_context_exports));
27803
- const basePath = path68.join(root, "plugins", "data");
27836
+ const basePath = path69.join(root, "plugins", "data");
27804
27837
  const settingsManager = new SettingsManager2(basePath);
27805
27838
  const ctx = createInstallContext2({ pluginName: name, settingsManager, basePath });
27806
27839
  await plugin2.uninstall(ctx, { purge });
@@ -27808,7 +27841,7 @@ async function uninstallPlugin(name, purge, instanceRoot, json = false) {
27808
27841
  } catch {
27809
27842
  }
27810
27843
  if (purge) {
27811
- const pluginDir = path68.join(root, "plugins", name);
27844
+ const pluginDir = path69.join(root, "plugins", name);
27812
27845
  fs57.rmSync(pluginDir, { recursive: true, force: true });
27813
27846
  }
27814
27847
  registry.remove(name);
@@ -28638,13 +28671,13 @@ init_version();
28638
28671
  init_helpers();
28639
28672
  init_output();
28640
28673
  init_instance_hint();
28641
- import path38 from "path";
28674
+ import path39 from "path";
28642
28675
  import os17 from "os";
28643
28676
  import fs36 from "fs";
28644
28677
  async function cmdStart(args2 = [], instanceRoot) {
28645
28678
  const json = isJsonMode(args2);
28646
28679
  if (json) await muteForJson();
28647
- const root = instanceRoot ?? path38.join(os17.homedir(), ".openacp");
28680
+ const root = instanceRoot ?? path39.join(os17.homedir(), ".openacp");
28648
28681
  if (!json && wantsHelp(args2)) {
28649
28682
  console.log(`
28650
28683
  \x1B[1mopenacp start\x1B[0m \u2014 Start OpenACP as a background daemon
@@ -28670,7 +28703,7 @@ Requires an existing config \u2014 run 'openacp' first to set up.
28670
28703
  await checkAndPromptUpdate();
28671
28704
  const { startDaemon: startDaemon2, getPidPath: getPidPath2 } = await Promise.resolve().then(() => (init_daemon2(), daemon_exports));
28672
28705
  const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
28673
- const cm = new ConfigManager2(path38.join(root, "config.json"));
28706
+ const cm = new ConfigManager2(path39.join(root, "config.json"));
28674
28707
  if (await cm.exists()) {
28675
28708
  await cm.load();
28676
28709
  const config = cm.get();
@@ -28681,11 +28714,11 @@ Requires an existing config \u2014 run 'openacp' first to set up.
28681
28714
  process.exit(1);
28682
28715
  }
28683
28716
  if (json) {
28684
- let instanceId = path38.basename(root);
28717
+ let instanceId = path39.basename(root);
28685
28718
  try {
28686
28719
  const { getGlobalRoot: getGlobalRoot2 } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
28687
28720
  const { InstanceRegistry: InstanceRegistry2 } = await Promise.resolve().then(() => (init_instance_registry(), instance_registry_exports));
28688
- const reg = new InstanceRegistry2(path38.join(getGlobalRoot2(), "instances.json"));
28721
+ const reg = new InstanceRegistry2(path39.join(getGlobalRoot2(), "instances.json"));
28689
28722
  reg.load();
28690
28723
  const entry = reg.getByRoot(root);
28691
28724
  if (entry) instanceId = entry.id;
@@ -28693,7 +28726,7 @@ Requires an existing config \u2014 run 'openacp' first to set up.
28693
28726
  }
28694
28727
  let port = null;
28695
28728
  try {
28696
- const portStr = fs36.readFileSync(path38.join(root, "api.port"), "utf-8").trim();
28729
+ const portStr = fs36.readFileSync(path39.join(root, "api.port"), "utf-8").trim();
28697
28730
  port = parseInt(portStr) || null;
28698
28731
  } catch {
28699
28732
  port = config.api.port ?? null;
@@ -28702,7 +28735,7 @@ Requires an existing config \u2014 run 'openacp' first to set up.
28702
28735
  pid: result.pid,
28703
28736
  instanceId,
28704
28737
  name: config.instanceName ?? null,
28705
- directory: path38.dirname(root),
28738
+ directory: path39.dirname(root),
28706
28739
  dir: root,
28707
28740
  port
28708
28741
  });
@@ -28847,7 +28880,7 @@ the API for live updates. When stopped, edits config file directly.
28847
28880
  process.exit(1);
28848
28881
  }
28849
28882
  const root = instanceRoot ?? getGlobalRoot2();
28850
- const settingsManager = new SettingsManager2(pathMod.join(root, "plugins"));
28883
+ const settingsManager = new SettingsManager2(pathMod.join(root, "plugins", "data"));
28851
28884
  const port = readApiPort(void 0, instanceRoot);
28852
28885
  if (port !== null) {
28853
28886
  await runConfigEditor2(cm, "api", port, settingsManager);
@@ -28874,8 +28907,8 @@ start fresh with the setup wizard. The daemon must be stopped first.
28874
28907
  return;
28875
28908
  }
28876
28909
  const os33 = await import("os");
28877
- const path68 = await import("path");
28878
- const root = instanceRoot ?? path68.join(os33.homedir(), ".openacp");
28910
+ const path69 = await import("path");
28911
+ const root = instanceRoot ?? path69.join(os33.homedir(), ".openacp");
28879
28912
  const { getStatus: getStatus2, getPidPath: getPidPath2 } = await Promise.resolve().then(() => (init_daemon2(), daemon_exports));
28880
28913
  const status = getStatus2(getPidPath2(root));
28881
28914
  if (status.running) {
@@ -29033,11 +29066,11 @@ init_instance_context();
29033
29066
  init_status();
29034
29067
  init_output();
29035
29068
  init_helpers();
29036
- import path59 from "path";
29069
+ import path60 from "path";
29037
29070
  import os28 from "os";
29038
29071
  import fs52 from "fs";
29039
29072
  async function buildInstanceListEntries() {
29040
- const registryPath = path59.join(getGlobalRoot(), "instances.json");
29073
+ const registryPath = path60.join(getGlobalRoot(), "instances.json");
29041
29074
  const registry = new InstanceRegistry(registryPath);
29042
29075
  registry.load();
29043
29076
  return registry.list().map((entry) => {
@@ -29045,7 +29078,7 @@ async function buildInstanceListEntries() {
29045
29078
  return {
29046
29079
  id: entry.id,
29047
29080
  name: info.name,
29048
- directory: path59.dirname(entry.root),
29081
+ directory: path60.dirname(entry.root),
29049
29082
  root: entry.root,
29050
29083
  status: info.pid ? "running" : "stopped",
29051
29084
  port: info.apiPort
@@ -29118,9 +29151,9 @@ async function cmdInstancesCreate(args2) {
29118
29151
  const agentIdx = args2.indexOf("--agent");
29119
29152
  const agent = agentIdx !== -1 ? args2[agentIdx + 1] : void 0;
29120
29153
  const noInteractive = args2.includes("--no-interactive");
29121
- const resolvedDir = path59.resolve(rawDir.replace(/^~/, os28.homedir()));
29122
- const instanceRoot = path59.join(resolvedDir, ".openacp");
29123
- const registryPath = path59.join(getGlobalRoot(), "instances.json");
29154
+ const resolvedDir = path60.resolve(rawDir.replace(/^~/, os28.homedir()));
29155
+ const instanceRoot = path60.join(resolvedDir, ".openacp");
29156
+ const registryPath = path60.join(getGlobalRoot(), "instances.json");
29124
29157
  const registry = new InstanceRegistry(registryPath);
29125
29158
  registry.load();
29126
29159
  if (fs52.existsSync(instanceRoot)) {
@@ -29130,8 +29163,8 @@ async function cmdInstancesCreate(args2) {
29130
29163
  console.error(`Error: Instance already exists at ${resolvedDir} (id: ${existing.id})`);
29131
29164
  process.exit(1);
29132
29165
  }
29133
- const configPath = path59.join(instanceRoot, "config.json");
29134
- let name2 = path59.basename(resolvedDir);
29166
+ const configPath = path60.join(instanceRoot, "config.json");
29167
+ let name2 = path60.basename(resolvedDir);
29135
29168
  try {
29136
29169
  const config = JSON.parse(fs52.readFileSync(configPath, "utf-8"));
29137
29170
  name2 = config.instanceName ?? name2;
@@ -29146,15 +29179,15 @@ async function cmdInstancesCreate(args2) {
29146
29179
  const name = instanceName ?? `openacp-${registry.list().length + 1}`;
29147
29180
  const id = registry.uniqueId(generateSlug(name));
29148
29181
  if (rawFrom) {
29149
- const fromRoot = path59.join(path59.resolve(rawFrom.replace(/^~/, os28.homedir())), ".openacp");
29150
- if (!fs52.existsSync(path59.join(fromRoot, "config.json"))) {
29182
+ const fromRoot = path60.join(path60.resolve(rawFrom.replace(/^~/, os28.homedir())), ".openacp");
29183
+ if (!fs52.existsSync(path60.join(fromRoot, "config.json"))) {
29151
29184
  console.error(`Error: No OpenACP instance found at ${rawFrom}`);
29152
29185
  process.exit(1);
29153
29186
  }
29154
29187
  fs52.mkdirSync(instanceRoot, { recursive: true });
29155
29188
  const { copyInstance: copyInstance2 } = await Promise.resolve().then(() => (init_instance_copy(), instance_copy_exports));
29156
29189
  await copyInstance2(fromRoot, instanceRoot, {});
29157
- const configPath = path59.join(instanceRoot, "config.json");
29190
+ const configPath = path60.join(instanceRoot, "config.json");
29158
29191
  try {
29159
29192
  const config = JSON.parse(fs52.readFileSync(configPath, "utf-8"));
29160
29193
  config.instanceName = name;
@@ -29165,14 +29198,14 @@ async function cmdInstancesCreate(args2) {
29165
29198
  fs52.mkdirSync(instanceRoot, { recursive: true });
29166
29199
  const config = { instanceName: name, runMode: "daemon" };
29167
29200
  if (agent) config.defaultAgent = agent;
29168
- fs52.writeFileSync(path59.join(instanceRoot, "config.json"), JSON.stringify(config, null, 2));
29169
- fs52.writeFileSync(path59.join(instanceRoot, "plugins.json"), JSON.stringify({ version: 1, installed: {} }, null, 2));
29201
+ fs52.writeFileSync(path60.join(instanceRoot, "config.json"), JSON.stringify(config, null, 2));
29202
+ fs52.writeFileSync(path60.join(instanceRoot, "plugins.json"), JSON.stringify({ version: 1, installed: {} }, null, 2));
29170
29203
  } else {
29171
29204
  fs52.mkdirSync(instanceRoot, { recursive: true });
29172
29205
  const config = { instanceName: name, runMode: "daemon" };
29173
29206
  if (agent) config.defaultAgent = agent;
29174
- fs52.writeFileSync(path59.join(instanceRoot, "config.json"), JSON.stringify(config, null, 2));
29175
- fs52.writeFileSync(path59.join(instanceRoot, "plugins.json"), JSON.stringify({ version: 1, installed: {} }, null, 2));
29207
+ fs52.writeFileSync(path60.join(instanceRoot, "config.json"), JSON.stringify(config, null, 2));
29208
+ fs52.writeFileSync(path60.join(instanceRoot, "plugins.json"), JSON.stringify({ version: 1, installed: {} }, null, 2));
29176
29209
  console.log(`Instance created at ${resolvedDir}. Run 'openacp setup' inside that directory to configure it.`);
29177
29210
  }
29178
29211
  registry.register(id, instanceRoot);
@@ -29184,7 +29217,7 @@ async function outputInstance(json, { id, root }) {
29184
29217
  const entry = {
29185
29218
  id,
29186
29219
  name: info.name,
29187
- directory: path59.dirname(root),
29220
+ directory: path60.dirname(root),
29188
29221
  root,
29189
29222
  status: info.pid ? "running" : "stopped",
29190
29223
  port: info.apiPort
@@ -29193,7 +29226,7 @@ async function outputInstance(json, { id, root }) {
29193
29226
  jsonSuccess(entry);
29194
29227
  return;
29195
29228
  }
29196
- console.log(`Instance created: ${info.name ?? id} at ${path59.dirname(root)}`);
29229
+ console.log(`Instance created: ${info.name ?? id} at ${path60.dirname(root)}`);
29197
29230
  }
29198
29231
 
29199
29232
  // src/cli/commands/integrate.ts
@@ -29956,22 +29989,22 @@ Options:
29956
29989
  }
29957
29990
 
29958
29991
  // src/cli/commands/onboard.ts
29959
- import * as path60 from "path";
29992
+ import * as path61 from "path";
29960
29993
  async function cmdOnboard(instanceRoot) {
29961
29994
  const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
29962
29995
  const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
29963
29996
  const { PluginRegistry: PluginRegistry2 } = await Promise.resolve().then(() => (init_plugin_registry(), plugin_registry_exports));
29964
29997
  const { getGlobalRoot: getGlobalRoot2 } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
29965
29998
  const OPENACP_DIR = instanceRoot ?? getGlobalRoot2();
29966
- const PLUGINS_DATA_DIR = path60.join(OPENACP_DIR, "plugins", "data");
29967
- const REGISTRY_PATH = path60.join(OPENACP_DIR, "plugins.json");
29968
- const cm = new ConfigManager2(path60.join(OPENACP_DIR, "config.json"));
29999
+ const PLUGINS_DATA_DIR = path61.join(OPENACP_DIR, "plugins", "data");
30000
+ const REGISTRY_PATH = path61.join(OPENACP_DIR, "plugins.json");
30001
+ const cm = new ConfigManager2(path61.join(OPENACP_DIR, "config.json"));
29969
30002
  const settingsManager = new SettingsManager2(PLUGINS_DATA_DIR);
29970
30003
  const pluginRegistry = new PluginRegistry2(REGISTRY_PATH);
29971
30004
  await pluginRegistry.load();
29972
30005
  if (await cm.exists()) {
29973
30006
  const { runReconfigure: runReconfigure2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
29974
- await runReconfigure2(cm);
30007
+ await runReconfigure2(cm, settingsManager);
29975
30008
  } else {
29976
30009
  const { runSetup: runSetup2 } = await Promise.resolve().then(() => (init_setup(), setup_exports));
29977
30010
  await runSetup2(cm, { skipRunMode: true, settingsManager, pluginRegistry, instanceRoot: OPENACP_DIR });
@@ -29984,7 +30017,7 @@ init_instance_context();
29984
30017
  init_instance_registry();
29985
30018
  init_instance_hint();
29986
30019
  init_output();
29987
- import path61 from "path";
30020
+ import path62 from "path";
29988
30021
  import os29 from "os";
29989
30022
  import fs53 from "fs";
29990
30023
  import { randomUUID as randomUUID5 } from "crypto";
@@ -29992,9 +30025,9 @@ async function cmdDefault(command2, instanceRoot) {
29992
30025
  const args2 = command2 ? [command2] : [];
29993
30026
  const json = isJsonMode(args2);
29994
30027
  if (json) await muteForJson();
29995
- const root = instanceRoot ?? path61.join(os29.homedir(), ".openacp");
29996
- const pluginsDataDir = path61.join(root, "plugins", "data");
29997
- const registryPath = path61.join(root, "plugins.json");
30028
+ const root = instanceRoot ?? path62.join(os29.homedir(), ".openacp");
30029
+ const pluginsDataDir = path62.join(root, "plugins", "data");
30030
+ const registryPath = path62.join(root, "plugins.json");
29998
30031
  const forceForeground = command2 === "--foreground";
29999
30032
  if (command2 && !command2.startsWith("-")) {
30000
30033
  const { suggestMatch: suggestMatch2 } = await Promise.resolve().then(() => (init_suggest(), suggest_exports));
@@ -30026,7 +30059,7 @@ async function cmdDefault(command2, instanceRoot) {
30026
30059
  }
30027
30060
  await checkAndPromptUpdate();
30028
30061
  const { ConfigManager: ConfigManager2 } = await Promise.resolve().then(() => (init_config2(), config_exports));
30029
- const configPath = path61.join(root, "config.json");
30062
+ const configPath = path62.join(root, "config.json");
30030
30063
  const cm = new ConfigManager2(configPath);
30031
30064
  if (!await cm.exists()) {
30032
30065
  const { SettingsManager: SettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
@@ -30054,9 +30087,9 @@ async function cmdDefault(command2, instanceRoot) {
30054
30087
  process.exit(1);
30055
30088
  }
30056
30089
  if (json) {
30057
- let instanceId2 = path61.basename(root);
30090
+ let instanceId2 = path62.basename(root);
30058
30091
  try {
30059
- const reg2 = new InstanceRegistry(path61.join(getGlobalRoot(), "instances.json"));
30092
+ const reg2 = new InstanceRegistry(path62.join(getGlobalRoot(), "instances.json"));
30060
30093
  reg2.load();
30061
30094
  const entry = reg2.getByRoot(root);
30062
30095
  if (entry) instanceId2 = entry.id;
@@ -30064,7 +30097,7 @@ async function cmdDefault(command2, instanceRoot) {
30064
30097
  }
30065
30098
  let port = null;
30066
30099
  try {
30067
- const portStr = fs53.readFileSync(path61.join(root, "api.port"), "utf-8").trim();
30100
+ const portStr = fs53.readFileSync(path62.join(root, "api.port"), "utf-8").trim();
30068
30101
  port = parseInt(portStr) || null;
30069
30102
  } catch {
30070
30103
  port = config.api.port ?? null;
@@ -30073,7 +30106,7 @@ async function cmdDefault(command2, instanceRoot) {
30073
30106
  pid: result.pid,
30074
30107
  instanceId: instanceId2,
30075
30108
  name: config.instanceName ?? null,
30076
- directory: path61.dirname(root),
30109
+ directory: path62.dirname(root),
30077
30110
  dir: root,
30078
30111
  port
30079
30112
  });
@@ -30086,7 +30119,7 @@ async function cmdDefault(command2, instanceRoot) {
30086
30119
  markRunning2(root);
30087
30120
  printInstanceHint(root);
30088
30121
  const { startServer: startServer2 } = await Promise.resolve().then(() => (init_main(), main_exports));
30089
- const reg = new InstanceRegistry(path61.join(getGlobalRoot(), "instances.json"));
30122
+ const reg = new InstanceRegistry(path62.join(getGlobalRoot(), "instances.json"));
30090
30123
  reg.load();
30091
30124
  const existingEntry = reg.getByRoot(root);
30092
30125
  const instanceId = existingEntry?.id ?? randomUUID5();
@@ -30098,7 +30131,7 @@ async function cmdDefault(command2, instanceRoot) {
30098
30131
  if (json) {
30099
30132
  let port = null;
30100
30133
  try {
30101
- const portStr = fs53.readFileSync(path61.join(root, "api.port"), "utf-8").trim();
30134
+ const portStr = fs53.readFileSync(path62.join(root, "api.port"), "utf-8").trim();
30102
30135
  port = parseInt(portStr) || null;
30103
30136
  } catch {
30104
30137
  port = config.api.port ?? null;
@@ -30107,7 +30140,7 @@ async function cmdDefault(command2, instanceRoot) {
30107
30140
  pid: process.pid,
30108
30141
  instanceId,
30109
30142
  name: config.instanceName ?? null,
30110
- directory: path61.dirname(root),
30143
+ directory: path62.dirname(root),
30111
30144
  dir: root,
30112
30145
  port
30113
30146
  });
@@ -30176,7 +30209,7 @@ async function showAlreadyRunningMenu(root) {
30176
30209
  // src/cli/commands/dev.ts
30177
30210
  init_helpers();
30178
30211
  import fs54 from "fs";
30179
- import path62 from "path";
30212
+ import path63 from "path";
30180
30213
  async function cmdDev(args2 = []) {
30181
30214
  if (wantsHelp(args2)) {
30182
30215
  console.log(`
@@ -30203,12 +30236,12 @@ async function cmdDev(args2 = []) {
30203
30236
  console.error("Error: missing plugin path. Usage: openacp dev <plugin-path>");
30204
30237
  process.exit(1);
30205
30238
  }
30206
- const pluginPath = path62.resolve(pluginPathArg);
30239
+ const pluginPath = path63.resolve(pluginPathArg);
30207
30240
  if (!fs54.existsSync(pluginPath)) {
30208
30241
  console.error(`Error: plugin path does not exist: ${pluginPath}`);
30209
30242
  process.exit(1);
30210
30243
  }
30211
- const tsconfigPath = path62.join(pluginPath, "tsconfig.json");
30244
+ const tsconfigPath = path63.join(pluginPath, "tsconfig.json");
30212
30245
  const hasTsconfig = fs54.existsSync(tsconfigPath);
30213
30246
  if (hasTsconfig) {
30214
30247
  console.log("Compiling plugin TypeScript...");
@@ -30250,10 +30283,10 @@ async function cmdDev(args2 = []) {
30250
30283
 
30251
30284
  // src/cli/commands/attach.ts
30252
30285
  init_helpers();
30253
- import path63 from "path";
30286
+ import path64 from "path";
30254
30287
  import os30 from "os";
30255
30288
  async function cmdAttach(args2 = [], instanceRoot) {
30256
- const root = instanceRoot ?? path63.join(os30.homedir(), ".openacp");
30289
+ const root = instanceRoot ?? path64.join(os30.homedir(), ".openacp");
30257
30290
  if (wantsHelp(args2)) {
30258
30291
  console.log(`
30259
30292
  \x1B[1mopenacp attach\x1B[0m \u2014 Attach to a running daemon
@@ -30287,15 +30320,15 @@ Press Ctrl+C to detach.
30287
30320
  console.log("");
30288
30321
  const { spawn: spawn9 } = await import("child_process");
30289
30322
  const { expandHome: expandHome4 } = await Promise.resolve().then(() => (init_config2(), config_exports));
30290
- let logDir2 = path63.join(root, "logs");
30323
+ let logDir2 = path64.join(root, "logs");
30291
30324
  try {
30292
- const configPath = path63.join(root, "config.json");
30325
+ const configPath = path64.join(root, "config.json");
30293
30326
  const { readFileSync: readFileSync19 } = await import("fs");
30294
30327
  const config = JSON.parse(readFileSync19(configPath, "utf-8"));
30295
30328
  if (config.logging?.logDir) logDir2 = expandHome4(config.logging.logDir);
30296
30329
  } catch {
30297
30330
  }
30298
- const logFile = path63.join(logDir2, "openacp.log");
30331
+ const logFile = path64.join(logDir2, "openacp.log");
30299
30332
  const tail = spawn9("tail", ["-f", "-n", "50", logFile], { stdio: "inherit" });
30300
30333
  tail.on("error", (err) => {
30301
30334
  console.error(`Cannot tail log file: ${err.message}`);
@@ -30307,7 +30340,7 @@ Press Ctrl+C to detach.
30307
30340
  init_api_client();
30308
30341
  init_instance_registry();
30309
30342
  init_output();
30310
- import path64 from "path";
30343
+ import path65 from "path";
30311
30344
  import os31 from "os";
30312
30345
  import qrcode from "qrcode-terminal";
30313
30346
  async function cmdRemote(args2, instanceRoot) {
@@ -30323,7 +30356,7 @@ async function cmdRemote(args2, instanceRoot) {
30323
30356
  const scopes = scopesRaw ? scopesRaw.split(",").map((s) => s.trim()) : void 0;
30324
30357
  let resolvedInstanceRoot2 = instanceRoot;
30325
30358
  if (instanceId) {
30326
- const registryPath = path64.join(os31.homedir(), ".openacp", "instances.json");
30359
+ const registryPath = path65.join(os31.homedir(), ".openacp", "instances.json");
30327
30360
  const registry = new InstanceRegistry(registryPath);
30328
30361
  await registry.load();
30329
30362
  const entry = registry.get(instanceId);
@@ -30461,7 +30494,7 @@ function extractFlag(args2, flag) {
30461
30494
  // src/cli/commands/setup.ts
30462
30495
  init_output();
30463
30496
  import * as fs55 from "fs";
30464
- import * as path65 from "path";
30497
+ import * as path66 from "path";
30465
30498
  function parseFlag(args2, flag) {
30466
30499
  const idx = args2.indexOf(flag);
30467
30500
  return idx !== -1 ? args2[idx + 1] : void 0;
@@ -30489,7 +30522,7 @@ async function cmdSetup(args2, instanceRoot) {
30489
30522
  }
30490
30523
  const runMode = rawRunMode;
30491
30524
  const defaultAgent = agentRaw.split(",")[0].trim();
30492
- const configPath = path65.join(instanceRoot, "config.json");
30525
+ const configPath = path66.join(instanceRoot, "config.json");
30493
30526
  let existing = {};
30494
30527
  if (fs55.existsSync(configPath)) {
30495
30528
  try {
@@ -30597,7 +30630,7 @@ async function main() {
30597
30630
  if (envRoot) {
30598
30631
  const { createInstanceContext: createInstanceContext2, getGlobalRoot: getGlobal } = await Promise.resolve().then(() => (init_instance_context(), instance_context_exports));
30599
30632
  const { InstanceRegistry: InstanceRegistry2 } = await Promise.resolve().then(() => (init_instance_registry(), instance_registry_exports));
30600
- const registry = new InstanceRegistry2(path67.join(getGlobal(), "instances.json"));
30633
+ const registry = new InstanceRegistry2(path68.join(getGlobal(), "instances.json"));
30601
30634
  await registry.load();
30602
30635
  const entry = registry.getByRoot(envRoot);
30603
30636
  const { randomUUID: randomUUID6 } = await import("crypto");