opencode-tbot 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/plugin.js +57 -45
- package/dist/plugin.js.map +1 -1
- package/package.json +1 -1
package/dist/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { i as preparePluginConfiguration, s as loadAppConfig } from "./assets/plugin-config-BYsYAzvx.js";
|
|
2
2
|
import { mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
3
|
-
import { basename, dirname, extname, join } from "node:path";
|
|
3
|
+
import { basename, dirname, extname, isAbsolute, join } from "node:path";
|
|
4
4
|
import { parse, printParseErrorCode } from "jsonc-parser";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { OpenRouter } from "@openrouter/sdk";
|
|
@@ -962,13 +962,14 @@ var GetPathUseCase = class {
|
|
|
962
962
|
//#endregion
|
|
963
963
|
//#region src/use-cases/get-status.usecase.ts
|
|
964
964
|
var GetStatusUseCase = class {
|
|
965
|
-
constructor(getHealthUseCase, getPathUseCase, listLspUseCase, listMcpUseCase, listSessionsUseCase, sessionRepo) {
|
|
965
|
+
constructor(getHealthUseCase, getPathUseCase, listLspUseCase, listMcpUseCase, listSessionsUseCase, sessionRepo, voiceTranscriptionEnabled) {
|
|
966
966
|
this.getHealthUseCase = getHealthUseCase;
|
|
967
967
|
this.getPathUseCase = getPathUseCase;
|
|
968
968
|
this.listLspUseCase = listLspUseCase;
|
|
969
969
|
this.listMcpUseCase = listMcpUseCase;
|
|
970
970
|
this.listSessionsUseCase = listSessionsUseCase;
|
|
971
971
|
this.sessionRepo = sessionRepo;
|
|
972
|
+
this.voiceTranscriptionEnabled = voiceTranscriptionEnabled;
|
|
972
973
|
}
|
|
973
974
|
async execute(input) {
|
|
974
975
|
const [health, path, lsp, mcp] = await Promise.allSettled([
|
|
@@ -983,6 +984,7 @@ var GetStatusUseCase = class {
|
|
|
983
984
|
health: mapSettledResult(health),
|
|
984
985
|
path: pathResult,
|
|
985
986
|
plugins,
|
|
987
|
+
voiceRecognition: { enabled: this.voiceTranscriptionEnabled },
|
|
986
988
|
workspace,
|
|
987
989
|
lsp: mapSettledResult(lsp),
|
|
988
990
|
mcp: mapSettledResult(mcp)
|
|
@@ -1050,11 +1052,11 @@ async function loadWorkspaceStatusResult(chatId, path, listSessionsUseCase, sess
|
|
|
1050
1052
|
status: "error"
|
|
1051
1053
|
};
|
|
1052
1054
|
const binding = await sessionRepo.getByChatId(chatId);
|
|
1053
|
-
let currentProject = path.data
|
|
1055
|
+
let currentProject = resolveWorkspaceProjectPath(path.data);
|
|
1054
1056
|
let currentSession = binding?.sessionId ?? null;
|
|
1055
1057
|
try {
|
|
1056
1058
|
const sessions = await listSessionsUseCase.execute({ chatId });
|
|
1057
|
-
currentProject = sessions.currentDirectory;
|
|
1059
|
+
currentProject = resolveWorkspaceProjectPath(path.data, sessions.currentDirectory);
|
|
1058
1060
|
currentSession = sessions.currentSessionId ? formatSessionStatusLabel(sessions.sessions.find((session) => session.id === sessions.currentSessionId) ?? null, sessions.currentSessionId) : null;
|
|
1059
1061
|
} catch {}
|
|
1060
1062
|
return {
|
|
@@ -1070,6 +1072,20 @@ function formatSessionStatusLabel(session, fallbackId) {
|
|
|
1070
1072
|
const title = session.title.trim() || session.slug || session.id;
|
|
1071
1073
|
return title === session.slug ? title : `${title} (${session.slug})`;
|
|
1072
1074
|
}
|
|
1075
|
+
function resolveWorkspaceProjectPath(path, preferredPath) {
|
|
1076
|
+
const candidates = [
|
|
1077
|
+
preferredPath,
|
|
1078
|
+
path.worktree,
|
|
1079
|
+
path.directory
|
|
1080
|
+
];
|
|
1081
|
+
for (const candidate of candidates) if (isUsableWorkspacePath(candidate)) return candidate;
|
|
1082
|
+
return preferredPath ?? path.worktree ?? path.directory;
|
|
1083
|
+
}
|
|
1084
|
+
function isUsableWorkspacePath(value) {
|
|
1085
|
+
if (typeof value !== "string") return false;
|
|
1086
|
+
const normalized = value.trim();
|
|
1087
|
+
return normalized.length > 0 && normalized !== "/" && normalized !== "\\" && isAbsolute(normalized);
|
|
1088
|
+
}
|
|
1073
1089
|
async function resolveOpenCodeConfigFilePath(configPath) {
|
|
1074
1090
|
try {
|
|
1075
1091
|
return (await stat(configPath)).isDirectory() ? join(configPath, "opencode.json") : configPath;
|
|
@@ -1601,7 +1617,7 @@ function createContainer(config, opencodeClient, logger) {
|
|
|
1601
1617
|
const listLspUseCase = new ListLspUseCase(sessionRepo, opencodeClient);
|
|
1602
1618
|
const listMcpUseCase = new ListMcpUseCase(sessionRepo, opencodeClient);
|
|
1603
1619
|
const listSessionsUseCase = new ListSessionsUseCase(sessionRepo, opencodeClient);
|
|
1604
|
-
const getStatusUseCase = new GetStatusUseCase(getHealthUseCase, getPathUseCase, listLspUseCase, listMcpUseCase, listSessionsUseCase, sessionRepo);
|
|
1620
|
+
const getStatusUseCase = new GetStatusUseCase(getHealthUseCase, getPathUseCase, listLspUseCase, listMcpUseCase, listSessionsUseCase, sessionRepo, config.openrouter.configured);
|
|
1605
1621
|
const listModelsUseCase = new ListModelsUseCase(sessionRepo, opencodeClient);
|
|
1606
1622
|
const renameSessionUseCase = new RenameSessionUseCase(sessionRepo, opencodeClient, logger);
|
|
1607
1623
|
const sendPromptUseCase = new SendPromptUseCase(sessionRepo, opencodeClient, logger, foregroundSessionTracker);
|
|
@@ -2634,32 +2650,26 @@ var VARIANT_ORDER = [
|
|
|
2634
2650
|
];
|
|
2635
2651
|
function presentStatusMessage(input, copy = BOT_COPY) {
|
|
2636
2652
|
const layout = getStatusLayoutCopy(copy);
|
|
2637
|
-
|
|
2653
|
+
return presentStatusSections([
|
|
2638
2654
|
presentStatusPlainSection(layout.overviewTitle, presentStatusPlainOverviewLines(input, copy, layout)),
|
|
2639
2655
|
presentStatusPlainSection(layout.workspaceTitle, presentStatusPlainWorkspaceLines(input, copy, layout)),
|
|
2640
2656
|
presentStatusPlainSection(layout.pluginsTitle, presentStatusPlainPluginLines(input, copy, layout)),
|
|
2641
2657
|
presentStatusPlainSection(layout.mcpTitle, presentStatusPlainMcpLines(input, copy, layout)),
|
|
2642
2658
|
presentStatusPlainSection(layout.lspTitle, presentStatusPlainLspLines(input, copy, layout))
|
|
2643
|
-
];
|
|
2644
|
-
return presentStatusSections(layout.pageTitle, sections);
|
|
2659
|
+
]);
|
|
2645
2660
|
}
|
|
2646
2661
|
function presentStatusMarkdownMessage(input, copy = BOT_COPY) {
|
|
2647
2662
|
const layout = getStatusLayoutCopy(copy);
|
|
2648
|
-
|
|
2663
|
+
return presentStatusSections([
|
|
2649
2664
|
presentStatusMarkdownSection(layout.overviewTitle, presentStatusMarkdownOverviewLines(input, copy, layout)),
|
|
2650
2665
|
presentStatusMarkdownSection(layout.workspaceTitle, presentStatusMarkdownWorkspaceLines(input, copy, layout)),
|
|
2651
2666
|
presentStatusMarkdownSection(layout.pluginsTitle, presentStatusMarkdownPluginLines(input, copy, layout)),
|
|
2652
2667
|
presentStatusMarkdownSection(layout.mcpTitle, presentStatusMarkdownMcpLines(input, copy, layout)),
|
|
2653
2668
|
presentStatusMarkdownSection(layout.lspTitle, presentStatusMarkdownLspLines(input, copy, layout))
|
|
2654
|
-
];
|
|
2655
|
-
return presentStatusSections(`# ${layout.pageTitle}`, sections);
|
|
2669
|
+
]);
|
|
2656
2670
|
}
|
|
2657
|
-
function presentStatusSections(
|
|
2658
|
-
return [
|
|
2659
|
-
title,
|
|
2660
|
-
"",
|
|
2661
|
-
...sections.flatMap((section, index) => index === 0 ? [section] : ["", section])
|
|
2662
|
-
].join("\n");
|
|
2671
|
+
function presentStatusSections(sections) {
|
|
2672
|
+
return sections.flatMap((section, index) => index === 0 ? [section] : ["", section]).join("\n");
|
|
2663
2673
|
}
|
|
2664
2674
|
function presentStatusPlainSection(title, lines) {
|
|
2665
2675
|
return [title, ...lines].join("\n");
|
|
@@ -2668,7 +2678,7 @@ function presentStatusMarkdownSection(title, lines) {
|
|
|
2668
2678
|
return [`## ${title}`, ...lines].join("\n");
|
|
2669
2679
|
}
|
|
2670
2680
|
function presentStatusPlainOverviewLines(input, copy, layout) {
|
|
2671
|
-
const lines = [presentPlainStatusBullet(layout.connectivityLabel, input.health.status === "error" ? layout.errorStatus : formatHealthBadge(input.health.data.healthy, layout))];
|
|
2681
|
+
const lines = [presentPlainStatusBullet(layout.connectivityLabel, input.health.status === "error" ? layout.errorStatus : formatHealthBadge(input.health.data.healthy, layout)), presentPlainStatusBullet(layout.voiceRecognitionLabel, formatVoiceRecognitionBadge(input.voiceRecognition.enabled))];
|
|
2672
2682
|
if (input.health.status === "error") return [
|
|
2673
2683
|
...lines,
|
|
2674
2684
|
...presentStatusPlainErrorDetailLines(input.health.error, copy, layout),
|
|
@@ -2681,7 +2691,7 @@ function presentStatusPlainOverviewLines(input, copy, layout) {
|
|
|
2681
2691
|
];
|
|
2682
2692
|
}
|
|
2683
2693
|
function presentStatusMarkdownOverviewLines(input, copy, layout) {
|
|
2684
|
-
const lines = [presentMarkdownStatusBullet(layout.connectivityLabel, input.health.status === "error" ? layout.errorStatus : formatHealthBadge(input.health.data.healthy, layout))];
|
|
2694
|
+
const lines = [presentMarkdownStatusBullet(layout.connectivityLabel, input.health.status === "error" ? layout.errorStatus : formatHealthBadge(input.health.data.healthy, layout)), presentMarkdownStatusBullet(layout.voiceRecognitionLabel, formatVoiceRecognitionBadge(input.voiceRecognition.enabled))];
|
|
2685
2695
|
if (input.health.status === "error") return [
|
|
2686
2696
|
...lines,
|
|
2687
2697
|
...presentStatusMarkdownErrorDetailLines(input.health.error, copy, layout),
|
|
@@ -2695,21 +2705,21 @@ function presentStatusMarkdownOverviewLines(input, copy, layout) {
|
|
|
2695
2705
|
}
|
|
2696
2706
|
function presentStatusPlainWorkspaceLines(input, copy, layout) {
|
|
2697
2707
|
if (input.workspace.status === "error") return presentStatusPlainErrorLines(input.workspace.error, copy, layout);
|
|
2698
|
-
return [presentPlainStatusBullet(layout.currentProjectLabel, input.workspace.data.currentProject), presentPlainStatusBullet(layout.currentSessionLabel, input.workspace.data.currentSession ??
|
|
2708
|
+
return [presentPlainStatusBullet(layout.currentProjectLabel, input.workspace.data.currentProject), presentPlainStatusBullet(layout.currentSessionLabel, input.workspace.data.currentSession ?? layout.defaultSessionValue)];
|
|
2699
2709
|
}
|
|
2700
2710
|
function presentStatusMarkdownWorkspaceLines(input, copy, layout) {
|
|
2701
2711
|
if (input.workspace.status === "error") return presentStatusMarkdownErrorLines(input.workspace.error, copy, layout);
|
|
2702
|
-
return [presentMarkdownStatusBullet(layout.currentProjectLabel, input.workspace.data.currentProject, { codeValue: true }), presentMarkdownStatusBullet(layout.currentSessionLabel, input.workspace.data.currentSession ??
|
|
2712
|
+
return [presentMarkdownStatusBullet(layout.currentProjectLabel, input.workspace.data.currentProject, { codeValue: true }), presentMarkdownStatusBullet(layout.currentSessionLabel, input.workspace.data.currentSession ?? layout.defaultSessionValue)];
|
|
2703
2713
|
}
|
|
2704
2714
|
function presentStatusPlainPluginLines(input, copy, layout) {
|
|
2705
2715
|
if (input.plugins.status === "error") return presentStatusPlainErrorLines(input.plugins.error, copy, layout);
|
|
2706
2716
|
if (input.plugins.data.plugins.length === 0) return [...presentPlainEmptyStatusLines(layout.noPluginsMessage, layout)];
|
|
2707
|
-
return
|
|
2717
|
+
return input.plugins.data.plugins.map((plugin) => `- ${plugin}`);
|
|
2708
2718
|
}
|
|
2709
2719
|
function presentStatusMarkdownPluginLines(input, copy, layout) {
|
|
2710
2720
|
if (input.plugins.status === "error") return presentStatusMarkdownErrorLines(input.plugins.error, copy, layout);
|
|
2711
2721
|
if (input.plugins.data.plugins.length === 0) return [...presentMarkdownEmptyStatusLines(layout.noPluginsMessage, layout)];
|
|
2712
|
-
return
|
|
2722
|
+
return input.plugins.data.plugins.map((plugin) => `- \`${plugin}\``);
|
|
2713
2723
|
}
|
|
2714
2724
|
function presentStatusPlainLspLines(input, copy, layout) {
|
|
2715
2725
|
if (input.lsp.status === "error") return presentStatusPlainErrorLines(input.lsp.error, copy, layout);
|
|
@@ -2738,24 +2748,12 @@ function presentStatusMarkdownLspLines(input, copy, layout) {
|
|
|
2738
2748
|
function presentStatusPlainMcpLines(input, copy, layout) {
|
|
2739
2749
|
if (input.mcp.status === "error") return presentStatusPlainErrorLines(input.mcp.error, copy, layout);
|
|
2740
2750
|
if (input.mcp.data.statuses.length === 0) return presentPlainEmptyStatusLines(copy.mcp.none, layout);
|
|
2741
|
-
return input.mcp.data.statuses.flatMap(({ name, status }) => presentPlainStatusGroup(name,
|
|
2742
|
-
label: layout.statusLabel,
|
|
2743
|
-
value: formatMcpStatusBadge(status, layout)
|
|
2744
|
-
}, {
|
|
2745
|
-
label: layout.mcpNotesLabel,
|
|
2746
|
-
value: formatMcpStatusNotes(status, copy, layout)
|
|
2747
|
-
}]));
|
|
2751
|
+
return input.mcp.data.statuses.flatMap(({ name, status }) => presentPlainStatusGroup(name, getMcpStatusDetailLines(status, copy, layout)));
|
|
2748
2752
|
}
|
|
2749
2753
|
function presentStatusMarkdownMcpLines(input, copy, layout) {
|
|
2750
2754
|
if (input.mcp.status === "error") return presentStatusMarkdownErrorLines(input.mcp.error, copy, layout);
|
|
2751
2755
|
if (input.mcp.data.statuses.length === 0) return presentMarkdownEmptyStatusLines(copy.mcp.none, layout);
|
|
2752
|
-
return input.mcp.data.statuses.flatMap(({ name, status }) => presentMarkdownStatusGroup(name,
|
|
2753
|
-
label: layout.statusLabel,
|
|
2754
|
-
value: formatMcpStatusBadge(status, layout)
|
|
2755
|
-
}, {
|
|
2756
|
-
label: layout.mcpNotesLabel,
|
|
2757
|
-
value: formatMcpStatusNotes(status, copy, layout)
|
|
2758
|
-
}], { codeName: true }));
|
|
2756
|
+
return input.mcp.data.statuses.flatMap(({ name, status }) => presentMarkdownStatusGroup(name, getMcpStatusDetailLines(status, copy, layout), { codeName: true }));
|
|
2759
2757
|
}
|
|
2760
2758
|
function presentStatusPlainErrorLines(error, copy, layout) {
|
|
2761
2759
|
return [presentPlainStatusBullet(layout.statusLabel, layout.errorStatus), ...presentStatusPlainErrorDetailLines(error, copy, layout)];
|
|
@@ -2793,6 +2791,9 @@ function splitStatusLines(text) {
|
|
|
2793
2791
|
function formatHealthBadge(healthy, layout) {
|
|
2794
2792
|
return healthy ? "🟢" : layout.errorStatus;
|
|
2795
2793
|
}
|
|
2794
|
+
function formatVoiceRecognitionBadge(enabled) {
|
|
2795
|
+
return enabled ? "🟢" : "⚪";
|
|
2796
|
+
}
|
|
2796
2797
|
function formatLspStatusBadge(status) {
|
|
2797
2798
|
switch (status.status) {
|
|
2798
2799
|
case "connected": return "🟢";
|
|
@@ -2810,10 +2811,23 @@ function formatMcpStatusBadge(status, layout) {
|
|
|
2810
2811
|
}
|
|
2811
2812
|
return status;
|
|
2812
2813
|
}
|
|
2814
|
+
function getMcpStatusDetailLines(status, copy, layout) {
|
|
2815
|
+
const notes = formatMcpStatusNotes(status, copy, layout);
|
|
2816
|
+
return notes ? [{
|
|
2817
|
+
label: layout.statusLabel,
|
|
2818
|
+
value: formatMcpStatusBadge(status, layout)
|
|
2819
|
+
}, {
|
|
2820
|
+
label: layout.mcpNotesLabel,
|
|
2821
|
+
value: notes
|
|
2822
|
+
}] : [{
|
|
2823
|
+
label: layout.statusLabel,
|
|
2824
|
+
value: formatMcpStatusBadge(status, layout)
|
|
2825
|
+
}];
|
|
2826
|
+
}
|
|
2813
2827
|
function formatMcpStatusNotes(status, copy, layout) {
|
|
2814
2828
|
switch (status.status) {
|
|
2815
|
-
case "connected": return
|
|
2816
|
-
case "disabled": return
|
|
2829
|
+
case "connected": return null;
|
|
2830
|
+
case "disabled": return null;
|
|
2817
2831
|
case "needs_auth": return copy.mcp.needsAuth;
|
|
2818
2832
|
case "failed": return status.error;
|
|
2819
2833
|
case "needs_client_registration": return status.error;
|
|
@@ -2830,9 +2844,9 @@ function normalizeStatusInlineValue(value) {
|
|
|
2830
2844
|
function getStatusLayoutCopy(copy) {
|
|
2831
2845
|
if (copy.systemStatus.title === BOT_COPY.systemStatus.title) return {
|
|
2832
2846
|
connectivityLabel: "Connectivity",
|
|
2833
|
-
configuredPluginsLabel: "Configured Plugins",
|
|
2834
2847
|
currentProjectLabel: "Current Project",
|
|
2835
2848
|
currentSessionLabel: "Current Session",
|
|
2849
|
+
defaultSessionValue: "OpenCode Default",
|
|
2836
2850
|
detailsLabel: "Details",
|
|
2837
2851
|
errorStatus: "🔴",
|
|
2838
2852
|
lspTitle: "🧠 LSP",
|
|
@@ -2843,20 +2857,19 @@ function getStatusLayoutCopy(copy) {
|
|
|
2843
2857
|
noPluginsMessage: "No plugins configured in the OpenCode config.",
|
|
2844
2858
|
noneStatus: "⚪",
|
|
2845
2859
|
openCodeVersionLabel: "OpenCode Version",
|
|
2846
|
-
okLabel: "OK",
|
|
2847
2860
|
overviewTitle: "🖥️ Overview",
|
|
2848
|
-
pageTitle: "📊 Service Status",
|
|
2849
2861
|
pluginsTitle: "🧩 Plugins",
|
|
2850
2862
|
rootLabel: "Root",
|
|
2851
2863
|
statusLabel: "Status",
|
|
2852
2864
|
tbotVersionLabel: "opencode-tbot Version",
|
|
2865
|
+
voiceRecognitionLabel: "Voice Recognition",
|
|
2853
2866
|
workspaceTitle: "📁 Workspace"
|
|
2854
2867
|
};
|
|
2855
2868
|
return {
|
|
2856
2869
|
connectivityLabel: "连通性",
|
|
2857
|
-
configuredPluginsLabel: "已配置插件",
|
|
2858
2870
|
currentProjectLabel: "当前项目",
|
|
2859
2871
|
currentSessionLabel: "当前会话",
|
|
2872
|
+
defaultSessionValue: "OpenCode 默认",
|
|
2860
2873
|
detailsLabel: "详情",
|
|
2861
2874
|
errorStatus: "🔴",
|
|
2862
2875
|
lspTitle: "🧠 LSP",
|
|
@@ -2867,13 +2880,12 @@ function getStatusLayoutCopy(copy) {
|
|
|
2867
2880
|
noPluginsMessage: "当前 OpenCode 配置中未配置插件。",
|
|
2868
2881
|
noneStatus: "⚪",
|
|
2869
2882
|
openCodeVersionLabel: "OpenCode版本",
|
|
2870
|
-
okLabel: "正常",
|
|
2871
2883
|
overviewTitle: "🖥️ 概览",
|
|
2872
|
-
pageTitle: "📊 服务状态",
|
|
2873
2884
|
pluginsTitle: "🧩 插件",
|
|
2874
2885
|
rootLabel: "根目录",
|
|
2875
2886
|
statusLabel: "状态",
|
|
2876
2887
|
tbotVersionLabel: "opencode-tbot版本",
|
|
2888
|
+
voiceRecognitionLabel: "语音识别",
|
|
2877
2889
|
workspaceTitle: "📁 工作区"
|
|
2878
2890
|
};
|
|
2879
2891
|
}
|