pi-squad 0.16.5 → 0.16.7

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.
package/src/store.ts CHANGED
@@ -356,8 +356,15 @@ export function findLatestSquad(projectCwd?: string): Squad | null {
356
356
  // Tasks
357
357
  // ============================================================================
358
358
 
359
+ function normalizeLegacyCancelledTask(task: Task | null): Task | null {
360
+ if (task?.status === "failed" && task.error === "Cancelled by user") {
361
+ return { ...task, status: "cancelled", error: null };
362
+ }
363
+ return task;
364
+ }
365
+
359
366
  export function loadTask(squadId: string, taskId: string, parentPath?: string): Task | null {
360
- return readJson<Task>(getTaskFilePath(squadId, taskId, parentPath));
367
+ return normalizeLegacyCancelledTask(readJson<Task>(getTaskFilePath(squadId, taskId, parentPath)));
361
368
  }
362
369
 
363
370
  export function saveTask(squadId: string, task: Task, parentPath?: string): void {
@@ -377,7 +384,7 @@ export function loadAllTasks(squadId: string): Task[] {
377
384
  if (!entry.isDirectory()) continue;
378
385
  if (entry.name === "knowledge") continue;
379
386
  const taskFile = path.join(squadDir, entry.name, "task.json");
380
- const task = readJson<Task>(taskFile);
387
+ const task = normalizeLegacyCancelledTask(readJson<Task>(taskFile));
381
388
  if (task && !seen.has(task.id)) {
382
389
  seen.add(task.id);
383
390
  tasks.push(task);
@@ -401,7 +408,7 @@ function collectSubtasks(squadDir: string, parentPath: string, tasks: Task[], se
401
408
  for (const entry of entries) {
402
409
  if (!entry.isDirectory()) continue;
403
410
  const taskFile = path.join(parentDir, entry.name, "task.json");
404
- const task = readJson<Task>(taskFile);
411
+ const task = normalizeLegacyCancelledTask(readJson<Task>(taskFile));
405
412
  if (task && !seen.has(task.id)) {
406
413
  seen.add(task.id);
407
414
  tasks.push(task);
package/src/types.ts CHANGED
@@ -85,6 +85,17 @@ export interface SquadReview {
85
85
  issues: string[];
86
86
  }
87
87
 
88
+ export interface SuspendedStallAttention {
89
+ kind: "suspended_stall";
90
+ /** Canonical identity of the exact suspended/blocked task sets. */
91
+ fingerprint: string;
92
+ suspendedTaskIds: string[];
93
+ blockedTaskIds: string[];
94
+ detectedAt: string;
95
+ delivery: "pending" | "delivered";
96
+ deliveredAt: string | null;
97
+ }
98
+
88
99
  export interface SquadConfig {
89
100
  maxConcurrency: number;
90
101
  autoUnblock: boolean;
@@ -116,13 +127,15 @@ export interface Squad {
116
127
  review?: SquadReview;
117
128
  /** Completed prior review attempts retained as same-squad audit evidence. */
118
129
  reviewHistory?: SquadReview[];
130
+ /** Durable, level-triggered attention for an explicit-suspension stall. */
131
+ suspendedStallAttention?: SuspendedStallAttention;
119
132
  }
120
133
 
121
134
  // ============================================================================
122
135
  // Tasks
123
136
  // ============================================================================
124
137
 
125
- export type TaskStatus = "pending" | "blocked" | "in_progress" | "done" | "failed" | "suspended";
138
+ export type TaskStatus = "pending" | "blocked" | "in_progress" | "done" | "failed" | "suspended" | "cancelled";
126
139
 
127
140
  export interface TaskUsage {
128
141
  inputTokens: number;