@diffohq/diffo 0.5.0 → 0.6.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 (97) hide show
  1. package/dist/cli.mjs +117 -20
  2. package/dist/client/assets/{abnfDiagram-O67JEVCF-Eku-JiMb.js → abnfDiagram-O67JEVCF-vILxBZcB.js} +1 -1
  3. package/dist/client/assets/{arc-lV5GSLJD.js → arc-KM37zfEu.js} +1 -1
  4. package/dist/client/assets/architecture-7GRP2DOG-DzlmD0Wj.js +1 -0
  5. package/dist/client/assets/{architectureDiagram-NJMV4G6O-DIH1VGVe.js → architectureDiagram-NJMV4G6O-CCe24XcA.js} +1 -1
  6. package/dist/client/assets/{blockDiagram-BEXU5L5S-CaCCdXJr.js → blockDiagram-BEXU5L5S-GL2esJ0w.js} +1 -1
  7. package/dist/client/assets/{c4Diagram-YGBWAQC7-DmnVa0_m.js → c4Diagram-YGBWAQC7-BcRujrvs.js} +1 -1
  8. package/dist/client/assets/channel-BffjfVqs.js +1 -0
  9. package/dist/client/assets/{chunk-3FUC2YCW-DDROCT3x.js → chunk-3FUC2YCW-Gj4X9KK9.js} +1 -1
  10. package/dist/client/assets/{chunk-5DYCD2WN-CL5xMelX.js → chunk-5DYCD2WN-DZs-erj_.js} +1 -1
  11. package/dist/client/assets/{chunk-742MDFTN-CTz8pFT1.js → chunk-742MDFTN-Db1JJZ9G.js} +1 -1
  12. package/dist/client/assets/{chunk-7INBJB4K-mTzp3uc7.js → chunk-7INBJB4K-B_wqJ7Xn.js} +1 -1
  13. package/dist/client/assets/{chunk-7M6MHVWA-AyZcKoA0.js → chunk-7M6MHVWA-DuALBizw.js} +1 -1
  14. package/dist/client/assets/{chunk-7PRAP22T-CEPNl3r7.js → chunk-7PRAP22T-D9QvZUm3.js} +1 -1
  15. package/dist/client/assets/{chunk-GTNCS2PH-DnfAIbaL.js → chunk-GTNCS2PH-JFHsSpPU.js} +1 -1
  16. package/dist/client/assets/{chunk-GWA4HPMP-DuzmSd5n.js → chunk-GWA4HPMP-CX_60U9Y.js} +1 -1
  17. package/dist/client/assets/{chunk-MBY4JIJT-BGNKEJZT.js → chunk-MBY4JIJT-BVqUStmy.js} +1 -1
  18. package/dist/client/assets/{chunk-NETBCI7D-CXPYvz5G.js → chunk-NETBCI7D-BoSm0O5f.js} +1 -1
  19. package/dist/client/assets/{chunk-O7XYJQB3-CYftULw7.js → chunk-O7XYJQB3-DG64mbS_.js} +1 -1
  20. package/dist/client/assets/{chunk-UA2S7LBM-DQbf9Dl1.js → chunk-UA2S7LBM-BL039fcM.js} +1 -1
  21. package/dist/client/assets/{chunk-WEXAMYUT-CcNQw347.js → chunk-WEXAMYUT-BPFyuzbi.js} +1 -1
  22. package/dist/client/assets/{chunk-XXDRQBXY-Bf1t_xv6.js → chunk-XXDRQBXY-BzCs4oPB.js} +1 -1
  23. package/dist/client/assets/{chunk-Z7XXMR3K-pRmpdAOe.js → chunk-Z7XXMR3K-D9UN9ldM.js} +1 -1
  24. package/dist/client/assets/{chunk-ZIGJFQKS-B5DDwrRj.js → chunk-ZIGJFQKS-D47UlTiy.js} +1 -1
  25. package/dist/client/assets/{classDiagram-v2-NBCMYWYE-DCpEkxmb.js → classDiagram-v2-NBCMYWYE-CXeBds6Z.js} +1 -1
  26. package/dist/client/assets/{core-Cl3AV7cB.js → core-De6Bel6T.js} +1 -1
  27. package/dist/client/assets/{cose-bilkent-JH36ORCC-DQEwYOPh.js → cose-bilkent-JH36ORCC-C5C9BMn5.js} +1 -1
  28. package/dist/client/assets/{cynefin-OW5HDTMX-B8MfDKLI.js → cynefin-OW5HDTMX-TQm3krMs.js} +1 -1
  29. package/dist/client/assets/{cynefinDiagram-VND7K2PF-B4WvhUhO.js → cynefinDiagram-VND7K2PF-D9L1g2S1.js} +1 -1
  30. package/dist/client/assets/{dagre-6A5THRUB-B9IMFM72.js → dagre-6A5THRUB-D9iVd0tg.js} +1 -1
  31. package/dist/client/assets/{diagram-22UHCM2B-DB0QnlzY.js → diagram-22UHCM2B-CD_1yZgj.js} +1 -1
  32. package/dist/client/assets/{diagram-3UASUU5V-DW2JbaXS.js → diagram-3UASUU5V-BLiXkub3.js} +1 -1
  33. package/dist/client/assets/{diagram-ATOU4E4O-kELWjFhd.js → diagram-ATOU4E4O-CnXY0tjf.js} +1 -1
  34. package/dist/client/assets/{diagram-CDSNMT55-DHJN8X6p.js → diagram-CDSNMT55-BBnDsrf_.js} +1 -1
  35. package/dist/client/assets/{diagram-MLGK6HIB-3hlAEcUl.js → diagram-MLGK6HIB-BUiu4OKD.js} +1 -1
  36. package/dist/client/assets/{diagram-MPIPVDR6-BmI2ylfG.js → diagram-MPIPVDR6-DiI9FWeO.js} +1 -1
  37. package/dist/client/assets/{dist-DOT26anA.js → dist-BWYGCgdo.js} +1 -1
  38. package/dist/client/assets/{dist-DNMzTuVG.js → dist-Co85aeoI.js} +1 -1
  39. package/dist/client/assets/{ebnfDiagram-ZINNZB2B-lJT30vWx.js → ebnfDiagram-ZINNZB2B-Bg_BLedv.js} +1 -1
  40. package/dist/client/assets/{elk-276RUBZZ-Y2ie1QZI.js → elk-276RUBZZ-BO7Zoa7U.js} +1 -1
  41. package/dist/client/assets/{engine-oniguruma-qcHcQ7gy.js → engine-oniguruma-DCFwTJLE.js} +1 -1
  42. package/dist/client/assets/{erDiagram-OPXOYQCR-BBPmg1YD.js → erDiagram-OPXOYQCR-DjBak3Ld.js} +1 -1
  43. package/dist/client/assets/eventmodeling-NTZA5JFV-BA4dpxhq.js +1 -0
  44. package/dist/client/assets/flowDiagram-KWPJA3E3-BXSGu0Q5.js +1 -0
  45. package/dist/client/assets/{ganttDiagram-FUAMR5RP-xPVj2AwG.js → ganttDiagram-FUAMR5RP-CEn0Np5L.js} +1 -1
  46. package/dist/client/assets/{gitGraph-4MIJSDKK-pvXQROBw.js → gitGraph-4MIJSDKK-DVMdaaG2.js} +1 -1
  47. package/dist/client/assets/{gitGraphDiagram-X574FWY7-pp7frUxm.js → gitGraphDiagram-X574FWY7-B6ZkiY7u.js} +1 -1
  48. package/dist/client/assets/index-6w3rS9cw.js +91 -0
  49. package/dist/client/assets/{index-BUmM006M.css → index-D934d4yh.css} +1 -1
  50. package/dist/client/assets/{info-A6RAGUB7-DLCTmODc.js → info-A6RAGUB7-Idt2RahI.js} +1 -1
  51. package/dist/client/assets/{infoDiagram-VRGFBTTK-BGnYOvv2.js → infoDiagram-VRGFBTTK-CA8T3csq.js} +1 -1
  52. package/dist/client/assets/{ishikawaDiagram-OU5B5YK6-DYbwoJB-.js → ishikawaDiagram-OU5B5YK6-DcgLwVJX.js} +1 -1
  53. package/dist/client/assets/{journeyDiagram-ZHPQQLJL-DHav_LIH.js → journeyDiagram-ZHPQQLJL-_AVEW5aE.js} +1 -1
  54. package/dist/client/assets/{kanban-definition-PNTS6WVX-Cj645S2T.js → kanban-definition-PNTS6WVX-CZ2gNo-B.js} +1 -1
  55. package/dist/client/assets/{line-Htxv9F4J.js → line-CHew3ngr.js} +1 -1
  56. package/dist/client/assets/{linear-e0hVUtYI.js → linear-Baz1Hb3u.js} +1 -1
  57. package/dist/client/assets/{mermaid-parser.core-DtRc-ypM.js → mermaid-parser.core-D2BrkwRE.js} +3 -3
  58. package/dist/client/assets/{mermaid.core-CyG7EFf-.js → mermaid.core-CCFlYVgY.js} +4 -4
  59. package/dist/client/assets/{mindmap-definition-NLK3R4M7-501wUG6-.js → mindmap-definition-NLK3R4M7-BXG9w5sC.js} +1 -1
  60. package/dist/client/assets/{packet-AYTQ26CC-CBEtSauH.js → packet-AYTQ26CC-BOvg32Rh.js} +1 -1
  61. package/dist/client/assets/{pegDiagram-GJSIUBJH-958m_CS_.js → pegDiagram-GJSIUBJH-COukdq7o.js} +1 -1
  62. package/dist/client/assets/{pie-WAS4IAKB-CtMX8NyM.js → pie-WAS4IAKB-ChHsdIQV.js} +1 -1
  63. package/dist/client/assets/{pieDiagram-5QR66LMP-Ch_R04up.js → pieDiagram-5QR66LMP-Deng5oun.js} +1 -1
  64. package/dist/client/assets/{quadrantDiagram-O4NWA36T-WpRKg-an.js → quadrantDiagram-O4NWA36T-DmEJ83mR.js} +1 -1
  65. package/dist/client/assets/{radar-RG4KPBEZ-C6cMrg-A.js → radar-RG4KPBEZ-YxcXBiXc.js} +1 -1
  66. package/dist/client/assets/{railroad-74A4TZTK-D5TKF4bs.js → railroad-74A4TZTK-RkYX7A2D.js} +1 -1
  67. package/dist/client/assets/railroad-abnf-HS5TGJTU-CYF7Z2Wu.js +1 -0
  68. package/dist/client/assets/railroad-ebnf-LZEXJU2U-CqV11tet.js +1 -0
  69. package/dist/client/assets/railroad-peg-WCYAUIDC-CPusJj6I.js +1 -0
  70. package/dist/client/assets/{railroadDiagram-XR7U4H2S-CsGtkzal.js → railroadDiagram-XR7U4H2S-uj5HQbYy.js} +1 -1
  71. package/dist/client/assets/{requirementDiagram-PLB6GJNP-By5yShOx.js → requirementDiagram-PLB6GJNP-C_QtkIlI.js} +1 -1
  72. package/dist/client/assets/{sankeyDiagram-IPEJSGJF-D0iqRNhC.js → sankeyDiagram-IPEJSGJF-BfxM5TKv.js} +1 -1
  73. package/dist/client/assets/{sequenceDiagram-PO4LG4MO-BbN6AjiL.js → sequenceDiagram-PO4LG4MO-DXflg1u_.js} +1 -1
  74. package/dist/client/assets/{src-BPEEiDps.js → src-YTrwJCk8.js} +1 -1
  75. package/dist/client/assets/{stateDiagram-v2-GCMORJYK-69H8hCN6.js → stateDiagram-v2-GCMORJYK-BjDmED1Q.js} +1 -1
  76. package/dist/client/assets/{swimlanes-2SLR337P-VMJm_C1R.js → swimlanes-2SLR337P-BAvnQ6KT.js} +1 -1
  77. package/dist/client/assets/swimlanesDiagram-TC7HE7FX-CbFPwcec.js +8 -0
  78. package/dist/client/assets/{timeline-definition-EJHVYXUP-DWTI0Vqo.js → timeline-definition-EJHVYXUP-BYemcgr1.js} +1 -1
  79. package/dist/client/assets/{treeView-Q6P3EWNA-DoBvpaMV.js → treeView-Q6P3EWNA-CsuBtqLq.js} +1 -1
  80. package/dist/client/assets/{treemap-WGGIJYW6-B43_cUvq.js → treemap-WGGIJYW6-DUk1Z6g4.js} +1 -1
  81. package/dist/client/assets/{usecaseDiagram-POWQR4AR-C9eMeNe5.js → usecaseDiagram-POWQR4AR-j1nHXvyL.js} +1 -1
  82. package/dist/client/assets/{vennDiagram-UO4OBE2U-pUMZhTOS.js → vennDiagram-UO4OBE2U-B5eUL-dD.js} +1 -1
  83. package/dist/client/assets/{wardley-WFR3VGLG-CIzaJFvJ.js → wardley-WFR3VGLG-1YjpwPJM.js} +1 -1
  84. package/dist/client/assets/{wardleyDiagram-VNRHLVJA-Cj_u7NlG.js → wardleyDiagram-VNRHLVJA-C7laBq5A.js} +1 -1
  85. package/dist/client/assets/{xychartDiagram-PMCCYNJV-mGddxyW6.js → xychartDiagram-PMCCYNJV-BkYPx-ts.js} +1 -1
  86. package/dist/client/index.html +2 -2
  87. package/package.json +1 -1
  88. package/plugin.json +1 -1
  89. package/dist/client/assets/architecture-7GRP2DOG-Cjj-qeXa.js +0 -1
  90. package/dist/client/assets/channel-wy7dEM75.js +0 -1
  91. package/dist/client/assets/eventmodeling-NTZA5JFV-BDUZgpVa.js +0 -1
  92. package/dist/client/assets/flowDiagram-KWPJA3E3-B8jw0PgP.js +0 -1
  93. package/dist/client/assets/index-B10socvp.js +0 -91
  94. package/dist/client/assets/railroad-abnf-HS5TGJTU-DadVNrmb.js +0 -1
  95. package/dist/client/assets/railroad-ebnf-LZEXJU2U-Can6uT-b.js +0 -1
  96. package/dist/client/assets/railroad-peg-WCYAUIDC-BB7kTpaz.js +0 -1
  97. package/dist/client/assets/swimlanesDiagram-TC7HE7FX-C9C4mAsA.js +0 -8
package/dist/cli.mjs CHANGED
@@ -83,6 +83,15 @@ function parseSuggestedReply(value) {
83
83
  function startedByAgent(thread) {
84
84
  return thread.messages[0]?.author === "agent";
85
85
  }
86
+ /** The agent has this message: it replied after it, or a delivery carried it.
87
+ * Decides what an edit is — a draft fixed in place, or a change of mind the
88
+ * agent has to be told about. */
89
+ function seenByAgent(thread, index) {
90
+ const message = thread.messages[index];
91
+ if (!message) return false;
92
+ if (thread.messages.slice(index + 1).some((m) => m.author === "agent")) return true;
93
+ return thread.deliveredThrough !== void 0 && Date.parse(message.at) <= Date.parse(thread.deliveredThrough);
94
+ }
86
95
  /** Agent-started with nothing of the reviewer's in it. Only these are excluded
87
96
  * from the reviewer's counts, Send, and the finish flush — the moment the
88
97
  * reviewer writes a reply into an agent thread, it carries their feedback and
@@ -283,8 +292,10 @@ const ACK_NEXT_STEP = {
283
292
  * POLL_STANCE keeps the poll rules aligned: the surfaces phrase it at different
284
293
  * lengths, but these invariants cannot drift apart.
285
294
  *
286
- * It is a map, not a tour. Every other tool infers a summary by reading the
287
- * diff back; the session that wrote the change still holds what no diff shows
295
+ * It is a map, not a tour, written for a reader who never saw the session:
296
+ * the problem comes before the mechanism, and the diagram draws what happens,
297
+ * not which code names which — a change to text alone has no call graph worth
298
+ * drawing. Every other tool infers a summary by reading the diff back; the session that wrote the change still holds what no diff shows
288
299
  * — the invariant it had to respect, the seam it chose, the alternative it
289
300
  * rejected, what it left alone on purpose — and that is what the reviewer
290
301
  * cannot get anywhere else. Reading order is not on the list: layers own it.
@@ -293,15 +304,15 @@ const GUIDE = {
293
304
  /** When one is warranted — and that silence is a valid outcome. */
294
305
  when: "multi-file, structural, or subtle — skip when the diff explains itself",
295
306
  /** What it contains: ingredients, not sections — use the ones this change needs. */
296
- what: "a map of the change, not a tour of it: what it does and why, in a sentence; how the changed pieces talk to each other, as a small ```mermaid diagram of the runtime flow (functions and modules, not a file list) when a picture beats words; what is worth checking as they read — an invariant the change must keep, a judgment call it made, a shortcoming it knows about — said in plain words, never behind a label of your own; and what is safe to skip",
307
+ what: "a map of the change, not a tour of it: the problem it solves and what it changes, in a sentence or two a reader who never saw your session follows; the flow it changes, from what sets it off to what someone sees, as a small ```mermaid diagram when a picture beats words — functions where code carries it, people and screens when they are the flow, never a file list or which code references which; what is worth checking as they read — an invariant the change must keep, a judgment call it made, a shortcoming it knows about — said in plain words, never behind a label of your own; and what is safe to skip",
297
308
  /** The line it must not cross. */
298
309
  stance: "Orient reading, never pre-review: no verdicts, nothing is \"fine\"",
299
310
  /** What layers took over: the guide never orders the read. */
300
311
  order: "no reading order and no file list — layers and the Files tab own those; a change that reads better in order gets a layers suggestion, not a numbered guide",
301
312
  /** How much: one screen, and only the parts that apply. */
302
313
  budget: "about a hundred words of prose plus the diagram — one screen; use only the parts this change needs, in whatever form fits",
303
- /** The diagram convention: two tags, and a plain node means existing code. */
304
- legend: "in the diagram tag new code `:::new` and changed code `:::changed`, declared by the two classDef lines below; a plain node is existing code the change now leans on",
314
+ /** The diagram convention: two tags, and a plain node means anything existing. */
315
+ legend: "in the diagram tag new code `:::new` and changed code `:::changed`, declared by the two classDef lines below; a plain node is anything existing the change now leans on",
305
316
  /** Staleness: the guide is a thread, so updates land under it. */
306
317
  update: "reply to your own guide thread with a short update"
307
318
  };
@@ -323,7 +334,13 @@ const GUIDE_CLASSDEFS = ["classDef new stroke:#2e9e4f,stroke-width:2px", "classD
323
334
  */
324
335
  const LAYERS = {
325
336
  /** What one is. */
326
- what: "one step of the change — a coherent unit you would explain in one breath — with the files that belong to it and a one- or two-sentence summary (markdown; a ```mermaid fence renders)",
337
+ what: "one step of the change — a coherent unit you would explain in one breath — with the files that belong to it and a short summary",
338
+ /** What the summary is for — a goal, not a template: the model writes it
339
+ * however this step reads best. The files sit right under it, so retelling
340
+ * them spends the reviewer's attention twice. */
341
+ summary: "say what this layer is about and give the reviewer enough context to review it — the part the files below cannot show on their own. Write it however fits the step, keep it short, and don't retell the diff",
342
+ /** Diagrams when they help: a picture of the step usually beats a paragraph. */
343
+ diagram: "when the step has a shape — a flow, a decision, a before/after — a small ```mermaid diagram usually says it better than prose; tag nodes as the guide does (`:::new`, `:::changed`, plain for anything existing) with the same two classDef lines",
327
344
  /** How to order them. */
328
345
  order: "the order you would explain it, not the order you wrote it — the file that explains the rest first, mechanical consequences last; for a feature, follow the request from entry point to effect; for a refactor, contract first, then consumers",
329
346
  /** When to raise the flag at open — and that not raising it is the common case. */
@@ -361,7 +378,7 @@ function guideNudge(hasGuide) {
361
378
  */
362
379
  function layersNudge(review) {
363
380
  if (review.layers || review.layersSuggested) return null;
364
- return `if this changeset reads better in order — ${LAYERS.suggest} — flag it: \`${CLI_COMMANDS.layersSuggest}\`, and offer it in your handoff ("say layers and I'll outline it"). Post the outline only when asked: \`${CLI_COMMANDS.layers}\` — each layer ${LAYERS.what}; ${LAYERS.order}. ${LAYERS.stance}. \`diffo help layers\` has the shape.`;
381
+ return `if this changeset reads better in order — ${LAYERS.suggest} — flag it: \`${CLI_COMMANDS.layersSuggest}\`, and offer it in your handoff ("say layers and I'll outline it"). Post the outline only when asked: \`${CLI_COMMANDS.layers}\` — each layer ${LAYERS.what}; ${LAYERS.summary}; ${LAYERS.diagram}; ${LAYERS.order}. ${LAYERS.stance}. \`diffo help layers\` has the shape.`;
365
382
  }
366
383
  /**
367
384
  * Printed to stderr when a poll takes the review over and the review already
@@ -588,8 +605,9 @@ function threadBlock(thread, index) {
588
605
  `id: ${thread.id}`,
589
606
  ...anchorNote(thread),
590
607
  ...snapshotBlock(thread),
608
+ ...thread.rewound ? ["EDITED: the reviewer rewrote the message marked (edited) and withdrew everything after it, your earlier replies included. Answer the edited version. Code you changed for the withdrawn replies is still in the tree: keep it or revert it as the new message implies, and say which."] : [],
591
609
  "Messages:",
592
- ...thread.messages.map((m) => `- ${m.author}: ${m.text.replace(/\n/g, "\n ")}`)
610
+ ...thread.messages.map((m) => `- ${m.author}${m.editedAt ? " (edited)" : ""}: ${m.text.replace(/\n/g, "\n ")}`)
593
611
  ].join("\n");
594
612
  }
595
613
  function buildThreadPrompt(thread, ctx) {
@@ -632,11 +650,15 @@ function buildLayersRequestPrompt(ctx, existing) {
632
650
  const refresh = existing !== null && existing.length > 0;
633
651
  const titles = refresh ? existing.map((l) => `"${l.title}"`).join(", ") : "";
634
652
  return [
635
- refresh ? `The reviewer asked you to refresh the layers in \`${ctx.repo.name}\` (branch \`${ctx.repo.branch}\`): the code moved since you outlined it, and files outside the outline have been gathering under "Since your review". Re-post the whole list as the change stands now.` : `The reviewer asked for layers in \`${ctx.repo.name}\` (branch \`${ctx.repo.branch}\`): outline the changeset as steps to read in order. The Layers tab reads "The agent is outlining…" until you post.`,
653
+ refresh ? `The reviewer asked you to refresh the layers in \`${ctx.repo.name}\` (branch \`${ctx.repo.branch}\`): the code moved since you outlined it, and files outside the outline have been gathering under "Since your review". Re-post the whole list as the change stands now.` : `The reviewer asked for layers in \`${ctx.repo.name}\` (branch \`${ctx.repo.branch}\`): outline the changeset as steps to read in order. The Layers tab reads "Outlining…" until you post.`,
636
654
  "",
637
655
  ...ctx.changeset ? [specLine(ctx.changeset), ""] : [],
638
656
  ...refresh ? [`The outline they have: ${titles}. Keep a title that still fits its step, rename or drop the ones that don't — ${LAYERS.replace}.`, ""] : [],
639
- `Each layer is ${LAYERS.what}. Order: ${LAYERS.order}. ${LAYERS.mechanical}. ${LAYERS.stance}. Files are whole files, by path relative to the repo root; list every file of the changeset somewhere, or the leftovers land in "Since your review".`,
657
+ `Each layer is ${LAYERS.what}. Summary: ${LAYERS.summary}. Diagram: ${LAYERS.diagram}:`,
658
+ "",
659
+ ...GUIDE_CLASSDEFS.map((line) => ` ${line}`),
660
+ "",
661
+ `Order: ${LAYERS.order}. ${LAYERS.mechanical}. ${LAYERS.stance}. Files are whole files, by path relative to the repo root; list every file of the changeset somewhere, or the leftovers land in "Since your review".`,
640
662
  "",
641
663
  `Shape: ${LAYERS.shape}`,
642
664
  "",
@@ -702,8 +724,8 @@ function buildFinishPrompt(threads, ctx, coverage) {
702
724
  }
703
725
  //#endregion
704
726
  //#region src/shared/layers.ts
705
- /** A summary is one or two sentences by doctrine; this is the backstop against
706
- * an essay, the same cap a closing note gets. */
727
+ /** A summary is short by doctrine; this is the backstop against an essay, the
728
+ * same cap a closing note gets. */
707
729
  const SUMMARY_CAP = 4e3;
708
730
  /** A note is one line by contract — anything past the first newline is dropped,
709
731
  * and the line itself is capped so the file header stays a header. */
@@ -927,6 +949,7 @@ The loop:
927
949
  outline only when the reviewer asks — in chat, or through the poll as a
928
950
  \`"kind": "layers"\` payload: \`diffo layers --json '<Layer[]>'\`
929
951
  (or pipe it to \`diffo layers --stdin\`). Each layer is ${LAYERS.what}.
952
+ Summary: ${LAYERS.summary}. Diagram: ${LAYERS.diagram}.
930
953
  Order: ${LAYERS.order}. ${LAYERS.mechanical}. ${LAYERS.stance}.
931
954
  ${LAYERS.replace}. \`diffo help layers\` has the shape.
932
955
  4. Listen: run \`${CLI_COMMANDS.firstPoll}\` — it blocks until the reviewer
@@ -990,9 +1013,9 @@ would have to decode.
990
1013
  One shape that works — not THE shape: a rename needs no diagram, a one-file
991
1014
  change needs no checks, and headings are optional.
992
1015
 
993
- Caps oversized tool results at the model boundary and adds
994
- \`read_tool_result\` so the model can page the rest — nothing is stored,
995
- the text is recomputed on read.
1016
+ A huge tool result could overflow the model's context. This caps it at the
1017
+ model boundary and adds \`read_tool_result\` so the model can page the
1018
+ rest — nothing is stored, the text is recomputed on read.
996
1019
 
997
1020
  \`\`\`mermaid
998
1021
  flowchart LR
@@ -1085,6 +1108,12 @@ Usage: diffo layers --suggest ["<why, in one line>"] at open: this read benefi
1085
1108
  … | diffo layers --stdin the same payload, piped
1086
1109
 
1087
1110
  Each layer is ${LAYERS.what}.
1111
+ Summary: ${LAYERS.summary}.
1112
+ Diagram: ${LAYERS.diagram}:
1113
+
1114
+ ${GUIDE_CLASSDEFS[0]}
1115
+ ${GUIDE_CLASSDEFS[1]}
1116
+
1088
1117
  Order: ${LAYERS.order}.
1089
1118
  ${LAYERS.mechanical}.
1090
1119
  ${LAYERS.stance}.
@@ -1100,7 +1129,7 @@ Output: {"ok":true,"layers":4,"next_step":"…"}
1100
1129
 
1101
1130
  Examples:
1102
1131
  diffo layers --suggest "the parser change explains the rest"
1103
- diffo layers --json '[{"title":"Parser contract","summary":"parse() now returns null instead of throwing.","files":["src/parse.ts"]},{"title":"Callers adapted","kind":"mechanical","files":["src/cli.ts","src/api.ts"]}]'`,
1132
+ diffo layers --json '[{"title":"Parser contract","summary":"The contract the rest of the change leans on: bad input now comes back as null, not an exception.","files":["src/parse.ts"]},{"title":"Callers adapted","kind":"mechanical","summary":"Call sites following the new return type.","files":["src/cli.ts","src/api.ts"]}]'`,
1104
1133
  end: `diffo end — detach from the review politely
1105
1134
 
1106
1135
  Usage: diffo end
@@ -2991,18 +3020,56 @@ var ReviewStore = class {
2991
3020
  };
2992
3021
  });
2993
3022
  }
3023
+ /**
3024
+ * The reviewer rewrites one of their own messages. Words the agent never saw
3025
+ * are a draft fixed in place. Words it did see are a change of mind, like
3026
+ * editing a chat message: the message is stamped edited and everything after
3027
+ * it is cut — the agent's answers to the old words included — so the thread
3028
+ * is the agent's to answer again. Cut, not kept: the old branch is not worth
3029
+ * a second history on the card. `withheld` holds a seen rewrite back from the
3030
+ * agent, the same as a withheld reply.
3031
+ */
3032
+ editMessage(threadId, messageId, text, withheld = false) {
3033
+ const current = this.state.threads.find((t) => t.id === threadId);
3034
+ const index = current?.messages.findIndex((m) => m.id === messageId) ?? -1;
3035
+ if (!current || index === -1) return null;
3036
+ const seen = seenByAgent(current, index);
3037
+ const cut = current.messages.slice(index + 1);
3038
+ const cutAnswer = cut.some((m) => m.author === "agent");
3039
+ return this.update(threadId, ({ unanswered, awaitingFollowUp, ...thread }) => {
3040
+ const before = thread.messages[index];
3041
+ const edited = {
3042
+ ...before,
3043
+ text,
3044
+ ...seen || before.editedAt ? { editedAt: (/* @__PURE__ */ new Date()).toISOString() } : {}
3045
+ };
3046
+ return {
3047
+ ...thread,
3048
+ ...unanswered && !seen ? { unanswered } : {},
3049
+ ...awaitingFollowUp && !cutAnswer ? { awaitingFollowUp } : {},
3050
+ ...cutAnswer && thread.state === "addressed" ? { state: "sent" } : {},
3051
+ ...seen && cut.length > 0 ? { rewound: true } : {},
3052
+ ...seen && withheld ? { withheld: true } : {},
3053
+ messages: [...thread.messages.slice(0, index), edited]
3054
+ };
3055
+ });
3056
+ }
2994
3057
  /** A delivery just handed these threads to the agent — remember through when,
2995
- * so replies and the typing indicator can tell delivered words from raced ones. */
3058
+ * so replies and the typing indicator can tell delivered words from raced ones.
3059
+ * The delivery also carried the word that a rewind withdrew the old replies. */
2996
3060
  markDelivered(threadIds) {
2997
3061
  const ids = new Set(threadIds);
2998
3062
  if (ids.size === 0) return;
2999
3063
  const at = (/* @__PURE__ */ new Date()).toISOString();
3000
3064
  this.state = {
3001
3065
  ...this.state,
3002
- threads: this.state.threads.map((t) => ids.has(t.id) ? {
3066
+ threads: this.state.threads.map(({ rewound, ...t }) => ids.has(t.id) ? {
3003
3067
  ...t,
3004
3068
  deliveredThrough: at
3005
- } : t)
3069
+ } : {
3070
+ ...t,
3071
+ ...rewound ? { rewound } : {}
3072
+ })
3006
3073
  };
3007
3074
  this.commit();
3008
3075
  }
@@ -3457,7 +3524,8 @@ function normalizeThread(value, now) {
3457
3524
  text: msg.text,
3458
3525
  at: typeof msg.at === "string" ? msg.at : now,
3459
3526
  ...typeof msg.durationMs === "number" ? { durationMs: msg.durationMs } : {},
3460
- ...msg.author === "agent" && typeof msg.suggestedReply === "string" && msg.suggestedReply ? { suggestedReply: msg.suggestedReply } : {}
3527
+ ...msg.author === "agent" && typeof msg.suggestedReply === "string" && msg.suggestedReply ? { suggestedReply: msg.suggestedReply } : {},
3528
+ ...typeof msg.editedAt === "string" ? { editedAt: msg.editedAt } : {}
3461
3529
  });
3462
3530
  }
3463
3531
  return {
@@ -3472,6 +3540,7 @@ function normalizeThread(value, now) {
3472
3540
  ...t.awaitingFollowUp === true && t.unanswered !== true ? { awaitingFollowUp: true } : {},
3473
3541
  ...t.closingNote === true ? { closingNote: true } : {},
3474
3542
  ...typeof t.sentAt === "string" ? { sentAt: t.sentAt } : {},
3543
+ ...t.rewound === true ? { rewound: true } : {},
3475
3544
  messages,
3476
3545
  createdAt: typeof t.createdAt === "string" ? t.createdAt : now,
3477
3546
  updatedAt: typeof t.updatedAt === "string" ? t.updatedAt : now
@@ -4090,6 +4159,34 @@ function createApp(ctx, store, review, queue) {
4090
4159
  presence: queue?.presence() ?? "waiting"
4091
4160
  });
4092
4161
  });
4162
+ app.patch("/api/review/threads/:id/messages/:messageId", async (c) => {
4163
+ if (!review) return c.json({ error: "review unavailable" }, 503);
4164
+ const body = await c.req.json().catch(() => null);
4165
+ const text = typeof body?.text === "string" ? body.text.trim() : "";
4166
+ if (!text) return c.json({ error: "need {text}" }, 400);
4167
+ const id = c.req.param("id");
4168
+ const messageId = c.req.param("messageId");
4169
+ const current = review.get().threads.find((t) => t.id === id);
4170
+ const index = current?.messages.findIndex((m) => m.id === messageId) ?? -1;
4171
+ if (!current || index === -1) return c.json({ error: "no such message" }, 404);
4172
+ if (current.messages[index].author !== "reviewer") return c.json({ error: "only your own messages can be edited" }, 400);
4173
+ if (current.state === "resolved") return c.json({ error: "reopen the thread to edit it" }, 409);
4174
+ if (queue?.deliveredThreadIds().includes(id)) return c.json({ error: "the agent is answering this thread — edit after it replies" }, 409);
4175
+ const seen = seenByAgent(current, index);
4176
+ const deliver = body?.deliver !== false;
4177
+ let thread = review.editMessage(id, messageId, text, !deliver);
4178
+ let delivered = false;
4179
+ if (seen && deliver && (thread.state === "sent" || thread.state === "addressed")) {
4180
+ delivered = deliverThreads([id]);
4181
+ review.clearWithheld([id]);
4182
+ thread = review.get().threads.find((t) => t.id === id) ?? thread;
4183
+ }
4184
+ return c.json({
4185
+ thread,
4186
+ delivered,
4187
+ presence: queue?.presence() ?? "waiting"
4188
+ });
4189
+ });
4093
4190
  app.post("/api/review/threads/:id/state", async (c) => {
4094
4191
  if (!review) return c.json({ error: "review unavailable" }, 503);
4095
4192
  const state = (await c.req.json().catch(() => null))?.state;
@@ -1 +1 @@
1
- import{m as e,t}from"./mermaid-parser.core-DtRc-ypM.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-BPEEiDps.js";import"./chunk-O7XYJQB3-CYftULw7.js";import{n as i,r as a,t as o}from"./chunk-GTNCS2PH-DnfAIbaL.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-CyG7EFf-.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
1
+ import{m as e,t}from"./mermaid-parser.core-D2BrkwRE.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-YTrwJCk8.js";import"./chunk-O7XYJQB3-DG64mbS_.js";import{n as i,r as a,t as o}from"./chunk-GTNCS2PH-JFHsSpPU.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-CCFlYVgY.js";var c=e().RailroadAbnf.parser.LangiumParser,l=n(e=>{let t=e.alternatives.map(u);return t.length===1?t[0]:{type:`choice`,alternatives:t}},`transformAlternation`),u=n(e=>{let t=e.elements.map(f);return t.length===1?t[0]:{type:`sequence`,elements:t}},`transformConcatenation`),d=n(e=>{if(e.includes(`*`)){let[t,n]=e.split(`*`);return{min:t?parseInt(t,10):0,max:n?parseInt(n,10):1/0}}let t=parseInt(e,10);return{min:t,max:t}},`parseRepeat`),f=n(e=>{let t=p(e.primary);if(!e.repeat)return t;let{min:n,max:r}=d(e.repeat);return n===0&&r===1?{type:`optional`,element:t}:{type:`repetition`,element:t,min:n,max:r}},`transformElement`),p=n(e=>{switch(e.$type){case`AbnfStringLiteral`:return{type:`terminal`,value:e.value};case`AbnfNumVal`:return{type:`terminal`,value:e.value};case`AbnfRuleName`:return{type:`nonterminal`,name:e.name};case`AbnfGroup`:return l(e.element);case`AbnfOptionalGroup`:return{type:`optional`,element:l(e.element)};default:throw Error(`Unsupported ABNF primary node: ${e.$type}`)}},`transformPrimary`),m=n(e=>({name:e.name,definition:l(e.definition)}),`transformRule`),h=n(e=>{s(e,o),e.title&&o.setTitle(e.title),e.rules.map(e=>o.addRule(m(e)))},`populateDb`),g={parser:{parse:n(e=>{o.clear(),r.debug(`[ABNF Parser] Starting Langium parse`);let n=c.parse(e);if(n.lexerErrors.length>0||n.parserErrors.length>0)throw new t(n);let i=n.value;r.debug(`[ABNF Parser] Parsed rules:`,i.rules.length),h(i),r.debug(`[ABNF Parser] Parse complete`)},`parse`),parser:{yy:o}},db:o,renderer:a,styles:i};export{g as diagram};
@@ -1 +1 @@
1
- import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-DOT26anA.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
1
+ import{n as e,t}from"./path-fybaL0A-.js";import{a as n,c as r,d as i,f as a,i as o,l as s,m as c,n as l,o as u,p as d,r as f,u as p}from"./dist-BWYGCgdo.js";function m(e){return e.innerRadius}function h(e){return e.outerRadius}function g(e){return e.startAngle}function _(e){return e.endAngle}function v(e){return e&&e.padAngle}function y(e,t,n,r,i,a,o,s){var c=n-e,l=r-t,u=o-i,d=s-a,f=d*c-u*l;if(!(f*f<1e-12))return f=(u*(t-a)-d*(e-i))/f,[e+f*c,t+f*l]}function b(e,t,n,r,i,a,o){var c=e-n,l=t-r,u=(o?a:-a)/d(c*c+l*l),f=u*l,p=-u*c,m=e+f,h=t+p,g=n+f,_=r+p,v=(m+g)/2,y=(h+_)/2,b=g-m,x=_-h,S=b*b+x*x,C=i-a,w=m*_-g*h,T=(x<0?-1:1)*d(s(0,C*C*S-w*w)),E=(w*x-b*T)/S,D=(-w*b-x*T)/S,O=(w*x+b*T)/S,k=(-w*b+x*T)/S,A=E-v,j=D-y,M=O-v,N=k-y;return A*A+j*j>M*M+N*N&&(E=O,D=k),{cx:E,cy:D,x01:-f,y01:-p,x11:E*(i/C-1),y11:D*(i/C-1)}}function x(){var s=m,x=h,S=e(0),C=null,w=g,T=_,E=v,D=null,O=t(k);function k(){var e,t,m=+s.apply(this,arguments),h=+x.apply(this,arguments),g=w.apply(this,arguments)-r,_=T.apply(this,arguments)-r,v=l(_-g),k=_>g;if(D||=e=O(),h<m&&(t=h,h=m,m=t),!(h>1e-12))D.moveTo(0,0);else if(v>c-1e-12)D.moveTo(h*u(g),h*a(g)),D.arc(0,0,h,g,_,!k),m>1e-12&&(D.moveTo(m*u(_),m*a(_)),D.arc(0,0,m,_,g,k));else{var A=g,j=_,M=g,N=_,P=v,F=v,I=E.apply(this,arguments)/2,L=I>1e-12&&(C?+C.apply(this,arguments):d(m*m+h*h)),R=p(l(h-m)/2,+S.apply(this,arguments)),z=R,B=R,V,H;if(L>1e-12){var U=o(L/m*a(I)),W=o(L/h*a(I));(P-=U*2)>1e-12?(U*=k?1:-1,M+=U,N-=U):(P=0,M=N=(g+_)/2),(F-=W*2)>1e-12?(W*=k?1:-1,A+=W,j-=W):(F=0,A=j=(g+_)/2)}var G=h*u(A),K=h*a(A),q=m*u(N),J=m*a(N);if(R>1e-12){var Y=h*u(j),X=h*a(j),Z=m*u(M),Q=m*a(M),$;if(v<i){if($=y(G,K,Z,Q,Y,X,q,J)){var ee=G-$[0],te=K-$[1],ne=Y-$[0],re=X-$[1],ie=1/a(f((ee*ne+te*re)/(d(ee*ee+te*te)*d(ne*ne+re*re)))/2),ae=d($[0]*$[0]+$[1]*$[1]);z=p(R,(m-ae)/(ie-1)),B=p(R,(h-ae)/(ie+1))}else z=B=0}}F>1e-12?B>1e-12?(V=b(Z,Q,G,K,h,B,k),H=b(Y,X,q,J,h,B,k),D.moveTo(V.cx+V.x01,V.cy+V.y01),B<R?D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,B,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,h,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),!k),D.arc(H.cx,H.cy,B,n(H.y11,H.x11),n(H.y01,H.x01),!k))):(D.moveTo(G,K),D.arc(0,0,h,A,j,!k)):D.moveTo(G,K),!(m>1e-12)||!(P>1e-12)?D.lineTo(q,J):z>1e-12?(V=b(q,J,Y,X,m,-z,k),H=b(G,K,Z,Q,m,-z,k),D.lineTo(V.cx+V.x01,V.cy+V.y01),z<R?D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(H.y01,H.x01),!k):(D.arc(V.cx,V.cy,z,n(V.y01,V.x01),n(V.y11,V.x11),!k),D.arc(0,0,m,n(V.cy+V.y11,V.cx+V.x11),n(H.cy+H.y11,H.cx+H.x11),k),D.arc(H.cx,H.cy,z,n(H.y11,H.x11),n(H.y01,H.x01),!k))):D.arc(0,0,m,N,M,k)}if(D.closePath(),e)return D=null,e+``||null}return k.centroid=function(){var e=(+s.apply(this,arguments)+ +x.apply(this,arguments))/2,t=(+w.apply(this,arguments)+ +T.apply(this,arguments))/2-i/2;return[u(t)*e,a(t)*e]},k.innerRadius=function(t){return arguments.length?(s=typeof t==`function`?t:e(+t),k):s},k.outerRadius=function(t){return arguments.length?(x=typeof t==`function`?t:e(+t),k):x},k.cornerRadius=function(t){return arguments.length?(S=typeof t==`function`?t:e(+t),k):S},k.padRadius=function(t){return arguments.length?(C=t==null?null:typeof t==`function`?t:e(+t),k):C},k.startAngle=function(t){return arguments.length?(w=typeof t==`function`?t:e(+t),k):w},k.endAngle=function(t){return arguments.length?(T=typeof t==`function`?t:e(+t),k):T},k.padAngle=function(t){return arguments.length?(E=typeof t==`function`?t:e(+t),k):E},k.context=function(e){return arguments.length?(D=e??null,k):D},k}export{x as t};
@@ -0,0 +1 @@
1
+ import"./chunk-FOHPRMQF-DzxwRta7.js";import{M as e}from"./mermaid-parser.core-D2BrkwRE.js";export{e as createArchitectureServices};