super-dsh 0.1.6 → 0.1.10-e
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/README.md +25 -3
- package/agent-agy/cordis.patch.yml +7 -4
- package/agent-agy/dist/agent.d.ts +12 -11
- package/agent-agy/dist/agy-auth-gateway.d.ts +124 -0
- package/agent-agy/dist/agy-auth-gateway.js +233 -0
- package/agent-agy/dist/agy-auth.d.ts +153 -0
- package/agent-agy/dist/agy-auth.js +179 -0
- package/agent-agy/dist/agy-cli-client.d.ts +39 -9
- package/agent-agy/dist/agy-cli-client.js +82 -18
- package/agent-agy/dist/agy-store.d.ts +8 -0
- package/agent-agy/dist/index.d.ts +46 -16
- package/agent-agy/dist/index.js +82 -56
- package/agent-agy/dist/models.d.ts +70 -0
- package/agent-agy/dist/models.js +102 -3
- package/agent-agy/package.json +7 -5
- package/agent-agy-sdk/cordis.patch.yml +58 -0
- package/agent-agy-sdk/dist/adapter.d.ts +15 -0
- package/agent-agy-sdk/dist/adapter.js +42 -0
- package/agent-agy-sdk/dist/agent-preset-agy.d.ts +27 -0
- package/agent-agy-sdk/dist/agent-preset-agy.js +32 -0
- package/agent-agy-sdk/dist/agent.d.ts +138 -0
- package/agent-agy-sdk/dist/agent.js +494 -0
- package/{agent-agy → agent-agy-sdk}/dist/agy-client.d.ts +26 -6
- package/{agent-agy → agent-agy-sdk}/dist/agy-client.js +43 -25
- package/agent-agy-sdk/dist/agy-sessions.d.ts +25 -0
- package/agent-agy-sdk/dist/agy-sessions.js +107 -0
- package/agent-agy-sdk/dist/agy-store.d.ts +39 -0
- package/agent-agy-sdk/dist/agy-store.js +83 -0
- package/agent-agy-sdk/dist/inbox.d.ts +26 -0
- package/agent-agy-sdk/dist/inbox.js +53 -0
- package/agent-agy-sdk/dist/index.d.ts +93 -0
- package/agent-agy-sdk/dist/index.js +476 -0
- package/agent-agy-sdk/dist/models.d.ts +41 -0
- package/agent-agy-sdk/dist/models.js +74 -0
- package/agent-agy-sdk/dist/sdk-venv.d.ts +76 -0
- package/agent-agy-sdk/dist/sdk-venv.js +173 -0
- package/agent-agy-sdk/dist/world-plugin.d.ts +10 -0
- package/agent-agy-sdk/dist/world-plugin.js +82 -0
- package/agent-agy-sdk/package.json +64 -0
- package/agent-claude/dist/adapter.js +106 -31
- package/agent-claude/dist/agent.js +154 -17
- package/agent-claude/dist/claude-client.js +84 -43
- package/agent-claude/dist/claude-launch.js +101 -0
- package/agent-claude/dist/claude-native-config.js +169 -0
- package/agent-claude/dist/claude-provider-gateway.js +340 -0
- package/agent-claude/dist/claude-providers.js +391 -0
- package/agent-claude/dist/claude-route.js +152 -0
- package/agent-claude/dist/index.js +214 -37
- package/agent-claude/dist/models.js +14 -0
- package/agent-claude/dist/sdk-runtime.js +320 -0
- package/agent-claude/package.json +6 -4
- package/agent-codex/README.md +141 -36
- package/agent-codex/cordis.patch.yml +14 -10
- package/agent-codex/dist/adapter.js +64 -28
- package/agent-codex/dist/agent.js +255 -81
- package/agent-codex/dist/app-server-approvals.js +165 -0
- package/agent-codex/dist/app-server-client.js +723 -0
- package/agent-codex/dist/app-server-events.js +432 -0
- package/agent-codex/dist/app-server-protocol.js +95 -0
- package/agent-codex/dist/app-server-wire.js +299 -0
- package/agent-codex/dist/codex-launch.js +78 -0
- package/agent-codex/dist/codex-native-config.js +392 -0
- package/agent-codex/dist/codex-provider-gateway.js +402 -0
- package/agent-codex/dist/codex-providers.js +376 -0
- package/agent-codex/dist/codex-route.js +86 -0
- package/agent-codex/dist/index.js +256 -115
- package/agent-codex/dist/permission.js +75 -1
- package/agent-codex/package.json +1 -2
- package/agent-codex-sdk/README.md +79 -0
- package/agent-codex-sdk/cordis.patch.yml +81 -0
- package/agent-codex-sdk/dist/adapter.js +91 -0
- package/agent-codex-sdk/dist/agent-preset-codex.js +32 -0
- package/agent-codex-sdk/dist/agent.js +1085 -0
- package/agent-codex-sdk/dist/codex-native-config.js +392 -0
- package/agent-codex-sdk/dist/codex-provider-gateway.js +402 -0
- package/agent-codex-sdk/dist/codex-providers.js +376 -0
- package/agent-codex-sdk/dist/codex-route.js +86 -0
- package/{agent-codex/dist/codex-client.js → agent-codex-sdk/dist/codex-sdk-client.js} +253 -32
- package/agent-codex-sdk/dist/codex-sdk-launch.js +92 -0
- package/agent-codex-sdk/dist/codex-store.js +180 -0
- package/agent-codex-sdk/dist/inbox.js +53 -0
- package/agent-codex-sdk/dist/index.js +739 -0
- package/agent-codex-sdk/dist/permission.js +71 -0
- package/agent-codex-sdk/dist/sdk-runtime.js +307 -0
- package/agent-codex-sdk/dist/session-map.js +167 -0
- package/agent-codex-sdk/dist/world-plugin.js +93 -0
- package/agent-codex-sdk/package.json +79 -0
- package/agent-codex-sdk/scripts/fetch-sdk-runtime.mjs +57 -0
- package/agent-omp/README.md +72 -55
- package/agent-omp/dist/agent.js +36 -11
- package/agent-omp/dist/index.js +92 -52
- package/agent-omp/dist/lazy-rpc.js +11 -4
- package/agent-omp/dist/omp-cli.js +114 -97
- package/agent-omp/dist/omp-store.js +12 -4
- package/agent-omp/dist/permission.js +70 -5
- package/agent-omp/dist/rpc-client.js +409 -0
- package/agent-omp/dist/world-plugin.js +36 -3
- package/agent-omp/package.json +2 -6
- package/agent-omp-sdk/README.md +103 -0
- package/agent-omp-sdk/cordis.patch.yml +108 -0
- package/agent-omp-sdk/dist/adapter.d.ts +21 -0
- package/agent-omp-sdk/dist/adapter.js +36 -0
- package/agent-omp-sdk/dist/agent-preset-omp.d.ts +31 -0
- package/agent-omp-sdk/dist/agent-preset-omp.js +32 -0
- package/agent-omp-sdk/dist/agent.d.ts +64 -0
- package/agent-omp-sdk/dist/agent.js +1178 -0
- package/agent-omp-sdk/dist/discovery.d.ts +57 -0
- package/agent-omp-sdk/dist/discovery.js +116 -0
- package/agent-omp-sdk/dist/inbox.d.ts +28 -0
- package/agent-omp-sdk/dist/inbox.js +53 -0
- package/agent-omp-sdk/dist/index.d.ts +60 -0
- package/agent-omp-sdk/dist/index.js +632 -0
- package/agent-omp-sdk/dist/knobs.d.ts +34 -0
- package/agent-omp-sdk/dist/knobs.js +50 -0
- package/agent-omp-sdk/dist/lazy-rpc.d.ts +98 -0
- package/agent-omp-sdk/dist/lazy-rpc.js +178 -0
- package/agent-omp-sdk/dist/mobile/zoom-guard.d.ts +187 -0
- package/agent-omp-sdk/dist/mobile/zoom-guard.js +294 -0
- package/agent-omp-sdk/dist/mobile-boot.d.ts +49 -0
- package/agent-omp-sdk/dist/mobile-boot.js +38 -0
- package/agent-omp-sdk/dist/models.d.ts +39 -0
- package/agent-omp-sdk/dist/models.js +299 -0
- package/agent-omp-sdk/dist/omp-cli.d.ts +67 -0
- package/agent-omp-sdk/dist/omp-cli.js +164 -0
- package/agent-omp-sdk/dist/omp-disk-discovery.d.ts +27 -0
- package/agent-omp-sdk/dist/omp-disk-discovery.js +178 -0
- package/agent-omp-sdk/dist/omp-executable.d.ts +2 -0
- package/agent-omp-sdk/dist/omp-executable.js +30 -0
- package/agent-omp-sdk/dist/omp-store.d.ts +134 -0
- package/agent-omp-sdk/dist/omp-store.js +526 -0
- package/agent-omp-sdk/dist/pairing.d.ts +7 -0
- package/agent-omp-sdk/dist/pairing.js +45 -0
- package/agent-omp-sdk/dist/permission.d.ts +138 -0
- package/agent-omp-sdk/dist/permission.js +161 -0
- package/agent-omp-sdk/dist/protocol.d.ts +189 -0
- package/agent-omp-sdk/dist/rpc-types.d.ts +77 -0
- package/agent-omp-sdk/dist/rpc-types.js +1 -0
- package/agent-omp-sdk/dist/sdk-client.d.ts +160 -0
- package/{agent-omp → agent-omp-sdk}/dist/sdk-client.js +108 -56
- package/agent-omp-sdk/dist/sdk-runtime.d.ts +211 -0
- package/agent-omp-sdk/dist/sdk-runtime.js +418 -0
- package/agent-omp-sdk/dist/sidecar-client.d.ts +87 -0
- package/agent-omp-sdk/dist/sidecar-client.js +197 -0
- package/agent-omp-sdk/dist/store/adapter.d.ts +17 -0
- package/agent-omp-sdk/dist/store/adapter.js +47 -0
- package/agent-omp-sdk/dist/store/db.d.ts +70 -0
- package/agent-omp-sdk/dist/store/db.js +210 -0
- package/agent-omp-sdk/dist/store/index.d.ts +23 -0
- package/agent-omp-sdk/dist/store/index.js +59 -0
- package/agent-omp-sdk/dist/store/reconcile.d.ts +15 -0
- package/agent-omp-sdk/dist/store/reconcile.js +51 -0
- package/agent-omp-sdk/dist/store/schema.d.ts +8 -0
- package/agent-omp-sdk/dist/store/schema.js +40 -0
- package/agent-omp-sdk/dist/transport.d.ts +49 -0
- package/agent-omp-sdk/dist/transport.js +35 -0
- package/agent-omp-sdk/dist/world-home.d.ts +4 -0
- package/agent-omp-sdk/dist/world-home.js +23 -0
- package/agent-omp-sdk/dist/world-plugin.d.ts +10 -0
- package/agent-omp-sdk/dist/world-plugin.js +137 -0
- package/agent-omp-sdk/package.json +87 -0
- package/client/index.js +1883 -287
- package/cordis.patch.yml +80 -0
- package/package.json +23 -9
- 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 +29 -18
- 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/agent-settings.d.ts +210 -0
- package/superd-hub/dist/client/agent-settings.js +300 -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 +102 -0
- package/superd-hub/dist/client/runtime-settings-api.d.ts +76 -0
- package/superd-hub/dist/client/runtime-settings-api.js +137 -0
- package/superd-hub/dist/client/switch.d.ts +165 -0
- package/superd-hub/dist/client/switch.js +295 -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/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 +15 -1
- package/superd-hub/dist/index.js +16 -0
- 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 +6 -0
- 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 +62 -25
- package/superd-hub/dist/switch-core.js +53 -30
- package/superd-hub/dist/system-head.d.ts +22 -12
- package/superd-hub/dist/system-head.js +100 -84
- package/superd-hub/dist/wire-endpoints.d.ts +264 -0
- package/superd-hub/dist/wire-endpoints.js +180 -0
- package/superd-hub/lib/client/index.js +1883 -287
- package/superd-hub/package.json +11 -2
- package/agent-agy/dist/agent-preset-projection.d.ts +0 -31
- package/agent-agy/dist/agent-preset-projection.js +0 -33
- package/agent-claude/dist/agent-preset-projection.js +0 -30
- package/agent-codex/dist/agent-preset-projection.js +0 -37
- package/agent-codex/dist/app-home.js +0 -65
- package/agent-codex/dist/models.js +0 -152
- package/agent-codex/dist/spike.js +0 -46
- package/agent-hermes/dist/agent-preset-projection.js +0 -34
- package/agent-omp/dist/agent-preset-projection.js +0 -36
- package/agent-omp/dist/app-home.js +0 -86
- package/agent-omp/dist/sidecar-client.js +0 -195
- package/agent-pi/dist/agent-preset-projection.js +0 -29
- package/superd-hub/dist/client-shim.d.ts +0 -28
- package/superd-hub/dist/client-shim.js +0 -251
- package/superd-hub/dist/index-pass.d.ts +0 -22
- package/superd-hub/dist/index-pass.js +0 -47
- package/superd-hub/dist/labels.d.ts +0 -45
- package/superd-hub/dist/labels.js +0 -83
- /package/{agent-agy → agent-agy-sdk}/bridge/agy_bridge.py +0 -0
- /package/{agent-agy → agent-agy-sdk}/bridge/gemini_openai_server.mjs +0 -0
- /package/{agent-codex/dist/codex-events.js → agent-codex-sdk/dist/codex-sdk-events.js} +0 -0
- /package/{agent-omp → agent-omp-sdk}/dist/protocol.js +0 -0
- /package/{agent-omp → agent-omp-sdk}/sidecar/main.ts +0 -0
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* retired `mountWorld` no-op are gone (git history keeps them), and worlds
|
|
15
15
|
* compose as pure data planes (no webui rows).
|
|
16
16
|
*/
|
|
17
|
+
export { handleMeshMachines, registerMeshRpc, MESH_API_BASE, type MeshDeps, type MachinePublicRow } from './mesh-rpc.js';
|
|
17
18
|
export { handleAgentRuntime, registerSelectorRpc, AGENT_RUNTIME_RPC_PATH, registryTargets, type RuntimeTargetSource } from './rpc.js';
|
|
18
19
|
export { registerForeignTarget, unregisterForeignTarget, getTarget, listRuntimeKeys, type ForeignTarget, type GatewayFace } from './targets.js';
|
|
19
20
|
export { registerAgent, unregisterAgent, setReady, setFailed, listAgents, onRosterChanged, type RosterEntry } from './roster.js';
|
|
@@ -22,10 +23,14 @@ export { provisionWorldProfile, resolveInstallAnchor, type ProvisionWorldOptions
|
|
|
22
23
|
export { WorldWebServer, stripLabelFromUrl, type WorldWebRoute, type WorldWebUpgradeRoute, type RealWebServerFace } from './world-web-server.js';
|
|
23
24
|
export { parseClientRequest, serverResponse, serverError, serverResult, wireErrorOf, EnvelopeError, type ClientRequestEnvelope, type WireError } from './envelope.js';
|
|
24
25
|
export { WorldMuxServer, parseClientMessage, defaultFailure, type MuxOpen, type MuxFailure, type WorldMuxOptions } from './world-mux.js';
|
|
26
|
+
export { createRemoteGateway, defaultWsFactory, type RemoteGateway, type RemoteGatewayOptions, type MuxClientSocket } from './mesh-gateway.js';
|
|
27
|
+
export { federateAgents, defederateMachine, defederateStaleMachine, degradeMachine, federatedGatewayOf, startMeshFederation, type FederatedAgent, type FederatedMachine, type FederationWireDeps, } from './mesh-federate.js';
|
|
28
|
+
export { cookieOf, onMeshFederationEvent, emitMachineRemoved, versionWarningFor, runReprobeSweep, startReprobeSweep, REPROBE_SWEEP_DEFAULT_SEC, REPROBE_SWEEP_MIN_SEC, type MeshFederationEvent, type ProbeAgent, type ProbeResult, type PairOutcome, type MachineStatusEntry, type ReprobeSweepDeps, } from './mesh-link.js';
|
|
25
29
|
export { forwardApiCall, forwardWorldFetch, worldMuxOf, writeJson, type CarrierGatewayFace, type ForwardOptions } from './carrier.js';
|
|
26
30
|
export { registerHubRoute, HUB_MOUNT_PATH, HUB_MUX_PATH, type HubRouteOptions } from './hub-route.js';
|
|
27
31
|
export { renderFusionTransport, FUSION_FLAG_GLOBAL, type FusionConfig } from './fusion-transport.js';
|
|
28
32
|
export { createSwitchController, parseLandingTarget, namespacedKey, storageNamespace, seatClickDecision, NATIVE_AGENT, SESSIONS_CURRENT_KEY, SWITCH_FALLBACK_MS, type SwitchHost, type SwitchController, type SwitchOptions, type SeatClickInput, type SeatClickDecision } from './switch-core.js';
|
|
33
|
+
export { ensureAgentId, agentIdMap, type AgentIdMap } from './agent-ids.js';
|
|
29
34
|
export { agentLinks, agentRosterRow, AGENT_ROSTER_GLOBAL, type AgentLink } from './agent-roster.js';
|
|
30
35
|
export { createOwnershipIndex, type OwnershipIndex, type OwnershipRow } from './ownership.js';
|
|
31
36
|
export { registerHostMount, takeHostMount, listHostMounts, noteWorldServer, worldServerOf, type HostMount } from './world-host.js';
|
|
@@ -34,4 +39,13 @@ export { buildTrustScript, deriveDefaultPageAuthorities, type BootScriptRow, typ
|
|
|
34
39
|
export { withSystemHead, type HeadAwareSessionFace, type HeadPlaceholder, type WithSystemHead } from './system-head.js';
|
|
35
40
|
export { default as worldApply, name as worldPluginName, type Config as WorldEntryConfig } from './world-entry.js';
|
|
36
41
|
export { default as joinApply, name as worldJoinPluginName, type Config as WorldJoinConfig } from './world-join.js';
|
|
37
|
-
export {
|
|
42
|
+
export { createA2aService, A2A_MESSAGE_TEMPLATE, A2A_UNTITLED, A2A_BUFFER_MAX, A2A_NO_SESSION_CLOSE_REASON, A2A_NO_TURN_ACTIVE_NOTE, renderA2aEnvelope, loadConversations, saveConversations, shortIdFor, isDegenerateShortId, migrateConversations, type A2aService, subscribeSessionCompletion, sessionRpc, turnLivenessOf, addressErrorBody, type A2aSessionSource, type A2aGateway, type A2aAddress, type A2aInitiator, type A2aDelivery, type A2aSendRequest, type A2aReceipt, type A2aReceiptOutcome, type A2aReceiptError, type A2aConversationRef, type A2aCompletion, type A2aCompletionCb, type A2aErrorCb, type A2aSubscribeOptions, type A2aStopScope, type A2aStopResult, type A2aBufferedMessage, type A2aBufferInput, type ConversationRow, type ConversationsFile, } from './a2a-service.js';
|
|
43
|
+
export { A2A_WIRE_VERSION, A2A_TITLE_PLACEHOLDER, A2A_ENDPOINT_PATH, A2A_OUTBOX_PATH, A2A_WIRE_TIMEOUT_MS, A2aAddressError, a2aWireFrameOf, isA2aEnvelope, isA2aWireFrame, decodeA2aWireFrame, normalizeA2aTitle, a2aAddressOf, postA2aEnvelope, fetchA2aOutbox, type A2aWireTarget, type A2aWireOrigin, type A2aWireDelivery, type A2aNewConversationEnvelope, type A2aMessageEnvelope, type A2aStopEnvelope, type A2aReplyEnvelope, type A2aNoticeEnvelope, type A2aEnvelope, type A2aWireFrame, type A2aSendReceipt, type A2aStopReceipt, type A2aWireReceipt, type A2aWireOptions, } from './a2a-wire.js';
|
|
44
|
+
export { createA2aIngest, type A2aIngest, type A2aIngestDeps, type A2aReturnRoute, } from './a2a-ingest.js';
|
|
45
|
+
export { loadAgentStatus, recordMachineCollection, recordMachineFailure, collectRemoteMachine, collectLocalMachine, pullOutboxFor, statusSweepLegs, federatedFaceOf, AGENT_STATUS_ROWS_MAX, type AgentStatusRow, type AgentStatusAgent, type AgentStatusMachine, type AgentStatusFile, type RemoteFaceOf, type StatusSweepLegs, } from './agent-status.js';
|
|
46
|
+
export { registerA2aRpc, handleA2aIngestPost, handleA2aOutboxGet, } from './mesh-rpc.js';
|
|
47
|
+
export { deliverReply, deliverNotice, wireCompletionToDelivery, renderA2aRelayText, boundNoticeSummary, A2A_NOTICE_SUMMARY_MAX, type A2aRelaySource, type A2aNoticeSource, type A2aNoticeReason, type A2aDeliveredMessage, type A2aAgentHandle, type A2aDeliveryCtx, type A2aReplyMeta, type A2aNoticeMeta, type A2aReplyDelivery, type A2aDeliveryOutcome, type A2aCompletionSource, } from './a2a-delivery.js';
|
|
48
|
+
export { resolveA2aGatewayFor, localA2aInitiator, createA2aHost, bridgeTypertGateway, type A2aHostOptions, type RawTypertGatewayFace, } from './a2a-host.js';
|
|
49
|
+
export { createSuperdHubTool, parseAgentAddress, RECENT_CONVERSATIONS_MAX, AGENT_STATUS_WINDOW_MAX, HUB_A2A_TITLE_MARKER, UNHOSTED_TITLE, shapeAgentStatusWindow, type AgentStatusEntryRow, EXEC_PLACEHOLDER_NOTE, type HubToolDeps, type HubToolService, type HubRosterView, type HubMachineEntry, type HubAgentEntry, } from './hub-tool.js';
|
|
50
|
+
export { wireHubToolRow, name as a2aRowName, default as a2aRow, type HubToolRowOptions, } from './a2a-row.js';
|
|
51
|
+
export { default, type HubConfig } from './gateway.js';
|
package/superd-hub/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* retired `mountWorld` no-op are gone (git history keeps them), and worlds
|
|
15
15
|
* compose as pure data planes (no webui rows).
|
|
16
16
|
*/
|
|
17
|
+
export { handleMeshMachines, registerMeshRpc, MESH_API_BASE } from './mesh-rpc.js';
|
|
17
18
|
export { handleAgentRuntime, registerSelectorRpc, AGENT_RUNTIME_RPC_PATH, registryTargets } from './rpc.js';
|
|
18
19
|
export { registerForeignTarget, unregisterForeignTarget, getTarget, listRuntimeKeys } from './targets.js';
|
|
19
20
|
export { registerAgent, unregisterAgent, setReady, setFailed, listAgents, onRosterChanged } from './roster.js';
|
|
@@ -22,10 +23,14 @@ export { provisionWorldProfile, resolveInstallAnchor } from './world-provision.j
|
|
|
22
23
|
export { WorldWebServer, stripLabelFromUrl } from './world-web-server.js';
|
|
23
24
|
export { parseClientRequest, serverResponse, serverError, serverResult, wireErrorOf, EnvelopeError } from './envelope.js';
|
|
24
25
|
export { WorldMuxServer, parseClientMessage, defaultFailure } from './world-mux.js';
|
|
26
|
+
export { createRemoteGateway, defaultWsFactory } from './mesh-gateway.js';
|
|
27
|
+
export { federateAgents, defederateMachine, defederateStaleMachine, degradeMachine, federatedGatewayOf, startMeshFederation, } from './mesh-federate.js';
|
|
28
|
+
export { cookieOf, onMeshFederationEvent, emitMachineRemoved, versionWarningFor, runReprobeSweep, startReprobeSweep, REPROBE_SWEEP_DEFAULT_SEC, REPROBE_SWEEP_MIN_SEC, } from './mesh-link.js';
|
|
25
29
|
export { forwardApiCall, forwardWorldFetch, worldMuxOf, writeJson } from './carrier.js';
|
|
26
30
|
export { registerHubRoute, HUB_MOUNT_PATH, HUB_MUX_PATH } from './hub-route.js';
|
|
27
31
|
export { renderFusionTransport, FUSION_FLAG_GLOBAL } from './fusion-transport.js';
|
|
28
32
|
export { createSwitchController, parseLandingTarget, namespacedKey, storageNamespace, seatClickDecision, NATIVE_AGENT, SESSIONS_CURRENT_KEY, SWITCH_FALLBACK_MS } from './switch-core.js';
|
|
33
|
+
export { ensureAgentId, agentIdMap } from './agent-ids.js';
|
|
29
34
|
export { agentLinks, agentRosterRow, AGENT_ROSTER_GLOBAL } from './agent-roster.js';
|
|
30
35
|
export { createOwnershipIndex } from './ownership.js';
|
|
31
36
|
export { registerHostMount, takeHostMount, listHostMounts, noteWorldServer, worldServerOf } from './world-host.js';
|
|
@@ -34,4 +39,15 @@ export { buildTrustScript, deriveDefaultPageAuthorities, } from './web-trust.js'
|
|
|
34
39
|
export { withSystemHead } from './system-head.js';
|
|
35
40
|
export { default as worldApply, name as worldPluginName } from './world-entry.js';
|
|
36
41
|
export { default as joinApply, name as worldJoinPluginName } from './world-join.js';
|
|
42
|
+
export { createA2aService, A2A_MESSAGE_TEMPLATE, A2A_UNTITLED, A2A_BUFFER_MAX, A2A_NO_SESSION_CLOSE_REASON, A2A_NO_TURN_ACTIVE_NOTE, renderA2aEnvelope, loadConversations, saveConversations, shortIdFor, isDegenerateShortId, migrateConversations,
|
|
43
|
+
// (A2aAddressError re-exported via the a2a-wire block below — postoffice R1)
|
|
44
|
+
subscribeSessionCompletion, sessionRpc, turnLivenessOf, addressErrorBody, } from './a2a-service.js';
|
|
45
|
+
export { A2A_WIRE_VERSION, A2A_TITLE_PLACEHOLDER, A2A_ENDPOINT_PATH, A2A_OUTBOX_PATH, A2A_WIRE_TIMEOUT_MS, A2aAddressError, a2aWireFrameOf, isA2aEnvelope, isA2aWireFrame, decodeA2aWireFrame, normalizeA2aTitle, a2aAddressOf, postA2aEnvelope, fetchA2aOutbox, } from './a2a-wire.js';
|
|
46
|
+
export { createA2aIngest, } from './a2a-ingest.js';
|
|
47
|
+
export { loadAgentStatus, recordMachineCollection, recordMachineFailure, collectRemoteMachine, collectLocalMachine, pullOutboxFor, statusSweepLegs, federatedFaceOf, AGENT_STATUS_ROWS_MAX, } from './agent-status.js';
|
|
48
|
+
export { registerA2aRpc, handleA2aIngestPost, handleA2aOutboxGet, } from './mesh-rpc.js';
|
|
49
|
+
export { deliverReply, deliverNotice, wireCompletionToDelivery, renderA2aRelayText, boundNoticeSummary, A2A_NOTICE_SUMMARY_MAX, } from './a2a-delivery.js';
|
|
50
|
+
export { resolveA2aGatewayFor, localA2aInitiator, createA2aHost, bridgeTypertGateway, } from './a2a-host.js';
|
|
51
|
+
export { createSuperdHubTool, parseAgentAddress, RECENT_CONVERSATIONS_MAX, AGENT_STATUS_WINDOW_MAX, HUB_A2A_TITLE_MARKER, UNHOSTED_TITLE, shapeAgentStatusWindow, EXEC_PLACEHOLDER_NOTE, } from './hub-tool.js';
|
|
52
|
+
export { wireHubToolRow, name as a2aRowName, default as a2aRow, } from './a2a-row.js';
|
|
37
53
|
export { default } from './gateway.js';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** One remote machine added by pairing (D1: cookie-grade token kept for re-mint). */
|
|
2
|
+
export interface MachineRow {
|
|
3
|
+
/** Machine id (m4) — minted by the owning machine, adopted as-is (D4). */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Operator-facing machine name on the remote. */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Display label for the machines UI. */
|
|
8
|
+
label: string;
|
|
9
|
+
/** Base origin of the remote hub (`http://host:port`). */
|
|
10
|
+
origin: string;
|
|
11
|
+
/** Retained auth token for cookie re-mint; same sensitivity as the cookie itself. */
|
|
12
|
+
token?: string;
|
|
13
|
+
/** Last minted request cookie (spec §4): persisted so hub restarts keep the remote's 30-day session instead of forcing a re-mint on every boot. */
|
|
14
|
+
cookie?: string;
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
/** P4 exec knob on the INITIATOR side (spec §5): undefined/true = this machine's agents may exec there; false = the tool leg refuses. */
|
|
17
|
+
execEnabled?: boolean;
|
|
18
|
+
/** Epoch ms when this row was added. */
|
|
19
|
+
addedAt: number;
|
|
20
|
+
}
|
|
21
|
+
/** The whole registry file. `self.id === ''` means not yet minted. */
|
|
22
|
+
export interface MachinesFile {
|
|
23
|
+
self: {
|
|
24
|
+
id: string;
|
|
25
|
+
label: string;
|
|
26
|
+
};
|
|
27
|
+
remotes: MachineRow[];
|
|
28
|
+
}
|
|
29
|
+
/** Mint a random short id over [a-z0-9], re-minting on collision with `taken`; loud after 32 attempts. */
|
|
30
|
+
export declare function mintShortId(len: 4 | 6, taken: Iterable<string>): string;
|
|
31
|
+
/** Read the registry; a missing or unreadable/corrupt file degrades to the empty shape (never throws). */
|
|
32
|
+
export declare function loadMachines(home: string): MachinesFile;
|
|
33
|
+
/** Persist the whole registry: recursive mkdir, tmp write, chmod 0600, atomic rename. */
|
|
34
|
+
export declare function saveMachines(home: string, file: MachinesFile): void;
|
|
35
|
+
/** Lazily mint + persist the self identity; an already-minted self is returned unchanged. */
|
|
36
|
+
export declare function ensureSelf(home: string, fallbackLabel: string): {
|
|
37
|
+
id: string;
|
|
38
|
+
label: string;
|
|
39
|
+
};
|
|
40
|
+
/** Snapshot copy of the remote rows — callers can hold it without aliasing the store. */
|
|
41
|
+
export declare function listRemotes(home: string): MachineRow[];
|
|
42
|
+
/** Insert or overwrite (same id) one remote row; full read-modify-write persistence. */
|
|
43
|
+
export declare function upsertRemote(home: string, row: MachineRow): void;
|
|
44
|
+
/** Drop one remote row; returns false when the id was not present. */
|
|
45
|
+
export declare function removeRemote(home: string, id: string): boolean;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Machine registry (mesh P1, spec §3.1/§3.3): the persisted identity of
|
|
3
|
+
* THIS machine (`self`, owner-minted m4 per D4) plus the remote machine
|
|
4
|
+
* rows created by pairing.
|
|
5
|
+
*
|
|
6
|
+
* Pure module — no cordis dependencies. All state lives in
|
|
7
|
+
* `<home>/superd/machines.json` (0600, atomic tmp+rename writes); every
|
|
8
|
+
* mutation is a read-modify-write of the whole file with no in-process
|
|
9
|
+
* cache, which is sufficient at P1 machine counts. A missing or
|
|
10
|
+
* unreadable file reads as the empty shape (`self.id === ''` = not yet
|
|
11
|
+
* minted); `ensureSelf` mints lazily on first need and never re-mints.
|
|
12
|
+
*/
|
|
13
|
+
import { randomInt } from 'node:crypto';
|
|
14
|
+
import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
15
|
+
import { join } from 'node:path';
|
|
16
|
+
const ID_ALPHABET = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
17
|
+
const MINT_MAX_ATTEMPTS = 32;
|
|
18
|
+
function machinesPath(home) {
|
|
19
|
+
return join(home, 'superd', 'machines.json');
|
|
20
|
+
}
|
|
21
|
+
function emptyMachines() {
|
|
22
|
+
return { self: { id: '', label: '' }, remotes: [] };
|
|
23
|
+
}
|
|
24
|
+
function isMachineRow(v) {
|
|
25
|
+
if (typeof v !== 'object' || v === null)
|
|
26
|
+
return false;
|
|
27
|
+
const r = v;
|
|
28
|
+
return (typeof r.id === 'string' && typeof r.name === 'string' && typeof r.label === 'string' &&
|
|
29
|
+
typeof r.origin === 'string' && typeof r.enabled === 'boolean' && typeof r.addedAt === 'number' &&
|
|
30
|
+
(r.token === undefined || typeof r.token === 'string') &&
|
|
31
|
+
(r.cookie === undefined || typeof r.cookie === 'string') &&
|
|
32
|
+
(r.execEnabled === undefined || r.execEnabled === true || r.execEnabled === false));
|
|
33
|
+
}
|
|
34
|
+
/** Mint a random short id over [a-z0-9], re-minting on collision with `taken`; loud after 32 attempts. */
|
|
35
|
+
export function mintShortId(len, taken) {
|
|
36
|
+
const used = new Set(taken);
|
|
37
|
+
for (let attempt = 0; attempt < MINT_MAX_ATTEMPTS; attempt++) {
|
|
38
|
+
let id = '';
|
|
39
|
+
for (let i = 0; i < len; i++)
|
|
40
|
+
id += ID_ALPHABET[randomInt(ID_ALPHABET.length)];
|
|
41
|
+
if (!used.has(id))
|
|
42
|
+
return id;
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`machines: short-id space exhausted after ${MINT_MAX_ATTEMPTS} attempts (len=${len})`);
|
|
45
|
+
}
|
|
46
|
+
/** Read the registry; a missing or unreadable/corrupt file degrades to the empty shape (never throws). */
|
|
47
|
+
export function loadMachines(home) {
|
|
48
|
+
let raw;
|
|
49
|
+
try {
|
|
50
|
+
raw = readFileSync(machinesPath(home), 'utf8');
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return emptyMachines();
|
|
54
|
+
}
|
|
55
|
+
let parsed;
|
|
56
|
+
try {
|
|
57
|
+
parsed = JSON.parse(raw);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return emptyMachines();
|
|
61
|
+
}
|
|
62
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
63
|
+
return emptyMachines();
|
|
64
|
+
const o = parsed;
|
|
65
|
+
const self = o.self;
|
|
66
|
+
if (typeof self !== 'object' || self === null)
|
|
67
|
+
return emptyMachines();
|
|
68
|
+
const s = self;
|
|
69
|
+
if (typeof s.id !== 'string' || typeof s.label !== 'string' || !Array.isArray(o.remotes)) {
|
|
70
|
+
return emptyMachines();
|
|
71
|
+
}
|
|
72
|
+
return { self: { id: s.id, label: s.label }, remotes: o.remotes.filter(isMachineRow) };
|
|
73
|
+
}
|
|
74
|
+
/** Persist the whole registry: recursive mkdir, tmp write, chmod 0600, atomic rename. */
|
|
75
|
+
export function saveMachines(home, file) {
|
|
76
|
+
if (typeof file.self?.id !== 'string' || typeof file.self?.label !== 'string' || !Array.isArray(file.remotes)) {
|
|
77
|
+
throw new TypeError('machines: save rejected — file must be {self: {id, label}, remotes: []}');
|
|
78
|
+
}
|
|
79
|
+
for (const r of file.remotes) {
|
|
80
|
+
if (typeof r?.id !== 'string' || r.id === '' || typeof r.name !== 'string' || r.name === '' ||
|
|
81
|
+
typeof r.origin !== 'string' || r.origin === '') {
|
|
82
|
+
throw new TypeError('machines: save rejected — row id/name/origin must be non-empty strings');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const dir = join(home, 'superd');
|
|
86
|
+
mkdirSync(dir, { recursive: true });
|
|
87
|
+
const target = machinesPath(home);
|
|
88
|
+
const tmp = `${target}.tmp`;
|
|
89
|
+
writeFileSync(tmp, JSON.stringify(file, null, 2) + '\n', { encoding: 'utf8', mode: 0o600 });
|
|
90
|
+
chmodSync(tmp, 0o600);
|
|
91
|
+
renameSync(tmp, target);
|
|
92
|
+
}
|
|
93
|
+
/** Lazily mint + persist the self identity; an already-minted self is returned unchanged. */
|
|
94
|
+
export function ensureSelf(home, fallbackLabel) {
|
|
95
|
+
const file = loadMachines(home);
|
|
96
|
+
if (file.self.id !== '')
|
|
97
|
+
return file.self;
|
|
98
|
+
const taken = new Set([...file.remotes.map((r) => r.id)]);
|
|
99
|
+
const self = { id: mintShortId(4, taken), label: fallbackLabel };
|
|
100
|
+
saveMachines(home, { self, remotes: file.remotes });
|
|
101
|
+
return self;
|
|
102
|
+
}
|
|
103
|
+
/** Snapshot copy of the remote rows — callers can hold it without aliasing the store. */
|
|
104
|
+
export function listRemotes(home) {
|
|
105
|
+
return loadMachines(home).remotes.map((r) => ({ ...r }));
|
|
106
|
+
}
|
|
107
|
+
/** Insert or overwrite (same id) one remote row; full read-modify-write persistence. */
|
|
108
|
+
export function upsertRemote(home, row) {
|
|
109
|
+
const file = loadMachines(home);
|
|
110
|
+
const idx = file.remotes.findIndex((r) => r.id === row.id);
|
|
111
|
+
if (idx === -1)
|
|
112
|
+
file.remotes.push({ ...row });
|
|
113
|
+
else
|
|
114
|
+
file.remotes[idx] = { ...row };
|
|
115
|
+
saveMachines(home, file);
|
|
116
|
+
}
|
|
117
|
+
/** Drop one remote row; returns false when the id was not present. */
|
|
118
|
+
export function removeRemote(home, id) {
|
|
119
|
+
const file = loadMachines(home);
|
|
120
|
+
const remotes = file.remotes.filter((r) => r.id !== id);
|
|
121
|
+
if (remotes.length === file.remotes.length)
|
|
122
|
+
return false;
|
|
123
|
+
saveMachines(home, { self: file.self, remotes });
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Federation registrar (machine-mesh P2 Task 3): adopts a paired machine's
|
|
3
|
+
* PROBED roster into the LOCAL registries, so a remote agent is addressable
|
|
4
|
+
* and visible exactly like a local world:
|
|
5
|
+
*
|
|
6
|
+
* targets.ts `registerForeignTarget({key: a6, gateway})` — the a6-keyed
|
|
7
|
+
* wire gateway (Task 2's `createRemoteGateway`), so the `/hub`
|
|
8
|
+
* family demuxes `?agent=<a6>` to the peer's `/hub` family
|
|
9
|
+
* carrying the remote RUNTIME key (`?agent=codex` at the peer).
|
|
10
|
+
* The peer's NATIVE agent row federates the same way — its
|
|
11
|
+
* row carries a minted a6 plus `key:'native'`, and its gateway
|
|
12
|
+
* is built with the NATIVE face (Task 2's `face` option): the
|
|
13
|
+
* peer's ctx0 `/api` surface, no demux key — exactly how a
|
|
14
|
+
* browser ON the peer consumes its native DSH (the `/hub`
|
|
15
|
+
* family would 404 `?agent=native` as foreign-only).
|
|
16
|
+
* roster.ts one row per agent: `{key: a6, label: '<Label> · <machine
|
|
17
|
+
* name>', machine: m4, ready, failed}` — `machine` set marks
|
|
18
|
+
* the row federated; `agentLinks` projects it into the UI rows.
|
|
19
|
+
*
|
|
20
|
+
* The a6 IS the local registration key (spec §3.2): runtime keys are NOT
|
|
21
|
+
* reused across machines (a remote `codex` would collide with — and silently
|
|
22
|
+
* replace — the local codex world), while a6s are owner-minted 6-char ids
|
|
23
|
+
* adopted verbatim. EVERY row federates, the peer's native included — the
|
|
24
|
+
* face selector is `agent.key === 'native'`, never an a6 test (only
|
|
25
|
+
* `'native'` is pre-screened as a hard reserve). Cross-machine a6 collision
|
|
26
|
+
* (two peers minting the same id, p ≈ 36⁻¹² per pair) and a6-vs-local-key
|
|
27
|
+
* collision (p ≈ 36⁻⁶ per adoption) are accepted at P2 machine counts — the
|
|
28
|
+
* registry replaces last-write-wins, same ruling as spec §3.1's m4 collision
|
|
29
|
+
* roughness.
|
|
30
|
+
*
|
|
31
|
+
* ## Import direction (frozen): mesh-federate → {mesh-link, mesh-gateway,
|
|
32
|
+
* ## roster, targets} — NEVER the reverse. mesh-link emits machine lifecycle
|
|
33
|
+
* ## events (`onMeshFederationEvent`: federated / degraded / defederated);
|
|
34
|
+
* ## this module subscribes at wiring time ({@link startMeshFederation},
|
|
35
|
+
* ## called once from gateway.ts apply). mesh-rpc's DELETE path announces
|
|
36
|
+
* ## removals through mesh-link's {@link emitMachineRemoved} — no route-module
|
|
37
|
+
* ## federation logic anywhere.
|
|
38
|
+
*
|
|
39
|
+
* ## Gateway memo — one `RemoteGateway` per (m4, a6), built by the wiring's
|
|
40
|
+
* ## factory, keyed by a6. Reused across probe events (identity-stable: a
|
|
41
|
+
* ## reprobe does not rebuild a live gateway); rebuilt when the peer facts
|
|
42
|
+
* ## change (origin moved, remote runtime key re-minted); disposed and
|
|
43
|
+
* ## forgotten on defederate. The cookie is NOT memoized — the gateway reads
|
|
44
|
+
* ## it per call through `cookieOf(m4, home)` (jar-fronted), so a re-minted
|
|
45
|
+
* ## cookie is picked up by the NEXT call with zero rebuilds.
|
|
46
|
+
*
|
|
47
|
+
* ## Degrade semantics (spec §6.3): a failed probe KEEPS the machine's rows
|
|
48
|
+
* ## and flips `ready` false — visible but not servable. Defederate (machine
|
|
49
|
+
* ## removal) and stale-convergence (an agent vanished from the peer's
|
|
50
|
+
* ## roster) are the only row-removing paths.
|
|
51
|
+
*/
|
|
52
|
+
import { type MuxClientSocket } from './mesh-gateway.js';
|
|
53
|
+
import { type GatewayFace } from './targets.js';
|
|
54
|
+
/** One remote agent as adopted from a probe — mesh-link's `ProbeAgent` shape
|
|
55
|
+
* (kept structural so callers and tests can pass plain objects). */
|
|
56
|
+
export interface FederatedAgent {
|
|
57
|
+
/** The remote-owner-minted a6 — the LOCAL registration key. */
|
|
58
|
+
id: string;
|
|
59
|
+
/** The remote RUNTIME key (`codex`, `omp`, …) — the peer's `?agent=` demux
|
|
60
|
+
* key on the wire; `'native'` selects the NATIVE face (peer ctx0 `/api`, no
|
|
61
|
+
* demux key) in the wiring's gateway factory. An EMPTY key cannot address
|
|
62
|
+
* anything at the peer; {@link gatewayFor} falls back to the a6 there
|
|
63
|
+
* (T3-M1) rather than shipping `?agent=` on the wire. */
|
|
64
|
+
key: string;
|
|
65
|
+
label: string;
|
|
66
|
+
ready: boolean;
|
|
67
|
+
failed: boolean;
|
|
68
|
+
}
|
|
69
|
+
/** The machine half of a federation fact (m4 + display name for label suffixes). */
|
|
70
|
+
export interface FederatedMachine {
|
|
71
|
+
id: string;
|
|
72
|
+
name: string;
|
|
73
|
+
}
|
|
74
|
+
/** Wiring deps: the hub home (cookie row fallback) + test seams for the wire. */
|
|
75
|
+
export interface FederationWireDeps {
|
|
76
|
+
home: string;
|
|
77
|
+
fetchImpl?: typeof fetch;
|
|
78
|
+
wsFactory?: (url: string, headers: Record<string, string>) => MuxClientSocket;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Register one machine's probed agents — IDEMPOTENT replace per a6: a row
|
|
82
|
+
* whose key/label/machine/ready/failed all match the live registry is left
|
|
83
|
+
* untouched (zero roster churn on repeated probes); a changed row is
|
|
84
|
+
* unregistered then re-registered (`registerAgent` throws on duplicate keys —
|
|
85
|
+
* federate always unregisters first, so repeated probes never throw).
|
|
86
|
+
* Agents with an empty id (unkeyable) are skipped; EVERY keyed row
|
|
87
|
+
* federates — the peer's native row included (its `key:'native'` selects the
|
|
88
|
+
* native gateway face; see {@link gatewayFor}).
|
|
89
|
+
* @param machine - the peer's identity (m4 + name; the name lands in every label suffix).
|
|
90
|
+
* @param agents - the probe's agent snapshot (a6 `id`, remote `key`, label, ready, failed).
|
|
91
|
+
* @param gatewayOf - gateway factory receiving the FULL agent row (the wiring
|
|
92
|
+
* derives the face from `agent.key`; tests inject fakes) — called once per
|
|
93
|
+
* (re)registration and once per converged-row target re-arm.
|
|
94
|
+
*/
|
|
95
|
+
export declare function federateAgents(machine: FederatedMachine, agents: FederatedAgent[], gatewayOf: (agent: FederatedAgent) => GatewayFace): void;
|
|
96
|
+
/**
|
|
97
|
+
* Drop EVERY federated row of one machine (mesh-rpc DELETE / unpair): roster
|
|
98
|
+
* rows, target registrations, and the memoized wire gateways (disposed —
|
|
99
|
+
* in-flight streams fail `gateway/disposed` per Task 2's contract).
|
|
100
|
+
*/
|
|
101
|
+
export declare function defederateMachine(m4: string): void;
|
|
102
|
+
/**
|
|
103
|
+
* Roster convergence: unregister the machine's rows whose a6s are ABSENT from
|
|
104
|
+
* the peer's latest probe (the agent was removed/renamed remotely) — live
|
|
105
|
+
* agents are left to {@link federateAgents}.
|
|
106
|
+
* @param m4 - the machine id.
|
|
107
|
+
* @param liveA6s - the a6 set of the latest successful probe.
|
|
108
|
+
*/
|
|
109
|
+
export declare function defederateStaleMachine(m4: string, liveA6s: ReadonlySet<string>): void;
|
|
110
|
+
/**
|
|
111
|
+
* Degrade one machine's rows after a failed probe (unreachable peer or
|
|
112
|
+
* auth-expired cookie): rows are KEPT, `ready` flipped false, `failed`
|
|
113
|
+
* untouched — visible but not servable (spec §6.3; the orchestra downgrade).
|
|
114
|
+
* Rows already degraded are left alone (no roster churn); local rows are
|
|
115
|
+
* never touched.
|
|
116
|
+
*/
|
|
117
|
+
export declare function degradeMachine(m4: string): void;
|
|
118
|
+
/**
|
|
119
|
+
* The federated gateway of one a6 — the `/hub` demux's federation-table step
|
|
120
|
+
* (exact a6 match; the same pair `federateAgents` registers into the shared
|
|
121
|
+
* target registry, so the two sources never disagree). Undefined for local
|
|
122
|
+
* labels and unknown/defederated a6s.
|
|
123
|
+
*/
|
|
124
|
+
export declare function federatedGatewayOf(a6: string): GatewayFace | undefined;
|
|
125
|
+
/**
|
|
126
|
+
* Wire the registrar to mesh-link's machine lifecycle events (called ONCE at
|
|
127
|
+
* plugin activation — gateway.ts apply):
|
|
128
|
+
*
|
|
129
|
+
* - `federated` → {@link federateAgents} (converge onto the probe snapshot)
|
|
130
|
+
* + {@link defederateStaleMachine} (drop vanished agents);
|
|
131
|
+
* - `degraded` → {@link degradeMachine} (rows kept, ready=false);
|
|
132
|
+
* - `defederated` → {@link defederateMachine} (mesh-rpc DELETE).
|
|
133
|
+
*
|
|
134
|
+
* Re-probing a machine after a hub restart rebuilds its federation from the
|
|
135
|
+
* probe alone — the events are the single rebuild path.
|
|
136
|
+
* @returns the disposer (unsubscribes; registered rows are left as-is).
|
|
137
|
+
*/
|
|
138
|
+
export declare function startMeshFederation(deps: FederationWireDeps): () => void;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Federation registrar (machine-mesh P2 Task 3): adopts a paired machine's
|
|
3
|
+
* PROBED roster into the LOCAL registries, so a remote agent is addressable
|
|
4
|
+
* and visible exactly like a local world:
|
|
5
|
+
*
|
|
6
|
+
* targets.ts `registerForeignTarget({key: a6, gateway})` — the a6-keyed
|
|
7
|
+
* wire gateway (Task 2's `createRemoteGateway`), so the `/hub`
|
|
8
|
+
* family demuxes `?agent=<a6>` to the peer's `/hub` family
|
|
9
|
+
* carrying the remote RUNTIME key (`?agent=codex` at the peer).
|
|
10
|
+
* The peer's NATIVE agent row federates the same way — its
|
|
11
|
+
* row carries a minted a6 plus `key:'native'`, and its gateway
|
|
12
|
+
* is built with the NATIVE face (Task 2's `face` option): the
|
|
13
|
+
* peer's ctx0 `/api` surface, no demux key — exactly how a
|
|
14
|
+
* browser ON the peer consumes its native DSH (the `/hub`
|
|
15
|
+
* family would 404 `?agent=native` as foreign-only).
|
|
16
|
+
* roster.ts one row per agent: `{key: a6, label: '<Label> · <machine
|
|
17
|
+
* name>', machine: m4, ready, failed}` — `machine` set marks
|
|
18
|
+
* the row federated; `agentLinks` projects it into the UI rows.
|
|
19
|
+
*
|
|
20
|
+
* The a6 IS the local registration key (spec §3.2): runtime keys are NOT
|
|
21
|
+
* reused across machines (a remote `codex` would collide with — and silently
|
|
22
|
+
* replace — the local codex world), while a6s are owner-minted 6-char ids
|
|
23
|
+
* adopted verbatim. EVERY row federates, the peer's native included — the
|
|
24
|
+
* face selector is `agent.key === 'native'`, never an a6 test (only
|
|
25
|
+
* `'native'` is pre-screened as a hard reserve). Cross-machine a6 collision
|
|
26
|
+
* (two peers minting the same id, p ≈ 36⁻¹² per pair) and a6-vs-local-key
|
|
27
|
+
* collision (p ≈ 36⁻⁶ per adoption) are accepted at P2 machine counts — the
|
|
28
|
+
* registry replaces last-write-wins, same ruling as spec §3.1's m4 collision
|
|
29
|
+
* roughness.
|
|
30
|
+
*
|
|
31
|
+
* ## Import direction (frozen): mesh-federate → {mesh-link, mesh-gateway,
|
|
32
|
+
* ## roster, targets} — NEVER the reverse. mesh-link emits machine lifecycle
|
|
33
|
+
* ## events (`onMeshFederationEvent`: federated / degraded / defederated);
|
|
34
|
+
* ## this module subscribes at wiring time ({@link startMeshFederation},
|
|
35
|
+
* ## called once from gateway.ts apply). mesh-rpc's DELETE path announces
|
|
36
|
+
* ## removals through mesh-link's {@link emitMachineRemoved} — no route-module
|
|
37
|
+
* ## federation logic anywhere.
|
|
38
|
+
*
|
|
39
|
+
* ## Gateway memo — one `RemoteGateway` per (m4, a6), built by the wiring's
|
|
40
|
+
* ## factory, keyed by a6. Reused across probe events (identity-stable: a
|
|
41
|
+
* ## reprobe does not rebuild a live gateway); rebuilt when the peer facts
|
|
42
|
+
* ## change (origin moved, remote runtime key re-minted); disposed and
|
|
43
|
+
* ## forgotten on defederate. The cookie is NOT memoized — the gateway reads
|
|
44
|
+
* ## it per call through `cookieOf(m4, home)` (jar-fronted), so a re-minted
|
|
45
|
+
* ## cookie is picked up by the NEXT call with zero rebuilds.
|
|
46
|
+
*
|
|
47
|
+
* ## Degrade semantics (spec §6.3): a failed probe KEEPS the machine's rows
|
|
48
|
+
* ## and flips `ready` false — visible but not servable. Defederate (machine
|
|
49
|
+
* ## removal) and stale-convergence (an agent vanished from the peer's
|
|
50
|
+
* ## roster) are the only row-removing paths.
|
|
51
|
+
*/
|
|
52
|
+
import { createRemoteGateway } from './mesh-gateway.js';
|
|
53
|
+
import { cookieOf, onMeshFederationEvent } from './mesh-link.js';
|
|
54
|
+
import { registerAgent, unregisterAgent, listAgents, setReady } from './roster.js';
|
|
55
|
+
import { registerForeignTarget, unregisterForeignTarget, getTarget } from './targets.js';
|
|
56
|
+
const gatewayMemo = new Map();
|
|
57
|
+
/** Roster rows of one machine (its a6s), from the live registry. */
|
|
58
|
+
function rowsOf(m4) {
|
|
59
|
+
return listAgents().filter((e) => (e.machine ?? 'local') === m4);
|
|
60
|
+
}
|
|
61
|
+
/** Unregister one federated a6 from both registries + drop its memo gateway. */
|
|
62
|
+
function dropA6(a6) {
|
|
63
|
+
if (listAgents().some((e) => e.key === a6))
|
|
64
|
+
unregisterAgent(a6); // guard: unregister no-ops still emit roster churn
|
|
65
|
+
unregisterForeignTarget(a6);
|
|
66
|
+
const memo = gatewayMemo.get(a6);
|
|
67
|
+
if (memo !== undefined) {
|
|
68
|
+
gatewayMemo.delete(a6);
|
|
69
|
+
memo.gateway.dispose();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Register one machine's probed agents — IDEMPOTENT replace per a6: a row
|
|
74
|
+
* whose key/label/machine/ready/failed all match the live registry is left
|
|
75
|
+
* untouched (zero roster churn on repeated probes); a changed row is
|
|
76
|
+
* unregistered then re-registered (`registerAgent` throws on duplicate keys —
|
|
77
|
+
* federate always unregisters first, so repeated probes never throw).
|
|
78
|
+
* Agents with an empty id (unkeyable) are skipped; EVERY keyed row
|
|
79
|
+
* federates — the peer's native row included (its `key:'native'` selects the
|
|
80
|
+
* native gateway face; see {@link gatewayFor}).
|
|
81
|
+
* @param machine - the peer's identity (m4 + name; the name lands in every label suffix).
|
|
82
|
+
* @param agents - the probe's agent snapshot (a6 `id`, remote `key`, label, ready, failed).
|
|
83
|
+
* @param gatewayOf - gateway factory receiving the FULL agent row (the wiring
|
|
84
|
+
* derives the face from `agent.key`; tests inject fakes) — called once per
|
|
85
|
+
* (re)registration and once per converged-row target re-arm.
|
|
86
|
+
*/
|
|
87
|
+
export function federateAgents(machine, agents, gatewayOf) {
|
|
88
|
+
for (const agent of agents) {
|
|
89
|
+
if (agent.id === '')
|
|
90
|
+
continue;
|
|
91
|
+
const desired = {
|
|
92
|
+
key: agent.id,
|
|
93
|
+
label: `${agent.label} · ${machine.name}`,
|
|
94
|
+
machine: machine.id,
|
|
95
|
+
ready: agent.ready === true,
|
|
96
|
+
failed: agent.failed === true,
|
|
97
|
+
};
|
|
98
|
+
const existing = listAgents().find((e) => e.key === agent.id);
|
|
99
|
+
if (existing !== undefined
|
|
100
|
+
&& existing.label === desired.label
|
|
101
|
+
&& existing.ready === desired.ready
|
|
102
|
+
&& (existing.failed ?? false) === desired.failed
|
|
103
|
+
&& (existing.machine ?? 'local') === machine.id) {
|
|
104
|
+
// Converged — but never trust a half-state: the roster row may survive
|
|
105
|
+
// a target that something else dropped. Re-arm the registration only.
|
|
106
|
+
if (getTarget(agent.id) === undefined)
|
|
107
|
+
registerForeignTarget({ key: agent.id, gateway: gatewayOf(agent) });
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (existing !== undefined)
|
|
111
|
+
unregisterAgent(agent.id); // defeats registerAgent's duplicate-key throw
|
|
112
|
+
unregisterForeignTarget(agent.id); // explicit replace, not map-overwrite
|
|
113
|
+
registerForeignTarget({ key: agent.id, gateway: gatewayOf(agent) });
|
|
114
|
+
registerAgent(desired);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Drop EVERY federated row of one machine (mesh-rpc DELETE / unpair): roster
|
|
119
|
+
* rows, target registrations, and the memoized wire gateways (disposed —
|
|
120
|
+
* in-flight streams fail `gateway/disposed` per Task 2's contract).
|
|
121
|
+
*/
|
|
122
|
+
export function defederateMachine(m4) {
|
|
123
|
+
for (const row of rowsOf(m4))
|
|
124
|
+
dropA6(row.key);
|
|
125
|
+
// Belt: memo entries whose roster rows vanished independently still die with the machine.
|
|
126
|
+
for (const [a6, memo] of [...gatewayMemo]) {
|
|
127
|
+
if (memo.machineId === m4)
|
|
128
|
+
dropA6(a6);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Roster convergence: unregister the machine's rows whose a6s are ABSENT from
|
|
133
|
+
* the peer's latest probe (the agent was removed/renamed remotely) — live
|
|
134
|
+
* agents are left to {@link federateAgents}.
|
|
135
|
+
* @param m4 - the machine id.
|
|
136
|
+
* @param liveA6s - the a6 set of the latest successful probe.
|
|
137
|
+
*/
|
|
138
|
+
export function defederateStaleMachine(m4, liveA6s) {
|
|
139
|
+
for (const row of rowsOf(m4)) {
|
|
140
|
+
if (!liveA6s.has(row.key))
|
|
141
|
+
dropA6(row.key);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Degrade one machine's rows after a failed probe (unreachable peer or
|
|
146
|
+
* auth-expired cookie): rows are KEPT, `ready` flipped false, `failed`
|
|
147
|
+
* untouched — visible but not servable (spec §6.3; the orchestra downgrade).
|
|
148
|
+
* Rows already degraded are left alone (no roster churn); local rows are
|
|
149
|
+
* never touched.
|
|
150
|
+
*/
|
|
151
|
+
export function degradeMachine(m4) {
|
|
152
|
+
for (const row of rowsOf(m4)) {
|
|
153
|
+
if (row.ready !== false)
|
|
154
|
+
setReady(row.key, false);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* The federated gateway of one a6 — the `/hub` demux's federation-table step
|
|
159
|
+
* (exact a6 match; the same pair `federateAgents` registers into the shared
|
|
160
|
+
* target registry, so the two sources never disagree). Undefined for local
|
|
161
|
+
* labels and unknown/defederated a6s.
|
|
162
|
+
*/
|
|
163
|
+
export function federatedGatewayOf(a6) {
|
|
164
|
+
return gatewayMemo.get(a6)?.gateway;
|
|
165
|
+
}
|
|
166
|
+
/** The wiring's gateway factory: memoized per a6, rebuilt on peer-fact
|
|
167
|
+
* change (origin, remote runtime key, or face flip). The FACE is selected
|
|
168
|
+
* from the agent ROW — `key === 'native'` → the peer's ctx0 `/api` surface,
|
|
169
|
+
* anything else → the `/hub` family with the runtime-key demux. */
|
|
170
|
+
function gatewayFor(event, agent, deps) {
|
|
171
|
+
const a6 = agent.id;
|
|
172
|
+
const face = agent.key === 'native' ? 'native' : 'foreign';
|
|
173
|
+
// T3-M1: an empty remote key must not ride the wire as `?agent=` (the
|
|
174
|
+
// nullish class miss — '' is not nullish); fall back to the a6 so the
|
|
175
|
+
// registration stays addressable and the wrong key fails LOUDLY at the
|
|
176
|
+
// peer (its demux 404s the unknown key) instead of silently here.
|
|
177
|
+
const agentKey = agent.key !== '' ? agent.key : agent.id;
|
|
178
|
+
const memo = gatewayMemo.get(a6);
|
|
179
|
+
if (memo !== undefined && memo.machineId === event.machineId && memo.origin === event.origin && memo.agentKey === agentKey && memo.face === face) {
|
|
180
|
+
return memo.gateway;
|
|
181
|
+
}
|
|
182
|
+
if (memo !== undefined) {
|
|
183
|
+
gatewayMemo.delete(a6);
|
|
184
|
+
memo.gateway.dispose();
|
|
185
|
+
}
|
|
186
|
+
const gateway = createRemoteGateway({
|
|
187
|
+
origin: event.origin,
|
|
188
|
+
agentKey,
|
|
189
|
+
face,
|
|
190
|
+
cookie: () => cookieOf(event.machineId, deps.home),
|
|
191
|
+
fetchImpl: deps.fetchImpl,
|
|
192
|
+
wsFactory: deps.wsFactory,
|
|
193
|
+
});
|
|
194
|
+
gatewayMemo.set(a6, { gateway, machineId: event.machineId, origin: event.origin, agentKey, face });
|
|
195
|
+
return gateway;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Wire the registrar to mesh-link's machine lifecycle events (called ONCE at
|
|
199
|
+
* plugin activation — gateway.ts apply):
|
|
200
|
+
*
|
|
201
|
+
* - `federated` → {@link federateAgents} (converge onto the probe snapshot)
|
|
202
|
+
* + {@link defederateStaleMachine} (drop vanished agents);
|
|
203
|
+
* - `degraded` → {@link degradeMachine} (rows kept, ready=false);
|
|
204
|
+
* - `defederated` → {@link defederateMachine} (mesh-rpc DELETE).
|
|
205
|
+
*
|
|
206
|
+
* Re-probing a machine after a hub restart rebuilds its federation from the
|
|
207
|
+
* probe alone — the events are the single rebuild path.
|
|
208
|
+
* @returns the disposer (unsubscribes; registered rows are left as-is).
|
|
209
|
+
*/
|
|
210
|
+
export function startMeshFederation(deps) {
|
|
211
|
+
return onMeshFederationEvent((event) => {
|
|
212
|
+
if (event.type === 'federated') {
|
|
213
|
+
federateAgents({ id: event.machineId, name: event.machineName }, event.agents, (agent) => gatewayFor(event, agent, deps));
|
|
214
|
+
defederateStaleMachine(event.machineId, new Set(event.agents.map((a) => a.id)));
|
|
215
|
+
}
|
|
216
|
+
else if (event.type === 'degraded') {
|
|
217
|
+
degradeMachine(event.machineId);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
defederateMachine(event.machineId);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|