@cotal-ai/connector-opencode 0.11.2 → 0.11.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/index.js +604 -2
- package/dist/plugin.bundle.js +398 -98
- package/dist/plugin.d.ts.map +1 -1
- package/dist/serve.js +145 -208
- package/dist/tools.d.ts +2 -3
- package/dist/tools.d.ts.map +1 -1
- package/package.json +5 -7
- package/dist/extension.js +0 -231
- package/dist/extension.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/plugin.js +0 -501
- package/dist/plugin.js.map +0 -1
- package/dist/serve.js.map +0 -1
- package/dist/tools.js +0 -42
- package/dist/tools.js.map +0 -1
- package/dist/transcript.js +0 -107
- package/dist/transcript.js.map +0 -1
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAgCA,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;AAiBzD,eAAO,MAAM,KAAK,EAAE,MA6anB,CAAC"}
|
package/dist/serve.js
CHANGED
|
@@ -1,233 +1,170 @@
|
|
|
1
|
-
|
|
2
|
-
* Launcher shim for the OpenCode connector — gives a spawned agent a *watchable* TUI bound to the
|
|
3
|
-
* exact session it drives, using OpenCode's own client/server split:
|
|
4
|
-
*
|
|
5
|
-
* 1. start `opencode serve` (headless) on a free port, with the Cotal plugin loaded inline;
|
|
6
|
-
* 2. poke it once so the lazily-loaded plugin initializes (joins the mesh, creates ONE session);
|
|
7
|
-
* 3. the plugin announces that session's id on stderr (`[cotal-session] <id>`);
|
|
8
|
-
* 4. launch a foreground `opencode attach <url> --session <id>` — the TUI opens straight onto the
|
|
9
|
-
* agent's session, and every turn the plugin drives through this exact server renders live.
|
|
10
|
-
*
|
|
11
|
-
* The attach TUI is a pure viewer (it connects to the running server); its env strips the plugin
|
|
12
|
-
* config + COTAL_* so it never loads a *second* mesh endpoint.
|
|
13
|
-
*
|
|
14
|
-
* SECURITY: `opencode serve` is UNAUTHENTICATED by default — the CVE-2026-22812 surface (any local
|
|
15
|
-
* process, or a malicious site via DNS-rebind, can drive the session: arbitrary code execution as
|
|
16
|
-
* this user + full mesh-identity takeover via the ungated cotal_* tools). So we set a random
|
|
17
|
-
* per-launch `OPENCODE_SERVER_PASSWORD` in the child env; the poke and the attach TUI present it as
|
|
18
|
-
* HTTP basic auth. Bind stays loopback; no CORS / mDNS.
|
|
19
|
-
*/
|
|
1
|
+
// src/serve.ts
|
|
20
2
|
import { execFileSync, spawn } from "node:child_process";
|
|
21
3
|
import { createServer } from "node:net";
|
|
22
4
|
import { once } from "node:events";
|
|
23
5
|
import { randomBytes } from "node:crypto";
|
|
24
6
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
25
7
|
import { delimiter, join } from "node:path";
|
|
26
|
-
/** The opencode binary to spawn. `COTAL_OPENCODE_BIN` overrides. On Windows, `opencode` on PATH is
|
|
27
|
-
* an npm `.cmd` shim that child_process can't spawn, and the real `opencode.exe` it wraps
|
|
28
|
-
* (`<bindir>/node_modules/opencode-ai/bin/opencode.exe`) isn't itself on PATH — resolve and spawn
|
|
29
|
-
* it directly, so there's no `cmd.exe` wrapper to orphan the server on kill. POSIX spawns the name
|
|
30
|
-
* as-is. Unresolved on Windows → returns the bare name so spawn fails with a clear ENOENT. */
|
|
31
8
|
function resolveOpencodeBin() {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
for (const
|
|
38
|
-
|
|
39
|
-
continue;
|
|
40
|
-
for (const exe of [join(dir, "opencode.exe"), join(dir, "node_modules", "opencode-ai", "bin", "opencode.exe")]) {
|
|
41
|
-
if (existsSync(exe))
|
|
42
|
-
return exe;
|
|
43
|
-
}
|
|
9
|
+
const override = process.env.COTAL_OPENCODE_BIN?.trim();
|
|
10
|
+
if (override) return override;
|
|
11
|
+
if (process.platform !== "win32") return "opencode";
|
|
12
|
+
for (const dir of (process.env.PATH ?? "").split(delimiter)) {
|
|
13
|
+
if (!dir) continue;
|
|
14
|
+
for (const exe of [join(dir, "opencode.exe"), join(dir, "node_modules", "opencode-ai", "bin", "opencode.exe")]) {
|
|
15
|
+
if (existsSync(exe)) return exe;
|
|
44
16
|
}
|
|
45
|
-
|
|
17
|
+
}
|
|
18
|
+
return "opencode";
|
|
46
19
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const SECRET = randomBytes(24).toString("hex");
|
|
51
|
-
/** Ask the OS for a free port (bind :0, read it, release) so co-located peers don't collide. */
|
|
20
|
+
var BIN = resolveOpencodeBin();
|
|
21
|
+
var USERNAME = "opencode";
|
|
22
|
+
var SECRET = randomBytes(24).toString("hex");
|
|
52
23
|
async function freePort() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
24
|
+
const srv = createServer();
|
|
25
|
+
srv.listen(0, "127.0.0.1");
|
|
26
|
+
await once(srv, "listening");
|
|
27
|
+
const port = srv.address().port;
|
|
28
|
+
await new Promise((r) => srv.close(() => r()));
|
|
29
|
+
return port;
|
|
59
30
|
}
|
|
60
|
-
/** SIGTERM the serve, then SIGKILL if it's still alive 3s later — a lingering serve keeps the
|
|
61
|
-
* agent's data dir (SQLite) open and wedges every later same-name spawn. Resolves once it's dead. */
|
|
62
31
|
async function killServe(serve) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
32
|
+
if (serve.exitCode !== null || serve.signalCode !== null) return;
|
|
33
|
+
serve.kill("SIGTERM");
|
|
34
|
+
const dead = await Promise.race([
|
|
35
|
+
once(serve, "exit").then(() => true),
|
|
36
|
+
new Promise((r) => setTimeout(() => r(false), 3e3))
|
|
37
|
+
]);
|
|
38
|
+
if (!dead) {
|
|
39
|
+
serve.kill("SIGKILL");
|
|
40
|
+
await once(serve, "exit");
|
|
41
|
+
}
|
|
74
42
|
}
|
|
75
43
|
function processCommand(pid) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
return execFileSync("ps", ["-p", String(pid), "-o", "command="], {
|
|
86
|
-
encoding: "utf8",
|
|
87
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
88
|
-
}).trim();
|
|
89
|
-
}
|
|
90
|
-
catch {
|
|
91
|
-
return undefined;
|
|
44
|
+
try {
|
|
45
|
+
if (process.platform === "win32") {
|
|
46
|
+
return execFileSync("powershell.exe", [
|
|
47
|
+
"-NoProfile",
|
|
48
|
+
"-NonInteractive",
|
|
49
|
+
"-Command",
|
|
50
|
+
`(Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}').CommandLine`
|
|
51
|
+
], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
92
52
|
}
|
|
53
|
+
return execFileSync("ps", ["-p", String(pid), "-o", "command="], {
|
|
54
|
+
encoding: "utf8",
|
|
55
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
56
|
+
}).trim();
|
|
57
|
+
} catch {
|
|
58
|
+
return void 0;
|
|
59
|
+
}
|
|
93
60
|
}
|
|
94
61
|
function isLiveOpencodeServe(pid) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (!cmd)
|
|
105
|
-
return true; // If the platform cannot inspect it, keep the old fail-closed behavior.
|
|
106
|
-
return /\bserve\b/.test(cmd) && (/(?:^|[\\/\s])opencode(?:\.exe)?(?:\s|$)/i.test(cmd) ||
|
|
107
|
-
(/--hostname\s+127\.0\.0\.1\b/.test(cmd) && /--port\s+\d+\b/.test(cmd)));
|
|
62
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
63
|
+
try {
|
|
64
|
+
process.kill(pid, 0);
|
|
65
|
+
} catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const cmd = processCommand(pid);
|
|
69
|
+
if (!cmd) return true;
|
|
70
|
+
return /\bserve\b/.test(cmd) && (/(?:^|[\\/\s])opencode(?:\.exe)?(?:\s|$)/i.test(cmd) || /--hostname\s+127\.0\.0\.1\b/.test(cmd) && /--port\s+\d+\b/.test(cmd));
|
|
108
71
|
}
|
|
109
72
|
async function main() {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
73
|
+
const port = process.env.COTAL_OPENCODE_PORT?.trim() || String(await freePort());
|
|
74
|
+
const url = `http://127.0.0.1:${port}`;
|
|
75
|
+
const name = process.env.COTAL_NAME?.trim() || "agent";
|
|
76
|
+
const dataRoot = process.env.COTAL_OPENCODE_HOME?.trim();
|
|
77
|
+
if (!dataRoot) throw new Error("COTAL_OPENCODE_HOME is not set \u2014 the connector must pin the agent's data root");
|
|
78
|
+
const agentHome = join(dataRoot, ".cotal", "opencode", name);
|
|
79
|
+
const dbPath = join(agentHome, "opencode.db");
|
|
80
|
+
const pidFile = join(agentHome, "serve.pid");
|
|
81
|
+
if (existsSync(pidFile)) {
|
|
82
|
+
const pid = Number(readFileSync(pidFile, "utf8"));
|
|
83
|
+
if (isLiveOpencodeServe(pid))
|
|
84
|
+
throw new Error(`agent "${name}" is already running (opencode serve pid ${pid}) \u2014 kill it first`);
|
|
85
|
+
rmSync(pidFile);
|
|
86
|
+
}
|
|
87
|
+
mkdirSync(agentHome, { recursive: true });
|
|
88
|
+
const serve = spawn(BIN, ["serve", "--hostname", "127.0.0.1", "--port", port], {
|
|
89
|
+
env: {
|
|
90
|
+
...process.env,
|
|
91
|
+
COTAL_OPENCODE_SERVER_URL: url,
|
|
92
|
+
OPENCODE_SERVER_USERNAME: USERNAME,
|
|
93
|
+
OPENCODE_SERVER_PASSWORD: SECRET,
|
|
94
|
+
OPENCODE_DB: dbPath
|
|
95
|
+
},
|
|
96
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
97
|
+
});
|
|
98
|
+
writeFileSync(pidFile, String(serve.pid));
|
|
99
|
+
serve.on("exit", () => rmSync(pidFile, { force: true }));
|
|
100
|
+
let sessionId;
|
|
101
|
+
let attached = false;
|
|
102
|
+
let onSession;
|
|
103
|
+
const scan = (d) => {
|
|
104
|
+
if (!attached) process.stderr.write(d);
|
|
105
|
+
if (!sessionId) {
|
|
106
|
+
const m = d.toString().match(/\[cotal-session\] (\S+)/);
|
|
107
|
+
if (m) {
|
|
108
|
+
sessionId = m[1];
|
|
109
|
+
onSession?.(sessionId);
|
|
110
|
+
}
|
|
130
111
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// until the TUI takes over the terminal (after that, drop them so they can't corrupt its display).
|
|
146
|
-
let sessionId;
|
|
147
|
-
let attached = false;
|
|
148
|
-
let onSession;
|
|
149
|
-
const scan = (d) => {
|
|
150
|
-
if (!attached)
|
|
151
|
-
process.stderr.write(d);
|
|
152
|
-
if (!sessionId) {
|
|
153
|
-
const m = d.toString().match(/\[cotal-session\] (\S+)/);
|
|
154
|
-
if (m) {
|
|
155
|
-
sessionId = m[1];
|
|
156
|
-
onSession?.(sessionId);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
serve.stdout?.on("data", scan);
|
|
161
|
-
serve.stderr?.on("data", scan);
|
|
162
|
-
serve.on("exit", (code, signal) => {
|
|
163
|
-
if (!attached)
|
|
164
|
-
process.exit(code ?? (signal ? 1 : 0)); // died before the TUI came up
|
|
165
|
-
});
|
|
166
|
-
// Poke the server until the plugin's session handshake lands (lazy plugin load → mesh join +
|
|
167
|
-
// session create). Poking must NOT stop at the first 2xx: early in boot the server can answer
|
|
168
|
-
// /session before the project instance has bootstrapped, and only a later request triggers the
|
|
169
|
-
// bootstrap that loads the plugin. Each poke carries its own abort timeout: a request that
|
|
170
|
-
// lands in the early-boot window can hang with no response, and an un-timed fetch would pin
|
|
171
|
-
// the loop on it forever (undici queues later requests behind it on the pooled connection).
|
|
172
|
-
const auth = `Basic ${Buffer.from(`${USERNAME}:${SECRET}`).toString("base64")}`;
|
|
173
|
-
void (async () => {
|
|
174
|
-
for (let i = 0; i < 300 && !sessionId; i++) {
|
|
175
|
-
try {
|
|
176
|
-
await fetch(`${url}/session`, { headers: { authorization: auth }, signal: AbortSignal.timeout(1500) });
|
|
177
|
-
}
|
|
178
|
-
catch {
|
|
179
|
-
/* not up yet (or a hung early request, aborted) — retry on a fresh connection */
|
|
180
|
-
}
|
|
181
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
182
|
-
}
|
|
183
|
-
})();
|
|
184
|
-
// Wait for the agent's session, then attach a foreground TUI to it.
|
|
185
|
-
const id = await new Promise((resolve) => {
|
|
186
|
-
if (sessionId)
|
|
187
|
-
return resolve(sessionId);
|
|
188
|
-
onSession = resolve;
|
|
189
|
-
setTimeout(() => resolve(sessionId), 60_000);
|
|
190
|
-
});
|
|
191
|
-
if (!id) {
|
|
192
|
-
process.stderr.write(`[cotal-connector] serve: agent session never came up (~60s) — aborting. Check the boot log above for plugin/mesh errors (OPENCODE_DB=${dbPath})\n`);
|
|
193
|
-
await killServe(serve);
|
|
194
|
-
process.exit(1);
|
|
112
|
+
};
|
|
113
|
+
serve.stdout?.on("data", scan);
|
|
114
|
+
serve.stderr?.on("data", scan);
|
|
115
|
+
serve.on("exit", (code, signal) => {
|
|
116
|
+
if (!attached) process.exit(code ?? (signal ? 1 : 0));
|
|
117
|
+
});
|
|
118
|
+
const auth = `Basic ${Buffer.from(`${USERNAME}:${SECRET}`).toString("base64")}`;
|
|
119
|
+
void (async () => {
|
|
120
|
+
for (let i = 0; i < 300 && !sessionId; i++) {
|
|
121
|
+
try {
|
|
122
|
+
await fetch(`${url}/session`, { headers: { authorization: auth }, signal: AbortSignal.timeout(1500) });
|
|
123
|
+
} catch {
|
|
124
|
+
}
|
|
125
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
195
126
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
delete tuiEnv.OPENCODE_CONFIG_CONTENT; // a viewer, not a peer — must NOT load the plugin again
|
|
214
|
-
for (const k of Object.keys(tuiEnv))
|
|
215
|
-
if (k.startsWith("COTAL_"))
|
|
216
|
-
delete tuiEnv[k];
|
|
217
|
-
attached = true;
|
|
218
|
-
const tui = spawn(BIN, ["attach", url, "--session", id, "--password", SECRET], {
|
|
219
|
-
env: tuiEnv,
|
|
220
|
-
stdio: "inherit",
|
|
221
|
-
});
|
|
127
|
+
})();
|
|
128
|
+
const id = await new Promise((resolve) => {
|
|
129
|
+
if (sessionId) return resolve(sessionId);
|
|
130
|
+
onSession = resolve;
|
|
131
|
+
setTimeout(() => resolve(sessionId), 6e4);
|
|
132
|
+
});
|
|
133
|
+
if (!id) {
|
|
134
|
+
process.stderr.write(
|
|
135
|
+
`[cotal-connector] serve: agent session never came up (~60s) \u2014 aborting. Check the boot log above for plugin/mesh errors (OPENCODE_DB=${dbPath})
|
|
136
|
+
`
|
|
137
|
+
);
|
|
138
|
+
await killServe(serve);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
if (process.env.COTAL_SERVE_HEADLESS?.trim() === "1") {
|
|
142
|
+
process.stdout.write(`[cotal-serve] ${JSON.stringify({ port: Number(port), session: id, password: SECRET })}
|
|
143
|
+
`);
|
|
222
144
|
for (const sig of ["SIGINT", "SIGTERM"])
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
145
|
+
process.on(sig, () => void killServe(serve).then(() => process.exit(0)));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const tuiEnv = {
|
|
149
|
+
...process.env,
|
|
150
|
+
OPENCODE_SERVER_USERNAME: USERNAME,
|
|
151
|
+
OPENCODE_SERVER_PASSWORD: SECRET,
|
|
152
|
+
OPENCODE_DB: dbPath
|
|
153
|
+
};
|
|
154
|
+
delete tuiEnv.OPENCODE_CONFIG_CONTENT;
|
|
155
|
+
for (const k of Object.keys(tuiEnv)) if (k.startsWith("COTAL_")) delete tuiEnv[k];
|
|
156
|
+
attached = true;
|
|
157
|
+
const tui = spawn(BIN, ["attach", url, "--session", id, "--password", SECRET], {
|
|
158
|
+
env: tuiEnv,
|
|
159
|
+
stdio: "inherit"
|
|
160
|
+
});
|
|
161
|
+
for (const sig of ["SIGINT", "SIGTERM"])
|
|
162
|
+
process.on(sig, () => {
|
|
163
|
+
tui.kill(sig);
|
|
164
|
+
serve.kill(sig);
|
|
230
165
|
});
|
|
166
|
+
tui.on("exit", (code, signal) => {
|
|
167
|
+
void killServe(serve).then(() => process.exit(code ?? (signal ? 1 : 0)));
|
|
168
|
+
});
|
|
231
169
|
}
|
|
232
170
|
void main();
|
|
233
|
-
//# sourceMappingURL=serve.js.map
|
package/dist/tools.d.ts
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
* tools (the `tool()` helper). One source of truth → the cotal_* surface can't drift across
|
|
5
5
|
* adapters: an OpenCode peer gets the same tools (incl. channels / join / leave / channel_info).
|
|
6
6
|
*
|
|
7
|
-
* The one OpenCode-specific tool is `cotal_inbox`:
|
|
8
|
-
*
|
|
9
|
-
* peeks (never drains), or it would race the connector's ack. It still honors focus-mode recall.
|
|
7
|
+
* The one OpenCode-specific tool is `cotal_inbox`: automatic traffic remains owned by the driver,
|
|
8
|
+
* while the tool destructively pulls only quiet ambient (plus read-only focus recall).
|
|
10
9
|
*/
|
|
11
10
|
import { type ToolDefinition } from "@opencode-ai/plugin";
|
|
12
11
|
import { type MeshAgent, type AgentConfig } from "@cotal-ai/connector-core";
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAQ,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAkB,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE5F,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0BrG"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cotal-ai/connector-opencode",
|
|
3
3
|
"description": "Cotal connector for OpenCode: a native in-process plugin that joins a session to the mesh.",
|
|
4
|
-
"version": "0.11.
|
|
4
|
+
"version": "0.11.4",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -17,9 +17,6 @@
|
|
|
17
17
|
"import": "./dist/index.js"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
-
"dependencies": {
|
|
21
|
-
"@cotal-ai/connector-core": "0.11.2"
|
|
22
|
-
},
|
|
23
20
|
"peerDependencies": {
|
|
24
21
|
"@cotal-ai/core": ">=0.1.0",
|
|
25
22
|
"@opencode-ai/plugin": "^1.16.2",
|
|
@@ -30,7 +27,8 @@
|
|
|
30
27
|
"@opencode-ai/sdk": "^1.16.2",
|
|
31
28
|
"esbuild": "^0.28.0",
|
|
32
29
|
"tsx": "^4.22.4",
|
|
33
|
-
"@cotal-ai/core": "0.11.
|
|
30
|
+
"@cotal-ai/connector-core": "0.11.4",
|
|
31
|
+
"@cotal-ai/core": "0.11.4"
|
|
34
32
|
},
|
|
35
33
|
"files": [
|
|
36
34
|
"dist"
|
|
@@ -40,7 +38,7 @@
|
|
|
40
38
|
},
|
|
41
39
|
"scripts": {
|
|
42
40
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
43
|
-
"build": "tsc -p tsconfig.json && pnpm run bundle",
|
|
44
|
-
"bundle": "esbuild src/plugin.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/plugin.bundle.js --external:@opencode-ai/plugin --external:@opencode-ai/sdk"
|
|
41
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json --emitDeclarationOnly && pnpm run bundle",
|
|
42
|
+
"bundle": "esbuild src/index.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/index.js --external:@cotal-ai/core --external:@opencode-ai/plugin --external:@opencode-ai/sdk && esbuild src/plugin.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/plugin.bundle.js --external:@opencode-ai/plugin --external:@opencode-ai/sdk && esbuild src/serve.ts --bundle --platform=node --format=esm --target=node20 --outfile=dist/serve.js --external:@opencode-ai/plugin --external:@opencode-ai/sdk"
|
|
45
43
|
}
|
|
46
44
|
}
|