@4xeoz/re-entry 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +337 -0
- package/node_modules/@webmcp-challenge/reentry-core/README.md +112 -0
- package/node_modules/@webmcp-challenge/reentry-core/package.json +38 -0
- package/node_modules/@webmcp-challenge/reentry-core/protocol/test-vectors/v0.1.json +47 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/agent-adapter.mjs +438 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/cloud-receiver-http.mjs +268 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/host-sdk.mjs +278 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/index.mjs +3 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/local-connector-client.mjs +530 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/managed-context-adapter.mjs +275 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/protocol.mjs +845 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/receiver-core.mjs +867 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/receiver-delivery.mjs +613 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/receiver-http-contract.mjs +24 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/receiver-support.mjs +151 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/sqlite-receiver-schema.mjs +184 -0
- package/node_modules/@webmcp-challenge/reentry-core/src/sqlite-receiver-store.mjs +573 -0
- package/package.json +44 -0
- package/src/browser-prompt.mjs +18 -0
- package/src/codex-discovery.mjs +246 -0
- package/src/codex-exec-adapter.mjs +197 -0
- package/src/codex-queue-adapter.mjs +214 -0
- package/src/credentials.mjs +87 -0
- package/src/index.mjs +6 -0
- package/src/local-connector.mjs +82 -0
- package/src/macos-service.mjs +184 -0
- package/src/main.mjs +733 -0
- package/src/pairing-client.mjs +545 -0
- package/src/terminal-ui.mjs +99 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AGENT_ACTIVATION_RESULT_TYPE,
|
|
3
|
+
validateAgentActivation,
|
|
4
|
+
} from "./agent-adapter.mjs";
|
|
5
|
+
import { PROTOCOL_VERSION } from "./protocol.mjs";
|
|
6
|
+
|
|
7
|
+
export const MANAGED_CONTEXT_BINDING_TYPE = "webmcp.managed_context_binding";
|
|
8
|
+
|
|
9
|
+
const OPTION_FIELDS = Object.freeze([
|
|
10
|
+
"adapterId",
|
|
11
|
+
"bindingAuthority",
|
|
12
|
+
"activateBoundContext",
|
|
13
|
+
"clock",
|
|
14
|
+
]);
|
|
15
|
+
const BINDING_FIELDS = Object.freeze([
|
|
16
|
+
"type",
|
|
17
|
+
"protocol_version",
|
|
18
|
+
"grant_id",
|
|
19
|
+
"adapter_id",
|
|
20
|
+
"binding_ref",
|
|
21
|
+
"bound_at",
|
|
22
|
+
"expires_at",
|
|
23
|
+
]);
|
|
24
|
+
const RESOLUTION_FIELDS = Object.freeze(["grantId", "adapterId"]);
|
|
25
|
+
const DRIVER_FIELDS = Object.freeze(["activation", "bindingRef"]);
|
|
26
|
+
const IDENTIFIER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,159}$/;
|
|
27
|
+
const MAXIMUM_BINDING_REFERENCE_BYTES = 4 * 1_024;
|
|
28
|
+
const CONTROL_CHARACTER_PATTERN = /[\u0000-\u001f\u007f]/;
|
|
29
|
+
|
|
30
|
+
export class ManagedContextBindingError extends Error {
|
|
31
|
+
constructor(code, message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "ManagedContextBindingError";
|
|
34
|
+
this.code = code;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function createManagedContextAdapter(options) {
|
|
39
|
+
requireExactRecord(options, OPTION_FIELDS, "Managed-context adapter options");
|
|
40
|
+
const adapterId = requireIdentifier(options.adapterId, "Managed-context adapter identifier");
|
|
41
|
+
const resolveBinding = requireAuthority(options.bindingAuthority);
|
|
42
|
+
const activateBoundContext = requireFunction(
|
|
43
|
+
options.activateBoundContext,
|
|
44
|
+
"Managed-context activation driver",
|
|
45
|
+
);
|
|
46
|
+
const clock = requireFunction(options.clock, "Managed-context adapter clock");
|
|
47
|
+
|
|
48
|
+
return Object.freeze({
|
|
49
|
+
async activate(value) {
|
|
50
|
+
const activation = validateAgentActivation(value);
|
|
51
|
+
const now = readClock(clock);
|
|
52
|
+
assertActivationLive(activation, now);
|
|
53
|
+
const lookup = deepFreeze({
|
|
54
|
+
grantId: activation.receipt.grant_id,
|
|
55
|
+
adapterId,
|
|
56
|
+
});
|
|
57
|
+
requireExactRecord(lookup, RESOLUTION_FIELDS, "Managed-context binding lookup");
|
|
58
|
+
const rawBinding = await resolveBinding(lookup);
|
|
59
|
+
const resolutionTime = readClock(clock);
|
|
60
|
+
assertActivationLive(activation, resolutionTime);
|
|
61
|
+
if (rawBinding === null) {
|
|
62
|
+
return activationResult(
|
|
63
|
+
activation,
|
|
64
|
+
"unsupported",
|
|
65
|
+
"required_capability_unavailable",
|
|
66
|
+
"managed_context_resume",
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const binding = normalizeBinding(rawBinding, activation, adapterId, resolutionTime);
|
|
71
|
+
if (Date.parse(binding.expires_at) <= resolutionTime.getTime()) {
|
|
72
|
+
return activationResult(activation, "rejected", "activation_rejected", null);
|
|
73
|
+
}
|
|
74
|
+
if (Date.parse(binding.expires_at) < Date.parse(activation.lease_expires_at)) {
|
|
75
|
+
throw bindingError(
|
|
76
|
+
"managed_context_binding_scope_invalid",
|
|
77
|
+
"Managed-context binding expires before the activation lease",
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const driverInput = deepFreeze({
|
|
82
|
+
activation,
|
|
83
|
+
bindingRef: binding.binding_ref,
|
|
84
|
+
});
|
|
85
|
+
requireExactRecord(driverInput, DRIVER_FIELDS, "Managed-context driver input");
|
|
86
|
+
return activateBoundContext(driverInput);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function normalizeBinding(value, activation, adapterId, now) {
|
|
92
|
+
requireExactRecord(value, BINDING_FIELDS, "Managed-context binding");
|
|
93
|
+
if (
|
|
94
|
+
value.type !== MANAGED_CONTEXT_BINDING_TYPE ||
|
|
95
|
+
value.protocol_version !== PROTOCOL_VERSION
|
|
96
|
+
) {
|
|
97
|
+
throw bindingError(
|
|
98
|
+
"managed_context_binding_version_invalid",
|
|
99
|
+
"Managed-context binding version is unsupported",
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
const grantId = requireIdentifier(value.grant_id, "Managed-context binding Grant identifier");
|
|
103
|
+
const resolvedAdapterId = requireIdentifier(
|
|
104
|
+
value.adapter_id,
|
|
105
|
+
"Managed-context binding adapter identifier",
|
|
106
|
+
);
|
|
107
|
+
if (grantId !== activation.receipt.grant_id || resolvedAdapterId !== adapterId) {
|
|
108
|
+
throw bindingError(
|
|
109
|
+
"managed_context_binding_scope_invalid",
|
|
110
|
+
"Managed-context binding is outside the activation scope",
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
const boundAt = requireTimestamp(value.bound_at, "Managed-context binding time");
|
|
114
|
+
const expiresAt = requireTimestamp(value.expires_at, "Managed-context binding expiry");
|
|
115
|
+
if (
|
|
116
|
+
Date.parse(boundAt) > now.getTime() ||
|
|
117
|
+
Date.parse(expiresAt) <= Date.parse(boundAt) ||
|
|
118
|
+
Date.parse(expiresAt) > Date.parse(activation.receipt.expires_at)
|
|
119
|
+
) {
|
|
120
|
+
throw bindingError(
|
|
121
|
+
"managed_context_binding_time_invalid",
|
|
122
|
+
"Managed-context binding time is outside the Receipt authority",
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
return deepFreeze({
|
|
126
|
+
type: MANAGED_CONTEXT_BINDING_TYPE,
|
|
127
|
+
protocol_version: PROTOCOL_VERSION,
|
|
128
|
+
grant_id: grantId,
|
|
129
|
+
adapter_id: resolvedAdapterId,
|
|
130
|
+
binding_ref: requireBindingReference(value.binding_ref),
|
|
131
|
+
bound_at: boundAt,
|
|
132
|
+
expires_at: expiresAt,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function assertActivationLive(activation, now) {
|
|
137
|
+
if (
|
|
138
|
+
Date.parse(activation.lease_expires_at) <= now.getTime() ||
|
|
139
|
+
Date.parse(activation.receipt.expires_at) <= now.getTime()
|
|
140
|
+
) {
|
|
141
|
+
throw bindingError(
|
|
142
|
+
"managed_context_activation_expired",
|
|
143
|
+
"Managed-context activation authority has expired",
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function activationResult(activation, outcome, code, capability) {
|
|
149
|
+
return deepFreeze({
|
|
150
|
+
type: AGENT_ACTIVATION_RESULT_TYPE,
|
|
151
|
+
protocol_version: PROTOCOL_VERSION,
|
|
152
|
+
delivery_id: activation.delivery_id,
|
|
153
|
+
event_id: activation.event_id,
|
|
154
|
+
attempt: activation.attempt,
|
|
155
|
+
outcome,
|
|
156
|
+
code,
|
|
157
|
+
unavailable_capability: capability,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function requireAuthority(value) {
|
|
162
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
163
|
+
throw bindingError(
|
|
164
|
+
"managed_context_binding_authority_invalid",
|
|
165
|
+
"Managed-context binding authority must implement resolveBinding",
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, "resolveBinding");
|
|
169
|
+
if (!descriptor?.enumerable || !("value" in descriptor) || typeof descriptor.value !== "function") {
|
|
170
|
+
throw bindingError(
|
|
171
|
+
"managed_context_binding_authority_invalid",
|
|
172
|
+
"Managed-context binding authority must implement resolveBinding",
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
return descriptor.value.bind(value);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function requireFunction(value, label) {
|
|
179
|
+
if (typeof value !== "function") {
|
|
180
|
+
throw bindingError("managed_context_adapter_invalid", `${label} must be a function`);
|
|
181
|
+
}
|
|
182
|
+
return value;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function readClock(clock) {
|
|
186
|
+
const value = clock();
|
|
187
|
+
if (!(value instanceof Date) || !Number.isFinite(value.getTime())) {
|
|
188
|
+
throw bindingError(
|
|
189
|
+
"managed_context_binding_time_invalid",
|
|
190
|
+
"Managed-context adapter clock must return a valid Date",
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
return new Date(value.getTime());
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function requireIdentifier(value, label) {
|
|
197
|
+
if (
|
|
198
|
+
typeof value !== "string" ||
|
|
199
|
+
Buffer.byteLength(value, "utf8") > 160 ||
|
|
200
|
+
!IDENTIFIER_PATTERN.test(value)
|
|
201
|
+
) {
|
|
202
|
+
throw bindingError("managed_context_binding_identifier_invalid", `${label} is invalid`);
|
|
203
|
+
}
|
|
204
|
+
return value;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function requireBindingReference(value) {
|
|
208
|
+
if (
|
|
209
|
+
typeof value !== "string" ||
|
|
210
|
+
value.trim() !== value ||
|
|
211
|
+
value.length === 0 ||
|
|
212
|
+
Buffer.byteLength(value, "utf8") > MAXIMUM_BINDING_REFERENCE_BYTES ||
|
|
213
|
+
CONTROL_CHARACTER_PATTERN.test(value)
|
|
214
|
+
) {
|
|
215
|
+
throw bindingError(
|
|
216
|
+
"managed_context_binding_reference_invalid",
|
|
217
|
+
"Managed-context binding reference is invalid",
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
return value;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function requireTimestamp(value, label) {
|
|
224
|
+
if (typeof value !== "string" || value.length > 27) {
|
|
225
|
+
throw bindingError("managed_context_binding_timestamp_invalid", `${label} is invalid`);
|
|
226
|
+
}
|
|
227
|
+
const parsed = Date.parse(value);
|
|
228
|
+
if (!Number.isFinite(parsed) || new Date(parsed).toISOString() !== value) {
|
|
229
|
+
throw bindingError("managed_context_binding_timestamp_invalid", `${label} is invalid`);
|
|
230
|
+
}
|
|
231
|
+
return value;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function requireExactRecord(value, expectedFields, label) {
|
|
235
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
236
|
+
throw bindingError("managed_context_binding_contract_invalid", `${label} must be an object`);
|
|
237
|
+
}
|
|
238
|
+
const prototype = Object.getPrototypeOf(value);
|
|
239
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
240
|
+
throw bindingError("managed_context_binding_contract_invalid", `${label} must be a plain object`);
|
|
241
|
+
}
|
|
242
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
243
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
244
|
+
if (
|
|
245
|
+
typeof key === "symbol" ||
|
|
246
|
+
!descriptor?.enumerable ||
|
|
247
|
+
!("value" in descriptor)
|
|
248
|
+
) {
|
|
249
|
+
throw bindingError(
|
|
250
|
+
"managed_context_binding_contract_invalid",
|
|
251
|
+
`${label} must contain enumerable data fields only`,
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const actual = Object.keys(value).sort();
|
|
256
|
+
const expected = [...expectedFields].sort();
|
|
257
|
+
if (
|
|
258
|
+
actual.length !== expected.length ||
|
|
259
|
+
actual.some((field, index) => field !== expected[index])
|
|
260
|
+
) {
|
|
261
|
+
throw bindingError("managed_context_binding_contract_invalid", `${label} fields are invalid`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function deepFreeze(value) {
|
|
266
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
267
|
+
for (const child of Object.values(value)) deepFreeze(child);
|
|
268
|
+
Object.freeze(value);
|
|
269
|
+
}
|
|
270
|
+
return value;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function bindingError(code, message) {
|
|
274
|
+
return new ManagedContextBindingError(code, message);
|
|
275
|
+
}
|