feat(FN-3539): remove duplicate todos entry and update navigation docs
Merged branch removes the duplicate desktop "Todos" nav entry from the Header, syncs the `allowParallelExecution` runtime toggle into `AgentDetailView`, and updates the corresponding docs (agents.md, settings-reference.md, todo-view.md, dashboard-guide.md) to reflect the navigation change. Tests wer Fusion-Task-Id: FN-3539
This commit is contained in:
@@ -6722,7 +6722,8 @@ Task with acceptance criteria
|
||||
// Full reset: prior branch/summary/recovery state discarded so the next
|
||||
// run starts from scratch.
|
||||
expect(retried.branch).toBeUndefined();
|
||||
expect(retried.baseBranch).toBeUndefined();
|
||||
expect(retried.baseBranch).toBe("main");
|
||||
expect(retried.executionStartBranch).toBeUndefined();
|
||||
expect(retried.baseCommitSha).toBeUndefined();
|
||||
expect(retried.summary).toBeUndefined();
|
||||
expect(retried.recoveryRetryCount).toBeUndefined();
|
||||
@@ -6761,7 +6762,8 @@ Task with acceptance criteria
|
||||
expect(respec.blockedBy).toBeUndefined();
|
||||
expect(respec.workflowStepResults).toBeUndefined();
|
||||
expect(respec.branch).toBeUndefined();
|
||||
expect(respec.baseBranch).toBeUndefined();
|
||||
expect(respec.baseBranch).toBe("main");
|
||||
expect(respec.executionStartBranch).toBeUndefined();
|
||||
expect(respec.baseCommitSha).toBeUndefined();
|
||||
expect(respec.summary).toBeUndefined();
|
||||
expect(respec.recoveryRetryCount).toBeUndefined();
|
||||
@@ -7093,13 +7095,13 @@ Task with acceptance criteria
|
||||
expect(duplicated.blockedBy).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does NOT copy baseBranch", async () => {
|
||||
it("copies baseBranch", async () => {
|
||||
const task = await store.createTask({ description: "Test task" });
|
||||
await store.updateTask(task.id, { baseBranch: "some-branch" });
|
||||
|
||||
const duplicated = await store.duplicateTask(task.id);
|
||||
|
||||
expect(duplicated.baseBranch).toBeUndefined();
|
||||
expect(duplicated.baseBranch).toBe("some-branch");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11238,39 +11240,39 @@ describe("RunMutationContext", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("clearStaleBaseBranchReferences (FN-2165)", () => {
|
||||
describe("clearStaleExecutionStartBranchReferences (FN-2165)", () => {
|
||||
it("nulls baseBranch on live tasks that reference a deleted branch", async () => {
|
||||
const upstream = await store.createTask({ description: "Upstream" });
|
||||
const dependent = await store.createTask({ description: "Dependent" });
|
||||
await store.updateTask(dependent.id, {
|
||||
baseBranch: `fusion/${upstream.id.toLowerCase()}-2`,
|
||||
executionStartBranch: `fusion/${upstream.id.toLowerCase()}-2`,
|
||||
});
|
||||
|
||||
const cleared = store.clearStaleBaseBranchReferences([
|
||||
const cleared = store.clearStaleExecutionStartBranchReferences([
|
||||
`fusion/${upstream.id.toLowerCase()}-2`,
|
||||
]);
|
||||
|
||||
expect(cleared).toEqual([dependent.id]);
|
||||
const reloaded = await store.getTask(dependent.id);
|
||||
expect(reloaded.baseBranch).toBeUndefined();
|
||||
expect(reloaded.executionStartBranch).toBeUndefined();
|
||||
});
|
||||
|
||||
it("excludes the owner task so archival doesn't null its own baseBranch", async () => {
|
||||
const upstream = await store.createTask({ description: "Upstream" });
|
||||
await store.updateTask(upstream.id, { baseBranch: "fusion/some-base" });
|
||||
await store.updateTask(upstream.id, { executionStartBranch: "fusion/some-base" });
|
||||
|
||||
const cleared = store.clearStaleBaseBranchReferences(
|
||||
const cleared = store.clearStaleExecutionStartBranchReferences(
|
||||
["fusion/some-base"],
|
||||
upstream.id,
|
||||
);
|
||||
|
||||
expect(cleared).toEqual([]);
|
||||
const reloaded = await store.getTask(upstream.id);
|
||||
expect(reloaded.baseBranch).toBe("fusion/some-base");
|
||||
expect(reloaded.executionStartBranch).toBe("fusion/some-base");
|
||||
});
|
||||
|
||||
it("returns [] and is a no-op when no branches given", () => {
|
||||
expect(store.clearStaleBaseBranchReferences([])).toEqual([]);
|
||||
expect(store.clearStaleExecutionStartBranchReferences([])).toEqual([]);
|
||||
});
|
||||
|
||||
it("clears baseBranch on multiple dependents in one call", async () => {
|
||||
@@ -11279,18 +11281,18 @@ describe("RunMutationContext", () => {
|
||||
store.createTask({ description: "B" }),
|
||||
store.createTask({ description: "C" }),
|
||||
]);
|
||||
await store.updateTask(a.id, { baseBranch: "fusion/gone-a" });
|
||||
await store.updateTask(b.id, { baseBranch: "fusion/gone-b" });
|
||||
await store.updateTask(c.id, { baseBranch: "fusion/still-alive" });
|
||||
await store.updateTask(a.id, { executionStartBranch: "fusion/gone-a" });
|
||||
await store.updateTask(b.id, { executionStartBranch: "fusion/gone-b" });
|
||||
await store.updateTask(c.id, { executionStartBranch: "fusion/still-alive" });
|
||||
|
||||
const cleared = store.clearStaleBaseBranchReferences([
|
||||
const cleared = store.clearStaleExecutionStartBranchReferences([
|
||||
"fusion/gone-a",
|
||||
"fusion/gone-b",
|
||||
]);
|
||||
|
||||
expect(cleared.sort()).toEqual([a.id, b.id].sort());
|
||||
const cReloaded = await store.getTask(c.id);
|
||||
expect(cReloaded.baseBranch).toBe("fusion/still-alive");
|
||||
expect(cReloaded.executionStartBranch).toBe("fusion/still-alive");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -217,7 +217,7 @@ async function migrateTasks(fusionDir: string, db: Database): Promise<void> {
|
||||
const insertStmt = db.prepare(`
|
||||
INSERT OR REPLACE INTO tasks (
|
||||
id, title, description, priority, "column", status, size, reviewLevel, currentStep,
|
||||
worktree, blockedBy, paused, baseBranch, baseCommitSha, modelPresetId,
|
||||
worktree, blockedBy, paused, baseBranch, branch, executionStartBranch, baseCommitSha, modelPresetId,
|
||||
modelProvider, modelId, validatorModelProvider, validatorModelId,
|
||||
mergeRetries, recoveryRetryCount, nextRecoveryAt,
|
||||
error, summary, thinkingLevel, createdAt, updatedAt,
|
||||
@@ -226,8 +226,8 @@ async function migrateTasks(fusionDir: string, db: Database): Promise<void> {
|
||||
sourceIssueProvider, sourceIssueRepository, sourceIssueExternalIssueId, sourceIssueNumber, sourceIssueUrl,
|
||||
mergeDetails, breakIntoSubtasks, enabledWorkflowSteps, modifiedFiles, sliceId
|
||||
) VALUES (
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
)
|
||||
`);
|
||||
|
||||
@@ -260,6 +260,8 @@ async function migrateTasks(fusionDir: string, db: Database): Promise<void> {
|
||||
task.blockedBy ?? null,
|
||||
task.paused ? 1 : 0,
|
||||
task.baseBranch ?? null,
|
||||
task.branch ?? null,
|
||||
task.executionStartBranch ?? null,
|
||||
task.baseCommitSha ?? null,
|
||||
task.modelPresetId ?? null,
|
||||
task.modelProvider ?? null,
|
||||
|
||||
@@ -165,6 +165,7 @@ CREATE TABLE IF NOT EXISTS tasks (
|
||||
paused INTEGER DEFAULT 0,
|
||||
baseBranch TEXT,
|
||||
branch TEXT,
|
||||
executionStartBranch TEXT,
|
||||
baseCommitSha TEXT,
|
||||
modelPresetId TEXT,
|
||||
modelProvider TEXT,
|
||||
@@ -1145,6 +1146,10 @@ export class Database {
|
||||
private migrate(): void {
|
||||
const version = this.getSchemaVersion() || 1;
|
||||
|
||||
if (this.hasTable("tasks")) {
|
||||
this.addColumnIfMissing("tasks", "executionStartBranch", "TEXT");
|
||||
}
|
||||
|
||||
if (version >= SCHEMA_VERSION) return;
|
||||
|
||||
if (version < 2) {
|
||||
|
||||
@@ -42,6 +42,7 @@ interface TaskRow {
|
||||
blockedBy: string | null;
|
||||
paused: number | null;
|
||||
baseBranch: string | null;
|
||||
executionStartBranch: string | null;
|
||||
branch: string | null;
|
||||
baseCommitSha: string | null;
|
||||
modelPresetId: string | null;
|
||||
@@ -673,6 +674,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
blockedBy: row.blockedBy || undefined,
|
||||
paused: row.paused ? true : undefined,
|
||||
baseBranch: row.baseBranch || undefined,
|
||||
executionStartBranch: row.executionStartBranch || undefined,
|
||||
branch: row.branch || undefined,
|
||||
baseCommitSha: row.baseCommitSha || undefined,
|
||||
modelPresetId: row.modelPresetId || undefined,
|
||||
@@ -997,7 +999,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
const prefix = tableAlias ? `${tableAlias}.` : "";
|
||||
return [
|
||||
"id", "title", "description", "priority", "\"column\"", "status", "size", "reviewLevel", "currentStep",
|
||||
"worktree", "blockedBy", "paused", "baseBranch", "branch", "baseCommitSha",
|
||||
"worktree", "blockedBy", "paused", "baseBranch", "branch", "executionStartBranch", "baseCommitSha",
|
||||
"modelPresetId", "modelProvider", "modelId",
|
||||
"validatorModelProvider", "validatorModelId",
|
||||
"planningModelProvider", "planningModelId",
|
||||
@@ -1046,7 +1048,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
private getTaskSelectClauseWithActivityLogLimit(limit: number): string {
|
||||
const columns = [
|
||||
"id", "title", "description", "priority", "\"column\"", "status", "size", "reviewLevel", "currentStep",
|
||||
"worktree", "blockedBy", "paused", "baseBranch", "branch", "baseCommitSha",
|
||||
"worktree", "blockedBy", "paused", "baseBranch", "branch", "executionStartBranch", "baseCommitSha",
|
||||
"modelPresetId", "modelProvider", "modelId",
|
||||
"validatorModelProvider", "validatorModelId",
|
||||
"planningModelProvider", "planningModelId",
|
||||
@@ -1091,7 +1093,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
this.db.prepare(`
|
||||
INSERT INTO tasks (
|
||||
id, title, description, priority, "column", status, size, reviewLevel, currentStep,
|
||||
worktree, blockedBy, paused, baseBranch, branch, baseCommitSha, modelPresetId, modelProvider,
|
||||
worktree, blockedBy, paused, baseBranch, branch, executionStartBranch, baseCommitSha, modelPresetId, modelProvider,
|
||||
modelId, validatorModelProvider, validatorModelId, planningModelProvider, planningModelId, mergeRetries,
|
||||
workflowStepRetries, stuckKillCount, postReviewFixCount, recoveryRetryCount, taskDoneRetryCount, verificationFailureCount, mergeConflictBounceCount, nextRecoveryAt, error,
|
||||
summary, thinkingLevel, executionMode, tokenUsageInputTokens, tokenUsageOutputTokens, tokenUsageCachedTokens,
|
||||
@@ -1102,7 +1104,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
sourceIssueProvider, sourceIssueRepository, sourceIssueExternalIssueId, sourceIssueNumber, sourceIssueUrl,
|
||||
mergeDetails, breakIntoSubtasks, enabledWorkflowSteps, modifiedFiles, missionId, sliceId, assignedAgentId, pausedByAgentId, assigneeUserId, nodeId, effectiveNodeId, effectiveNodeSource, sourceType, sourceAgentId, sourceRunId, sourceSessionId, sourceMessageId, sourceParentTaskId, sourceMetadata, checkedOutBy, checkedOutAt
|
||||
) VALUES (
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
|
||||
)
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
title = excluded.title,
|
||||
@@ -1118,6 +1120,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
paused = excluded.paused,
|
||||
baseBranch = excluded.baseBranch,
|
||||
branch = excluded.branch,
|
||||
executionStartBranch = excluded.executionStartBranch,
|
||||
baseCommitSha = excluded.baseCommitSha,
|
||||
modelPresetId = excluded.modelPresetId,
|
||||
modelProvider = excluded.modelProvider,
|
||||
@@ -1200,6 +1203,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
task.paused ? 1 : 0,
|
||||
task.baseBranch ?? null,
|
||||
task.branch ?? null,
|
||||
task.executionStartBranch ?? null,
|
||||
task.baseCommitSha ?? null,
|
||||
task.modelPresetId ?? null,
|
||||
task.modelProvider ?? null,
|
||||
@@ -2354,8 +2358,9 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
columnMovedAt: now,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
// Explicitly NOT copied: worktree, status, blockedBy, paused, baseBranch,
|
||||
// Explicitly NOT copied: worktree, status, blockedBy, paused, executionStartBranch,
|
||||
// attachments, comments, prInfo, agent logs, size, reviewLevel
|
||||
baseBranch: sourceTask.baseBranch,
|
||||
};
|
||||
|
||||
const newDir = this.taskDir(newId);
|
||||
@@ -2947,7 +2952,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
// starts from scratch.
|
||||
if (fromColumn === "in-review" && (toColumn === "todo" || toColumn === "triage")) {
|
||||
task.branch = undefined;
|
||||
task.baseBranch = undefined;
|
||||
task.executionStartBranch = undefined;
|
||||
task.baseCommitSha = undefined;
|
||||
task.summary = undefined;
|
||||
task.recoveryRetryCount = undefined;
|
||||
@@ -2995,7 +3000,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
|
||||
async updateTask(
|
||||
id: string,
|
||||
updates: { title?: string; description?: string; priority?: TaskPriority | null; prompt?: string; worktree?: string | null; status?: string | null; dependencies?: string[]; steps?: import("./types.js").TaskStep[]; currentStep?: number; blockedBy?: string | null; assignedAgentId?: string | null; pausedByAgentId?: string | null; assigneeUserId?: string | null; nodeId?: string | null; effectiveNodeId?: string | null; effectiveNodeSource?: 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; verificationFailureCount?: number | null; mergeConflictBounceCount?: 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; executionStartedAt?: string | null; executionCompletedAt?: string | null; workflowStepResults?: import("./types.js").WorkflowStepResult[] | null; mergeDetails?: import("./types.js").MergeDetails | null; sourceIssue?: import("./types.js").TaskSourceIssue | null; tokenUsage?: import("./types.js").TaskTokenUsage | null; modifiedFiles?: string[] | null; missionId?: string | null; sliceId?: string | null },
|
||||
updates: { title?: string; description?: string; priority?: TaskPriority | null; prompt?: string; worktree?: string | null; status?: string | null; dependencies?: string[]; steps?: import("./types.js").TaskStep[]; currentStep?: number; blockedBy?: string | null; assignedAgentId?: string | null; pausedByAgentId?: string | null; assigneeUserId?: string | null; nodeId?: string | null; effectiveNodeId?: string | null; effectiveNodeSource?: string | null; checkedOutBy?: string | null; checkedOutAt?: string | null; paused?: boolean; baseBranch?: string | null; branch?: string | null; executionStartBranch?: 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; verificationFailureCount?: number | null; mergeConflictBounceCount?: 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; executionStartedAt?: string | null; executionCompletedAt?: string | null; workflowStepResults?: import("./types.js").WorkflowStepResult[] | null; mergeDetails?: import("./types.js").MergeDetails | null; sourceIssue?: import("./types.js").TaskSourceIssue | null; tokenUsage?: import("./types.js").TaskTokenUsage | null; modifiedFiles?: string[] | null; missionId?: string | null; sliceId?: string | null },
|
||||
runContext?: RunMutationContext,
|
||||
): Promise<Task> {
|
||||
return this.withTaskLock(id, async () => {
|
||||
@@ -3123,6 +3128,11 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
} else if (updates.branch !== undefined) {
|
||||
task.branch = updates.branch;
|
||||
}
|
||||
if (updates.executionStartBranch === null) {
|
||||
task.executionStartBranch = undefined;
|
||||
} else if (updates.executionStartBranch !== undefined) {
|
||||
task.executionStartBranch = updates.executionStartBranch;
|
||||
}
|
||||
if (updates.baseCommitSha === null) {
|
||||
task.baseCommitSha = undefined;
|
||||
} else if (updates.baseCommitSha !== undefined) {
|
||||
@@ -3997,7 +4007,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
}
|
||||
}
|
||||
if (deleted.length > 0) {
|
||||
this.clearStaleBaseBranchReferences(deleted, task.id);
|
||||
this.clearStaleExecutionStartBranchReferences(deleted, task.id);
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
@@ -4015,11 +4025,11 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
*
|
||||
* @returns IDs of tasks whose baseBranch was cleared
|
||||
*/
|
||||
clearStaleBaseBranchReferences(deletedBranches: string[], ownerTaskId?: string): string[] {
|
||||
clearStaleExecutionStartBranchReferences(deletedBranches: string[], ownerTaskId?: string): string[] {
|
||||
if (deletedBranches.length === 0) return [];
|
||||
const placeholders = deletedBranches.map(() => "?").join(",");
|
||||
const params: string[] = [...deletedBranches];
|
||||
let whereClause = `baseBranch IN (${placeholders})`;
|
||||
let whereClause = `executionStartBranch IN (${placeholders})`;
|
||||
if (ownerTaskId) {
|
||||
whereClause += ` AND id != ?`;
|
||||
params.push(ownerTaskId);
|
||||
@@ -4030,7 +4040,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
|
||||
if (rows.length === 0) return [];
|
||||
const update = this.db.prepare(
|
||||
`UPDATE tasks SET baseBranch = NULL, updatedAt = ? WHERE id = ?`,
|
||||
`UPDATE tasks SET executionStartBranch = NULL, updatedAt = ? WHERE id = ?`,
|
||||
);
|
||||
const now = new Date().toISOString();
|
||||
const clearedIds: string[] = [];
|
||||
@@ -4040,7 +4050,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
if (this.isWatching) {
|
||||
const cached = this.taskCache.get(row.id);
|
||||
if (cached) {
|
||||
cached.baseBranch = undefined;
|
||||
cached.executionStartBranch = undefined;
|
||||
cached.updatedAt = now;
|
||||
}
|
||||
}
|
||||
@@ -5900,7 +5910,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
planningModelId: entry.planningModelId,
|
||||
breakIntoSubtasks: entry.breakIntoSubtasks,
|
||||
modifiedFiles: entry.modifiedFiles,
|
||||
// Intentionally NOT restoring: worktree, status, blockedBy, paused, baseBranch, baseCommitSha, error
|
||||
// Intentionally NOT restoring: worktree, status, blockedBy, paused, executionStartBranch, baseCommitSha, error
|
||||
};
|
||||
|
||||
// Write task.json
|
||||
|
||||
@@ -883,19 +883,19 @@ export interface Task {
|
||||
paused?: boolean;
|
||||
/** When set, this task was paused because the agent with this ID was paused. Cleared when the agent resumes. Distinct from user-initiated pause. */
|
||||
pausedByAgentId?: string;
|
||||
/** Git branch name (or task ID) to use as the starting point when
|
||||
* creating this task's worktree. Set by the scheduler when a task's
|
||||
* explicit dependency or `blockedBy` task is in-review with an
|
||||
* unmerged branch. The executor reads this to branch from the
|
||||
* dependency's branch instead of HEAD. Cleared after worktree creation. */
|
||||
/** Configured merge target/base branch for this task (task intent).
|
||||
* Defaults to the project default branch when omitted. */
|
||||
baseBranch?: string;
|
||||
/** Actual git branch name used for this task's worktree. May differ from
|
||||
/** Actual git working branch name used for this task's worktree. May differ from
|
||||
* the conventional `fn/{task-id}` when conflict recovery generated a
|
||||
* unique suffixed name (e.g., `fn/fn-042-2`). The merger and PR systems
|
||||
* read this field instead of deriving the branch from the task ID. */
|
||||
* unique suffixed name (e.g., `fn/fn-042-2`). */
|
||||
branch?: string;
|
||||
/** Base commit SHA for creating this task's worktree. Used with baseBranch
|
||||
* to establish the exact starting point for the worktree. */
|
||||
/** Internal execution-only provenance for dependency-start handoff.
|
||||
* When set, the scheduler asked executor to start from an upstream dependency
|
||||
* branch. This is transient execution state and should be cleared after use. */
|
||||
executionStartBranch?: string;
|
||||
/** Base commit SHA for creating this task's worktree. Used with the start ref
|
||||
* chosen for the worktree to establish the exact starting point. */
|
||||
baseCommitSha?: string;
|
||||
/** List of files modified by this task (populated during execution) */
|
||||
modifiedFiles?: string[];
|
||||
|
||||
Reference in New Issue
Block a user