super-dsh 0.1.5 → 0.1.9

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 (79) hide show
  1. package/client/index.js +1010 -345
  2. package/cordis.patch.yml +22 -5
  3. package/package.json +8 -3
  4. package/superd-hub/dist/a2a-delivery.d.ts +189 -0
  5. package/superd-hub/dist/a2a-delivery.js +240 -0
  6. package/superd-hub/dist/a2a-host.d.ts +76 -0
  7. package/superd-hub/dist/a2a-host.js +145 -0
  8. package/superd-hub/dist/a2a-ingest.d.ts +31 -0
  9. package/superd-hub/dist/a2a-ingest.js +636 -0
  10. package/superd-hub/dist/a2a-log.d.ts +17 -0
  11. package/superd-hub/dist/a2a-log.js +42 -0
  12. package/superd-hub/dist/a2a-row.d.ts +65 -0
  13. package/superd-hub/dist/a2a-row.js +162 -0
  14. package/superd-hub/dist/a2a-service.d.ts +357 -0
  15. package/superd-hub/dist/a2a-service.js +980 -0
  16. package/superd-hub/dist/a2a-wire.d.ts +220 -0
  17. package/superd-hub/dist/a2a-wire.js +305 -0
  18. package/superd-hub/dist/agent-ids.d.ts +10 -0
  19. package/superd-hub/dist/agent-ids.js +68 -0
  20. package/superd-hub/dist/agent-roster.d.ts +32 -17
  21. package/superd-hub/dist/agent-roster.js +54 -15
  22. package/superd-hub/dist/agent-status.d.ts +119 -0
  23. package/superd-hub/dist/agent-status.js +386 -0
  24. package/superd-hub/dist/client/mesh-api.d.ts +134 -0
  25. package/superd-hub/dist/client/mesh-api.js +219 -0
  26. package/superd-hub/dist/client/mesh-groups.d.ts +63 -0
  27. package/superd-hub/dist/client/mesh-groups.js +66 -0
  28. package/superd-hub/dist/client/roster.d.ts +48 -0
  29. package/superd-hub/dist/client/roster.js +96 -0
  30. package/superd-hub/dist/exec-pty-channel.d.ts +58 -0
  31. package/superd-hub/dist/exec-pty-channel.js +162 -0
  32. package/superd-hub/dist/exec-pty-framing.d.ts +32 -0
  33. package/superd-hub/dist/exec-pty-framing.js +81 -0
  34. package/superd-hub/dist/exec-pty-rpc.d.ts +21 -0
  35. package/superd-hub/dist/exec-pty-rpc.js +128 -0
  36. package/superd-hub/dist/exec-pty-session.d.ts +76 -0
  37. package/superd-hub/dist/exec-pty-session.js +234 -0
  38. package/superd-hub/dist/exec.d.ts +56 -0
  39. package/superd-hub/dist/exec.js +225 -0
  40. package/superd-hub/dist/fusion-transport.d.ts +23 -21
  41. package/superd-hub/dist/fusion-transport.js +12 -40
  42. package/superd-hub/dist/gateway.d.ts +39 -2
  43. package/superd-hub/dist/gateway.js +62 -3
  44. package/superd-hub/dist/hub-tool.d.ts +174 -0
  45. package/superd-hub/dist/hub-tool.js +464 -0
  46. package/superd-hub/dist/index.d.ts +18 -4
  47. package/superd-hub/dist/index.js +19 -3
  48. package/superd-hub/dist/machines.d.ts +45 -0
  49. package/superd-hub/dist/machines.js +125 -0
  50. package/superd-hub/dist/mesh-federate.d.ts +138 -0
  51. package/superd-hub/dist/mesh-federate.js +223 -0
  52. package/superd-hub/dist/mesh-gateway.d.ts +67 -0
  53. package/superd-hub/dist/mesh-gateway.js +408 -0
  54. package/superd-hub/dist/mesh-link.d.ts +274 -0
  55. package/superd-hub/dist/mesh-link.js +441 -0
  56. package/superd-hub/dist/mesh-rpc.d.ts +123 -0
  57. package/superd-hub/dist/mesh-rpc.js +250 -0
  58. package/superd-hub/dist/mux-client.d.ts +71 -0
  59. package/superd-hub/dist/mux-client.js +281 -0
  60. package/superd-hub/dist/pack-version.d.ts +2 -0
  61. package/superd-hub/dist/pack-version.js +30 -0
  62. package/superd-hub/dist/roster.d.ts +10 -0
  63. package/superd-hub/dist/roster.js +9 -1
  64. package/superd-hub/dist/rpc.d.ts +18 -2
  65. package/superd-hub/dist/rpc.js +34 -4
  66. package/superd-hub/dist/spawn-world.js +3 -1
  67. package/superd-hub/dist/switch-core.d.ts +98 -21
  68. package/superd-hub/dist/switch-core.js +123 -28
  69. package/superd-hub/dist/system-head.d.ts +22 -12
  70. package/superd-hub/dist/system-head.js +100 -84
  71. package/superd-hub/dist/toast-core.d.ts +43 -0
  72. package/superd-hub/dist/toast-core.js +63 -0
  73. package/superd-hub/dist/wire-endpoints.d.ts +264 -0
  74. package/superd-hub/dist/wire-endpoints.js +180 -0
  75. package/superd-hub/dist/world-join.js +8 -3
  76. package/superd-hub/dist/world-mount.d.ts +27 -0
  77. package/superd-hub/dist/world-mount.js +67 -0
  78. package/superd-hub/lib/client/index.js +1010 -345
  79. package/superd-hub/package.json +11 -2
@@ -48,9 +48,9 @@
48
48
  * so cordis's FIFO effect order guarantees trust pushes first and fusion
49
49
  * pushes last — the non-merging `if(!window.__DSH_TRANSPORT__)` verdict in the
50
50
  * trust script is always evaluated before anything could own that global.
51
- * Flag gate (minimal, Task 5 formalizes the config face): row config
52
- * `enabled`, defaulting OFF from the `SUPERD_UI_FUSION` env — while the flag
53
- * is off the component stays dormant and injects no row at all.
51
+ * Row gate: the row config `enabled`, ON by default — the composite patch
52
+ * composing this row is the switch. `enabled: false` (or `disabled: true`)
53
+ * leaves the component dormant: no listener, no script, no flag global.
54
54
  *
55
55
  * @module @pgmi-builds/superd-hub/fusion-transport
56
56
  */
@@ -319,49 +319,19 @@ try {
319
319
  } catch { /* the whole install is best-effort: a partial page is still a page */ }
320
320
  })()`;
321
321
  }
322
- /** The env name the minimal Task-3 gate reads; Task 5 builds the config face on it. */
323
- export const FUSION_FLAG_ENV = 'SUPERD_UI_FUSION';
324
322
  /**
325
- * The page global the ctx0 index carries when the gate is on: the client
323
+ * The page global the ctx0 index carries when this row is on: the client
326
324
  * half's fusion-branch discriminator (the Hub UI switch surfaces read its
327
325
  * presence to intercept agent clicks into the switch orchestration instead
328
326
  * of letting the hyperlinks navigate — the sole switch surface since the T-B
329
327
  * RuntimeSeat retirement; world pages never carry it, so they keep the real
330
- * navigation half — spec §5 双半边). Baked by the SAME gated listener as the
328
+ * navigation half — spec §5 双半边). Baked by the SAME listener as the
331
329
  * transport script, so the two halves can never disagree.
332
330
  */
333
331
  export const FUSION_FLAG_GLOBAL = '__SUPERD_UI_FUSION__';
334
- /**
335
- * The flag's SEMANTICS after the path-separation Part 2 closeout (T-C/T-D
336
- * landed; this block is the T-E closeout record) — native-ui-only, there is
337
- * no fallback route anywhere:
338
- *
339
- * - ON: the ctx0 page fuses. The transport script arms the in-place switch
340
- * and `/hub` is the sole surface for every runtime. The per-label URL
341
- * family (`/<label>/` ctx0 pages, T-C) and the world web UIs (T-D) are
342
- * RETIRED from the product, not gated by this flag — there is nothing
343
- * navigational behind them to fall back to.
344
- * - OFF: NO foreign entry exists AT ALL. The served product is the bare
345
- * native UI plus the Hub panel as an information surface: the roster
346
- * still lists the runtimes (the control plane is not gated), but the
347
- * switch affordances render inert with the degradation hint
348
- * (`switchAffordance` in switch-core) instead of dead controls — a row
349
- * has no /<label>/ page to reach and the Hub UI ships no hrefs to reach
350
- * one with.
351
- *
352
- * The shipped default stays OFF (truthy env opt-in). Moving the default ON is
353
- * the user's 放行 (acceptance/release) round — a two-gate decision per repo
354
- * §〇.1, never a code-side choice.
355
- *
356
- * Derivation: truthy spellings only (`1` / `true` / `yes` / `on`,
357
- * case-insensitive, trimmed). Anything else — unset included — is OFF.
358
- */
359
- export function deriveFusionFlag(env) {
360
- return ['1', 'true', 'yes', 'on'].includes((env ?? '').trim().toLowerCase());
361
- }
362
- /** Row config (schema-level default derives from the {@link FUSION_FLAG_ENV} env). */
332
+ /** Row config: ON unless a patch layer restates the row with `enabled: false`. */
363
333
  export const Config = z.object({
364
- enabled: z.boolean().default(deriveFusionFlag(process.env[FUSION_FLAG_ENV])),
334
+ enabled: z.boolean().default(true),
365
335
  });
366
336
  /** Cordis plugin name. */
367
337
  export const name = 'superd-fusion-transport';
@@ -379,13 +349,15 @@ export const inject = [];
379
349
  * the {@link FUSION_FLAG_GLOBAL} baked global row (Task 4): one gate, both
380
350
  * halves.
381
351
  *
382
- * Flag off → the component registers nothing: no listener, no row, no script,
352
+ * Off → the component registers nothing: no listener, no row, no script,
383
353
  * no flag global.
384
354
  * @param ctx - host plugin context.
385
- * @param config - the row config.
355
+ * @param config - the row config (`enabled`, default on).
386
356
  */
387
357
  export function apply(ctx, config) {
388
- if (config?.enabled !== true)
358
+ // Composed row = on. Only an explicit `enabled: false` turns it off, so a
359
+ // composition that omits the config key cannot silently disable the surface.
360
+ if (config?.enabled === false)
389
361
  return;
390
362
  ctx.inject(['webServer'], () => {
391
363
  ctx.on('webserver/index-inject', (table) => {
@@ -12,14 +12,36 @@
12
12
  * per-world mount registers through `carrier.ts` (AW-B tasks 2-9), which calls
13
13
  * the addressed world's own `typertGateway` instance directly — again without
14
14
  * any shared selection value.
15
+ *
16
+ * Mesh P2 Task 3 adds the federation wiring: mesh-link's machine lifecycle
17
+ * events drive mesh-federate's registrar (pair/reprobe success → converge the
18
+ * remote roster into the registries, probe failure → degrade, removal →
19
+ * defederate), and the `/hub` family's demux gains the federation table ahead
20
+ * of the local target registry (spec §3.2 dual-key: a6 canonical, label
21
+ * aliases compatible).
15
22
  */
16
23
  import type { Context } from '@deepseek-ai/cordis';
24
+ import z from '@deepseek-ai/schemastery';
17
25
  /** Stable Cordis plugin name. */
18
26
  export declare const name = "superd-hub";
27
+ /** Row config schema (mesh P3 Task 5a): the periodic reprobe sweep's knob —
28
+ * seconds between sweeps, default the user mandate's 5 minutes, floored at
29
+ * 60 by the schema AND clamped again in `startReprobeSweep` (a bare-library
30
+ * caller cannot bypass the floor). Patch rows restate the whole config
31
+ * object; schema defaults fill the un-configured one. */
32
+ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
33
+ reprobeIntervalSec: z<number, number, "defined">;
34
+ }>>, Schemastery.ObjectT<NoInfer<{
35
+ reprobeIntervalSec: z<number, number, "defined">;
36
+ }>>, "plain">;
37
+ /** The row config's TypeScript face (the schema-declared knob). */
38
+ export interface HubConfig {
39
+ reprobeIntervalSec?: number;
40
+ }
19
41
  /**
20
42
  * The plugin form (row contract): applied when the row mounts.
21
43
  *
22
- * Three CTX0-owned contributions, none carrying any selection value:
44
+ * CTX0-owned contributions, none carrying any selection value:
23
45
  * - the world inventory control plane (read-only);
24
46
  * - the agent roster row baked into ctx0's own index, so the selector lists
25
47
  * every mount path the hub currently serves;
@@ -28,6 +50,21 @@ export declare const name = "superd-hub";
28
50
  * World trees compose this same row, but their `webServer` is the VIRTUAL
29
51
  * per-world translation surface — the `/hub` family belongs to ctx0's
30
52
  * real listener only (one family per process, demuxed by `?agent=`).
53
+ * - the mesh federation wiring (mesh P2 Task 3): home resolved HERE at
54
+ * registration time (mesh-rpc stays a pure route module; tests inject a
55
+ * tmpdir home instead); the one-way seam is mesh-link's federation event
56
+ * bus — mesh-federate subscribes, mesh-link never imports it.
57
+ * - the periodic reprobe sweep (mesh P3 Task 5a I1-a, user mandate
58
+ * "状态更新走单向 API + 5 分钟周期轮询"): every `reprobeIntervalSec`
59
+ * (default 300, floor 60) one sweep re-probes every ENABLED remote —
60
+ * success converges federation, failure degrades (both via the existing
61
+ * mesh-link hooks). CTX0-ONLY, gated by the same WorldWebServer check as
62
+ * the `/hub` family: world trees compose this row too (world-mount.ts
63
+ * WORLD_HUB_ROW) and must never start their own sweep against the shared
64
+ * machines registry.
65
+ * @param ctx - host plugin context.
66
+ * @param config - the row config (`reprobeIntervalSec`; schema defaults
67
+ * apply when the row is composed without one).
31
68
  */
32
- export declare function apply(ctx: Context): void;
69
+ export declare function apply(ctx: Context, config?: HubConfig): void;
33
70
  export default apply;
@@ -1,14 +1,29 @@
1
+ import z from '@deepseek-ai/schemastery';
1
2
  import { registerSelectorRpc, registryTargets } from './rpc.js';
3
+ import { registerMeshRpc } from './mesh-rpc.js';
4
+ import { startReprobeSweep } from './mesh-link.js';
5
+ import { federatedGatewayOf, startMeshFederation } from './mesh-federate.js';
6
+ import { resolveDshHome } from '@deepseek-ai/dsh-home-paths';
2
7
  import { agentRosterRow } from './agent-roster.js';
3
8
  import { getTarget } from './targets.js';
4
9
  import { registerHubRoute } from './hub-route.js';
5
10
  import { WorldWebServer } from './world-web-server.js';
11
+ import { registerPtyExecutor } from './exec-pty-rpc.js';
12
+ import { consoleA2aLog } from './a2a-log.js';
6
13
  /** Stable Cordis plugin name. */
7
14
  export const name = 'superd-hub';
15
+ /** Row config schema (mesh P3 Task 5a): the periodic reprobe sweep's knob —
16
+ * seconds between sweeps, default the user mandate's 5 minutes, floored at
17
+ * 60 by the schema AND clamped again in `startReprobeSweep` (a bare-library
18
+ * caller cannot bypass the floor). Patch rows restate the whole config
19
+ * object; schema defaults fill the un-configured one. */
20
+ export const Config = z.object({
21
+ reprobeIntervalSec: z.number().min(60).default(300),
22
+ });
8
23
  /**
9
24
  * The plugin form (row contract): applied when the row mounts.
10
25
  *
11
- * Three CTX0-owned contributions, none carrying any selection value:
26
+ * CTX0-owned contributions, none carrying any selection value:
12
27
  * - the world inventory control plane (read-only);
13
28
  * - the agent roster row baked into ctx0's own index, so the selector lists
14
29
  * every mount path the hub currently serves;
@@ -17,9 +32,27 @@ export const name = 'superd-hub';
17
32
  * World trees compose this same row, but their `webServer` is the VIRTUAL
18
33
  * per-world translation surface — the `/hub` family belongs to ctx0's
19
34
  * real listener only (one family per process, demuxed by `?agent=`).
35
+ * - the mesh federation wiring (mesh P2 Task 3): home resolved HERE at
36
+ * registration time (mesh-rpc stays a pure route module; tests inject a
37
+ * tmpdir home instead); the one-way seam is mesh-link's federation event
38
+ * bus — mesh-federate subscribes, mesh-link never imports it.
39
+ * - the periodic reprobe sweep (mesh P3 Task 5a I1-a, user mandate
40
+ * "状态更新走单向 API + 5 分钟周期轮询"): every `reprobeIntervalSec`
41
+ * (default 300, floor 60) one sweep re-probes every ENABLED remote —
42
+ * success converges federation, failure degrades (both via the existing
43
+ * mesh-link hooks). CTX0-ONLY, gated by the same WorldWebServer check as
44
+ * the `/hub` family: world trees compose this row too (world-mount.ts
45
+ * WORLD_HUB_ROW) and must never start their own sweep against the shared
46
+ * machines registry.
47
+ * @param ctx - host plugin context.
48
+ * @param config - the row config (`reprobeIntervalSec`; schema defaults
49
+ * apply when the row is composed without one).
20
50
  */
21
- export function apply(ctx) {
51
+ export function apply(ctx, config) {
22
52
  registerSelectorRpc(ctx, registryTargets);
53
+ const home = resolveDshHome();
54
+ registerMeshRpc(ctx, { home });
55
+ ctx.effect(() => startMeshFederation({ home }), 'superd-hub: mesh federation wiring');
23
56
  const on = ctx.on;
24
57
  on?.call(ctx, 'webserver/index-inject', (table) => { table.push(agentRosterRow()); });
25
58
  ctx.inject(['webServer', 'connection'], (host) => {
@@ -32,13 +65,39 @@ export function apply(ctx) {
32
65
  // table — never a shared selection. The requestRejection face is the
33
66
  // ctx0 browser-trust fence: auth first, then Host/Origin — the family is
34
67
  // never weaker than the neighbors carrying identical traffic.
68
+ //
69
+ // Demux (mesh P2 Task 3, spec §3.2 dual-key): the mesh FEDERATION table
70
+ // first — an exact a6 match is the canonical spelling and beats label
71
+ // aliases — then the shared local target registry (local runtime keys;
72
+ // federated a6s are registered there too, so the fallback re-arms a
73
+ // registration whose memo was cleared independently). Local label aliases
74
+ // and `?agent=<a6>` therefore both demux; under the astronomically rare
75
+ // a6↔local-key collision the federation wins deterministically (documented
76
+ // in mesh-federate's header) instead of last-write-wins in the registry.
77
+ // I1(a) periodic reprobe sweep — CTX0-ONLY by the same gate as the
78
+ // `/hub` family below (world trees see a WorldWebServer and returned
79
+ // early): the machines registry is ctx0-owned, and a per-world timer
80
+ // would multiply probes against every paired remote. The effect's
81
+ // disposer IS the sweep disposer — the timer dies with the row
82
+ // (unref'd, overlap-skipping, per-machine errors swallowed; mesh-link).
83
+ ctx.effect(() => startReprobeSweep({ home, intervalSec: config?.reprobeIntervalSec, immediate: true }), 'superd-hub: mesh reprobe sweep');
35
84
  const dispose = registerHubRoute({
36
85
  real: real,
37
86
  authorize: (req, res) => connection.authorizeIndex(req, res),
38
87
  requestRejection: (req) => connection.requestRejection(req),
39
- gatewayOf: (label) => getTarget(label)?.gateway,
88
+ gatewayOf: (label) => (federatedGatewayOf(label) ?? getTarget(label)?.gateway),
40
89
  });
41
90
  ctx.effect(() => dispose, 'superd-hub: /hub route family');
91
+ // P4 §8.2: the PTY executor's upgrade route — same gate as the /hub family
92
+ // (authorizeIndex cookie auth first, then the browser-trust fence). The
93
+ // dumb pump lives in exec-pty-rpc.ts; a2a-row owns the initiator half.
94
+ void registerPtyExecutor(real, {
95
+ authorize: (req, res) => connection.authorizeIndex(req, res),
96
+ requestRejection: (req) => connection.requestRejection(req),
97
+ log: consoleA2aLog(),
98
+ }).then((disposePty) => {
99
+ ctx.effect(() => disposePty, 'superd-hub: PTY executor upgrade route');
100
+ }, () => { });
42
101
  });
43
102
  }
44
103
  export default apply;
@@ -0,0 +1,174 @@
1
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
2
+ import type { A2aDeliveryCtx } from './a2a-delivery.js';
3
+ import type { AgentLink } from './agent-roster.js';
4
+ import type { AgentStatusFile } from './agent-status.js';
5
+ import { type OneShotExecInput, type OneShotExecResult } from './exec.js';
6
+ /** P4 exec face (spec §8.1): the executing side + the wire leg, closed over the hub home by a2a-row. */
7
+ export interface HubToolExecFace {
8
+ /** This machine's m4 (the default exec target). */
9
+ selfM4(): string;
10
+ /** Run one command on THIS machine. */
11
+ run(input: OneShotExecInput): Promise<OneShotExecResult>;
12
+ /** Run one command on a paired machine over the wire. Throws typed Errors: unknown machine / exec disabled / peer unreachable. */
13
+ post(machineId: string, input: OneShotExecInput): Promise<OneShotExecResult>;
14
+ /**
15
+ * P4 §8.2 persistent PTY: dispatch one command into a per-(session,
16
+ * machine) shell that KEEPS its cwd/env across dispatches. Throws typed
17
+ * Errors: unknown machine / exec disabled / transport failure.
18
+ */
19
+ pty(sessionKey: string, machine: string, cmd: string, opts?: {
20
+ timeoutSec?: number;
21
+ }): Promise<import('./exec-pty-session.js').PtyDispatchResult>;
22
+ }
23
+ import type { A2aAddress, A2aInitiator, A2aService } from './a2a-service.js';
24
+ /** The service face the tool consumes (structural subset of T2/T3's A2aService). */
25
+ export type HubToolService = Pick<A2aService, 'send' | 'subscribeCompletion' | 'stop' | 'read' | 'listConversations'>;
26
+ /** Per-agent recent-conversation bound (spec §7.2: alive-first, ≤5). */
27
+ /** R6: retired from the agents listing (the strip); kept exported for compat — agent_status windows AGENT_STATUS_WINDOW_MAX rows instead. */
28
+ export declare const RECENT_CONVERSATIONS_MAX = 5;
29
+ /** The exec placeholder note (P4 owns the leg; spec §9 placeholder discipline). */
30
+ export declare const EXEC_PLACEHOLDER_NOTE = "not yet implemented: exec (P4)";
31
+ /** One addressable agent row in the listing (R6: THIN — the conversations embedding is retired; per-agent session state lives on the agent_status leg). */
32
+ export type HubAgentEntry = {
33
+ /** Agent id (a6). */
34
+ id: string;
35
+ /** Chip label (`DSH`, `Codex · dev3`, …). */
36
+ label: string;
37
+ /** Full tool address `<m4>-<a6>` — what the `agent` parameter wants. */
38
+ address: string;
39
+ /** Whether the agent's data plane is up. */
40
+ ready: boolean;
41
+ /** Whether the agent's spawn rejected (row stays for diagnosis). */
42
+ failed: boolean;
43
+ };
44
+ /** One machine block: its agents grouped under it. */
45
+ export type HubMachineEntry = {
46
+ /** Machine id (m4). */
47
+ machine: string;
48
+ /** Machine display label. */
49
+ label: string;
50
+ /** Agents running on this machine (self's machine first, roster order). */
51
+ agents: HubAgentEntry[];
52
+ };
53
+ /**
54
+ * The roster view the `agents` listing renders — the `/api/agent-runtime`
55
+ * family of facts (rpc.ts + agent-roster.ts), injected so the factory stays
56
+ * filesystem-free.
57
+ */
58
+ export interface HubRosterView {
59
+ /** THIS machine: owner-minted m4 + display label (machines.ts `ensureSelf`). */
60
+ self: {
61
+ id: string;
62
+ label: string;
63
+ };
64
+ /** Paired remote machines in pairing order (machines.ts `listRemotes`). */
65
+ remotes: {
66
+ id: string;
67
+ label: string;
68
+ }[];
69
+ /** `agentLinks(home)` output: local rows carry `machine: 'local'`, federated rows the owning m4. */
70
+ agents: AgentLink[];
71
+ }
72
+ /** Everything the factory needs, all injected (pure module — see header). */
73
+ export interface HubToolDeps {
74
+ /** The A2A conversation service (T2 core behind T3's host assembly). */
75
+ service: HubToolService;
76
+ /** T3's delivery face: live-agent routing + the bounded unread buffer. */
77
+ delivery: A2aDeliveryCtx;
78
+ /** Roster snapshot for the `agents` listing (row: the real hub home view). */
79
+ roster(): HubRosterView;
80
+ /**
81
+ * P4 exec face (spec §8.1): the local executing side + the cross-machine
82
+ * wire leg, closed over the hub home by a2a-row (self id, remote rows,
83
+ * pairing cookies, journal). `post` throws typed Errors (unknown machine,
84
+ * exec disabled on the row, peer unreachable).
85
+ */
86
+ exec: HubToolExecFace;
87
+ /**
88
+ * Initiator identity for the calling session — the row closes this over
89
+ * T3's `localA2aInitiator(home, 'native', sessionId)`. Called exactly once
90
+ * per session-bound action, with `exec.agent.id`.
91
+ */
92
+ initiatorOf(sessionId: string): A2aInitiator;
93
+ /**
94
+ * Owns one completion-watch disposer per successful send (the row parks it
95
+ * in a fiber `ctx.effect`; requestId-armed watches self-dispose after
96
+ * their turn fires). Absent = disposers dropped (happy path still leaks
97
+ * nothing — the subscription auto-disposes on fire).
98
+ */
99
+ onWatch?(dispose: () => void): void;
100
+ /**
101
+ * R6: the R5 information-status cache reader (the row wires
102
+ * `() => loadAgentStatus(home)`); absent = agent_status answers honestly
103
+ * empty with collectedAt 0.
104
+ */
105
+ status?(): AgentStatusFile;
106
+ }
107
+ /**
108
+ * Parse the `agent` parameter: `<m4>-<a6>`. Both halves are minted over
109
+ * `[a-z0-9]` (machines.ts `ID_ALPHABET`) at fixed lengths (m4 = 4, a6 = 6), so
110
+ * a malformed address is refused HERE (0.1.8 T4) instead of being mis-split
111
+ * into a bogus machine and reported downstream as "unknown machine" — the
112
+ * `no-such-agent-zzz` → machine `no` is not paired trap the 0.1.7 surface
113
+ * analysis flagged.
114
+ * @param agent - the raw `agent` parameter.
115
+ * @returns the address the service consumes.
116
+ * @throws `[E_BAD_ADDRESS]` when the value is not a well-formed `<m4>-<a6>`.
117
+ */
118
+ export declare function parseAgentAddress(agent: unknown): A2aAddress;
119
+ /** The agent_status window size (Orchestra semantics — not-in-window implies nothing). */
120
+ export declare const AGENT_STATUS_WINDOW_MAX = 5;
121
+ /** D18 marker appended to registry-joined titles. */
122
+ export declare const HUB_A2A_TITLE_MARKER = "[hub A2A]";
123
+ /** The honest fallback when neither the registry nor a workspace names the session. */
124
+ export declare const UNHOSTED_TITLE = "[unhosted]";
125
+ /** One shaped agent_status row. */
126
+ export interface AgentStatusEntryRow {
127
+ conversationId?: string;
128
+ /** Display-truncated session id (uuid head; the full id stays in the cache). */
129
+ sessionId: string;
130
+ title: string;
131
+ status: 'busy' | 'idle' | 'unknown';
132
+ agentAvailable: boolean;
133
+ mtime: number;
134
+ /** D30: the peer's last delivered output — present ONLY when the caller is this conversation's initiator (ownership gate). */
135
+ lastOutput?: string;
136
+ /** D30: epoch ms of lastOutput. */
137
+ lastOutputAt?: number;
138
+ }
139
+ /**
140
+ * Shape one agent's window from the R5 cache (D18): alive-first (a session
141
+ * owning a live Agent first), mtime desc within each group, ≤5 rows —
142
+ * not-in-window implies nothing. Title: registry join (full session id) →
143
+ * `{conversationTitle} [hub A2A]`; else the owning workspace's title
144
+ * verbatim; else '[unhosted]'. conversationId rides only on a registry hit.
145
+ */
146
+ export declare function shapeAgentStatusWindow(entry: {
147
+ rows: AgentStatusEntrySrcRow[];
148
+ workspaces?: Array<{
149
+ title: string;
150
+ sessionIds: string[];
151
+ }>;
152
+ }, conversations: ReadonlyArray<{
153
+ shortId: string;
154
+ sessionId: string;
155
+ title?: string;
156
+ initiatorSession?: string;
157
+ lastOutput?: string;
158
+ lastOutputAt?: number;
159
+ }>,
160
+ /** D30 ownership gate: the caller's session — lastOutput is surfaced only to the conversation's initiator. */
161
+ callerSessionId?: string): AgentStatusEntryRow[];
162
+ /** The cache row face the shaper consumes (structural subset of AgentStatusRow). */
163
+ export interface AgentStatusEntrySrcRow {
164
+ sessionId: string;
165
+ mtime: number;
166
+ status: 'busy' | 'idle' | 'unknown';
167
+ agentAvailable: boolean;
168
+ }
169
+ /**
170
+ * Build the one SuperD Hub tool.
171
+ * @param deps - service, delivery, roster view, initiator factory, watch owner.
172
+ * @returns the registry-ready `superd-hub` ToolDefinition.
173
+ */
174
+ export declare function createSuperdHubTool(deps: HubToolDeps): ToolDefinition;