@code-yeongyu/senpi 2026.10.25-2 → 2026.10.25-4
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/CHANGELOG.md +37 -0
- package/dist/bundle/chunks/{args-JXULI4EH.js → args-B444OQBK.js} +1 -1
- package/dist/bundle/chunks/{auth-4NUNUSTF.js → auth-C77UQA55.js} +1 -1
- package/dist/bundle/chunks/{chunk-XBUSVKWC.js → chunk-2RB5EL4X.js} +1 -1
- package/dist/bundle/chunks/{chunk-KUE4AQN6.js → chunk-3QCYBOKN.js} +1 -1
- package/dist/bundle/chunks/{chunk-2EFVQWXZ.js → chunk-4MOZXOJX.js} +5 -5
- package/dist/bundle/chunks/{chunk-MXZPAUFB.js → chunk-5JJDR6XI.js} +1 -1
- package/dist/bundle/chunks/chunk-6VWIMHMH.js +2 -0
- package/dist/bundle/chunks/{chunk-Y5OTHMXO.js → chunk-7CNOCJCN.js} +1 -1
- package/dist/bundle/chunks/chunk-AX72VNRS.js +27 -0
- package/dist/bundle/chunks/{chunk-VNN2V74Y.js → chunk-BZ7726QO.js} +1 -1
- package/dist/bundle/chunks/{chunk-J2U5VDG7.js → chunk-C2MQ4QXN.js} +30 -30
- package/dist/bundle/chunks/{chunk-JRXKLIEQ.js → chunk-DODH3N6U.js} +5 -5
- package/dist/bundle/chunks/{chunk-EHQXLHRB.js → chunk-E6D4RIT7.js} +2 -2
- package/dist/bundle/chunks/chunk-J37GRED2.js +5 -0
- package/dist/bundle/chunks/chunk-JMOUU75H.js +2 -0
- package/dist/bundle/chunks/chunk-JPGT64RV.js +2 -0
- package/dist/bundle/chunks/chunk-KKD4CYCI.js +3 -0
- package/dist/bundle/chunks/{chunk-YN7ELQ43.js → chunk-KNVNKDER.js} +1 -1
- package/dist/bundle/chunks/chunk-KXB5WIS5.js +4 -0
- package/dist/bundle/chunks/chunk-L73UYAH5.js +3 -0
- package/dist/bundle/chunks/{chunk-G2UETS2R.js → chunk-LOIF6PHI.js} +4 -4
- package/dist/bundle/chunks/chunk-LTU6UFEX.js +2 -0
- package/dist/bundle/chunks/chunk-N7IN46Q5.js +27 -0
- package/dist/bundle/chunks/{chunk-LYGAV6KU.js → chunk-PT6JJUN2.js} +1 -1
- package/dist/bundle/chunks/{chunk-WFXUCVIR.js → chunk-SBGIXMX3.js} +2 -5
- package/dist/bundle/chunks/{chunk-W2BKZBYJ.js → chunk-STMXIBXF.js} +2 -2
- package/dist/bundle/chunks/chunk-TBU6VYHN.js +13 -0
- package/dist/bundle/chunks/{chunk-RXKNOEQQ.js → chunk-V2UYXTRR.js} +1 -1
- package/dist/bundle/chunks/{chunk-U67ML6CQ.js → chunk-WD6WBYC5.js} +1 -1
- package/dist/bundle/chunks/chunk-WJOT3DFL.js +2 -0
- package/dist/bundle/chunks/chunk-XMJKZK5H.js +2 -0
- package/dist/bundle/chunks/chunk-YI7SPFDN.js +5 -0
- package/dist/bundle/chunks/cli-main-YYH3IBC6.js +3 -0
- package/dist/bundle/chunks/{client-KWTLTKVV.js → client-WTYEICLH.js} +3 -3
- package/dist/bundle/chunks/dispatch-MXG5YWLV.js +9 -0
- package/dist/bundle/chunks/{help-fast-path-ZHZGXAUG.js → help-fast-path-3Z26DQSV.js} +1 -1
- package/dist/bundle/chunks/host-command-TDLLHXVI.js +2 -0
- package/dist/bundle/chunks/host-lifecycle-3VHHIGDL.js +3 -0
- package/dist/bundle/chunks/host-lifecycle.js +8 -6
- package/dist/bundle/chunks/host-session-command-56XF6ACS.js +20 -0
- package/dist/bundle/chunks/{host-socket-request-AS2OCRLP.js → host-socket-request-QL2WEZTN.js} +1 -1
- package/dist/bundle/chunks/interactive-mode-OEPULLZK.js +2 -0
- package/dist/bundle/chunks/mcp-presenter-bootstrap-XUSCQVRC.js +2 -0
- package/dist/bundle/chunks/{multi-session-host-VTTY5MFT.js → multi-session-host-Z2CW4SDM.js} +12 -9
- package/dist/bundle/chunks/{package-manager-cli-DZFOC3MF.js → package-manager-cli-N55U6PEO.js} +1 -1
- package/dist/bundle/chunks/rotation-stream-CBGCBYHV.js +2 -0
- package/dist/bundle/chunks/rpc-mode-ETXQWEB2.js +2 -0
- package/dist/bundle/chunks/{rpc-monitor-source-B5NQ4ZVH.js → rpc-monitor-source-AE3C6EQV.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-SLISTG4V.js → schedule-command-VS7CZC2J.js} +1 -1
- package/dist/bundle/chunks/session-control-endpoint-4LEIDIVI.js +3 -0
- package/dist/bundle/chunks/session-picker-E4KUJDLO.js +2 -0
- package/dist/bundle/chunks/session-worker.js +292 -278
- package/dist/bundle/chunks/{stdio-IEC635SY.js → stdio-YXDKKKQZ.js} +1 -1
- package/dist/bundle/chunks/{streamableHttp-KJI5KE4K.js → streamableHttp-DKIBUWVY.js} +1 -1
- package/dist/bundle/chunks/{types-LLNV23LW.js → types-BJUEQ4II.js} +1 -1
- package/dist/bundle/chunks/zod-compat-RJDXCU7S.js +2 -0
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +8 -6
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/cli/args.d.ts +2 -0
- package/dist/cli/args.js +9 -0
- package/dist/cli/host-command-args.d.ts +1 -0
- package/dist/cli/host-command-args.js +7 -1
- package/dist/cli/host-command.js +3 -1
- package/dist/core/agent-session.js +22 -7
- package/dist/core/extensions/builtin/goal/index.js +1 -0
- package/dist/core/extensions/builtin/goal/lifecycle-facts.d.ts +3 -0
- package/dist/core/extensions/builtin/mcp/catalog.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/catalog.js +2 -0
- package/dist/core/extensions/builtin/mcp/connection.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/connection.js +46 -1
- package/dist/core/extensions/builtin/mcp/elicitation.d.ts +6 -1
- package/dist/core/extensions/builtin/mcp/elicitation.js +54 -2
- package/dist/core/extensions/builtin/mcp/expose/call.js +6 -2
- package/dist/core/extensions/builtin/mcp/expose/session.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/expose/session.js +7 -0
- package/dist/core/extensions/builtin/mcp/health.js +5 -0
- package/dist/core/extensions/builtin/mcp/host-registry.js +7 -1
- package/dist/core/extensions/builtin/mcp/index.js +2 -0
- package/dist/core/extensions/builtin/mcp/modern/client.d.ts +5 -0
- package/dist/core/extensions/builtin/mcp/modern/client.js +15 -0
- package/dist/core/extensions/builtin/mcp/modern/consent-queue.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/modern/consent-queue.js +59 -0
- package/dist/core/extensions/builtin/mcp/modern/diagnostics.d.ts +4 -0
- package/dist/core/extensions/builtin/mcp/modern/diagnostics.js +39 -0
- package/dist/core/extensions/builtin/mcp/modern/dispatch.js +21 -11
- package/dist/core/extensions/builtin/mcp/modern/elicitation.d.ts +14 -0
- package/dist/core/extensions/builtin/mcp/modern/elicitation.js +145 -0
- package/dist/core/extensions/builtin/mcp/modern/errors.d.ts +21 -0
- package/dist/core/extensions/builtin/mcp/modern/errors.js +23 -0
- package/dist/core/extensions/builtin/mcp/modern/form-schema.d.ts +20 -0
- package/dist/core/extensions/builtin/mcp/modern/form-schema.js +153 -0
- package/dist/core/extensions/builtin/mcp/modern/http-fetch.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/modern/http-fetch.js +8 -2
- package/dist/core/extensions/builtin/mcp/modern/inputs.d.ts +11 -0
- package/dist/core/extensions/builtin/mcp/modern/inputs.js +65 -0
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.d.ts +11 -0
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.js +109 -0
- package/dist/core/extensions/builtin/mcp/modern/request.d.ts +20 -0
- package/dist/core/extensions/builtin/mcp/modern/request.js +292 -0
- package/dist/core/extensions/builtin/mcp/modern/stdio-probe.d.ts +1 -1
- package/dist/core/extensions/builtin/mcp/modern/stdio-probe.js +54 -6
- package/dist/core/extensions/builtin/mcp/modern/transport.js +80 -14
- package/dist/core/extensions/builtin/mcp/modern/wire.js +11 -7
- package/dist/core/extensions/builtin/mcp/prompts.d.ts +5 -1
- package/dist/core/extensions/builtin/mcp/prompts.js +6 -1
- package/dist/core/extensions/builtin/mcp/request-origin.d.ts +47 -0
- package/dist/core/extensions/builtin/mcp/request-origin.js +59 -0
- package/dist/core/extensions/builtin/mcp/resources.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/resources.js +19 -4
- package/dist/core/extensions/builtin/mcp/sdk.lazy.d.ts +3 -1
- package/dist/core/extensions/builtin/mcp/sdk.lazy.js +3 -1
- package/dist/core/extensions/builtin/mcp/service-register.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/service-register.js +3 -0
- package/dist/core/extensions/builtin/mcp/service-types.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/service.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/service.js +79 -4
- package/dist/core/extensions/builtin/mcp/shared-connection.js +36 -2
- package/dist/core/extensions/builtin/mcp/shared-lease.d.ts +1 -0
- package/dist/core/extensions/builtin/mcp/shared-lease.js +9 -0
- package/dist/core/extensions/builtin/mcp/transport-sdk.d.ts +3 -2
- package/dist/core/extensions/builtin/mcp/transport-sdk.js +56 -25
- package/dist/core/extensions/builtin/mcp/wrap.d.ts +7 -0
- package/dist/core/extensions/builtin/mcp/wrap.js +6 -0
- package/dist/core/extensions/runner.js +3 -2
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/lifecycle-ledger.d.ts +1 -0
- package/dist/core/lifecycle-ledger.js +7 -2
- package/dist/core/lifecycle-record.js +3 -0
- package/dist/core/lifecycle-session-binding.d.ts +11 -1
- package/dist/core/lifecycle-session-binding.js +29 -2
- package/dist/core/lifecycle-stop.d.ts +41 -0
- package/dist/core/lifecycle-stop.js +92 -0
- package/dist/core/mcp-form-types.d.ts +89 -0
- package/dist/core/mcp-form-types.js +23 -0
- package/dist/core/mcp-mrtr-presentations.d.ts +15 -0
- package/dist/core/mcp-mrtr-presentations.js +17 -0
- package/dist/core/session-control-actions.js +0 -2
- package/dist/core/session-lifecycle-types.d.ts +15 -0
- package/dist/core/session-lifecycle.d.ts +17 -1
- package/dist/core/session-lifecycle.js +40 -2
- package/dist/main.js +5 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +1 -0
- package/dist/modes/interactive/components/extension-selector.js +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.js +34 -8
- package/dist/modes/interactive/mcp-local-presenter.d.ts +5 -0
- package/dist/modes/interactive/mcp-local-presenter.js +109 -0
- package/dist/modes/interactive/session-control-attach.d.ts +20 -0
- package/dist/modes/interactive/session-control-attach.js +13 -0
- package/dist/modes/interactive/session-control-commands.js +16 -6
- package/dist/modes/interactive/session-control-registry.d.ts +2 -1
- package/dist/modes/interactive/session-control-registry.js +3 -2
- package/dist/modes/interactive/session-control-rpc-commands.d.ts +4 -2
- package/dist/modes/interactive/session-control-rpc-commands.js +114 -4
- package/dist/modes/interactive/session-control-server.js +9 -3
- package/dist/modes/rpc/connection-handler.d.ts +1 -0
- package/dist/modes/rpc/connection-handler.js +13 -41
- package/dist/modes/rpc/custom-capability.d.ts +6 -0
- package/dist/modes/rpc/custom-capability.js +6 -0
- package/dist/modes/rpc/get-entries-command.d.ts +13 -0
- package/dist/modes/rpc/get-entries-command.js +61 -0
- package/dist/modes/rpc/get-entries-page.d.ts +22 -0
- package/dist/modes/rpc/get-entries-page.js +41 -2
- package/dist/modes/rpc/host-capabilities.d.ts +1 -0
- package/dist/modes/rpc/host-capabilities.js +6 -2
- package/dist/modes/rpc/host-ensure-start.js +13 -2
- package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
- package/dist/modes/rpc/host-ensure.js +1 -0
- package/dist/modes/rpc/host-handoff.d.ts +2 -0
- package/dist/modes/rpc/host-handover-wire.d.ts +2 -0
- package/dist/modes/rpc/host-handover-wire.js +1 -0
- package/dist/modes/rpc/host-lifecycle-launch.d.ts +1 -0
- package/dist/modes/rpc/host-lifecycle-launch.js +43 -2
- package/dist/modes/rpc/host-observe-request.d.ts +2 -1
- package/dist/modes/rpc/host-observe-request.js +4 -1
- package/dist/modes/rpc/host-runner.d.ts +2 -0
- package/dist/modes/rpc/host-runner.js +8 -6
- package/dist/modes/rpc/host-successor.js +11 -1
- package/dist/modes/rpc/mcp-form-dialog.d.ts +45 -0
- package/dist/modes/rpc/mcp-form-dialog.js +159 -0
- package/dist/modes/rpc/mcp-form-worker.d.ts +14 -0
- package/dist/modes/rpc/mcp-form-worker.js +167 -0
- package/dist/modes/rpc/mcp-presenter-authority.d.ts +53 -0
- package/dist/modes/rpc/mcp-presenter-authority.js +309 -0
- package/dist/modes/rpc/mcp-presenter-bootstrap.d.ts +8 -0
- package/dist/modes/rpc/mcp-presenter-bootstrap.js +111 -0
- package/dist/modes/rpc/mcp-presenter-control.d.ts +24 -0
- package/dist/modes/rpc/mcp-presenter-control.js +330 -0
- package/dist/modes/rpc/multi-session-host.d.ts +3 -0
- package/dist/modes/rpc/multi-session-host.js +36 -1
- package/dist/modes/rpc/rpc-read-response-types.d.ts +2 -0
- package/dist/modes/rpc/rpc-session-command-types.d.ts +8 -1
- package/dist/modes/rpc/session-binding.js +6 -1
- package/dist/modes/rpc/session-event-writer.d.ts +14 -0
- package/dist/modes/rpc/session-event-writer.js +128 -1
- package/dist/modes/rpc/session-router-routing.js +1 -0
- package/dist/modes/rpc/session-worker-client.d.ts +3 -0
- package/dist/modes/rpc/session-worker-client.js +89 -0
- package/dist/modes/rpc/session-worker-protocol.d.ts +41 -0
- package/dist/modes/rpc/session-worker.js +9 -0
- package/docs/extensions.md +5 -0
- package/docs/mcp.md +20 -3
- package/docs/rpc.md +151 -8
- package/package.json +6 -6
- package/dist/bundle/chunks/chunk-3LNSLJ7N.js +0 -2
- package/dist/bundle/chunks/chunk-B6TPQDBW.js +0 -5
- package/dist/bundle/chunks/chunk-CDRFFHLL.js +0 -4
- package/dist/bundle/chunks/chunk-HPCS4HM4.js +0 -27
- package/dist/bundle/chunks/chunk-KJZAY5YH.js +0 -27
- package/dist/bundle/chunks/chunk-MSQCTH6V.js +0 -2
- package/dist/bundle/chunks/chunk-OI4NMCKP.js +0 -3
- package/dist/bundle/chunks/chunk-SCVRKIFK.js +0 -2
- package/dist/bundle/chunks/cli-main-SWKFMTZQ.js +0 -3
- package/dist/bundle/chunks/dispatch-DEP4PEDZ.js +0 -10
- package/dist/bundle/chunks/host-command-BC6UWP33.js +0 -2
- package/dist/bundle/chunks/host-lifecycle-TN5NEGNF.js +0 -3
- package/dist/bundle/chunks/host-session-command-MGVBLBRV.js +0 -20
- package/dist/bundle/chunks/interactive-mode-SCSROHD5.js +0 -2
- package/dist/bundle/chunks/rotation-stream-U7YQMC7H.js +0 -2
- package/dist/bundle/chunks/rpc-mode-TOXYD4XA.js +0 -2
- package/dist/bundle/chunks/session-control-endpoint-HFFMBALG.js +0 -3
- package/dist/bundle/chunks/session-picker-465FVXQG.js +0 -2
|
@@ -37,9 +37,9 @@ import { hostRequestKeyRoot } from "./host-request-key-root.js";
|
|
|
37
37
|
import { withRpcKeyRoot } from "./rpc-auth-client.js";
|
|
38
38
|
const PROBE_TIMEOUT_MS = 10_000;
|
|
39
39
|
export async function runHostRequest(request, options = {}) {
|
|
40
|
-
return withRpcKeyRoot(hostRequestKeyRoot(request, options.keyRoot), () => runHostRequestInKeyRoot(request));
|
|
40
|
+
return withRpcKeyRoot(hostRequestKeyRoot(request, options.keyRoot), () => runHostRequestInKeyRoot(request, options.presenterBootstrap));
|
|
41
41
|
}
|
|
42
|
-
async function runHostRequestInKeyRoot(request) {
|
|
42
|
+
async function runHostRequestInKeyRoot(request, presenterBootstrap) {
|
|
43
43
|
if (request.action === "ensure" || request.action === "handoff" || request.action === "stop") {
|
|
44
44
|
const { socket, agentDir } = request.target;
|
|
45
45
|
if ((await endpointKindOfSocket(socket, agentDir)) === "tui") {
|
|
@@ -48,7 +48,7 @@ async function runHostRequestInKeyRoot(request) {
|
|
|
48
48
|
}
|
|
49
49
|
switch (request.action) {
|
|
50
50
|
case "ensure":
|
|
51
|
-
return ensureOutcome(request.target, request.spec, request.policy);
|
|
51
|
+
return ensureOutcome(request.target, request.spec, request.policy, presenterBootstrap);
|
|
52
52
|
case "status":
|
|
53
53
|
return request.all === true
|
|
54
54
|
? statusAllOutcome(request.target, request.includeWorkers)
|
|
@@ -57,7 +57,7 @@ async function runHostRequestInKeyRoot(request) {
|
|
|
57
57
|
return stopOutcome(request);
|
|
58
58
|
case "handoff":
|
|
59
59
|
return request.handover === undefined
|
|
60
|
-
? handoffOutcome(request.target, request.spec)
|
|
60
|
+
? handoffOutcome(request.target, request.spec, presenterBootstrap)
|
|
61
61
|
: idleHandoverOutcome(request.target, request.spec, request.handover);
|
|
62
62
|
case "shard_path":
|
|
63
63
|
return shardPathOutcome(request.kind, request.owner, request.root);
|
|
@@ -70,7 +70,7 @@ async function runHostRequestInKeyRoot(request) {
|
|
|
70
70
|
return assertNever(request);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
async function ensureOutcome(target, spec, policy) {
|
|
73
|
+
async function ensureOutcome(target, spec, policy, presenterBootstrap) {
|
|
74
74
|
const before = await probeProtocolInfo(target.socket, PROBE_TIMEOUT_MS);
|
|
75
75
|
if (policy === "fallback") {
|
|
76
76
|
// `fallback` is the caller saying it can live without a host. The decision is made HERE
|
|
@@ -84,6 +84,7 @@ async function ensureOutcome(target, spec, policy) {
|
|
|
84
84
|
try {
|
|
85
85
|
ensured = await ensureHost({
|
|
86
86
|
socket: target.socket,
|
|
87
|
+
presenterBootstrap,
|
|
87
88
|
agentDir: target.agentDir,
|
|
88
89
|
hostArgs: spec.hostArgs,
|
|
89
90
|
env: daemonEnvOverrides(process.env, spec.env),
|
|
@@ -181,10 +182,11 @@ async function stopOutcome(request) {
|
|
|
181
182
|
},
|
|
182
183
|
};
|
|
183
184
|
}
|
|
184
|
-
async function handoffOutcome(target, spec) {
|
|
185
|
+
async function handoffOutcome(target, spec, presenterBootstrap) {
|
|
185
186
|
const before = await probeProtocolInfo(target.socket, PROBE_TIMEOUT_MS);
|
|
186
187
|
const result = await handoffHost({
|
|
187
188
|
socket: target.socket,
|
|
189
|
+
presenterBootstrap,
|
|
188
190
|
agentDir: target.agentDir,
|
|
189
191
|
hostArgs: spec.hostArgs,
|
|
190
192
|
env: daemonEnvOverrides(process.env, spec.env),
|
|
@@ -28,6 +28,7 @@ import { defaultHostLaunch, PINNED_HOST_CLIENT_CAPABILITIES } from "./host-launc
|
|
|
28
28
|
import { DEFAULT_HOST_IDLE_EXIT_MS } from "./host-lifecycle.js";
|
|
29
29
|
import { keepOwnerPipe, OWNER_WATCH_FD } from "./host-lifecycle-launch.js";
|
|
30
30
|
import { probeProtocolInfo } from "./host-probe.js";
|
|
31
|
+
import { relayPresenterBootstrap } from "./mcp-presenter-bootstrap.js";
|
|
31
32
|
import { successorHostEnvironment } from "./host-spawn-environment.js";
|
|
32
33
|
import { signalGeneration } from "./host-stop.js";
|
|
33
34
|
import { hostLaunchProfile } from "./protocol-identity.js";
|
|
@@ -81,6 +82,7 @@ export async function startSuccessor(context) {
|
|
|
81
82
|
"--replace",
|
|
82
83
|
`${replaced.dev}:${replaced.ino}`,
|
|
83
84
|
...(inheritOwnerPipe ? ["--owner-fd", String(OWNER_WATCH_FD)] : []),
|
|
85
|
+
...(options.presenterBootstrap ? ["--mcp-presenter-fd", "4"] : []),
|
|
84
86
|
...(options.hostArgs ?? []),
|
|
85
87
|
];
|
|
86
88
|
const launch = (options._test?.launch ?? options.launch)?.(argv) ?? defaultHostLaunch(argv);
|
|
@@ -96,8 +98,15 @@ export async function startSuccessor(context) {
|
|
|
96
98
|
generation,
|
|
97
99
|
instanceId,
|
|
98
100
|
}),
|
|
99
|
-
stdio:
|
|
101
|
+
stdio: options.presenterBootstrap
|
|
102
|
+
? ["ignore", "ignore", stderr.fd, inheritOwnerPipe ? "pipe" : "ignore", "pipe"]
|
|
103
|
+
: inheritOwnerPipe
|
|
104
|
+
? ["ignore", "ignore", stderr.fd, "pipe"]
|
|
105
|
+
: ["ignore", "ignore", stderr.fd],
|
|
100
106
|
});
|
|
107
|
+
const presenterEnrollment = options.presenterBootstrap
|
|
108
|
+
? relayPresenterBootstrap(options.presenterBootstrap, spawned)
|
|
109
|
+
: undefined;
|
|
101
110
|
child = spawned;
|
|
102
111
|
exited = new Promise((resolve) => spawned.once("exit", () => resolve()));
|
|
103
112
|
await stderr.close();
|
|
@@ -135,6 +144,7 @@ export async function startSuccessor(context) {
|
|
|
135
144
|
// clients reach is still the predecessor, and the pointer has to name whoever owns the socket.
|
|
136
145
|
await options._test?.beforeRegistration?.();
|
|
137
146
|
await writeHostRegistration(paths, { ...registration, ...successorBuild(answer) });
|
|
147
|
+
await presenterEnrollment;
|
|
138
148
|
child.unref();
|
|
139
149
|
// The successor owns the socket now: the predecessor may drain. SIGUSR1 is sent only here,
|
|
140
150
|
// to a pid the record proved and a host that advertised it can survive the signal. A
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { McpFormInput, McpFormOutcome, McpFormRequest, McpFormResolved } from "../../core/mcp-form-types.ts";
|
|
2
|
+
export interface McpFormClock {
|
|
3
|
+
now(): number;
|
|
4
|
+
schedule(callback: () => void, delay: number): object;
|
|
5
|
+
cancel(timer: object): void;
|
|
6
|
+
}
|
|
7
|
+
export declare const mcpFormClock: McpFormClock;
|
|
8
|
+
type Termination = "presentation_lost" | "presentation_timeout" | "operation_aborted";
|
|
9
|
+
export type McpPresenterReply = {
|
|
10
|
+
readonly ok: true;
|
|
11
|
+
readonly form?: McpFormRequest;
|
|
12
|
+
} | {
|
|
13
|
+
readonly error: "presenter_not_authorized" | "invalid_form_response" | "form_stale" | "form_expired";
|
|
14
|
+
};
|
|
15
|
+
/** One private entry. Lifecycle closures retain this object even after its grant is removed. */
|
|
16
|
+
export declare class McpFormDialog {
|
|
17
|
+
readonly result: Promise<McpFormOutcome>;
|
|
18
|
+
readonly deadline: number;
|
|
19
|
+
private stage;
|
|
20
|
+
private request;
|
|
21
|
+
private readonly token;
|
|
22
|
+
private readonly cleanups;
|
|
23
|
+
private resolve;
|
|
24
|
+
private readonly input;
|
|
25
|
+
private readonly context;
|
|
26
|
+
constructor(input: McpFormInput, context: {
|
|
27
|
+
readonly clock: McpFormClock;
|
|
28
|
+
readonly envelope: Omit<McpFormRequest, "type" | "server" | "message" | "schema" | "deadlineAtMs" | "dialogToken">;
|
|
29
|
+
readonly current: () => boolean;
|
|
30
|
+
readonly remove: () => void;
|
|
31
|
+
readonly admit: () => void;
|
|
32
|
+
readonly send: (frame: McpFormRequest | McpFormResolved) => boolean;
|
|
33
|
+
});
|
|
34
|
+
start(): void;
|
|
35
|
+
sync(): McpFormRequest | undefined;
|
|
36
|
+
matches(token: string, revision: string): boolean;
|
|
37
|
+
presented(): McpPresenterReply;
|
|
38
|
+
respond(action: string, content: unknown): McpPresenterReply;
|
|
39
|
+
/** Internal-only: never called with a cause or entry reference decoded from RPC. */
|
|
40
|
+
terminate(cause: Termination): void;
|
|
41
|
+
private live;
|
|
42
|
+
private commit;
|
|
43
|
+
}
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=mcp-form-dialog.d.ts.map
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { validMcpFormContent } from "../../core/extensions/builtin/mcp/modern/form-schema.js";
|
|
3
|
+
export const mcpFormClock = {
|
|
4
|
+
now: () => performance.now(),
|
|
5
|
+
schedule: (callback, delay) => setTimeout(callback, delay),
|
|
6
|
+
cancel: (timer) => {
|
|
7
|
+
if ("close" in timer && typeof timer.close === "function")
|
|
8
|
+
timer.close();
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
/** One private entry. Lifecycle closures retain this object even after its grant is removed. */
|
|
12
|
+
export class McpFormDialog {
|
|
13
|
+
constructor(input, context) {
|
|
14
|
+
this.stage = "prepared";
|
|
15
|
+
this.token = randomBytes(32);
|
|
16
|
+
this.cleanups = [];
|
|
17
|
+
this.resolve = () => { };
|
|
18
|
+
this.input = input;
|
|
19
|
+
this.context = context;
|
|
20
|
+
this.deadline = context.clock.now() + Math.max(0, input.deadlineMs);
|
|
21
|
+
this.result = new Promise((resolve) => {
|
|
22
|
+
this.resolve = resolve;
|
|
23
|
+
});
|
|
24
|
+
this.request = {
|
|
25
|
+
...context.envelope,
|
|
26
|
+
type: "mcp_form_request",
|
|
27
|
+
dialogToken: this.token.toString("hex"),
|
|
28
|
+
server: structuredClone(input.server),
|
|
29
|
+
message: input.message,
|
|
30
|
+
schema: structuredClone(input.schema),
|
|
31
|
+
deadlineAtMs: Date.now() + Math.max(0, input.deadlineMs),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
start() {
|
|
35
|
+
const watch = (signal, cause) => {
|
|
36
|
+
const stop = () => this.terminate(cause);
|
|
37
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
38
|
+
this.cleanups.push(() => signal.removeEventListener("abort", stop));
|
|
39
|
+
if (signal.aborted)
|
|
40
|
+
stop();
|
|
41
|
+
};
|
|
42
|
+
watch(this.input.operationSignal, "operation_aborted");
|
|
43
|
+
watch(this.input.presentationSignal, "presentation_lost");
|
|
44
|
+
if (this.stage === "settled") {
|
|
45
|
+
for (const cleanup of this.cleanups.splice(0))
|
|
46
|
+
cleanup();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const timer = this.context.clock.schedule(() => this.terminate("presentation_timeout"), this.input.deadlineMs);
|
|
50
|
+
this.cleanups.push(() => this.context.clock.cancel(timer));
|
|
51
|
+
if (!this.context.current() || !this.request || !this.context.send(this.request))
|
|
52
|
+
this.terminate("presentation_lost");
|
|
53
|
+
}
|
|
54
|
+
sync() {
|
|
55
|
+
if (!this.live())
|
|
56
|
+
return undefined;
|
|
57
|
+
return this.request === undefined ? undefined : structuredClone(this.request);
|
|
58
|
+
}
|
|
59
|
+
matches(token, revision) {
|
|
60
|
+
return (this.request?.formRevision === revision &&
|
|
61
|
+
/^[a-f0-9]{64}$/.test(token) &&
|
|
62
|
+
timingSafeEqual(this.token, Buffer.from(token, "hex")));
|
|
63
|
+
}
|
|
64
|
+
presented() {
|
|
65
|
+
if (!this.live())
|
|
66
|
+
return { error: "form_expired" };
|
|
67
|
+
this.stage = "presented";
|
|
68
|
+
return { ok: true };
|
|
69
|
+
}
|
|
70
|
+
respond(action, content) {
|
|
71
|
+
if (!this.live())
|
|
72
|
+
return { error: "form_expired" };
|
|
73
|
+
if (this.stage !== "presented" || !this.request)
|
|
74
|
+
return { error: "invalid_form_response" };
|
|
75
|
+
let result;
|
|
76
|
+
switch (action) {
|
|
77
|
+
case "accept":
|
|
78
|
+
if (!validMcpFormContent(this.request.schema, content) ||
|
|
79
|
+
Buffer.byteLength(JSON.stringify(content)) > 1024 * 1024)
|
|
80
|
+
return { error: "invalid_form_response" };
|
|
81
|
+
result = { action, content: structuredClone(content) };
|
|
82
|
+
break;
|
|
83
|
+
case "decline":
|
|
84
|
+
case "cancel":
|
|
85
|
+
if (content !== undefined)
|
|
86
|
+
return { error: "invalid_form_response" };
|
|
87
|
+
result = { action };
|
|
88
|
+
break;
|
|
89
|
+
default:
|
|
90
|
+
return { error: "invalid_form_response" };
|
|
91
|
+
}
|
|
92
|
+
if (!this.live())
|
|
93
|
+
return { error: "form_expired" };
|
|
94
|
+
this.commit({ kind: "result", result, source: "presenter_action", humanAdmission: true });
|
|
95
|
+
return { ok: true };
|
|
96
|
+
}
|
|
97
|
+
/** Internal-only: never called with a cause or entry reference decoded from RPC. */
|
|
98
|
+
terminate(cause) {
|
|
99
|
+
const provenance = { source: "host_termination", humanAdmission: false };
|
|
100
|
+
if (cause === "operation_aborted" ||
|
|
101
|
+
this.input.operationSignal.aborted ||
|
|
102
|
+
this.input.operationCurrent?.() === false) {
|
|
103
|
+
this.commit({ kind: "operation_aborted", ...provenance });
|
|
104
|
+
}
|
|
105
|
+
else if (this.stage === "presented") {
|
|
106
|
+
this.commit({ kind: "result", result: { action: "cancel" }, ...provenance });
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
this.commit({ kind: "processing_failure", ...provenance });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
live() {
|
|
113
|
+
if (this.stage === "settled")
|
|
114
|
+
return false;
|
|
115
|
+
if (this.input.operationSignal.aborted || this.input.operationCurrent?.() === false) {
|
|
116
|
+
this.terminate("operation_aborted");
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (this.context.clock.now() >= this.deadline || !this.context.current()) {
|
|
120
|
+
this.terminate("presentation_timeout");
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
commit(outcome) {
|
|
126
|
+
if (this.stage === "settled")
|
|
127
|
+
return;
|
|
128
|
+
this.stage = "settled";
|
|
129
|
+
const request = this.request;
|
|
130
|
+
this.request = undefined;
|
|
131
|
+
this.token.fill(0);
|
|
132
|
+
this.context.remove();
|
|
133
|
+
for (const cleanup of this.cleanups.splice(0))
|
|
134
|
+
cleanup();
|
|
135
|
+
// No callback, promise resolution or admission precedes the synchronous terminal claim.
|
|
136
|
+
if (outcome.humanAdmission)
|
|
137
|
+
this.context.admit();
|
|
138
|
+
this.resolve(outcome);
|
|
139
|
+
if (request && this.context.current()) {
|
|
140
|
+
const reason = outcome.kind === "result"
|
|
141
|
+
? outcome.result.action === "accept"
|
|
142
|
+
? "answered"
|
|
143
|
+
: outcome.result.action === "decline"
|
|
144
|
+
? "declined"
|
|
145
|
+
: "cancelled"
|
|
146
|
+
: outcome.kind === "operation_aborted"
|
|
147
|
+
? "operation_aborted"
|
|
148
|
+
: "processing_failed";
|
|
149
|
+
this.context.send({
|
|
150
|
+
type: "mcp_form_resolved",
|
|
151
|
+
sessionId: request.sessionId,
|
|
152
|
+
grantId: request.grantId,
|
|
153
|
+
dialogId: request.dialogId,
|
|
154
|
+
reason,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=mcp-form-dialog.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HostToSessionWorker, SessionWorkerToHost } from "./session-worker-protocol.ts";
|
|
2
|
+
/** Private worker messages never pass through WorkerEventWriter.enqueue or a snapshot. */
|
|
3
|
+
export declare class McpFormWorker {
|
|
4
|
+
private readonly send;
|
|
5
|
+
private readonly binds;
|
|
6
|
+
private readonly ready;
|
|
7
|
+
private readonly settlements;
|
|
8
|
+
private readonly bindings;
|
|
9
|
+
private readonly entries;
|
|
10
|
+
constructor(send: (message: SessionWorkerToHost) => void);
|
|
11
|
+
bind(durableId: string, ui: object, admit: () => void): Promise<() => void>;
|
|
12
|
+
receive(message: HostToSessionWorker): boolean;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=mcp-form-worker.d.ts.map
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { bindPrivateMcpForms } from "../../core/mcp-form-types.js";
|
|
3
|
+
/** Private worker messages never pass through WorkerEventWriter.enqueue or a snapshot. */
|
|
4
|
+
export class McpFormWorker {
|
|
5
|
+
constructor(send) {
|
|
6
|
+
this.binds = new Map();
|
|
7
|
+
this.ready = new Map();
|
|
8
|
+
this.settlements = new Set();
|
|
9
|
+
this.bindings = new Map();
|
|
10
|
+
this.entries = new Map();
|
|
11
|
+
this.send = send;
|
|
12
|
+
}
|
|
13
|
+
async bind(durableId, ui, admit) {
|
|
14
|
+
const id = randomUUID();
|
|
15
|
+
const bound = Promise.withResolvers();
|
|
16
|
+
this.binds.set(id, bound.resolve);
|
|
17
|
+
const timer = setTimeout(() => bound.reject(new Error("private_form_unavailable")), 5_000);
|
|
18
|
+
timer.unref();
|
|
19
|
+
let message;
|
|
20
|
+
try {
|
|
21
|
+
this.send({ type: "mcp_form_bind", id, durableId });
|
|
22
|
+
message = await bound.promise;
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
this.binds.delete(id);
|
|
27
|
+
}
|
|
28
|
+
const lifetime = new AbortController();
|
|
29
|
+
const state = { version: message.version, active: true, admit, listeners: new Set() };
|
|
30
|
+
this.bindings.set(message.epoch, state);
|
|
31
|
+
const binding = {
|
|
32
|
+
epoch: message.epoch,
|
|
33
|
+
signal: lifetime.signal,
|
|
34
|
+
subscribe: (listener) => {
|
|
35
|
+
state.listeners.add(listener);
|
|
36
|
+
return () => {
|
|
37
|
+
state.listeners.delete(listener);
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
capture: () => {
|
|
41
|
+
const version = state.version;
|
|
42
|
+
if (!state.active || version === undefined)
|
|
43
|
+
return undefined;
|
|
44
|
+
return {
|
|
45
|
+
signal: new AbortController().signal,
|
|
46
|
+
ready: () => state.active && state.version === version,
|
|
47
|
+
synchronize: () => {
|
|
48
|
+
const request = randomUUID();
|
|
49
|
+
const answer = new Promise((resolve) => this.ready.set(request, resolve));
|
|
50
|
+
this.send({ type: "mcp_form_ready", id: request, epoch: message.epoch });
|
|
51
|
+
return answer;
|
|
52
|
+
},
|
|
53
|
+
present: (input) => new Promise((resolve) => {
|
|
54
|
+
const request = randomUUID();
|
|
55
|
+
const operationFence = new SharedArrayBuffer(4);
|
|
56
|
+
const fence = new Int32Array(operationFence);
|
|
57
|
+
const cancelOperation = () => {
|
|
58
|
+
Atomics.store(fence, 0, 1);
|
|
59
|
+
this.send({
|
|
60
|
+
type: "mcp_form_cancel",
|
|
61
|
+
id: request,
|
|
62
|
+
epoch: message.epoch,
|
|
63
|
+
lifetime: "operation",
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
const cancelPresentation = () => this.send({
|
|
67
|
+
type: "mcp_form_cancel",
|
|
68
|
+
id: request,
|
|
69
|
+
epoch: message.epoch,
|
|
70
|
+
lifetime: "presentation",
|
|
71
|
+
});
|
|
72
|
+
input.operationSignal.addEventListener("abort", cancelOperation, { once: true });
|
|
73
|
+
input.presentationSignal.addEventListener("abort", cancelPresentation, { once: true });
|
|
74
|
+
this.entries.set(request, {
|
|
75
|
+
epoch: message.epoch,
|
|
76
|
+
resolve,
|
|
77
|
+
fence,
|
|
78
|
+
cleanup: () => {
|
|
79
|
+
input.operationSignal.removeEventListener("abort", cancelOperation);
|
|
80
|
+
input.presentationSignal.removeEventListener("abort", cancelPresentation);
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
const { operationSignal, presentationSignal, operationCurrent: _current, ...wire } = input;
|
|
84
|
+
if (operationSignal.aborted)
|
|
85
|
+
Atomics.store(fence, 0, 1);
|
|
86
|
+
this.send({
|
|
87
|
+
type: "mcp_form_create",
|
|
88
|
+
id: request,
|
|
89
|
+
epoch: message.epoch,
|
|
90
|
+
version,
|
|
91
|
+
operationFence,
|
|
92
|
+
input: wire,
|
|
93
|
+
});
|
|
94
|
+
if (operationSignal.aborted)
|
|
95
|
+
cancelOperation();
|
|
96
|
+
if (presentationSignal.aborted)
|
|
97
|
+
cancelPresentation();
|
|
98
|
+
}),
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
dispose: () => {
|
|
102
|
+
lifetime.abort();
|
|
103
|
+
state.active = false;
|
|
104
|
+
for (const entry of this.entries.values())
|
|
105
|
+
if (entry.epoch === message.epoch)
|
|
106
|
+
Atomics.store(entry.fence, 0, 1);
|
|
107
|
+
this.bindings.delete(message.epoch);
|
|
108
|
+
state.listeners.clear();
|
|
109
|
+
this.send({ type: "mcp_form_release", epoch: message.epoch });
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
bindPrivateMcpForms(ui, binding);
|
|
113
|
+
return binding.dispose;
|
|
114
|
+
}
|
|
115
|
+
receive(message) {
|
|
116
|
+
switch (message.type) {
|
|
117
|
+
case "mcp_form_bound": {
|
|
118
|
+
const resolve = this.binds.get(message.id);
|
|
119
|
+
if (resolve)
|
|
120
|
+
resolve(message);
|
|
121
|
+
else
|
|
122
|
+
this.send({ type: "mcp_form_release", epoch: message.epoch });
|
|
123
|
+
this.binds.delete(message.id);
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
case "mcp_form_availability": {
|
|
127
|
+
const binding = this.bindings.get(message.epoch);
|
|
128
|
+
if (binding && binding.version !== message.version) {
|
|
129
|
+
binding.version = message.version;
|
|
130
|
+
for (const listener of binding.listeners)
|
|
131
|
+
listener();
|
|
132
|
+
}
|
|
133
|
+
if (message.id) {
|
|
134
|
+
this.ready.get(message.id)?.();
|
|
135
|
+
this.ready.delete(message.id);
|
|
136
|
+
}
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
case "mcp_form_settlement": {
|
|
140
|
+
const entry = this.entries.get(message.id);
|
|
141
|
+
if (!entry || entry.epoch !== message.epoch || this.settlements.has(message.settlementId))
|
|
142
|
+
return true;
|
|
143
|
+
this.settlements.add(message.settlementId);
|
|
144
|
+
if (this.settlements.size > 256) {
|
|
145
|
+
const oldest = this.settlements.values().next().value;
|
|
146
|
+
if (oldest !== undefined)
|
|
147
|
+
this.settlements.delete(oldest);
|
|
148
|
+
}
|
|
149
|
+
this.entries.delete(message.id);
|
|
150
|
+
entry.cleanup();
|
|
151
|
+
const binding = this.bindings.get(message.epoch);
|
|
152
|
+
if (!binding?.active) {
|
|
153
|
+
entry.resolve({ kind: "operation_aborted", source: "host_termination", humanAdmission: false });
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
// Host-only union provenance, never inferred from cancel/decline/accept alone.
|
|
157
|
+
if (message.outcome.source === "presenter_action" && message.outcome.humanAdmission)
|
|
158
|
+
binding.admit();
|
|
159
|
+
entry.resolve(message.outcome);
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
default:
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=mcp-form-worker.js.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { McpFormBinding, McpFormRequest, McpFormResolved, McpFormScope } from "../../core/mcp-form-types.ts";
|
|
2
|
+
import { type McpFormClock, type McpPresenterReply } from "./mcp-form-dialog.ts";
|
|
3
|
+
type Sender = (frame: McpFormRequest | McpFormResolved) => boolean;
|
|
4
|
+
export interface McpPresenterConnection {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly epoch: string;
|
|
7
|
+
readonly nonce: string;
|
|
8
|
+
}
|
|
9
|
+
export interface McpPresenterRegistration {
|
|
10
|
+
readonly id: string;
|
|
11
|
+
}
|
|
12
|
+
/** Host-owned only. No public session command can call enrollment or install a registration. */
|
|
13
|
+
export declare class McpPresenterAuthority {
|
|
14
|
+
readonly instance: `${string}-${string}-${string}-${string}-${string}`;
|
|
15
|
+
private readonly clock;
|
|
16
|
+
private readonly connections;
|
|
17
|
+
private readonly bindings;
|
|
18
|
+
private readonly registrations;
|
|
19
|
+
constructor(options?: {
|
|
20
|
+
readonly clock?: McpFormClock;
|
|
21
|
+
});
|
|
22
|
+
dispose(): void;
|
|
23
|
+
connect(id: string, send: Sender): McpPresenterConnection;
|
|
24
|
+
attach(sender: McpPresenterConnection, handle: McpFormBinding): void;
|
|
25
|
+
connectionContext(sender: McpPresenterConnection, sessionId: string): {
|
|
26
|
+
hostInstance: string;
|
|
27
|
+
connectionNonce: string;
|
|
28
|
+
bindingEpoch: string;
|
|
29
|
+
attachmentId: string;
|
|
30
|
+
attachmentEpoch: string;
|
|
31
|
+
} | undefined;
|
|
32
|
+
detach(sender: McpPresenterConnection, handle?: McpFormBinding): void;
|
|
33
|
+
withdraw(sender: McpPresenterConnection): void;
|
|
34
|
+
bind(sessionId: string, durableId: string, admit: () => void): McpFormBinding;
|
|
35
|
+
/** Called only after the protected bootstrap has pinned and authenticated its launch principal. */
|
|
36
|
+
enroll(principal?: string): {
|
|
37
|
+
register: (handle: McpFormBinding, sender: McpPresenterConnection, options: {
|
|
38
|
+
readonly kind: McpFormScope["presenterKind"];
|
|
39
|
+
}) => McpPresenterRegistration;
|
|
40
|
+
acquire: (handle: McpPresenterRegistration) => {
|
|
41
|
+
readonly grantId: string;
|
|
42
|
+
readonly scope: McpFormScope;
|
|
43
|
+
};
|
|
44
|
+
revoke: (handle: McpPresenterRegistration) => void;
|
|
45
|
+
};
|
|
46
|
+
receive(sender: McpPresenterConnection, value: unknown): McpPresenterReply;
|
|
47
|
+
private current;
|
|
48
|
+
private revoke;
|
|
49
|
+
private presentation;
|
|
50
|
+
private present;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=mcp-presenter-authority.d.ts.map
|