@openacp/cli 2026.327.3 → 2026.328.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.
- package/README.md +13 -13
- package/dist/adapter-HGJENQCN.js +13 -0
- package/dist/agent-catalog-SZQQERV7.js +10 -0
- package/dist/{agent-dependencies-WS7Z2DFW.js → agent-dependencies-ED2ZTUHG.js} +1 -2
- package/dist/{agent-registry-5LZT7CUB.js → agent-registry-YOGP656W.js} +1 -2
- package/dist/agent-store-5UHZH2XI.js +8 -0
- package/dist/{api-client-AQPNKXI2.js → api-client-XTLRRFPX.js} +1 -2
- package/dist/api-server-DSUW637I.js +7 -0
- package/dist/api-server-WFB5K6FP.js +10 -0
- package/dist/{autostart-6JS565RY.js → autostart-CUPZMKKC.js} +3 -4
- package/dist/{chunk-WIIZNPCR.js → chunk-2KT6TROD.js} +12 -33
- package/dist/chunk-2KT6TROD.js.map +1 -0
- package/dist/{chunk-PPSMUECX.js → chunk-2R5XM3ES.js} +2 -2
- package/dist/{chunk-SNPYTMPR.js → chunk-3EWTPOF7.js} +2 -2
- package/dist/{chunk-YEULD3SG.js → chunk-3NAFXVQM.js} +7 -2
- package/dist/{chunk-YEULD3SG.js.map → chunk-3NAFXVQM.js.map} +1 -1
- package/dist/{chunk-QAQDGPB4.js → chunk-43JVXFYP.js} +3 -3
- package/dist/{chunk-KMMEFXIE.js → chunk-4B6PCWQP.js} +37 -9
- package/dist/chunk-4B6PCWQP.js.map +1 -0
- package/dist/{chunk-A6Y4GZM3.js → chunk-566W6INH.js} +2 -2
- package/dist/{chunk-ODUM3D6X.js → chunk-5HKQCYOI.js} +1 -39
- package/dist/chunk-5HKQCYOI.js.map +1 -0
- package/dist/{chunk-36YQ44D7.js → chunk-5TCXYDLR.js} +3 -3
- package/dist/{chunk-XIBG7LSL.js → chunk-6VR4GWOO.js} +238 -108
- package/dist/chunk-6VR4GWOO.js.map +1 -0
- package/dist/{chunk-WXVT3AOY.js → chunk-7ZCQF6QM.js} +8 -3
- package/dist/chunk-7ZCQF6QM.js.map +1 -0
- package/dist/{chunk-HUWOFP2H.js → chunk-E2SLHZAC.js} +8 -12
- package/dist/{chunk-HUWOFP2H.js.map → chunk-E2SLHZAC.js.map} +1 -1
- package/dist/{chunk-RBYBSSGO.js → chunk-FCTC7KDT.js} +2 -2
- package/dist/chunk-I53NEV3S.js +45 -0
- package/dist/chunk-I53NEV3S.js.map +1 -0
- package/dist/{chunk-2YCW3QDV.js → chunk-IXMIC4GQ.js} +8 -7
- package/dist/chunk-IXMIC4GQ.js.map +1 -0
- package/dist/{chunk-BLQUXO7S.js → chunk-IZ5UEZF7.js} +27 -2
- package/dist/chunk-IZ5UEZF7.js.map +1 -0
- package/dist/{chunk-QVMEF6FB.js → chunk-JOMDPFQ2.js} +10 -24
- package/dist/chunk-JOMDPFQ2.js.map +1 -0
- package/dist/{chunk-4GMLGCF2.js → chunk-JUFN4XMB.js} +2 -2
- package/dist/{chunk-AD3X6DGK.js → chunk-NT6FYV27.js} +75 -13
- package/dist/chunk-NT6FYV27.js.map +1 -0
- package/dist/{chunk-UMT7RU77.js → chunk-QBEQJFGL.js} +9 -9
- package/dist/{chunk-XMMAGAT4.js → chunk-R6KZYF7D.js} +8 -1
- package/dist/{chunk-XMMAGAT4.js.map → chunk-R6KZYF7D.js.map} +1 -1
- package/dist/{chunk-LP45RCA4.js → chunk-RXMWJHWH.js} +1007 -495
- package/dist/chunk-RXMWJHWH.js.map +1 -0
- package/dist/{chunk-SHTGQGAU.js → chunk-V2YZWYXT.js} +3 -3
- package/dist/{chunk-BQ6FR32N.js → chunk-VD3QSMVY.js} +2 -2
- package/dist/cli.js +141 -115
- package/dist/cli.js.map +1 -1
- package/dist/{config-I4FMCJGZ.js → config-UCAFCS5W.js} +3 -4
- package/dist/config-editor-OU6PUY66.js +10 -0
- package/dist/{config-registry-CUMNXFGK.js → config-registry-ZXAIJNYB.js} +2 -3
- package/dist/{context-XM6E22LM.js → context-7MPU7RL5.js} +1 -2
- package/dist/core-plugins-R2EVZAJV.js +22 -0
- package/dist/{daemon-PXO5QPCR.js → daemon-DTA6KYYY.js} +4 -5
- package/dist/{dev-loader-DRU3R7ZM.js → dev-loader-7P3HZCIA.js} +1 -3
- package/dist/{dev-loader-DRU3R7ZM.js.map → dev-loader-7P3HZCIA.js.map} +1 -1
- package/dist/doctor-D723IB2I.js +9 -0
- package/dist/file-service-HHB3JQIO.js +8 -0
- package/dist/index.d.ts +41 -150
- package/dist/index.js +63 -29
- package/dist/index.js.map +1 -1
- package/dist/{install-cloudflared-AN24L4DP.js → install-cloudflared-JRJ4BSOM.js} +3 -4
- package/dist/{install-cloudflared-AN24L4DP.js.map → install-cloudflared-JRJ4BSOM.js.map} +1 -1
- package/dist/{install-context-XPWTFT3J.js → install-context-EHYV5WRY.js} +2 -3
- package/dist/{install-context-XPWTFT3J.js.map → install-context-EHYV5WRY.js.map} +1 -1
- package/dist/{install-jq-CRVDJGF3.js → install-jq-ISTGT263.js} +3 -4
- package/dist/{install-jq-CRVDJGF3.js.map → install-jq-ISTGT263.js.map} +1 -1
- package/dist/{integrate-G6CVXTGT.js → integrate-JIEZYDOR.js} +1 -2
- package/dist/{integrate-G6CVXTGT.js.map → integrate-JIEZYDOR.js.map} +1 -1
- package/dist/{log-LZ7FTRKG.js → log-YZ243M5G.js} +4 -3
- package/dist/{main-UVTZ46WP.js → main-RRSX5SRL.js} +117 -40
- package/dist/main-RRSX5SRL.js.map +1 -0
- package/dist/{menu-YDQ2LWAR.js → menu-ALFN37IR.js} +1 -2
- package/dist/notifications-MO23S7S3.js +8 -0
- package/dist/{plugin-create-5HQRF2ID.js → plugin-create-EHL76ZZG.js} +1 -2
- package/dist/{plugin-create-5HQRF2ID.js.map → plugin-create-EHL76ZZG.js.map} +1 -1
- package/dist/plugin-installer-5XHORMLS.js +9 -0
- package/dist/{plugin-registry-WB3DR67H.js → plugin-registry-6J3YSFHF.js} +1 -2
- package/dist/{plugin-search-HQ4WQKOF.js → plugin-search-MGKAL5JM.js} +1 -2
- package/dist/{plugin-search-HQ4WQKOF.js.map → plugin-search-MGKAL5JM.js.map} +1 -1
- package/dist/{post-upgrade-3ADZRMYJ.js → post-upgrade-Y26S2ZQ7.js} +6 -7
- package/dist/{post-upgrade-3ADZRMYJ.js.map → post-upgrade-Y26S2ZQ7.js.map} +1 -1
- package/dist/{read-text-file-IRZM3QLM.js → read-text-file-DJBTITIB.js} +1 -2
- package/dist/{registry-client-AVGRE4CF.js → registry-client-GTBWLXYU.js} +1 -2
- package/dist/{security-YNRBW6S7.js → security-2BA265LN.js} +1 -2
- package/dist/{settings-manager-MD2U4ZV2.js → settings-manager-B4UN2LAC.js} +1 -2
- package/dist/{setup-EYAFK2WI.js → setup-OI6A3OXW.js} +109 -80
- package/dist/setup-OI6A3OXW.js.map +1 -0
- package/dist/speech-GB7PHVQZ.js +9 -0
- package/dist/{suggest-7D6B542M.js → suggest-RST5VOHB.js} +1 -3
- package/dist/{suggest-7D6B542M.js.map → suggest-RST5VOHB.js.map} +1 -1
- package/dist/telegram-UVIAXADE.js +7 -0
- package/dist/tunnel-4WNFC7GO.js +7 -0
- package/dist/{tunnel-service-QJPUYEKU.js → tunnel-service-I2NFUX3V.js} +3 -4
- package/dist/{tunnel-service-QJPUYEKU.js.map → tunnel-service-I2NFUX3V.js.map} +1 -1
- package/dist/{validators-WSTBNKRW.js → validators-GITLOFXC.js} +1 -2
- package/dist/{version-NQZBM5M7.js → version-AXXV6IV2.js} +1 -2
- package/package.json +1 -3
- package/dist/adapter-LC2QSDAS.js +0 -15
- package/dist/adapter-Y55NXX6I.js +0 -1006
- package/dist/adapter-Y55NXX6I.js.map +0 -1
- package/dist/agent-catalog-YHBFERYO.js +0 -11
- package/dist/agent-store-VSHNY5GT.js +0 -9
- package/dist/api-server-7G3ZUZRM.js +0 -8
- package/dist/api-server-CAYNPUF2.js +0 -11
- package/dist/chunk-2YCW3QDV.js.map +0 -1
- package/dist/chunk-3ASUU6WW.js +0 -124
- package/dist/chunk-3ASUU6WW.js.map +0 -1
- package/dist/chunk-AD3X6DGK.js.map +0 -1
- package/dist/chunk-BLQUXO7S.js.map +0 -1
- package/dist/chunk-KMMEFXIE.js.map +0 -1
- package/dist/chunk-LP45RCA4.js.map +0 -1
- package/dist/chunk-ODUM3D6X.js.map +0 -1
- package/dist/chunk-QVMEF6FB.js.map +0 -1
- package/dist/chunk-TRXBJEZ5.js +0 -447
- package/dist/chunk-TRXBJEZ5.js.map +0 -1
- package/dist/chunk-VUNV25KB.js +0 -16
- package/dist/chunk-WIIZNPCR.js.map +0 -1
- package/dist/chunk-WXVT3AOY.js.map +0 -1
- package/dist/chunk-XIBG7LSL.js.map +0 -1
- package/dist/config-editor-3IKBPZA7.js +0 -11
- package/dist/core-plugins-ROU4GPLT.js +0 -23
- package/dist/dist-UHQK5CXN.js +0 -21151
- package/dist/dist-UHQK5CXN.js.map +0 -1
- package/dist/doctor-QZQAP46W.js +0 -10
- package/dist/file-service-EUODJAIT.js +0 -9
- package/dist/main-UVTZ46WP.js.map +0 -1
- package/dist/notifications-D5BRDNSU.js +0 -9
- package/dist/plugin-installer-GQ2P3Q3E.js +0 -23
- package/dist/plugin-installer-GQ2P3Q3E.js.map +0 -1
- package/dist/setup-EYAFK2WI.js.map +0 -1
- package/dist/slack-37ZWBDUI.js +0 -8
- package/dist/speech-2GHQNRIO.js +0 -9
- package/dist/telegram-2ZCCCZIY.js +0 -8
- package/dist/tunnel-45HA72MB.js +0 -8
- package/dist/version-NQZBM5M7.js.map +0 -1
- /package/dist/{adapter-LC2QSDAS.js.map → adapter-HGJENQCN.js.map} +0 -0
- /package/dist/{agent-catalog-YHBFERYO.js.map → agent-catalog-SZQQERV7.js.map} +0 -0
- /package/dist/{agent-dependencies-WS7Z2DFW.js.map → agent-dependencies-ED2ZTUHG.js.map} +0 -0
- /package/dist/{agent-registry-5LZT7CUB.js.map → agent-registry-YOGP656W.js.map} +0 -0
- /package/dist/{agent-store-VSHNY5GT.js.map → agent-store-5UHZH2XI.js.map} +0 -0
- /package/dist/{api-client-AQPNKXI2.js.map → api-client-XTLRRFPX.js.map} +0 -0
- /package/dist/{api-server-7G3ZUZRM.js.map → api-server-DSUW637I.js.map} +0 -0
- /package/dist/{api-server-CAYNPUF2.js.map → api-server-WFB5K6FP.js.map} +0 -0
- /package/dist/{autostart-6JS565RY.js.map → autostart-CUPZMKKC.js.map} +0 -0
- /package/dist/{chunk-PPSMUECX.js.map → chunk-2R5XM3ES.js.map} +0 -0
- /package/dist/{chunk-SNPYTMPR.js.map → chunk-3EWTPOF7.js.map} +0 -0
- /package/dist/{chunk-QAQDGPB4.js.map → chunk-43JVXFYP.js.map} +0 -0
- /package/dist/{chunk-A6Y4GZM3.js.map → chunk-566W6INH.js.map} +0 -0
- /package/dist/{chunk-36YQ44D7.js.map → chunk-5TCXYDLR.js.map} +0 -0
- /package/dist/{chunk-RBYBSSGO.js.map → chunk-FCTC7KDT.js.map} +0 -0
- /package/dist/{chunk-4GMLGCF2.js.map → chunk-JUFN4XMB.js.map} +0 -0
- /package/dist/{chunk-UMT7RU77.js.map → chunk-QBEQJFGL.js.map} +0 -0
- /package/dist/{chunk-SHTGQGAU.js.map → chunk-V2YZWYXT.js.map} +0 -0
- /package/dist/{chunk-BQ6FR32N.js.map → chunk-VD3QSMVY.js.map} +0 -0
- /package/dist/{chunk-VUNV25KB.js.map → config-UCAFCS5W.js.map} +0 -0
- /package/dist/{config-I4FMCJGZ.js.map → config-editor-OU6PUY66.js.map} +0 -0
- /package/dist/{config-editor-3IKBPZA7.js.map → config-registry-ZXAIJNYB.js.map} +0 -0
- /package/dist/{config-registry-CUMNXFGK.js.map → context-7MPU7RL5.js.map} +0 -0
- /package/dist/{context-XM6E22LM.js.map → core-plugins-R2EVZAJV.js.map} +0 -0
- /package/dist/{core-plugins-ROU4GPLT.js.map → daemon-DTA6KYYY.js.map} +0 -0
- /package/dist/{daemon-PXO5QPCR.js.map → doctor-D723IB2I.js.map} +0 -0
- /package/dist/{doctor-QZQAP46W.js.map → file-service-HHB3JQIO.js.map} +0 -0
- /package/dist/{file-service-EUODJAIT.js.map → log-YZ243M5G.js.map} +0 -0
- /package/dist/{log-LZ7FTRKG.js.map → menu-ALFN37IR.js.map} +0 -0
- /package/dist/{menu-YDQ2LWAR.js.map → notifications-MO23S7S3.js.map} +0 -0
- /package/dist/{notifications-D5BRDNSU.js.map → plugin-installer-5XHORMLS.js.map} +0 -0
- /package/dist/{plugin-registry-WB3DR67H.js.map → plugin-registry-6J3YSFHF.js.map} +0 -0
- /package/dist/{read-text-file-IRZM3QLM.js.map → read-text-file-DJBTITIB.js.map} +0 -0
- /package/dist/{registry-client-AVGRE4CF.js.map → registry-client-GTBWLXYU.js.map} +0 -0
- /package/dist/{security-YNRBW6S7.js.map → security-2BA265LN.js.map} +0 -0
- /package/dist/{settings-manager-MD2U4ZV2.js.map → settings-manager-B4UN2LAC.js.map} +0 -0
- /package/dist/{slack-37ZWBDUI.js.map → speech-GB7PHVQZ.js.map} +0 -0
- /package/dist/{speech-2GHQNRIO.js.map → telegram-UVIAXADE.js.map} +0 -0
- /package/dist/{telegram-2ZCCCZIY.js.map → tunnel-4WNFC7GO.js.map} +0 -0
- /package/dist/{tunnel-45HA72MB.js.map → validators-GITLOFXC.js.map} +0 -0
- /package/dist/{validators-WSTBNKRW.js.map → version-AXXV6IV2.js.map} +0 -0
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
installNpmPlugin
|
|
3
|
+
} from "./chunk-I53NEV3S.js";
|
|
4
|
+
import {
|
|
3
5
|
GroqSTT,
|
|
4
6
|
SpeechService
|
|
5
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-2KT6TROD.js";
|
|
6
8
|
|
|
7
9
|
// src/plugins/speech/index.ts
|
|
10
|
+
var EDGE_TTS_PLUGIN = "@openacp/msedge-tts-plugin";
|
|
8
11
|
var speechPlugin = {
|
|
9
12
|
name: "@openacp/speech",
|
|
10
13
|
version: "1.0.0",
|
|
11
14
|
description: "Text-to-speech and speech-to-text with pluggable providers",
|
|
12
15
|
essential: false,
|
|
13
16
|
optionalPluginDependencies: { "@openacp/file-service": "^1.0.0" },
|
|
14
|
-
permissions: ["services:register", "commands:register"],
|
|
17
|
+
permissions: ["services:register", "commands:register", "kernel:access"],
|
|
15
18
|
async install(ctx) {
|
|
16
19
|
const { terminal, settings, legacyConfig } = ctx;
|
|
17
20
|
if (legacyConfig) {
|
|
@@ -59,6 +62,13 @@ var speechPlugin = {
|
|
|
59
62
|
});
|
|
60
63
|
let ttsVoice = "";
|
|
61
64
|
if (ttsProvider === "edge-tts") {
|
|
65
|
+
terminal.log.info("Installing Edge TTS plugin...");
|
|
66
|
+
try {
|
|
67
|
+
await installNpmPlugin(EDGE_TTS_PLUGIN);
|
|
68
|
+
terminal.log.success("Edge TTS plugin installed");
|
|
69
|
+
} catch (err) {
|
|
70
|
+
terminal.log.warning(`Failed to install Edge TTS plugin: ${err}. You can install it later with: openacp plugin install ${EDGE_TTS_PLUGIN}`);
|
|
71
|
+
}
|
|
62
72
|
ttsVoice = await terminal.text({
|
|
63
73
|
message: "TTS voice (leave blank for default):",
|
|
64
74
|
placeholder: "e.g. en-US-AriaNeural"
|
|
@@ -111,7 +121,6 @@ var speechPlugin = {
|
|
|
111
121
|
async setup(ctx) {
|
|
112
122
|
const config = ctx.pluginConfig;
|
|
113
123
|
const groqApiKey = config.groqApiKey;
|
|
114
|
-
const ttsVoice = config.ttsVoice;
|
|
115
124
|
const sttProvider = groqApiKey ? "groq" : null;
|
|
116
125
|
const speechConfig = {
|
|
117
126
|
stt: {
|
|
@@ -119,7 +128,7 @@ var speechPlugin = {
|
|
|
119
128
|
providers: groqApiKey ? { groq: { apiKey: groqApiKey } } : {}
|
|
120
129
|
},
|
|
121
130
|
tts: {
|
|
122
|
-
provider: "edge-tts",
|
|
131
|
+
provider: config.ttsProvider ?? "edge-tts",
|
|
123
132
|
providers: {}
|
|
124
133
|
}
|
|
125
134
|
};
|
|
@@ -127,7 +136,6 @@ var speechPlugin = {
|
|
|
127
136
|
if (groqApiKey) {
|
|
128
137
|
service.registerSTTProvider("groq", new GroqSTT(groqApiKey));
|
|
129
138
|
}
|
|
130
|
-
service.registerTTSProvider("edge-tts", new EdgeTTS(ttsVoice));
|
|
131
139
|
service.setProviderFactory((cfg) => {
|
|
132
140
|
const sttMap = /* @__PURE__ */ new Map();
|
|
133
141
|
const ttsMap = /* @__PURE__ */ new Map();
|
|
@@ -135,23 +143,77 @@ var speechPlugin = {
|
|
|
135
143
|
if (groqCfg?.apiKey) {
|
|
136
144
|
sttMap.set("groq", new GroqSTT(groqCfg.apiKey, groqCfg.model));
|
|
137
145
|
}
|
|
138
|
-
const edgeVoice = cfg.tts?.providers?.["edge-tts"]?.voice;
|
|
139
|
-
ttsMap.set("edge-tts", new EdgeTTS(edgeVoice));
|
|
140
146
|
return { stt: sttMap, tts: ttsMap };
|
|
141
147
|
});
|
|
142
148
|
ctx.registerService("speech", service);
|
|
149
|
+
const setSessionVoiceMode = (pluginCtx, sessionId, voiceMode) => {
|
|
150
|
+
if (!sessionId) return;
|
|
151
|
+
try {
|
|
152
|
+
const sessionManager = pluginCtx.sessions;
|
|
153
|
+
const session = sessionManager.getSession(sessionId);
|
|
154
|
+
if (session) {
|
|
155
|
+
session.setVoiceMode(voiceMode);
|
|
156
|
+
}
|
|
157
|
+
} catch {
|
|
158
|
+
}
|
|
159
|
+
};
|
|
143
160
|
ctx.registerCommand({
|
|
144
161
|
name: "tts",
|
|
145
162
|
description: "Toggle text-to-speech",
|
|
146
|
-
usage: "on|off",
|
|
163
|
+
usage: "on|off|next|install",
|
|
147
164
|
category: "plugin",
|
|
148
165
|
handler: async (args) => {
|
|
149
166
|
const mode = args.raw.trim().toLowerCase();
|
|
150
|
-
if (mode === "on"
|
|
151
|
-
|
|
167
|
+
if ((mode === "on" || mode === "" || mode === "next") && !service.isTTSAvailable()) {
|
|
168
|
+
return {
|
|
169
|
+
type: "menu",
|
|
170
|
+
title: "TTS provider not installed. Install Edge TTS plugin?",
|
|
171
|
+
options: [
|
|
172
|
+
{ label: "Install Edge TTS", command: "/tts install" },
|
|
173
|
+
{ label: "Cancel", command: "/tts off" }
|
|
174
|
+
]
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (mode === "install") {
|
|
178
|
+
try {
|
|
179
|
+
const mod = await installNpmPlugin(EDGE_TTS_PLUGIN);
|
|
180
|
+
const plugin = mod.default;
|
|
181
|
+
if (plugin && ctx.core) {
|
|
182
|
+
const lm = ctx.core.lifecycleManager;
|
|
183
|
+
const registry = lm.registry;
|
|
184
|
+
if (registry) {
|
|
185
|
+
registry.register(plugin.name, {
|
|
186
|
+
version: plugin.version,
|
|
187
|
+
source: "npm",
|
|
188
|
+
enabled: true,
|
|
189
|
+
settingsPath: "",
|
|
190
|
+
description: plugin.description
|
|
191
|
+
});
|
|
192
|
+
await registry.save();
|
|
193
|
+
}
|
|
194
|
+
await lm.boot([plugin]);
|
|
195
|
+
}
|
|
196
|
+
return { type: "text", text: "Edge TTS plugin installed and ready! Use /tts on to enable." };
|
|
197
|
+
} catch (err) {
|
|
198
|
+
return { type: "error", message: `Failed to install Edge TTS plugin: ${err}. Try manually: openacp plugin install ${EDGE_TTS_PLUGIN}` };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (mode === "on") {
|
|
202
|
+
setSessionVoiceMode(ctx, args.sessionId, "on");
|
|
203
|
+
return { type: "text", text: "Text-to-speech enabled" };
|
|
204
|
+
}
|
|
205
|
+
if (mode === "off") {
|
|
206
|
+
setSessionVoiceMode(ctx, args.sessionId, "off");
|
|
207
|
+
return { type: "text", text: "Text-to-speech disabled" };
|
|
208
|
+
}
|
|
209
|
+
if (mode === "next") {
|
|
210
|
+
setSessionVoiceMode(ctx, args.sessionId, "next");
|
|
211
|
+
return { type: "text", text: "Text-to-speech enabled for next message" };
|
|
212
|
+
}
|
|
152
213
|
return { type: "menu", title: "Text to Speech", options: [
|
|
153
214
|
{ label: "Enable", command: "/tts on" },
|
|
154
|
-
{ label: "Disable", command: "/tts off" }
|
|
215
|
+
{ label: "Disable", command: "/tts off" },
|
|
216
|
+
{ label: "Next message only", command: "/tts next" }
|
|
155
217
|
] };
|
|
156
218
|
}
|
|
157
219
|
});
|
|
@@ -163,4 +225,4 @@ var speech_default = speechPlugin;
|
|
|
163
225
|
export {
|
|
164
226
|
speech_default
|
|
165
227
|
};
|
|
166
|
-
//# sourceMappingURL=chunk-
|
|
228
|
+
//# sourceMappingURL=chunk-NT6FYV27.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/plugins/speech/index.ts"],"sourcesContent":["import type { OpenACPPlugin, InstallContext, PluginContext } from '../../core/plugin/types.js'\nimport type { OpenACPCore } from '../../core/core.js'\nimport type { Session } from '../../core/sessions/session.js'\nimport { SpeechService, GroqSTT } from './exports.js'\nimport type { SpeechServiceConfig } from './exports.js'\nimport { installNpmPlugin } from '../../core/plugin/plugin-installer.js'\n\nconst EDGE_TTS_PLUGIN = '@openacp/msedge-tts-plugin'\n\nconst speechPlugin: OpenACPPlugin = {\n name: '@openacp/speech',\n version: '1.0.0',\n description: 'Text-to-speech and speech-to-text with pluggable providers',\n essential: false,\n optionalPluginDependencies: { '@openacp/file-service': '^1.0.0' },\n permissions: ['services:register', 'commands:register', 'kernel:access'],\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 speechCfg = legacyConfig.speech as Record<string, unknown> | undefined\n if (speechCfg) {\n const stt = speechCfg.stt as Record<string, unknown> | undefined\n const tts = speechCfg.tts as Record<string, unknown> | undefined\n const groqProviders = stt?.providers as Record<string, unknown> | undefined\n const groqConfig = groqProviders?.groq as Record<string, unknown> | undefined\n await settings.setAll({\n sttProvider: stt?.provider ?? null,\n groqApiKey: groqConfig?.apiKey ?? '',\n ttsProvider: tts?.provider ?? 'edge-tts',\n ttsVoice: '',\n })\n terminal.log.success('Speech settings migrated from legacy config')\n return\n }\n }\n\n // Interactive setup\n const enableStt = await terminal.confirm({\n message: 'Enable speech-to-text (STT)?',\n initialValue: false,\n })\n\n let sttProvider: string | null = null\n let groqApiKey = ''\n\n if (enableStt) {\n sttProvider = await terminal.select({\n message: 'STT provider:',\n options: [{ value: 'groq', label: 'Groq (Whisper)', hint: 'Fast and affordable' }],\n })\n\n if (sttProvider === 'groq') {\n groqApiKey = await terminal.text({\n message: 'Groq API key:',\n validate: (v) => (!v.trim() ? 'API key cannot be empty' : undefined),\n })\n groqApiKey = groqApiKey.trim()\n }\n }\n\n const ttsProvider = await terminal.select({\n message: 'TTS provider:',\n options: [\n { value: 'edge-tts', label: 'Edge TTS', hint: 'Free, good quality' },\n { value: 'none', label: 'None (disable TTS)' },\n ],\n })\n\n let ttsVoice = ''\n if (ttsProvider === 'edge-tts') {\n terminal.log.info('Installing Edge TTS plugin...')\n try {\n await installNpmPlugin(EDGE_TTS_PLUGIN)\n terminal.log.success('Edge TTS plugin installed')\n } catch (err) {\n terminal.log.warning(`Failed to install Edge TTS plugin: ${err}. You can install it later with: openacp plugin install ${EDGE_TTS_PLUGIN}`)\n }\n\n ttsVoice = await terminal.text({\n message: 'TTS voice (leave blank for default):',\n placeholder: 'e.g. en-US-AriaNeural',\n })\n ttsVoice = ttsVoice.trim()\n }\n\n await settings.setAll({\n sttProvider,\n groqApiKey,\n ttsProvider: ttsProvider === 'none' ? null : ttsProvider,\n ttsVoice,\n })\n terminal.log.success('Speech 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: 'stt', label: 'Change STT provider/key' },\n { value: 'tts', label: 'Change TTS provider/voice' },\n { value: 'done', label: 'Done' },\n ],\n })\n\n if (choice === 'stt') {\n const key = await terminal.text({\n message: 'Groq API key (leave blank to disable STT):',\n defaultValue: (current.groqApiKey as string) ?? '',\n })\n const trimmed = key.trim()\n await settings.set('sttProvider', trimmed ? 'groq' : null)\n await settings.set('groqApiKey', trimmed)\n terminal.log.success('STT settings updated')\n } else if (choice === 'tts') {\n const voice = await terminal.text({\n message: 'TTS voice (leave blank for default):',\n defaultValue: (current.ttsVoice as string) ?? '',\n })\n await settings.set('ttsVoice', voice.trim())\n terminal.log.success('TTS settings updated')\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('Speech settings cleared')\n }\n },\n\n async setup(ctx) {\n const config = ctx.pluginConfig as Record<string, unknown>\n const groqApiKey = config.groqApiKey as string | undefined\n\n const sttProvider = groqApiKey ? 'groq' : null\n const speechConfig: SpeechServiceConfig = {\n stt: {\n provider: sttProvider,\n providers: groqApiKey ? { groq: { apiKey: groqApiKey } } : {},\n },\n tts: {\n provider: (config.ttsProvider as string) ?? 'edge-tts',\n providers: {},\n },\n }\n\n const service = new SpeechService(speechConfig)\n\n if (groqApiKey) {\n service.registerSTTProvider('groq', new GroqSTT(groqApiKey))\n }\n\n // TTS provider is now registered by @openacp/msedge-tts-plugin (no EdgeTTS here)\n\n // Register provider factory for hot-reload (STT only — TTS providers are managed by external plugins)\n service.setProviderFactory((cfg) => {\n const sttMap = new Map()\n const ttsMap = new Map()\n const groqCfg = cfg.stt?.providers?.groq\n if (groqCfg?.apiKey) {\n sttMap.set('groq', new GroqSTT(groqCfg.apiKey, groqCfg.model))\n }\n return { stt: sttMap, tts: ttsMap }\n })\n\n ctx.registerService('speech', service)\n\n // Helper to look up the session and set voiceMode\n const setSessionVoiceMode = (pluginCtx: PluginContext, sessionId: string | null, voiceMode: 'off' | 'next' | 'on'): void => {\n if (!sessionId) return\n try {\n const sessionManager = pluginCtx.sessions as { getSession(id: string): Session | undefined }\n const session = sessionManager.getSession(sessionId)\n if (session) {\n session.setVoiceMode(voiceMode)\n }\n } catch {\n // Session lookup may fail if kernel:access is unavailable; silently ignore\n }\n }\n\n ctx.registerCommand({\n name: 'tts',\n description: 'Toggle text-to-speech',\n usage: 'on|off|next|install',\n category: 'plugin',\n handler: async (args) => {\n const mode = args.raw.trim().toLowerCase()\n\n // Check if TTS provider is available\n if ((mode === 'on' || mode === '' || mode === 'next') && !service.isTTSAvailable()) {\n return {\n type: 'menu' as const,\n title: 'TTS provider not installed. Install Edge TTS plugin?',\n options: [\n { label: 'Install Edge TTS', command: '/tts install' },\n { label: 'Cancel', command: '/tts off' },\n ],\n }\n }\n\n if (mode === 'install') {\n try {\n const mod = await installNpmPlugin(EDGE_TTS_PLUGIN)\n const plugin = mod.default\n if (plugin && ctx.core) {\n const lm = (ctx.core as OpenACPCore).lifecycleManager\n const registry = lm.registry\n if (registry) {\n registry.register(plugin.name, {\n version: plugin.version,\n source: 'npm',\n enabled: true,\n settingsPath: '',\n description: plugin.description,\n })\n await registry.save()\n }\n await lm.boot([plugin])\n }\n return { type: 'text' as const, text: 'Edge TTS plugin installed and ready! Use /tts on to enable.' }\n } catch (err) {\n return { type: 'error' as const, message: `Failed to install Edge TTS plugin: ${err}. Try manually: openacp plugin install ${EDGE_TTS_PLUGIN}` }\n }\n }\n\n if (mode === 'on') {\n setSessionVoiceMode(ctx, args.sessionId, 'on')\n return { type: 'text' as const, text: 'Text-to-speech enabled' }\n }\n if (mode === 'off') {\n setSessionVoiceMode(ctx, args.sessionId, 'off')\n return { type: 'text' as const, text: 'Text-to-speech disabled' }\n }\n if (mode === 'next') {\n setSessionVoiceMode(ctx, args.sessionId, 'next')\n return { type: 'text' as const, text: 'Text-to-speech enabled for next message' }\n }\n return { type: 'menu' as const, title: 'Text to Speech', options: [\n { label: 'Enable', command: '/tts on' },\n { label: 'Disable', command: '/tts off' },\n { label: 'Next message only', command: '/tts next' },\n ]}\n },\n })\n\n ctx.log.info('Speech service ready')\n },\n}\n\nexport default speechPlugin\n"],"mappings":"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","names":[]}
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
isAutoStartInstalled,
|
|
4
4
|
isAutoStartSupported,
|
|
5
5
|
uninstallAutoStart
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2R5XM3ES.js";
|
|
7
7
|
import {
|
|
8
8
|
expandHome
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JOMDPFQ2.js";
|
|
10
10
|
|
|
11
11
|
// src/core/config/config-editor.ts
|
|
12
12
|
import * as os from "os";
|
|
@@ -102,7 +102,7 @@ async function editTelegram(config, updates) {
|
|
|
102
102
|
validate: (val) => val.trim().length > 0 || "Token cannot be empty"
|
|
103
103
|
});
|
|
104
104
|
try {
|
|
105
|
-
const { validateBotToken } = await import("./validators-
|
|
105
|
+
const { validateBotToken } = await import("./validators-GITLOFXC.js");
|
|
106
106
|
const result = await validateBotToken(token.trim());
|
|
107
107
|
if (result.ok) {
|
|
108
108
|
console.log(ok(`Connected to @${result.botUsername}`));
|
|
@@ -134,7 +134,7 @@ async function editTelegram(config, updates) {
|
|
|
134
134
|
return currentToken;
|
|
135
135
|
})();
|
|
136
136
|
try {
|
|
137
|
-
const { validateChatId } = await import("./validators-
|
|
137
|
+
const { validateChatId } = await import("./validators-GITLOFXC.js");
|
|
138
138
|
const result = await validateChatId(tokenForValidation, chatId);
|
|
139
139
|
if (result.ok) {
|
|
140
140
|
console.log(ok(`Group: ${result.title}${result.isForum ? "" : warn(" (topics not enabled)")}`));
|
|
@@ -167,7 +167,7 @@ async function ensureDiscordPlugin() {
|
|
|
167
167
|
}
|
|
168
168
|
try {
|
|
169
169
|
console.log(dim(`Installing ${DISCORD_PACKAGE}...`));
|
|
170
|
-
const { installNpmPlugin } = await import("./plugin-installer-
|
|
170
|
+
const { installNpmPlugin } = await import("./plugin-installer-5XHORMLS.js");
|
|
171
171
|
const mod = await installNpmPlugin(DISCORD_PACKAGE);
|
|
172
172
|
console.log(ok(`${DISCORD_PACKAGE} installed`));
|
|
173
173
|
return mod;
|
|
@@ -182,8 +182,8 @@ async function editDiscord(_config, _updates) {
|
|
|
182
182
|
if (!pluginModule) return;
|
|
183
183
|
const plugin = pluginModule.default;
|
|
184
184
|
if (plugin?.configure) {
|
|
185
|
-
const { SettingsManager } = await import("./settings-manager-
|
|
186
|
-
const { createInstallContext } = await import("./install-context-
|
|
185
|
+
const { SettingsManager } = await import("./settings-manager-B4UN2LAC.js");
|
|
186
|
+
const { createInstallContext } = await import("./install-context-EHYV5WRY.js");
|
|
187
187
|
const basePath = path.join(os.homedir(), ".openacp", "plugins");
|
|
188
188
|
const settingsManager = new SettingsManager(basePath);
|
|
189
189
|
const ctx = createInstallContext({
|
|
@@ -644,7 +644,7 @@ ${c.cyan}${c.bold}OpenACP Config Editor${c.reset}`);
|
|
|
644
644
|
}
|
|
645
645
|
}
|
|
646
646
|
async function sendConfigViaApi(port, updates) {
|
|
647
|
-
const { apiCall: call } = await import("./api-client-
|
|
647
|
+
const { apiCall: call } = await import("./api-client-XTLRRFPX.js");
|
|
648
648
|
const paths = flattenToPaths(updates);
|
|
649
649
|
for (const { path: path2, value } of paths) {
|
|
650
650
|
const res = await call(port, "/api/config", {
|
|
@@ -676,4 +676,4 @@ function flattenToPaths(obj, prefix = "") {
|
|
|
676
676
|
export {
|
|
677
677
|
runConfigEditor
|
|
678
678
|
};
|
|
679
|
-
//# sourceMappingURL=chunk-
|
|
679
|
+
//# sourceMappingURL=chunk-QBEQJFGL.js.map
|
|
@@ -169,6 +169,12 @@ function createSessionLogger(sessionId, parentLogger) {
|
|
|
169
169
|
return parentLogger.child({ sessionId });
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
|
+
function closeSessionLogger(logger) {
|
|
173
|
+
const dest = logger.__sessionDest;
|
|
174
|
+
if (dest && typeof dest.destroy === "function") {
|
|
175
|
+
dest.destroy();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
172
178
|
async function shutdownLogger() {
|
|
173
179
|
if (!initialized) return;
|
|
174
180
|
const transport = currentTransport;
|
|
@@ -218,7 +224,8 @@ export {
|
|
|
218
224
|
setLogLevel,
|
|
219
225
|
createChildLogger,
|
|
220
226
|
createSessionLogger,
|
|
227
|
+
closeSessionLogger,
|
|
221
228
|
shutdownLogger,
|
|
222
229
|
cleanupOldSessionLogs
|
|
223
230
|
};
|
|
224
|
-
//# sourceMappingURL=chunk-
|
|
231
|
+
//# sourceMappingURL=chunk-R6KZYF7D.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/utils/log.ts"],"sourcesContent":["import pino from 'pino'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport type { LoggingConfig } from '../config/config.js'\n\nexport type Logger = pino.Logger\n\n// --- Default console-only logger (pre-init) ---\nlet rootLogger: pino.Logger = pino({\n level: 'debug',\n transport: { target: 'pino-pretty', options: { colorize: true, translateTime: 'SYS:standard' } },\n})\nlet initialized = false\nlet logDir: string | undefined\nlet currentTransport: ReturnType<typeof pino.transport> | undefined\n\nfunction expandHome(p: string): string {\n return p.startsWith('~') ? path.join(os.homedir(), p.slice(1)) : p\n}\n\n// --- Variadic wrapper for backward compatibility ---\nfunction wrapVariadic(logger: pino.Logger) {\n return {\n info: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.info(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.info(args.map(String).join(' '))\n }\n },\n warn: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.warn(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.warn(args.map(String).join(' '))\n }\n },\n error: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.error(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.error(args.map(String).join(' '))\n }\n },\n debug: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.debug(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.debug(args.map(String).join(' '))\n }\n },\n fatal: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.fatal(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.fatal(args.map(String).join(' '))\n }\n },\n child: (bindings: pino.Bindings) => logger.child(bindings),\n }\n}\n\nexport const log = wrapVariadic(rootLogger)\n\n// --- Mute/unmute (suppress pino output during interactive prompts) ---\n\nlet muteCount = 0\nlet savedLevel = 'info'\n\nexport function muteLogger(): void {\n if (muteCount === 0) {\n savedLevel = rootLogger.level\n rootLogger.level = 'silent'\n }\n muteCount++\n}\n\nexport function unmuteLogger(): void {\n muteCount--\n if (muteCount <= 0) {\n muteCount = 0\n rootLogger.level = savedLevel\n }\n}\n\n// --- Public API ---\n\nexport function initLogger(config: LoggingConfig): Logger {\n if (initialized) return rootLogger\n\n const resolvedLogDir = expandHome(config.logDir)\n logDir = resolvedLogDir\n\n try {\n fs.mkdirSync(resolvedLogDir, { recursive: true })\n fs.mkdirSync(path.join(resolvedLogDir, 'sessions'), { recursive: true })\n } catch (err) {\n console.error(`[WARN] Failed to create log directory ${resolvedLogDir}, falling back to console-only:`, err)\n return rootLogger\n }\n\n const transports = pino.transport({\n targets: [\n {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'HH:mm:ss',\n ignore: 'pid,hostname',\n singleLine: true,\n },\n level: config.level,\n },\n {\n target: 'pino-roll',\n options: {\n file: path.join(resolvedLogDir, 'openacp.log'),\n size: config.maxFileSize,\n limit: { count: config.maxFiles },\n },\n level: config.level,\n },\n ],\n })\n\n currentTransport = transports\n rootLogger = pino({ level: config.level }, transports)\n initialized = true\n\n // Update the default log wrapper to use the new root logger\n Object.assign(log, wrapVariadic(rootLogger))\n\n return rootLogger\n}\n\n/** Change log level at runtime. Pino transport targets respect parent level changes automatically. */\nexport function setLogLevel(level: string): void {\n rootLogger.level = level\n}\n\nexport function createChildLogger(context: { module: string; [key: string]: unknown }): Logger {\n // Return a proxy that always delegates to the current rootLogger.\n // This ensures child loggers created at module-level (before initLogger)\n // pick up the initialized logger with pino-pretty transport.\n return new Proxy({} as Logger, {\n get(_target, prop, receiver) {\n const child = rootLogger.child(context)\n const value = Reflect.get(child, prop, receiver)\n return typeof value === 'function' ? value.bind(child) : value\n },\n })\n}\n\nexport function createSessionLogger(sessionId: string, parentLogger: Logger): Logger {\n const sessionLogDir = logDir ? path.join(logDir, 'sessions') : undefined\n if (!sessionLogDir) {\n return parentLogger.child({ sessionId })\n }\n\n try {\n const sessionLogPath = path.join(sessionLogDir, `${sessionId}.log`)\n const dest = pino.destination(sessionLogPath)\n const sessionFileLogger = pino({ level: parentLogger.level }, dest).child({ sessionId })\n\n // Create a logger that writes to both parent (combined) and session file\n const combinedChild = parentLogger.child({ sessionId })\n const originalInfo = combinedChild.info.bind(combinedChild)\n const originalWarn = combinedChild.warn.bind(combinedChild)\n const originalError = combinedChild.error.bind(combinedChild)\n const originalDebug = combinedChild.debug.bind(combinedChild)\n const originalFatal = combinedChild.fatal.bind(combinedChild)\n\n // Proxy log methods to write to both destinations\n combinedChild.info = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.info(objOrMsg, ...rest)\n return originalInfo(objOrMsg, ...rest)\n }) as any\n combinedChild.warn = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.warn(objOrMsg, ...rest)\n return originalWarn(objOrMsg, ...rest)\n }) as any\n combinedChild.error = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.error(objOrMsg, ...rest)\n return originalError(objOrMsg, ...rest)\n }) as any\n combinedChild.debug = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.debug(objOrMsg, ...rest)\n return originalDebug(objOrMsg, ...rest)\n }) as any\n combinedChild.fatal = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.fatal(objOrMsg, ...rest)\n return originalFatal(objOrMsg, ...rest)\n }) as any\n\n // Store dest for cleanup\n ;(combinedChild as any).__sessionDest = dest\n\n return combinedChild\n } catch (err) {\n // Graceful degradation: session file failed, just use combined log\n parentLogger.warn({ sessionId, err }, 'Failed to create session log file, using combined log only')\n return parentLogger.child({ sessionId })\n }\n}\n\nexport async function shutdownLogger(): Promise<void> {\n if (!initialized) return\n\n const transport = currentTransport\n\n // Reset state immediately so re-init is possible\n rootLogger = pino({ level: 'debug' })\n Object.assign(log, wrapVariadic(rootLogger))\n currentTransport = undefined\n logDir = undefined\n initialized = false\n\n if (transport) {\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(resolve, 3000)\n transport.on('close', () => {\n clearTimeout(timeout)\n resolve()\n })\n transport.end()\n })\n }\n}\n\nexport async function cleanupOldSessionLogs(retentionDays: number): Promise<void> {\n if (!logDir) return\n\n const sessionsDir = path.join(logDir, 'sessions')\n try {\n const files = await fs.promises.readdir(sessionsDir)\n const cutoff = Date.now() - retentionDays * 24 * 60 * 60 * 1000\n\n for (const file of files) {\n try {\n const filePath = path.join(sessionsDir, file)\n const stat = await fs.promises.stat(filePath)\n if (stat.mtimeMs < cutoff) {\n await fs.promises.unlink(filePath)\n rootLogger.debug({ file }, 'Deleted old session log')\n }\n } catch (err) {\n rootLogger.warn({ file, err }, 'Failed to delete old session log')\n }\n }\n } catch {\n // Sessions directory doesn't exist — no-op\n }\n}\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,QAAQ;AAMf,IAAI,aAA0B,KAAK;AAAA,EACjC,OAAO;AAAA,EACP,WAAW,EAAE,QAAQ,eAAe,SAAS,EAAE,UAAU,MAAM,eAAe,eAAe,EAAE;AACjG,CAAC;AACD,IAAI,cAAc;AAClB,IAAI;AACJ,IAAI;AAEJ,SAAS,WAAW,GAAmB;AACrC,SAAO,EAAE,WAAW,GAAG,IAAI,KAAK,KAAK,GAAG,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC,IAAI;AACnE;AAGA,SAAS,aAAa,QAAqB;AACzC,SAAO;AAAA,IACL,MAAM,IAAI,SAAoB;AAC5B,UAAI,KAAK,WAAW,EAAG;AACvB,UAAI,OAAO,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,QAAQ,EAAE,KAAK,CAAC,aAAa,QAAQ;AAClF,eAAO,KAAK,KAAK,CAAC,GAAa,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,MACxD,OAAO;AACL,eAAO,KAAK,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,IACA,MAAM,IAAI,SAAoB;AAC5B,UAAI,KAAK,WAAW,EAAG;AACvB,UAAI,OAAO,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,QAAQ,EAAE,KAAK,CAAC,aAAa,QAAQ;AAClF,eAAO,KAAK,KAAK,CAAC,GAAa,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,MACxD,OAAO;AACL,eAAO,KAAK,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,IACA,OAAO,IAAI,SAAoB;AAC7B,UAAI,KAAK,WAAW,EAAG;AACvB,UAAI,OAAO,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,QAAQ,EAAE,KAAK,CAAC,aAAa,QAAQ;AAClF,eAAO,MAAM,KAAK,CAAC,GAAa,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,MACzD,OAAO;AACL,eAAO,MAAM,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,IACA,OAAO,IAAI,SAAoB;AAC7B,UAAI,KAAK,WAAW,EAAG;AACvB,UAAI,OAAO,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,QAAQ,EAAE,KAAK,CAAC,aAAa,QAAQ;AAClF,eAAO,MAAM,KAAK,CAAC,GAAa,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,MACzD,OAAO;AACL,eAAO,MAAM,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,IACA,OAAO,IAAI,SAAoB;AAC7B,UAAI,KAAK,WAAW,EAAG;AACvB,UAAI,OAAO,KAAK,CAAC,MAAM,YAAY,KAAK,CAAC,MAAM,QAAQ,EAAE,KAAK,CAAC,aAAa,QAAQ;AAClF,eAAO,MAAM,KAAK,CAAC,GAAa,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC;AAAA,MACzD,OAAO;AACL,eAAO,MAAM,KAAK,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,IACA,OAAO,CAAC,aAA4B,OAAO,MAAM,QAAQ;AAAA,EAC3D;AACF;AAEO,IAAM,MAAM,aAAa,UAAU;AAI1C,IAAI,YAAY;AAChB,IAAI,aAAa;AAEV,SAAS,aAAmB;AACjC,MAAI,cAAc,GAAG;AACnB,iBAAa,WAAW;AACxB,eAAW,QAAQ;AAAA,EACrB;AACA;AACF;AAEO,SAAS,eAAqB;AACnC;AACA,MAAI,aAAa,GAAG;AAClB,gBAAY;AACZ,eAAW,QAAQ;AAAA,EACrB;AACF;AAIO,SAAS,WAAW,QAA+B;AACxD,MAAI,YAAa,QAAO;AAExB,QAAM,iBAAiB,WAAW,OAAO,MAAM;AAC/C,WAAS;AAET,MAAI;AACF,OAAG,UAAU,gBAAgB,EAAE,WAAW,KAAK,CAAC;AAChD,OAAG,UAAU,KAAK,KAAK,gBAAgB,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,EACzE,SAAS,KAAK;AACZ,YAAQ,MAAM,yCAAyC,cAAc,mCAAmC,GAAG;AAC3G,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,KAAK,UAAU;AAAA,IAChC,SAAS;AAAA,MACP;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,UAAU;AAAA,UACV,eAAe;AAAA,UACf,QAAQ;AAAA,UACR,YAAY;AAAA,QACd;AAAA,QACA,OAAO,OAAO;AAAA,MAChB;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,MAAM,KAAK,KAAK,gBAAgB,aAAa;AAAA,UAC7C,MAAM,OAAO;AAAA,UACb,OAAO,EAAE,OAAO,OAAO,SAAS;AAAA,QAClC;AAAA,QACA,OAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAAA,EACF,CAAC;AAED,qBAAmB;AACnB,eAAa,KAAK,EAAE,OAAO,OAAO,MAAM,GAAG,UAAU;AACrD,gBAAc;AAGd,SAAO,OAAO,KAAK,aAAa,UAAU,CAAC;AAE3C,SAAO;AACT;AAGO,SAAS,YAAY,OAAqB;AAC/C,aAAW,QAAQ;AACrB;AAEO,SAAS,kBAAkB,SAA6D;AAI7F,SAAO,IAAI,MAAM,CAAC,GAAa;AAAA,IAC7B,IAAI,SAAS,MAAM,UAAU;AAC3B,YAAM,QAAQ,WAAW,MAAM,OAAO;AACtC,YAAM,QAAQ,QAAQ,IAAI,OAAO,MAAM,QAAQ;AAC/C,aAAO,OAAO,UAAU,aAAa,MAAM,KAAK,KAAK,IAAI;AAAA,IAC3D;AAAA,EACF,CAAC;AACH;AAEO,SAAS,oBAAoB,WAAmB,cAA8B;AACnF,QAAM,gBAAgB,SAAS,KAAK,KAAK,QAAQ,UAAU,IAAI;AAC/D,MAAI,CAAC,eAAe;AAClB,WAAO,aAAa,MAAM,EAAE,UAAU,CAAC;AAAA,EACzC;AAEA,MAAI;AACF,UAAM,iBAAiB,KAAK,KAAK,eAAe,GAAG,SAAS,MAAM;AAClE,UAAM,OAAO,KAAK,YAAY,cAAc;AAC5C,UAAM,oBAAoB,KAAK,EAAE,OAAO,aAAa,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC;AAGvF,UAAM,gBAAgB,aAAa,MAAM,EAAE,UAAU,CAAC;AACtD,UAAM,eAAe,cAAc,KAAK,KAAK,aAAa;AAC1D,UAAM,eAAe,cAAc,KAAK,KAAK,aAAa;AAC1D,UAAM,gBAAgB,cAAc,MAAM,KAAK,aAAa;AAC5D,UAAM,gBAAgB,cAAc,MAAM,KAAK,aAAa;AAC5D,UAAM,gBAAgB,cAAc,MAAM,KAAK,aAAa;AAG5D,kBAAc,QAAQ,CAAC,aAAkB,SAAgB;AACvD,wBAAkB,KAAK,UAAU,GAAG,IAAI;AACxC,aAAO,aAAa,UAAU,GAAG,IAAI;AAAA,IACvC;AACA,kBAAc,QAAQ,CAAC,aAAkB,SAAgB;AACvD,wBAAkB,KAAK,UAAU,GAAG,IAAI;AACxC,aAAO,aAAa,UAAU,GAAG,IAAI;AAAA,IACvC;AACA,kBAAc,SAAS,CAAC,aAAkB,SAAgB;AACxD,wBAAkB,MAAM,UAAU,GAAG,IAAI;AACzC,aAAO,cAAc,UAAU,GAAG,IAAI;AAAA,IACxC;AACA,kBAAc,SAAS,CAAC,aAAkB,SAAgB;AACxD,wBAAkB,MAAM,UAAU,GAAG,IAAI;AACzC,aAAO,cAAc,UAAU,GAAG,IAAI;AAAA,IACxC;AACA,kBAAc,SAAS,CAAC,aAAkB,SAAgB;AACxD,wBAAkB,MAAM,UAAU,GAAG,IAAI;AACzC,aAAO,cAAc,UAAU,GAAG,IAAI;AAAA,IACxC;AAGC,IAAC,cAAsB,gBAAgB;AAExC,WAAO;AAAA,EACT,SAAS,KAAK;AAEZ,iBAAa,KAAK,EAAE,WAAW,IAAI,GAAG,4DAA4D;AAClG,WAAO,aAAa,MAAM,EAAE,UAAU,CAAC;AAAA,EACzC;AACF;AAEA,eAAsB,iBAAgC;AACpD,MAAI,CAAC,YAAa;AAElB,QAAM,YAAY;AAGlB,eAAa,KAAK,EAAE,OAAO,QAAQ,CAAC;AACpC,SAAO,OAAO,KAAK,aAAa,UAAU,CAAC;AAC3C,qBAAmB;AACnB,WAAS;AACT,gBAAc;AAEd,MAAI,WAAW;AACb,UAAM,IAAI,QAAc,CAAC,YAAY;AACnC,YAAM,UAAU,WAAW,SAAS,GAAI;AACxC,gBAAU,GAAG,SAAS,MAAM;AAC1B,qBAAa,OAAO;AACpB,gBAAQ;AAAA,MACV,CAAC;AACD,gBAAU,IAAI;AAAA,IAChB,CAAC;AAAA,EACH;AACF;AAEA,eAAsB,sBAAsB,eAAsC;AAChF,MAAI,CAAC,OAAQ;AAEb,QAAM,cAAc,KAAK,KAAK,QAAQ,UAAU;AAChD,MAAI;AACF,UAAM,QAAQ,MAAM,GAAG,SAAS,QAAQ,WAAW;AACnD,UAAM,SAAS,KAAK,IAAI,IAAI,gBAAgB,KAAK,KAAK,KAAK;AAE3D,eAAW,QAAQ,OAAO;AACxB,UAAI;AACF,cAAM,WAAW,KAAK,KAAK,aAAa,IAAI;AAC5C,cAAM,OAAO,MAAM,GAAG,SAAS,KAAK,QAAQ;AAC5C,YAAI,KAAK,UAAU,QAAQ;AACzB,gBAAM,GAAG,SAAS,OAAO,QAAQ;AACjC,qBAAW,MAAM,EAAE,KAAK,GAAG,yBAAyB;AAAA,QACtD;AAAA,MACF,SAAS,KAAK;AACZ,mBAAW,KAAK,EAAE,MAAM,IAAI,GAAG,kCAAkC;AAAA,MACnE;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/core/utils/log.ts"],"sourcesContent":["import pino from 'pino'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport type { LoggingConfig } from '../config/config.js'\n\nexport type Logger = pino.Logger\n\n// --- Default console-only logger (pre-init) ---\nlet rootLogger: pino.Logger = pino({\n level: 'debug',\n transport: { target: 'pino-pretty', options: { colorize: true, translateTime: 'SYS:standard' } },\n})\nlet initialized = false\nlet logDir: string | undefined\nlet currentTransport: ReturnType<typeof pino.transport> | undefined\n\nfunction expandHome(p: string): string {\n return p.startsWith('~') ? path.join(os.homedir(), p.slice(1)) : p\n}\n\n// --- Variadic wrapper for backward compatibility ---\nfunction wrapVariadic(logger: pino.Logger) {\n return {\n info: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.info(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.info(args.map(String).join(' '))\n }\n },\n warn: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.warn(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.warn(args.map(String).join(' '))\n }\n },\n error: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.error(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.error(args.map(String).join(' '))\n }\n },\n debug: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.debug(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.debug(args.map(String).join(' '))\n }\n },\n fatal: (...args: unknown[]) => {\n if (args.length === 0) return\n if (typeof args[0] === 'object' && args[0] !== null && !(args[0] instanceof Error)) {\n logger.fatal(args[0] as object, args.slice(1).join(' '))\n } else {\n logger.fatal(args.map(String).join(' '))\n }\n },\n child: (bindings: pino.Bindings) => logger.child(bindings),\n }\n}\n\nexport const log = wrapVariadic(rootLogger)\n\n// --- Mute/unmute (suppress pino output during interactive prompts) ---\n\nlet muteCount = 0\nlet savedLevel = 'info'\n\nexport function muteLogger(): void {\n if (muteCount === 0) {\n savedLevel = rootLogger.level\n rootLogger.level = 'silent'\n }\n muteCount++\n}\n\nexport function unmuteLogger(): void {\n muteCount--\n if (muteCount <= 0) {\n muteCount = 0\n rootLogger.level = savedLevel\n }\n}\n\n// --- Public API ---\n\nexport function initLogger(config: LoggingConfig): Logger {\n if (initialized) return rootLogger\n\n const resolvedLogDir = expandHome(config.logDir)\n logDir = resolvedLogDir\n\n try {\n fs.mkdirSync(resolvedLogDir, { recursive: true })\n fs.mkdirSync(path.join(resolvedLogDir, 'sessions'), { recursive: true })\n } catch (err) {\n console.error(`[WARN] Failed to create log directory ${resolvedLogDir}, falling back to console-only:`, err)\n return rootLogger\n }\n\n const transports = pino.transport({\n targets: [\n {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'HH:mm:ss',\n ignore: 'pid,hostname',\n singleLine: true,\n },\n level: config.level,\n },\n {\n target: 'pino-roll',\n options: {\n file: path.join(resolvedLogDir, 'openacp.log'),\n size: config.maxFileSize,\n limit: { count: config.maxFiles },\n },\n level: config.level,\n },\n ],\n })\n\n currentTransport = transports\n rootLogger = pino({ level: config.level }, transports)\n initialized = true\n\n // Update the default log wrapper to use the new root logger\n Object.assign(log, wrapVariadic(rootLogger))\n\n return rootLogger\n}\n\n/** Change log level at runtime. Pino transport targets respect parent level changes automatically. */\nexport function setLogLevel(level: string): void {\n rootLogger.level = level\n}\n\nexport function createChildLogger(context: { module: string; [key: string]: unknown }): Logger {\n // Return a proxy that always delegates to the current rootLogger.\n // This ensures child loggers created at module-level (before initLogger)\n // pick up the initialized logger with pino-pretty transport.\n return new Proxy({} as Logger, {\n get(_target, prop, receiver) {\n const child = rootLogger.child(context)\n const value = Reflect.get(child, prop, receiver)\n return typeof value === 'function' ? value.bind(child) : value\n },\n })\n}\n\nexport function createSessionLogger(sessionId: string, parentLogger: Logger): Logger {\n const sessionLogDir = logDir ? path.join(logDir, 'sessions') : undefined\n if (!sessionLogDir) {\n return parentLogger.child({ sessionId })\n }\n\n try {\n const sessionLogPath = path.join(sessionLogDir, `${sessionId}.log`)\n const dest = pino.destination(sessionLogPath)\n const sessionFileLogger = pino({ level: parentLogger.level }, dest).child({ sessionId })\n\n // Create a logger that writes to both parent (combined) and session file\n const combinedChild = parentLogger.child({ sessionId })\n const originalInfo = combinedChild.info.bind(combinedChild)\n const originalWarn = combinedChild.warn.bind(combinedChild)\n const originalError = combinedChild.error.bind(combinedChild)\n const originalDebug = combinedChild.debug.bind(combinedChild)\n const originalFatal = combinedChild.fatal.bind(combinedChild)\n\n // Proxy log methods to write to both destinations\n combinedChild.info = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.info(objOrMsg, ...rest)\n return originalInfo(objOrMsg, ...rest)\n }) as any\n combinedChild.warn = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.warn(objOrMsg, ...rest)\n return originalWarn(objOrMsg, ...rest)\n }) as any\n combinedChild.error = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.error(objOrMsg, ...rest)\n return originalError(objOrMsg, ...rest)\n }) as any\n combinedChild.debug = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.debug(objOrMsg, ...rest)\n return originalDebug(objOrMsg, ...rest)\n }) as any\n combinedChild.fatal = ((objOrMsg: any, ...rest: any[]) => {\n sessionFileLogger.fatal(objOrMsg, ...rest)\n return originalFatal(objOrMsg, ...rest)\n }) as any\n\n // Store dest for cleanup\n ;(combinedChild as any).__sessionDest = dest\n\n return combinedChild\n } catch (err) {\n // Graceful degradation: session file failed, just use combined log\n parentLogger.warn({ sessionId, err }, 'Failed to create session log file, using combined log only')\n return parentLogger.child({ sessionId })\n }\n}\n\nexport function closeSessionLogger(logger: Logger): void {\n const dest = (logger as any).__sessionDest\n if (dest && typeof dest.destroy === 'function') {\n dest.destroy()\n }\n}\n\nexport async function shutdownLogger(): Promise<void> {\n if (!initialized) return\n\n const transport = currentTransport\n\n // Reset state immediately so re-init is possible\n rootLogger = pino({ level: 'debug' })\n Object.assign(log, wrapVariadic(rootLogger))\n currentTransport = undefined\n logDir = undefined\n initialized = false\n\n if (transport) {\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(resolve, 3000)\n transport.on('close', () => {\n clearTimeout(timeout)\n resolve()\n })\n transport.end()\n })\n }\n}\n\nexport async function cleanupOldSessionLogs(retentionDays: number): Promise<void> {\n if (!logDir) return\n\n const sessionsDir = path.join(logDir, 'sessions')\n try {\n const files = await fs.promises.readdir(sessionsDir)\n const cutoff = Date.now() - retentionDays * 24 * 60 * 60 * 1000\n\n for (const file of files) {\n try {\n const filePath = path.join(sessionsDir, file)\n const stat = await fs.promises.stat(filePath)\n if (stat.mtimeMs < cutoff) {\n await fs.promises.unlink(filePath)\n rootLogger.debug({ file }, 'Deleted old session log')\n }\n } catch (err) {\n rootLogger.warn({ file, err }, 'Failed to delete old session log')\n }\n }\n } catch {\n // Sessions directory doesn't exist — no-op\n }\n}\n"],"mappings":"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","names":[]}
|