@diffohq/diffo 0.18.2 → 0.19.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 (92) hide show
  1. package/dist/cli.mjs +122 -37
  2. package/dist/client/assets/{abnfDiagram-WEYOIA3C-BXaIJpBN.js → abnfDiagram-WEYOIA3C-C4F66yrf.js} +1 -1
  3. package/dist/client/assets/{arc-BbvYkM1t.js → arc-DBJ10kEG.js} +1 -1
  4. package/dist/client/assets/{architecture-WOLXFQ4H-dgnSoWOO.js → architecture-WOLXFQ4H-C2zkRoho.js} +1 -1
  5. package/dist/client/assets/{architectureDiagram-ZHVYKT53-DlkedRRd.js → architectureDiagram-ZHVYKT53-CA6mi6wr.js} +1 -1
  6. package/dist/client/assets/{blockDiagram-RJAE7QA3-BypREGFC.js → blockDiagram-RJAE7QA3-BU9p_PIC.js} +1 -1
  7. package/dist/client/assets/{c4Diagram-XDPPPE54-CS4XxzVb.js → c4Diagram-XDPPPE54-jJGc-KP3.js} +1 -1
  8. package/dist/client/assets/channel-V7p0fz-O.js +1 -0
  9. package/dist/client/assets/{chunk-2E7WHVMD-Dop1N6Br.js → chunk-2E7WHVMD-DfTh-gtY.js} +1 -1
  10. package/dist/client/assets/{chunk-4EMNKR2T-7DXqrGJu.js → chunk-4EMNKR2T-DyD0H1sX.js} +1 -1
  11. package/dist/client/assets/{chunk-55XCU76K-DHJxyDSK.js → chunk-55XCU76K-D_u6ulSk.js} +1 -1
  12. package/dist/client/assets/{chunk-7S6XSTFO-D1DcTy9U.js → chunk-7S6XSTFO-Be0YqE1I.js} +1 -1
  13. package/dist/client/assets/{chunk-AQDTSKZB-DRrnmajZ.js → chunk-AQDTSKZB-DdHQVHcb.js} +1 -1
  14. package/dist/client/assets/{chunk-DSNLSHJZ-0Nqpe1Hg.js → chunk-DSNLSHJZ-DiIzqoT2.js} +1 -1
  15. package/dist/client/assets/{chunk-HAGFOTED-ClGG5EBa.js → chunk-HAGFOTED-CpZxC5T_.js} +1 -1
  16. package/dist/client/assets/{chunk-HNE4Q36P-DYQEFDob.js → chunk-HNE4Q36P-Ct6fc1OS.js} +1 -1
  17. package/dist/client/assets/{chunk-NQOKRVIF-tbR3jZ3d.js → chunk-NQOKRVIF-CB1EBGI7.js} +1 -1
  18. package/dist/client/assets/{chunk-UHW7PFBP-XPwp96hi.js → chunk-UHW7PFBP-DMafWre5.js} +1 -1
  19. package/dist/client/assets/{chunk-VQ5W62QI-QxWYd-NQ.js → chunk-VQ5W62QI-B73OlRFu.js} +1 -1
  20. package/dist/client/assets/{chunk-WQQL4CDK-BDs4Qw1V.js → chunk-WQQL4CDK-BVplvMci.js} +1 -1
  21. package/dist/client/assets/{chunk-XXDRQBXY-DZTYKQL4.js → chunk-XXDRQBXY-CUJAy2BW.js} +1 -1
  22. package/dist/client/assets/{chunk-YZO67HFG-uTEN-1K1.js → chunk-YZO67HFG-CQkECnpj.js} +1 -1
  23. package/dist/client/assets/{chunk-ZAUX2LTX-BoM_25lp.js → chunk-ZAUX2LTX-D0fTc1cY.js} +1 -1
  24. package/dist/client/assets/{chunk-ZCHMQSOR-OZKt3t2o.js → chunk-ZCHMQSOR-BmCQaGs2.js} +1 -1
  25. package/dist/client/assets/{classDiagram-v2-4MYWR3UA-5eVImAgV.js → classDiagram-v2-4MYWR3UA-CXMC0OW_.js} +1 -1
  26. package/dist/client/assets/{core-D_eKwUPZ.js → core-DT06f97y.js} +1 -1
  27. package/dist/client/assets/{cose-bilkent-JH36ORCC-chWLMn-5.js → cose-bilkent-JH36ORCC-DNe_fGor.js} +1 -1
  28. package/dist/client/assets/{cynefin-EF2NZ3EQ-Cz6ERHsX.js → cynefin-EF2NZ3EQ-iQmVGcYW.js} +1 -1
  29. package/dist/client/assets/{cynefinDiagram-WF24UDRP-BnB53zQb.js → cynefinDiagram-WF24UDRP-CF0fXuLp.js} +1 -1
  30. package/dist/client/assets/{dagre-NK4GIZVX-BfhsX1WF.js → dagre-NK4GIZVX-BuB4gzco.js} +1 -1
  31. package/dist/client/assets/{diagram-CBK3MWTC-poDE7PQY.js → diagram-CBK3MWTC-BiM7vTDb.js} +1 -1
  32. package/dist/client/assets/{diagram-I5XIIV2D-DIBlIqSp.js → diagram-I5XIIV2D-DqY9bg30.js} +1 -1
  33. package/dist/client/assets/{diagram-ODIL2UCW-DrILl72A.js → diagram-ODIL2UCW-cT3u1nmA.js} +1 -1
  34. package/dist/client/assets/{diagram-PFBEJUXE-Cv1FXBK_.js → diagram-PFBEJUXE-DRQIfHKp.js} +1 -1
  35. package/dist/client/assets/{diagram-RJA3I4VV-BiIKgRrJ.js → diagram-RJA3I4VV-BDG4uVXT.js} +1 -1
  36. package/dist/client/assets/{diagram-TYUNFSNR-BLyJnBDm.js → diagram-TYUNFSNR-Dwwtg61C.js} +1 -1
  37. package/dist/client/assets/{dist-CTGUU8Z5.js → dist-DDVyMjMP.js} +1 -1
  38. package/dist/client/assets/{dist-B5xF88x8.js → dist-F1lvNP36.js} +1 -1
  39. package/dist/client/assets/{ebnfDiagram-V4P3TTPT-Ba1TIAJm.js → ebnfDiagram-V4P3TTPT-B0jhalBP.js} +1 -1
  40. package/dist/client/assets/{elk-QONTBCTQ-DOKz-mbT.js → elk-QONTBCTQ-CfqdQUKw.js} +1 -1
  41. package/dist/client/assets/{engine-oniguruma-D8NZ2rGI.js → engine-oniguruma-hBSdHLHU.js} +1 -1
  42. package/dist/client/assets/{erDiagram-KYQIGQAA-DntQLVl7.js → erDiagram-KYQIGQAA-D40nMMfT.js} +1 -1
  43. package/dist/client/assets/{eventmodeling-K75KTNOO-2Qa72ey3.js → eventmodeling-K75KTNOO-CJm1KP0d.js} +1 -1
  44. package/dist/client/assets/flowDiagram-IUGLLWBU-B-bQRWZP.js +1 -0
  45. package/dist/client/assets/{ganttDiagram-R7GPNTJY-yBdAatJb.js → ganttDiagram-R7GPNTJY-ihydgTMP.js} +1 -1
  46. package/dist/client/assets/{gitGraph-VSP46ZUC-D_FaOwJv.js → gitGraph-VSP46ZUC-CMx6LECR.js} +1 -1
  47. package/dist/client/assets/{gitGraphDiagram-PDYL7XHY-B3CmgW0R.js → gitGraphDiagram-PDYL7XHY-CA9toxR4.js} +1 -1
  48. package/dist/client/assets/index-C5auPEXZ.js +103 -0
  49. package/dist/client/assets/{index-Caehfsn0.css → index-CnUT5mJM.css} +1 -1
  50. package/dist/client/assets/{info-OHQRW6UA-z3nafB_H.js → info-OHQRW6UA-C1kNo6oH.js} +1 -1
  51. package/dist/client/assets/{infoDiagram-MVDRKAX5-dlG1r_bv.js → infoDiagram-MVDRKAX5-C32rywQB.js} +1 -1
  52. package/dist/client/assets/{ishikawaDiagram-HPEHV2GE-BXEvg3sg.js → ishikawaDiagram-HPEHV2GE-DUEsJoMN.js} +1 -1
  53. package/dist/client/assets/{journeyDiagram-BOSHW7O7-BIEy3U2j.js → journeyDiagram-BOSHW7O7-Bo99TW48.js} +1 -1
  54. package/dist/client/assets/{kanban-definition-FNSA4HC5-CptiP1s8.js → kanban-definition-FNSA4HC5-giCfuZic.js} +1 -1
  55. package/dist/client/assets/{line-CSNAdVe3.js → line-D1mykNiO.js} +1 -1
  56. package/dist/client/assets/{linear-CEQlosco.js → linear-DiA_-VS5.js} +1 -1
  57. package/dist/client/assets/{mermaid-parser.core-Cvl3-NHE.js → mermaid-parser.core-C6WMZqm3.js} +3 -3
  58. package/dist/client/assets/{mermaid.core-BTw9trpK.js → mermaid.core-BOSV4eXG.js} +4 -4
  59. package/dist/client/assets/{mindmap-definition-6OY57UG3-DBMHbF7R.js → mindmap-definition-6OY57UG3-sK7Obrx4.js} +1 -1
  60. package/dist/client/assets/{packet-JDAUHWVQ-DVs3zXtN.js → packet-JDAUHWVQ-DSaqNHgQ.js} +1 -1
  61. package/dist/client/assets/{pegDiagram-ECIUJNBX-DnmNX8QO.js → pegDiagram-ECIUJNBX-LKaQbFjA.js} +1 -1
  62. package/dist/client/assets/{pie-XZMESJXO-CBcybtKq.js → pie-XZMESJXO-CXJhZGvq.js} +1 -1
  63. package/dist/client/assets/{pieDiagram-GNMPY74T-D8qPgAgw.js → pieDiagram-GNMPY74T-CajavLjL.js} +1 -1
  64. package/dist/client/assets/{quadrantDiagram-D57K4MC3-BRC7Vbm8.js → quadrantDiagram-D57K4MC3-B_Ndp3Y0.js} +1 -1
  65. package/dist/client/assets/{radar-ABXABTNO-41LgehHh.js → radar-ABXABTNO-Dbnb1wX5.js} +1 -1
  66. package/dist/client/assets/{railroad-I3PHUGI6-1PP4FslK.js → railroad-I3PHUGI6-DLB2nOq0.js} +1 -1
  67. package/dist/client/assets/{railroad-abnf-LNEFI6M7-w18ZmITB.js → railroad-abnf-LNEFI6M7-CG567ncb.js} +1 -1
  68. package/dist/client/assets/{railroad-ebnf-DWYD2UWJ-BJH4xWEw.js → railroad-ebnf-DWYD2UWJ-CVJvSIu9.js} +1 -1
  69. package/dist/client/assets/{railroad-peg-JR7BVNR7-x7l-dk5i.js → railroad-peg-JR7BVNR7-CHu58vSv.js} +1 -1
  70. package/dist/client/assets/{railroadDiagram-Y72NRBL7-D7ske7kG.js → railroadDiagram-Y72NRBL7-D-K-VPDM.js} +1 -1
  71. package/dist/client/assets/{requirementDiagram-EQYSW5RA-3-pQIz0a.js → requirementDiagram-EQYSW5RA-BtMhaTfI.js} +1 -1
  72. package/dist/client/assets/{sankeyDiagram-SY24JHO5-BC9UkV1t.js → sankeyDiagram-SY24JHO5-BE2B_sMV.js} +1 -1
  73. package/dist/client/assets/{sequenceDiagram-BLEHNHQU-B42xFHsK.js → sequenceDiagram-BLEHNHQU-1AsNdi7T.js} +1 -1
  74. package/dist/client/assets/{src-BOAZLa52.js → src-wNqkFAEP.js} +1 -1
  75. package/dist/client/assets/{stateDiagram-v2-A6IESKWZ-BNcZGfFQ.js → stateDiagram-v2-A6IESKWZ-C-QG4RxI.js} +1 -1
  76. package/dist/client/assets/{swimlanes-B3ENRKFQ-Q3HEFOfH.js → swimlanes-B3ENRKFQ-IpJ9gT29.js} +1 -1
  77. package/dist/client/assets/swimlanesDiagram-AYQRV4AK-uV0LG_4r.js +8 -0
  78. package/dist/client/assets/{timeline-definition-JXYKGLGB-D3-bRJWH.js → timeline-definition-JXYKGLGB-DPliIZed.js} +1 -1
  79. package/dist/client/assets/{treeView-D4JQ5SDB-B-9uvXot.js → treeView-D4JQ5SDB-RqsIcDef.js} +1 -1
  80. package/dist/client/assets/{treemap-SAJKECNS-wNk-lpBb.js → treemap-SAJKECNS-B1FOTerZ.js} +1 -1
  81. package/dist/client/assets/{usecaseDiagram-WPOLBNNX-C1M8VoMq.js → usecaseDiagram-WPOLBNNX-DuTzlDeh.js} +1 -1
  82. package/dist/client/assets/{vennDiagram-Q3Y3IDCW-Buucko7J.js → vennDiagram-Q3Y3IDCW-DKPiHpL3.js} +1 -1
  83. package/dist/client/assets/{wardley-7MLQ67FV-Ba2Ip0Nm.js → wardley-7MLQ67FV-w4FLBbHY.js} +1 -1
  84. package/dist/client/assets/{wardleyDiagram-IVAIDKWA-BVOlZPzc.js → wardleyDiagram-IVAIDKWA-Kt50wWFD.js} +1 -1
  85. package/dist/client/assets/{xychartDiagram-4URNHDU4-DKHhUTSz.js → xychartDiagram-4URNHDU4-C7Ok6qBr.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/channel-BX7tU_cE.js +0 -1
  90. package/dist/client/assets/flowDiagram-IUGLLWBU-D1Fj5EhG.js +0 -1
  91. package/dist/client/assets/index-CkQXI35i.js +0 -91
  92. package/dist/client/assets/swimlanesDiagram-AYQRV4AK-DxGPW8Ks.js +0 -8
package/dist/cli.mjs CHANGED
@@ -308,6 +308,23 @@ function describeAnchor(anchor) {
308
308
  if (anchor.kind === "layer") return `layer "${anchor.title}"`;
309
309
  return `${anchor.path}:${anchorSpan(anchor)} (${anchor.side} side)`;
310
310
  }
311
+ /** It rides every poll prompt on a pull request, so it stays short. */
312
+ const VOICE_MAX = 1500;
313
+ /**
314
+ * A stored or submitted voice as the prompt uses it: trimmed, or null for
315
+ * "the default" (absent, empty, not a string, or over the cap, which a
316
+ * client never sends but an edited DB row could hold).
317
+ */
318
+ function normalizeVoice(value) {
319
+ if (typeof value !== "string") return null;
320
+ const text = value.trim();
321
+ if (text === "" || text.length > 1500) return null;
322
+ return text;
323
+ }
324
+ /** The voice the agent reads: the reviewer's own, or the default. */
325
+ function effectiveVoice(value) {
326
+ return normalizeVoice(value) ?? "Write it the way I'd type a review comment at the line: one or two short sentences, the point first, then stop. \"This resets the streak on late completions. Should it?\" is a comment. A paragraph that states the finding, explains why it matters and proposes the fix is a report; I rewrite those every time.\n\nSound like a teammate, not a model. Direct about the issue, concrete about the fix, kind to the person. Plain words, contractions, sentences of different lengths. \"I think\" or \"probably\" when I'm actually unsure, never softening for its own sake. A real question is often the whole comment. Start a nit with \"nit:\". Name the fix only when it isn't obvious; if it fits the anchored lines, put it in a ```suggestion block instead of describing it.\n\nGiveaways to avoid: em-dashes; \"Consider...\" or \"It might be worth...\"; \"not X but Y\"; \"I noticed that\"; \"it's important to note\"; stacked hedges (\"perhaps we might want to\"); lists of three for the sake of three; bold; praise before the point; restating what the diff shows; \"robust\", \"leverage\", \"ensure\", \"streamline\"; trailing \"-ing\" riders (\"...ensuring consistency\"); sign-offs like \"let me know\".";
327
+ }
311
328
  //#endregion
312
329
  //#region src/server/prompt.ts
313
330
  /** A comment can anchor to a long range; the frozen text keeps its head. */
@@ -445,7 +462,7 @@ const TAB_TITLE = {
445
462
  };
446
463
  function nextStepFor(kind, actionable) {
447
464
  if (kind === "submitted") return `Nothing to act on — tell the user the review was submitted, then run \`${CLI_COMMANDS.poll}\` again to keep listening (${POLL_STANCE}), or \`${CLI_COMMANDS.end}\` if they are done.`;
448
- if (kind === "layers") return `Post the outline with \`${CLI_COMMANDS.layers}\` (or pipe it to \`${CLI_COMMANDS.layersStdin}\`), then run \`${CLI_COMMANDS.poll}\` again to keep listening (${POLL_STANCE}).`;
465
+ if (kind === "layers") return `Post the outline with \`${CLI_COMMANDS.layers}\` — ${LAYERS.post} (\`${CLI_COMMANDS.layersStdin}\`). If the post is refused, say so to the reviewer in chat — they are watching the Layers tab for it. Then run \`${CLI_COMMANDS.poll}\` again to keep listening (${POLL_STANCE}).`;
449
466
  if (kind === "cleared") return `Post the guide if this changeset warrants one, then run \`${CLI_COMMANDS.firstPoll}\` again to keep listening (${POLL_STANCE}) — this is a fresh round, so give it a fresh title.`;
450
467
  if (kind === "finish" && actionable === 0) return `Nothing to act on — run \`${CLI_COMMANDS.poll}\` again to keep listening (${POLL_STANCE}); the reviewer may follow up.`;
451
468
  return `${kind === "finish" ? "The reviewer is done reading — work the whole batch. " : ""}Act on each thread, reply with \`${CLI_COMMANDS.reply}\`, then run \`${CLI_COMMANDS.poll}\` again to keep listening.`;
@@ -520,9 +537,10 @@ const HELP_AGENT_PR = `Reviewing a pull request (\`diffo <PR URL | owner/repo#N
520
537
  when they were wrong (say so privately), not on pushback against your own
521
538
  reply — redraft the one already in the thread instead — and not when asked
522
539
  but you have nothing worth saying to the author: say so privately, never
523
- invent one. Keep it to one or two short sentences, the point first, the
524
- way a person types a review comment; no preamble, no "Suggest …", no
525
- report.
540
+ invent one. Write it in the reviewer's voice: their standing instructions
541
+ for how their comments read (Settings → Voice) come with every delivery.
542
+ By default, one or two short sentences, the point first, the way a person
543
+ types a review comment; no preamble, no "Suggest …", no report.
526
544
  - The guide and layers work as above, built from the description, the commits
527
545
  and the diff; skip the guide when the description already orients.
528
546
  - When the reviewer submits, a poll returns a \`"kind": "submitted"\` notice:
@@ -593,6 +611,13 @@ const LAYERS = {
593
611
  stance: GUIDE.stance,
594
612
  /** A post is the whole list. */
595
613
  replace: "a post replaces the whole list, never merges; ids are kept for titles that match, so a re-post never moves the reviewer's place",
614
+ /** How the payload reaches the CLI. Two commands when it is long, because a
615
+ * harness that screens each command on its own (Claude Code's auto mode, for
616
+ * one) refuses a post it cannot trace: a command that writes the file and
617
+ * pipes it in one go, or a pipe from a file the session never visibly wrote.
618
+ * The refusal also tells the agent to stop, so the reviewer sees "Outlining…"
619
+ * until the server gives up on it (see OUTLINE_STALL_MS). */
620
+ post: "inline with --json when it fits on a command line; when it is long, write the JSON to a file in one command and pipe that file to --stdin in the next — never write and post in the same command, and never pipe a file this session did not itself write, because a harness that screens commands one at a time refuses a post it cannot trace back to you",
596
621
  /** What earns a line in a layer's `decisions`, and the bar for it. The
597
622
  * reviewer reads these before the diff — or instead of it — so every entry
598
623
  * must be something they could act on, never a retelling of the change. */
@@ -612,7 +637,8 @@ const AUTHOR_DOCTRINE = {
612
637
  * addressed to the author in the reviewer's voice; nothing of it posts until the
613
638
  * reviewer adds it to their review and submits.
614
639
  */
615
- const PR_COMMENT_DOCTRINE = `## Drafting a review comment for the author
640
+ function prCommentDoctrine(voice) {
641
+ return `## Drafting a review comment for the author
616
642
 
617
643
  The reviewer's private messages are of two kinds. A question to you ("what
618
644
  calls this?") wants an answer. A finding stated about the code ("this resets
@@ -637,23 +663,26 @@ request is the one thing the reviewer cannot tell apart from a finding. On a
637
663
  comment of your own (\`${CLI} comment\`), the same flag carries a finding you
638
664
  can show, never a hunch.
639
665
 
640
- Write it the way a person types a review comment at the line: one or two
641
- short sentences, the point first, done. "This resets the streak on late
642
- completions — should it?" is a review comment. A paragraph that states the
643
- finding, explains why it matters and proposes the fix is not; it is a report,
644
- and the reviewer rewrites it every time. No preamble ("This reads as…"), no
645
- "Suggest …" or "Consider …" framing, no restating what the diff already
646
- shows, no examples in parentheses, no hedging. Name the fix only when it is
647
- not obvious from the finding, and when it is local to the anchored lines put
648
- it in a \`\`\`suggestion block instead of prose. A question is often the
649
- whole comment. Nothing about you, the worktree, tests you ran, or Diffo —
650
- that evidence goes in --message, where the reviewer reads it. Match how this
651
- reviewer writes: their own review comments on this pull request are quoted
652
- under "The reviewer's voice" when there are any.
666
+ Write it in the reviewer's voice. Their standing instructions for how a
667
+ review comment of theirs reads (Settings → Voice in Diffo; every delivery
668
+ carries the current text, so follow the latest):
669
+
670
+ ${indent(effectiveVoice(voice))}
671
+
672
+ Nothing about you, the worktree, tests you ran, or Diffo — that evidence
673
+ goes in --message, where the reviewer reads it. Their own review comments
674
+ on this pull request are quoted under "The reviewer's voice" when there are
675
+ any; match those too.
653
676
 
654
677
  Nothing you attach reaches GitHub. It appears under your reply with Add as
655
678
  PR comment draft / Edit / Dismiss; the reviewer decides, and the submit
656
679
  notice tells you what happened to each.`;
680
+ }
681
+ /** The doctrine as shipped before the voice could be set: the default voice. */
682
+ const PR_COMMENT_DOCTRINE = prCommentDoctrine();
683
+ function indent(text) {
684
+ return text.split("\n").map((line) => line === "" ? "" : ` ${line}`).join("\n");
685
+ }
657
686
  const PR_DOCTRINE = {
658
687
  guide: {
659
688
  when: "the pull request description leaves a cold reader without the shape of the change — skip when the description already orients",
@@ -668,8 +697,15 @@ const PR_DOCTRINE = {
668
697
  fix: "- `issue` threads want a fix you cannot push: work it out in the worktree, verify it the cheapest honest way, restore the worktree (`git checkout -- .`), and reply with a ```suggestion block plus what you checked. Never commit or push to the pull request.",
669
698
  prComment: PR_COMMENT_DOCTRINE
670
699
  };
671
- function doctrineFor(changeset) {
672
- return changeset?.pr ? PR_DOCTRINE : AUTHOR_DOCTRINE;
700
+ /** The doctrine for a review, with the reviewer's voice folded into the PR
701
+ * comment rule when they set one; the author's doctrine has no voice to carry. */
702
+ function doctrineFor(changeset, voice) {
703
+ if (!changeset?.pr) return AUTHOR_DOCTRINE;
704
+ const custom = normalizeVoice(voice);
705
+ return custom === null ? PR_DOCTRINE : {
706
+ ...PR_DOCTRINE,
707
+ prComment: prCommentDoctrine(custom)
708
+ };
673
709
  }
674
710
  /**
675
711
  * The pull request, framed for an agent that did not write it. Every PR-mode
@@ -1021,7 +1057,7 @@ function prLines(ctx) {
1021
1057
  }
1022
1058
  function buildThreadPrompt(thread, ctx) {
1023
1059
  const siblings = siblingLines(ctx.siblings ?? []);
1024
- const D = doctrineFor(ctx.changeset);
1060
+ const D = doctrineFor(ctx.changeset, ctx.voiceSetting);
1025
1061
  const pr = ctx.changeset?.pr;
1026
1062
  return [
1027
1063
  pr ? `A reviewer is reading pull request #${pr.number} in \`${ctx.repo.name}\` with you as their copilot, and asked you this privately.` : `A reviewer is reading your changes in \`${ctx.repo.name}\` (branch \`${ctx.repo.branch}\`) and sent you this review thread.`,
@@ -1038,7 +1074,7 @@ function buildThreadPrompt(thread, ctx) {
1038
1074
  }
1039
1075
  function buildCoalescedPrompt(threads, ctx) {
1040
1076
  const siblings = siblingLines(ctx.siblings ?? []);
1041
- const D = doctrineFor(ctx.changeset);
1077
+ const D = doctrineFor(ctx.changeset, ctx.voiceSetting);
1042
1078
  const pr = ctx.changeset?.pr;
1043
1079
  return [
1044
1080
  pr ? `The reviewer of pull request #${pr.number} in \`${ctx.repo.name}\` sent you new private messages on ${threads.length} threads.` : `The reviewer sent new messages on ${threads.length} review threads in \`${ctx.repo.name}\` (branch \`${ctx.repo.branch}\`).`,
@@ -1097,7 +1133,7 @@ function buildSubmittedPrompt(ctx, submitted) {
1097
1133
  function buildLayersRequestPrompt(ctx, existing) {
1098
1134
  const refresh = existing !== null && existing.length > 0;
1099
1135
  const titles = refresh ? existing.map((l) => `"${l.title}"`).join(", ") : "";
1100
- const D = doctrineFor(ctx.changeset);
1136
+ const D = doctrineFor(ctx.changeset, ctx.voiceSetting);
1101
1137
  return [
1102
1138
  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.`,
1103
1139
  "",
@@ -1114,14 +1150,14 @@ function buildLayersRequestPrompt(ctx, existing) {
1114
1150
  "",
1115
1151
  `Shape: ${LAYERS.shape}`,
1116
1152
  "",
1117
- `Post it: \`${CLI_COMMANDS.layers}\`, or pipe the JSON to \`${CLI_COMMANDS.layersStdin}\` when it is long. Nothing else is owed for this item — no reply, no comment.`,
1153
+ `Post it: \`${CLI_COMMANDS.layers}\` — ${D.layers.post} (\`${CLI_COMMANDS.layersStdin}\`). If the post is refused, tell the reviewer in chat; they are watching the Layers tab for it. Nothing else is owed for this item — no reply, no comment.`,
1118
1154
  "",
1119
1155
  `Then run \`${CLI_COMMANDS.poll}\` again to keep listening (${POLL_STANCE}).`,
1120
1156
  ""
1121
1157
  ].join("\n");
1122
1158
  }
1123
1159
  function buildClearedPrompt(ctx) {
1124
- const D = doctrineFor(ctx.changeset);
1160
+ const D = doctrineFor(ctx.changeset, ctx.voiceSetting);
1125
1161
  return [
1126
1162
  `The reviewer cleared the review in \`${ctx.repo.name}\` (branch \`${ctx.repo.branch}\`): the previous round landed, and its threads and guide are gone. What the reviewer sees now is a fresh round.`,
1127
1163
  "",
@@ -1159,7 +1195,7 @@ function buildFinishPrompt(threads, ctx, coverage) {
1159
1195
  "leaves the reviewer with nothing to do.",
1160
1196
  ""
1161
1197
  ] : [];
1162
- const D = doctrineFor(ctx.changeset);
1198
+ const D = doctrineFor(ctx.changeset, ctx.voiceSetting);
1163
1199
  const pr = ctx.changeset?.pr;
1164
1200
  const parts = [
1165
1201
  pr ? `The reviewer finished reading pull request #${pr.number} in \`${repo.name}\` and is handing you what they still have for you privately.` : `A reviewer finished reading your changes in \`${repo.name}\` (branch \`${repo.branch}\`).`,
@@ -1468,8 +1504,8 @@ The loop:
1468
1504
  Flag it at open with \`diffo layers --suggest "<why, in one line>"\` and
1469
1505
  say so in your handoff ("say layers and I'll outline it"). Post the
1470
1506
  outline only when the reviewer asks, in chat or through the poll as a
1471
- \`"kind": "layers"\` payload: \`diffo layers --json '<Layer[]>'\`
1472
- (or pipe it to \`diffo layers --stdin\`). Each layer is ${LAYERS.what}.
1507
+ \`"kind": "layers"\` payload: \`diffo layers --json '<Layer[]>'\` —
1508
+ ${LAYERS.post} (\`diffo layers --stdin\`). Each layer is ${LAYERS.what}.
1473
1509
  Summary: ${LAYERS.summary}. Diagram: ${LAYERS.diagram}.
1474
1510
  Order: ${LAYERS.order}. ${LAYERS.mechanical}. ${LAYERS.stance}.
1475
1511
  ${LAYERS.replace}. \`diffo help layers\` has the shape.
@@ -1675,7 +1711,8 @@ Examples:
1675
1711
 
1676
1712
  Usage: diffo layers --suggest ["<why, in one line>"] at open: this read benefits from layers
1677
1713
  diffo layers --json '<Layer[]>' post the outline, replacing the last one
1678
- … | diffo layers --stdin the same payload, piped
1714
+ … | diffo layers --stdin the same payload, piped — from a file
1715
+ written in a command of its own
1679
1716
 
1680
1717
  Each layer is ${LAYERS.what}.
1681
1718
  Summary: ${LAYERS.summary}.
@@ -4364,6 +4401,11 @@ const STALL_AFTER_MS = 3e5;
4364
4401
  const REPLY_GRACE_MS = 9e4;
4365
4402
  /** A re-poll within this window of a delivery reads as "hasn't started yet". */
4366
4403
  const BATCH_SETTLE_MS = 2e3;
4404
+ /** An outline owed this long with no post reads as stalled: the reviewer gets
4405
+ * the reason and their button back instead of "Outlining…" for good. Shorter
4406
+ * than a reply's stall — an agent whose harness refused the post is told to
4407
+ * stop, and nothing else ends the wait: no re-poll, no reply clock. */
4408
+ const OUTLINE_STALL_MS = 18e4;
4367
4409
  /** Signal 0 probes existence without touching the process; EPERM still proves it exists. */
4368
4410
  function pidAlive(pid) {
4369
4411
  try {
@@ -4378,6 +4420,7 @@ var DeliveryQueue = class DeliveryQueue {
4378
4420
  replyGraceMs;
4379
4421
  liveness;
4380
4422
  batchSettleMs;
4423
+ outlineStallMs;
4381
4424
  buckets = /* @__PURE__ */ new Map();
4382
4425
  scope = "";
4383
4426
  waiter = null;
@@ -4386,6 +4429,7 @@ var DeliveryQueue = class DeliveryQueue {
4386
4429
  deliveredAt = /* @__PURE__ */ new Map();
4387
4430
  listeners = /* @__PURE__ */ new Set();
4388
4431
  stalled = false;
4432
+ outlineTimer = null;
4389
4433
  stallTimer = null;
4390
4434
  betweenPolls = false;
4391
4435
  /** Why the agent is parked between polls: a reply just landed, its poll
@@ -4409,11 +4453,12 @@ var DeliveryQueue = class DeliveryQueue {
4409
4453
  batchWatch = null;
4410
4454
  waiterWatch = null;
4411
4455
  batchListeners = /* @__PURE__ */ new Set();
4412
- constructor(stallAfterMs = STALL_AFTER_MS, replyGraceMs = REPLY_GRACE_MS, liveness = {}, batchSettleMs = BATCH_SETTLE_MS) {
4456
+ constructor(stallAfterMs = STALL_AFTER_MS, replyGraceMs = REPLY_GRACE_MS, liveness = {}, batchSettleMs = BATCH_SETTLE_MS, outlineStallMs = OUTLINE_STALL_MS) {
4413
4457
  this.stallAfterMs = stallAfterMs;
4414
4458
  this.replyGraceMs = replyGraceMs;
4415
4459
  this.liveness = liveness;
4416
4460
  this.batchSettleMs = batchSettleMs;
4461
+ this.outlineStallMs = outlineStallMs;
4417
4462
  }
4418
4463
  onBatchClosed(listener) {
4419
4464
  this.batchListeners.add(listener);
@@ -4521,13 +4566,19 @@ var DeliveryQueue = class DeliveryQueue {
4521
4566
  }
4522
4567
  /** Where the reviewer's layers request stands (see `LayersRequest`). */
4523
4568
  layersRequest() {
4524
- if (this.outlining() !== null) return "outlining";
4569
+ if (this.outlining() !== null) return this.outlineStalled() ? "stalled" : "outlining";
4525
4570
  if (this.buckets.get(this.scope)?.layers) return "queued";
4526
4571
  return null;
4527
4572
  }
4528
4573
  outlining() {
4529
4574
  return this.buckets.get(this.scope)?.outlining ?? null;
4530
4575
  }
4576
+ /** Derived, not flagged: the clock is the delivery itself, so a stall needs
4577
+ * no state to clear — only `armOutlineWatch` to announce the crossing. */
4578
+ outlineStalled() {
4579
+ const since = this.outlining();
4580
+ return since !== null && Date.now() - since >= this.outlineStallMs;
4581
+ }
4531
4582
  presenceDetail() {
4532
4583
  return {
4533
4584
  state: this.presence(),
@@ -4537,7 +4588,7 @@ var DeliveryQueue = class DeliveryQueue {
4537
4588
  }
4538
4589
  reason() {
4539
4590
  if (this.awaitingReply) return this.stalled ? "stalled" : "delivered";
4540
- if (this.outlining() !== null) return "delivered";
4591
+ if (this.outlining() !== null) return this.outlineStalled() ? "stalled" : "delivered";
4541
4592
  if (this.waiter) return "polling";
4542
4593
  if (this.betweenPolls) return this.parked;
4543
4594
  return this.lastDetach ?? "no-agent";
@@ -4592,6 +4643,20 @@ var DeliveryQueue = class DeliveryQueue {
4592
4643
  if (this.stallTimer !== null) clearTimeout(this.stallTimer);
4593
4644
  this.stallTimer = null;
4594
4645
  }
4646
+ armOutlineWatch() {
4647
+ this.clearOutlineWatch();
4648
+ const since = this.outlining();
4649
+ const timer = setTimeout(() => {
4650
+ this.outlineTimer = null;
4651
+ if (this.outlining() === since) this.notify();
4652
+ }, this.outlineStallMs);
4653
+ timer.unref?.();
4654
+ this.outlineTimer = timer;
4655
+ }
4656
+ clearOutlineWatch() {
4657
+ if (this.outlineTimer !== null) clearTimeout(this.outlineTimer);
4658
+ this.outlineTimer = null;
4659
+ }
4595
4660
  armGrace(why = "replied", windowMs = this.replyGraceMs) {
4596
4661
  this.clearGrace();
4597
4662
  this.betweenPolls = true;
@@ -4697,7 +4762,12 @@ var DeliveryQueue = class DeliveryQueue {
4697
4762
  * the cleared heads-up: a boolean per scope, surfaced once real feedback is
4698
4763
  * answered. */
4699
4764
  enqueueLayers() {
4700
- this.bucket().layers = true;
4765
+ const bucket = this.bucket();
4766
+ bucket.layers = true;
4767
+ if (this.outlineStalled()) {
4768
+ bucket.outlining = null;
4769
+ this.clearOutlineWatch();
4770
+ }
4701
4771
  const queued = this.waiter === null;
4702
4772
  this.wake();
4703
4773
  if (queued) this.notify();
@@ -4711,6 +4781,7 @@ var DeliveryQueue = class DeliveryQueue {
4711
4781
  bucket.layers = false;
4712
4782
  bucket.outlining = null;
4713
4783
  }
4784
+ this.clearOutlineWatch();
4714
4785
  this.notify();
4715
4786
  }
4716
4787
  /** The agent posted layers. Concludes an outstanding request; a spontaneous
@@ -4720,6 +4791,7 @@ var DeliveryQueue = class DeliveryQueue {
4720
4791
  const since = bucket?.outlining ?? null;
4721
4792
  if (bucket === void 0 || since === null) return null;
4722
4793
  bucket.outlining = null;
4794
+ this.clearOutlineWatch();
4723
4795
  if (!this.awaitingReply && !this.betweenPolls) this.armGrace();
4724
4796
  this.notify();
4725
4797
  return Date.now() - since;
@@ -4742,7 +4814,10 @@ var DeliveryQueue = class DeliveryQueue {
4742
4814
  if (this.batch.sawReply || Date.now() - this.batch.deliveredAt >= this.batchSettleMs) this.closeBatch("repoll");
4743
4815
  }
4744
4816
  const owing = this.buckets.get(this.scope);
4745
- if (owing !== void 0 && owing.outlining !== null && Date.now() - owing.outlining >= this.batchSettleMs) owing.outlining = null;
4817
+ if (owing !== void 0 && owing.outlining !== null && Date.now() - owing.outlining >= this.batchSettleMs) {
4818
+ owing.outlining = null;
4819
+ this.clearOutlineWatch();
4820
+ }
4746
4821
  if (this.hasPending()) return Promise.resolve("data");
4747
4822
  return new Promise((resolve) => {
4748
4823
  const waiter = (outcome) => resolve(outcome);
@@ -4821,6 +4896,7 @@ var DeliveryQueue = class DeliveryQueue {
4821
4896
  const bucket = this.bucket();
4822
4897
  bucket.layers = false;
4823
4898
  bucket.outlining = Date.now();
4899
+ this.armOutlineWatch();
4824
4900
  this.notify();
4825
4901
  return;
4826
4902
  }
@@ -4893,6 +4969,7 @@ var DeliveryQueue = class DeliveryQueue {
4893
4969
  this.closeBatch("ended");
4894
4970
  this.awaitingReply = false;
4895
4971
  for (const bucket of this.buckets.values()) bucket.outlining = null;
4972
+ this.clearOutlineWatch();
4896
4973
  this.stalled = false;
4897
4974
  this.clearStall();
4898
4975
  this.clearGrace();
@@ -7431,10 +7508,12 @@ function createApp(ctx, store, review, queue) {
7431
7508
  const value = ctx.uiSettings?.get(key) ?? null;
7432
7509
  return value !== null && values.has(value) ? value : null;
7433
7510
  };
7511
+ const storedVoice = () => normalizeVoice(ctx.uiSettings?.get("voice"));
7434
7512
  app.get("/api/settings", (c) => {
7435
7513
  return c.json({
7436
7514
  theme: stored("theme", THEME_VALUES),
7437
- critter: stored("critter", CRITTER_VALUES)
7515
+ critter: stored("critter", CRITTER_VALUES),
7516
+ voice: storedVoice()
7438
7517
  });
7439
7518
  });
7440
7519
  app.put("/api/settings", async (c) => {
@@ -7442,11 +7521,14 @@ function createApp(ctx, store, review, queue) {
7442
7521
  const body = await c.req.json().catch(() => null);
7443
7522
  const theme = body?.theme;
7444
7523
  const critter = body?.critter;
7524
+ const voice = body?.voice;
7445
7525
  const themeOk = typeof theme === "string" && THEME_VALUES.has(theme);
7446
7526
  const critterOk = typeof critter === "string" && CRITTER_VALUES.has(critter);
7447
- if (theme !== void 0 && !themeOk || critter !== void 0 && !critterOk || !(themeOk || critterOk)) return c.json({ error: "need {theme?: \"system\" | \"light\" | \"dark\", critter?: \"on\" | \"off\"}, at least one" }, 400);
7527
+ const voiceOk = typeof voice === "string" && voice.trim().length <= 1500;
7528
+ if (theme !== void 0 && !themeOk || critter !== void 0 && !critterOk || voice !== void 0 && !voiceOk || !(themeOk || critterOk || voiceOk)) return c.json({ error: `need {theme?: "system" | "light" | "dark", critter?: "on" | "off", voice?: string (up to ${VOICE_MAX} characters, empty for the default)}, at least one` }, 400);
7448
7529
  if (themeOk) ctx.uiSettings.set("theme", theme);
7449
7530
  if (critterOk) ctx.uiSettings.set("critter", critter);
7531
+ if (voiceOk) ctx.uiSettings.set("voice", voice.trim());
7450
7532
  return c.json({ ok: true });
7451
7533
  });
7452
7534
  const reviewKind = () => reviewKindOf(ctx.spec, ctx.pr !== void 0);
@@ -7483,7 +7565,10 @@ function createApp(ctx, store, review, queue) {
7483
7565
  const promptCtx = (...excludeThreadIds) => ({
7484
7566
  repo: repoInfo(),
7485
7567
  changeset: store?.get() ?? null,
7486
- ...ctx.pr && review ? { voice: review.get().threads } : {},
7568
+ ...ctx.pr && review ? {
7569
+ voice: review.get().threads,
7570
+ voiceSetting: storedVoice()
7571
+ } : {},
7487
7572
  siblings: review?.get().threads.filter((t) => !excludeThreadIds.includes(t.id) && (t.state === "open" || t.state === "sent")) ?? []
7488
7573
  });
7489
7574
  const deliverThreads = (threadIds) => {
@@ -1 +1 @@
1
- import{m as e,t}from"./mermaid-parser.core-Cvl3-NHE.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-BOAZLa52.js";import"./chunk-DSNLSHJZ-0Nqpe1Hg.js";import{n as i,r as a,t as o}from"./chunk-2E7WHVMD-Dop1N6Br.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-BTw9trpK.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-C6WMZqm3.js";import{n}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import{m as r}from"./src-wNqkFAEP.js";import"./chunk-DSNLSHJZ-DiIzqoT2.js";import{n as i,r as a,t as o}from"./chunk-2E7WHVMD-DfTh-gtY.js";import{t as s}from"./chunk-JWPE2WC7-DVXcaiue.js";import"./mermaid.core-BOSV4eXG.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-B5xF88x8.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-F1lvNP36.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 +1 @@
1
- import"./chunk-NGNAAXSQ-Bw6tHVuc.js";export{M as createArchitectureServices}from"./mermaid-parser.core-Cvl3-NHE.js";
1
+ import"./chunk-NGNAAXSQ-Bw6tHVuc.js";export{M as createArchitectureServices}from"./mermaid-parser.core-C6WMZqm3.js";