@cotal-ai/cli 0.7.0 → 0.8.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.
Files changed (114) hide show
  1. package/dist/commands/down-manifest.d.ts +6 -0
  2. package/dist/commands/down-manifest.d.ts.map +1 -0
  3. package/dist/commands/down-manifest.js +282 -0
  4. package/dist/commands/down-manifest.js.map +1 -0
  5. package/dist/commands/down.d.ts +5 -3
  6. package/dist/commands/down.d.ts.map +1 -1
  7. package/dist/commands/down.js +24 -4
  8. package/dist/commands/down.js.map +1 -1
  9. package/dist/commands/meshes.js +1 -1
  10. package/dist/commands/meshes.js.map +1 -1
  11. package/dist/commands/mint.d.ts.map +1 -1
  12. package/dist/commands/mint.js +2 -1
  13. package/dist/commands/mint.js.map +1 -1
  14. package/dist/commands/setup.d.ts.map +1 -1
  15. package/dist/commands/setup.js +66 -16
  16. package/dist/commands/setup.js.map +1 -1
  17. package/dist/commands/spawn-manifest.d.ts +10 -0
  18. package/dist/commands/spawn-manifest.d.ts.map +1 -0
  19. package/dist/commands/spawn-manifest.js +197 -0
  20. package/dist/commands/spawn-manifest.js.map +1 -0
  21. package/dist/commands/spawn.d.ts.map +1 -1
  22. package/dist/commands/spawn.js +31 -4
  23. package/dist/commands/spawn.js.map +1 -1
  24. package/dist/commands/topology.d.ts +10 -0
  25. package/dist/commands/topology.d.ts.map +1 -0
  26. package/dist/commands/topology.js +46 -0
  27. package/dist/commands/topology.js.map +1 -0
  28. package/dist/commands/up.d.ts +4 -0
  29. package/dist/commands/up.d.ts.map +1 -1
  30. package/dist/commands/up.js +112 -2
  31. package/dist/commands/up.js.map +1 -1
  32. package/dist/commands/use.d.ts +1 -1
  33. package/dist/commands/use.d.ts.map +1 -1
  34. package/dist/commands/use.js +1 -1
  35. package/dist/commands/use.js.map +1 -1
  36. package/dist/commands/web.d.ts.map +1 -1
  37. package/dist/commands/web.js +3 -1
  38. package/dist/commands/web.js.map +1 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +10 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/lib/connect.d.ts +18 -16
  43. package/dist/lib/connect.d.ts.map +1 -1
  44. package/dist/lib/connect.js +27 -51
  45. package/dist/lib/connect.js.map +1 -1
  46. package/dist/lib/delivery-proc.d.ts.map +1 -1
  47. package/dist/lib/delivery-proc.js +2 -1
  48. package/dist/lib/delivery-proc.js.map +1 -1
  49. package/dist/lib/manager-proc.d.ts +4 -0
  50. package/dist/lib/manager-proc.d.ts.map +1 -1
  51. package/dist/lib/manager-proc.js +17 -0
  52. package/dist/lib/manager-proc.js.map +1 -1
  53. package/dist/lib/manifest/apply.d.ts +29 -0
  54. package/dist/lib/manifest/apply.d.ts.map +1 -0
  55. package/dist/lib/manifest/apply.js +138 -0
  56. package/dist/lib/manifest/apply.js.map +1 -0
  57. package/dist/lib/manifest/errors.d.ts +21 -0
  58. package/dist/lib/manifest/errors.d.ts.map +1 -0
  59. package/dist/lib/manifest/errors.js +19 -0
  60. package/dist/lib/manifest/errors.js.map +1 -0
  61. package/dist/lib/manifest/index.d.ts +13 -0
  62. package/dist/lib/manifest/index.d.ts.map +1 -0
  63. package/dist/lib/manifest/index.js +21 -0
  64. package/dist/lib/manifest/index.js.map +1 -0
  65. package/dist/lib/manifest/ledger.d.ts +81 -0
  66. package/dist/lib/manifest/ledger.d.ts.map +1 -0
  67. package/dist/lib/manifest/ledger.js +213 -0
  68. package/dist/lib/manifest/ledger.js.map +1 -0
  69. package/dist/lib/manifest/live.d.ts +25 -0
  70. package/dist/lib/manifest/live.d.ts.map +1 -0
  71. package/dist/lib/manifest/live.js +61 -0
  72. package/dist/lib/manifest/live.js.map +1 -0
  73. package/dist/lib/manifest/model.d.ts +71 -0
  74. package/dist/lib/manifest/model.d.ts.map +1 -0
  75. package/dist/lib/manifest/model.js +2 -0
  76. package/dist/lib/manifest/model.js.map +1 -0
  77. package/dist/lib/manifest/preflight.d.ts +12 -0
  78. package/dist/lib/manifest/preflight.d.ts.map +1 -0
  79. package/dist/lib/manifest/preflight.js +43 -0
  80. package/dist/lib/manifest/preflight.js.map +1 -0
  81. package/dist/lib/manifest/prepare.d.ts +57 -0
  82. package/dist/lib/manifest/prepare.d.ts.map +1 -0
  83. package/dist/lib/manifest/prepare.js +95 -0
  84. package/dist/lib/manifest/prepare.js.map +1 -0
  85. package/dist/lib/manifest/render.d.ts +41 -0
  86. package/dist/lib/manifest/render.d.ts.map +1 -0
  87. package/dist/lib/manifest/render.js +177 -0
  88. package/dist/lib/manifest/render.js.map +1 -0
  89. package/dist/lib/manifest/resolve.d.ts +5 -0
  90. package/dist/lib/manifest/resolve.d.ts.map +1 -0
  91. package/dist/lib/manifest/resolve.js +185 -0
  92. package/dist/lib/manifest/resolve.js.map +1 -0
  93. package/dist/lib/manifest/schema.d.ts +103 -0
  94. package/dist/lib/manifest/schema.d.ts.map +1 -0
  95. package/dist/lib/manifest/schema.js +77 -0
  96. package/dist/lib/manifest/schema.js.map +1 -0
  97. package/dist/lib/manifest/spawn-plan.d.ts +87 -0
  98. package/dist/lib/manifest/spawn-plan.d.ts.map +1 -0
  99. package/dist/lib/manifest/spawn-plan.js +75 -0
  100. package/dist/lib/manifest/spawn-plan.js.map +1 -0
  101. package/dist/lib/meshes.d.ts +1 -7
  102. package/dist/lib/meshes.d.ts.map +1 -1
  103. package/dist/lib/meshes.js +5 -14
  104. package/dist/lib/meshes.js.map +1 -1
  105. package/dist/lib/onboard.js +1 -1
  106. package/dist/lib/onboard.js.map +1 -1
  107. package/dist/lib/paths.js +1 -1
  108. package/dist/lib/paths.js.map +1 -1
  109. package/dist/lib/status.d.ts.map +1 -1
  110. package/dist/lib/status.js +2 -1
  111. package/dist/lib/status.js.map +1 -1
  112. package/dist/web/graph.html +3 -0
  113. package/dist/web/graph.js +76 -21
  114. package/package.json +6 -2
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The mesh-manifest schema (`cotal.yaml`, `kind: Mesh`) — the strict Zod shape the parser
3
+ * validates before any normalization. Strict objects reject unknown keys (no silent ignore —
4
+ * matches the repo's "no fallbacks" rule); the resolved/inverted model lives in {@link ./model.js}.
5
+ *
6
+ * This is shape-only: cross-field rules (names resolve to an agent, `allowSubscribe ⊇ subscribe`,
7
+ * concrete channel tokens) are pure semantic checks in {@link ./resolve.js}, where they can report
8
+ * the offending file + line.
9
+ */
10
+ import { z } from "zod";
11
+ const DeliveryClass = z.enum(["live", "durable"]);
12
+ const PersonaPermissions = z.enum(["reject", "include"]);
13
+ /** An `agents:` value is a string (a bare persona path) OR an object — either an override on a
14
+ * persona file (`persona:` present) or a fully inline agent (no `persona:`). One object schema
15
+ * covers both; {@link ./resolve.js} splits them on the presence of `persona`. */
16
+ const AgentEntryObject = z
17
+ .strictObject({
18
+ persona: z.string().min(1).optional(),
19
+ /** Connector type to spawn this agent with (claude / opencode / hermes / …). Overrides the
20
+ * top-level `agent:` default; one of the two must be set (no silent default — matches roster). */
21
+ agent: z.string().min(1).optional(),
22
+ model: z.string().min(1).optional(),
23
+ role: z.string().min(1).optional(),
24
+ description: z.string().optional(),
25
+ instructions: z.string().optional(),
26
+ capabilities: z.array(z.string().min(1)).optional(),
27
+ /** Per-agent override of the top-level `personaPermissions` policy. */
28
+ personaPermissions: PersonaPermissions.optional(),
29
+ })
30
+ .refine((v) => v.persona !== undefined || v.model !== undefined || v.instructions !== undefined, {
31
+ message: "inline agent (no `persona:`) needs at least `model` or `instructions` — otherwise reference a persona file",
32
+ });
33
+ /** An `agents:` value is a string (bare persona path) OR the object above. A plain `z.union`
34
+ * collapses an object with a bad key to a useless "Invalid input", so normalize the string form to
35
+ * `{ persona }` first and validate the one strict object — its real errors (unrecognized key, …)
36
+ * then surface with their path. */
37
+ const AgentEntry = z.preprocess((v) => (typeof v === "string" ? { persona: v } : v), AgentEntryObject);
38
+ /** A channel carries its registry card (description/instructions + replay knobs — the existing
39
+ * ChannelConfig fields) plus the three native access verbs listed per-channel (agents under it). */
40
+ const ChannelEntry = z.strictObject({
41
+ description: z.string().optional(),
42
+ instructions: z.string().optional(),
43
+ subscribe: z.array(z.string().min(1)).optional(),
44
+ allowSubscribe: z.array(z.string().min(1)).optional(),
45
+ allowPublish: z.array(z.string().min(1)).optional(),
46
+ replay: z.boolean().optional(),
47
+ replayWindow: z.string().optional(),
48
+ deliveryClass: DeliveryClass.optional(),
49
+ });
50
+ const Defaults = z.strictObject({
51
+ replay: z.boolean().optional(),
52
+ replayWindow: z.string().optional(),
53
+ deliveryClass: DeliveryClass.optional(),
54
+ });
55
+ const Broker = z.strictObject({
56
+ servers: z.string().min(1).optional(),
57
+ host: z.string().min(1).optional(),
58
+ auth: z.boolean().optional(),
59
+ });
60
+ /** The whole manifest. `apiVersion`/`kind` are literals so a foreign YAML doc is rejected up front;
61
+ * `agents` and `channels` are required maps. */
62
+ export const MeshManifestSchema = z.strictObject({
63
+ apiVersion: z.literal("cotal/v1"),
64
+ kind: z.literal("Mesh"),
65
+ space: z.string().min(1),
66
+ broker: Broker.optional(),
67
+ runtime: z.enum(["pty", "tmux", "cmux"]).optional(),
68
+ /** Default connector for agents that don't set their own `agent:`. */
69
+ agent: z.string().min(1).optional(),
70
+ personaPermissions: PersonaPermissions.optional(),
71
+ // `agents` is optional — a channels-first manifest can seed the rooms now and add agents later.
72
+ // A channel that references an undeclared name is still a hard error (in resolve.ts).
73
+ agents: z.record(z.string().min(1), AgentEntry).optional(),
74
+ defaults: Defaults.optional(),
75
+ channels: z.record(z.string().min(1), ChannelEntry),
76
+ });
77
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/lib/manifest/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * `cotal spawn -f` classification — the pure decision layer over a running mesh's live state (the
3
+ * channel registry, the roster, the broker-sourced membership feed) plus any prior ledger for this
4
+ * manifest. It never mutates: it produces the plan that drives `--dry-run`, the apply grouping, and
5
+ * the SECURITY warnings. Creation-only by construction — a pre-existing unmanaged channel/agent is
6
+ * classified, never adopted or patched.
7
+ */
8
+ import { type ChannelConfig, type ChannelRegistryFile, type MembershipSnapshot, type Presence } from "@cotal-ai/core";
9
+ import type { ResolvedChannel } from "./model.js";
10
+ import type { PreparedAgent } from "./prepare.js";
11
+ import type { MeshLedger } from "./ledger.js";
12
+ export interface ChannelPlan {
13
+ /** Brand-new registry keys this run will create + seed + ledger-own. */
14
+ create: ResolvedChannel[];
15
+ /** Keys that already exist and are NOT owned by this run — left untouched (no card mutation); the
16
+ * manifest-desired card is shown against the live one. */
17
+ existsUnmanaged: Array<{
18
+ channel: ResolvedChannel;
19
+ live: ChannelConfig;
20
+ }>;
21
+ /** Keys this run already owns (prior ledger) — ours to additively re-seed. */
22
+ owned: ResolvedChannel[];
23
+ }
24
+ /** Classify each declared channel against the live registry + this run's owned keys. Only brand-new
25
+ * keys are creatable/ownable; a key present but unowned is `exists-unmanaged` (never adopted). */
26
+ export declare function classifyChannels(declared: ResolvedChannel[], live: ChannelRegistryFile, ownedKeys: Set<string>): ChannelPlan;
27
+ export type AgentDisposition = "will-create" | "already-owned" | "stale";
28
+ export interface PriorAgent {
29
+ requested: string;
30
+ name: string;
31
+ id: string;
32
+ hash: string;
33
+ }
34
+ export interface AgentPlanEntry {
35
+ agent: PreparedAgent;
36
+ /** Resolved hash of the declared agent (drift key). */
37
+ hash: string;
38
+ disposition: AgentDisposition;
39
+ /** The prior ledger entry, for `already-owned` / `stale`. */
40
+ prior?: PriorAgent;
41
+ /** Whether the prior spawned agent is currently present on the mesh (stale wording). */
42
+ running?: boolean;
43
+ }
44
+ export interface AgentPlan {
45
+ entries: AgentPlanEntry[];
46
+ willCreate: AgentPlanEntry[];
47
+ alreadyOwned: AgentPlanEntry[];
48
+ stale: AgentPlanEntry[];
49
+ }
50
+ /** Classify declared agents against any prior ledger (matched by manifest key) + the live roster:
51
+ * not previously created → `will-create`; previously created + same resolved hash → `already-owned`
52
+ * (no-op); previously created + hash changed → `stale` (restart required). */
53
+ export declare function classifyAgents(agents: PreparedAgent[], roster: Presence[], prior?: MeshLedger): AgentPlan;
54
+ export interface UnmanagedActor {
55
+ id: string;
56
+ name?: string;
57
+ /** How the access was observed: a durable membership record, or a live (CONNZ) subscription. */
58
+ via: "durable" | "live";
59
+ }
60
+ export interface ChannelExposure {
61
+ channel: string;
62
+ actors: UnmanagedActor[];
63
+ }
64
+ export interface UnmanagedReport {
65
+ /** Per declared channel: unmanaged actors observed with read access to it (a SECURITY conflict). */
66
+ perChannel: ChannelExposure[];
67
+ /** True when the broker-sourced membership feed was readable (the per-channel signal is meaningful).
68
+ * When false, the report is presence-only — an explicit LOWER BOUND, not "no unmanaged access." */
69
+ feedAvailable: boolean;
70
+ /** Feed freshness (epoch ms) when available. */
71
+ asOf?: number;
72
+ /** Present peers not owned by this run — mesh-level context (not necessarily on a declared channel). */
73
+ presentUnowned: Array<{
74
+ id: string;
75
+ name: string;
76
+ role?: string;
77
+ }>;
78
+ }
79
+ /** Observe unmanaged actors with read access to a manifest-declared channel — an isolation conflict
80
+ * on a shared mesh. v1 is an explicit LOWER BOUND: it uses the roster (presence) + the broker
81
+ * membership feed (durable members + CONNZ live subscriptions); when the feed is absent it falls back
82
+ * to presence only and says so. `owned` is this run's agents (ids + spawned names) to exclude. */
83
+ export declare function detectUnmanagedActors(declared: string[], snapshot: MembershipSnapshot | null, roster: Presence[], owned: {
84
+ ids: Set<string>;
85
+ names: Set<string>;
86
+ }): UnmanagedReport;
87
+ //# sourceMappingURL=spawn-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-plan.d.ts","sourceRoot":"","sources":["../../../src/lib/manifest/spawn-plan.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACtI,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C,MAAM,WAAW,WAAW;IAC1B,wEAAwE;IACxE,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B;+DAC2D;IAC3D,eAAe,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,eAAe,CAAC;QAAC,IAAI,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;IAC1E,8EAA8E;IAC9E,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED;mGACmG;AACnG,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,WAAW,CAW5H;AAID,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,eAAe,GAAG,OAAO,CAAC;AAEzE,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,gBAAgB,CAAC;IAC9B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED;;+EAE+E;AAC/E,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,SAAS,CAgBzG;AAID,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gGAAgG;IAChG,GAAG,EAAE,SAAS,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,oGAAoG;IACpG,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B;wGACoG;IACpG,aAAa,EAAE,OAAO,CAAC;IACvB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wGAAwG;IACxG,cAAc,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE;AAED;;;mGAGmG;AACnG,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,EAAE,kBAAkB,GAAG,IAAI,EACnC,MAAM,EAAE,QAAQ,EAAE,EAClB,KAAK,EAAE;IAAE,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,GAC9C,eAAe,CAmBjB"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `cotal spawn -f` classification — the pure decision layer over a running mesh's live state (the
3
+ * channel registry, the roster, the broker-sourced membership feed) plus any prior ledger for this
4
+ * manifest. It never mutates: it produces the plan that drives `--dry-run`, the apply grouping, and
5
+ * the SECURITY warnings. Creation-only by construction — a pre-existing unmanaged channel/agent is
6
+ * classified, never adopted or patched.
7
+ */
8
+ import { subjectMatches } from "@cotal-ai/core";
9
+ import { hashAgent } from "./apply.js";
10
+ /** Classify each declared channel against the live registry + this run's owned keys. Only brand-new
11
+ * keys are creatable/ownable; a key present but unowned is `exists-unmanaged` (never adopted). */
12
+ export function classifyChannels(declared, live, ownedKeys) {
13
+ const create = [];
14
+ const existsUnmanaged = [];
15
+ const owned = [];
16
+ for (const ch of declared) {
17
+ const liveCfg = live.channels?.[ch.name];
18
+ if (!liveCfg)
19
+ create.push(ch);
20
+ else if (ownedKeys.has(ch.name))
21
+ owned.push(ch);
22
+ else
23
+ existsUnmanaged.push({ channel: ch, live: liveCfg });
24
+ }
25
+ return { create, existsUnmanaged, owned };
26
+ }
27
+ /** Classify declared agents against any prior ledger (matched by manifest key) + the live roster:
28
+ * not previously created → `will-create`; previously created + same resolved hash → `already-owned`
29
+ * (no-op); previously created + hash changed → `stale` (restart required). */
30
+ export function classifyAgents(agents, roster, prior) {
31
+ const present = new Set(roster.filter((p) => p.status !== "offline").map((p) => p.card.name));
32
+ const priorByKey = new Map((prior?.created.agents ?? []).map((a) => [a.requested, a]));
33
+ const entries = agents.map((agent) => {
34
+ const hash = hashAgent(agent);
35
+ const p = priorByKey.get(agent.name); // PreparedAgent.name is the manifest `agents:` key
36
+ if (!p)
37
+ return { agent, hash, disposition: "will-create" };
38
+ const running = present.has(p.name);
39
+ return { agent, hash, disposition: p.hash === hash ? "already-owned" : "stale", prior: p, running };
40
+ });
41
+ return {
42
+ entries,
43
+ willCreate: entries.filter((e) => e.disposition === "will-create"),
44
+ alreadyOwned: entries.filter((e) => e.disposition === "already-owned"),
45
+ stale: entries.filter((e) => e.disposition === "stale"),
46
+ };
47
+ }
48
+ /** Observe unmanaged actors with read access to a manifest-declared channel — an isolation conflict
49
+ * on a shared mesh. v1 is an explicit LOWER BOUND: it uses the roster (presence) + the broker
50
+ * membership feed (durable members + CONNZ live subscriptions); when the feed is absent it falls back
51
+ * to presence only and says so. `owned` is this run's agents (ids + spawned names) to exclude. */
52
+ export function detectUnmanagedActors(declared, snapshot, roster, owned) {
53
+ const presentUnowned = roster
54
+ .filter((p) => p.status !== "offline" && !owned.ids.has(p.card.id) && !owned.names.has(p.card.name))
55
+ .map((p) => ({ id: p.card.id, name: p.card.name, role: p.card.role }));
56
+ const nameOf = new Map(roster.map((p) => [p.card.id, p.card.name]));
57
+ const perChannel = [];
58
+ if (snapshot) {
59
+ for (const channel of declared) {
60
+ const actors = [];
61
+ for (const m of snapshot.members) {
62
+ if (owned.ids.has(m.id))
63
+ continue;
64
+ const durable = m.durable.includes(channel);
65
+ const live = !durable && m.live.some((pat) => subjectMatches(pat, channel)); // channel-token wildcards (`team.>`)
66
+ if (durable || live)
67
+ actors.push({ id: m.id, name: nameOf.get(m.id), via: durable ? "durable" : "live" });
68
+ }
69
+ if (actors.length)
70
+ perChannel.push({ channel, actors });
71
+ }
72
+ }
73
+ return { perChannel, feedAvailable: Boolean(snapshot?.asOf), asOf: snapshot?.asOf, presentUnowned };
74
+ }
75
+ //# sourceMappingURL=spawn-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn-plan.js","sourceRoot":"","sources":["../../../src/lib/manifest/spawn-plan.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,2 @@
1
- /**
2
- * Drop registry entries whose broker is gone — a `cotal up` that crashed or was `kill -9`'d without
3
- * `cotal down` leaves a record behind. Probe each in parallel; only `unreachable` (refused/timeout)
4
- * is stale, an auth broker answering `auth-required` is alive. Called by `spawn`/`use`/`meshes`
5
- * before they act on the registry — never by completion (a `<TAB>` must not open the network).
6
- */
7
- export declare function pruneStaleMeshes(): Promise<void>;
1
+ export { pruneStaleMeshes } from "@cotal-ai/workspace";
8
2
  //# sourceMappingURL=meshes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"meshes.d.ts","sourceRoot":"","sources":["../../src/lib/meshes.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOtD"}
1
+ {"version":3,"file":"meshes.d.ts","sourceRoot":"","sources":["../../src/lib/meshes.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,15 +1,6 @@
1
- import { loadMeshes, probeConnect, removeMesh } from "@cotal-ai/core";
2
- /**
3
- * Drop registry entries whose broker is gone — a `cotal up` that crashed or was `kill -9`'d without
4
- * `cotal down` leaves a record behind. Probe each in parallel; only `unreachable` (refused/timeout)
5
- * is stale, an auth broker answering `auth-required` is alive. Called by `spawn`/`use`/`meshes`
6
- * before they act on the registry — never by completion (a `<TAB>` must not open the network).
7
- */
8
- export async function pruneStaleMeshes() {
9
- await Promise.all(loadMeshes().map(async (m) => {
10
- const r = await probeConnect(m.server);
11
- if (!r.ok && r.reason === "unreachable")
12
- removeMesh(m.space);
13
- }));
14
- }
1
+ // `pruneStaleMeshes` lives in `@cotal-ai/workspace` (`preflight.ts`) — the workstation layer the
2
+ // manager control commands share too. Re-exported from here so its CLI importers (`connect`,
3
+ // `commands/meshes`, `commands/use`) and the `spawn-from-anywhere` smokes keep resolving it from
4
+ // this module unchanged.
5
+ export { pruneStaleMeshes } from "@cotal-ai/workspace";
15
6
  //# sourceMappingURL=meshes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"meshes.js","sourceRoot":"","sources":["../../src/lib/meshes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEtE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,OAAO,CAAC,GAAG,CACf,UAAU,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3B,MAAM,CAAC,GAAG,MAAM,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,aAAa;YAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC/D,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"meshes.js","sourceRoot":"","sources":["../../src/lib/meshes.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,6FAA6F;AAC7F,iGAAiG;AACjG,yBAAyB;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { existsSync, mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { homeCotalDir } from "@cotal-ai/core";
3
+ import { homeCotalDir } from "@cotal-ai/workspace";
4
4
  /** Machine-level "I've onboarded before" marker. Its presence flips `cotal` from the
5
5
  * full first-run flow to the compact ensure+status run. Lives next to the materialized
6
6
  * plugin marketplace under ~/.cotal (COTAL_HOME-overridable, via {@link homeCotalDir}). */
@@ -1 +1 @@
1
- {"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/lib/onboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C;;4FAE4F;AAC5F,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAE5D,MAAM,UAAU,WAAW;IACzB,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,SAAS,CAAC,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,aAAa,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC"}
1
+ {"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/lib/onboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;4FAE4F;AAC5F,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAE5D,MAAM,UAAU,WAAW;IACzB,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,SAAS,CAAC,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,aAAa,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC"}
package/dist/lib/paths.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { join } from "node:path";
2
- import { findCotalRoot } from "@cotal-ai/core";
2
+ import { findCotalRoot } from "@cotal-ai/workspace";
3
3
  /** The project's `.cotal/` root, found by walking up from cwd (like git finds `.git`), so every
4
4
  * command resolves the same `.cotal/` whether you're at the project root or a subdirectory. */
5
5
  export function cotalRoot() {
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C;gGACgG;AAChG,MAAM,UAAU,SAAS;IACvB,OAAO,aAAa,EAAE,CAAC;AACzB,CAAC;AAED;yDACyD;AACzD,MAAM,UAAU,SAAS,CAAC,GAAG,QAAkB;IAC7C,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD;gGACgG;AAChG,MAAM,UAAU,SAAS;IACvB,OAAO,aAAa,EAAE,CAAC;AACzB,CAAC;AAED;yDACyD;AACzD,MAAM,UAAU,SAAS,CAAC,GAAG,QAAkB;IAC7C,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,GAAG,QAAQ,CAAC,CAAC;AAClD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lib/status.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;sEAEsE;AACtE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;8FAC8F;AAC9F,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CASjE;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;CAChD;AAED,kEAAkE;AAClE,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,CAe5D;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG3C;AAQD,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGjD"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lib/status.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;sEAEsE;AACtE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;8FAC8F;AAC9F,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CASjE;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;CAChD;AAED,kEAAkE;AAClE,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,CAe5D;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG3C;AAQD,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGjD"}
@@ -1,7 +1,8 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import { existsSync } from "node:fs";
3
3
  import { join } from "node:path";
4
- import { DEFAULT_SERVER, DEFAULT_SPACE, authDir, findCotalRoot, isReachable, loadSpaceAuth } from "@cotal-ai/core";
4
+ import { DEFAULT_SERVER, DEFAULT_SPACE, isReachable } from "@cotal-ai/core";
5
+ import { authDir, findCotalRoot, loadSpaceAuth } from "@cotal-ai/workspace";
5
6
  import { resolveNatsServer } from "./nats-bin.js";
6
7
  /** The space this folder operates on: its `.cotal/auth` space if set up, else the default.
7
8
  * A folder has exactly one space (its auth) — commands resolve it through here so they always
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/lib/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AASlD;;sEAEsE;AACtE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,aAAa,CAAC;AAC5E,CAAC;AAED;8FAC8F;AAC9F,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,MAAM,GAAG,cAAc,CAAC;IAC9B,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO;QACL,SAAS,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC;QACpC,MAAM;QACN,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,aAAa;QACnC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;KACpB,CAAC;AACJ,CAAC;AAQD,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,IAAI,GAA0B,SAAS,CAAC;IAC5C,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,SAAS,CAAC;IACnB,CAAC;IACD,OAAO;QACL,IAAI;QACJ,YAAY,EAAE,qBAAqB,EAAE;QACrC,MAAM,EAAE;YACN,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC;YACxB,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC;SAC7B;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAW;IAChC,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,qBAAqB;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC;AACzF,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3G,CAAC"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/lib/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AASlD;;sEAEsE;AACtE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,OAAO,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,aAAa,CAAC;AAC5E,CAAC;AAED;8FAC8F;AAC9F,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,MAAM,GAAG,cAAc,CAAC;IAC9B,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO;QACL,SAAS,EAAE,MAAM,WAAW,CAAC,MAAM,CAAC;QACpC,MAAM;QACN,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,aAAa;QACnC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;KACpB,CAAC;AACJ,CAAC;AAQD,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,IAAI,GAA0B,SAAS,CAAC;IAC5C,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,SAAS,CAAC;IACnB,CAAC;IACD,OAAO;QACL,IAAI;QACJ,YAAY,EAAE,qBAAqB,EAAE;QACrC,MAAM,EAAE;YACN,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC;YACxB,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC;SAC7B;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAW;IAChC,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,qBAAqB;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC;AACzF,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAChC,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAC3G,CAAC"}
@@ -73,6 +73,7 @@
73
73
  .chip.mode.chat.on { color: var(--chat); } .chip.mode.unicast.on { color: var(--unicast); }
74
74
  .chip.mode.anycast.on { color: var(--anycast); }
75
75
  .chip.pause.on { color: var(--waiting); border-color: var(--waiting); }
76
+ .chip.offline.on { color: var(--idle); border-color: var(--line); }
76
77
 
77
78
  /* ── legend (bottom-left, collapsible) ── */
78
79
  #legend { position: fixed; left: 14px; bottom: 14px; z-index: 10; padding: 0;
@@ -175,6 +176,8 @@
175
176
  <span class="chip mode unicast on" data-mode="unicast">direct</span>
176
177
  <span class="chip mode anycast on" data-mode="anycast">anycast</span>
177
178
  </div>
179
+ <span class="chip offline on" id="hideOffline">hide offline</span>
180
+ <span class="chip offline on" id="hideEmpty">hide empty</span>
178
181
  <span class="chip pause" id="pause">⏸ pause</span>
179
182
  </div>
180
183
  </header>