@openacp/cli 2026.330.3 → 2026.331.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +19 -1
  2. package/dist/cli.d.ts +11 -0
  3. package/dist/cli.js +25134 -278
  4. package/dist/cli.js.map +1 -1
  5. package/dist/data/registry-snapshot.json +1 -1
  6. package/dist/index.d.ts +259 -30
  7. package/dist/index.js +17632 -404
  8. package/dist/index.js.map +1 -1
  9. package/package.json +2 -2
  10. package/dist/adapter-AWSI4GML.js +0 -13
  11. package/dist/adapter-AWSI4GML.js.map +0 -1
  12. package/dist/agent-catalog-SZQQERV7.js +0 -10
  13. package/dist/agent-catalog-SZQQERV7.js.map +0 -1
  14. package/dist/agent-dependencies-ED2ZTUHG.js +0 -23
  15. package/dist/agent-dependencies-ED2ZTUHG.js.map +0 -1
  16. package/dist/agent-registry-YOGP656W.js +0 -8
  17. package/dist/agent-registry-YOGP656W.js.map +0 -1
  18. package/dist/agent-store-5UHZH2XI.js +0 -8
  19. package/dist/agent-store-5UHZH2XI.js.map +0 -1
  20. package/dist/api-client-XTLRRFPX.js +0 -13
  21. package/dist/api-client-XTLRRFPX.js.map +0 -1
  22. package/dist/api-server-5VNYFWJE.js +0 -7
  23. package/dist/api-server-5VNYFWJE.js.map +0 -1
  24. package/dist/api-server-JLBDKCU4.js +0 -10
  25. package/dist/api-server-JLBDKCU4.js.map +0 -1
  26. package/dist/autostart-CUPZMKKC.js +0 -22
  27. package/dist/autostart-CUPZMKKC.js.map +0 -1
  28. package/dist/chunk-237WYH6H.js +0 -235
  29. package/dist/chunk-237WYH6H.js.map +0 -1
  30. package/dist/chunk-2HEFALTZ.js +0 -44
  31. package/dist/chunk-2HEFALTZ.js.map +0 -1
  32. package/dist/chunk-2KT6TROD.js +0 -129
  33. package/dist/chunk-2KT6TROD.js.map +0 -1
  34. package/dist/chunk-2R5XM3ES.js +0 -154
  35. package/dist/chunk-2R5XM3ES.js.map +0 -1
  36. package/dist/chunk-3EWTPOF7.js +0 -51
  37. package/dist/chunk-3EWTPOF7.js.map +0 -1
  38. package/dist/chunk-3NAFXVQM.js +0 -67
  39. package/dist/chunk-3NAFXVQM.js.map +0 -1
  40. package/dist/chunk-4WXALZA3.js +0 -45
  41. package/dist/chunk-4WXALZA3.js.map +0 -1
  42. package/dist/chunk-566W6INH.js +0 -83
  43. package/dist/chunk-566W6INH.js.map +0 -1
  44. package/dist/chunk-5HKQCYOI.js +0 -145
  45. package/dist/chunk-5HKQCYOI.js.map +0 -1
  46. package/dist/chunk-5OCGO27U.js +0 -125
  47. package/dist/chunk-5OCGO27U.js.map +0 -1
  48. package/dist/chunk-5WGVYX3C.js +0 -55
  49. package/dist/chunk-5WGVYX3C.js.map +0 -1
  50. package/dist/chunk-7ZCQF6QM.js +0 -27
  51. package/dist/chunk-7ZCQF6QM.js.map +0 -1
  52. package/dist/chunk-AFKX424Q.js +0 -92
  53. package/dist/chunk-AFKX424Q.js.map +0 -1
  54. package/dist/chunk-APS6UEFU.js +0 -259
  55. package/dist/chunk-APS6UEFU.js.map +0 -1
  56. package/dist/chunk-BTJHGSLM.js +0 -1116
  57. package/dist/chunk-BTJHGSLM.js.map +0 -1
  58. package/dist/chunk-CDAUYTVP.js +0 -41
  59. package/dist/chunk-CDAUYTVP.js.map +0 -1
  60. package/dist/chunk-FCTC7KDT.js +0 -101
  61. package/dist/chunk-FCTC7KDT.js.map +0 -1
  62. package/dist/chunk-FNRSWA2K.js +0 -1
  63. package/dist/chunk-FNRSWA2K.js.map +0 -1
  64. package/dist/chunk-GEOXPGCO.js +0 -650
  65. package/dist/chunk-GEOXPGCO.js.map +0 -1
  66. package/dist/chunk-IZ5UEZF7.js +0 -138
  67. package/dist/chunk-IZ5UEZF7.js.map +0 -1
  68. package/dist/chunk-KDU3ZEWT.js +0 -97
  69. package/dist/chunk-KDU3ZEWT.js.map +0 -1
  70. package/dist/chunk-LGFWH3AE.js +0 -26
  71. package/dist/chunk-LGFWH3AE.js.map +0 -1
  72. package/dist/chunk-MITTQMGZ.js +0 -543
  73. package/dist/chunk-MITTQMGZ.js.map +0 -1
  74. package/dist/chunk-MLF4W5R6.js +0 -101
  75. package/dist/chunk-MLF4W5R6.js.map +0 -1
  76. package/dist/chunk-MPGEHTGE.js +0 -679
  77. package/dist/chunk-MPGEHTGE.js.map +0 -1
  78. package/dist/chunk-OYSAN7UX.js +0 -15
  79. package/dist/chunk-OYSAN7UX.js.map +0 -1
  80. package/dist/chunk-PA6MNBG4.js +0 -190
  81. package/dist/chunk-PA6MNBG4.js.map +0 -1
  82. package/dist/chunk-QWVHCTCA.js +0 -172
  83. package/dist/chunk-QWVHCTCA.js.map +0 -1
  84. package/dist/chunk-R6KZYF7D.js +0 -231
  85. package/dist/chunk-R6KZYF7D.js.map +0 -1
  86. package/dist/chunk-S64CB6J3.js +0 -98
  87. package/dist/chunk-S64CB6J3.js.map +0 -1
  88. package/dist/chunk-TMVTSWVH.js +0 -228
  89. package/dist/chunk-TMVTSWVH.js.map +0 -1
  90. package/dist/chunk-UCIZM5SW.js +0 -3917
  91. package/dist/chunk-UCIZM5SW.js.map +0 -1
  92. package/dist/chunk-UWH7KIAA.js +0 -701
  93. package/dist/chunk-UWH7KIAA.js.map +0 -1
  94. package/dist/chunk-V2YZWYXT.js +0 -484
  95. package/dist/chunk-V2YZWYXT.js.map +0 -1
  96. package/dist/chunk-W26AUH5B.js +0 -61
  97. package/dist/chunk-W26AUH5B.js.map +0 -1
  98. package/dist/chunk-W4LK6WJP.js +0 -446
  99. package/dist/chunk-W4LK6WJP.js.map +0 -1
  100. package/dist/chunk-WQCJTU2C.js +0 -84
  101. package/dist/chunk-WQCJTU2C.js.map +0 -1
  102. package/dist/chunk-XBZIHNKV.js +0 -6410
  103. package/dist/chunk-XBZIHNKV.js.map +0 -1
  104. package/dist/chunk-ZSLHHQPQ.js +0 -282
  105. package/dist/chunk-ZSLHHQPQ.js.map +0 -1
  106. package/dist/config-KN6NKKPF.js +0 -20
  107. package/dist/config-KN6NKKPF.js.map +0 -1
  108. package/dist/config-editor-76RVZS4B.js +0 -10
  109. package/dist/config-editor-76RVZS4B.js.map +0 -1
  110. package/dist/config-registry-ZXAIJNYB.js +0 -17
  111. package/dist/config-registry-ZXAIJNYB.js.map +0 -1
  112. package/dist/context-NXXW62NJ.js +0 -9
  113. package/dist/context-NXXW62NJ.js.map +0 -1
  114. package/dist/core-plugins-BPZY7SEB.js +0 -22
  115. package/dist/core-plugins-BPZY7SEB.js.map +0 -1
  116. package/dist/daemon-XFEMMJSZ.js +0 -29
  117. package/dist/daemon-XFEMMJSZ.js.map +0 -1
  118. package/dist/dev-loader-7P3HZCIA.js +0 -37
  119. package/dist/dev-loader-7P3HZCIA.js.map +0 -1
  120. package/dist/doctor-AV6AUO22.js +0 -9
  121. package/dist/doctor-AV6AUO22.js.map +0 -1
  122. package/dist/file-service-HHB3JQIO.js +0 -8
  123. package/dist/file-service-HHB3JQIO.js.map +0 -1
  124. package/dist/install-cloudflared-JRJ4BSOM.js +0 -32
  125. package/dist/install-cloudflared-JRJ4BSOM.js.map +0 -1
  126. package/dist/install-context-EHYV5WRY.js +0 -77
  127. package/dist/install-context-EHYV5WRY.js.map +0 -1
  128. package/dist/install-jq-ISTGT263.js +0 -31
  129. package/dist/install-jq-ISTGT263.js.map +0 -1
  130. package/dist/integrate-JIEZYDOR.js +0 -371
  131. package/dist/integrate-JIEZYDOR.js.map +0 -1
  132. package/dist/log-YZ243M5G.js +0 -25
  133. package/dist/log-YZ243M5G.js.map +0 -1
  134. package/dist/main-VEJCG5PY.js +0 -654
  135. package/dist/main-VEJCG5PY.js.map +0 -1
  136. package/dist/menu-ALFN37IR.js +0 -15
  137. package/dist/menu-ALFN37IR.js.map +0 -1
  138. package/dist/notifications-MO23S7S3.js +0 -8
  139. package/dist/notifications-MO23S7S3.js.map +0 -1
  140. package/dist/plugin-create-EHL76ZZG.js +0 -966
  141. package/dist/plugin-create-EHL76ZZG.js.map +0 -1
  142. package/dist/plugin-installer-VSTYZSXC.js +0 -9
  143. package/dist/plugin-installer-VSTYZSXC.js.map +0 -1
  144. package/dist/plugin-registry-6J3YSFHF.js +0 -7
  145. package/dist/plugin-registry-6J3YSFHF.js.map +0 -1
  146. package/dist/plugin-search-MGKAL5JM.js +0 -39
  147. package/dist/plugin-search-MGKAL5JM.js.map +0 -1
  148. package/dist/post-upgrade-Y26S2ZQ7.js +0 -79
  149. package/dist/post-upgrade-Y26S2ZQ7.js.map +0 -1
  150. package/dist/read-text-file-DJBTITIB.js +0 -7
  151. package/dist/read-text-file-DJBTITIB.js.map +0 -1
  152. package/dist/registry-client-GTBWLXYU.js +0 -7
  153. package/dist/registry-client-GTBWLXYU.js.map +0 -1
  154. package/dist/security-2BA265LN.js +0 -8
  155. package/dist/security-2BA265LN.js.map +0 -1
  156. package/dist/settings-manager-B4UN2LAC.js +0 -7
  157. package/dist/settings-manager-B4UN2LAC.js.map +0 -1
  158. package/dist/setup-DISPNDEK.js +0 -802
  159. package/dist/setup-DISPNDEK.js.map +0 -1
  160. package/dist/speech-SG62JYIF.js +0 -9
  161. package/dist/speech-SG62JYIF.js.map +0 -1
  162. package/dist/suggest-RST5VOHB.js +0 -36
  163. package/dist/suggest-RST5VOHB.js.map +0 -1
  164. package/dist/telegram-L3YM6SQJ.js +0 -7
  165. package/dist/telegram-L3YM6SQJ.js.map +0 -1
  166. package/dist/tunnel-HWJ27WDH.js +0 -7
  167. package/dist/tunnel-HWJ27WDH.js.map +0 -1
  168. package/dist/tunnel-service-ZMO4THKE.js +0 -1261
  169. package/dist/tunnel-service-ZMO4THKE.js.map +0 -1
  170. package/dist/validators-GITLOFXC.js +0 -11
  171. package/dist/validators-GITLOFXC.js.map +0 -1
  172. package/dist/version-AXXV6IV2.js +0 -15
  173. package/dist/version-AXXV6IV2.js.map +0 -1
@@ -1,61 +0,0 @@
1
- // src/core/plugin/plugin-registry.ts
2
- import fs from "fs";
3
- import path from "path";
4
- var PluginRegistry = class {
5
- constructor(registryPath) {
6
- this.registryPath = registryPath;
7
- }
8
- data = { installed: {} };
9
- list() {
10
- return new Map(Object.entries(this.data.installed));
11
- }
12
- get(name) {
13
- return this.data.installed[name];
14
- }
15
- register(name, entry) {
16
- const now = (/* @__PURE__ */ new Date()).toISOString();
17
- this.data.installed[name] = { ...entry, installedAt: now, updatedAt: now };
18
- }
19
- remove(name) {
20
- delete this.data.installed[name];
21
- }
22
- setEnabled(name, enabled) {
23
- const entry = this.data.installed[name];
24
- if (!entry) return;
25
- entry.enabled = enabled;
26
- entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
27
- }
28
- updateVersion(name, version) {
29
- const entry = this.data.installed[name];
30
- if (!entry) return;
31
- entry.version = version;
32
- entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
33
- }
34
- listEnabled() {
35
- return new Map(Object.entries(this.data.installed).filter(([, e]) => e.enabled));
36
- }
37
- listBySource(source) {
38
- return new Map(Object.entries(this.data.installed).filter(([, e]) => e.source === source));
39
- }
40
- async load() {
41
- try {
42
- const content = fs.readFileSync(this.registryPath, "utf-8");
43
- const parsed = JSON.parse(content);
44
- if (parsed && typeof parsed.installed === "object") {
45
- this.data = parsed;
46
- }
47
- } catch {
48
- this.data = { installed: {} };
49
- }
50
- }
51
- async save() {
52
- const dir = path.dirname(this.registryPath);
53
- fs.mkdirSync(dir, { recursive: true });
54
- fs.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2));
55
- }
56
- };
57
-
58
- export {
59
- PluginRegistry
60
- };
61
- //# sourceMappingURL=chunk-W26AUH5B.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/core/plugin/plugin-registry.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\nexport interface PluginEntry {\n version: string\n installedAt: string\n updatedAt: string\n source: 'builtin' | 'npm' | 'local'\n enabled: boolean\n settingsPath: string\n description?: string\n}\n\ntype RegisterInput = Omit<PluginEntry, 'installedAt' | 'updatedAt'>\n\ninterface RegistryData {\n installed: Record<string, PluginEntry>\n}\n\nexport class PluginRegistry {\n private data: RegistryData = { installed: {} }\n\n constructor(private registryPath: string) {}\n\n list(): Map<string, PluginEntry> {\n return new Map(Object.entries(this.data.installed))\n }\n\n get(name: string): PluginEntry | undefined {\n return this.data.installed[name]\n }\n\n register(name: string, entry: RegisterInput): void {\n const now = new Date().toISOString()\n this.data.installed[name] = { ...entry, installedAt: now, updatedAt: now }\n }\n\n remove(name: string): void {\n delete this.data.installed[name]\n }\n\n setEnabled(name: string, enabled: boolean): void {\n const entry = this.data.installed[name]\n if (!entry) return\n entry.enabled = enabled\n entry.updatedAt = new Date().toISOString()\n }\n\n updateVersion(name: string, version: string): void {\n const entry = this.data.installed[name]\n if (!entry) return\n entry.version = version\n entry.updatedAt = new Date().toISOString()\n }\n\n listEnabled(): Map<string, PluginEntry> {\n return new Map(Object.entries(this.data.installed).filter(([, e]) => e.enabled))\n }\n\n listBySource(source: PluginEntry['source']): Map<string, PluginEntry> {\n return new Map(Object.entries(this.data.installed).filter(([, e]) => e.source === source))\n }\n\n async load(): Promise<void> {\n try {\n const content = fs.readFileSync(this.registryPath, 'utf-8')\n const parsed = JSON.parse(content)\n if (parsed && typeof parsed.installed === 'object') {\n this.data = parsed\n }\n } catch {\n this.data = { installed: {} }\n }\n }\n\n async save(): Promise<void> {\n const dir = path.dirname(this.registryPath)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(this.registryPath, JSON.stringify(this.data, null, 2))\n }\n}\n"],"mappings":";AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAkBV,IAAM,iBAAN,MAAqB;AAAA,EAG1B,YAAoB,cAAsB;AAAtB;AAAA,EAAuB;AAAA,EAFnC,OAAqB,EAAE,WAAW,CAAC,EAAE;AAAA,EAI7C,OAAiC;AAC/B,WAAO,IAAI,IAAI,OAAO,QAAQ,KAAK,KAAK,SAAS,CAAC;AAAA,EACpD;AAAA,EAEA,IAAI,MAAuC;AACzC,WAAO,KAAK,KAAK,UAAU,IAAI;AAAA,EACjC;AAAA,EAEA,SAAS,MAAc,OAA4B;AACjD,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAK,KAAK,UAAU,IAAI,IAAI,EAAE,GAAG,OAAO,aAAa,KAAK,WAAW,IAAI;AAAA,EAC3E;AAAA,EAEA,OAAO,MAAoB;AACzB,WAAO,KAAK,KAAK,UAAU,IAAI;AAAA,EACjC;AAAA,EAEA,WAAW,MAAc,SAAwB;AAC/C,UAAM,QAAQ,KAAK,KAAK,UAAU,IAAI;AACtC,QAAI,CAAC,MAAO;AACZ,UAAM,UAAU;AAChB,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EAC3C;AAAA,EAEA,cAAc,MAAc,SAAuB;AACjD,UAAM,QAAQ,KAAK,KAAK,UAAU,IAAI;AACtC,QAAI,CAAC,MAAO;AACZ,UAAM,UAAU;AAChB,UAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AAAA,EAC3C;AAAA,EAEA,cAAwC;AACtC,WAAO,IAAI,IAAI,OAAO,QAAQ,KAAK,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;AAAA,EACjF;AAAA,EAEA,aAAa,QAAyD;AACpE,WAAO,IAAI,IAAI,OAAO,QAAQ,KAAK,KAAK,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,MAAM,CAAC;AAAA,EAC3F;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI;AACF,YAAM,UAAU,GAAG,aAAa,KAAK,cAAc,OAAO;AAC1D,YAAM,SAAS,KAAK,MAAM,OAAO;AACjC,UAAI,UAAU,OAAO,OAAO,cAAc,UAAU;AAClD,aAAK,OAAO;AAAA,MACd;AAAA,IACF,QAAQ;AACN,WAAK,OAAO,EAAE,WAAW,CAAC,EAAE;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,MAAM,OAAsB;AAC1B,UAAM,MAAM,KAAK,QAAQ,KAAK,YAAY;AAC1C,OAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AACrC,OAAG,cAAc,KAAK,cAAc,KAAK,UAAU,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,EACxE;AACF;","names":[]}
@@ -1,446 +0,0 @@
1
- import {
2
- createChildLogger
3
- } from "./chunk-R6KZYF7D.js";
4
-
5
- // src/core/config/config.ts
6
- import { z } from "zod";
7
- import * as fs2 from "fs";
8
- import * as path2 from "path";
9
- import * as os2 from "os";
10
- import { EventEmitter } from "events";
11
-
12
- // src/core/config/config-migrations.ts
13
- import * as fs from "fs";
14
- import * as path from "path";
15
- import * as os from "os";
16
- var log = createChildLogger({ module: "config-migrations" });
17
- var migrations = [
18
- {
19
- name: "add-tunnel-section",
20
- apply(raw) {
21
- if (raw.tunnel) return false;
22
- raw.tunnel = {
23
- enabled: true,
24
- port: 3100,
25
- provider: "cloudflare",
26
- options: {},
27
- storeTtlMinutes: 60,
28
- auth: { enabled: false }
29
- };
30
- log.info("Added tunnel section to config (enabled by default with cloudflare)");
31
- return true;
32
- }
33
- },
34
- {
35
- name: "fix-agent-commands",
36
- apply(raw) {
37
- const COMMAND_MIGRATIONS = {
38
- "claude-agent-acp": ["claude", "claude-code"]
39
- };
40
- const agents = raw.agents;
41
- if (!agents || typeof agents !== "object") return false;
42
- let changed = false;
43
- for (const [agentName, agentDef] of Object.entries(agents)) {
44
- if (!agentDef || typeof agentDef !== "object" || !("command" in agentDef)) continue;
45
- const def = agentDef;
46
- if (typeof def.command !== "string") continue;
47
- for (const [correctCmd, legacyCmds] of Object.entries(COMMAND_MIGRATIONS)) {
48
- if (legacyCmds.includes(def.command)) {
49
- log.warn(
50
- { agent: agentName, oldCommand: def.command, newCommand: correctCmd },
51
- `Auto-migrating agent command: "${def.command}" \u2192 "${correctCmd}"`
52
- );
53
- def.command = correctCmd;
54
- changed = true;
55
- }
56
- }
57
- }
58
- return changed;
59
- }
60
- },
61
- {
62
- name: "migrate-agents-to-store",
63
- apply(raw) {
64
- const agentsJsonPath = path.join(os.homedir(), ".openacp", "agents.json");
65
- if (fs.existsSync(agentsJsonPath)) return false;
66
- const agents = raw.agents;
67
- if (!agents || Object.keys(agents).length === 0) return false;
68
- const COMMAND_TO_REGISTRY = {
69
- "claude-agent-acp": "claude-acp",
70
- "codex": "codex-acp"
71
- };
72
- const installed = {};
73
- for (const [key, val] of Object.entries(agents)) {
74
- const cfg = val;
75
- const command = typeof cfg.command === "string" ? cfg.command : "";
76
- const registryId = COMMAND_TO_REGISTRY[command] ?? null;
77
- installed[key] = {
78
- registryId,
79
- name: key.charAt(0).toUpperCase() + key.slice(1),
80
- version: "unknown",
81
- distribution: "custom",
82
- command: cfg.command,
83
- args: cfg.args ?? [],
84
- env: cfg.env ?? {},
85
- workingDirectory: cfg.workingDirectory ?? void 0,
86
- installedAt: (/* @__PURE__ */ new Date()).toISOString(),
87
- binaryPath: null
88
- };
89
- }
90
- fs.mkdirSync(path.dirname(agentsJsonPath), { recursive: true });
91
- fs.writeFileSync(agentsJsonPath, JSON.stringify({ version: 1, installed }, null, 2));
92
- raw.agents = {};
93
- return true;
94
- }
95
- },
96
- {
97
- name: "migrate-display-verbosity-to-output-mode",
98
- apply(raw) {
99
- const channels = raw.channels;
100
- if (!channels) return false;
101
- let changed = false;
102
- for (const [, channelCfg] of Object.entries(channels)) {
103
- if (!channelCfg || typeof channelCfg !== "object") continue;
104
- const cfg = channelCfg;
105
- if (cfg.displayVerbosity && !cfg.outputMode) {
106
- cfg.outputMode = cfg.displayVerbosity;
107
- changed = true;
108
- }
109
- }
110
- return changed;
111
- }
112
- }
113
- ];
114
- function applyMigrations(raw, migrationList = migrations) {
115
- let changed = false;
116
- for (const migration of migrationList) {
117
- if (migration.apply(raw)) {
118
- changed = true;
119
- }
120
- }
121
- return { changed };
122
- }
123
-
124
- // src/core/config/config.ts
125
- var log2 = createChildLogger({ module: "config" });
126
- var BaseChannelSchema = z.object({
127
- enabled: z.boolean().default(false),
128
- adapter: z.string().optional(),
129
- // package name for plugin adapters
130
- displayVerbosity: z.enum(["low", "medium", "high"]).optional(),
131
- outputMode: z.enum(["low", "medium", "high"]).optional()
132
- }).passthrough();
133
- var OPENACP_DIR = path2.join(os2.homedir(), ".openacp");
134
- var PLUGINS_DIR = path2.join(OPENACP_DIR, "plugins");
135
- var PLUGINS_DATA_DIR = path2.join(OPENACP_DIR, "plugins", "data");
136
- var REGISTRY_PATH = path2.join(OPENACP_DIR, "plugins.json");
137
- var AgentSchema = z.object({
138
- command: z.string(),
139
- args: z.array(z.string()).default([]),
140
- workingDirectory: z.string().optional(),
141
- env: z.record(z.string(), z.string()).default({})
142
- });
143
- var LoggingSchema = z.object({
144
- level: z.enum(["silent", "debug", "info", "warn", "error", "fatal"]).default("info"),
145
- logDir: z.string().default("~/.openacp/logs"),
146
- maxFileSize: z.union([z.string(), z.number()]).default("10m"),
147
- maxFiles: z.number().default(7),
148
- sessionLogRetentionDays: z.number().default(30)
149
- }).default({});
150
- var TunnelAuthSchema = z.object({
151
- enabled: z.boolean().default(false),
152
- token: z.string().optional()
153
- }).default({});
154
- var TunnelSchema = z.object({
155
- enabled: z.boolean().default(false),
156
- port: z.number().default(3100),
157
- provider: z.enum(["cloudflare", "ngrok", "bore", "tailscale"]).default("cloudflare"),
158
- options: z.record(z.string(), z.unknown()).default({}),
159
- maxUserTunnels: z.number().default(5),
160
- storeTtlMinutes: z.number().default(60),
161
- auth: TunnelAuthSchema
162
- }).default({});
163
- var UsageSchema = z.object({
164
- enabled: z.boolean().default(true),
165
- monthlyBudget: z.number().optional(),
166
- warningThreshold: z.number().default(0.8),
167
- currency: z.string().default("USD"),
168
- retentionDays: z.number().default(90)
169
- }).default({});
170
- var SpeechProviderSchema = z.object({
171
- apiKey: z.string().min(1).optional(),
172
- model: z.string().optional()
173
- }).passthrough();
174
- var SpeechSchema = z.object({
175
- stt: z.object({
176
- provider: z.string().nullable().default(null),
177
- providers: z.record(SpeechProviderSchema).default({})
178
- }).default({}),
179
- tts: z.object({
180
- provider: z.string().nullable().default(null),
181
- providers: z.record(SpeechProviderSchema).default({})
182
- }).default({})
183
- }).optional().default({});
184
- var ConfigSchema = z.object({
185
- channels: z.object({}).catchall(BaseChannelSchema),
186
- agents: z.record(z.string(), AgentSchema).optional().default({}),
187
- defaultAgent: z.string(),
188
- workspace: z.object({
189
- baseDir: z.string().default("~/openacp-workspace")
190
- }).default({}),
191
- security: z.object({
192
- allowedUserIds: z.array(z.string()).default([]),
193
- maxConcurrentSessions: z.number().default(20),
194
- sessionTimeoutMinutes: z.number().default(60)
195
- }).default({}),
196
- logging: LoggingSchema,
197
- runMode: z.enum(["foreground", "daemon"]).default("foreground"),
198
- autoStart: z.boolean().default(false),
199
- api: z.object({
200
- port: z.number().default(21420),
201
- host: z.string().default("127.0.0.1")
202
- }).default({}),
203
- sessionStore: z.object({
204
- ttlDays: z.number().default(30)
205
- }).default({}),
206
- tunnel: TunnelSchema,
207
- usage: UsageSchema,
208
- integrations: z.record(
209
- z.string(),
210
- z.object({
211
- installed: z.boolean(),
212
- installedAt: z.string().optional()
213
- })
214
- ).default({}),
215
- speech: SpeechSchema,
216
- outputMode: z.enum(["low", "medium", "high"]).default("medium").optional()
217
- });
218
- function expandHome(p) {
219
- if (p.startsWith("~")) {
220
- return path2.join(os2.homedir(), p.slice(1));
221
- }
222
- return p;
223
- }
224
- var DEFAULT_CONFIG = {
225
- channels: {
226
- telegram: {
227
- enabled: false,
228
- botToken: "YOUR_BOT_TOKEN_HERE",
229
- chatId: 0,
230
- notificationTopicId: null,
231
- assistantTopicId: null
232
- },
233
- discord: {
234
- enabled: false,
235
- botToken: "YOUR_DISCORD_BOT_TOKEN_HERE",
236
- guildId: "",
237
- forumChannelId: null,
238
- notificationChannelId: null,
239
- assistantThreadId: null
240
- }
241
- },
242
- agents: {
243
- claude: { command: "claude-agent-acp", args: [], env: {} },
244
- codex: { command: "codex", args: ["--acp"], env: {} }
245
- },
246
- defaultAgent: "claude",
247
- workspace: { baseDir: "~/openacp-workspace" },
248
- security: {
249
- allowedUserIds: [],
250
- maxConcurrentSessions: 20,
251
- sessionTimeoutMinutes: 60
252
- },
253
- sessionStore: { ttlDays: 30 },
254
- tunnel: {
255
- enabled: true,
256
- port: 3100,
257
- provider: "cloudflare",
258
- options: {},
259
- storeTtlMinutes: 60,
260
- auth: { enabled: false }
261
- },
262
- usage: {}
263
- };
264
- var ConfigManager = class extends EventEmitter {
265
- config;
266
- configPath;
267
- constructor() {
268
- super();
269
- this.configPath = process.env.OPENACP_CONFIG_PATH || expandHome("~/.openacp/config.json");
270
- }
271
- async load() {
272
- const dir = path2.dirname(this.configPath);
273
- fs2.mkdirSync(dir, { recursive: true });
274
- if (!fs2.existsSync(this.configPath)) {
275
- fs2.writeFileSync(
276
- this.configPath,
277
- JSON.stringify(DEFAULT_CONFIG, null, 2)
278
- );
279
- log2.info({ configPath: this.configPath }, "Config created");
280
- log2.info(
281
- "Please edit it with your channel credentials (Telegram bot token, Discord bot token, etc.), then restart."
282
- );
283
- process.exit(1);
284
- }
285
- const raw = JSON.parse(fs2.readFileSync(this.configPath, "utf-8"));
286
- const { changed: configUpdated } = applyMigrations(raw);
287
- if (configUpdated) {
288
- fs2.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));
289
- }
290
- this.applyEnvOverrides(raw);
291
- const result = ConfigSchema.safeParse(raw);
292
- if (!result.success) {
293
- log2.error("Config validation failed");
294
- for (const issue of result.error.issues) {
295
- log2.error(
296
- { path: issue.path.join("."), message: issue.message },
297
- "Validation error"
298
- );
299
- }
300
- process.exit(1);
301
- }
302
- this.config = result.data;
303
- }
304
- get() {
305
- return structuredClone(this.config);
306
- }
307
- async save(updates, changePath) {
308
- const oldConfig = this.config ? structuredClone(this.config) : void 0;
309
- const raw = JSON.parse(fs2.readFileSync(this.configPath, "utf-8"));
310
- this.deepMerge(raw, updates);
311
- const result = ConfigSchema.safeParse(raw);
312
- if (!result.success) {
313
- log2.error({ errors: result.error.issues }, "Config validation failed, not saving");
314
- return;
315
- }
316
- fs2.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));
317
- this.config = result.data;
318
- if (changePath) {
319
- const { getConfigValue } = await import("./config-registry-ZXAIJNYB.js");
320
- const value = getConfigValue(this.config, changePath);
321
- const oldValue = oldConfig ? getConfigValue(oldConfig, changePath) : void 0;
322
- this.emit("config:changed", { path: changePath, value, oldValue });
323
- }
324
- }
325
- resolveWorkspace(input) {
326
- if (!input) {
327
- const resolved2 = expandHome(this.config.workspace.baseDir);
328
- fs2.mkdirSync(resolved2, { recursive: true });
329
- return resolved2;
330
- }
331
- if (input.startsWith("/") || input.startsWith("~")) {
332
- const resolved2 = expandHome(input);
333
- fs2.mkdirSync(resolved2, { recursive: true });
334
- return resolved2;
335
- }
336
- const name = input.toLowerCase();
337
- const resolved = path2.join(expandHome(this.config.workspace.baseDir), name);
338
- fs2.mkdirSync(resolved, { recursive: true });
339
- return resolved;
340
- }
341
- async exists() {
342
- return fs2.existsSync(this.configPath);
343
- }
344
- getConfigPath() {
345
- return this.configPath;
346
- }
347
- async writeNew(config) {
348
- const dir = path2.dirname(this.configPath);
349
- fs2.mkdirSync(dir, { recursive: true });
350
- fs2.writeFileSync(this.configPath, JSON.stringify(config, null, 2));
351
- }
352
- applyEnvOverrides(raw) {
353
- const overrides = [
354
- ["OPENACP_TELEGRAM_BOT_TOKEN", ["channels", "telegram", "botToken"]],
355
- ["OPENACP_TELEGRAM_CHAT_ID", ["channels", "telegram", "chatId"]],
356
- ["OPENACP_DISCORD_BOT_TOKEN", ["channels", "discord", "botToken"]],
357
- ["OPENACP_DISCORD_GUILD_ID", ["channels", "discord", "guildId"]],
358
- ["OPENACP_SLACK_BOT_TOKEN", ["channels", "slack", "botToken"]],
359
- ["OPENACP_SLACK_APP_TOKEN", ["channels", "slack", "appToken"]],
360
- ["OPENACP_SLACK_SIGNING_SECRET", ["channels", "slack", "signingSecret"]],
361
- ["OPENACP_DEFAULT_AGENT", ["defaultAgent"]],
362
- ["OPENACP_RUN_MODE", ["runMode"]],
363
- ["OPENACP_API_PORT", ["api", "port"]]
364
- ];
365
- for (const [envVar, configPath] of overrides) {
366
- const value = process.env[envVar];
367
- if (value !== void 0) {
368
- let target = raw;
369
- for (let i = 0; i < configPath.length - 1; i++) {
370
- if (!target[configPath[i]]) target[configPath[i]] = {};
371
- target = target[configPath[i]];
372
- }
373
- const key = configPath[configPath.length - 1];
374
- target[key] = key === "chatId" || key === "port" ? Number(value) : value;
375
- }
376
- }
377
- if (process.env.OPENACP_LOG_LEVEL) {
378
- raw.logging = raw.logging || {};
379
- raw.logging.level = process.env.OPENACP_LOG_LEVEL;
380
- }
381
- if (process.env.OPENACP_LOG_DIR) {
382
- raw.logging = raw.logging || {};
383
- raw.logging.logDir = process.env.OPENACP_LOG_DIR;
384
- }
385
- if (process.env.OPENACP_DEBUG && !process.env.OPENACP_LOG_LEVEL) {
386
- raw.logging = raw.logging || {};
387
- raw.logging.level = "debug";
388
- }
389
- if (process.env.OPENACP_TUNNEL_ENABLED) {
390
- raw.tunnel = raw.tunnel || {};
391
- raw.tunnel.enabled = process.env.OPENACP_TUNNEL_ENABLED === "true";
392
- }
393
- if (process.env.OPENACP_TUNNEL_PORT) {
394
- raw.tunnel = raw.tunnel || {};
395
- raw.tunnel.port = Number(
396
- process.env.OPENACP_TUNNEL_PORT
397
- );
398
- }
399
- if (process.env.OPENACP_TUNNEL_PROVIDER) {
400
- raw.tunnel = raw.tunnel || {};
401
- raw.tunnel.provider = process.env.OPENACP_TUNNEL_PROVIDER;
402
- }
403
- if (process.env.OPENACP_SPEECH_STT_PROVIDER) {
404
- raw.speech = raw.speech || {};
405
- const speech = raw.speech;
406
- speech.stt = speech.stt || {};
407
- speech.stt.provider = process.env.OPENACP_SPEECH_STT_PROVIDER;
408
- }
409
- if (process.env.OPENACP_SPEECH_GROQ_API_KEY) {
410
- raw.speech = raw.speech || {};
411
- const speech = raw.speech;
412
- speech.stt = speech.stt || {};
413
- const stt = speech.stt;
414
- stt.providers = stt.providers || {};
415
- const providers = stt.providers;
416
- providers.groq = providers.groq || {};
417
- providers.groq.apiKey = process.env.OPENACP_SPEECH_GROQ_API_KEY;
418
- }
419
- }
420
- deepMerge(target, source) {
421
- for (const key of Object.keys(source)) {
422
- const val = source[key];
423
- if (val && typeof val === "object" && !Array.isArray(val)) {
424
- if (!target[key]) target[key] = {};
425
- this.deepMerge(
426
- target[key],
427
- val
428
- );
429
- } else {
430
- target[key] = val;
431
- }
432
- }
433
- }
434
- };
435
-
436
- export {
437
- applyMigrations,
438
- OPENACP_DIR,
439
- PLUGINS_DIR,
440
- PLUGINS_DATA_DIR,
441
- REGISTRY_PATH,
442
- ConfigSchema,
443
- expandHome,
444
- ConfigManager
445
- };
446
- //# sourceMappingURL=chunk-W4LK6WJP.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/core/config/config.ts","../../src/core/config/config-migrations.ts"],"sourcesContent":["import { z } from \"zod\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { EventEmitter } from \"node:events\";\nimport { applyMigrations } from \"./config-migrations.js\";\nimport { createChildLogger } from \"../utils/log.js\";\nconst log = createChildLogger({ module: \"config\" });\n\nconst BaseChannelSchema = z\n .object({\n enabled: z.boolean().default(false),\n adapter: z.string().optional(), // package name for plugin adapters\n displayVerbosity: z\n .enum([\"low\", \"medium\", \"high\"])\n .optional(),\n outputMode: z.enum([\"low\", \"medium\", \"high\"]).optional(),\n })\n .passthrough();\n\nexport const OPENACP_DIR = path.join(os.homedir(), \".openacp\");\nexport const PLUGINS_DIR = path.join(OPENACP_DIR, \"plugins\");\nexport const PLUGINS_DATA_DIR = path.join(OPENACP_DIR, \"plugins\", \"data\");\nexport const REGISTRY_PATH = path.join(OPENACP_DIR, \"plugins.json\");\n\nconst AgentSchema = z.object({\n command: z.string(),\n args: z.array(z.string()).default([]),\n workingDirectory: z.string().optional(),\n env: z.record(z.string(), z.string()).default({}),\n});\n\nconst LoggingSchema = z\n .object({\n level: z\n .enum([\"silent\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"])\n .default(\"info\"),\n logDir: z.string().default(\"~/.openacp/logs\"),\n maxFileSize: z.union([z.string(), z.number()]).default(\"10m\"),\n maxFiles: z.number().default(7),\n sessionLogRetentionDays: z.number().default(30),\n })\n .default({});\n\nexport type LoggingConfig = z.infer<typeof LoggingSchema>;\n\nconst TunnelAuthSchema = z\n .object({\n enabled: z.boolean().default(false),\n token: z.string().optional(),\n })\n .default({});\n\nconst TunnelSchema = z\n .object({\n enabled: z.boolean().default(false),\n port: z.number().default(3100),\n provider: z\n .enum([\"cloudflare\", \"ngrok\", \"bore\", \"tailscale\"])\n .default(\"cloudflare\"),\n options: z.record(z.string(), z.unknown()).default({}),\n maxUserTunnels: z.number().default(5),\n storeTtlMinutes: z.number().default(60),\n auth: TunnelAuthSchema,\n })\n .default({});\n\nexport type TunnelConfig = z.infer<typeof TunnelSchema>;\n\n\nconst UsageSchema = z\n .object({\n enabled: z.boolean().default(true),\n monthlyBudget: z.number().optional(),\n warningThreshold: z.number().default(0.8),\n currency: z.string().default(\"USD\"),\n retentionDays: z.number().default(90),\n })\n .default({});\n\nexport type UsageConfig = z.infer<typeof UsageSchema>;\n\nconst SpeechProviderSchema = z\n .object({\n apiKey: z.string().min(1).optional(),\n model: z.string().optional(),\n })\n .passthrough();\n\nconst SpeechSchema = z\n .object({\n stt: z\n .object({\n provider: z.string().nullable().default(null),\n providers: z.record(SpeechProviderSchema).default({}),\n })\n .default({}),\n tts: z\n .object({\n provider: z.string().nullable().default(null),\n providers: z.record(SpeechProviderSchema).default({}),\n })\n .default({}),\n })\n .optional()\n .default({});\n\nexport const ConfigSchema = z.object({\n channels: z\n .object({})\n .catchall(BaseChannelSchema),\n agents: z.record(z.string(), AgentSchema).optional().default({}),\n defaultAgent: z.string(),\n workspace: z\n .object({\n baseDir: z.string().default(\"~/openacp-workspace\"),\n })\n .default({}),\n security: z\n .object({\n allowedUserIds: z.array(z.string()).default([]),\n maxConcurrentSessions: z.number().default(20),\n sessionTimeoutMinutes: z.number().default(60),\n })\n .default({}),\n logging: LoggingSchema,\n runMode: z.enum([\"foreground\", \"daemon\"]).default(\"foreground\"),\n autoStart: z.boolean().default(false),\n api: z\n .object({\n port: z.number().default(21420),\n host: z.string().default(\"127.0.0.1\"),\n })\n .default({}),\n sessionStore: z\n .object({\n ttlDays: z.number().default(30),\n })\n .default({}),\n tunnel: TunnelSchema,\n usage: UsageSchema,\n integrations: z\n .record(\n z.string(),\n z.object({\n installed: z.boolean(),\n installedAt: z.string().optional(),\n }),\n )\n .default({}),\n speech: SpeechSchema,\n outputMode: z.enum([\"low\", \"medium\", \"high\"]).default(\"medium\").optional(),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nexport function expandHome(p: string): string {\n if (p.startsWith(\"~\")) {\n return path.join(os.homedir(), p.slice(1));\n }\n return p;\n}\n\nconst DEFAULT_CONFIG = {\n channels: {\n telegram: {\n enabled: false,\n botToken: \"YOUR_BOT_TOKEN_HERE\",\n chatId: 0,\n notificationTopicId: null,\n assistantTopicId: null,\n },\n discord: {\n enabled: false,\n botToken: \"YOUR_DISCORD_BOT_TOKEN_HERE\",\n guildId: \"\",\n forumChannelId: null,\n notificationChannelId: null,\n assistantThreadId: null,\n },\n },\n agents: {\n claude: { command: \"claude-agent-acp\", args: [], env: {} },\n codex: { command: \"codex\", args: [\"--acp\"], env: {} },\n },\n defaultAgent: \"claude\",\n workspace: { baseDir: \"~/openacp-workspace\" },\n security: {\n allowedUserIds: [],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n usage: {},\n};\n\nexport class ConfigManager extends EventEmitter {\n private config!: Config;\n private configPath: string;\n\n constructor() {\n super();\n this.configPath =\n process.env.OPENACP_CONFIG_PATH || expandHome(\"~/.openacp/config.json\");\n }\n\n async load(): Promise<void> {\n // 1. Ensure directory exists\n const dir = path.dirname(this.configPath);\n fs.mkdirSync(dir, { recursive: true });\n\n // 2. If config file doesn't exist, create default\n if (!fs.existsSync(this.configPath)) {\n fs.writeFileSync(\n this.configPath,\n JSON.stringify(DEFAULT_CONFIG, null, 2),\n );\n log.info({ configPath: this.configPath }, \"Config created\");\n log.info(\n \"Please edit it with your channel credentials (Telegram bot token, Discord bot token, etc.), then restart.\",\n );\n process.exit(1);\n }\n\n // 3. Read and parse\n const raw = JSON.parse(fs.readFileSync(this.configPath, \"utf-8\"));\n\n // 3.5. Auto-migrate config\n const { changed: configUpdated } = applyMigrations(raw);\n if (configUpdated) {\n fs.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));\n }\n\n // 4. Apply env var overrides\n this.applyEnvOverrides(raw);\n\n // 5. Validate with Zod\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n log.error(\"Config validation failed\");\n for (const issue of result.error.issues) {\n log.error(\n { path: issue.path.join(\".\"), message: issue.message },\n \"Validation error\",\n );\n }\n process.exit(1);\n }\n this.config = result.data;\n }\n\n get(): Config {\n return structuredClone(this.config);\n }\n\n async save(\n updates: Record<string, unknown>,\n changePath?: string,\n ): Promise<void> {\n const oldConfig = this.config ? structuredClone(this.config) : undefined;\n // Read current file, merge updates\n const raw = JSON.parse(fs.readFileSync(this.configPath, \"utf-8\"));\n this.deepMerge(raw, updates);\n // Validate BEFORE writing to disk\n const result = ConfigSchema.safeParse(raw);\n if (!result.success) {\n log.error({ errors: result.error.issues }, \"Config validation failed, not saving\");\n return;\n }\n fs.writeFileSync(this.configPath, JSON.stringify(raw, null, 2));\n this.config = result.data;\n // Emit change event if path provided\n if (changePath) {\n const { getConfigValue } = await import(\"./config-registry.js\");\n const value = getConfigValue(this.config, changePath);\n const oldValue = oldConfig\n ? getConfigValue(oldConfig, changePath)\n : undefined;\n this.emit(\"config:changed\", { path: changePath, value, oldValue });\n }\n }\n\n resolveWorkspace(input?: string): string {\n if (!input) {\n const resolved = expandHome(this.config.workspace.baseDir);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n if (input.startsWith(\"/\") || input.startsWith(\"~\")) {\n const resolved = expandHome(input);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n // Named workspace → lowercase, under baseDir\n const name = input.toLowerCase();\n const resolved = path.join(expandHome(this.config.workspace.baseDir), name);\n fs.mkdirSync(resolved, { recursive: true });\n return resolved;\n }\n\n async exists(): Promise<boolean> {\n return fs.existsSync(this.configPath);\n }\n\n getConfigPath(): string {\n return this.configPath;\n }\n\n async writeNew(config: Config): Promise<void> {\n const dir = path.dirname(this.configPath);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2));\n }\n\n private applyEnvOverrides(raw: Record<string, unknown>): void {\n const overrides: [string, string[]][] = [\n [\"OPENACP_TELEGRAM_BOT_TOKEN\", [\"channels\", \"telegram\", \"botToken\"]],\n [\"OPENACP_TELEGRAM_CHAT_ID\", [\"channels\", \"telegram\", \"chatId\"]],\n [\"OPENACP_DISCORD_BOT_TOKEN\", [\"channels\", \"discord\", \"botToken\"]],\n [\"OPENACP_DISCORD_GUILD_ID\", [\"channels\", \"discord\", \"guildId\"]],\n [\"OPENACP_SLACK_BOT_TOKEN\", [\"channels\", \"slack\", \"botToken\"]],\n [\"OPENACP_SLACK_APP_TOKEN\", [\"channels\", \"slack\", \"appToken\"]],\n [\"OPENACP_SLACK_SIGNING_SECRET\", [\"channels\", \"slack\", \"signingSecret\"]],\n [\"OPENACP_DEFAULT_AGENT\", [\"defaultAgent\"]],\n [\"OPENACP_RUN_MODE\", [\"runMode\"]],\n [\"OPENACP_API_PORT\", [\"api\", \"port\"]],\n ];\n for (const [envVar, configPath] of overrides) {\n const value = process.env[envVar];\n if (value !== undefined) {\n let target: Record<string, unknown> = raw;\n for (let i = 0; i < configPath.length - 1; i++) {\n if (!target[configPath[i]]) target[configPath[i]] = {};\n target = target[configPath[i]] as Record<string, unknown>;\n }\n const key = configPath[configPath.length - 1];\n // Convert numeric fields to number\n target[key] =\n key === \"chatId\" || key === \"port\" ? Number(value) : value;\n }\n }\n\n // Logging env var overrides\n if (process.env.OPENACP_LOG_LEVEL) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).level =\n process.env.OPENACP_LOG_LEVEL;\n }\n if (process.env.OPENACP_LOG_DIR) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).logDir =\n process.env.OPENACP_LOG_DIR;\n }\n if (process.env.OPENACP_DEBUG && !process.env.OPENACP_LOG_LEVEL) {\n raw.logging = raw.logging || {};\n (raw.logging as Record<string, unknown>).level = \"debug\";\n }\n\n // Tunnel env var overrides\n if (process.env.OPENACP_TUNNEL_ENABLED) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).enabled =\n process.env.OPENACP_TUNNEL_ENABLED === \"true\";\n }\n if (process.env.OPENACP_TUNNEL_PORT) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).port = Number(\n process.env.OPENACP_TUNNEL_PORT,\n );\n }\n if (process.env.OPENACP_TUNNEL_PROVIDER) {\n raw.tunnel = raw.tunnel || {};\n (raw.tunnel as Record<string, unknown>).provider =\n process.env.OPENACP_TUNNEL_PROVIDER;\n }\n\n // Speech env var overrides\n if (process.env.OPENACP_SPEECH_STT_PROVIDER) {\n raw.speech = raw.speech || {};\n const speech = raw.speech as Record<string, unknown>;\n speech.stt = speech.stt || {};\n (speech.stt as Record<string, unknown>).provider =\n process.env.OPENACP_SPEECH_STT_PROVIDER;\n }\n if (process.env.OPENACP_SPEECH_GROQ_API_KEY) {\n raw.speech = raw.speech || {};\n const speech = raw.speech as Record<string, unknown>;\n speech.stt = speech.stt || {};\n const stt = speech.stt as Record<string, unknown>;\n stt.providers = stt.providers || {};\n const providers = stt.providers as Record<string, unknown>;\n providers.groq = providers.groq || {};\n (providers.groq as Record<string, unknown>).apiKey =\n process.env.OPENACP_SPEECH_GROQ_API_KEY;\n }\n }\n\n private deepMerge(\n target: Record<string, unknown>,\n source: Record<string, unknown>,\n ): void {\n for (const key of Object.keys(source)) {\n const val = source[key];\n if (val && typeof val === \"object\" && !Array.isArray(val)) {\n if (!target[key]) target[key] = {};\n this.deepMerge(\n target[key] as Record<string, unknown>,\n val as Record<string, unknown>,\n );\n } else {\n target[key] = val;\n }\n }\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport { createChildLogger } from \"../utils/log.js\";\nconst log = createChildLogger({ module: \"config-migrations\" });\n\ntype RawConfig = Record<string, unknown>;\n\nexport interface Migration {\n name: string;\n apply: (raw: RawConfig) => boolean; // returns true if config was modified\n}\n\nexport const migrations: Migration[] = [\n {\n name: \"add-tunnel-section\",\n apply(raw) {\n if (raw.tunnel) return false;\n raw.tunnel = {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n storeTtlMinutes: 60,\n auth: { enabled: false },\n };\n log.info(\"Added tunnel section to config (enabled by default with cloudflare)\");\n return true;\n },\n },\n {\n name: \"fix-agent-commands\",\n apply(raw) {\n const COMMAND_MIGRATIONS: Record<string, string[]> = {\n \"claude-agent-acp\": [\"claude\", \"claude-code\"],\n };\n\n const agents = raw.agents;\n if (!agents || typeof agents !== \"object\") return false;\n\n let changed = false;\n for (const [agentName, agentDef] of Object.entries(agents as Record<string, unknown>)) {\n if (!agentDef || typeof agentDef !== \"object\" || !(\"command\" in agentDef)) continue;\n const def = agentDef as Record<string, unknown>;\n if (typeof def.command !== \"string\") continue;\n for (const [correctCmd, legacyCmds] of Object.entries(COMMAND_MIGRATIONS)) {\n if (legacyCmds.includes(def.command as string)) {\n log.warn(\n { agent: agentName, oldCommand: def.command, newCommand: correctCmd },\n `Auto-migrating agent command: \"${def.command}\" → \"${correctCmd}\"`,\n );\n def.command = correctCmd;\n changed = true;\n }\n }\n }\n return changed;\n },\n },\n {\n name: \"migrate-agents-to-store\",\n apply(raw) {\n const agentsJsonPath = path.join(os.homedir(), \".openacp\", \"agents.json\");\n if (fs.existsSync(agentsJsonPath)) return false;\n\n const agents = raw.agents as Record<string, unknown> | undefined;\n if (!agents || Object.keys(agents).length === 0) return false;\n\n const COMMAND_TO_REGISTRY: Record<string, string> = {\n \"claude-agent-acp\": \"claude-acp\",\n \"codex\": \"codex-acp\",\n };\n\n const installed: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(agents)) {\n const cfg = val as Record<string, unknown>;\n const command = typeof cfg.command === \"string\" ? cfg.command : \"\";\n const registryId = COMMAND_TO_REGISTRY[command] ?? null;\n installed[key] = {\n registryId,\n name: key.charAt(0).toUpperCase() + key.slice(1),\n version: \"unknown\",\n distribution: \"custom\",\n command: cfg.command,\n args: cfg.args ?? [],\n env: cfg.env ?? {},\n workingDirectory: cfg.workingDirectory ?? undefined,\n installedAt: new Date().toISOString(),\n binaryPath: null,\n };\n }\n\n fs.mkdirSync(path.dirname(agentsJsonPath), { recursive: true });\n fs.writeFileSync(agentsJsonPath, JSON.stringify({ version: 1, installed }, null, 2));\n\n raw.agents = {};\n return true;\n },\n },\n {\n name: \"migrate-display-verbosity-to-output-mode\",\n apply(raw) {\n const channels = raw.channels as Record<string, unknown> | undefined;\n if (!channels) return false;\n let changed = false;\n for (const [, channelCfg] of Object.entries(channels)) {\n if (!channelCfg || typeof channelCfg !== \"object\") continue;\n const cfg = channelCfg as Record<string, unknown>;\n if (cfg.displayVerbosity && !cfg.outputMode) {\n cfg.outputMode = cfg.displayVerbosity;\n changed = true;\n }\n }\n return changed;\n },\n },\n];\n\n/**\n * Apply all migrations to raw config (mutates in place).\n * Returns whether any changes were made.\n */\nexport function applyMigrations(\n raw: RawConfig,\n migrationList: Migration[] = migrations,\n): { changed: boolean } {\n let changed = false;\n for (const migration of migrationList) {\n if (migration.apply(raw)) {\n changed = true;\n }\n }\n return { changed };\n}\n"],"mappings":"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","names":["fs","path","os","log","resolved"]}
@@ -1,84 +0,0 @@
1
- // src/plugins/telegram/validators.ts
2
- async function validateBotToken(token) {
3
- try {
4
- const res = await fetch(`https://api.telegram.org/bot${token}/getMe`);
5
- const data = await res.json();
6
- if (data.ok && data.result) {
7
- return {
8
- ok: true,
9
- botName: data.result.first_name,
10
- botUsername: data.result.username
11
- };
12
- }
13
- return { ok: false, error: data.description || "Invalid token" };
14
- } catch (err) {
15
- return { ok: false, error: err.message };
16
- }
17
- }
18
- async function validateChatId(token, chatId) {
19
- try {
20
- const res = await fetch(`https://api.telegram.org/bot${token}/getChat`, {
21
- method: "POST",
22
- headers: { "Content-Type": "application/json" },
23
- body: JSON.stringify({ chat_id: chatId })
24
- });
25
- const data = await res.json();
26
- if (!data.ok || !data.result) {
27
- return { ok: false, error: data.description || "Invalid chat ID" };
28
- }
29
- if (data.result.type !== "supergroup") {
30
- return {
31
- ok: false,
32
- error: `Chat is "${data.result.type}", must be a supergroup`
33
- };
34
- }
35
- return {
36
- ok: true,
37
- title: data.result.title,
38
- isForum: data.result.is_forum === true
39
- };
40
- } catch (err) {
41
- return { ok: false, error: err.message };
42
- }
43
- }
44
- async function validateBotAdmin(token, chatId) {
45
- try {
46
- const meRes = await fetch(`https://api.telegram.org/bot${token}/getMe`);
47
- const meData = await meRes.json();
48
- if (!meData.ok || !meData.result) {
49
- return { ok: false, error: "Could not retrieve bot info" };
50
- }
51
- const res = await fetch(
52
- `https://api.telegram.org/bot${token}/getChatMember`,
53
- {
54
- method: "POST",
55
- headers: { "Content-Type": "application/json" },
56
- body: JSON.stringify({ chat_id: chatId, user_id: meData.result.id })
57
- }
58
- );
59
- const data = await res.json();
60
- if (!data.ok || !data.result) {
61
- return {
62
- ok: false,
63
- error: data.description || "Could not check bot membership"
64
- };
65
- }
66
- const { status } = data.result;
67
- if (status === "administrator" || status === "creator") {
68
- return { ok: true };
69
- }
70
- return {
71
- ok: false,
72
- error: `Bot is "${status}" in this group. It must be an admin. Please promote the bot to admin in group settings.`
73
- };
74
- } catch (err) {
75
- return { ok: false, error: err.message };
76
- }
77
- }
78
-
79
- export {
80
- validateBotToken,
81
- validateChatId,
82
- validateBotAdmin
83
- };
84
- //# sourceMappingURL=chunk-WQCJTU2C.js.map