@tickernelz/paperclip-pro-adapter-utils 2026.1006.0 → 2026.1006.2
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 +13 -0
- package/dist/acpx-engine/ephemeral-session-environment.d.ts +4 -0
- package/dist/acpx-engine/ephemeral-session-environment.d.ts.map +1 -0
- package/dist/acpx-engine/ephemeral-session-environment.js +29 -0
- package/dist/acpx-engine/ephemeral-session-environment.js.map +1 -0
- package/dist/acpx-engine/ephemeral-session-environment.test.d.ts +2 -0
- package/dist/acpx-engine/ephemeral-session-environment.test.d.ts.map +1 -0
- package/dist/acpx-engine/ephemeral-session-environment.test.js +177 -0
- package/dist/acpx-engine/ephemeral-session-environment.test.js.map +1 -0
- package/dist/acpx-engine/execute.d.ts +2 -6
- package/dist/acpx-engine/execute.d.ts.map +1 -1
- package/dist/acpx-engine/execute.js +125 -62
- package/dist/acpx-engine/execute.js.map +1 -1
- package/dist/acpx-engine/execute.test.js +299 -3
- package/dist/acpx-engine/execute.test.js.map +1 -1
- package/dist/acpx-engine/session-codec.d.ts.map +1 -1
- package/dist/acpx-engine/session-codec.js +1 -0
- package/dist/acpx-engine/session-codec.js.map +1 -1
- package/dist/acpx-engine/settlement-characterization.test.js +105 -0
- package/dist/acpx-engine/settlement-characterization.test.js.map +1 -1
- package/dist/acpx-engine/spawn-smoke.test.js +16 -7
- package/dist/acpx-engine/spawn-smoke.test.js.map +1 -1
- package/dist/acpx-engine/startup-cancellation.d.ts +1 -0
- package/dist/acpx-engine/startup-cancellation.d.ts.map +1 -1
- package/dist/acpx-engine/startup-cancellation.js +7 -2
- package/dist/acpx-engine/startup-cancellation.js.map +1 -1
- package/dist/acpx-engine/terminal-session-failure.d.ts +18 -0
- package/dist/acpx-engine/terminal-session-failure.d.ts.map +1 -0
- package/dist/acpx-engine/terminal-session-failure.js +106 -0
- package/dist/acpx-engine/terminal-session-failure.js.map +1 -0
- package/dist/acpx-engine/terminal-session-failure.test.d.ts +2 -0
- package/dist/acpx-engine/terminal-session-failure.test.d.ts.map +1 -0
- package/dist/acpx-engine/terminal-session-failure.test.js +139 -0
- package/dist/acpx-engine/terminal-session-failure.test.js.map +1 -0
- package/dist/acpx-engine/turn-characterization.test.js +4 -3
- package/dist/acpx-engine/turn-characterization.test.js.map +1 -1
- package/dist/command-managed-runtime.d.ts +2 -0
- package/dist/command-managed-runtime.d.ts.map +1 -1
- package/dist/command-managed-runtime.js +2 -0
- package/dist/command-managed-runtime.js.map +1 -1
- package/dist/command-redaction.d.ts +2 -0
- package/dist/command-redaction.d.ts.map +1 -1
- package/dist/command-redaction.js +20 -10
- package/dist/command-redaction.js.map +1 -1
- package/dist/command-redaction.test.js +20 -1
- package/dist/command-redaction.test.js.map +1 -1
- package/dist/directory-merge-lock.test.d.ts +2 -0
- package/dist/directory-merge-lock.test.d.ts.map +1 -0
- package/dist/directory-merge-lock.test.js +166 -0
- package/dist/directory-merge-lock.test.js.map +1 -0
- package/dist/execution-phase.d.ts +10 -0
- package/dist/execution-phase.d.ts.map +1 -0
- package/dist/execution-phase.js +27 -0
- package/dist/execution-phase.js.map +1 -0
- package/dist/execution-phase.test.d.ts +2 -0
- package/dist/execution-phase.test.d.ts.map +1 -0
- package/dist/execution-phase.test.js +26 -0
- package/dist/execution-phase.test.js.map +1 -0
- package/dist/execution-target-sandbox.test.js +49 -7
- package/dist/execution-target-sandbox.test.js.map +1 -1
- package/dist/execution-target-stdin-race.test.js +245 -2
- package/dist/execution-target-stdin-race.test.js.map +1 -1
- package/dist/execution-target.d.ts +6 -0
- package/dist/execution-target.d.ts.map +1 -1
- package/dist/execution-target.js +74 -22
- package/dist/execution-target.js.map +1 -1
- package/dist/git-workspace-sync.d.ts +15 -5
- package/dist/git-workspace-sync.d.ts.map +1 -1
- package/dist/git-workspace-sync.js +267 -124
- package/dist/git-workspace-sync.js.map +1 -1
- package/dist/git-workspace-sync.test.js +296 -20
- package/dist/git-workspace-sync.test.js.map +1 -1
- package/dist/github-launcher.d.ts.map +1 -1
- package/dist/github-launcher.js +26 -11
- package/dist/github-launcher.js.map +1 -1
- package/dist/github-launcher.test.js +34 -1
- package/dist/github-launcher.test.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/paperclip-runner-permissions.d.ts +28 -1
- package/dist/paperclip-runner-permissions.d.ts.map +1 -1
- package/dist/paperclip-runner-permissions.js +9 -1
- package/dist/paperclip-runner-permissions.js.map +1 -1
- package/dist/prompt-sections.test.d.ts +2 -0
- package/dist/prompt-sections.test.d.ts.map +1 -0
- package/dist/prompt-sections.test.js +53 -0
- package/dist/prompt-sections.test.js.map +1 -0
- package/dist/provider-stopped-boundary.d.ts +7 -0
- package/dist/provider-stopped-boundary.d.ts.map +1 -0
- package/dist/provider-stopped-boundary.js +22 -0
- package/dist/provider-stopped-boundary.js.map +1 -0
- package/dist/provider-stopped-boundary.test.d.ts +2 -0
- package/dist/provider-stopped-boundary.test.d.ts.map +1 -0
- package/dist/provider-stopped-boundary.test.js +76 -0
- package/dist/provider-stopped-boundary.test.js.map +1 -0
- package/dist/remote-managed-runtime.d.ts +2 -0
- package/dist/remote-managed-runtime.d.ts.map +1 -1
- package/dist/remote-managed-runtime.js +3 -1
- package/dist/remote-managed-runtime.js.map +1 -1
- package/dist/remote-managed-runtime.test.js +25 -0
- package/dist/remote-managed-runtime.test.js.map +1 -1
- package/dist/sandbox-callback-bridge.d.ts +2 -0
- package/dist/sandbox-callback-bridge.d.ts.map +1 -1
- package/dist/sandbox-callback-bridge.js +34 -10
- package/dist/sandbox-callback-bridge.js.map +1 -1
- package/dist/sandbox-callback-bridge.test.js +106 -3
- package/dist/sandbox-callback-bridge.test.js.map +1 -1
- package/dist/sandbox-managed-runtime.d.ts +3 -0
- package/dist/sandbox-managed-runtime.d.ts.map +1 -1
- package/dist/sandbox-managed-runtime.js +749 -718
- package/dist/sandbox-managed-runtime.js.map +1 -1
- package/dist/sandbox-managed-runtime.test.js +171 -2
- package/dist/sandbox-managed-runtime.test.js.map +1 -1
- package/dist/server-utils.d.ts +43 -1
- package/dist/server-utils.d.ts.map +1 -1
- package/dist/server-utils.js +103 -31
- package/dist/server-utils.js.map +1 -1
- package/dist/server-utils.test.js +235 -45
- package/dist/server-utils.test.js.map +1 -1
- package/dist/session-compaction.d.ts.map +1 -1
- package/dist/session-compaction.js +6 -0
- package/dist/session-compaction.js.map +1 -1
- package/dist/ssh-fixture.test.js +22 -0
- package/dist/ssh-fixture.test.js.map +1 -1
- package/dist/ssh.d.ts +2 -0
- package/dist/ssh.d.ts.map +1 -1
- package/dist/ssh.js +2 -2
- package/dist/ssh.js.map +1 -1
- package/dist/test-fixtures/prompt-context.d.ts +54 -0
- package/dist/test-fixtures/prompt-context.d.ts.map +1 -0
- package/dist/test-fixtures/prompt-context.js +55 -0
- package/dist/test-fixtures/prompt-context.js.map +1 -0
- package/dist/types.d.ts +12 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/workspace-git-stream.d.ts +19 -0
- package/dist/workspace-git-stream.d.ts.map +1 -0
- package/dist/workspace-git-stream.js +99 -0
- package/dist/workspace-git-stream.js.map +1 -0
- package/dist/workspace-git-stream.test.d.ts +2 -0
- package/dist/workspace-git-stream.test.d.ts.map +1 -0
- package/dist/workspace-git-stream.test.js +71 -0
- package/dist/workspace-git-stream.test.js.map +1 -0
- package/dist/workspace-manifest.d.ts +61 -0
- package/dist/workspace-manifest.d.ts.map +1 -0
- package/dist/workspace-manifest.js +257 -0
- package/dist/workspace-manifest.js.map +1 -0
- package/dist/workspace-manifest.test.d.ts +2 -0
- package/dist/workspace-manifest.test.d.ts.map +1 -0
- package/dist/workspace-manifest.test.js +160 -0
- package/dist/workspace-manifest.test.js.map +1 -0
- package/dist/workspace-restore-diagnostics.d.ts +34 -0
- package/dist/workspace-restore-diagnostics.d.ts.map +1 -0
- package/dist/workspace-restore-diagnostics.js +238 -0
- package/dist/workspace-restore-diagnostics.js.map +1 -0
- package/dist/workspace-restore-diagnostics.test.d.ts +2 -0
- package/dist/workspace-restore-diagnostics.test.d.ts.map +1 -0
- package/dist/workspace-restore-diagnostics.test.js +258 -0
- package/dist/workspace-restore-diagnostics.test.js.map +1 -0
- package/dist/workspace-restore-merge.d.ts +47 -6
- package/dist/workspace-restore-merge.d.ts.map +1 -1
- package/dist/workspace-restore-merge.js +382 -114
- package/dist/workspace-restore-merge.js.map +1 -1
- package/dist/workspace-restore-merge.test.js +253 -4
- package/dist/workspace-restore-merge.test.js.map +1 -1
- package/dist/workspace-restore-result.d.ts +6 -0
- package/dist/workspace-restore-result.d.ts.map +1 -0
- package/dist/workspace-restore-result.js +72 -0
- package/dist/workspace-restore-result.js.map +1 -0
- package/dist/workspace-restore-result.test.d.ts +2 -0
- package/dist/workspace-restore-result.test.d.ts.map +1 -0
- package/dist/workspace-restore-result.test.js +74 -0
- package/dist/workspace-restore-result.test.js.map +1 -0
- package/dist/workspace-restore-teardown.d.ts.map +1 -1
- package/dist/workspace-restore-teardown.js +5 -3
- package/dist/workspace-restore-teardown.js.map +1 -1
- package/dist/workspace-restore-teardown.test.js +24 -0
- package/dist/workspace-restore-teardown.test.js.map +1 -1
- package/node_modules/acpx/dist/live-checkpoint-ClPCSdrW.js +4 -3
- package/package.json +2 -2
package/dist/execution-target.js
CHANGED
|
@@ -9,7 +9,7 @@ import { githubLauncherSource } from "./github-launcher.js";
|
|
|
9
9
|
import { prepareCommandManagedRuntime, } from "./command-managed-runtime.js";
|
|
10
10
|
import { buildRemoteExecutionSessionIdentity, prepareRemoteManagedRuntime, remoteExecutionSessionMatches, } from "./remote-managed-runtime.js";
|
|
11
11
|
export { resolveReferencedSourceIgnore } from "./sandbox-managed-runtime.js";
|
|
12
|
-
import { createCommandManagedSandboxCallbackBridgeQueueClient, createSandboxCallbackBridgeAsset, createSandboxCallbackBridgeToken, DEFAULT_SANDBOX_CALLBACK_BRIDGE_MAX_BODY_BYTES, HTTP2_SANDBOX_CALLBACK_BRIDGE_ROUTE_ALLOWLIST, SANDBOX_CALLBACK_BRIDGE_HTTP2_MODE, sandboxCallbackBridgeDirectories, startSandboxCallbackBridgeServer, startSandboxCallbackBridgeWorker, syncRemoteTextFileWithHashSkip, syncSandboxCallbackBridgeEntrypoint, } from "./sandbox-callback-bridge.js";
|
|
12
|
+
import { createCommandManagedSandboxCallbackBridgeQueueClient, createSandboxCallbackBridgeAsset, createSandboxCallbackBridgeToken, DEFAULT_SANDBOX_CALLBACK_BRIDGE_MAX_BODY_BYTES, HTTP2_SANDBOX_CALLBACK_BRIDGE_ROUTE_ALLOWLIST, runSandboxBridgeControlCommand, SANDBOX_CALLBACK_BRIDGE_HTTP2_MODE, sandboxCallbackBridgeDirectories, startSandboxCallbackBridgeServer, startSandboxCallbackBridgeWorker, syncRemoteTextFileWithHashSkip, syncSandboxCallbackBridgeEntrypoint, } from "./sandbox-callback-bridge.js";
|
|
13
13
|
import { createHttp2BridgeServer, BridgeProcessCapacityError, } from "./http2-bridge-server.js";
|
|
14
14
|
import { createSandboxRunLogTailFactory, } from "./sandbox-run-log-stream.js";
|
|
15
15
|
import { DEFAULT_DUPLEX_BROKER_BUDGETS, DUPLEX_CHANNEL_LOST_ERROR_CODE, isSafeBridgeMethod, } from "./bridge-transport-contract.js";
|
|
@@ -34,13 +34,9 @@ export function postedIssueCommentLogMarker(method, requestPath, status, body) {
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
export { sanitizeRemoteExecutionEnv } from "./remote-execution-env.js";
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
// codex-local's 7-minute monitor). The value intentionally matches the
|
|
41
|
-
// recovery watchdog's ACTIVE_RUN_OUTPUT_CRITICAL_THRESHOLD_MS (4h) in
|
|
42
|
-
// server/src/services/recovery/service.ts so healthy long runs are never
|
|
43
|
-
// killed by the adapter before the watchdog would even consider them stuck.
|
|
37
|
+
// Four-hour wall-clock backstop for sandbox-backed adapter runs. Keep this
|
|
38
|
+
// execution limit independent of the earlier informational silence warnings
|
|
39
|
+
// and the short deadlines for bridge control operations.
|
|
44
40
|
export const DEFAULT_REMOTE_SANDBOX_ADAPTER_TIMEOUT_SEC = 14_400;
|
|
45
41
|
function parseObject(value) {
|
|
46
42
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
@@ -434,6 +430,8 @@ export async function runAdapterExecutionTargetProcess(runId, target, command, a
|
|
|
434
430
|
// after the clean process completion cannot latch a false mid-run loss. A
|
|
435
431
|
// control channel that died before this clean completion still fails the
|
|
436
432
|
// run closed.
|
|
433
|
+
if (!result.timedOut && typeof result.exitCode === "number" && Number.isInteger(result.exitCode) && result.exitCode >= 0)
|
|
434
|
+
options.onProcessStopped?.();
|
|
437
435
|
const settled = applyRunDispositionSeam(result, options.settleRunDisposition);
|
|
438
436
|
if (runLogTail) {
|
|
439
437
|
await runLogTail.finish({ stdout: result.stdout, stderr: result.stderr });
|
|
@@ -450,7 +448,7 @@ export async function runAdapterExecutionTargetProcess(runId, target, command, a
|
|
|
450
448
|
const env = target?.kind === "remote" && target.transport === "ssh"
|
|
451
449
|
? sanitizeRemoteExecutionEnv(options.env)
|
|
452
450
|
: options.env;
|
|
453
|
-
|
|
451
|
+
const result = await runChildProcess(runId, command, args, {
|
|
454
452
|
cwd: options.cwd,
|
|
455
453
|
env,
|
|
456
454
|
stdin: options.stdin,
|
|
@@ -463,6 +461,13 @@ export async function runAdapterExecutionTargetProcess(runId, target, command, a
|
|
|
463
461
|
localProcessSandbox: target?.kind === "local" || !target ? options.localProcessSandbox : null,
|
|
464
462
|
remoteExecution: adapterExecutionTargetToRemoteSpec(target),
|
|
465
463
|
});
|
|
464
|
+
// Closing an SSH client on timeout/disconnect does not prove the remote
|
|
465
|
+
// provider exited. SSH status 255 is transport failure, never a stop receipt.
|
|
466
|
+
if (!target || target.kind === "local" ||
|
|
467
|
+
(!result.timedOut && !result.signal && result.exitCode !== null && result.exitCode >= 0 && result.exitCode < 255)) {
|
|
468
|
+
options.onProcessStopped?.();
|
|
469
|
+
}
|
|
470
|
+
return result;
|
|
466
471
|
}
|
|
467
472
|
export async function runAdapterExecutionTargetShellCommand(runId, target, command, options) {
|
|
468
473
|
const onLog = options.onLog ?? (async () => { });
|
|
@@ -849,6 +854,8 @@ export async function prepareAdapterExecutionTargetRuntime(input) {
|
|
|
849
854
|
workspaceLocalDir: input.workspaceLocalDir,
|
|
850
855
|
workspaceRemoteDir: input.workspaceRemoteDir,
|
|
851
856
|
syncWorkspace: input.syncWorkspace,
|
|
857
|
+
workspaceFileMode: input.workspaceFileMode,
|
|
858
|
+
workspaceExclude: input.workspaceExclude,
|
|
852
859
|
assets: input.assets,
|
|
853
860
|
additionalSources: input.additionalSources,
|
|
854
861
|
onProgress: input.onProgress,
|
|
@@ -886,6 +893,7 @@ export async function prepareAdapterExecutionTargetRuntime(input) {
|
|
|
886
893
|
workspaceBaseline: input.workspaceBaseline,
|
|
887
894
|
workspaceGitSnapshot: input.workspaceGitSnapshot,
|
|
888
895
|
workspaceExclude: input.workspaceExclude,
|
|
896
|
+
workspaceFileMode: input.workspaceFileMode,
|
|
889
897
|
preserveAbsentOnRestore: input.preserveAbsentOnRestore,
|
|
890
898
|
assets: input.assets,
|
|
891
899
|
additionalSources: input.additionalSources,
|
|
@@ -903,6 +911,7 @@ export async function prepareAdapterExecutionTargetRuntime(input) {
|
|
|
903
911
|
additionalSourceDirs: prepared.additionalSourceDirs,
|
|
904
912
|
additionalSourceFailures: prepared.additionalSourceFailures,
|
|
905
913
|
workspaceSyncSnapshot: prepared.workspaceSyncSnapshot,
|
|
914
|
+
cleanupWorkspaceSnapshot: prepared.cleanupWorkspaceSnapshot,
|
|
906
915
|
restoreWorkspace: prepared.restoreWorkspace,
|
|
907
916
|
};
|
|
908
917
|
}
|
|
@@ -1283,6 +1292,11 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input) {
|
|
|
1283
1292
|
}
|
|
1284
1293
|
const target = input.target;
|
|
1285
1294
|
const onLog = input.onLog ?? (async () => { });
|
|
1295
|
+
// Failure diagnostics are best effort: stalled or failed run-log persistence
|
|
1296
|
+
// must not prevent sending shutdown or removing the bridge's session files.
|
|
1297
|
+
const logFailureWithoutWaiting = (message) => {
|
|
1298
|
+
void Promise.resolve().then(() => onLog("stderr", message)).catch(() => undefined);
|
|
1299
|
+
};
|
|
1286
1300
|
const runner = requireSandboxRunner(target);
|
|
1287
1301
|
// Run one unit of run-time work under its named wrapper span when a span
|
|
1288
1302
|
// runner is injected. Without a runner, run the work under the current run
|
|
@@ -1347,7 +1361,7 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input) {
|
|
|
1347
1361
|
else {
|
|
1348
1362
|
const payloadPath = path.posix.join(sessionDir, "command.b64");
|
|
1349
1363
|
const runPayloadSetup = async (script) => {
|
|
1350
|
-
const result = await runner
|
|
1364
|
+
const result = await runSandboxBridgeControlCommand(runner, {
|
|
1351
1365
|
command: shellCommand,
|
|
1352
1366
|
args: shellCommandArgs(script),
|
|
1353
1367
|
cwd: target.remoteCwd,
|
|
@@ -1376,7 +1390,7 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input) {
|
|
|
1376
1390
|
// as one foreground session command further down instead, so skip this.
|
|
1377
1391
|
if (!streamOutput) {
|
|
1378
1392
|
await onLog("stdout", `[paperclip] Starting ACP process session bridge in sandbox (${target.providerKey ?? "provider"}).\n`);
|
|
1379
|
-
const startResult = await runner
|
|
1393
|
+
const startResult = await runSandboxBridgeControlCommand(runner, {
|
|
1380
1394
|
command: shellCommand,
|
|
1381
1395
|
args: shellCommandArgs([
|
|
1382
1396
|
`mkdir -p ${shellQuote(stdinDir)} ${shellQuote(eventsDir)}`,
|
|
@@ -1421,6 +1435,28 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input) {
|
|
|
1421
1435
|
// a big earlier chunk, so the wrapper reads the stdin bytes out of order and
|
|
1422
1436
|
// corrupts a large prompt on the stdin path.
|
|
1423
1437
|
let stdinWriteChain = Promise.resolve();
|
|
1438
|
+
let stdinDeliveryFailed = false;
|
|
1439
|
+
const writeStdinFile = async (filePath, body) => {
|
|
1440
|
+
// Retry the same sequence, never the ACP request or the tool itself. Each
|
|
1441
|
+
// upload uses private temporary paths, and the wrapper drops sequences it
|
|
1442
|
+
// already consumed when a provider loses the final rename's response.
|
|
1443
|
+
for (let attempt = 1;; attempt += 1) {
|
|
1444
|
+
try {
|
|
1445
|
+
await client.writeTextFile(filePath, body);
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
catch (error) {
|
|
1449
|
+
// Plugin RPC preserves provider messages but not HTTP error classes.
|
|
1450
|
+
// Match the Daytona SDK and Cloudflare bridge's gateway diagnostics
|
|
1451
|
+
// exactly; shell failures and auth errors must still fail immediately.
|
|
1452
|
+
const gatewayFailure = error instanceof Error && (/^Request failed with status code (502|503|504)$/.test(error.message) ||
|
|
1453
|
+
/^Cloudflare sandbox bridge request failed with HTTP (502|503|504)\.$/.test(error.message));
|
|
1454
|
+
if (!gatewayFailure || attempt >= 3)
|
|
1455
|
+
throw error;
|
|
1456
|
+
await new Promise((resolve) => setTimeout(resolve, attempt * 250));
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1424
1460
|
let pollTimer = null;
|
|
1425
1461
|
const pendingRemoteEvents = [];
|
|
1426
1462
|
const token = createSandboxCallbackBridgeToken(18);
|
|
@@ -1547,15 +1583,24 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input) {
|
|
|
1547
1583
|
// Chain this write after the previous one, so the atomic rename for
|
|
1548
1584
|
// file N finishes before the write for file N+1 starts. Keep the
|
|
1549
1585
|
// per-message `sandbox.agentSession.sendInput` span inside the chain.
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1586
|
+
stdinWriteChain = stdinWriteChain.then(async () => {
|
|
1587
|
+
if (stdinDeliveryFailed)
|
|
1588
|
+
return;
|
|
1589
|
+
try {
|
|
1590
|
+
await runRuntimeWork(AGENT_SESSION_SEND_INPUT_SPAN, () => writeStdinFile(filePath, jsonLine(stdinPayload)));
|
|
1591
|
+
}
|
|
1592
|
+
catch {
|
|
1593
|
+
stdinDeliveryFailed = true;
|
|
1594
|
+
stopping = true;
|
|
1595
|
+
const message = "ACP process session input delivery failed.";
|
|
1596
|
+
// Flush the diagnostic before closing; destroy() can discard it
|
|
1597
|
+
// and leave only ACP's generic connection_close error. Do not
|
|
1598
|
+
// expose provider error text, which may contain a command payload.
|
|
1599
|
+
nextSocket.end(jsonLine({ type: "error", message }));
|
|
1600
|
+
// stop() awaits this input chain before sending shutdown. Run-log
|
|
1601
|
+
// persistence must not hold teardown open when it stalls or fails.
|
|
1602
|
+
logFailureWithoutWaiting(`[paperclip] ${message}\n`);
|
|
1603
|
+
}
|
|
1559
1604
|
});
|
|
1560
1605
|
}
|
|
1561
1606
|
}
|
|
@@ -1818,7 +1863,7 @@ export async function startAdapterExecutionTargetProcessSessionBridge(input) {
|
|
|
1818
1863
|
]);
|
|
1819
1864
|
stopReadingForShutdownAck = true;
|
|
1820
1865
|
if (!acknowledgedInTime) {
|
|
1821
|
-
|
|
1866
|
+
logFailureWithoutWaiting(`[paperclip] ACP process session wrapper did not acknowledge shutdown within ${DEFAULT_PROCESS_SESSION_SHUTDOWN_WAIT_MS}ms; removing the session directory anyway.\n`);
|
|
1822
1867
|
}
|
|
1823
1868
|
// Unconditional: this removal runs whether or not the wrapper
|
|
1824
1869
|
// acknowledged, and whether or not any event (real or forged) arrived
|
|
@@ -2246,6 +2291,14 @@ async function pollStdin() {
|
|
|
2246
2291
|
for (const name of entries) {
|
|
2247
2292
|
if (shuttingDown) break;
|
|
2248
2293
|
const entrySeq = Number.parseInt(name, 10);
|
|
2294
|
+
const file = path.posix.join(stdinDir, name);
|
|
2295
|
+
// A successful publication can be retried after its provider response
|
|
2296
|
+
// was lost, even after we consumed it. Never send those bytes twice or
|
|
2297
|
+
// move the expected sequence backwards. This also handles late uploads.
|
|
2298
|
+
if (Number.isFinite(entrySeq) && entrySeq < stdinExpectedSeq) {
|
|
2299
|
+
await fs.rm(file, { force: true }).catch(() => undefined);
|
|
2300
|
+
continue;
|
|
2301
|
+
}
|
|
2249
2302
|
// Hold the send order when an earlier file has not appeared. Do not consume
|
|
2250
2303
|
// this later file: wait for the missing file on a later cycle, bounded by
|
|
2251
2304
|
// the retry budget. After the budget, fail loud and advance past the gap,
|
|
@@ -2264,7 +2317,6 @@ async function pollStdin() {
|
|
|
2264
2317
|
stdinGapRetries = 0;
|
|
2265
2318
|
stdinExpectedSeq = entrySeq;
|
|
2266
2319
|
}
|
|
2267
|
-
const file = path.posix.join(stdinDir, name);
|
|
2268
2320
|
let message;
|
|
2269
2321
|
try {
|
|
2270
2322
|
// Hardening (I3): open with O_NOFOLLOW where the platform defines it,
|