pmx-canvas 0.3.0 → 0.3.1

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 (156) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/canvas/index.js +2 -2
  3. package/dist/types/cli/daemon.d.ts +74 -0
  4. package/dist/types/cli/watch.d.ts +2 -2
  5. package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
  6. package/dist/types/client/canvas/CommandPalette.d.ts +1 -1
  7. package/dist/types/client/canvas/Minimap.d.ts +1 -1
  8. package/dist/types/client/nodes/FileNode.d.ts +1 -1
  9. package/dist/types/client/nodes/ImageNode.d.ts +1 -1
  10. package/dist/types/client/nodes/InlineFormatBar.d.ts +1 -1
  11. package/dist/types/client/nodes/MarkdownNode.d.ts +1 -1
  12. package/dist/types/client/nodes/PromptNode.d.ts +1 -1
  13. package/dist/types/client/nodes/ResponseNode.d.ts +1 -1
  14. package/dist/types/server/canvas-schema.d.ts +1 -1
  15. package/dist/types/server/html-primitives.d.ts +1 -1
  16. package/dist/types/server/index.d.ts +4 -4
  17. package/dist/types/server/operations/index.d.ts +1 -1
  18. package/dist/types/server/operations/ops/ax-read.d.ts +2 -0
  19. package/dist/types/server/operations/ops/canvas-wire.d.ts +2 -0
  20. package/dist/types/server/operations/ops/ext-app.d.ts +2 -0
  21. package/docs/http-api.md +28 -0
  22. package/docs/plans/plan-009-tech-debt-backlog.md +5 -5
  23. package/docs/tech-debt-assessment-2026-07.md +2 -2
  24. package/package.json +5 -2
  25. package/skills/pmx-canvas/SKILL.md +3 -1
  26. package/skills/pmx-canvas/references/full-reference.md +10 -3
  27. package/src/cli/agent.ts +1861 -1548
  28. package/src/cli/daemon.ts +460 -0
  29. package/src/cli/index.ts +63 -326
  30. package/src/cli/watch.ts +2 -10
  31. package/src/client/App.tsx +48 -46
  32. package/src/client/canvas/AttentionHistory.tsx +11 -1
  33. package/src/client/canvas/CanvasNode.tsx +41 -29
  34. package/src/client/canvas/CanvasViewport.tsx +101 -66
  35. package/src/client/canvas/CommandPalette.tsx +61 -27
  36. package/src/client/canvas/ContextMenu.tsx +13 -20
  37. package/src/client/canvas/ContextPinBar.tsx +1 -5
  38. package/src/client/canvas/ContextPinHud.tsx +1 -6
  39. package/src/client/canvas/DockedNode.tsx +4 -4
  40. package/src/client/canvas/EdgeLayer.tsx +37 -36
  41. package/src/client/canvas/ExpandedNodeOverlay.tsx +69 -45
  42. package/src/client/canvas/FocusFieldLayer.tsx +20 -22
  43. package/src/client/canvas/IntentLayer.tsx +31 -14
  44. package/src/client/canvas/Minimap.tsx +11 -16
  45. package/src/client/canvas/SelectionBar.tsx +4 -11
  46. package/src/client/canvas/ShortcutOverlay.tsx +3 -1
  47. package/src/client/canvas/SnapshotPanel.tsx +77 -95
  48. package/src/client/canvas/auto-fit.ts +15 -14
  49. package/src/client/canvas/snap-guides.ts +12 -12
  50. package/src/client/canvas/use-node-resize.ts +1 -5
  51. package/src/client/canvas/use-pan-zoom.ts +25 -26
  52. package/src/client/ext-app/bridge.ts +3 -12
  53. package/src/client/icons.tsx +63 -20
  54. package/src/client/nodes/ContextNode.tsx +14 -25
  55. package/src/client/nodes/ExtAppFrame.tsx +60 -39
  56. package/src/client/nodes/FileNode.tsx +74 -62
  57. package/src/client/nodes/GroupNode.tsx +4 -6
  58. package/src/client/nodes/HtmlNode.tsx +76 -46
  59. package/src/client/nodes/ImageNode.tsx +18 -27
  60. package/src/client/nodes/InlineFormatBar.tsx +4 -21
  61. package/src/client/nodes/InlineMarkdownEditor.tsx +0 -1
  62. package/src/client/nodes/LedgerNode.tsx +10 -4
  63. package/src/client/nodes/MarkdownNode.tsx +3 -10
  64. package/src/client/nodes/McpAppNode.tsx +26 -22
  65. package/src/client/nodes/MdFormatBar.tsx +10 -7
  66. package/src/client/nodes/PromptNode.tsx +23 -51
  67. package/src/client/nodes/ResponseNode.tsx +3 -13
  68. package/src/client/nodes/StatusNode.tsx +5 -9
  69. package/src/client/nodes/StatusSummary.tsx +2 -8
  70. package/src/client/nodes/WebpageNode.tsx +20 -14
  71. package/src/client/nodes/iframe-document-url.ts +25 -16
  72. package/src/client/nodes/image-warnings.ts +1 -7
  73. package/src/client/nodes/md-format.ts +20 -5
  74. package/src/client/state/attention-bridge.ts +4 -9
  75. package/src/client/state/attention-store.ts +1 -7
  76. package/src/client/state/canvas-store.ts +52 -36
  77. package/src/client/state/intent-bridge.ts +176 -112
  78. package/src/client/state/intent-store.ts +4 -1
  79. package/src/client/state/sse-bridge.ts +53 -70
  80. package/src/json-render/catalog.ts +12 -16
  81. package/src/json-render/charts/components.tsx +16 -20
  82. package/src/json-render/charts/extra-components.tsx +8 -16
  83. package/src/json-render/charts/extra-definitions.ts +1 -2
  84. package/src/json-render/charts/tufte-components.tsx +37 -20
  85. package/src/json-render/charts/tufte-definitions.ts +8 -2
  86. package/src/json-render/renderer/index.tsx +42 -22
  87. package/src/json-render/schema.ts +6 -3
  88. package/src/json-render/server.ts +33 -39
  89. package/src/mcp/canvas-access.ts +35 -21
  90. package/src/mcp/server.ts +132 -70
  91. package/src/server/agent-context.ts +63 -36
  92. package/src/server/ax-context.ts +7 -5
  93. package/src/server/ax-interaction.ts +176 -43
  94. package/src/server/ax-state-manager.ts +182 -39
  95. package/src/server/ax-state.ts +142 -47
  96. package/src/server/canvas-db.ts +213 -95
  97. package/src/server/canvas-operations.ts +177 -120
  98. package/src/server/canvas-provenance.ts +1 -4
  99. package/src/server/canvas-schema.ts +454 -73
  100. package/src/server/canvas-serialization.ts +27 -35
  101. package/src/server/canvas-state.ts +150 -58
  102. package/src/server/chart-template.ts +4 -5
  103. package/src/server/code-graph.ts +19 -6
  104. package/src/server/diagram-presets.ts +28 -29
  105. package/src/server/ext-app-lookup.ts +3 -12
  106. package/src/server/html-node-summary.ts +19 -10
  107. package/src/server/html-primitives.ts +326 -97
  108. package/src/server/html-surface.ts +6 -9
  109. package/src/server/image-source.ts +6 -4
  110. package/src/server/index.ts +320 -217
  111. package/src/server/intent-registry.ts +2 -5
  112. package/src/server/mcp-app-candidate.ts +5 -10
  113. package/src/server/mcp-app-host.ts +14 -38
  114. package/src/server/mcp-app-runtime.ts +12 -20
  115. package/src/server/mutation-history.ts +15 -5
  116. package/src/server/operations/composites.ts +1 -3
  117. package/src/server/operations/http.ts +2 -3
  118. package/src/server/operations/index.ts +7 -1
  119. package/src/server/operations/invoker.ts +4 -3
  120. package/src/server/operations/mcp.ts +22 -30
  121. package/src/server/operations/ops/annotation.ts +122 -10
  122. package/src/server/operations/ops/app.ts +98 -73
  123. package/src/server/operations/ops/ax-await.ts +17 -10
  124. package/src/server/operations/ops/ax-read.ts +347 -0
  125. package/src/server/operations/ops/ax-shared.ts +2 -7
  126. package/src/server/operations/ops/ax-state.ts +32 -14
  127. package/src/server/operations/ops/ax-timeline.ts +32 -19
  128. package/src/server/operations/ops/ax-work.ts +54 -37
  129. package/src/server/operations/ops/batch.ts +39 -14
  130. package/src/server/operations/ops/canvas-wire.ts +91 -0
  131. package/src/server/operations/ops/edges.ts +37 -25
  132. package/src/server/operations/ops/ext-app.ts +346 -0
  133. package/src/server/operations/ops/groups.ts +49 -20
  134. package/src/server/operations/ops/intent.ts +18 -12
  135. package/src/server/operations/ops/json-render.ts +239 -98
  136. package/src/server/operations/ops/nodes.ts +298 -109
  137. package/src/server/operations/ops/query.ts +46 -28
  138. package/src/server/operations/ops/snapshots.ts +35 -26
  139. package/src/server/operations/ops/validate.ts +2 -1
  140. package/src/server/operations/ops/viewport.ts +60 -16
  141. package/src/server/operations/ops/webview.ts +44 -18
  142. package/src/server/operations/registry.ts +2 -3
  143. package/src/server/operations/types.ts +7 -5
  144. package/src/server/operations/webview-runner.ts +1 -3
  145. package/src/server/placement.ts +8 -18
  146. package/src/server/server.ts +108 -1027
  147. package/src/server/spatial-analysis.ts +39 -25
  148. package/src/server/trace-manager.ts +3 -8
  149. package/src/server/web-artifacts.ts +23 -27
  150. package/src/server/webpage-node.ts +5 -13
  151. package/src/shared/auto-arrange.ts +12 -5
  152. package/src/shared/content-height-reporter.ts +8 -6
  153. package/src/shared/ext-app-tool-result.ts +2 -6
  154. package/src/shared/placement.ts +1 -4
  155. package/src/shared/semantic-attention.ts +39 -37
  156. package/src/shared/surface.ts +8 -4
@@ -251,8 +251,16 @@ export class AxStateManager {
251
251
  this.deps.recordMutation({
252
252
  operationType: 'addWorkItem',
253
253
  description: `Added work item "${item.title}"`,
254
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
255
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
254
+ forward: this.deps.suppressed(() => {
255
+ this.applyAxState(applied);
256
+ this.deps.scheduleSave();
257
+ this.deps.notifyChange('ax');
258
+ }),
259
+ inverse: this.deps.suppressed(() => {
260
+ this.applyAxState(oldAxState);
261
+ this.deps.scheduleSave();
262
+ this.deps.notifyChange('ax');
263
+ }),
256
264
  });
257
265
  return applied.workItems.find((w) => w.id === item.id) ?? item;
258
266
  }
@@ -282,8 +290,16 @@ export class AxStateManager {
282
290
  this.deps.recordMutation({
283
291
  operationType: 'updateWorkItem',
284
292
  description: `Updated work item ${id}`,
285
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
286
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
293
+ forward: this.deps.suppressed(() => {
294
+ this.applyAxState(applied);
295
+ this.deps.scheduleSave();
296
+ this.deps.notifyChange('ax');
297
+ }),
298
+ inverse: this.deps.suppressed(() => {
299
+ this.applyAxState(oldAxState);
300
+ this.deps.scheduleSave();
301
+ this.deps.notifyChange('ax');
302
+ }),
287
303
  });
288
304
  return applied.workItems.find((w) => w.id === id) ?? null;
289
305
  }
@@ -306,8 +322,16 @@ export class AxStateManager {
306
322
  this.deps.recordMutation({
307
323
  operationType: 'requestApproval',
308
324
  description: `Requested approval "${gate.title}"`,
309
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
310
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
325
+ forward: this.deps.suppressed(() => {
326
+ this.applyAxState(applied);
327
+ this.deps.scheduleSave();
328
+ this.deps.notifyChange('ax');
329
+ }),
330
+ inverse: this.deps.suppressed(() => {
331
+ this.applyAxState(oldAxState);
332
+ this.deps.scheduleSave();
333
+ this.deps.notifyChange('ax');
334
+ }),
311
335
  });
312
336
  return applied.approvalGates.find((g) => g.id === gate.id) ?? gate;
313
337
  }
@@ -334,8 +358,16 @@ export class AxStateManager {
334
358
  this.deps.recordMutation({
335
359
  operationType: 'resolveApproval',
336
360
  description: `Resolved approval ${id} -> ${decision}`,
337
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
338
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
361
+ forward: this.deps.suppressed(() => {
362
+ this.applyAxState(applied);
363
+ this.deps.scheduleSave();
364
+ this.deps.notifyChange('ax');
365
+ }),
366
+ inverse: this.deps.suppressed(() => {
367
+ this.applyAxState(oldAxState);
368
+ this.deps.scheduleSave();
369
+ this.deps.notifyChange('ax');
370
+ }),
339
371
  });
340
372
  return applied.approvalGates.find((g) => g.id === id) ?? null;
341
373
  }
@@ -381,8 +413,16 @@ export class AxStateManager {
381
413
  this.deps.recordMutation({
382
414
  operationType: 'addReviewAnnotation',
383
415
  description: `Added review ${annotation.kind} (${annotation.severity})`,
384
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
385
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
416
+ forward: this.deps.suppressed(() => {
417
+ this.applyAxState(applied);
418
+ this.deps.scheduleSave();
419
+ this.deps.notifyChange('ax');
420
+ }),
421
+ inverse: this.deps.suppressed(() => {
422
+ this.applyAxState(oldAxState);
423
+ this.deps.scheduleSave();
424
+ this.deps.notifyChange('ax');
425
+ }),
386
426
  });
387
427
  return applied.reviewAnnotations.find((r) => r.id === annotation.id) ?? annotation;
388
428
  }
@@ -411,8 +451,16 @@ export class AxStateManager {
411
451
  this.deps.recordMutation({
412
452
  operationType: 'updateReviewAnnotation',
413
453
  description: `Updated review ${id}`,
414
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
415
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
454
+ forward: this.deps.suppressed(() => {
455
+ this.applyAxState(applied);
456
+ this.deps.scheduleSave();
457
+ this.deps.notifyChange('ax');
458
+ }),
459
+ inverse: this.deps.suppressed(() => {
460
+ this.applyAxState(oldAxState);
461
+ this.deps.scheduleSave();
462
+ this.deps.notifyChange('ax');
463
+ }),
416
464
  });
417
465
  return applied.reviewAnnotations.find((r) => r.id === id) ?? null;
418
466
  }
@@ -440,8 +488,16 @@ export class AxStateManager {
440
488
  this.deps.recordMutation({
441
489
  operationType: 'requestElicitation',
442
490
  description: `Requested elicitation "${elicitation.prompt}"`,
443
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
444
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
491
+ forward: this.deps.suppressed(() => {
492
+ this.applyAxState(applied);
493
+ this.deps.scheduleSave();
494
+ this.deps.notifyChange('ax');
495
+ }),
496
+ inverse: this.deps.suppressed(() => {
497
+ this.applyAxState(oldAxState);
498
+ this.deps.scheduleSave();
499
+ this.deps.notifyChange('ax');
500
+ }),
445
501
  });
446
502
  return applied.elicitations.find((e) => e.id === elicitation.id) ?? elicitation;
447
503
  }
@@ -468,8 +524,16 @@ export class AxStateManager {
468
524
  this.deps.recordMutation({
469
525
  operationType: 'respondElicitation',
470
526
  description: `Answered elicitation ${id}`,
471
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
472
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
527
+ forward: this.deps.suppressed(() => {
528
+ this.applyAxState(applied);
529
+ this.deps.scheduleSave();
530
+ this.deps.notifyChange('ax');
531
+ }),
532
+ inverse: this.deps.suppressed(() => {
533
+ this.applyAxState(oldAxState);
534
+ this.deps.scheduleSave();
535
+ this.deps.notifyChange('ax');
536
+ }),
473
537
  });
474
538
  return applied.elicitations.find((e) => e.id === id) ?? null;
475
539
  }
@@ -492,8 +556,16 @@ export class AxStateManager {
492
556
  this.deps.recordMutation({
493
557
  operationType: 'requestMode',
494
558
  description: `Requested mode "${request.mode}"`,
495
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
496
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
559
+ forward: this.deps.suppressed(() => {
560
+ this.applyAxState(applied);
561
+ this.deps.scheduleSave();
562
+ this.deps.notifyChange('ax');
563
+ }),
564
+ inverse: this.deps.suppressed(() => {
565
+ this.applyAxState(oldAxState);
566
+ this.deps.scheduleSave();
567
+ this.deps.notifyChange('ax');
568
+ }),
497
569
  });
498
570
  return applied.modeRequests.find((m) => m.id === request.id) ?? request;
499
571
  }
@@ -520,8 +592,16 @@ export class AxStateManager {
520
592
  this.deps.recordMutation({
521
593
  operationType: 'resolveModeRequest',
522
594
  description: `Resolved mode request ${id} -> ${decision}`,
523
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
524
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
595
+ forward: this.deps.suppressed(() => {
596
+ this.applyAxState(applied);
597
+ this.deps.scheduleSave();
598
+ this.deps.notifyChange('ax');
599
+ }),
600
+ inverse: this.deps.suppressed(() => {
601
+ this.applyAxState(oldAxState);
602
+ this.deps.scheduleSave();
603
+ this.deps.notifyChange('ax');
604
+ }),
525
605
  });
526
606
  return applied.modeRequests.find((m) => m.id === id) ?? null;
527
607
  }
@@ -544,10 +624,19 @@ export class AxStateManager {
544
624
  }
545
625
 
546
626
  /** Invoke a registry-gated PMX command intent — records a timeline event (no execution). */
547
- invokeCommand(name: string, args: Record<string, unknown> | null = null, options: { source?: PmxAxSource } = {}): PmxAxEvent | null {
627
+ invokeCommand(
628
+ name: string,
629
+ args: Record<string, unknown> | null = null,
630
+ options: { source?: PmxAxSource } = {},
631
+ ): PmxAxEvent | null {
548
632
  if (!isAxCommand(name)) return null;
549
633
  return this.recordAxEvent(
550
- { kind: 'command', summary: name, detail: AX_COMMAND_REGISTRY[name].description, data: { command: name, ...(args ? { args } : {}) } },
634
+ {
635
+ kind: 'command',
636
+ summary: name,
637
+ detail: AX_COMMAND_REGISTRY[name].description,
638
+ data: { command: name, ...(args ? { args } : {}) },
639
+ },
551
640
  options,
552
641
  );
553
642
  }
@@ -573,18 +662,25 @@ export class AxStateManager {
573
662
  this.deps.recordMutation({
574
663
  operationType: 'setPolicy',
575
664
  description: 'Updated AX policy',
576
- forward: this.deps.suppressed(() => { this.applyAxState(applied); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
577
- inverse: this.deps.suppressed(() => { this.applyAxState(oldAxState); this.deps.scheduleSave(); this.deps.notifyChange('ax'); }),
665
+ forward: this.deps.suppressed(() => {
666
+ this.applyAxState(applied);
667
+ this.deps.scheduleSave();
668
+ this.deps.notifyChange('ax');
669
+ }),
670
+ inverse: this.deps.suppressed(() => {
671
+ this.applyAxState(oldAxState);
672
+ this.deps.scheduleSave();
673
+ this.deps.notifyChange('ax');
674
+ }),
578
675
  });
579
676
  return applied.policy;
580
677
  }
581
678
 
582
679
  setHostCapability(input: unknown, _options: { source?: PmxAxSource } = {}): PmxAxHostCapability {
583
- const cap = normalizeAxHostCapability(
584
- isRecord(input)
585
- ? { ...input, reportedAt: new Date().toISOString() }
586
- : { reportedAt: new Date().toISOString() },
587
- ) ?? createEmptyAxHostCapability();
680
+ const cap =
681
+ normalizeAxHostCapability(
682
+ isRecord(input) ? { ...input, reportedAt: new Date().toISOString() } : { reportedAt: new Date().toISOString() },
683
+ ) ?? createEmptyAxHostCapability();
588
684
  this._axHostCapability = cap;
589
685
  const db = this.deps.getDb();
590
686
  if (db) {
@@ -600,7 +696,13 @@ export class AxStateManager {
600
696
 
601
697
  // ── Timeline (DB-direct; NOT in _axState; NOT history-recorded) ───
602
698
  recordAxEvent(
603
- input: { kind: PmxAxEventKind; summary: string; detail?: string | null; nodeIds?: string[]; data?: Record<string, unknown> | null },
699
+ input: {
700
+ kind: PmxAxEventKind;
701
+ summary: string;
702
+ detail?: string | null;
703
+ nodeIds?: string[];
704
+ data?: Record<string, unknown> | null;
705
+ },
604
706
  options: { source?: PmxAxSource } = {},
605
707
  ): PmxAxEvent {
606
708
  const draft = createAxEvent(input, options.source ?? 'api');
@@ -619,7 +721,14 @@ export class AxStateManager {
619
721
  }
620
722
 
621
723
  addEvidence(
622
- input: { kind: PmxAxEvidenceKind; title: string; body?: string | null; ref?: string | null; nodeIds?: string[]; data?: Record<string, unknown> | null },
724
+ input: {
725
+ kind: PmxAxEvidenceKind;
726
+ title: string;
727
+ body?: string | null;
728
+ ref?: string | null;
729
+ nodeIds?: string[];
730
+ data?: Record<string, unknown> | null;
731
+ },
623
732
  options: { source?: PmxAxSource } = {},
624
733
  ): PmxAxEvidence {
625
734
  const draft = createAxEvidence(input, options.source ?? 'api');
@@ -690,11 +799,23 @@ export class AxStateManager {
690
799
  reactions?: {
691
800
  workItem?: false | { status?: PmxAxWorkItemStatus; detail?: string | null };
692
801
  evidence?: false | { kind?: PmxAxEvidenceKind; body?: string | null };
693
- review?: false | { severity?: PmxAxReviewSeverity; kind?: PmxAxReviewKind; anchorType?: PmxAxReviewAnchorType; nodeId?: string | null };
802
+ review?:
803
+ | false
804
+ | {
805
+ severity?: PmxAxReviewSeverity;
806
+ kind?: PmxAxReviewKind;
807
+ anchorType?: PmxAxReviewAnchorType;
808
+ nodeId?: string | null;
809
+ };
694
810
  };
695
811
  },
696
812
  options: { source?: PmxAxSource } = {},
697
- ): { event: PmxAxEvent; workItem: PmxAxWorkItem | null; evidence: PmxAxEvidence | null; review: PmxAxReviewAnnotation | null } {
813
+ ): {
814
+ event: PmxAxEvent;
815
+ workItem: PmxAxWorkItem | null;
816
+ evidence: PmxAxEvidence | null;
817
+ review: PmxAxReviewAnnotation | null;
818
+ } {
698
819
  const source = options.source ?? 'api';
699
820
  const summary = input.summary ?? input.title;
700
821
  const isFailure = input.kind === 'failure' || input.kind === 'error' || input.outcome === 'failure';
@@ -726,15 +847,26 @@ export class AxStateManager {
726
847
  // (2) Resolve reactions: kind-driven defaults, overridable per call.
727
848
  const r = input.reactions ?? {};
728
849
  const wantWorkItem = r.workItem === false ? null : (r.workItem ?? (isFailure ? {} : null));
729
- const wantEvidence = r.evidence === false
730
- ? null
731
- : (r.evidence ?? (isFailure ? { kind: 'logs' as PmxAxEvidenceKind } : isToolSuccess ? { kind: 'tool-result' as PmxAxEvidenceKind } : null));
850
+ const wantEvidence =
851
+ r.evidence === false
852
+ ? null
853
+ : (r.evidence ??
854
+ (isFailure
855
+ ? { kind: 'logs' as PmxAxEvidenceKind }
856
+ : isToolSuccess
857
+ ? { kind: 'tool-result' as PmxAxEvidenceKind }
858
+ : null));
732
859
  const wantReview = r.review === false ? null : (r.review ?? (isFailure ? {} : null));
733
860
 
734
861
  let workItem: PmxAxWorkItem | null = null;
735
862
  if (wantWorkItem) {
736
863
  workItem = this.addWorkItem(
737
- { title: input.title, status: wantWorkItem.status ?? 'blocked', detail: wantWorkItem.detail ?? summary, nodeIds },
864
+ {
865
+ title: input.title,
866
+ status: wantWorkItem.status ?? 'blocked',
867
+ detail: wantWorkItem.detail ?? summary,
868
+ nodeIds,
869
+ },
738
870
  { source },
739
871
  );
740
872
  }
@@ -742,7 +874,13 @@ export class AxStateManager {
742
874
  let evidence: PmxAxEvidence | null = null;
743
875
  if (wantEvidence) {
744
876
  evidence = this.addEvidence(
745
- { kind: wantEvidence.kind ?? 'logs', title: input.title, body: wantEvidence.body ?? input.summary ?? null, ref: input.ref ?? null, nodeIds },
877
+ {
878
+ kind: wantEvidence.kind ?? 'logs',
879
+ title: input.title,
880
+ body: wantEvidence.body ?? input.summary ?? null,
881
+ ref: input.ref ?? null,
882
+ nodeIds,
883
+ },
746
884
  { source },
747
885
  );
748
886
  }
@@ -816,7 +954,12 @@ export class AxStateManager {
816
954
  : { recentEvents: [], recentEvidence: [], pendingSteering: [], counts: { events: 0, evidence: 0, steering: 0 } };
817
955
  }
818
956
 
819
- getAxTimeline(q: AxTimelineQuery = {}): { events: PmxAxEvent[]; evidence: PmxAxEvidence[]; steering: PmxAxSteeringMessage[]; summary: PmxAxTimelineSummary } {
957
+ getAxTimeline(q: AxTimelineQuery = {}): {
958
+ events: PmxAxEvent[];
959
+ evidence: PmxAxEvidence[];
960
+ steering: PmxAxSteeringMessage[];
961
+ summary: PmxAxTimelineSummary;
962
+ } {
820
963
  return {
821
964
  events: this.getAxEvents(q),
822
965
  evidence: this.getAxEvidence(q),