@openacp/cli 0.6.10 → 2026.326.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/{action-detect-P7ZE4NEM.js → action-detect-QPA775HB.js} +2 -2
- package/dist/adapter-6ANPBSVU.js +16 -0
- package/dist/{discord-OMC52Y54.js → adapter-77ZCVABT.js} +520 -365
- package/dist/adapter-77ZCVABT.js.map +1 -0
- package/dist/{adapter-ZOANORGM.js → adapter-PQGHVG4K.js} +300 -93
- package/dist/adapter-PQGHVG4K.js.map +1 -0
- package/dist/{admin-6SYB6XCZ.js → admin-GBPZFFAU.js} +3 -3
- package/dist/agent-catalog-YHBFERYO.js +11 -0
- package/dist/{agent-dependencies-4OWBMZWZ.js → agent-dependencies-WS7Z2DFW.js} +2 -2
- package/dist/agent-registry-5LZT7CUB.js +9 -0
- package/dist/agent-store-VSHNY5GT.js +9 -0
- package/dist/{agents-QO7DKARJ.js → agents-BWU4MRRD.js} +3 -3
- package/dist/{api-client-CFQT5U7D.js → api-client-AQPNKXI2.js} +2 -2
- package/dist/api-server-3PYLRBCN.js +8 -0
- package/dist/api-server-CHVSUDBX.js +11 -0
- package/dist/{autostart-X33OGMX6.js → autostart-6JS565RY.js} +3 -3
- package/dist/chunk-2CX4IEEC.js +124 -0
- package/dist/chunk-2CX4IEEC.js.map +1 -0
- package/dist/{chunk-O7CPGUAI.js → chunk-4KGLKKQK.js} +4 -4
- package/dist/chunk-4KGLKKQK.js.map +1 -0
- package/dist/{chunk-W3EYKZNQ.js → chunk-4WXALZA3.js} +2 -2
- package/dist/chunk-4WXALZA3.js.map +1 -0
- package/dist/chunk-5OCGO27U.js +125 -0
- package/dist/chunk-5OCGO27U.js.map +1 -0
- package/dist/{chunk-OWP7RZ62.js → chunk-5ZOFBTOR.js} +118 -262
- package/dist/chunk-5ZOFBTOR.js.map +1 -0
- package/dist/chunk-6RXVEXF3.js +23 -0
- package/dist/chunk-6RXVEXF3.js.map +1 -0
- package/dist/{chunk-34M4OS5P.js → chunk-A6Y4GZM3.js} +3 -3
- package/dist/chunk-A6Y4GZM3.js.map +1 -0
- package/dist/chunk-AD3X6DGK.js +166 -0
- package/dist/chunk-AD3X6DGK.js.map +1 -0
- package/dist/{chunk-7QJS2XBD.js → chunk-AFKX424Q.js} +2 -2
- package/dist/chunk-AFKX424Q.js.map +1 -0
- package/dist/chunk-APS6UEFU.js +259 -0
- package/dist/chunk-APS6UEFU.js.map +1 -0
- package/dist/chunk-BLQUXO7S.js +113 -0
- package/dist/chunk-BLQUXO7S.js.map +1 -0
- package/dist/{chunk-WTZDAYZX.js → chunk-BQ6FR32N.js} +3 -3
- package/dist/chunk-BQ6FR32N.js.map +1 -0
- package/dist/chunk-FNRSWA2K.js +1 -0
- package/dist/chunk-FQEBWOZR.js +3557 -0
- package/dist/chunk-FQEBWOZR.js.map +1 -0
- package/dist/{chunk-4CTX774K.js → chunk-GJOY37U7.js} +4 -4
- package/dist/chunk-GJOY37U7.js.map +1 -0
- package/dist/{chunk-I7WC6E5S.js → chunk-HVBNCPAY.js} +2 -2
- package/dist/chunk-HVBNCPAY.js.map +1 -0
- package/dist/{chunk-2HMQOC7N.js → chunk-I3CGU5W7.js} +4 -4
- package/dist/chunk-I3CGU5W7.js.map +1 -0
- package/dist/{chunk-NVPG6JCL.js → chunk-L7YNNBI5.js} +3 -3
- package/dist/chunk-L7YNNBI5.js.map +1 -0
- package/dist/chunk-LGFWH3AE.js +26 -0
- package/dist/chunk-LGFWH3AE.js.map +1 -0
- package/dist/chunk-MLF4W5R6.js +101 -0
- package/dist/chunk-MLF4W5R6.js.map +1 -0
- package/dist/{chunk-KIRH7TUJ.js → chunk-MTSDOSXS.js} +3 -3
- package/dist/chunk-MTSDOSXS.js.map +1 -0
- package/dist/{chunk-J4SJTKIK.js → chunk-NAM4ERUW.js} +3 -3
- package/dist/chunk-NAM4ERUW.js.map +1 -0
- package/dist/{chunk-MKHUZLII.js → chunk-NBFIBGAT.js} +39 -25
- package/dist/chunk-NBFIBGAT.js.map +1 -0
- package/dist/{chunk-BNLGTZ34.js → chunk-O5RG4YZY.js} +3 -3
- package/dist/chunk-O5RG4YZY.js.map +1 -0
- package/dist/{chunk-JHYXKVV2.js → chunk-ODUM3D6X.js} +2 -2
- package/dist/chunk-ODUM3D6X.js.map +1 -0
- package/dist/chunk-OYSAN7UX.js +15 -0
- package/dist/chunk-OYSAN7UX.js.map +1 -0
- package/dist/chunk-P4SNGQNI.js +158 -0
- package/dist/chunk-P4SNGQNI.js.map +1 -0
- package/dist/{chunk-2CJ46J3C.js → chunk-PPSMUECX.js} +3 -3
- package/dist/chunk-PPSMUECX.js.map +1 -0
- package/dist/chunk-Q6ZXJTZB.js +56 -0
- package/dist/chunk-Q6ZXJTZB.js.map +1 -0
- package/dist/{chunk-XANPHG7W.js → chunk-QSDZDHNS.js} +7 -7
- package/dist/chunk-QSDZDHNS.js.map +1 -0
- package/dist/{chunk-33RP6K2O.js → chunk-QVMEF6FB.js} +6 -6
- package/dist/chunk-QVMEF6FB.js.map +1 -0
- package/dist/chunk-QWP76EBW.js +536 -0
- package/dist/chunk-QWP76EBW.js.map +1 -0
- package/dist/{chunk-V5GZQEIY.js → chunk-RBYBSSGO.js} +4 -4
- package/dist/chunk-RBYBSSGO.js.map +1 -0
- package/dist/{chunk-CS3KCJ5D.js → chunk-RKB2ZK6S.js} +555 -383
- package/dist/chunk-RKB2ZK6S.js.map +1 -0
- package/dist/{chunk-UKT3G5IA.js → chunk-SHTGQGAU.js} +7 -7
- package/dist/chunk-SHTGQGAU.js.map +1 -0
- package/dist/chunk-SNPYTMPR.js +51 -0
- package/dist/chunk-SNPYTMPR.js.map +1 -0
- package/dist/chunk-UB2QB6DE.js +124 -0
- package/dist/chunk-UB2QB6DE.js.map +1 -0
- package/dist/chunk-UNJUWWQO.js +1108 -0
- package/dist/chunk-UNJUWWQO.js.map +1 -0
- package/dist/chunk-V2M243KZ.js +445 -0
- package/dist/chunk-V2M243KZ.js.map +1 -0
- package/dist/chunk-V5JT5TPD.js +97 -0
- package/dist/chunk-V5JT5TPD.js.map +1 -0
- package/dist/chunk-W26AUH5B.js +61 -0
- package/dist/chunk-W26AUH5B.js.map +1 -0
- package/dist/chunk-WAAD23KY.js +222 -0
- package/dist/chunk-WAAD23KY.js.map +1 -0
- package/dist/chunk-WIIZNPCR.js +150 -0
- package/dist/chunk-WIIZNPCR.js.map +1 -0
- package/dist/chunk-WQCJTU2C.js +84 -0
- package/dist/chunk-WQCJTU2C.js.map +1 -0
- package/dist/chunk-WVLDNYOJ.js +150 -0
- package/dist/chunk-WVLDNYOJ.js.map +1 -0
- package/dist/chunk-WXVT3AOY.js +22 -0
- package/dist/chunk-WXVT3AOY.js.map +1 -0
- package/dist/{chunk-GAK6PIBW.js → chunk-XMMAGAT4.js} +2 -2
- package/dist/chunk-XMMAGAT4.js.map +1 -0
- package/dist/chunk-Y64XWMJ4.js +212 -0
- package/dist/chunk-Y64XWMJ4.js.map +1 -0
- package/dist/chunk-YEULD3SG.js +62 -0
- package/dist/chunk-YEULD3SG.js.map +1 -0
- package/dist/chunk-ZHGPZBS4.js +49 -0
- package/dist/chunk-ZHGPZBS4.js.map +1 -0
- package/dist/{chunk-JKBFUAJK.js → chunk-ZSLHHQPQ.js} +2 -2
- package/dist/chunk-ZSLHHQPQ.js.map +1 -0
- package/dist/cli.js +496 -150
- package/dist/cli.js.map +1 -1
- package/dist/{config-6S355X75.js → config-I4FMCJGZ.js} +3 -3
- package/dist/config-editor-HNEKXRLQ.js +11 -0
- package/dist/{config-registry-AHYI4MYL.js → config-registry-CUMNXFGK.js} +2 -2
- package/dist/context-XM6E22LM.js +10 -0
- package/dist/core-plugins-VEUNFTMB.js +27 -0
- package/dist/{daemon-4CS6HMB5.js → daemon-PXO5QPCR.js} +4 -4
- package/dist/dev-loader-RDC5E2CW.js +50 -0
- package/dist/dev-loader-RDC5E2CW.js.map +1 -0
- package/dist/discord-NOJQ5PZO.js +8 -0
- package/dist/doctor-H72BZOPA.js +10 -0
- package/dist/{doctor-OLYBO3V3.js → doctor-RF6BHMCC.js} +5 -5
- package/dist/file-service-EUODJAIT.js +9 -0
- package/dist/file-service-EUODJAIT.js.map +1 -0
- package/dist/index.d.ts +1293 -188
- package/dist/index.js +387 -48
- package/dist/index.js.map +1 -1
- package/dist/{install-cloudflared-Z7VCGOVG.js → install-cloudflared-AN24L4DP.js} +5 -5
- package/dist/install-cloudflared-AN24L4DP.js.map +1 -0
- package/dist/install-context-XPWTFT3J.js +78 -0
- package/dist/install-context-XPWTFT3J.js.map +1 -0
- package/dist/{install-jq-HUYSQWKR.js → install-jq-CRVDJGF3.js} +5 -5
- package/dist/install-jq-CRVDJGF3.js.map +1 -0
- package/dist/{integrate-PNEHRY2I.js → integrate-5C6KSU6D.js} +2 -2
- package/dist/integrate-5C6KSU6D.js.map +1 -0
- package/dist/{log-NXABYJTT.js → log-LZ7FTRKG.js} +2 -2
- package/dist/log-LZ7FTRKG.js.map +1 -0
- package/dist/main-T5WVCCFN.js +715 -0
- package/dist/main-T5WVCCFN.js.map +1 -0
- package/dist/{menu-YY5MKHEK.js → menu-YDQ2LWAR.js} +2 -2
- package/dist/menu-YDQ2LWAR.js.map +1 -0
- package/dist/{new-session-FEO4J4VU.js → new-session-AVQCNXRG.js} +5 -5
- package/dist/new-session-AVQCNXRG.js.map +1 -0
- package/dist/notifications-D5BRDNSU.js +9 -0
- package/dist/notifications-D5BRDNSU.js.map +1 -0
- package/dist/plugin-create-LYF5PP5W.js +327 -0
- package/dist/plugin-create-LYF5PP5W.js.map +1 -0
- package/dist/plugin-registry-WB3DR67H.js +8 -0
- package/dist/plugin-registry-WB3DR67H.js.map +1 -0
- package/dist/{post-upgrade-CJG5I7M2.js → post-upgrade-XLHZ6ZB7.js} +8 -8
- package/dist/post-upgrade-XLHZ6ZB7.js.map +1 -0
- package/dist/read-text-file-IRZM3QLM.js +8 -0
- package/dist/read-text-file-IRZM3QLM.js.map +1 -0
- package/dist/security-YNRBW6S7.js +9 -0
- package/dist/security-YNRBW6S7.js.map +1 -0
- package/dist/{session-IUSI7P5S.js → session-KZFA6Z26.js} +4 -4
- package/dist/session-KZFA6Z26.js.map +1 -0
- package/dist/{settings-RQPAM4KC.js → settings-MFYM7CZO.js} +4 -4
- package/dist/settings-MFYM7CZO.js.map +1 -0
- package/dist/settings-manager-MD2U4ZV2.js +8 -0
- package/dist/settings-manager-MD2U4ZV2.js.map +1 -0
- package/dist/{chunk-LCRLAV4G.js → setup-BAI2F24H.js} +154 -492
- package/dist/setup-BAI2F24H.js.map +1 -0
- package/dist/slack-KH7E3VBS.js +8 -0
- package/dist/slack-KH7E3VBS.js.map +1 -0
- package/dist/speech-2GHQNRIO.js +9 -0
- package/dist/speech-2GHQNRIO.js.map +1 -0
- package/dist/telegram-ZDC3JQF2.js +8 -0
- package/dist/telegram-ZDC3JQF2.js.map +1 -0
- package/dist/tunnel-M47I7H4B.js +8 -0
- package/dist/tunnel-M47I7H4B.js.map +1 -0
- package/dist/{tunnel-service-CJLUH6SZ.js → tunnel-service-WADYHREX.js} +17 -17
- package/dist/tunnel-service-WADYHREX.js.map +1 -0
- package/dist/usage-WYNK6ZC5.js +10 -0
- package/dist/usage-WYNK6ZC5.js.map +1 -0
- package/dist/validators-6CLEZUBD.js +8 -0
- package/dist/validators-6CLEZUBD.js.map +1 -0
- package/dist/validators-WSTBNKRW.js +12 -0
- package/dist/validators-WSTBNKRW.js.map +1 -0
- package/package.json +1 -1
- package/dist/adapter-ZOANORGM.js.map +0 -1
- package/dist/agent-catalog-FC3HGDEQ.js +0 -11
- package/dist/agent-registry-WT4NXPYG.js +0 -9
- package/dist/agent-store-VZLFPTZU.js +0 -9
- package/dist/chunk-2CJ46J3C.js.map +0 -1
- package/dist/chunk-2HMQOC7N.js.map +0 -1
- package/dist/chunk-33RP6K2O.js.map +0 -1
- package/dist/chunk-34M4OS5P.js.map +0 -1
- package/dist/chunk-4CTX774K.js.map +0 -1
- package/dist/chunk-7QJS2XBD.js.map +0 -1
- package/dist/chunk-BNLGTZ34.js.map +0 -1
- package/dist/chunk-CS3KCJ5D.js.map +0 -1
- package/dist/chunk-GAK6PIBW.js.map +0 -1
- package/dist/chunk-I7WC6E5S.js.map +0 -1
- package/dist/chunk-J4SJTKIK.js.map +0 -1
- package/dist/chunk-JHYXKVV2.js.map +0 -1
- package/dist/chunk-JKBFUAJK.js.map +0 -1
- package/dist/chunk-KIRH7TUJ.js.map +0 -1
- package/dist/chunk-LBIKITQT.js +0 -22
- package/dist/chunk-LBIKITQT.js.map +0 -1
- package/dist/chunk-LCRLAV4G.js.map +0 -1
- package/dist/chunk-LGP2YGRL.js +0 -4880
- package/dist/chunk-LGP2YGRL.js.map +0 -1
- package/dist/chunk-MKHUZLII.js.map +0 -1
- package/dist/chunk-NAMYZIS5.js +0 -1
- package/dist/chunk-NVPG6JCL.js.map +0 -1
- package/dist/chunk-O7CPGUAI.js.map +0 -1
- package/dist/chunk-OWP7RZ62.js.map +0 -1
- package/dist/chunk-UKT3G5IA.js.map +0 -1
- package/dist/chunk-V5GZQEIY.js.map +0 -1
- package/dist/chunk-VOIJ6OY4.js +0 -63
- package/dist/chunk-VOIJ6OY4.js.map +0 -1
- package/dist/chunk-W3EYKZNQ.js.map +0 -1
- package/dist/chunk-WTZDAYZX.js.map +0 -1
- package/dist/chunk-XANPHG7W.js.map +0 -1
- package/dist/config-editor-QQTZMWGD.js +0 -13
- package/dist/discord-OMC52Y54.js.map +0 -1
- package/dist/doctor-HZZ5BSHB.js +0 -10
- package/dist/install-cloudflared-Z7VCGOVG.js.map +0 -1
- package/dist/install-jq-HUYSQWKR.js.map +0 -1
- package/dist/integrate-PNEHRY2I.js.map +0 -1
- package/dist/main-XOZCLFUK.js +0 -238
- package/dist/main-XOZCLFUK.js.map +0 -1
- package/dist/post-upgrade-CJG5I7M2.js.map +0 -1
- package/dist/setup-XHS4OMPM.js +0 -37
- package/dist/tunnel-service-CJLUH6SZ.js.map +0 -1
- /package/dist/{action-detect-P7ZE4NEM.js.map → action-detect-QPA775HB.js.map} +0 -0
- /package/dist/{admin-6SYB6XCZ.js.map → adapter-6ANPBSVU.js.map} +0 -0
- /package/dist/{agent-catalog-FC3HGDEQ.js.map → admin-GBPZFFAU.js.map} +0 -0
- /package/dist/{agent-dependencies-4OWBMZWZ.js.map → agent-catalog-YHBFERYO.js.map} +0 -0
- /package/dist/{agent-registry-WT4NXPYG.js.map → agent-dependencies-WS7Z2DFW.js.map} +0 -0
- /package/dist/{agent-store-VZLFPTZU.js.map → agent-registry-5LZT7CUB.js.map} +0 -0
- /package/dist/{agents-QO7DKARJ.js.map → agent-store-VSHNY5GT.js.map} +0 -0
- /package/dist/{api-client-CFQT5U7D.js.map → agents-BWU4MRRD.js.map} +0 -0
- /package/dist/{autostart-X33OGMX6.js.map → api-client-AQPNKXI2.js.map} +0 -0
- /package/dist/{chunk-NAMYZIS5.js.map → api-server-3PYLRBCN.js.map} +0 -0
- /package/dist/{config-6S355X75.js.map → api-server-CHVSUDBX.js.map} +0 -0
- /package/dist/{config-editor-QQTZMWGD.js.map → autostart-6JS565RY.js.map} +0 -0
- /package/dist/{config-registry-AHYI4MYL.js.map → chunk-FNRSWA2K.js.map} +0 -0
- /package/dist/{daemon-4CS6HMB5.js.map → config-I4FMCJGZ.js.map} +0 -0
- /package/dist/{doctor-HZZ5BSHB.js.map → config-editor-HNEKXRLQ.js.map} +0 -0
- /package/dist/{doctor-OLYBO3V3.js.map → config-registry-CUMNXFGK.js.map} +0 -0
- /package/dist/{log-NXABYJTT.js.map → context-XM6E22LM.js.map} +0 -0
- /package/dist/{menu-YY5MKHEK.js.map → core-plugins-VEUNFTMB.js.map} +0 -0
- /package/dist/{new-session-FEO4J4VU.js.map → daemon-PXO5QPCR.js.map} +0 -0
- /package/dist/{session-IUSI7P5S.js.map → discord-NOJQ5PZO.js.map} +0 -0
- /package/dist/{settings-RQPAM4KC.js.map → doctor-H72BZOPA.js.map} +0 -0
- /package/dist/{setup-XHS4OMPM.js.map → doctor-RF6BHMCC.js.map} +0 -0
|
@@ -3,17 +3,12 @@ import {
|
|
|
3
3
|
isAutoStartInstalled,
|
|
4
4
|
isAutoStartSupported,
|
|
5
5
|
uninstallAutoStart
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
validateBotToken,
|
|
9
|
-
validateChatId,
|
|
10
|
-
validateDiscordToken
|
|
11
|
-
} from "./chunk-LCRLAV4G.js";
|
|
6
|
+
} from "./chunk-PPSMUECX.js";
|
|
12
7
|
import {
|
|
13
8
|
expandHome
|
|
14
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-QVMEF6FB.js";
|
|
15
10
|
|
|
16
|
-
// src/core/config-editor.ts
|
|
11
|
+
// src/core/config/config-editor.ts
|
|
17
12
|
import * as clack from "@clack/prompts";
|
|
18
13
|
async function select2(opts) {
|
|
19
14
|
const result = await clack.select({
|
|
@@ -104,11 +99,16 @@ async function editTelegram(config, updates) {
|
|
|
104
99
|
default: currentToken,
|
|
105
100
|
validate: (val) => val.trim().length > 0 || "Token cannot be empty"
|
|
106
101
|
});
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
try {
|
|
103
|
+
const { validateBotToken } = await import("./validators-WSTBNKRW.js");
|
|
104
|
+
const result = await validateBotToken(token.trim());
|
|
105
|
+
if (result.ok) {
|
|
106
|
+
console.log(ok(`Connected to @${result.botUsername}`));
|
|
107
|
+
} else {
|
|
108
|
+
console.log(warn(`Validation failed: ${result.error} \u2014 saving anyway`));
|
|
109
|
+
}
|
|
110
|
+
} catch {
|
|
111
|
+
console.log(warn("Telegram validator not available \u2014 skipping validation"));
|
|
112
112
|
}
|
|
113
113
|
const tgUp = ensureTelegramUpdates();
|
|
114
114
|
tgUp.botToken = token.trim();
|
|
@@ -131,11 +131,16 @@ async function editTelegram(config, updates) {
|
|
|
131
131
|
if (typeof tgUp2?.botToken === "string") return tgUp2.botToken;
|
|
132
132
|
return currentToken;
|
|
133
133
|
})();
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
134
|
+
try {
|
|
135
|
+
const { validateChatId } = await import("./validators-WSTBNKRW.js");
|
|
136
|
+
const result = await validateChatId(tokenForValidation, chatId);
|
|
137
|
+
if (result.ok) {
|
|
138
|
+
console.log(ok(`Group: ${result.title}${result.isForum ? "" : warn(" (topics not enabled)")}`));
|
|
139
|
+
} else {
|
|
140
|
+
console.log(warn(`Validation failed: ${result.error} \u2014 saving anyway`));
|
|
141
|
+
}
|
|
142
|
+
} catch {
|
|
143
|
+
console.log(warn("Telegram validator not available \u2014 skipping validation"));
|
|
139
144
|
}
|
|
140
145
|
const tgUp = ensureTelegramUpdates();
|
|
141
146
|
tgUp.chatId = chatId;
|
|
@@ -204,11 +209,20 @@ async function editDiscord(config, updates) {
|
|
|
204
209
|
default: currentToken,
|
|
205
210
|
validate: (val) => val.trim().length > 0 || "Token cannot be empty"
|
|
206
211
|
});
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
+
let tokenValid = true;
|
|
213
|
+
try {
|
|
214
|
+
const { validateDiscordToken } = await import("./validators-6CLEZUBD.js");
|
|
215
|
+
const tokenResult = await validateDiscordToken(token.trim());
|
|
216
|
+
if (tokenResult.ok) {
|
|
217
|
+
console.log(ok(`Connected as @${tokenResult.username}`));
|
|
218
|
+
} else {
|
|
219
|
+
console.log(warn(`Token validation failed: ${tokenResult.error}`));
|
|
220
|
+
tokenValid = false;
|
|
221
|
+
}
|
|
222
|
+
} catch {
|
|
223
|
+
console.log(warn("Discord validator not available \u2014 skipping validation"));
|
|
224
|
+
}
|
|
225
|
+
if (!tokenValid) {
|
|
212
226
|
const action = await select2({
|
|
213
227
|
message: "What to do?",
|
|
214
228
|
choices: [
|
|
@@ -703,7 +717,7 @@ ${c.cyan}${c.bold}OpenACP Config Editor${c.reset}`);
|
|
|
703
717
|
}
|
|
704
718
|
}
|
|
705
719
|
async function sendConfigViaApi(port, updates) {
|
|
706
|
-
const { apiCall: call } = await import("./api-client-
|
|
720
|
+
const { apiCall: call } = await import("./api-client-AQPNKXI2.js");
|
|
707
721
|
const paths = flattenToPaths(updates);
|
|
708
722
|
for (const { path, value } of paths) {
|
|
709
723
|
const res = await call(port, "/api/config", {
|
|
@@ -735,4 +749,4 @@ function flattenToPaths(obj, prefix = "") {
|
|
|
735
749
|
export {
|
|
736
750
|
runConfigEditor
|
|
737
751
|
};
|
|
738
|
-
//# sourceMappingURL=chunk-
|
|
752
|
+
//# sourceMappingURL=chunk-NBFIBGAT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/config/config-editor.ts"],"sourcesContent":["import * as clack from '@clack/prompts'\nimport type { Config, ConfigManager } from './config.js'\n\n// Compatibility wrappers — convert @inquirer/prompts API to @clack/prompts\nasync function select<T extends string>(opts: { message: string; choices: Array<{ name: string; value: T; description?: string }>; default?: T }): Promise<T> {\n const result = await clack.select({\n message: opts.message,\n options: opts.choices.map(ch => ({ label: ch.name, value: ch.value, hint: ch.description })) as any,\n initialValue: opts.default,\n })\n if (clack.isCancel(result)) { clack.cancel('Cancelled.'); process.exit(0) }\n return result as T\n}\n\nasync function input(opts: { message: string; default?: string; validate?: (val: string) => string | boolean }): Promise<string> {\n const result = await clack.text({\n message: opts.message,\n initialValue: opts.default,\n validate: opts.validate ? (val) => {\n const r = opts.validate!((val ?? \"\") as string)\n if (r === true || r === undefined) return undefined\n if (typeof r === 'string') return r\n return undefined\n } : undefined,\n })\n if (clack.isCancel(result)) { clack.cancel('Cancelled.'); process.exit(0) }\n return result as string\n}\n// Validators are lazy-loaded from plugins to avoid static core→plugin dependencies\n// They're only needed when user edits specific config sections\nimport { installAutoStart, uninstallAutoStart, isAutoStartInstalled, isAutoStartSupported } from '../../cli/autostart.js'\nimport { expandHome } from './config.js'\n\n// ANSI color helpers\nconst c = {\n reset: '\\x1b[0m',\n bold: '\\x1b[1m',\n dim: '\\x1b[2m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n cyan: '\\x1b[36m',\n}\n\nconst ok = (msg: string) => `${c.green}${c.bold}✓${c.reset} ${c.green}${msg}${c.reset}`\nconst warn = (msg: string) => `${c.yellow}⚠ ${msg}${c.reset}`\nconst dim = (msg: string) => `${c.dim}${msg}${c.reset}`\nconst header = (title: string) => `\\n${c.cyan}${c.bold}[${title}]${c.reset}\\n`\n\ntype ConfigUpdates = Record<string, unknown>\n\n// --- Edit: Telegram ---\n\nasync function editTelegram(config: Config, updates: ConfigUpdates): Promise<void> {\n const tg = (config.channels?.telegram ?? {}) as Record<string, unknown>\n const currentToken = (tg.botToken as string) ?? ''\n const currentChatId = (tg.chatId as number) ?? 0\n const currentEnabled = (tg.enabled as boolean) ?? false\n\n console.log(header('Telegram'))\n console.log(` Enabled : ${currentEnabled ? ok('yes') : dim('no')}`)\n const tokenDisplay = currentToken.length > 12\n ? currentToken.slice(0, 6) + '...' + currentToken.slice(-6)\n : currentToken || dim('(not set)')\n console.log(` Bot Token : ${tokenDisplay}`)\n console.log(` Chat ID : ${currentChatId || dim('(not set)')}`)\n console.log('')\n\n const ensureTelegramUpdates = () => {\n if (!updates.channels) updates.channels = {}\n if (!(updates.channels as Record<string, unknown>).telegram) {\n (updates.channels as Record<string, unknown>).telegram = {}\n }\n return (updates.channels as Record<string, unknown>).telegram as Record<string, unknown>\n }\n\n while (true) {\n const isEnabled = (() => {\n const ch = updates.channels as Record<string, unknown> | undefined\n const tgUp = ch?.telegram as Record<string, unknown> | undefined\n if (tgUp && 'enabled' in tgUp) return tgUp.enabled as boolean\n return currentEnabled\n })()\n\n const choice = await select({\n message: 'Telegram settings:',\n choices: [\n { name: isEnabled ? 'Disable Telegram' : 'Enable Telegram', value: 'toggle' },\n { name: 'Change Bot Token', value: 'token' },\n { name: 'Change Chat ID', value: 'chatid' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'toggle') {\n const tgUp = ensureTelegramUpdates()\n tgUp.enabled = !isEnabled\n console.log(!isEnabled ? ok('Telegram enabled') : ok('Telegram disabled'))\n }\n\n if (choice === 'token') {\n const token = await input({\n message: 'New bot token:',\n default: currentToken,\n validate: (val) => val.trim().length > 0 || 'Token cannot be empty',\n })\n\n try {\n const { validateBotToken } = await import('../../plugins/telegram/validators.js')\n const result = await validateBotToken(token.trim())\n if (result.ok) {\n console.log(ok(`Connected to @${result.botUsername}`))\n } else {\n console.log(warn(`Validation failed: ${result.error} — saving anyway`))\n }\n } catch {\n console.log(warn('Telegram validator not available — skipping validation'))\n }\n\n const tgUp = ensureTelegramUpdates()\n tgUp.botToken = token.trim()\n tgUp.enabled = true\n }\n\n if (choice === 'chatid') {\n const chatIdStr = await input({\n message: 'New chat ID (e.g. -1001234567890):',\n default: String(currentChatId),\n validate: (val) => {\n const n = Number(val.trim())\n if (isNaN(n) || !Number.isInteger(n)) return 'Chat ID must be an integer'\n return true\n },\n })\n\n const chatId = Number(chatIdStr.trim())\n\n // Use the current (or already-updated) token for validation\n const tokenForValidation = (() => {\n const ch = updates.channels as Record<string, unknown> | undefined\n const tgUp = ch?.telegram as Record<string, unknown> | undefined\n if (typeof tgUp?.botToken === 'string') return tgUp.botToken\n return currentToken\n })()\n\n try {\n const { validateChatId } = await import('../../plugins/telegram/validators.js')\n const result = await validateChatId(tokenForValidation, chatId)\n if (result.ok) {\n console.log(ok(`Group: ${result.title}${result.isForum ? '' : warn(' (topics not enabled)')}`))\n } else {\n console.log(warn(`Validation failed: ${result.error} — saving anyway`))\n }\n } catch {\n console.log(warn('Telegram validator not available — skipping validation'))\n }\n\n const tgUp = ensureTelegramUpdates()\n tgUp.chatId = chatId\n }\n }\n}\n\n// --- Edit: Discord ---\n\nasync function validateDiscordGuild(\n token: string,\n guildId: string,\n): Promise<{ ok: true; name: string } | { ok: false; error: string }> {\n try {\n const res = await fetch(`https://discord.com/api/v10/guilds/${guildId}`, {\n headers: { Authorization: `Bot ${token}` },\n })\n if (res.status === 200) {\n const data = (await res.json()) as { name: string }\n return { ok: true, name: data.name }\n }\n if (res.status === 403) {\n return { ok: false, error: 'Bot is not a member of this server. Invite the bot first.' }\n }\n return { ok: false, error: `Discord API returned ${res.status}` }\n } catch (err) {\n return { ok: false, error: (err as Error).message }\n }\n}\n\nasync function editDiscord(config: Config, updates: ConfigUpdates): Promise<void> {\n const dc = (config.channels?.discord ?? {}) as Record<string, unknown>\n const currentToken = (dc.botToken as string) ?? ''\n const currentGuildId = (dc.guildId as string) ?? ''\n const currentEnabled = (dc.enabled as boolean) ?? false\n\n console.log(header('Discord'))\n console.log(` Enabled : ${currentEnabled ? ok('yes') : dim('no')}`)\n const tokenDisplay = currentToken.length > 12\n ? currentToken.slice(0, 6) + '...' + currentToken.slice(-6)\n : currentToken || dim('(not set)')\n console.log(` Bot Token : ${tokenDisplay}`)\n console.log(` Guild ID : ${currentGuildId || dim('(not set)')}`)\n console.log('')\n\n // Helper to ensure discord updates object exists\n const ensureDiscordUpdates = () => {\n if (!updates.channels) updates.channels = {}\n if (!(updates.channels as Record<string, unknown>).discord) {\n (updates.channels as Record<string, unknown>).discord = {}\n }\n return (updates.channels as Record<string, unknown>).discord as Record<string, unknown>\n }\n\n while (true) {\n const isEnabled = (() => {\n const ch = updates.channels as Record<string, unknown> | undefined\n const dcUp = ch?.discord as Record<string, unknown> | undefined\n if (dcUp && 'enabled' in dcUp) return dcUp.enabled as boolean\n return currentEnabled\n })()\n\n const choice = await select({\n message: 'Discord settings:',\n choices: [\n { name: isEnabled ? 'Disable Discord' : 'Enable Discord', value: 'toggle' },\n { name: 'Configure Bot Token & Server', value: 'setup' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'toggle') {\n const dcUp = ensureDiscordUpdates()\n dcUp.enabled = !isEnabled\n console.log(!isEnabled ? ok('Discord enabled') : ok('Discord disabled'))\n }\n\n if (choice === 'setup') {\n // Step 1: Bot Token\n const token = await input({\n message: 'Bot token:',\n default: currentToken,\n validate: (val) => val.trim().length > 0 || 'Token cannot be empty',\n })\n\n let tokenValid = true\n try {\n const { validateDiscordToken } = await import('../../plugins/discord/validators.js')\n const tokenResult = await validateDiscordToken(token.trim())\n if (tokenResult.ok) {\n console.log(ok(`Connected as @${tokenResult.username}`))\n } else {\n console.log(warn(`Token validation failed: ${tokenResult.error}`))\n tokenValid = false\n }\n } catch {\n console.log(warn('Discord validator not available — skipping validation'))\n }\n if (!tokenValid) {\n const action = await select({\n message: 'What to do?',\n choices: [\n { name: 'Continue anyway', value: 'continue' },\n { name: 'Cancel', value: 'cancel' },\n ],\n })\n if (action === 'cancel') continue\n }\n\n // Step 2: Guild ID\n const guildIdStr = await input({\n message: 'Guild (server) ID:',\n default: currentGuildId,\n validate: (val) => {\n const trimmed = val.trim()\n if (!trimmed) return 'Guild ID cannot be empty'\n if (!/^\\d{17,20}$/.test(trimmed)) return 'Guild ID must be a numeric Discord snowflake (17-20 digits)'\n return true\n },\n })\n\n // Step 3: Validate guild with the token\n const validToken = token.trim()\n const validGuildId = guildIdStr.trim()\n const guildResult = await validateDiscordGuild(validToken, validGuildId)\n if (guildResult.ok) {\n console.log(ok(`Server: ${guildResult.name}`))\n } else {\n console.log(warn(`Guild validation failed: ${guildResult.error}`))\n const action = await select({\n message: 'What to do?',\n choices: [\n { name: 'Save anyway', value: 'continue' },\n { name: 'Cancel', value: 'cancel' },\n ],\n })\n if (action === 'cancel') continue\n }\n\n // Step 4: Save both + auto-enable\n const dcUp = ensureDiscordUpdates()\n dcUp.botToken = validToken\n dcUp.guildId = validGuildId\n dcUp.enabled = true\n // Clear old channel IDs so they get recreated on next start\n dcUp.forumChannelId = null\n dcUp.notificationChannelId = null\n dcUp.assistantThreadId = null\n console.log(ok('Discord configured and enabled'))\n }\n }\n}\n\n// --- Edit: Channels (parent menu) ---\n\nasync function editChannels(config: Config, updates: ConfigUpdates): Promise<void> {\n const tgEnabled = (config.channels?.telegram as Record<string, unknown>)?.enabled !== false && config.channels?.telegram\n const dcEnabled = (config.channels?.discord as Record<string, unknown>)?.enabled !== false && config.channels?.discord\n\n console.log(header('Channels'))\n console.log(` Telegram : ${tgEnabled ? ok('configured') : dim('not configured')}`)\n console.log(` Discord : ${dcEnabled ? ok('configured') : dim('not configured')}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Channel settings:',\n choices: [\n { name: 'Telegram', value: 'telegram' },\n { name: 'Discord', value: 'discord' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'telegram') await editTelegram(config, updates)\n if (choice === 'discord') await editDiscord(config, updates)\n }\n}\n\n// --- Edit: Agent ---\n\nasync function editAgent(config: Config, updates: ConfigUpdates): Promise<void> {\n const agentNames = Object.keys(config.agents ?? {})\n const currentDefault = config.defaultAgent\n\n console.log(header('Agent'))\n console.log(` Default agent : ${c.bold}${currentDefault}${c.reset}`)\n console.log(` Available : ${agentNames.join(', ') || dim('(none)')}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Agent settings:',\n choices: [\n { name: 'Change default agent', value: 'default' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'default') {\n if (agentNames.length === 0) {\n console.log(warn('No agents configured.'))\n continue\n }\n\n const chosen = await select({\n message: 'Select default agent:',\n choices: agentNames.map((name) => ({ name, value: name })),\n })\n\n updates.defaultAgent = chosen\n console.log(ok(`Default agent set to ${chosen}`))\n }\n }\n}\n\n// --- Edit: Workspace ---\n\nasync function editWorkspace(config: Config, updates: ConfigUpdates): Promise<void> {\n const currentDir = config.workspace?.baseDir ?? '~/openacp-workspace'\n\n console.log(header('Workspace'))\n console.log(` Base directory : ${currentDir}`)\n console.log('')\n\n const newDir = await input({\n message: 'Workspace base directory:',\n default: currentDir,\n validate: (val) => val.trim().length > 0 || 'Path cannot be empty',\n })\n\n updates.workspace = { baseDir: newDir.trim() }\n console.log(ok(`Workspace set to ${newDir.trim()}`))\n}\n\n// --- Edit: Security ---\n\nasync function editSecurity(config: Config, updates: ConfigUpdates): Promise<void> {\n const sec = config.security ?? { allowedUserIds: [], maxConcurrentSessions: 20, sessionTimeoutMinutes: 60 }\n\n console.log(header('Security'))\n console.log(` Allowed user IDs : ${sec.allowedUserIds?.length ? sec.allowedUserIds.join(', ') : dim('(all users allowed)')}`)\n console.log(` Max concurrent sessions : ${sec.maxConcurrentSessions}`)\n console.log(` Session timeout (min) : ${sec.sessionTimeoutMinutes}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Security settings:',\n choices: [\n { name: 'Max concurrent sessions', value: 'maxSessions' },\n { name: 'Session timeout (minutes)', value: 'timeout' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'maxSessions') {\n const val = await input({\n message: 'Max concurrent sessions:',\n default: String(sec.maxConcurrentSessions),\n validate: (v) => {\n const n = Number(v.trim())\n if (!Number.isInteger(n) || n < 1) return 'Must be a positive integer'\n return true\n },\n })\n\n if (!updates.security) updates.security = {}\n ;(updates.security as Record<string, unknown>).maxConcurrentSessions = Number(val.trim())\n console.log(ok(`Max concurrent sessions set to ${val.trim()}`))\n }\n\n if (choice === 'timeout') {\n const val = await input({\n message: 'Session timeout in minutes:',\n default: String(sec.sessionTimeoutMinutes),\n validate: (v) => {\n const n = Number(v.trim())\n if (!Number.isInteger(n) || n < 1) return 'Must be a positive integer'\n return true\n },\n })\n\n if (!updates.security) updates.security = {}\n ;(updates.security as Record<string, unknown>).sessionTimeoutMinutes = Number(val.trim())\n console.log(ok(`Session timeout set to ${val.trim()} minutes`))\n }\n }\n}\n\n// --- Edit: Logging ---\n\nasync function editLogging(config: Config, updates: ConfigUpdates): Promise<void> {\n const logging = config.logging ?? { level: 'info', logDir: '~/.openacp/logs', maxFileSize: '10m', maxFiles: 7, sessionLogRetentionDays: 30 }\n\n console.log(header('Logging'))\n console.log(` Log level : ${logging.level}`)\n console.log(` Log dir : ${logging.logDir}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Logging settings:',\n choices: [\n { name: 'Log level', value: 'level' },\n { name: 'Log directory', value: 'logDir' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (choice === 'level') {\n const level = await select({\n message: 'Select log level:',\n choices: [\n { name: 'silent', value: 'silent' },\n { name: 'debug', value: 'debug' },\n { name: 'info', value: 'info' },\n { name: 'warn', value: 'warn' },\n { name: 'error', value: 'error' },\n { name: 'fatal', value: 'fatal' },\n ],\n })\n\n if (!updates.logging) updates.logging = {}\n ;(updates.logging as Record<string, unknown>).level = level\n console.log(ok(`Log level set to ${level}`))\n }\n\n if (choice === 'logDir') {\n const dir = await input({\n message: 'Log directory:',\n default: logging.logDir,\n validate: (val) => val.trim().length > 0 || 'Path cannot be empty',\n })\n\n if (!updates.logging) updates.logging = {}\n ;(updates.logging as Record<string, unknown>).logDir = dir.trim()\n console.log(ok(`Log directory set to ${dir.trim()}`))\n }\n }\n}\n\n// --- Edit: Run Mode ---\n\nasync function editRunMode(config: Config, updates: ConfigUpdates): Promise<void> {\n const currentMode = config.runMode ?? 'foreground'\n const currentAutoStart = config.autoStart ?? false\n const autoStartInstalled = isAutoStartInstalled()\n const autoStartSupported = isAutoStartSupported()\n\n console.log(header('Run Mode'))\n console.log(` Current mode : ${c.bold}${currentMode}${c.reset}`)\n console.log(` Auto-start : ${currentAutoStart ? ok('enabled') : dim('disabled')}${autoStartInstalled ? ` ${dim('(installed)')}` : ''}`)\n console.log('')\n\n while (true) {\n const isDaemon = (() => {\n if ('runMode' in updates) return updates.runMode === 'daemon'\n return currentMode === 'daemon'\n })()\n\n const choices = [\n isDaemon\n ? { name: 'Switch to foreground mode', value: 'foreground' }\n : { name: 'Switch to daemon mode', value: 'daemon' },\n ]\n\n if (autoStartSupported) {\n const autoStartCurrent = (() => {\n if ('autoStart' in updates) return updates.autoStart as boolean\n return currentAutoStart\n })()\n choices.push({\n name: autoStartCurrent ? 'Disable auto-start' : 'Enable auto-start',\n value: 'toggleAutoStart',\n })\n }\n\n choices.push({ name: 'Back', value: 'back' })\n\n const choice = await select({\n message: 'Run mode settings:',\n choices,\n })\n\n if (choice === 'back') break\n\n if (choice === 'daemon') {\n updates.runMode = 'daemon'\n const logDir = (config.logging?.logDir) ?? '~/.openacp/logs'\n const result = installAutoStart(expandHome(logDir))\n if (result.success) {\n updates.autoStart = true\n console.log(ok('Switched to daemon mode with auto-start'))\n } else {\n console.log(warn(`Switched to daemon mode (auto-start failed: ${result.error})`))\n }\n }\n\n if (choice === 'foreground') {\n updates.runMode = 'foreground'\n updates.autoStart = false\n uninstallAutoStart()\n console.log(ok('Switched to foreground mode'))\n }\n\n if (choice === 'toggleAutoStart') {\n const autoStartCurrent = (() => {\n if ('autoStart' in updates) return updates.autoStart as boolean\n return currentAutoStart\n })()\n\n if (autoStartCurrent) {\n const result = uninstallAutoStart()\n updates.autoStart = false\n if (result.success) {\n console.log(ok('Auto-start disabled'))\n } else {\n console.log(warn(`Auto-start uninstall failed: ${result.error}`))\n }\n } else {\n const logDir = (config.logging?.logDir) ?? '~/.openacp/logs'\n const result = installAutoStart(expandHome(logDir))\n updates.autoStart = result.success\n if (result.success) {\n console.log(ok('Auto-start enabled'))\n } else {\n console.log(warn(`Auto-start install failed: ${result.error}`))\n }\n }\n }\n }\n}\n\n// --- Edit: API ---\n\nasync function editApi(config: Config, updates: ConfigUpdates): Promise<void> {\n const api = config.api ?? { port: 21420, host: '127.0.0.1' }\n\n console.log(header('API'))\n console.log(` Port : ${api.port}`)\n console.log(` Host : ${api.host} ${dim('(localhost only)')}`)\n console.log('')\n\n const newPort = await input({\n message: 'API port:',\n default: String(api.port),\n validate: (v) => {\n const n = Number(v.trim())\n if (!Number.isInteger(n) || n < 1 || n > 65535) return 'Must be a valid port (1-65535)'\n return true\n },\n })\n\n updates.api = { port: Number(newPort.trim()) }\n console.log(ok(`API port set to ${newPort.trim()}`))\n}\n\n// --- Edit: Tunnel ---\n\nasync function editTunnel(config: Config, updates: ConfigUpdates): Promise<void> {\n const tunnel = config.tunnel ?? { enabled: false, port: 3100, provider: 'cloudflare', options: {}, storeTtlMinutes: 60, auth: { enabled: false } }\n const currentUpdates = (updates.tunnel ?? {}) as Record<string, unknown>\n\n const getVal = <T>(key: string, fallback: T): T =>\n (key in currentUpdates ? currentUpdates[key] : (tunnel as Record<string, unknown>)[key] ?? fallback) as T\n\n console.log(header('Tunnel'))\n console.log(` Enabled : ${getVal('enabled', false) ? ok('yes') : dim('no')}`)\n console.log(` Provider : ${c.bold}${getVal('provider', 'cloudflare')}${c.reset}`)\n console.log(` Port : ${getVal('port', 3100)}`)\n const authEnabled = (getVal('auth', { enabled: false }) as { enabled: boolean }).enabled\n console.log(` Auth : ${authEnabled ? ok('enabled') : dim('disabled')}`)\n console.log('')\n\n while (true) {\n const choice = await select({\n message: 'Tunnel settings:',\n choices: [\n { name: getVal('enabled', false) ? 'Disable tunnel' : 'Enable tunnel', value: 'toggle' },\n { name: 'Change provider', value: 'provider' },\n { name: 'Change port', value: 'port' },\n { name: 'Provider options', value: 'options' },\n { name: authEnabled ? 'Disable auth' : 'Enable auth', value: 'auth' },\n { name: 'Back', value: 'back' },\n ],\n })\n\n if (choice === 'back') break\n\n if (!updates.tunnel) updates.tunnel = { ...tunnel }\n const tun = updates.tunnel as Record<string, unknown>\n\n if (choice === 'toggle') {\n const current = getVal('enabled', false)\n tun.enabled = !current\n console.log(!current ? ok('Tunnel enabled') : ok('Tunnel disabled'))\n }\n\n if (choice === 'provider') {\n const provider = await select({\n message: 'Select tunnel provider:',\n choices: [\n { name: 'Cloudflare (default)', value: 'cloudflare' },\n { name: 'ngrok', value: 'ngrok' },\n { name: 'bore', value: 'bore' },\n { name: 'Tailscale Funnel', value: 'tailscale' },\n ],\n })\n tun.provider = provider\n tun.options = {} // reset options when switching provider\n console.log(ok(`Provider set to ${provider}`))\n }\n\n if (choice === 'port') {\n const val = await input({\n message: 'Tunnel port:',\n default: String(getVal('port', 3100)),\n validate: (v) => {\n const n = Number(v.trim())\n if (!Number.isInteger(n) || n < 1 || n > 65535) return 'Must be a valid port (1-65535)'\n return true\n },\n })\n tun.port = Number(val.trim())\n console.log(ok(`Tunnel port set to ${val.trim()}`))\n }\n\n if (choice === 'options') {\n const provider = getVal('provider', 'cloudflare')\n const currentOptions = getVal('options', {}) as Record<string, unknown>\n await editProviderOptions(provider, currentOptions, tun)\n }\n\n if (choice === 'auth') {\n const currentAuth = getVal('auth', { enabled: false }) as { enabled: boolean; token?: string }\n if (currentAuth.enabled) {\n tun.auth = { enabled: false }\n console.log(ok('Tunnel auth disabled'))\n } else {\n const token = await input({\n message: 'Auth token (leave empty to auto-generate):',\n default: '',\n })\n tun.auth = token.trim()\n ? { enabled: true, token: token.trim() }\n : { enabled: true }\n console.log(ok('Tunnel auth enabled'))\n }\n }\n }\n}\n\nasync function editProviderOptions(\n provider: string,\n currentOptions: Record<string, unknown>,\n tun: Record<string, unknown>,\n): Promise<void> {\n if (provider === 'cloudflare') {\n const domain = await input({\n message: 'Custom domain (leave empty for random):',\n default: (currentOptions.domain as string) ?? '',\n })\n tun.options = domain.trim() ? { domain: domain.trim() } : {}\n if (domain.trim()) console.log(ok(`Domain set to ${domain.trim()}`))\n else console.log(dim('Using random cloudflare domain'))\n } else if (provider === 'ngrok') {\n const authtoken = await input({\n message: 'ngrok authtoken (leave empty to skip):',\n default: (currentOptions.authtoken as string) ?? '',\n })\n const domain = await input({\n message: 'ngrok domain (leave empty for random):',\n default: (currentOptions.domain as string) ?? '',\n })\n const region = await input({\n message: 'ngrok region (us, eu, ap — leave empty for default):',\n default: (currentOptions.region as string) ?? '',\n })\n const opts: Record<string, string> = {}\n if (authtoken.trim()) opts.authtoken = authtoken.trim()\n if (domain.trim()) opts.domain = domain.trim()\n if (region.trim()) opts.region = region.trim()\n tun.options = opts\n console.log(ok('ngrok options saved'))\n } else if (provider === 'bore') {\n const server = await input({\n message: 'bore server:',\n default: (currentOptions.server as string) ?? 'bore.pub',\n })\n const port = await input({\n message: 'bore port (leave empty for auto):',\n default: currentOptions.port ? String(currentOptions.port) : '',\n })\n const secret = await input({\n message: 'bore secret (leave empty to skip):',\n default: (currentOptions.secret as string) ?? '',\n })\n const opts: Record<string, unknown> = { server: server.trim() }\n if (port.trim()) opts.port = Number(port.trim())\n if (secret.trim()) opts.secret = secret.trim()\n tun.options = opts\n console.log(ok('bore options saved'))\n } else if (provider === 'tailscale') {\n const bg = await select({\n message: 'Run Tailscale Funnel in background?',\n choices: [\n { name: 'No', value: 'no' },\n { name: 'Yes', value: 'yes' },\n ],\n })\n tun.options = bg === 'yes' ? { bg: true } : {}\n console.log(ok('Tailscale options saved'))\n } else {\n console.log(dim(`No configurable options for provider \"${provider}\"`))\n }\n}\n\n// --- Main Config Editor ---\n\nexport async function runConfigEditor(\n configManager: ConfigManager,\n mode: 'file' | 'api' = 'file',\n apiPort?: number,\n): Promise<void> {\n await configManager.load()\n const config = configManager.get()\n const updates: ConfigUpdates = {}\n\n console.log(`\\n${c.cyan}${c.bold}OpenACP Config Editor${c.reset}`)\n console.log(dim(`Config: ${configManager.getConfigPath()}`))\n console.log('')\n\n try {\n while (true) {\n const hasChanges = mode === 'file' ? Object.keys(updates).length > 0 : false\n const choice = await select({\n message: `What would you like to edit?${hasChanges ? ` ${c.yellow}(unsaved changes)${c.reset}` : ''}`,\n choices: [\n { name: 'Channels', value: 'channels' },\n { name: 'Agent', value: 'agent' },\n { name: 'Workspace', value: 'workspace' },\n { name: 'Security', value: 'security' },\n { name: 'Logging', value: 'logging' },\n { name: 'Run Mode', value: 'runMode' },\n { name: 'API', value: 'api' },\n { name: 'Tunnel', value: 'tunnel' },\n { name: hasChanges ? 'Save & Exit' : 'Exit', value: 'exit' },\n ],\n })\n\n if (choice === 'exit') {\n if (mode === 'file' && hasChanges) {\n await configManager.save(updates)\n console.log(ok(`Config saved to ${configManager.getConfigPath()}`))\n } else if (mode === 'file') {\n console.log(dim('No changes made.'))\n }\n break\n }\n\n const sectionUpdates: ConfigUpdates = {}\n\n if (choice === 'channels') await editChannels(config, sectionUpdates)\n else if (choice === 'agent') await editAgent(config, sectionUpdates)\n else if (choice === 'workspace') await editWorkspace(config, sectionUpdates)\n else if (choice === 'security') await editSecurity(config, sectionUpdates)\n else if (choice === 'logging') await editLogging(config, sectionUpdates)\n else if (choice === 'runMode') await editRunMode(config, sectionUpdates)\n else if (choice === 'api') await editApi(config, sectionUpdates)\n else if (choice === 'tunnel') await editTunnel(config, sectionUpdates)\n\n if (mode === 'api' && Object.keys(sectionUpdates).length > 0) {\n await sendConfigViaApi(apiPort!, sectionUpdates)\n // Refresh in-memory config\n await configManager.load()\n Object.assign(config, configManager.get())\n } else {\n // Accumulate for file mode\n Object.assign(updates, sectionUpdates)\n }\n }\n } catch (err) {\n if ((err as Error).name === 'ExitPromptError') {\n console.log(dim('\\nConfig editor cancelled. Changes discarded.'))\n return\n }\n throw err\n }\n}\n\nasync function sendConfigViaApi(port: number, updates: ConfigUpdates): Promise<void> {\n const { apiCall: call } = await import('../../cli/api-client.js')\n\n const paths = flattenToPaths(updates)\n for (const { path, value } of paths) {\n const res = await call(port, '/api/config', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ path, value }),\n })\n const data = await res.json() as Record<string, unknown>\n if (!res.ok) {\n console.log(warn(`Failed to update ${path}: ${data.error}`))\n } else if (data.needsRestart) {\n console.log(warn(`${path} updated — restart required`))\n }\n }\n}\n\nfunction flattenToPaths(obj: Record<string, unknown>, prefix = ''): Array<{ path: string; value: unknown }> {\n const result: Array<{ path: string; value: unknown }> = []\n for (const [key, val] of Object.entries(obj)) {\n const fullPath = prefix ? `${prefix}.${key}` : key\n if (val && typeof val === 'object' && !Array.isArray(val)) {\n result.push(...flattenToPaths(val as Record<string, unknown>, fullPath))\n } else {\n result.push({ path: fullPath, value: val })\n }\n }\n return result\n}\n"],"mappings":"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","names":["select","tgUp"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
log
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XMMAGAT4.js";
|
|
4
4
|
|
|
5
|
-
// src/
|
|
5
|
+
// src/plugins/discord/forums.ts
|
|
6
6
|
import { ChannelType } from "discord.js";
|
|
7
7
|
async function ensureForums(guild, config, saveConfig) {
|
|
8
8
|
let forumChannelId = config.forumChannelId;
|
|
@@ -119,4 +119,4 @@ export {
|
|
|
119
119
|
ensureUnarchived,
|
|
120
120
|
buildDeepLink
|
|
121
121
|
};
|
|
122
|
-
//# sourceMappingURL=chunk-
|
|
122
|
+
//# sourceMappingURL=chunk-O5RG4YZY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plugins/discord/forums.ts"],"sourcesContent":["import { ChannelType } from 'discord.js'\nimport type { ForumChannel, ThreadChannel, Guild, TextChannel } from 'discord.js'\nimport { log } from '../../core/utils/log.js'\n\n// ─── ensureForums ─────────────────────────────────────────────────────────────\n\n/**\n * Ensures both the forum channel and notification channel exist.\n * Creates them if their IDs are null, then persists the IDs via saveConfig.\n *\n * saveConfig uses nested object path: { channels: { discord: { forumChannelId: ... } } }\n */\nexport async function ensureForums(\n guild: Guild,\n config: {\n forumChannelId: string | null\n notificationChannelId: string | null\n },\n saveConfig: (updates: Record<string, unknown>) => Promise<void>,\n): Promise<{ forumChannel: ForumChannel | TextChannel; notificationChannel: TextChannel }> {\n let forumChannelId = config.forumChannelId\n let notificationChannelId = config.notificationChannelId\n\n // Ensure forum/sessions channel exists — fetch existing or create new\n let forumChannel: ForumChannel | TextChannel | null = null\n if (forumChannelId) {\n try {\n const ch = guild.channels.cache.get(forumChannelId)\n ?? await guild.channels.fetch(forumChannelId)\n if (ch && (ch.type === ChannelType.GuildForum || ch.type === ChannelType.GuildText)) {\n forumChannel = ch as ForumChannel | TextChannel\n log.info({ forumChannelId, type: ch.type }, '[forums] Reusing existing sessions channel')\n }\n } catch {\n log.warn({ forumChannelId }, '[forums] Saved sessions channel not found, recreating...')\n }\n }\n if (!forumChannel) {\n // Prefer Forum Channel (requires Community mode), fallback to Text Channel with threads\n if (guild.features.includes('COMMUNITY')) {\n const channel = await guild.channels.create({\n name: 'openacp-sessions',\n type: ChannelType.GuildForum,\n })\n forumChannel = channel as ForumChannel\n log.info({ forumChannelId: channel.id }, '[forums] Created forum channel')\n } else {\n const channel = await guild.channels.create({\n name: 'openacp-sessions',\n type: ChannelType.GuildText,\n })\n forumChannel = channel as TextChannel\n log.info({ forumChannelId: channel.id }, '[forums] Created text channel (Community mode not enabled, using threads fallback)')\n }\n await saveConfig({ channels: { discord: { forumChannelId: forumChannel.id } } })\n }\n\n // Ensure notification channel exists — fetch existing or create new\n let notificationChannel: TextChannel | null = null\n if (notificationChannelId) {\n try {\n const ch = guild.channels.cache.get(notificationChannelId)\n ?? await guild.channels.fetch(notificationChannelId)\n if (ch && ch.type === ChannelType.GuildText) {\n notificationChannel = ch as TextChannel\n log.info({ notificationChannelId }, '[forums] Reusing existing notification channel')\n }\n } catch {\n log.warn({ notificationChannelId }, '[forums] Saved notification channel not found, recreating...')\n }\n }\n if (!notificationChannel) {\n const channel = await guild.channels.create({\n name: 'openacp-notifications',\n type: ChannelType.GuildText,\n })\n notificationChannel = channel as TextChannel\n await saveConfig({ channels: { discord: { notificationChannelId: channel.id } } })\n log.info({ notificationChannelId: channel.id }, '[forums] Created notification channel')\n }\n\n return { forumChannel, notificationChannel }\n}\n\n// ─── createSessionThread ──────────────────────────────────────────────────────\n\n/**\n * Creates a new thread for a session.\n * - Forum Channel: creates a forum post (thread with initial message)\n * - Text Channel: creates a public thread\n */\nexport async function createSessionThread(\n forumChannel: ForumChannel | TextChannel,\n name: string,\n): Promise<ThreadChannel> {\n if (forumChannel.type === ChannelType.GuildForum) {\n // Forum channel: create a post (thread with initial message)\n const thread = await (forumChannel as ForumChannel).threads.create({\n name,\n message: { content: '⏳ Setting up...' },\n })\n return thread\n }\n\n // Text channel fallback: send a message first, then create a thread on it\n const textChannel = forumChannel as TextChannel\n const msg = await textChannel.send({ content: `📂 **${name}** — ⏳ Setting up...` })\n const thread = await msg.startThread({ name })\n return thread\n}\n\n// ─── renameSessionThread ──────────────────────────────────────────────────────\n\n/**\n * Fetches and renames a thread. Ignores all errors (thread may be deleted/archived).\n */\nexport async function renameSessionThread(\n guild: Guild,\n threadId: string,\n newName: string,\n): Promise<void> {\n try {\n const channel = guild.channels.cache.get(threadId)\n ?? await guild.channels.fetch(threadId)\n if (channel && 'setName' in channel) {\n await (channel as ThreadChannel).setName(newName)\n }\n } catch {\n // Ignore — thread may be deleted or archived\n }\n}\n\n// ─── deleteSessionThread ──────────────────────────────────────────────────────\n\n/**\n * Archives and locks a thread instead of permanently deleting it.\n * Unlike Telegram (which just closes a topic), Discord delete is permanent\n * and destroys all messages. Archiving preserves the conversation history.\n */\nexport async function deleteSessionThread(\n guild: Guild,\n threadId: string,\n): Promise<void> {\n try {\n const channel = guild.channels.cache.get(threadId)\n ?? await guild.channels.fetch(threadId)\n if (channel && channel.isThread()) {\n const thread = channel as ThreadChannel\n if (!thread.archived) {\n await thread.setArchived(true)\n }\n if (!thread.locked) {\n await thread.setLocked(true)\n }\n }\n } catch {\n // Ignore — thread may already be deleted or inaccessible\n }\n}\n\n// ─── ensureUnarchived ─────────────────────────────────────────────────────────\n\n/**\n * If the thread is archived, unarchives it.\n */\nexport async function ensureUnarchived(thread: ThreadChannel): Promise<void> {\n if (thread.archived) {\n try {\n await thread.setArchived(false)\n } catch (err) {\n log.warn({ err, threadId: thread.id }, '[forums] Failed to unarchive thread')\n }\n }\n}\n\n// ─── buildDeepLink ────────────────────────────────────────────────────────────\n\n/**\n * Builds a Discord deep link URL to a channel/thread, optionally to a specific message.\n */\nexport function buildDeepLink(\n guildId: string,\n channelId: string,\n messageId?: string,\n): string {\n const base = `https://discord.com/channels/${guildId}/${channelId}`\n return messageId ? `${base}/${messageId}` : base\n}\n"],"mappings":"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","names":["thread"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/core/config-registry.ts
|
|
1
|
+
// src/core/config/config-registry.ts
|
|
2
2
|
import * as fs from "fs";
|
|
3
3
|
import * as path from "path";
|
|
4
4
|
import * as os from "os";
|
|
@@ -180,4 +180,4 @@ export {
|
|
|
180
180
|
resolveOptions,
|
|
181
181
|
getConfigValue
|
|
182
182
|
};
|
|
183
|
-
//# sourceMappingURL=chunk-
|
|
183
|
+
//# sourceMappingURL=chunk-ODUM3D6X.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/config/config-registry.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport type { Config } from \"./config.js\";\n\nexport interface ConfigFieldDef {\n path: string;\n displayName: string;\n group: string;\n type: \"toggle\" | \"select\" | \"number\" | \"string\";\n options?: string[] | ((config: Config) => string[]);\n scope: \"safe\" | \"sensitive\";\n hotReload: boolean;\n}\n\nexport const CONFIG_REGISTRY: ConfigFieldDef[] = [\n {\n path: \"defaultAgent\",\n displayName: \"Default Agent\",\n group: \"agent\",\n type: \"select\",\n options: (config) => {\n try {\n const agentsPath = path.join(os.homedir(), \".openacp\", \"agents.json\");\n if (fs.existsSync(agentsPath)) {\n const data = JSON.parse(fs.readFileSync(agentsPath, \"utf-8\"));\n return Object.keys(data.installed ?? {});\n }\n } catch {\n /* fallback */\n }\n return Object.keys(config.agents ?? {});\n },\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"channels.telegram.displayVerbosity\",\n displayName: \"Telegram Verbosity\",\n group: \"display\",\n type: \"select\",\n options: [\"low\", \"medium\", \"high\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"channels.discord.displayVerbosity\",\n displayName: \"Discord Verbosity\",\n group: \"display\",\n type: \"select\",\n options: [\"low\", \"medium\", \"high\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"logging.level\",\n displayName: \"Log Level\",\n group: \"logging\",\n type: \"select\",\n options: [\"silent\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"tunnel.enabled\",\n displayName: \"Tunnel\",\n group: \"tunnel\",\n type: \"toggle\",\n scope: \"safe\",\n hotReload: false,\n },\n {\n path: \"security.maxConcurrentSessions\",\n displayName: \"Max Concurrent Sessions\",\n group: \"security\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"security.sessionTimeoutMinutes\",\n displayName: \"Session Timeout (min)\",\n group: \"security\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"workspace.baseDir\",\n displayName: \"Workspace Directory\",\n group: \"workspace\",\n type: \"string\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"sessionStore.ttlDays\",\n displayName: \"Session Store TTL (days)\",\n group: \"storage\",\n type: \"number\",\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"speech.stt.provider\",\n displayName: \"Speech to Text\",\n group: \"speech\",\n type: \"select\",\n options: [\"groq\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"speech.stt.apiKey\",\n displayName: \"STT API Key\",\n group: \"speech\",\n type: \"string\",\n scope: \"sensitive\",\n hotReload: true,\n },\n {\n path: \"speech.tts.provider\",\n displayName: \"Text to Speech\",\n group: \"speech\",\n type: \"select\",\n options: [\"edge-tts\"],\n scope: \"safe\",\n hotReload: true,\n },\n {\n path: \"speech.tts.providers.edge-tts.voice\",\n displayName: \"Edge TTS Voice\",\n group: \"speech\",\n type: \"select\",\n options: [\n \"en-US-AriaNeural\",\n \"en-US-GuyNeural\",\n \"en-US-JennyNeural\",\n \"en-GB-SoniaNeural\",\n \"en-AU-NatashaNeural\",\n \"vi-VN-HoaiMyNeural\",\n \"vi-VN-NamMinhNeural\",\n \"zh-CN-XiaoxiaoNeural\",\n \"zh-CN-YunxiNeural\",\n \"ja-JP-NanamiNeural\",\n \"ja-JP-KeitaNeural\",\n \"ko-KR-SunHiNeural\",\n \"ko-KR-InJoonNeural\",\n \"es-ES-ElviraNeural\",\n \"fr-FR-DeniseNeural\",\n \"de-DE-KatjaNeural\",\n \"pt-BR-FranciscaNeural\",\n \"hi-IN-SwaraNeural\",\n \"ar-SA-ZariyahNeural\",\n ],\n scope: \"safe\",\n hotReload: true,\n },\n];\n\nexport function getFieldDef(path: string): ConfigFieldDef | undefined {\n return CONFIG_REGISTRY.find((f) => f.path === path);\n}\n\nexport function getSafeFields(): ConfigFieldDef[] {\n return CONFIG_REGISTRY.filter((f) => f.scope === \"safe\");\n}\n\nexport function isHotReloadable(path: string): boolean {\n const def = getFieldDef(path);\n return def?.hotReload ?? false;\n}\n\nexport function resolveOptions(\n def: ConfigFieldDef,\n config: Config,\n): string[] | undefined {\n if (!def.options) return undefined;\n return typeof def.options === \"function\" ? def.options(config) : def.options;\n}\n\nexport function getConfigValue(config: Config, path: string): unknown {\n const parts = path.split(\".\");\n let current: unknown = config;\n for (const part of parts) {\n if (current && typeof current === \"object\" && part in current) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n}\n"],"mappings":"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","names":["path"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/core/utils/read-text-file.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
async function readTextFileWithRange(filePath, options) {
|
|
4
|
+
const content = await fs.promises.readFile(filePath, "utf-8");
|
|
5
|
+
if (!options?.line && !options?.limit) return content;
|
|
6
|
+
const lines = content.split("\n");
|
|
7
|
+
const start = Math.max(0, (options.line ?? 1) - 1);
|
|
8
|
+
const end = options.limit ? start + options.limit : lines.length;
|
|
9
|
+
return lines.slice(start, end).join("\n");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
readTextFileWithRange
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=chunk-OYSAN7UX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/utils/read-text-file.ts"],"sourcesContent":["import fs from \"node:fs\";\n\n/**\n * Read a text file, optionally returning only a range of lines.\n * Pure utility — no dependencies on plugin code.\n */\nexport async function readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n): Promise<string> {\n const content = await fs.promises.readFile(filePath, \"utf-8\");\n if (!options?.line && !options?.limit) return content;\n const lines = content.split(\"\\n\");\n const start = Math.max(0, (options.line ?? 1) - 1);\n const end = options.limit ? start + options.limit : lines.length;\n return lines.slice(start, end).join(\"\\n\");\n}\n"],"mappings":";AAAA,OAAO,QAAQ;AAMf,eAAsB,sBACpB,UACA,SACiB;AACjB,QAAM,UAAU,MAAM,GAAG,SAAS,SAAS,UAAU,OAAO;AAC5D,MAAI,CAAC,SAAS,QAAQ,CAAC,SAAS,MAAO,QAAO;AAC9C,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,QAAM,QAAQ,KAAK,IAAI,IAAI,QAAQ,QAAQ,KAAK,CAAC;AACjD,QAAM,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,QAAQ,MAAM;AAC1D,SAAO,MAAM,MAAM,OAAO,GAAG,EAAE,KAAK,IAAI;AAC1C;","names":[]}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// src/plugins/tunnel/index.ts
|
|
2
|
+
function createTunnelPlugin() {
|
|
3
|
+
let service = null;
|
|
4
|
+
return {
|
|
5
|
+
name: "@openacp/tunnel",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
description: "Expose local services to internet via tunnel providers",
|
|
8
|
+
essential: false,
|
|
9
|
+
permissions: ["services:register", "kernel:access", "commands:register"],
|
|
10
|
+
async install(ctx) {
|
|
11
|
+
const { terminal, settings, legacyConfig } = ctx;
|
|
12
|
+
if (legacyConfig) {
|
|
13
|
+
const tunnelCfg = legacyConfig.tunnel;
|
|
14
|
+
if (tunnelCfg) {
|
|
15
|
+
await settings.setAll({
|
|
16
|
+
enabled: tunnelCfg.enabled ?? true,
|
|
17
|
+
provider: tunnelCfg.provider ?? "cloudflare",
|
|
18
|
+
port: tunnelCfg.port ?? 3100,
|
|
19
|
+
options: tunnelCfg.options ?? {},
|
|
20
|
+
maxUserTunnels: tunnelCfg.maxUserTunnels ?? 5,
|
|
21
|
+
storeTtlMinutes: tunnelCfg.storeTtlMinutes ?? 60,
|
|
22
|
+
auth: tunnelCfg.auth ?? { enabled: false }
|
|
23
|
+
});
|
|
24
|
+
terminal.log.success("Tunnel settings migrated from legacy config");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const provider = await terminal.select({
|
|
29
|
+
message: "Tunnel provider:",
|
|
30
|
+
options: [
|
|
31
|
+
{ value: "cloudflare", label: "Cloudflare (cloudflared)", hint: "Free, no account needed" },
|
|
32
|
+
{ value: "ngrok", label: "ngrok", hint: "Requires auth token" },
|
|
33
|
+
{ value: "bore", label: "bore", hint: "Self-hostable" },
|
|
34
|
+
{ value: "tailscale", label: "Tailscale Funnel" }
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
const portStr = await terminal.text({
|
|
38
|
+
message: "Local port to expose:",
|
|
39
|
+
defaultValue: "3100",
|
|
40
|
+
validate: (v) => {
|
|
41
|
+
const n = Number(v.trim());
|
|
42
|
+
if (isNaN(n) || n < 1 || n > 65535) return "Port must be 1-65535";
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
let authToken = "";
|
|
47
|
+
if (provider === "ngrok") {
|
|
48
|
+
authToken = await terminal.text({
|
|
49
|
+
message: "ngrok auth token:",
|
|
50
|
+
validate: (v) => !v.trim() ? "Auth token cannot be empty" : void 0
|
|
51
|
+
});
|
|
52
|
+
authToken = authToken.trim();
|
|
53
|
+
}
|
|
54
|
+
await settings.setAll({
|
|
55
|
+
enabled: true,
|
|
56
|
+
provider,
|
|
57
|
+
port: Number(portStr.trim()),
|
|
58
|
+
options: authToken ? { authtoken: authToken } : {},
|
|
59
|
+
maxUserTunnels: 5,
|
|
60
|
+
storeTtlMinutes: 60,
|
|
61
|
+
auth: { enabled: false }
|
|
62
|
+
});
|
|
63
|
+
terminal.log.success("Tunnel settings saved");
|
|
64
|
+
},
|
|
65
|
+
async configure(ctx) {
|
|
66
|
+
const { terminal, settings } = ctx;
|
|
67
|
+
const current = await settings.getAll();
|
|
68
|
+
const choice = await terminal.select({
|
|
69
|
+
message: "What to configure?",
|
|
70
|
+
options: [
|
|
71
|
+
{ value: "provider", label: `Change provider (current: ${current.provider ?? "none"})` },
|
|
72
|
+
{ value: "port", label: `Change port (current: ${current.port ?? 3100})` },
|
|
73
|
+
{ value: "toggle", label: `${current.enabled ? "Disable" : "Enable"} tunnel` },
|
|
74
|
+
{ value: "done", label: "Done" }
|
|
75
|
+
]
|
|
76
|
+
});
|
|
77
|
+
if (choice === "provider") {
|
|
78
|
+
const provider = await terminal.select({
|
|
79
|
+
message: "Tunnel provider:",
|
|
80
|
+
options: [
|
|
81
|
+
{ value: "cloudflare", label: "Cloudflare" },
|
|
82
|
+
{ value: "ngrok", label: "ngrok" },
|
|
83
|
+
{ value: "bore", label: "bore" },
|
|
84
|
+
{ value: "tailscale", label: "Tailscale" }
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
await settings.set("provider", provider);
|
|
88
|
+
terminal.log.success("Provider updated");
|
|
89
|
+
} else if (choice === "port") {
|
|
90
|
+
const val = await terminal.text({
|
|
91
|
+
message: "New port:",
|
|
92
|
+
defaultValue: String(current.port ?? 3100),
|
|
93
|
+
validate: (v) => {
|
|
94
|
+
const n = Number(v.trim());
|
|
95
|
+
if (isNaN(n) || n < 1 || n > 65535) return "Port must be 1-65535";
|
|
96
|
+
return void 0;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
await settings.set("port", Number(val.trim()));
|
|
100
|
+
terminal.log.success("Port updated");
|
|
101
|
+
} else if (choice === "toggle") {
|
|
102
|
+
const newState = !current.enabled;
|
|
103
|
+
await settings.set("enabled", newState);
|
|
104
|
+
terminal.log.success(`Tunnel ${newState ? "enabled" : "disabled"}`);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
async uninstall(ctx, opts) {
|
|
108
|
+
if (opts.purge) {
|
|
109
|
+
await ctx.settings.clear();
|
|
110
|
+
ctx.terminal.log.success("Tunnel settings cleared");
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
async setup(ctx) {
|
|
114
|
+
const config = ctx.pluginConfig;
|
|
115
|
+
if (!config.provider) {
|
|
116
|
+
ctx.log.info("Tunnel disabled (no provider configured)");
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const { TunnelService } = await import("./tunnel-service-WADYHREX.js");
|
|
120
|
+
const tunnelSvc = new TunnelService(config);
|
|
121
|
+
const publicUrl = await tunnelSvc.start();
|
|
122
|
+
service = tunnelSvc;
|
|
123
|
+
ctx.registerService("tunnel", tunnelSvc);
|
|
124
|
+
ctx.registerCommand({
|
|
125
|
+
name: "tunnel",
|
|
126
|
+
description: "Show tunnel status and URL",
|
|
127
|
+
category: "plugin",
|
|
128
|
+
handler: async () => {
|
|
129
|
+
const url = tunnelSvc.getPublicUrl();
|
|
130
|
+
return { type: "text", text: `Tunnel active: ${url}` };
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
ctx.registerCommand({
|
|
134
|
+
name: "tunnels",
|
|
135
|
+
description: "List active tunnels",
|
|
136
|
+
category: "plugin",
|
|
137
|
+
handler: async () => {
|
|
138
|
+
const url = tunnelSvc.getPublicUrl();
|
|
139
|
+
return { type: "list", title: "Active Tunnels", items: [
|
|
140
|
+
{ label: "Primary", detail: url }
|
|
141
|
+
] };
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
ctx.log.info(`Tunnel ready: ${publicUrl}`);
|
|
145
|
+
},
|
|
146
|
+
async teardown() {
|
|
147
|
+
if (service) {
|
|
148
|
+
await service.stop();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
var tunnel_default = createTunnelPlugin();
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
tunnel_default
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=chunk-P4SNGQNI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plugins/tunnel/index.ts"],"sourcesContent":["import type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport type { TunnelConfig } from '../../core/config/config.js'\n\nfunction createTunnelPlugin(): OpenACPPlugin {\n let service: { stop(): Promise<void> } | null = null\n\n return {\n name: '@openacp/tunnel',\n version: '1.0.0',\n description: 'Expose local services to internet via tunnel providers',\n essential: false,\n permissions: ['services:register', 'kernel:access', 'commands:register'],\n\n async install(ctx: InstallContext) {\n const { terminal, settings, legacyConfig } = ctx\n\n // Migrate from legacy config if present\n if (legacyConfig) {\n const tunnelCfg = legacyConfig.tunnel as Record<string, unknown> | undefined\n if (tunnelCfg) {\n await settings.setAll({\n enabled: tunnelCfg.enabled ?? true,\n provider: tunnelCfg.provider ?? 'cloudflare',\n port: tunnelCfg.port ?? 3100,\n options: tunnelCfg.options ?? {},\n maxUserTunnels: tunnelCfg.maxUserTunnels ?? 5,\n storeTtlMinutes: tunnelCfg.storeTtlMinutes ?? 60,\n auth: tunnelCfg.auth ?? { enabled: false },\n })\n terminal.log.success('Tunnel settings migrated from legacy config')\n return\n }\n }\n\n // Interactive setup\n const provider = await terminal.select({\n message: 'Tunnel provider:',\n options: [\n { value: 'cloudflare', label: 'Cloudflare (cloudflared)', hint: 'Free, no account needed' },\n { value: 'ngrok', label: 'ngrok', hint: 'Requires auth token' },\n { value: 'bore', label: 'bore', hint: 'Self-hostable' },\n { value: 'tailscale', label: 'Tailscale Funnel' },\n ],\n })\n\n const portStr = await terminal.text({\n message: 'Local port to expose:',\n defaultValue: '3100',\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1 || n > 65535) return 'Port must be 1-65535'\n return undefined\n },\n })\n\n let authToken = ''\n if (provider === 'ngrok') {\n authToken = await terminal.text({\n message: 'ngrok auth token:',\n validate: (v) => (!v.trim() ? 'Auth token cannot be empty' : undefined),\n })\n authToken = authToken.trim()\n }\n\n await settings.setAll({\n enabled: true,\n provider,\n port: Number(portStr.trim()),\n options: authToken ? { authtoken: authToken } : {},\n maxUserTunnels: 5,\n storeTtlMinutes: 60,\n auth: { enabled: false },\n })\n terminal.log.success('Tunnel settings saved')\n },\n\n async configure(ctx: InstallContext) {\n const { terminal, settings } = ctx\n const current = await settings.getAll()\n\n const choice = await terminal.select({\n message: 'What to configure?',\n options: [\n { value: 'provider', label: `Change provider (current: ${current.provider ?? 'none'})` },\n { value: 'port', label: `Change port (current: ${current.port ?? 3100})` },\n { value: 'toggle', label: `${current.enabled ? 'Disable' : 'Enable'} tunnel` },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'provider') {\n const provider = await terminal.select({\n message: 'Tunnel provider:',\n options: [\n { value: 'cloudflare', label: 'Cloudflare' },\n { value: 'ngrok', label: 'ngrok' },\n { value: 'bore', label: 'bore' },\n { value: 'tailscale', label: 'Tailscale' },\n ],\n })\n await settings.set('provider', provider)\n terminal.log.success('Provider updated')\n } else if (choice === 'port') {\n const val = await terminal.text({\n message: 'New port:',\n defaultValue: String(current.port ?? 3100),\n validate: (v) => {\n const n = Number(v.trim())\n if (isNaN(n) || n < 1 || n > 65535) return 'Port must be 1-65535'\n return undefined\n },\n })\n await settings.set('port', Number(val.trim()))\n terminal.log.success('Port updated')\n } else if (choice === 'toggle') {\n const newState = !current.enabled\n await settings.set('enabled', newState)\n terminal.log.success(`Tunnel ${newState ? 'enabled' : 'disabled'}`)\n }\n },\n\n async uninstall(ctx: InstallContext, opts: { purge: boolean }) {\n if (opts.purge) {\n await ctx.settings.clear()\n ctx.terminal.log.success('Tunnel settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n if (!config.provider) {\n ctx.log.info('Tunnel disabled (no provider configured)')\n return\n }\n\n const { TunnelService } = await import('./tunnel-service.js')\n const tunnelSvc = new TunnelService(config as unknown as TunnelConfig)\n const publicUrl = await tunnelSvc.start()\n service = tunnelSvc\n\n ctx.registerService('tunnel', tunnelSvc)\n\n ctx.registerCommand({\n name: 'tunnel',\n description: 'Show tunnel status and URL',\n category: 'plugin',\n handler: async () => {\n const url = tunnelSvc.getPublicUrl()\n return { type: 'text', text: `Tunnel active: ${url}` }\n },\n })\n\n ctx.registerCommand({\n name: 'tunnels',\n description: 'List active tunnels',\n category: 'plugin',\n handler: async () => {\n const url = tunnelSvc.getPublicUrl()\n return { type: 'list', title: 'Active Tunnels', items: [\n { label: 'Primary', detail: url },\n ]}\n },\n })\n\n ctx.log.info(`Tunnel ready: ${publicUrl}`)\n },\n\n async teardown() {\n if (service) {\n await service.stop()\n }\n },\n }\n}\n\nexport default createTunnelPlugin()\n"],"mappings":";AAGA,SAAS,qBAAoC;AAC3C,MAAI,UAA4C;AAEhD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,aAAa,CAAC,qBAAqB,iBAAiB,mBAAmB;AAAA,IAEvE,MAAM,QAAQ,KAAqB;AACjC,YAAM,EAAE,UAAU,UAAU,aAAa,IAAI;AAG7C,UAAI,cAAc;AAChB,cAAM,YAAY,aAAa;AAC/B,YAAI,WAAW;AACb,gBAAM,SAAS,OAAO;AAAA,YACpB,SAAS,UAAU,WAAW;AAAA,YAC9B,UAAU,UAAU,YAAY;AAAA,YAChC,MAAM,UAAU,QAAQ;AAAA,YACxB,SAAS,UAAU,WAAW,CAAC;AAAA,YAC/B,gBAAgB,UAAU,kBAAkB;AAAA,YAC5C,iBAAiB,UAAU,mBAAmB;AAAA,YAC9C,MAAM,UAAU,QAAQ,EAAE,SAAS,MAAM;AAAA,UAC3C,CAAC;AACD,mBAAS,IAAI,QAAQ,6CAA6C;AAClE;AAAA,QACF;AAAA,MACF;AAGA,YAAM,WAAW,MAAM,SAAS,OAAO;AAAA,QACrC,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,OAAO,cAAc,OAAO,4BAA4B,MAAM,0BAA0B;AAAA,UAC1F,EAAE,OAAO,SAAS,OAAO,SAAS,MAAM,sBAAsB;AAAA,UAC9D,EAAE,OAAO,QAAQ,OAAO,QAAQ,MAAM,gBAAgB;AAAA,UACtD,EAAE,OAAO,aAAa,OAAO,mBAAmB;AAAA,QAClD;AAAA,MACF,CAAC;AAED,YAAM,UAAU,MAAM,SAAS,KAAK;AAAA,QAClC,SAAS;AAAA,QACT,cAAc;AAAA,QACd,UAAU,CAAC,MAAM;AACf,gBAAM,IAAI,OAAO,EAAE,KAAK,CAAC;AACzB,cAAI,MAAM,CAAC,KAAK,IAAI,KAAK,IAAI,MAAO,QAAO;AAC3C,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAED,UAAI,YAAY;AAChB,UAAI,aAAa,SAAS;AACxB,oBAAY,MAAM,SAAS,KAAK;AAAA,UAC9B,SAAS;AAAA,UACT,UAAU,CAAC,MAAO,CAAC,EAAE,KAAK,IAAI,+BAA+B;AAAA,QAC/D,CAAC;AACD,oBAAY,UAAU,KAAK;AAAA,MAC7B;AAEA,YAAM,SAAS,OAAO;AAAA,QACpB,SAAS;AAAA,QACT;AAAA,QACA,MAAM,OAAO,QAAQ,KAAK,CAAC;AAAA,QAC3B,SAAS,YAAY,EAAE,WAAW,UAAU,IAAI,CAAC;AAAA,QACjD,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,MAAM,EAAE,SAAS,MAAM;AAAA,MACzB,CAAC;AACD,eAAS,IAAI,QAAQ,uBAAuB;AAAA,IAC9C;AAAA,IAEA,MAAM,UAAU,KAAqB;AACnC,YAAM,EAAE,UAAU,SAAS,IAAI;AAC/B,YAAM,UAAU,MAAM,SAAS,OAAO;AAEtC,YAAM,SAAS,MAAM,SAAS,OAAO;AAAA,QACnC,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,OAAO,YAAY,OAAO,6BAA6B,QAAQ,YAAY,MAAM,IAAI;AAAA,UACvF,EAAE,OAAO,QAAQ,OAAO,yBAAyB,QAAQ,QAAQ,IAAI,IAAI;AAAA,UACzE,EAAE,OAAO,UAAU,OAAO,GAAG,QAAQ,UAAU,YAAY,QAAQ,UAAU;AAAA,UAC7E,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,QACjC;AAAA,MACF,CAAC;AAED,UAAI,WAAW,YAAY;AACzB,cAAM,WAAW,MAAM,SAAS,OAAO;AAAA,UACrC,SAAS;AAAA,UACT,SAAS;AAAA,YACP,EAAE,OAAO,cAAc,OAAO,aAAa;AAAA,YAC3C,EAAE,OAAO,SAAS,OAAO,QAAQ;AAAA,YACjC,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,YAC/B,EAAE,OAAO,aAAa,OAAO,YAAY;AAAA,UAC3C;AAAA,QACF,CAAC;AACD,cAAM,SAAS,IAAI,YAAY,QAAQ;AACvC,iBAAS,IAAI,QAAQ,kBAAkB;AAAA,MACzC,WAAW,WAAW,QAAQ;AAC5B,cAAM,MAAM,MAAM,SAAS,KAAK;AAAA,UAC9B,SAAS;AAAA,UACT,cAAc,OAAO,QAAQ,QAAQ,IAAI;AAAA,UACzC,UAAU,CAAC,MAAM;AACf,kBAAM,IAAI,OAAO,EAAE,KAAK,CAAC;AACzB,gBAAI,MAAM,CAAC,KAAK,IAAI,KAAK,IAAI,MAAO,QAAO;AAC3C,mBAAO;AAAA,UACT;AAAA,QACF,CAAC;AACD,cAAM,SAAS,IAAI,QAAQ,OAAO,IAAI,KAAK,CAAC,CAAC;AAC7C,iBAAS,IAAI,QAAQ,cAAc;AAAA,MACrC,WAAW,WAAW,UAAU;AAC9B,cAAM,WAAW,CAAC,QAAQ;AAC1B,cAAM,SAAS,IAAI,WAAW,QAAQ;AACtC,iBAAS,IAAI,QAAQ,UAAU,WAAW,YAAY,UAAU,EAAE;AAAA,MACpE;AAAA,IACF;AAAA,IAEA,MAAM,UAAU,KAAqB,MAA0B;AAC7D,UAAI,KAAK,OAAO;AACd,cAAM,IAAI,SAAS,MAAM;AACzB,YAAI,SAAS,IAAI,QAAQ,yBAAyB;AAAA,MACpD;AAAA,IACF;AAAA,IAEA,MAAM,MAAM,KAAK;AACf,YAAM,SAAS,IAAI;AACnB,UAAI,CAAC,OAAO,UAAU;AACpB,YAAI,IAAI,KAAK,0CAA0C;AACvD;AAAA,MACF;AAEA,YAAM,EAAE,cAAc,IAAI,MAAM,OAAO,8BAAqB;AAC5D,YAAM,YAAY,IAAI,cAAc,MAAiC;AACrE,YAAM,YAAY,MAAM,UAAU,MAAM;AACxC,gBAAU;AAEV,UAAI,gBAAgB,UAAU,SAAS;AAEvC,UAAI,gBAAgB;AAAA,QAClB,MAAM;AAAA,QACN,aAAa;AAAA,QACb,UAAU;AAAA,QACV,SAAS,YAAY;AACnB,gBAAM,MAAM,UAAU,aAAa;AACnC,iBAAO,EAAE,MAAM,QAAQ,MAAM,kBAAkB,GAAG,GAAG;AAAA,QACvD;AAAA,MACF,CAAC;AAED,UAAI,gBAAgB;AAAA,QAClB,MAAM;AAAA,QACN,aAAa;AAAA,QACb,UAAU;AAAA,QACV,SAAS,YAAY;AACnB,gBAAM,MAAM,UAAU,aAAa;AACnC,iBAAO,EAAE,MAAM,QAAQ,OAAO,kBAAkB,OAAO;AAAA,YACrD,EAAE,OAAO,WAAW,QAAQ,IAAI;AAAA,UAClC,EAAC;AAAA,QACH;AAAA,MACF,CAAC;AAED,UAAI,IAAI,KAAK,iBAAiB,SAAS,EAAE;AAAA,IAC3C;AAAA,IAEA,MAAM,WAAW;AACf,UAAI,SAAS;AACX,cAAM,QAAQ,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAO,iBAAQ,mBAAmB;","names":[]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createChildLogger
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XMMAGAT4.js";
|
|
4
4
|
|
|
5
|
-
// src/
|
|
5
|
+
// src/cli/autostart.ts
|
|
6
6
|
import { execFileSync } from "child_process";
|
|
7
7
|
import * as fs from "fs";
|
|
8
8
|
import * as path from "path";
|
|
@@ -151,4 +151,4 @@ export {
|
|
|
151
151
|
uninstallAutoStart,
|
|
152
152
|
isAutoStartInstalled
|
|
153
153
|
};
|
|
154
|
-
//# sourceMappingURL=chunk-
|
|
154
|
+
//# sourceMappingURL=chunk-PPSMUECX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/autostart.ts"],"sourcesContent":["import { execFileSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport * as os from 'node:os'\nimport { createChildLogger } from '../core/utils/log.js'\n\nconst log = createChildLogger({ module: 'autostart' })\n\nconst LAUNCHD_LABEL = 'com.openacp.daemon'\nconst LAUNCHD_PLIST_PATH = path.join(os.homedir(), 'Library', 'LaunchAgents', `${LAUNCHD_LABEL}.plist`)\nconst SYSTEMD_SERVICE_PATH = path.join(os.homedir(), '.config', 'systemd', 'user', 'openacp.service')\n\nexport function isAutoStartSupported(): boolean {\n return process.platform === 'darwin' || process.platform === 'linux'\n}\n\nexport function escapeXml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n}\n\nexport function escapeSystemdValue(str: string): string {\n const escaped = str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\$/g, '$$$$')\n .replace(/%/g, '%%')\n return `\"${escaped}\"`\n}\n\nexport function generateLaunchdPlist(nodePath: string, cliPath: string, logDir: string): string {\n const logFile = path.join(logDir, 'openacp.log')\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${LAUNCHD_LABEL}</string>\n <key>ProgramArguments</key>\n <array>\n <string>${escapeXml(nodePath)}</string>\n <string>${escapeXml(cliPath)}</string>\n <string>--daemon-child</string>\n </array>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>StandardOutPath</key>\n <string>${escapeXml(logFile)}</string>\n <key>StandardErrorPath</key>\n <string>${escapeXml(logFile)}</string>\n</dict>\n</plist>\n`\n}\n\nexport function generateSystemdUnit(nodePath: string, cliPath: string): string {\n return `[Unit]\nDescription=OpenACP Daemon\n\n[Service]\nExecStart=${escapeSystemdValue(nodePath)} ${escapeSystemdValue(cliPath)} --daemon-child\nRestart=on-failure\n\n[Install]\nWantedBy=default.target\n`\n}\n\nexport function installAutoStart(logDir: string): { success: boolean; error?: string } {\n if (!isAutoStartSupported()) {\n return { success: false, error: 'Auto-start not supported on this platform' }\n }\n\n const nodePath = process.execPath\n const cliPath = path.resolve(process.argv[1])\n const resolvedLogDir = logDir.startsWith('~')\n ? path.join(os.homedir(), logDir.slice(1))\n : logDir\n\n try {\n if (process.platform === 'darwin') {\n const plist = generateLaunchdPlist(nodePath, cliPath, resolvedLogDir)\n const dir = path.dirname(LAUNCHD_PLIST_PATH)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(LAUNCHD_PLIST_PATH, plist)\n execFileSync('launchctl', ['load', LAUNCHD_PLIST_PATH], { stdio: 'pipe' })\n log.info('LaunchAgent installed')\n return { success: true }\n }\n\n if (process.platform === 'linux') {\n const unit = generateSystemdUnit(nodePath, cliPath)\n const dir = path.dirname(SYSTEMD_SERVICE_PATH)\n fs.mkdirSync(dir, { recursive: true })\n fs.writeFileSync(SYSTEMD_SERVICE_PATH, unit)\n execFileSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' })\n execFileSync('systemctl', ['--user', 'enable', 'openacp'], { stdio: 'pipe' })\n log.info('systemd user service installed')\n return { success: true }\n }\n\n return { success: false, error: 'Unsupported platform' }\n } catch (e) {\n const msg = (e as Error).message\n log.error({ err: msg }, 'Failed to install auto-start')\n return { success: false, error: msg }\n }\n}\n\nexport function uninstallAutoStart(): { success: boolean; error?: string } {\n if (!isAutoStartSupported()) {\n return { success: false, error: 'Auto-start not supported on this platform' }\n }\n\n try {\n if (process.platform === 'darwin') {\n if (fs.existsSync(LAUNCHD_PLIST_PATH)) {\n try {\n execFileSync('launchctl', ['unload', LAUNCHD_PLIST_PATH], { stdio: 'pipe' })\n } catch {\n // may already be unloaded\n }\n fs.unlinkSync(LAUNCHD_PLIST_PATH)\n log.info('LaunchAgent removed')\n }\n return { success: true }\n }\n\n if (process.platform === 'linux') {\n if (fs.existsSync(SYSTEMD_SERVICE_PATH)) {\n try {\n execFileSync('systemctl', ['--user', 'disable', 'openacp'], { stdio: 'pipe' })\n } catch {\n // may already be disabled\n }\n fs.unlinkSync(SYSTEMD_SERVICE_PATH)\n execFileSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' })\n log.info('systemd user service removed')\n }\n return { success: true }\n }\n\n return { success: false, error: 'Unsupported platform' }\n } catch (e) {\n const msg = (e as Error).message\n log.error({ err: msg }, 'Failed to uninstall auto-start')\n return { success: false, error: msg }\n }\n}\n\nexport function isAutoStartInstalled(): boolean {\n if (process.platform === 'darwin') {\n return fs.existsSync(LAUNCHD_PLIST_PATH)\n }\n if (process.platform === 'linux') {\n return fs.existsSync(SYSTEMD_SERVICE_PATH)\n }\n return false\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
slack_default
|
|
3
|
+
} from "./chunk-UB2QB6DE.js";
|
|
4
|
+
import {
|
|
5
|
+
discord_default
|
|
6
|
+
} from "./chunk-WVLDNYOJ.js";
|
|
7
|
+
import {
|
|
8
|
+
telegram_default
|
|
9
|
+
} from "./chunk-Y64XWMJ4.js";
|
|
10
|
+
import {
|
|
11
|
+
tunnel_default
|
|
12
|
+
} from "./chunk-P4SNGQNI.js";
|
|
13
|
+
import {
|
|
14
|
+
api_server_default
|
|
15
|
+
} from "./chunk-V5JT5TPD.js";
|
|
16
|
+
import {
|
|
17
|
+
security_default
|
|
18
|
+
} from "./chunk-5OCGO27U.js";
|
|
19
|
+
import {
|
|
20
|
+
file_service_default
|
|
21
|
+
} from "./chunk-YEULD3SG.js";
|
|
22
|
+
import {
|
|
23
|
+
context_default
|
|
24
|
+
} from "./chunk-ZHGPZBS4.js";
|
|
25
|
+
import {
|
|
26
|
+
usage_default
|
|
27
|
+
} from "./chunk-2CX4IEEC.js";
|
|
28
|
+
import {
|
|
29
|
+
speech_default
|
|
30
|
+
} from "./chunk-AD3X6DGK.js";
|
|
31
|
+
import {
|
|
32
|
+
notifications_default
|
|
33
|
+
} from "./chunk-SNPYTMPR.js";
|
|
34
|
+
|
|
35
|
+
// src/plugins/core-plugins.ts
|
|
36
|
+
var corePlugins = [
|
|
37
|
+
// Service plugins (no adapter dependencies)
|
|
38
|
+
security_default,
|
|
39
|
+
file_service_default,
|
|
40
|
+
context_default,
|
|
41
|
+
usage_default,
|
|
42
|
+
speech_default,
|
|
43
|
+
notifications_default,
|
|
44
|
+
// Infrastructure plugins
|
|
45
|
+
tunnel_default,
|
|
46
|
+
api_server_default,
|
|
47
|
+
// Adapter plugins (depend on security, notifications, etc.)
|
|
48
|
+
telegram_default,
|
|
49
|
+
discord_default,
|
|
50
|
+
slack_default
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
export {
|
|
54
|
+
corePlugins
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=chunk-Q6ZXJTZB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plugins/core-plugins.ts"],"sourcesContent":["/**\n * All built-in plugins: services, infrastructure, and adapters.\n * Booted by LifecycleManager in dependency order.\n * Adapter plugins depend on service plugins, so they boot last.\n */\nimport securityPlugin from './security/index.js'\nimport fileServicePlugin from './file-service/index.js'\nimport contextPlugin from './context/index.js'\nimport usagePlugin from './usage/index.js'\nimport speechPlugin from './speech/index.js'\nimport notificationsPlugin from './notifications/index.js'\nimport tunnelPlugin from './tunnel/index.js'\nimport apiServerPlugin from './api-server/index.js'\nimport telegramPlugin from './telegram/index.js'\nimport discordPlugin from './discord/index.js'\nimport slackPlugin from './slack/index.js'\n\nexport const corePlugins = [\n // Service plugins (no adapter dependencies)\n securityPlugin,\n fileServicePlugin,\n contextPlugin,\n usagePlugin,\n speechPlugin,\n notificationsPlugin,\n // Infrastructure plugins\n tunnelPlugin,\n apiServerPlugin,\n // Adapter plugins (depend on security, notifications, etc.)\n telegramPlugin,\n discordPlugin,\n slackPlugin,\n]\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBO,IAAM,cAAc;AAAA;AAAA,EAEzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
|