@zixt/host 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +144 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { homedir } from "node:os";
|
|
|
31
31
|
// package.json
|
|
32
32
|
var package_default = {
|
|
33
33
|
name: "@zixt/host",
|
|
34
|
-
version: "0.0.
|
|
34
|
+
version: "0.0.9",
|
|
35
35
|
type: "module",
|
|
36
36
|
exports: {
|
|
37
37
|
".": "./src/client.ts",
|
|
@@ -15272,6 +15272,12 @@ var HostTelemetry = external_exports.object({
|
|
|
15272
15272
|
* recovery path; this is deliberately not inferred from package version.
|
|
15273
15273
|
*/
|
|
15274
15274
|
taskAuthorityLifecycle: external_exports.literal(true).optional(),
|
|
15275
|
+
/**
|
|
15276
|
+
* Understands structured provider-operation retry responses and can
|
|
15277
|
+
* wait cancellably before repeating the same logical request. Missing
|
|
15278
|
+
* legacy Hosts must receive the original strict refusal frame.
|
|
15279
|
+
*/
|
|
15280
|
+
providerOperationGrantRetry: external_exports.literal(true).optional(),
|
|
15275
15281
|
linearToolPack: external_exports.boolean().default(false),
|
|
15276
15282
|
providerToolPacks: external_exports.array(ProviderToolPackCapability).max(20).superRefine((capabilities, ctx) => {
|
|
15277
15283
|
const providers = capabilities.map(({ provider }) => provider);
|
|
@@ -15412,12 +15418,37 @@ var HostRequiredIntegrationSummary = external_exports.object({
|
|
|
15412
15418
|
failedCount: external_exports.number().int().min(0),
|
|
15413
15419
|
unknownCount: external_exports.number().int().min(0)
|
|
15414
15420
|
});
|
|
15421
|
+
var HostQueuedTaskDetail = external_exports.object({
|
|
15422
|
+
id: TaskId,
|
|
15423
|
+
title: external_exports.string().min(1).max(300),
|
|
15424
|
+
agentName: external_exports.string().min(1).max(120),
|
|
15425
|
+
runnerType: RunnerType,
|
|
15426
|
+
placement: external_exports.enum([
|
|
15427
|
+
"ready_here",
|
|
15428
|
+
"ready_elsewhere",
|
|
15429
|
+
"blocked_everywhere",
|
|
15430
|
+
"assigned_elsewhere",
|
|
15431
|
+
"evaluation_unknown"
|
|
15432
|
+
]),
|
|
15433
|
+
placementReason: external_exports.string().min(1).max(2e3),
|
|
15434
|
+
eligibleMachineCount: external_exports.number().int().min(0),
|
|
15435
|
+
/** A bounded preview; eligibleMachineCount remains exact when this is truncated. */
|
|
15436
|
+
eligibleMachineNames: external_exports.array(external_exports.string().min(1).max(120)).max(10),
|
|
15437
|
+
/** Queue timing is independent from Machine placement above. */
|
|
15438
|
+
queueState: external_exports.enum(["ready", "decision_pending", "waiting", "retry_due", "retry_overdue"]),
|
|
15439
|
+
queueReason: external_exports.string().min(1).max(2e3),
|
|
15440
|
+
retryAt: IsoDate2.nullable()
|
|
15441
|
+
});
|
|
15415
15442
|
var HostWorkSummary = external_exports.object({
|
|
15416
15443
|
activeTaskCount: external_exports.number().int().min(0),
|
|
15417
15444
|
queuedOrgTaskCount: external_exports.number().int().min(0),
|
|
15418
15445
|
queuedEligibleTaskCount: external_exports.number().int().min(0),
|
|
15446
|
+
/** Exact count across the full relevant queue, independent of the bounded detail preview. */
|
|
15447
|
+
overdueRelevantTaskCount: external_exports.number().int().min(0),
|
|
15419
15448
|
/** Runner families used by queued Tasks that may target this Machine. */
|
|
15420
15449
|
queuedRunnerTypes: external_exports.array(RunnerType),
|
|
15450
|
+
/** Bounded attention-first queue preview with exact Admin/Owner placement evidence. */
|
|
15451
|
+
queuedTaskDetails: external_exports.array(HostQueuedTaskDetail).max(10),
|
|
15421
15452
|
eligibilityState: HostEligibilityState,
|
|
15422
15453
|
eligibilityReason: external_exports.string().min(1).max(2e3)
|
|
15423
15454
|
});
|
|
@@ -18133,6 +18164,30 @@ var ProviderOperationGrantRequestFrame = external_exports.discriminatedUnion("op
|
|
|
18133
18164
|
}
|
|
18134
18165
|
)
|
|
18135
18166
|
]);
|
|
18167
|
+
var ProviderOperationGrantFailureCode = external_exports.enum([
|
|
18168
|
+
"provider_timeout",
|
|
18169
|
+
"provider_rate_limited",
|
|
18170
|
+
"provider_unavailable",
|
|
18171
|
+
"provider_authority_rejected",
|
|
18172
|
+
"provider_request_rejected",
|
|
18173
|
+
"provider_not_found",
|
|
18174
|
+
"provider_invalid_response",
|
|
18175
|
+
"provider_issuance_unresolved",
|
|
18176
|
+
"provider_grant_delivery_unresolved"
|
|
18177
|
+
]);
|
|
18178
|
+
var ProviderOperationGrantRetryCode = external_exports.enum([
|
|
18179
|
+
"provider_timeout",
|
|
18180
|
+
"provider_rate_limited",
|
|
18181
|
+
"provider_unavailable",
|
|
18182
|
+
"provider_invalid_response",
|
|
18183
|
+
"provider_issuance_unresolved",
|
|
18184
|
+
"provider_grant_delivery_unresolved"
|
|
18185
|
+
]);
|
|
18186
|
+
var ProviderOperationGrantRetry = external_exports.object({
|
|
18187
|
+
code: ProviderOperationGrantRetryCode,
|
|
18188
|
+
/** Never earlier than the durable claim's safe reclaim boundary. */
|
|
18189
|
+
retryAt: IsoDate
|
|
18190
|
+
}).strict();
|
|
18136
18191
|
var ProviderOperationGrantResultFrame = external_exports.discriminatedUnion("ok", [
|
|
18137
18192
|
external_exports.object({
|
|
18138
18193
|
type: external_exports.literal("provider.operation.grant.result"),
|
|
@@ -18150,7 +18205,9 @@ var ProviderOperationGrantResultFrame = external_exports.discriminatedUnion("ok"
|
|
|
18150
18205
|
requestId: external_exports.string().min(1).max(200),
|
|
18151
18206
|
ok: external_exports.literal(false),
|
|
18152
18207
|
grant: external_exports.never().optional(),
|
|
18153
|
-
error: external_exports.string().min(1).max(2e3).optional()
|
|
18208
|
+
error: external_exports.string().min(1).max(2e3).optional(),
|
|
18209
|
+
/** Sent only when the connected Host explicitly advertised support. */
|
|
18210
|
+
retry: ProviderOperationGrantRetry.optional()
|
|
18154
18211
|
}).strict()
|
|
18155
18212
|
]);
|
|
18156
18213
|
var BrowserStateFrame = external_exports.object({
|
|
@@ -19210,6 +19267,52 @@ var GithubGrantError = class extends Error {
|
|
|
19210
19267
|
this.name = `GithubGrantError:${reason}`;
|
|
19211
19268
|
}
|
|
19212
19269
|
};
|
|
19270
|
+
async function waitForOperationGrantRetry(retryAt, signal) {
|
|
19271
|
+
const deadline = Date.parse(retryAt);
|
|
19272
|
+
if (!Number.isFinite(deadline) || signal.aborted) return false;
|
|
19273
|
+
if (deadline <= Date.now()) return true;
|
|
19274
|
+
return await new Promise((resolve13) => {
|
|
19275
|
+
let settled = false;
|
|
19276
|
+
let timer;
|
|
19277
|
+
const finish = (ready) => {
|
|
19278
|
+
if (settled) return;
|
|
19279
|
+
settled = true;
|
|
19280
|
+
if (timer) clearTimeout(timer);
|
|
19281
|
+
signal.removeEventListener("abort", onAbort);
|
|
19282
|
+
resolve13(ready);
|
|
19283
|
+
};
|
|
19284
|
+
const onAbort = () => finish(false);
|
|
19285
|
+
const schedule = () => {
|
|
19286
|
+
const remaining = deadline - Date.now();
|
|
19287
|
+
if (remaining <= 0) {
|
|
19288
|
+
finish(true);
|
|
19289
|
+
return;
|
|
19290
|
+
}
|
|
19291
|
+
timer = setTimeout(schedule, Math.min(remaining, 2147e6));
|
|
19292
|
+
timer.unref?.();
|
|
19293
|
+
};
|
|
19294
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
19295
|
+
if (signal.aborted) {
|
|
19296
|
+
finish(false);
|
|
19297
|
+
return;
|
|
19298
|
+
}
|
|
19299
|
+
schedule();
|
|
19300
|
+
});
|
|
19301
|
+
}
|
|
19302
|
+
function operationGrantRetryCause(code) {
|
|
19303
|
+
if (code === "provider_timeout") return "GitHub did not answer the credential request in time";
|
|
19304
|
+
if (code === "provider_rate_limited") return "GitHub rate-limited the credential request";
|
|
19305
|
+
if (code === "provider_invalid_response") {
|
|
19306
|
+
return "GitHub returned an invalid credential response";
|
|
19307
|
+
}
|
|
19308
|
+
if (code === "provider_issuance_unresolved") {
|
|
19309
|
+
return "GitHub credential issuance is still unresolved";
|
|
19310
|
+
}
|
|
19311
|
+
if (code === "provider_grant_delivery_unresolved") {
|
|
19312
|
+
return "Zixt is waiting for a previously issued GitHub credential to expire before retrying delivery";
|
|
19313
|
+
}
|
|
19314
|
+
return "GitHub is temporarily unavailable for credential issuance";
|
|
19315
|
+
}
|
|
19213
19316
|
var HostClient = class _HostClient {
|
|
19214
19317
|
constructor(opts) {
|
|
19215
19318
|
this.opts = opts;
|
|
@@ -19887,7 +19990,13 @@ var HostClient = class _HostClient {
|
|
|
19887
19990
|
if (!frame.ok) {
|
|
19888
19991
|
clearTimeout(waiter.timer);
|
|
19889
19992
|
this.operationGrantWaiters.delete(frame.requestId);
|
|
19890
|
-
waiter.deny(
|
|
19993
|
+
waiter.deny(
|
|
19994
|
+
frame.retry !== void 0,
|
|
19995
|
+
"refused_by_zixt",
|
|
19996
|
+
frame.error,
|
|
19997
|
+
frame.retry?.retryAt,
|
|
19998
|
+
frame.retry?.code
|
|
19999
|
+
);
|
|
19891
20000
|
return;
|
|
19892
20001
|
}
|
|
19893
20002
|
const { grant } = frame;
|
|
@@ -19977,6 +20086,7 @@ var HostClient = class _HostClient {
|
|
|
19977
20086
|
capabilities: {
|
|
19978
20087
|
...measuredCapabilities,
|
|
19979
20088
|
linearToolPack: measured.capabilities?.linearToolPack ?? false,
|
|
20089
|
+
providerOperationGrantRetry: true,
|
|
19980
20090
|
...workerWatchdogIsActive() ? { taskAuthorityLifecycle: true } : {}
|
|
19981
20091
|
},
|
|
19982
20092
|
// Evidence, not configuration: the cloud says which paths matter and
|
|
@@ -20458,9 +20568,11 @@ var HostClient = class _HostClient {
|
|
|
20458
20568
|
throw new Error("No GitHub change was attempted; the authority grant was not received.");
|
|
20459
20569
|
}
|
|
20460
20570
|
const attempts = options?.maxAttempts ?? 1;
|
|
20571
|
+
let attemptBudget = attempts;
|
|
20572
|
+
let structuredRetryUsed = false;
|
|
20461
20573
|
let failureReason = "no_reply_from_zixt";
|
|
20462
20574
|
let failureDetail;
|
|
20463
|
-
for (let attempt = 0; attempt <
|
|
20575
|
+
for (let attempt = 0; attempt < attemptBudget; attempt++) {
|
|
20464
20576
|
if (authorityController.signal.aborted) break;
|
|
20465
20577
|
const socket = this.ws;
|
|
20466
20578
|
if (!socket || socket.readyState !== WebSocket.OPEN) break;
|
|
@@ -20497,7 +20609,14 @@ var HostClient = class _HostClient {
|
|
|
20497
20609
|
addSensitiveValues(providerGrantSensitiveValues(grant));
|
|
20498
20610
|
resolve13({ grant });
|
|
20499
20611
|
},
|
|
20500
|
-
deny: (retryable, reason, detail) => resolve13({
|
|
20612
|
+
deny: (retryable, reason, detail, retryAt, retryCode) => resolve13({
|
|
20613
|
+
grant: null,
|
|
20614
|
+
retryable,
|
|
20615
|
+
reason,
|
|
20616
|
+
...detail ? { detail } : {},
|
|
20617
|
+
...retryAt ? { retryAt } : {},
|
|
20618
|
+
...retryCode ? { retryCode } : {}
|
|
20619
|
+
})
|
|
20501
20620
|
});
|
|
20502
20621
|
try {
|
|
20503
20622
|
socket.send(JSON.stringify(parsed.data));
|
|
@@ -20515,7 +20634,22 @@ var HostClient = class _HostClient {
|
|
|
20515
20634
|
}
|
|
20516
20635
|
failureReason = outcome.reason;
|
|
20517
20636
|
failureDetail = outcome.detail;
|
|
20518
|
-
|
|
20637
|
+
const structuredRetryAt = outcome.retryAt;
|
|
20638
|
+
const structuredRetryCode = outcome.retryCode;
|
|
20639
|
+
const structuredRetry = structuredRetryAt !== void 0 && structuredRetryCode !== void 0;
|
|
20640
|
+
if (structuredRetry && structuredRetryAt && structuredRetryCode) {
|
|
20641
|
+
if (structuredRetryUsed) break;
|
|
20642
|
+
structuredRetryUsed = true;
|
|
20643
|
+
if (attempt + 1 >= attemptBudget) attemptBudget += 1;
|
|
20644
|
+
emitEvent(
|
|
20645
|
+
"status",
|
|
20646
|
+
`${operationGrantRetryCause(structuredRetryCode)}. Zixt will retry automatically at ${structuredRetryAt}; no repository change was attempted.`
|
|
20647
|
+
);
|
|
20648
|
+
}
|
|
20649
|
+
if (!outcome.retryable || attempt + 1 >= attemptBudget) break;
|
|
20650
|
+
if (outcome.retryAt !== void 0 && !await waitForOperationGrantRetry(outcome.retryAt, authorityController.signal)) {
|
|
20651
|
+
break;
|
|
20652
|
+
}
|
|
20519
20653
|
}
|
|
20520
20654
|
throw new GithubGrantError(failureReason, failureDetail);
|
|
20521
20655
|
};
|
|
@@ -27199,7 +27333,10 @@ function createGithubRepositoryCreator(input) {
|
|
|
27199
27333
|
operation: "repository.clone_created",
|
|
27200
27334
|
repositoryId: repository.repositoryId
|
|
27201
27335
|
},
|
|
27202
|
-
|
|
27336
|
+
// The request only obtains fenced credential authority; it does not
|
|
27337
|
+
// repeat repository creation. A second transport probe is required
|
|
27338
|
+
// to recover a cloud commit whose volatile success frame was lost.
|
|
27339
|
+
{ maxAttempts: 2 }
|
|
27203
27340
|
),
|
|
27204
27341
|
{
|
|
27205
27342
|
operation: "repository.clone_created",
|