@joeyshi12/casper 0.15.4 → 0.15.6

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 (69) hide show
  1. package/dist/mcp.js +1 -1
  2. package/dist/server.js +299 -16
  3. package/dist/web/assets/{abnfDiagram-N423BO3Z-DakyBrXm.js → abnfDiagram-N423BO3Z-jvSYyvNw.js} +1 -1
  4. package/dist/web/assets/{arc-DSs2NjEc.js → arc-BiHYHdUQ.js} +1 -1
  5. package/dist/web/assets/{architectureDiagram-T3A2C74G-zU22qX0G.js → architectureDiagram-T3A2C74G-4Eqc-u3C.js} +1 -1
  6. package/dist/web/assets/{blockDiagram-VBNYF7ZC-D-YU0KEh.js → blockDiagram-VBNYF7ZC-BcOcmlBN.js} +1 -1
  7. package/dist/web/assets/{c4Diagram-5PPSVZJV-znUKddvh.js → c4Diagram-5PPSVZJV-BUudyYqU.js} +1 -1
  8. package/dist/web/assets/channel-BueZNEdT.js +1 -0
  9. package/dist/web/assets/{chunk-2GRJ4B5K-BcSZhh-L.js → chunk-2GRJ4B5K-bTMhoJSQ.js} +1 -1
  10. package/dist/web/assets/{chunk-2Q5K7J3B-DP8hhxaC.js → chunk-2Q5K7J3B-BYp6dfdp.js} +1 -1
  11. package/dist/web/assets/{chunk-5RXB4S5H-8yqaedk-.js → chunk-5RXB4S5H-Dg3ASlI5.js} +1 -1
  12. package/dist/web/assets/{chunk-5VM5RSS4-DtpYRQi9.js → chunk-5VM5RSS4-B7uwpCHf.js} +1 -1
  13. package/dist/web/assets/{chunk-6Q2QTUOP-Dr2Efztw.js → chunk-6Q2QTUOP-DVTiWdGW.js} +1 -1
  14. package/dist/web/assets/{chunk-GF5L2VYU-tz1ADOXm.js → chunk-GF5L2VYU-C2LdpbyU.js} +1 -1
  15. package/dist/web/assets/{chunk-JWPE2WC7-D0Agbn3V.js → chunk-JWPE2WC7-CMX4-S8P.js} +1 -1
  16. package/dist/web/assets/{chunk-KBJHAD2P-Ds5UEEfs.js → chunk-KBJHAD2P-D92STFuF.js} +1 -1
  17. package/dist/web/assets/{chunk-RYQCIY6F-D5nf0UrM.js → chunk-RYQCIY6F-B2PLxj_Q.js} +1 -1
  18. package/dist/web/assets/{chunk-XXDRQBXY-BM0szAFy.js → chunk-XXDRQBXY-DCpI_0Ix.js} +1 -1
  19. package/dist/web/assets/classDiagram-JCYQIIEL-CSEqsvyn.js +1 -0
  20. package/dist/web/assets/classDiagram-v2-OCEON4UE-CSEqsvyn.js +1 -0
  21. package/dist/web/assets/{cose-bilkent-JH36ORCC-DlBbNDq_.js → cose-bilkent-JH36ORCC-KtY-8vxF.js} +1 -1
  22. package/dist/web/assets/{cynefin-VYW2F7L2-9VHL0nlG.js → cynefin-VYW2F7L2-DkTsGV_4.js} +1 -1
  23. package/dist/web/assets/{cynefinDiagram-MW4NZA55-wB8q5DQ3.js → cynefinDiagram-MW4NZA55-BVPMHgGu.js} +1 -1
  24. package/dist/web/assets/{dagre-VZM6K2ZE-BKVMWxlX.js → dagre-VZM6K2ZE-DT-S1NOU.js} +1 -1
  25. package/dist/web/assets/{diagram-7IWD3JNH-tFLFSGbq.js → diagram-7IWD3JNH-DUJvV7wV.js} +1 -1
  26. package/dist/web/assets/{diagram-B4RE2ZJO-wvB3E98W.js → diagram-B4RE2ZJO-DmpnY7ob.js} +1 -1
  27. package/dist/web/assets/{diagram-LBJQPF4R-G9xyHlao.js → diagram-LBJQPF4R-nEMZNwen.js} +1 -1
  28. package/dist/web/assets/{diagram-Q27KOJAE-L2oBVFYq.js → diagram-Q27KOJAE-Dr-59ElI.js} +1 -1
  29. package/dist/web/assets/{diagram-UB23O5K3-BfFooN6P.js → diagram-UB23O5K3-4wvmRauY.js} +1 -1
  30. package/dist/web/assets/{ebnfDiagram-BXEA7PRR-CjAqXN08.js → ebnfDiagram-BXEA7PRR-055xAlHi.js} +1 -1
  31. package/dist/web/assets/{erDiagram-JOGREHBK-Dn4Z2761.js → erDiagram-JOGREHBK-DqWTDG8u.js} +1 -1
  32. package/dist/web/assets/{flowDiagram-UKHOOZJN-DGwa0dmn.js → flowDiagram-UKHOOZJN-D3lUh0yb.js} +1 -1
  33. package/dist/web/assets/{ganttDiagram-PKOTCBZU-DHJ-GczS.js → ganttDiagram-PKOTCBZU-aV5l2zrT.js} +1 -1
  34. package/dist/web/assets/{gitGraphDiagram-DS77QQ5N-DLglv3lW.js → gitGraphDiagram-DS77QQ5N-BK2KCI35.js} +1 -1
  35. package/dist/web/assets/{index-D0Vzz5GV.js → index-B5ZDbS-R.js} +54 -54
  36. package/dist/web/assets/index-CRxbcY2R.css +1 -0
  37. package/dist/web/assets/{index-14KCvlDZ.js → index-Dv1My9Ob.js} +1 -1
  38. package/dist/web/assets/{infoDiagram-6WML65LV-bdHFhrwE.js → infoDiagram-6WML65LV-BcSXYnWm.js} +1 -1
  39. package/dist/web/assets/{ishikawaDiagram-WSZJBQD7-jAr1MKpS.js → ishikawaDiagram-WSZJBQD7-C0LFAfcz.js} +1 -1
  40. package/dist/web/assets/{journeyDiagram-NVQOT4AX-DvBhBloa.js → journeyDiagram-NVQOT4AX-1Zs22Gpd.js} +1 -1
  41. package/dist/web/assets/{kanban-definition-27J2QSJJ-DubwpPH6.js → kanban-definition-27J2QSJJ-DW6RwD7S.js} +1 -1
  42. package/dist/web/assets/{linear-dKGqbR5Q.js → linear-Cfzhrbed.js} +1 -1
  43. package/dist/web/assets/{mermaid.core-C4PgRjNY.js → mermaid.core-D0VPssrU.js} +4 -4
  44. package/dist/web/assets/{mindmap-definition-FAOFIHXS-B6mdA1Tm.js → mindmap-definition-FAOFIHXS-BeD5KiWO.js} +1 -1
  45. package/dist/web/assets/{pegDiagram-VL7TDLO6-BCfJtGLE.js → pegDiagram-VL7TDLO6-JDLyI4Gc.js} +1 -1
  46. package/dist/web/assets/{pieDiagram-7S7Q4E2Y-FFGYMW6G.js → pieDiagram-7S7Q4E2Y-BY3XpjEU.js} +1 -1
  47. package/dist/web/assets/{quadrantDiagram-CIZ2JOQS-DjTYPfPb.js → quadrantDiagram-CIZ2JOQS-C4oT4Lqc.js} +1 -1
  48. package/dist/web/assets/{railroadDiagram-AXF67PYL-eIMXQZRc.js → railroadDiagram-AXF67PYL-lfzvVyK7.js} +1 -1
  49. package/dist/web/assets/{requirementDiagram-LRYGKXZP-BbZF_AvG.js → requirementDiagram-LRYGKXZP-wGnOD5SS.js} +1 -1
  50. package/dist/web/assets/{sankeyDiagram-W5VNT64P-ef1nmrcw.js → sankeyDiagram-W5VNT64P-DJQ2VW0G.js} +1 -1
  51. package/dist/web/assets/{sequenceDiagram-SI44F4Z6-CTcZ0S9h.js → sequenceDiagram-SI44F4Z6-Bz_rjvWZ.js} +1 -1
  52. package/dist/web/assets/{sizeCapture-X5ZJPWSS-CE9kBifO.js → sizeCapture-X5ZJPWSS-BgxIA36S.js} +1 -1
  53. package/dist/web/assets/{stateDiagram-OKZ733FA-2dDgqu9B.js → stateDiagram-OKZ733FA-DpL_B9Mu.js} +1 -1
  54. package/dist/web/assets/stateDiagram-v2-UEYNNEHI-DsD9j9Fu.js +1 -0
  55. package/dist/web/assets/{swimlanes-SLNWSIFB-CdH90qY_.js → swimlanes-SLNWSIFB-B6uTv46X.js} +2 -2
  56. package/dist/web/assets/swimlanesDiagram-ULZ7WXOC-BxNKQaPC.js +8 -0
  57. package/dist/web/assets/{timeline-definition-Z64GVDOM-Cgx_G2Hj.js → timeline-definition-Z64GVDOM-DvMUcNNs.js} +1 -1
  58. package/dist/web/assets/{vennDiagram-T6HMQDX7-DQYwQJ21.js → vennDiagram-T6HMQDX7-K_9U-J2A.js} +1 -1
  59. package/dist/web/assets/{wardleyDiagram-T6FBY63Y-D1-xqaxE.js → wardleyDiagram-T6FBY63Y-DwMi4kCd.js} +1 -1
  60. package/dist/web/assets/{xychartDiagram-ELKLHX3M-DIE_jW87.js → xychartDiagram-ELKLHX3M-BkcnShpk.js} +1 -1
  61. package/dist/web/index.html +2 -2
  62. package/dist/web/sw.js +1 -1
  63. package/package.json +1 -1
  64. package/dist/web/assets/channel-CJtkudqm.js +0 -1
  65. package/dist/web/assets/classDiagram-JCYQIIEL-2UVMTtN-.js +0 -1
  66. package/dist/web/assets/classDiagram-v2-OCEON4UE-2UVMTtN-.js +0 -1
  67. package/dist/web/assets/index-DNWKm_GR.css +0 -1
  68. package/dist/web/assets/stateDiagram-v2-UEYNNEHI-DTDb4pVC.js +0 -1
  69. package/dist/web/assets/swimlanesDiagram-ULZ7WXOC-pYse4_gV.js +0 -8
package/dist/mcp.js CHANGED
@@ -369,7 +369,7 @@ function handleMessage(req, version) {
369
369
  }
370
370
 
371
371
  // server/src/mcp/server.ts
372
- var VERSION = true ? "0.15.4" : "dev";
372
+ var VERSION = true ? "0.15.6" : "dev";
373
373
  function runMcpServer() {
374
374
  const rl = createInterface({ input: process.stdin });
375
375
  rl.on("line", (line) => {
package/dist/server.js CHANGED
@@ -392,6 +392,17 @@ CREATE TABLE IF NOT EXISTS message_attachments (
392
392
  kind TEXT NOT NULL,
393
393
  PRIMARY KEY (chat_id, ordinal, path)
394
394
  );
395
+ CREATE TABLE IF NOT EXISTS turn_endings (
396
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
397
+ chat_id TEXT NOT NULL,
398
+ started_at INTEGER NOT NULL,
399
+ ended_at INTEGER NOT NULL,
400
+ prompt TEXT NOT NULL,
401
+ kind TEXT NOT NULL,
402
+ message TEXT,
403
+ items TEXT NOT NULL
404
+ );
405
+ CREATE INDEX IF NOT EXISTS turn_endings_chat ON turn_endings (chat_id);
395
406
  CREATE TABLE IF NOT EXISTS subagent_links (
396
407
  child_session_id TEXT PRIMARY KEY,
397
408
  parent_session_id TEXT NOT NULL,
@@ -712,6 +723,88 @@ var init_titles = __esm({
712
723
  }
713
724
  });
714
725
 
726
+ // shared/dist/turnFold.js
727
+ function commitDraft(draft, baseId, ts = Date.now()) {
728
+ const next = [...draft.items];
729
+ if (draft.streamingThought.trim()) {
730
+ next.push({
731
+ type: "message",
732
+ message: {
733
+ id: `t-${baseId}`,
734
+ role: "thinking",
735
+ text: draft.streamingThought.trim(),
736
+ timestamp: ts
737
+ }
738
+ });
739
+ }
740
+ if (draft.streamingText.trim()) {
741
+ next.push({
742
+ type: "message",
743
+ message: { id: `a-${baseId}`, role: "assistant", text: draft.streamingText, timestamp: ts }
744
+ });
745
+ }
746
+ return next;
747
+ }
748
+ function settleTools(items) {
749
+ return items.map((it) => it.type === "tool_call" && (it.tool.status === "pending" || it.tool.status === "in_progress") ? { type: "tool_call", tool: { ...it.tool, status: "failed" } } : it);
750
+ }
751
+ function foldSessionUpdate(draft, u, seq, ts) {
752
+ if (u.sessionUpdate === "agent_message_chunk") {
753
+ const chunk = u.content?.text ?? "";
754
+ return { ...draft, streamingText: draft.streamingText + chunk };
755
+ }
756
+ if (u.sessionUpdate === "agent_thought_chunk") {
757
+ const chunk = u.content?.text ?? "";
758
+ return { ...draft, streamingThought: draft.streamingThought + chunk };
759
+ }
760
+ if (u.sessionUpdate === "tool_call") {
761
+ const tc = u;
762
+ const toolName = tc._meta?.kiro?.toolName;
763
+ return {
764
+ items: [
765
+ ...commitDraft(draft, `s-${seq}`, ts),
766
+ {
767
+ type: "tool_call",
768
+ tool: {
769
+ id: tc.toolCallId,
770
+ name: toolName,
771
+ title: tc.title ?? tc.toolCallId,
772
+ kind: tc.kind,
773
+ status: tc.status ?? "pending",
774
+ input: tc.rawInput,
775
+ content: tc.content ?? []
776
+ }
777
+ }
778
+ ],
779
+ streamingText: "",
780
+ streamingThought: ""
781
+ };
782
+ }
783
+ if (u.sessionUpdate === "tool_call_update") {
784
+ const tu = u;
785
+ return {
786
+ ...draft,
787
+ items: draft.items.map((it) => it.type === "tool_call" && it.tool.id === tu.toolCallId ? {
788
+ type: "tool_call",
789
+ tool: {
790
+ ...it.tool,
791
+ status: tu.status ?? it.tool.status,
792
+ output: tu.rawOutput ?? it.tool.output,
793
+ content: tu.content ?? it.tool.content
794
+ }
795
+ } : it)
796
+ };
797
+ }
798
+ return draft;
799
+ }
800
+ var emptyDraft;
801
+ var init_turnFold = __esm({
802
+ "shared/dist/turnFold.js"() {
803
+ "use strict";
804
+ emptyDraft = () => ({ items: [], streamingText: "", streamingThought: "" });
805
+ }
806
+ });
807
+
715
808
  // shared/dist/ws-protocol.js
716
809
  var init_ws_protocol = __esm({
717
810
  "shared/dist/ws-protocol.js"() {
@@ -728,6 +821,7 @@ var init_dist = __esm({
728
821
  init_observability();
729
822
  init_rest_dto();
730
823
  init_titles();
824
+ init_turnFold();
731
825
  init_ws_protocol();
732
826
  }
733
827
  });
@@ -1249,6 +1343,75 @@ var init_TurnState = __esm({
1249
1343
  }
1250
1344
  });
1251
1345
 
1346
+ // server/src/session/TurnRecorder.ts
1347
+ function cap(value) {
1348
+ if (typeof value === "string") {
1349
+ return value.length > MAX_STRING ? `${value.slice(0, MAX_STRING)}
1350
+ [truncated]` : value;
1351
+ }
1352
+ if (Array.isArray(value)) return value.filter((v) => !isImage(v)).map(cap);
1353
+ if (value && typeof value === "object") {
1354
+ return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, cap(v)]));
1355
+ }
1356
+ return value;
1357
+ }
1358
+ var MAX_STRING, isImage, bounded, TurnRecorder;
1359
+ var init_TurnRecorder = __esm({
1360
+ "server/src/session/TurnRecorder.ts"() {
1361
+ "use strict";
1362
+ init_dist();
1363
+ MAX_STRING = 2e4;
1364
+ isImage = (block) => {
1365
+ const b = block;
1366
+ return b?.type === "image" || b?.content?.type === "image";
1367
+ };
1368
+ bounded = (items) => items.map(
1369
+ (it) => it.type === "tool_call" ? {
1370
+ type: "tool_call",
1371
+ tool: {
1372
+ ...it.tool,
1373
+ input: cap(it.tool.input),
1374
+ output: cap(it.tool.output),
1375
+ content: cap(it.tool.content)
1376
+ }
1377
+ } : it
1378
+ );
1379
+ TurnRecorder = class {
1380
+ draft = null;
1381
+ startedAt = 0;
1382
+ prompt = "";
1383
+ observe(e) {
1384
+ const p = e.payload;
1385
+ if (p.kind === "turn_started") {
1386
+ this.draft = emptyDraft();
1387
+ this.startedAt = e.ts;
1388
+ this.prompt = stripAttachmentsLine(
1389
+ p.prompt.filter((b) => b.type === "text").map((b) => b.text).join("")
1390
+ );
1391
+ } else if (p.kind === "session_update" && this.draft) {
1392
+ this.draft = foldSessionUpdate(this.draft, p.update, e.seq, e.ts);
1393
+ }
1394
+ }
1395
+ /** Null when no turn was being followed. */
1396
+ finish(ending, endedAt = Date.now()) {
1397
+ const draft = this.draft;
1398
+ this.draft = null;
1399
+ if (!draft) return null;
1400
+ return {
1401
+ startedAt: this.startedAt,
1402
+ endedAt,
1403
+ prompt: this.prompt,
1404
+ ...ending,
1405
+ items: bounded(settleTools(commitDraft(draft, `end-${endedAt}`, endedAt)))
1406
+ };
1407
+ }
1408
+ discard() {
1409
+ this.draft = null;
1410
+ }
1411
+ };
1412
+ }
1413
+ });
1414
+
1252
1415
  // server/src/session/SubagentTracker.ts
1253
1416
  var SubagentTracker;
1254
1417
  var init_SubagentTracker = __esm({
@@ -1537,10 +1700,26 @@ async function hasRecordedTurns(sessionId) {
1537
1700
  return false;
1538
1701
  }
1539
1702
  }
1540
- async function hydrateTranscript(sessionId, attachments) {
1703
+ function endingItems(e) {
1704
+ const prefix = `te${e.id}-`;
1705
+ const items = e.items.map(
1706
+ (it) => it.type === "message" ? { type: "message", message: { ...it.message, id: prefix + it.message.id } } : it
1707
+ );
1708
+ items.push(
1709
+ e.kind === "failed" ? { type: "turn_error", id: `${prefix}end`, message: e.message ?? "", timestamp: e.endedAt } : { type: "turn_interrupted", id: `${prefix}end`, timestamp: e.endedAt }
1710
+ );
1711
+ return items;
1712
+ }
1713
+ async function hydrateTranscript(sessionId, attachments, endings = []) {
1541
1714
  const items = [];
1542
1715
  let userOrdinal = 0;
1543
1716
  const toolsById = /* @__PURE__ */ new Map();
1717
+ const waiting = [...endings];
1718
+ let replaced = false;
1719
+ const unrecorded = (e) => [
1720
+ { type: "message", message: { id: `te${e.id}-u`, role: "user", text: e.prompt, timestamp: e.startedAt } },
1721
+ ...endingItems(e)
1722
+ ];
1544
1723
  for (const entry of await readJsonlEntries(sessionId)) {
1545
1724
  const content = contentBlocks(entry.data.content);
1546
1725
  const textOf = (kind) => content.filter((c) => c.kind === kind).map(blockText).join("");
@@ -1548,12 +1727,29 @@ async function hydrateTranscript(sessionId, attachments) {
1548
1727
  const ts = entry.data.meta?.timestamp;
1549
1728
  const pushMsg = (msg) => items.push({ type: "message", message: msg });
1550
1729
  if (entry.kind === "Prompt") {
1730
+ replaced = false;
1551
1731
  const text2 = stripAttachmentsLine(textOf("text"));
1732
+ let matched;
1733
+ if (ts !== void 0) {
1734
+ const at = ts * 1e3;
1735
+ matched = waiting.find(
1736
+ (e) => e.prompt.trim() === text2.trim() && at >= e.startedAt - STAMP_PAD_MS && at <= e.endedAt + STAMP_PAD_MS
1737
+ );
1738
+ while (waiting.length && waiting[0] !== matched && waiting[0].endedAt < at - STAMP_PAD_MS) {
1739
+ items.push(...unrecorded(waiting.shift()));
1740
+ }
1741
+ if (matched) waiting.splice(waiting.indexOf(matched), 1);
1742
+ }
1552
1743
  const attached = attachments?.get(userOrdinal);
1553
1744
  userOrdinal++;
1554
1745
  if (text2.trim() || attached?.length)
1555
1746
  pushMsg({ id: `u-${baseId}`, role: "user", text: text2, timestamp: ts, attachments: attached });
1747
+ if (matched) {
1748
+ items.push(...endingItems(matched));
1749
+ replaced = true;
1750
+ }
1556
1751
  } else if (entry.kind === "AssistantMessage") {
1752
+ if (replaced) continue;
1557
1753
  const thinking = textOf("thinking");
1558
1754
  if (thinking.trim())
1559
1755
  pushMsg({ id: `t-${baseId}`, role: "thinking", text: thinking.trim(), timestamp: ts });
@@ -1575,6 +1771,7 @@ async function hydrateTranscript(sessionId, attachments) {
1575
1771
  items.push({ type: "tool_call", tool });
1576
1772
  }
1577
1773
  } else if (entry.kind === "ToolResults") {
1774
+ if (replaced) continue;
1578
1775
  for (const c of content) {
1579
1776
  const d = toolResultData(c);
1580
1777
  if (!d) continue;
@@ -1589,9 +1786,10 @@ async function hydrateTranscript(sessionId, attachments) {
1589
1786
  items.push({ type: "compaction", id: `c-${baseId}`, summary, timestamp: ts });
1590
1787
  }
1591
1788
  }
1789
+ for (const e of waiting) items.push(...unrecorded(e));
1592
1790
  return items;
1593
1791
  }
1594
- var isRecord;
1792
+ var isRecord, STAMP_PAD_MS;
1595
1793
  var init_kiroFiles = __esm({
1596
1794
  "server/src/session/kiroFiles.ts"() {
1597
1795
  "use strict";
@@ -1599,6 +1797,7 @@ var init_kiroFiles = __esm({
1599
1797
  init_config();
1600
1798
  init_paths2();
1601
1799
  isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
1800
+ STAMP_PAD_MS = 2e3;
1602
1801
  }
1603
1802
  });
1604
1803
 
@@ -1672,9 +1871,38 @@ var init_chatStore = __esm({
1672
1871
  }
1673
1872
  return out;
1674
1873
  }
1874
+ addTurnEnding(chatId, e) {
1875
+ db().prepare(
1876
+ `INSERT INTO turn_endings (chat_id, started_at, ended_at, prompt, kind, message, items)
1877
+ VALUES (?, ?, ?, ?, ?, ?, ?)`
1878
+ ).run(chatId, e.startedAt, e.endedAt, e.prompt, e.kind, e.message ?? null, JSON.stringify(e.items));
1879
+ }
1880
+ turnEndingsByChat(chatId) {
1881
+ const rows = db().prepare(
1882
+ `SELECT id, started_at, ended_at, prompt, kind, message, items FROM turn_endings
1883
+ WHERE chat_id = ? ORDER BY id`
1884
+ ).all(chatId);
1885
+ const out = [];
1886
+ for (const r of rows) {
1887
+ try {
1888
+ out.push({
1889
+ id: r.id,
1890
+ startedAt: r.started_at,
1891
+ endedAt: r.ended_at,
1892
+ prompt: r.prompt,
1893
+ kind: r.kind === "interrupted" ? "interrupted" : "failed",
1894
+ ...r.message === null ? {} : { message: r.message },
1895
+ items: JSON.parse(r.items)
1896
+ });
1897
+ } catch {
1898
+ }
1899
+ }
1900
+ return out;
1901
+ }
1675
1902
  remove(chatId) {
1676
1903
  db().prepare("DELETE FROM chats WHERE chat_id = ?").run(chatId);
1677
1904
  db().prepare("DELETE FROM message_attachments WHERE chat_id = ?").run(chatId);
1905
+ db().prepare("DELETE FROM turn_endings WHERE chat_id = ?").run(chatId);
1678
1906
  }
1679
1907
  read(chatId, column) {
1680
1908
  const row = db().prepare(`SELECT ${column} AS value FROM chats WHERE chat_id = ?`).get(chatId);
@@ -1783,7 +2011,7 @@ function firstPromptText(transcript) {
1783
2011
  function isGhost(s, hasFile) {
1784
2012
  return !hasFile && s.hasBeenLive && !s.proc;
1785
2013
  }
1786
- var Session, TRANSCRIPT_PAGE_SIZE, SessionManager;
2014
+ var CANCEL_GRACE_MS, Session, TRANSCRIPT_PAGE_SIZE, SessionManager;
1787
2015
  var init_SessionManager = __esm({
1788
2016
  "server/src/session/SessionManager.ts"() {
1789
2017
  "use strict";
@@ -1795,16 +2023,19 @@ var init_SessionManager = __esm({
1795
2023
  init_KiroProcess();
1796
2024
  init_EventStore();
1797
2025
  init_TurnState();
2026
+ init_TurnRecorder();
1798
2027
  init_SubagentTracker();
1799
2028
  init_subagentResult();
1800
2029
  init_subagentFallbackMatch();
1801
2030
  init_kiroFiles();
1802
2031
  init_chatStore();
1803
2032
  init_subagentLinks();
2033
+ CANCEL_GRACE_MS = 1e4;
1804
2034
  Session = class {
1805
2035
  sessionId;
1806
2036
  store;
1807
2037
  turnState = new TurnState();
2038
+ recorder = new TurnRecorder();
1808
2039
  subagents = new SubagentTracker();
1809
2040
  cwd;
1810
2041
  agentId;
@@ -1816,6 +2047,9 @@ var init_SessionManager = __esm({
1816
2047
  updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1817
2048
  lastActivity = Date.now();
1818
2049
  running = false;
2050
+ cancelRequested = false;
2051
+ // Set while a cancelled turn is given time to end before its process is killed.
2052
+ cancelTimer;
1819
2053
  everLive = false;
1820
2054
  proc;
1821
2055
  spawning;
@@ -1839,7 +2073,9 @@ var init_SessionManager = __esm({
1839
2073
  record(payload) {
1840
2074
  this.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1841
2075
  this.turnState.apply(payload);
1842
- return this.store.append(payload);
2076
+ const event = this.store.append(payload);
2077
+ this.recorder.observe(event);
2078
+ return event;
1843
2079
  }
1844
2080
  };
1845
2081
  TRANSCRIPT_PAGE_SIZE = 80;
@@ -1852,9 +2088,11 @@ var init_SessionManager = __esm({
1852
2088
  // whole parent transcript (145 MB in one chat), so each child is tried once per process.
1853
2089
  unmatchedChildren = /* @__PURE__ */ new Map();
1854
2090
  spawnProcess;
2091
+ cancelGraceMs;
1855
2092
  constructor(log, opts = {}) {
1856
2093
  this.log = log;
1857
2094
  this.spawnProcess = opts.spawn ?? ((o, l) => new KiroProcess(o, l));
2095
+ this.cancelGraceMs = opts.cancelGraceMs ?? CANCEL_GRACE_MS;
1858
2096
  }
1859
2097
  /** What a session is called, from every read path. */
1860
2098
  titleOf(chat, parts) {
@@ -2138,22 +2376,63 @@ var init_SessionManager = __esm({
2138
2376
  recorded = attachments;
2139
2377
  }
2140
2378
  s.record({ kind: "turn_started", prompt: content, attachments: recorded });
2141
- proc.prompt({ sessionId: s.sessionId, prompt: content }).then((res) => s.record({ kind: "turn_ended", stopReason: res.stopReason })).catch((err) => {
2379
+ proc.prompt({ sessionId: s.sessionId, prompt: content }).then((res) => {
2380
+ if (res.stopReason === "cancelled") this.saveEnding(chatId, s.recorder.finish({ kind: "interrupted" }));
2381
+ else s.recorder.discard();
2382
+ s.record({ kind: "turn_ended", stopReason: res.stopReason });
2383
+ }).catch((err) => {
2384
+ if (s.cancelRequested) {
2385
+ this.saveEnding(chatId, s.recorder.finish({ kind: "interrupted" }));
2386
+ s.record({ kind: "turn_ended", stopReason: "cancelled" });
2387
+ return;
2388
+ }
2142
2389
  this.log.error({ err, sessionId: s.sessionId }, "prompt turn failed");
2143
2390
  const tail = proc.stderrTail();
2144
2391
  const message = tail && !err.message.includes(tail) ? `${err.message}
2145
2392
 
2146
2393
  kiro-cli output:
2147
2394
  ${tail}` : err.message;
2395
+ this.saveEnding(chatId, s.recorder.finish({ kind: "failed", message }));
2148
2396
  s.record({ kind: "turn_error", message });
2149
2397
  }).finally(() => {
2398
+ s.cancelRequested = false;
2399
+ clearTimeout(s.cancelTimer);
2400
+ s.cancelTimer = void 0;
2150
2401
  s.running = false;
2151
2402
  s.lastActivity = Date.now();
2152
2403
  });
2153
2404
  }
2405
+ saveEnding(chatId, ending) {
2406
+ if (!ending) return;
2407
+ try {
2408
+ this.store.addTurnEnding(chatId, ending);
2409
+ } catch (err) {
2410
+ this.log.error({ err, chatId }, "could not store a failed turn");
2411
+ }
2412
+ }
2413
+ /**
2414
+ * Asks kiro to cancel the turn. If the turn has not ended within the grace period, kiro
2415
+ * has stopped handling the session (its agent loop can panic while the process stays
2416
+ * up), so the process is killed. Its exit then fails the pending prompt.
2417
+ */
2154
2418
  cancel(chatId) {
2155
2419
  const s = this.sessions.get(this.store.sessionIdForChat(chatId) ?? "");
2156
- s?.proc?.cancel(s.sessionId);
2420
+ const proc = s?.proc;
2421
+ if (!s || !proc) return;
2422
+ proc.cancel(s.sessionId);
2423
+ if (!s.running) return;
2424
+ s.cancelRequested = true;
2425
+ if (s.cancelTimer) return;
2426
+ s.cancelTimer = setTimeout(() => {
2427
+ s.cancelTimer = void 0;
2428
+ if (!s.running || s.proc !== proc) return;
2429
+ this.log.warn(
2430
+ { sessionId: s.sessionId, graceMs: this.cancelGraceMs },
2431
+ "turn did not end after cancel; killing kiro-cli"
2432
+ );
2433
+ proc.dispose();
2434
+ }, this.cancelGraceMs);
2435
+ s.cancelTimer.unref?.();
2157
2436
  }
2158
2437
  async setMode(chatId, modeId) {
2159
2438
  const s = await this.ensureOpen(chatId);
@@ -2227,12 +2506,19 @@ ${tail}` : err.message;
2227
2506
  if (!sessionId) throw new Error(`Unknown chat: ${chatId}`);
2228
2507
  return sessionId;
2229
2508
  }
2509
+ hydrate(chatId, sessionId) {
2510
+ return hydrateTranscript(
2511
+ sessionId,
2512
+ this.store.attachmentsByChat(chatId),
2513
+ this.store.turnEndingsByChat(chatId)
2514
+ );
2515
+ }
2230
2516
  async getDetail(chatId) {
2231
2517
  const chat = this.store.get(chatId);
2232
2518
  if (!chat) throw new Error(`Unknown chat: ${chatId}`);
2233
2519
  const sessionId = chat.sessionId;
2234
2520
  const [transcript, persisted] = await Promise.all([
2235
- sessionId ? hydrateTranscript(sessionId, this.store.attachmentsByChat(chatId)) : Promise.resolve([]),
2521
+ sessionId ? this.hydrate(chatId, sessionId) : Promise.resolve([]),
2236
2522
  sessionId ? readPersistedSession(sessionId) : Promise.resolve(null)
2237
2523
  ]);
2238
2524
  const s = sessionId ? this.sessions.get(sessionId) : void 0;
@@ -2242,10 +2528,7 @@ ${tail}` : err.message;
2242
2528
  /** A transcript slice for lazy "load older on scroll up". offset/limit are
2243
2529
  * clamped to the transcript bounds. */
2244
2530
  async getTranscriptPage(chatId, offset, limit) {
2245
- const transcript = await hydrateTranscript(
2246
- this.sessionIdOf(chatId),
2247
- this.store.attachmentsByChat(chatId)
2248
- );
2531
+ const transcript = await this.hydrate(chatId, this.sessionIdOf(chatId));
2249
2532
  const start = Math.max(0, Math.min(offset, transcript.length));
2250
2533
  const end = Math.max(start, Math.min(start + limit, transcript.length));
2251
2534
  return transcript.slice(start, end);
@@ -2878,11 +3161,11 @@ function hexdump(buf) {
2878
3161
  async function sendFilePreview(req, reply, realTarget, stat) {
2879
3162
  const ext = path14.extname(realTarget).toLowerCase();
2880
3163
  const mime = mimeForExt(ext);
2881
- const isImage = mime.startsWith("image/");
3164
+ const isImage2 = mime.startsWith("image/");
2882
3165
  const isPdf = mime === "application/pdf";
2883
3166
  const isHtml = mime === "text/html" && req.query.raw === "1";
2884
3167
  const kind = classifyKind(realTarget);
2885
- if (isImage || isPdf) {
3168
+ if (isImage2 || isPdf) {
2886
3169
  if (stat.size > MAX_IMAGE_PREVIEW_BYTES) {
2887
3170
  reply.code(413);
2888
3171
  return tooLargeForPreview(stat.size, MAX_IMAGE_PREVIEW_BYTES);
@@ -2903,7 +3186,7 @@ async function sendFilePreview(req, reply, realTarget, stat) {
2903
3186
  reply.header("Cache-Control", "no-store");
2904
3187
  return reply.send(createReadStream(realTarget));
2905
3188
  }
2906
- if (isImage || isPdf) {
3189
+ if (isImage2 || isPdf) {
2907
3190
  const etag = `W/"${stat.size}-${stat.mtimeMs}"`;
2908
3191
  reply.header("Cache-Control", "private, no-cache");
2909
3192
  reply.header("ETag", etag);
@@ -4358,7 +4641,7 @@ var init_server2 = __esm({
4358
4641
  "server/src/mcp/server.ts"() {
4359
4642
  "use strict";
4360
4643
  init_protocol();
4361
- VERSION = true ? "0.15.4" : "dev";
4644
+ VERSION = true ? "0.15.6" : "dev";
4362
4645
  }
4363
4646
  });
4364
4647
 
@@ -7738,7 +8021,7 @@ var program = new Command();
7738
8021
  // server/src/cli/program.ts
7739
8022
  init_paths();
7740
8023
  init_settings();
7741
- var VERSION2 = true ? "0.15.4" : "dev";
8024
+ var VERSION2 = true ? "0.15.6" : "dev";
7742
8025
  async function bootstrap() {
7743
8026
  const file = configFilePath();
7744
8027
  const settings = readSettings(file);
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-Dr2Efztw.js";import{p as f}from"./chunk-JWPE2WC7-D0Agbn3V.js";import{_ as n,l as o}from"./mermaid.core-C4PgRjNY.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-9VHL0nlG.js";import"./index-D0Vzz5GV.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=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 i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
1
+ import{g as p,r as u,d as a}from"./chunk-6Q2QTUOP-DVTiWdGW.js";import{p as f}from"./chunk-JWPE2WC7-CMX4-S8P.js";import{_ as n,l as o}from"./mermaid.core-D0VPssrU.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-DkTsGV_4.js";import"./index-B5ZDbS-R.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=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 i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},B={parser:R,db:a,renderer:u,styles:p};export{B as diagram};
@@ -1 +1 @@
1
- import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-C4PgRjNY.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
1
+ import{Y as ln,$ as an,a0 as F,a1 as q,a2 as j,a3 as un,a4 as y,a5 as tn,a6 as J,a7 as _,a8 as rn,a9 as o,aa as on,ab as sn,ac as fn}from"./mermaid.core-D0VPssrU.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,z,a){var O=I-l,i=D-h,n=z-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function U(l,h,I,D,v,A,z){var a=l-I,O=h-D,i=(z?A:-A)/J(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,B=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*J(on(0,T*T*R-P*P)),Y=(P*g-m*S)/R,$=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=Y-B,e=$-t,r=w-B,C=p-t;return x*x+e*e>r*r+C*C&&(Y=w,$=p),{cx:Y,cy:$,x01:-n,y01:-d,x11:Y*(v/T-1),y11:$*(v/T-1)}}function hn(){var l=cn,h=yn,I=j(0),D=null,v=gn,A=dn,z=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-un,c=A.apply(this,arguments)-un,B=rn(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(B>tn-y)a.moveTo(s*F(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*F(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=B,S=B,Y=z.apply(this,arguments)/2,$=Y>y&&(D?+D.apply(this,arguments):J(u*u+s*s)),w=_(rn(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if($>y){var C=sn($/u*q(Y)),K=sn($/s*q(Y));(P-=C*2)>y?(C*=t?1:-1,R+=C,T-=C):(P=0,R=T=(f+c)/2),(S-=K*2)>y?(K*=t?1:-1,m+=K,g-=K):(S=0,m=g=(f+c)/2)}var G=s*F(m),H=s*q(m),L=u*F(T),M=u*q(T);if(w>y){var N=s*F(g),Q=s*q(g),V=u*F(R),W=u*q(R),E;if(B<an)if(E=pn(G,H,V,W,N,Q,L,M)){var X=G-E[0],Z=H-E[1],b=N-E[0],k=Q-E[1],nn=1/q(fn((X*b+Z*k)/(J(X*X+Z*Z)*J(b*b+k*k)))/2),en=J(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=U(V,W,G,H,s,x,t),r=U(N,Q,L,M,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(G,H),a.arc(0,0,s,m,g,!t)):a.moveTo(G,H),!(u>y)||!(P>y)?a.lineTo(L,M):p>y?(e=U(L,M,N,Q,u,-p,t),r=U(G,H,V,W,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-an/2;return[F(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:j(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:j(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:j(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:j(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:j(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:j(+n),i):A},i.padAngle=function(n){return arguments.length?(z=typeof n=="function"?n:j(+n),i):z},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};