@sellable/install 0.1.471 → 0.1.472
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.
|
@@ -53,8 +53,10 @@ import {
|
|
|
53
53
|
exchangeFlyAdminIdentity,
|
|
54
54
|
flyRuntimeDigest,
|
|
55
55
|
handoffFlyOidcSocket,
|
|
56
|
+
isFlyCustomerEnrollmentRenewalError,
|
|
56
57
|
loadOrCreateFlyRuntimeIdentity,
|
|
57
58
|
obtainFlyOidcToken,
|
|
59
|
+
renewFlyAdminControlSession,
|
|
58
60
|
signedWorkerAuthorization,
|
|
59
61
|
} from "../fly-runtime-identity.mjs";
|
|
60
62
|
import {
|
|
@@ -2263,7 +2265,7 @@ async function runAdminProduction() {
|
|
|
2263
2265
|
identityRoot: join(RUNTIME_ROOT, "identity"),
|
|
2264
2266
|
persistent: true,
|
|
2265
2267
|
});
|
|
2266
|
-
|
|
2268
|
+
let exchange = await exchangeFlyAdminIdentity({
|
|
2267
2269
|
origin: ORIGIN,
|
|
2268
2270
|
runtimeId: RUNTIME_ID,
|
|
2269
2271
|
audience: AUDIENCE,
|
|
@@ -2280,7 +2282,7 @@ async function runAdminProduction() {
|
|
|
2280
2282
|
}
|
|
2281
2283
|
const deliveryKey = loadOrCreateDeliveryKey();
|
|
2282
2284
|
await enrollDeliveryKey({ identity, exchange, deliveryKey });
|
|
2283
|
-
|
|
2285
|
+
let client = createFlyCustomerControlClient({
|
|
2284
2286
|
origin: ORIGIN,
|
|
2285
2287
|
identity,
|
|
2286
2288
|
exchange,
|
|
@@ -2321,7 +2323,35 @@ async function runAdminProduction() {
|
|
|
2321
2323
|
let failures = 0;
|
|
2322
2324
|
while (!controller.signal.aborted) {
|
|
2323
2325
|
try {
|
|
2324
|
-
|
|
2326
|
+
let claim;
|
|
2327
|
+
try {
|
|
2328
|
+
claim = await client.claim(60);
|
|
2329
|
+
} catch (error) {
|
|
2330
|
+
if (!isFlyCustomerEnrollmentRenewalError(error)) throw error;
|
|
2331
|
+
const renewed = await renewFlyAdminControlSession({
|
|
2332
|
+
origin: ORIGIN,
|
|
2333
|
+
runtimeId: RUNTIME_ID,
|
|
2334
|
+
audience: AUDIENCE,
|
|
2335
|
+
identity,
|
|
2336
|
+
bootSessionId: BOOT_SESSION_ID,
|
|
2337
|
+
runtimeGeneration: RUNTIME_GENERATION,
|
|
2338
|
+
adminRuntimeGenerationId:
|
|
2339
|
+
exchange.adminDeliveryTarget.adminRuntimeGenerationId,
|
|
2340
|
+
adminRuntimeGenerationFence:
|
|
2341
|
+
exchange.adminDeliveryTarget.adminRuntimeGenerationFence,
|
|
2342
|
+
});
|
|
2343
|
+
exchange = renewed.exchange;
|
|
2344
|
+
client = renewed.client;
|
|
2345
|
+
failures = 0;
|
|
2346
|
+
process.stderr.write(
|
|
2347
|
+
`${JSON.stringify({
|
|
2348
|
+
ok: true,
|
|
2349
|
+
code: "admin_enrollment_renewed",
|
|
2350
|
+
keyGeneration: exchange.keyGeneration,
|
|
2351
|
+
})}\n`
|
|
2352
|
+
);
|
|
2353
|
+
continue;
|
|
2354
|
+
}
|
|
2325
2355
|
if (controller.signal.aborted) break;
|
|
2326
2356
|
if (!claim) {
|
|
2327
2357
|
if (activeLaunch) {
|
|
@@ -998,3 +998,65 @@ export async function renewFlyCustomerControlSession({
|
|
|
998
998
|
});
|
|
999
999
|
return Object.freeze({ exchange, client });
|
|
1000
1000
|
}
|
|
1001
|
+
|
|
1002
|
+
export async function renewFlyAdminControlSession({
|
|
1003
|
+
origin,
|
|
1004
|
+
runtimeId,
|
|
1005
|
+
audience,
|
|
1006
|
+
identity,
|
|
1007
|
+
bootSessionId,
|
|
1008
|
+
runtimeGeneration,
|
|
1009
|
+
adminRuntimeGenerationId,
|
|
1010
|
+
adminRuntimeGenerationFence,
|
|
1011
|
+
obtainOidcTokenImpl = obtainFlyOidcToken,
|
|
1012
|
+
exchangeFlyAdminIdentityImpl = exchangeFlyAdminIdentity,
|
|
1013
|
+
createFlyCustomerControlClientImpl = createFlyCustomerControlClient,
|
|
1014
|
+
}) {
|
|
1015
|
+
if (
|
|
1016
|
+
!Number.isSafeInteger(runtimeGeneration) ||
|
|
1017
|
+
runtimeGeneration < 1 ||
|
|
1018
|
+
!/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(
|
|
1019
|
+
bootSessionId ?? ""
|
|
1020
|
+
) ||
|
|
1021
|
+
!SAFE_ID.test(adminRuntimeGenerationId ?? "") ||
|
|
1022
|
+
!/^[1-9][0-9]{0,19}$/.test(adminRuntimeGenerationFence ?? "") ||
|
|
1023
|
+
typeof obtainOidcTokenImpl !== "function" ||
|
|
1024
|
+
typeof exchangeFlyAdminIdentityImpl !== "function" ||
|
|
1025
|
+
typeof createFlyCustomerControlClientImpl !== "function"
|
|
1026
|
+
) {
|
|
1027
|
+
throw new Error("admin_runtime_generation_rejected");
|
|
1028
|
+
}
|
|
1029
|
+
let oidcToken = await obtainOidcTokenImpl({ audience });
|
|
1030
|
+
let exchange;
|
|
1031
|
+
try {
|
|
1032
|
+
exchange = await exchangeFlyAdminIdentityImpl({
|
|
1033
|
+
origin,
|
|
1034
|
+
runtimeId,
|
|
1035
|
+
audience,
|
|
1036
|
+
identity,
|
|
1037
|
+
bootSessionId,
|
|
1038
|
+
oidcToken,
|
|
1039
|
+
});
|
|
1040
|
+
} finally {
|
|
1041
|
+
oidcToken = null;
|
|
1042
|
+
}
|
|
1043
|
+
if (
|
|
1044
|
+
exchange?.kind !== "ADMIN" ||
|
|
1045
|
+
exchange.runtimeId !== runtimeId ||
|
|
1046
|
+
exchange.publicKeyHash !== identity?.publicKeyHash ||
|
|
1047
|
+
exchange.keyGeneration !== runtimeGeneration ||
|
|
1048
|
+
exchange.adminDeliveryTarget?.runtimeGeneration !== runtimeGeneration ||
|
|
1049
|
+
exchange.adminDeliveryTarget.adminRuntimeGenerationId !==
|
|
1050
|
+
adminRuntimeGenerationId ||
|
|
1051
|
+
exchange.adminDeliveryTarget.adminRuntimeGenerationFence !==
|
|
1052
|
+
adminRuntimeGenerationFence
|
|
1053
|
+
) {
|
|
1054
|
+
throw new Error("admin_runtime_generation_rejected");
|
|
1055
|
+
}
|
|
1056
|
+
const client = createFlyCustomerControlClientImpl({
|
|
1057
|
+
origin,
|
|
1058
|
+
identity,
|
|
1059
|
+
exchange,
|
|
1060
|
+
});
|
|
1061
|
+
return Object.freeze({ exchange, client });
|
|
1062
|
+
}
|
package/package.json
CHANGED
|
@@ -18,6 +18,7 @@ allowed-tools:
|
|
|
18
18
|
- mcp__sellable__search_subskill_prompts
|
|
19
19
|
- mcp__sellable__list_senders
|
|
20
20
|
- mcp__sellable__select_campaign_cells
|
|
21
|
+
- mcp__sellable__wait_for_campaign_processing
|
|
21
22
|
---
|
|
22
23
|
|
|
23
24
|
# Refill Sends
|
|
@@ -591,8 +592,16 @@ asset is the contract to load — load the prompt and that asset, verify the `v3
|
|
|
591
592
|
compatible range, and report the version before the first call. Call
|
|
592
593
|
`refill_v3_advance` with `{workspaceId, scope}` — plus `yolo: true` only when the
|
|
593
594
|
operator asked for `--yolo` — and call it again after each `advanced` or
|
|
594
|
-
`campaign_attention_required` result
|
|
595
|
-
`
|
|
595
|
+
`campaign_attention_required` result. An `awaiting_external_change` result with
|
|
596
|
+
`deferral.code:"campaign_work_in_flight"` and a campaign id is a bounded
|
|
597
|
+
read-only continuation, not permission to walk the next campaign: call
|
|
598
|
+
`wait_for_campaign_processing({ workspaceId, campaignId, requireIdle:true })`,
|
|
599
|
+
then call `refill_v3_advance` again with the identical scope and yolo grant.
|
|
600
|
+
This reuses Create Campaign's campaign-table waiter and guarantees the same
|
|
601
|
+
campaign is freshly replanned after its cohort settles. If the bounded wait
|
|
602
|
+
returns a partial timeout, surface that checkpoint and make the fresh advance;
|
|
603
|
+
if it reports the same live campaign, repeat the bounded wait. Stop on every
|
|
604
|
+
other `awaiting_external_change`, `complete`, or `blocked` result.
|
|
596
605
|
|
|
597
606
|
Resolve the workspace BEFORE the first call, exactly as the V1 route already
|
|
598
607
|
requires. `workspaceId` must be an exact id on every automation call: when the
|