fix: --no-auth override, workflow revision in-place fix, state-driven heartbeats
Three orthogonal fixes bundled together so they re-land as a unit after earlier worktree-based reverts kept wiping them individually. 1. `--no-auth` flag now actually disables auth. Previously a stale FUSION_DAEMON_TOKEN in .env silently re-armed bearer-token auth despite the CLI flag. Added a `noAuth` option to ServerOptions; auth-middleware's isDaemonAuthActive/getDaemonToken short-circuit to false/undefined when set; CLI plumbs opts.noAuth through both createServer call sites. 2. Workflow review failures no longer reset every completed step. Previously a single CSS nit from a workflow reviewer could drag 5+ already-approved steps back through plan review, code review, and re-execution because determineRevisionResetStart fuzzy-matched feedback tokens against step names. handleWorkflowRevisionRequest, handleWorkflowStepFailure, and sendTaskBackForFix now call a new reopenLastStepForRevision helper that flips only the last non-pending step back to pending (with currentStep rewind via a newly-accepted updateTask field) — all earlier done steps stay done, and the agent applies the feedback as an in-place patch per the updated PROMPT.md instructions. determineRevisionResetStart stays exported as @deprecated so existing unit tests still link. 3. Heartbeat scheduling is now state-driven. Previously a non-ephemeral agent with a stale runtimeConfig.enabled=false on disk would never tick and the Pause/Resume button couldn't arm the timer without also flipping that hidden flag. HeartbeatTriggerScheduler's watchAgentLifecycle now registers on transitions into active/running and clears on transitions out; the tick and assignment-trigger guards key off state + ephemeral classification. InProcessRuntime's created/updated listeners and startup scan mirror the same semantics. runtimeConfig.enabled is only retained for ephemeral (task-worker) opt-out. Tests updated: agent-heartbeat.test.ts — one test renamed from "skips registration when enabled is false" (obsolete behavior) to "registers regardless of the legacy enabled flag"; 4 assignment-watching tests now pass a realistic `state: "active"` on mock agents. 207 heartbeat tests + 330 executor tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2215,7 +2215,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
|
||||
async updateTask(
|
||||
id: string,
|
||||
updates: { title?: string; description?: string; prompt?: string; worktree?: string | null; status?: string | null; dependencies?: string[]; steps?: import("./types.js").TaskStep[]; blockedBy?: string | null; assignedAgentId?: string | null; assigneeUserId?: string | null; checkedOutBy?: string | null; checkedOutAt?: string | null; paused?: boolean; baseBranch?: string | null; branch?: string | null; baseCommitSha?: string | null; size?: "S" | "M" | "L"; reviewLevel?: number; executionMode?: import("./types.js").ExecutionMode | null; mergeRetries?: number; workflowStepRetries?: number; stuckKillCount?: number | null; postReviewFixCount?: number | null; recoveryRetryCount?: number | null; taskDoneRetryCount?: number | null; nextRecoveryAt?: string | null; enabledWorkflowSteps?: string[]; modelProvider?: string | null; modelId?: string | null; validatorModelProvider?: string | null; validatorModelId?: string | null; planningModelProvider?: string | null; planningModelId?: string | null; thinkingLevel?: string | null; error?: string | null; summary?: string | null; sessionFile?: string | null; workflowStepResults?: import("./types.js").WorkflowStepResult[] | null; mergeDetails?: import("./types.js").MergeDetails | null; modifiedFiles?: string[] | null; missionId?: string | null; sliceId?: string | null },
|
||||
updates: { title?: string; description?: string; prompt?: string; worktree?: string | null; status?: string | null; dependencies?: string[]; steps?: import("./types.js").TaskStep[]; currentStep?: number; blockedBy?: string | null; assignedAgentId?: string | null; assigneeUserId?: string | null; checkedOutBy?: string | null; checkedOutAt?: string | null; paused?: boolean; baseBranch?: string | null; branch?: string | null; baseCommitSha?: string | null; size?: "S" | "M" | "L"; reviewLevel?: number; executionMode?: import("./types.js").ExecutionMode | null; mergeRetries?: number; workflowStepRetries?: number; stuckKillCount?: number | null; postReviewFixCount?: number | null; recoveryRetryCount?: number | null; taskDoneRetryCount?: number | null; nextRecoveryAt?: string | null; enabledWorkflowSteps?: string[]; modelProvider?: string | null; modelId?: string | null; validatorModelProvider?: string | null; validatorModelId?: string | null; planningModelProvider?: string | null; planningModelId?: string | null; thinkingLevel?: string | null; error?: string | null; summary?: string | null; sessionFile?: string | null; workflowStepResults?: import("./types.js").WorkflowStepResult[] | null; mergeDetails?: import("./types.js").MergeDetails | null; modifiedFiles?: string[] | null; missionId?: string | null; sliceId?: string | null },
|
||||
runContext?: RunMutationContext,
|
||||
): Promise<Task> {
|
||||
return this.withTaskLock(id, async () => {
|
||||
@@ -2262,6 +2262,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
}
|
||||
}
|
||||
if (updates.steps !== undefined) task.steps = updates.steps;
|
||||
if (updates.currentStep !== undefined) task.currentStep = updates.currentStep;
|
||||
if (updates.status === null) {
|
||||
task.status = undefined;
|
||||
} else if (updates.status !== undefined) {
|
||||
|
||||
Reference in New Issue
Block a user