@cotal-ai/core 0.3.2 → 0.5.0
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/README.md +11 -0
- package/dist/agent-file.d.ts +36 -5
- package/dist/agent-file.d.ts.map +1 -1
- package/dist/agent-file.js +91 -11
- package/dist/agent-file.js.map +1 -1
- package/dist/channels.d.ts +13 -2
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +24 -1
- package/dist/channels.js.map +1 -1
- package/dist/command.d.ts +21 -0
- package/dist/command.d.ts.map +1 -1
- package/dist/connector-config.d.ts +42 -0
- package/dist/connector-config.d.ts.map +1 -0
- package/dist/connector-config.js +103 -0
- package/dist/connector-config.js.map +1 -0
- package/dist/connector.d.ts +11 -0
- package/dist/connector.d.ts.map +1 -1
- package/dist/endpoint.d.ts +331 -40
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/endpoint.js +1280 -246
- package/dist/endpoint.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/members.d.ts +93 -0
- package/dist/members.d.ts.map +1 -0
- package/dist/members.js +193 -0
- package/dist/members.js.map +1 -0
- package/dist/provision.d.ts +49 -11
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +92 -31
- package/dist/provision.js.map +1 -1
- package/dist/resolve.d.ts +53 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +61 -0
- package/dist/resolve.js.map +1 -0
- package/dist/streams.d.ts +37 -0
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +91 -4
- package/dist/streams.js.map +1 -1
- package/dist/subjects.d.ts +80 -2
- package/dist/subjects.d.ts.map +1 -1
- package/dist/subjects.js +127 -3
- package/dist/subjects.js.map +1 -1
- package/dist/types.d.ts +111 -5
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -2
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @cotal-ai/core
|
|
2
|
+
|
|
3
|
+
The Cotal protocol: the endpoint, subjects, and message types, plus the NATS client layer and
|
|
4
|
+
the extension contracts (`Connector`, `Command`, `Runtime`) and the `Registry` they
|
|
5
|
+
self-register into.
|
|
6
|
+
|
|
7
|
+
**Tier:** `packages/` (the standard). Everything depends on core; core depends on nothing else
|
|
8
|
+
in the repo.
|
|
9
|
+
|
|
10
|
+
See the [root AGENTS.md](../../AGENTS.md) for the tier rules, [SPEC.md](../../SPEC.md) for the
|
|
11
|
+
normative wire contract, and [docs/](../../docs/) for the protocol.
|
package/dist/agent-file.d.ts
CHANGED
|
@@ -5,13 +5,39 @@ export interface AgentDef {
|
|
|
5
5
|
kind?: EndpointKind;
|
|
6
6
|
description?: string;
|
|
7
7
|
tags?: string[];
|
|
8
|
-
channels
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
/** The *active* read set: channels this agent subscribes to at boot (the live chat-durable
|
|
9
|
+
* filter; mutable at runtime via join/leave). Must be ⊆ {@link allowSubscribe}. Default `[general]`. */
|
|
10
|
+
subscribe?: string[];
|
|
11
|
+
/** The read **ACL**: channels this agent *may* read (auth mode → minted as per-channel
|
|
12
|
+
* history-consumer create grants; the live durable's filter is also held within it). Entries
|
|
13
|
+
* may be wildcard subtrees (`team.>`). Omitted ⇒ defaults to {@link subscribe} — it can read
|
|
14
|
+
* exactly what it subscribes to. */
|
|
15
|
+
allowSubscribe?: string[];
|
|
16
|
+
/** The post **ACL**: channels this agent may publish to (auth mode → minted into pub-allow
|
|
17
|
+
* ACLs). Entries may be wildcard subtrees (`team.>`). Omitted ⇒ **deny** (default-deny):
|
|
18
|
+
* publishing is the dangerous capability, so it must be declared explicitly. */
|
|
19
|
+
allowPublish?: string[];
|
|
20
|
+
/** Per-channel attention DEFAULT: channels delivered but never waking this agent — per-channel
|
|
21
|
+
* `dnd`. Concrete channels within the read ACL (`allowSubscribe`). One-way operator default; the runtime toggle is
|
|
22
|
+
* connector state, never written back here (the file is a shared template). */
|
|
23
|
+
quiet?: string[];
|
|
24
|
+
/** Per-channel attention DEFAULT: channels dropped on receive (incl. `@`-mentions) — "don't receive
|
|
25
|
+
* this channel". Same one-way default semantics as {@link quiet}. */
|
|
26
|
+
muted?: string[];
|
|
13
27
|
/** Model override handed to the agent CLI (e.g. `claude --model`). */
|
|
14
28
|
model?: string;
|
|
29
|
+
/** Capabilities this agent may exercise on the control plane (auth mode → minted into the
|
|
30
|
+
* cred's publish allow-list). Today `spawn` is the only one: it grants publish to the
|
|
31
|
+
* privileged control subject (start/purge/definePersona/named stop). Default-deny when
|
|
32
|
+
* absent — nats-server, not a handler, is the boundary. Granting authority is operator-level
|
|
33
|
+
* (`definePersona` is itself privileged), so no peer can self-grant via its own agent file. */
|
|
34
|
+
capabilities?: string[];
|
|
35
|
+
/** Authenticated id of the agent that first defined this persona via `definePersona` (P6). A
|
|
36
|
+
* POLICY field, not content: the privileged tier may *redefine* an existing file only if its
|
|
37
|
+
* `owner` equals the caller; everyone else needs the admin tier. Fail-closed — an ownerless
|
|
38
|
+
* file (legacy / operator-written) is admin-only, and a caller can never claim ownership of an
|
|
39
|
+
* existing file. Set once at creation (owner = creator), preserved on every later redefine. */
|
|
40
|
+
owner?: string;
|
|
15
41
|
/** Frontmatter keys not modelled above, kept verbatim so a connector can read its own launcher
|
|
16
42
|
* hints without core knowing about each one (e.g. the OpenCode face viewer's `face:` avatar id). */
|
|
17
43
|
meta?: Record<string, string>;
|
|
@@ -29,4 +55,9 @@ export declare function saveAgentFile(path: string, def: AgentDef): void;
|
|
|
29
55
|
* or ends in `.md`) is used as given; a bare name maps to the directory
|
|
30
56
|
* convention `<root>/.cotal/agents/<name>.md`. */
|
|
31
57
|
export declare function agentFilePath(root: string, nameOrPath: string): string;
|
|
58
|
+
/** First free name in the series `base`, `base-2`, `base-3`, … — the first candidate for which
|
|
59
|
+
* `taken` returns false. The single source of the spawn auto-numbering scheme, shared by the
|
|
60
|
+
* manager's funnel (checked against its live + reserved slots) and `cotal spawn` (checked against
|
|
61
|
+
* the live mesh roster), so a colliding name numbers up identically whichever path spawns it. */
|
|
62
|
+
export declare function firstFreeName(base: string, taken: (name: string) => boolean): string;
|
|
32
63
|
//# sourceMappingURL=agent-file.d.ts.map
|
package/dist/agent-file.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-file.d.ts","sourceRoot":"","sources":["../src/agent-file.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-file.d.ts","sourceRoot":"","sources":["../src/agent-file.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;6GACyG;IACzG,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB;;;yCAGqC;IACrC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;qFAEiF;IACjF,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;oFAEgF;IAChF,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;0EACsE;IACtE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;oGAIgG;IAChG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;oGAIgG;IAChG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;yGACqG;IACrG,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmCD,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAmGpD;AAED;;;8CAG8C;AAC9C,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,CAqB/D;AAmBD;;mDAEmD;AACnD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAItE;AAED;;;kGAGkG;AAClG,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAMpF"}
|
package/dist/agent-file.js
CHANGED
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* .cotal/agents/<name>.md
|
|
5
5
|
* ---
|
|
6
|
-
* name: builder
|
|
6
|
+
* name: builder # AgentCard-shaped identity in the frontmatter
|
|
7
7
|
* role: builder
|
|
8
8
|
* description: …
|
|
9
9
|
* tags: [edit, test]
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
10
|
+
* subscribe: [general] # channels this agent actively reads at boot (the live set)
|
|
11
|
+
* allowSubscribe: [general] # read ACL — channels it MAY read; omit ⇒ same as `subscribe`
|
|
12
|
+
* allowPublish: [general] # post ACL — channels it may publish to; omit ⇒ DENY (default-deny)
|
|
13
|
+
* model: opus # optional CLI/model override
|
|
14
|
+
* capabilities: [spawn] # control-plane capabilities (spawn → may start/despawn others)
|
|
13
15
|
* face: sven # any unmodelled key is kept verbatim in AgentDef.meta — e.g. the
|
|
14
16
|
* # OpenCode connector reads meta.face for its avatar viewer
|
|
15
17
|
* ---
|
|
@@ -22,6 +24,8 @@
|
|
|
22
24
|
*/
|
|
23
25
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
24
26
|
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
27
|
+
import { assertValidName } from "./resolve.js";
|
|
28
|
+
import { assertValidChannel, channelInAllow, isConcreteChannel } from "./subjects.js";
|
|
25
29
|
/** Strip wrapping quotes from a scalar value. */
|
|
26
30
|
function unquote(v) {
|
|
27
31
|
if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'")))
|
|
@@ -80,12 +84,59 @@ export function loadAgentFile(path) {
|
|
|
80
84
|
const name = str("name");
|
|
81
85
|
if (!name)
|
|
82
86
|
throw new Error(`agent file ${path}: "name" is required`);
|
|
87
|
+
assertValidName(name);
|
|
83
88
|
const kind = str("kind");
|
|
84
89
|
if (kind && kind !== "agent" && kind !== "endpoint")
|
|
85
90
|
throw new Error(`agent file ${path}: "kind" must be "agent" or "endpoint"`);
|
|
91
|
+
// The pre-ACL field names were renamed (channels→subscribe, publish→allowPublish, +allowSubscribe).
|
|
92
|
+
// Fail loud on the old names rather than silently sweeping them into meta and ignoring them —
|
|
93
|
+
// an unmigrated file would otherwise lose its read/post scope without warning (no silent degrade).
|
|
94
|
+
for (const old of ["channels", "publish"])
|
|
95
|
+
if (old in fm)
|
|
96
|
+
throw new Error(`agent file ${path}: "${old}" was renamed — use "subscribe"/"allowSubscribe" (read) and "allowPublish" (post)`);
|
|
97
|
+
const subscribe = list("subscribe");
|
|
98
|
+
const allowSubscribe = list("allowSubscribe");
|
|
99
|
+
const allowPublish = list("allowPublish");
|
|
100
|
+
const quiet = list("quiet");
|
|
101
|
+
const muted = list("muted");
|
|
102
|
+
// Reject channel names the wire layer would silently rewrite — a policy name must equal its wire
|
|
103
|
+
// token, or the ACL aliases (see assertValidChannel). Covers all three scope fields.
|
|
104
|
+
for (const ch of [...(subscribe ?? []), ...(allowSubscribe ?? []), ...(allowPublish ?? [])])
|
|
105
|
+
try {
|
|
106
|
+
assertValidChannel(ch);
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
throw new Error(`agent file ${path}: ${e.message}`);
|
|
110
|
+
}
|
|
111
|
+
// Invariant (fail-loud at load): the active read set must be within the read ACL. Defaults:
|
|
112
|
+
// subscribe ⇒ [general]; allowSubscribe ⇒ subscribe (read exactly what you subscribe to).
|
|
113
|
+
const effSubscribe = subscribe?.length ? subscribe : ["general"];
|
|
114
|
+
const effAllow = allowSubscribe?.length ? allowSubscribe : effSubscribe;
|
|
115
|
+
for (const ch of effSubscribe)
|
|
116
|
+
if (!channelInAllow(effAllow, ch))
|
|
117
|
+
throw new Error(`agent file ${path}: subscribe channel "${ch}" is not within allowSubscribe [${effAllow.join(", ")}]`);
|
|
118
|
+
// Per-channel attention defaults (quiet/muted): concrete channels within the read ACL (allowSubscribe)
|
|
119
|
+
// — silencing a channel you can't read, or with a wildcard the ingest match would never hit, is a config error. A
|
|
120
|
+
// channel can't be both at once. Fail loud (no silent no-op), matching the checks above.
|
|
121
|
+
const both = (quiet ?? []).filter((c) => (muted ?? []).includes(c));
|
|
122
|
+
if (both.length)
|
|
123
|
+
throw new Error(`agent file ${path}: channel(s) [${both.join(", ")}] are in both quiet and muted — pick one`);
|
|
124
|
+
for (const [field, chans] of [["quiet", quiet], ["muted", muted]])
|
|
125
|
+
for (const ch of chans ?? []) {
|
|
126
|
+
try {
|
|
127
|
+
assertValidChannel(ch);
|
|
128
|
+
}
|
|
129
|
+
catch (e) {
|
|
130
|
+
throw new Error(`agent file ${path}: ${e.message}`);
|
|
131
|
+
}
|
|
132
|
+
if (!isConcreteChannel(ch))
|
|
133
|
+
throw new Error(`agent file ${path}: ${field} channel "${ch}" must be a concrete channel (no wildcard)`);
|
|
134
|
+
if (!channelInAllow(effAllow, ch))
|
|
135
|
+
throw new Error(`agent file ${path}: ${field} channel "${ch}" is not within your read ACL / allowSubscribe [${effAllow.join(", ")}]`);
|
|
136
|
+
}
|
|
86
137
|
// Sweep every scalar frontmatter key we don't model into meta, verbatim — connector hints
|
|
87
138
|
// (face, etc.) ride here so core stays ignorant of surface-specific keys.
|
|
88
|
-
const known = new Set(["name", "role", "kind", "description", "tags", "
|
|
139
|
+
const known = new Set(["name", "role", "kind", "description", "tags", "subscribe", "allowSubscribe", "allowPublish", "quiet", "muted", "model", "capabilities", "owner"]);
|
|
89
140
|
const meta = {};
|
|
90
141
|
for (const [k, v] of Object.entries(fm))
|
|
91
142
|
if (!known.has(k) && typeof v === "string")
|
|
@@ -96,9 +147,14 @@ export function loadAgentFile(path) {
|
|
|
96
147
|
kind: kind,
|
|
97
148
|
description: str("description"),
|
|
98
149
|
tags: list("tags"),
|
|
99
|
-
|
|
100
|
-
|
|
150
|
+
subscribe,
|
|
151
|
+
allowSubscribe,
|
|
152
|
+
allowPublish,
|
|
153
|
+
quiet,
|
|
154
|
+
muted,
|
|
101
155
|
model: str("model"),
|
|
156
|
+
capabilities: list("capabilities"),
|
|
157
|
+
owner: str("owner"),
|
|
102
158
|
meta: Object.keys(meta).length ? meta : undefined,
|
|
103
159
|
persona: persona || undefined,
|
|
104
160
|
};
|
|
@@ -110,6 +166,7 @@ export function loadAgentFile(path) {
|
|
|
110
166
|
export function saveAgentFile(path, def) {
|
|
111
167
|
if (!def.name)
|
|
112
168
|
throw new Error('saveAgentFile: "name" is required');
|
|
169
|
+
assertValidName(def.name);
|
|
113
170
|
const lines = ["---", `name: ${fmScalar(def.name)}`];
|
|
114
171
|
if (def.role)
|
|
115
172
|
lines.push(`role: ${fmScalar(def.role)}`);
|
|
@@ -119,12 +176,22 @@ export function saveAgentFile(path, def) {
|
|
|
119
176
|
lines.push(`description: ${fmScalar(def.description)}`);
|
|
120
177
|
if (def.tags?.length)
|
|
121
178
|
lines.push(`tags: [${def.tags.map(fmItem).join(", ")}]`);
|
|
122
|
-
if (def.
|
|
123
|
-
lines.push(`
|
|
124
|
-
if (def.
|
|
125
|
-
lines.push(`
|
|
179
|
+
if (def.subscribe?.length)
|
|
180
|
+
lines.push(`subscribe: [${def.subscribe.map(fmItem).join(", ")}]`);
|
|
181
|
+
if (def.allowSubscribe?.length)
|
|
182
|
+
lines.push(`allowSubscribe: [${def.allowSubscribe.map(fmItem).join(", ")}]`);
|
|
183
|
+
if (def.allowPublish?.length)
|
|
184
|
+
lines.push(`allowPublish: [${def.allowPublish.map(fmItem).join(", ")}]`);
|
|
185
|
+
if (def.quiet?.length)
|
|
186
|
+
lines.push(`quiet: [${def.quiet.map(fmItem).join(", ")}]`);
|
|
187
|
+
if (def.muted?.length)
|
|
188
|
+
lines.push(`muted: [${def.muted.map(fmItem).join(", ")}]`);
|
|
126
189
|
if (def.model)
|
|
127
190
|
lines.push(`model: ${fmScalar(def.model)}`);
|
|
191
|
+
if (def.capabilities?.length)
|
|
192
|
+
lines.push(`capabilities: [${def.capabilities.map(fmItem).join(", ")}]`);
|
|
193
|
+
if (def.owner)
|
|
194
|
+
lines.push(`owner: ${fmScalar(def.owner)}`);
|
|
128
195
|
if (def.meta)
|
|
129
196
|
for (const [k, v] of Object.entries(def.meta))
|
|
130
197
|
lines.push(`${k}: ${fmScalar(v)}`);
|
|
@@ -163,4 +230,17 @@ export function agentFilePath(root, nameOrPath) {
|
|
|
163
230
|
return resolve(root, nameOrPath);
|
|
164
231
|
return join(root, ".cotal", "agents", `${nameOrPath}.md`);
|
|
165
232
|
}
|
|
233
|
+
/** First free name in the series `base`, `base-2`, `base-3`, … — the first candidate for which
|
|
234
|
+
* `taken` returns false. The single source of the spawn auto-numbering scheme, shared by the
|
|
235
|
+
* manager's funnel (checked against its live + reserved slots) and `cotal spawn` (checked against
|
|
236
|
+
* the live mesh roster), so a colliding name numbers up identically whichever path spawns it. */
|
|
237
|
+
export function firstFreeName(base, taken) {
|
|
238
|
+
if (!taken(base))
|
|
239
|
+
return base;
|
|
240
|
+
for (let n = 2;; n++) {
|
|
241
|
+
const candidate = `${base}-${n}`;
|
|
242
|
+
if (!taken(candidate))
|
|
243
|
+
return candidate;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
166
246
|
//# sourceMappingURL=agent-file.js.map
|
package/dist/agent-file.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-file.js","sourceRoot":"","sources":["../src/agent-file.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"agent-file.js","sourceRoot":"","sources":["../src/agent-file.ts"],"names":[],"mappings":"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"}
|
package/dist/channels.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { type KV } from "@nats-io/kv";
|
|
11
11
|
import { type NatsConnection } from "@nats-io/transport-node";
|
|
12
|
-
import type { ChannelConfig, ChannelDefaults } from "./types.js";
|
|
12
|
+
import type { ChannelConfig, ChannelDefaults, DeliveryClass } from "./types.js";
|
|
13
13
|
/** The declarative channel-config file read at `cotal up` to seed the registry. */
|
|
14
14
|
export interface ChannelRegistryFile {
|
|
15
15
|
defaults?: ChannelDefaults;
|
|
@@ -23,6 +23,10 @@ export declare const MAX_CHANNEL_INSTRUCTIONS = 2000;
|
|
|
23
23
|
/** Throw if a config is invalid: oversize text (rejected, never clamped — a write past the cap
|
|
24
24
|
* is a caller bug) or an unparseable `replayWindow`. */
|
|
25
25
|
export declare function validateChannelConfig(cfg: ChannelConfig): void;
|
|
26
|
+
/** Validate a defaults patch the same way per-channel config is — the space default feeds
|
|
27
|
+
* {@link effectiveDeliveryClass} as a co-equal input, so a bad value must fail loud here, not
|
|
28
|
+
* silently become the space-wide effective class. */
|
|
29
|
+
export declare function validateChannelDefaults(d: ChannelDefaults): void;
|
|
26
30
|
/** Parse a duration like `"24h"`, `"30m"`, `"7d"`, `"90s"` into milliseconds. Throws on a bad
|
|
27
31
|
* format — a typo'd window must fail loud, not silently mean "no window". */
|
|
28
32
|
export declare function parseDuration(s: string): number;
|
|
@@ -32,6 +36,12 @@ export declare function effectiveReplay(cfg: ChannelConfig | undefined, defaults
|
|
|
32
36
|
/** Effective backfill window in ms (per-channel ?? space default), or undefined for "the full
|
|
33
37
|
* retained window". Only meaningful when {@link effectiveReplay} is true. */
|
|
34
38
|
export declare function effectiveReplayWindowMs(cfg: ChannelConfig | undefined, defaults: ChannelDefaults | undefined): number | undefined;
|
|
39
|
+
/** Effective delivery class for a channel (SPEC §4): per-channel override ?? space default ??
|
|
40
|
+
* `"durable"`. Default-durable keeps persistence on when a space declares no default — the safe
|
|
41
|
+
* fallback; a space sets `defaults.deliveryClass` at creation per deployment profile. The SAME
|
|
42
|
+
* resolution MUST drive live join, durable fan-out, history read, and membership surfacing, so
|
|
43
|
+
* every path agrees on a channel's class. */
|
|
44
|
+
export declare function effectiveDeliveryClass(cfg: ChannelConfig | undefined, defaults: ChannelDefaults | undefined): DeliveryClass;
|
|
35
45
|
/** Open the channels registry bucket. Auth mode (creds present) OPENs the bucket pre-created
|
|
36
46
|
* at `cotal up`; open dev mode lazily CREATEs it. Mirrors the presence-bucket open/create
|
|
37
47
|
* split (and, like presence, agents are denied KV stream-create so they must OPEN). */
|
|
@@ -45,7 +55,8 @@ export declare function readChannelDefaults(kv: KV): Promise<ChannelDefaults | u
|
|
|
45
55
|
/** Privileged write of a channel's config. **Merges** over any existing entry so a partial
|
|
46
56
|
* set (e.g. `--desc` only) doesn't wipe `replay`. Validated before the put. */
|
|
47
57
|
export declare function writeChannelConfig(kv: KV, channel: string, patch: ChannelConfig): Promise<void>;
|
|
48
|
-
/** Privileged write of the space-wide defaults (merged over any existing).
|
|
58
|
+
/** Privileged write of the space-wide defaults (merged over any existing). Validated before the
|
|
59
|
+
* put — a bad default would otherwise feed {@link effectiveDeliveryClass} silently. */
|
|
49
60
|
export declare function writeChannelDefaults(kv: KV, patch: ChannelDefaults): Promise<void>;
|
|
50
61
|
/** Connect (with the given privileged creds, or open if none), seed the registry from a
|
|
51
62
|
* declarative {@link ChannelRegistryFile} (defaults + per-channel config, merged), disconnect.
|
package/dist/channels.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAO,KAAK,EAAE,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE3F,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAO,KAAK,EAAE,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE3F,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhF,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC1C;AAED;iFACiF;AACjF,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C;yDACyD;AACzD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAgB9D;AAED;;sDAEsD;AACtD,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,eAAe,GAAG,IAAI,CAIhE;AAED;8EAC8E;AAC9E,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED;8EAC8E;AAC9E,wBAAgB,eAAe,CAC7B,GAAG,EAAE,aAAa,GAAG,SAAS,EAC9B,QAAQ,EAAE,eAAe,GAAG,SAAS,GACpC,OAAO,CAET;AAED;8EAC8E;AAC9E,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,aAAa,GAAG,SAAS,EAC9B,QAAQ,EAAE,eAAe,GAAG,SAAS,GACpC,MAAM,GAAG,SAAS,CAGpB;AAED;;;;8CAI8C;AAC9C,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,aAAa,GAAG,SAAS,EAC9B,QAAQ,EAAE,eAAe,GAAG,SAAS,GACpC,aAAa,CAEf;AAED;;wFAEwF;AACxF,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,cAAc,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9B,OAAO,CAAC,EAAE,CAAC,CAGb;AAED,iEAAiE;AACjE,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAEpC;AAED,4DAA4D;AAC5D,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAEtF;AAED;gFACgF;AAChF,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;wFACwF;AACxF,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAIxF;AAYD;;;iGAGiG;AACjG,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,mBAAmB,CAAC;CAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhB;AAED;;qCAEqC;AACrC,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuB/B"}
|
package/dist/channels.js
CHANGED
|
@@ -23,6 +23,19 @@ export function validateChannelConfig(cfg) {
|
|
|
23
23
|
throw new Error(`channel instructions too long (${cfg.instructions.length} > ${MAX_CHANNEL_INSTRUCTIONS} chars)`);
|
|
24
24
|
if (cfg.replayWindow !== undefined)
|
|
25
25
|
parseDuration(cfg.replayWindow); // throws if unparseable
|
|
26
|
+
if (cfg.deliveryClass !== undefined &&
|
|
27
|
+
cfg.deliveryClass !== "live" &&
|
|
28
|
+
cfg.deliveryClass !== "durable")
|
|
29
|
+
throw new Error(`invalid deliveryClass "${cfg.deliveryClass}" — expected "live" or "durable"`);
|
|
30
|
+
}
|
|
31
|
+
/** Validate a defaults patch the same way per-channel config is — the space default feeds
|
|
32
|
+
* {@link effectiveDeliveryClass} as a co-equal input, so a bad value must fail loud here, not
|
|
33
|
+
* silently become the space-wide effective class. */
|
|
34
|
+
export function validateChannelDefaults(d) {
|
|
35
|
+
if (d.replayWindow !== undefined)
|
|
36
|
+
parseDuration(d.replayWindow); // throws if unparseable
|
|
37
|
+
if (d.deliveryClass !== undefined && d.deliveryClass !== "live" && d.deliveryClass !== "durable")
|
|
38
|
+
throw new Error(`invalid deliveryClass "${d.deliveryClass}" — expected "live" or "durable"`);
|
|
26
39
|
}
|
|
27
40
|
/** Parse a duration like `"24h"`, `"30m"`, `"7d"`, `"90s"` into milliseconds. Throws on a bad
|
|
28
41
|
* format — a typo'd window must fail loud, not silently mean "no window". */
|
|
@@ -45,6 +58,14 @@ export function effectiveReplayWindowMs(cfg, defaults) {
|
|
|
45
58
|
const w = cfg?.replayWindow ?? defaults?.replayWindow;
|
|
46
59
|
return w === undefined ? undefined : parseDuration(w);
|
|
47
60
|
}
|
|
61
|
+
/** Effective delivery class for a channel (SPEC §4): per-channel override ?? space default ??
|
|
62
|
+
* `"durable"`. Default-durable keeps persistence on when a space declares no default — the safe
|
|
63
|
+
* fallback; a space sets `defaults.deliveryClass` at creation per deployment profile. The SAME
|
|
64
|
+
* resolution MUST drive live join, durable fan-out, history read, and membership surfacing, so
|
|
65
|
+
* every path agrees on a channel's class. */
|
|
66
|
+
export function effectiveDeliveryClass(cfg, defaults) {
|
|
67
|
+
return cfg?.deliveryClass ?? defaults?.deliveryClass ?? "durable";
|
|
68
|
+
}
|
|
48
69
|
/** Open the channels registry bucket. Auth mode (creds present) OPENs the bucket pre-created
|
|
49
70
|
* at `cotal up`; open dev mode lazily CREATEs it. Mirrors the presence-bucket open/create
|
|
50
71
|
* split (and, like presence, agents are denied KV stream-create so they must OPEN). */
|
|
@@ -67,8 +88,10 @@ export async function writeChannelConfig(kv, channel, patch) {
|
|
|
67
88
|
const merged = { ...(await readChannelConfig(kv, channel)), ...patch };
|
|
68
89
|
await kv.put(channel, JSON.stringify(merged));
|
|
69
90
|
}
|
|
70
|
-
/** Privileged write of the space-wide defaults (merged over any existing).
|
|
91
|
+
/** Privileged write of the space-wide defaults (merged over any existing). Validated before the
|
|
92
|
+
* put — a bad default would otherwise feed {@link effectiveDeliveryClass} silently. */
|
|
71
93
|
export async function writeChannelDefaults(kv, patch) {
|
|
94
|
+
validateChannelDefaults(patch);
|
|
72
95
|
const merged = { ...(await readChannelDefaults(kv)), ...patch };
|
|
73
96
|
await kv.put(CHANNEL_DEFAULTS_KEY, JSON.stringify(merged));
|
|
74
97
|
}
|
package/dist/channels.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,GAAG,EAAW,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAuB,MAAM,yBAAyB,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAUpE;iFACiF;AACjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C;yDACyD;AACzD,MAAM,UAAU,qBAAqB,CAAC,GAAkB;IACtD,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,uBAAuB;QACnF,MAAM,IAAI,KAAK,CACb,iCAAiC,GAAG,CAAC,WAAW,CAAC,MAAM,MAAM,uBAAuB,SAAS,CAC9F,CAAC;IACJ,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS,IAAI,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,wBAAwB;QACtF,MAAM,IAAI,KAAK,CACb,kCAAkC,GAAG,CAAC,YAAY,CAAC,MAAM,MAAM,wBAAwB,SAAS,CACjG,CAAC;IACJ,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;QAAE,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,wBAAwB;
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"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"}
|
package/dist/command.d.ts
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import type { Extension } from "./registry.js";
|
|
2
|
+
/** One shell-completion candidate. `value` is inserted on the command line; `description`
|
|
3
|
+
* is a one-line hint shown by shells that support it (zsh, fish) and ignored by bash. */
|
|
4
|
+
export interface CompletionItem {
|
|
5
|
+
value: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
}
|
|
8
|
+
/** What a command's {@link Command.complete} returns for the current cursor position: the
|
|
9
|
+
* candidates, plus a directive telling the shell glue how to treat them.
|
|
10
|
+
* - `nofiles` (the norm for our completions): don't fall back to filename completion.
|
|
11
|
+
* - `nospace`: don't append a trailing space (the value is a prefix, e.g. `owner/`).
|
|
12
|
+
* - `default`: normal behaviour (a trailing space is added; files may be offered). */
|
|
13
|
+
export interface CompletionResult {
|
|
14
|
+
items: CompletionItem[];
|
|
15
|
+
directive?: "default" | "nospace" | "nofiles";
|
|
16
|
+
}
|
|
2
17
|
/**
|
|
3
18
|
* The contract for a composable CLI command — an {@link Extension} of kind
|
|
4
19
|
* `"command"`. An implementation (the mesh CLI, the manager …) self-registers its
|
|
@@ -14,5 +29,11 @@ export interface Command extends Extension {
|
|
|
14
29
|
* Falls back to `summary` when unset. */
|
|
15
30
|
readonly usage?: string;
|
|
16
31
|
run(argv: string[]): Promise<void>;
|
|
32
|
+
/** Optional shell-completion provider, owned by the command exactly as `run` is. Given the
|
|
33
|
+
* args typed so far (everything after the command name; the last element is the word being
|
|
34
|
+
* completed, possibly empty), returns the candidates for that position. Runs on every <TAB>
|
|
35
|
+
* via the hidden `__complete` dispatcher, so it MUST be import-light and side-effect-free —
|
|
36
|
+
* no network, no spawns. Omit it to offer no argument completion for this command. */
|
|
37
|
+
complete?(argv: string[]): CompletionResult | Promise<CompletionResult>;
|
|
17
38
|
}
|
|
18
39
|
//# sourceMappingURL=command.d.ts.map
|
package/dist/command.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C;;;;GAIG;AACH,MAAM,WAAW,OAAQ,SAAQ,SAAS;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;8CAC0C;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C;0FAC0F;AAC1F,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;uFAIuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;CAC/C;AAED;;;;GAIG;AACH,MAAM,WAAW,OAAQ,SAAQ,SAAS;IACxC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;8CAC0C;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC;;;;2FAIuF;IACvF,QAAQ,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACzE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** One MCP server, in the de-facto `.mcp.json` shape. Secrets belong in `env` (or `headers`) as
|
|
2
|
+
* `${VAR}` references, resolved from the operator's environment at launch. Remote-transport fields
|
|
3
|
+
* (`type`/`url`/`headers`) are carried verbatim for connectors that support them. Any other
|
|
4
|
+
* `.mcp.json` key an operator copies in (e.g. `timeout`) passes through to the rendered config
|
|
5
|
+
* unchanged but gets NO `${VAR}` expansion — Claude only expands command/args/env/url/headers,
|
|
6
|
+
* which is exactly the set {@link mcpServerEnvKeys} scans for secret names to forward. */
|
|
7
|
+
export interface McpServerSpec {
|
|
8
|
+
command?: string;
|
|
9
|
+
args?: string[];
|
|
10
|
+
env?: Record<string, string>;
|
|
11
|
+
type?: string;
|
|
12
|
+
url?: string;
|
|
13
|
+
headers?: Record<string, string>;
|
|
14
|
+
/** Pass-through for any other `.mcp.json` key (carried verbatim, no env expansion). */
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
/** Per-connector settings. `mcpServers` are the operator servers SHARED with agents this connector
|
|
18
|
+
* spawns, keyed by server name (`.mcp.json`-style). */
|
|
19
|
+
export interface ConnectorConfig {
|
|
20
|
+
mcpServers?: Record<string, McpServerSpec>;
|
|
21
|
+
}
|
|
22
|
+
/** The parsed cotal config file: a section per connector, keyed by connector name ("claude", …). */
|
|
23
|
+
export interface CotalConfig {
|
|
24
|
+
connectors?: Record<string, ConnectorConfig>;
|
|
25
|
+
}
|
|
26
|
+
/** Operator-level config path: `$XDG_CONFIG_HOME/cotal/config.json`, else `~/.config/cotal/config.json`. */
|
|
27
|
+
export declare function globalConfigPath(): string;
|
|
28
|
+
/** Space-local config path: `<root>/.cotal/config.json`. */
|
|
29
|
+
export declare function spaceConfigPath(root: string): string;
|
|
30
|
+
/** Load the merged cotal config: the operator-level file as the base, the space-local file layered
|
|
31
|
+
* on top (more specific wins, per connector + server name). */
|
|
32
|
+
export declare function loadCotalConfig(root: string): CotalConfig;
|
|
33
|
+
/** The MCP servers a connector should share with an agent it spawns, after applying an optional
|
|
34
|
+
* per-spawn `selection` (the parsed `--share-tools` value):
|
|
35
|
+
* `undefined` → every server declared for the connector (the config default)
|
|
36
|
+
* `[]` → none (e.g. `--share-tools none`)
|
|
37
|
+
* `[a, b]` → only those named, which MUST be declared (throws otherwise — no silent drop). */
|
|
38
|
+
export declare function connectorServers(config: CotalConfig, connector: string, selection?: readonly string[]): Record<string, McpServerSpec>;
|
|
39
|
+
/** Parse a `--share-tools` flag value into a selection for {@link connectorServers}: flag absent
|
|
40
|
+
* → `undefined` (share all declared); `none` or empty → `[]` (share nothing); else the comma list. */
|
|
41
|
+
export declare function parseShareSelection(value: string | undefined): readonly string[] | undefined;
|
|
42
|
+
//# sourceMappingURL=connector-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-config.d.ts","sourceRoot":"","sources":["../src/connector-config.ts"],"names":[],"mappings":"AA4BA;;;;;2FAK2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,uFAAuF;IACvF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;wDACwD;AACxD,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC5C;AAED,oGAAoG;AACpG,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC9C;AAED,4GAA4G;AAC5G,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAED,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AA+BD;gEACgE;AAChE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAEzD;AAED;;;;oGAIoG;AACpG,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAC5B,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAc/B;AAED;uGACuG;AACvG,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAQ5F"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cotal config file — per-connector launch settings, the first general config notion in
|
|
3
|
+
* the repo (alongside `.cotal/{auth,agents,creds}`, which are about identity, not settings).
|
|
4
|
+
*
|
|
5
|
+
* ~/.config/cotal/config.json (operator-level, every space) ← base layer
|
|
6
|
+
* <root>/.cotal/config.json (space-local override) ← higher precedence
|
|
7
|
+
*
|
|
8
|
+
* Today it carries one thing: which of the operator's personal MCP servers a connector should
|
|
9
|
+
* SHARE with the agents it spawns. By default a spawned agent gets none — the Claude connector
|
|
10
|
+
* launches with `--strict-mcp-config`, dropping every operator server, because they're heavy
|
|
11
|
+
* (a headless Chromium server alone can climb past a gigabyte) and useless to a meshed teammate.
|
|
12
|
+
* This file is the explicit opt-in to pass named ones through.
|
|
13
|
+
*
|
|
14
|
+
* Each server is written in the de-facto `.mcp.json` shape, so an operator can copy an entry
|
|
15
|
+
* straight out of their own Claude / VS Code / Cursor config. Secrets ride as `${VAR}` references
|
|
16
|
+
* resolved from the operator's environment at launch — never literals — so the file stays safe to
|
|
17
|
+
* keep in `~/.config` or a gitignored `.cotal/`.
|
|
18
|
+
*
|
|
19
|
+
* This is deliberately NOT in the agent file ({@link AgentDef}): that's the connector-agnostic
|
|
20
|
+
* identity, portable across Claude Code / OpenCode / Hermes, and MCP-passthrough isn't a shared
|
|
21
|
+
* concept (Claude uses `--mcp-config`, OpenCode inherits via a merge layer, Hermes has no MCP).
|
|
22
|
+
* The caller (both spawn paths) resolves this once and hands the chosen servers to the connector,
|
|
23
|
+
* which renders them into its own host format.
|
|
24
|
+
*/
|
|
25
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
26
|
+
import { homedir } from "node:os";
|
|
27
|
+
import { join } from "node:path";
|
|
28
|
+
/** Operator-level config path: `$XDG_CONFIG_HOME/cotal/config.json`, else `~/.config/cotal/config.json`. */
|
|
29
|
+
export function globalConfigPath() {
|
|
30
|
+
const base = process.env.XDG_CONFIG_HOME?.trim() || join(homedir(), ".config");
|
|
31
|
+
return join(base, "cotal", "config.json");
|
|
32
|
+
}
|
|
33
|
+
/** Space-local config path: `<root>/.cotal/config.json`. */
|
|
34
|
+
export function spaceConfigPath(root) {
|
|
35
|
+
return join(root, ".cotal", "config.json");
|
|
36
|
+
}
|
|
37
|
+
/** Parse one config file. A missing file is empty (no config is a valid state); malformed JSON or a
|
|
38
|
+
* non-object top level throws — a typo in your settings should be loud, not silently ignored. */
|
|
39
|
+
function readConfigFile(path) {
|
|
40
|
+
if (!existsSync(path))
|
|
41
|
+
return {};
|
|
42
|
+
let parsed;
|
|
43
|
+
try {
|
|
44
|
+
parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
throw new Error(`cotal config ${path}: invalid JSON — ${e.message}`);
|
|
48
|
+
}
|
|
49
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
50
|
+
throw new Error(`cotal config ${path}: top level must be a JSON object`);
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
/** Layer `over` onto `base`: per connector, a server in `over` replaces the same-named server in
|
|
54
|
+
* `base` (whole-spec replace, by name — the same merge the MCP clients do); servers/connectors
|
|
55
|
+
* present in only one side are kept. */
|
|
56
|
+
function mergeConfig(base, over) {
|
|
57
|
+
const connectors = {};
|
|
58
|
+
const names = new Set([...Object.keys(base.connectors ?? {}), ...Object.keys(over.connectors ?? {})]);
|
|
59
|
+
for (const name of names) {
|
|
60
|
+
const b = base.connectors?.[name];
|
|
61
|
+
const o = over.connectors?.[name];
|
|
62
|
+
connectors[name] = { ...b, ...o, mcpServers: { ...(b?.mcpServers ?? {}), ...(o?.mcpServers ?? {}) } };
|
|
63
|
+
}
|
|
64
|
+
return { connectors };
|
|
65
|
+
}
|
|
66
|
+
/** Load the merged cotal config: the operator-level file as the base, the space-local file layered
|
|
67
|
+
* on top (more specific wins, per connector + server name). */
|
|
68
|
+
export function loadCotalConfig(root) {
|
|
69
|
+
return mergeConfig(readConfigFile(globalConfigPath()), readConfigFile(spaceConfigPath(root)));
|
|
70
|
+
}
|
|
71
|
+
/** The MCP servers a connector should share with an agent it spawns, after applying an optional
|
|
72
|
+
* per-spawn `selection` (the parsed `--share-tools` value):
|
|
73
|
+
* `undefined` → every server declared for the connector (the config default)
|
|
74
|
+
* `[]` → none (e.g. `--share-tools none`)
|
|
75
|
+
* `[a, b]` → only those named, which MUST be declared (throws otherwise — no silent drop). */
|
|
76
|
+
export function connectorServers(config, connector, selection) {
|
|
77
|
+
const declared = config.connectors?.[connector]?.mcpServers ?? {};
|
|
78
|
+
if (selection === undefined)
|
|
79
|
+
return { ...declared };
|
|
80
|
+
const chosen = {};
|
|
81
|
+
for (const name of selection) {
|
|
82
|
+
const spec = declared[name];
|
|
83
|
+
if (!spec)
|
|
84
|
+
throw new Error(`--share-tools: "${name}" is not a shared server for connector "${connector}" ` +
|
|
85
|
+
`(declared: ${Object.keys(declared).join(", ") || "none"})`);
|
|
86
|
+
chosen[name] = spec;
|
|
87
|
+
}
|
|
88
|
+
return chosen;
|
|
89
|
+
}
|
|
90
|
+
/** Parse a `--share-tools` flag value into a selection for {@link connectorServers}: flag absent
|
|
91
|
+
* → `undefined` (share all declared); `none` or empty → `[]` (share nothing); else the comma list. */
|
|
92
|
+
export function parseShareSelection(value) {
|
|
93
|
+
if (value === undefined)
|
|
94
|
+
return undefined;
|
|
95
|
+
const trimmed = value.trim();
|
|
96
|
+
if (trimmed === "" || trimmed.toLowerCase() === "none")
|
|
97
|
+
return [];
|
|
98
|
+
return trimmed
|
|
99
|
+
.split(",")
|
|
100
|
+
.map((s) => s.trim())
|
|
101
|
+
.filter(Boolean);
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=connector-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector-config.js","sourceRoot":"","sources":["../src/connector-config.ts"],"names":[],"mappings":"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"}
|