pi-harness-runtime 1.1.192 → 1.1.193

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.
Files changed (110) hide show
  1. package/package.json +1 -1
  2. package/packages/a2a-adapter/package.json +1 -1
  3. package/packages/agent-policy/package.json +1 -1
  4. package/packages/architecture-generator/package.json +1 -1
  5. package/packages/auth/package.json +1 -1
  6. package/packages/autonomous-refactor/package.json +1 -1
  7. package/packages/autonomous-runtime/package.json +1 -1
  8. package/packages/cache-strategy/package.json +1 -1
  9. package/packages/capability-registry/package.json +1 -1
  10. package/packages/checkpoint/package.json +1 -1
  11. package/packages/cli-plugin-sdk/package.json +1 -1
  12. package/packages/clipboard/package.json +1 -1
  13. package/packages/clipboard-plugin/package.json +1 -1
  14. package/packages/code-generation/package.json +1 -1
  15. package/packages/code-review/package.json +1 -1
  16. package/packages/codex-adapter/package.json +1 -1
  17. package/packages/codex-watcher/package.json +1 -1
  18. package/packages/config-capture/package.json +1 -1
  19. package/packages/context-compiler/package.json +1 -1
  20. package/packages/context-discovery/package.json +1 -1
  21. package/packages/context-manager/package.json +1 -1
  22. package/packages/cookie-sanitizer/package.json +1 -1
  23. package/packages/cost-optimizer/package.json +1 -1
  24. package/packages/dependency-analyzer/package.json +1 -1
  25. package/packages/django-plugin/package.json +1 -1
  26. package/packages/doc-generator/package.json +1 -1
  27. package/packages/e2e-tester/package.json +1 -1
  28. package/packages/evaluation-engine/package.json +1 -1
  29. package/packages/evaluation-runner/package.json +1 -1
  30. package/packages/event-bus/package.json +1 -1
  31. package/packages/event-store/package.json +1 -1
  32. package/packages/experience-replay/package.json +1 -1
  33. package/packages/feedback-collector/package.json +1 -1
  34. package/packages/file-copy-helper/package.json +1 -1
  35. package/packages/framework-detector/package.json +1 -1
  36. package/packages/framework-plugin-sdk/package.json +1 -1
  37. package/packages/frappe-plugin/package.json +1 -1
  38. package/packages/generic-web-plugin/package.json +1 -1
  39. package/packages/health-monitor/package.json +1 -1
  40. package/packages/intent-analyzer/package.json +1 -1
  41. package/packages/jev-judge/dist/continuation-controller.d.ts +87 -0
  42. package/packages/jev-judge/dist/continuation-controller.d.ts.map +1 -0
  43. package/packages/jev-judge/dist/continuation-controller.js +279 -0
  44. package/packages/jev-judge/dist/continuation-controller.js.map +1 -0
  45. package/packages/jev-judge/dist/todo-provider.d.ts +103 -0
  46. package/packages/jev-judge/dist/todo-provider.d.ts.map +1 -0
  47. package/packages/jev-judge/dist/todo-provider.js +85 -0
  48. package/packages/jev-judge/dist/todo-provider.js.map +1 -0
  49. package/packages/jev-judge/package.json +1 -1
  50. package/packages/jev-judge/src/continuation-controller.ts +374 -0
  51. package/packages/jev-judge/src/todo-provider.ts +185 -0
  52. package/packages/knowledge-graph/package.json +1 -1
  53. package/packages/knowledge-retrieval/package.json +1 -1
  54. package/packages/laravel-plugin/package.json +1 -1
  55. package/packages/learning-engine/package.json +1 -1
  56. package/packages/mcp-adapter/package.json +1 -1
  57. package/packages/memory-engine/package.json +1 -1
  58. package/packages/milestone-manager/package.json +1 -1
  59. package/packages/model-registry/package.json +1 -1
  60. package/packages/nextjs-plugin/package.json +1 -1
  61. package/packages/notification/package.json +1 -1
  62. package/packages/observability/package.json +1 -1
  63. package/packages/okf-indexer/package.json +1 -1
  64. package/packages/paperclip-integration/package.json +1 -1
  65. package/packages/performance-optimizer/package.json +1 -1
  66. package/packages/privilege-broker/package.json +1 -1
  67. package/packages/project-analyzer/package.json +1 -1
  68. package/packages/project-bootstrap/package.json +1 -1
  69. package/packages/projection-engine/package.json +1 -1
  70. package/packages/prompt-compiler/package.json +1 -1
  71. package/packages/prompt-versioning/package.json +1 -1
  72. package/packages/provider-adapter-sdk/package.json +1 -1
  73. package/packages/provider-router/package.json +1 -1
  74. package/packages/provider-selector/package.json +1 -1
  75. package/packages/providers/package.json +1 -1
  76. package/packages/qdrant-skills/package.json +1 -1
  77. package/packages/quota-manager/package.json +1 -1
  78. package/packages/rate-limiter/package.json +1 -1
  79. package/packages/react-vite-plugin/package.json +1 -1
  80. package/packages/release-manager/package.json +1 -1
  81. package/packages/requirement-compiler/package.json +1 -1
  82. package/packages/runtime/package.json +1 -1
  83. package/packages/scheduler/package.json +1 -1
  84. package/packages/scheduler-adapter/package.json +1 -1
  85. package/packages/session/package.json +1 -1
  86. package/packages/session-api/package.json +1 -1
  87. package/packages/session-export/package.json +1 -1
  88. package/packages/shared-context/package.json +1 -1
  89. package/packages/skill-mcp-client/package.json +1 -1
  90. package/packages/skill-registry/package.json +1 -1
  91. package/packages/skills/package.json +1 -1
  92. package/packages/sprint-planner/package.json +1 -1
  93. package/packages/subscription-engine/package.json +1 -1
  94. package/packages/task-compiler/package.json +1 -1
  95. package/packages/telegram/package.json +1 -1
  96. package/packages/tencentdb-memory/package.json +1 -1
  97. package/packages/tencentdb-sync/package.json +1 -1
  98. package/packages/test-data-generator/package.json +1 -1
  99. package/packages/test-generator/package.json +1 -1
  100. package/packages/todo-bd-sync/package.json +1 -1
  101. package/packages/token-estimation/package.json +1 -1
  102. package/packages/token-optimizer/package.json +1 -1
  103. package/packages/trajectory/package.json +1 -1
  104. package/packages/tui/package.json +1 -1
  105. package/packages/types/package.json +1 -1
  106. package/packages/webmcp-tester/package.json +1 -1
  107. package/packages/workflow-events/package.json +1 -1
  108. package/packages/workspace-scanner/package.json +1 -1
  109. package/packages/worktree/package.json +1 -1
  110. package/packages/write-review/package.json +1 -1
@@ -0,0 +1,374 @@
1
+ /**
2
+ * Todo-Driven Continuation Controller
3
+ *
4
+ * Executes authorized todo items without repeated prompts.
5
+ * Uses deterministic rules + optional Jev for ambiguous cases.
6
+ *
7
+ * Architecture:
8
+ * A. Read real todo state (not bd)
9
+ * B. Deterministic continuation on agent_settled
10
+ * C. Jev for ambiguous classification only
11
+ * D. Single continuation controller
12
+ * E. Update prompts/Telegram/status together
13
+ */
14
+
15
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
16
+ import { createTodoProvider, type TodoItem, type TodoSnapshot } from "./todo-provider.js";
17
+ import { AutoContinueJudge } from "./auto-continue.js";
18
+ import type { AutoContinueDecision } from "./auto-continue.js";
19
+
20
+ /**
21
+ * Continuation state
22
+ */
23
+ interface ContinuationState {
24
+ sessionId: string;
25
+ generation: number; // Incremented on edits/cancellation/switch
26
+ todoRevision: number;
27
+ currentItemId: number | null;
28
+ nextItemId: number | null;
29
+ lastMessageId: string | null;
30
+ continuationQueued: boolean;
31
+ userPaused: boolean;
32
+ lastSteerMessage: string | null;
33
+ steerAttempts: number;
34
+ }
35
+
36
+ /**
37
+ * Continuation result
38
+ */
39
+ interface ContinuationResult {
40
+ action: "continue" | "stop" | "ask" | "blocked";
41
+ nextItemId?: number;
42
+ question?: string;
43
+ reason?: string;
44
+ }
45
+
46
+ /**
47
+ * Continuation controller configuration
48
+ */
49
+ interface ContinuationConfig {
50
+ /** Minimum wait time before Jev fallback (ms) */
51
+ jevFallbackMinWaitMs?: number;
52
+ /** Jev probability threshold for routine continuation */
53
+ routineThreshold?: number;
54
+ /** Max steer attempts before reporting blocker */
55
+ maxSteerAttempts?: number;
56
+ /** Enable Jev classification for ambiguous cases */
57
+ enableJev?: boolean;
58
+ }
59
+
60
+ /**
61
+ * Todo-Driven Continuation Controller
62
+ *
63
+ * Evaluates todo state on agent_settled and determines next action.
64
+ */
65
+ export class TodoContinuationController {
66
+ private pi: ExtensionAPI;
67
+ private config: Required<ContinuationConfig>;
68
+ private todoProvider = createTodoProvider();
69
+ private jevJudge?: AutoContinueJudge;
70
+
71
+ private state: ContinuationState = {
72
+ sessionId: "",
73
+ generation: 0,
74
+ todoRevision: 0,
75
+ currentItemId: null,
76
+ nextItemId: null,
77
+ lastMessageId: null,
78
+ continuationQueued: false,
79
+ userPaused: false,
80
+ lastSteerMessage: null,
81
+ steerAttempts: 0,
82
+ };
83
+
84
+ constructor(pi: ExtensionAPI, config?: ContinuationConfig) {
85
+ this.pi = pi;
86
+ this.config = {
87
+ jevFallbackMinWaitMs: 5 * 60 * 1000, // 5 minutes
88
+ routineThreshold: 0.7,
89
+ maxSteerAttempts: 3,
90
+ enableJev: true,
91
+ ...config,
92
+ } as Required<ContinuationConfig>;
93
+
94
+ // Initialize Jev judge if enabled
95
+ if (this.config.enableJev) {
96
+ // Jev will be initialized with API key from environment
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Register lifecycle hooks
102
+ */
103
+ register(): void {
104
+ console.log("[TodoContinuation] Registering lifecycle hooks...");
105
+
106
+ // Session start - reset state
107
+ this.pi.on("session_start", () => {
108
+ this.reset();
109
+ console.log("[TodoContinuation] Session started");
110
+ });
111
+
112
+ // Agent settled - evaluate continuation
113
+ this.pi.on("agent_settled", () => {
114
+ this.evaluateContinuation().catch((err) =>
115
+ console.error("[TodoContinuation] Evaluation failed:", err)
116
+ );
117
+ });
118
+
119
+ // User input - reset pause state
120
+ this.pi.on("message_start", (event) => {
121
+ const msg = event.message as { role?: string };
122
+ if (msg?.role === "user") {
123
+ this.state.userPaused = false;
124
+ this.state.lastSteerMessage = null;
125
+ }
126
+ });
127
+
128
+ // Session shutdown - cleanup
129
+ this.pi.on("session_shutdown", () => {
130
+ this.cleanup();
131
+ });
132
+
133
+ // Tool call - track mutations that might invalidate state
134
+ this.pi.on("tool_call", (event) => {
135
+ // Increment generation on edits
136
+ if (["write", "edit", "bash"].includes(event.toolName)) {
137
+ this.state.generation++;
138
+ this.state.continuationQueued = false;
139
+ }
140
+ });
141
+
142
+ console.log("[TodoContinuation] Lifecycle hooks registered");
143
+ }
144
+
145
+ /**
146
+ * Evaluate continuation decision
147
+ */
148
+ private async evaluateContinuation(): Promise<ContinuationResult> {
149
+ // 1. Check user pause
150
+ if (this.state.userPaused) {
151
+ return { action: "stop", reason: "User paused" };
152
+ }
153
+
154
+ // 2. Get current todo snapshot
155
+ const availability = await this.todoProvider.availability();
156
+ if (!availability.available) {
157
+ console.log("[TodoContinuation] Todo provider unavailable:", availability.error);
158
+ return { action: "stop", reason: "Todo provider unavailable" };
159
+ }
160
+
161
+ const snapshot = await this.todoProvider.getSnapshot();
162
+
163
+ // 3. Check if state changed significantly
164
+ if (snapshot.revision === this.state.todoRevision && this.state.nextItemId) {
165
+ // Same todo state, try to continue next item
166
+ } else {
167
+ // Todo state changed, recalculate
168
+ this.state.todoRevision = snapshot.revision;
169
+ this.state.currentItemId = null;
170
+ this.state.nextItemId = null;
171
+ }
172
+
173
+ // 4. Get ready items
174
+ const readyItems = await this.todoProvider.getReady();
175
+ const completedItems = await this.todoProvider.getCompleted();
176
+ const pendingItems = await this.todoProvider.getPending();
177
+
178
+ // 5. Determine action
179
+ if (readyItems.length === 0 && pendingItems.length === 0) {
180
+ console.log("[TodoContinuation] All items complete");
181
+ return { action: "stop", reason: "All todos complete" };
182
+ }
183
+
184
+ if (readyItems.length === 0 && pendingItems.length > 0) {
185
+ // Items exist but all blocked
186
+ const blockedItems = await this.todoProvider.getBlocked();
187
+ const blocker = blockedItems[0];
188
+ console.log("[TodoContinuation] Items blocked:", blocker?.subject);
189
+ return {
190
+ action: "blocked",
191
+ question: `Task "${blocker?.subject}" is blocked. What is needed to unblock it?`,
192
+ reason: `Blocked by dependencies`,
193
+ };
194
+ }
195
+
196
+ // 6. Select next ready item
197
+ const nextItem = this.state.nextItemId
198
+ ? readyItems.find((i) => i.id === this.state.nextItemId) ?? readyItems[0]
199
+ : readyItems[0];
200
+
201
+ if (!nextItem) {
202
+ return { action: "stop", reason: "No ready items" };
203
+ }
204
+
205
+ // 7. Check if current item should be marked complete
206
+ if (this.state.currentItemId && this.state.currentItemId !== nextItem.id) {
207
+ // Item changed, mark previous complete
208
+ console.log(`[TodoContinuation] Item ${this.state.currentItemId} complete`);
209
+ }
210
+
211
+ // 8. Update state
212
+ this.state.currentItemId = nextItem.id;
213
+ this.state.nextItemId = readyItems.length > 1 ? readyItems[1].id : null;
214
+
215
+ // 9. Determine if we should continue or ask
216
+ const shouldContinue = await this.shouldAutoContinue(nextItem);
217
+
218
+ if (shouldContinue.continue) {
219
+ console.log(
220
+ `[TodoContinuation] Continuing item ${nextItem.id}: ${nextItem.subject}`
221
+ );
222
+ return { action: "continue", nextItemId: nextItem.id };
223
+ }
224
+
225
+ // 10. Jev says ask user
226
+ return {
227
+ action: "ask",
228
+ nextItemId: nextItem.id,
229
+ question: shouldContinue.question,
230
+ reason: shouldContinue.reason,
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Determine if we should auto-continue
236
+ */
237
+ private async shouldAutoContinue(
238
+ item: TodoItem
239
+ ): Promise<{ continue: boolean; question?: string; reason?: string }> {
240
+ // If no current work, continue is routine
241
+ if (!this.state.currentItemId) {
242
+ return { continue: true };
243
+ }
244
+
245
+ // If completing current item and next is ready, continue is routine
246
+ if (this.state.currentItemId !== item.id && this.state.nextItemId === item.id) {
247
+ return { continue: true };
248
+ }
249
+
250
+ // Check if we're mid-item
251
+ if (this.state.currentItemId === item.id) {
252
+ // Already working on this item, continue
253
+ return { continue: true };
254
+ }
255
+
256
+ // For ambiguous cases, use Jev
257
+ if (this.config.enableJev && this.jevJudge) {
258
+ const decision = await this.jevJudge.decide({
259
+ completedTasks: [],
260
+ remainingTasks: [item.subject],
261
+ totalTasks: 1,
262
+ waitTimeMinutes: 0,
263
+ userResponded: false,
264
+ sessionStartTime: new Date(),
265
+ });
266
+
267
+ if (decision.action === "proceed") {
268
+ return { continue: true };
269
+ }
270
+
271
+ return {
272
+ continue: false,
273
+ question: `Ready to continue: "${item.subject}"?`,
274
+ reason: decision.reasoning,
275
+ };
276
+ }
277
+
278
+ // Default: continue for ready items
279
+ return { continue: true };
280
+ }
281
+
282
+ /**
283
+ * Steer to continue a todo item
284
+ */
285
+ async steerToContinue(itemId: number): Promise<void> {
286
+ if (this.state.steerAttempts >= this.config.maxSteerAttempts) {
287
+ console.warn("[TodoContinuation] Max steer attempts reached");
288
+ return;
289
+ }
290
+
291
+ this.state.steerAttempts++;
292
+ this.state.continuationQueued = true;
293
+
294
+ const snapshot = await this.todoProvider.getSnapshot();
295
+ const item = snapshot.items.find((i) => i.id === itemId);
296
+
297
+ const message = item
298
+ ? `Continue todo item: "${item.subject}". ${item.description ?? ""}`
299
+ : `Continue work on the next ready task.`;
300
+
301
+ this.state.lastSteerMessage = message;
302
+ this.state.todoRevision = snapshot.revision;
303
+
304
+ console.log(`[TodoContinuation] Steering to continue item ${itemId}`);
305
+ }
306
+
307
+ /**
308
+ * Mark a todo item as complete
309
+ */
310
+ async markComplete(itemId: number): Promise<void> {
311
+ console.log(`[TodoContinuation] Marking item ${itemId} complete`);
312
+ this.state.currentItemId = null;
313
+ this.state.generation++;
314
+ }
315
+
316
+ /**
317
+ * User paused
318
+ */
319
+ pause(): void {
320
+ this.state.userPaused = true;
321
+ this.state.continuationQueued = false;
322
+ console.log("[TodoContinuation] User paused");
323
+ }
324
+
325
+ /**
326
+ * Reset state for new session
327
+ */
328
+ private reset(): void {
329
+ this.state = {
330
+ sessionId: `session-${Date.now()}`,
331
+ generation: 0,
332
+ todoRevision: 0,
333
+ currentItemId: null,
334
+ nextItemId: null,
335
+ lastMessageId: null,
336
+ continuationQueued: false,
337
+ userPaused: false,
338
+ lastSteerMessage: null,
339
+ steerAttempts: 0,
340
+ };
341
+ }
342
+
343
+ /**
344
+ * Cleanup on shutdown
345
+ */
346
+ private cleanup(): void {
347
+ console.log("[TodoContinuation] Cleaning up");
348
+ this.state.continuationQueued = false;
349
+ this.state.generation++;
350
+ }
351
+
352
+ /**
353
+ * Get current state summary
354
+ */
355
+ getState(): { current: TodoItem | null; next: TodoItem | null; ready: number } {
356
+ return {
357
+ current: null, // Would need to fetch
358
+ next: null,
359
+ ready: 0,
360
+ };
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Create and register a todo continuation controller
366
+ */
367
+ export function createTodoContinuation(
368
+ pi: ExtensionAPI,
369
+ config?: ContinuationConfig
370
+ ): TodoContinuationController {
371
+ const controller = new TodoContinuationController(pi, config);
372
+ controller.register();
373
+ return controller;
374
+ }
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Todo Provider - Read local todo state
3
+ *
4
+ * Provides typed access to the local todo list.
5
+ * Separates todo from bd (issue tracker).
6
+ */
7
+
8
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
9
+
10
+ /**
11
+ * Todo item status
12
+ */
13
+ export type TodoStatus = "pending" | "in_progress" | "completed" | "deleted";
14
+
15
+ /**
16
+ * A single todo item
17
+ */
18
+ export interface TodoItem {
19
+ id: number;
20
+ subject: string;
21
+ description?: string;
22
+ status: TodoStatus;
23
+ activeForm?: string;
24
+ blockedBy?: number[];
25
+ owner?: string;
26
+ metadata?: Record<string, unknown>;
27
+ }
28
+
29
+ /**
30
+ * Snapshot of the todo list at a point in time
31
+ */
32
+ export interface TodoSnapshot {
33
+ items: TodoItem[];
34
+ sessionId: string;
35
+ revision: number; // Monotonically increasing per-session version
36
+ createdAt: Date;
37
+ }
38
+
39
+ /**
40
+ * Availability result for todo provider
41
+ */
42
+ export interface TodoAvailability {
43
+ available: boolean;
44
+ error?: string;
45
+ provider?: string;
46
+ }
47
+
48
+ /**
49
+ * Todo Provider interface
50
+ */
51
+ export interface TodoProvider {
52
+ /**
53
+ * Check if todo is available
54
+ */
55
+ availability(): Promise<TodoAvailability>;
56
+
57
+ /**
58
+ * Get current snapshot of todo list
59
+ */
60
+ getSnapshot(): Promise<TodoSnapshot>;
61
+
62
+ /**
63
+ * Get items by status
64
+ */
65
+ getByStatus(status: TodoStatus): Promise<TodoItem[]>;
66
+
67
+ /**
68
+ * Get in-progress items
69
+ */
70
+ getInProgress(): Promise<TodoItem[]>;
71
+
72
+ /**
73
+ * Get pending items (not completed)
74
+ */
75
+ getPending(): Promise<TodoItem[]>;
76
+
77
+ /**
78
+ * Get completed items
79
+ */
80
+ getCompleted(): Promise<TodoItem[]>;
81
+
82
+ /**
83
+ * Get ready items (pending with satisfied dependencies)
84
+ */
85
+ getReady(): Promise<TodoItem[]>;
86
+
87
+ /**
88
+ * Get blocked items (pending with unsatisfied dependencies)
89
+ */
90
+ getBlocked(): Promise<TodoItem[]>;
91
+ }
92
+
93
+ /**
94
+ * Mock Todo Provider for testing
95
+ */
96
+ export class MockTodoProvider implements TodoProvider {
97
+ private items: TodoItem[] = [];
98
+ private _sessionId: string;
99
+ private _revision = 0;
100
+
101
+ constructor(sessionId?: string) {
102
+ this._sessionId = sessionId ?? `mock-${Date.now()}`;
103
+ }
104
+
105
+ async availability(): Promise<TodoAvailability> {
106
+ return { available: true, provider: "mock" };
107
+ }
108
+
109
+ async getSnapshot(): Promise<TodoSnapshot> {
110
+ this._revision++;
111
+ return {
112
+ items: [...this.items],
113
+ sessionId: this._sessionId,
114
+ revision: this._revision,
115
+ createdAt: new Date(),
116
+ };
117
+ }
118
+
119
+ async getByStatus(status: TodoStatus): Promise<TodoItem[]> {
120
+ return this.items.filter((item) => item.status === status);
121
+ }
122
+
123
+ async getInProgress(): Promise<TodoItem[]> {
124
+ return this.getByStatus("in_progress");
125
+ }
126
+
127
+ async getPending(): Promise<TodoItem[]> {
128
+ return this.items.filter((item) => item.status === "pending");
129
+ }
130
+
131
+ async getCompleted(): Promise<TodoItem[]> {
132
+ return this.getByStatus("completed");
133
+ }
134
+
135
+ async getReady(): Promise<TodoItem[]> {
136
+ const pending = await this.getPending();
137
+ return pending.filter((item) => {
138
+ if (!item.blockedBy?.length) return true;
139
+ const blockedIds = new Set(item.blockedBy);
140
+ return !this.items.some(
141
+ (i) => blockedIds.has(i.id) && i.status !== "completed"
142
+ );
143
+ });
144
+ }
145
+
146
+ async getBlocked(): Promise<TodoItem[]> {
147
+ const pending = await this.getPending();
148
+ return pending.filter((item) => {
149
+ if (!item.blockedBy?.length) return false;
150
+ const blockedIds = new Set(item.blockedBy);
151
+ return this.items.some(
152
+ (i) => blockedIds.has(i.id) && i.status !== "completed"
153
+ );
154
+ });
155
+ }
156
+
157
+ // Test helpers
158
+ addItem(item: Omit<TodoItem, "id">): TodoItem {
159
+ const id = this.items.length + 1;
160
+ const newItem: TodoItem = { ...item, id };
161
+ this.items.push(newItem);
162
+ return newItem;
163
+ }
164
+
165
+ setStatus(id: number, status: TodoStatus): void {
166
+ const item = this.items.find((i) => i.id === id);
167
+ if (item) {
168
+ item.status = status;
169
+ }
170
+ }
171
+
172
+ clear(): void {
173
+ this.items = [];
174
+ this._revision++;
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Create a todo provider based on available tools
180
+ */
181
+ export function createTodoProvider(pi?: ExtensionAPI): TodoProvider {
182
+ // For now, return mock provider
183
+ // TODO: Integrate with actual Pi todo extension when available
184
+ return new MockTodoProvider();
185
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/knowledge-graph",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Knowledge Graph extraction and provenance linking for SKILL.md files",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/knowledge-retrieval",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Knowledge retrieval via TencentDB-Agent-Memory MCP (RFC-0105)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/laravel-plugin",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Laravel framework analysis — artisan commands, Eloquent models, Blade",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/learning-engine",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Learning engine for extracting lessons from runtime execution (RFC-0058)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/mcp-adapter",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "type": "module",
5
5
  "description": "MCP server adapter for pi-harness — exposes harness capabilities as MCP tools/resources/prompts (RFC-0068)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/memory-engine",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Memory engine with OKF integration for durable knowledge management (RFC-0060)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/milestone-manager",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Track milestones and alerts when items are at risk",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/model-registry",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Model Registry for pi-harness-runtime — centralized model metadata with pricing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/nextjs-plugin",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Next.js framework detection and analysis for pi-harness-runtime (RFC-0062)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/notification",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "pi-harness-runtime — notification",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/observability",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Comprehensive observability system with structured logging, tracing, metrics, and alerting",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/okf-indexer",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "OKF document indexer for SKILL.md files (RFC-0106)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/paperclip-integration",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Paperclip API integration: poll agent inbox, route tasks to pi.dev, Telegram alerts",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/performance-optimizer",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Performance optimization analyzer for pi-harness runtime (RFC-0056)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/privilege-broker",
3
- "version": "1.1.192",
3
+ "version": "1.1.193",
4
4
  "description": "Privilege Broker — capability registry and command executor for autonomous runtime (RFC-0101 §7)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",