whipped 0.8.1 → 0.9.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 (86) hide show
  1. package/dist/cli.js +1294 -259
  2. package/dist/mcp-server.js +150 -2
  3. package/dist/migrations/014_companion_sessions.sql +34 -0
  4. package/dist/migrations/015_companion_worktree_mode.sql +45 -0
  5. package/dist/migrations/016_companion_plans.sql +22 -0
  6. package/dist/migrations/017_companion_saved_plans.sql +23 -0
  7. package/dist/migrations/018_generalize_plan_session_ref.sql +29 -0
  8. package/dist/migrations/019_rename_plan_to_canvas.sql +20 -0
  9. package/dist/web-ui/assets/abnfDiagram-VRR7QNED-RwOyl_Kz.js +119 -0
  10. package/dist/web-ui/assets/arc-DmDBHE0H.js +131 -0
  11. package/dist/web-ui/assets/architectureDiagram-ZJ3FMSHR-RTwadm6J.js +8821 -0
  12. package/dist/web-ui/assets/blockDiagram-677ZJIJ3-Dvv5uMUE.js +3801 -0
  13. package/dist/web-ui/assets/c4Diagram-LMCZKHZV-bvr9R9cD.js +2479 -0
  14. package/dist/web-ui/assets/channel-BGhlETgZ.js +7 -0
  15. package/dist/web-ui/assets/chunk-2Q5K7J3B-BRq-Qbau.js +17 -0
  16. package/dist/web-ui/assets/chunk-32BRIVSS-Dy1BUZGx.js +116 -0
  17. package/dist/web-ui/assets/chunk-5VM5RSS4-DCUiIwIc.js +19 -0
  18. package/dist/web-ui/assets/chunk-EX3LRPZG-Cg_Vtzwz.js +1996 -0
  19. package/dist/web-ui/assets/chunk-JWPE2WC7-BW4n_ZhH.js +17 -0
  20. package/dist/web-ui/assets/chunk-MOJQB5TN-BykRa615.js +855 -0
  21. package/dist/web-ui/assets/chunk-RYQCIY6F-D4F7oV1d.js +476 -0
  22. package/dist/web-ui/assets/chunk-V7JOEXUC-DD4mm30h.js +2022 -0
  23. package/dist/web-ui/assets/chunk-VR4S4FIN-Fgvcluvk.js +25 -0
  24. package/dist/web-ui/assets/chunk-XXDRQBXY-C4FVmO5r.js +13 -0
  25. package/dist/web-ui/assets/classDiagram-OUVF2IWQ-DD4KIYF1.js +24 -0
  26. package/dist/web-ui/assets/classDiagram-v2-EOCWNBFH-DD4KIYF1.js +24 -0
  27. package/dist/web-ui/assets/cose-bilkent-JH36ORCC-ekFwvYt9.js +4943 -0
  28. package/dist/web-ui/assets/cynefin-VYW2F7L2-DTNV7gvQ.js +31527 -0
  29. package/dist/web-ui/assets/cynefinDiagram-TSTJHNR4-koYialeC.js +454 -0
  30. package/dist/web-ui/assets/cytoscape.esm-CaQ7Fomf.js +30346 -0
  31. package/dist/web-ui/assets/dagre-VKFMJZFB-Do43FV3o.js +526 -0
  32. package/dist/web-ui/assets/defaultLocale-B2RvLBDe.js +206 -0
  33. package/dist/web-ui/assets/diagram-FQU43EPY-D0STdny6.js +636 -0
  34. package/dist/web-ui/assets/diagram-G47NLZAW-D9g6BdZT.js +858 -0
  35. package/dist/web-ui/assets/diagram-NH7WQ7WH-zLW6CAmi.js +212 -0
  36. package/dist/web-ui/assets/diagram-OA4YK3LP-CA5tvsYw.js +492 -0
  37. package/dist/web-ui/assets/diagram-WEI45ONY-CLmYUHR0.js +309 -0
  38. package/dist/web-ui/assets/ebnfDiagram-CCIWWBDH-KkHubBI6.js +139 -0
  39. package/dist/web-ui/assets/erDiagram-Q63AITRT-BJna2u1n.js +1238 -0
  40. package/dist/web-ui/assets/flowDiagram-23GEKE2U-DVJKalah.js +2353 -0
  41. package/dist/web-ui/assets/ganttDiagram-NO4QXBWP-D9HwNV4u.js +3733 -0
  42. package/dist/web-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  43. package/dist/web-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  44. package/dist/web-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  45. package/dist/web-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  46. package/dist/web-ui/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
  47. package/dist/web-ui/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
  48. package/dist/web-ui/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
  49. package/dist/web-ui/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
  50. package/dist/web-ui/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
  51. package/dist/web-ui/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
  52. package/dist/web-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  53. package/dist/web-ui/assets/gitGraphDiagram-IHSO6WYX-B7wnoO0J.js +1385 -0
  54. package/dist/web-ui/assets/graph-BMLV0goG.js +2042 -0
  55. package/dist/web-ui/assets/{index-CRXPsGTP.css → index-DPjATOCj.css} +800 -1207
  56. package/dist/web-ui/assets/{index-BMFVAmy4.js → index-DZ7I8r_C.js} +41392 -39594
  57. package/dist/web-ui/assets/infoDiagram-FWYZ7A6U-BY6XoiF8.js +32 -0
  58. package/dist/web-ui/assets/init-ZxktEp_H.js +16 -0
  59. package/dist/web-ui/assets/ishikawaDiagram-FXEZZL3T-BaZVnO8j.js +967 -0
  60. package/dist/web-ui/assets/journeyDiagram-5HDEW3XC-CUA6DUAQ.js +1256 -0
  61. package/dist/web-ui/assets/kanban-definition-HUTT4EX6-5W5tiWrd.js +1055 -0
  62. package/dist/web-ui/assets/katex-CqNtglxf.js +14499 -0
  63. package/dist/web-ui/assets/layout-BNmRhaUB.js +2359 -0
  64. package/dist/web-ui/assets/linear-CfvGIyDE.js +340 -0
  65. package/dist/web-ui/assets/map-BEO0Bu8q.js +298 -0
  66. package/dist/web-ui/assets/mermaid.core-BRk3IzY2.js +26639 -0
  67. package/dist/web-ui/assets/mindmap-definition-LN4V7U3C-2GmLg6ou.js +1183 -0
  68. package/dist/web-ui/assets/ordinal-DSZU4PqD.js +76 -0
  69. package/dist/web-ui/assets/pegDiagram-2B236MQR-gTEdrkJg.js +127 -0
  70. package/dist/web-ui/assets/pieDiagram-ENE6RG2P-CYXjIhqC.js +318 -0
  71. package/dist/web-ui/assets/quadrantDiagram-ABIIQ3AL-BStRZxwf.js +1341 -0
  72. package/dist/web-ui/assets/railroadDiagram-RFXS5EU6-btveDRG2.js +93 -0
  73. package/dist/web-ui/assets/requirementDiagram-TGXJPOKE-Cy_155rE.js +1205 -0
  74. package/dist/web-ui/assets/sankeyDiagram-HTMAVEWB-Chtvw3_G.js +1264 -0
  75. package/dist/web-ui/assets/sequenceDiagram-DBY2YBRQ-DDuMVEX1.js +4523 -0
  76. package/dist/web-ui/assets/sizeCapture-X5ZJPWSS-Bylf0o6J.js +64 -0
  77. package/dist/web-ui/assets/stateDiagram-2N3HPSRC-DIzLeR5G.js +453 -0
  78. package/dist/web-ui/assets/stateDiagram-v2-6OUMAXLB-zG_WjT1-.js +23 -0
  79. package/dist/web-ui/assets/swimlanes-5IMT3BWC-TKaCmVta.js +8575 -0
  80. package/dist/web-ui/assets/swimlanesDiagram-G3AALYLV-C5eB3qqS.js +21 -0
  81. package/dist/web-ui/assets/timeline-definition-FHXFAJF6-CC5Ujpcu.js +1606 -0
  82. package/dist/web-ui/assets/vennDiagram-L72KCM5P-DUSVXSYT.js +2523 -0
  83. package/dist/web-ui/assets/wardleyDiagram-EHGQE667-CoP9xn89.js +978 -0
  84. package/dist/web-ui/assets/xychartDiagram-FW5EYKEG-B9FqP_kk.js +1972 -0
  85. package/dist/web-ui/index.html +2 -2
  86. package/package.json +1 -1
@@ -33,7 +33,7 @@ function highestWorkflowLevel(workflow) {
33
33
  }
34
34
  return LEVEL_ORDER[bestIdx] ?? "medium";
35
35
  }
36
- var ASSISTANT_AGENT_PREFIX, runtimeAgentIdSchema, effortLevelSchema, agentModelChoiceSchema, workflowSlotTypeSchema, tierLevelSchema, LEVEL_ORDER, modelPairSchema, pairSelectionModeSchema, SLOT_TOOL_IDS, slotToolSchema, slotModelConfigSchema, cardModelConfigSchema, promptValueSchema, EMPTY_INLINE_PROMPT, workflowSlotSchema, DEFAULT_MODEL_PAIR, DEFAULT_SLOT_MODEL_FIELDS, workflowSchema, DEFAULT_WORKFLOW, DEFAULT_STORY_WORKFLOW, DEFAULT_GIT_INSTRUCTIONS, runtimeBoardColumnIdSchema, BOARD_COLUMNS, reviewActorSchema, reviewIssueSchema, reviewAttachmentSchema, runtimeReviewCommentSchema, runtimeActivityEntrySchema, runtimeTaskSessionStateSchema, runtimeTerminalSessionEntrySchema, runtimeCardPrioritySchema, cardTypeSchema, runtimePrMetaSchema, runtimeBoardCardSchema, runtimeBoardColumnSchema, runtimeBoardDataSchema, notificationSoundsConfigSchema, runtimeGlobalConfigSchema, runtimeGithubConfigSchema, runtimeWorktreeCopyEntrySchema, runtimeWorktreeSetupSchema, runtimeProjectSecretSchema, runtimeProjectConfigSchema, runtimeWorkspaceStateResponseSchema, runtimeWorkspaceStateSaveRequestSchema, runtimeVisualElementSchema, runtimeVisualCommentSchema, runtimeCardCreateRequestSchema, runtimeBulkCardImportItemSchema, runtimeBulkCardsCreateRequestSchema, runtimeCardMoveRequestSchema, runtimeCardUpdateRequestSchema, memoryScopeSchema, memoryTypeSchema, memorySourceTypeSchema, memoryStatusSchema, runtimeMemoryOriginAgentSchema, runtimeMemorySchema, recurringScheduleKindSchema, recurringScheduleSchema, recurringRunStatusSchema, recurringRunTriggerSchema, recurringAgentRunSchema, recurringAgentSchema, recurringAgentCreateRequestSchema, recurringAgentUpdateRequestSchema, projectFolderSchema, topLevelItemSchema, projectsLayoutSchema, runtimeProjectSchema;
36
+ var ASSISTANT_AGENT_PREFIX, runtimeAgentIdSchema, effortLevelSchema, agentModelChoiceSchema, workflowSlotTypeSchema, tierLevelSchema, LEVEL_ORDER, modelPairSchema, pairSelectionModeSchema, SLOT_TOOL_IDS, slotToolSchema, slotModelConfigSchema, cardModelConfigSchema, promptValueSchema, EMPTY_INLINE_PROMPT, workflowSlotSchema, DEFAULT_MODEL_PAIR, DEFAULT_SLOT_MODEL_FIELDS, workflowSchema, DEFAULT_WORKFLOW, DEFAULT_STORY_WORKFLOW, DEFAULT_GIT_INSTRUCTIONS, runtimeBoardColumnIdSchema, BOARD_COLUMNS, reviewActorSchema, reviewIssueSchema, reviewAttachmentSchema, runtimeReviewCommentSchema, runtimeActivityEntrySchema, runtimeTaskSessionStateSchema, runtimeTerminalSessionEntrySchema, runtimeCardPrioritySchema, cardTypeSchema, runtimePrMetaSchema, runtimeBoardCardSchema, runtimeBoardColumnSchema, runtimeBoardDataSchema, notificationSoundsConfigSchema, runtimeGlobalConfigSchema, runtimeGithubConfigSchema, runtimeWorktreeCopyEntrySchema, runtimeWorktreeSetupSchema, runtimeProjectSecretSchema, runtimeProjectConfigSchema, runtimeWorkspaceStateResponseSchema, runtimeWorkspaceStateSaveRequestSchema, runtimeVisualElementSchema, runtimeVisualCommentSchema, runtimeCardCreateRequestSchema, runtimeBulkCardImportItemSchema, runtimeBulkCardsCreateRequestSchema, runtimeCardMoveRequestSchema, runtimeCardUpdateRequestSchema, memoryScopeSchema, memoryTypeSchema, memorySourceTypeSchema, memoryStatusSchema, runtimeMemoryOriginAgentSchema, runtimeMemorySchema, recurringScheduleKindSchema, recurringScheduleSchema, recurringRunStatusSchema, recurringRunTriggerSchema, recurringAgentRunSchema, recurringAgentSchema, recurringAgentCreateRequestSchema, recurringAgentUpdateRequestSchema, companionSessionStatusSchema, companionSessionSchema, companionSessionCreateRequestSchema, choiceOptionSchema, REQUIRED_FIELD_DESCRIPTION, questionLeafInputSchema, questionInputSchema, canvasBlockSchema, canvasDocumentSchema, companionSavedCanvasSchema, projectFolderSchema, topLevelItemSchema, projectsLayoutSchema, runtimeProjectSchema;
37
37
  var init_api_contract = __esm({
38
38
  "src/core/api-contract.ts"() {
39
39
  "use strict";
@@ -594,6 +594,104 @@ Do NOT include:
594
594
  enabled: z.boolean().optional(),
595
595
  journal: z.string().optional()
596
596
  });
597
+ companionSessionStatusSchema = z.enum(["installing", "running", "stopped", "merged", "discarded"]);
598
+ companionSessionSchema = z.object({
599
+ id: z.string(),
600
+ name: z.string(),
601
+ useWorktree: z.boolean(),
602
+ baseRef: z.string(),
603
+ branchName: z.string().nullable(),
604
+ worktreePath: z.string().nullable(),
605
+ workflowId: z.string().nullable(),
606
+ seedPrompt: z.string().default(""),
607
+ agentId: runtimeAgentIdSchema,
608
+ model: z.string().nullable(),
609
+ effort: effortLevelSchema.nullable(),
610
+ status: companionSessionStatusSchema.default("stopped"),
611
+ savedCanvasId: z.string().nullable(),
612
+ createdAt: z.number(),
613
+ updatedAt: z.number()
614
+ });
615
+ companionSessionCreateRequestSchema = z.object({
616
+ name: z.string().optional(),
617
+ useWorktree: z.boolean().default(true),
618
+ baseRef: z.string().min(1),
619
+ branchName: z.string().optional(),
620
+ workflowId: z.string().optional(),
621
+ model: agentModelChoiceSchema.optional(),
622
+ savedCanvasId: z.string().optional()
623
+ });
624
+ choiceOptionSchema = z.object({
625
+ value: z.string(),
626
+ label: z.string(),
627
+ description: z.string().optional()
628
+ });
629
+ REQUIRED_FIELD_DESCRIPTION = 'Signal only \u2014 not enforced by the panel, the developer can send/approve without answering. If this comes back "(not answered)" and you still need it, ask again in your next canvas version.';
630
+ questionLeafInputSchema = z.discriminatedUnion("kind", [
631
+ z.object({
632
+ kind: z.literal("single_choice"),
633
+ name: z.string(),
634
+ label: z.string().optional(),
635
+ options: z.array(choiceOptionSchema),
636
+ allowOther: z.boolean().optional(),
637
+ required: z.boolean().optional().describe(REQUIRED_FIELD_DESCRIPTION)
638
+ }),
639
+ z.object({
640
+ kind: z.literal("multi_choice"),
641
+ name: z.string(),
642
+ label: z.string().optional(),
643
+ options: z.array(choiceOptionSchema),
644
+ allowOther: z.boolean().optional(),
645
+ required: z.boolean().optional().describe(REQUIRED_FIELD_DESCRIPTION)
646
+ }),
647
+ z.object({
648
+ kind: z.literal("text"),
649
+ name: z.string(),
650
+ label: z.string().optional(),
651
+ placeholder: z.string().optional(),
652
+ multiline: z.boolean().optional(),
653
+ required: z.boolean().optional().describe(REQUIRED_FIELD_DESCRIPTION)
654
+ })
655
+ ]);
656
+ questionInputSchema = z.discriminatedUnion("kind", [
657
+ ...questionLeafInputSchema.options,
658
+ z.object({ kind: z.literal("composite"), parts: z.array(questionLeafInputSchema) })
659
+ ]);
660
+ canvasBlockSchema = z.discriminatedUnion("type", [
661
+ z.object({ id: z.string(), type: z.literal("markdown"), body: z.string() }),
662
+ // Rendered via dangerouslySetInnerHTML, unsanitized — same trust boundary as
663
+ // the markdown block's rehype-raw pass-through (the agent is the user's own
664
+ // coding agent, not untrusted third-party input).
665
+ z.object({
666
+ id: z.string(),
667
+ type: z.literal("html"),
668
+ body: z.string().describe(
669
+ `Raw HTML rendered via dangerouslySetInnerHTML at runtime. Use this whenever the developer wants to see UI, layout, or visual design \u2014 a dashboard, a page structure, a component arrangement \u2014 since markdown can only describe that in prose while an actual html mockup shows it. It is NOT run through the app's build-time Tailwind compiler, so Tailwind utility classes (e.g. class="grid grid-cols-3 gap-4") produce no CSS and render unstyled \u2014 style the mockup with inline style="..." attributes, or a <style> block scoped to unique ids/classes you define within the same body.`
670
+ )
671
+ }),
672
+ z.object({
673
+ id: z.string(),
674
+ type: z.literal("diagram"),
675
+ format: z.literal("mermaid"),
676
+ source: z.string(),
677
+ caption: z.string().optional()
678
+ }),
679
+ z.object({ id: z.string(), type: z.literal("question"), prompt: z.string(), input: questionInputSchema })
680
+ ]);
681
+ canvasDocumentSchema = z.object({
682
+ version: z.number(),
683
+ createdAt: z.number(),
684
+ blocks: z.array(canvasBlockSchema)
685
+ });
686
+ companionSavedCanvasSchema = z.object({
687
+ id: z.string(),
688
+ workspaceId: z.string(),
689
+ title: z.string(),
690
+ blocks: z.array(canvasBlockSchema),
691
+ sourceSessionId: z.string().nullable(),
692
+ createdAt: z.number(),
693
+ updatedAt: z.number()
694
+ });
597
695
  projectFolderSchema = z.object({
598
696
  id: z.string(),
599
697
  name: z.string(),
@@ -1694,6 +1792,7 @@ function namedArg(flag) {
1694
1792
  }
1695
1793
  var mcpRole = namedArg("--role") ?? "task";
1696
1794
  var recurringAgentId = namedArg("--recurring-agent-id") ?? "";
1795
+ var companionSessionId = namedArg("--companion-session-id") ?? "";
1697
1796
  var apiToken = process.env.WHIPPED_API_TOKEN ?? "";
1698
1797
  var authHeaders = apiToken ? { "x-whipped-token": apiToken } : {};
1699
1798
  var ROUTES = {
@@ -1718,7 +1817,9 @@ var ROUTES = {
1718
1817
  "recurring.create": { method: "POST", path: () => "recurring-agents" },
1719
1818
  "recurring.update": { method: "PATCH", path: (i) => `recurring-agents/${i.id}` },
1720
1819
  "recurring.delete": { method: "DELETE", path: (i) => `recurring-agents/${i.id}` },
1721
- "recurring.setJournal": { method: "POST", path: (i) => `recurring-agents/${i.id}/journal` }
1820
+ "recurring.setJournal": { method: "POST", path: (i) => `recurring-agents/${i.id}/journal` },
1821
+ "companion.showCanvas": { method: "POST", path: (i) => `companion-sessions/${i.sessionId}/canvas` },
1822
+ "companion.saveCanvas": { method: "POST", path: (i) => `companion-sessions/${i.sessionId}/save-canvas` }
1722
1823
  };
1723
1824
  async function apiMutate(procedure, input) {
1724
1825
  const route = ROUTES[procedure];
@@ -1761,9 +1862,11 @@ var RECURRING_OBSERVER_TOOLS = /* @__PURE__ */ new Set([
1761
1862
  "update_journal",
1762
1863
  "disable_self"
1763
1864
  ]);
1865
+ var COMPANION_ALLOWED_TOOLS = /* @__PURE__ */ new Set(["kanban_get_board", "whipped_show_canvas", "whipped_save_canvas"]);
1764
1866
  var baseRegisterTool = server.registerTool;
1765
1867
  var registerTool = ((name, ...rest) => {
1766
1868
  if (mcpRole === "recurring" && !RECURRING_OBSERVER_TOOLS.has(name)) return void 0;
1869
+ if (mcpRole === "companion" && !COMPANION_ALLOWED_TOOLS.has(name)) return void 0;
1767
1870
  return baseRegisterTool.call(server, name, ...rest);
1768
1871
  });
1769
1872
  var attachmentInputSchema = z2.object({
@@ -2649,5 +2752,50 @@ if (mcpRole === "recurring" && recurringAgentId) {
2649
2752
  }
2650
2753
  );
2651
2754
  }
2755
+ var canvasSessionId = mcpRole === "companion" ? companionSessionId : mcpRole === "assistant" ? `${ASSISTANT_AGENT_PREFIX}${workspaceId}` : "";
2756
+ if (canvasSessionId) {
2757
+ registerTool(
2758
+ "whipped_show_canvas",
2759
+ {
2760
+ description: "Push structured, interactive content \u2014 a plan, a report, findings, or a set of questions \u2014 to the developer's canvas: markdown, raw HTML, mermaid diagrams, and interactive questions. Use markdown for reasoning, steps, and options; use an html block whenever the developer wants to see UI, layout, or visual design \u2014 a dashboard, a page structure, a component arrangement \u2014 since a real mockup shows it and markdown can only describe it in prose. HTML blocks are rendered unsanitized via dangerouslySetInnerHTML at runtime \u2014 NOT compiled by the app's build-time Tailwind setup, so Tailwind utility classes in that HTML produce no styling; style mockups with inline style attributes or a <style> block instead. Each call appends a new version; it does not overwrite the last one. Call this AT MOST ONCE per turn \u2014 never call it twice in a row before the developer has replied. If you're not happy with a version before they've responded, that's still one call: think it through and send the version you actually want, don't push a draft and then immediately push a fix. The developer's answers, comments, and notes come back as a normal follow-up chat message \u2014 there is no separate response channel.",
2761
+ inputSchema: {
2762
+ blocks: z2.array(canvasBlockSchema).describe("Ordered canvas blocks: markdown, html, diagram, or question")
2763
+ }
2764
+ },
2765
+ async ({ blocks }) => {
2766
+ try {
2767
+ await apiMutate("companion.showCanvas", { sessionId: canvasSessionId, workspaceId, blocks });
2768
+ return { content: [{ type: "text", text: "Canvas sent to the developer." }] };
2769
+ } catch (err) {
2770
+ return { content: [{ type: "text", text: `Failed to send canvas: ${err.message}` }] };
2771
+ }
2772
+ }
2773
+ );
2774
+ registerTool(
2775
+ "whipped_save_canvas",
2776
+ {
2777
+ description: "Consolidate everything proposed across this session's canvas versions into ONE final, coherent canvas and save it to the project's reusable canvas library, so it can seed future work later. If this session already has a saved canvas (resumed from one, or already saved once), this UPDATES that same canvas instead of creating a duplicate \u2014 call it again whenever you finish a meaningful chunk of work, describing what's done explicitly in the blocks, so a future resumption knows what's already handled and what's left.",
2778
+ inputSchema: {
2779
+ title: z2.string().describe("Short, descriptive title for the saved canvas"),
2780
+ blocks: z2.array(canvasBlockSchema).describe(
2781
+ "The final, consolidated canvas \u2014 merge every prior version's content into one coherent canvas, don't just resend the latest version verbatim"
2782
+ )
2783
+ }
2784
+ },
2785
+ async ({ title, blocks }) => {
2786
+ try {
2787
+ const saved = await apiMutate("companion.saveCanvas", {
2788
+ sessionId: canvasSessionId,
2789
+ workspaceId,
2790
+ title,
2791
+ blocks
2792
+ });
2793
+ return { content: [{ type: "text", text: `Canvas saved as "${saved.title}".` }] };
2794
+ } catch (err) {
2795
+ return { content: [{ type: "text", text: `Failed to save canvas: ${err.message}` }] };
2796
+ }
2797
+ }
2798
+ );
2799
+ }
2652
2800
  var transport = new StdioServerTransport();
2653
2801
  await server.connect(transport);
@@ -0,0 +1,34 @@
1
+ -- =====================================================================
2
+ -- 014 companion sessions
3
+ --
4
+ -- Synchronous, chat-driven coding sessions isolated in their own git worktree.
5
+ -- Unlike cards, these are not part of the kanban ticket lifecycle — no FK to
6
+ -- cards, no dependency graph, no workflow slot pipeline. `workflow_id` is a
7
+ -- soft (unenforced) reference: a workflow may be edited or deleted after a
8
+ -- session starts without affecting it, since `seed_prompt` already snapshots
9
+ -- the workflow's dev-slot prompt text at session-creation time.
10
+ --
11
+ -- No turn/message history table: like the assistant agent, a companion session
12
+ -- is a single persistent interactive terminal stream (keyed by this row's id),
13
+ -- backed by the daemon's in-memory session map + RuntimeStateHub's terminal
14
+ -- buffer — not by DB rows.
15
+ -- =====================================================================
16
+
17
+ CREATE TABLE companion_sessions (
18
+ id TEXT PRIMARY KEY,
19
+ workspace_id TEXT NOT NULL,
20
+ name TEXT NOT NULL,
21
+ base_ref TEXT NOT NULL,
22
+ branch_name TEXT NOT NULL,
23
+ worktree_path TEXT,
24
+ workflow_id TEXT,
25
+ seed_prompt TEXT NOT NULL DEFAULT '',
26
+ agent_id TEXT NOT NULL DEFAULT 'claude',
27
+ model TEXT,
28
+ effort TEXT,
29
+ status TEXT NOT NULL DEFAULT 'stopped' CHECK (status IN ('running', 'stopped', 'merged', 'discarded')),
30
+ created_at INTEGER NOT NULL,
31
+ updated_at INTEGER NOT NULL
32
+ );
33
+
34
+ CREATE INDEX idx_companion_sessions_workspace ON companion_sessions(workspace_id);
@@ -0,0 +1,45 @@
1
+ -- =====================================================================
2
+ -- 015 companion sessions: worktree vs main-repo mode
3
+ --
4
+ -- Adds use_worktree (1 = dedicated git worktree on branch_name branched from
5
+ -- base_ref, as before; 0 = work directly in the main repo checkout — no
6
+ -- worktree, no new branch) and widens the status CHECK with 'installing' (the
7
+ -- worktree-setup install command now runs before the agent spawns). SQLite
8
+ -- can't alter a column/CHECK in place, so the table is rebuilt (as in 013).
9
+ -- Existing rows all predate this column and were all worktree sessions, so
10
+ -- they backfill use_worktree = 1 and branch_name is left as-is (still NOT
11
+ -- semantically required to be non-null going forward, hence dropping NOT NULL).
12
+ -- =====================================================================
13
+
14
+ CREATE TABLE companion_sessions_new (
15
+ id TEXT PRIMARY KEY,
16
+ workspace_id TEXT NOT NULL,
17
+ name TEXT NOT NULL,
18
+ use_worktree INTEGER NOT NULL DEFAULT 1,
19
+ base_ref TEXT NOT NULL,
20
+ branch_name TEXT,
21
+ worktree_path TEXT,
22
+ workflow_id TEXT,
23
+ seed_prompt TEXT NOT NULL DEFAULT '',
24
+ agent_id TEXT NOT NULL DEFAULT 'claude',
25
+ model TEXT,
26
+ effort TEXT,
27
+ status TEXT NOT NULL DEFAULT 'stopped'
28
+ CHECK (status IN ('installing', 'running', 'stopped', 'merged', 'discarded')),
29
+ created_at INTEGER NOT NULL,
30
+ updated_at INTEGER NOT NULL
31
+ );
32
+
33
+ INSERT INTO companion_sessions_new (
34
+ id, workspace_id, name, use_worktree, base_ref, branch_name, worktree_path, workflow_id,
35
+ seed_prompt, agent_id, model, effort, status, created_at, updated_at
36
+ )
37
+ SELECT
38
+ id, workspace_id, name, 1, base_ref, branch_name, worktree_path, workflow_id,
39
+ seed_prompt, agent_id, model, effort, status, created_at, updated_at
40
+ FROM companion_sessions;
41
+
42
+ DROP INDEX IF EXISTS idx_companion_sessions_workspace;
43
+ DROP TABLE companion_sessions;
44
+ ALTER TABLE companion_sessions_new RENAME TO companion_sessions;
45
+ CREATE INDEX idx_companion_sessions_workspace ON companion_sessions(workspace_id);
@@ -0,0 +1,22 @@
1
+ -- =====================================================================
2
+ -- 016 companion plans
3
+ --
4
+ -- Structured plans a companion agent pushes via the companion_show_plan MCP
5
+ -- tool — markdown, mermaid diagrams, and interactive question blocks, stored
6
+ -- as JSON. Versioned and append-only: each push is a new row, never an
7
+ -- overwrite, so the panel can show a version history. The developer's
8
+ -- answers/comments are composed client-side into one message and typed into
9
+ -- the agent's terminal — never persisted here or anywhere else.
10
+ -- =====================================================================
11
+
12
+ CREATE TABLE companion_plans (
13
+ id TEXT PRIMARY KEY,
14
+ session_id TEXT NOT NULL,
15
+ workspace_id TEXT NOT NULL,
16
+ version INTEGER NOT NULL,
17
+ blocks_json TEXT NOT NULL,
18
+ created_at INTEGER NOT NULL,
19
+ FOREIGN KEY (session_id) REFERENCES companion_sessions(id) ON DELETE CASCADE
20
+ );
21
+
22
+ CREATE INDEX idx_companion_plans_session ON companion_plans(session_id, version DESC);
@@ -0,0 +1,23 @@
1
+ -- =====================================================================
2
+ -- 017 companion saved plans
3
+ --
4
+ -- companion_saved_plans — workspace-level plan library. A session's version
5
+ -- history (companion_plans) is consolidated into one
6
+ -- row here when the agent calls companion_save_plan.
7
+ -- companion_sessions.saved_plan_id — soft link to the row a session's saves
8
+ -- should update in place, and/or the plan it resumed
9
+ -- from. Nullable, no FK (same convention as workflow_id).
10
+ -- =====================================================================
11
+
12
+ CREATE TABLE companion_saved_plans (
13
+ id TEXT PRIMARY KEY,
14
+ workspace_id TEXT NOT NULL,
15
+ title TEXT NOT NULL,
16
+ blocks_json TEXT NOT NULL,
17
+ source_session_id TEXT,
18
+ created_at INTEGER NOT NULL,
19
+ updated_at INTEGER NOT NULL
20
+ );
21
+ CREATE INDEX idx_companion_saved_plans_workspace ON companion_saved_plans(workspace_id);
22
+
23
+ ALTER TABLE companion_sessions ADD COLUMN saved_plan_id TEXT;
@@ -0,0 +1,29 @@
1
+ -- =====================================================================
2
+ -- 018 generalize companion_plans' session reference
3
+ --
4
+ -- companion_plans.session_id carried a hard FK to companion_sessions(id),
5
+ -- which the assistant agent's synthetic per-workspace session id
6
+ -- (__assistant__:<workspaceId>, see ASSISTANT_AGENT_PREFIX) can never satisfy
7
+ -- since it has no companion_sessions row. Rebuilding it as a soft reference —
8
+ -- same convention already used by companion_saved_plans.source_session_id —
9
+ -- lets the same table store plan versions for either kind of session.
10
+ --
11
+ -- SQLite can't drop a FK in place, so rebuild (as in 013_agent_id_add_mimo.sql).
12
+ -- =====================================================================
13
+
14
+ CREATE TABLE companion_plans_new (
15
+ id TEXT PRIMARY KEY,
16
+ session_id TEXT NOT NULL,
17
+ workspace_id TEXT NOT NULL,
18
+ version INTEGER NOT NULL,
19
+ blocks_json TEXT NOT NULL,
20
+ created_at INTEGER NOT NULL
21
+ );
22
+
23
+ INSERT INTO companion_plans_new (id, session_id, workspace_id, version, blocks_json, created_at)
24
+ SELECT id, session_id, workspace_id, version, blocks_json, created_at FROM companion_plans;
25
+
26
+ DROP INDEX IF EXISTS idx_companion_plans_session;
27
+ DROP TABLE companion_plans;
28
+ ALTER TABLE companion_plans_new RENAME TO companion_plans;
29
+ CREATE INDEX idx_companion_plans_session ON companion_plans(session_id, version DESC);
@@ -0,0 +1,20 @@
1
+ -- =====================================================================
2
+ -- 019 rename plan -> canvas
3
+ --
4
+ -- The plan panel is used for more than plans now (questions, reports,
5
+ -- findings, mockups — "plan" is one trigger phrase among several), so the
6
+ -- feature is renamed "canvas" throughout. SQLite supports RENAME TO /
7
+ -- RENAME COLUMN directly (no rebuild needed) and carries index definitions
8
+ -- forward automatically — only the index *names* need an explicit
9
+ -- drop+recreate to match.
10
+ -- =====================================================================
11
+
12
+ ALTER TABLE companion_plans RENAME TO companion_canvases;
13
+ DROP INDEX idx_companion_plans_session;
14
+ CREATE INDEX idx_companion_canvases_session ON companion_canvases(session_id, version DESC);
15
+
16
+ ALTER TABLE companion_saved_plans RENAME TO companion_saved_canvases;
17
+ DROP INDEX idx_companion_saved_plans_workspace;
18
+ CREATE INDEX idx_companion_saved_canvases_workspace ON companion_saved_canvases(workspace_id);
19
+
20
+ ALTER TABLE companion_sessions RENAME COLUMN saved_plan_id TO saved_canvas_id;
@@ -0,0 +1,119 @@
1
+ import { g as getStyles, r as renderer, d as db } from "./chunk-MOJQB5TN-BykRa615.js";
2
+ import { p as populateCommonDb } from "./chunk-JWPE2WC7-BW4n_ZhH.js";
3
+ import { _ as __name, l as log } from "./mermaid.core-BRk3IzY2.js";
4
+ import { M as MermaidParseError, b as createRailroadAbnfServices } from "./cynefin-VYW2F7L2-DTNV7gvQ.js";
5
+ import "./index-DZ7I8r_C.js";
6
+ var langiumParser = createRailroadAbnfServices().RailroadAbnf.parser.LangiumParser;
7
+ var transformAlternation = /* @__PURE__ */ __name((alt) => {
8
+ const alternatives = alt.alternatives.map(transformConcatenation);
9
+ if (alternatives.length === 1) {
10
+ return alternatives[0];
11
+ }
12
+ return {
13
+ type: "choice",
14
+ alternatives
15
+ };
16
+ }, "transformAlternation");
17
+ var transformConcatenation = /* @__PURE__ */ __name((concat) => {
18
+ const elements = concat.elements.map(transformElement);
19
+ if (elements.length === 1) {
20
+ return elements[0];
21
+ }
22
+ return {
23
+ type: "sequence",
24
+ elements
25
+ };
26
+ }, "transformConcatenation");
27
+ var parseRepeat = /* @__PURE__ */ __name((repeat) => {
28
+ if (repeat.includes("*")) {
29
+ const [minStr, maxStr] = repeat.split("*");
30
+ const min = minStr ? parseInt(minStr, 10) : 0;
31
+ const max = maxStr ? parseInt(maxStr, 10) : Infinity;
32
+ return { min, max };
33
+ }
34
+ const exact = parseInt(repeat, 10);
35
+ return { min: exact, max: exact };
36
+ }, "parseRepeat");
37
+ var transformElement = /* @__PURE__ */ __name((element) => {
38
+ const inner = transformPrimary(element.primary);
39
+ if (!element.repeat) {
40
+ return inner;
41
+ }
42
+ const { min, max } = parseRepeat(element.repeat);
43
+ if (min === 0 && max === 1) {
44
+ return { type: "optional", element: inner };
45
+ }
46
+ return {
47
+ type: "repetition",
48
+ element: inner,
49
+ min,
50
+ max
51
+ };
52
+ }, "transformElement");
53
+ var transformPrimary = /* @__PURE__ */ __name((primary) => {
54
+ switch (primary.$type) {
55
+ case "AbnfStringLiteral":
56
+ return {
57
+ type: "terminal",
58
+ value: primary.value
59
+ };
60
+ case "AbnfNumVal":
61
+ return {
62
+ type: "terminal",
63
+ value: primary.value
64
+ };
65
+ case "AbnfRuleName":
66
+ return {
67
+ type: "nonterminal",
68
+ name: primary.name
69
+ };
70
+ case "AbnfGroup":
71
+ return transformAlternation(primary.element);
72
+ case "AbnfOptionalGroup":
73
+ return {
74
+ type: "optional",
75
+ element: transformAlternation(primary.element)
76
+ };
77
+ default:
78
+ throw new Error(`Unsupported ABNF primary node: ${primary.$type}`);
79
+ }
80
+ }, "transformPrimary");
81
+ var transformRule = /* @__PURE__ */ __name((rule) => {
82
+ return {
83
+ name: rule.name,
84
+ definition: transformAlternation(rule.definition)
85
+ };
86
+ }, "transformRule");
87
+ var populateDb = /* @__PURE__ */ __name((ast) => {
88
+ populateCommonDb(ast, db);
89
+ if (ast.title) {
90
+ db.setTitle(ast.title);
91
+ }
92
+ ast.rules.map((rule) => db.addRule(transformRule(rule)));
93
+ }, "populateDb");
94
+ var parser = {
95
+ parse: /* @__PURE__ */ __name((input) => {
96
+ db.clear();
97
+ log.debug("[ABNF Parser] Starting Langium parse");
98
+ const result = langiumParser.parse(input);
99
+ if (result.lexerErrors.length > 0 || result.parserErrors.length > 0) {
100
+ throw new MermaidParseError(result);
101
+ }
102
+ const ast = result.value;
103
+ log.debug("[ABNF Parser] Parsed rules:", ast.rules.length);
104
+ populateDb(ast);
105
+ log.debug("[ABNF Parser] Parse complete");
106
+ }, "parse"),
107
+ parser: {
108
+ yy: db
109
+ }
110
+ };
111
+ var diagram = {
112
+ parser,
113
+ db,
114
+ renderer,
115
+ styles: getStyles
116
+ };
117
+ export {
118
+ diagram
119
+ };
@@ -0,0 +1,131 @@
1
+ import { Y as withPath, $ as pi, a0 as cos, a1 as sin, a2 as constant, a3 as halfPi, a4 as epsilon, a5 as tau, a6 as sqrt, a7 as min, a8 as abs, a9 as atan2, aa as max, ab as asin, ac as acos } from "./mermaid.core-BRk3IzY2.js";
2
+ function arcInnerRadius(d) {
3
+ return d.innerRadius;
4
+ }
5
+ function arcOuterRadius(d) {
6
+ return d.outerRadius;
7
+ }
8
+ function arcStartAngle(d) {
9
+ return d.startAngle;
10
+ }
11
+ function arcEndAngle(d) {
12
+ return d.endAngle;
13
+ }
14
+ function arcPadAngle(d) {
15
+ return d && d.padAngle;
16
+ }
17
+ function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
18
+ var x10 = x1 - x0, y10 = y1 - y0, x32 = x3 - x2, y32 = y3 - y2, t = y32 * x10 - x32 * y10;
19
+ if (t * t < epsilon) return;
20
+ t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;
21
+ return [x0 + t * x10, y0 + t * y10];
22
+ }
23
+ function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
24
+ var x01 = x0 - x1, y01 = y0 - y1, lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x11 = x0 + ox, y11 = y0 + oy, x10 = x1 + ox, y10 = y1 + oy, x00 = (x11 + x10) / 2, y00 = (y11 + y10) / 2, dx = x10 - x11, dy = y10 - y11, d2 = dx * dx + dy * dy, r = r1 - rc, D = x11 * y10 - x10 * y11, d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x00, dy0 = cy0 - y00, dx1 = cx1 - x00, dy1 = cy1 - y00;
25
+ if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
26
+ return {
27
+ cx: cx0,
28
+ cy: cy0,
29
+ x01: -ox,
30
+ y01: -oy,
31
+ x11: cx0 * (r1 / r - 1),
32
+ y11: cy0 * (r1 / r - 1)
33
+ };
34
+ }
35
+ function d3arc() {
36
+ var innerRadius = arcInnerRadius, outerRadius = arcOuterRadius, cornerRadius = constant(0), padRadius = null, startAngle = arcStartAngle, endAngle = arcEndAngle, padAngle = arcPadAngle, context = null, path = withPath(arc);
37
+ function arc() {
38
+ var buffer, r, r0 = +innerRadius.apply(this, arguments), r1 = +outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) - halfPi, a1 = endAngle.apply(this, arguments) - halfPi, da = abs(a1 - a0), cw = a1 > a0;
39
+ if (!context) context = buffer = path();
40
+ if (r1 < r0) r = r1, r1 = r0, r0 = r;
41
+ if (!(r1 > epsilon)) context.moveTo(0, 0);
42
+ else if (da > tau - epsilon) {
43
+ context.moveTo(r1 * cos(a0), r1 * sin(a0));
44
+ context.arc(0, 0, r1, a0, a1, !cw);
45
+ if (r0 > epsilon) {
46
+ context.moveTo(r0 * cos(a1), r0 * sin(a1));
47
+ context.arc(0, 0, r0, a1, a0, cw);
48
+ }
49
+ } else {
50
+ var a01 = a0, a11 = a1, a00 = a0, a10 = a1, da0 = da, da1 = da, ap = padAngle.apply(this, arguments) / 2, rp = ap > epsilon && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)), rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), rc0 = rc, rc1 = rc, t0, t1;
51
+ if (rp > epsilon) {
52
+ var p0 = asin(rp / r0 * sin(ap)), p1 = asin(rp / r1 * sin(ap));
53
+ if ((da0 -= p0 * 2) > epsilon) p0 *= cw ? 1 : -1, a00 += p0, a10 -= p0;
54
+ else da0 = 0, a00 = a10 = (a0 + a1) / 2;
55
+ if ((da1 -= p1 * 2) > epsilon) p1 *= cw ? 1 : -1, a01 += p1, a11 -= p1;
56
+ else da1 = 0, a01 = a11 = (a0 + a1) / 2;
57
+ }
58
+ var x01 = r1 * cos(a01), y01 = r1 * sin(a01), x10 = r0 * cos(a10), y10 = r0 * sin(a10);
59
+ if (rc > epsilon) {
60
+ var x11 = r1 * cos(a11), y11 = r1 * sin(a11), x00 = r0 * cos(a00), y00 = r0 * sin(a00), oc;
61
+ if (da < pi) {
62
+ if (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10)) {
63
+ var ax = x01 - oc[0], ay = y01 - oc[1], bx = x11 - oc[0], by = y11 - oc[1], kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2), lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
64
+ rc0 = min(rc, (r0 - lc) / (kc - 1));
65
+ rc1 = min(rc, (r1 - lc) / (kc + 1));
66
+ } else {
67
+ rc0 = rc1 = 0;
68
+ }
69
+ }
70
+ }
71
+ if (!(da1 > epsilon)) context.moveTo(x01, y01);
72
+ else if (rc1 > epsilon) {
73
+ t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
74
+ t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
75
+ context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
76
+ if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
77
+ else {
78
+ context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
79
+ context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
80
+ context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
81
+ }
82
+ } else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
83
+ if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);
84
+ else if (rc0 > epsilon) {
85
+ t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
86
+ t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
87
+ context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
88
+ if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
89
+ else {
90
+ context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
91
+ context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
92
+ context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
93
+ }
94
+ } else context.arc(0, 0, r0, a10, a00, cw);
95
+ }
96
+ context.closePath();
97
+ if (buffer) return context = null, buffer + "" || null;
98
+ }
99
+ arc.centroid = function() {
100
+ var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;
101
+ return [cos(a) * r, sin(a) * r];
102
+ };
103
+ arc.innerRadius = function(_) {
104
+ return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant(+_), arc) : innerRadius;
105
+ };
106
+ arc.outerRadius = function(_) {
107
+ return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant(+_), arc) : outerRadius;
108
+ };
109
+ arc.cornerRadius = function(_) {
110
+ return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant(+_), arc) : cornerRadius;
111
+ };
112
+ arc.padRadius = function(_) {
113
+ return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant(+_), arc) : padRadius;
114
+ };
115
+ arc.startAngle = function(_) {
116
+ return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), arc) : startAngle;
117
+ };
118
+ arc.endAngle = function(_) {
119
+ return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), arc) : endAngle;
120
+ };
121
+ arc.padAngle = function(_) {
122
+ return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), arc) : padAngle;
123
+ };
124
+ arc.context = function(_) {
125
+ return arguments.length ? (context = _ == null ? null : _, arc) : context;
126
+ };
127
+ return arc;
128
+ }
129
+ export {
130
+ d3arc as d
131
+ };