@yorz/cli 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/cli/index.js +235 -193
  2. package/dist/gui/assets/{abnfDiagram-VRR7QNED-pQ0yp01L.js → abnfDiagram-VRR7QNED-Bfi5VmJM.js} +1 -1
  3. package/dist/gui/assets/{arc-k5zxnVZT.js → arc-DW35HiMx.js} +1 -1
  4. package/dist/gui/assets/{architectureDiagram-ZJ3FMSHR-DX-yKkN9.js → architectureDiagram-ZJ3FMSHR-D6ol2HjT.js} +1 -1
  5. package/dist/gui/assets/{blockDiagram-677ZJIJ3-CMoP3PmZ.js → blockDiagram-677ZJIJ3-DimsChzs.js} +1 -1
  6. package/dist/gui/assets/{c4Diagram-LMCZKHZV-CFAjMeqQ.js → c4Diagram-LMCZKHZV-aQtOPEhO.js} +1 -1
  7. package/dist/gui/assets/channel-CYD2fo3z.js +1 -0
  8. package/dist/gui/assets/{chunk-2Q5K7J3B-CSYRtuuw.js → chunk-2Q5K7J3B-Bg7XMADz.js} +1 -1
  9. package/dist/gui/assets/{chunk-32BRIVSS-BRohWK3g.js → chunk-32BRIVSS-CJvj41Qg.js} +1 -1
  10. package/dist/gui/assets/{chunk-5VM5RSS4-BANnogAt.js → chunk-5VM5RSS4-B6iQkE6V.js} +1 -1
  11. package/dist/gui/assets/{chunk-EX3LRPZG-BcVKPAuP.js → chunk-EX3LRPZG-Bime3fML.js} +1 -1
  12. package/dist/gui/assets/{chunk-JWPE2WC7-D4KqJLpk.js → chunk-JWPE2WC7-B2d6pOPL.js} +1 -1
  13. package/dist/gui/assets/{chunk-MOJQB5TN-CDFJAykP.js → chunk-MOJQB5TN-C2BtAAqD.js} +1 -1
  14. package/dist/gui/assets/{chunk-RYQCIY6F-BJN0o293.js → chunk-RYQCIY6F-DvOYjxsw.js} +1 -1
  15. package/dist/gui/assets/{chunk-V7JOEXUC-B3m1VhnM.js → chunk-V7JOEXUC-HRF7SSaJ.js} +1 -1
  16. package/dist/gui/assets/{chunk-VR4S4FIN-BLYOZzRK.js → chunk-VR4S4FIN-oMVpMTS0.js} +1 -1
  17. package/dist/gui/assets/{chunk-XXDRQBXY-s69CKrwP.js → chunk-XXDRQBXY-Gx6kiEHQ.js} +1 -1
  18. package/dist/gui/assets/classDiagram-OUVF2IWQ-CFzbN5IF.js +1 -0
  19. package/dist/gui/assets/classDiagram-v2-EOCWNBFH-CFzbN5IF.js +1 -0
  20. package/dist/gui/assets/{cose-bilkent-JH36ORCC-BrNJSX1S.js → cose-bilkent-JH36ORCC-MoHCpl37.js} +1 -1
  21. package/dist/gui/assets/{cynefin-VYW2F7L2-i8qxCu_0.js → cynefin-VYW2F7L2-2tnFSmNB.js} +1 -1
  22. package/dist/gui/assets/{cynefinDiagram-TSTJHNR4-dpueKRs1.js → cynefinDiagram-TSTJHNR4-Cp7uDUjl.js} +1 -1
  23. package/dist/gui/assets/{dagre-VKFMJZFB-fqwQB8CS.js → dagre-VKFMJZFB-CTNuVp99.js} +1 -1
  24. package/dist/gui/assets/{diagram-FQU43EPY-B99SBDqa.js → diagram-FQU43EPY-Z9nTO-2q.js} +1 -1
  25. package/dist/gui/assets/{diagram-G47NLZAW-DF4Oz_Q6.js → diagram-G47NLZAW-D1H3xA3x.js} +1 -1
  26. package/dist/gui/assets/{diagram-NH7WQ7WH-BIaXJ_6B.js → diagram-NH7WQ7WH-BGpM31nf.js} +1 -1
  27. package/dist/gui/assets/{diagram-OA4YK3LP-CJ4_-IYz.js → diagram-OA4YK3LP-Bhn6yNbV.js} +1 -1
  28. package/dist/gui/assets/{diagram-WEI45ONY-LvUrzfuG.js → diagram-WEI45ONY-BDJ6eaig.js} +1 -1
  29. package/dist/gui/assets/{ebnfDiagram-CCIWWBDH-De5G_4vB.js → ebnfDiagram-CCIWWBDH-C8UHOTF4.js} +1 -1
  30. package/dist/gui/assets/{erDiagram-Q63AITRT-rYLQVUAr.js → erDiagram-Q63AITRT-BpoLARsO.js} +1 -1
  31. package/dist/gui/assets/{flowDiagram-23GEKE2U-CwDsoVsz.js → flowDiagram-23GEKE2U-DSODAemd.js} +1 -1
  32. package/dist/gui/assets/{ganttDiagram-NO4QXBWP-Bm1KWOcG.js → ganttDiagram-NO4QXBWP-Bv5JA_dU.js} +1 -1
  33. package/dist/gui/assets/{gitGraphDiagram-IHSO6WYX-s3jsEQWl.js → gitGraphDiagram-IHSO6WYX-CW7ObzYy.js} +1 -1
  34. package/dist/gui/assets/index-CAnHTFea.js +38 -0
  35. package/dist/gui/assets/{infoDiagram-FWYZ7A6U-xmq3a-E3.js → infoDiagram-FWYZ7A6U-uTM_03X9.js} +1 -1
  36. package/dist/gui/assets/{ishikawaDiagram-FXEZZL3T-CFPUA4LV.js → ishikawaDiagram-FXEZZL3T-BlbCXOf8.js} +1 -1
  37. package/dist/gui/assets/{journeyDiagram-5HDEW3XC-BOiMo2WC.js → journeyDiagram-5HDEW3XC-BwtfR_HU.js} +1 -1
  38. package/dist/gui/assets/{kanban-definition-HUTT4EX6-o_oz2FbJ.js → kanban-definition-HUTT4EX6-BXwvYv3u.js} +1 -1
  39. package/dist/gui/assets/{linear-D1YtFTY4.js → linear-C5c8PyN7.js} +1 -1
  40. package/dist/gui/assets/{mermaid.core-DQyDucFo.js → mermaid.core-Dbw2b69i.js} +4 -4
  41. package/dist/gui/assets/{mindmap-definition-LN4V7U3C-CX9Et0Qr.js → mindmap-definition-LN4V7U3C-9P8fXZBY.js} +1 -1
  42. package/dist/gui/assets/{pegDiagram-2B236MQR-DKoIr3v7.js → pegDiagram-2B236MQR-81kUPbkr.js} +1 -1
  43. package/dist/gui/assets/{pieDiagram-ENE6RG2P-BSJigzmR.js → pieDiagram-ENE6RG2P-BI7iwgtu.js} +1 -1
  44. package/dist/gui/assets/{quadrantDiagram-ABIIQ3AL-Bpmh7Mn0.js → quadrantDiagram-ABIIQ3AL-CSxA_Epi.js} +1 -1
  45. package/dist/gui/assets/{railroadDiagram-RFXS5EU6-DoaeONQd.js → railroadDiagram-RFXS5EU6-D4DnN2WS.js} +1 -1
  46. package/dist/gui/assets/{requirementDiagram-TGXJPOKE-B7GlOm4X.js → requirementDiagram-TGXJPOKE-DjNONyxQ.js} +1 -1
  47. package/dist/gui/assets/{sankeyDiagram-HTMAVEWB-B7IwnQiq.js → sankeyDiagram-HTMAVEWB-Di4S5cUR.js} +1 -1
  48. package/dist/gui/assets/{sequenceDiagram-DBY2YBRQ-Nwq2uhP9.js → sequenceDiagram-DBY2YBRQ-CLVwUzez.js} +1 -1
  49. package/dist/gui/assets/{sizeCapture-X5ZJPWSS-CCdTHNj_.js → sizeCapture-X5ZJPWSS-C5y0Ry_b.js} +1 -1
  50. package/dist/gui/assets/{stateDiagram-2N3HPSRC-CqxRfIAb.js → stateDiagram-2N3HPSRC-IdHsn6JH.js} +1 -1
  51. package/dist/gui/assets/stateDiagram-v2-6OUMAXLB-CJBs-brH.js +1 -0
  52. package/dist/gui/assets/{swimlanes-5IMT3BWC-Bn-R9jtG.js → swimlanes-5IMT3BWC-bDCHEODt.js} +2 -2
  53. package/dist/gui/assets/swimlanesDiagram-G3AALYLV-BpY4RNvM.js +8 -0
  54. package/dist/gui/assets/{timeline-definition-FHXFAJF6-BKXgnjEG.js → timeline-definition-FHXFAJF6-B6f6vq0E.js} +1 -1
  55. package/dist/gui/assets/{vennDiagram-L72KCM5P-Czw5UU3t.js → vennDiagram-L72KCM5P-AjYH8jaU.js} +1 -1
  56. package/dist/gui/assets/{wardleyDiagram-EHGQE667-BJS3BME3.js → wardleyDiagram-EHGQE667-NV3g14vB.js} +1 -1
  57. package/dist/gui/assets/{xychartDiagram-FW5EYKEG-DBt-6lUr.js → xychartDiagram-FW5EYKEG-D4yDWaI8.js} +1 -1
  58. package/dist/gui/index.html +1 -1
  59. package/package.json +1 -1
  60. package/dist/gui/assets/channel-sLqZREwh.js +0 -1
  61. package/dist/gui/assets/classDiagram-OUVF2IWQ-DpZPCbfk.js +0 -1
  62. package/dist/gui/assets/classDiagram-v2-EOCWNBFH-DpZPCbfk.js +0 -1
  63. package/dist/gui/assets/index-eECshTCa.js +0 -36
  64. package/dist/gui/assets/stateDiagram-v2-6OUMAXLB-CWQWNOHt.js +0 -1
  65. package/dist/gui/assets/swimlanesDiagram-G3AALYLV-D7kdlDFk.js +0 -8
package/dist/cli/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { homedir, platform } from "node:os";
3
3
  import { Command, Option } from "commander";
4
4
  import { stat, mkdir, writeFile, rename, readFile, rm, access, readdir, appendFile, copyFile } from "node:fs/promises";
5
- import { join, isAbsolute, resolve, basename as basename$1, dirname, extname, sep, relative, normalize } from "node:path";
5
+ import { join, isAbsolute, resolve, basename as basename$1, dirname, extname, relative, sep, normalize } from "node:path";
6
6
  import { createHash, randomUUID, randomBytes } from "node:crypto";
7
7
  import { existsSync, openSync, closeSync, statSync, readSync, mkdirSync, watch, createReadStream } from "node:fs";
8
8
  import { spawn, execFile, execFileSync } from "node:child_process";
@@ -23,7 +23,7 @@ import { createOpencode } from "@opencode-ai/sdk";
23
23
  import { createInterface as createInterface$1 } from "node:readline/promises";
24
24
  import MarkdownIt from "markdown-it";
25
25
  const name = "@yorz/cli";
26
- const version = "0.7.0";
26
+ const version = "0.7.1";
27
27
  const type = "module";
28
28
  const description = "";
29
29
  const bin = { "yorz": "./dist/cli/index.js" };
@@ -54,6 +54,93 @@ const pkg = {
54
54
  dependencies,
55
55
  devDependencies
56
56
  };
57
+ const HIDDEN_PROMPT_OPEN = "<!-- yorz:hidden -->";
58
+ const HIDDEN_PROMPT_CLOSE = "<!-- /yorz:hidden -->";
59
+ const SLASH_NAME_RE$1 = /^\/([\w-]+)(?:\s|$)/;
60
+ function matchCustomInstruction(prompt, instructions) {
61
+ const matched = SLASH_NAME_RE$1.exec(prompt.trim());
62
+ if (!matched) return null;
63
+ const name2 = matched[1];
64
+ return instructions.find((item) => item.name === name2) ?? null;
65
+ }
66
+ function wrapHiddenPrompt(hidden, original) {
67
+ const body = hidden.trim();
68
+ if (!body) return original;
69
+ return [HIDDEN_PROMPT_OPEN, body, HIDDEN_PROMPT_CLOSE, original].join("\n");
70
+ }
71
+ function appendHiddenPrompt(original, hidden) {
72
+ const body = hidden.trim();
73
+ if (!body) return original;
74
+ return [original, "", HIDDEN_PROMPT_OPEN, body, HIDDEN_PROMPT_CLOSE].join("\n");
75
+ }
76
+ function normalizeCustomInstructions(value) {
77
+ if (!Array.isArray(value)) return [];
78
+ const out = [];
79
+ const seen = /* @__PURE__ */ new Set();
80
+ for (const item of value) {
81
+ if (!item || typeof item !== "object") continue;
82
+ const obj = item;
83
+ const id = typeof obj.id === "string" ? obj.id.trim() : "";
84
+ const name2 = typeof obj.name === "string" ? obj.name.trim().replace(/^\/+/, "") : "";
85
+ if (!id || !name2 || seen.has(id) || !/^[\w-]+$/.test(name2)) continue;
86
+ seen.add(id);
87
+ out.push({
88
+ id,
89
+ name: name2,
90
+ description: typeof obj.description === "string" ? obj.description : "",
91
+ // Fall back to the pre-rename `systemPrompt` so existing configs keep
92
+ // working; the next save rewrites them under the new key.
93
+ hiddenPrompt: typeof obj.hiddenPrompt === "string" ? obj.hiddenPrompt : typeof obj.systemPrompt === "string" ? obj.systemPrompt : "",
94
+ prefill: typeof obj.prefill === "string" ? obj.prefill : "",
95
+ createdAt: typeof obj.createdAt === "number" && obj.createdAt > 0 ? obj.createdAt : 0
96
+ });
97
+ }
98
+ return out;
99
+ }
100
+ function parseCustomInstructions(value) {
101
+ if (value === void 0) return [];
102
+ if (!Array.isArray(value)) return { error: "customInstructions must be an array" };
103
+ const out = [];
104
+ const seen = /* @__PURE__ */ new Set();
105
+ for (const [index, item] of value.entries()) {
106
+ if (!item || typeof item !== "object") {
107
+ return { error: `customInstructions.${index} must be an object` };
108
+ }
109
+ const obj = item;
110
+ const id = typeof obj.id === "string" ? obj.id.trim() : "";
111
+ const name2 = typeof obj.name === "string" ? obj.name.trim().replace(/^\/+/, "") : "";
112
+ if (!id) return { error: `customInstructions.${index}.id required` };
113
+ if (!name2 || !/^[\w-]+$/.test(name2)) {
114
+ return {
115
+ error: `customInstructions.${index}.name must use letters, numbers, underscores, or hyphens`
116
+ };
117
+ }
118
+ if (seen.has(id)) return { error: `duplicate custom instruction id: ${id}` };
119
+ seen.add(id);
120
+ const description2 = obj.description;
121
+ const hiddenPrompt = obj.hiddenPrompt ?? obj.systemPrompt;
122
+ const prefill = obj.prefill;
123
+ const createdAt = obj.createdAt;
124
+ if (typeof description2 !== "string") {
125
+ return { error: `customInstructions.${index}.description must be a string` };
126
+ }
127
+ if (typeof hiddenPrompt !== "string") {
128
+ return { error: `customInstructions.${index}.hiddenPrompt must be a string` };
129
+ }
130
+ if (typeof prefill !== "string") {
131
+ return { error: `customInstructions.${index}.prefill must be a string` };
132
+ }
133
+ if (typeof createdAt !== "number" || createdAt <= 0) {
134
+ return { error: `customInstructions.${index}.createdAt must be a positive number` };
135
+ }
136
+ out.push({ id, name: name2, description: description2, hiddenPrompt, prefill, createdAt });
137
+ }
138
+ return out;
139
+ }
140
+ function mergeCustomInstructions(project, global) {
141
+ const names = new Set(project.map((item) => item.name));
142
+ return [...project, ...global.filter((item) => !names.has(item.name))];
143
+ }
57
144
  const CURRENT_VERSION$1 = 1;
58
145
  const DEFAULT_GLOBAL_AGENT = { defaultKind: "claude" };
59
146
  const DEFAULT_NOTIFICATIONS = {
@@ -233,30 +320,6 @@ function normalizeAppearance(value) {
233
320
  language: isLanguage(language) ? language : DEFAULT_APPEARANCE.language
234
321
  };
235
322
  }
236
- function normalizeCustomInstructions(value) {
237
- if (!Array.isArray(value)) return [];
238
- const out = [];
239
- const seen = /* @__PURE__ */ new Set();
240
- for (const item of value) {
241
- if (!item || typeof item !== "object") continue;
242
- const obj = item;
243
- const id = typeof obj.id === "string" ? obj.id.trim() : "";
244
- const name2 = typeof obj.name === "string" ? obj.name.trim().replace(/^\/+/, "") : "";
245
- if (!id || !name2 || seen.has(id) || !/^[\w-]+$/.test(name2)) continue;
246
- seen.add(id);
247
- out.push({
248
- id,
249
- name: name2,
250
- description: typeof obj.description === "string" ? obj.description : "",
251
- // Fall back to the pre-rename `systemPrompt` so existing configs keep
252
- // working; the next save rewrites them under the new key.
253
- hiddenPrompt: typeof obj.hiddenPrompt === "string" ? obj.hiddenPrompt : typeof obj.systemPrompt === "string" ? obj.systemPrompt : "",
254
- prefill: typeof obj.prefill === "string" ? obj.prefill : "",
255
- createdAt: typeof obj.createdAt === "number" && obj.createdAt > 0 ? obj.createdAt : 0
256
- });
257
- }
258
- return out;
259
- }
260
323
  function isThemeMode(value) {
261
324
  return value === "system" || value === "light" || value === "dark";
262
325
  }
@@ -1604,25 +1667,6 @@ function parseAnnotateBody(body) {
1604
1667
  if (note.length > 2e3) return { error: "note too long (max 2000)" };
1605
1668
  return { sectionPath, quote, note };
1606
1669
  }
1607
- const HIDDEN_PROMPT_OPEN = "<!-- yorz:hidden -->";
1608
- const HIDDEN_PROMPT_CLOSE = "<!-- /yorz:hidden -->";
1609
- const SLASH_NAME_RE$1 = /^\/([\w-]+)(?:\s|$)/;
1610
- function matchCustomInstruction(prompt, instructions) {
1611
- const matched = SLASH_NAME_RE$1.exec(prompt.trim());
1612
- if (!matched) return null;
1613
- const name2 = matched[1];
1614
- return instructions.find((item) => item.name === name2) ?? null;
1615
- }
1616
- function wrapHiddenPrompt(hidden, original) {
1617
- const body = hidden.trim();
1618
- if (!body) return original;
1619
- return [HIDDEN_PROMPT_OPEN, body, HIDDEN_PROMPT_CLOSE, original].join("\n");
1620
- }
1621
- function appendHiddenPrompt(original, hidden) {
1622
- const body = hidden.trim();
1623
- if (!body) return original;
1624
- return [original, "", HIDDEN_PROMPT_OPEN, body, HIDDEN_PROMPT_CLOSE].join("\n");
1625
- }
1626
1670
  const CHAT_DEBUG_DIR_REL = ".yorz/tmp/debug";
1627
1671
  const CHAT_DEBUG_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
1628
1672
  const CHAT_DEBUG_CLEANUP_INTERVAL_MS = 60 * 60 * 1e3;
@@ -1690,6 +1734,113 @@ function formatDebugTimestamp(date) {
1690
1734
  pad(date.getSeconds())
1691
1735
  ].join("");
1692
1736
  }
1737
+ const CURRENT_VERSION = 1;
1738
+ const DEFAULT_SPECS_DIR = ".yorz/specs";
1739
+ function defaultProjectConfig() {
1740
+ return {
1741
+ version: CURRENT_VERSION,
1742
+ agent: { kind: "inherit" },
1743
+ specsDir: DEFAULT_SPECS_DIR,
1744
+ commands: [],
1745
+ customInstructions: []
1746
+ };
1747
+ }
1748
+ function configPath(cwd) {
1749
+ return join(cwd, ".yorz", "config.json");
1750
+ }
1751
+ async function loadProjectConfig(cwd) {
1752
+ const fp = configPath(cwd);
1753
+ if (!existsSync(fp)) return defaultProjectConfig();
1754
+ let raw;
1755
+ try {
1756
+ raw = await readFile(fp, "utf8");
1757
+ } catch {
1758
+ return defaultProjectConfig();
1759
+ }
1760
+ if (!raw.trim()) return defaultProjectConfig();
1761
+ let parsed;
1762
+ try {
1763
+ parsed = JSON.parse(raw);
1764
+ } catch {
1765
+ return defaultProjectConfig();
1766
+ }
1767
+ return normalizeConfig(parsed);
1768
+ }
1769
+ async function saveProjectConfig(cwd, cfg) {
1770
+ const fp = configPath(cwd);
1771
+ await mkdir(dirname(fp), { recursive: true });
1772
+ const normalized = normalizeConfig(cfg);
1773
+ const body = `${JSON.stringify(normalized, null, 2)}
1774
+ `;
1775
+ const tmp = `${fp}.tmp-${process.pid}-${Date.now().toString(36)}`;
1776
+ await writeFile(tmp, body, "utf8");
1777
+ await rename(tmp, fp);
1778
+ }
1779
+ function resolveSpecsDir(cwd, cfg) {
1780
+ const root = resolve(cwd);
1781
+ const raw = (cfg.specsDir || DEFAULT_SPECS_DIR).trim() || DEFAULT_SPECS_DIR;
1782
+ const abs = isAbsolute(raw) ? resolve(raw) : resolve(root, raw);
1783
+ const rel = relative(root, abs);
1784
+ if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
1785
+ throw new Error(`specsDir must stay within the project root: ${raw}`);
1786
+ }
1787
+ return abs;
1788
+ }
1789
+ async function ensureSpecsDirExists(absSpecsDir) {
1790
+ await mkdir(absSpecsDir, { recursive: true });
1791
+ }
1792
+ function normalizeConfig(value) {
1793
+ if (!value || typeof value !== "object") return defaultProjectConfig();
1794
+ const obj = value;
1795
+ const agent = normalizeAgent(obj.agent);
1796
+ const specsDir = normalizeSpecsDir(obj.specsDir);
1797
+ const commands = normalizeCommands(obj.commands);
1798
+ const customInstructions = normalizeCustomInstructions(obj.customInstructions);
1799
+ return { version: CURRENT_VERSION, agent, specsDir, commands, customInstructions };
1800
+ }
1801
+ function normalizeCommands(value) {
1802
+ if (!Array.isArray(value)) return [];
1803
+ const out = [];
1804
+ const seen = /* @__PURE__ */ new Set();
1805
+ for (const item of value) {
1806
+ if (!item || typeof item !== "object") continue;
1807
+ const obj = item;
1808
+ const id = typeof obj.id === "string" ? obj.id.trim() : "";
1809
+ const name2 = typeof obj.name === "string" ? obj.name.trim() : "";
1810
+ const cli = typeof obj.cli === "string" ? obj.cli.trim() : "";
1811
+ if (!id || !name2 || !cli || seen.has(id)) continue;
1812
+ seen.add(id);
1813
+ const createdAt = typeof obj.createdAt === "number" && obj.createdAt > 0 ? obj.createdAt : 0;
1814
+ out.push({ id, name: name2, cli, createdAt });
1815
+ }
1816
+ return out;
1817
+ }
1818
+ function normalizeAgent(value) {
1819
+ if (typeof value === "string") {
1820
+ if (value === "opencode") return { kind: "opencode" };
1821
+ if (value === "codex") return { kind: "codex" };
1822
+ return { kind: "claude" };
1823
+ }
1824
+ if (!value || typeof value !== "object") return { kind: "claude" };
1825
+ const obj = value;
1826
+ const kind = obj.kind;
1827
+ if (kind === "inherit") return { kind: "inherit" };
1828
+ if (kind === "opencode") return { kind: "opencode" };
1829
+ if (kind === "codex") return { kind: "codex" };
1830
+ if (kind === "custom") {
1831
+ const cmd = typeof obj.cmd === "string" ? obj.cmd.trim() : "";
1832
+ if (!cmd) return { kind: "claude" };
1833
+ const args = Array.isArray(obj.args) ? obj.args.filter((a) => typeof a === "string") : [];
1834
+ return { kind: "custom", cmd, args };
1835
+ }
1836
+ return { kind: "claude" };
1837
+ }
1838
+ function normalizeSpecsDir(value) {
1839
+ if (typeof value !== "string") return DEFAULT_SPECS_DIR;
1840
+ const trimmed = value.trim();
1841
+ if (!trimmed) return DEFAULT_SPECS_DIR;
1842
+ return trimmed;
1843
+ }
1693
1844
  const SLASH_NAME_RE = /^\/([\w-]+)(?:\s|$)/;
1694
1845
  const SPEC_COMMAND_RE = /^\/yorz-spec(?:\s|$)/;
1695
1846
  function isSlashCommand(prompt) {
@@ -1739,6 +1890,13 @@ function resolveChatPrompt(prompt, instructions, opts = {}) {
1739
1890
  }
1740
1891
  return { prompt: buildUnknownCommandPrompt(original, hit), builtin: null };
1741
1892
  }
1893
+ async function loadCustomInstructions(projectPath) {
1894
+ const [project, global] = await Promise.all([
1895
+ loadProjectConfig(projectPath).then((cfg) => cfg.customInstructions).catch(() => []),
1896
+ loadGlobalConfig().then((cfg) => cfg.customInstructions).catch(() => [])
1897
+ ]);
1898
+ return mergeCustomInstructions(project, global);
1899
+ }
1742
1900
  const KINDS = ["claude", "codex", "opencode"];
1743
1901
  const DRAFT_ID_RE = /^[a-zA-Z0-9-]{1,64}$/;
1744
1902
  function buildChatPrompt(prompt, draftId, attachments) {
@@ -1827,7 +1985,7 @@ function createSessionsRoutes(resolveProject) {
1827
1985
  }
1828
1986
  const prompt = typeof body.prompt === "string" ? body.prompt.trim() : "";
1829
1987
  if (!prompt) return c.json({ error: "prompt required" }, 400);
1830
- const instructions = isSlashCommand(prompt) ? await loadGlobalConfig().then((cfg) => cfg.customInstructions).catch(() => []) : [];
1988
+ const instructions = isSlashCommand(prompt) ? await loadCustomInstructions(p.path) : [];
1831
1989
  const resolved = resolveChatPrompt(prompt, instructions, {
1832
1990
  specsDirRelative: p.specsDirRelative
1833
1991
  });
@@ -2018,7 +2176,7 @@ async function commit(cwd, opts) {
2018
2176
  const extraPaths = renamed.map((r) => r.renamedFrom);
2019
2177
  const allPaths = [...opts.paths, ...extraPaths];
2020
2178
  await runGit(cwd, ["add", "--", ...allPaths]);
2021
- await runGit(cwd, ["commit", "-m", message, "--", ...allPaths]);
2179
+ await runGit(cwd, ["commit", "-m", message]);
2022
2180
  const { stdout } = await runGit(cwd, ["rev-parse", "HEAD"]);
2023
2181
  return { commit: stdout.trim() };
2024
2182
  }
@@ -2593,111 +2751,6 @@ function createProjectRoutes(registry, worktreeManager) {
2593
2751
  });
2594
2752
  return app;
2595
2753
  }
2596
- const CURRENT_VERSION = 1;
2597
- const DEFAULT_SPECS_DIR = ".yorz/specs";
2598
- function defaultProjectConfig() {
2599
- return {
2600
- version: CURRENT_VERSION,
2601
- agent: { kind: "inherit" },
2602
- specsDir: DEFAULT_SPECS_DIR,
2603
- commands: []
2604
- };
2605
- }
2606
- function configPath(cwd) {
2607
- return join(cwd, ".yorz", "config.json");
2608
- }
2609
- async function loadProjectConfig(cwd) {
2610
- const fp = configPath(cwd);
2611
- if (!existsSync(fp)) return defaultProjectConfig();
2612
- let raw;
2613
- try {
2614
- raw = await readFile(fp, "utf8");
2615
- } catch {
2616
- return defaultProjectConfig();
2617
- }
2618
- if (!raw.trim()) return defaultProjectConfig();
2619
- let parsed;
2620
- try {
2621
- parsed = JSON.parse(raw);
2622
- } catch {
2623
- return defaultProjectConfig();
2624
- }
2625
- return normalizeConfig(parsed);
2626
- }
2627
- async function saveProjectConfig(cwd, cfg) {
2628
- const fp = configPath(cwd);
2629
- await mkdir(dirname(fp), { recursive: true });
2630
- const normalized = normalizeConfig(cfg);
2631
- const body = `${JSON.stringify(normalized, null, 2)}
2632
- `;
2633
- const tmp = `${fp}.tmp-${process.pid}-${Date.now().toString(36)}`;
2634
- await writeFile(tmp, body, "utf8");
2635
- await rename(tmp, fp);
2636
- }
2637
- function resolveSpecsDir(cwd, cfg) {
2638
- const root = resolve(cwd);
2639
- const raw = (cfg.specsDir || DEFAULT_SPECS_DIR).trim() || DEFAULT_SPECS_DIR;
2640
- const abs = isAbsolute(raw) ? resolve(raw) : resolve(root, raw);
2641
- const rel = relative(root, abs);
2642
- if (rel === "" || rel.startsWith("..") || isAbsolute(rel)) {
2643
- throw new Error(`specsDir must stay within the project root: ${raw}`);
2644
- }
2645
- return abs;
2646
- }
2647
- async function ensureSpecsDirExists(absSpecsDir) {
2648
- await mkdir(absSpecsDir, { recursive: true });
2649
- }
2650
- function normalizeConfig(value) {
2651
- if (!value || typeof value !== "object") return defaultProjectConfig();
2652
- const obj = value;
2653
- const agent = normalizeAgent(obj.agent);
2654
- const specsDir = normalizeSpecsDir(obj.specsDir);
2655
- const commands = normalizeCommands(obj.commands);
2656
- return { version: CURRENT_VERSION, agent, specsDir, commands };
2657
- }
2658
- function normalizeCommands(value) {
2659
- if (!Array.isArray(value)) return [];
2660
- const out = [];
2661
- const seen = /* @__PURE__ */ new Set();
2662
- for (const item of value) {
2663
- if (!item || typeof item !== "object") continue;
2664
- const obj = item;
2665
- const id = typeof obj.id === "string" ? obj.id.trim() : "";
2666
- const name2 = typeof obj.name === "string" ? obj.name.trim() : "";
2667
- const cli = typeof obj.cli === "string" ? obj.cli.trim() : "";
2668
- if (!id || !name2 || !cli || seen.has(id)) continue;
2669
- seen.add(id);
2670
- const createdAt = typeof obj.createdAt === "number" && obj.createdAt > 0 ? obj.createdAt : 0;
2671
- out.push({ id, name: name2, cli, createdAt });
2672
- }
2673
- return out;
2674
- }
2675
- function normalizeAgent(value) {
2676
- if (typeof value === "string") {
2677
- if (value === "opencode") return { kind: "opencode" };
2678
- if (value === "codex") return { kind: "codex" };
2679
- return { kind: "claude" };
2680
- }
2681
- if (!value || typeof value !== "object") return { kind: "claude" };
2682
- const obj = value;
2683
- const kind = obj.kind;
2684
- if (kind === "inherit") return { kind: "inherit" };
2685
- if (kind === "opencode") return { kind: "opencode" };
2686
- if (kind === "codex") return { kind: "codex" };
2687
- if (kind === "custom") {
2688
- const cmd = typeof obj.cmd === "string" ? obj.cmd.trim() : "";
2689
- if (!cmd) return { kind: "claude" };
2690
- const args = Array.isArray(obj.args) ? obj.args.filter((a) => typeof a === "string") : [];
2691
- return { kind: "custom", cmd, args };
2692
- }
2693
- return { kind: "claude" };
2694
- }
2695
- function normalizeSpecsDir(value) {
2696
- if (typeof value !== "string") return DEFAULT_SPECS_DIR;
2697
- const trimmed = value.trim();
2698
- if (!trimmed) return DEFAULT_SPECS_DIR;
2699
- return trimmed;
2700
- }
2701
2754
  function createProjectConfigRoutes(registry) {
2702
2755
  const app = new Hono();
2703
2756
  app.get("/projects/:projectId/config", async (c) => {
@@ -2724,7 +2777,8 @@ function createProjectConfigRoutes(registry) {
2724
2777
  version: 1,
2725
2778
  agent: parsed.agent,
2726
2779
  specsDir: parsed.specsDir,
2727
- commands: current.commands
2780
+ commands: current.commands,
2781
+ customInstructions: current.customInstructions
2728
2782
  };
2729
2783
  let absSpecsDir;
2730
2784
  try {
@@ -2745,6 +2799,34 @@ function createProjectConfigRoutes(registry) {
2745
2799
  await registry.reload(id);
2746
2800
  return c.json({ ok: true, config: cfg });
2747
2801
  });
2802
+ app.get("/projects/:projectId/custom-instructions", async (c) => {
2803
+ const id = c.req.param("projectId");
2804
+ const entry = await registry.findEntry(id);
2805
+ if (!entry) return c.json({ error: "project not found" }, 404);
2806
+ const cfg = await loadProjectConfig(entry.path);
2807
+ return c.json({ customInstructions: cfg.customInstructions });
2808
+ });
2809
+ app.put("/projects/:projectId/custom-instructions", async (c) => {
2810
+ const id = c.req.param("projectId");
2811
+ const entry = await registry.findEntry(id);
2812
+ if (!entry) return c.json({ error: "project not found" }, 404);
2813
+ let raw;
2814
+ try {
2815
+ raw = await c.req.json();
2816
+ } catch {
2817
+ return c.json({ error: "invalid JSON body" }, 400);
2818
+ }
2819
+ if (!raw || typeof raw !== "object") return c.json({ error: "body must be an object" }, 400);
2820
+ const parsed = parseCustomInstructions(raw.customInstructions);
2821
+ if ("error" in parsed) return c.json({ error: parsed.error }, 400);
2822
+ const current = await loadProjectConfig(entry.path);
2823
+ try {
2824
+ await saveProjectConfig(entry.path, { ...current, customInstructions: parsed });
2825
+ } catch (err) {
2826
+ return c.json({ error: err.message }, 500);
2827
+ }
2828
+ return c.json({ ok: true, customInstructions: parsed });
2829
+ });
2748
2830
  return app;
2749
2831
  }
2750
2832
  function parseBody$1(value) {
@@ -3062,46 +3144,6 @@ function parseAppearance(value) {
3062
3144
  if (!isLanguage(language)) return { error: "appearance.language must be zh-CN | en" };
3063
3145
  return { themeMode, themeName, language };
3064
3146
  }
3065
- function parseCustomInstructions(value) {
3066
- if (value === void 0) return [];
3067
- if (!Array.isArray(value)) return { error: "customInstructions must be an array" };
3068
- const out = [];
3069
- const seen = /* @__PURE__ */ new Set();
3070
- for (const [index, item] of value.entries()) {
3071
- if (!item || typeof item !== "object") {
3072
- return { error: `customInstructions.${index} must be an object` };
3073
- }
3074
- const obj = item;
3075
- const id = typeof obj.id === "string" ? obj.id.trim() : "";
3076
- const name2 = typeof obj.name === "string" ? obj.name.trim().replace(/^\/+/, "") : "";
3077
- if (!id) return { error: `customInstructions.${index}.id required` };
3078
- if (!name2 || !/^[\w-]+$/.test(name2)) {
3079
- return {
3080
- error: `customInstructions.${index}.name must use letters, numbers, underscores, or hyphens`
3081
- };
3082
- }
3083
- if (seen.has(id)) return { error: `duplicate custom instruction id: ${id}` };
3084
- seen.add(id);
3085
- const description2 = obj.description;
3086
- const hiddenPrompt = obj.hiddenPrompt ?? obj.systemPrompt;
3087
- const prefill = obj.prefill;
3088
- const createdAt = obj.createdAt;
3089
- if (typeof description2 !== "string") {
3090
- return { error: `customInstructions.${index}.description must be a string` };
3091
- }
3092
- if (typeof hiddenPrompt !== "string") {
3093
- return { error: `customInstructions.${index}.hiddenPrompt must be a string` };
3094
- }
3095
- if (typeof prefill !== "string") {
3096
- return { error: `customInstructions.${index}.prefill must be a string` };
3097
- }
3098
- if (typeof createdAt !== "number" || createdAt <= 0) {
3099
- return { error: `customInstructions.${index}.createdAt must be a positive number` };
3100
- }
3101
- out.push({ id, name: name2, description: description2, hiddenPrompt, prefill, createdAt });
3102
- }
3103
- return out;
3104
- }
3105
3147
  function createSpecDraftsRoutes(resolveProject) {
3106
3148
  const app = new Hono();
3107
3149
  const need = async (c) => {
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-CDFJAykP.js";import{p as f}from"./chunk-JWPE2WC7-D4KqJLpk.js";import{_ as n,l as o}from"./mermaid.core-DQyDucFo.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-i8qxCu_0.js";import"./index-eECshTCa.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-MOJQB5TN-C2BtAAqD.js";import{p as f}from"./chunk-JWPE2WC7-B2d6pOPL.js";import{_ as n,l as o}from"./mermaid.core-Dbw2b69i.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-2tnFSmNB.js";import"./index-CAnHTFea.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-DQyDucFo.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-Dbw2b69i.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};