fix: emit real checkpoint artifact for wrapper integration

This commit is contained in:
Eve
2026-04-24 08:37:59 +08:00
parent e5db414a00
commit 213804a6f7
2 changed files with 68 additions and 10 deletions

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env node
import fs from 'fs';
import path from 'path';
function fail(code, message) {
process.stderr.write(`${code}: ${message}\n`);
@@ -124,6 +125,35 @@ function toSlug(value) {
.slice(0, 48);
}
function ensureCheckpointArtifact(externalizedCheckpointPath, input, classificationResult) {
if (classificationResult.classification !== 'long_task') return null;
if (!classificationResult.silentCandidate) return null;
if (!externalizedCheckpointPath) return null;
const artifactPath = path.resolve(process.cwd(), externalizedCheckpointPath);
const artifact = {
kind: 'long_task_checkpoint',
triggerKind: input.triggerKind || 'artifact',
checkpointTrigger: input.checkpointTrigger || '',
currentStep: input.currentStep || '',
nextStep: input.nextStep || '',
waitingOn: input.waitingOn || '',
blocker: input.blocker || '',
};
fs.mkdirSync(path.dirname(artifactPath), { recursive: true });
fs.writeFileSync(artifactPath, JSON.stringify(artifact, null, 2) + '\n', 'utf8');
const stats = fs.statSync(artifactPath);
const readable = fs.readFileSync(artifactPath, 'utf8');
return {
absolutePath: artifactPath,
bytes: stats.size,
readable: readable.trim().length > 0,
};
}
function buildExternalizedCheckpointPath(input, classificationResult) {
if (classificationResult.classification !== 'long_task') return '';
if (!classificationResult.silentCandidate) return '';
@@ -138,14 +168,16 @@ function buildExternalizedCheckpointPath(input, classificationResult) {
return `checkpoints/${stableSeed}.json`;
}
function buildProgressEvidence(input, classificationResult, externalizedCheckpointPath) {
function buildProgressEvidence(input, classificationResult, externalizedCheckpointPath, checkpointArtifact) {
if (classificationResult.classification !== 'long_task') return null;
if (!classificationResult.silentCandidate) return null;
if (!externalizedCheckpointPath) return null;
if (!checkpointArtifact || checkpointArtifact.readable !== true) return null;
return {
sessionKey: toSlug([input.currentStep, input.waitingOn, input.nextStep].filter(Boolean).join('-')) || 'long-task-session',
checkpointPath: externalizedCheckpointPath,
verificationResult: `checkpoint artifact readable at ${externalizedCheckpointPath}`,
};
}
@@ -197,7 +229,8 @@ function main() {
const classificationResult = classify(input);
const taskRecord = bootstrapTaskState(input, classificationResult);
const externalizedCheckpointPath = buildExternalizedCheckpointPath(input, classificationResult);
const progressEvidence = buildProgressEvidence(input, classificationResult, externalizedCheckpointPath);
const checkpointArtifact = ensureCheckpointArtifact(externalizedCheckpointPath, input, classificationResult);
const progressEvidence = buildProgressEvidence(input, classificationResult, externalizedCheckpointPath, checkpointArtifact);
const silentLaunch = validateSilentLaunch(input, classificationResult);
const handoff = planHandoff(classificationResult);
@@ -210,6 +243,7 @@ function main() {
taskRecord,
progressEvidence,
externalizedCheckpointPath,
checkpointArtifact,
silentLaunchOk: silentLaunch.ok,
silentLaunchReason: silentLaunch.reason,
recommendedFallback: silentLaunch.recommendedFallback,