@autopilot-harness/cli 0.2.5 → 0.2.6
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/assets/vendor/runtime.mjs +167 -41
- package/dist/init/types.d.ts +1 -1
- package/dist/init/types.js +1 -1
- package/package.json +5 -5
|
@@ -500,7 +500,7 @@ function evaluateVerifyReport(options) {
|
|
|
500
500
|
return { outcome: "pass" };
|
|
501
501
|
}
|
|
502
502
|
function hasNoCodeCompletionEvidence(options) {
|
|
503
|
-
const { reportPath, currentItemId, projectRoot } = options;
|
|
503
|
+
const { reportPath, currentItemId, projectRoot, notBefore } = options;
|
|
504
504
|
if (!currentItemId || typeof currentItemId !== "string") return false;
|
|
505
505
|
let root;
|
|
506
506
|
if (projectRoot !== void 0 && projectRoot !== null) {
|
|
@@ -528,8 +528,44 @@ function hasNoCodeCompletionEvidence(options) {
|
|
|
528
528
|
}
|
|
529
529
|
const ok = report.ok;
|
|
530
530
|
if (ok === false) return false;
|
|
531
|
+
const notBeforeRaw = typeof notBefore === "string" && notBefore.trim() && !notBefore.includes("\0") ? notBefore.trim() : null;
|
|
532
|
+
if (notBeforeRaw) {
|
|
533
|
+
const floor = Date.parse(notBeforeRaw);
|
|
534
|
+
if (Number.isNaN(floor)) return false;
|
|
535
|
+
const rawAt = report.at;
|
|
536
|
+
if (rawAt !== void 0 && rawAt !== null) {
|
|
537
|
+
const atMs = parseEvidenceAtMs(rawAt);
|
|
538
|
+
if (Number.isNaN(atMs) || atMs < floor) {
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
531
543
|
return true;
|
|
532
544
|
}
|
|
545
|
+
function parseEvidenceAtMs(rawAt) {
|
|
546
|
+
let atMs = NaN;
|
|
547
|
+
if (typeof rawAt === "number" && Number.isFinite(rawAt)) {
|
|
548
|
+
atMs = rawAt;
|
|
549
|
+
} else if (typeof rawAt === "string" && rawAt.trim() && !rawAt.includes("\0")) {
|
|
550
|
+
const trimmed = rawAt.trim();
|
|
551
|
+
if (/^[+-]?\d+(\.\d+)?([eE][+-]?\d+)?$/.test(trimmed)) {
|
|
552
|
+
const n = Number(trimmed);
|
|
553
|
+
if (Number.isFinite(n)) atMs = n;
|
|
554
|
+
} else {
|
|
555
|
+
atMs = Date.parse(trimmed);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (!Number.isNaN(atMs) && atMs >= 0) {
|
|
559
|
+
const whole = Math.trunc(atMs);
|
|
560
|
+
if (Math.abs(atMs - whole) < 1e-9) {
|
|
561
|
+
const digits = String(Math.abs(whole)).length;
|
|
562
|
+
if (digits >= 1 && digits <= 10) {
|
|
563
|
+
atMs = whole * 1e3;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
return atMs;
|
|
568
|
+
}
|
|
533
569
|
function defaultVerifyReportPath(projectRoot) {
|
|
534
570
|
const root = normalizeProjectRoot(projectRoot) ?? "";
|
|
535
571
|
return path2.join(root, ".autopilot", "verify-last.json");
|
|
@@ -1336,7 +1372,7 @@ var StateStore = class _StateStore {
|
|
|
1336
1372
|
* Column-only: neutralize fix/confirm/pending re-entry without ensure/session.
|
|
1337
1373
|
* Used when pause-threshold upsert failed but the session is still armed — a
|
|
1338
1374
|
* later completed stop must not resume the review loop via code_edited/pending
|
|
1339
|
-
* or
|
|
1375
|
+
* or checklist executing fix_round>0→E3 (fix_round cleared here).
|
|
1340
1376
|
*/
|
|
1341
1377
|
neutralizeReviewChain(conversationId) {
|
|
1342
1378
|
if (this.isInvalidConversationId(conversationId)) {
|
|
@@ -1419,7 +1455,8 @@ var StateStore = class _StateStore {
|
|
|
1419
1455
|
}
|
|
1420
1456
|
/**
|
|
1421
1457
|
* Column-only pause/disarm when the full upsertSession pause write failed.
|
|
1422
|
-
* Without this,
|
|
1458
|
+
* Without this, checklist executing completed stops can still hit E3 via
|
|
1459
|
+
* fix_round>0 / chain_pending while the session looks armed.
|
|
1423
1460
|
*/
|
|
1424
1461
|
pauseSessionForRepeatedErrors(conversationId, errorCount, lastError) {
|
|
1425
1462
|
if (this.isInvalidConversationId(conversationId)) {
|
|
@@ -2462,11 +2499,36 @@ var ReviewEngine = class {
|
|
|
2462
2499
|
if (chain.confirm_left === 0 || chain.item_confirm_complete === 1 && chain.confirm_left === null) {
|
|
2463
2500
|
return this.e5Gate(session, chain);
|
|
2464
2501
|
}
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2502
|
+
if (chain.chain_pending === 0 && chain.fix_round > 0 && chain.code_edited === 0 && chain.item_confirm_complete === 0 && isChecklistExecuting(session)) {
|
|
2503
|
+
const cid2 = session.conversation_id;
|
|
2504
|
+
const rearmed = this.store.exclusiveWrite(() => {
|
|
2505
|
+
if (!this.sessionRunnable(cid2)) {
|
|
2506
|
+
return { commit: false, value: false };
|
|
2507
|
+
}
|
|
2508
|
+
const fresh = this.store.getReviewChain(cid2);
|
|
2509
|
+
if (!fresh || fresh.code_edited === 1 || fresh.confirm_left !== null || fresh.item_confirm_complete === 1 || fresh.chain_pending === 1 || fresh.fix_round <= 0) {
|
|
2510
|
+
return { commit: false, value: false };
|
|
2511
|
+
}
|
|
2512
|
+
this.store.updateReviewChain(cid2, { code_edited: 1 });
|
|
2513
|
+
return { commit: true, value: true };
|
|
2514
|
+
});
|
|
2515
|
+
if (rearmed) {
|
|
2516
|
+
const live = this.store.getReviewChain(cid2);
|
|
2517
|
+
if (live?.code_edited === 1) {
|
|
2518
|
+
const fix = this.e2Fix(session, live);
|
|
2519
|
+
if (fix) return fix;
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2468
2522
|
}
|
|
2469
|
-
|
|
2523
|
+
const chainNow = this.store.getReviewChain(input.conversationId) ?? chain;
|
|
2524
|
+
if (chainNow.code_edited === 1) {
|
|
2525
|
+
return this.e2Fix(session, chainNow);
|
|
2526
|
+
}
|
|
2527
|
+
const inChain = chainNow.chain_pending === 1 || chainNow.fix_round > 0 && isChecklistExecuting(session);
|
|
2528
|
+
if (chainNow.confirm_left === null && chainNow.item_confirm_complete === 0 && inChain) {
|
|
2529
|
+
return this.e3ArmConfirm(session, chainNow);
|
|
2530
|
+
}
|
|
2531
|
+
return this.e0NoCodeContinue(session, chainNow);
|
|
2470
2532
|
} catch (err) {
|
|
2471
2533
|
const msg = err instanceof Error ? err.message : String(err);
|
|
2472
2534
|
if (msg.includes("No session for conversation") || msg.includes("Invalid conversation id")) {
|
|
@@ -2812,10 +2874,9 @@ var ReviewEngine = class {
|
|
|
2812
2874
|
this.store.updateReviewChain(conversationId, { code_edited: 1 });
|
|
2813
2875
|
}
|
|
2814
2876
|
} else {
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
}
|
|
2877
|
+
this.applyExecutingErrorRecoverChainAdjustments(conversationId, {
|
|
2878
|
+
fixTipAtClaim
|
|
2879
|
+
});
|
|
2819
2880
|
}
|
|
2820
2881
|
this.store.savePendingFollowup(conversationId, message, {
|
|
2821
2882
|
armChain: false
|
|
@@ -3118,29 +3179,32 @@ var ReviewEngine = class {
|
|
|
3118
3179
|
*/
|
|
3119
3180
|
emitRecoverAfterFailedClaim(conversationId, action, opts) {
|
|
3120
3181
|
const ambientSoftReset = opts?.ambientSoftReset === true;
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
const live = this.store.getReviewChain(conversationId)?.pending_followup?.trim() ?? "";
|
|
3138
|
-
if (!isRecoverFollowupMessage(live)) {
|
|
3139
|
-
return { commit: false, value: null };
|
|
3140
|
-
}
|
|
3141
|
-
this.store.clearChainPending(conversationId);
|
|
3142
|
-
return { commit: true, value: action };
|
|
3182
|
+
const writeRecover = () => this.store.exclusiveWrite(() => {
|
|
3183
|
+
const session = this.store.getSession(conversationId);
|
|
3184
|
+
if (!session || !this.sessionErrorRecoverable(session)) {
|
|
3185
|
+
return { commit: false, value: null };
|
|
3186
|
+
}
|
|
3187
|
+
const pending = this.store.getReviewChain(conversationId)?.pending_followup?.trim() ?? "";
|
|
3188
|
+
if (isRecoverFollowupMessage(pending)) {
|
|
3189
|
+
return { commit: false, value: null };
|
|
3190
|
+
}
|
|
3191
|
+
if (ambientSoftReset) {
|
|
3192
|
+
this.applySoftResetAmbientChainForErrorRecover(conversationId);
|
|
3193
|
+
} else {
|
|
3194
|
+
this.applyExecutingErrorRecoverChainAdjustments(conversationId);
|
|
3195
|
+
}
|
|
3196
|
+
this.store.savePendingFollowup(conversationId, action.message, {
|
|
3197
|
+
armChain: false
|
|
3143
3198
|
});
|
|
3199
|
+
const live = this.store.getReviewChain(conversationId)?.pending_followup?.trim() ?? "";
|
|
3200
|
+
if (!isRecoverFollowupMessage(live)) {
|
|
3201
|
+
return { commit: false, value: null };
|
|
3202
|
+
}
|
|
3203
|
+
this.store.clearChainPending(conversationId);
|
|
3204
|
+
return { commit: true, value: action };
|
|
3205
|
+
});
|
|
3206
|
+
try {
|
|
3207
|
+
return writeRecover();
|
|
3144
3208
|
} catch {
|
|
3145
3209
|
if (!this.sessionStillErrorRecoverable(conversationId)) {
|
|
3146
3210
|
return null;
|
|
@@ -3152,6 +3216,31 @@ var ReviewEngine = class {
|
|
|
3152
3216
|
}
|
|
3153
3217
|
} catch {
|
|
3154
3218
|
}
|
|
3219
|
+
try {
|
|
3220
|
+
return writeRecover();
|
|
3221
|
+
} catch {
|
|
3222
|
+
}
|
|
3223
|
+
try {
|
|
3224
|
+
return this.store.exclusiveWrite(() => {
|
|
3225
|
+
if (!this.sessionStillErrorRecoverable(conversationId)) {
|
|
3226
|
+
return { commit: false, value: null };
|
|
3227
|
+
}
|
|
3228
|
+
const pending = this.store.getReviewChain(conversationId)?.pending_followup?.trim() ?? "";
|
|
3229
|
+
if (isRecoverFollowupMessage(pending)) {
|
|
3230
|
+
return { commit: false, value: null };
|
|
3231
|
+
}
|
|
3232
|
+
this.store.savePendingFollowup(conversationId, action.message, {
|
|
3233
|
+
armChain: false
|
|
3234
|
+
});
|
|
3235
|
+
const live = this.store.getReviewChain(conversationId)?.pending_followup?.trim() ?? "";
|
|
3236
|
+
if (!isRecoverFollowupMessage(live)) {
|
|
3237
|
+
return { commit: false, value: null };
|
|
3238
|
+
}
|
|
3239
|
+
this.store.clearChainPending(conversationId);
|
|
3240
|
+
return { commit: true, value: action };
|
|
3241
|
+
});
|
|
3242
|
+
} catch {
|
|
3243
|
+
}
|
|
3155
3244
|
this.emit(conversationId, action);
|
|
3156
3245
|
try {
|
|
3157
3246
|
this.store.clearChainPending(conversationId);
|
|
@@ -3197,6 +3286,37 @@ var ReviewEngine = class {
|
|
|
3197
3286
|
return "failed";
|
|
3198
3287
|
}
|
|
3199
3288
|
}
|
|
3289
|
+
/**
|
|
3290
|
+
* Executing error-recover chain adjust (call under exclusiveWrite, before
|
|
3291
|
+
* savePendingFollowup + clearChainPending). Mirrors ambient readyForE3 /
|
|
3292
|
+
* resumeFix without soft-resetting mid-confirm/E5.
|
|
3293
|
+
*
|
|
3294
|
+
* Ready-for-E3 (delivered fix, chain_pending only, empty pending) arms
|
|
3295
|
+
* confirm_left=confirmRounds so post-recover continues E4 — not another E2
|
|
3296
|
+
* solely from fix_round>0. Mid-fix residue still forces code_edited.
|
|
3297
|
+
*/
|
|
3298
|
+
applyExecutingErrorRecoverChainAdjustments(conversationId, opts) {
|
|
3299
|
+
this.store.ensureReviewChain(conversationId);
|
|
3300
|
+
const chain = this.store.getReviewChain(conversationId);
|
|
3301
|
+
if (!chain) return;
|
|
3302
|
+
if (isRecoverFollowupMessage(chain.pending_followup?.trim() ?? "")) {
|
|
3303
|
+
return;
|
|
3304
|
+
}
|
|
3305
|
+
const pending = chain.pending_followup?.trim() ?? "";
|
|
3306
|
+
const readyForE3 = !this.isMidConfirmOrE5(chain) && chain.chain_pending === 1 && chain.code_edited === 0 && pending.length === 0;
|
|
3307
|
+
const rounds = this.config.confirmRounds;
|
|
3308
|
+
if (readyForE3 && rounds > 0) {
|
|
3309
|
+
this.store.updateReviewChain(conversationId, {
|
|
3310
|
+
confirm_left: rounds,
|
|
3311
|
+
code_edited: 0
|
|
3312
|
+
});
|
|
3313
|
+
return;
|
|
3314
|
+
}
|
|
3315
|
+
const resumeFix = !this.isMidConfirmOrE5(chain) && (this.isFixFollowupMessage(pending) || chain.code_edited === 1 || opts?.fixTipAtClaim === true || chain.fix_round > 0);
|
|
3316
|
+
if (resumeFix) {
|
|
3317
|
+
this.store.updateReviewChain(conversationId, { code_edited: 1 });
|
|
3318
|
+
}
|
|
3319
|
+
}
|
|
3200
3320
|
/**
|
|
3201
3321
|
* Ambient/planning error recover: drop confirm/pending arming so recover
|
|
3202
3322
|
* (armChain=false) cannot leave chain_pending=1 → phantom E3.
|
|
@@ -3287,7 +3407,9 @@ var ReviewEngine = class {
|
|
|
3287
3407
|
*/
|
|
3288
3408
|
e0NoCodeContinue(session, chain) {
|
|
3289
3409
|
if (!isChecklistExecuting(session)) return null;
|
|
3290
|
-
if (chain.code_edited === 1 || chain.confirm_left !== null || chain.item_confirm_complete === 1 || chain.chain_pending === 1)
|
|
3410
|
+
if (chain.code_edited === 1 || chain.confirm_left !== null || chain.item_confirm_complete === 1 || chain.chain_pending === 1 || // Mid-item review residue (e.g. recover cleared chain_pending): never
|
|
3411
|
+
// soft-advance/done — caller should have taken residue-E2 or E3.
|
|
3412
|
+
chain.fix_round > 0) {
|
|
3291
3413
|
return null;
|
|
3292
3414
|
}
|
|
3293
3415
|
const parsed = this.parseSessionChecklist(session);
|
|
@@ -3322,7 +3444,8 @@ var ReviewEngine = class {
|
|
|
3322
3444
|
if (!hasNoCodeCompletionEvidence({
|
|
3323
3445
|
reportPath,
|
|
3324
3446
|
currentItemId: liveId,
|
|
3325
|
-
projectRoot: trustRoot ?? void 0
|
|
3447
|
+
projectRoot: trustRoot ?? void 0,
|
|
3448
|
+
notBefore: liveChain?.updated_at
|
|
3326
3449
|
})) {
|
|
3327
3450
|
return null;
|
|
3328
3451
|
}
|
|
@@ -3378,7 +3501,7 @@ var ReviewEngine = class {
|
|
|
3378
3501
|
return { commit: false, value: null };
|
|
3379
3502
|
}
|
|
3380
3503
|
const fresh = this.store.getReviewChain(cid2);
|
|
3381
|
-
if (!fresh || fresh.code_edited === 1 || fresh.confirm_left !== null || fresh.item_confirm_complete === 1 || fresh.chain_pending === 1) {
|
|
3504
|
+
if (!fresh || fresh.code_edited === 1 || fresh.confirm_left !== null || fresh.item_confirm_complete === 1 || fresh.chain_pending === 1 || fresh.fix_round > 0) {
|
|
3382
3505
|
return { commit: false, value: null };
|
|
3383
3506
|
}
|
|
3384
3507
|
const refreshed = this.parseSessionChecklist(lockedSession);
|
|
@@ -3398,7 +3521,8 @@ var ReviewEngine = class {
|
|
|
3398
3521
|
if (!hasNoCodeCompletionEvidence({
|
|
3399
3522
|
reportPath,
|
|
3400
3523
|
currentItemId: targets.current.id,
|
|
3401
|
-
projectRoot: trustRoot ?? void 0
|
|
3524
|
+
projectRoot: trustRoot ?? void 0,
|
|
3525
|
+
notBefore: fresh.updated_at
|
|
3402
3526
|
})) {
|
|
3403
3527
|
return { commit: false, value: null };
|
|
3404
3528
|
}
|
|
@@ -3489,7 +3613,7 @@ var ReviewEngine = class {
|
|
|
3489
3613
|
return { commit: false, value: null };
|
|
3490
3614
|
}
|
|
3491
3615
|
const fresh = this.store.getReviewChain(cid2);
|
|
3492
|
-
if (!fresh || fresh.code_edited === 1 || fresh.confirm_left !== null || fresh.item_confirm_complete === 1 || fresh.chain_pending === 1) {
|
|
3616
|
+
if (!fresh || fresh.code_edited === 1 || fresh.confirm_left !== null || fresh.item_confirm_complete === 1 || fresh.chain_pending === 1 || fresh.fix_round > 0) {
|
|
3493
3617
|
return { commit: false, value: null };
|
|
3494
3618
|
}
|
|
3495
3619
|
const refreshed = this.parseSessionChecklist(sess);
|
|
@@ -3508,7 +3632,8 @@ var ReviewEngine = class {
|
|
|
3508
3632
|
if (hasNoCodeCompletionEvidence({
|
|
3509
3633
|
reportPath,
|
|
3510
3634
|
currentItemId: lockedItem.id,
|
|
3511
|
-
projectRoot: trustRoot ?? void 0
|
|
3635
|
+
projectRoot: trustRoot ?? void 0,
|
|
3636
|
+
notBefore: fresh.updated_at
|
|
3512
3637
|
})) {
|
|
3513
3638
|
return { commit: false, value: null };
|
|
3514
3639
|
}
|
|
@@ -3568,7 +3693,7 @@ var ReviewEngine = class {
|
|
|
3568
3693
|
return { commit: false, value: false };
|
|
3569
3694
|
}
|
|
3570
3695
|
const fresh = this.store.getReviewChain(conversationId);
|
|
3571
|
-
if (!fresh || fresh.code_edited === 1 || fresh.confirm_left !== null || fresh.item_confirm_complete === 1 || fresh.chain_pending === 1) {
|
|
3696
|
+
if (!fresh || fresh.code_edited === 1 || fresh.confirm_left !== null || fresh.item_confirm_complete === 1 || fresh.chain_pending === 1 || fresh.fix_round > 0) {
|
|
3572
3697
|
return { commit: false, value: false };
|
|
3573
3698
|
}
|
|
3574
3699
|
this.store.updateReviewChain(conversationId, {
|
|
@@ -3651,7 +3776,8 @@ var ReviewEngine = class {
|
|
|
3651
3776
|
return { commit: false, value: null };
|
|
3652
3777
|
}
|
|
3653
3778
|
const fresh = this.store.getReviewChain(cid2);
|
|
3654
|
-
|
|
3779
|
+
const pendingLive = fresh?.pending_followup?.trim() ?? "";
|
|
3780
|
+
if (!fresh || fresh.code_edited === 1 || fresh.confirm_left !== null || fresh.item_confirm_complete === 1 || this.isFixFollowupMessage(pendingLive) || isRecoverOrStuckFollowupMessage(pendingLive)) {
|
|
3655
3781
|
return { commit: false, value: null };
|
|
3656
3782
|
}
|
|
3657
3783
|
const sessionRound = this.nextSessionRound(fresh);
|
package/dist/init/types.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export interface HooksFile {
|
|
|
75
75
|
[event: string]: HookCommand[] | undefined;
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
-
export declare const PACKAGE_VERSION = "0.2.
|
|
78
|
+
export declare const PACKAGE_VERSION = "0.2.6";
|
|
79
79
|
export declare const HOOK_MARKER = "autopilot-harness";
|
|
80
80
|
export declare const AUTOPILOT_EVENTS: readonly ["beforeSubmitPrompt", "afterFileEdit", "stop"];
|
|
81
81
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/init/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autopilot-harness/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Autopilot harness CLI — structured planning, checklist execution, and multi-lens self-review for Cursor and Claude Code (bin: autopilot-harness)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"@clack/prompts": "^0.10.0",
|
|
32
32
|
"commander": "^13.1.0",
|
|
33
33
|
"yaml": "^2.7.0",
|
|
34
|
-
"@autopilot-harness/core": "0.2.
|
|
35
|
-
"@autopilot-harness/
|
|
36
|
-
"@autopilot-harness/
|
|
37
|
-
"@autopilot-harness/port-
|
|
34
|
+
"@autopilot-harness/core": "0.2.6",
|
|
35
|
+
"@autopilot-harness/i18n": "0.2.6",
|
|
36
|
+
"@autopilot-harness/port-claude-code": "0.2.6",
|
|
37
|
+
"@autopilot-harness/port-cursor": "0.2.6"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"esbuild": "^0.25.12",
|