@cotal-ai/connector-opencode 0.28.0 → 0.28.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/dist/index.js CHANGED
@@ -14831,7 +14831,7 @@ import { isConcreteChannel as isConcreteChannel3, channelInAllow as channelInAll
14831
14831
 
14832
14832
  // ../connector-core/dist/docs-bundle.generated.js
14833
14833
  var DOCS_BUNDLE = {
14834
- "version": "0.28.0",
14834
+ "version": "0.28.2",
14835
14835
  "generatedFrom": "docs/*.md + SPEC.md + spec/cotal-lang.md + spec/cotal.schema.json",
14836
14836
  "pages": [
14837
14837
  {
@@ -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 = connect8;
13613
+ exports.connect = connect7;
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 connect8(opts = {}) {
13617
+ function connect7(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
  }
@@ -35850,49 +35850,33 @@ var SYS_LIMITS = { ...BASE_LIMITS, mem_storage: 0, disk_storage: 0 };
35850
35850
  var import_nkeys4 = __toESM(require_mod2(), 1);
35851
35851
 
35852
35852
  // ../../packages/core/dist/channels.js
35853
- var import_kv4 = __toESM(require_mod6(), 1);
35854
- var import_transport_node13 = __toESM(require_transport_node(), 1);
35855
- function parseDuration(s) {
35856
- const m = /^(\d+)(s|m|h|d)$/.exec(s.trim());
35857
- if (!m)
35858
- throw new Error(`invalid duration "${s}" - expected <number><s|m|h|d>, e.g. "24h"`);
35859
- const n = Number(m[1]);
35860
- const unit = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 }[m[2]];
35861
- return n * unit;
35862
- }
35863
- function effectiveReplay(cfg, defaults) {
35864
- return cfg?.replay ?? defaults?.replay ?? true;
35865
- }
35866
- function effectiveReplayWindowMs(cfg, defaults) {
35867
- const w = cfg?.replayWindow ?? defaults?.replayWindow;
35868
- return w === void 0 ? void 0 : parseDuration(w);
35869
- }
35870
- function effectiveDeliveryClass(cfg, defaults) {
35871
- return cfg?.deliveryClass ?? defaults?.deliveryClass ?? "durable";
35872
- }
35873
- async function openChannelRegistry(nc, space, opts = {}) {
35874
- const kvm = new import_kv4.Kvm(nc);
35875
- return opts.create ? kvm.create(channelBucket(space)) : kvm.open(channelBucket(space));
35876
- }
35877
- async function readChannelConfig(kv, channel) {
35878
- return decode2(kv, channel);
35879
- }
35880
- async function readChannelDefaults(kv) {
35881
- return decode2(kv, CHANNEL_DEFAULTS_KEY);
35882
- }
35883
- async function decode2(kv, key) {
35884
- const e = await kv.get(key);
35885
- if (!e || e.operation === "DEL" || e.operation === "PURGE")
35886
- return void 0;
35887
- try {
35888
- return e.json();
35889
- } catch {
35890
- return void 0;
35891
- }
35853
+ var import_kv7 = __toESM(require_mod6(), 1);
35854
+ var import_transport_node15 = __toESM(require_transport_node(), 1);
35855
+
35856
+ // ../../packages/core/dist/endpoint.js
35857
+ var import_transport_node14 = __toESM(require_transport_node(), 1);
35858
+ var import_nats_core = __toESM(require_mod3(), 1);
35859
+ import { EventEmitter } from "node:events";
35860
+ import { randomUUID } from "node:crypto";
35861
+ import { createConnection } from "node:net";
35862
+
35863
+ // ../../packages/core/dist/artifact.js
35864
+ var ARTIFACT_PART_KIND = "artifact";
35865
+ function isArtifactPart(value) {
35866
+ if (!value || typeof value !== "object")
35867
+ return false;
35868
+ const p = value;
35869
+ return p.kind === ARTIFACT_PART_KIND && typeof p.name === "string" && p.name.length > 0 && typeof p.mediaType === "string" && p.mediaType.length > 0 && typeof p.digest === "string" && isContractDigest(p.digest) && typeof p.size === "number" && Number.isSafeInteger(p.size) && p.size >= 0;
35892
35870
  }
35893
35871
 
35872
+ // ../../packages/core/dist/endpoint.js
35873
+ var import_jetstream13 = __toESM(require_mod4(), 1);
35874
+ var import_jetstream14 = __toESM(require_mod4(), 1);
35875
+ var import_kv6 = __toESM(require_mod6(), 1);
35876
+ var import_internal2 = __toESM(require_internal_mod3(), 1);
35877
+
35894
35878
  // ../../packages/core/dist/members.js
35895
- var import_kv5 = __toESM(require_mod6(), 1);
35879
+ var import_kv4 = __toESM(require_mod6(), 1);
35896
35880
  var StaleMembershipWrite = class extends Error {
35897
35881
  constructor(channel, owner, attempted, current) {
35898
35882
  super(`stale membership write for ${channel}/${owner}: generation ${attempted} < current ${current}`);
@@ -35900,7 +35884,7 @@ var StaleMembershipWrite = class extends Error {
35900
35884
  }
35901
35885
  };
35902
35886
  async function openMembersRegistry(nc, space, opts = {}) {
35903
- const kvm = new import_kv5.Kvm(nc);
35887
+ const kvm = new import_kv4.Kvm(nc);
35904
35888
  return opts.create ? kvm.create(membersBucket(space)) : kvm.open(membersBucket(space));
35905
35889
  }
35906
35890
  async function readMember(kv, channel, owner, lifecycleUid) {
@@ -36000,266 +35984,14 @@ function durableEligible(rec, seq) {
36000
35984
  return true;
36001
35985
  }
36002
35986
 
36003
- // ../../packages/core/dist/membership-feed.js
36004
- var import_transport_node14 = __toESM(require_transport_node(), 1);
36005
- var import_kv6 = __toESM(require_mod6(), 1);
36006
-
36007
- // ../../packages/core/dist/evict.js
36008
- var import_transport_node15 = __toESM(require_transport_node(), 1);
36009
-
36010
35987
  // ../../packages/core/dist/lease.js
36011
- var import_kv7 = __toESM(require_mod6(), 1);
36012
- var import_transport_node16 = __toESM(require_transport_node(), 1);
35988
+ var import_kv5 = __toESM(require_mod6(), 1);
35989
+ var import_transport_node13 = __toESM(require_transport_node(), 1);
36013
35990
  async function openDeliveryRegistry(nc, space) {
36014
- return new import_kv7.Kvm(nc).open(deliveryBucket(space));
36015
- }
36016
-
36017
- // ../../packages/core/dist/agent-file.js
36018
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
36019
- var import_yaml = __toESM(require_dist(), 1);
36020
- function parseFrontmatter(src, path) {
36021
- let doc;
36022
- try {
36023
- doc = (0, import_yaml.parse)(src);
36024
- } catch (e) {
36025
- throw new Error(`agent file ${path}: invalid YAML frontmatter; ${e.message}`);
36026
- }
36027
- if (doc === null || doc === void 0)
36028
- return {};
36029
- if (typeof doc !== "object" || Array.isArray(doc))
36030
- throw new Error(`agent file ${path}: frontmatter must be a YAML mapping (key: value pairs)`);
36031
- return doc;
36032
- }
36033
- function loadAgentFile(path) {
36034
- const src = readFileSync(path, "utf8");
36035
- const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(src);
36036
- if (!m)
36037
- throw new Error(`agent file ${path}: missing "---" frontmatter block`);
36038
- const fm = parseFrontmatter(m[1], path);
36039
- const persona = m[2].trim();
36040
- const str2 = (k) => {
36041
- const v = fm[k];
36042
- if (v === void 0 || v === null)
36043
- return void 0;
36044
- if (typeof v === "object")
36045
- throw new Error(`agent file ${path}: "${k}" must be a scalar`);
36046
- return String(v);
36047
- };
36048
- const list = (k) => {
36049
- const v = fm[k];
36050
- if (v === void 0 || v === null)
36051
- return void 0;
36052
- return (Array.isArray(v) ? v : [v]).map((x) => {
36053
- if (x === null || typeof x === "object")
36054
- throw new Error(`agent file ${path}: "${k}" list items must be scalars`);
36055
- return String(x);
36056
- });
36057
- };
36058
- const name = str2("name");
36059
- if (!name)
36060
- throw new Error(`agent file ${path}: "name" is required`);
36061
- assertValidName(name);
36062
- const kind = str2("kind");
36063
- if (kind && kind !== "agent" && kind !== "endpoint")
36064
- throw new Error(`agent file ${path}: "kind" must be "agent" or "endpoint"`);
36065
- for (const old of ["channels", "publish"])
36066
- if (old in fm)
36067
- throw new Error(`agent file ${path}: "${old}" was renamed - use "subscribe"/"allowSubscribe" (read) and "allowPublish" (post)`);
36068
- const subscribe = list("subscribe");
36069
- const allowSubscribe = list("allowSubscribe");
36070
- const allowPublish = list("allowPublish");
36071
- const quiet = list("quiet");
36072
- const muted = list("muted");
36073
- for (const ch of [...subscribe ?? [], ...allowSubscribe ?? [], ...allowPublish ?? []])
36074
- try {
36075
- assertValidChannel(ch);
36076
- } catch (e) {
36077
- throw new Error(`agent file ${path}: ${e.message}`);
36078
- }
36079
- const effSubscribe = subscribe ?? [];
36080
- const effAllow = allowSubscribe?.length ? allowSubscribe : effSubscribe;
36081
- for (const ch of effSubscribe)
36082
- if (!channelInAllow(effAllow, ch))
36083
- throw new Error(`agent file ${path}: subscribe channel "${ch}" is not within allowSubscribe [${effAllow.join(", ")}]`);
36084
- const both = (quiet ?? []).filter((c) => (muted ?? []).includes(c));
36085
- if (both.length)
36086
- throw new Error(`agent file ${path}: channel(s) [${both.join(", ")}] are in both quiet and muted - pick one`);
36087
- for (const [field, chans] of [["quiet", quiet], ["muted", muted]])
36088
- for (const ch of chans ?? []) {
36089
- try {
36090
- assertValidChannel(ch);
36091
- } catch (e) {
36092
- throw new Error(`agent file ${path}: ${e.message}`);
36093
- }
36094
- if (!isConcreteChannel(ch))
36095
- throw new Error(`agent file ${path}: ${field} channel "${ch}" must be a concrete channel (no wildcard)`);
36096
- if (!channelInAllow(effAllow, ch))
36097
- throw new Error(`agent file ${path}: ${field} channel "${ch}" is not within your read ACL / allowSubscribe [${effAllow.join(", ")}]`);
36098
- }
36099
- const launchOptionsRaw = fm["launchOptions"];
36100
- let launchOptions;
36101
- if (launchOptionsRaw !== void 0 && launchOptionsRaw !== null) {
36102
- if (typeof launchOptionsRaw !== "object" || Array.isArray(launchOptionsRaw))
36103
- throw new Error(`agent file ${path}: "launchOptions" must be a mapping of key: value pairs`);
36104
- launchOptions = launchOptionsRaw;
36105
- }
36106
- const known = /* @__PURE__ */ new Set(["name", "role", "kind", "description", "tags", "subscribe", "allowSubscribe", "allowPublish", "quiet", "muted", "model", "variant", "launchOptions", "capabilities", "owner"]);
36107
- const meta3 = {};
36108
- for (const [k, v] of Object.entries(fm))
36109
- if (!known.has(k) && v !== null && typeof v !== "object")
36110
- meta3[k] = String(v);
36111
- return {
36112
- name,
36113
- role: str2("role"),
36114
- kind,
36115
- description: str2("description"),
36116
- tags: list("tags"),
36117
- subscribe,
36118
- allowSubscribe,
36119
- allowPublish,
36120
- quiet,
36121
- muted,
36122
- model: str2("model"),
36123
- variant: str2("variant"),
36124
- launchOptions,
36125
- capabilities: list("capabilities"),
36126
- owner: str2("owner"),
36127
- meta: Object.keys(meta3).length ? meta3 : void 0,
36128
- persona: persona || void 0
36129
- };
36130
- }
36131
-
36132
- // ../../packages/core/dist/fs-safe.js
36133
- import { lstatSync, mkdirSync as mkdirSync2, unlinkSync } from "node:fs";
36134
- import { join } from "node:path";
36135
- function ensureDirNoSymlink(parent, ...segments) {
36136
- let dir = parent;
36137
- for (const seg of segments) {
36138
- dir = join(dir, seg);
36139
- let st;
36140
- try {
36141
- st = lstatSync(dir);
36142
- } catch (e) {
36143
- if (e.code === "ENOENT") {
36144
- mkdirSync2(dir, { mode: 448 });
36145
- continue;
36146
- }
36147
- throw e;
36148
- }
36149
- if (st.isSymbolicLink())
36150
- throw new Error(`refusing to write under "${dir}": it is a symlink`);
36151
- if (!st.isDirectory())
36152
- throw new Error(`refusing to write under "${dir}": not a directory`);
36153
- }
36154
- return dir;
36155
- }
36156
-
36157
- // ../../packages/core/dist/secret-fs.js
36158
- var isWin = process.platform === "win32";
36159
-
36160
- // ../../packages/core/dist/launch-material.js
36161
- import { mkdtempSync, readFileSync as readFileSync2, realpathSync, rmSync, rmdirSync, statSync } from "node:fs";
36162
- import { tmpdir } from "node:os";
36163
- import { basename, dirname, join as join2, resolve } from "node:path";
36164
- var DIR_PREFIX = "cotal-launch-";
36165
- var MATERIAL_FILE = "material.json";
36166
- var LAUNCH_MATERIAL_ENV = "COTAL_LAUNCH_MATERIAL";
36167
- function readLaunchMaterial(path) {
36168
- let raw;
36169
- try {
36170
- if (process.platform !== "win32") {
36171
- const mode = statSync(path).mode & 511;
36172
- if (mode & 63)
36173
- throw new Error(`is readable beyond its owner (mode ${mode.toString(8)}) - refusing to read connection material out of a file other local users can open`);
36174
- }
36175
- raw = readFileSync2(path, "utf8");
36176
- } catch (e) {
36177
- throw new Error(`launch material: cannot read ${path} (${e instanceof Error ? e.message : String(e)})`);
36178
- }
36179
- let parsed;
36180
- try {
36181
- parsed = JSON.parse(raw);
36182
- } catch {
36183
- throw new Error(`launch material: ${path} is not valid JSON`);
36184
- }
36185
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
36186
- throw new Error(`launch material: ${path} must contain a JSON object`);
36187
- return validate(parsed, path);
36188
- }
36189
- function validate(raw, path) {
36190
- const material = {};
36191
- const str2 = (key) => {
36192
- const v = raw[key];
36193
- if (v === void 0)
36194
- return;
36195
- if (typeof v !== "string" || !v.trim())
36196
- throw new Error(`launch material: ${path} has a ${key} that is not a non-empty string`);
36197
- material[key] = v;
36198
- };
36199
- str2("servers");
36200
- str2("creds");
36201
- str2("token");
36202
- str2("controlToken");
36203
- if (raw.userAuth !== void 0) {
36204
- const u = raw.userAuth;
36205
- if (typeof u !== "object" || u === null || Array.isArray(u))
36206
- throw new Error(`launch material: ${path} has a userAuth that is not an object`);
36207
- const { owner, actor, sentinelCredsPath, bearerCmd } = u;
36208
- const named = { owner, actor, sentinelCredsPath };
36209
- for (const [k, v] of Object.entries(named))
36210
- if (typeof v !== "string" || !v.trim())
36211
- throw new Error(`launch material: ${path} has a userAuth.${k} that is not a non-empty string`);
36212
- if (!Array.isArray(bearerCmd) || bearerCmd.length === 0 || !bearerCmd.every((a) => typeof a === "string" && a))
36213
- throw new Error(`launch material: ${path} has a userAuth.bearerCmd that is not a non-empty array of strings`);
36214
- material.userAuth = {
36215
- owner,
36216
- actor,
36217
- sentinelCredsPath,
36218
- bearerCmd
36219
- };
36220
- }
36221
- if (Object.keys(material).length === 0)
36222
- throw new Error(`launch material: ${path} carries nothing this reader recognises. A launch that references material and supplies none is a broken launcher, not an open-mode launch, so it is refused rather than defaulted.`);
36223
- return material;
36224
- }
36225
- function discardLaunchMaterial(path) {
36226
- const file2 = resolve(path);
36227
- try {
36228
- rmSync(file2, { force: true });
36229
- } catch {
36230
- }
36231
- const dir = dirname(file2);
36232
- if (basename(file2) !== MATERIAL_FILE || !basename(dir).startsWith(DIR_PREFIX))
36233
- return;
36234
- try {
36235
- if (realpathSync(dirname(dir)) !== realpathSync(tmpdir()))
36236
- return;
36237
- rmdirSync(dir);
36238
- } catch {
36239
- }
35991
+ return new import_kv5.Kvm(nc).open(deliveryBucket(space));
36240
35992
  }
36241
35993
 
36242
35994
  // ../../packages/core/dist/endpoint.js
36243
- var import_transport_node17 = __toESM(require_transport_node(), 1);
36244
- var import_nats_core = __toESM(require_mod3(), 1);
36245
- import { EventEmitter } from "node:events";
36246
- import { randomUUID } from "node:crypto";
36247
- import { createConnection } from "node:net";
36248
-
36249
- // ../../packages/core/dist/artifact.js
36250
- var ARTIFACT_PART_KIND = "artifact";
36251
- function isArtifactPart(value) {
36252
- if (!value || typeof value !== "object")
36253
- return false;
36254
- const p = value;
36255
- return p.kind === ARTIFACT_PART_KIND && typeof p.name === "string" && p.name.length > 0 && typeof p.mediaType === "string" && p.mediaType.length > 0 && typeof p.digest === "string" && isContractDigest(p.digest) && typeof p.size === "number" && Number.isSafeInteger(p.size) && p.size >= 0;
36256
- }
36257
-
36258
- // ../../packages/core/dist/endpoint.js
36259
- var import_jetstream13 = __toESM(require_mod4(), 1);
36260
- var import_jetstream14 = __toESM(require_mod4(), 1);
36261
- var import_kv8 = __toESM(require_mod6(), 1);
36262
- var import_internal2 = __toESM(require_internal_mod3(), 1);
36263
35995
  var DEFAULT_SERVER = "nats://127.0.0.1:4222";
36264
35996
  var PLANE3_FRAME_HEADER = "Cotal-Delivery-Frame";
36265
35997
  var READER_MAX_REDELIVERIES = 10;
@@ -36773,7 +36505,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
36773
36505
  this.watchStatus();
36774
36506
  this.js = (0, import_jetstream13.jetstream)(this.nc);
36775
36507
  if (this.doWatch || this.doRegister) {
36776
- const kvm = new import_kv8.Kvm(this.nc);
36508
+ const kvm = new import_kv6.Kvm(this.nc);
36777
36509
  this.kv = this.authed ? await kvm.open(presenceBucket(this.space)) : await kvm.create(presenceBucket(this.space), { ttl: this.ttlMs });
36778
36510
  }
36779
36511
  if (this.doWatch) {
@@ -37155,7 +36887,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
37155
36887
  throw new Error(`expectedLastSubjectSeq must be a non-negative safe integer, got ${JSON.stringify(opts.expectedLastSubjectSeq)}`);
37156
36888
  if (!Array.isArray(opts.parts) || opts.parts.length === 0)
37157
36889
  throw new Error("encodedSize requires at least one part");
37158
- const mh = (0, import_transport_node17.headers)();
36890
+ const mh = (0, import_transport_node14.headers)();
37159
36891
  mh.set("Nats-Msg-Id", opts.id);
37160
36892
  mh.set("Nats-Expected-Last-Subject-Sequence", `${opts.expectedLastSubjectSeq}`);
37161
36893
  const headerBytes = mh.encode().length;
@@ -37661,7 +37393,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
37661
37393
  async membershipFeedRegistry() {
37662
37394
  if (!this.nc)
37663
37395
  throw new Error("endpoint not started");
37664
- this.membershipFeedKv ??= await new import_kv8.Kvm(this.nc).open(membershipBucket(this.space));
37396
+ this.membershipFeedKv ??= await new import_kv6.Kvm(this.nc).open(membershipBucket(this.space));
37665
37397
  return this.membershipFeedKv;
37666
37398
  }
37667
37399
  /**
@@ -38027,7 +37759,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
38027
37759
  for await (const s of this.nc.status()) {
38028
37760
  if (s.type !== "error")
38029
37761
  continue;
38030
- if (s.error instanceof import_transport_node17.PermissionViolationError && this.confirmingChatSubs.has(s.error.subject))
37762
+ if (s.error instanceof import_transport_node14.PermissionViolationError && this.confirmingChatSubs.has(s.error.subject))
38031
37763
  continue;
38032
37764
  this.emit("error", describeStatusError(s.error));
38033
37765
  }
@@ -38250,7 +37982,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
38250
37982
  throw new Error("endpoint not started");
38251
37983
  if (this.managerLeaseKv)
38252
37984
  return this.managerLeaseKv;
38253
- const kvm = new import_kv8.Kvm((0, import_jetstream13.jetstream)(this.nc, { timeout: MANAGER_LEASE_ATTEMPT_MS }));
37985
+ const kvm = new import_kv6.Kvm((0, import_jetstream13.jetstream)(this.nc, { timeout: MANAGER_LEASE_ATTEMPT_MS }));
38254
37986
  if (this.authed) {
38255
37987
  this.managerLeaseKv = await kvm.open(managerBucket(this.space));
38256
37988
  } else {
@@ -38480,7 +38212,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
38480
38212
  filter_subject: subject,
38481
38213
  ack_policy: import_jetstream13.AckPolicy.None,
38482
38214
  mem_storage: true,
38483
- inactive_threshold: (0, import_transport_node17.nanos)(3e4),
38215
+ inactive_threshold: (0, import_transport_node14.nanos)(3e4),
38484
38216
  deliver_policy: import_jetstream13.DeliverPolicy.StartSequence,
38485
38217
  opt_start_seq: fromSeqExcl + 1
38486
38218
  });
@@ -38942,7 +38674,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
38942
38674
  channel: entry.channel,
38943
38675
  msg: authenticatedChannelMessage(entry.msg, entry.channel)
38944
38676
  };
38945
- const frameHeaders = (0, import_transport_node17.headers)();
38677
+ const frameHeaders = (0, import_transport_node14.headers)();
38946
38678
  frameHeaders.set(PLANE3_FRAME_HEADER, "1");
38947
38679
  await this.js.publish(dlvSubject(this.space, pr.owner, pr.actor, pr.lifecycleUid), JSON.stringify(frame), {
38948
38680
  msgID: `${entry.msg.id}:${owner}:${pr.lifecycleUid}:${entry.generation}`,
@@ -39072,7 +38804,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
39072
38804
  * distinct from a responder that errored. nats.js surfaces it as NoRespondersError, or a RequestError
39073
38805
  * whose `isNoResponders()` is true. */
39074
38806
  isNoResponders(e) {
39075
- return e instanceof import_transport_node17.NoRespondersError || e instanceof import_transport_node17.RequestError && e.isNoResponders();
38807
+ return e instanceof import_transport_node14.NoRespondersError || e instanceof import_transport_node14.RequestError && e.isNoResponders();
39076
38808
  }
39077
38809
  /** Agent-side: this session's CURRENT durable memberships (channel + join generation) from the
39078
38810
  * manager — the agent holds no read on the privileged members KV. `undefined` ⇒ NO control responder
@@ -39415,7 +39147,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
39415
39147
  filter_subject: subject,
39416
39148
  ack_policy: import_jetstream13.AckPolicy.None,
39417
39149
  mem_storage: true,
39418
- inactive_threshold: (0, import_transport_node17.nanos)(3e4),
39150
+ inactive_threshold: (0, import_transport_node14.nanos)(3e4),
39419
39151
  ..."time" in start ? { deliver_policy: import_jetstream13.DeliverPolicy.StartTime, opt_start_time: start.time.toISOString() } : { deliver_policy: import_jetstream13.DeliverPolicy.StartSequence, opt_start_seq: start.seq }
39420
39152
  });
39421
39153
  try {
@@ -39776,7 +39508,7 @@ function authOpts(a) {
39776
39508
  if (!a.sentinelCreds)
39777
39509
  throw new Error("user-mode bearer requires sentinelCreds");
39778
39510
  return {
39779
- authenticator: [(0, import_transport_node17.credsAuthenticator)(new TextEncoder().encode(a.sentinelCreds)), (0, import_transport_node17.tokenAuthenticator)(a.bearer)],
39511
+ authenticator: [(0, import_transport_node14.credsAuthenticator)(new TextEncoder().encode(a.sentinelCreds)), (0, import_transport_node14.tokenAuthenticator)(a.bearer)],
39780
39512
  tls
39781
39513
  };
39782
39514
  }
@@ -39784,7 +39516,7 @@ function authOpts(a) {
39784
39516
  if (a.token || a.user || a.pass)
39785
39517
  throw new Error("creds are mutually exclusive with token/user/pass auth");
39786
39518
  const creds = a.creds;
39787
- const authenticator = typeof creds === "function" ? (nonce3) => (0, import_transport_node17.credsAuthenticator)(new TextEncoder().encode(creds()))(nonce3) : (0, import_transport_node17.credsAuthenticator)(new TextEncoder().encode(creds));
39519
+ const authenticator = typeof creds === "function" ? (nonce3) => (0, import_transport_node14.credsAuthenticator)(new TextEncoder().encode(creds()))(nonce3) : (0, import_transport_node14.credsAuthenticator)(new TextEncoder().encode(creds));
39788
39520
  return { authenticator, tls };
39789
39521
  }
39790
39522
  return { token: a.token, user: a.user, pass: a.pass, tls };
@@ -39819,25 +39551,32 @@ function decodeBearerPrincipal(bearer) {
39819
39551
  return { owner, actor };
39820
39552
  }
39821
39553
  function describeStatusError(err2) {
39822
- if (err2 instanceof import_transport_node17.PermissionViolationError) {
39554
+ if (err2 instanceof import_transport_node14.PermissionViolationError) {
39823
39555
  return new Error(`NATS permission denied: cannot ${err2.operation} "${err2.subject}" - check this endpoint's ACLs (a denied peer looks "absent" rather than blocked)`, { cause: err2 });
39824
39556
  }
39825
39557
  return err2;
39826
39558
  }
39827
39559
  function isPermissionDenied(e) {
39828
- if (e instanceof import_transport_node17.PermissionViolationError)
39560
+ if (e instanceof import_transport_node14.PermissionViolationError)
39829
39561
  return true;
39830
- if (e?.cause instanceof import_transport_node17.PermissionViolationError)
39562
+ if (e?.cause instanceof import_transport_node14.PermissionViolationError)
39831
39563
  return true;
39832
39564
  return /permissions?\s+violation/i.test(String(e?.message ?? ""));
39833
39565
  }
39834
39566
  function isPublishPermissionDenied(e) {
39835
- const typed = e instanceof import_transport_node17.PermissionViolationError ? e : e?.cause instanceof import_transport_node17.PermissionViolationError ? e.cause : void 0;
39567
+ const typed = e instanceof import_transport_node14.PermissionViolationError ? e : e?.cause instanceof import_transport_node14.PermissionViolationError ? e.cause : void 0;
39836
39568
  return typed?.operation === "publish";
39837
39569
  }
39570
+ function wsServers(servers) {
39571
+ return /^wss?:\/\//i.test((servers.split(",")[0] ?? "").trim());
39572
+ }
39838
39573
  function dialerFor(servers) {
39839
- const first = (servers.split(",")[0] ?? "").trim();
39840
- return /^wss?:\/\//i.test(first) ? import_nats_core.wsconnect : import_transport_node17.connect;
39574
+ if (!wsServers(servers))
39575
+ return import_transport_node14.connect;
39576
+ return ((opts) => {
39577
+ const { tls: _tls, ...rest } = opts ?? {};
39578
+ return (0, import_nats_core.wsconnect)(rest);
39579
+ });
39841
39580
  }
39842
39581
  function hostPort(server) {
39843
39582
  const raw = (server.split(",")[0] ?? "").trim();
@@ -39902,13 +39641,285 @@ function classifyProbeFailure(e, opts) {
39902
39641
  } catch {
39903
39642
  }
39904
39643
  }
39905
- if (e instanceof import_transport_node17.UserAuthenticationExpiredError)
39644
+ if (e instanceof import_transport_node14.UserAuthenticationExpiredError)
39906
39645
  return { ok: false, reason: "stale-auth" };
39907
- if (e instanceof import_transport_node17.AuthorizationError)
39646
+ if (e instanceof import_transport_node14.AuthorizationError)
39908
39647
  return { ok: false, reason: "auth-required" };
39909
39648
  return { ok: false, reason: "unreachable" };
39910
39649
  }
39911
39650
 
39651
+ // ../../packages/core/dist/channels.js
39652
+ function parseDuration(s) {
39653
+ const m = /^(\d+)(s|m|h|d)$/.exec(s.trim());
39654
+ if (!m)
39655
+ throw new Error(`invalid duration "${s}" - expected <number><s|m|h|d>, e.g. "24h"`);
39656
+ const n = Number(m[1]);
39657
+ const unit = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 }[m[2]];
39658
+ return n * unit;
39659
+ }
39660
+ function effectiveReplay(cfg, defaults) {
39661
+ return cfg?.replay ?? defaults?.replay ?? true;
39662
+ }
39663
+ function effectiveReplayWindowMs(cfg, defaults) {
39664
+ const w = cfg?.replayWindow ?? defaults?.replayWindow;
39665
+ return w === void 0 ? void 0 : parseDuration(w);
39666
+ }
39667
+ function effectiveDeliveryClass(cfg, defaults) {
39668
+ return cfg?.deliveryClass ?? defaults?.deliveryClass ?? "durable";
39669
+ }
39670
+ async function openChannelRegistry(nc, space, opts = {}) {
39671
+ const kvm = new import_kv7.Kvm(nc);
39672
+ return opts.create ? kvm.create(channelBucket(space)) : kvm.open(channelBucket(space));
39673
+ }
39674
+ async function readChannelConfig(kv, channel) {
39675
+ return decode2(kv, channel);
39676
+ }
39677
+ async function readChannelDefaults(kv) {
39678
+ return decode2(kv, CHANNEL_DEFAULTS_KEY);
39679
+ }
39680
+ async function decode2(kv, key) {
39681
+ const e = await kv.get(key);
39682
+ if (!e || e.operation === "DEL" || e.operation === "PURGE")
39683
+ return void 0;
39684
+ try {
39685
+ return e.json();
39686
+ } catch {
39687
+ return void 0;
39688
+ }
39689
+ }
39690
+
39691
+ // ../../packages/core/dist/membership-feed.js
39692
+ var import_transport_node16 = __toESM(require_transport_node(), 1);
39693
+ var import_kv8 = __toESM(require_mod6(), 1);
39694
+
39695
+ // ../../packages/core/dist/evict.js
39696
+ var import_transport_node17 = __toESM(require_transport_node(), 1);
39697
+
39698
+ // ../../packages/core/dist/agent-file.js
39699
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
39700
+ var import_yaml = __toESM(require_dist(), 1);
39701
+ function parseFrontmatter(src, path) {
39702
+ let doc;
39703
+ try {
39704
+ doc = (0, import_yaml.parse)(src);
39705
+ } catch (e) {
39706
+ throw new Error(`agent file ${path}: invalid YAML frontmatter; ${e.message}`);
39707
+ }
39708
+ if (doc === null || doc === void 0)
39709
+ return {};
39710
+ if (typeof doc !== "object" || Array.isArray(doc))
39711
+ throw new Error(`agent file ${path}: frontmatter must be a YAML mapping (key: value pairs)`);
39712
+ return doc;
39713
+ }
39714
+ function loadAgentFile(path) {
39715
+ const src = readFileSync(path, "utf8");
39716
+ const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(src);
39717
+ if (!m)
39718
+ throw new Error(`agent file ${path}: missing "---" frontmatter block`);
39719
+ const fm = parseFrontmatter(m[1], path);
39720
+ const persona = m[2].trim();
39721
+ const str2 = (k) => {
39722
+ const v = fm[k];
39723
+ if (v === void 0 || v === null)
39724
+ return void 0;
39725
+ if (typeof v === "object")
39726
+ throw new Error(`agent file ${path}: "${k}" must be a scalar`);
39727
+ return String(v);
39728
+ };
39729
+ const list = (k) => {
39730
+ const v = fm[k];
39731
+ if (v === void 0 || v === null)
39732
+ return void 0;
39733
+ return (Array.isArray(v) ? v : [v]).map((x) => {
39734
+ if (x === null || typeof x === "object")
39735
+ throw new Error(`agent file ${path}: "${k}" list items must be scalars`);
39736
+ return String(x);
39737
+ });
39738
+ };
39739
+ const name = str2("name");
39740
+ if (!name)
39741
+ throw new Error(`agent file ${path}: "name" is required`);
39742
+ assertValidName(name);
39743
+ const kind = str2("kind");
39744
+ if (kind && kind !== "agent" && kind !== "endpoint")
39745
+ throw new Error(`agent file ${path}: "kind" must be "agent" or "endpoint"`);
39746
+ for (const old of ["channels", "publish"])
39747
+ if (old in fm)
39748
+ throw new Error(`agent file ${path}: "${old}" was renamed - use "subscribe"/"allowSubscribe" (read) and "allowPublish" (post)`);
39749
+ const subscribe = list("subscribe");
39750
+ const allowSubscribe = list("allowSubscribe");
39751
+ const allowPublish = list("allowPublish");
39752
+ const quiet = list("quiet");
39753
+ const muted = list("muted");
39754
+ for (const ch of [...subscribe ?? [], ...allowSubscribe ?? [], ...allowPublish ?? []])
39755
+ try {
39756
+ assertValidChannel(ch);
39757
+ } catch (e) {
39758
+ throw new Error(`agent file ${path}: ${e.message}`);
39759
+ }
39760
+ const effSubscribe = subscribe ?? [];
39761
+ const effAllow = allowSubscribe?.length ? allowSubscribe : effSubscribe;
39762
+ for (const ch of effSubscribe)
39763
+ if (!channelInAllow(effAllow, ch))
39764
+ throw new Error(`agent file ${path}: subscribe channel "${ch}" is not within allowSubscribe [${effAllow.join(", ")}]`);
39765
+ const both = (quiet ?? []).filter((c) => (muted ?? []).includes(c));
39766
+ if (both.length)
39767
+ throw new Error(`agent file ${path}: channel(s) [${both.join(", ")}] are in both quiet and muted - pick one`);
39768
+ for (const [field, chans] of [["quiet", quiet], ["muted", muted]])
39769
+ for (const ch of chans ?? []) {
39770
+ try {
39771
+ assertValidChannel(ch);
39772
+ } catch (e) {
39773
+ throw new Error(`agent file ${path}: ${e.message}`);
39774
+ }
39775
+ if (!isConcreteChannel(ch))
39776
+ throw new Error(`agent file ${path}: ${field} channel "${ch}" must be a concrete channel (no wildcard)`);
39777
+ if (!channelInAllow(effAllow, ch))
39778
+ throw new Error(`agent file ${path}: ${field} channel "${ch}" is not within your read ACL / allowSubscribe [${effAllow.join(", ")}]`);
39779
+ }
39780
+ const launchOptionsRaw = fm["launchOptions"];
39781
+ let launchOptions;
39782
+ if (launchOptionsRaw !== void 0 && launchOptionsRaw !== null) {
39783
+ if (typeof launchOptionsRaw !== "object" || Array.isArray(launchOptionsRaw))
39784
+ throw new Error(`agent file ${path}: "launchOptions" must be a mapping of key: value pairs`);
39785
+ launchOptions = launchOptionsRaw;
39786
+ }
39787
+ const known = /* @__PURE__ */ new Set(["name", "role", "kind", "description", "tags", "subscribe", "allowSubscribe", "allowPublish", "quiet", "muted", "model", "variant", "launchOptions", "capabilities", "owner"]);
39788
+ const meta3 = {};
39789
+ for (const [k, v] of Object.entries(fm))
39790
+ if (!known.has(k) && v !== null && typeof v !== "object")
39791
+ meta3[k] = String(v);
39792
+ return {
39793
+ name,
39794
+ role: str2("role"),
39795
+ kind,
39796
+ description: str2("description"),
39797
+ tags: list("tags"),
39798
+ subscribe,
39799
+ allowSubscribe,
39800
+ allowPublish,
39801
+ quiet,
39802
+ muted,
39803
+ model: str2("model"),
39804
+ variant: str2("variant"),
39805
+ launchOptions,
39806
+ capabilities: list("capabilities"),
39807
+ owner: str2("owner"),
39808
+ meta: Object.keys(meta3).length ? meta3 : void 0,
39809
+ persona: persona || void 0
39810
+ };
39811
+ }
39812
+
39813
+ // ../../packages/core/dist/fs-safe.js
39814
+ import { lstatSync, mkdirSync as mkdirSync2, unlinkSync } from "node:fs";
39815
+ import { join } from "node:path";
39816
+ function ensureDirNoSymlink(parent, ...segments) {
39817
+ let dir = parent;
39818
+ for (const seg of segments) {
39819
+ dir = join(dir, seg);
39820
+ let st;
39821
+ try {
39822
+ st = lstatSync(dir);
39823
+ } catch (e) {
39824
+ if (e.code === "ENOENT") {
39825
+ mkdirSync2(dir, { mode: 448 });
39826
+ continue;
39827
+ }
39828
+ throw e;
39829
+ }
39830
+ if (st.isSymbolicLink())
39831
+ throw new Error(`refusing to write under "${dir}": it is a symlink`);
39832
+ if (!st.isDirectory())
39833
+ throw new Error(`refusing to write under "${dir}": not a directory`);
39834
+ }
39835
+ return dir;
39836
+ }
39837
+
39838
+ // ../../packages/core/dist/secret-fs.js
39839
+ var isWin = process.platform === "win32";
39840
+
39841
+ // ../../packages/core/dist/launch-material.js
39842
+ import { mkdtempSync, readFileSync as readFileSync2, realpathSync, rmSync, rmdirSync, statSync } from "node:fs";
39843
+ import { tmpdir } from "node:os";
39844
+ import { basename, dirname, join as join2, resolve } from "node:path";
39845
+ var DIR_PREFIX = "cotal-launch-";
39846
+ var MATERIAL_FILE = "material.json";
39847
+ var LAUNCH_MATERIAL_ENV = "COTAL_LAUNCH_MATERIAL";
39848
+ function readLaunchMaterial(path) {
39849
+ let raw;
39850
+ try {
39851
+ if (process.platform !== "win32") {
39852
+ const mode = statSync(path).mode & 511;
39853
+ if (mode & 63)
39854
+ throw new Error(`is readable beyond its owner (mode ${mode.toString(8)}) - refusing to read connection material out of a file other local users can open`);
39855
+ }
39856
+ raw = readFileSync2(path, "utf8");
39857
+ } catch (e) {
39858
+ throw new Error(`launch material: cannot read ${path} (${e instanceof Error ? e.message : String(e)})`);
39859
+ }
39860
+ let parsed;
39861
+ try {
39862
+ parsed = JSON.parse(raw);
39863
+ } catch {
39864
+ throw new Error(`launch material: ${path} is not valid JSON`);
39865
+ }
39866
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
39867
+ throw new Error(`launch material: ${path} must contain a JSON object`);
39868
+ return validate(parsed, path);
39869
+ }
39870
+ function validate(raw, path) {
39871
+ const material = {};
39872
+ const str2 = (key) => {
39873
+ const v = raw[key];
39874
+ if (v === void 0)
39875
+ return;
39876
+ if (typeof v !== "string" || !v.trim())
39877
+ throw new Error(`launch material: ${path} has a ${key} that is not a non-empty string`);
39878
+ material[key] = v;
39879
+ };
39880
+ str2("servers");
39881
+ str2("creds");
39882
+ str2("token");
39883
+ str2("controlToken");
39884
+ if (raw.userAuth !== void 0) {
39885
+ const u = raw.userAuth;
39886
+ if (typeof u !== "object" || u === null || Array.isArray(u))
39887
+ throw new Error(`launch material: ${path} has a userAuth that is not an object`);
39888
+ const { owner, actor, sentinelCredsPath, bearerCmd } = u;
39889
+ const named = { owner, actor, sentinelCredsPath };
39890
+ for (const [k, v] of Object.entries(named))
39891
+ if (typeof v !== "string" || !v.trim())
39892
+ throw new Error(`launch material: ${path} has a userAuth.${k} that is not a non-empty string`);
39893
+ if (!Array.isArray(bearerCmd) || bearerCmd.length === 0 || !bearerCmd.every((a) => typeof a === "string" && a))
39894
+ throw new Error(`launch material: ${path} has a userAuth.bearerCmd that is not a non-empty array of strings`);
39895
+ material.userAuth = {
39896
+ owner,
39897
+ actor,
39898
+ sentinelCredsPath,
39899
+ bearerCmd
39900
+ };
39901
+ }
39902
+ if (Object.keys(material).length === 0)
39903
+ throw new Error(`launch material: ${path} carries nothing this reader recognises. A launch that references material and supplies none is a broken launcher, not an open-mode launch, so it is refused rather than defaulted.`);
39904
+ return material;
39905
+ }
39906
+ function discardLaunchMaterial(path) {
39907
+ const file2 = resolve(path);
39908
+ try {
39909
+ rmSync(file2, { force: true });
39910
+ } catch {
39911
+ }
39912
+ const dir = dirname(file2);
39913
+ if (basename(file2) !== MATERIAL_FILE || !basename(dir).startsWith(DIR_PREFIX))
39914
+ return;
39915
+ try {
39916
+ if (realpathSync(dirname(dir)) !== realpathSync(tmpdir()))
39917
+ return;
39918
+ rmdirSync(dir);
39919
+ } catch {
39920
+ }
39921
+ }
39922
+
39912
39923
  // ../../packages/core/dist/spaces.js
39913
39924
  var import_transport_node18 = __toESM(require_transport_node(), 1);
39914
39925
  var import_jetstream15 = __toESM(require_mod4(), 1);
@@ -57607,7 +57618,7 @@ config(en_default());
57607
57618
 
57608
57619
  // ../connector-core/dist/docs-bundle.generated.js
57609
57620
  var DOCS_BUNDLE = {
57610
- "version": "0.28.0",
57621
+ "version": "0.28.2",
57611
57622
  "generatedFrom": "docs/*.md + SPEC.md + spec/cotal-lang.md + spec/cotal.schema.json",
57612
57623
  "pages": [
57613
57624
  {
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.28.0",
4
+ "version": "0.28.2",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
@@ -24,8 +24,8 @@
24
24
  "@opencode-ai/plugin": "^1.16.2",
25
25
  "esbuild": "^0.28.0",
26
26
  "tsx": "^4.22.4",
27
- "@cotal-ai/connector-core": "0.28.0",
28
- "@cotal-ai/core": "0.28.0",
27
+ "@cotal-ai/connector-core": "0.28.2",
28
+ "@cotal-ai/core": "0.28.2",
29
29
  "@cotal-ai/smoke-kit": "0.0.0"
30
30
  },
31
31
  "files": [