@cotal-ai/cli 0.1.3 → 0.2.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/commands/console.d.ts +6 -0
- package/dist/commands/console.d.ts.map +1 -1
- package/dist/commands/console.js +83 -24
- package/dist/commands/console.js.map +1 -1
- package/dist/commands/demo.d.ts +2 -0
- package/dist/commands/demo.d.ts.map +1 -0
- package/dist/commands/demo.js +162 -0
- package/dist/commands/demo.js.map +1 -0
- package/dist/commands/feedback.d.ts +1 -0
- package/dist/commands/feedback.d.ts.map +1 -1
- package/dist/commands/feedback.js +87 -0
- package/dist/commands/feedback.js.map +1 -1
- package/dist/commands/history.d.ts +4 -0
- package/dist/commands/history.d.ts.map +1 -0
- package/dist/commands/history.js +48 -0
- package/dist/commands/history.js.map +1 -0
- package/dist/commands/join.d.ts.map +1 -1
- package/dist/commands/join.js +2 -2
- package/dist/commands/join.js.map +1 -1
- package/dist/commands/setup.d.ts +7 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +64 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/up.d.ts.map +1 -1
- package/dist/commands/up.js +2 -2
- package/dist/commands/up.js.map +1 -1
- package/dist/commands/watch.d.ts +2 -0
- package/dist/commands/watch.d.ts.map +1 -1
- package/dist/commands/watch.js +5 -61
- package/dist/commands/watch.js.map +1 -1
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +2 -2
- package/dist/commands/web.js.map +1 -1
- package/dist/console/app.d.ts +15 -0
- package/dist/console/app.d.ts.map +1 -0
- package/dist/console/app.js +240 -0
- package/dist/console/app.js.map +1 -0
- package/dist/console/commands.d.ts +27 -0
- package/dist/console/commands.d.ts.map +1 -0
- package/dist/console/commands.js +111 -0
- package/dist/console/commands.js.map +1 -0
- package/dist/console/mesh.d.ts +8 -0
- package/dist/console/mesh.d.ts.map +1 -0
- package/dist/console/mesh.js +26 -0
- package/dist/console/mesh.js.map +1 -0
- package/dist/console/root.d.ts +18 -0
- package/dist/console/root.d.ts.map +1 -0
- package/dist/console/root.js +36 -0
- package/dist/console/root.js.map +1 -0
- package/dist/console/ui/CommandPalette.d.ts +15 -0
- package/dist/console/ui/CommandPalette.d.ts.map +1 -0
- package/dist/console/ui/CommandPalette.js +81 -0
- package/dist/console/ui/CommandPalette.js.map +1 -0
- package/dist/console/ui/Confirm.d.ts +19 -0
- package/dist/console/ui/Confirm.d.ts.map +1 -0
- package/dist/console/ui/Confirm.js +32 -0
- package/dist/console/ui/Confirm.js.map +1 -0
- package/dist/console/ui/Detail.d.ts +18 -0
- package/dist/console/ui/Detail.d.ts.map +1 -0
- package/dist/console/ui/Detail.js +43 -0
- package/dist/console/ui/Detail.js.map +1 -0
- package/dist/console/ui/Dm.d.ts +15 -0
- package/dist/console/ui/Dm.d.ts.map +1 -0
- package/dist/console/ui/Dm.js +135 -0
- package/dist/console/ui/Dm.js.map +1 -0
- package/dist/console/ui/Feed.d.ts +20 -0
- package/dist/console/ui/Feed.d.ts.map +1 -0
- package/dist/console/ui/Feed.js +141 -0
- package/dist/console/ui/Feed.js.map +1 -0
- package/dist/console/ui/Help.d.ts +8 -0
- package/dist/console/ui/Help.d.ts.map +1 -0
- package/dist/console/ui/Help.js +55 -0
- package/dist/console/ui/Help.js.map +1 -0
- package/dist/console/ui/NeedsYou.d.ts +14 -0
- package/dist/console/ui/NeedsYou.d.ts.map +1 -0
- package/dist/console/ui/NeedsYou.js +36 -0
- package/dist/console/ui/NeedsYou.js.map +1 -0
- package/dist/console/ui/Prompt.d.ts +12 -0
- package/dist/console/ui/Prompt.d.ts.map +1 -0
- package/dist/console/ui/Prompt.js +19 -0
- package/dist/console/ui/Prompt.js.map +1 -0
- package/dist/console/ui/Roster.d.ts +17 -0
- package/dist/console/ui/Roster.d.ts.map +1 -0
- package/dist/console/ui/Roster.js +52 -0
- package/dist/console/ui/Roster.js.map +1 -0
- package/dist/console/ui/Search.d.ts +12 -0
- package/dist/console/ui/Search.d.ts.map +1 -0
- package/dist/console/ui/Search.js +19 -0
- package/dist/console/ui/Search.js.map +1 -0
- package/dist/console/ui/SpacePicker.d.ts +10 -0
- package/dist/console/ui/SpacePicker.d.ts.map +1 -0
- package/dist/console/ui/SpacePicker.js +77 -0
- package/dist/console/ui/SpacePicker.js.map +1 -0
- package/dist/console/ui/StatusBar.d.ts +14 -0
- package/dist/console/ui/StatusBar.d.ts.map +1 -0
- package/dist/console/ui/StatusBar.js +18 -0
- package/dist/console/ui/StatusBar.js.map +1 -0
- package/dist/console/ui/Tabs.d.ts +8 -0
- package/dist/console/ui/Tabs.d.ts.map +1 -0
- package/dist/console/ui/Tabs.js +12 -0
- package/dist/console/ui/Tabs.js.map +1 -0
- package/dist/console/ui/Tiles.d.ts +9 -0
- package/dist/console/ui/Tiles.d.ts.map +1 -0
- package/dist/console/ui/Tiles.js +10 -0
- package/dist/console/ui/Tiles.js.map +1 -0
- package/dist/console/ui/theme.d.ts +11 -0
- package/dist/console/ui/theme.d.ts.map +1 -0
- package/dist/console/ui/theme.js +63 -0
- package/dist/console/ui/theme.js.map +1 -0
- package/dist/console/ui/topo/Map.d.ts +17 -0
- package/dist/console/ui/topo/Map.d.ts.map +1 -0
- package/dist/console/ui/topo/Map.js +158 -0
- package/dist/console/ui/topo/Map.js.map +1 -0
- package/dist/console/ui/topo/Matrix.d.ts +16 -0
- package/dist/console/ui/topo/Matrix.d.ts.map +1 -0
- package/dist/console/ui/topo/Matrix.js +80 -0
- package/dist/console/ui/topo/Matrix.js.map +1 -0
- package/dist/console/ui/topo/Sequence.d.ts +17 -0
- package/dist/console/ui/topo/Sequence.d.ts.map +1 -0
- package/dist/console/ui/topo/Sequence.js +117 -0
- package/dist/console/ui/topo/Sequence.js.map +1 -0
- package/dist/console/ui/topo/Topo.d.ts +20 -0
- package/dist/console/ui/topo/Topo.d.ts.map +1 -0
- package/dist/console/ui/topo/Topo.js +30 -0
- package/dist/console/ui/topo/Topo.js.map +1 -0
- package/dist/console/ui/topo/model.d.ts +51 -0
- package/dist/console/ui/topo/model.d.ts.map +1 -0
- package/dist/console/ui/topo/model.js +113 -0
- package/dist/console/ui/topo/model.js.map +1 -0
- package/dist/console/ui/topo/raster.d.ts +18 -0
- package/dist/console/ui/topo/raster.d.ts.map +1 -0
- package/dist/console/ui/topo/raster.js +36 -0
- package/dist/console/ui/topo/raster.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/dist/render.d.ts +4 -29
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +0 -0
- package/dist/render.js.map +1 -1
- package/dist/view/mesh-view.d.ts +138 -0
- package/dist/view/mesh-view.d.ts.map +1 -0
- package/dist/view/mesh-view.js +346 -0
- package/dist/view/mesh-view.js.map +1 -0
- package/package.json +7 -2
package/dist/index.js
CHANGED
|
@@ -3,10 +3,13 @@ import { up } from "./commands/up.js";
|
|
|
3
3
|
import { join } from "./commands/join.js";
|
|
4
4
|
import { watch } from "./commands/watch.js";
|
|
5
5
|
import { console_ } from "./commands/console.js";
|
|
6
|
+
import { demo } from "./commands/demo.js";
|
|
6
7
|
import { web } from "./commands/web.js";
|
|
7
8
|
import { spawn } from "./commands/spawn.js";
|
|
8
9
|
import { mint } from "./commands/mint.js";
|
|
10
|
+
import { setup } from "./commands/setup.js";
|
|
9
11
|
import { channels } from "./commands/channels.js";
|
|
12
|
+
import { history } from "./commands/history.js";
|
|
10
13
|
import { feedback } from "./commands/feedback.js";
|
|
11
14
|
/** The minimal mesh CLI: thin NATS clients (up/join/watch), plus `spawn` — a
|
|
12
15
|
* foreground agent launch that reuses the connector's launch recipe. Self-registers
|
|
@@ -38,9 +41,16 @@ const baseCommands = [
|
|
|
38
41
|
kind: "command",
|
|
39
42
|
name: "console",
|
|
40
43
|
group: "Mesh",
|
|
41
|
-
summary: "live
|
|
44
|
+
summary: "live protocol view for a space — lazygit-style TUI, or a line stream on --plain — --space <s> [--plain]",
|
|
42
45
|
run: console_,
|
|
43
46
|
},
|
|
47
|
+
{
|
|
48
|
+
kind: "command",
|
|
49
|
+
name: "demo",
|
|
50
|
+
group: "Mesh",
|
|
51
|
+
summary: "replay a scripted multi-agent trace (all message types) to exercise the console/web — --space <s> [--interval <ms>] [--once]",
|
|
52
|
+
run: demo,
|
|
53
|
+
},
|
|
44
54
|
{
|
|
45
55
|
kind: "command",
|
|
46
56
|
name: "web",
|
|
@@ -48,6 +58,13 @@ const baseCommands = [
|
|
|
48
58
|
summary: "browser observability dashboard — presence, channels, live feed — --space <s> [--port <n>] [--no-open]",
|
|
49
59
|
run: web,
|
|
50
60
|
},
|
|
61
|
+
{
|
|
62
|
+
kind: "command",
|
|
63
|
+
name: "setup",
|
|
64
|
+
group: "Agents",
|
|
65
|
+
summary: "install the cotal plugin into Claude Code so this repo's sessions get the cotal tools (idempotent)",
|
|
66
|
+
run: setup,
|
|
67
|
+
},
|
|
51
68
|
{
|
|
52
69
|
kind: "command",
|
|
53
70
|
name: "spawn",
|
|
@@ -69,11 +86,18 @@ const baseCommands = [
|
|
|
69
86
|
summary: "inspect/set channel registry — channels <list | set <name> [--replay|--no-replay] [--desc <s>] [--instructions <s>] | default --replay|--no-replay>",
|
|
70
87
|
run: channels,
|
|
71
88
|
},
|
|
89
|
+
{
|
|
90
|
+
kind: "command",
|
|
91
|
+
name: "history",
|
|
92
|
+
group: "Mesh",
|
|
93
|
+
summary: "clear retained message history — history clear --force [--dms] [--space <s>]",
|
|
94
|
+
run: history,
|
|
95
|
+
},
|
|
72
96
|
{
|
|
73
97
|
kind: "command",
|
|
74
98
|
name: "feedback",
|
|
75
99
|
group: "Mesh",
|
|
76
|
-
summary:
|
|
100
|
+
summary: 'send feedback — feedback "<summary>" [--type <t>] [--email <e>] — or run the intake server: feedback --keys <keys.json> --creds <creds> [--port <n>]',
|
|
77
101
|
run: feedback,
|
|
78
102
|
},
|
|
79
103
|
];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAgB,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD;;;kCAGkC;AAClC,MAAM,YAAY,GAAc;IAC9B;QACE,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,oGAAoG;QAC7G,GAAG,EAAE,EAAE;KACR;IACD;QACE,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,kEAAkE;QAC3E,GAAG,EAAE,IAAI;KACV;IACD;QACE,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,+CAA+C;QACxD,GAAG,EAAE,KAAK;KACX;IACD;QACE,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
CHANGED
|
@@ -1,32 +1,7 @@
|
|
|
1
|
-
import type { CotalEndpoint
|
|
1
|
+
import type { CotalEndpoint } from "@cotal-ai/core";
|
|
2
2
|
export declare function agentColor(name: string): (s: string) => string;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
private byId;
|
|
7
|
-
constructor(ep: CotalEndpoint, onChange?: () => void);
|
|
8
|
-
nameOf(id: string): string;
|
|
9
|
-
}
|
|
10
|
-
/** A rendered message split into pieces so consumers can lay it out (e.g. hanging wrap). */
|
|
11
|
-
export interface LogEntry {
|
|
12
|
-
/** Raw timestamp (no ANSI) — its visible width sets the hanging indent. */
|
|
13
|
-
time: string;
|
|
14
|
-
/** Colored `sender → target:` prefix. */
|
|
15
|
-
head: string;
|
|
16
|
-
/** The message body. */
|
|
17
|
-
body: string;
|
|
18
|
-
}
|
|
19
|
-
/** Groups same-sender, same-text unicast bursts into one line; passes everything else through. */
|
|
20
|
-
export declare class Fanout {
|
|
21
|
-
private onEntry;
|
|
22
|
-
private nameOf;
|
|
23
|
-
private pending;
|
|
24
|
-
constructor(onEntry: (e: LogEntry) => void, nameOf: (id: string) => string);
|
|
25
|
-
add(subject: string, msg: CotalMessage): void;
|
|
26
|
-
private flush;
|
|
27
|
-
stop(): void;
|
|
28
|
-
}
|
|
29
|
-
/** Wires the endpoint (not yet started) into the classic log and parks until SIGINT. */
|
|
3
|
+
/** Wire the (not-yet-started) observer into a scrolling line log via the shared MeshView, and
|
|
4
|
+
* park until SIGINT. MeshView owns the endpoint lifecycle and all the normalization; this just
|
|
5
|
+
* prints presence changes and each classified+coalesced feed entry as it lands. */
|
|
30
6
|
export declare function runLog(ep: CotalEndpoint, space: string, tapSubject?: string): Promise<void>;
|
|
31
|
-
export declare function runDashboard(ep: CotalEndpoint, space: string, tapSubject?: string): Promise<void>;
|
|
32
7
|
//# sourceMappingURL=render.d.ts.map
|
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,gBAAgB,CAAC;AAYnE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAS9D;AAmCD;;oFAEoF;AACpF,wBAAsB,MAAM,CAAC,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcjG"}
|
package/dist/render.js
CHANGED
|
Binary file
|
package/dist/render.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import type { CotalEndpoint, EndpointRef, Presence, PresenceStatus } from "@cotal-ai/core";
|
|
3
|
+
export type FeedDelivery = "multicast" | "unicast" | "anycast";
|
|
4
|
+
/** One feed row. A same-sender/same-text unicast burst coalesces into a single entry with a
|
|
5
|
+
* deterministic id (the first message's) and ts (the earliest), so a history prefill and the
|
|
6
|
+
* live tap dedupe-by-id and order correctly. `text` is plain — the surface colors it. */
|
|
7
|
+
export interface FeedEntry {
|
|
8
|
+
id: string;
|
|
9
|
+
ts: number;
|
|
10
|
+
from: EndpointRef;
|
|
11
|
+
delivery: FeedDelivery;
|
|
12
|
+
channel?: string;
|
|
13
|
+
toService?: string;
|
|
14
|
+
toNames?: string[];
|
|
15
|
+
count?: number;
|
|
16
|
+
text: string;
|
|
17
|
+
}
|
|
18
|
+
export interface StatusCounts {
|
|
19
|
+
working: number;
|
|
20
|
+
waiting: number;
|
|
21
|
+
idle: number;
|
|
22
|
+
offline: number;
|
|
23
|
+
}
|
|
24
|
+
/** One message inside a DM thread (un-coalesced). */
|
|
25
|
+
export interface DmMessage {
|
|
26
|
+
ts: number;
|
|
27
|
+
from: string;
|
|
28
|
+
to: string;
|
|
29
|
+
text: string;
|
|
30
|
+
}
|
|
31
|
+
/** A conversation between a peer and one counterparty. */
|
|
32
|
+
export interface DmThread {
|
|
33
|
+
with: string;
|
|
34
|
+
role?: string;
|
|
35
|
+
status: PresenceStatus;
|
|
36
|
+
lastTs: number;
|
|
37
|
+
messages: DmMessage[];
|
|
38
|
+
}
|
|
39
|
+
/** A peer's whole DM footprint — every counterparty it has talked to. */
|
|
40
|
+
export interface DmPeer {
|
|
41
|
+
name: string;
|
|
42
|
+
role?: string;
|
|
43
|
+
status: PresenceStatus;
|
|
44
|
+
lastTs: number;
|
|
45
|
+
conversations: DmThread[];
|
|
46
|
+
}
|
|
47
|
+
/** Derived operator signals — golden-signal counts, who needs attention, the DM roll-up. */
|
|
48
|
+
export interface MeshSignals {
|
|
49
|
+
counts: StatusCounts;
|
|
50
|
+
waiting: Presence[];
|
|
51
|
+
oldestWaitingTs?: number;
|
|
52
|
+
dms: DmPeer[];
|
|
53
|
+
}
|
|
54
|
+
export interface MeshSnapshot {
|
|
55
|
+
agents: Presence[];
|
|
56
|
+
endpoints: Presence[];
|
|
57
|
+
channels: {
|
|
58
|
+
channel: string;
|
|
59
|
+
messages: number;
|
|
60
|
+
}[];
|
|
61
|
+
feed: FeedEntry[];
|
|
62
|
+
rates: {
|
|
63
|
+
msgsPerSec: number;
|
|
64
|
+
};
|
|
65
|
+
status: {
|
|
66
|
+
connected: boolean;
|
|
67
|
+
space: string;
|
|
68
|
+
dmVisible: boolean;
|
|
69
|
+
error?: string;
|
|
70
|
+
};
|
|
71
|
+
signals: MeshSignals;
|
|
72
|
+
nameOf: (id: string) => string;
|
|
73
|
+
}
|
|
74
|
+
export interface MeshViewOptions {
|
|
75
|
+
/** Feed cap, in entries. Default 300. */
|
|
76
|
+
window?: number;
|
|
77
|
+
/** The read-only tap subject. `chatWildcard(space)` narrows to multicast (auth — DMs/anycast
|
|
78
|
+
* stay confidential); `spaceWildcard(space)` or undefined taps the whole space (god-view). */
|
|
79
|
+
tapSubject?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Events:
|
|
83
|
+
* - `"entry"` `(e: FeedEntry)` — one live feed row, as it lands (for the stream renderer).
|
|
84
|
+
* - `"presence"` `(ev: PresenceEvent)` — forwarded presence change (join/update/offline).
|
|
85
|
+
* - `"change"` `(s: MeshSnapshot)` — a batched snapshot every ~75ms (for dashboards).
|
|
86
|
+
*/
|
|
87
|
+
export declare class MeshView extends EventEmitter {
|
|
88
|
+
private readonly ep;
|
|
89
|
+
private roster;
|
|
90
|
+
private byId;
|
|
91
|
+
private channelCounts;
|
|
92
|
+
private feed;
|
|
93
|
+
private seen;
|
|
94
|
+
private pending;
|
|
95
|
+
private dmLog;
|
|
96
|
+
private recentTs;
|
|
97
|
+
private msgsPerSec;
|
|
98
|
+
private connected;
|
|
99
|
+
private error?;
|
|
100
|
+
private dirty;
|
|
101
|
+
private readonly window;
|
|
102
|
+
private readonly tapSubject?;
|
|
103
|
+
private readonly chatOnly;
|
|
104
|
+
private timers;
|
|
105
|
+
private readonly onRoster;
|
|
106
|
+
private readonly onPresence;
|
|
107
|
+
private readonly onError;
|
|
108
|
+
constructor(ep: CotalEndpoint, opts?: MeshViewOptions);
|
|
109
|
+
start(): Promise<void>;
|
|
110
|
+
stop(): Promise<void>;
|
|
111
|
+
snapshot(): MeshSnapshot;
|
|
112
|
+
nameOf: (id: string) => string;
|
|
113
|
+
private setRoster;
|
|
114
|
+
/** Live read-only tap. Drops control/presence/trace frames (deliveryOf → null). */
|
|
115
|
+
private ingest;
|
|
116
|
+
/** Group a same-sender/same-text unicast burst into one feed entry over BURST_MS, and retain
|
|
117
|
+
* each raw message for the DM roll-up. */
|
|
118
|
+
private coalesce;
|
|
119
|
+
private flushBurst;
|
|
120
|
+
/** Append to the feed, dedupe by id, keep it windowed, and notify stream consumers. */
|
|
121
|
+
private push;
|
|
122
|
+
private trim;
|
|
123
|
+
private recordDm;
|
|
124
|
+
/** One-shot backlog: prefill each channel's history (multicast), plus the DM backlog when DMs
|
|
125
|
+
* are visible (god-view — `dmHistory` needs an admin cred), deduped by id, oldest-first. */
|
|
126
|
+
private prefill;
|
|
127
|
+
/** Best-effort DM backlog for the roll-up — only meaningful for a god-view cred; a non-admin
|
|
128
|
+
* observer's `dmHistory` throws (ACL), which just leaves the DM lens live-only. */
|
|
129
|
+
private prefillDms;
|
|
130
|
+
private refreshChannels;
|
|
131
|
+
private signals;
|
|
132
|
+
/** Group raw DMs into per-peer rows; each peer lists its counterparties (conversations).
|
|
133
|
+
* Only pairs that actually talked — never the n² cross-product. */
|
|
134
|
+
private rollupDms;
|
|
135
|
+
/** The single batch point: recompute the rolling rate, then emit one snapshot if dirty. */
|
|
136
|
+
private flush;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=mesh-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesh-view.d.ts","sourceRoot":"","sources":["../../src/view/mesh-view.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
// MeshView — the shared, render-agnostic model behind every "protocol view" surface
|
|
2
|
+
// (the terminal console, the plain stream, the web dashboard). It consumes ONE read-only
|
|
3
|
+
// observer endpoint and turns the raw wire into a normalized model: a status-sorted roster,
|
|
4
|
+
// a classified + burst-coalesced + windowed feed, channel counts, a msgs/s rate, and the
|
|
5
|
+
// derived operator signals (status counts, who's waiting, a per-peer DM roll-up). No ANSI,
|
|
6
|
+
// no React, no HTML, no color — a surface only lays this out, it never re-derives it.
|
|
7
|
+
// See docs/protocol-view.md.
|
|
8
|
+
import { EventEmitter } from "node:events";
|
|
9
|
+
import { deliveryOf, chatWildcard } from "@cotal-ai/core";
|
|
10
|
+
// ---- internals -------------------------------------------------------------
|
|
11
|
+
const STATUS_ORDER = { working: 0, waiting: 1, idle: 2, offline: 3 };
|
|
12
|
+
const BURST_MS = 400; // unicast burst-coalescing window
|
|
13
|
+
const TICK_MS = 75; // batch every source into one "change"
|
|
14
|
+
const CHANNELS_MS = 2000; // listChannels() refresh
|
|
15
|
+
const DEFAULT_WINDOW = 300;
|
|
16
|
+
const HISTORY_LIMIT = 50; // per-channel prefill depth
|
|
17
|
+
const DM_LOG_CAP = 1000; // raw DMs retained for the roll-up
|
|
18
|
+
function bodyText(msg) {
|
|
19
|
+
return msg.parts.map((p) => (p.kind === "text" ? p.text : JSON.stringify(p.data))).join(" ");
|
|
20
|
+
}
|
|
21
|
+
function sortRoster(r) {
|
|
22
|
+
// getRoster()/the "roster" event sort by name only — re-apply the status order here.
|
|
23
|
+
return [...r].sort((a, b) => (STATUS_ORDER[a.status] ?? 9) - (STATUS_ORDER[b.status] ?? 9) ||
|
|
24
|
+
a.card.name.localeCompare(b.card.name));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Events:
|
|
28
|
+
* - `"entry"` `(e: FeedEntry)` — one live feed row, as it lands (for the stream renderer).
|
|
29
|
+
* - `"presence"` `(ev: PresenceEvent)` — forwarded presence change (join/update/offline).
|
|
30
|
+
* - `"change"` `(s: MeshSnapshot)` — a batched snapshot every ~75ms (for dashboards).
|
|
31
|
+
*/
|
|
32
|
+
export class MeshView extends EventEmitter {
|
|
33
|
+
ep;
|
|
34
|
+
roster = [];
|
|
35
|
+
byId = new Map();
|
|
36
|
+
channelCounts = new Map();
|
|
37
|
+
feed = [];
|
|
38
|
+
seen = new Set(); // feed ids, for prefill ∪ live dedupe-by-id
|
|
39
|
+
pending = new Map();
|
|
40
|
+
dmLog = []; // raw unicast for the DM roll-up
|
|
41
|
+
recentTs = []; // tap arrivals in the last 1s → msgs/s
|
|
42
|
+
msgsPerSec = 0;
|
|
43
|
+
connected = false;
|
|
44
|
+
error;
|
|
45
|
+
dirty = true;
|
|
46
|
+
window;
|
|
47
|
+
tapSubject;
|
|
48
|
+
chatOnly;
|
|
49
|
+
timers = [];
|
|
50
|
+
onRoster = (r) => this.setRoster(r);
|
|
51
|
+
onPresence = (ev) => this.emit("presence", ev);
|
|
52
|
+
onError = (e) => {
|
|
53
|
+
this.error = e.message;
|
|
54
|
+
this.dirty = true;
|
|
55
|
+
};
|
|
56
|
+
constructor(ep, opts = {}) {
|
|
57
|
+
super();
|
|
58
|
+
this.ep = ep;
|
|
59
|
+
this.window = opts.window ?? DEFAULT_WINDOW;
|
|
60
|
+
this.tapSubject = opts.tapSubject;
|
|
61
|
+
// DMs are hidden only when the tap is narrowed to the chat subtree.
|
|
62
|
+
this.chatOnly = opts.tapSubject === chatWildcard(ep.space);
|
|
63
|
+
}
|
|
64
|
+
async start() {
|
|
65
|
+
// The error listener MUST be attached before start() — async faults surface as events.
|
|
66
|
+
this.ep.on("error", this.onError);
|
|
67
|
+
this.ep.on("roster", this.onRoster);
|
|
68
|
+
this.ep.on("presence", this.onPresence);
|
|
69
|
+
await this.ep.start();
|
|
70
|
+
this.connected = true;
|
|
71
|
+
this.setRoster(this.ep.getRoster());
|
|
72
|
+
this.ep.tap((subject, msg) => {
|
|
73
|
+
if (msg)
|
|
74
|
+
this.ingest(subject, msg);
|
|
75
|
+
}, this.tapSubject ? { subject: this.tapSubject } : undefined);
|
|
76
|
+
void this.prefill();
|
|
77
|
+
void this.refreshChannels();
|
|
78
|
+
this.timers.push(setInterval(() => this.flush(), TICK_MS));
|
|
79
|
+
this.timers.push(setInterval(() => void this.refreshChannels(), CHANNELS_MS));
|
|
80
|
+
this.timers.push(setInterval(() => (this.dirty = true), 1000)); // refresh ages + decay rate
|
|
81
|
+
}
|
|
82
|
+
async stop() {
|
|
83
|
+
for (const t of this.timers)
|
|
84
|
+
clearInterval(t);
|
|
85
|
+
this.timers = [];
|
|
86
|
+
for (const b of this.pending.values())
|
|
87
|
+
clearTimeout(b.timer); // bursts hold live timers
|
|
88
|
+
this.pending.clear();
|
|
89
|
+
this.ep.off("error", this.onError);
|
|
90
|
+
this.ep.off("roster", this.onRoster);
|
|
91
|
+
this.ep.off("presence", this.onPresence);
|
|
92
|
+
await this.ep.stop();
|
|
93
|
+
}
|
|
94
|
+
snapshot() {
|
|
95
|
+
const channels = [...this.channelCounts]
|
|
96
|
+
.map(([channel, messages]) => ({ channel, messages }))
|
|
97
|
+
.sort((a, b) => a.channel.localeCompare(b.channel));
|
|
98
|
+
return {
|
|
99
|
+
agents: this.roster.filter((p) => p.card.kind === "agent"),
|
|
100
|
+
endpoints: this.roster.filter((p) => p.card.kind !== "agent"),
|
|
101
|
+
channels,
|
|
102
|
+
feed: this.feed.slice(),
|
|
103
|
+
rates: { msgsPerSec: this.msgsPerSec },
|
|
104
|
+
status: {
|
|
105
|
+
connected: this.connected,
|
|
106
|
+
space: this.ep.space,
|
|
107
|
+
dmVisible: !this.chatOnly,
|
|
108
|
+
error: this.error,
|
|
109
|
+
},
|
|
110
|
+
signals: this.signals(),
|
|
111
|
+
nameOf: this.nameOf,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
// Stable identity across snapshots; reads the live byId map.
|
|
115
|
+
nameOf = (id) => this.byId.get(id) ?? id.slice(0, 8);
|
|
116
|
+
// ---- sources -------------------------------------------------------------
|
|
117
|
+
setRoster(r) {
|
|
118
|
+
this.roster = sortRoster(r);
|
|
119
|
+
for (const p of r)
|
|
120
|
+
this.byId.set(p.card.id, p.card.name);
|
|
121
|
+
this.dirty = true;
|
|
122
|
+
}
|
|
123
|
+
/** Live read-only tap. Drops control/presence/trace frames (deliveryOf → null). */
|
|
124
|
+
ingest(subject, msg) {
|
|
125
|
+
const kind = deliveryOf(subject);
|
|
126
|
+
if (!kind)
|
|
127
|
+
return;
|
|
128
|
+
this.recentTs.push(Date.now());
|
|
129
|
+
if (msg.from?.id && msg.from.name)
|
|
130
|
+
this.byId.set(msg.from.id, msg.from.name); // sharpen id→name
|
|
131
|
+
if (kind === "unicast")
|
|
132
|
+
return this.coalesce(msg);
|
|
133
|
+
this.push({
|
|
134
|
+
id: msg.id,
|
|
135
|
+
ts: msg.ts,
|
|
136
|
+
from: msg.from,
|
|
137
|
+
delivery: kind === "anycast" ? "anycast" : "multicast", // "chat" → multicast
|
|
138
|
+
channel: kind === "anycast" ? undefined : msg.channel,
|
|
139
|
+
toService: kind === "anycast" ? msg.toService : undefined,
|
|
140
|
+
text: bodyText(msg),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/** Group a same-sender/same-text unicast burst into one feed entry over BURST_MS, and retain
|
|
144
|
+
* each raw message for the DM roll-up. */
|
|
145
|
+
coalesce(msg) {
|
|
146
|
+
const body = bodyText(msg);
|
|
147
|
+
if (msg.to)
|
|
148
|
+
this.recordDm({ ts: msg.ts, from: msg.from, toId: msg.to, text: body });
|
|
149
|
+
const key = msg.from.id + " " + body;
|
|
150
|
+
let b = this.pending.get(key);
|
|
151
|
+
if (!b) {
|
|
152
|
+
b = {
|
|
153
|
+
from: msg.from,
|
|
154
|
+
body,
|
|
155
|
+
id: msg.id,
|
|
156
|
+
ts: msg.ts,
|
|
157
|
+
ids: [],
|
|
158
|
+
timer: setTimeout(() => this.flushBurst(key), BURST_MS),
|
|
159
|
+
};
|
|
160
|
+
this.pending.set(key, b);
|
|
161
|
+
}
|
|
162
|
+
b.ts = Math.min(b.ts, msg.ts); // earliest in the burst → deterministic order
|
|
163
|
+
if (msg.to)
|
|
164
|
+
b.ids.push(msg.to);
|
|
165
|
+
}
|
|
166
|
+
flushBurst(key) {
|
|
167
|
+
const b = this.pending.get(key);
|
|
168
|
+
if (!b)
|
|
169
|
+
return;
|
|
170
|
+
this.pending.delete(key);
|
|
171
|
+
this.push({
|
|
172
|
+
id: b.id,
|
|
173
|
+
ts: b.ts,
|
|
174
|
+
from: b.from,
|
|
175
|
+
delivery: "unicast",
|
|
176
|
+
toNames: b.ids.map((id) => this.nameOf(id)),
|
|
177
|
+
count: b.ids.length,
|
|
178
|
+
text: b.body,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/** Append to the feed, dedupe by id, keep it windowed, and notify stream consumers. */
|
|
182
|
+
push(e) {
|
|
183
|
+
if (this.seen.has(e.id))
|
|
184
|
+
return;
|
|
185
|
+
this.seen.add(e.id);
|
|
186
|
+
this.feed.push(e);
|
|
187
|
+
this.trim();
|
|
188
|
+
// Surface a brand-new channel as a tab now, not at the next poll.
|
|
189
|
+
if (e.delivery === "multicast" && e.channel && !this.channelCounts.has(e.channel))
|
|
190
|
+
this.channelCounts.set(e.channel, 1);
|
|
191
|
+
this.dirty = true;
|
|
192
|
+
this.emit("entry", e);
|
|
193
|
+
}
|
|
194
|
+
trim() {
|
|
195
|
+
if (this.feed.length <= this.window)
|
|
196
|
+
return;
|
|
197
|
+
for (const d of this.feed.splice(0, this.feed.length - this.window))
|
|
198
|
+
this.seen.delete(d.id);
|
|
199
|
+
}
|
|
200
|
+
recordDm(d) {
|
|
201
|
+
this.dmLog.push(d);
|
|
202
|
+
if (this.dmLog.length > DM_LOG_CAP)
|
|
203
|
+
this.dmLog.splice(0, this.dmLog.length - DM_LOG_CAP);
|
|
204
|
+
}
|
|
205
|
+
/** One-shot backlog: prefill each channel's history (multicast), plus the DM backlog when DMs
|
|
206
|
+
* are visible (god-view — `dmHistory` needs an admin cred), deduped by id, oldest-first. */
|
|
207
|
+
async prefill() {
|
|
208
|
+
let chans;
|
|
209
|
+
try {
|
|
210
|
+
chans = await this.ep.listChannels();
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
const batches = await Promise.all(chans.map((c) => this.ep.channelHistory(c.channel, { limit: HISTORY_LIMIT }).catch(() => [])));
|
|
216
|
+
const history = [];
|
|
217
|
+
for (const msgs of batches)
|
|
218
|
+
for (const msg of msgs) {
|
|
219
|
+
if (!msg.channel || this.seen.has(msg.id))
|
|
220
|
+
continue;
|
|
221
|
+
this.seen.add(msg.id);
|
|
222
|
+
history.push({
|
|
223
|
+
id: msg.id,
|
|
224
|
+
ts: msg.ts,
|
|
225
|
+
from: msg.from,
|
|
226
|
+
delivery: "multicast",
|
|
227
|
+
channel: msg.channel,
|
|
228
|
+
text: bodyText(msg),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
if (history.length) {
|
|
232
|
+
this.feed = [...history, ...this.feed].sort((a, b) => a.ts - b.ts);
|
|
233
|
+
this.trim();
|
|
234
|
+
this.dirty = true;
|
|
235
|
+
}
|
|
236
|
+
if (!this.chatOnly)
|
|
237
|
+
await this.prefillDms();
|
|
238
|
+
}
|
|
239
|
+
/** Best-effort DM backlog for the roll-up — only meaningful for a god-view cred; a non-admin
|
|
240
|
+
* observer's `dmHistory` throws (ACL), which just leaves the DM lens live-only. */
|
|
241
|
+
async prefillDms() {
|
|
242
|
+
let msgs;
|
|
243
|
+
try {
|
|
244
|
+
msgs = await this.ep.dmHistory({ limit: DM_LOG_CAP });
|
|
245
|
+
}
|
|
246
|
+
catch {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// Merge backlog into the live dmLog, deduped by sender+recipient+ts (a live tap may already
|
|
250
|
+
// have collected backlog-adjacent messages), then keep it ordered and capped.
|
|
251
|
+
const key = (d) => d.from.id + ">" + d.toId + "@" + d.ts;
|
|
252
|
+
const have = new Set(this.dmLog.map(key));
|
|
253
|
+
for (const m of msgs) {
|
|
254
|
+
if (!m.to)
|
|
255
|
+
continue;
|
|
256
|
+
if (m.from?.id && m.from.name)
|
|
257
|
+
this.byId.set(m.from.id, m.from.name);
|
|
258
|
+
const d = { ts: m.ts, from: m.from, toId: m.to, text: bodyText(m) };
|
|
259
|
+
if (have.has(key(d)))
|
|
260
|
+
continue;
|
|
261
|
+
have.add(key(d));
|
|
262
|
+
this.dmLog.push(d);
|
|
263
|
+
}
|
|
264
|
+
this.dmLog.sort((a, b) => a.ts - b.ts);
|
|
265
|
+
if (this.dmLog.length > DM_LOG_CAP)
|
|
266
|
+
this.dmLog.splice(0, this.dmLog.length - DM_LOG_CAP);
|
|
267
|
+
this.dirty = true;
|
|
268
|
+
}
|
|
269
|
+
async refreshChannels() {
|
|
270
|
+
let chans;
|
|
271
|
+
try {
|
|
272
|
+
chans = await this.ep.listChannels();
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
for (const { channel, messages } of chans)
|
|
278
|
+
this.channelCounts.set(channel, messages);
|
|
279
|
+
this.dirty = true;
|
|
280
|
+
}
|
|
281
|
+
// ---- derived signals -----------------------------------------------------
|
|
282
|
+
signals() {
|
|
283
|
+
const agents = this.roster.filter((p) => p.card.kind === "agent");
|
|
284
|
+
const counts = { working: 0, waiting: 0, idle: 0, offline: 0 };
|
|
285
|
+
for (const p of agents)
|
|
286
|
+
if (p.status in counts)
|
|
287
|
+
counts[p.status]++;
|
|
288
|
+
const waiting = agents.filter((p) => p.status === "waiting").sort((a, b) => a.ts - b.ts);
|
|
289
|
+
return {
|
|
290
|
+
counts,
|
|
291
|
+
waiting,
|
|
292
|
+
oldestWaitingTs: waiting.length ? waiting[0].ts : undefined,
|
|
293
|
+
dms: this.rollupDms(),
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/** Group raw DMs into per-peer rows; each peer lists its counterparties (conversations).
|
|
297
|
+
* Only pairs that actually talked — never the n² cross-product. */
|
|
298
|
+
rollupDms() {
|
|
299
|
+
const statusOf = (name) => this.roster.find((p) => p.card.name === name)?.status ?? "offline";
|
|
300
|
+
const roleOf = (name) => this.roster.find((p) => p.card.name === name)?.card.role;
|
|
301
|
+
const conv = new Map();
|
|
302
|
+
for (const d of this.dmLog) {
|
|
303
|
+
const a = d.from.name;
|
|
304
|
+
const b = this.nameOf(d.toId);
|
|
305
|
+
if (!a || !b || a === b)
|
|
306
|
+
continue;
|
|
307
|
+
const parts = [a, b].sort();
|
|
308
|
+
const k = parts.join("");
|
|
309
|
+
let c = conv.get(k);
|
|
310
|
+
if (!c)
|
|
311
|
+
conv.set(k, (c = { parts, msgs: [], last: 0 }));
|
|
312
|
+
c.msgs.push({ ts: d.ts, from: a, to: b, text: d.text });
|
|
313
|
+
c.last = Math.max(c.last, d.ts);
|
|
314
|
+
}
|
|
315
|
+
const peers = new Map();
|
|
316
|
+
for (const c of conv.values()) {
|
|
317
|
+
c.msgs.sort((x, y) => x.ts - y.ts);
|
|
318
|
+
for (const name of c.parts) {
|
|
319
|
+
const other = c.parts[0] === name ? c.parts[1] : c.parts[0];
|
|
320
|
+
let pe = peers.get(name);
|
|
321
|
+
if (!pe)
|
|
322
|
+
peers.set(name, (pe = { name, role: roleOf(name), status: statusOf(name), lastTs: 0, conversations: [] }));
|
|
323
|
+
pe.conversations.push({ with: other, role: roleOf(other), status: statusOf(other), lastTs: c.last, messages: c.msgs });
|
|
324
|
+
pe.lastTs = Math.max(pe.lastTs, c.last);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
for (const pe of peers.values())
|
|
328
|
+
pe.conversations.sort((a, b) => b.lastTs - a.lastTs);
|
|
329
|
+
return [...peers.values()].sort((a, b) => b.lastTs - a.lastTs);
|
|
330
|
+
}
|
|
331
|
+
/** The single batch point: recompute the rolling rate, then emit one snapshot if dirty. */
|
|
332
|
+
flush() {
|
|
333
|
+
const cutoff = Date.now() - 1000;
|
|
334
|
+
while (this.recentTs.length && this.recentTs[0] < cutoff)
|
|
335
|
+
this.recentTs.shift();
|
|
336
|
+
if (this.recentTs.length !== this.msgsPerSec) {
|
|
337
|
+
this.msgsPerSec = this.recentTs.length;
|
|
338
|
+
this.dirty = true;
|
|
339
|
+
}
|
|
340
|
+
if (!this.dirty)
|
|
341
|
+
return;
|
|
342
|
+
this.dirty = false;
|
|
343
|
+
this.emit("change", this.snapshot());
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=mesh-view.js.map
|