@cotal-ai/cli 0.51.0 → 0.52.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/dist/command.d.ts.map +1 -1
- package/dist/command.js +8 -0
- package/dist/command.js.map +1 -1
- package/dist/commands/agents.d.ts +41 -2
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +67 -18
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/clean.d.ts.map +1 -1
- package/dist/commands/clean.js +5 -1
- package/dist/commands/clean.js.map +1 -1
- package/dist/commands/console.d.ts.map +1 -1
- package/dist/commands/console.js +9 -1
- package/dist/commands/console.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +13 -8
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/down.d.ts.map +1 -1
- package/dist/commands/down.js +38 -3
- package/dist/commands/down.js.map +1 -1
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +9 -8
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/spawn.d.ts.map +1 -1
- package/dist/commands/spawn.js +18 -2
- package/dist/commands/spawn.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +122 -35
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/up.d.ts +7 -0
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +104 -11
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/update.d.ts +12 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +58 -5
- package/dist/commands/update.js.map +1 -1
- package/dist/console/app.d.ts +14 -6
- package/dist/console/app.d.ts.map +1 -1
- package/dist/console/app.js +308 -40
- package/dist/console/app.js.map +1 -1
- package/dist/console/commands.d.ts +29 -1
- package/dist/console/commands.d.ts.map +1 -1
- package/dist/console/commands.js +109 -13
- package/dist/console/commands.js.map +1 -1
- package/dist/console/control.d.ts +141 -0
- package/dist/console/control.d.ts.map +1 -0
- package/dist/console/control.js +189 -0
- package/dist/console/control.js.map +1 -0
- package/dist/console/mesh.d.ts +1 -1
- package/dist/console/mesh.d.ts.map +1 -1
- package/dist/console/root.d.ts +13 -1
- package/dist/console/root.d.ts.map +1 -1
- package/dist/console/root.js +25 -5
- package/dist/console/root.js.map +1 -1
- package/dist/console/ui/CommandPalette.d.ts +2 -1
- package/dist/console/ui/CommandPalette.d.ts.map +1 -1
- package/dist/console/ui/CommandPalette.js +3 -2
- package/dist/console/ui/CommandPalette.js.map +1 -1
- package/dist/console/ui/Confirm.d.ts +13 -4
- package/dist/console/ui/Confirm.d.ts.map +1 -1
- package/dist/console/ui/Confirm.js +13 -5
- package/dist/console/ui/Confirm.js.map +1 -1
- package/dist/console/ui/Detail.d.ts +8 -1
- package/dist/console/ui/Detail.d.ts.map +1 -1
- package/dist/console/ui/Detail.js +11 -4
- package/dist/console/ui/Detail.js.map +1 -1
- package/dist/console/ui/Help.d.ts.map +1 -1
- package/dist/console/ui/Help.js +3 -2
- package/dist/console/ui/Help.js.map +1 -1
- package/dist/console/ui/Roster.d.ts +9 -1
- package/dist/console/ui/Roster.d.ts.map +1 -1
- package/dist/console/ui/Roster.js +16 -5
- package/dist/console/ui/Roster.js.map +1 -1
- package/dist/console/ui/Sparkline.d.ts +13 -0
- package/dist/console/ui/Sparkline.d.ts.map +1 -0
- package/dist/console/ui/Sparkline.js +21 -0
- package/dist/console/ui/Sparkline.js.map +1 -0
- package/dist/console/ui/StatusBar.d.ts +4 -1
- package/dist/console/ui/StatusBar.d.ts.map +1 -1
- package/dist/console/ui/StatusBar.js +5 -3
- package/dist/console/ui/StatusBar.js.map +1 -1
- package/dist/console/ui/Tabs.d.ts +4 -2
- package/dist/console/ui/Tabs.d.ts.map +1 -1
- package/dist/console/ui/Tabs.js +5 -3
- package/dist/console/ui/Tabs.js.map +1 -1
- package/dist/console/ui/topo/Map.d.ts.map +1 -1
- package/dist/console/ui/topo/Map.js +34 -2
- package/dist/console/ui/topo/Map.js.map +1 -1
- package/dist/console/ui/topo/Matrix.d.ts.map +1 -1
- package/dist/console/ui/topo/Matrix.js +12 -3
- package/dist/console/ui/topo/Matrix.js.map +1 -1
- package/dist/console/ui/topo/Sequence.js +1 -1
- package/dist/console/ui/topo/Sequence.js.map +1 -1
- package/dist/console/ui/topo/Topo.d.ts +10 -2
- package/dist/console/ui/topo/Topo.d.ts.map +1 -1
- package/dist/console/ui/topo/Topo.js +6 -4
- package/dist/console/ui/topo/Topo.js.map +1 -1
- package/dist/console/ui/topo/model.d.ts +50 -2
- package/dist/console/ui/topo/model.d.ts.map +1 -1
- package/dist/console/ui/topo/model.js +69 -6
- package/dist/console/ui/topo/model.js.map +1 -1
- package/dist/lib/attach-client.d.ts.map +1 -1
- package/dist/lib/attach-client.js +7 -1
- package/dist/lib/attach-client.js.map +1 -1
- package/dist/lib/delivery-proc.d.ts +10 -2
- package/dist/lib/delivery-proc.d.ts.map +1 -1
- package/dist/lib/delivery-proc.js +7 -1
- package/dist/lib/delivery-proc.js.map +1 -1
- package/dist/view/mesh-view.d.ts +41 -1
- package/dist/view/mesh-view.d.ts.map +1 -1
- package/dist/view/mesh-view.js +107 -8
- package/dist/view/mesh-view.js.map +1 -1
- package/package.json +13 -6
package/dist/console/commands.js
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
// The console's `:` command catalog — the operator's send/control verbs. A small local list (NOT
|
|
2
2
|
// the CLI `Command` registry, which is argv/process-exit shaped). The catalog drives both execution
|
|
3
3
|
// and the palette's autocomplete. Write commands publish over the mesh via the observer endpoint;
|
|
4
|
-
// they are gated on `canWrite` (open mode, or a privileged --creds).
|
|
4
|
+
// they are gated on `canWrite` (open mode, or a privileged --creds). Control commands go through
|
|
5
|
+
// `ctx.control` (one per-action call on the CLI's control path, console/control.ts), gated on
|
|
6
|
+
// `canControl`; the observer endpoint never carries control.
|
|
5
7
|
import { resolvePeer, AmbiguousPeerError } from "@cotal-ai/core";
|
|
6
8
|
import { mentionsIn } from "../lib/mentions.js";
|
|
9
|
+
/** The reply's error, or a generic word: the status line has one row. */
|
|
10
|
+
const why = (r) => r.error ?? "failed";
|
|
11
|
+
/** One managed-agent row as `:status` prints it. Two facts, printed as two facts, the way
|
|
12
|
+
* `cotal ps` prints them: `status` is the PROCESS the manager runs and `mesh` is that seat's
|
|
13
|
+
* presence, and they disagree in the common failure (running for days, offline on the mesh).
|
|
14
|
+
*
|
|
15
|
+
* Presence `working` is the one word that needs qualifying. It records that the seat said it was
|
|
16
|
+
* working, never that anyone observed progress, so it reaches the reader as `working · progress
|
|
17
|
+
* unknown` here exactly as it does from `cotal ps`, the roster, and the connector's orientation.
|
|
18
|
+
* A bare `working` would claim an observation the manager never made. */
|
|
19
|
+
export function formatManagedRow(a) {
|
|
20
|
+
const mesh = a.mesh === "working" ? "working · progress unknown" : a.mesh;
|
|
21
|
+
const role = a.role ? ` (${a.role})` : "";
|
|
22
|
+
return `${a.name}${role} · ${a.agent} · ${a.mode} · ${a.status} · mesh ${mesh} · up ${Math.round(a.uptimeMs / 60000)}m`;
|
|
23
|
+
}
|
|
7
24
|
/** Resolve an agent/endpoint name (with or without a leading @) to its instance id. Fail-loud:
|
|
8
25
|
* an exact id or a unique name resolves; a same-name collision throws `AmbiguousPeerError`
|
|
9
26
|
* (the caller renders {@link ambiguityNote}). */
|
|
@@ -30,6 +47,8 @@ export const COMMANDS = [
|
|
|
30
47
|
}
|
|
31
48
|
if (!text.trim())
|
|
32
49
|
return ctx.notify("usage: msg [#channel] <text>");
|
|
50
|
+
if (!(await ctx.ensureParticipant()))
|
|
51
|
+
return;
|
|
33
52
|
await ctx.ep.multicast(text, { channel, mentions: mentionsIn(text) });
|
|
34
53
|
ctx.notify(`→ #${channel}`);
|
|
35
54
|
},
|
|
@@ -54,6 +73,8 @@ export const COMMANDS = [
|
|
|
54
73
|
}
|
|
55
74
|
if (!id)
|
|
56
75
|
return ctx.notify(`no agent "${m[1]}"`);
|
|
76
|
+
if (!(await ctx.ensureParticipant()))
|
|
77
|
+
return;
|
|
57
78
|
await ctx.ep.unicast(id, m[2]);
|
|
58
79
|
ctx.notify(`→ ${m[1].replace(/^@/, "")}`);
|
|
59
80
|
},
|
|
@@ -76,6 +97,8 @@ export const COMMANDS = [
|
|
|
76
97
|
}
|
|
77
98
|
if (!id)
|
|
78
99
|
return ctx.notify(`no agent "${name}"`);
|
|
100
|
+
if (!(await ctx.ensureParticipant()))
|
|
101
|
+
return;
|
|
79
102
|
await ctx.ep.unicast(id, "👋 ping");
|
|
80
103
|
ctx.setMode("dm");
|
|
81
104
|
ctx.notify(`called ${name}`);
|
|
@@ -90,6 +113,8 @@ export const COMMANDS = [
|
|
|
90
113
|
const m = rest.match(/^@?(\S+)\s+([\s\S]+)/);
|
|
91
114
|
if (!m)
|
|
92
115
|
return ctx.notify("usage: ask <@role> <text>");
|
|
116
|
+
if (!(await ctx.ensureParticipant()))
|
|
117
|
+
return;
|
|
93
118
|
await ctx.ep.anycast(m[1], m[2]);
|
|
94
119
|
ctx.notify(`→ @${m[1]}`);
|
|
95
120
|
},
|
|
@@ -97,17 +122,84 @@ export const COMMANDS = [
|
|
|
97
122
|
{
|
|
98
123
|
name: "ps",
|
|
99
124
|
summary: "list manager-spawned agents",
|
|
125
|
+
control: true,
|
|
100
126
|
run: async (ctx) => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
127
|
+
const r = await ctx.ps();
|
|
128
|
+
if (!r.ok)
|
|
129
|
+
return ctx.notify("ps: " + r.error);
|
|
130
|
+
// A silent or failed instance is named, never dropped: without it a merged list short by a
|
|
131
|
+
// whole manager's seats reads as the complete managed set of the space.
|
|
132
|
+
const issues = [
|
|
133
|
+
...r.failed.map((f) => `${f.instanceId}: ${f.error}`),
|
|
134
|
+
...(r.silent.length ? [`${r.silent.length} manager instance(s) gave no answer: ${r.silent.join(", ")}`] : []),
|
|
135
|
+
];
|
|
136
|
+
const partial = issues.length ? ` (${issues.join("; ")})` : "";
|
|
137
|
+
ctx.notify((r.rows.length ? "agents: " + r.rows.map((a) => a.name).join(", ") : "no managed agents") + partial);
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "spawn",
|
|
142
|
+
summary: "spawn an agent from a persona (waits for it to join)",
|
|
143
|
+
usage: "spawn <persona> [name]",
|
|
144
|
+
control: true,
|
|
145
|
+
run: async (ctx, rest) => {
|
|
146
|
+
const [persona, identity] = rest.trim().split(/\s+/).filter(Boolean);
|
|
147
|
+
if (!persona)
|
|
148
|
+
return ctx.notify("usage: spawn <persona> [name]");
|
|
149
|
+
ctx.notify(`spawning ${persona}… (the manager answers on join, exit, or its readiness deadline)`);
|
|
150
|
+
// The event plane is on by default since #1758, and a connector that cannot publish one is
|
|
151
|
+
// refused by the manager. The palette has no events toggle (nothing here consumes the plane),
|
|
152
|
+
// so it mirrors `cotal spawn --no-events`: a seat spawned from the console is spawned to be
|
|
153
|
+
// watched and driven here, and the plane is the connector's own concern.
|
|
154
|
+
const r = await ctx.control("start", identity ? { name: persona, identity, events: false } : { name: persona, events: false });
|
|
155
|
+
if (!r.ok)
|
|
156
|
+
return ctx.notify("spawn: " + why(r));
|
|
157
|
+
ctx.notify(`spawned ${r.data?.name ?? persona}`);
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "status",
|
|
162
|
+
summary: "one managed agent's state",
|
|
163
|
+
usage: "status <agent>",
|
|
164
|
+
control: true,
|
|
165
|
+
run: async (ctx, rest) => {
|
|
166
|
+
const name = rest.replace(/^@/, "").trim().split(/\s+/)[0] ?? "";
|
|
167
|
+
if (!name)
|
|
168
|
+
return ctx.notify("usage: status <agent>");
|
|
169
|
+
const r = await ctx.control("status", { name });
|
|
170
|
+
if (!r.ok)
|
|
171
|
+
return ctx.notify("status: " + why(r));
|
|
172
|
+
ctx.notify(formatManagedRow(r.data));
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: "attach",
|
|
177
|
+
summary: "open a managed seat's terminal (Ctrl-] to detach)",
|
|
178
|
+
usage: "attach <agent>",
|
|
179
|
+
control: true,
|
|
180
|
+
run: (ctx, rest) => {
|
|
181
|
+
const name = rest.replace(/^@/, "").trim().split(/\s+/)[0] ?? "";
|
|
182
|
+
if (!name)
|
|
183
|
+
return ctx.notify("usage: attach <agent>");
|
|
184
|
+
ctx.startAttach(name);
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: "purge",
|
|
189
|
+
summary: "clear the space's history (type the space name to confirm)",
|
|
190
|
+
control: true,
|
|
191
|
+
run: (ctx) => ctx.confirmPurge(),
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: "delchan",
|
|
195
|
+
summary: "delete one channel's history + registry entry (type its name to confirm)",
|
|
196
|
+
usage: "delchan <channel>",
|
|
197
|
+
control: true,
|
|
198
|
+
run: (ctx, rest) => {
|
|
199
|
+
const channel = rest.replace(/^#/, "").trim().split(/\s+/)[0] ?? "";
|
|
200
|
+
if (!channel)
|
|
201
|
+
return ctx.notify("usage: delchan <channel>");
|
|
202
|
+
ctx.confirmDelchan(channel);
|
|
111
203
|
},
|
|
112
204
|
},
|
|
113
205
|
{ name: "dms", summary: "toggle the DM lens", run: (ctx) => ctx.setMode("dm") },
|
|
@@ -118,7 +210,7 @@ export const COMMANDS = [
|
|
|
118
210
|
{ name: "quit", summary: "quit the console", run: (ctx) => ctx.exit() },
|
|
119
211
|
];
|
|
120
212
|
/** Parse + dispatch a typed palette line. Unknown / read-only-blocked commands notify and no-op. */
|
|
121
|
-
export function runCommand(line, ctx, canWrite) {
|
|
213
|
+
export function runCommand(line, ctx, canWrite, canControl) {
|
|
122
214
|
const trimmed = line.trim();
|
|
123
215
|
if (!trimmed)
|
|
124
216
|
return;
|
|
@@ -129,6 +221,10 @@ export function runCommand(line, ctx, canWrite) {
|
|
|
129
221
|
return ctx.notify(`unknown command: ${name}`);
|
|
130
222
|
if (cmd.write && !canWrite)
|
|
131
223
|
return ctx.notify("read-only - pass --creds to send");
|
|
132
|
-
|
|
224
|
+
if (cmd.control && !canControl)
|
|
225
|
+
return ctx.notify("no control path - a raw --creds file cannot drive the manager; run against a registered mesh");
|
|
226
|
+
// A verb that throws (a control call that could not even start) lands on the status line rather
|
|
227
|
+
// than as an unhandled rejection that would take the console down over one bad line.
|
|
228
|
+
void Promise.resolve(cmd.run(ctx, rest)).catch((e) => ctx.notify(`${name}: ${e.message}`));
|
|
133
229
|
}
|
|
134
230
|
//# sourceMappingURL=commands.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/console/commands.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,oGAAoG;AACpG,kGAAkG;AAClG,
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/console/commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { type ManagerReply } from "../lib/control.js";
|
|
2
|
+
import { type ConnectFlags } from "../lib/connect.js";
|
|
3
|
+
/** The console's control coordinates: the same `ConnectFlags` triple the CLI's control commands
|
|
4
|
+
* resolve from. `space` is the one the console is currently watching. */
|
|
5
|
+
export type ControlCtx = ConnectFlags;
|
|
6
|
+
/** The manager ops the console drives, each with the instrument profile the matching CLI command
|
|
7
|
+
* mints and whether the op names a seat (a targeted op resolves seat locality first, so it is
|
|
8
|
+
* served by the manager actually hosting the seat). */
|
|
9
|
+
declare const OPS: {
|
|
10
|
+
readonly status: {
|
|
11
|
+
readonly profile: "control-caller-privileged";
|
|
12
|
+
readonly targeted: true;
|
|
13
|
+
};
|
|
14
|
+
readonly start: {
|
|
15
|
+
readonly profile: "control-caller-privileged";
|
|
16
|
+
readonly targeted: false;
|
|
17
|
+
readonly timeoutMs: 40000;
|
|
18
|
+
};
|
|
19
|
+
readonly purge: {
|
|
20
|
+
readonly profile: "control-caller-admin";
|
|
21
|
+
readonly targeted: false;
|
|
22
|
+
};
|
|
23
|
+
readonly stop: {
|
|
24
|
+
readonly profile: "control-caller-admin";
|
|
25
|
+
readonly targeted: true;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export type ControlOp = keyof typeof OPS;
|
|
29
|
+
/** Delete one channel: its retained history (a filtered purge) and its registry entry, through
|
|
30
|
+
* core's `clearChannel`, the operation the web dashboard's delete button runs, with the same
|
|
31
|
+
* per-action authority: a static-auth mesh mints a one-shot `channel-purger` credential from the
|
|
32
|
+
* resolved mesh's seed, a user mesh asks for a `channel-purger` view (a fresh ledger check per
|
|
33
|
+
* click), an open mesh connects bare. No manager involved. The name must be the one the mesh
|
|
34
|
+
* uses, concrete and valid: a wildcard is refused (it would purge channels the operator did not
|
|
35
|
+
* name) and a name the wire would rewrite is refused rather than quietly rewritten. */
|
|
36
|
+
export declare function deleteChannel(ctx: ControlCtx, channel: string): Promise<{
|
|
37
|
+
ok: true;
|
|
38
|
+
purged: number;
|
|
39
|
+
} | {
|
|
40
|
+
ok: false;
|
|
41
|
+
error: string;
|
|
42
|
+
}>;
|
|
43
|
+
/** One managed-agent row as the manager's `ps` / `inspect` answer it (the fields the console reads). */
|
|
44
|
+
export interface ManagedRow {
|
|
45
|
+
name: string;
|
|
46
|
+
id: string;
|
|
47
|
+
role?: string;
|
|
48
|
+
agent: string;
|
|
49
|
+
mode: string;
|
|
50
|
+
status: string;
|
|
51
|
+
uptimeMs: number;
|
|
52
|
+
mesh: string;
|
|
53
|
+
model?: string;
|
|
54
|
+
}
|
|
55
|
+
/** One control call. A targeted op names its seat in `args.name`; the alias is resolved to the
|
|
56
|
+
* incarnation triple inside `askManager` (the manager's `inspect` read), so the wire never carries
|
|
57
|
+
* a name as a target. Reach is `owner` on a user mesh (the bearer's one path; the manager decides
|
|
58
|
+
* by ledger scope) and `any` on a static or open mesh (the admin instrument's cross-agent row). */
|
|
59
|
+
export declare function control(ctx: ControlCtx, op: ControlOp, args?: Record<string, unknown>): Promise<ManagerReply>;
|
|
60
|
+
/** The managed rows of every reachable manager in the space: the `cotal ps` read.
|
|
61
|
+
*
|
|
62
|
+
* `rows` is the merged list, `silent` the instances that did not answer, `failed` the reachable
|
|
63
|
+
* instances that answered with an error, and `answered` the rows attributed to the instance that
|
|
64
|
+
* served them. The attribution is what makes a partial answer
|
|
65
|
+
* usable: a caller holding state across polls can replace exactly the instances that spoke and
|
|
66
|
+
* keep only what a silent one last said, which neither a merged list nor a flat rebuild allows.
|
|
67
|
+
* `cotal ps` prints a silent instance rather than dropping it, and the console must not be the
|
|
68
|
+
* one surface that quietly answers a narrower question than the one asked. */
|
|
69
|
+
export type PsReply = {
|
|
70
|
+
ok: true;
|
|
71
|
+
rows: ManagedRow[];
|
|
72
|
+
silent: string[];
|
|
73
|
+
failed: {
|
|
74
|
+
instanceId: string;
|
|
75
|
+
error: string;
|
|
76
|
+
}[];
|
|
77
|
+
answered: {
|
|
78
|
+
instanceId: string;
|
|
79
|
+
rows: ManagedRow[];
|
|
80
|
+
}[];
|
|
81
|
+
} | {
|
|
82
|
+
ok: false;
|
|
83
|
+
error: string;
|
|
84
|
+
};
|
|
85
|
+
/** Fold one ps answer into the rows held per manager instance, which is the only shape that can
|
|
86
|
+
* both DROP a despawned seat and KEEP a quiet manager's seats.
|
|
87
|
+
*
|
|
88
|
+
* An instance that answered has its rows replaced wholesale, so a seat it no longer lists is gone
|
|
89
|
+
* on that tick. An instance that was asked and stayed silent keeps what it last said, because a
|
|
90
|
+
* seat is not gone just because nobody could be reached to ask about it. An instance that is
|
|
91
|
+
* neither has left the registry, and its rows leave with it.
|
|
92
|
+
*
|
|
93
|
+
* A flat merge across instances cannot express the first of those: it can add and overwrite but
|
|
94
|
+
* never delete, so one silent registration, which can persist indefinitely when a manager's host
|
|
95
|
+
* dies without deregistering, would freeze every other manager's seats in place forever. A flat
|
|
96
|
+
* rebuild is the opposite error, emptying a quiet manager's seats off the display. */
|
|
97
|
+
export declare function foldManagedRows(prev: Map<string, ManagedRow[]>, reply: {
|
|
98
|
+
answered: {
|
|
99
|
+
instanceId: string;
|
|
100
|
+
rows: ManagedRow[];
|
|
101
|
+
}[];
|
|
102
|
+
silent: string[];
|
|
103
|
+
}): Map<string, ManagedRow[]>;
|
|
104
|
+
/** The per-instance rows flattened to the id-keyed harness facts the roster and detail card read. */
|
|
105
|
+
export declare function managedById(byInstance: Map<string, ManagedRow[]>): Map<string, {
|
|
106
|
+
agent?: string;
|
|
107
|
+
mode?: string;
|
|
108
|
+
}>;
|
|
109
|
+
/** What one tick did, so a caller (and a test) can tell the three apart. */
|
|
110
|
+
export type PollOutcome = "applied" | "skipped" | "stopped";
|
|
111
|
+
/** The managed-row poll, SINGLE FLIGHT. One read may outlast the interval that scheduled it: the
|
|
112
|
+
* scatter alone budgets a service resolve, a gather and a reconcile, and the resolve and mint in
|
|
113
|
+
* front of it are additional. Left unguarded, two reads overlap and are applied in COMPLETION
|
|
114
|
+
* order rather than request order, so an older answer can land after a newer one and restore the
|
|
115
|
+
* very rows the newer one retired. That is the fold's own guarantee undone one layer up, and no
|
|
116
|
+
* test of the fold can see it.
|
|
117
|
+
*
|
|
118
|
+
* A tick while a read is in flight is therefore skipped outright rather than queued: the state is
|
|
119
|
+
* a snapshot of the whole space, so a skipped tick loses nothing that the next one will not carry,
|
|
120
|
+
* and skipping also bounds how much control traffic a slow mesh can accumulate. Being single
|
|
121
|
+
* flight is also what keeps a STALE FAILURE from stopping the poll after a newer success, since
|
|
122
|
+
* there can be no newer success in flight to race.
|
|
123
|
+
*
|
|
124
|
+
* Stopping on a failed read is deliberate and reported by the caller: an open mesh with no
|
|
125
|
+
* supervisor must not knock every tick. */
|
|
126
|
+
export declare function createManagedPoller(read: () => Promise<PsReply>, on: {
|
|
127
|
+
rows(flat: Map<string, {
|
|
128
|
+
agent?: string;
|
|
129
|
+
mode?: string;
|
|
130
|
+
}>): void;
|
|
131
|
+
partial(silent: string[], failed: {
|
|
132
|
+
instanceId: string;
|
|
133
|
+
error: string;
|
|
134
|
+
}[]): void;
|
|
135
|
+
stopped(error: string): void;
|
|
136
|
+
}): {
|
|
137
|
+
tick(): Promise<PollOutcome>;
|
|
138
|
+
};
|
|
139
|
+
export declare function controlPs(ctx: ControlCtx): Promise<PsReply>;
|
|
140
|
+
export {};
|
|
141
|
+
//# sourceMappingURL=control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../../src/console/control.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// The console's control door: every operator action (kill / spawn / purge / status) is ONE call
|
|
2
|
+
// through the CLI's own per-action path (`ps` is the scatter below, one call per manager) — `resolveControlTarget` resolves
|
|
3
|
+
// the mesh and mints a one-shot instrument (or connects bare on an open mesh), `askManager` rides
|
|
4
|
+
// the ep rails, and nothing survives the call. The observer endpoint the console watches through
|
|
5
|
+
// never carries control, and the console never holds a seed or a standing instrument: the only
|
|
6
|
+
// thing it keeps is the `--space` / `--server` / `--creds` triple the CLI's control commands take.
|
|
7
|
+
//
|
|
8
|
+
// Every refusal comes back as a `{ok:false, error}` the status line can show. The THROWING resolve
|
|
9
|
+
// form is used throughout (`onRefusal: "throw"`): the CLI commands' default prints a sentence and
|
|
10
|
+
// exits the process, which inside a TUI would blank the screen mid-session.
|
|
11
|
+
import { assertValidChannel, clearChannel, isConcreteChannel } from "@cotal-ai/core";
|
|
12
|
+
import { askManager, resolveControlTarget, scatterManager, START_TIMEOUT_MS } from "../lib/control.js";
|
|
13
|
+
import { connectOrThrow, userViewAuth } from "../lib/connect.js";
|
|
14
|
+
import { locateSeat, seatNotFoundMessage } from "../commands/agents.js";
|
|
15
|
+
/** The manager ops the console drives, each with the instrument profile the matching CLI command
|
|
16
|
+
* mints and whether the op names a seat (a targeted op resolves seat locality first, so it is
|
|
17
|
+
* served by the manager actually hosting the seat). */
|
|
18
|
+
const OPS = {
|
|
19
|
+
// `status` is `inspect` on the manager that HOSTS the seat: a multi-manager space answers a
|
|
20
|
+
// class-queue call from whichever manager is quickest, which may not be the host, and reports a
|
|
21
|
+
// false miss. Located and pinned like `stop`.
|
|
22
|
+
status: { profile: "control-caller-privileged", targeted: true },
|
|
23
|
+
start: { profile: "control-caller-privileged", targeted: false, timeoutMs: START_TIMEOUT_MS },
|
|
24
|
+
purge: { profile: "control-caller-admin", targeted: false },
|
|
25
|
+
stop: { profile: "control-caller-admin", targeted: true },
|
|
26
|
+
};
|
|
27
|
+
/** Delete one channel: its retained history (a filtered purge) and its registry entry, through
|
|
28
|
+
* core's `clearChannel`, the operation the web dashboard's delete button runs, with the same
|
|
29
|
+
* per-action authority: a static-auth mesh mints a one-shot `channel-purger` credential from the
|
|
30
|
+
* resolved mesh's seed, a user mesh asks for a `channel-purger` view (a fresh ledger check per
|
|
31
|
+
* click), an open mesh connects bare. No manager involved. The name must be the one the mesh
|
|
32
|
+
* uses, concrete and valid: a wildcard is refused (it would purge channels the operator did not
|
|
33
|
+
* name) and a name the wire would rewrite is refused rather than quietly rewritten. */
|
|
34
|
+
export async function deleteChannel(ctx, channel) {
|
|
35
|
+
try {
|
|
36
|
+
assertValidChannel(channel);
|
|
37
|
+
if (!isConcreteChannel(channel))
|
|
38
|
+
return { ok: false, error: `"${channel}" is a wildcard, not a deletable channel` };
|
|
39
|
+
const conn = await connectOrThrow(ctx, "channel-purger");
|
|
40
|
+
const r = conn.bearer
|
|
41
|
+
? await userViewAuth(conn, "channel-purger").then((p) => clearChannel({ servers: conn.server, space: conn.space, channel, bearer: p.bearer, sentinelCreds: p.sentinelCreds }))
|
|
42
|
+
: await clearChannel({ servers: conn.server, space: conn.space, channel, creds: conn.creds });
|
|
43
|
+
return { ok: true, purged: r.purged };
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
return { ok: false, error: e.message };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** One control call. A targeted op names its seat in `args.name`; the alias is resolved to the
|
|
50
|
+
* incarnation triple inside `askManager` (the manager's `inspect` read), so the wire never carries
|
|
51
|
+
* a name as a target. Reach is `owner` on a user mesh (the bearer's one path; the manager decides
|
|
52
|
+
* by ledger scope) and `any` on a static or open mesh (the admin instrument's cross-agent row). */
|
|
53
|
+
export async function control(ctx, op, args) {
|
|
54
|
+
const spec = OPS[op];
|
|
55
|
+
try {
|
|
56
|
+
let on;
|
|
57
|
+
if (spec.targeted) {
|
|
58
|
+
const name = String(args?.name ?? "").trim();
|
|
59
|
+
if (!name)
|
|
60
|
+
return { ok: false, error: `${op} requires a name` };
|
|
61
|
+
const loc = await locateSeat(ctx, name, { onRefusal: "throw" });
|
|
62
|
+
if (loc.kind === "absent")
|
|
63
|
+
return { ok: false, error: seatNotFoundMessage(loc, name) };
|
|
64
|
+
if (loc.kind === "pin")
|
|
65
|
+
on = loc.instanceId;
|
|
66
|
+
}
|
|
67
|
+
const t = await resolveControlTarget(ctx, spec.profile, on, { onRefusal: "throw" });
|
|
68
|
+
const reach = t.auth.bearer ? "owner" : "any";
|
|
69
|
+
const timeoutMs = "timeoutMs" in spec ? spec.timeoutMs : undefined;
|
|
70
|
+
// `args` goes through as given: a void-input command is refused by the manager's schema when it
|
|
71
|
+
// is handed `{}` instead of nothing, so no default is filled in here.
|
|
72
|
+
return await askManager(t.space, t.server, op, args, t.auth, reach, timeoutMs, spec.targeted ? { instanceId: on } : undefined);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
return { ok: false, error: e.message };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** The single manager a user-mesh bearer reaches, which has no scatter and therefore no instance
|
|
79
|
+
* id of its own. A caller keeping rows per instance needs one key for it. */
|
|
80
|
+
const BEARER_INSTANCE = "owner";
|
|
81
|
+
/** Fold one ps answer into the rows held per manager instance, which is the only shape that can
|
|
82
|
+
* both DROP a despawned seat and KEEP a quiet manager's seats.
|
|
83
|
+
*
|
|
84
|
+
* An instance that answered has its rows replaced wholesale, so a seat it no longer lists is gone
|
|
85
|
+
* on that tick. An instance that was asked and stayed silent keeps what it last said, because a
|
|
86
|
+
* seat is not gone just because nobody could be reached to ask about it. An instance that is
|
|
87
|
+
* neither has left the registry, and its rows leave with it.
|
|
88
|
+
*
|
|
89
|
+
* A flat merge across instances cannot express the first of those: it can add and overwrite but
|
|
90
|
+
* never delete, so one silent registration, which can persist indefinitely when a manager's host
|
|
91
|
+
* dies without deregistering, would freeze every other manager's seats in place forever. A flat
|
|
92
|
+
* rebuild is the opposite error, emptying a quiet manager's seats off the display. */
|
|
93
|
+
export function foldManagedRows(prev, reply) {
|
|
94
|
+
const next = new Map(prev);
|
|
95
|
+
for (const id of [...next.keys()])
|
|
96
|
+
if (!reply.answered.some((a) => a.instanceId === id) && !reply.silent.includes(id))
|
|
97
|
+
next.delete(id);
|
|
98
|
+
for (const a of reply.answered)
|
|
99
|
+
next.set(a.instanceId, a.rows);
|
|
100
|
+
return next;
|
|
101
|
+
}
|
|
102
|
+
/** The per-instance rows flattened to the id-keyed harness facts the roster and detail card read. */
|
|
103
|
+
export function managedById(byInstance) {
|
|
104
|
+
const flat = new Map();
|
|
105
|
+
for (const rows of byInstance.values())
|
|
106
|
+
for (const a of rows)
|
|
107
|
+
flat.set(a.id, { agent: a.agent, mode: a.mode });
|
|
108
|
+
return flat;
|
|
109
|
+
}
|
|
110
|
+
/** The managed-row poll, SINGLE FLIGHT. One read may outlast the interval that scheduled it: the
|
|
111
|
+
* scatter alone budgets a service resolve, a gather and a reconcile, and the resolve and mint in
|
|
112
|
+
* front of it are additional. Left unguarded, two reads overlap and are applied in COMPLETION
|
|
113
|
+
* order rather than request order, so an older answer can land after a newer one and restore the
|
|
114
|
+
* very rows the newer one retired. That is the fold's own guarantee undone one layer up, and no
|
|
115
|
+
* test of the fold can see it.
|
|
116
|
+
*
|
|
117
|
+
* A tick while a read is in flight is therefore skipped outright rather than queued: the state is
|
|
118
|
+
* a snapshot of the whole space, so a skipped tick loses nothing that the next one will not carry,
|
|
119
|
+
* and skipping also bounds how much control traffic a slow mesh can accumulate. Being single
|
|
120
|
+
* flight is also what keeps a STALE FAILURE from stopping the poll after a newer success, since
|
|
121
|
+
* there can be no newer success in flight to race.
|
|
122
|
+
*
|
|
123
|
+
* Stopping on a failed read is deliberate and reported by the caller: an open mesh with no
|
|
124
|
+
* supervisor must not knock every tick. */
|
|
125
|
+
export function createManagedPoller(read, on) {
|
|
126
|
+
let byInstance = new Map();
|
|
127
|
+
let inFlight = false;
|
|
128
|
+
let stopped = false;
|
|
129
|
+
let announcedPartial = "";
|
|
130
|
+
return {
|
|
131
|
+
async tick() {
|
|
132
|
+
if (stopped)
|
|
133
|
+
return "stopped";
|
|
134
|
+
if (inFlight)
|
|
135
|
+
return "skipped";
|
|
136
|
+
inFlight = true;
|
|
137
|
+
try {
|
|
138
|
+
const r = await read();
|
|
139
|
+
if (!r.ok) {
|
|
140
|
+
stopped = true;
|
|
141
|
+
on.stopped(r.error);
|
|
142
|
+
return "stopped";
|
|
143
|
+
}
|
|
144
|
+
const partialKey = JSON.stringify({ silent: r.silent, failed: r.failed });
|
|
145
|
+
if ((r.silent.length || r.failed.length) && partialKey !== announcedPartial) {
|
|
146
|
+
announcedPartial = partialKey;
|
|
147
|
+
on.partial(r.silent, r.failed);
|
|
148
|
+
}
|
|
149
|
+
if (!r.silent.length && !r.failed.length)
|
|
150
|
+
announcedPartial = "";
|
|
151
|
+
byInstance = foldManagedRows(byInstance, r);
|
|
152
|
+
on.rows(managedById(byInstance));
|
|
153
|
+
return "applied";
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
inFlight = false;
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
export async function controlPs(ctx) {
|
|
162
|
+
try {
|
|
163
|
+
const t = await resolveControlTarget(ctx, "control-caller-privileged", undefined, { onRefusal: "throw" });
|
|
164
|
+
if (t.auth.bearer) {
|
|
165
|
+
const r = await askManager(t.space, t.server, "ps", undefined, t.auth, "owner", undefined, {});
|
|
166
|
+
if (!r.ok)
|
|
167
|
+
return { ok: false, error: r.error ?? "error" };
|
|
168
|
+
const rows = r.data ?? [];
|
|
169
|
+
return { ok: true, rows, silent: [], failed: [], answered: [{ instanceId: BEARER_INSTANCE, rows }] };
|
|
170
|
+
}
|
|
171
|
+
const s = await scatterManager(t.space, t.server, "ps", t.auth, t.spaceAuth);
|
|
172
|
+
if (!s.ok)
|
|
173
|
+
return s;
|
|
174
|
+
const answered = s.instances
|
|
175
|
+
.filter((i) => i.reachable && !i.error)
|
|
176
|
+
.map((i) => ({ instanceId: i.instanceId, rows: (i.data ?? []) }));
|
|
177
|
+
return {
|
|
178
|
+
ok: true,
|
|
179
|
+
rows: answered.flatMap((i) => i.rows),
|
|
180
|
+
silent: s.instances.filter((i) => !i.reachable).map((i) => i.instanceId),
|
|
181
|
+
failed: s.instances.filter((i) => i.reachable && i.error).map((i) => ({ instanceId: i.instanceId, error: i.error })),
|
|
182
|
+
answered,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
catch (e) {
|
|
186
|
+
return { ok: false, error: e.message };
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control.js","sourceRoot":"","sources":["../../src/console/control.ts"],"names":[],"mappings":"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"}
|
package/dist/console/mesh.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CotalEndpoint } from "@cotal-ai/core";
|
|
2
2
|
import type { MeshSnapshot, MeshViewOptions } from "../view/mesh-view.js";
|
|
3
|
-
export type { FeedEntry, MeshViewOptions, FeedDelivery } from "../view/mesh-view.js";
|
|
3
|
+
export type { FeedEntry, MeshViewOptions, FeedDelivery, MembershipView } from "../view/mesh-view.js";
|
|
4
4
|
export type MeshState = MeshSnapshot;
|
|
5
5
|
/** Focusable panes across the console (normal panels + the DM and topology lenses). */
|
|
6
6
|
export type FocusId = "roster" | "feed" | "needsyou" | "dmpeers" | "dmthread" | "topo";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mesh.d.ts","sourceRoot":"","sources":["../../src/console/mesh.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI1E,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"mesh.d.ts","sourceRoot":"","sources":["../../src/console/mesh.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI1E,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACrG,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC;AAErC,uFAAuF;AACvF,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAEvF,wBAAgB,OAAO,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,YAAY,CAgB/E"}
|
package/dist/console/root.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CotalEndpoint } from "@cotal-ai/core";
|
|
2
|
+
import type { ControlCtx } from "./control.js";
|
|
2
3
|
/** How the observer authenticates: a static/open creds file, OR the user-mode admin-view material
|
|
3
4
|
* (a bearer SOURCE so the standing tap survives the ≤5-min token life, plus the pinned principal a
|
|
4
5
|
* source-mode endpoint requires). Never both. */
|
|
@@ -14,17 +15,28 @@ export interface ObserverAuth {
|
|
|
14
15
|
/** The read-only observer the console watches a space through — invisible to peers. Built once
|
|
15
16
|
* per selected space (the picker can switch spaces at runtime). */
|
|
16
17
|
export declare function makeObserver(space: string, server: string, auth?: ObserverAuth, name?: string): CotalEndpoint;
|
|
18
|
+
/** The operator's presence peer: a second endpoint carrying the observer's own card (the same id,
|
|
19
|
+
* name, and role, so it IS the `from` of everything the observer sends) that does nothing but
|
|
20
|
+
* register presence. The console starts it on the operator's first send, so a pure-watch session
|
|
21
|
+
* stays invisible and a speaking operator becomes a roster peer agents can reply to; the replies
|
|
22
|
+
* arrive over the observer's whole-space tap. Open mesh only: the console's authed observers hold
|
|
23
|
+
* no presence-write grant and no live read of their own inbox, so Root offers no factory there.
|
|
24
|
+
* Not started here: App owns its lifecycle (start on first send, stop with the console). */
|
|
25
|
+
export declare function makeParticipant(observer: CotalEndpoint, server: string): CotalEndpoint;
|
|
17
26
|
/**
|
|
18
27
|
* Console root. With a fixed `space` (explicit `--space`, or the single space under auth) it goes
|
|
19
28
|
* straight into the per-space console. Without one (open mesh) it shows the space overview first;
|
|
20
29
|
* picking a space mounts the console for it — `key={space}` forces a clean MeshView remount, and
|
|
21
30
|
* `onBack` tears it down to return to the overview.
|
|
22
31
|
*/
|
|
23
|
-
export declare function Root({ server, auth, space, canWrite, name, }: {
|
|
32
|
+
export declare function Root({ server, auth, space, canWrite, canControl, controlCtx, name, }: {
|
|
24
33
|
server: string;
|
|
25
34
|
auth: ObserverAuth;
|
|
26
35
|
space?: string;
|
|
27
36
|
canWrite?: boolean;
|
|
37
|
+
canControl?: boolean;
|
|
38
|
+
/** Trust material for per-action control mints — space-less; App adds its own space. */
|
|
39
|
+
controlCtx?: Omit<ControlCtx, "space">;
|
|
28
40
|
name?: string;
|
|
29
41
|
}): import("react").JSX.Element;
|
|
30
42
|
//# sourceMappingURL=root.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/console/root.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAkC,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/console/root.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAkC,MAAM,gBAAgB,CAAC;AAE/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C;;kDAEkD;AAClD,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/F;AAED;oEACoE;AACpE,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,YAAiB,EACvB,IAAI,SAAY,GACf,aAAa,CAuBf;AAED;;;;;;6FAM6F;AAC7F,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAYtF;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,EACnB,MAAM,EACN,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,UAAU,EACV,UAAU,EACV,IAAI,GACL,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,+BAwBA"}
|