@spinabot/brigade 1.12.0 → 1.14.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 +20 -0
- package/convex/logs.d.ts +3 -3
- package/convex/memory.d.ts +21 -21
- package/convex/schema.d.ts +9 -9
- package/convex/skills.d.ts +3 -3
- package/dist/buildstamp.json +1 -1
- package/dist/cli/commands/config-cmd.d.ts +12 -19
- package/dist/cli/commands/config-cmd.d.ts.map +1 -1
- package/dist/cli/commands/config-cmd.js +14 -197
- package/dist/cli/commands/config-cmd.js.map +1 -1
- package/dist/cli/commands/connect.d.ts +6 -0
- package/dist/cli/commands/connect.d.ts.map +1 -1
- package/dist/cli/commands/connect.js +7 -0
- package/dist/cli/commands/connect.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +2 -1
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/expose.d.ts.map +1 -1
- package/dist/cli/commands/expose.js +22 -3
- package/dist/cli/commands/expose.js.map +1 -1
- package/dist/cli/commands/gateway.d.ts +12 -0
- package/dist/cli/commands/gateway.d.ts.map +1 -1
- package/dist/cli/commands/gateway.js +114 -2
- package/dist/cli/commands/gateway.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +2 -1
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/program/build-program.d.ts.map +1 -1
- package/dist/cli/program/build-program.js +36 -0
- package/dist/cli/program/build-program.js.map +1 -1
- package/dist/config/io.d.ts +13 -0
- package/dist/config/io.d.ts.map +1 -1
- package/dist/config/io.js.map +1 -1
- package/dist/core/agents-crud-ops.d.ts +15 -0
- package/dist/core/agents-crud-ops.d.ts.map +1 -0
- package/dist/core/agents-crud-ops.js +27 -0
- package/dist/core/agents-crud-ops.js.map +1 -0
- package/dist/core/agents-ops.d.ts +43 -0
- package/dist/core/agents-ops.d.ts.map +1 -0
- package/dist/core/agents-ops.js +117 -0
- package/dist/core/agents-ops.js.map +1 -0
- package/dist/core/channels-ops.d.ts +30 -0
- package/dist/core/channels-ops.d.ts.map +1 -0
- package/dist/core/channels-ops.js +52 -0
- package/dist/core/channels-ops.js.map +1 -0
- package/dist/core/config-ops.d.ts +77 -0
- package/dist/core/config-ops.d.ts.map +1 -0
- package/dist/core/config-ops.js +241 -0
- package/dist/core/config-ops.js.map +1 -0
- package/dist/core/exec-ops.d.ts +48 -0
- package/dist/core/exec-ops.d.ts.map +1 -0
- package/dist/core/exec-ops.js +101 -0
- package/dist/core/exec-ops.js.map +1 -0
- package/dist/core/gateway-auth.d.ts +86 -0
- package/dist/core/gateway-auth.d.ts.map +1 -0
- package/dist/core/gateway-auth.js +156 -0
- package/dist/core/gateway-auth.js.map +1 -0
- package/dist/core/gateway-probe.d.ts +5 -0
- package/dist/core/gateway-probe.d.ts.map +1 -1
- package/dist/core/gateway-probe.js +2 -1
- package/dist/core/gateway-probe.js.map +1 -1
- package/dist/core/gateway-spawn.d.ts.map +1 -1
- package/dist/core/gateway-spawn.js +5 -2
- package/dist/core/gateway-spawn.js.map +1 -1
- package/dist/core/integrations-ops.d.ts +25 -0
- package/dist/core/integrations-ops.d.ts.map +1 -0
- package/dist/core/integrations-ops.js +40 -0
- package/dist/core/integrations-ops.js.map +1 -0
- package/dist/core/memory-ops.d.ts +20 -0
- package/dist/core/memory-ops.d.ts.map +1 -0
- package/dist/core/memory-ops.js +40 -0
- package/dist/core/memory-ops.js.map +1 -0
- package/dist/core/pairing-ops.d.ts +33 -0
- package/dist/core/pairing-ops.d.ts.map +1 -0
- package/dist/core/pairing-ops.js +78 -0
- package/dist/core/pairing-ops.js.map +1 -0
- package/dist/core/provider-ops.d.ts +17 -0
- package/dist/core/provider-ops.d.ts.map +1 -0
- package/dist/core/provider-ops.js +29 -0
- package/dist/core/provider-ops.js.map +1 -0
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +112 -1
- package/dist/core/server.js.map +1 -1
- package/dist/core/sessions-ops.d.ts +25 -0
- package/dist/core/sessions-ops.d.ts.map +1 -0
- package/dist/core/sessions-ops.js +77 -0
- package/dist/core/sessions-ops.js.map +1 -0
- package/dist/core/skills-ops.d.ts +14 -0
- package/dist/core/skills-ops.d.ts.map +1 -0
- package/dist/core/skills-ops.js +28 -0
- package/dist/core/skills-ops.js.map +1 -0
- package/dist/core/tunnel/auth-proxy.d.ts +3 -2
- package/dist/core/tunnel/auth-proxy.d.ts.map +1 -1
- package/dist/core/tunnel/auth-proxy.js +8 -34
- package/dist/core/tunnel/auth-proxy.js.map +1 -1
- package/dist/core/tunnel/manager.d.ts +4 -2
- package/dist/core/tunnel/manager.d.ts.map +1 -1
- package/dist/core/tunnel/manager.js +3 -2
- package/dist/core/tunnel/manager.js.map +1 -1
- package/dist/protocol/methods.d.ts +478 -0
- package/dist/protocol/methods.d.ts.map +1 -1
- package/dist/tui/client.d.ts +8 -0
- package/dist/tui/client.d.ts.map +1 -1
- package/dist/tui/client.js +5 -1
- package/dist/tui/client.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent routing-binding operations behind the `agents.*` gateway RPCs — the
|
|
3
|
+
* `brigade agents <bindings|bind|unbind>` surface, reachable from a remote
|
|
4
|
+
* client.
|
|
5
|
+
*
|
|
6
|
+
* These are the genuine no-other-path gap: agent ADD/DELETE/SET-IDENTITY are
|
|
7
|
+
* already reachable over the gateway via the `manage_agent` tool (a prompt), but
|
|
8
|
+
* routing bindings (which agent owns which channel/account) had no remote path
|
|
9
|
+
* at all. This module closes that.
|
|
10
|
+
*
|
|
11
|
+
* OPERATOR-SCOPED config mutations (which agent routes which channel) — not
|
|
12
|
+
* session-targeted, so no per-session access guard (allowlisted by name in the
|
|
13
|
+
* guard-sweep). Reuses the SAME binding domain primitives the CLI calls, so
|
|
14
|
+
* `brigade agents bind` and `agents.bind` over the wire behave identically,
|
|
15
|
+
* including conflict detection (a slot already owned by another agent).
|
|
16
|
+
*/
|
|
17
|
+
import { applyAgentBindings, describeBinding, listRouteBindings, parseBindingSpecs, removeAgentBindings, } from "../cli/commands/agents-bindings.js";
|
|
18
|
+
import { DEFAULT_AGENT_ID, normalizeAgentId } from "../agents/routing/session-key.js";
|
|
19
|
+
import { loadConfig, saveConfig } from "./config.js";
|
|
20
|
+
/** Lightweight existence check — `main` always exists; otherwise a configured entry. */
|
|
21
|
+
function hasAgent(cfg, agentId) {
|
|
22
|
+
if (agentId === DEFAULT_AGENT_ID)
|
|
23
|
+
return true;
|
|
24
|
+
const agents = (cfg.agents ?? {});
|
|
25
|
+
return agentId !== "defaults" && agentId in agents;
|
|
26
|
+
}
|
|
27
|
+
function conflictLines(conflicts) {
|
|
28
|
+
return conflicts.map((c) => `${describeBinding(c.binding)} (owned by ${c.existingAgentId})`);
|
|
29
|
+
}
|
|
30
|
+
export function handleAgentsBindings(params) {
|
|
31
|
+
const p = (params ?? {});
|
|
32
|
+
const cfg = loadConfig();
|
|
33
|
+
const filter = p.agentId?.trim() ? normalizeAgentId(p.agentId) : null;
|
|
34
|
+
const bindings = listRouteBindings(cfg)
|
|
35
|
+
.filter((b) => !filter || normalizeAgentId(b.agentId) === filter)
|
|
36
|
+
.map((b) => ({ agentId: normalizeAgentId(b.agentId), description: describeBinding(b) }));
|
|
37
|
+
return { bindings };
|
|
38
|
+
}
|
|
39
|
+
export function handleAgentsBind(params) {
|
|
40
|
+
const p = (params ?? {});
|
|
41
|
+
const cfg = loadConfig();
|
|
42
|
+
const agentId = normalizeAgentId(p.agentId ?? DEFAULT_AGENT_ID);
|
|
43
|
+
const fail = (errors) => ({
|
|
44
|
+
ok: false,
|
|
45
|
+
agentId,
|
|
46
|
+
added: [],
|
|
47
|
+
updated: [],
|
|
48
|
+
skipped: [],
|
|
49
|
+
conflicts: [],
|
|
50
|
+
errors,
|
|
51
|
+
});
|
|
52
|
+
if (!hasAgent(cfg, agentId))
|
|
53
|
+
return fail([`agent "${agentId}" not found`]);
|
|
54
|
+
const specs = (p.specs ?? []).map((s) => String(s).trim()).filter(Boolean);
|
|
55
|
+
if (specs.length === 0)
|
|
56
|
+
return fail(["provide at least one binding spec, e.g. \"whatsapp\" or \"slack:T123\""]);
|
|
57
|
+
// channels omitted → skip channel-name validation (an operator RPC; a client
|
|
58
|
+
// can validate against `system.capabilities`). An unknown channel just yields
|
|
59
|
+
// an inert binding rather than a hard error.
|
|
60
|
+
const parsed = parseBindingSpecs({ agentId, specs, config: cfg });
|
|
61
|
+
if (parsed.errors.length > 0)
|
|
62
|
+
return fail(parsed.errors);
|
|
63
|
+
const result = applyAgentBindings(cfg, parsed.bindings);
|
|
64
|
+
if (result.added.length > 0 || result.updated.length > 0)
|
|
65
|
+
saveConfig(result.config);
|
|
66
|
+
return {
|
|
67
|
+
ok: result.conflicts.length === 0,
|
|
68
|
+
agentId,
|
|
69
|
+
added: result.added.map(describeBinding),
|
|
70
|
+
updated: result.updated.map(describeBinding),
|
|
71
|
+
skipped: result.skipped.map(describeBinding),
|
|
72
|
+
conflicts: conflictLines(result.conflicts),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export function handleAgentsUnbind(params) {
|
|
76
|
+
const p = (params ?? {});
|
|
77
|
+
const cfg = loadConfig();
|
|
78
|
+
const agentId = normalizeAgentId(p.agentId ?? DEFAULT_AGENT_ID);
|
|
79
|
+
const fail = (errors) => ({
|
|
80
|
+
ok: false,
|
|
81
|
+
agentId,
|
|
82
|
+
removed: [],
|
|
83
|
+
missing: [],
|
|
84
|
+
conflicts: [],
|
|
85
|
+
errors,
|
|
86
|
+
});
|
|
87
|
+
if (!hasAgent(cfg, agentId))
|
|
88
|
+
return fail([`agent "${agentId}" not found`]);
|
|
89
|
+
if (p.all) {
|
|
90
|
+
const existing = listRouteBindings(cfg);
|
|
91
|
+
const removed = existing.filter((b) => normalizeAgentId(b.agentId) === agentId);
|
|
92
|
+
const kept = existing.filter((b) => normalizeAgentId(b.agentId) !== agentId);
|
|
93
|
+
if (removed.length > 0)
|
|
94
|
+
saveConfig({ ...cfg, bindings: { entries: kept } });
|
|
95
|
+
return { ok: true, agentId, removed: removed.map(describeBinding), missing: [], conflicts: [] };
|
|
96
|
+
}
|
|
97
|
+
const specs = (p.specs ?? []).map((s) => String(s).trim()).filter(Boolean);
|
|
98
|
+
if (specs.length === 0)
|
|
99
|
+
return fail(["provide at least one binding spec, or pass all:true"]);
|
|
100
|
+
// channels omitted → skip channel-name validation (an operator RPC; a client
|
|
101
|
+
// can validate against `system.capabilities`). An unknown channel just yields
|
|
102
|
+
// an inert binding rather than a hard error.
|
|
103
|
+
const parsed = parseBindingSpecs({ agentId, specs, config: cfg });
|
|
104
|
+
if (parsed.errors.length > 0)
|
|
105
|
+
return fail(parsed.errors);
|
|
106
|
+
const result = removeAgentBindings(cfg, parsed.bindings);
|
|
107
|
+
if (result.removed.length > 0)
|
|
108
|
+
saveConfig(result.config);
|
|
109
|
+
return {
|
|
110
|
+
ok: result.conflicts.length === 0,
|
|
111
|
+
agentId,
|
|
112
|
+
removed: result.removed.map(describeBinding),
|
|
113
|
+
missing: result.missing.map(describeBinding),
|
|
114
|
+
conflicts: conflictLines(result.conflicts),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=agents-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents-ops.js","sourceRoot":"","sources":["../../src/core/agents-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel runtime + DM-allow control behind the `channels.*` gateway RPCs —
|
|
3
|
+
* reachable from a remote client.
|
|
4
|
+
*
|
|
5
|
+
* Channel *config* (enable/disable, group policy) is already config.set-
|
|
6
|
+
* reachable. These close the genuine gaps: LIVE connect/disconnect (a runtime
|
|
7
|
+
* adapter op, not config) and the DM allow-from store (a per-channel file, not
|
|
8
|
+
* brigade.json). Operator-scoped (no per-session guard — allowlisted).
|
|
9
|
+
*
|
|
10
|
+
* connect/disconnect reuse the owner-scoped `connect_channel` tool (its execute
|
|
11
|
+
* is ctx-free; the manager comes from the global `getActiveChannelManager()`).
|
|
12
|
+
* allow-add/remove/list call the access-control store directly.
|
|
13
|
+
*/
|
|
14
|
+
export declare function handleChannelsConnect(params: unknown): Promise<unknown>;
|
|
15
|
+
export declare function handleChannelsDisconnect(params: unknown): Promise<unknown>;
|
|
16
|
+
export interface ChannelsAllowResult {
|
|
17
|
+
ok: boolean;
|
|
18
|
+
channel: string;
|
|
19
|
+
senderId: string;
|
|
20
|
+
changed: boolean;
|
|
21
|
+
reason?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function handleChannelsAllowAdd(params: unknown): ChannelsAllowResult;
|
|
24
|
+
export declare function handleChannelsAllowRemove(params: unknown): ChannelsAllowResult;
|
|
25
|
+
export interface ChannelsAllowListResult {
|
|
26
|
+
channel: string;
|
|
27
|
+
senders: string[];
|
|
28
|
+
}
|
|
29
|
+
export declare function handleChannelsAllowList(params: unknown): ChannelsAllowListResult;
|
|
30
|
+
//# sourceMappingURL=channels-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels-ops.d.ts","sourceRoot":"","sources":["../../src/core/channels-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAE7E;AACD,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAEhF;AAED,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,mBAAmB,CAO3E;AACD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,mBAAmB,CAO9E;AAED,MAAM,WAAW,uBAAuB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AACD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,uBAAuB,CAKhF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel runtime + DM-allow control behind the `channels.*` gateway RPCs —
|
|
3
|
+
* reachable from a remote client.
|
|
4
|
+
*
|
|
5
|
+
* Channel *config* (enable/disable, group policy) is already config.set-
|
|
6
|
+
* reachable. These close the genuine gaps: LIVE connect/disconnect (a runtime
|
|
7
|
+
* adapter op, not config) and the DM allow-from store (a per-channel file, not
|
|
8
|
+
* brigade.json). Operator-scoped (no per-session guard — allowlisted).
|
|
9
|
+
*
|
|
10
|
+
* connect/disconnect reuse the owner-scoped `connect_channel` tool (its execute
|
|
11
|
+
* is ctx-free; the manager comes from the global `getActiveChannelManager()`).
|
|
12
|
+
* allow-add/remove/list call the access-control store directly.
|
|
13
|
+
*/
|
|
14
|
+
import { addAllowFrom, readAllowFrom, removeAllowFrom } from "../agents/channels/access-control/store.js";
|
|
15
|
+
import { makeConnectChannelTool } from "../agents/tools/connect-channel-tool.js";
|
|
16
|
+
async function runConnectChannel(args) {
|
|
17
|
+
const tool = makeConnectChannelTool({ senderIsOwner: true });
|
|
18
|
+
const res = await tool.execute("gateway", args);
|
|
19
|
+
return res.details;
|
|
20
|
+
}
|
|
21
|
+
export async function handleChannelsConnect(params) {
|
|
22
|
+
return runConnectChannel({ ...(params ?? {}), action: "connect" });
|
|
23
|
+
}
|
|
24
|
+
export async function handleChannelsDisconnect(params) {
|
|
25
|
+
return runConnectChannel({ ...(params ?? {}), action: "disconnect" });
|
|
26
|
+
}
|
|
27
|
+
export function handleChannelsAllowAdd(params) {
|
|
28
|
+
const p = (params ?? {});
|
|
29
|
+
const channel = (p.channel ?? "").trim();
|
|
30
|
+
const senderId = (p.senderId ?? "").trim();
|
|
31
|
+
if (!channel || !senderId)
|
|
32
|
+
return { ok: false, channel, senderId, changed: false, reason: "missing 'channel' or 'senderId'" };
|
|
33
|
+
const added = addAllowFrom(channel, senderId, p.accountId ?? null);
|
|
34
|
+
return { ok: true, channel, senderId, changed: added };
|
|
35
|
+
}
|
|
36
|
+
export function handleChannelsAllowRemove(params) {
|
|
37
|
+
const p = (params ?? {});
|
|
38
|
+
const channel = (p.channel ?? "").trim();
|
|
39
|
+
const senderId = (p.senderId ?? "").trim();
|
|
40
|
+
if (!channel || !senderId)
|
|
41
|
+
return { ok: false, channel, senderId, changed: false, reason: "missing 'channel' or 'senderId'" };
|
|
42
|
+
const removed = removeAllowFrom(channel, senderId, p.accountId ?? null);
|
|
43
|
+
return { ok: removed, channel, senderId, changed: removed, ...(removed ? {} : { reason: "sender not on the allow-from list" }) };
|
|
44
|
+
}
|
|
45
|
+
export function handleChannelsAllowList(params) {
|
|
46
|
+
const p = (params ?? {});
|
|
47
|
+
const channel = (p.channel ?? "").trim();
|
|
48
|
+
if (!channel)
|
|
49
|
+
throw new Error("channels.allow-list: missing 'channel'");
|
|
50
|
+
return { channel, senders: readAllowFrom(channel, p.accountId ?? null) };
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=channels-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels-ops.js","sourceRoot":"","sources":["../../src/core/channels-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config path operations — the pure logic behind `brigade config <get|set|
|
|
3
|
+
* unset|list|schema|validate>` AND the `config.*` gateway RPCs.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `cli/commands/config-cmd.ts` so the CLI and the gateway speak
|
|
6
|
+
* to ONE implementation: a remote client (web console) doing `config.set` and
|
|
7
|
+
* an operator doing `brigade config set` parse paths, redact secrets, and
|
|
8
|
+
* mutate brigade.json identically.
|
|
9
|
+
*
|
|
10
|
+
* The path helpers are pure (no I/O). The `handle*` functions are the gateway
|
|
11
|
+
* handlers: they read/write through the mode-aware `loadConfig`/`saveConfig`
|
|
12
|
+
* (filesystem OR Convex), so `config.*` works in both storage modes.
|
|
13
|
+
*
|
|
14
|
+
* Secret handling mirrors the CLI: any segment matching SENSITIVE_SEGMENT
|
|
15
|
+
* renders as `__BRIGADE_REDACTED__` in get/list output. Writes are NOT
|
|
16
|
+
* redacted (you can set a key you can't read back in plaintext), and the
|
|
17
|
+
* on-disk `${VAR}` restoration in `saveConfig` keeps resolved secrets off disk.
|
|
18
|
+
*/
|
|
19
|
+
export declare const REDACTED_SENTINEL = "__BRIGADE_REDACTED__";
|
|
20
|
+
/**
|
|
21
|
+
* Parse a config path into segments. Supports dot-notation
|
|
22
|
+
* (`agents.defaults.provider`), escaped dots (`keys.foo\.bar`), bracket array
|
|
23
|
+
* indices (`a.b[0]`), and bracket literal keys (`a["my.key"]`).
|
|
24
|
+
*/
|
|
25
|
+
export declare function parsePath(raw: string): string[];
|
|
26
|
+
export declare function getNested(root: unknown, segments: string[]): unknown;
|
|
27
|
+
export declare function setNested(root: Record<string, unknown>, segments: string[], value: unknown): void;
|
|
28
|
+
export declare function deleteNested(root: Record<string, unknown>, segments: string[]): boolean;
|
|
29
|
+
/** JSON5-parse a CLI string value, falling back to the raw string. */
|
|
30
|
+
export declare function parseConfigValue(raw: string, opts?: {
|
|
31
|
+
strictJson?: boolean;
|
|
32
|
+
}): unknown;
|
|
33
|
+
/** Deep-redact any string value whose key looks secret. */
|
|
34
|
+
export declare function redactDeep(value: unknown): unknown;
|
|
35
|
+
/** Read a redacted value at `rawPath`. `found:false` when the key is absent. */
|
|
36
|
+
export declare function configGetValue(cfg: unknown, rawPath: string): {
|
|
37
|
+
found: boolean;
|
|
38
|
+
value?: unknown;
|
|
39
|
+
};
|
|
40
|
+
/** Mutate `cfg` in place: set `rawPath` to `value`. */
|
|
41
|
+
export declare function configSetValue(cfg: Record<string, unknown>, rawPath: string, value: unknown): void;
|
|
42
|
+
/** Mutate `cfg` in place: remove `rawPath`. Returns whether anything was removed. */
|
|
43
|
+
export declare function configUnsetValue(cfg: Record<string, unknown>, rawPath: string): boolean;
|
|
44
|
+
export interface ConfigGetResult {
|
|
45
|
+
found: boolean;
|
|
46
|
+
value?: unknown;
|
|
47
|
+
}
|
|
48
|
+
export interface ConfigSetResult {
|
|
49
|
+
ok: boolean;
|
|
50
|
+
path: string;
|
|
51
|
+
value: unknown;
|
|
52
|
+
}
|
|
53
|
+
export interface ConfigUnsetResult {
|
|
54
|
+
ok: boolean;
|
|
55
|
+
path: string;
|
|
56
|
+
removed: boolean;
|
|
57
|
+
}
|
|
58
|
+
export interface ConfigListResult {
|
|
59
|
+
config: unknown;
|
|
60
|
+
}
|
|
61
|
+
export interface ConfigSchemaResult {
|
|
62
|
+
schema: unknown;
|
|
63
|
+
}
|
|
64
|
+
export interface ConfigValidateResult {
|
|
65
|
+
valid: boolean;
|
|
66
|
+
issues: Array<{
|
|
67
|
+
path: string;
|
|
68
|
+
message: string;
|
|
69
|
+
}>;
|
|
70
|
+
}
|
|
71
|
+
export declare function handleConfigGet(params: unknown): ConfigGetResult;
|
|
72
|
+
export declare function handleConfigSet(params: unknown): ConfigSetResult;
|
|
73
|
+
export declare function handleConfigUnset(params: unknown): ConfigUnsetResult;
|
|
74
|
+
export declare function handleConfigList(params: unknown): ConfigListResult;
|
|
75
|
+
export declare function handleConfigSchema(_params?: unknown): ConfigSchemaResult;
|
|
76
|
+
export declare function handleConfigValidate(_params?: unknown): ConfigValidateResult;
|
|
77
|
+
//# sourceMappingURL=config-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-ops.d.ts","sourceRoot":"","sources":["../../src/core/config-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,eAAO,MAAM,iBAAiB,yBAAyB,CAAC;AAKxD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAoD/C;AAOD,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAYpE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CA0BjG;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAuBvF;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAS1F;AAED,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAYlD;AAID,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAIjG;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAElG;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvF;AAUD,MAAM,WAAW,eAAe;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AACD,MAAM,WAAW,eAAe;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CACf;AACD,MAAM,WAAW,iBAAiB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CACjB;AACD,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,OAAO,CAAC;CAChB;AACD,MAAM,WAAW,kBAAkB;IAClC,MAAM,EAAE,OAAO,CAAC;CAChB;AACD,MAAM,WAAW,oBAAoB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,eAAe,CAKhE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,eAAe,CAQhE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,iBAAiB,CAQpE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAIlE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAExE;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,oBAAoB,CAG5E"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config path operations — the pure logic behind `brigade config <get|set|
|
|
3
|
+
* unset|list|schema|validate>` AND the `config.*` gateway RPCs.
|
|
4
|
+
*
|
|
5
|
+
* Extracted from `cli/commands/config-cmd.ts` so the CLI and the gateway speak
|
|
6
|
+
* to ONE implementation: a remote client (web console) doing `config.set` and
|
|
7
|
+
* an operator doing `brigade config set` parse paths, redact secrets, and
|
|
8
|
+
* mutate brigade.json identically.
|
|
9
|
+
*
|
|
10
|
+
* The path helpers are pure (no I/O). The `handle*` functions are the gateway
|
|
11
|
+
* handlers: they read/write through the mode-aware `loadConfig`/`saveConfig`
|
|
12
|
+
* (filesystem OR Convex), so `config.*` works in both storage modes.
|
|
13
|
+
*
|
|
14
|
+
* Secret handling mirrors the CLI: any segment matching SENSITIVE_SEGMENT
|
|
15
|
+
* renders as `__BRIGADE_REDACTED__` in get/list output. Writes are NOT
|
|
16
|
+
* redacted (you can set a key you can't read back in plaintext), and the
|
|
17
|
+
* on-disk `${VAR}` restoration in `saveConfig` keeps resolved secrets off disk.
|
|
18
|
+
*/
|
|
19
|
+
import JSON5 from "json5";
|
|
20
|
+
import { BrigadeConfigSchema, collectBrigadeConfigErrors } from "./brigade-config.js";
|
|
21
|
+
import { loadConfig, saveConfig } from "./config.js";
|
|
22
|
+
export const REDACTED_SENTINEL = "__BRIGADE_REDACTED__";
|
|
23
|
+
const SENSITIVE_SEGMENT = /^(key|apikey|token|secret|password|refreshtoken|accesstoken)$/i;
|
|
24
|
+
/* ───────────────────────── path helpers ───────────────────────── */
|
|
25
|
+
/**
|
|
26
|
+
* Parse a config path into segments. Supports dot-notation
|
|
27
|
+
* (`agents.defaults.provider`), escaped dots (`keys.foo\.bar`), bracket array
|
|
28
|
+
* indices (`a.b[0]`), and bracket literal keys (`a["my.key"]`).
|
|
29
|
+
*/
|
|
30
|
+
export function parsePath(raw) {
|
|
31
|
+
const trimmed = raw.trim();
|
|
32
|
+
if (trimmed.length === 0) {
|
|
33
|
+
throw new Error("config path is empty");
|
|
34
|
+
}
|
|
35
|
+
const segments = [];
|
|
36
|
+
let buf = "";
|
|
37
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
38
|
+
const ch = trimmed[i];
|
|
39
|
+
if (ch === "\\" && trimmed[i + 1] === ".") {
|
|
40
|
+
buf += ".";
|
|
41
|
+
i++;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (ch === ".") {
|
|
45
|
+
if (buf.length === 0) {
|
|
46
|
+
throw new Error(`empty segment in config path "${raw}"`);
|
|
47
|
+
}
|
|
48
|
+
segments.push(buf);
|
|
49
|
+
buf = "";
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (ch === "[") {
|
|
53
|
+
if (buf.length > 0) {
|
|
54
|
+
segments.push(buf);
|
|
55
|
+
buf = "";
|
|
56
|
+
}
|
|
57
|
+
const close = trimmed.indexOf("]", i);
|
|
58
|
+
if (close === -1) {
|
|
59
|
+
throw new Error(`unclosed "[" in config path "${raw}"`);
|
|
60
|
+
}
|
|
61
|
+
let inside = trimmed.slice(i + 1, close).trim();
|
|
62
|
+
if ((inside.startsWith('"') && inside.endsWith('"')) ||
|
|
63
|
+
(inside.startsWith("'") && inside.endsWith("'"))) {
|
|
64
|
+
inside = inside.slice(1, -1);
|
|
65
|
+
}
|
|
66
|
+
if (inside.length === 0) {
|
|
67
|
+
throw new Error(`empty bracket segment in config path "${raw}"`);
|
|
68
|
+
}
|
|
69
|
+
segments.push(inside);
|
|
70
|
+
i = close;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
buf += ch;
|
|
74
|
+
}
|
|
75
|
+
if (buf.length > 0)
|
|
76
|
+
segments.push(buf);
|
|
77
|
+
if (segments.length === 0) {
|
|
78
|
+
throw new Error(`unable to parse config path "${raw}"`);
|
|
79
|
+
}
|
|
80
|
+
return segments;
|
|
81
|
+
}
|
|
82
|
+
/** True iff the segment looks like a non-negative integer (array index). */
|
|
83
|
+
function isIndexSegment(seg) {
|
|
84
|
+
return /^[0-9]+$/.test(seg);
|
|
85
|
+
}
|
|
86
|
+
export function getNested(root, segments) {
|
|
87
|
+
let cur = root;
|
|
88
|
+
for (const seg of segments) {
|
|
89
|
+
if (cur === null || cur === undefined)
|
|
90
|
+
return undefined;
|
|
91
|
+
if (Array.isArray(cur) && isIndexSegment(seg)) {
|
|
92
|
+
cur = cur[Number(seg)];
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (typeof cur !== "object")
|
|
96
|
+
return undefined;
|
|
97
|
+
cur = cur[seg];
|
|
98
|
+
}
|
|
99
|
+
return cur;
|
|
100
|
+
}
|
|
101
|
+
export function setNested(root, segments, value) {
|
|
102
|
+
// biome-ignore lint/suspicious/noExplicitAny: walking an untyped config tree.
|
|
103
|
+
let cur = root;
|
|
104
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
105
|
+
const seg = segments[i] ?? "";
|
|
106
|
+
const nextSeg = segments[i + 1] ?? "";
|
|
107
|
+
const wantArray = isIndexSegment(nextSeg);
|
|
108
|
+
const existing = Array.isArray(cur) && isIndexSegment(seg) ? cur[Number(seg)] : cur[seg];
|
|
109
|
+
if (existing === undefined || existing === null || typeof existing !== "object") {
|
|
110
|
+
const fresh = wantArray ? [] : {};
|
|
111
|
+
if (Array.isArray(cur) && isIndexSegment(seg)) {
|
|
112
|
+
cur[Number(seg)] = fresh;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
cur[seg] = fresh;
|
|
116
|
+
}
|
|
117
|
+
cur = fresh;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
cur = Array.isArray(cur) && isIndexSegment(seg) ? cur[Number(seg)] : cur[seg];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const tail = segments[segments.length - 1] ?? "";
|
|
124
|
+
if (Array.isArray(cur) && isIndexSegment(tail)) {
|
|
125
|
+
cur[Number(tail)] = value;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
cur[tail] = value;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export function deleteNested(root, segments) {
|
|
132
|
+
// biome-ignore lint/suspicious/noExplicitAny: walking an untyped config tree.
|
|
133
|
+
let cur = root;
|
|
134
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
135
|
+
const seg = segments[i] ?? "";
|
|
136
|
+
const next = Array.isArray(cur) && isIndexSegment(seg) ? cur[Number(seg)] : cur?.[seg];
|
|
137
|
+
if (next === undefined || next === null || typeof next !== "object")
|
|
138
|
+
return false;
|
|
139
|
+
cur = next;
|
|
140
|
+
}
|
|
141
|
+
const tail = segments[segments.length - 1] ?? "";
|
|
142
|
+
if (Array.isArray(cur) && isIndexSegment(tail)) {
|
|
143
|
+
const idx = Number(tail);
|
|
144
|
+
if (idx < cur.length) {
|
|
145
|
+
cur.splice(idx, 1);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (cur && typeof cur === "object" && tail in cur) {
|
|
151
|
+
delete cur[tail];
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
/** JSON5-parse a CLI string value, falling back to the raw string. */
|
|
157
|
+
export function parseConfigValue(raw, opts = {}) {
|
|
158
|
+
if (opts.strictJson) {
|
|
159
|
+
return JSON.parse(raw);
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
return JSON5.parse(raw);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return raw;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/** Deep-redact any string value whose key looks secret. */
|
|
169
|
+
export function redactDeep(value) {
|
|
170
|
+
if (value === null || typeof value !== "object")
|
|
171
|
+
return value;
|
|
172
|
+
if (Array.isArray(value))
|
|
173
|
+
return value.map((v) => redactDeep(v));
|
|
174
|
+
const out = {};
|
|
175
|
+
for (const [k, v] of Object.entries(value)) {
|
|
176
|
+
if (SENSITIVE_SEGMENT.test(k) && typeof v === "string" && v.length > 0) {
|
|
177
|
+
out[k] = REDACTED_SENTINEL;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
out[k] = redactDeep(v);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
/* ───────────────────── structured operations ──────────────────── */
|
|
186
|
+
/** Read a redacted value at `rawPath`. `found:false` when the key is absent. */
|
|
187
|
+
export function configGetValue(cfg, rawPath) {
|
|
188
|
+
const value = getNested(cfg, parsePath(rawPath));
|
|
189
|
+
if (value === undefined)
|
|
190
|
+
return { found: false };
|
|
191
|
+
return { found: true, value: redactDeep(value) };
|
|
192
|
+
}
|
|
193
|
+
/** Mutate `cfg` in place: set `rawPath` to `value`. */
|
|
194
|
+
export function configSetValue(cfg, rawPath, value) {
|
|
195
|
+
setNested(cfg, parsePath(rawPath), value);
|
|
196
|
+
}
|
|
197
|
+
/** Mutate `cfg` in place: remove `rawPath`. Returns whether anything was removed. */
|
|
198
|
+
export function configUnsetValue(cfg, rawPath) {
|
|
199
|
+
return deleteNested(cfg, parsePath(rawPath));
|
|
200
|
+
}
|
|
201
|
+
export function handleConfigGet(params) {
|
|
202
|
+
const p = (params ?? {});
|
|
203
|
+
const rawPath = (p.path ?? "").trim();
|
|
204
|
+
if (!rawPath)
|
|
205
|
+
throw new Error("config.get: missing 'path'");
|
|
206
|
+
return configGetValue(loadConfig(), rawPath);
|
|
207
|
+
}
|
|
208
|
+
export function handleConfigSet(params) {
|
|
209
|
+
const p = (params ?? {});
|
|
210
|
+
const rawPath = (p.path ?? "").trim();
|
|
211
|
+
if (!rawPath)
|
|
212
|
+
throw new Error("config.set: missing 'path'");
|
|
213
|
+
const cfg = loadConfig();
|
|
214
|
+
configSetValue(cfg, rawPath, p.value);
|
|
215
|
+
saveConfig(cfg);
|
|
216
|
+
return { ok: true, path: rawPath, value: redactDeep(p.value) };
|
|
217
|
+
}
|
|
218
|
+
export function handleConfigUnset(params) {
|
|
219
|
+
const p = (params ?? {});
|
|
220
|
+
const rawPath = (p.path ?? "").trim();
|
|
221
|
+
if (!rawPath)
|
|
222
|
+
throw new Error("config.unset: missing 'path'");
|
|
223
|
+
const cfg = loadConfig();
|
|
224
|
+
const removed = configUnsetValue(cfg, rawPath);
|
|
225
|
+
if (removed)
|
|
226
|
+
saveConfig(cfg);
|
|
227
|
+
return { ok: removed, path: rawPath, removed };
|
|
228
|
+
}
|
|
229
|
+
export function handleConfigList(params) {
|
|
230
|
+
const p = (params ?? {});
|
|
231
|
+
const cfg = loadConfig();
|
|
232
|
+
return { config: p.redact === false ? cfg : redactDeep(cfg) };
|
|
233
|
+
}
|
|
234
|
+
export function handleConfigSchema(_params) {
|
|
235
|
+
return { schema: BrigadeConfigSchema };
|
|
236
|
+
}
|
|
237
|
+
export function handleConfigValidate(_params) {
|
|
238
|
+
const issues = collectBrigadeConfigErrors(loadConfig());
|
|
239
|
+
return { valid: issues.length === 0, issues };
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=config-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-ops.js","sourceRoot":"","sources":["../../src/core/config-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exec-approval operations behind the `exec.*` gateway RPCs — the
|
|
3
|
+
* `brigade exec <list|allow|allow-pattern|remove|deny-test>` surface, reachable
|
|
4
|
+
* from a remote client.
|
|
5
|
+
*
|
|
6
|
+
* OPERATOR-SCOPED, per-agent: manages an agent's bash approval allowlist. NOT
|
|
7
|
+
* session-targeted — the operator manages exec trust for their OWN agents, the
|
|
8
|
+
* same posture as the already-allowlisted `exec-grant-skill` / `exec-allow-all`
|
|
9
|
+
* RPCs. No per-session access guard is needed (and the guard-sweep allowlists
|
|
10
|
+
* these by name for that reason).
|
|
11
|
+
*
|
|
12
|
+
* All structured returns (no console I/O) so the gateway can hand them straight
|
|
13
|
+
* back to a WS client. The underlying primitives in `exec-approvals.ts` are the
|
|
14
|
+
* SAME ones the CLI calls, so `brigade exec allow` and `exec.allow` over the
|
|
15
|
+
* wire behave identically — including the hard-deny safety net.
|
|
16
|
+
*/
|
|
17
|
+
import { type ApprovalDecision } from "./exec-approvals.js";
|
|
18
|
+
export interface ExecListResult {
|
|
19
|
+
agentId: string;
|
|
20
|
+
filePath: string;
|
|
21
|
+
commands: string[];
|
|
22
|
+
patterns: string[];
|
|
23
|
+
}
|
|
24
|
+
export declare function handleExecList(params: unknown): ExecListResult;
|
|
25
|
+
export interface ExecMutateResult {
|
|
26
|
+
ok: boolean;
|
|
27
|
+
agentId: string;
|
|
28
|
+
kind?: "exact" | "pattern";
|
|
29
|
+
value?: string;
|
|
30
|
+
reason?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function handleExecAllow(params: unknown): ExecMutateResult;
|
|
33
|
+
export declare function handleExecAllowPattern(params: unknown): ExecMutateResult;
|
|
34
|
+
export interface ExecRemoveResult {
|
|
35
|
+
ok: boolean;
|
|
36
|
+
agentId: string;
|
|
37
|
+
removedCommands: number;
|
|
38
|
+
removedPatterns: number;
|
|
39
|
+
reason?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare function handleExecRemove(params: unknown): ExecRemoveResult;
|
|
42
|
+
export interface ExecDenyTestResult {
|
|
43
|
+
agentId: string;
|
|
44
|
+
command: string;
|
|
45
|
+
decision: ApprovalDecision;
|
|
46
|
+
}
|
|
47
|
+
export declare function handleExecDenyTest(params: unknown): ExecDenyTestResult;
|
|
48
|
+
//# sourceMappingURL=exec-ops.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-ops.d.ts","sourceRoot":"","sources":["../../src/core/exec-ops.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACN,KAAK,gBAAgB,EAOrB,MAAM,qBAAqB,CAAC;AAO7B,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AACD,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CAK9D;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAejE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAiBxE;AAED,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AACD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,gBAAgB,CAsBlE;AAED,MAAM,WAAW,kBAAkB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,gBAAgB,CAAC;CAC3B;AACD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,kBAAkB,CAKtE"}
|