@deksden-com/dd-flow-cli 0.9.0-beta.123 → 0.9.0-beta.127
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 +26 -0
- package/README.md +33 -1
- package/dist/build-info.json +7 -7
- package/dist/cli/argument-values.js +38 -0
- package/dist/cli/command-inputs.js +4 -3
- package/dist/cli/help.js +1 -0
- package/dist/cli/hook-ingress.js +1 -1
- package/dist/cli/run-cli.js +126 -193
- package/dist/cli/runtime-maintenance-diagnostics.js +46 -0
- package/dist/cli/runtime-maintenance-ingress.js +51 -0
- package/dist/cli/runtime-process.js +128 -0
- package/dist/cli.js +8 -5
- package/dist/domain/stage-catalog.js +1 -1
- package/dist/harness-runtime/bin/dd-agy.mjs +3 -2
- package/dist/harness-runtime/bin/dd-codex.mjs +3 -2
- package/dist/harness-runtime/bin/dd-droid.mjs +3 -2
- package/dist/harness-runtime/bin/dd-grok.mjs +16 -6
- package/dist/harness-runtime/bin/dd-opencode.mjs +3 -2
- package/dist/harness-runtime/bin/dd-zcode.mjs +20 -16
- package/dist/harness-runtime/lib/adapter-timeouts.d.mts +5 -0
- package/dist/harness-runtime/lib/adapter-timeouts.mjs +34 -0
- package/dist/harness-runtime/lib/codex-capacity-policy.d.mts +10 -0
- package/dist/harness-runtime/lib/codex-capacity-policy.mjs +89 -0
- package/dist/harness-runtime/lib/daemon-observation.d.mts +2 -0
- package/dist/harness-runtime/lib/daemon-observation.mjs +163 -0
- package/dist/harness-runtime/lib/daemon-operations.mjs +159 -15
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +215 -86
- package/dist/harness-runtime/lib/dd-agy.mjs +11 -13
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +47 -23
- package/dist/harness-runtime/lib/dd-codex.mjs +257 -99
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +32 -30
- package/dist/harness-runtime/lib/dd-droid.mjs +117 -31
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +96 -38
- package/dist/harness-runtime/lib/dd-grok.mjs +15 -13
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +54 -20
- package/dist/harness-runtime/lib/dd-opencode.mjs +44 -14
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +81 -76
- package/dist/harness-runtime/lib/dd-zcode.mjs +204 -116
- package/dist/harness-runtime/lib/driver-recovery.mjs +12 -2
- package/dist/harness-runtime/lib/lease-renewal.d.mts +8 -0
- package/dist/harness-runtime/lib/lease-renewal.mjs +23 -0
- package/dist/harness-runtime/lib/lifecycle-command.d.mts +3 -3
- package/dist/harness-runtime/lib/lifecycle-command.mjs +74 -20
- package/dist/harness-runtime/lib/managed-daemon.d.mts +11 -0
- package/dist/harness-runtime/lib/managed-daemon.mjs +321 -65
- package/dist/harness-runtime/lib/native-children.d.mts +13 -0
- package/dist/harness-runtime/lib/native-children.mjs +78 -0
- package/dist/harness-runtime/lib/native-hook-command.d.mts +4 -0
- package/dist/harness-runtime/lib/native-hook-command.mjs +115 -11
- package/dist/harness-runtime/lib/native-streams.mjs +45 -0
- package/dist/harness-runtime/lib/observation-clock.d.mts +18 -0
- package/dist/harness-runtime/lib/observation-clock.mjs +73 -17
- package/dist/harness-runtime/lib/operation-errors.d.mts +14 -0
- package/dist/harness-runtime/lib/operation-errors.mjs +105 -8
- package/dist/harness-runtime/lib/operation-progress.d.mts +7 -0
- package/dist/harness-runtime/lib/operation-progress.mjs +112 -0
- package/dist/harness-runtime/lib/process-json.mjs +136 -38
- package/dist/harness-runtime/lib/tool-observations.d.mts +1 -0
- package/dist/harness-runtime/lib/tool-observations.mjs +5 -2
- package/dist/harness-runtime/lib/zcode-usage.mjs +3 -2
- package/dist/runtime/context.js +8 -4
- package/dist/schemas/flow-run.schema.json +1 -0
- package/dist/schemas/plan-review-decision.schema.json +3 -3
- package/dist/schemas/run-control-receipt.schema.json +19 -0
- package/dist/services/code-checks.js +93 -27
- package/dist/services/codex-capacity.js +251 -74
- package/dist/services/codex-hook-delivery.js +2 -2
- package/dist/services/compatibility-preflight.js +4 -1
- package/dist/services/controller-fanout.js +9 -75
- package/dist/services/engines.js +70 -20
- package/dist/services/eval-snapshots.js +179 -40
- package/dist/services/external-work-launch.js +21 -9
- package/dist/services/harness-adapter.js +195 -25
- package/dist/services/hooks.js +65 -21
- package/dist/services/lifecycle-invocations.js +404 -32
- package/dist/services/managed-lease-monitor.js +128 -0
- package/dist/services/managed-processes.js +117 -53
- package/dist/services/merge-server.js +66 -23
- package/dist/services/recovery-observation-budget.js +67 -7
- package/dist/services/recovery-snapshot-database.js +7 -4
- package/dist/services/review-deferral.js +23 -0
- package/dist/services/run-control-receipt.js +1 -1
- package/dist/services/run-control-worker.js +177 -118
- package/dist/services/run-control.js +99 -8
- package/dist/services/run-controller-adapter.js +177 -51
- package/dist/services/run-controller-capture.js +14 -2
- package/dist/services/run-controller-process.js +11 -4
- package/dist/services/run-controller-recovery.js +17 -0
- package/dist/services/run-controller-state.js +68 -7
- package/dist/services/run-controller.js +207 -107
- package/dist/services/run-fork.js +8 -3
- package/dist/services/run-recovery-guard.js +75 -0
- package/dist/services/run-recovery-runtime.js +21 -30
- package/dist/services/run-recovery.js +17 -13
- package/dist/services/runs.js +40 -7
- package/dist/services/runtime-budget.js +32 -15
- package/dist/services/runtime-scope-control.js +8 -0
- package/dist/services/runtime-scope-resume.js +30 -8
- package/dist/services/runtime-scope-worker.js +118 -73
- package/dist/services/runtime-service.js +6 -7
- package/dist/services/scope-writer-cleanup.js +3 -2
- package/dist/services/stage-context.js +135 -0
- package/dist/services/stage-lifecycle.js +3 -15
- package/dist/services/stage-pause.js +3 -2
- package/dist/services/usage.js +14 -3
- package/dist/services/verification-matrix.js +30 -1
- package/dist/services/vnext-code-review.js +26 -13
- package/dist/services/vnext-code.js +10 -8
- package/dist/services/vnext-contracts.js +10 -1
- package/dist/services/vnext-execution-profile.js +75 -2
- package/dist/services/vnext-fanout.js +5 -0
- package/dist/services/vnext-merge.js +30 -11
- package/dist/services/vnext-plan-review.js +102 -35
- package/dist/services/vnext-plan.js +9 -7
- package/dist/services/vnext-protocolize.js +15 -9
- package/dist/services/vnext-specify.js +6 -6
- package/dist/services/work-registry.js +43 -6
- package/dist/services/workspace-bootstrap.js +14 -3
- package/dist/shared/errors.js +11 -6
- package/dist/storage/agent-output.js +26 -0
- package/dist/storage/database.js +80 -21
- package/package.json +7 -4
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { isGitlessWorkspace, ownedWorkspaceHookPath, projectServicePathFilter, workspaceGitFiles } from "./workspace-files.js";
|
|
3
3
|
import { spawn, spawnSync } from "node:child_process";
|
|
4
|
+
import { ObservationClock, validateObservationDuration } from "../harness-runtime/lib/observation-clock.mjs";
|
|
4
5
|
import fs from "node:fs";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
import { isDeepStrictEqual } from "node:util";
|
|
7
8
|
import { parse } from "shell-quote";
|
|
8
9
|
import { assertRunMutationAllowed } from "./run-recovery.js";
|
|
9
|
-
import { AppError } from "../shared/errors.js";
|
|
10
|
-
import {
|
|
10
|
+
import { AppError, errorRecord } from "../shared/errors.js";
|
|
11
|
+
import { stopProcessGroup } from "../harness-runtime/lib/managed-daemon.mjs";
|
|
12
|
+
import { createRenewalState, maintenanceRetryable, renewalConfirmed, renewalDelay, renewalFailure, renewalRemaining, RENEWAL_POLICY } from "../harness-runtime/lib/lease-renewal.mjs";
|
|
13
|
+
import { confirmManagedProcess, finishManagedProcess, renewManagedProcess, managedProcessStatus, managedProcessRuntimeHome, managedOwnerIsAlive, processTreeIsAlive, registerManagedProcess, reservePorts } from "./managed-processes.js";
|
|
11
14
|
import { admitRuntimeCheck, runtimeBudgetForRun } from "./runtime-budget.js";
|
|
12
15
|
import { getResourceDatabase } from "../storage/database.js";
|
|
13
16
|
const profileRelativePath = path.join(".memory-bank", "spec", "engineering", "code-check-profile.json");
|
|
@@ -233,6 +236,8 @@ function assertDirectCheckExecutable(workspaceRoot, command, checkId) {
|
|
|
233
236
|
if (!program)
|
|
234
237
|
return;
|
|
235
238
|
const probe = spawnSync("/bin/sh", ["-c", "command -v -- \"$1\" >/dev/null", "dd-flow-check", program], { cwd: workspaceRoot, env, encoding: "utf8", timeout: 5000 });
|
|
239
|
+
if (probe.error || probe.signal)
|
|
240
|
+
throw new AppError("check_command_probe_unavailable", "Executable probe could not be observed; availability is unknown", 2, { check_id: checkId, executable: program, cause: probe.error?.message, signal: probe.signal });
|
|
236
241
|
if (probe.status !== 0)
|
|
237
242
|
throw new AppError("check_command_unavailable", "Available CODE check names an executable that is unavailable in this environment", 2, { check_id: checkId, command, executable: program });
|
|
238
243
|
}
|
|
@@ -330,7 +335,7 @@ async function runCodeChecksOwned(context, input, workspaceGateId, generation) {
|
|
|
330
335
|
assertRunMutationAllowed(context, input.projectId, input.runId, generation);
|
|
331
336
|
if (budget)
|
|
332
337
|
admitRuntimeCheck(context, managed.id, managed.lease_token);
|
|
333
|
-
},
|
|
338
|
+
}, attemptMs => renewManagedProcess({ ...context, resourceDatabaseMode: "prepared_existing", databaseDeadlineAt: Date.now() + attemptMs }, { id: managed.id, leaseToken: managed.lease_token }));
|
|
334
339
|
}
|
|
335
340
|
finally {
|
|
336
341
|
fs.closeSync(stdout);
|
|
@@ -340,7 +345,8 @@ async function runCodeChecksOwned(context, input, workspaceGateId, generation) {
|
|
|
340
345
|
if (processTreeIsAlive(current))
|
|
341
346
|
throw new AppError("check_in_progress", "The check shell exited but its process tree is still live; retain this receipt and its resources until settlement", 2, { process_id: managed.id, check_receipt_id: id });
|
|
342
347
|
allocation.release();
|
|
343
|
-
|
|
348
|
+
if (!result.cleanupUnconfirmed)
|
|
349
|
+
finishManagedProcess(context, { id: managed.id, leaseToken: managed.lease_token, state: result.aborted || result.exitCode !== 0 || Boolean(result.error) ? "failed" : "stopped", reason: result.error });
|
|
344
350
|
}
|
|
345
351
|
catch (error) {
|
|
346
352
|
if (error instanceof AppError && error.code === "check_in_progress")
|
|
@@ -421,7 +427,7 @@ export function reconcileUnfinishedChecks(context, input) {
|
|
|
421
427
|
if (process)
|
|
422
428
|
finishManagedProcess(context, { id: process.id, leaseToken: process.lease_token, state: status === "passed" ? "stopped" : "failed", reason: status === "passed" ? "reconciled_completion" : completion === null ? "completion_marker_missing" : "reconciled_check_failed" });
|
|
423
429
|
if (receipt) {
|
|
424
|
-
const repaired = { ...receipt, completion_path: receipt.completion_path || path.join(path.dirname(pendingReceipt.receipt_path), "completion.json"), required_artifacts: receipt.required_artifacts ?? [], status, exit_code: exitCode, after_fingerprint: after.fingerprint, mutation_paths: workspaceUnchanged ? [] : ["<workspace changed while detached check ran>"], artifacts: artifacts.items, finished_at: finishedAt };
|
|
430
|
+
const repaired = { ...receipt, completion_path: receipt.completion_path || path.join(path.dirname(pendingReceipt.receipt_path), "completion.json"), required_artifacts: receipt.required_artifacts ?? [], ...(status === "aborted" ? { abort_reason: "completion_marker_missing" } : {}), status, exit_code: exitCode, after_fingerprint: after.fingerprint, mutation_paths: workspaceUnchanged ? [] : ["<workspace changed while detached check ran>"], artifacts: artifacts.items, finished_at: finishedAt };
|
|
425
431
|
writeReceipt(pendingReceipt.receipt_path, repaired);
|
|
426
432
|
reconciled.push(repaired);
|
|
427
433
|
}
|
|
@@ -485,7 +491,7 @@ function reserveOrReuseReceipt(context, input) {
|
|
|
485
491
|
return { reserved };
|
|
486
492
|
}, "checks.reserveOrReuseReceipt");
|
|
487
493
|
}
|
|
488
|
-
function receiptFor(input) { return { id: input.id, local_id: input.localId, declaration_id: input.group.declarations[0].id, check_refs: input.group.declarations.map(checkRef), gate: input.group.gate, scope: input.scope, work_id: input.workId ?? null, command: input.group.command, input_hash: input.inputHash, verification_epoch: input.epoch, retry_of_receipt_id: input.retryOf ?? null, retry_reason: input.retryReason ?? null, status: input.status, exit_code: input.status === "running" ? null : input.result.exitCode, stdout_path: input.stdoutPath, stderr_path: input.stderrPath, receipt_path: input.receiptPath, completion_path: input.completionPath, required_artifacts: input.group.requiredArtifacts, inputs: input.group.inputs, workspace_fingerprint: input.before.fingerprint, before_fingerprint: input.before.fingerprint, after_fingerprint: input.after.fingerprint, profile_hash: input.profileHash, mutation_paths: input.mutationPaths, artifacts: input.artifacts, resources: { ports: input.resources }, started_at: input.startedAt, finished_at: input.status === "running" ? input.startedAt : new Date().toISOString() }; }
|
|
494
|
+
function receiptFor(input) { return { id: input.id, local_id: input.localId, declaration_id: input.group.declarations[0].id, check_refs: input.group.declarations.map(checkRef), gate: input.group.gate, scope: input.scope, work_id: input.workId ?? null, command: input.group.command, input_hash: input.inputHash, verification_epoch: input.epoch, retry_of_receipt_id: input.retryOf ?? null, retry_reason: input.retryReason ?? null, status: input.status, ...(input.status === "aborted" ? { abort_reason: input.result.error } : {}), exit_code: input.status === "running" ? null : input.result.exitCode, stdout_path: input.stdoutPath, stderr_path: input.stderrPath, receipt_path: input.receiptPath, completion_path: input.completionPath, required_artifacts: input.group.requiredArtifacts, inputs: input.group.inputs, workspace_fingerprint: input.before.fingerprint, before_fingerprint: input.before.fingerprint, after_fingerprint: input.after.fingerprint, profile_hash: input.profileHash, mutation_paths: input.mutationPaths, artifacts: input.artifacts, resources: { ports: input.resources }, started_at: input.startedAt, finished_at: input.status === "running" ? input.startedAt : new Date().toISOString() }; }
|
|
489
495
|
function writeReceipt(file, receipt) { const temporary = `${file}.tmp-${process.pid}-${crypto.randomUUID()}`; fs.writeFileSync(temporary, `${JSON.stringify(receipt, null, 2)}\n`); fs.renameSync(temporary, file); }
|
|
490
496
|
function readReceipt(file) { try {
|
|
491
497
|
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
@@ -818,14 +824,23 @@ function listFiles(root) {
|
|
|
818
824
|
});
|
|
819
825
|
return visit(root).filter(file => file.split(path.sep).join("/") !== ownedHook).sort();
|
|
820
826
|
}
|
|
821
|
-
export function runCheck(command, cwd, environment, stdout, stderr, heartbeat, onSpawn, renewLease) {
|
|
827
|
+
export function runCheck(command, cwd, environment, stdout, stderr, heartbeat, onSpawn, renewLease, observation = {}) {
|
|
828
|
+
const inactivityTimeoutMs = validateObservationDuration(observation.inactivityTimeoutMs ?? 30 * 60_000);
|
|
822
829
|
return new Promise((resolve) => {
|
|
823
830
|
const started = Date.now();
|
|
824
|
-
const child = spawn("/bin/sh", ["-c", checkShellScript()], { cwd, env: { ...environment, DD_FLOW_CHECK_COMMAND: command }, stdio: ["pipe",
|
|
831
|
+
const child = spawn("/bin/sh", ["-c", checkShellScript()], { cwd, env: { ...environment, DD_FLOW_CHECK_COMMAND: command }, stdio: ["pipe", "pipe", "pipe"], detached: process.platform !== "win32" });
|
|
825
832
|
let error = null;
|
|
826
833
|
let stopping = false;
|
|
834
|
+
let closed = false;
|
|
827
835
|
let progress;
|
|
828
|
-
let
|
|
836
|
+
let cleanup;
|
|
837
|
+
let cleanupUnconfirmed = false;
|
|
838
|
+
const renewal = createRenewalState();
|
|
839
|
+
let renewalTimer;
|
|
840
|
+
const clock = new ObservationClock({ timeoutMs: inactivityTimeoutMs });
|
|
841
|
+
let outputCursor = 0;
|
|
842
|
+
const outputs = [fs.createWriteStream("", { fd: stdout, autoClose: false }), fs.createWriteStream("", { fd: stderr, autoClose: false })];
|
|
843
|
+
const flushed = outputs.map(output => new Promise(resolve => { output.once("finish", resolve); output.once("error", () => resolve()); }));
|
|
829
844
|
const stop = (cause) => {
|
|
830
845
|
if (stopping)
|
|
831
846
|
return;
|
|
@@ -835,23 +850,42 @@ export function runCheck(command, cwd, environment, stdout, stderr, heartbeat, o
|
|
|
835
850
|
clearInterval(progress);
|
|
836
851
|
progress = undefined;
|
|
837
852
|
}
|
|
838
|
-
if (
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
853
|
+
if (renewalTimer)
|
|
854
|
+
clearTimeout(renewalTimer);
|
|
855
|
+
if (observationTimer)
|
|
856
|
+
clearInterval(observationTimer);
|
|
857
|
+
cleanup = stopProcessGroup(child, 5_000).catch(cause => {
|
|
858
|
+
cleanupUnconfirmed = true;
|
|
859
|
+
error = `${error}; cleanup: ${JSON.stringify(errorRecord(cause))}`;
|
|
860
|
+
resolve({ exitCode: null, error, aborted: true, cleanupUnconfirmed });
|
|
861
|
+
});
|
|
842
862
|
};
|
|
863
|
+
const observationTimer = setInterval(() => {
|
|
864
|
+
if (stopping || closed || observation.phase?.() === "serving")
|
|
865
|
+
return;
|
|
866
|
+
if (clock.sample(outputCursor))
|
|
867
|
+
stop(new AppError("operation_observation_lost", "Owned command has no confirmed progress within its inactivity window", 1, { phase: observation.phase?.() ?? "finite", inactivity_timeout_ms: inactivityTimeoutMs }));
|
|
868
|
+
}, Math.min(1000, inactivityTimeoutMs));
|
|
843
869
|
// Register handlers before checking pid or calling persistence callbacks.
|
|
844
870
|
// Failure is not completion until the spawned process has actually closed.
|
|
845
871
|
child.once("error", (value) => { error = value.message; });
|
|
872
|
+
for (const [index, stream] of [child.stdout, child.stderr].entries()) {
|
|
873
|
+
outputs[index].once("error", stop);
|
|
874
|
+
stream.on("data", () => { outputCursor++; clock.sample(outputCursor); });
|
|
875
|
+
stream.pipe(outputs[index]);
|
|
876
|
+
}
|
|
846
877
|
child.stdin.on("error", stop);
|
|
847
|
-
child.once("close", (exitCode, signal) => {
|
|
878
|
+
child.once("close", async (exitCode, signal) => {
|
|
879
|
+
closed = true;
|
|
848
880
|
if (progress)
|
|
849
881
|
clearInterval(progress);
|
|
850
|
-
if (
|
|
851
|
-
clearTimeout(
|
|
852
|
-
if (
|
|
853
|
-
|
|
854
|
-
|
|
882
|
+
if (renewalTimer)
|
|
883
|
+
clearTimeout(renewalTimer);
|
|
884
|
+
if (observationTimer)
|
|
885
|
+
clearInterval(observationTimer);
|
|
886
|
+
await cleanup;
|
|
887
|
+
await Promise.all(flushed);
|
|
888
|
+
resolve({ exitCode, error: error ?? (signal ? `terminated by ${signal}` : null), aborted: stopping || Boolean(signal) || Boolean(error), ...(cleanupUnconfirmed ? { cleanupUnconfirmed } : {}) });
|
|
855
889
|
});
|
|
856
890
|
if (!child.pid) {
|
|
857
891
|
error = "check process did not provide a PID";
|
|
@@ -865,18 +899,55 @@ export function runCheck(command, cwd, environment, stdout, stderr, heartbeat, o
|
|
|
865
899
|
return;
|
|
866
900
|
}
|
|
867
901
|
child.stdin.end("admitted\n");
|
|
868
|
-
|
|
902
|
+
clock.sample(outputCursor);
|
|
903
|
+
const renew = () => {
|
|
904
|
+
if (stopping || closed)
|
|
905
|
+
return;
|
|
906
|
+
if (renewalTimer) {
|
|
907
|
+
clearTimeout(renewalTimer);
|
|
908
|
+
renewalTimer = undefined;
|
|
909
|
+
}
|
|
869
910
|
try {
|
|
870
|
-
|
|
911
|
+
renewal.uncertainSince ??= performance.now();
|
|
912
|
+
const remaining = renewalRemaining(renewal);
|
|
913
|
+
if (!remaining) {
|
|
914
|
+
stop("managed process renewal budget exhausted");
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
const receipt = renewLease(Math.min(RENEWAL_POLICY.attemptMs, remaining));
|
|
918
|
+
if (receipt === false || typeof receipt === "object" && !receipt.owned) {
|
|
871
919
|
stop("managed process lease lost");
|
|
872
920
|
return;
|
|
873
921
|
}
|
|
922
|
+
if (typeof receipt === "object" && receipt.owned) {
|
|
923
|
+
const expiry = Date.parse(receipt.lease_expires_at);
|
|
924
|
+
if (!Number.isFinite(expiry))
|
|
925
|
+
throw new AppError("managed_lease_receipt_invalid", "Check renewal returned invalid expiry", 1);
|
|
926
|
+
if (expiry <= Date.now())
|
|
927
|
+
throw Object.assign(new Error("Check renewal receipt expired before acknowledgement"), { code: "process_maintenance_timeout" });
|
|
928
|
+
}
|
|
929
|
+
if (!renewalRemaining(renewal) || !renewalConfirmed(renewal)) {
|
|
930
|
+
stop("managed process renewal budget exhausted");
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
catch (cause) {
|
|
935
|
+
if (!maintenanceRetryable(cause) || !renewalFailure(renewal)) {
|
|
936
|
+
stop(cause);
|
|
937
|
+
return;
|
|
938
|
+
}
|
|
939
|
+
renewalTimer = setTimeout(renew, Math.min(renewalDelay(renewal), renewalRemaining(renewal)));
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
// A progress callback error is not a retryable renewal failure.
|
|
943
|
+
try {
|
|
874
944
|
heartbeat(Math.floor((Date.now() - started) / 1000));
|
|
875
945
|
}
|
|
876
946
|
catch (cause) {
|
|
877
947
|
stop(cause);
|
|
878
948
|
}
|
|
879
|
-
}
|
|
949
|
+
};
|
|
950
|
+
progress = setInterval(renew, 15_000);
|
|
880
951
|
});
|
|
881
952
|
}
|
|
882
953
|
function checkShellScript() {
|
|
@@ -890,8 +961,3 @@ function checkShellScript() {
|
|
|
890
961
|
'exit "$code"'
|
|
891
962
|
].join("\n");
|
|
892
963
|
}
|
|
893
|
-
function terminateProcessGroup(pid, signal) { if (!pid)
|
|
894
|
-
return; try {
|
|
895
|
-
process.kill(process.platform === "win32" ? pid : -pid, signal);
|
|
896
|
-
}
|
|
897
|
-
catch { /* already exited */ } }
|