@kylecheng3146/agent-ops 0.8.3 → 0.8.4
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.
|
@@ -483,7 +483,7 @@ export async function createInstallPlan(options) {
|
|
|
483
483
|
});
|
|
484
484
|
const contribution = {
|
|
485
485
|
artifacts: [
|
|
486
|
-
...(options.scope === "project" ? [{ id: "runtime-ignore", path: ".agent-ops/.gitignore", content: "/tasks/\n/reviews/\n" }] : []),
|
|
486
|
+
...(options.scope === "project" ? [{ id: "runtime-ignore", path: ".agent-ops/.gitignore", content: "/tasks/\n/reviews/\n/state/\n" }] : []),
|
|
487
487
|
...baseContribution.artifacts,
|
|
488
488
|
...loopContribution.artifacts
|
|
489
489
|
],
|
|
@@ -87,9 +87,6 @@ export function debugRemainingMs(state, now = Date.now()) {
|
|
|
87
87
|
export function debugStopCause(state, now = Date.now()) {
|
|
88
88
|
if (state.control?.paused === true)
|
|
89
89
|
return "user-pause";
|
|
90
|
-
const latest = state.receipts.at(-1);
|
|
91
|
-
if (latest?.cause !== null && latest?.cause !== undefined)
|
|
92
|
-
return latest.cause;
|
|
93
90
|
if (debugRemainingMs(state, now) === 0)
|
|
94
91
|
return "budget";
|
|
95
92
|
if (debugRounds(state) >= state.maxRounds)
|
|
@@ -102,7 +99,9 @@ export function debugStopCause(state, now = Date.now()) {
|
|
|
102
99
|
break;
|
|
103
100
|
stagnant++;
|
|
104
101
|
}
|
|
105
|
-
|
|
102
|
+
if (stagnant >= 2)
|
|
103
|
+
return state.strategy === null ? "strategy-required" : "stagnation";
|
|
104
|
+
return state.receipts.at(-1)?.cause ?? null;
|
|
106
105
|
}
|
|
107
106
|
/** Only reviewed reasoning/proof belongs in the digest; operations and clocks do not. */
|
|
108
107
|
export function debugProofDigest(state) {
|
|
@@ -349,9 +349,9 @@ export class DebugService {
|
|
|
349
349
|
fail("TASK_DEBUG_HISTORY_LIMIT", "Execution history is full; retain it and report the blocker.");
|
|
350
350
|
const productDigest = await this.#productDigest(root.debug);
|
|
351
351
|
const previousCandidate = root.debug.receipts.filter(r => r.kind === "verify" && (r.outcome === "PASS" || r.outcome === "FAIL")).at(-1)?.productDigest ?? sha256("[]");
|
|
352
|
-
const latestAttempt = root.debug.receipts.filter(r => r.kind === "verify").at(-1)?.productDigest ?? sha256("[]");
|
|
353
352
|
const cause = debugStopCause(root.debug);
|
|
354
|
-
|
|
353
|
+
// Recovery reruns the original verifier; changed product content still needs fresh proof.
|
|
354
|
+
if (cause !== null && !(["environment", "permission"].includes(cause) && (kind === "investigate" || kind === "verify")) && !(cause === "iterations" && kind === "review" && productDigest === previousCandidate))
|
|
355
355
|
fail("TASK_DEBUG_STOP_REQUIRED", `Runtime stop predicate: ${cause}. Record a checkpoint; resume alone cannot reset it.`);
|
|
356
356
|
const processIdentity = await nativeProcessIdentity(process.pid);
|
|
357
357
|
if (processIdentity === null)
|
|
@@ -579,7 +579,7 @@ export class DebugService {
|
|
|
579
579
|
const exhaustedAtEvent = foregroundActive
|
|
580
580
|
? remainingAtEvent === 0
|
|
581
581
|
: debugRemainingMs(root.debug) === 0 && event.timestamp > lastSealedAt;
|
|
582
|
-
if (!exhaustedAtEvent || otherCause !== null || !/^(?:繼續|继续|continue)[。.!!]?$/iu.test(event.text.trim()))
|
|
582
|
+
if (!exhaustedAtEvent || (otherCause !== null && !["environment", "permission"].includes(otherCause)) || !/^(?:繼續|继续|continue)[。.!!]?$/iu.test(event.text.trim()))
|
|
583
583
|
fail("TASK_DEBUG_GRANT_INVALID", "Only a contemporaneous human continue event extends exhausted time; other blockers remain authoritative.");
|
|
584
584
|
await this.#mutate(root, { ...root.debug, grants: [...root.debug.grants, { eventId: event.id, sessionId, sourceDigest: event.sourceDigest, grantedMs: DEBUG_EXTENSION_MS }], checkpoint: null });
|
|
585
585
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { TextDecoder } from "node:util";
|
|
2
2
|
import { AgentOpsError } from "../fs/paths.js";
|
|
3
3
|
const WINDOWS_RESERVED_SEGMENT = /^(?:aux|com[1-9]|con|lpt[1-9]|nul|prn)(?:\..*)?$/i;
|
|
4
|
+
const HARNESS_PROCESS_HEARTBEAT = /^\.(?:claude|codex)\/\.agent-ops-process-[1-9]\d*-[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
|
|
4
5
|
function sortedUnique(values) {
|
|
5
6
|
return [...new Set(values)].sort();
|
|
6
7
|
}
|
|
@@ -91,7 +92,9 @@ export async function collectChangeSurface(runner) {
|
|
|
91
92
|
])).filter(
|
|
92
93
|
// Indexed runtime was rejected above; only generated, untracked output is excluded.
|
|
93
94
|
(path) => !path.startsWith(".agent-ops/tasks/") &&
|
|
94
|
-
!path.startsWith(".agent-ops/reviews/")
|
|
95
|
+
!path.startsWith(".agent-ops/reviews/") &&
|
|
96
|
+
// Private marker locks keep these runtime heartbeats until process exit.
|
|
97
|
+
!HARNESS_PROCESS_HEARTBEAT.test(path));
|
|
95
98
|
return {
|
|
96
99
|
staged,
|
|
97
100
|
unstaged,
|