taskplane 0.29.2 → 0.30.0

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 (41) hide show
  1. package/bin/gitignore-patterns.mjs +11 -8
  2. package/bin/rpc-wrapper.mjs +410 -357
  3. package/bin/taskplane.mjs +533 -250
  4. package/extensions/reviewer-extension.ts +17 -11
  5. package/extensions/taskplane/abort.ts +50 -18
  6. package/extensions/taskplane/agent-bridge-extension.ts +232 -105
  7. package/extensions/taskplane/agent-host.ts +224 -97
  8. package/extensions/taskplane/cleanup.ts +71 -42
  9. package/extensions/taskplane/config-loader.ts +142 -58
  10. package/extensions/taskplane/config-schema.ts +6 -13
  11. package/extensions/taskplane/config.ts +10 -2
  12. package/extensions/taskplane/diagnostic-reports.ts +59 -47
  13. package/extensions/taskplane/diagnostics.ts +13 -13
  14. package/extensions/taskplane/discovery.ts +35 -61
  15. package/extensions/taskplane/engine-worker.ts +53 -46
  16. package/extensions/taskplane/engine.ts +1760 -602
  17. package/extensions/taskplane/execution.ts +426 -206
  18. package/extensions/taskplane/extension.ts +1073 -598
  19. package/extensions/taskplane/formatting.ts +136 -124
  20. package/extensions/taskplane/git.ts +0 -2
  21. package/extensions/taskplane/lane-runner.ts +542 -311
  22. package/extensions/taskplane/mailbox.ts +57 -49
  23. package/extensions/taskplane/merge.ts +662 -383
  24. package/extensions/taskplane/messages.ts +109 -51
  25. package/extensions/taskplane/migrations.ts +1 -1
  26. package/extensions/taskplane/path-resolver.ts +8 -9
  27. package/extensions/taskplane/persistence.ts +425 -262
  28. package/extensions/taskplane/process-registry.ts +36 -7
  29. package/extensions/taskplane/quality-gate.ts +107 -55
  30. package/extensions/taskplane/resume.ts +774 -267
  31. package/extensions/taskplane/sessions.ts +1 -1
  32. package/extensions/taskplane/settings-tui.ts +505 -164
  33. package/extensions/taskplane/sidecar-telemetry.ts +25 -10
  34. package/extensions/taskplane/supervisor.ts +477 -270
  35. package/extensions/taskplane/task-executor-core.ts +178 -53
  36. package/extensions/taskplane/types.ts +186 -108
  37. package/extensions/taskplane/verification.ts +27 -22
  38. package/extensions/taskplane/waves.ts +59 -43
  39. package/extensions/taskplane/workspace.ts +14 -12
  40. package/extensions/taskplane/worktree.ts +218 -196
  41. package/package.json +14 -2
@@ -24,7 +24,16 @@
24
24
  */
25
25
 
26
26
  import { join, dirname } from "path";
27
- import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, renameSync, unlinkSync, appendFileSync } from "fs";
27
+ import {
28
+ existsSync,
29
+ mkdirSync,
30
+ writeFileSync,
31
+ readFileSync,
32
+ readdirSync,
33
+ renameSync,
34
+ unlinkSync,
35
+ appendFileSync,
36
+ } from "fs";
28
37
  import { randomBytes } from "crypto";
29
38
  import type { MailboxMessage, MailboxMessageType, WriteMailboxMessageOpts } from "./types.ts";
30
39
  import { MAILBOX_DIR_NAME, MAILBOX_MAX_CONTENT_BYTES, MAILBOX_MESSAGE_TYPES } from "./types.ts";
@@ -85,7 +94,6 @@ export function broadcastInboxDir(stateRoot: string, batchId: string): string {
85
94
  return join(stateRoot, ".pi", MAILBOX_DIR_NAME, batchId, "_broadcast", "inbox");
86
95
  }
87
96
 
88
-
89
97
  // ── Write ────────────────────────────────────────────────────────────
90
98
 
91
99
  /**
@@ -116,8 +124,8 @@ export function writeMailboxMessage(
116
124
  if (contentBytes > MAILBOX_MAX_CONTENT_BYTES) {
117
125
  throw new Error(
118
126
  `Mailbox message content exceeds ${MAILBOX_MAX_CONTENT_BYTES} byte limit ` +
119
- `(${contentBytes} bytes). Steering messages should be concise directives. ` +
120
- `Write larger context to a file and reference it by path.`,
127
+ `(${contentBytes} bytes). Steering messages should be concise directives. ` +
128
+ `Write larger context to a file and reference it by path.`,
121
129
  );
122
130
  }
123
131
 
@@ -140,9 +148,10 @@ export function writeMailboxMessage(
140
148
  };
141
149
 
142
150
  // Determine inbox directory
143
- const inboxDir = to === "_broadcast"
144
- ? broadcastInboxDir(stateRoot, batchId)
145
- : sessionInboxDir(stateRoot, batchId, to);
151
+ const inboxDir =
152
+ to === "_broadcast"
153
+ ? broadcastInboxDir(stateRoot, batchId)
154
+ : sessionInboxDir(stateRoot, batchId, to);
146
155
 
147
156
  // Ensure inbox directory exists
148
157
  mkdirSync(inboxDir, { recursive: true });
@@ -171,7 +180,6 @@ export function writeMailboxMessage(
171
180
  return message;
172
181
  }
173
182
 
174
-
175
183
  // ── Read ─────────────────────────────────────────────────────────────
176
184
 
177
185
  /**
@@ -208,7 +216,7 @@ export function readInbox(
208
216
  }
209
217
 
210
218
  // Filter: only *.msg.json files (excludes .msg.json.tmp, .tmp, etc.)
211
- const msgFiles = entries.filter(f => f.endsWith(".msg.json") && !f.endsWith(".msg.json.tmp"));
219
+ const msgFiles = entries.filter((f) => f.endsWith(".msg.json") && !f.endsWith(".msg.json.tmp"));
212
220
 
213
221
  const results: Array<{ filename: string; message: MailboxMessage }> = [];
214
222
 
@@ -228,17 +236,13 @@ export function readInbox(
228
236
  try {
229
237
  parsed = JSON.parse(raw);
230
238
  } catch {
231
- process.stderr.write(
232
- `[mailbox] WARNING: malformed JSON in ${filename}, skipping\n`,
233
- );
239
+ process.stderr.write(`[mailbox] WARNING: malformed JSON in ${filename}, skipping\n`);
234
240
  continue;
235
241
  }
236
242
 
237
243
  // Validate shape
238
244
  if (!isValidMailboxMessage(parsed)) {
239
- process.stderr.write(
240
- `[mailbox] WARNING: invalid message shape in ${filename}, skipping\n`,
241
- );
245
+ process.stderr.write(`[mailbox] WARNING: invalid message shape in ${filename}, skipping\n`);
242
246
  continue;
243
247
  }
244
248
 
@@ -265,7 +269,6 @@ export function readInbox(
265
269
  return results;
266
270
  }
267
271
 
268
-
269
272
  // ── Acknowledge ──────────────────────────────────────────────────────
270
273
 
271
274
  /**
@@ -312,7 +315,6 @@ export function ackMessage(inboxDir: string, filename: string): boolean {
312
315
  }
313
316
  }
314
317
 
315
-
316
318
  // ── Validation ───────────────────────────────────────────────────────
317
319
 
318
320
  /**
@@ -334,13 +336,14 @@ export function isValidMailboxMessage(obj: unknown): obj is MailboxMessage {
334
336
  typeof m.batchId === "string" &&
335
337
  typeof m.from === "string" &&
336
338
  typeof m.to === "string" &&
337
- typeof m.timestamp === "number" && Number.isFinite(m.timestamp) &&
338
- typeof m.type === "string" && MAILBOX_MESSAGE_TYPES.has(m.type) &&
339
+ typeof m.timestamp === "number" &&
340
+ Number.isFinite(m.timestamp) &&
341
+ typeof m.type === "string" &&
342
+ MAILBOX_MESSAGE_TYPES.has(m.type) &&
339
343
  typeof m.content === "string"
340
344
  );
341
345
  }
342
346
 
343
-
344
347
  // ── Outbox (Agent → Supervisor, TP-106) ─────────────────────────
345
348
 
346
349
  /**
@@ -413,8 +416,14 @@ export function writeOutboxMessage(
413
416
  writeFileSync(tempPath, JSON.stringify(message, null, 2) + "\n", "utf-8");
414
417
  renameSync(tempPath, finalPath);
415
418
  } catch (err) {
416
- try { if (existsSync(tempPath)) unlinkSync(tempPath); } catch { /* cleanup */ }
417
- throw new Error(`Failed to write outbox message: ${err instanceof Error ? err.message : String(err)}`);
419
+ try {
420
+ if (existsSync(tempPath)) unlinkSync(tempPath);
421
+ } catch {
422
+ /* cleanup */
423
+ }
424
+ throw new Error(
425
+ `Failed to write outbox message: ${err instanceof Error ? err.message : String(err)}`,
426
+ );
418
427
  }
419
428
 
420
429
  return message;
@@ -430,11 +439,7 @@ export function writeOutboxMessage(
430
439
  *
431
440
  * @since TP-106
432
441
  */
433
- export function readOutbox(
434
- stateRoot: string,
435
- batchId: string,
436
- agentId: string,
437
- ): MailboxMessage[] {
442
+ export function readOutbox(stateRoot: string, batchId: string, agentId: string): MailboxMessage[] {
438
443
  const outboxDir = sessionOutboxDir(stateRoot, batchId, agentId);
439
444
  if (!existsSync(outboxDir)) return [];
440
445
 
@@ -445,7 +450,7 @@ export function readOutbox(
445
450
  return [];
446
451
  }
447
452
 
448
- const msgFiles = entries.filter(f => f.endsWith(".msg.json") && !f.endsWith(".msg.json.tmp"));
453
+ const msgFiles = entries.filter((f) => f.endsWith(".msg.json") && !f.endsWith(".msg.json.tmp"));
449
454
  const messages: MailboxMessage[] = [];
450
455
 
451
456
  for (const filename of msgFiles) {
@@ -455,7 +460,9 @@ export function readOutbox(
455
460
  if (isValidMailboxMessage(parsed)) {
456
461
  messages.push(parsed);
457
462
  }
458
- } catch { /* skip malformed */ }
463
+ } catch {
464
+ /* skip malformed */
465
+ }
459
466
  }
460
467
 
461
468
  messages.sort((a, b) => a.timestamp - b.timestamp);
@@ -484,12 +491,19 @@ export function readOutboxHistory(
484
491
  const outboxDir = sessionOutboxDir(stateRoot, batchId, agentId);
485
492
  const results: Array<{ message: MailboxMessage; acked: boolean }> = [];
486
493
 
487
- for (const [dir, acked] of [[outboxDir, false], [join(outboxDir, "processed"), true]] as const) {
494
+ for (const [dir, acked] of [
495
+ [outboxDir, false],
496
+ [join(outboxDir, "processed"), true],
497
+ ] as const) {
488
498
  if (!existsSync(dir)) continue;
489
499
  let entries: string[];
490
- try { entries = readdirSync(dir); } catch { continue; }
500
+ try {
501
+ entries = readdirSync(dir);
502
+ } catch {
503
+ continue;
504
+ }
491
505
 
492
- const msgFiles = entries.filter(f => f.endsWith(".msg.json") && !f.endsWith(".msg.json.tmp"));
506
+ const msgFiles = entries.filter((f) => f.endsWith(".msg.json") && !f.endsWith(".msg.json.tmp"));
493
507
  for (const filename of msgFiles) {
494
508
  try {
495
509
  const raw = readFileSync(join(dir, filename), "utf-8");
@@ -497,7 +511,9 @@ export function readOutboxHistory(
497
511
  if (isValidMailboxMessage(parsed)) {
498
512
  results.push({ message: parsed, acked });
499
513
  }
500
- } catch { /* skip malformed */ }
514
+ } catch {
515
+ /* skip malformed */
516
+ }
501
517
  }
502
518
  }
503
519
 
@@ -557,11 +573,7 @@ export function ackOutboxMessage(
557
573
  *
558
574
  * @since TP-187 (#538)
559
575
  */
560
- export function drainAgentOutbox(
561
- stateRoot: string,
562
- batchId: string,
563
- agentId: string,
564
- ): number {
576
+ export function drainAgentOutbox(stateRoot: string, batchId: string, agentId: string): number {
565
577
  const outboxDir = sessionOutboxDir(stateRoot, batchId, agentId);
566
578
  if (!existsSync(outboxDir)) return 0;
567
579
 
@@ -587,7 +599,11 @@ export function drainAgentOutbox(
587
599
 
588
600
  if (entry.endsWith(".msg.json")) {
589
601
  if (!processedDirEnsured) {
590
- try { mkdirSync(processedDir, { recursive: true }); } catch { /* fall through to rename error handling */ }
602
+ try {
603
+ mkdirSync(processedDir, { recursive: true });
604
+ } catch {
605
+ /* fall through to rename error handling */
606
+ }
591
607
  processedDirEnsured = true;
592
608
  }
593
609
  const dstPath = join(processedDir, entry);
@@ -632,23 +648,17 @@ export function drainAgentOutbox(
632
648
  *
633
649
  * @since TP-091
634
650
  */
635
- export function discoverMailboxAgentIds(
636
- stateRoot: string,
637
- batchId: string,
638
- ): string[] {
651
+ export function discoverMailboxAgentIds(stateRoot: string, batchId: string): string[] {
639
652
  const mbRoot = join(stateRoot, ".pi", MAILBOX_DIR_NAME, batchId);
640
653
  if (!existsSync(mbRoot)) return [];
641
654
  try {
642
655
  const entries = readdirSync(mbRoot, { withFileTypes: true });
643
- return entries
644
- .filter(e => e.isDirectory() && e.name !== "_broadcast")
645
- .map(e => e.name);
656
+ return entries.filter((e) => e.isDirectory() && e.name !== "_broadcast").map((e) => e.name);
646
657
  } catch {
647
658
  return [];
648
659
  }
649
660
  }
650
661
 
651
-
652
662
  export type MailboxAuditEventType =
653
663
  | "message_sent"
654
664
  | "message_delivered"
@@ -694,7 +704,6 @@ export function appendMailboxAuditEvent(
694
704
  }
695
705
  }
696
706
 
697
-
698
707
  // ── Broadcast (TP-106) ────────────────────────────────────────
699
708
 
700
709
  /**
@@ -721,7 +730,6 @@ export function writeBroadcastMessage(
721
730
  });
722
731
  }
723
732
 
724
-
725
733
  // ── Rate Limiting (TP-106) ─────────────────────────────────────
726
734
 
727
735
  /** Default rate limit: max 1 message per agent per 30 seconds. */