From 6491441102a71eb31fccca880d0c5186c3312148 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 4 Jun 2026 01:03:34 -0700 Subject: [PATCH] feat(core): widen moveTask entry point to ColumnId for workflow-defined columns (KTD-1) --- packages/core/src/store.ts | 9 ++++++--- packages/core/src/types.ts | 9 +++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/core/src/store.ts b/packages/core/src/store.ts index 8a58ff0fb3..8095ad72c7 100644 --- a/packages/core/src/store.ts +++ b/packages/core/src/store.ts @@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto"; import { mkdir, readdir, readFile, writeFile, rename, unlink } from "node:fs/promises"; import { join } from "node:path"; import { existsSync, watch, type FSWatcher } from "node:fs"; -import type { Task, TaskDetail, TaskCreateInput, TaskAttachment, AgentLogEntry, BoardConfig, Column, CheckoutClaimPrecondition, MergeResult, Settings, GlobalSettings, ProjectSettings, ActivityLogEntry, ActivityEventType, TaskDocument, TaskDocumentRevision, TaskDocumentCreateInput, TaskDocumentWithTask, InboxTask, TaskLogEntry, RunMutationContext, RunAuditEvent, RunAuditEventInput, RunAuditEventFilter, ArchivedTaskEntry, ArchiveAgentLogMode, TaskPriority, SourceType, WorkflowStepTemplate, Agent, AutostashOrphanRecord, TaskCommitAssociation, TaskCommitAssociationMatchSource, TaskCommitAssociationConfidence, GithubIssueAction, MergeQueueEntry, MergeQueueEnqueueOptions, MergeQueueAcquireOptions, MergeQueueReleaseOutcome, HandoffToReviewOptions, GoalCitation, GoalCitationFilter, GoalCitationInput, GoalCitationSurface, BranchGroup, BranchGroupCreateInput, BranchGroupUpdate, TaskBranchAssignmentMode, MergeRequestRecord, MergeRequestState, CompletionHandoffMarker } from "./types.js"; +import type { Task, TaskDetail, TaskCreateInput, TaskAttachment, AgentLogEntry, BoardConfig, Column, ColumnId, CheckoutClaimPrecondition, MergeResult, Settings, GlobalSettings, ProjectSettings, ActivityLogEntry, ActivityEventType, TaskDocument, TaskDocumentRevision, TaskDocumentCreateInput, TaskDocumentWithTask, InboxTask, TaskLogEntry, RunMutationContext, RunAuditEvent, RunAuditEventInput, RunAuditEventFilter, ArchivedTaskEntry, ArchiveAgentLogMode, TaskPriority, SourceType, WorkflowStepTemplate, Agent, AutostashOrphanRecord, TaskCommitAssociation, TaskCommitAssociationMatchSource, TaskCommitAssociationConfidence, GithubIssueAction, MergeQueueEntry, MergeQueueEnqueueOptions, MergeQueueAcquireOptions, MergeQueueReleaseOutcome, HandoffToReviewOptions, GoalCitation, GoalCitationFilter, GoalCitationInput, GoalCitationSurface, BranchGroup, BranchGroupCreateInput, BranchGroupUpdate, TaskBranchAssignmentMode, MergeRequestRecord, MergeRequestState, CompletionHandoffMarker } from "./types.js"; import { createActivityLogSnapshot, createRunAuditSnapshot, createTaskMetadataSnapshot, toTaskMetadataRecord, validateSnapshotEnvelope, type ActivityLogSnapshot, type RunAuditSnapshot, type TaskMetadataSnapshot } from "./shared-mesh-state.js"; import { VALID_TRANSITIONS, DEFAULT_SETTINGS, isGlobalOnlySettingsKey, WORKFLOW_STEP_TEMPLATES, validateDocumentKey } from "./types.js"; import { DEFAULT_PROJECT_SETTINGS } from "./settings-schema.js"; @@ -5573,10 +5573,13 @@ export class TaskStore extends EventEmitter { async moveTask( id: string, - toColumn: Column, + toColumn: ColumnId, options?: MoveTaskOptions, ): Promise { - return this.withTaskLock(id, () => this.moveTaskInternal(id, toColumn, options, { fromHandoff: false })); + // ColumnId admits workflow-defined custom column ids (KTD-1). Both paths + // runtime-validate: flag-ON against the task's resolved workflow, flag-OFF + // via the VALID_TRANSITIONS lookup (non-legacy ids reject as before). + return this.withTaskLock(id, () => this.moveTaskInternal(id, toColumn as Column, options, { fromHandoff: false })); } async handoffToReview(taskId: string, opts: HandoffToReviewOptions): Promise { diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 043f161575..e40b0be208 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -18,6 +18,15 @@ export type ThinkingLevel = (typeof THINKING_LEVELS)[number]; export const COLUMNS = ["triage", "todo", "in-progress", "in-review", "done", "archived"] as const; export type Column = (typeof COLUMNS)[number]; +/** + * Column identifier accepted at task-movement entry points (KTD-1). + * Equals the legacy `Column` union for autocomplete purposes, but admits + * workflow-defined custom column ids; flag-ON paths validate the id against + * the task's resolved workflow at runtime, flag-OFF paths reject non-legacy + * ids exactly as before. + */ +export type ColumnId = Column | (string & {}); + export const DEFAULT_COLUMN: Column = "triage"; export function isColumn(value: unknown): value is Column {