@cotal-ai/connector-hermes 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 +1 -1
- package/dist/launch.js +368 -357
- package/package.json +3 -3
- package/plugin/cotal/_sidecar/standalone.cjs +284 -273
package/dist/launch.js
CHANGED
|
@@ -13611,11 +13611,11 @@ var require_connect = __commonJS({
|
|
|
13611
13611
|
"../../node_modules/.pnpm/@nats-io+transport-node@3.4.0/node_modules/@nats-io/transport-node/lib/connect.js"(exports) {
|
|
13612
13612
|
"use strict";
|
|
13613
13613
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13614
|
-
exports.connect =
|
|
13614
|
+
exports.connect = connect7;
|
|
13615
13615
|
var node_transport_1 = require_node_transport();
|
|
13616
13616
|
var nats_base_client_1 = require_nats_base_client();
|
|
13617
13617
|
var nats_base_client_2 = require_nats_base_client();
|
|
13618
|
-
function
|
|
13618
|
+
function connect7(opts = {}) {
|
|
13619
13619
|
if ((0, nats_base_client_2.hasWsProtocol)(opts)) {
|
|
13620
13620
|
return Promise.reject(nats_base_client_2.errors.InvalidArgumentError.format(`servers`, `node client doesn't support websockets, use the 'wsconnect' function instead`));
|
|
13621
13621
|
}
|
|
@@ -35854,49 +35854,33 @@ var SYS_LIMITS = { ...BASE_LIMITS, mem_storage: 0, disk_storage: 0 };
|
|
|
35854
35854
|
var import_nkeys4 = __toESM(require_mod2(), 1);
|
|
35855
35855
|
|
|
35856
35856
|
// ../../packages/core/dist/channels.js
|
|
35857
|
-
var
|
|
35858
|
-
var
|
|
35859
|
-
|
|
35860
|
-
|
|
35861
|
-
|
|
35862
|
-
|
|
35863
|
-
|
|
35864
|
-
|
|
35865
|
-
|
|
35866
|
-
|
|
35867
|
-
|
|
35868
|
-
|
|
35869
|
-
|
|
35870
|
-
|
|
35871
|
-
|
|
35872
|
-
|
|
35873
|
-
|
|
35874
|
-
function effectiveDeliveryClass(cfg, defaults) {
|
|
35875
|
-
return cfg?.deliveryClass ?? defaults?.deliveryClass ?? "durable";
|
|
35876
|
-
}
|
|
35877
|
-
async function openChannelRegistry(nc, space, opts = {}) {
|
|
35878
|
-
const kvm = new import_kv4.Kvm(nc);
|
|
35879
|
-
return opts.create ? kvm.create(channelBucket(space)) : kvm.open(channelBucket(space));
|
|
35880
|
-
}
|
|
35881
|
-
async function readChannelConfig(kv, channel) {
|
|
35882
|
-
return decode2(kv, channel);
|
|
35883
|
-
}
|
|
35884
|
-
async function readChannelDefaults(kv) {
|
|
35885
|
-
return decode2(kv, CHANNEL_DEFAULTS_KEY);
|
|
35886
|
-
}
|
|
35887
|
-
async function decode2(kv, key) {
|
|
35888
|
-
const e = await kv.get(key);
|
|
35889
|
-
if (!e || e.operation === "DEL" || e.operation === "PURGE")
|
|
35890
|
-
return void 0;
|
|
35891
|
-
try {
|
|
35892
|
-
return e.json();
|
|
35893
|
-
} catch {
|
|
35894
|
-
return void 0;
|
|
35895
|
-
}
|
|
35857
|
+
var import_kv7 = __toESM(require_mod6(), 1);
|
|
35858
|
+
var import_transport_node15 = __toESM(require_transport_node(), 1);
|
|
35859
|
+
|
|
35860
|
+
// ../../packages/core/dist/endpoint.js
|
|
35861
|
+
var import_transport_node14 = __toESM(require_transport_node(), 1);
|
|
35862
|
+
var import_nats_core = __toESM(require_mod3(), 1);
|
|
35863
|
+
import { EventEmitter } from "node:events";
|
|
35864
|
+
import { randomUUID } from "node:crypto";
|
|
35865
|
+
import { createConnection } from "node:net";
|
|
35866
|
+
|
|
35867
|
+
// ../../packages/core/dist/artifact.js
|
|
35868
|
+
var ARTIFACT_PART_KIND = "artifact";
|
|
35869
|
+
function isArtifactPart(value) {
|
|
35870
|
+
if (!value || typeof value !== "object")
|
|
35871
|
+
return false;
|
|
35872
|
+
const p = value;
|
|
35873
|
+
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;
|
|
35896
35874
|
}
|
|
35897
35875
|
|
|
35876
|
+
// ../../packages/core/dist/endpoint.js
|
|
35877
|
+
var import_jetstream13 = __toESM(require_mod4(), 1);
|
|
35878
|
+
var import_jetstream14 = __toESM(require_mod4(), 1);
|
|
35879
|
+
var import_kv6 = __toESM(require_mod6(), 1);
|
|
35880
|
+
var import_internal2 = __toESM(require_internal_mod3(), 1);
|
|
35881
|
+
|
|
35898
35882
|
// ../../packages/core/dist/members.js
|
|
35899
|
-
var
|
|
35883
|
+
var import_kv4 = __toESM(require_mod6(), 1);
|
|
35900
35884
|
var StaleMembershipWrite = class extends Error {
|
|
35901
35885
|
constructor(channel, owner, attempted, current) {
|
|
35902
35886
|
super(`stale membership write for ${channel}/${owner}: generation ${attempted} < current ${current}`);
|
|
@@ -35904,7 +35888,7 @@ var StaleMembershipWrite = class extends Error {
|
|
|
35904
35888
|
}
|
|
35905
35889
|
};
|
|
35906
35890
|
async function openMembersRegistry(nc, space, opts = {}) {
|
|
35907
|
-
const kvm = new
|
|
35891
|
+
const kvm = new import_kv4.Kvm(nc);
|
|
35908
35892
|
return opts.create ? kvm.create(membersBucket(space)) : kvm.open(membersBucket(space));
|
|
35909
35893
|
}
|
|
35910
35894
|
async function readMember(kv, channel, owner, lifecycleUid) {
|
|
@@ -36004,305 +35988,14 @@ function durableEligible(rec, seq) {
|
|
|
36004
35988
|
return true;
|
|
36005
35989
|
}
|
|
36006
35990
|
|
|
36007
|
-
// ../../packages/core/dist/membership-feed.js
|
|
36008
|
-
var import_transport_node14 = __toESM(require_transport_node(), 1);
|
|
36009
|
-
var import_kv6 = __toESM(require_mod6(), 1);
|
|
36010
|
-
|
|
36011
|
-
// ../../packages/core/dist/evict.js
|
|
36012
|
-
var import_transport_node15 = __toESM(require_transport_node(), 1);
|
|
36013
|
-
|
|
36014
35991
|
// ../../packages/core/dist/lease.js
|
|
36015
|
-
var
|
|
36016
|
-
var
|
|
35992
|
+
var import_kv5 = __toESM(require_mod6(), 1);
|
|
35993
|
+
var import_transport_node13 = __toESM(require_transport_node(), 1);
|
|
36017
35994
|
async function openDeliveryRegistry(nc, space) {
|
|
36018
|
-
return new
|
|
36019
|
-
}
|
|
36020
|
-
|
|
36021
|
-
// ../../packages/core/dist/agent-file.js
|
|
36022
|
-
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
36023
|
-
var import_yaml = __toESM(require_dist(), 1);
|
|
36024
|
-
function parseFrontmatter(src, path) {
|
|
36025
|
-
let doc;
|
|
36026
|
-
try {
|
|
36027
|
-
doc = (0, import_yaml.parse)(src);
|
|
36028
|
-
} catch (e) {
|
|
36029
|
-
throw new Error(`agent file ${path}: invalid YAML frontmatter; ${e.message}`);
|
|
36030
|
-
}
|
|
36031
|
-
if (doc === null || doc === void 0)
|
|
36032
|
-
return {};
|
|
36033
|
-
if (typeof doc !== "object" || Array.isArray(doc))
|
|
36034
|
-
throw new Error(`agent file ${path}: frontmatter must be a YAML mapping (key: value pairs)`);
|
|
36035
|
-
return doc;
|
|
36036
|
-
}
|
|
36037
|
-
function loadAgentFile(path) {
|
|
36038
|
-
const src = readFileSync(path, "utf8");
|
|
36039
|
-
const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(src);
|
|
36040
|
-
if (!m)
|
|
36041
|
-
throw new Error(`agent file ${path}: missing "---" frontmatter block`);
|
|
36042
|
-
const fm = parseFrontmatter(m[1], path);
|
|
36043
|
-
const persona = m[2].trim();
|
|
36044
|
-
const str2 = (k) => {
|
|
36045
|
-
const v = fm[k];
|
|
36046
|
-
if (v === void 0 || v === null)
|
|
36047
|
-
return void 0;
|
|
36048
|
-
if (typeof v === "object")
|
|
36049
|
-
throw new Error(`agent file ${path}: "${k}" must be a scalar`);
|
|
36050
|
-
return String(v);
|
|
36051
|
-
};
|
|
36052
|
-
const list = (k) => {
|
|
36053
|
-
const v = fm[k];
|
|
36054
|
-
if (v === void 0 || v === null)
|
|
36055
|
-
return void 0;
|
|
36056
|
-
return (Array.isArray(v) ? v : [v]).map((x) => {
|
|
36057
|
-
if (x === null || typeof x === "object")
|
|
36058
|
-
throw new Error(`agent file ${path}: "${k}" list items must be scalars`);
|
|
36059
|
-
return String(x);
|
|
36060
|
-
});
|
|
36061
|
-
};
|
|
36062
|
-
const name = str2("name");
|
|
36063
|
-
if (!name)
|
|
36064
|
-
throw new Error(`agent file ${path}: "name" is required`);
|
|
36065
|
-
assertValidName(name);
|
|
36066
|
-
const kind = str2("kind");
|
|
36067
|
-
if (kind && kind !== "agent" && kind !== "endpoint")
|
|
36068
|
-
throw new Error(`agent file ${path}: "kind" must be "agent" or "endpoint"`);
|
|
36069
|
-
for (const old of ["channels", "publish"])
|
|
36070
|
-
if (old in fm)
|
|
36071
|
-
throw new Error(`agent file ${path}: "${old}" was renamed - use "subscribe"/"allowSubscribe" (read) and "allowPublish" (post)`);
|
|
36072
|
-
const subscribe = list("subscribe");
|
|
36073
|
-
const allowSubscribe = list("allowSubscribe");
|
|
36074
|
-
const allowPublish = list("allowPublish");
|
|
36075
|
-
const quiet = list("quiet");
|
|
36076
|
-
const muted = list("muted");
|
|
36077
|
-
for (const ch of [...subscribe ?? [], ...allowSubscribe ?? [], ...allowPublish ?? []])
|
|
36078
|
-
try {
|
|
36079
|
-
assertValidChannel(ch);
|
|
36080
|
-
} catch (e) {
|
|
36081
|
-
throw new Error(`agent file ${path}: ${e.message}`);
|
|
36082
|
-
}
|
|
36083
|
-
const effSubscribe = subscribe ?? [];
|
|
36084
|
-
const effAllow = allowSubscribe?.length ? allowSubscribe : effSubscribe;
|
|
36085
|
-
for (const ch of effSubscribe)
|
|
36086
|
-
if (!channelInAllow(effAllow, ch))
|
|
36087
|
-
throw new Error(`agent file ${path}: subscribe channel "${ch}" is not within allowSubscribe [${effAllow.join(", ")}]`);
|
|
36088
|
-
const both = (quiet ?? []).filter((c) => (muted ?? []).includes(c));
|
|
36089
|
-
if (both.length)
|
|
36090
|
-
throw new Error(`agent file ${path}: channel(s) [${both.join(", ")}] are in both quiet and muted - pick one`);
|
|
36091
|
-
for (const [field, chans] of [["quiet", quiet], ["muted", muted]])
|
|
36092
|
-
for (const ch of chans ?? []) {
|
|
36093
|
-
try {
|
|
36094
|
-
assertValidChannel(ch);
|
|
36095
|
-
} catch (e) {
|
|
36096
|
-
throw new Error(`agent file ${path}: ${e.message}`);
|
|
36097
|
-
}
|
|
36098
|
-
if (!isConcreteChannel(ch))
|
|
36099
|
-
throw new Error(`agent file ${path}: ${field} channel "${ch}" must be a concrete channel (no wildcard)`);
|
|
36100
|
-
if (!channelInAllow(effAllow, ch))
|
|
36101
|
-
throw new Error(`agent file ${path}: ${field} channel "${ch}" is not within your read ACL / allowSubscribe [${effAllow.join(", ")}]`);
|
|
36102
|
-
}
|
|
36103
|
-
const launchOptionsRaw = fm["launchOptions"];
|
|
36104
|
-
let launchOptions;
|
|
36105
|
-
if (launchOptionsRaw !== void 0 && launchOptionsRaw !== null) {
|
|
36106
|
-
if (typeof launchOptionsRaw !== "object" || Array.isArray(launchOptionsRaw))
|
|
36107
|
-
throw new Error(`agent file ${path}: "launchOptions" must be a mapping of key: value pairs`);
|
|
36108
|
-
launchOptions = launchOptionsRaw;
|
|
36109
|
-
}
|
|
36110
|
-
const known = /* @__PURE__ */ new Set(["name", "role", "kind", "description", "tags", "subscribe", "allowSubscribe", "allowPublish", "quiet", "muted", "model", "variant", "launchOptions", "capabilities", "owner"]);
|
|
36111
|
-
const meta3 = {};
|
|
36112
|
-
for (const [k, v] of Object.entries(fm))
|
|
36113
|
-
if (!known.has(k) && v !== null && typeof v !== "object")
|
|
36114
|
-
meta3[k] = String(v);
|
|
36115
|
-
return {
|
|
36116
|
-
name,
|
|
36117
|
-
role: str2("role"),
|
|
36118
|
-
kind,
|
|
36119
|
-
description: str2("description"),
|
|
36120
|
-
tags: list("tags"),
|
|
36121
|
-
subscribe,
|
|
36122
|
-
allowSubscribe,
|
|
36123
|
-
allowPublish,
|
|
36124
|
-
quiet,
|
|
36125
|
-
muted,
|
|
36126
|
-
model: str2("model"),
|
|
36127
|
-
variant: str2("variant"),
|
|
36128
|
-
launchOptions,
|
|
36129
|
-
capabilities: list("capabilities"),
|
|
36130
|
-
owner: str2("owner"),
|
|
36131
|
-
meta: Object.keys(meta3).length ? meta3 : void 0,
|
|
36132
|
-
persona: persona || void 0
|
|
36133
|
-
};
|
|
36134
|
-
}
|
|
36135
|
-
|
|
36136
|
-
// ../../packages/core/dist/secret-fs.js
|
|
36137
|
-
import { chmodSync, mkdirSync as mkdirSync2, renameSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
36138
|
-
import { execFileSync } from "node:child_process";
|
|
36139
|
-
import { join } from "node:path";
|
|
36140
|
-
var isWin = process.platform === "win32";
|
|
36141
|
-
function sys32(exe) {
|
|
36142
|
-
const root = process.env.SystemRoot || process.env.windir || "C:\\Windows";
|
|
36143
|
-
return join(root, "System32", exe);
|
|
36144
|
-
}
|
|
36145
|
-
var cachedSid;
|
|
36146
|
-
function ownerSid() {
|
|
36147
|
-
if (cachedSid)
|
|
36148
|
-
return cachedSid;
|
|
36149
|
-
const out = execFileSync(sys32("whoami.exe"), ["/user", "/fo", "csv", "/nh"], { encoding: "utf8" });
|
|
36150
|
-
const sid = out.trim().split(",").pop()?.replace(/^"|"$/g, "").trim();
|
|
36151
|
-
if (!sid || !/^S-1-/.test(sid))
|
|
36152
|
-
throw new Error(`could not determine the current user's SID from \`whoami\` (got: ${out.trim()})`);
|
|
36153
|
-
cachedSid = sid;
|
|
36154
|
-
return sid;
|
|
36155
|
-
}
|
|
36156
|
-
var BROAD_SIDS = ["S-1-1-0", "S-1-5-11", "S-1-5-32-545"];
|
|
36157
|
-
function hardenPrivate(path, kind) {
|
|
36158
|
-
if (!isWin) {
|
|
36159
|
-
chmodSync(path, kind === "dir" ? 448 : 384);
|
|
36160
|
-
return;
|
|
36161
|
-
}
|
|
36162
|
-
const perm = kind === "dir" ? "(OI)(CI)(F)" : "(F)";
|
|
36163
|
-
const removeBroad = BROAD_SIDS.flatMap((sid) => ["/remove:g", `*${sid}`]);
|
|
36164
|
-
const grant = (sid) => ["/grant:r", `*${sid}:${perm}`];
|
|
36165
|
-
try {
|
|
36166
|
-
execFileSync(sys32("icacls.exe"), [
|
|
36167
|
-
path,
|
|
36168
|
-
"/inheritance:r",
|
|
36169
|
-
...removeBroad,
|
|
36170
|
-
...grant(ownerSid()),
|
|
36171
|
-
...grant("S-1-5-18"),
|
|
36172
|
-
...grant("S-1-5-32-544")
|
|
36173
|
-
], { stdio: ["ignore", "ignore", "pipe"] });
|
|
36174
|
-
} catch (e) {
|
|
36175
|
-
throw new Error(`failed to harden ${kind} "${path}" to private via icacls: ${e.message.trim()}. Cotal will not leave a secret with a permissive ACL - ensure the path is on an NTFS volume and %SystemRoot%\\System32\\icacls.exe is available.`);
|
|
36176
|
-
}
|
|
36177
|
-
}
|
|
36178
|
-
function writeSecretFile(path, data) {
|
|
36179
|
-
writeFileSync2(path, data, { mode: 384 });
|
|
36180
|
-
if (!isWin)
|
|
36181
|
-
return;
|
|
36182
|
-
try {
|
|
36183
|
-
hardenPrivate(path, "file");
|
|
36184
|
-
} catch (e) {
|
|
36185
|
-
try {
|
|
36186
|
-
unlinkSync(path);
|
|
36187
|
-
} catch {
|
|
36188
|
-
}
|
|
36189
|
-
throw e;
|
|
36190
|
-
}
|
|
36191
|
-
}
|
|
36192
|
-
|
|
36193
|
-
// ../../packages/core/dist/launch-material.js
|
|
36194
|
-
import { mkdtempSync, readFileSync as readFileSync2, realpathSync, rmSync, rmdirSync, statSync } from "node:fs";
|
|
36195
|
-
import { tmpdir } from "node:os";
|
|
36196
|
-
import { basename, dirname, join as join2, resolve } from "node:path";
|
|
36197
|
-
var DIR_PREFIX = "cotal-launch-";
|
|
36198
|
-
var MATERIAL_FILE = "material.json";
|
|
36199
|
-
var LAUNCH_MATERIAL_ENV = "COTAL_LAUNCH_MATERIAL";
|
|
36200
|
-
function writeLaunchMaterial(material) {
|
|
36201
|
-
const present = Object.values(material).some((v) => v !== void 0);
|
|
36202
|
-
if (!present)
|
|
36203
|
-
throw new Error("launch material: refusing to write an empty material file - a launch with nothing to hand the session must not reference one at all");
|
|
36204
|
-
const dir = mkdtempSync(join2(tmpdir(), DIR_PREFIX));
|
|
36205
|
-
hardenPrivate(dir, "dir");
|
|
36206
|
-
const path = join2(dir, MATERIAL_FILE);
|
|
36207
|
-
writeSecretFile(path, JSON.stringify(material));
|
|
36208
|
-
return path;
|
|
36209
|
-
}
|
|
36210
|
-
function readLaunchMaterial(path) {
|
|
36211
|
-
let raw;
|
|
36212
|
-
try {
|
|
36213
|
-
if (process.platform !== "win32") {
|
|
36214
|
-
const mode = statSync(path).mode & 511;
|
|
36215
|
-
if (mode & 63)
|
|
36216
|
-
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`);
|
|
36217
|
-
}
|
|
36218
|
-
raw = readFileSync2(path, "utf8");
|
|
36219
|
-
} catch (e) {
|
|
36220
|
-
throw new Error(`launch material: cannot read ${path} (${e instanceof Error ? e.message : String(e)})`);
|
|
36221
|
-
}
|
|
36222
|
-
let parsed;
|
|
36223
|
-
try {
|
|
36224
|
-
parsed = JSON.parse(raw);
|
|
36225
|
-
} catch {
|
|
36226
|
-
throw new Error(`launch material: ${path} is not valid JSON`);
|
|
36227
|
-
}
|
|
36228
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
36229
|
-
throw new Error(`launch material: ${path} must contain a JSON object`);
|
|
36230
|
-
return validate(parsed, path);
|
|
36231
|
-
}
|
|
36232
|
-
function validate(raw, path) {
|
|
36233
|
-
const material = {};
|
|
36234
|
-
const str2 = (key) => {
|
|
36235
|
-
const v = raw[key];
|
|
36236
|
-
if (v === void 0)
|
|
36237
|
-
return;
|
|
36238
|
-
if (typeof v !== "string" || !v.trim())
|
|
36239
|
-
throw new Error(`launch material: ${path} has a ${key} that is not a non-empty string`);
|
|
36240
|
-
material[key] = v;
|
|
36241
|
-
};
|
|
36242
|
-
str2("servers");
|
|
36243
|
-
str2("creds");
|
|
36244
|
-
str2("token");
|
|
36245
|
-
str2("controlToken");
|
|
36246
|
-
if (raw.userAuth !== void 0) {
|
|
36247
|
-
const u = raw.userAuth;
|
|
36248
|
-
if (typeof u !== "object" || u === null || Array.isArray(u))
|
|
36249
|
-
throw new Error(`launch material: ${path} has a userAuth that is not an object`);
|
|
36250
|
-
const { owner, actor, sentinelCredsPath, bearerCmd } = u;
|
|
36251
|
-
const named = { owner, actor, sentinelCredsPath };
|
|
36252
|
-
for (const [k, v] of Object.entries(named))
|
|
36253
|
-
if (typeof v !== "string" || !v.trim())
|
|
36254
|
-
throw new Error(`launch material: ${path} has a userAuth.${k} that is not a non-empty string`);
|
|
36255
|
-
if (!Array.isArray(bearerCmd) || bearerCmd.length === 0 || !bearerCmd.every((a) => typeof a === "string" && a))
|
|
36256
|
-
throw new Error(`launch material: ${path} has a userAuth.bearerCmd that is not a non-empty array of strings`);
|
|
36257
|
-
material.userAuth = {
|
|
36258
|
-
owner,
|
|
36259
|
-
actor,
|
|
36260
|
-
sentinelCredsPath,
|
|
36261
|
-
bearerCmd
|
|
36262
|
-
};
|
|
36263
|
-
}
|
|
36264
|
-
if (Object.keys(material).length === 0)
|
|
36265
|
-
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.`);
|
|
36266
|
-
return material;
|
|
36267
|
-
}
|
|
36268
|
-
function discardLaunchMaterial(path) {
|
|
36269
|
-
const file2 = resolve(path);
|
|
36270
|
-
try {
|
|
36271
|
-
rmSync(file2, { force: true });
|
|
36272
|
-
} catch {
|
|
36273
|
-
}
|
|
36274
|
-
const dir = dirname(file2);
|
|
36275
|
-
if (basename(file2) !== MATERIAL_FILE || !basename(dir).startsWith(DIR_PREFIX))
|
|
36276
|
-
return;
|
|
36277
|
-
try {
|
|
36278
|
-
if (realpathSync(dirname(dir)) !== realpathSync(tmpdir()))
|
|
36279
|
-
return;
|
|
36280
|
-
rmdirSync(dir);
|
|
36281
|
-
} catch {
|
|
36282
|
-
}
|
|
36283
|
-
}
|
|
36284
|
-
|
|
36285
|
-
// ../../packages/core/dist/endpoint.js
|
|
36286
|
-
var import_transport_node17 = __toESM(require_transport_node(), 1);
|
|
36287
|
-
var import_nats_core = __toESM(require_mod3(), 1);
|
|
36288
|
-
import { EventEmitter } from "node:events";
|
|
36289
|
-
import { randomUUID } from "node:crypto";
|
|
36290
|
-
import { createConnection } from "node:net";
|
|
36291
|
-
|
|
36292
|
-
// ../../packages/core/dist/artifact.js
|
|
36293
|
-
var ARTIFACT_PART_KIND = "artifact";
|
|
36294
|
-
function isArtifactPart(value) {
|
|
36295
|
-
if (!value || typeof value !== "object")
|
|
36296
|
-
return false;
|
|
36297
|
-
const p = value;
|
|
36298
|
-
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;
|
|
35995
|
+
return new import_kv5.Kvm(nc).open(deliveryBucket(space));
|
|
36299
35996
|
}
|
|
36300
35997
|
|
|
36301
35998
|
// ../../packages/core/dist/endpoint.js
|
|
36302
|
-
var import_jetstream13 = __toESM(require_mod4(), 1);
|
|
36303
|
-
var import_jetstream14 = __toESM(require_mod4(), 1);
|
|
36304
|
-
var import_kv8 = __toESM(require_mod6(), 1);
|
|
36305
|
-
var import_internal2 = __toESM(require_internal_mod3(), 1);
|
|
36306
35999
|
var DEFAULT_SERVER = "nats://127.0.0.1:4222";
|
|
36307
36000
|
var PLANE3_FRAME_HEADER = "Cotal-Delivery-Frame";
|
|
36308
36001
|
var READER_MAX_REDELIVERIES = 10;
|
|
@@ -36816,7 +36509,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
36816
36509
|
this.watchStatus();
|
|
36817
36510
|
this.js = (0, import_jetstream13.jetstream)(this.nc);
|
|
36818
36511
|
if (this.doWatch || this.doRegister) {
|
|
36819
|
-
const kvm = new
|
|
36512
|
+
const kvm = new import_kv6.Kvm(this.nc);
|
|
36820
36513
|
this.kv = this.authed ? await kvm.open(presenceBucket(this.space)) : await kvm.create(presenceBucket(this.space), { ttl: this.ttlMs });
|
|
36821
36514
|
}
|
|
36822
36515
|
if (this.doWatch) {
|
|
@@ -37198,7 +36891,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
37198
36891
|
throw new Error(`expectedLastSubjectSeq must be a non-negative safe integer, got ${JSON.stringify(opts.expectedLastSubjectSeq)}`);
|
|
37199
36892
|
if (!Array.isArray(opts.parts) || opts.parts.length === 0)
|
|
37200
36893
|
throw new Error("encodedSize requires at least one part");
|
|
37201
|
-
const mh = (0,
|
|
36894
|
+
const mh = (0, import_transport_node14.headers)();
|
|
37202
36895
|
mh.set("Nats-Msg-Id", opts.id);
|
|
37203
36896
|
mh.set("Nats-Expected-Last-Subject-Sequence", `${opts.expectedLastSubjectSeq}`);
|
|
37204
36897
|
const headerBytes = mh.encode().length;
|
|
@@ -37704,7 +37397,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
37704
37397
|
async membershipFeedRegistry() {
|
|
37705
37398
|
if (!this.nc)
|
|
37706
37399
|
throw new Error("endpoint not started");
|
|
37707
|
-
this.membershipFeedKv ??= await new
|
|
37400
|
+
this.membershipFeedKv ??= await new import_kv6.Kvm(this.nc).open(membershipBucket(this.space));
|
|
37708
37401
|
return this.membershipFeedKv;
|
|
37709
37402
|
}
|
|
37710
37403
|
/**
|
|
@@ -38070,7 +37763,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
38070
37763
|
for await (const s of this.nc.status()) {
|
|
38071
37764
|
if (s.type !== "error")
|
|
38072
37765
|
continue;
|
|
38073
|
-
if (s.error instanceof
|
|
37766
|
+
if (s.error instanceof import_transport_node14.PermissionViolationError && this.confirmingChatSubs.has(s.error.subject))
|
|
38074
37767
|
continue;
|
|
38075
37768
|
this.emit("error", describeStatusError(s.error));
|
|
38076
37769
|
}
|
|
@@ -38293,7 +37986,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
38293
37986
|
throw new Error("endpoint not started");
|
|
38294
37987
|
if (this.managerLeaseKv)
|
|
38295
37988
|
return this.managerLeaseKv;
|
|
38296
|
-
const kvm = new
|
|
37989
|
+
const kvm = new import_kv6.Kvm((0, import_jetstream13.jetstream)(this.nc, { timeout: MANAGER_LEASE_ATTEMPT_MS }));
|
|
38297
37990
|
if (this.authed) {
|
|
38298
37991
|
this.managerLeaseKv = await kvm.open(managerBucket(this.space));
|
|
38299
37992
|
} else {
|
|
@@ -38523,7 +38216,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
38523
38216
|
filter_subject: subject,
|
|
38524
38217
|
ack_policy: import_jetstream13.AckPolicy.None,
|
|
38525
38218
|
mem_storage: true,
|
|
38526
|
-
inactive_threshold: (0,
|
|
38219
|
+
inactive_threshold: (0, import_transport_node14.nanos)(3e4),
|
|
38527
38220
|
deliver_policy: import_jetstream13.DeliverPolicy.StartSequence,
|
|
38528
38221
|
opt_start_seq: fromSeqExcl + 1
|
|
38529
38222
|
});
|
|
@@ -38985,7 +38678,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
38985
38678
|
channel: entry.channel,
|
|
38986
38679
|
msg: authenticatedChannelMessage(entry.msg, entry.channel)
|
|
38987
38680
|
};
|
|
38988
|
-
const frameHeaders = (0,
|
|
38681
|
+
const frameHeaders = (0, import_transport_node14.headers)();
|
|
38989
38682
|
frameHeaders.set(PLANE3_FRAME_HEADER, "1");
|
|
38990
38683
|
await this.js.publish(dlvSubject(this.space, pr.owner, pr.actor, pr.lifecycleUid), JSON.stringify(frame), {
|
|
38991
38684
|
msgID: `${entry.msg.id}:${owner}:${pr.lifecycleUid}:${entry.generation}`,
|
|
@@ -39115,7 +38808,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
39115
38808
|
* distinct from a responder that errored. nats.js surfaces it as NoRespondersError, or a RequestError
|
|
39116
38809
|
* whose `isNoResponders()` is true. */
|
|
39117
38810
|
isNoResponders(e) {
|
|
39118
|
-
return e instanceof
|
|
38811
|
+
return e instanceof import_transport_node14.NoRespondersError || e instanceof import_transport_node14.RequestError && e.isNoResponders();
|
|
39119
38812
|
}
|
|
39120
38813
|
/** Agent-side: this session's CURRENT durable memberships (channel + join generation) from the
|
|
39121
38814
|
* manager — the agent holds no read on the privileged members KV. `undefined` ⇒ NO control responder
|
|
@@ -39458,7 +39151,7 @@ var CotalEndpoint = class _CotalEndpoint extends EventEmitter {
|
|
|
39458
39151
|
filter_subject: subject,
|
|
39459
39152
|
ack_policy: import_jetstream13.AckPolicy.None,
|
|
39460
39153
|
mem_storage: true,
|
|
39461
|
-
inactive_threshold: (0,
|
|
39154
|
+
inactive_threshold: (0, import_transport_node14.nanos)(3e4),
|
|
39462
39155
|
..."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 }
|
|
39463
39156
|
});
|
|
39464
39157
|
try {
|
|
@@ -39819,7 +39512,7 @@ function authOpts(a) {
|
|
|
39819
39512
|
if (!a.sentinelCreds)
|
|
39820
39513
|
throw new Error("user-mode bearer requires sentinelCreds");
|
|
39821
39514
|
return {
|
|
39822
|
-
authenticator: [(0,
|
|
39515
|
+
authenticator: [(0, import_transport_node14.credsAuthenticator)(new TextEncoder().encode(a.sentinelCreds)), (0, import_transport_node14.tokenAuthenticator)(a.bearer)],
|
|
39823
39516
|
tls
|
|
39824
39517
|
};
|
|
39825
39518
|
}
|
|
@@ -39827,7 +39520,7 @@ function authOpts(a) {
|
|
|
39827
39520
|
if (a.token || a.user || a.pass)
|
|
39828
39521
|
throw new Error("creds are mutually exclusive with token/user/pass auth");
|
|
39829
39522
|
const creds = a.creds;
|
|
39830
|
-
const authenticator = typeof creds === "function" ? (nonce3) => (0,
|
|
39523
|
+
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));
|
|
39831
39524
|
return { authenticator, tls };
|
|
39832
39525
|
}
|
|
39833
39526
|
return { token: a.token, user: a.user, pass: a.pass, tls };
|
|
@@ -39862,25 +39555,32 @@ function decodeBearerPrincipal(bearer) {
|
|
|
39862
39555
|
return { owner, actor };
|
|
39863
39556
|
}
|
|
39864
39557
|
function describeStatusError(err2) {
|
|
39865
|
-
if (err2 instanceof
|
|
39558
|
+
if (err2 instanceof import_transport_node14.PermissionViolationError) {
|
|
39866
39559
|
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 });
|
|
39867
39560
|
}
|
|
39868
39561
|
return err2;
|
|
39869
39562
|
}
|
|
39870
39563
|
function isPermissionDenied(e) {
|
|
39871
|
-
if (e instanceof
|
|
39564
|
+
if (e instanceof import_transport_node14.PermissionViolationError)
|
|
39872
39565
|
return true;
|
|
39873
|
-
if (e?.cause instanceof
|
|
39566
|
+
if (e?.cause instanceof import_transport_node14.PermissionViolationError)
|
|
39874
39567
|
return true;
|
|
39875
39568
|
return /permissions?\s+violation/i.test(String(e?.message ?? ""));
|
|
39876
39569
|
}
|
|
39877
39570
|
function isPublishPermissionDenied(e) {
|
|
39878
|
-
const typed = e instanceof
|
|
39571
|
+
const typed = e instanceof import_transport_node14.PermissionViolationError ? e : e?.cause instanceof import_transport_node14.PermissionViolationError ? e.cause : void 0;
|
|
39879
39572
|
return typed?.operation === "publish";
|
|
39880
39573
|
}
|
|
39574
|
+
function wsServers(servers) {
|
|
39575
|
+
return /^wss?:\/\//i.test((servers.split(",")[0] ?? "").trim());
|
|
39576
|
+
}
|
|
39881
39577
|
function dialerFor(servers) {
|
|
39882
|
-
|
|
39883
|
-
|
|
39578
|
+
if (!wsServers(servers))
|
|
39579
|
+
return import_transport_node14.connect;
|
|
39580
|
+
return ((opts) => {
|
|
39581
|
+
const { tls: _tls, ...rest } = opts ?? {};
|
|
39582
|
+
return (0, import_nats_core.wsconnect)(rest);
|
|
39583
|
+
});
|
|
39884
39584
|
}
|
|
39885
39585
|
function hostPort(server) {
|
|
39886
39586
|
const raw = (server.split(",")[0] ?? "").trim();
|
|
@@ -39945,13 +39645,324 @@ function classifyProbeFailure(e, opts) {
|
|
|
39945
39645
|
} catch {
|
|
39946
39646
|
}
|
|
39947
39647
|
}
|
|
39948
|
-
if (e instanceof
|
|
39648
|
+
if (e instanceof import_transport_node14.UserAuthenticationExpiredError)
|
|
39949
39649
|
return { ok: false, reason: "stale-auth" };
|
|
39950
|
-
if (e instanceof
|
|
39650
|
+
if (e instanceof import_transport_node14.AuthorizationError)
|
|
39951
39651
|
return { ok: false, reason: "auth-required" };
|
|
39952
39652
|
return { ok: false, reason: "unreachable" };
|
|
39953
39653
|
}
|
|
39954
39654
|
|
|
39655
|
+
// ../../packages/core/dist/channels.js
|
|
39656
|
+
function parseDuration(s) {
|
|
39657
|
+
const m = /^(\d+)(s|m|h|d)$/.exec(s.trim());
|
|
39658
|
+
if (!m)
|
|
39659
|
+
throw new Error(`invalid duration "${s}" - expected <number><s|m|h|d>, e.g. "24h"`);
|
|
39660
|
+
const n = Number(m[1]);
|
|
39661
|
+
const unit = { s: 1e3, m: 6e4, h: 36e5, d: 864e5 }[m[2]];
|
|
39662
|
+
return n * unit;
|
|
39663
|
+
}
|
|
39664
|
+
function effectiveReplay(cfg, defaults) {
|
|
39665
|
+
return cfg?.replay ?? defaults?.replay ?? true;
|
|
39666
|
+
}
|
|
39667
|
+
function effectiveReplayWindowMs(cfg, defaults) {
|
|
39668
|
+
const w = cfg?.replayWindow ?? defaults?.replayWindow;
|
|
39669
|
+
return w === void 0 ? void 0 : parseDuration(w);
|
|
39670
|
+
}
|
|
39671
|
+
function effectiveDeliveryClass(cfg, defaults) {
|
|
39672
|
+
return cfg?.deliveryClass ?? defaults?.deliveryClass ?? "durable";
|
|
39673
|
+
}
|
|
39674
|
+
async function openChannelRegistry(nc, space, opts = {}) {
|
|
39675
|
+
const kvm = new import_kv7.Kvm(nc);
|
|
39676
|
+
return opts.create ? kvm.create(channelBucket(space)) : kvm.open(channelBucket(space));
|
|
39677
|
+
}
|
|
39678
|
+
async function readChannelConfig(kv, channel) {
|
|
39679
|
+
return decode2(kv, channel);
|
|
39680
|
+
}
|
|
39681
|
+
async function readChannelDefaults(kv) {
|
|
39682
|
+
return decode2(kv, CHANNEL_DEFAULTS_KEY);
|
|
39683
|
+
}
|
|
39684
|
+
async function decode2(kv, key) {
|
|
39685
|
+
const e = await kv.get(key);
|
|
39686
|
+
if (!e || e.operation === "DEL" || e.operation === "PURGE")
|
|
39687
|
+
return void 0;
|
|
39688
|
+
try {
|
|
39689
|
+
return e.json();
|
|
39690
|
+
} catch {
|
|
39691
|
+
return void 0;
|
|
39692
|
+
}
|
|
39693
|
+
}
|
|
39694
|
+
|
|
39695
|
+
// ../../packages/core/dist/membership-feed.js
|
|
39696
|
+
var import_transport_node16 = __toESM(require_transport_node(), 1);
|
|
39697
|
+
var import_kv8 = __toESM(require_mod6(), 1);
|
|
39698
|
+
|
|
39699
|
+
// ../../packages/core/dist/evict.js
|
|
39700
|
+
var import_transport_node17 = __toESM(require_transport_node(), 1);
|
|
39701
|
+
|
|
39702
|
+
// ../../packages/core/dist/agent-file.js
|
|
39703
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
39704
|
+
var import_yaml = __toESM(require_dist(), 1);
|
|
39705
|
+
function parseFrontmatter(src, path) {
|
|
39706
|
+
let doc;
|
|
39707
|
+
try {
|
|
39708
|
+
doc = (0, import_yaml.parse)(src);
|
|
39709
|
+
} catch (e) {
|
|
39710
|
+
throw new Error(`agent file ${path}: invalid YAML frontmatter; ${e.message}`);
|
|
39711
|
+
}
|
|
39712
|
+
if (doc === null || doc === void 0)
|
|
39713
|
+
return {};
|
|
39714
|
+
if (typeof doc !== "object" || Array.isArray(doc))
|
|
39715
|
+
throw new Error(`agent file ${path}: frontmatter must be a YAML mapping (key: value pairs)`);
|
|
39716
|
+
return doc;
|
|
39717
|
+
}
|
|
39718
|
+
function loadAgentFile(path) {
|
|
39719
|
+
const src = readFileSync(path, "utf8");
|
|
39720
|
+
const m = /^---\n([\s\S]*?)\n---\n?([\s\S]*)$/.exec(src);
|
|
39721
|
+
if (!m)
|
|
39722
|
+
throw new Error(`agent file ${path}: missing "---" frontmatter block`);
|
|
39723
|
+
const fm = parseFrontmatter(m[1], path);
|
|
39724
|
+
const persona = m[2].trim();
|
|
39725
|
+
const str2 = (k) => {
|
|
39726
|
+
const v = fm[k];
|
|
39727
|
+
if (v === void 0 || v === null)
|
|
39728
|
+
return void 0;
|
|
39729
|
+
if (typeof v === "object")
|
|
39730
|
+
throw new Error(`agent file ${path}: "${k}" must be a scalar`);
|
|
39731
|
+
return String(v);
|
|
39732
|
+
};
|
|
39733
|
+
const list = (k) => {
|
|
39734
|
+
const v = fm[k];
|
|
39735
|
+
if (v === void 0 || v === null)
|
|
39736
|
+
return void 0;
|
|
39737
|
+
return (Array.isArray(v) ? v : [v]).map((x) => {
|
|
39738
|
+
if (x === null || typeof x === "object")
|
|
39739
|
+
throw new Error(`agent file ${path}: "${k}" list items must be scalars`);
|
|
39740
|
+
return String(x);
|
|
39741
|
+
});
|
|
39742
|
+
};
|
|
39743
|
+
const name = str2("name");
|
|
39744
|
+
if (!name)
|
|
39745
|
+
throw new Error(`agent file ${path}: "name" is required`);
|
|
39746
|
+
assertValidName(name);
|
|
39747
|
+
const kind = str2("kind");
|
|
39748
|
+
if (kind && kind !== "agent" && kind !== "endpoint")
|
|
39749
|
+
throw new Error(`agent file ${path}: "kind" must be "agent" or "endpoint"`);
|
|
39750
|
+
for (const old of ["channels", "publish"])
|
|
39751
|
+
if (old in fm)
|
|
39752
|
+
throw new Error(`agent file ${path}: "${old}" was renamed - use "subscribe"/"allowSubscribe" (read) and "allowPublish" (post)`);
|
|
39753
|
+
const subscribe = list("subscribe");
|
|
39754
|
+
const allowSubscribe = list("allowSubscribe");
|
|
39755
|
+
const allowPublish = list("allowPublish");
|
|
39756
|
+
const quiet = list("quiet");
|
|
39757
|
+
const muted = list("muted");
|
|
39758
|
+
for (const ch of [...subscribe ?? [], ...allowSubscribe ?? [], ...allowPublish ?? []])
|
|
39759
|
+
try {
|
|
39760
|
+
assertValidChannel(ch);
|
|
39761
|
+
} catch (e) {
|
|
39762
|
+
throw new Error(`agent file ${path}: ${e.message}`);
|
|
39763
|
+
}
|
|
39764
|
+
const effSubscribe = subscribe ?? [];
|
|
39765
|
+
const effAllow = allowSubscribe?.length ? allowSubscribe : effSubscribe;
|
|
39766
|
+
for (const ch of effSubscribe)
|
|
39767
|
+
if (!channelInAllow(effAllow, ch))
|
|
39768
|
+
throw new Error(`agent file ${path}: subscribe channel "${ch}" is not within allowSubscribe [${effAllow.join(", ")}]`);
|
|
39769
|
+
const both = (quiet ?? []).filter((c) => (muted ?? []).includes(c));
|
|
39770
|
+
if (both.length)
|
|
39771
|
+
throw new Error(`agent file ${path}: channel(s) [${both.join(", ")}] are in both quiet and muted - pick one`);
|
|
39772
|
+
for (const [field, chans] of [["quiet", quiet], ["muted", muted]])
|
|
39773
|
+
for (const ch of chans ?? []) {
|
|
39774
|
+
try {
|
|
39775
|
+
assertValidChannel(ch);
|
|
39776
|
+
} catch (e) {
|
|
39777
|
+
throw new Error(`agent file ${path}: ${e.message}`);
|
|
39778
|
+
}
|
|
39779
|
+
if (!isConcreteChannel(ch))
|
|
39780
|
+
throw new Error(`agent file ${path}: ${field} channel "${ch}" must be a concrete channel (no wildcard)`);
|
|
39781
|
+
if (!channelInAllow(effAllow, ch))
|
|
39782
|
+
throw new Error(`agent file ${path}: ${field} channel "${ch}" is not within your read ACL / allowSubscribe [${effAllow.join(", ")}]`);
|
|
39783
|
+
}
|
|
39784
|
+
const launchOptionsRaw = fm["launchOptions"];
|
|
39785
|
+
let launchOptions;
|
|
39786
|
+
if (launchOptionsRaw !== void 0 && launchOptionsRaw !== null) {
|
|
39787
|
+
if (typeof launchOptionsRaw !== "object" || Array.isArray(launchOptionsRaw))
|
|
39788
|
+
throw new Error(`agent file ${path}: "launchOptions" must be a mapping of key: value pairs`);
|
|
39789
|
+
launchOptions = launchOptionsRaw;
|
|
39790
|
+
}
|
|
39791
|
+
const known = /* @__PURE__ */ new Set(["name", "role", "kind", "description", "tags", "subscribe", "allowSubscribe", "allowPublish", "quiet", "muted", "model", "variant", "launchOptions", "capabilities", "owner"]);
|
|
39792
|
+
const meta3 = {};
|
|
39793
|
+
for (const [k, v] of Object.entries(fm))
|
|
39794
|
+
if (!known.has(k) && v !== null && typeof v !== "object")
|
|
39795
|
+
meta3[k] = String(v);
|
|
39796
|
+
return {
|
|
39797
|
+
name,
|
|
39798
|
+
role: str2("role"),
|
|
39799
|
+
kind,
|
|
39800
|
+
description: str2("description"),
|
|
39801
|
+
tags: list("tags"),
|
|
39802
|
+
subscribe,
|
|
39803
|
+
allowSubscribe,
|
|
39804
|
+
allowPublish,
|
|
39805
|
+
quiet,
|
|
39806
|
+
muted,
|
|
39807
|
+
model: str2("model"),
|
|
39808
|
+
variant: str2("variant"),
|
|
39809
|
+
launchOptions,
|
|
39810
|
+
capabilities: list("capabilities"),
|
|
39811
|
+
owner: str2("owner"),
|
|
39812
|
+
meta: Object.keys(meta3).length ? meta3 : void 0,
|
|
39813
|
+
persona: persona || void 0
|
|
39814
|
+
};
|
|
39815
|
+
}
|
|
39816
|
+
|
|
39817
|
+
// ../../packages/core/dist/secret-fs.js
|
|
39818
|
+
import { chmodSync, mkdirSync as mkdirSync2, renameSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
39819
|
+
import { execFileSync } from "node:child_process";
|
|
39820
|
+
import { join } from "node:path";
|
|
39821
|
+
var isWin = process.platform === "win32";
|
|
39822
|
+
function sys32(exe) {
|
|
39823
|
+
const root = process.env.SystemRoot || process.env.windir || "C:\\Windows";
|
|
39824
|
+
return join(root, "System32", exe);
|
|
39825
|
+
}
|
|
39826
|
+
var cachedSid;
|
|
39827
|
+
function ownerSid() {
|
|
39828
|
+
if (cachedSid)
|
|
39829
|
+
return cachedSid;
|
|
39830
|
+
const out = execFileSync(sys32("whoami.exe"), ["/user", "/fo", "csv", "/nh"], { encoding: "utf8" });
|
|
39831
|
+
const sid = out.trim().split(",").pop()?.replace(/^"|"$/g, "").trim();
|
|
39832
|
+
if (!sid || !/^S-1-/.test(sid))
|
|
39833
|
+
throw new Error(`could not determine the current user's SID from \`whoami\` (got: ${out.trim()})`);
|
|
39834
|
+
cachedSid = sid;
|
|
39835
|
+
return sid;
|
|
39836
|
+
}
|
|
39837
|
+
var BROAD_SIDS = ["S-1-1-0", "S-1-5-11", "S-1-5-32-545"];
|
|
39838
|
+
function hardenPrivate(path, kind) {
|
|
39839
|
+
if (!isWin) {
|
|
39840
|
+
chmodSync(path, kind === "dir" ? 448 : 384);
|
|
39841
|
+
return;
|
|
39842
|
+
}
|
|
39843
|
+
const perm = kind === "dir" ? "(OI)(CI)(F)" : "(F)";
|
|
39844
|
+
const removeBroad = BROAD_SIDS.flatMap((sid) => ["/remove:g", `*${sid}`]);
|
|
39845
|
+
const grant = (sid) => ["/grant:r", `*${sid}:${perm}`];
|
|
39846
|
+
try {
|
|
39847
|
+
execFileSync(sys32("icacls.exe"), [
|
|
39848
|
+
path,
|
|
39849
|
+
"/inheritance:r",
|
|
39850
|
+
...removeBroad,
|
|
39851
|
+
...grant(ownerSid()),
|
|
39852
|
+
...grant("S-1-5-18"),
|
|
39853
|
+
...grant("S-1-5-32-544")
|
|
39854
|
+
], { stdio: ["ignore", "ignore", "pipe"] });
|
|
39855
|
+
} catch (e) {
|
|
39856
|
+
throw new Error(`failed to harden ${kind} "${path}" to private via icacls: ${e.message.trim()}. Cotal will not leave a secret with a permissive ACL - ensure the path is on an NTFS volume and %SystemRoot%\\System32\\icacls.exe is available.`);
|
|
39857
|
+
}
|
|
39858
|
+
}
|
|
39859
|
+
function writeSecretFile(path, data) {
|
|
39860
|
+
writeFileSync2(path, data, { mode: 384 });
|
|
39861
|
+
if (!isWin)
|
|
39862
|
+
return;
|
|
39863
|
+
try {
|
|
39864
|
+
hardenPrivate(path, "file");
|
|
39865
|
+
} catch (e) {
|
|
39866
|
+
try {
|
|
39867
|
+
unlinkSync(path);
|
|
39868
|
+
} catch {
|
|
39869
|
+
}
|
|
39870
|
+
throw e;
|
|
39871
|
+
}
|
|
39872
|
+
}
|
|
39873
|
+
|
|
39874
|
+
// ../../packages/core/dist/launch-material.js
|
|
39875
|
+
import { mkdtempSync, readFileSync as readFileSync2, realpathSync, rmSync, rmdirSync, statSync } from "node:fs";
|
|
39876
|
+
import { tmpdir } from "node:os";
|
|
39877
|
+
import { basename, dirname, join as join2, resolve } from "node:path";
|
|
39878
|
+
var DIR_PREFIX = "cotal-launch-";
|
|
39879
|
+
var MATERIAL_FILE = "material.json";
|
|
39880
|
+
var LAUNCH_MATERIAL_ENV = "COTAL_LAUNCH_MATERIAL";
|
|
39881
|
+
function writeLaunchMaterial(material) {
|
|
39882
|
+
const present = Object.values(material).some((v) => v !== void 0);
|
|
39883
|
+
if (!present)
|
|
39884
|
+
throw new Error("launch material: refusing to write an empty material file - a launch with nothing to hand the session must not reference one at all");
|
|
39885
|
+
const dir = mkdtempSync(join2(tmpdir(), DIR_PREFIX));
|
|
39886
|
+
hardenPrivate(dir, "dir");
|
|
39887
|
+
const path = join2(dir, MATERIAL_FILE);
|
|
39888
|
+
writeSecretFile(path, JSON.stringify(material));
|
|
39889
|
+
return path;
|
|
39890
|
+
}
|
|
39891
|
+
function readLaunchMaterial(path) {
|
|
39892
|
+
let raw;
|
|
39893
|
+
try {
|
|
39894
|
+
if (process.platform !== "win32") {
|
|
39895
|
+
const mode = statSync(path).mode & 511;
|
|
39896
|
+
if (mode & 63)
|
|
39897
|
+
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`);
|
|
39898
|
+
}
|
|
39899
|
+
raw = readFileSync2(path, "utf8");
|
|
39900
|
+
} catch (e) {
|
|
39901
|
+
throw new Error(`launch material: cannot read ${path} (${e instanceof Error ? e.message : String(e)})`);
|
|
39902
|
+
}
|
|
39903
|
+
let parsed;
|
|
39904
|
+
try {
|
|
39905
|
+
parsed = JSON.parse(raw);
|
|
39906
|
+
} catch {
|
|
39907
|
+
throw new Error(`launch material: ${path} is not valid JSON`);
|
|
39908
|
+
}
|
|
39909
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
39910
|
+
throw new Error(`launch material: ${path} must contain a JSON object`);
|
|
39911
|
+
return validate(parsed, path);
|
|
39912
|
+
}
|
|
39913
|
+
function validate(raw, path) {
|
|
39914
|
+
const material = {};
|
|
39915
|
+
const str2 = (key) => {
|
|
39916
|
+
const v = raw[key];
|
|
39917
|
+
if (v === void 0)
|
|
39918
|
+
return;
|
|
39919
|
+
if (typeof v !== "string" || !v.trim())
|
|
39920
|
+
throw new Error(`launch material: ${path} has a ${key} that is not a non-empty string`);
|
|
39921
|
+
material[key] = v;
|
|
39922
|
+
};
|
|
39923
|
+
str2("servers");
|
|
39924
|
+
str2("creds");
|
|
39925
|
+
str2("token");
|
|
39926
|
+
str2("controlToken");
|
|
39927
|
+
if (raw.userAuth !== void 0) {
|
|
39928
|
+
const u = raw.userAuth;
|
|
39929
|
+
if (typeof u !== "object" || u === null || Array.isArray(u))
|
|
39930
|
+
throw new Error(`launch material: ${path} has a userAuth that is not an object`);
|
|
39931
|
+
const { owner, actor, sentinelCredsPath, bearerCmd } = u;
|
|
39932
|
+
const named = { owner, actor, sentinelCredsPath };
|
|
39933
|
+
for (const [k, v] of Object.entries(named))
|
|
39934
|
+
if (typeof v !== "string" || !v.trim())
|
|
39935
|
+
throw new Error(`launch material: ${path} has a userAuth.${k} that is not a non-empty string`);
|
|
39936
|
+
if (!Array.isArray(bearerCmd) || bearerCmd.length === 0 || !bearerCmd.every((a) => typeof a === "string" && a))
|
|
39937
|
+
throw new Error(`launch material: ${path} has a userAuth.bearerCmd that is not a non-empty array of strings`);
|
|
39938
|
+
material.userAuth = {
|
|
39939
|
+
owner,
|
|
39940
|
+
actor,
|
|
39941
|
+
sentinelCredsPath,
|
|
39942
|
+
bearerCmd
|
|
39943
|
+
};
|
|
39944
|
+
}
|
|
39945
|
+
if (Object.keys(material).length === 0)
|
|
39946
|
+
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.`);
|
|
39947
|
+
return material;
|
|
39948
|
+
}
|
|
39949
|
+
function discardLaunchMaterial(path) {
|
|
39950
|
+
const file2 = resolve(path);
|
|
39951
|
+
try {
|
|
39952
|
+
rmSync(file2, { force: true });
|
|
39953
|
+
} catch {
|
|
39954
|
+
}
|
|
39955
|
+
const dir = dirname(file2);
|
|
39956
|
+
if (basename(file2) !== MATERIAL_FILE || !basename(dir).startsWith(DIR_PREFIX))
|
|
39957
|
+
return;
|
|
39958
|
+
try {
|
|
39959
|
+
if (realpathSync(dirname(dir)) !== realpathSync(tmpdir()))
|
|
39960
|
+
return;
|
|
39961
|
+
rmdirSync(dir);
|
|
39962
|
+
} catch {
|
|
39963
|
+
}
|
|
39964
|
+
}
|
|
39965
|
+
|
|
39955
39966
|
// ../../packages/core/dist/spaces.js
|
|
39956
39967
|
var import_transport_node18 = __toESM(require_transport_node(), 1);
|
|
39957
39968
|
var import_jetstream15 = __toESM(require_mod4(), 1);
|
|
@@ -55862,7 +55873,7 @@ config(en_default());
|
|
|
55862
55873
|
|
|
55863
55874
|
// ../connector-core/dist/docs-bundle.generated.js
|
|
55864
55875
|
var DOCS_BUNDLE = {
|
|
55865
|
-
"version": "0.28.
|
|
55876
|
+
"version": "0.28.2",
|
|
55866
55877
|
"generatedFrom": "docs/*.md + SPEC.md + spec/cotal-lang.md + spec/cotal.schema.json",
|
|
55867
55878
|
"pages": [
|
|
55868
55879
|
{
|