@cotal-ai/connector-opencode 0.28.0-hack-20260823234508 → 0.28.1
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 +1 -1
- package/dist/plugin.bundle.js +334 -321
- package/package.json +5 -5
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.
|
|
14834
|
+
"version": "0.28.1",
|
|
14835
14835
|
"generatedFrom": "docs/*.md + SPEC.md + spec/cotal-lang.md + spec/cotal.schema.json",
|
|
14836
14836
|
"pages": [
|
|
14837
14837
|
{
|
package/dist/plugin.bundle.js
CHANGED
|
@@ -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 = 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
|
|
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
|
|
35854
|
-
var
|
|
35855
|
-
|
|
35856
|
-
|
|
35857
|
-
|
|
35858
|
-
|
|
35859
|
-
|
|
35860
|
-
|
|
35861
|
-
|
|
35862
|
-
|
|
35863
|
-
|
|
35864
|
-
|
|
35865
|
-
|
|
35866
|
-
|
|
35867
|
-
|
|
35868
|
-
|
|
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
|
|
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
|
|
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
|
|
36012
|
-
var
|
|
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
|
|
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?.length ? subscribe : ["general"];
|
|
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
|
-
}
|
|
36240
|
-
}
|
|
36241
|
-
|
|
36242
|
-
// ../../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;
|
|
35991
|
+
return new import_kv5.Kvm(nc).open(deliveryBucket(space));
|
|
36256
35992
|
}
|
|
36257
35993
|
|
|
36258
35994
|
// ../../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;
|
|
@@ -36510,7 +36242,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
36510
36242
|
this.user = opts.user;
|
|
36511
36243
|
this.pass = opts.pass;
|
|
36512
36244
|
this.tls = opts.tls ?? false;
|
|
36513
|
-
this.channels = opts.channels ?? [
|
|
36245
|
+
this.channels = opts.channels ?? [];
|
|
36514
36246
|
this.heartbeatMs = opts.heartbeatMs ?? 2e3;
|
|
36515
36247
|
this.ttlMs = opts.ttlMs ?? 6e3;
|
|
36516
36248
|
this.doRegister = opts.registerPresence ?? true;
|
|
@@ -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
|
|
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) {
|
|
@@ -37037,7 +36769,9 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
37037
36769
|
// ---- messaging -----------------------------------------------------------
|
|
37038
36770
|
/** Multicast: broadcast to everyone on a channel. */
|
|
37039
36771
|
async multicast(text, opts) {
|
|
37040
|
-
const channel = opts?.channel ?? this.channels.find(isConcreteChannel)
|
|
36772
|
+
const channel = opts?.channel ?? this.channels.find(isConcreteChannel);
|
|
36773
|
+
if (!channel)
|
|
36774
|
+
throw new Error("send() needs a channel: this endpoint is on no concrete channel, so there is no default to fall back to - pass opts.channel");
|
|
37041
36775
|
if (!isConcreteChannel(channel))
|
|
37042
36776
|
throw new Error(`cannot publish to wildcard channel "${channel}" - pick a concrete sub-channel`);
|
|
37043
36777
|
const msg = {
|
|
@@ -37153,7 +36887,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
37153
36887
|
throw new Error(`expectedLastSubjectSeq must be a non-negative safe integer, got ${JSON.stringify(opts.expectedLastSubjectSeq)}`);
|
|
37154
36888
|
if (!Array.isArray(opts.parts) || opts.parts.length === 0)
|
|
37155
36889
|
throw new Error("encodedSize requires at least one part");
|
|
37156
|
-
const mh = (0,
|
|
36890
|
+
const mh = (0, import_transport_node14.headers)();
|
|
37157
36891
|
mh.set("Nats-Msg-Id", opts.id);
|
|
37158
36892
|
mh.set("Nats-Expected-Last-Subject-Sequence", `${opts.expectedLastSubjectSeq}`);
|
|
37159
36893
|
const headerBytes = mh.encode().length;
|
|
@@ -37659,7 +37393,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
37659
37393
|
async membershipFeedRegistry() {
|
|
37660
37394
|
if (!this.nc)
|
|
37661
37395
|
throw new Error("endpoint not started");
|
|
37662
|
-
this.membershipFeedKv ??= await new
|
|
37396
|
+
this.membershipFeedKv ??= await new import_kv6.Kvm(this.nc).open(membershipBucket(this.space));
|
|
37663
37397
|
return this.membershipFeedKv;
|
|
37664
37398
|
}
|
|
37665
37399
|
/**
|
|
@@ -38025,7 +37759,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
38025
37759
|
for await (const s of this.nc.status()) {
|
|
38026
37760
|
if (s.type !== "error")
|
|
38027
37761
|
continue;
|
|
38028
|
-
if (s.error instanceof
|
|
37762
|
+
if (s.error instanceof import_transport_node14.PermissionViolationError && this.confirmingChatSubs.has(s.error.subject))
|
|
38029
37763
|
continue;
|
|
38030
37764
|
this.emit("error", describeStatusError(s.error));
|
|
38031
37765
|
}
|
|
@@ -38248,7 +37982,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
38248
37982
|
throw new Error("endpoint not started");
|
|
38249
37983
|
if (this.managerLeaseKv)
|
|
38250
37984
|
return this.managerLeaseKv;
|
|
38251
|
-
const kvm = new
|
|
37985
|
+
const kvm = new import_kv6.Kvm((0, import_jetstream13.jetstream)(this.nc, { timeout: MANAGER_LEASE_ATTEMPT_MS }));
|
|
38252
37986
|
if (this.authed) {
|
|
38253
37987
|
this.managerLeaseKv = await kvm.open(managerBucket(this.space));
|
|
38254
37988
|
} else {
|
|
@@ -38478,7 +38212,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
38478
38212
|
filter_subject: subject,
|
|
38479
38213
|
ack_policy: import_jetstream13.AckPolicy.None,
|
|
38480
38214
|
mem_storage: true,
|
|
38481
|
-
inactive_threshold: (0,
|
|
38215
|
+
inactive_threshold: (0, import_transport_node14.nanos)(3e4),
|
|
38482
38216
|
deliver_policy: import_jetstream13.DeliverPolicy.StartSequence,
|
|
38483
38217
|
opt_start_seq: fromSeqExcl + 1
|
|
38484
38218
|
});
|
|
@@ -38940,7 +38674,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
38940
38674
|
channel: entry.channel,
|
|
38941
38675
|
msg: authenticatedChannelMessage(entry.msg, entry.channel)
|
|
38942
38676
|
};
|
|
38943
|
-
const frameHeaders = (0,
|
|
38677
|
+
const frameHeaders = (0, import_transport_node14.headers)();
|
|
38944
38678
|
frameHeaders.set(PLANE3_FRAME_HEADER, "1");
|
|
38945
38679
|
await this.js.publish(dlvSubject(this.space, pr.owner, pr.actor, pr.lifecycleUid), JSON.stringify(frame), {
|
|
38946
38680
|
msgID: `${entry.msg.id}:${owner}:${pr.lifecycleUid}:${entry.generation}`,
|
|
@@ -39070,7 +38804,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
39070
38804
|
* distinct from a responder that errored. nats.js surfaces it as NoRespondersError, or a RequestError
|
|
39071
38805
|
* whose `isNoResponders()` is true. */
|
|
39072
38806
|
isNoResponders(e) {
|
|
39073
|
-
return e instanceof
|
|
38807
|
+
return e instanceof import_transport_node14.NoRespondersError || e instanceof import_transport_node14.RequestError && e.isNoResponders();
|
|
39074
38808
|
}
|
|
39075
38809
|
/** Agent-side: this session's CURRENT durable memberships (channel + join generation) from the
|
|
39076
38810
|
* manager — the agent holds no read on the privileged members KV. `undefined` ⇒ NO control responder
|
|
@@ -39413,7 +39147,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
39413
39147
|
filter_subject: subject,
|
|
39414
39148
|
ack_policy: import_jetstream13.AckPolicy.None,
|
|
39415
39149
|
mem_storage: true,
|
|
39416
|
-
inactive_threshold: (0,
|
|
39150
|
+
inactive_threshold: (0, import_transport_node14.nanos)(3e4),
|
|
39417
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 }
|
|
39418
39152
|
});
|
|
39419
39153
|
try {
|
|
@@ -39774,7 +39508,7 @@ function authOpts(a) {
|
|
|
39774
39508
|
if (!a.sentinelCreds)
|
|
39775
39509
|
throw new Error("user-mode bearer requires sentinelCreds");
|
|
39776
39510
|
return {
|
|
39777
|
-
authenticator: [(0,
|
|
39511
|
+
authenticator: [(0, import_transport_node14.credsAuthenticator)(new TextEncoder().encode(a.sentinelCreds)), (0, import_transport_node14.tokenAuthenticator)(a.bearer)],
|
|
39778
39512
|
tls
|
|
39779
39513
|
};
|
|
39780
39514
|
}
|
|
@@ -39782,7 +39516,7 @@ function authOpts(a) {
|
|
|
39782
39516
|
if (a.token || a.user || a.pass)
|
|
39783
39517
|
throw new Error("creds are mutually exclusive with token/user/pass auth");
|
|
39784
39518
|
const creds = a.creds;
|
|
39785
|
-
const authenticator = typeof creds === "function" ? (nonce3) => (0,
|
|
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));
|
|
39786
39520
|
return { authenticator, tls };
|
|
39787
39521
|
}
|
|
39788
39522
|
return { token: a.token, user: a.user, pass: a.pass, tls };
|
|
@@ -39817,25 +39551,32 @@ function decodeBearerPrincipal(bearer) {
|
|
|
39817
39551
|
return { owner, actor };
|
|
39818
39552
|
}
|
|
39819
39553
|
function describeStatusError(err2) {
|
|
39820
|
-
if (err2 instanceof
|
|
39554
|
+
if (err2 instanceof import_transport_node14.PermissionViolationError) {
|
|
39821
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 });
|
|
39822
39556
|
}
|
|
39823
39557
|
return err2;
|
|
39824
39558
|
}
|
|
39825
39559
|
function isPermissionDenied(e) {
|
|
39826
|
-
if (e instanceof
|
|
39560
|
+
if (e instanceof import_transport_node14.PermissionViolationError)
|
|
39827
39561
|
return true;
|
|
39828
|
-
if (e?.cause instanceof
|
|
39562
|
+
if (e?.cause instanceof import_transport_node14.PermissionViolationError)
|
|
39829
39563
|
return true;
|
|
39830
39564
|
return /permissions?\s+violation/i.test(String(e?.message ?? ""));
|
|
39831
39565
|
}
|
|
39832
39566
|
function isPublishPermissionDenied(e) {
|
|
39833
|
-
const typed = e instanceof
|
|
39567
|
+
const typed = e instanceof import_transport_node14.PermissionViolationError ? e : e?.cause instanceof import_transport_node14.PermissionViolationError ? e.cause : void 0;
|
|
39834
39568
|
return typed?.operation === "publish";
|
|
39835
39569
|
}
|
|
39570
|
+
function wsServers(servers) {
|
|
39571
|
+
return /^wss?:\/\//i.test((servers.split(",")[0] ?? "").trim());
|
|
39572
|
+
}
|
|
39836
39573
|
function dialerFor(servers) {
|
|
39837
|
-
|
|
39838
|
-
|
|
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
|
+
});
|
|
39839
39580
|
}
|
|
39840
39581
|
function hostPort(server) {
|
|
39841
39582
|
const raw = (server.split(",")[0] ?? "").trim();
|
|
@@ -39900,13 +39641,285 @@ function classifyProbeFailure(e, opts) {
|
|
|
39900
39641
|
} catch {
|
|
39901
39642
|
}
|
|
39902
39643
|
}
|
|
39903
|
-
if (e instanceof
|
|
39644
|
+
if (e instanceof import_transport_node14.UserAuthenticationExpiredError)
|
|
39904
39645
|
return { ok: false, reason: "stale-auth" };
|
|
39905
|
-
if (e instanceof
|
|
39646
|
+
if (e instanceof import_transport_node14.AuthorizationError)
|
|
39906
39647
|
return { ok: false, reason: "auth-required" };
|
|
39907
39648
|
return { ok: false, reason: "unreachable" };
|
|
39908
39649
|
}
|
|
39909
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
|
+
|
|
39910
39923
|
// ../../packages/core/dist/spaces.js
|
|
39911
39924
|
var import_transport_node18 = __toESM(require_transport_node(), 1);
|
|
39912
39925
|
var import_jetstream15 = __toESM(require_mod4(), 1);
|
|
@@ -40113,7 +40126,7 @@ function configFromEnv(env = process.env) {
|
|
|
40113
40126
|
if (!name)
|
|
40114
40127
|
throw new Error("COTAL_NAME, COTAL_AGENT_FILE or COTAL_LINK is required \u2014 a Cotal session needs an explicit identity from its launcher");
|
|
40115
40128
|
const subscribe = splitList(env.COTAL_SUBSCRIBE);
|
|
40116
|
-
const resolvedSubscribe = subscribe.length ? subscribe : def?.subscribe ?? link?.channels ?? [
|
|
40129
|
+
const resolvedSubscribe = subscribe.length ? subscribe : def?.subscribe ?? link?.channels ?? [];
|
|
40117
40130
|
const allowSub = splitList(env.COTAL_ALLOW_SUBSCRIBE);
|
|
40118
40131
|
const resolvedAllowSub = allowSub.length ? allowSub : def?.allowSubscribe ?? resolvedSubscribe;
|
|
40119
40132
|
for (const ch of resolvedSubscribe)
|
|
@@ -57605,7 +57618,7 @@ config(en_default());
|
|
|
57605
57618
|
|
|
57606
57619
|
// ../connector-core/dist/docs-bundle.generated.js
|
|
57607
57620
|
var DOCS_BUNDLE = {
|
|
57608
|
-
"version": "0.
|
|
57621
|
+
"version": "0.28.1",
|
|
57609
57622
|
"generatedFrom": "docs/*.md + SPEC.md + spec/cotal-lang.md + spec/cotal.schema.json",
|
|
57610
57623
|
"pages": [
|
|
57611
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.
|
|
4
|
+
"version": "0.28.1",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
|
-
"@cotal-ai/core": "0.
|
|
21
|
+
"@cotal-ai/core": ">=0.1.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
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.
|
|
28
|
-
"@cotal-ai/
|
|
29
|
-
"@cotal-ai/
|
|
27
|
+
"@cotal-ai/connector-core": "0.28.1",
|
|
28
|
+
"@cotal-ai/core": "0.28.1",
|
|
29
|
+
"@cotal-ai/smoke-kit": "0.0.0"
|
|
30
30
|
},
|
|
31
31
|
"files": [
|
|
32
32
|
"dist"
|