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.
- package/client/index.js +1010 -345
- package/cordis.patch.yml +22 -5
- package/package.json +8 -3
- package/superd-hub/dist/a2a-delivery.d.ts +189 -0
- package/superd-hub/dist/a2a-delivery.js +240 -0
- package/superd-hub/dist/a2a-host.d.ts +76 -0
- package/superd-hub/dist/a2a-host.js +145 -0
- package/superd-hub/dist/a2a-ingest.d.ts +31 -0
- package/superd-hub/dist/a2a-ingest.js +636 -0
- package/superd-hub/dist/a2a-log.d.ts +17 -0
- package/superd-hub/dist/a2a-log.js +42 -0
- package/superd-hub/dist/a2a-row.d.ts +65 -0
- package/superd-hub/dist/a2a-row.js +162 -0
- package/superd-hub/dist/a2a-service.d.ts +357 -0
- package/superd-hub/dist/a2a-service.js +980 -0
- package/superd-hub/dist/a2a-wire.d.ts +220 -0
- package/superd-hub/dist/a2a-wire.js +305 -0
- package/superd-hub/dist/agent-ids.d.ts +10 -0
- package/superd-hub/dist/agent-ids.js +68 -0
- package/superd-hub/dist/agent-roster.d.ts +32 -17
- package/superd-hub/dist/agent-roster.js +54 -15
- package/superd-hub/dist/agent-status.d.ts +119 -0
- package/superd-hub/dist/agent-status.js +386 -0
- package/superd-hub/dist/client/mesh-api.d.ts +134 -0
- package/superd-hub/dist/client/mesh-api.js +219 -0
- package/superd-hub/dist/client/mesh-groups.d.ts +63 -0
- package/superd-hub/dist/client/mesh-groups.js +66 -0
- package/superd-hub/dist/client/roster.d.ts +48 -0
- package/superd-hub/dist/client/roster.js +96 -0
- package/superd-hub/dist/exec-pty-channel.d.ts +58 -0
- package/superd-hub/dist/exec-pty-channel.js +162 -0
- package/superd-hub/dist/exec-pty-framing.d.ts +32 -0
- package/superd-hub/dist/exec-pty-framing.js +81 -0
- package/superd-hub/dist/exec-pty-rpc.d.ts +21 -0
- package/superd-hub/dist/exec-pty-rpc.js +128 -0
- package/superd-hub/dist/exec-pty-session.d.ts +76 -0
- package/superd-hub/dist/exec-pty-session.js +234 -0
- package/superd-hub/dist/exec.d.ts +56 -0
- package/superd-hub/dist/exec.js +225 -0
- package/superd-hub/dist/fusion-transport.d.ts +23 -21
- package/superd-hub/dist/fusion-transport.js +12 -40
- package/superd-hub/dist/gateway.d.ts +39 -2
- package/superd-hub/dist/gateway.js +62 -3
- package/superd-hub/dist/hub-tool.d.ts +174 -0
- package/superd-hub/dist/hub-tool.js +464 -0
- package/superd-hub/dist/index.d.ts +18 -4
- package/superd-hub/dist/index.js +19 -3
- package/superd-hub/dist/machines.d.ts +45 -0
- package/superd-hub/dist/machines.js +125 -0
- package/superd-hub/dist/mesh-federate.d.ts +138 -0
- package/superd-hub/dist/mesh-federate.js +223 -0
- package/superd-hub/dist/mesh-gateway.d.ts +67 -0
- package/superd-hub/dist/mesh-gateway.js +408 -0
- package/superd-hub/dist/mesh-link.d.ts +274 -0
- package/superd-hub/dist/mesh-link.js +441 -0
- package/superd-hub/dist/mesh-rpc.d.ts +123 -0
- package/superd-hub/dist/mesh-rpc.js +250 -0
- package/superd-hub/dist/mux-client.d.ts +71 -0
- package/superd-hub/dist/mux-client.js +281 -0
- package/superd-hub/dist/pack-version.d.ts +2 -0
- package/superd-hub/dist/pack-version.js +30 -0
- package/superd-hub/dist/roster.d.ts +10 -0
- package/superd-hub/dist/roster.js +9 -1
- package/superd-hub/dist/rpc.d.ts +18 -2
- package/superd-hub/dist/rpc.js +34 -4
- package/superd-hub/dist/spawn-world.js +3 -1
- package/superd-hub/dist/switch-core.d.ts +98 -21
- package/superd-hub/dist/switch-core.js +123 -28
- package/superd-hub/dist/system-head.d.ts +22 -12
- package/superd-hub/dist/system-head.js +100 -84
- package/superd-hub/dist/toast-core.d.ts +43 -0
- package/superd-hub/dist/toast-core.js +63 -0
- package/superd-hub/dist/wire-endpoints.d.ts +264 -0
- package/superd-hub/dist/wire-endpoints.js +180 -0
- package/superd-hub/dist/world-join.js +8 -3
- package/superd-hub/dist/world-mount.d.ts +27 -0
- package/superd-hub/dist/world-mount.js +67 -0
- package/superd-hub/lib/client/index.js +1010 -345
- 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
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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;
|