@tropass/connect 2.4.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/LICENSE +22 -0
- package/README.md +62 -0
- package/dist/bin/tropass-connect.d.ts +2 -0
- package/dist/bin/tropass-connect.js +8 -0
- package/dist/bin/tropass-connect.js.map +1 -0
- package/dist/skills/agent-response-display/SKILL.md +111 -0
- package/dist/skills/tropass-gateway/SKILL.md +52 -0
- package/dist/src/cli.d.ts +1 -0
- package/dist/src/cli.js +52 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/constants.d.ts +8 -0
- package/dist/src/constants.js +9 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/installer.d.ts +4 -0
- package/dist/src/installer.js +171 -0
- package/dist/src/installer.js.map +1 -0
- package/dist/src/installers/cli.d.ts +6 -0
- package/dist/src/installers/cli.js +40 -0
- package/dist/src/installers/cli.js.map +1 -0
- package/dist/src/installers/opencode.d.ts +2 -0
- package/dist/src/installers/opencode.js +159 -0
- package/dist/src/installers/opencode.js.map +1 -0
- package/dist/src/installers/shared.d.ts +7 -0
- package/dist/src/installers/shared.js +43 -0
- package/dist/src/installers/shared.js.map +1 -0
- package/dist/src/installers/types.d.ts +9 -0
- package/dist/src/installers/types.js +2 -0
- package/dist/src/installers/types.js.map +1 -0
- package/dist/src/interactive-installer.d.ts +15 -0
- package/dist/src/interactive-installer.js +138 -0
- package/dist/src/interactive-installer.js.map +1 -0
- package/dist/src/logging.d.ts +1 -0
- package/dist/src/logging.js +5 -0
- package/dist/src/logging.js.map +1 -0
- package/dist/src/path-utils.d.ts +3 -0
- package/dist/src/path-utils.js +43 -0
- package/dist/src/path-utils.js.map +1 -0
- package/dist/src/spawn.d.ts +5 -0
- package/dist/src/spawn.js +13 -0
- package/dist/src/spawn.js.map +1 -0
- package/dist/src/types.d.ts +50 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/uvx.d.ts +2 -0
- package/dist/src/uvx.js +33 -0
- package/dist/src/uvx.js.map +1 -0
- package/dist/tools/tropass-provider.js +57 -0
- package/dist/tools/tropass.mjs +257 -0
- package/dist/tools/wait_for_model_task.py +24 -0
- package/dist/tools/wait_for_model_task.ts +51 -0
- package/package.json +57 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const providerId = "tropass";
|
|
2
|
+
const preferredModel = "GLM-5.2";
|
|
3
|
+
|
|
4
|
+
export async function loadTropassModels(config, fetchModels = fetch) {
|
|
5
|
+
if (typeof config.model === "string" && config.model.startsWith(`${providerId}/`)) {
|
|
6
|
+
delete config.model;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const provider = config.provider?.[providerId];
|
|
10
|
+
if (!provider || typeof provider !== "object") return;
|
|
11
|
+
provider.models = {};
|
|
12
|
+
|
|
13
|
+
const baseURL = provider.options?.baseURL;
|
|
14
|
+
const apiKey = provider.options?.apiKey;
|
|
15
|
+
if (typeof baseURL !== "string" || typeof apiKey !== "string" || !baseURL || !apiKey) {
|
|
16
|
+
console.warn("Tropass model discovery skipped: provider settings are incomplete.");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetchModels(`${baseURL.replace(/\/+$/, "")}/models`, {
|
|
22
|
+
headers: {Authorization: apiKey.startsWith("Bearer ") ? apiKey : `Bearer ${apiKey}`},
|
|
23
|
+
signal: AbortSignal.timeout(3_000),
|
|
24
|
+
});
|
|
25
|
+
if (!response.ok) throw new Error("Tropass model discovery failed.");
|
|
26
|
+
|
|
27
|
+
const payload = await response.json();
|
|
28
|
+
if (!Array.isArray(payload?.data)) throw new TypeError("Invalid Tropass model catalog.");
|
|
29
|
+
|
|
30
|
+
const modelIds = [...new Set(payload.data.flatMap((model) => {
|
|
31
|
+
const modelId = typeof model?.id === "string" ? model.id.trim() : "";
|
|
32
|
+
return modelId ? [modelId] : [];
|
|
33
|
+
}))];
|
|
34
|
+
provider.models = Object.fromEntries(modelIds.map((modelId) => [
|
|
35
|
+
modelId,
|
|
36
|
+
{
|
|
37
|
+
name: modelId,
|
|
38
|
+
...(modelId === preferredModel && {
|
|
39
|
+
modalities: {input: ["text", "image"], output: ["text"]},
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
42
|
+
]));
|
|
43
|
+
if (!modelIds.length) {
|
|
44
|
+
console.warn("Tropass model discovery returned no models.");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
config.model = `${providerId}/${modelIds.includes(preferredModel) ? preferredModel : modelIds[0]}`;
|
|
49
|
+
} catch {
|
|
50
|
+
console.warn("Tropass model discovery failed; starting without Tropass models.");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default {
|
|
55
|
+
id: "tropass-provider",
|
|
56
|
+
server: async () => ({config: loadTropassModels}),
|
|
57
|
+
};
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import {spawn} from "node:child_process";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
|
|
4
|
+
const decode = (value) => Buffer.from(value, "base64").toString();
|
|
5
|
+
const usageUrl = decode("{{USAGE_URL}}");
|
|
6
|
+
const apiToken = decode("{{API_TOKEN}}");
|
|
7
|
+
const configPath = decode("{{CONFIG_PATH}}");
|
|
8
|
+
const projectDir = decode("{{PROJECT_DIR}}");
|
|
9
|
+
const currentVersion = "{{INSTALLER_VERSION}}";
|
|
10
|
+
const installScope = "{{INSTALL_SCOPE}}";
|
|
11
|
+
const installerPackage = "@tropass/connect@latest";
|
|
12
|
+
const registryUrl = "https://registry.npmjs.org/@tropass%2Fconnect/latest";
|
|
13
|
+
const remindAfterKey = "tropass.update.remindAfter";
|
|
14
|
+
const updateCheckKey = Symbol.for("tropass.update.checkStarted");
|
|
15
|
+
|
|
16
|
+
export const REMIND_DELAY_MS = 24 * 60 * 60 * 1000;
|
|
17
|
+
|
|
18
|
+
export function formatUsage(data, locale, timeZone) {
|
|
19
|
+
const usage = data?.usage ?? data?.data ?? data;
|
|
20
|
+
const used = Number(usage?.used ?? usage?.used_tokens);
|
|
21
|
+
const limitValue = usage?.limit ?? usage?.limit_tokens ?? usage?.initial_limit_tokens;
|
|
22
|
+
const remainingValue = usage?.remaining ?? usage?.remaining_tokens;
|
|
23
|
+
const limit = limitValue === null ? null : Number(limitValue);
|
|
24
|
+
const remaining = remainingValue === null ? null : Number(remainingValue);
|
|
25
|
+
const reset = usage?.resetAt ?? usage?.reset_time ?? usage?.reset_at;
|
|
26
|
+
if (!Number.isFinite(used) || (limit !== null && !Number.isFinite(limit)) || (remaining !== null && !Number.isFinite(remaining)) || reset === undefined) {
|
|
27
|
+
return JSON.stringify(data, null, 2);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const percent = limit === null ? null : Math.min(100, Math.max(0, limit > 0 ? Math.round(used / limit * 100) : 0));
|
|
31
|
+
const filled = percent === null ? 0 : Math.round(percent * 24 / 100);
|
|
32
|
+
const number = new Intl.NumberFormat(locale).format;
|
|
33
|
+
const resetDate = new Date(typeof reset === "number" && reset < 1e12 ? reset * 1000 : reset);
|
|
34
|
+
const resetText = reset === null ? "Not scheduled" : Number.isNaN(resetDate.valueOf())
|
|
35
|
+
? String(reset)
|
|
36
|
+
: new Intl.DateTimeFormat(locale, {dateStyle: "medium", timeStyle: "short", timeZone}).format(resetDate);
|
|
37
|
+
|
|
38
|
+
return [
|
|
39
|
+
"Weekly tokens",
|
|
40
|
+
"",
|
|
41
|
+
percent === null ? "──────────────────────── ∞" : `${"█".repeat(filled)}${"░".repeat(24 - filled)} ${percent}%`,
|
|
42
|
+
"",
|
|
43
|
+
`Used ${number(used)}`,
|
|
44
|
+
`Remaining ${remaining === null ? "Unlimited" : number(remaining)}`,
|
|
45
|
+
`Limit ${limit === null ? "Unlimited" : number(limit)}`,
|
|
46
|
+
`Resets ${resetText}`,
|
|
47
|
+
].join("\n");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function isNewerVersion(candidate, installed) {
|
|
51
|
+
const candidateParts = parseStableVersion(candidate);
|
|
52
|
+
const installedParts = parseStableVersion(installed);
|
|
53
|
+
if (!candidateParts || !installedParts) return false;
|
|
54
|
+
|
|
55
|
+
for (let index = 0; index < candidateParts.length; index += 1) {
|
|
56
|
+
if (candidateParts[index] !== installedParts[index]) {
|
|
57
|
+
return candidateParts[index] > installedParts[index];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function buildUpdateCommand({
|
|
64
|
+
packageSpec = installerPackage,
|
|
65
|
+
scope = installScope,
|
|
66
|
+
configuration = configPath,
|
|
67
|
+
project = projectDir,
|
|
68
|
+
platform = process.platform,
|
|
69
|
+
} = {}) {
|
|
70
|
+
return {
|
|
71
|
+
command: platform === "win32" ? "npx.cmd" : "npx",
|
|
72
|
+
args: [
|
|
73
|
+
"-y",
|
|
74
|
+
packageSpec,
|
|
75
|
+
"opencode",
|
|
76
|
+
"--scope",
|
|
77
|
+
scope,
|
|
78
|
+
"--config",
|
|
79
|
+
configuration,
|
|
80
|
+
...(project ? ["--project", project] : []),
|
|
81
|
+
"--yes",
|
|
82
|
+
],
|
|
83
|
+
cwd: project || undefined,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function runInstallerUpdate(spawnProcess = spawn, updateCommand = buildUpdateCommand()) {
|
|
88
|
+
return new Promise((resolve, reject) => {
|
|
89
|
+
const child = spawnProcess(updateCommand.command, updateCommand.args, {
|
|
90
|
+
cwd: updateCommand.cwd,
|
|
91
|
+
env: {...process.env, TROPASS_API_TOKEN: apiToken},
|
|
92
|
+
shell: false,
|
|
93
|
+
stdio: "ignore",
|
|
94
|
+
windowsHide: true,
|
|
95
|
+
});
|
|
96
|
+
child.once("error", reject);
|
|
97
|
+
child.once("close", (exitCode) => resolve(exitCode === 0));
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export async function checkForUpdate(api, {
|
|
102
|
+
fetchLatestVersion = retrieveLatestVersion,
|
|
103
|
+
installUpdate = runInstallerUpdate,
|
|
104
|
+
now = Date.now,
|
|
105
|
+
version = currentVersion,
|
|
106
|
+
} = {}) {
|
|
107
|
+
if (globalThis[updateCheckKey]) return;
|
|
108
|
+
globalThis[updateCheckKey] = true;
|
|
109
|
+
|
|
110
|
+
if (!await waitForKv(api)) return;
|
|
111
|
+
const remindAfter = Number(api.kv.get(remindAfterKey, 0));
|
|
112
|
+
if (Number.isFinite(remindAfter) && remindAfter > now()) return;
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const latestVersion = await fetchLatestVersion();
|
|
116
|
+
if (!isNewerVersion(latestVersion, version)) return;
|
|
117
|
+
showUpdateDialog(api, version, latestVersion, installUpdate, now);
|
|
118
|
+
} catch {}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function parseStableVersion(value) {
|
|
122
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(value);
|
|
123
|
+
return match?.slice(1).map(Number);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function waitForKv(api) {
|
|
127
|
+
while (!api.kv.ready) {
|
|
128
|
+
if (api.lifecycle?.signal.aborted) return false;
|
|
129
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function retrieveLatestVersion() {
|
|
135
|
+
const response = await fetch(registryUrl, {signal: AbortSignal.timeout(3_000)});
|
|
136
|
+
if (!response.ok) return undefined;
|
|
137
|
+
const payload = await response.json();
|
|
138
|
+
return typeof payload?.version === "string" ? payload.version : undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function showUpdateDialog(api, installedVersion, latestVersion, installUpdate, now) {
|
|
142
|
+
let handled = false;
|
|
143
|
+
const remindTomorrow = () => api.kv.set(remindAfterKey, now() + REMIND_DELAY_MS);
|
|
144
|
+
|
|
145
|
+
api.ui.dialog.replace(
|
|
146
|
+
() => api.ui.DialogSelect({
|
|
147
|
+
title: `Обновление Tropass ${installedVersion} → ${latestVersion}`,
|
|
148
|
+
options: [
|
|
149
|
+
{
|
|
150
|
+
title: "Обновить сейчас",
|
|
151
|
+
value: "update",
|
|
152
|
+
description: "Обновить конфигурацию и плагины Tropass",
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
title: "Напомнить завтра",
|
|
156
|
+
value: "later",
|
|
157
|
+
description: "Скрыть предложение на 24 часа",
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
current: "update",
|
|
161
|
+
flat: true,
|
|
162
|
+
skipFilter: true,
|
|
163
|
+
onSelect(option) {
|
|
164
|
+
handled = true;
|
|
165
|
+
api.ui.dialog.clear();
|
|
166
|
+
if (option.value === "later") {
|
|
167
|
+
remindTomorrow();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
void installWithFeedback(api, installUpdate);
|
|
171
|
+
},
|
|
172
|
+
}),
|
|
173
|
+
() => {
|
|
174
|
+
if (!handled) remindTomorrow();
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function installWithFeedback(api, installUpdate) {
|
|
180
|
+
api.ui.toast({
|
|
181
|
+
variant: "info",
|
|
182
|
+
message: "Обновляем Tropass…",
|
|
183
|
+
duration: 30_000,
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
if (!await installUpdate()) throw new Error("Установщик завершился с ошибкой.");
|
|
188
|
+
api.ui.dialog.replace(() => api.ui.DialogAlert({
|
|
189
|
+
title: "Tropass обновлён",
|
|
190
|
+
message: "Перезапустите OpenCode, чтобы применить обновление.",
|
|
191
|
+
onConfirm: () => api.ui.dialog.clear(),
|
|
192
|
+
}));
|
|
193
|
+
} catch (error) {
|
|
194
|
+
api.ui.toast({
|
|
195
|
+
variant: "error",
|
|
196
|
+
message: error instanceof Error ? error.message : "Не удалось обновить Tropass.",
|
|
197
|
+
duration: 10_000,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function registerUsage(api) {
|
|
203
|
+
const run = async () => {
|
|
204
|
+
try {
|
|
205
|
+
api.ui.toast({variant: "info", message: "Loading Tropass usage…", duration: 2_000});
|
|
206
|
+
const response = await fetch(usageUrl, {headers: {Authorization: `Bearer ${apiToken}`}});
|
|
207
|
+
const body = await response.text();
|
|
208
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}: ${body}`);
|
|
209
|
+
let message = body;
|
|
210
|
+
try {
|
|
211
|
+
message = formatUsage(JSON.parse(body));
|
|
212
|
+
} catch {}
|
|
213
|
+
api.ui.dialog.replace(() => api.ui.DialogAlert({
|
|
214
|
+
title: "Tropass usage",
|
|
215
|
+
message,
|
|
216
|
+
onConfirm: () => api.ui.dialog.clear(),
|
|
217
|
+
}));
|
|
218
|
+
} catch (error) {
|
|
219
|
+
api.ui.toast({
|
|
220
|
+
variant: "error",
|
|
221
|
+
message: error instanceof Error ? error.message : String(error),
|
|
222
|
+
duration: 10_000,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
if (api.command) {
|
|
228
|
+
api.command.register(() => [{
|
|
229
|
+
title: "Tropass token usage",
|
|
230
|
+
value: "tropass.usage",
|
|
231
|
+
category: "Tropass",
|
|
232
|
+
slash: {name: "usage"},
|
|
233
|
+
onSelect: run,
|
|
234
|
+
}]);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
api.keymap.registerLayer({
|
|
239
|
+
mode: "base",
|
|
240
|
+
commands: [{
|
|
241
|
+
name: "tropass.usage",
|
|
242
|
+
title: "Tropass token usage",
|
|
243
|
+
category: "Tropass",
|
|
244
|
+
namespace: "palette",
|
|
245
|
+
slashName: "usage",
|
|
246
|
+
run,
|
|
247
|
+
}],
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export default {
|
|
252
|
+
id: "tropass",
|
|
253
|
+
async tui(api) {
|
|
254
|
+
registerUsage(api);
|
|
255
|
+
if (api.kv && api.ui.DialogSelect) void checkForUpdate(api);
|
|
256
|
+
},
|
|
257
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
import sys
|
|
4
|
+
import uuid
|
|
5
|
+
|
|
6
|
+
from tropass_sdk.client import GatewayClient
|
|
7
|
+
|
|
8
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
9
|
+
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def main() -> None:
|
|
13
|
+
task_id = uuid.UUID(sys.argv[1])
|
|
14
|
+
gateway_url = sys.argv[2]
|
|
15
|
+
gateway_api_token = sys.argv[3]
|
|
16
|
+
async with GatewayClient(
|
|
17
|
+
gateway_url=gateway_url,
|
|
18
|
+
gateway_api_token=gateway_api_token,
|
|
19
|
+
) as gateway_client:
|
|
20
|
+
result = await gateway_client.wait_for_model_task(task_id)
|
|
21
|
+
print(json.dumps(result, ensure_ascii=False))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import childProcess from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
|
|
8
|
+
import { tool } from "@opencode-ai/plugin";
|
|
9
|
+
|
|
10
|
+
const GATEWAY_URL = "{{GATEWAY_URL}}";
|
|
11
|
+
const GATEWAY_API_TOKEN = "{{GATEWAY_API_TOKEN}}";
|
|
12
|
+
const UVX_COMMAND = "{{UVX_COMMAND}}";
|
|
13
|
+
|
|
14
|
+
const execFile = promisify(childProcess.execFile);
|
|
15
|
+
|
|
16
|
+
const TOOL_DIRECTORY = resolveToolDirectory();
|
|
17
|
+
|
|
18
|
+
export default tool({
|
|
19
|
+
description:
|
|
20
|
+
"Wait for a Tropass model task to complete and return the final result. Call this once with the task_id returned by a model tool; it polls the gateway until the task finishes and returns the result payload.",
|
|
21
|
+
args: {
|
|
22
|
+
task_id: tool.schema.string().describe("Task ID returned by the model call submit response"),
|
|
23
|
+
},
|
|
24
|
+
async execute(args) {
|
|
25
|
+
const scriptPath = path.join(TOOL_DIRECTORY, "wait_for_model_task.py");
|
|
26
|
+
if (!fs.existsSync(scriptPath)) {
|
|
27
|
+
throw new Error(`Не найден скрипт ожидания задачи: ${scriptPath}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const { stdout } = await execFile(
|
|
31
|
+
UVX_COMMAND,
|
|
32
|
+
["--with", "tropass-sdk[server]", "python", scriptPath, args.task_id, GATEWAY_URL, GATEWAY_API_TOKEN],
|
|
33
|
+
{
|
|
34
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
35
|
+
windowsHide: true,
|
|
36
|
+
encoding: "utf8",
|
|
37
|
+
env: { ...process.env, PYTHONUTF8: "1", PYTHONIOENCODING: "utf-8" },
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
return stdout.trim();
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
function resolveToolDirectory(): string {
|
|
45
|
+
const bunDirectory = (import.meta as { dir?: string }).dir;
|
|
46
|
+
if (typeof bunDirectory === "string" && bunDirectory.length > 0) {
|
|
47
|
+
return bunDirectory;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return path.dirname(fileURLToPath(import.meta.url));
|
|
51
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tropass/connect",
|
|
3
|
+
"version": "2.4.2",
|
|
4
|
+
"description": "Connects agent environments to Tropass models, tools, and skills.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/tropass-ai/tropass-connect.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"tropass",
|
|
13
|
+
"mcp",
|
|
14
|
+
"model-context-protocol",
|
|
15
|
+
"ai-agents",
|
|
16
|
+
"opencode",
|
|
17
|
+
"integration",
|
|
18
|
+
"ml-models"
|
|
19
|
+
],
|
|
20
|
+
"bin": {
|
|
21
|
+
"tropass-connect": "./dist/bin/tropass-connect.js"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"commander": "^14.0.2",
|
|
25
|
+
"ink": "^7.1.1",
|
|
26
|
+
"ink-link": "^4.1.0",
|
|
27
|
+
"ink-select-input": "^6.2.0",
|
|
28
|
+
"ink-text-input": "^6.0.0",
|
|
29
|
+
"react": "^19.2.7"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@emnapi/core": "^1.11.2",
|
|
33
|
+
"@emnapi/runtime": "^1.11.2",
|
|
34
|
+
"@eslint/js": "^9.39.1",
|
|
35
|
+
"@types/node": "^24.10.1",
|
|
36
|
+
"@types/react": "^19.2.17",
|
|
37
|
+
"eslint": "^9.39.1",
|
|
38
|
+
"opencode-ai": "^1.17.16",
|
|
39
|
+
"typescript": "^5.9.3",
|
|
40
|
+
"typescript-eslint": "^8.48.0",
|
|
41
|
+
"vitest": "^4.0.14"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=22"
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist/",
|
|
48
|
+
"README.md"
|
|
49
|
+
],
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "node scripts/copy-build-assets.mjs && tsc -p tsconfig.build.json",
|
|
52
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
53
|
+
"lint": "eslint bin src test scripts --ext .ts,.tsx,.mjs",
|
|
54
|
+
"test": "vitest run",
|
|
55
|
+
"check": "npm run typecheck && npm run lint && npm run test && npm run build"
|
|
56
|
+
}
|
|
57
|
+
}
|