@cotal-ai/connector-opencode 0.1.1 → 1.0.0-next-20260614011207
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/extension.d.ts.map +1 -1
- package/dist/extension.js +3 -0
- package/dist/extension.js.map +1 -1
- package/dist/plugin.bundle.js +193 -17
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +20 -1
- package/dist/plugin.js.map +1 -1
- package/dist/serve.js +71 -15
- package/dist/serve.js.map +1 -1
- package/dist/tools.js +1 -1
- package/dist/tools.js.map +1 -1
- package/package.json +4 -4
package/dist/extension.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,SAAS,EAAoC,MAAM,gBAAgB,CAAC;AAY3G;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"extension.d.ts","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,SAAS,EAAoC,MAAM,gBAAgB,CAAC;AAY3G;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAuC/B,CAAC"}
|
package/dist/extension.js
CHANGED
|
@@ -52,6 +52,9 @@ export const opencodeConnector = {
|
|
|
52
52
|
const def = loadAgentFile(path);
|
|
53
53
|
if (def.model)
|
|
54
54
|
config.model = def.model;
|
|
55
|
+
const face = def.meta?.face;
|
|
56
|
+
if (face)
|
|
57
|
+
env.COTAL_FACE_PERSONA = face; // shim swaps the TUI for the face viewer
|
|
55
58
|
}
|
|
56
59
|
env.OPENCODE_CONFIG_CONTENT = JSON.stringify(config);
|
|
57
60
|
// Run the shim (node dist/serve.js): `opencode serve` + an attached foreground TUI.
|
package/dist/extension.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAoD,MAAM,gBAAgB,CAAC;AAE3G;;;oCAGoC;AACpC,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEnF;uFACuF;AACvF,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEzE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAc;IAC1C,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,UAAU;IAChB,WAAW,CAAC,IAAgB;QAC1B,0FAA0F;QAC1F,2EAA2E;QAC3E,MAAM,GAAG,GAA2B,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACvF,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;QAC1C,IAAI,IAAI,CAAC,EAAE;YAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,KAAK;YAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7C,IAAI,IAAI,CAAC,OAAO;YAAE,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC;QAEnD,MAAM,MAAM,GAA4B;YACtC,OAAO,EAAE,iCAAiC;YAC1C,UAAU,EAAE,OAAO;YACnB,MAAM,EAAE,CAAC,YAAY,CAAC;SACvB,CAAC;QAEF,8FAA8F;QAC9F,8FAA8F;QAC9F,+EAA+E;QAC/E,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtC,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC,+BAA+B;YAC5D,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,GAAG,CAAC,KAAK;gBAAE,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAoD,MAAM,gBAAgB,CAAC;AAE3G;;;oCAGoC;AACpC,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEnF;uFACuF;AACvF,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEzE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAc;IAC1C,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,UAAU;IAChB,WAAW,CAAC,IAAgB;QAC1B,0FAA0F;QAC1F,2EAA2E;QAC3E,MAAM,GAAG,GAA2B,EAAE,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACvF,IAAI,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC;QAC1C,IAAI,IAAI,CAAC,EAAE;YAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,KAAK;YAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7C,IAAI,IAAI,CAAC,OAAO;YAAE,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC;QAEnD,MAAM,MAAM,GAA4B;YACtC,OAAO,EAAE,iCAAiC;YAC1C,UAAU,EAAE,OAAO;YACnB,MAAM,EAAE,CAAC,YAAY,CAAC;SACvB,CAAC;QAEF,8FAA8F;QAC9F,8FAA8F;QAC9F,+EAA+E;QAC/E,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtC,GAAG,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC,+BAA+B;YAC5D,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,GAAG,CAAC,KAAK;gBAAE,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YACxC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC;YAC5B,IAAI,IAAI;gBAAE,GAAG,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC,yCAAyC;QACpF,CAAC;QAED,GAAG,CAAC,uBAAuB,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAErD,oFAAoF;QACpF,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,QAAQ;YACzB,IAAI,EAAE,CAAC,UAAU,CAAC;YAClB,GAAG;SACJ,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC"}
|
package/dist/plugin.bundle.js
CHANGED
|
@@ -6430,7 +6430,7 @@ var require_authenticator = __commonJS({
|
|
|
6430
6430
|
exports.tokenAuthenticator = tokenAuthenticator;
|
|
6431
6431
|
exports.nkeyAuthenticator = nkeyAuthenticator;
|
|
6432
6432
|
exports.jwtAuthenticator = jwtAuthenticator;
|
|
6433
|
-
exports.credsAuthenticator =
|
|
6433
|
+
exports.credsAuthenticator = credsAuthenticator5;
|
|
6434
6434
|
var nkeys_1 = require_nkeys2();
|
|
6435
6435
|
var encoders_1 = require_encoders();
|
|
6436
6436
|
function multiAuthenticator(authenticators) {
|
|
@@ -6480,7 +6480,7 @@ var require_authenticator = __commonJS({
|
|
|
6480
6480
|
return { jwt: jwt2, nkey, sig };
|
|
6481
6481
|
};
|
|
6482
6482
|
}
|
|
6483
|
-
function
|
|
6483
|
+
function credsAuthenticator5(creds) {
|
|
6484
6484
|
const fn = typeof creds !== "function" ? () => creds : creds;
|
|
6485
6485
|
const parse3 = () => {
|
|
6486
6486
|
const CREDS = /\s*(?:(?:[-]{3,}[^\n]*[-]{3,}\n)(.+)(?:\n\s*[-]{3,}[^\n]*[-]{3,}\n))/ig;
|
|
@@ -12413,7 +12413,7 @@ var require_jsclient = __commonJS({
|
|
|
12413
12413
|
exports.startFastIngest = startFastIngest;
|
|
12414
12414
|
exports.toJetStreamClient = toJetStreamClient;
|
|
12415
12415
|
exports.jetstream = jetstream2;
|
|
12416
|
-
exports.jetstreamManager =
|
|
12416
|
+
exports.jetstreamManager = jetstreamManager4;
|
|
12417
12417
|
exports.scheduleSpecToHeader = scheduleSpecToHeader;
|
|
12418
12418
|
var jsbaseclient_api_1 = require_jsbaseclient_api();
|
|
12419
12419
|
var jsmconsumer_api_1 = require_jsmconsumer_api();
|
|
@@ -12500,7 +12500,7 @@ var require_jsclient = __commonJS({
|
|
|
12500
12500
|
function jetstream2(nc, opts = {}) {
|
|
12501
12501
|
return new JetStreamClientImpl(nc, opts);
|
|
12502
12502
|
}
|
|
12503
|
-
async function
|
|
12503
|
+
async function jetstreamManager4(nc, opts = {}) {
|
|
12504
12504
|
const adm = new JetStreamManagerImpl(nc, opts);
|
|
12505
12505
|
if (opts.checkAPI !== false) {
|
|
12506
12506
|
try {
|
|
@@ -12615,7 +12615,7 @@ var require_jsclient = __commonJS({
|
|
|
12615
12615
|
} catch (err2) {
|
|
12616
12616
|
return Promise.reject(err2);
|
|
12617
12617
|
}
|
|
12618
|
-
return
|
|
12618
|
+
return jetstreamManager4(this.nc, opts);
|
|
12619
12619
|
}
|
|
12620
12620
|
get apiPrefix() {
|
|
12621
12621
|
return this.prefix;
|
|
@@ -13610,11 +13610,11 @@ var require_connect = __commonJS({
|
|
|
13610
13610
|
"../../node_modules/.pnpm/@nats-io+transport-node@3.4.0/node_modules/@nats-io/transport-node/lib/connect.js"(exports) {
|
|
13611
13611
|
"use strict";
|
|
13612
13612
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13613
|
-
exports.connect =
|
|
13613
|
+
exports.connect = connect5;
|
|
13614
13614
|
var node_transport_1 = require_node_transport();
|
|
13615
13615
|
var nats_base_client_1 = require_nats_base_client();
|
|
13616
13616
|
var nats_base_client_2 = require_nats_base_client();
|
|
13617
|
-
function
|
|
13617
|
+
function connect5(opts = {}) {
|
|
13618
13618
|
if ((0, nats_base_client_2.hasWsProtocol)(opts)) {
|
|
13619
13619
|
return Promise.reject(nats_base_client_2.errors.InvalidArgumentError.format(`servers`, `node client doesn't support websockets, use the 'wsconnect' function instead`));
|
|
13620
13620
|
}
|
|
@@ -13806,7 +13806,7 @@ var require_kv = __commonJS({
|
|
|
13806
13806
|
throw new Error(`invalid bucket name: ${name}`);
|
|
13807
13807
|
}
|
|
13808
13808
|
}
|
|
13809
|
-
var
|
|
13809
|
+
var Kvm5 = class {
|
|
13810
13810
|
js;
|
|
13811
13811
|
/**
|
|
13812
13812
|
* Creates an instance of the Kv that allows you to create and access KV stores.
|
|
@@ -13872,7 +13872,7 @@ var require_kv = __commonJS({
|
|
|
13872
13872
|
return new internal_2.ListerImpl(subj, filter, this.js);
|
|
13873
13873
|
}
|
|
13874
13874
|
};
|
|
13875
|
-
exports.Kvm =
|
|
13875
|
+
exports.Kvm = Kvm5;
|
|
13876
13876
|
var Bucket = class _Bucket {
|
|
13877
13877
|
js;
|
|
13878
13878
|
jsm;
|
|
@@ -16583,7 +16583,7 @@ async function decode(kv, key) {
|
|
|
16583
16583
|
}
|
|
16584
16584
|
|
|
16585
16585
|
// ../../packages/core/dist/agent-file.js
|
|
16586
|
-
import { readFileSync } from "node:fs";
|
|
16586
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16587
16587
|
function unquote(v) {
|
|
16588
16588
|
if (v.startsWith('"') && v.endsWith('"') || v.startsWith("'") && v.endsWith("'"))
|
|
16589
16589
|
return v.slice(1, -1);
|
|
@@ -16635,6 +16635,11 @@ function loadAgentFile(path) {
|
|
|
16635
16635
|
const kind = str("kind");
|
|
16636
16636
|
if (kind && kind !== "agent" && kind !== "endpoint")
|
|
16637
16637
|
throw new Error(`agent file ${path}: "kind" must be "agent" or "endpoint"`);
|
|
16638
|
+
const known = /* @__PURE__ */ new Set(["name", "role", "kind", "description", "tags", "channels", "publish", "model"]);
|
|
16639
|
+
const meta3 = {};
|
|
16640
|
+
for (const [k, v] of Object.entries(fm))
|
|
16641
|
+
if (!known.has(k) && typeof v === "string")
|
|
16642
|
+
meta3[k] = v;
|
|
16638
16643
|
return {
|
|
16639
16644
|
name,
|
|
16640
16645
|
role: str("role"),
|
|
@@ -16644,6 +16649,7 @@ function loadAgentFile(path) {
|
|
|
16644
16649
|
channels: list("channels"),
|
|
16645
16650
|
publish: list("publish"),
|
|
16646
16651
|
model: str("model"),
|
|
16652
|
+
meta: Object.keys(meta3).length ? meta3 : void 0,
|
|
16647
16653
|
persona: persona || void 0
|
|
16648
16654
|
};
|
|
16649
16655
|
}
|
|
@@ -17591,6 +17597,11 @@ function describeStatusError(err2) {
|
|
|
17591
17597
|
return err2;
|
|
17592
17598
|
}
|
|
17593
17599
|
|
|
17600
|
+
// ../../packages/core/dist/spaces.js
|
|
17601
|
+
var import_transport_node4 = __toESM(require_transport_node(), 1);
|
|
17602
|
+
var import_jetstream3 = __toESM(require_mod4(), 1);
|
|
17603
|
+
var import_kv4 = __toESM(require_mod6(), 1);
|
|
17604
|
+
|
|
17594
17605
|
// ../../packages/core/dist/registry.js
|
|
17595
17606
|
var Registry = class {
|
|
17596
17607
|
#byKey = /* @__PURE__ */ new Map();
|
|
@@ -17620,6 +17631,8 @@ var registry = new Registry();
|
|
|
17620
17631
|
// ../connector-core/dist/config.js
|
|
17621
17632
|
import { userInfo } from "node:os";
|
|
17622
17633
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
17634
|
+
var FEEDBACK_URL = "https://broker.cotal.ai/v1/feedback";
|
|
17635
|
+
var PUBLIC_FEEDBACK_URL = "https://cotal.ai/v1/feedback";
|
|
17623
17636
|
function splitList(v) {
|
|
17624
17637
|
if (!v)
|
|
17625
17638
|
return [];
|
|
@@ -17654,7 +17667,8 @@ function configFromEnv(env = process.env) {
|
|
|
17654
17667
|
user: link?.user,
|
|
17655
17668
|
pass: link?.pass,
|
|
17656
17669
|
tls: env.COTAL_TLS?.trim() === "1" || link?.tls || false,
|
|
17657
|
-
feedbackKey: env.COTAL_FEEDBACK_KEY?.trim() || void 0
|
|
17670
|
+
feedbackKey: env.COTAL_FEEDBACK_KEY?.trim() || void 0,
|
|
17671
|
+
feedbackUrl: env.COTAL_FEEDBACK_URL?.trim() || void 0
|
|
17658
17672
|
};
|
|
17659
17673
|
}
|
|
17660
17674
|
|
|
@@ -17897,6 +17911,38 @@ var MeshAgent = class extends EventEmitter2 {
|
|
|
17897
17911
|
this.assertConnected();
|
|
17898
17912
|
return this.ep.requestControl("manager", { op: "start", args: { name, role } });
|
|
17899
17913
|
}
|
|
17914
|
+
/** Ask the manager to tear a teammate down (its `stop` op). Graceful by default —
|
|
17915
|
+
* the session is told to exit cleanly (so it leaves the mesh) before the
|
|
17916
|
+
* process/tab is closed; `graceful:false` is a hard, immediate kill. */
|
|
17917
|
+
async despawn(name, opts) {
|
|
17918
|
+
this.assertConnected();
|
|
17919
|
+
return this.ep.requestControl("manager", {
|
|
17920
|
+
op: "stop",
|
|
17921
|
+
args: { name, graceful: opts?.graceful ?? true }
|
|
17922
|
+
});
|
|
17923
|
+
}
|
|
17924
|
+
/** Ask the manager to purge the space's retained chat backlog (its `purge` op). Cleanup only —
|
|
17925
|
+
* it doesn't touch live agents or the anycast work queue. `includeDms` also clears DM history. */
|
|
17926
|
+
async purgeHistory(opts) {
|
|
17927
|
+
this.assertConnected();
|
|
17928
|
+
return this.ep.requestControl("manager", {
|
|
17929
|
+
op: "purge",
|
|
17930
|
+
args: { includeDms: opts?.includeDms ?? false }
|
|
17931
|
+
});
|
|
17932
|
+
}
|
|
17933
|
+
/** Define a persona and persist it as config (the manager's `definePersona` op writes
|
|
17934
|
+
* .cotal/agents/<name>.md). On success, announce it on the channel — the "send it out"
|
|
17935
|
+
* half — so peers see the new persona; `spawn(name)` then launches an agent wearing it. */
|
|
17936
|
+
async definePersona(def) {
|
|
17937
|
+
this.assertConnected();
|
|
17938
|
+
const reply = await this.ep.requestControl("manager", {
|
|
17939
|
+
op: "definePersona",
|
|
17940
|
+
args: { name: def.name, role: def.role, model: def.model, persona: def.prompt }
|
|
17941
|
+
});
|
|
17942
|
+
if (reply.ok)
|
|
17943
|
+
await this.send(`persona \`${def.name}\` is now available \u2014 spawn it to bring it online`);
|
|
17944
|
+
return reply;
|
|
17945
|
+
}
|
|
17900
17946
|
// ---- presence ------------------------------------------------------------
|
|
17901
17947
|
/** The full roster, including ourselves. */
|
|
17902
17948
|
roster() {
|
|
@@ -17978,6 +18024,9 @@ ${lines.join("\n")}`;
|
|
|
17978
18024
|
}
|
|
17979
18025
|
};
|
|
17980
18026
|
|
|
18027
|
+
// ../connector-core/dist/tool-specs.js
|
|
18028
|
+
import { execFileSync } from "node:child_process";
|
|
18029
|
+
|
|
17981
18030
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
17982
18031
|
var external_exports = {};
|
|
17983
18032
|
__export(external_exports, {
|
|
@@ -32498,6 +32547,8 @@ var err = (text) => ({ text, isError: true });
|
|
|
32498
32547
|
function statusGlyph(s) {
|
|
32499
32548
|
return s === "working" ? "\u25CF" : s === "waiting" ? "\u25D0" : s === "idle" ? "\u25CB" : "\xB7";
|
|
32500
32549
|
}
|
|
32550
|
+
var FACE_TAG_RE = /\[\[\s*face\s*:\s*[\w-]+\s*\]\]\s?/gi;
|
|
32551
|
+
var stripFaceTags = (text) => text.replace(FACE_TAG_RE, "");
|
|
32501
32552
|
var ATTENTION_DESC = {
|
|
32502
32553
|
open: "open \u2014 you receive everything; untagged channel chatter wakes you when idle",
|
|
32503
32554
|
dnd: "dnd \u2014 channel chatter no longer wakes you (it still arrives in your next turn); DMs, anycast, and @mentions still wake you",
|
|
@@ -32527,7 +32578,19 @@ function renderChannelInfo(channel, info) {
|
|
|
32527
32578
|
lines.push(` \u2022 replay-on-join: ${info.replay ? "on \u2014 new joiners see recent history" : "off \u2014 new joiners start from now (no backfill)"}`);
|
|
32528
32579
|
return lines.join("\n");
|
|
32529
32580
|
}
|
|
32530
|
-
function
|
|
32581
|
+
function resolveFeedbackEmail(explicit) {
|
|
32582
|
+
if (explicit?.trim())
|
|
32583
|
+
return explicit.trim();
|
|
32584
|
+
if (process.env.COTAL_FEEDBACK_EMAIL?.trim())
|
|
32585
|
+
return process.env.COTAL_FEEDBACK_EMAIL.trim();
|
|
32586
|
+
try {
|
|
32587
|
+
const email3 = execFileSync("git", ["config", "user.email"], { encoding: "utf8" }).trim();
|
|
32588
|
+
return email3 || void 0;
|
|
32589
|
+
} catch {
|
|
32590
|
+
return void 0;
|
|
32591
|
+
}
|
|
32592
|
+
}
|
|
32593
|
+
function cotalToolSpecs(config2, source = "connector") {
|
|
32531
32594
|
return [
|
|
32532
32595
|
{
|
|
32533
32596
|
name: "cotal_roster",
|
|
@@ -32590,7 +32653,7 @@ ${all.map(fmtItem).join("\n")}`);
|
|
|
32590
32653
|
},
|
|
32591
32654
|
async run(agent, _config, { text: msg, channel, mentions }) {
|
|
32592
32655
|
try {
|
|
32593
|
-
const m = await agent.send(msg, channel, mentions);
|
|
32656
|
+
const m = await agent.send(stripFaceTags(msg), channel, mentions);
|
|
32594
32657
|
return ok(`Sent to #${m.channel}${m.mentions?.length ? ` (mentioned @${m.mentions.join(", @")})` : ""}.`);
|
|
32595
32658
|
} catch (e) {
|
|
32596
32659
|
return err(`Couldn't send: ${e.message}`);
|
|
@@ -32607,7 +32670,7 @@ ${all.map(fmtItem).join("\n")}`);
|
|
|
32607
32670
|
},
|
|
32608
32671
|
async run(agent, _config, { to, text: msg }) {
|
|
32609
32672
|
try {
|
|
32610
|
-
const { peer } = await agent.dm(to, msg);
|
|
32673
|
+
const { peer } = await agent.dm(to, stripFaceTags(msg));
|
|
32611
32674
|
return ok(`DM sent to ${peer.card.name}.`);
|
|
32612
32675
|
} catch (e) {
|
|
32613
32676
|
return err(`Couldn't DM: ${e.message}`);
|
|
@@ -32624,7 +32687,7 @@ ${all.map(fmtItem).join("\n")}`);
|
|
|
32624
32687
|
},
|
|
32625
32688
|
async run(agent, _config, { role, text: msg }) {
|
|
32626
32689
|
try {
|
|
32627
|
-
await agent.anycast(role, msg);
|
|
32690
|
+
await agent.anycast(role, stripFaceTags(msg));
|
|
32628
32691
|
return ok(`Sent to one @${role}.`);
|
|
32629
32692
|
} catch (e) {
|
|
32630
32693
|
return err(`Couldn't send: ${e.message}`);
|
|
@@ -32749,6 +32812,116 @@ ${info}${caught}`);
|
|
|
32749
32812
|
return err(`Couldn't spawn ${name}: no manager reachable (${e.message}). Is the manager running?`);
|
|
32750
32813
|
}
|
|
32751
32814
|
}
|
|
32815
|
+
},
|
|
32816
|
+
{
|
|
32817
|
+
name: "cotal_feedback",
|
|
32818
|
+
title: "Cotal: send beta feedback",
|
|
32819
|
+
description: "Send feedback about Cotal to its developers. With a configured feedback key it goes to the keyed beta intake; without one it goes to the public cotal.ai intake, which requires a contact email.",
|
|
32820
|
+
schema: {
|
|
32821
|
+
origin: external_exports.enum(["human", "agent"]).describe(`"human" when relaying the user's feedback, "agent" when reporting an issue you hit yourself.`),
|
|
32822
|
+
type: external_exports.enum(["bug", "idea", "friction", "praise", "other"]).describe("What kind of feedback this is."),
|
|
32823
|
+
summary: external_exports.string().max(300).describe("Required one-line summary, max 300 characters."),
|
|
32824
|
+
details: external_exports.string().max(1e4).optional().describe("Longer free-form details. Do not include secrets."),
|
|
32825
|
+
severity: external_exports.enum(["low", "medium", "high"]).optional().describe("How badly this hurts (bugs/friction)."),
|
|
32826
|
+
area: external_exports.string().max(120).optional().describe("The part of Cotal this concerns (e.g. presence, channels, CLI)."),
|
|
32827
|
+
repro: external_exports.string().max(1e4).optional().describe("Steps to reproduce."),
|
|
32828
|
+
expected: external_exports.string().max(5e3).optional().describe("What you expected to happen."),
|
|
32829
|
+
actual: external_exports.string().max(5e3).optional().describe("What actually happened."),
|
|
32830
|
+
diagnostics: external_exports.string().max(1e4).optional().describe("Relevant diagnostics as text (logs, errors). Never include secrets."),
|
|
32831
|
+
email: external_exports.string().optional().describe("Contact email \u2014 required on the keyless public path when none is configured in the environment.")
|
|
32832
|
+
},
|
|
32833
|
+
async run(_agent, _config, args) {
|
|
32834
|
+
const { email: email3, ...payload } = args;
|
|
32835
|
+
const url2 = config2.feedbackUrl ?? (config2.feedbackKey ? FEEDBACK_URL : PUBLIC_FEEDBACK_URL);
|
|
32836
|
+
const headers = { "content-type": "application/json" };
|
|
32837
|
+
const body = { ...payload, source };
|
|
32838
|
+
if (config2.feedbackKey) {
|
|
32839
|
+
headers.authorization = `Bearer ${config2.feedbackKey}`;
|
|
32840
|
+
} else {
|
|
32841
|
+
const contact = resolveFeedbackEmail(email3);
|
|
32842
|
+
if (!contact)
|
|
32843
|
+
return err("Keyless feedback goes to the public cotal.ai intake, which requires a traceable contact email \u2014 ask the user for one and retry with the email argument (or set COTAL_FEEDBACK_EMAIL).");
|
|
32844
|
+
body.email = contact;
|
|
32845
|
+
}
|
|
32846
|
+
try {
|
|
32847
|
+
const res = await fetch(url2, { method: "POST", headers, body: JSON.stringify(body) });
|
|
32848
|
+
const raw = await res.text();
|
|
32849
|
+
let reply = {};
|
|
32850
|
+
if (raw)
|
|
32851
|
+
try {
|
|
32852
|
+
reply = JSON.parse(raw);
|
|
32853
|
+
} catch {
|
|
32854
|
+
reply = { error: raw };
|
|
32855
|
+
}
|
|
32856
|
+
if (!res.ok)
|
|
32857
|
+
return err(`Feedback rejected (${res.status}${reply.error ? `: ${reply.error}` : ""}).`);
|
|
32858
|
+
const note = reply.published === false ? " (stored, but the internal feedback channel publish failed)" : "";
|
|
32859
|
+
return ok(`Feedback sent${reply.id ? ` (id ${reply.id})` : ""}${note}. Thanks!`);
|
|
32860
|
+
} catch (e) {
|
|
32861
|
+
return err(`Couldn't reach the feedback intake at ${url2}: ${e.message}`);
|
|
32862
|
+
}
|
|
32863
|
+
}
|
|
32864
|
+
},
|
|
32865
|
+
{
|
|
32866
|
+
name: "cotal_despawn",
|
|
32867
|
+
title: "Cotal: stop a teammate",
|
|
32868
|
+
description: "Ask the manager to tear a teammate down \u2014 it leaves the mesh and its process/tab is closed. Graceful by default (the session exits cleanly first); pass graceful:false for a hard, immediate kill. The inverse of cotal_spawn.",
|
|
32869
|
+
schema: {
|
|
32870
|
+
name: external_exports.string().describe("Name of the peer to stop."),
|
|
32871
|
+
graceful: external_exports.boolean().optional().describe("Default true: let the session exit cleanly. false = hard kill.")
|
|
32872
|
+
},
|
|
32873
|
+
async run(agent, _config, { name, graceful }) {
|
|
32874
|
+
try {
|
|
32875
|
+
const reply = await agent.despawn(name, { graceful });
|
|
32876
|
+
if (!reply.ok)
|
|
32877
|
+
return err(`Couldn't despawn ${name}: ${reply.error ?? "manager refused"}`);
|
|
32878
|
+
return ok(`Stopping ${name}${graceful === false ? " (hard)" : ""} \u2014 it will leave the roster shortly.`);
|
|
32879
|
+
} catch (e) {
|
|
32880
|
+
return err(`Couldn't despawn ${name}: no manager reachable (${e.message}). Is the manager running?`);
|
|
32881
|
+
}
|
|
32882
|
+
}
|
|
32883
|
+
},
|
|
32884
|
+
{
|
|
32885
|
+
name: "cotal_purge",
|
|
32886
|
+
title: "Cotal: clear chat history",
|
|
32887
|
+
description: "Ask the manager to purge this space's retained chat backlog (channel history). Set includeDms to also clear direct-message history. Cleanup only \u2014 it does not affect live agents or the anycast work queue. Irreversible.",
|
|
32888
|
+
schema: {
|
|
32889
|
+
includeDms: external_exports.boolean().optional().describe("Default false: channel history only. true = also purge DM history.")
|
|
32890
|
+
},
|
|
32891
|
+
async run(agent, _config, { includeDms }) {
|
|
32892
|
+
try {
|
|
32893
|
+
const reply = await agent.purgeHistory({ includeDms });
|
|
32894
|
+
if (!reply.ok)
|
|
32895
|
+
return err(`Couldn't purge history: ${reply.error ?? "manager refused"}`);
|
|
32896
|
+
const d = reply.data;
|
|
32897
|
+
const chat = d?.chat ?? 0;
|
|
32898
|
+
const dm = d?.dm;
|
|
32899
|
+
return ok(`Cleared ${chat} channel message${chat === 1 ? "" : "s"}${dm === void 0 ? "" : ` and ${dm} DM${dm === 1 ? "" : "s"}`} from "${_config.space}".`);
|
|
32900
|
+
} catch (e) {
|
|
32901
|
+
return err(`Couldn't purge history: no manager reachable (${e.message}). Is the manager running?`);
|
|
32902
|
+
}
|
|
32903
|
+
}
|
|
32904
|
+
},
|
|
32905
|
+
{
|
|
32906
|
+
name: "cotal_persona",
|
|
32907
|
+
title: "Cotal: define a persona",
|
|
32908
|
+
description: "Define a new persona and save it as config (the manager writes .cotal/agents/<name>.md), then announce it on the mesh. Afterwards cotal_spawn(name) launches a real agent wearing this persona/model. Use to grow the team with a custom role you describe on the fly.",
|
|
32909
|
+
schema: {
|
|
32910
|
+
name: external_exports.string().regex(/^[A-Za-z0-9_-]+$/, "letters, digits, _ or - only").describe("Unique name for the persona (also the spawn name): letters, digits, _ or -."),
|
|
32911
|
+
prompt: external_exports.string().max(1e4).describe("The persona \u2014 an appended system prompt describing who this agent is."),
|
|
32912
|
+
role: external_exports.string().max(120).optional().describe("Optional role label (e.g. reviewer, scout)."),
|
|
32913
|
+
model: external_exports.string().max(120).optional().describe("Optional model override (e.g. opus, sonnet).")
|
|
32914
|
+
},
|
|
32915
|
+
async run(agent, _config, { name, prompt, role, model }) {
|
|
32916
|
+
try {
|
|
32917
|
+
const reply = await agent.definePersona({ name, prompt, role, model });
|
|
32918
|
+
if (!reply.ok)
|
|
32919
|
+
return err(`Couldn't define ${name}: ${reply.error ?? "manager refused"}`);
|
|
32920
|
+
return ok(`Persona \`${name}\` saved \u2014 spawn it with cotal_spawn(name="${name}") to bring it online.`);
|
|
32921
|
+
} catch (e) {
|
|
32922
|
+
return err(`Couldn't define ${name}: no manager reachable (${e.message}). Is the manager running?`);
|
|
32923
|
+
}
|
|
32924
|
+
}
|
|
32752
32925
|
}
|
|
32753
32926
|
];
|
|
32754
32927
|
}
|
|
@@ -32779,7 +32952,7 @@ ${tail}`;
|
|
|
32779
32952
|
import { tool } from "@opencode-ai/plugin";
|
|
32780
32953
|
function buildCotalTools(agent, config2) {
|
|
32781
32954
|
const tools = {};
|
|
32782
|
-
for (const spec of cotalToolSpecs(config2)) {
|
|
32955
|
+
for (const spec of cotalToolSpecs(config2, "opencode")) {
|
|
32783
32956
|
if (spec.name === "cotal_inbox") {
|
|
32784
32957
|
tools.cotal_inbox = tool({
|
|
32785
32958
|
description: "Show the peer messages currently waiting for you (incl. focus-mode recall). You don't normally need this \u2014 the connector delivers peer messages into your turns automatically; use it to re-check what's pending mid-task. Read-only: it never consumes them.",
|
|
@@ -32820,7 +32993,9 @@ var cotal = async ({ client }) => {
|
|
|
32820
32993
|
const agent = new MeshAgent(config2);
|
|
32821
32994
|
agent.start();
|
|
32822
32995
|
const def = process.env.COTAL_AGENT_FILE?.trim() ? loadAgentFile(process.env.COTAL_AGENT_FILE.trim()) : void 0;
|
|
32823
|
-
const
|
|
32996
|
+
const facePrompt = process.env.COTAL_FACE_PERSONA?.trim() ? 'You speak through an animated pixel-art avatar of yourself. Hard formatting rule: the text you pass to the cotal send tools (cotal_send / cotal_dm) must START with an emotion tag [[face:X]], where X is one of: neutral, happy, sad, angry, surprised \u2014 pick the one matching your mood, and insert another tag mid-text whenever your mood shifts. Example: "[[face:angry]] That race condition cost me three days. [[face:happy]] But watch it run now." Never mention or explain the tags \u2014 they are stripped before peers see your message.' : void 0;
|
|
32997
|
+
const persona = [def?.persona, facePrompt].filter(Boolean).join("\n\n") || void 0;
|
|
32998
|
+
const faceReminder = facePrompt ? "(avatar: begin your cotal_send/cotal_dm text with [[face:X]] \u2014 neutral|happy|sad|angry|surprised \u2014 and add another tag when your mood shifts)" : void 0;
|
|
32824
32999
|
let sessionID;
|
|
32825
33000
|
let busy = false;
|
|
32826
33001
|
let driving = false;
|
|
@@ -32872,6 +33047,7 @@ var cotal = async ({ client }) => {
|
|
|
32872
33047
|
if (brief) parts.unshift({ type: "text", text: brief });
|
|
32873
33048
|
}
|
|
32874
33049
|
if (parts.length === 0) return;
|
|
33050
|
+
if (faceReminder) parts.push({ type: "text", text: faceReminder });
|
|
32875
33051
|
const body = { parts };
|
|
32876
33052
|
if (!primed && persona) body.system = persona;
|
|
32877
33053
|
busy = true;
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;AAazD,eAAO,MAAM,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,MAAM,EAAS,MAAM,qBAAqB,CAAC;AAazD,eAAO,MAAM,KAAK,EAAE,MAiPnB,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -41,7 +41,24 @@ export const cotal = async ({ client }) => {
|
|
|
41
41
|
const agent = new MeshAgent(config);
|
|
42
42
|
agent.start(); // background connect with retry — never blocks startup
|
|
43
43
|
const def = process.env.COTAL_AGENT_FILE?.trim() ? loadAgentFile(process.env.COTAL_AGENT_FILE.trim()) : undefined;
|
|
44
|
-
|
|
44
|
+
// Face-hosted (`face:` in the agent file → the shim attaches the face viewer): teach the agent
|
|
45
|
+
// to steer its avatar's expression with inline [[face:X]] tags in the text it passes to the
|
|
46
|
+
// cotal send tools. The viewer reads them from the tool-call input; the tool layer strips them
|
|
47
|
+
// before the wire, so peers never see them.
|
|
48
|
+
const facePrompt = process.env.COTAL_FACE_PERSONA?.trim()
|
|
49
|
+
? "You speak through an animated pixel-art avatar of yourself. Hard formatting rule: the text " +
|
|
50
|
+
"you pass to the cotal send tools (cotal_send / cotal_dm) must START with an emotion tag " +
|
|
51
|
+
"[[face:X]], where X is one of: neutral, happy, sad, angry, surprised — pick the one matching " +
|
|
52
|
+
"your mood, and insert another tag mid-text whenever your mood shifts. Example: " +
|
|
53
|
+
'"[[face:angry]] That race condition cost me three days. [[face:happy]] But watch it run now." ' +
|
|
54
|
+
"Never mention or explain the tags — they are stripped before peers see your message."
|
|
55
|
+
: undefined;
|
|
56
|
+
const persona = [def?.persona, facePrompt].filter(Boolean).join("\n\n") || undefined;
|
|
57
|
+
// System-position rules get ignored by some models — repeat the format rule in every injected
|
|
58
|
+
// turn (a fresh user-turn instruction is followed far more reliably).
|
|
59
|
+
const faceReminder = facePrompt
|
|
60
|
+
? "(avatar: begin your cotal_send/cotal_dm text with [[face:X]] — neutral|happy|sad|angry|surprised — and add another tag when your mood shifts)"
|
|
61
|
+
: undefined;
|
|
45
62
|
// This agent OWNS one session, created at boot. The serve shim attaches the foreground TUI to it
|
|
46
63
|
// (`opencode attach --session <id>`), so what the human watches IS the session we drive — no
|
|
47
64
|
// phantom home-screen, no stale-session guessing. Used to match our turn-end (idle) vs subagent idles.
|
|
@@ -119,6 +136,8 @@ export const cotal = async ({ client }) => {
|
|
|
119
136
|
}
|
|
120
137
|
if (parts.length === 0)
|
|
121
138
|
return;
|
|
139
|
+
if (faceReminder)
|
|
140
|
+
parts.push({ type: "text", text: faceReminder });
|
|
122
141
|
const body = { parts };
|
|
123
142
|
if (!primed && persona)
|
|
124
143
|
body.system = persona; // persona once, as system (no --append-system-prompt)
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,aAAa,EAAuB,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,aAAa,EACb,WAAW,EACX,SAAS,EACT,eAAe,EACf,OAAO,GAER,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,SAAS,GAAG,CAAC,GAAW;IACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAAC;AACrD,CAAC;AAED;;;0DAG0D;AAC1D,MAAM,KAAK,GAAG,UAA8C,CAAC;AAE7D,MAAM,CAAC,MAAM,KAAK,GAAW,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;IAChD,8EAA8E;IAC9E,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACnB,GAAG,CAAC,6DAA6D,CAAC,CAAC;QACnE,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,KAAK,CAAC,oBAAoB;QAAE,OAAO,KAAK,CAAC,oBAAoB,CAAC,CAAC,6BAA6B;IAChG,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,uDAAuD;IAEtE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAClH,MAAM,OAAO,GAAG,GAAG,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/serve.js
CHANGED
|
@@ -21,6 +21,7 @@ import { spawn } from "node:child_process";
|
|
|
21
21
|
import { createServer } from "node:net";
|
|
22
22
|
import { once } from "node:events";
|
|
23
23
|
import { randomBytes } from "node:crypto";
|
|
24
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
24
25
|
const BIN = process.env.COTAL_OPENCODE_BIN?.trim() || "opencode";
|
|
25
26
|
/** Per-launch secret gating the spawned server's HTTP API (see SECURITY above). */
|
|
26
27
|
const SECRET = randomBytes(24).toString("hex");
|
|
@@ -33,13 +34,53 @@ async function freePort() {
|
|
|
33
34
|
await new Promise((r) => srv.close(() => r()));
|
|
34
35
|
return port;
|
|
35
36
|
}
|
|
37
|
+
/** SIGTERM the serve, then SIGKILL if it's still alive 3s later — a lingering serve keeps the
|
|
38
|
+
* agent's data dir (SQLite) open and wedges every later same-name spawn. Resolves once it's dead. */
|
|
39
|
+
async function killServe(serve) {
|
|
40
|
+
if (serve.exitCode !== null || serve.signalCode !== null)
|
|
41
|
+
return;
|
|
42
|
+
serve.kill("SIGTERM");
|
|
43
|
+
const dead = await Promise.race([
|
|
44
|
+
once(serve, "exit").then(() => true),
|
|
45
|
+
new Promise((r) => setTimeout(() => r(false), 3000)),
|
|
46
|
+
]);
|
|
47
|
+
if (!dead) {
|
|
48
|
+
serve.kill("SIGKILL");
|
|
49
|
+
await once(serve, "exit");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
36
52
|
async function main() {
|
|
37
53
|
const port = process.env.COTAL_OPENCODE_PORT?.trim() || String(await freePort());
|
|
38
54
|
const url = `http://127.0.0.1:${port}`;
|
|
55
|
+
// Own data dir per agent: opencode keeps sessions in one SQLite file under XDG_DATA_HOME,
|
|
56
|
+
// and concurrent serves sharing it stall session-create on the write lock (the "agent
|
|
57
|
+
// session never came up" failure). Per-peer session state is the right scoping anyway;
|
|
58
|
+
// provider config/auth lives under XDG_CONFIG_HOME, untouched.
|
|
59
|
+
const name = process.env.COTAL_NAME?.trim() || "agent";
|
|
60
|
+
const dataHome = `${process.cwd()}/.cotal/opencode/${name}`;
|
|
61
|
+
// Two serves on one data dir share the SQLite file and stall each other — refuse up front.
|
|
62
|
+
const pidFile = `${dataHome}/serve.pid`;
|
|
63
|
+
if (existsSync(pidFile)) {
|
|
64
|
+
const pid = Number(readFileSync(pidFile, "utf8"));
|
|
65
|
+
let alive = false;
|
|
66
|
+
try {
|
|
67
|
+
process.kill(pid, 0);
|
|
68
|
+
alive = true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
/* stale pidfile */
|
|
72
|
+
}
|
|
73
|
+
if (alive)
|
|
74
|
+
throw new Error(`agent "${name}" is already running (opencode serve pid ${pid}) — kill it first`);
|
|
75
|
+
rmSync(pidFile);
|
|
76
|
+
}
|
|
39
77
|
const serve = spawn(BIN, ["serve", "--hostname", "127.0.0.1", "--port", port], {
|
|
40
|
-
env: { ...process.env, OPENCODE_SERVER_PASSWORD: SECRET },
|
|
78
|
+
env: { ...process.env, OPENCODE_SERVER_PASSWORD: SECRET, XDG_DATA_HOME: dataHome },
|
|
41
79
|
stdio: ["ignore", "pipe", "pipe"],
|
|
42
80
|
});
|
|
81
|
+
mkdirSync(dataHome, { recursive: true });
|
|
82
|
+
writeFileSync(pidFile, String(serve.pid));
|
|
83
|
+
serve.on("exit", () => rmSync(pidFile, { force: true }));
|
|
43
84
|
// Scan the server's output for the plugin's session handshake; forward boot logs to our stderr
|
|
44
85
|
// until the TUI takes over the terminal (after that, drop them so they can't corrupt its display).
|
|
45
86
|
let sessionId;
|
|
@@ -62,33 +103,34 @@ async function main() {
|
|
|
62
103
|
if (!attached)
|
|
63
104
|
process.exit(code ?? (signal ? 1 : 0)); // died before the TUI came up
|
|
64
105
|
});
|
|
65
|
-
// Poke the server (lazy plugin load → mesh join +
|
|
66
|
-
//
|
|
106
|
+
// Poke the server until the plugin's session handshake lands (lazy plugin load → mesh join +
|
|
107
|
+
// session create). Poking must NOT stop at the first 2xx: early in boot the server can answer
|
|
108
|
+
// /session before the project instance has bootstrapped, and only a later request triggers the
|
|
109
|
+
// bootstrap that loads the plugin. Each poke carries its own abort timeout: a request that
|
|
110
|
+
// lands in the early-boot window can hang with no response, and an un-timed fetch would pin
|
|
111
|
+
// the loop on it forever (undici queues later requests behind it on the pooled connection).
|
|
67
112
|
const auth = `Basic ${Buffer.from(`opencode:${SECRET}`).toString("base64")}`;
|
|
68
113
|
void (async () => {
|
|
69
|
-
for (let i = 0; i <
|
|
114
|
+
for (let i = 0; i < 300 && !sessionId; i++) {
|
|
70
115
|
try {
|
|
71
|
-
|
|
72
|
-
if (res.ok)
|
|
73
|
-
return;
|
|
116
|
+
await fetch(`${url}/session`, { headers: { authorization: auth }, signal: AbortSignal.timeout(1500) });
|
|
74
117
|
}
|
|
75
118
|
catch {
|
|
76
|
-
/* not up yet — retry */
|
|
119
|
+
/* not up yet (or a hung early request, aborted) — retry on a fresh connection */
|
|
77
120
|
}
|
|
78
121
|
await new Promise((r) => setTimeout(r, 200));
|
|
79
122
|
}
|
|
80
|
-
process.stderr.write("[cotal-connector] serve: no 2xx from the poke after ~10s — plugin may not have loaded\n");
|
|
81
123
|
})();
|
|
82
124
|
// Wait for the agent's session, then attach a foreground TUI to it.
|
|
83
125
|
const id = await new Promise((resolve) => {
|
|
84
126
|
if (sessionId)
|
|
85
127
|
return resolve(sessionId);
|
|
86
128
|
onSession = resolve;
|
|
87
|
-
setTimeout(() => resolve(sessionId),
|
|
129
|
+
setTimeout(() => resolve(sessionId), 60_000);
|
|
88
130
|
});
|
|
89
131
|
if (!id) {
|
|
90
|
-
process.stderr.write("[cotal-connector] serve: agent session never came up (~
|
|
91
|
-
serve
|
|
132
|
+
process.stderr.write("[cotal-connector] serve: agent session never came up (~60s) — aborting. Check the boot log above for plugin/mesh errors (.cotal/opencode/<name>/opencode/log/)\n");
|
|
133
|
+
await killServe(serve);
|
|
92
134
|
process.exit(1);
|
|
93
135
|
}
|
|
94
136
|
const tuiEnv = { ...process.env, OPENCODE_SERVER_PASSWORD: SECRET };
|
|
@@ -97,7 +139,21 @@ async function main() {
|
|
|
97
139
|
if (k.startsWith("COTAL_"))
|
|
98
140
|
delete tuiEnv[k];
|
|
99
141
|
attached = true;
|
|
100
|
-
|
|
142
|
+
// COTAL_FACE_PERSONA (from the agent file's `face:`) swaps the chat TUI for the animated
|
|
143
|
+
// face viewer (face-term). COTAL_FACE_BIN must point at face-term.mjs — no fallback.
|
|
144
|
+
const facePersona = process.env.COTAL_FACE_PERSONA?.trim();
|
|
145
|
+
const faceBin = process.env.COTAL_FACE_BIN?.trim();
|
|
146
|
+
if (facePersona && !faceBin) {
|
|
147
|
+
await killServe(serve); // don't orphan the server — it holds the agent's data dir
|
|
148
|
+
throw new Error("COTAL_FACE_PERSONA is set but COTAL_FACE_BIN is not — point it at face-term.mjs");
|
|
149
|
+
}
|
|
150
|
+
const [cmd, args] = facePersona
|
|
151
|
+
? [
|
|
152
|
+
process.execPath,
|
|
153
|
+
[faceBin, "--persona", facePersona, "--server", url, "--session", id, "--password", SECRET],
|
|
154
|
+
]
|
|
155
|
+
: [BIN, ["attach", url, "--session", id, "--password", SECRET]];
|
|
156
|
+
const tui = spawn(cmd, args, {
|
|
101
157
|
env: tuiEnv,
|
|
102
158
|
stdio: "inherit",
|
|
103
159
|
});
|
|
@@ -107,8 +163,8 @@ async function main() {
|
|
|
107
163
|
serve.kill(sig);
|
|
108
164
|
});
|
|
109
165
|
tui.on("exit", (code, signal) => {
|
|
110
|
-
|
|
111
|
-
process.exit(code ?? (signal ? 1 : 0));
|
|
166
|
+
// TUI closed → tear down the server, for real (SIGKILL fallback), before exiting.
|
|
167
|
+
void killServe(serve).then(() => process.exit(code ?? (signal ? 1 : 0)));
|
|
112
168
|
});
|
|
113
169
|
}
|
|
114
170
|
void main();
|
package/dist/serve.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.js
CHANGED
|
@@ -13,7 +13,7 @@ import { cotalToolSpecs } from "@cotal-ai/connector-core";
|
|
|
13
13
|
/** Build the cotal_* tool map wired to one mesh agent, rendered from the shared specs. */
|
|
14
14
|
export function buildCotalTools(agent, config) {
|
|
15
15
|
const tools = {};
|
|
16
|
-
for (const spec of cotalToolSpecs(config)) {
|
|
16
|
+
for (const spec of cotalToolSpecs(config, "opencode")) {
|
|
17
17
|
if (spec.name === "cotal_inbox") {
|
|
18
18
|
// Read-only: this connector delivers + acks each turn, so the tool must never drain. Force
|
|
19
19
|
// peek (still surfaces focus-mode recall), and reframe push-primary / pull-secondary. (norman)
|
package/dist/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,IAAI,EAAuB,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAoC,MAAM,0BAA0B,CAAC;AAE5F,0FAA0F;AAC1F,MAAM,UAAU,eAAe,CAAC,KAAgB,EAAE,MAAmB;IACnE,MAAM,KAAK,GAAmC,EAAE,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,IAAI,EAAuB,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAoC,MAAM,0BAA0B,CAAC;AAE5F,0FAA0F;AAC1F,MAAM,UAAU,eAAe,CAAC,KAAgB,EAAE,MAAmB;IACnE,MAAM,KAAK,GAAmC,EAAE,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;QACtD,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAChC,2FAA2F;YAC3F,+FAA+F;YAC/F,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;gBACvB,WAAW,EACT,+PAA+P;gBACjQ,IAAI,EAAE,EAAE;gBACR,KAAK,CAAC,OAAO;oBACX,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;oBACxD,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC5C,CAAC;aACF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACtB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,mGAAmG;YACnG,IAAI,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAA0B;YAClD,KAAK,CAAC,OAAO,CAAC,IAAa;gBACzB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAQ,CAAC,CAAC;gBAC7D,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC5C,CAAC;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cotal-ai/connector-opencode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-next-20260614011207",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,19 +17,19 @@
|
|
|
17
17
|
}
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@cotal-ai/connector-core": "0.
|
|
20
|
+
"@cotal-ai/connector-core": "1.0.0-next-20260614011207"
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"@opencode-ai/plugin": "^1.16.2",
|
|
24
24
|
"@opencode-ai/sdk": "^1.16.2",
|
|
25
|
-
"@cotal-ai/core": "0.
|
|
25
|
+
"@cotal-ai/core": "0.2.0-next-20260614011207"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@opencode-ai/plugin": "^1.16.2",
|
|
29
29
|
"@opencode-ai/sdk": "^1.16.2",
|
|
30
30
|
"esbuild": "^0.28.0",
|
|
31
31
|
"tsx": "^4.22.4",
|
|
32
|
-
"@cotal-ai/core": "0.
|
|
32
|
+
"@cotal-ai/core": "0.2.0-next-20260614011207"
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
35
35
|
"dist"
|