feat(KB-635): add mission management CLI commands and engine integration
- Add comprehensive mission CLI commands: create, list, show, start, abort, delete, and next - Add Pi extension tools for mission operations: list_missions, show_mission, start_mission, abort_mission - Implement mission-aware scheduler with task start handling and autoAdvance support - Add sliceId to Task type and autoAdvance flag to Mission type for slice sequencing - Add MissionStore helper methods for mission lifecycle operations - Include comprehensive tests for CLI commands and Pi extension mission tools
This commit is contained in:
@@ -725,6 +725,29 @@ export class MissionStore extends EventEmitter<MissionStoreEvents> {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the next pending slice in a mission.
|
||||
* Iterates milestones by orderIndex, then slices by orderIndex,
|
||||
* and returns the first slice with status "pending".
|
||||
*
|
||||
* @param missionId - Mission ID
|
||||
* @returns The next pending slice, or undefined if none found
|
||||
*/
|
||||
findNextPendingSlice(missionId: string): Slice | undefined {
|
||||
const milestones = this.listMilestones(missionId);
|
||||
|
||||
for (const milestone of milestones) {
|
||||
const slices = this.listSlices(milestone.id);
|
||||
for (const slice of slices) {
|
||||
if (slice.status === "pending") {
|
||||
return slice;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// ── Feature Operations ─────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
@@ -929,6 +952,29 @@ export class MissionStore extends EventEmitter<MissionStoreEvents> {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a feature's status.
|
||||
* Recomputes slice status after update.
|
||||
*
|
||||
* @param featureId - Feature ID
|
||||
* @param status - New status
|
||||
* @returns The updated feature
|
||||
* @throws Error if feature not found
|
||||
*/
|
||||
updateFeatureStatus(featureId: string, status: FeatureStatus): MissionFeature {
|
||||
const feature = this.getFeature(featureId);
|
||||
if (!feature) {
|
||||
throw new Error(`Feature ${featureId} not found`);
|
||||
}
|
||||
|
||||
const updated = this.updateFeature(featureId, { status });
|
||||
|
||||
// Recompute slice status
|
||||
this.recomputeSliceStatus(updated.sliceId);
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a feature by its linked task ID.
|
||||
*
|
||||
|
||||
@@ -48,6 +48,8 @@ export interface Mission {
|
||||
status: MissionStatus;
|
||||
/** State of the AI specification interview process */
|
||||
interviewState: InterviewState;
|
||||
/** When true, automatically activate the next pending slice when current slice completes */
|
||||
autoAdvance?: boolean;
|
||||
/** ISO-8601 timestamp of creation */
|
||||
createdAt: string;
|
||||
/** ISO-8601 timestamp of last update */
|
||||
|
||||
@@ -434,6 +434,8 @@ export interface Task {
|
||||
summary?: string;
|
||||
/** Files modified during agent execution, captured at task completion time */
|
||||
modifiedFiles?: string[];
|
||||
/** Optional ID of the slice this task is linked to (for mission-based work) */
|
||||
sliceId?: string;
|
||||
/** ISO-8601 timestamp of when the task last entered its current column.
|
||||
* Used to sort cards within a column so that recently-moved cards appear at the top. */
|
||||
columnMovedAt?: string;
|
||||
|
||||
Reference in New Issue
Block a user