@openacp/cli 2026.327.5 → 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-P2G275VD.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-S3ZGPPXY.js → chunk-E2SLHZAC.js} +8 -12
- package/dist/{chunk-S3ZGPPXY.js.map → chunk-E2SLHZAC.js.map} +1 -1
- package/dist/{chunk-RBYBSSGO.js → chunk-FCTC7KDT.js} +2 -2
- package/dist/{plugin-installer-QVJP6VKV.js → chunk-I53NEV3S.js} +6 -3
- 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-HRKAXFWR.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-XWDW3XBE.js → chunk-RXMWJHWH.js} +687 -99
- 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 +103 -97
- 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 +37 -145
- package/dist/index.js +32 -28
- 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-3GF3EQTE.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-A7VPW46C.js → setup-OI6A3OXW.js} +109 -82
- 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-JQFQ3JAO.js +0 -15
- package/dist/adapter-UORRGHNH.js +0 -1030
- package/dist/adapter-UORRGHNH.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-32LVIEPW.js +0 -477
- package/dist/chunk-32LVIEPW.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-ODUM3D6X.js.map +0 -1
- package/dist/chunk-QVMEF6FB.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/chunk-XWDW3XBE.js.map +0 -1
- package/dist/chunk-ZNSO2QVC.js +0 -124
- package/dist/chunk-ZNSO2QVC.js.map +0 -1
- package/dist/config-editor-7PKW42GZ.js +0 -11
- package/dist/core-plugins-Y5US6RED.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-3GF3EQTE.js.map +0 -1
- package/dist/notifications-D5BRDNSU.js +0 -9
- package/dist/plugin-installer-QVJP6VKV.js.map +0 -1
- package/dist/setup-A7VPW46C.js.map +0 -1
- package/dist/slack-2XNWBOWH.js +0 -8
- package/dist/speech-2GHQNRIO.js +0 -9
- package/dist/telegram-E65IWFBW.js +0 -8
- package/dist/tunnel-45HA72MB.js +0 -8
- package/dist/version-NQZBM5M7.js.map +0 -1
- /package/dist/{adapter-JQFQ3JAO.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-P2G275VD.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-HRKAXFWR.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-7PKW42GZ.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-Y5US6RED.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-2XNWBOWH.js.map → speech-GB7PHVQZ.js.map} +0 -0
- /package/dist/{speech-2GHQNRIO.js.map → telegram-UVIAXADE.js.map} +0 -0
- /package/dist/{telegram-E65IWFBW.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
package/dist/chunk-32LVIEPW.js
DELETED
|
@@ -1,477 +0,0 @@
|
|
|
1
|
-
// src/core/adapter-primitives/format-utils.ts
|
|
2
|
-
function progressBar(ratio, length = 10) {
|
|
3
|
-
const filled = Math.round(Math.min(ratio, 1) * length);
|
|
4
|
-
return "\u2593".repeat(filled) + "\u2591".repeat(length - filled);
|
|
5
|
-
}
|
|
6
|
-
function formatTokens(n) {
|
|
7
|
-
return n >= 1e3 ? `${Math.round(n / 1e3)}k` : String(n);
|
|
8
|
-
}
|
|
9
|
-
function stripCodeFences(text) {
|
|
10
|
-
return text.replace(/```\w*\n?/g, "").replace(/```$/gm, "").trim();
|
|
11
|
-
}
|
|
12
|
-
function truncateContent(text, maxLen) {
|
|
13
|
-
if (text.length <= maxLen) return text;
|
|
14
|
-
return text.slice(0, maxLen) + "\n\u2026 (truncated)";
|
|
15
|
-
}
|
|
16
|
-
function splitMessage(text, maxLength) {
|
|
17
|
-
if (text.length <= maxLength) return [text];
|
|
18
|
-
const chunks = [];
|
|
19
|
-
let remaining = text;
|
|
20
|
-
while (remaining.length > 0) {
|
|
21
|
-
if (remaining.length <= maxLength) {
|
|
22
|
-
chunks.push(remaining);
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
const wouldLeaveSmall = remaining.length < maxLength * 1.3;
|
|
26
|
-
const searchLimit = wouldLeaveSmall ? Math.floor(remaining.length / 2) + 300 : maxLength;
|
|
27
|
-
const threshold = maxLength * 0.2;
|
|
28
|
-
let splitAt = remaining.lastIndexOf("\n\n", searchLimit);
|
|
29
|
-
if (splitAt === -1 || splitAt < threshold) {
|
|
30
|
-
splitAt = remaining.lastIndexOf("\n", searchLimit);
|
|
31
|
-
}
|
|
32
|
-
if (splitAt === -1 || splitAt < threshold) {
|
|
33
|
-
splitAt = searchLimit;
|
|
34
|
-
}
|
|
35
|
-
const candidate = remaining.slice(0, splitAt);
|
|
36
|
-
const fences = candidate.match(/```/g);
|
|
37
|
-
if (fences && fences.length % 2 !== 0) {
|
|
38
|
-
const closingFence = remaining.indexOf("```", splitAt);
|
|
39
|
-
if (closingFence !== -1) {
|
|
40
|
-
const afterFence = remaining.indexOf("\n", closingFence + 3);
|
|
41
|
-
const fenceSplit = afterFence !== -1 ? afterFence + 1 : closingFence + 3;
|
|
42
|
-
if (fenceSplit <= maxLength * 2) {
|
|
43
|
-
splitAt = fenceSplit;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
chunks.push(remaining.slice(0, splitAt));
|
|
48
|
-
remaining = remaining.slice(splitAt).replace(/^\n+/, "");
|
|
49
|
-
}
|
|
50
|
-
return chunks;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// src/core/adapter-primitives/format-types.ts
|
|
54
|
-
var STATUS_ICONS = {
|
|
55
|
-
pending: "\u23F3",
|
|
56
|
-
in_progress: "\u{1F504}",
|
|
57
|
-
completed: "\u2705",
|
|
58
|
-
failed: "\u274C",
|
|
59
|
-
cancelled: "\u{1F6AB}",
|
|
60
|
-
running: "\u{1F504}",
|
|
61
|
-
done: "\u2705",
|
|
62
|
-
error: "\u274C"
|
|
63
|
-
};
|
|
64
|
-
var KIND_ICONS = {
|
|
65
|
-
read: "\u{1F4D6}",
|
|
66
|
-
edit: "\u270F\uFE0F",
|
|
67
|
-
write: "\u270F\uFE0F",
|
|
68
|
-
delete: "\u{1F5D1}\uFE0F",
|
|
69
|
-
execute: "\u25B6\uFE0F",
|
|
70
|
-
command: "\u25B6\uFE0F",
|
|
71
|
-
bash: "\u25B6\uFE0F",
|
|
72
|
-
terminal: "\u25B6\uFE0F",
|
|
73
|
-
search: "\u{1F50D}",
|
|
74
|
-
web: "\u{1F310}",
|
|
75
|
-
fetch: "\u{1F310}",
|
|
76
|
-
agent: "\u{1F9E0}",
|
|
77
|
-
think: "\u{1F9E0}",
|
|
78
|
-
install: "\u{1F4E6}",
|
|
79
|
-
move: "\u{1F4E6}",
|
|
80
|
-
other: "\u{1F6E0}\uFE0F"
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// src/core/adapter-primitives/message-formatter.ts
|
|
84
|
-
function extractContentText(content, depth = 0) {
|
|
85
|
-
if (!content || depth > 5) return "";
|
|
86
|
-
if (typeof content === "string") return content;
|
|
87
|
-
if (Array.isArray(content)) {
|
|
88
|
-
return content.map((c) => extractContentText(c, depth + 1)).filter(Boolean).join("\n");
|
|
89
|
-
}
|
|
90
|
-
if (typeof content !== "object") return String(content);
|
|
91
|
-
const obj = content;
|
|
92
|
-
if (obj.text && typeof obj.text === "string") return obj.text;
|
|
93
|
-
if (obj.content) {
|
|
94
|
-
if (typeof obj.content === "string") return obj.content;
|
|
95
|
-
if (Array.isArray(obj.content)) {
|
|
96
|
-
return obj.content.map((c) => extractContentText(c, depth + 1)).filter(Boolean).join("\n");
|
|
97
|
-
}
|
|
98
|
-
return extractContentText(obj.content, depth + 1);
|
|
99
|
-
}
|
|
100
|
-
if (obj.input) return extractContentText(obj.input, depth + 1);
|
|
101
|
-
if (obj.output) return extractContentText(obj.output, depth + 1);
|
|
102
|
-
const keys = Object.keys(obj).filter((k) => k !== "type");
|
|
103
|
-
if (keys.length === 0) return "";
|
|
104
|
-
try {
|
|
105
|
-
return JSON.stringify(obj, null, 2);
|
|
106
|
-
} catch {
|
|
107
|
-
return "";
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
function parseRawInput(rawInput) {
|
|
111
|
-
try {
|
|
112
|
-
if (typeof rawInput === "string") {
|
|
113
|
-
return JSON.parse(rawInput);
|
|
114
|
-
}
|
|
115
|
-
if (typeof rawInput === "object" && rawInput !== null) {
|
|
116
|
-
return rawInput;
|
|
117
|
-
}
|
|
118
|
-
} catch {
|
|
119
|
-
}
|
|
120
|
-
return {};
|
|
121
|
-
}
|
|
122
|
-
function formatToolSummary(name, rawInput, displaySummary) {
|
|
123
|
-
if (displaySummary && typeof displaySummary === "string") {
|
|
124
|
-
return displaySummary;
|
|
125
|
-
}
|
|
126
|
-
const args = parseRawInput(rawInput);
|
|
127
|
-
const lowerName = name.toLowerCase();
|
|
128
|
-
if (lowerName === "read") {
|
|
129
|
-
const fp = args.file_path ?? args.filePath ?? "";
|
|
130
|
-
const limit = args.limit ? ` (${args.limit} lines)` : "";
|
|
131
|
-
return fp ? `\u{1F4D6} Read ${fp}${limit}` : `\u{1F527} ${name}`;
|
|
132
|
-
}
|
|
133
|
-
if (lowerName === "edit") {
|
|
134
|
-
const fp = args.file_path ?? args.filePath ?? "";
|
|
135
|
-
return fp ? `\u270F\uFE0F Edit ${fp}` : `\u{1F527} ${name}`;
|
|
136
|
-
}
|
|
137
|
-
if (lowerName === "write") {
|
|
138
|
-
const fp = args.file_path ?? args.filePath ?? "";
|
|
139
|
-
return fp ? `\u{1F4DD} Write ${fp}` : `\u{1F527} ${name}`;
|
|
140
|
-
}
|
|
141
|
-
if (lowerName === "bash" || lowerName === "terminal") {
|
|
142
|
-
const cmd = String(args.command ?? args.cmd ?? "").slice(0, 60);
|
|
143
|
-
return cmd ? `\u25B6\uFE0F Run: ${cmd}` : `\u25B6\uFE0F Terminal`;
|
|
144
|
-
}
|
|
145
|
-
if (lowerName === "grep") {
|
|
146
|
-
const pattern = args.pattern ?? "";
|
|
147
|
-
const path = args.path ?? "";
|
|
148
|
-
return pattern ? `\u{1F50D} Grep "${pattern}"${path ? ` in ${path}` : ""}` : `\u{1F527} ${name}`;
|
|
149
|
-
}
|
|
150
|
-
if (lowerName === "glob") {
|
|
151
|
-
const pattern = args.pattern ?? "";
|
|
152
|
-
return pattern ? `\u{1F50D} Glob ${pattern}` : `\u{1F527} ${name}`;
|
|
153
|
-
}
|
|
154
|
-
if (lowerName === "agent") {
|
|
155
|
-
const desc = String(args.description ?? "").slice(0, 60);
|
|
156
|
-
return desc ? `\u{1F9E0} Agent: ${desc}` : `\u{1F527} ${name}`;
|
|
157
|
-
}
|
|
158
|
-
if (lowerName === "webfetch" || lowerName === "web_fetch") {
|
|
159
|
-
const url = String(args.url ?? "").slice(0, 60);
|
|
160
|
-
return url ? `\u{1F310} Fetch ${url}` : `\u{1F527} ${name}`;
|
|
161
|
-
}
|
|
162
|
-
if (lowerName === "websearch" || lowerName === "web_search") {
|
|
163
|
-
const query = String(args.query ?? "").slice(0, 60);
|
|
164
|
-
return query ? `\u{1F310} Search "${query}"` : `\u{1F527} ${name}`;
|
|
165
|
-
}
|
|
166
|
-
return `\u{1F527} ${name}`;
|
|
167
|
-
}
|
|
168
|
-
function formatToolTitle(name, rawInput, displayTitle) {
|
|
169
|
-
if (displayTitle && typeof displayTitle === "string") {
|
|
170
|
-
return displayTitle;
|
|
171
|
-
}
|
|
172
|
-
const args = parseRawInput(rawInput);
|
|
173
|
-
const lowerName = name.toLowerCase();
|
|
174
|
-
if (["read", "edit", "write"].includes(lowerName)) {
|
|
175
|
-
return String(args.file_path ?? args.filePath ?? name);
|
|
176
|
-
}
|
|
177
|
-
if (lowerName === "bash" || lowerName === "terminal") {
|
|
178
|
-
return String(args.command ?? args.cmd ?? name).slice(0, 60);
|
|
179
|
-
}
|
|
180
|
-
if (lowerName === "grep") {
|
|
181
|
-
const pattern = args.pattern ?? "";
|
|
182
|
-
const path = args.path ?? "";
|
|
183
|
-
return pattern ? `"${pattern}"${path ? ` in ${path}` : ""}` : name;
|
|
184
|
-
}
|
|
185
|
-
if (lowerName === "glob") {
|
|
186
|
-
return String(args.pattern ?? name);
|
|
187
|
-
}
|
|
188
|
-
if (lowerName === "agent") {
|
|
189
|
-
return String(args.description ?? name).slice(0, 60);
|
|
190
|
-
}
|
|
191
|
-
if (["webfetch", "web_fetch"].includes(lowerName)) {
|
|
192
|
-
return String(args.url ?? name).slice(0, 60);
|
|
193
|
-
}
|
|
194
|
-
if (["websearch", "web_search"].includes(lowerName)) {
|
|
195
|
-
return String(args.query ?? name).slice(0, 60);
|
|
196
|
-
}
|
|
197
|
-
return name;
|
|
198
|
-
}
|
|
199
|
-
function resolveToolIcon(tool) {
|
|
200
|
-
const statusIcon = STATUS_ICONS[tool.status || ""];
|
|
201
|
-
if (statusIcon) return statusIcon;
|
|
202
|
-
const kind = tool.displayKind ?? tool.kind;
|
|
203
|
-
if (kind && KIND_ICONS[kind]) return KIND_ICONS[kind];
|
|
204
|
-
return "\u{1F527}";
|
|
205
|
-
}
|
|
206
|
-
var NOISE_RULES = [
|
|
207
|
-
{
|
|
208
|
-
match: (name) => name.toLowerCase() === "ls",
|
|
209
|
-
action: "hide"
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
match: (_name, kind, rawInput) => {
|
|
213
|
-
if (kind !== "read") return false;
|
|
214
|
-
const args = parseRawInput(rawInput);
|
|
215
|
-
const p = String(args.file_path ?? args.filePath ?? args.path ?? "");
|
|
216
|
-
return p.endsWith("/");
|
|
217
|
-
},
|
|
218
|
-
action: "hide"
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
match: (name) => name.toLowerCase() === "glob",
|
|
222
|
-
action: "hide"
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
match: (name) => name.toLowerCase() === "grep",
|
|
226
|
-
action: "hide"
|
|
227
|
-
}
|
|
228
|
-
];
|
|
229
|
-
function evaluateNoise(name, kind, rawInput) {
|
|
230
|
-
for (const rule of NOISE_RULES) {
|
|
231
|
-
if (rule.match(name, kind, rawInput)) return rule.action;
|
|
232
|
-
}
|
|
233
|
-
return null;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// src/core/adapter-primitives/messaging-adapter.ts
|
|
237
|
-
var HIDDEN_ON_LOW = /* @__PURE__ */ new Set(["thought", "usage"]);
|
|
238
|
-
var MessagingAdapter = class {
|
|
239
|
-
constructor(context, adapterConfig) {
|
|
240
|
-
this.context = context;
|
|
241
|
-
this.adapterConfig = adapterConfig;
|
|
242
|
-
}
|
|
243
|
-
// === Message dispatch flow ===
|
|
244
|
-
async sendMessage(sessionId, content) {
|
|
245
|
-
const verbosity = this.getVerbosity();
|
|
246
|
-
if (!this.shouldDisplay(content, verbosity)) return;
|
|
247
|
-
await this.dispatchMessage(sessionId, content, verbosity);
|
|
248
|
-
}
|
|
249
|
-
async dispatchMessage(sessionId, content, verbosity) {
|
|
250
|
-
switch (content.type) {
|
|
251
|
-
case "text":
|
|
252
|
-
return this.handleText(sessionId, content);
|
|
253
|
-
case "thought":
|
|
254
|
-
return this.handleThought(sessionId, content, verbosity);
|
|
255
|
-
case "tool_call":
|
|
256
|
-
return this.handleToolCall(sessionId, content, verbosity);
|
|
257
|
-
case "tool_update":
|
|
258
|
-
return this.handleToolUpdate(sessionId, content, verbosity);
|
|
259
|
-
case "plan":
|
|
260
|
-
return this.handlePlan(sessionId, content, verbosity);
|
|
261
|
-
case "usage":
|
|
262
|
-
return this.handleUsage(sessionId, content, verbosity);
|
|
263
|
-
case "error":
|
|
264
|
-
return this.handleError(sessionId, content);
|
|
265
|
-
case "attachment":
|
|
266
|
-
return this.handleAttachment(sessionId, content);
|
|
267
|
-
case "system_message":
|
|
268
|
-
return this.handleSystem(sessionId, content);
|
|
269
|
-
case "session_end":
|
|
270
|
-
return this.handleSessionEnd(sessionId, content);
|
|
271
|
-
case "mode_change":
|
|
272
|
-
return this.handleModeChange(sessionId, content);
|
|
273
|
-
case "config_update":
|
|
274
|
-
return this.handleConfigUpdate(sessionId, content);
|
|
275
|
-
case "model_update":
|
|
276
|
-
return this.handleModelUpdate(sessionId, content);
|
|
277
|
-
case "user_replay":
|
|
278
|
-
return this.handleUserReplay(sessionId, content);
|
|
279
|
-
case "resource":
|
|
280
|
-
return this.handleResource(sessionId, content);
|
|
281
|
-
case "resource_link":
|
|
282
|
-
return this.handleResourceLink(sessionId, content);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
// === Default handlers — all protected, all overridable ===
|
|
286
|
-
async handleText(_sessionId, _content) {
|
|
287
|
-
}
|
|
288
|
-
async handleThought(_sessionId, _content, _verbosity) {
|
|
289
|
-
}
|
|
290
|
-
async handleToolCall(_sessionId, _content, _verbosity) {
|
|
291
|
-
}
|
|
292
|
-
async handleToolUpdate(_sessionId, _content, _verbosity) {
|
|
293
|
-
}
|
|
294
|
-
async handlePlan(_sessionId, _content, _verbosity) {
|
|
295
|
-
}
|
|
296
|
-
async handleUsage(_sessionId, _content, _verbosity) {
|
|
297
|
-
}
|
|
298
|
-
async handleError(_sessionId, _content) {
|
|
299
|
-
}
|
|
300
|
-
async handleAttachment(_sessionId, _content) {
|
|
301
|
-
}
|
|
302
|
-
async handleSystem(_sessionId, _content) {
|
|
303
|
-
}
|
|
304
|
-
async handleSessionEnd(_sessionId, _content) {
|
|
305
|
-
}
|
|
306
|
-
async handleModeChange(_sessionId, _content) {
|
|
307
|
-
}
|
|
308
|
-
async handleConfigUpdate(_sessionId, _content) {
|
|
309
|
-
}
|
|
310
|
-
async handleModelUpdate(_sessionId, _content) {
|
|
311
|
-
}
|
|
312
|
-
async handleUserReplay(_sessionId, _content) {
|
|
313
|
-
}
|
|
314
|
-
async handleResource(_sessionId, _content) {
|
|
315
|
-
}
|
|
316
|
-
async handleResourceLink(_sessionId, _content) {
|
|
317
|
-
}
|
|
318
|
-
// === Helpers ===
|
|
319
|
-
getVerbosity() {
|
|
320
|
-
const config = this.context.configManager.get();
|
|
321
|
-
const channelConfig = config.channels;
|
|
322
|
-
const v = channelConfig?.[this.name]?.displayVerbosity ?? this.adapterConfig.displayVerbosity;
|
|
323
|
-
if (v === "low" || v === "high") return v;
|
|
324
|
-
return "medium";
|
|
325
|
-
}
|
|
326
|
-
shouldDisplay(content, verbosity) {
|
|
327
|
-
if (verbosity === "low" && HIDDEN_ON_LOW.has(content.type)) return false;
|
|
328
|
-
if (content.type === "tool_call") {
|
|
329
|
-
const meta = content.metadata ?? {};
|
|
330
|
-
const toolName = meta.name ?? content.text ?? "";
|
|
331
|
-
const toolKind = String(meta.kind ?? "other");
|
|
332
|
-
const noiseAction = evaluateNoise(toolName, toolKind, meta.rawInput);
|
|
333
|
-
if (noiseAction === "hide" && verbosity !== "high") return false;
|
|
334
|
-
if (noiseAction === "collapse" && verbosity === "low") return false;
|
|
335
|
-
}
|
|
336
|
-
return true;
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
|
|
340
|
-
// src/core/adapter-primitives/rendering/renderer.ts
|
|
341
|
-
var BaseRenderer = class {
|
|
342
|
-
renderText(content) {
|
|
343
|
-
return { body: content.text, format: "plain" };
|
|
344
|
-
}
|
|
345
|
-
renderToolCall(content, verbosity) {
|
|
346
|
-
const meta = content.metadata ?? {};
|
|
347
|
-
const name = meta.name ?? content.text ?? "Tool";
|
|
348
|
-
const icon = resolveToolIcon(meta);
|
|
349
|
-
const label = verbosity === "low" ? formatToolTitle(
|
|
350
|
-
name,
|
|
351
|
-
meta.rawInput,
|
|
352
|
-
meta.displayTitle
|
|
353
|
-
) : formatToolSummary(
|
|
354
|
-
name,
|
|
355
|
-
meta.rawInput,
|
|
356
|
-
meta.displaySummary
|
|
357
|
-
);
|
|
358
|
-
return { body: `${icon} ${label}`, format: "plain" };
|
|
359
|
-
}
|
|
360
|
-
renderToolUpdate(content, verbosity) {
|
|
361
|
-
const meta = content.metadata ?? {};
|
|
362
|
-
const name = meta.name ?? content.text ?? "Tool";
|
|
363
|
-
const icon = resolveToolIcon(meta);
|
|
364
|
-
const label = verbosity === "low" ? formatToolTitle(
|
|
365
|
-
name,
|
|
366
|
-
meta.rawInput,
|
|
367
|
-
meta.displayTitle
|
|
368
|
-
) : formatToolSummary(
|
|
369
|
-
name,
|
|
370
|
-
meta.rawInput,
|
|
371
|
-
meta.displaySummary
|
|
372
|
-
);
|
|
373
|
-
return { body: `${icon} ${label}`, format: "plain" };
|
|
374
|
-
}
|
|
375
|
-
renderPlan(content) {
|
|
376
|
-
const entries = content.metadata?.entries ?? [];
|
|
377
|
-
const lines = entries.map((e, i) => {
|
|
378
|
-
const icon = e.status === "completed" ? "\u2705" : e.status === "in_progress" ? "\u{1F504}" : "\u2B1C";
|
|
379
|
-
return `${icon} ${i + 1}. ${e.content}`;
|
|
380
|
-
});
|
|
381
|
-
return { body: `\u{1F4CB} Plan
|
|
382
|
-
${lines.join("\n")}`, format: "plain" };
|
|
383
|
-
}
|
|
384
|
-
renderUsage(content, verbosity) {
|
|
385
|
-
const meta = content.metadata;
|
|
386
|
-
if (!meta?.tokensUsed)
|
|
387
|
-
return { body: "\u{1F4CA} Usage data unavailable", format: "plain" };
|
|
388
|
-
const costStr = meta.cost != null ? ` \xB7 $${meta.cost.toFixed(2)}` : "";
|
|
389
|
-
if (verbosity === "medium") {
|
|
390
|
-
return {
|
|
391
|
-
body: `\u{1F4CA} ${formatTokens(meta.tokensUsed)} tokens${costStr}`,
|
|
392
|
-
format: "plain"
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
if (!meta.contextSize)
|
|
396
|
-
return {
|
|
397
|
-
body: `\u{1F4CA} ${formatTokens(meta.tokensUsed)} tokens`,
|
|
398
|
-
format: "plain"
|
|
399
|
-
};
|
|
400
|
-
const ratio = meta.tokensUsed / meta.contextSize;
|
|
401
|
-
const pct = Math.round(ratio * 100);
|
|
402
|
-
const bar = progressBar(ratio);
|
|
403
|
-
let text = `\u{1F4CA} ${formatTokens(meta.tokensUsed)} / ${formatTokens(meta.contextSize)} tokens
|
|
404
|
-
${bar} ${pct}%`;
|
|
405
|
-
if (meta.cost != null) text += `
|
|
406
|
-
\u{1F4B0} $${meta.cost.toFixed(2)}`;
|
|
407
|
-
return { body: text, format: "plain" };
|
|
408
|
-
}
|
|
409
|
-
renderPermission(request) {
|
|
410
|
-
return {
|
|
411
|
-
body: request.description,
|
|
412
|
-
format: "plain",
|
|
413
|
-
actions: request.options.map((o) => ({
|
|
414
|
-
id: o.id,
|
|
415
|
-
label: o.label,
|
|
416
|
-
isAllow: o.isAllow
|
|
417
|
-
}))
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
renderError(content) {
|
|
421
|
-
return { body: `\u274C Error: ${content.text}`, format: "plain" };
|
|
422
|
-
}
|
|
423
|
-
renderNotification(notification) {
|
|
424
|
-
const emoji = {
|
|
425
|
-
completed: "\u2705",
|
|
426
|
-
error: "\u274C",
|
|
427
|
-
permission: "\u{1F510}",
|
|
428
|
-
input_required: "\u{1F4AC}",
|
|
429
|
-
budget_warning: "\u26A0\uFE0F"
|
|
430
|
-
};
|
|
431
|
-
return {
|
|
432
|
-
body: `${emoji[notification.type] || "\u2139\uFE0F"} ${notification.sessionName || "Session"}
|
|
433
|
-
${notification.summary}`,
|
|
434
|
-
format: "plain"
|
|
435
|
-
};
|
|
436
|
-
}
|
|
437
|
-
renderSystemMessage(content) {
|
|
438
|
-
return { body: content.text, format: "plain" };
|
|
439
|
-
}
|
|
440
|
-
renderModeChange(content) {
|
|
441
|
-
const modeId = content.metadata?.modeId ?? "";
|
|
442
|
-
return { body: `\u{1F504} Mode: ${modeId}`, format: "plain" };
|
|
443
|
-
}
|
|
444
|
-
renderConfigUpdate() {
|
|
445
|
-
return { body: "\u2699\uFE0F Config updated", format: "plain" };
|
|
446
|
-
}
|
|
447
|
-
renderModelUpdate(content) {
|
|
448
|
-
const modelId = content.metadata?.modelId ?? "";
|
|
449
|
-
return { body: `\u{1F916} Model: ${modelId}`, format: "plain" };
|
|
450
|
-
}
|
|
451
|
-
renderResource(content) {
|
|
452
|
-
const uri = content.metadata?.uri ?? "";
|
|
453
|
-
return { body: `\u{1F4C4} Resource: ${content.text} (${uri})`, format: "plain" };
|
|
454
|
-
}
|
|
455
|
-
renderResourceLink(content) {
|
|
456
|
-
const uri = content.metadata?.uri ?? "";
|
|
457
|
-
return { body: `\u{1F517} ${content.text}: ${uri}`, format: "plain" };
|
|
458
|
-
}
|
|
459
|
-
};
|
|
460
|
-
|
|
461
|
-
export {
|
|
462
|
-
progressBar,
|
|
463
|
-
formatTokens,
|
|
464
|
-
stripCodeFences,
|
|
465
|
-
truncateContent,
|
|
466
|
-
splitMessage,
|
|
467
|
-
STATUS_ICONS,
|
|
468
|
-
KIND_ICONS,
|
|
469
|
-
extractContentText,
|
|
470
|
-
formatToolSummary,
|
|
471
|
-
formatToolTitle,
|
|
472
|
-
resolveToolIcon,
|
|
473
|
-
evaluateNoise,
|
|
474
|
-
MessagingAdapter,
|
|
475
|
-
BaseRenderer
|
|
476
|
-
};
|
|
477
|
-
//# sourceMappingURL=chunk-32LVIEPW.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/adapter-primitives/format-utils.ts","../../src/core/adapter-primitives/format-types.ts","../../src/core/adapter-primitives/message-formatter.ts","../../src/core/adapter-primitives/messaging-adapter.ts","../../src/core/adapter-primitives/rendering/renderer.ts"],"sourcesContent":["export function progressBar(ratio: number, length = 10): string {\n const filled = Math.round(Math.min(ratio, 1) * length);\n return \"▓\".repeat(filled) + \"░\".repeat(length - filled);\n}\n\nexport function formatTokens(n: number): string {\n return n >= 1000 ? `${Math.round(n / 1000)}k` : String(n);\n}\n\nexport function stripCodeFences(text: string): string {\n return text\n .replace(/```\\w*\\n?/g, \"\")\n .replace(/```$/gm, \"\")\n .trim();\n}\n\nexport function truncateContent(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return text.slice(0, maxLen) + \"\\n… (truncated)\";\n}\n\nexport function splitMessage(text: string, maxLength: number): string[] {\n if (text.length <= maxLength) return [text];\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (remaining.length <= maxLength) {\n chunks.push(remaining);\n break;\n }\n\n const wouldLeaveSmall = remaining.length < maxLength * 1.3;\n const searchLimit = wouldLeaveSmall\n ? Math.floor(remaining.length / 2) + 300\n : maxLength;\n\n const threshold = maxLength * 0.2;\n let splitAt = remaining.lastIndexOf(\"\\n\\n\", searchLimit);\n if (splitAt === -1 || splitAt < threshold) {\n splitAt = remaining.lastIndexOf(\"\\n\", searchLimit);\n }\n if (splitAt === -1 || splitAt < threshold) {\n splitAt = searchLimit;\n }\n\n const candidate = remaining.slice(0, splitAt);\n const fences = candidate.match(/```/g);\n if (fences && fences.length % 2 !== 0) {\n const closingFence = remaining.indexOf(\"```\", splitAt);\n if (closingFence !== -1) {\n const afterFence = remaining.indexOf(\"\\n\", closingFence + 3);\n const fenceSplit =\n afterFence !== -1 ? afterFence + 1 : closingFence + 3;\n // Only extend to include the closing fence if it doesn't exceed 2x maxLength\n if (fenceSplit <= maxLength * 2) {\n splitAt = fenceSplit;\n }\n }\n }\n\n chunks.push(remaining.slice(0, splitAt));\n remaining = remaining.slice(splitAt).replace(/^\\n+/, \"\");\n }\n return chunks;\n}\n","// src/adapters/shared/format-types.ts\n\nexport type DisplayVerbosity = \"low\" | \"medium\" | \"high\";\n\nexport type NoiseAction = \"hide\" | \"collapse\";\n\nexport interface NoiseRule {\n match: (name: string, kind: string, rawInput: unknown) => boolean;\n action: NoiseAction;\n}\n\nexport type MessageStyle =\n | \"text\"\n | \"thought\"\n | \"tool\"\n | \"plan\"\n | \"usage\"\n | \"system\"\n | \"error\"\n | \"attachment\";\n\nexport interface MessageMetadata {\n toolName?: string;\n toolStatus?: string;\n toolKind?: string;\n filePath?: string;\n command?: string;\n planEntries?: { content: string; status: string }[];\n tokens?: number;\n contextSize?: number;\n cost?: number;\n viewerLinks?: ViewerLinks;\n viewerFilePath?: string;\n}\n\n/** summary and detail are always plain text (never pre-escaped HTML/markdown) — renderers handle escaping */\nexport interface FormattedMessage {\n summary: string;\n detail?: string;\n viewerLinks?: ViewerLinks;\n icon: string;\n originalType: string;\n style: MessageStyle;\n metadata?: MessageMetadata;\n}\n\nexport const STATUS_ICONS: Record<string, string> = {\n pending: \"⏳\",\n in_progress: \"🔄\",\n completed: \"✅\",\n failed: \"❌\",\n cancelled: \"🚫\",\n running: \"🔄\",\n done: \"✅\",\n error: \"❌\",\n};\n\nexport const KIND_ICONS: Record<string, string> = {\n read: \"📖\",\n edit: \"✏️\",\n write: \"✏️\",\n delete: \"🗑️\",\n execute: \"▶️\",\n command: \"▶️\",\n bash: \"▶️\",\n terminal: \"▶️\",\n search: \"🔍\",\n web: \"🌐\",\n fetch: \"🌐\",\n agent: \"🧠\",\n think: \"🧠\",\n install: \"📦\",\n move: \"📦\",\n other: \"🛠️\",\n};\n\nexport interface ViewerLinks {\n file?: string;\n diff?: string;\n}\n\nexport interface ToolCallMeta {\n id: string;\n name: string;\n kind?: string;\n status?: string;\n content?: unknown;\n rawInput?: unknown;\n viewerLinks?: ViewerLinks;\n viewerFilePath?: string;\n displaySummary?: string;\n displayTitle?: string;\n displayKind?: string;\n}\n\nexport interface ToolUpdateMeta extends ToolCallMeta {\n status: string;\n}\n","import type { NoiseAction, NoiseRule } from \"./format-types.js\";\nimport { STATUS_ICONS, KIND_ICONS } from \"./format-types.js\";\n\nexport function extractContentText(content: unknown, depth = 0): string {\n if (!content || depth > 5) return \"\";\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return content\n .map((c) => extractContentText(c, depth + 1))\n .filter(Boolean)\n .join(\"\\n\");\n }\n if (typeof content !== \"object\") return String(content);\n\n const obj = content as Record<string, unknown>;\n if (obj.text && typeof obj.text === \"string\") return obj.text;\n if (obj.content) {\n if (typeof obj.content === \"string\") return obj.content;\n if (Array.isArray(obj.content)) {\n return obj.content\n .map((c) => extractContentText(c, depth + 1))\n .filter(Boolean)\n .join(\"\\n\");\n }\n return extractContentText(obj.content, depth + 1);\n }\n if (obj.input) return extractContentText(obj.input, depth + 1);\n if (obj.output) return extractContentText(obj.output, depth + 1);\n\n // Skip objects with only a 'type' key and no content fields\n const keys = Object.keys(obj).filter((k) => k !== \"type\");\n if (keys.length === 0) return \"\";\n\n // Fallback: serialize unrecognized objects so edge-case agent responses are not silently dropped\n try {\n return JSON.stringify(obj, null, 2);\n } catch {\n return \"\";\n }\n}\n\nfunction parseRawInput(rawInput: unknown): Record<string, unknown> {\n try {\n if (typeof rawInput === \"string\") {\n return JSON.parse(rawInput) as Record<string, unknown>;\n }\n if (typeof rawInput === \"object\" && rawInput !== null) {\n return rawInput as Record<string, unknown>;\n }\n } catch {\n // fall through\n }\n return {};\n}\n\n// --- Step 5: formatToolSummary with displaySummary override ---\n\nexport function formatToolSummary(\n name: string,\n rawInput: unknown,\n displaySummary?: string,\n): string {\n if (displaySummary && typeof displaySummary === \"string\") {\n return displaySummary;\n }\n\n const args = parseRawInput(rawInput);\n const lowerName = name.toLowerCase();\n\n if (lowerName === \"read\") {\n const fp = args.file_path ?? args.filePath ?? \"\";\n const limit = args.limit ? ` (${args.limit} lines)` : \"\";\n return fp ? `📖 Read ${fp}${limit}` : `🔧 ${name}`;\n }\n if (lowerName === \"edit\") {\n const fp = args.file_path ?? args.filePath ?? \"\";\n return fp ? `✏️ Edit ${fp}` : `🔧 ${name}`;\n }\n if (lowerName === \"write\") {\n const fp = args.file_path ?? args.filePath ?? \"\";\n return fp ? `📝 Write ${fp}` : `🔧 ${name}`;\n }\n if (lowerName === \"bash\" || lowerName === \"terminal\") {\n const cmd = String(args.command ?? args.cmd ?? \"\").slice(0, 60);\n return cmd ? `▶️ Run: ${cmd}` : `▶️ Terminal`;\n }\n if (lowerName === \"grep\") {\n const pattern = args.pattern ?? \"\";\n const path = args.path ?? \"\";\n return pattern\n ? `🔍 Grep \"${pattern}\"${path ? ` in ${path}` : \"\"}`\n : `🔧 ${name}`;\n }\n if (lowerName === \"glob\") {\n const pattern = args.pattern ?? \"\";\n return pattern ? `🔍 Glob ${pattern}` : `🔧 ${name}`;\n }\n if (lowerName === \"agent\") {\n const desc = String(args.description ?? \"\").slice(0, 60);\n return desc ? `🧠 Agent: ${desc}` : `🔧 ${name}`;\n }\n if (lowerName === \"webfetch\" || lowerName === \"web_fetch\") {\n const url = String(args.url ?? \"\").slice(0, 60);\n return url ? `🌐 Fetch ${url}` : `🔧 ${name}`;\n }\n if (lowerName === \"websearch\" || lowerName === \"web_search\") {\n const query = String(args.query ?? \"\").slice(0, 60);\n return query ? `🌐 Search \"${query}\"` : `🔧 ${name}`;\n }\n\n return `🔧 ${name}`;\n}\n\n// --- Step 6: formatToolTitle for low verbosity ---\n\nexport function formatToolTitle(\n name: string,\n rawInput: unknown,\n displayTitle?: string,\n): string {\n if (displayTitle && typeof displayTitle === \"string\") {\n return displayTitle;\n }\n\n const args = parseRawInput(rawInput);\n const lowerName = name.toLowerCase();\n\n if ([\"read\", \"edit\", \"write\"].includes(lowerName)) {\n return String(args.file_path ?? args.filePath ?? name);\n }\n if (lowerName === \"bash\" || lowerName === \"terminal\") {\n return String(args.command ?? args.cmd ?? name).slice(0, 60);\n }\n if (lowerName === \"grep\") {\n const pattern = args.pattern ?? \"\";\n const path = args.path ?? \"\";\n return pattern ? `\"${pattern}\"${path ? ` in ${path}` : \"\"}` : name;\n }\n if (lowerName === \"glob\") {\n return String(args.pattern ?? name);\n }\n if (lowerName === \"agent\") {\n return String(args.description ?? name).slice(0, 60);\n }\n if ([\"webfetch\", \"web_fetch\"].includes(lowerName)) {\n return String(args.url ?? name).slice(0, 60);\n }\n if ([\"websearch\", \"web_search\"].includes(lowerName)) {\n return String(args.query ?? name).slice(0, 60);\n }\n\n return name;\n}\n\n// --- Step 7: resolveToolIcon ---\n\nexport function resolveToolIcon(tool: {\n status?: string;\n displayKind?: string;\n kind?: string;\n}): string {\n const statusIcon = STATUS_ICONS[tool.status || \"\"];\n if (statusIcon) return statusIcon;\n const kind = tool.displayKind ?? tool.kind;\n if (kind && KIND_ICONS[kind]) return KIND_ICONS[kind];\n return \"🔧\";\n}\n\n// --- Step 8: Noise filtering ---\n\nconst NOISE_RULES: NoiseRule[] = [\n {\n match: (name) => name.toLowerCase() === \"ls\",\n action: \"hide\",\n },\n {\n match: (_name, kind, rawInput) => {\n if (kind !== \"read\") return false;\n const args = parseRawInput(rawInput);\n const p = String(args.file_path ?? args.filePath ?? args.path ?? \"\");\n return p.endsWith(\"/\");\n },\n action: \"hide\",\n },\n {\n match: (name) => name.toLowerCase() === \"glob\",\n action: \"hide\",\n },\n {\n match: (name) => name.toLowerCase() === \"grep\",\n action: \"hide\",\n },\n];\n\nexport function evaluateNoise(\n name: string,\n kind: string,\n rawInput: unknown,\n): NoiseAction | null {\n for (const rule of NOISE_RULES) {\n if (rule.match(name, kind, rawInput)) return rule.action;\n }\n return null;\n}\n","import type {\n IChannelAdapter,\n ChannelConfig,\n AdapterCapabilities,\n} from \"../channel.js\";\nimport type {\n OutgoingMessage,\n PermissionRequest,\n NotificationMessage,\n} from \"../types.js\";\nimport type { DisplayVerbosity, ToolCallMeta } from \"./format-types.js\";\nimport type { IRenderer } from \"./rendering/renderer.js\";\nimport { evaluateNoise } from \"./message-formatter.js\";\n\nexport interface AdapterContext {\n configManager: { get(): Record<string, unknown> };\n fileService?: unknown;\n}\n\nexport interface MessagingAdapterConfig extends ChannelConfig {\n maxMessageLength: number;\n flushInterval?: number;\n sendInterval?: number;\n thinkingRefreshInterval?: number;\n thinkingDuration?: number;\n displayVerbosity?: DisplayVerbosity;\n}\n\nexport interface SentMessage {\n messageId: string;\n}\n\nconst HIDDEN_ON_LOW = new Set([\"thought\", \"usage\"]);\n\nexport abstract class MessagingAdapter implements IChannelAdapter {\n abstract readonly name: string;\n abstract readonly renderer: IRenderer;\n abstract readonly capabilities: AdapterCapabilities;\n\n constructor(\n protected context: AdapterContext,\n protected adapterConfig: MessagingAdapterConfig,\n ) {}\n\n // === Message dispatch flow ===\n\n async sendMessage(\n sessionId: string,\n content: OutgoingMessage,\n ): Promise<void> {\n const verbosity = this.getVerbosity();\n if (!this.shouldDisplay(content, verbosity)) return;\n await this.dispatchMessage(sessionId, content, verbosity);\n }\n\n protected async dispatchMessage(\n sessionId: string,\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): Promise<void> {\n switch (content.type) {\n case \"text\":\n return this.handleText(sessionId, content);\n case \"thought\":\n return this.handleThought(sessionId, content, verbosity);\n case \"tool_call\":\n return this.handleToolCall(sessionId, content, verbosity);\n case \"tool_update\":\n return this.handleToolUpdate(sessionId, content, verbosity);\n case \"plan\":\n return this.handlePlan(sessionId, content, verbosity);\n case \"usage\":\n return this.handleUsage(sessionId, content, verbosity);\n case \"error\":\n return this.handleError(sessionId, content);\n case \"attachment\":\n return this.handleAttachment(sessionId, content);\n case \"system_message\":\n return this.handleSystem(sessionId, content);\n case \"session_end\":\n return this.handleSessionEnd(sessionId, content);\n case \"mode_change\":\n return this.handleModeChange(sessionId, content);\n case \"config_update\":\n return this.handleConfigUpdate(sessionId, content);\n case \"model_update\":\n return this.handleModelUpdate(sessionId, content);\n case \"user_replay\":\n return this.handleUserReplay(sessionId, content);\n case \"resource\":\n return this.handleResource(sessionId, content);\n case \"resource_link\":\n return this.handleResourceLink(sessionId, content);\n }\n }\n\n // === Default handlers — all protected, all overridable ===\n\n protected async handleText(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleThought(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handleToolCall(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handleToolUpdate(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handlePlan(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handleUsage(\n _sessionId: string,\n _content: OutgoingMessage,\n _verbosity: DisplayVerbosity,\n ): Promise<void> {}\n protected async handleError(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleAttachment(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleSystem(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleSessionEnd(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleModeChange(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleConfigUpdate(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleModelUpdate(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleUserReplay(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleResource(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n protected async handleResourceLink(\n _sessionId: string,\n _content: OutgoingMessage,\n ): Promise<void> {}\n\n // === Helpers ===\n\n protected getVerbosity(): DisplayVerbosity {\n const config = this.context.configManager.get();\n const channelConfig = (config as Record<string, unknown>).channels as\n | Record<string, Record<string, unknown>>\n | undefined;\n const v =\n channelConfig?.[this.name]?.displayVerbosity ??\n this.adapterConfig.displayVerbosity;\n if (v === \"low\" || v === \"high\") return v;\n return \"medium\";\n }\n\n protected shouldDisplay(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): boolean {\n if (verbosity === \"low\" && HIDDEN_ON_LOW.has(content.type)) return false;\n\n if (content.type === \"tool_call\") {\n const meta = (content.metadata ?? {}) as Partial<ToolCallMeta>;\n const toolName = meta.name ?? content.text ?? \"\";\n const toolKind = String(meta.kind ?? \"other\");\n const noiseAction = evaluateNoise(toolName, toolKind, meta.rawInput);\n if (noiseAction === \"hide\" && verbosity !== \"high\") return false;\n if (noiseAction === \"collapse\" && verbosity === \"low\") return false;\n }\n\n return true;\n }\n\n // === Abstract — adapter MUST implement ===\n\n abstract start(): Promise<void>;\n abstract stop(): Promise<void>;\n abstract createSessionThread(\n sessionId: string,\n name: string,\n ): Promise<string>;\n abstract renameSessionThread(\n sessionId: string,\n newName: string,\n ): Promise<void>;\n abstract sendPermissionRequest(\n sessionId: string,\n request: PermissionRequest,\n ): Promise<void>;\n abstract sendNotification(notification: NotificationMessage): Promise<void>;\n}\n","import type {\n OutgoingMessage,\n PermissionRequest,\n NotificationMessage,\n} from \"../../types.js\";\nimport type {\n DisplayVerbosity,\n ToolCallMeta,\n ToolUpdateMeta,\n} from \"../format-types.js\";\nimport {\n formatToolSummary,\n formatToolTitle,\n resolveToolIcon,\n} from \"../message-formatter.js\";\nimport { progressBar, formatTokens } from \"../format-utils.js\";\n\nexport interface RenderedMessage<TComponents = unknown> {\n body: string;\n format: \"html\" | \"markdown\" | \"plain\" | \"structured\";\n attachments?: RenderedAttachment[];\n components?: TComponents;\n}\n\nexport interface RenderedPermission<\n TComponents = unknown,\n> extends RenderedMessage<TComponents> {\n actions: RenderedAction[];\n}\n\nexport interface RenderedAction {\n id: string;\n label: string;\n isAllow?: boolean;\n}\n\nexport interface RenderedAttachment {\n type: \"file\" | \"image\" | \"audio\";\n data: Buffer | string;\n mimeType?: string;\n filename?: string;\n}\n\nexport interface IRenderer {\n renderText(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderToolCall(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderToolUpdate(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderPlan(content: OutgoingMessage): RenderedMessage;\n renderUsage(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderPermission(request: PermissionRequest): RenderedPermission;\n renderError(content: OutgoingMessage): RenderedMessage;\n renderNotification(notification: NotificationMessage): RenderedMessage;\n renderThought?(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderAttachment?(content: OutgoingMessage): RenderedMessage;\n renderSessionEnd?(content: OutgoingMessage): RenderedMessage;\n renderSystemMessage?(content: OutgoingMessage): RenderedMessage;\n renderModeChange?(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderConfigUpdate?(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderModelUpdate?(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage;\n renderResource?(content: OutgoingMessage): RenderedMessage;\n renderResourceLink?(content: OutgoingMessage): RenderedMessage;\n}\n\n/**\n * BaseRenderer — plain text defaults. Extend for platform-specific rendering.\n */\nexport class BaseRenderer implements IRenderer {\n renderText(content: OutgoingMessage): RenderedMessage {\n return { body: content.text, format: \"plain\" };\n }\n\n renderToolCall(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = (content.metadata ?? {}) as Partial<ToolCallMeta>;\n const name = meta.name ?? content.text ?? \"Tool\";\n const icon = resolveToolIcon(meta);\n const label =\n verbosity === \"low\"\n ? formatToolTitle(\n name,\n meta.rawInput,\n meta.displayTitle as string | undefined,\n )\n : formatToolSummary(\n name,\n meta.rawInput,\n meta.displaySummary as string | undefined,\n );\n return { body: `${icon} ${label}`, format: \"plain\" };\n }\n\n renderToolUpdate(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = (content.metadata ?? {}) as Partial<ToolUpdateMeta>;\n const name = meta.name ?? content.text ?? \"Tool\";\n const icon = resolveToolIcon(meta);\n const label =\n verbosity === \"low\"\n ? formatToolTitle(\n name,\n meta.rawInput,\n meta.displayTitle as string | undefined,\n )\n : formatToolSummary(\n name,\n meta.rawInput,\n meta.displaySummary as string | undefined,\n );\n return { body: `${icon} ${label}`, format: \"plain\" };\n }\n\n renderPlan(content: OutgoingMessage): RenderedMessage {\n const entries =\n (\n content.metadata as {\n entries?: Array<{ content: string; status: string }>;\n }\n )?.entries ?? [];\n const lines = entries.map((e, i) => {\n const icon =\n e.status === \"completed\"\n ? \"✅\"\n : e.status === \"in_progress\"\n ? \"🔄\"\n : \"⬜\";\n return `${icon} ${i + 1}. ${e.content}`;\n });\n return { body: `📋 Plan\\n${lines.join(\"\\n\")}`, format: \"plain\" };\n }\n\n renderUsage(\n content: OutgoingMessage,\n verbosity: DisplayVerbosity,\n ): RenderedMessage {\n const meta = content.metadata as\n | { tokensUsed?: number; contextSize?: number; cost?: number }\n | undefined;\n if (!meta?.tokensUsed)\n return { body: \"📊 Usage data unavailable\", format: \"plain\" };\n const costStr = meta.cost != null ? ` · $${meta.cost.toFixed(2)}` : \"\";\n if (verbosity === \"medium\") {\n return {\n body: `📊 ${formatTokens(meta.tokensUsed)} tokens${costStr}`,\n format: \"plain\",\n };\n }\n if (!meta.contextSize)\n return {\n body: `📊 ${formatTokens(meta.tokensUsed)} tokens`,\n format: \"plain\",\n };\n const ratio = meta.tokensUsed / meta.contextSize;\n const pct = Math.round(ratio * 100);\n const bar = progressBar(ratio);\n let text = `📊 ${formatTokens(meta.tokensUsed)} / ${formatTokens(meta.contextSize)} tokens\\n${bar} ${pct}%`;\n if (meta.cost != null) text += `\\n💰 $${meta.cost.toFixed(2)}`;\n return { body: text, format: \"plain\" };\n }\n\n renderPermission(request: PermissionRequest): RenderedPermission {\n return {\n body: request.description,\n format: \"plain\",\n actions: request.options.map((o) => ({\n id: o.id,\n label: o.label,\n isAllow: o.isAllow,\n })),\n };\n }\n\n renderError(content: OutgoingMessage): RenderedMessage {\n return { body: `❌ Error: ${content.text}`, format: \"plain\" };\n }\n\n renderNotification(notification: NotificationMessage): RenderedMessage {\n const emoji: Record<string, string> = {\n completed: \"✅\",\n error: \"❌\",\n permission: \"🔐\",\n input_required: \"💬\",\n budget_warning: \"⚠️\",\n };\n return {\n body: `${emoji[notification.type] || \"ℹ️\"} ${notification.sessionName || \"Session\"}\\n${notification.summary}`,\n format: \"plain\",\n };\n }\n\n renderSystemMessage(content: OutgoingMessage): RenderedMessage {\n return { body: content.text, format: \"plain\" };\n }\n\n renderModeChange(content: OutgoingMessage): RenderedMessage {\n const modeId = (content.metadata as Record<string, unknown>)?.modeId ?? \"\";\n return { body: `🔄 Mode: ${modeId}`, format: \"plain\" };\n }\n\n renderConfigUpdate(): RenderedMessage {\n return { body: \"⚙️ Config updated\", format: \"plain\" };\n }\n\n renderModelUpdate(content: OutgoingMessage): RenderedMessage {\n const modelId =\n (content.metadata as Record<string, unknown>)?.modelId ?? \"\";\n return { body: `🤖 Model: ${modelId}`, format: \"plain\" };\n }\n\n renderResource(content: OutgoingMessage): RenderedMessage {\n const uri = (content.metadata as Record<string, unknown>)?.uri ?? \"\";\n return { body: `📄 Resource: ${content.text} (${uri})`, format: \"plain\" };\n }\n\n renderResourceLink(content: OutgoingMessage): RenderedMessage {\n const uri = (content.metadata as Record<string, unknown>)?.uri ?? \"\";\n return { body: `🔗 ${content.text}: ${uri}`, format: \"plain\" };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugins/speech/index.ts"],"sourcesContent":["import type { OpenACPPlugin, InstallContext } from '../../core/plugin/types.js'\nimport { SpeechService, GroqSTT, EdgeTTS } from './exports.js'\nimport type { SpeechServiceConfig } from './exports.js'\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'],\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 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 const ttsVoice = config.ttsVoice 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: '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 service.registerTTSProvider('edge-tts', new EdgeTTS(ttsVoice))\n\n // Register provider factory for hot-reload (core calls refreshProviders on config change)\n service.setProviderFactory((cfg) => {\n const sttMap = new Map<string, InstanceType<typeof GroqSTT>>()\n const ttsMap = new Map<string, InstanceType<typeof EdgeTTS>>()\n const groqCfg = cfg.stt?.providers?.groq\n if (groqCfg?.apiKey) {\n sttMap.set('groq', new GroqSTT(groqCfg.apiKey, groqCfg.model))\n }\n const edgeVoice = cfg.tts?.providers?.['edge-tts']?.voice as string | undefined\n ttsMap.set('edge-tts', new EdgeTTS(edgeVoice))\n return { stt: sttMap, tts: ttsMap }\n })\n\n ctx.registerService('speech', service)\n\n ctx.registerCommand({\n name: 'tts',\n description: 'Toggle text-to-speech',\n usage: 'on|off',\n category: 'plugin',\n handler: async (args) => {\n const mode = args.raw.trim().toLowerCase()\n if (mode === 'on') return { type: 'text', text: 'Text-to-speech enabled' }\n if (mode === 'off') return { type: 'text', text: 'Text-to-speech disabled' }\n return { type: 'menu', title: 'Text to Speech', options: [\n { label: 'Enable', command: '/tts on' },\n { label: 'Disable', command: '/tts off' },\n ]}\n },\n })\n\n ctx.log.info('Speech service ready')\n },\n}\n\nexport default speechPlugin\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugins/file-service/file-service.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { OggOpusDecoder } from \"ogg-opus-decoder\";\nimport wav from \"node-wav\";\nimport type { Attachment } from \"../../core/types.js\";\n\nconst MIME_TO_EXT: Record<string, string> = {\n \"image/jpeg\": \".jpg\",\n \"image/png\": \".png\",\n \"image/gif\": \".gif\",\n \"image/webp\": \".webp\",\n \"image/svg+xml\": \".svg\",\n \"audio/ogg\": \".ogg\",\n \"audio/mpeg\": \".mp3\",\n \"audio/wav\": \".wav\",\n \"audio/webm\": \".webm\",\n \"audio/mp4\": \".m4a\",\n \"video/mp4\": \".mp4\",\n \"video/webm\": \".webm\",\n \"application/pdf\": \".pdf\",\n \"text/plain\": \".txt\",\n};\n\nconst EXT_TO_MIME: Record<string, string> = {\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".ogg\": \"audio/ogg\",\n \".oga\": \"audio/ogg\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".m4a\": \"audio/mp4\",\n \".mp4\": \"video/mp4\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n};\n\nfunction classifyMime(mimeType: string): Attachment[\"type\"] {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n return \"file\";\n}\n\nexport class FileService {\n constructor(private baseDir: string) {}\n\n async saveFile(\n sessionId: string,\n fileName: string,\n data: Buffer,\n mimeType: string,\n ): Promise<Attachment> {\n const sessionDir = path.join(this.baseDir, sessionId);\n await fs.promises.mkdir(sessionDir, { recursive: true });\n\n const safeName = `${Date.now()}-${fileName.replace(/[^a-zA-Z0-9._-]/g, \"_\")}`;\n const filePath = path.join(sessionDir, safeName);\n await fs.promises.writeFile(filePath, data);\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName,\n mimeType,\n size: data.length,\n };\n }\n\n async resolveFile(filePath: string): Promise<Attachment | null> {\n try {\n const stat = await fs.promises.stat(filePath);\n if (!stat.isFile()) return null;\n\n const ext = path.extname(filePath).toLowerCase();\n const mimeType = EXT_TO_MIME[ext] || \"application/octet-stream\";\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName: path.basename(filePath),\n mimeType,\n size: stat.size,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Convert OGG Opus audio to WAV format.\n * Telegram voice messages use OGG Opus which many AI agents can't read.\n */\n async convertOggToWav(oggData: Buffer): Promise<Buffer> {\n const decoder = new OggOpusDecoder();\n await decoder.ready;\n try {\n const { channelData, sampleRate } = await decoder.decode(new Uint8Array(oggData));\n const wavData = wav.encode(channelData, { sampleRate, float: true, bitDepth: 32 });\n return Buffer.from(wavData);\n } finally {\n decoder.free();\n }\n }\n\n /** Instance method — delegates to static for FileServiceInterface compliance */\n async readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n ): Promise<string> {\n return FileService.readTextFileWithRange(filePath, options);\n }\n\n static async readTextFileWithRange(\n filePath: string,\n options?: { line?: number; limit?: number },\n ): Promise<string> {\n // Delegate to core utility (canonical implementation)\n const { readTextFileWithRange } = await import(\"../../core/utils/read-text-file.js\");\n return readTextFileWithRange(filePath, options);\n }\n\n /** Instance method — delegates to static for FileServiceInterface compliance */\n extensionFromMime(mimeType: string): string {\n return FileService.extensionFromMime(mimeType);\n }\n\n static extensionFromMime(mimeType: string): string {\n return MIME_TO_EXT[mimeType] || \".bin\";\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
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"]}
|