@youweichen/pi-harness 1.0.0 → 1.1.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 (84) hide show
  1. package/LICENSE +1 -1
  2. package/dist/server/agent-service.js +87 -7
  3. package/dist/server/control-socket.js +1 -0
  4. package/dist/server/extensions-worker.js +3 -2
  5. package/dist/server/files-service.js +8 -16
  6. package/dist/server/index.js +7 -3
  7. package/dist/server/node-agent.js +262 -0
  8. package/dist/server/node-workbench.js +62 -1
  9. package/dist/server/plan/extension.js +4 -4
  10. package/dist/server/plan/state.js +11 -1
  11. package/dist/server/slash-commands.js +6 -0
  12. package/dist/server/wiki-routes.js +8 -1
  13. package/dist/server/wiki-service.js +13 -0
  14. package/package.json +1 -1
  15. package/web/dist/assets/NodeWorkbench-BiP2ktQP.js +3 -0
  16. package/web/dist/assets/{TerminalPanel-CWh6vw_N.js → TerminalPanel-CKaSUsN-.js} +1 -1
  17. package/web/dist/assets/{abnfDiagram-VCTEODGH-D5Ti0Kpa.js → abnfDiagram-VCTEODGH-CnwRJDRL.js} +1 -1
  18. package/web/dist/assets/{arc-DKJilLd6.js → arc-CG4Q7-W_.js} +1 -1
  19. package/web/dist/assets/{architectureDiagram-5GKGNRK7-Cf0w38g-.js → architectureDiagram-5GKGNRK7-BrGqX_Rg.js} +1 -1
  20. package/web/dist/assets/{blockDiagram-I7D4REHJ-BOTLWLIL.js → blockDiagram-I7D4REHJ-C2t0PjZT.js} +1 -1
  21. package/web/dist/assets/{c4Diagram-7LVT6UL2-CLCCoJs3.js → c4Diagram-7LVT6UL2-CadrcgGL.js} +1 -1
  22. package/web/dist/assets/channel-C27Jizb6.js +1 -0
  23. package/web/dist/assets/{chunk-2Q5K7J3B-BHjga2Ge.js → chunk-2Q5K7J3B-CC3V2ITZ.js} +1 -1
  24. package/web/dist/assets/{chunk-5VM5RSS4-CQJ5VfDZ.js → chunk-5VM5RSS4-DqKSbGmE.js} +1 -1
  25. package/web/dist/assets/{chunk-F27PBJKO-C67qoPJH.js → chunk-F27PBJKO-_CDr3JbY.js} +1 -1
  26. package/web/dist/assets/{chunk-IMKFNOWR-CgXXGwI8.js → chunk-IMKFNOWR-BIR4H4fX.js} +1 -1
  27. package/web/dist/assets/{chunk-JWPE2WC7-D0RPyByP.js → chunk-JWPE2WC7-CrsdBGXT.js} +1 -1
  28. package/web/dist/assets/{chunk-POPQ4Y6H-BeYC9s9x.js → chunk-POPQ4Y6H-C6q9kQmf.js} +1 -1
  29. package/web/dist/assets/{chunk-SVP7TREG-eQPl4UBQ.js → chunk-SVP7TREG-l2XXTr2v.js} +1 -1
  30. package/web/dist/assets/{chunk-TICWLB2K-DT73arPU.js → chunk-TICWLB2K-29I_mZgB.js} +1 -1
  31. package/web/dist/assets/{chunk-XXDRQBXY-B4FwQcP-.js → chunk-XXDRQBXY-htV9FBqi.js} +1 -1
  32. package/web/dist/assets/classDiagram-ZZMXUADV-DYTBrAEP.js +1 -0
  33. package/web/dist/assets/classDiagram-v2-VYDZK3BY-DYTBrAEP.js +1 -0
  34. package/web/dist/assets/{cose-bilkent-JH36ORCC-Bnn5nlQN.js → cose-bilkent-JH36ORCC-Cop-ihyx.js} +1 -1
  35. package/web/dist/assets/{cynefin-OW5HDTMX-CStWX9kE.js → cynefin-OW5HDTMX-IEk8qBRq.js} +1 -1
  36. package/web/dist/assets/{cynefinDiagram-5FMLGOSQ-BMVHC03f.js → cynefinDiagram-5FMLGOSQ-Bmzt6Qb5.js} +1 -1
  37. package/web/dist/assets/{dagre-GXQ25YYZ-ClSaO4ml.js → dagre-GXQ25YYZ-DiXTJYYU.js} +1 -1
  38. package/web/dist/assets/{diagram-S7CK7UJ4-C43LL08C.js → diagram-S7CK7UJ4-BT7CLuNk.js} +1 -1
  39. package/web/dist/assets/{diagram-UQ7AKVKN-BPVn_ySW.js → diagram-UQ7AKVKN-BZZ3nTCO.js} +1 -1
  40. package/web/dist/assets/{diagram-VSXAHHWV-C34FFhRi.js → diagram-VSXAHHWV-Dal8LeZh.js} +1 -1
  41. package/web/dist/assets/{diagram-VX7I27RA-BRk4bncf.js → diagram-VX7I27RA-D6V9FfNA.js} +1 -1
  42. package/web/dist/assets/{diagram-Z3DM3KII-O5hYPLEd.js → diagram-Z3DM3KII-KUAIcFiD.js} +1 -1
  43. package/web/dist/assets/{ebnfDiagram-PWID7BFC-DVGEBm99.js → ebnfDiagram-PWID7BFC-s0FEPZrV.js} +1 -1
  44. package/web/dist/assets/{erDiagram-RLTQ6QDP-M-BLpTEV.js → erDiagram-RLTQ6QDP-CiIQPFCD.js} +1 -1
  45. package/web/dist/assets/{flowDiagram-HODETNUW-BwdLopEx.js → flowDiagram-HODETNUW-CvG4MYWn.js} +1 -1
  46. package/web/dist/assets/{ganttDiagram-EL5Y4UJY-DYxx2ppA.js → ganttDiagram-EL5Y4UJY-CUf115ii.js} +1 -1
  47. package/web/dist/assets/{gitGraphDiagram-WWUBYQGX-DUU0wMYB.js → gitGraphDiagram-WWUBYQGX-o3K1r6fL.js} +1 -1
  48. package/web/dist/assets/index-C3vDFSEV.css +10 -0
  49. package/web/dist/assets/index-C5or_GAq.js +276 -0
  50. package/web/dist/assets/{infoDiagram-27XIBGKW-CFaW5C0C.js → infoDiagram-27XIBGKW-BxiBeQ8E.js} +1 -1
  51. package/web/dist/assets/{ishikawaDiagram-5VMMS53U--ENP1MTB.js → ishikawaDiagram-5VMMS53U-B1ONuCkH.js} +1 -1
  52. package/web/dist/assets/{journeyDiagram-3NMN7TZE-DgnAzSTj.js → journeyDiagram-3NMN7TZE-DwmuoXcX.js} +1 -1
  53. package/web/dist/assets/{kanban-definition-UXKFOSKX-_STZN1vU.js → kanban-definition-UXKFOSKX-pMKHubxH.js} +1 -1
  54. package/web/dist/assets/{layout-CkUClkXt.js → layout-CEwfjQR0.js} +1 -1
  55. package/web/dist/assets/{linear-sYHiUOxa.js → linear-D22Gdbt1.js} +1 -1
  56. package/web/dist/assets/{markdown-vNTCZJ6d.js → markdown-BhJ_LInD.js} +1 -1
  57. package/web/dist/assets/{mermaid.core-B8fKGWsc.js → mermaid.core-CO2nrD04.js} +5 -5
  58. package/web/dist/assets/{mindmap-definition-YA3MSWOX-DP0BYOEx.js → mindmap-definition-YA3MSWOX-9MQn9ZAp.js} +1 -1
  59. package/web/dist/assets/{pegDiagram-XKGWAZYB-DkWTmZre.js → pegDiagram-XKGWAZYB-Dy6fLjM-.js} +1 -1
  60. package/web/dist/assets/{pieDiagram-E7YTZNPT-DfZgMV4u.js → pieDiagram-E7YTZNPT-EDLez6nA.js} +1 -1
  61. package/web/dist/assets/{quadrantDiagram-AXDQQJYC-Djl4TT7q.js → quadrantDiagram-AXDQQJYC-Cgcd9mvy.js} +1 -1
  62. package/web/dist/assets/{railroadDiagram-O6MQD6OU-DbKF6zXn.js → railroadDiagram-O6MQD6OU-B4Td0tjj.js} +1 -1
  63. package/web/dist/assets/{react-BNj3n7jX.js → react-BddUxV-9.js} +1 -1
  64. package/web/dist/assets/{requirementDiagram-BXWQKSXE-idola5qb.js → requirementDiagram-BXWQKSXE-aF2QNZ78.js} +1 -1
  65. package/web/dist/assets/{sankeyDiagram-P5KCCOFB-KA0hQOle.js → sankeyDiagram-P5KCCOFB-DgTYwYMa.js} +1 -1
  66. package/web/dist/assets/{sequenceDiagram-WJ2MYXX4-BXSKvxzP.js → sequenceDiagram-WJ2MYXX4-EUcddWUc.js} +1 -1
  67. package/web/dist/assets/{sizeCapture-INFHLROL-C_Ewv3S5.js → sizeCapture-INFHLROL-CXHOv9Sx.js} +1 -1
  68. package/web/dist/assets/{stateDiagram-D77RDMKH-DIf5X8oo.js → stateDiagram-D77RDMKH-B-xlgfaK.js} +1 -1
  69. package/web/dist/assets/stateDiagram-v2-MP3YSRHH-kwAwAlWX.js +1 -0
  70. package/web/dist/assets/{swimlanes-42K2YHIH-Cx_Rc8M2.js → swimlanes-42K2YHIH-BtFBOCDh.js} +1 -1
  71. package/web/dist/assets/swimlanesDiagram-VR7AAH4N-D5j5Cj3S.js +8 -0
  72. package/web/dist/assets/{timeline-definition-24CTP7MA-BRrDhWVz.js → timeline-definition-24CTP7MA-CZlQY6pb.js} +1 -1
  73. package/web/dist/assets/{vennDiagram-4TSXK5OY-Ad6G0YwD.js → vennDiagram-4TSXK5OY-Cn61dJvL.js} +1 -1
  74. package/web/dist/assets/{wardleyDiagram-VM6X3IG4-X6-ENpSi.js → wardleyDiagram-VM6X3IG4-fiMNrWpr.js} +1 -1
  75. package/web/dist/assets/{xychartDiagram-S5SC5T6Z-DhegNS6d.js → xychartDiagram-S5SC5T6Z-CuzM_sof.js} +1 -1
  76. package/web/dist/index.html +4 -4
  77. package/web/dist/assets/NodeWorkbench-C4U1PldE.js +0 -3
  78. package/web/dist/assets/channel-D8Hd7T4P.js +0 -1
  79. package/web/dist/assets/classDiagram-ZZMXUADV-B_btgYRB.js +0 -1
  80. package/web/dist/assets/classDiagram-v2-VYDZK3BY-B_btgYRB.js +0 -1
  81. package/web/dist/assets/index-CI2KfVSr.css +0 -10
  82. package/web/dist/assets/index-DQcpggFU.js +0 -275
  83. package/web/dist/assets/stateDiagram-v2-MP3YSRHH-DYwe_2mB.js +0 -1
  84. package/web/dist/assets/swimlanesDiagram-VR7AAH4N-52Y8tgRV.js +0 -8
@@ -6,7 +6,7 @@ export const planParameters = Type.Object({
6
6
  planId: Type.Optional(string(128)), expectedRevision: Type.Optional(Type.Integer({ minimum: 1 })),
7
7
  title: string(80), status: Type.Union([Type.Literal("active"), Type.Literal("completed"), Type.Literal("cancelled"), Type.Literal("failed")]),
8
8
  steps: Type.Array(Type.Object({ id: string(64), title: string(80), detail: Type.Optional(string(500)) }), { minItems: 1, maxItems: 16, description: "Required for BOTH create and update, including completion. Send every step with its id, title and detail; never omit unchanged steps." }),
9
- currentStepId: Type.Union([string(64), Type.Null()]), completedStepIds: Type.Array(string(64), { maxItems: 16, uniqueItems: true }),
9
+ currentStepId: Type.Union([string(64), Type.Null()], { description: "Current step for active plans; terminal statuses clear it automatically." }), completedStepIds: Type.Array(string(64), { maxItems: 16, uniqueItems: true, description: "Completed step IDs. Explicit status completed completes all submitted steps; cancelled/failed preserve this list." }),
10
10
  completionCriteria: string(240), changeSummary: Type.Optional(string(240)),
11
11
  });
12
12
  export function restorePlanContext(messages, branch) {
@@ -32,7 +32,7 @@ export function restorePlanContext(messages, branch) {
32
32
  const failedCall = lastPlanResult?.role === "toolResult" && lastPlanResult.isError;
33
33
  if (visibleResult && visibleCall && !failedCall)
34
34
  return messages;
35
- const content = `${failedCall ? "Plan call failed; the saved plan below is unchanged. To correct the call, submit the full state including steps, even if unchanged or marking completion. Use the saved planId and expectedRevision. This reminder does not authorize continuing work.\n" : ""}Historical plan background, not authorization to continue. Judge relevance to the current request yourself. For related implementation, first update this plan with its current identity and revision. For unrelated multi-step work, create a new plan. Ordinary questions do not require a plan. Follow user/skill instructions and waiting requirements; this tool grants no extra permissions.\n${JSON.stringify({ action: "update", planId: snapshot.planId, expectedRevision: snapshot.revision, ...editableState(snapshot) })}`;
35
+ const content = `${failedCall ? "Plan call failed; the saved plan below is unchanged. To correct the call, submit the full state including steps, even if unchanged or marking completion. Use the saved planId and expectedRevision. This reminder does not authorize continuing work.\n" : ""}Historical plan background, not authorization to continue. Judge relevance to the current request yourself. For related, already authorized implementation, update this plan with its current identity and revision and continue without requesting separate plan approval. For unrelated multi-step work, create a new plan. Ordinary questions do not require a plan. Follow user/skill instructions and waiting requirements; this tool grants no extra permissions.\n${JSON.stringify({ action: "update", planId: snapshot.planId, expectedRevision: snapshot.revision, ...editableState(snapshot) })}`;
36
36
  const reminder = { role: "custom", customType: "pi-harness:plan-background", content, display: false, timestamp: 0 };
37
37
  const summary = messages.findLastIndex(message => message.role === "compactionSummary");
38
38
  const user = messages.findLastIndex(message => message.role === "user");
@@ -55,11 +55,11 @@ export function restorePlanContext(messages, branch) {
55
55
  }
56
56
  export const createPlanExtension = () => pi => {
57
57
  pi.registerTool({
58
- name: "plan", label: "Plan", description: "Create or update a complete, versioned implementation plan on this session branch. Every call requires title, status, steps, currentStepId, completedStepIds and completionCriteria, even when completing or only changing status. Updates also require the latest planId and expectedRevision. This is full replacement, not a partial patch. Ended plans require create.",
58
+ name: "plan", label: "Plan", description: "Create or update a complete, versioned implementation plan on this session branch. Every call requires title, status, steps, currentStepId, completedStepIds and completionCriteria, even when completing or only changing status. Updates also require the latest planId and expectedRevision. This is full replacement, not a partial patch. Explicit completed status completes all submitted steps and clears currentStepId; cancelled/failed only clear currentStepId. Ended plans require create.",
59
59
  exposure: "model-only", executionMode: "sequential", defaultActive: false,
60
60
  annotations: { readOnlyHint: true, openWorldHint: false },
61
61
  promptSnippet: "Record and update a multi-step implementation plan.",
62
- promptGuidelines: ["For multi-step implementation, create or update a relevant plan before execution and update the current step before starting it. Submit the full state each time. Wait for create to return its identity before updating. Follow user and skill instructions, including waiting; a plan does not grant authorization. Ordinary questions need no plan. When work is merged into another step or becomes unnecessary, update or remove the superseded step and explain the change instead of leaving a stale pending item. Never mark unfinished work completed. Mark completion explicitly; never infer it from a stopped run."],
62
+ promptGuidelines: ["For multi-step implementation, create or update a relevant plan before execution and update the current step before starting it. For already authorized work, proceed without requesting separate plan approval. Submit the full state each time. Wait for create to return its identity before updating. Follow user and skill instructions, including waiting; a plan does not grant authorization. Ordinary questions need no plan. When work is merged into another step or becomes unnecessary, update or remove the superseded step and explain the change instead of leaving a stale pending item. Never mark unfinished work completed. Mark completion explicitly; never infer it from a stopped run."],
63
63
  parameters: planParameters,
64
64
  async execute(_id, args, _signal, _update, ctx) {
65
65
  const snapshot = transition(args, latestPlan(ctx.sessionManager.getBranch())?.snapshot);
@@ -56,6 +56,16 @@ export function changesBetween(before, after) {
56
56
  changes.push({ kind: "status", status: after.status });
57
57
  return changes;
58
58
  }
59
+ /** Terminal command intent is atomic; persisted snapshots remain strictly validated. */
60
+ function commandState(value) {
61
+ if (!["completed", "cancelled", "failed"].includes(String(value.status)))
62
+ return editableState(value);
63
+ const state = editableState({ ...value, status: "active", currentStepId: null });
64
+ if (value.currentStepId !== null && (typeof value.currentStepId !== "string" || !state.steps.some(step => step.id === value.currentStepId)))
65
+ throw new Error("currentStepId must be null or an existing step ID");
66
+ return { ...state, status: value.status,
67
+ completedStepIds: value.status === "completed" ? state.steps.map(step => step.id) : state.completedStepIds };
68
+ }
59
69
  export function transition(value, current, newId = randomUUID) {
60
70
  if (!object(value) || !["create", "update"].includes(String(value.action)))
61
71
  throw new Error("action must be create or update");
@@ -64,7 +74,7 @@ export function transition(value, current, newId = randomUUID) {
64
74
  if (reason)
65
75
  throw new Error(`${reason}. ${!current || current.status !== "active" ? "Use create for a new plan." : "Use update with the current planId and expectedRevision and submit the full corrected plan."}\nCurrent editable state: ${current ? JSON.stringify({ action: current.status === "active" ? "update" : "create", planId: current.planId, expectedRevision: current.revision, ...editableState(current) }) : "none; use create"}`);
66
76
  }
67
- const state = editableState(value);
77
+ const state = commandState(value);
68
78
  const changes = changesBetween(value.action === "update" ? current : undefined, state);
69
79
  if (value.action === "create" && current?.status === "active")
70
80
  changes.unshift({ kind: "replaced", planId: current.planId, revision: current.revision, reason: "Replaced by a newly created plan" });
@@ -9,6 +9,7 @@ export const NATIVE_COMMANDS = [
9
9
  { name: "fork", description: "选择用户消息派生新会话", descriptionEn: "Choose a user message to fork" },
10
10
  { name: "name", description: "重命名当前会话", descriptionEn: "Rename this session", argumentHint: "<名称>", argumentHintEn: "<name>" },
11
11
  { name: "new", description: "新建会话,保留当前会话历史", descriptionEn: "Start a new session, keeping previous history" },
12
+ { name: "restart", description: "重启当前会话运行环境,保留历史", descriptionEn: "Restart this session runtime, keeping history" },
12
13
  { name: "model", description: "切换模型", descriptionEn: "Switch model", argumentHint: "[名称]", argumentHintEn: "[name]" },
13
14
  { name: "compact", description: "压缩上下文", descriptionEn: "Compact context", argumentHint: "[说明]", argumentHintEn: "[instructions]" },
14
15
  { name: "cwd", description: "切换工作目录", descriptionEn: "Switch workspace", argumentHint: "<路径>", argumentHintEn: "<path>" },
@@ -111,6 +112,11 @@ export class SlashCommandsService {
111
112
  case "new":
112
113
  await this.host.startNewSession();
113
114
  return true;
115
+ case "restart":
116
+ if (!this.host.restartSession)
117
+ throw new Error("Session restart unavailable");
118
+ await this.host.restartSession(context.conversationId);
119
+ return true;
114
120
  case "model": {
115
121
  if (!args) {
116
122
  const current = this.host.getSession().model;
@@ -96,6 +96,13 @@ export function installWikiRoutes(app, service, dataDir, originAllowed) {
96
96
  wiki.write(cwd, path, text, version);
97
97
  result = await wiki.documentContent(cwd, path);
98
98
  break;
99
+ case "create-file":
100
+ if (service().quiesceInfo().quiesced || session.isStreaming)
101
+ throw new Error("Wait for the current request to finish");
102
+ if (typeof path !== "string" || conversationId !== cs.conversationId)
103
+ throw new Error("Invalid create request");
104
+ result = wiki.createFile(cwd, path);
105
+ break;
99
106
  case "restore":
100
107
  if (service().quiesceInfo().quiesced || session.isStreaming)
101
108
  throw new Error("Wait for the current request to finish");
@@ -128,7 +135,7 @@ export function installWikiRoutes(app, service, dataDir, originAllowed) {
128
135
  }
129
136
  default: throw new Error("Unknown Wiki action");
130
137
  }
131
- if (cs.switchingWorkspace || cs.cwd !== cwd || (["prompt", "write", "restore"].includes(action) && !valid())) {
138
+ if (cs.switchingWorkspace || cs.cwd !== cwd || (["prompt", "write", "restore", "create-file"].includes(action) && !valid())) {
132
139
  res.status(409).json({ error: "Workspace changed" });
133
140
  return;
134
141
  }
@@ -447,6 +447,19 @@ export class WikiService {
447
447
  }
448
448
  }
449
449
  cancel(cwd) { this.active.delete(this.key(cwd)); }
450
+ createFile(cwd, path) {
451
+ if (this.busy(cwd))
452
+ throw new Error("Wait for the current Wiki request to finish");
453
+ // Accept portable relative paths; parent directories must already exist.
454
+ path = path.replaceAll("\\", "/");
455
+ if (!path || path.split("/").some(part => !part || part === "." || part === ".." || /[<>:"|?*\x00-\x1f]/.test(part) || /[. ]$/.test(part) || /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i.test(part)))
456
+ throw new Error("Invalid file name");
457
+ const absolute = wikiPath(cwd, path);
458
+ // Exclusive creation also rejects existing files and symlinks without truncating them.
459
+ writeFileSync(absolute, "", { flag: "wx" });
460
+ this.record(cwd, { files: new Map(), skipped: [] }, { files: new Map([[path, Buffer.alloc(0)]]), skipped: [] }, "user", path);
461
+ return { path };
462
+ }
450
463
  write(cwd, path, text, version) {
451
464
  if (this.busy(cwd))
452
465
  throw new Error("Wait for the current Wiki request to finish");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youweichen/pi-harness",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Web chat interface for the pi coding agent, powered by the pi SDK (@earendil-works/pi-coding-agent) — one-command run, Docker/systemd/launchd deployable",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -0,0 +1,3 @@
1
+ import{a as r,j as e,M as Pn,b as Dn}from"./markdown-BhJ_LInD.js";import{u as Ee,b as jn,T as fn,r as je}from"./index-C5or_GAq.js";import{D as En,o as $n}from"./xterm-D1D2FVe3.js";/* empty css */import"./react-BddUxV-9.js";const Mn=r.memo(function({text:w}){return e.jsx(Pn,{remarkPlugins:[Dn],components:{a:({href:t,children:s})=>/^https?:\/\//.test(t??"")?e.jsx("a",{href:t,target:"_blank",rel:"noreferrer",children:s}):e.jsx("span",{children:s}),img:({alt:t})=>e.jsx("span",{children:t})},children:w})});function Rn({nodeId:P,defaultDir:w,connected:t,agent:s,request:ne,draft:T,setDraft:$,consumedEditors:J}){var oe;const u=Ee(),[te,se]=r.useState(w),[C,y]=r.useState({}),[b,G]=r.useState(""),[M,q]=r.useState(""),[z,le]=r.useState("followUp"),D=r.useRef(null),W=r.useRef(!0),x=s==null?void 0:s.dialogs[0],A=Object.keys(C).length>0,Q=Object.values(C).some(d=>d.action==="agent_dialog");r.useEffect(()=>{q((x==null?void 0:x.prefill)??"")},[x==null?void 0:x.id]),r.useEffect(()=>{s!=null&&s.editorText&&J[P]!==s.editorText.id&&(J[P]=s.editorText.id,$(s.editorText.text))},[s==null?void 0:s.editorText]),r.useEffect(()=>{W.current&&D.current&&(D.current.scrollTop=D.current.scrollHeight)},[s==null?void 0:s.messages,s==null?void 0:s.streamingMessage,s==null?void 0:s.tools]),r.useEffect(()=>{const d=a=>{var E;const S=a.detail,N=S.requestId?C[S.requestId]:void 0;S.nodeId!==P||!N||(S.event==="failure"&&(G(String(((E=S.data)==null?void 0:E.message)??"")),y(k=>{const R={...k};return delete R[S.requestId],R})),S.event==="result"&&(N.text!==void 0&&$(k=>k===N.text?"":k),y(k=>{const R={...k};return delete R[S.requestId],R})))};return window.addEventListener("pi-node-event",d),()=>window.removeEventListener("pi-node-event",d)},[P,C]),r.useEffect(()=>{t||y({})},[t]);const H=(d,a,S)=>{G("");const N=ne(d,P,a,void 0,s==null?void 0:s.id);N?y(E=>({...E,[N]:{action:d,text:S}})):G(u("nodeAgentOffline"))},ae=()=>{!T.trim()||A||!t||(s==null?void 0:s.phase)!=="ready"||(W.current=!0,H("agent_prompt",{text:T,...s.running?{queue:z}:{}},T))},U=[...(s==null?void 0:s.messages)??[],...s!=null&&s.streamingMessage?[s.streamingMessage]:[]],ce=new Map(U.filter(d=>d.role==="toolResult").map(d=>[d.toolCallId,d])),fe=d=>e.jsxs("article",{className:`node-agent-message ${d.role}`,children:[e.jsx("small",{children:d.role==="user"?u("nodeAgentYou"):"pi"}),d.errorMessage&&e.jsx("p",{role:"alert",className:"node-agent-error",children:d.errorMessage}),d.content.map((a,S)=>{if(a.type==="text"&&"text"in a&&typeof a.text=="string")return e.jsx(Mn,{text:a.text},S);if(a.type==="thinking"&&"thinking"in a&&typeof a.thinking=="string")return e.jsxs("details",{children:[e.jsx("summary",{children:u("nodeAgentThinking")}),e.jsx("pre",{children:a.thinking})]},S);if(a.type==="toolCall"&&"id"in a&&"name"in a){const N=ce.get(String(a.id)),E=s==null?void 0:s.tools.find(k=>k.id===a.id);return e.jsxs("details",{className:"node-agent-tool",children:[e.jsxs("summary",{children:[e.jsx("code",{children:String(a.name)}),e.jsx("span",{children:u(N!=null&&N.isError||E!=null&&E.isError?"error":N||E&&!E.running?"done":s!=null&&s.running?"running":"toolQueued")})]}),e.jsx("pre",{children:String(a.argumentsText??"")}),N==null?void 0:N.content.map((k,R)=>"text"in k&&typeof k.text=="string"?e.jsx("pre",{children:k.text},R):null)]},S)}return a.type==="image"&&"dataUrl"in a&&typeof a.dataUrl=="string"&&a.dataUrl.startsWith("data:image/")?e.jsx("img",{src:a.dataUrl,alt:u("toolResultImage")},S):null})]},d.id);return e.jsxs("section",{className:"node-agent","aria-label":u("nodeAgentTitle"),children:[e.jsxs("header",{children:[e.jsx("strong",{children:u("nodeAgentTitle")}),e.jsx("span",{children:s!=null&&s.model?`${s.model.provider} / ${s.model.name}`:u("nodeAgentRemote")}),(s==null?void 0:s.phase)==="ready"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{disabled:A||s.running||!t,onClick:()=>H("agent_new"),children:u("nodeAgentNew")}),e.jsx("button",{disabled:!t,onClick:()=>H("agent_close"),children:u("nodeAgentClose")})]})]}),(!s||s.phase==="closed")&&e.jsxs("div",{className:"node-agent-setup",children:[e.jsx("p",{children:u("nodeAgentSetup")}),e.jsxs("label",{children:[u("nodeDefaultDir"),e.jsx("input",{value:te,onChange:d=>se(d.target.value)})]}),e.jsx("button",{disabled:!t||A,onClick:()=>H("agent_start",{cwd:te}),children:u(A?"nodeAgentStarting":"nodeAgentStart")}),e.jsx("p",{className:"node-muted",children:u("nodeAgentInstall")}),e.jsx("code",{children:"npm install -g @earendil-works/pi-coding-agent@1.0.4"})]}),(s==null?void 0:s.phase)==="starting"&&e.jsx("p",{role:"status",children:u("nodeAgentStarting")}),!t&&e.jsx("p",{role:"status",children:u("nodeAgentOffline")}),(b||(s==null?void 0:s.error))&&e.jsx("p",{role:"alert",className:"node-agent-error",children:b||(s==null?void 0:s.error)}),(s==null?void 0:s.notice)&&e.jsx("p",{role:"status",className:"node-muted",children:s.notice}),e.jsxs("div",{className:"node-agent-feed",ref:D,onScroll:d=>{const a=d.currentTarget;W.current=a.scrollHeight-a.scrollTop-a.clientHeight<100},children:[U.filter(d=>d.role!=="toolResult"&&(d.errorMessage||d.content.some(a=>a.type==="toolCall"||a.type==="image"||"text"in a&&typeof a.text=="string"&&a.text.trim()||"thinking"in a&&typeof a.thinking=="string"&&a.thinking.trim()))).map(fe),(s==null?void 0:s.running)&&e.jsxs("p",{className:"node-agent-working",role:"status",children:[u("nodeAgentWorking"),s.tools.filter(d=>d.running).map(d=>e.jsx("code",{children:d.name},d.id))]})]}),x&&e.jsxs("form",{className:"node-agent-dialog",onSubmit:d=>{d.preventDefault(),H("agent_dialog",{id:x.id,value:M,confirmed:!0})},children:[e.jsx("strong",{children:x.title}),x.message&&e.jsx("p",{children:x.message}),x.method==="select"?e.jsxs("select",{"aria-label":x.title,required:!0,value:M,onChange:d=>q(d.target.value),children:[e.jsx("option",{value:"",disabled:!0,children:u("nodeAgentSelect")}),(oe=x.options)==null?void 0:oe.map(d=>e.jsx("option",{children:d},d))]}):x.method!=="confirm"&&e.jsx("textarea",{"aria-label":x.title,value:M,onChange:d=>q(d.target.value),rows:x.method==="editor"?6:2}),e.jsx("button",{disabled:Q||!t,type:"submit",children:u("confirm")}),e.jsx("button",{disabled:Q||!t,type:"button",onClick:()=>H("agent_dialog",{id:x.id,cancelled:!0}),children:u("cancel")})]}),(s==null?void 0:s.phase)==="ready"&&e.jsxs("form",{className:"node-agent-input",onSubmit:d=>{d.preventDefault(),ae()},children:[e.jsx("textarea",{"aria-label":u("nodeAgentPrompt"),placeholder:u("nodeAgentPrompt"),value:T,onChange:d=>$(d.target.value),rows:3,onKeyDown:d=>{d.key==="Enter"&&!d.shiftKey&&!d.nativeEvent.isComposing&&(d.preventDefault(),ae())}}),e.jsxs("div",{children:[e.jsxs("select",{"aria-label":u("nodeAgentModel"),value:s.model?JSON.stringify([s.model.provider,s.model.id]):"",disabled:s.running||A||!t,onChange:d=>{const[a,S]=JSON.parse(d.target.value);H("agent_model",{provider:a,modelId:S})},children:[e.jsx("option",{value:"",disabled:!0,children:u("nodeAgentModel")}),s.models.map(d=>e.jsxs("option",{value:JSON.stringify([d.provider,d.id]),children:[d.provider," / ",d.name]},`${d.provider}/${d.id}`))]}),s.running&&e.jsxs(e.Fragment,{children:[e.jsxs("select",{"aria-label":u("nodeAgentQueue"),value:z,onChange:d=>le(d.target.value),children:[e.jsx("option",{value:"followUp",children:u("nodeAgentFollowUp")}),e.jsx("option",{value:"steer",children:u("nodeAgentSteer")})]}),e.jsx("button",{type:"button",disabled:!t,onClick:()=>H("agent_abort"),children:u("stop")})]}),e.jsx("button",{type:"submit",disabled:!T.trim()||A||!t,children:u("nodeAgentSend")})]})]})]})}function Tn({nodeId:P,tab:w,active:t,send:s,initialOutput:ne}){const T=Ee(),$=r.useRef(null),J=r.useRef(w.closed);J.current=w.closed;const[u,te]=r.useState(""),[se,C]=r.useState("");return r.useEffect(()=>{if(!$.current)return;const y=getComputedStyle($.current),b=new En({theme:{...jn(),background:y.getPropertyValue("--node-terminal-bg").trim(),foreground:y.getPropertyValue("--node-terminal-fg").trim()},fontFamily:'"JetBrains Mono", Consolas, monospace',fontSize:13,scrollback:8e3,allowProposedApi:!0}),G=()=>{b.options.theme={...jn(),background:y.getPropertyValue("--node-terminal-bg").trim(),foreground:y.getPropertyValue("--node-terminal-fg").trim()}};window.addEventListener(fn,G);const M=new $n;b.loadAddon(M),b.open($.current),ne&&b.write(ne);const q=(x,A={})=>s({type:"node_request",action:x,requestId:je(),nodeId:P,terminalId:w.id,conversationId:w.conversationId,payload:A}),z=b.onData(x=>{J.current||q(x===""?"interrupt":"terminal_input",{data:x})}),le=b.onSelectionChange(()=>te(b.getSelection().slice(0,32e3))),D=x=>{var Q;const A=x.detail;A.nodeId!==P||A.terminalId!==w.id||A.event==="terminal_output"&&b.write(String(((Q=A.data)==null?void 0:Q.text)??""))};window.addEventListener("pi-node-event",D);const W=new ResizeObserver(()=>{var x;if(!(!((x=$.current)!=null&&x.clientWidth)||!$.current.clientHeight))try{M.fit(),J.current||q("terminal_resize",{cols:b.cols,rows:b.rows})}catch{}});return W.observe($.current),()=>{window.removeEventListener(fn,G),W.disconnect(),z.dispose(),le.dispose(),window.removeEventListener("pi-node-event",D),b.dispose()}},[P,w.id,w.conversationId,s]),e.jsxs("div",{className:"node-terminal-wrap",style:{display:t?"block":"none"},children:[e.jsx("div",{ref:$,className:"node-xterm"}),u&&e.jsxs("div",{className:"node-selection-menu",children:[e.jsx("button",{onClick:()=>void navigator.clipboard.writeText(u).then(()=>C(T("nodeCopied"))).catch(y=>C(String(y))),children:T("nodeCopy")}),se&&e.jsx("span",{role:"status",children:se})]})]})}const qn=()=>({name:"",group:"默认",host:"",port:22,username:"root",auth:"password",defaultDir:"/"});function Un({send:P,active:w}){var Be,Je,Ge,Ve;const t=Ee(),[s,ne]=r.useState([]),[T,$]=r.useState([]),[J,u]=r.useState(!1),[te,se]=r.useState(!1),[C,y]=r.useState(null),[b,G]=r.useState(""),[M,q]=r.useState(!1),[z,le]=r.useState(!1),[D,W]=r.useState("agent"),[x,A]=r.useState({}),Q=r.useRef({}),[H,ae]=r.useState({}),[U,ce]=r.useState("password"),[fe,oe]=r.useState(""),[d,a]=r.useState(null),[S,N]=r.useState(!0),[E,k]=r.useState(!1),[R,ge]=r.useState(!1),re=r.useRef(null),Y=r.useRef(new Set),$e=r.useRef(new Set),[Me,ve]=r.useState(""),[de,gn]=r.useState([]),[Se,vn]=r.useState({}),[Re,Sn]=r.useState(Date.now()),[K,yn]=r.useState({}),[Ie,ue]=r.useState({}),[c,ye]=r.useState(localStorage.getItem("pi-node-selected")??""),[bn,Te]=r.useState({}),[v,B]=r.useState(null),[be,F]=r.useState(""),[qe,he]=r.useState(""),[we,Ae]=r.useState("/"),[Ke,wn]=r.useState({}),[L,ke]=r.useState(null),Z=r.useRef(new Map),Fe=r.useRef(new Map),Le=r.useRef(new Map),me=r.useRef(null),j=r.useCallback((n,i,o,h,I)=>{const ie=je();return P({type:"node_request",requestId:ie,action:n,nodeId:i,terminalId:h,conversationId:I,payload:o})?ie:null},[P]);r.useEffect(()=>{if(!w||!M)return;const n=setInterval(()=>Sn(Date.now()),1e3);return()=>clearInterval(n)},[w,M]);const l=de.find(n=>n.id===c),pe=Ie[c]??[],g=pe.find(n=>n.id===bn[c])??pe.at(-1),V=de.find(n=>n.id===d),X=s.find(n=>n.id===(l==null?void 0:l.sourceId)),kn=((Be=Ke[c])==null?void 0:Be.path)===we?Ke[c].entries:[];r.useEffect(()=>{w&&(j("state"),j("source_detect"))},[w,j]),r.useEffect(()=>{l&&Ae(l.defaultDir)},[c,l==null?void 0:l.defaultDir]),r.useEffect(()=>{const n=i=>{var ie,_e,Pe,Ne,Xe,ze,Qe,Ye,Ze,en,nn,tn,sn,on,rn,dn,ln,an,cn,un,hn,mn,pn,xn;const o=i.detail,h=o.nodeId??"";if(o.event==="state"){const p=((ie=o.data)==null?void 0:ie.nodes)??[];gn(p),ae(m=>{var xe;const f=Object.fromEntries(Object.entries(m).map(([O,_])=>[O,{..._,phase:"closed",running:!1,dialogs:[]}]));for(const O of((xe=o.data)==null?void 0:xe.connections)??[])O.agent&&(f[O.nodeId]=O.agent);for(const O of Object.keys(f))p.some(_=>_.id===O)||delete f[O];return f}),vn(Object.fromEntries((((_e=o.data)==null?void 0:_e.connections)??[]).map(m=>[m.nodeId,m]))),ne(((Pe=o.data)==null?void 0:Pe.sources)??[]),yn(Object.fromEntries((((Ne=o.data)==null?void 0:Ne.connections)??[]).map(m=>[m.nodeId,m.status])));for(const m of((Xe=o.data)==null?void 0:Xe.connections)??[])for(const f of m.terminals)Z.current.set(`${m.nodeId}:${f.id}`,f.output??"");ue(m=>{var xe,O;const f={...m};for(const _ of((xe=o.data)==null?void 0:xe.connections)??[]){const ee=(m[_.nodeId]??[]).filter(De=>!_.terminals.some(_n=>_n.id===De.id)).map(De=>({...De,closed:!0}));f[_.nodeId]=[...ee,..._.terminals]}for(const _ of Object.keys(f))(((O=o.data)==null?void 0:O.connections)??[]).some(ee=>ee.nodeId===_)||(f[_]=f[_].map(ee=>({...ee,closed:!0})));for(const _ of Object.keys(f))p.some(ee=>ee.id===_)||delete f[_];return f});return}if(o.event==="agent_state"&&((ze=o.data)!=null&&ze.agent)){const p=o.data.agent;ae(m=>({...m,[h]:p}));return}if(o.event==="terminal_output"){const p=`${h}:${o.terminalId}`;Z.current.set(p,((Z.current.get(p)??"")+String(((Qe=o.data)==null?void 0:Qe.text)??"")).slice(-65536));return}if(o.event==="trust_required"){if(o.requestId&&$e.current.add(o.requestId),window.confirm(t("nodeTrust",{name:String(((Ye=o.data)==null?void 0:Ye.name)??""),host:String(((Ze=o.data)==null?void 0:Ze.host)??""),fingerprint:String(((en=o.data)==null?void 0:en.fingerprint)??"")}))){const p=re.current;(p==null?void 0:p.nodeId)===h?j("credential_test",h,{...p.payload,fingerprint:(nn=o.data)==null?void 0:nn.fingerprint}):j("trust",h,{fingerprint:(tn=o.data)==null?void 0:tn.fingerprint})}else Y.current.delete(h),re.current=null,ge(!1);return}if(o.event==="failure"&&String(((sn=o.data)==null?void 0:sn.action)??"").startsWith("agent_"))return;if(o.event==="failure"){o.requestId===me.current&&(me.current=null);const p=String(((on=o.data)==null?void 0:on.message)??"");o.requestId&&$e.current.delete(o.requestId)||(he(p),ge(!1),((rn=o.data)==null?void 0:rn.action)==="credential_test"&&(re.current=null),Y.current.delete(h));return}if(o.event==="terminal_busy"){ue(p=>({...p,[h]:(p[h]??[]).map(m=>{var f;return m.id===o.terminalId?{...m,busy:!!((f=o.data)!=null&&f.busy)}:m})}));return}if(o.event==="terminal_exit"){const p=`${h}:${o.terminalId}`;Z.current.set(p,(Z.current.get(p)??"")+`\r
2
+ [SSH 已断开]\r
3
+ `),ue(m=>({...m,[h]:(m[h]??[]).map(f=>f.id===o.terminalId?{...f,closed:!0}:f)}));return}if(o.event!=="result")return;const I=(dn=o.data)==null?void 0:dn.action;if(I==="source_detect"&&($(((ln=o.data)==null?void 0:ln.sources)??[]),se(!0)),I==="source_add"&&(y(null),u(!1)),I==="credential_test"&&(re.current=null,ge(!1),a(null),F(""),ve(t("nodeCredentialsSaved",{n:Number(((an=o.data)==null?void 0:an.count)??1)}))),(I==="connect"||I==="trust"||I==="credential_test")&&Y.current.has(h)&&(Y.current.delete(h),j("terminal_open",h,{},je()),q(!0)),I==="terminal_open"){const p={id:String((cn=o.data)==null?void 0:cn.terminalId),conversationId:String((un=o.data)==null?void 0:un.conversationId),busy:!1};ue(m=>({...m,[h]:(m[h]??[]).some(f=>f.id===p.id)?m[h]:[...m[h]??[],p]})),Te(m=>({...m,[h]:p.id}))}I==="list"&&o.requestId===Fe.current.get(h)&&wn(p=>{var m,f;return{...p,[h]:{path:String(((m=o.data)==null?void 0:m.path)??""),entries:((f=o.data)==null?void 0:f.entries)??[]}}}),I==="read"&&o.requestId===Le.current.get(h)&&ke({nodeId:h,path:String(((hn=o.data)==null?void 0:hn.path)??""),text:String(((mn=o.data)==null?void 0:mn.text)??"")}),I==="write"&&o.requestId===me.current&&(me.current=null,ke(p=>{var m;return(p==null?void 0:p.nodeId)===h&&p.path===((m=o.data)==null?void 0:m.path)?null:p})),I==="save"&&(B(null),F(""),(pn=o.data)!=null&&pn.id&&ye(String(o.data.id))),(I==="import_legacy"||I==="import")&&ve(t("nodeImported",{n:Number(((xn=o.data)==null?void 0:xn.count)??0)}))};return window.addEventListener("pi-node-event",n),()=>window.removeEventListener("pi-node-event",n)},[j,t]);const Ce=r.useMemo(()=>de.filter(n=>`${n.name} ${n.host} ${n.username}`.toLowerCase().includes(b.toLowerCase())),[de,b]),Cn=r.useMemo(()=>[...new Set(Ce.map(n=>n.group))],[Ce]),Oe=n=>{const i=j("list",c,{path:n},g==null?void 0:g.id,g==null?void 0:g.conversationId);i&&Fe.current.set(c,i)},Nn=n=>{const i=j("read",c,{path:n},g==null?void 0:g.id,g==null?void 0:g.conversationId);i&&Le.current.set(c,i)},In=()=>{!L||L.nodeId!==c||(me.current=j("write",L.nodeId,{path:L.path,text:L.text},g==null?void 0:g.id,g==null?void 0:g.conversationId))},He=n=>{var i;if(ye(n.id),he(""),n.auth==="password"&&!n.hasSecret||n.auth==="key"&&(!n.keyPath||(i=n.unsupported)!=null&&i.includes("key"))&&!n.localKeyPath){ce(n.auth==="key"?"key":"password"),oe(n.localKeyPath||n.keyPath||""),a(n.id),F(""),k(!1),Y.current.add(n.id);return}q(!0),u(!1),K[n.id]==="connected"?(Ie[n.id]??[]).some(o=>!o.closed)||j("terminal_open",n.id,{},je()):(Y.current.add(n.id),j("connect",n.id))},Ue=e.jsx("button",{onClick:()=>{B(qn()),F("")},"aria-label":t("nodeAdd"),children:"+"}),We=e.jsxs("label",{className:"node-secondary",children:[t("nodeImportJson"),e.jsx("input",{type:"file",accept:"application/json,.json",hidden:!0,onChange:async n=>{var o;const i=(o=n.target.files)==null?void 0:o[0];if(i){try{const h=JSON.parse(await i.text());j("import",void 0,{nodes:h.nodes})}catch{he(t("nodeInvalidJson"))}n.target.value=""}}})]}),An=e.jsxs("div",{className:"node-source-page",children:[e.jsx("div",{className:"node-eyebrow",children:t("nodeSources")}),e.jsx("h2",{children:t("nodeAdd")}),e.jsx("p",{className:"node-muted",children:t("nodeSourceIntro")}),te&&!T.length&&!s.length&&e.jsx("p",{className:"node-muted",children:t("nodeNoSources")}),[...s,...T.filter(n=>!s.some(i=>i.path===n.path))].map(n=>e.jsxs("section",{className:"node-source-card",children:[e.jsxs("header",{children:[e.jsx("span",{className:"node-source-icon",children:n.kind==="xshell"?"X":"~/"}),e.jsxs("div",{children:[e.jsx("strong",{children:n.kind==="xshell"?"Xshell 8":"SSH config"}),e.jsx("small",{children:t("nodeSyncInfo",{n:n.count??0,g:n.groups??0})})]})]}),e.jsx("code",{children:n.path}),e.jsxs("p",{children:["✓ ",t("nodeSyncFields")]}),e.jsxs("p",{className:"node-muted",children:["— ",t("nodeSyncPassword"),e.jsx("br",{}),"— ",t("nodeSyncUnsupported")]}),n.error&&e.jsx("p",{className:"node-error",role:"alert",children:n.error}),n.lastSync&&e.jsx("small",{children:t("nodeSyncTime",{time:new Date(n.lastSync).toLocaleString()})}),e.jsxs("div",{className:"node-actions",children:[n.id?e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:()=>j("source_sync",void 0,{id:n.id}),children:t("nodeSyncNow")}),e.jsx("button",{onClick:()=>j("source_toggle",void 0,{id:n.id,enabled:!n.enabled}),children:t(n.enabled?"nodeSyncPause":"nodeSyncResume")})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"node-primary",onClick:()=>j("source_add",void 0,{kind:n.kind,path:n.path,enabled:!0}),children:t("nodeSyncKeep")}),e.jsx("button",{onClick:()=>j("source_add",void 0,{kind:n.kind,path:n.path,enabled:!1}),children:t("nodeImportOnce")})]}),e.jsx("button",{onClick:()=>y({kind:n.kind??"xshell",path:n.path??""}),children:t("nodeChangePath")})]})]},n.path)),e.jsxs("div",{className:"node-actions",children:[e.jsx("button",{onClick:()=>y({kind:"xshell",path:""}),children:t("nodeAddSource")}),e.jsx("button",{onClick:()=>j("source_detect"),children:t("nodeDetect")}),Ue,We]})]});return e.jsxs("div",{className:`node-workbench ${D==="agent"?"node-agent-open":""} ${M&&l?"node-workspace-open":""}`,children:[qe&&e.jsxs("div",{className:"node-global-message node-error",role:"alert",children:[qe,e.jsx("button",{"aria-label":t("close"),onClick:()=>he(""),children:"×"})]}),Me&&e.jsxs("div",{className:"node-global-message node-notice",role:"status",children:[Me,e.jsx("button",{"aria-label":t("close"),onClick:()=>ve(""),children:"×"})]}),!M&&e.jsxs("aside",{className:"node-sidebar",children:[e.jsxs("header",{children:[e.jsx("strong",{children:t("nodeWorkbench")}),Ue]}),e.jsx("input",{"aria-label":t("nodeSearch"),placeholder:t("nodeSearch"),value:b,onChange:n=>G(n.target.value)}),s.map(n=>e.jsxs("button",{className:"node-source-status",onClick:()=>u(!0),children:[e.jsx("span",{className:`node-dot ${n.error?"connecting":n.enabled?"connected":"offline"}`}),n.kind==="xshell"?"Xshell 8":"SSH config",e.jsx("small",{children:n.error||(n.lastSync?new Date(n.lastSync).toLocaleTimeString():"…")})]},n.id)),e.jsx("div",{className:"node-list",children:Cn.map(n=>e.jsxs("section",{children:[e.jsxs("h3",{children:[n,e.jsx("span",{children:Ce.filter(i=>i.group===n).length})]}),Ce.filter(i=>i.group===n).map(i=>{var o,h;return e.jsxs("div",{className:`node-item ${c===i.id?"selected":""}`,children:[e.jsxs("button",{onClick:()=>{ye(i.id),u(!1)},children:[e.jsx("span",{className:`node-dot ${K[i.id]??"offline"}`}),i.name,e.jsxs("small",{children:[i.username,"@",i.host,":",i.port]})]}),(i.sourceMissing||((o=i.unsupported)==null?void 0:o.length)||i.auth==="password"&&!i.hasSecret)&&e.jsx("span",{className:"node-badge",children:t(i.sourceMissing?"nodeSourceMissing":(h=i.unsupported)!=null&&h.length?"nodeUnsupported":"nodeMissingSecret")}),!i.sourceId&&e.jsx("button",{title:t("nodeEdit"),onClick:()=>{B(i),F("")},children:"⋯"})]},i.id)})]},n))}),e.jsxs("footer",{children:[e.jsx("button",{onClick:()=>u(!0),children:t("nodeSources")}),We,e.jsxs("details",{children:[e.jsx("summary",{children:"⋯"}),e.jsx("button",{onClick:()=>j("import_legacy"),children:t("nodeImportLegacy")}),e.jsx("button",{onClick:()=>{const n=de.map(({hasSecret:h,fingerprint:I,sourceId:ie,sourceKey:_e,sourceMissing:Pe,...Ne})=>Ne),i=URL.createObjectURL(new Blob([JSON.stringify({nodes:n},null,2)],{type:"application/json"})),o=document.createElement("a");o.href=i,o.download="pi-nodes.json",o.click(),setTimeout(()=>URL.revokeObjectURL(i),1e3)},children:t("nodeExport")})]})]})]}),!M&&(J||!l?An:e.jsxs("section",{className:"node-detail",children:[e.jsxs("header",{className:"node-detail-head",children:[e.jsxs("div",{children:[e.jsx("div",{className:"node-eyebrow",children:l.group}),e.jsx("h2",{children:l.name}),e.jsxs("code",{children:[l.username,"@",l.host,":",l.port]})]}),e.jsxs("div",{className:"node-actions",children:[X&&e.jsx("button",{onClick:()=>j("source_reveal",void 0,{id:X.id}),children:t("nodeRevealSource")}),!l.sourceId&&e.jsx("button",{onClick:()=>{B(l),F("")},children:t("nodeEdit")}),e.jsx("button",{className:"node-primary",disabled:!!((Je=l.unsupported)!=null&&Je.some(n=>n!=="key"))||l.sourceMissing||K[l.id]==="connecting",onClick:()=>He(l),children:t("nodeOpenWorkbench")})]})]}),l.sourceMissing&&e.jsx("p",{className:"node-warning",children:t("nodeSourceMissing")}),!!((Ge=l.unsupported)!=null&&Ge.length)&&e.jsxs("p",{className:"node-warning",children:[t("nodeUnsupported"),": ",l.unsupported.join(", ")]}),e.jsxs("div",{className:l.hasSecret?"node-credential-note":"node-warning",children:[e.jsxs("div",{children:[e.jsxs("strong",{children:[t(l.auth==="agent"?"nodeAgentAuth":l.auth==="password"?"nodePassword":"nodePassphrase"),!l.hasSecret&&l.auth==="password"&&` · ${t("nodeMissingSecret")}`]}),e.jsx("p",{children:t("nodeCredentialHint")})]}),e.jsx("button",{onClick:()=>{ce(l.auth==="key"?"key":"password"),oe(l.localKeyPath||l.keyPath||""),a(l.id),F(""),k(!1)},children:t("nodeFillSecret")})]}),e.jsxs("dl",{children:[e.jsx("dt",{children:t("nodeAuth")}),e.jsx("dd",{children:t(l.auth==="key"?"nodeKey":l.auth==="agent"?"nodeAgentAuth":"nodePassword")}),(l.localKeyPath||l.keyPath)&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:t("nodeKeyPath")}),e.jsx("dd",{children:e.jsx("code",{children:l.localKeyPath||l.keyPath})})]}),X&&e.jsxs(e.Fragment,{children:[e.jsx("dt",{children:t("nodeSourceLocation")}),e.jsxs("dd",{children:[e.jsxs("code",{children:[X.path,X.kind==="xshell"?`/${l.sourceKey}`:` · ${l.sourceKey}`]}),e.jsx("small",{children:t("nodeSourceReadonly")}),e.jsx("button",{title:t("nodeSourceOpenHint"),onClick:()=>void navigator.clipboard.writeText(X.kind==="xshell"?`${X.path}/${l.sourceKey}`:X.path).then(()=>ve(t("nodeCopied"))).catch(n=>he(String(n))),children:t("nodeCopy")})]})]}),e.jsx("dt",{children:t("nodeLastConnected")}),e.jsx("dd",{children:l.lastConnected?new Date(l.lastConnected).toLocaleString():t("nodeNever")}),e.jsx("dt",{children:t("nodeDefaultDir")}),e.jsx("dd",{children:e.jsx("code",{children:l.defaultDir})})]})]})),M&&l&&e.jsxs("div",{className:"node-connected",children:[e.jsxs("nav",{className:"node-connection-tabs",children:[e.jsx("button",{onClick:()=>q(!1),children:t("nodeBackList")}),de.filter(n=>{var i;return n.id===c||K[n.id]||((i=Ie[n.id])==null?void 0:i.length)}).map(n=>e.jsxs("button",{className:n.id===c?"active":"",onClick:()=>ye(n.id),children:[e.jsx("span",{className:`node-dot ${K[n.id]??"offline"}`}),n.name]},n.id)),e.jsx("button",{onClick:()=>{q(!1),u(!0)},"aria-label":t("nodeAdd"),children:"+"}),((Ve=Se[c])==null?void 0:Ve.connectedAt)&&e.jsx("span",{className:"node-connection-timing",children:t("nodeConnectionTiming",{ms:Se[c].latencyMs??0,duration:`${Math.floor(Math.max(0,Re-Se[c].connectedAt)/6e4)}:${String(Math.floor(Math.max(0,Re-Se[c].connectedAt)/1e3)%60).padStart(2,"0")}`})})]}),e.jsx("div",{className:"node-connected-body",children:e.jsxs("section",{className:"node-main",children:[e.jsxs("header",{className:"node-main-head",children:[e.jsx("strong",{children:l.name}),e.jsxs("span",{children:[l.username,"@",l.host,":",l.port]}),e.jsx("em",{children:t(K[c]==="connected"?"nodeConnected":"nodeDisconnected")}),e.jsx("button",{onClick:()=>K[c]==="connected"?j("disconnect",c):He(l),children:t(K[c]==="connected"?"nodeDisconnect":"nodeConnect")})]}),e.jsxs("nav",{className:"node-workbench-modes","aria-label":t("nodeWorkbench"),children:[e.jsx("button",{className:D==="agent"?"active":"",onClick:()=>W("agent"),children:t("nodeAgentTitle")}),e.jsx("button",{className:D==="terminal"?"active":"",onClick:()=>W("terminal"),children:t("nodeAgentTerminal")})]}),e.jsx("div",{className:"node-agent-container",hidden:D!=="agent",children:e.jsx(Rn,{nodeId:c,defaultDir:l.defaultDir,connected:K[c]==="connected",agent:H[c],request:j,draft:x[c]??"",setDraft:n=>A(i=>({...i,[c]:typeof n=="function"?n(i[c]??""):n})),consumedEditors:Q.current},c)}),e.jsxs("div",{className:"node-manual-workbench",hidden:D!=="terminal",children:[e.jsxs("div",{className:"node-tabs",children:[pe.map((n,i)=>e.jsxs("div",{className:(g==null?void 0:g.id)===n.id?"active":"",children:[e.jsxs("button",{onClick:()=>Te(o=>({...o,[c]:n.id})),children:[t("nodeTab",{n:i+1}),n.closed?` · ${t("nodeTabClosed")}`:n.busy?` · ${t("nodeTabBusy")}`:""]}),e.jsx("button",{"aria-label":t("nodeCloseTab"),onClick:()=>{n.closed||j("terminal_close",c,{},n.id,n.conversationId),Z.current.delete(`${c}:${n.id}`),ue(o=>({...o,[c]:(o[c]??[]).filter(h=>h.id!==n.id)}))},children:"×"})]},n.id)),e.jsx("button",{disabled:K[c]!=="connected",onClick:()=>j("terminal_open",c,{},je()),children:"+"})]}),e.jsxs("div",{className:"node-terminals",children:[pe.map(n=>e.jsx(Tn,{nodeId:c,tab:n,active:w&&D==="terminal"&&(g==null?void 0:g.id)===n.id,send:P,initialOutput:Z.current.get(`${c}:${n.id}`)??n.output},`${c}:${n.id}`)),!pe.length&&e.jsx("div",{className:"node-empty",children:t("nodeOpenHint")})]}),e.jsxs("div",{className:"node-terminal-footer",children:[e.jsx("span",{children:t("nodeTerminalHint")}),e.jsx("button",{onClick:()=>le(!z),children:t("nodeShowFiles")})]}),z&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"node-filebar",children:[e.jsx("input",{value:we,onChange:n=>Ae(n.target.value),"aria-label":t("nodeDefaultDir")}),e.jsx("button",{disabled:K[c]!=="connected",onClick:()=>Oe(we),children:t("nodeBrowse")})]}),e.jsx("div",{className:"node-files",children:kn.map(n=>{const i=`${we.replace(/\/$/,"")}/${n.name}`;return e.jsxs("button",{onClick:()=>n.type==="dir"?(Ae(i),Oe(i)):Nn(i),children:[n.type==="dir"?"▸":"·"," ",n.name]},n.name)})})]}),(L==null?void 0:L.nodeId)===c&&e.jsxs("div",{className:"node-file-editor",children:[e.jsx("span",{children:L.path}),e.jsx("button",{onClick:In,children:t("save")}),e.jsx("button",{onClick:()=>ke(null),children:t("close")}),e.jsx("textarea",{value:L.text,onChange:n=>ke({...L,text:n.target.value})})]})]})]})})]}),C&&e.jsx("div",{className:"node-modal-backdrop",children:e.jsxs("form",{className:"node-modal",onSubmit:n=>{n.preventDefault(),j("source_add",void 0,{...C,enabled:!0})},children:[e.jsx("h2",{children:t("nodeAddSource")}),e.jsxs("label",{children:[t("nodeSources"),e.jsxs("select",{value:C.kind,onChange:n=>y({...C,kind:n.target.value}),children:[e.jsx("option",{value:"xshell",children:"Xshell 8"}),e.jsx("option",{value:"ssh",children:"SSH config"})]})]}),e.jsxs("label",{children:[t("nodeSourcePath"),e.jsx("input",{required:!0,autoFocus:!0,value:C.path,onChange:n=>y({...C,path:n.target.value})})]}),e.jsxs("div",{className:"node-modal-actions",children:[e.jsx("button",{type:"button",onClick:()=>y(null),children:t("cancel")}),e.jsx("button",{type:"submit",children:t("nodeSyncKeep")}),e.jsx("button",{type:"button",disabled:!C.path.trim(),onClick:()=>j("source_add",void 0,{...C,enabled:!1}),children:t("nodeImportOnce")})]})]})}),V&&e.jsx("div",{className:"node-modal-backdrop",children:e.jsxs("form",{className:"node-modal",onSubmit:n=>{n.preventDefault();const i={auth:U,secret:be,persist:S,sameGroup:E,...U==="key"?{keyPath:fe}:{}};re.current={nodeId:V.id,payload:i},ge(!0),j("credential_test",V.id,i)},children:[e.jsx("h2",{children:V.name}),e.jsxs("code",{children:[V.username,"@",V.host,":",V.port]}),e.jsxs("label",{children:[t("nodeAuth"),e.jsxs("select",{disabled:R,value:U,onChange:n=>{ce(n.target.value),F(""),k(!1)},children:[e.jsx("option",{value:"password",children:t("nodePassword")}),e.jsx("option",{value:"key",children:t("nodeKey")})]})]}),e.jsx("p",{className:"node-muted",children:t("nodeLocalAuthHint")}),e.jsx(e.Fragment,{children:U==="key"&&e.jsxs(e.Fragment,{children:[e.jsxs("label",{children:[t("nodeKeyPath"),e.jsx("input",{required:!0,value:fe,onChange:n=>oe(n.target.value)})]}),e.jsx("p",{className:"node-muted",children:t("nodePrivateKeyHint")})]})}),e.jsxs("label",{children:[t(U==="key"?"nodePassphrase":"nodePassword"),e.jsx("input",{autoFocus:!0,type:"password",autoComplete:"new-password",required:U==="password",value:be,onChange:n=>F(n.target.value)})]}),e.jsxs("label",{className:"node-checkbox",children:[e.jsx("input",{type:"checkbox",checked:S,onChange:n=>N(n.target.checked)}),t("nodePersistSecret")]}),U==="password"&&e.jsxs("label",{className:"node-checkbox",children:[e.jsx("input",{type:"checkbox",checked:E,onChange:n=>k(n.target.checked)}),t("nodeGroupSecret")]}),E&&e.jsx("p",{className:"node-muted",children:t("nodeGroupHint")}),e.jsx("p",{className:"node-muted",children:t("nodeCredentialHint")}),e.jsxs("div",{className:"node-modal-actions",children:[e.jsx("button",{type:"button",disabled:R,onClick:()=>{Y.current.delete(V.id),a(null),F(""),re.current=null},children:t("cancel")}),e.jsx("button",{disabled:R,className:"node-primary",children:t(R?"nodeTesting":"nodeTestSave")})]})]})}),v&&e.jsx("div",{className:"node-modal-backdrop",children:e.jsxs("form",{className:"node-modal",onSubmit:n=>{n.preventDefault(),j("save",v.id,{...v,secret:be||void 0})},children:[e.jsx("h2",{children:v.id?t("nodeEdit"):t("nodeAdd")}),[["group",t("nodeGroup")],["name",t("nodeName")],["host",t("nodeAddress")],["port",t("nodePort")],["username",t("nodeUsername")],["defaultDir",t("nodeDefaultDir")]].map(([n,i])=>e.jsxs("label",{children:[i,e.jsx("input",{required:n!=="group",value:String(v[n]??""),onChange:o=>B({...v,[n]:n==="port"?Number(o.target.value):o.target.value})})]},n)),e.jsxs("label",{children:[t("nodeAuth"),e.jsxs("select",{value:v.auth,onChange:n=>B({...v,auth:n.target.value}),children:[e.jsx("option",{value:"password",children:t("nodePassword")}),e.jsx("option",{value:"key",children:t("nodeKey")}),e.jsx("option",{value:"agent",children:t("nodeAgentAuth")})]})]}),v.auth==="key"&&e.jsxs("label",{children:[t("nodeKeyPath"),e.jsx("input",{value:v.keyPath??"",onChange:n=>B({...v,keyPath:n.target.value})})]}),v.auth!=="agent"&&e.jsxs("label",{children:[v.auth==="key"?t("nodePassphrase"):t("nodePassword"),e.jsx("input",{type:"password",value:be,onChange:n=>F(n.target.value),placeholder:v.hasSecret?t("nodeKeepSecret"):""})]}),e.jsxs("div",{className:"node-modal-actions",children:[v.id&&v.fingerprint&&e.jsx("button",{type:"button",onClick:()=>{window.confirm(t("nodeForgetHostKeyConfirm",{name:v.name??""}))&&j("forget_host_key",v.id)},children:t("nodeForgetHostKey")}),v.id&&e.jsx("button",{type:"button",onClick:()=>{window.confirm(t("nodeDeleteConfirm",{name:v.name??""}))&&(j("delete",v.id),B(null))},children:t("nodeDelete")}),e.jsx("button",{type:"button",onClick:()=>B(null),children:t("cancel")}),e.jsx("button",{type:"submit",children:t("save")})]})]})})," "]})}export{Un as NodeWorkbench};
@@ -1,2 +1,2 @@
1
- import{a as m,j as n}from"./markdown-vNTCZJ6d.js";import{b as $,T as K,u as P,F as q,a as A,c as L,d as B,e as J,f as W,g as X,h as G,r as Q}from"./index-DQcpggFU.js";import{D as U,o as V}from"./xterm-D1D2FVe3.js";/* empty css */import"./react-BNj3n7jX.js";function Y({conversationId:s,terminalId:r,command:f,cwd:R,active:t,send:u,register:x}){const v=m.useRef(null),w=m.useRef(t);w.current=t;const N=m.useRef(null),b=f?JSON.stringify(f):"";return m.useEffect(()=>{const d=v.current;if(!d)return;const a=new U({theme:$(),fontFamily:'"SF Mono", "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace',fontSize:13,cursorBlink:!0,scrollback:8e3}),l=new V;a.loadAddon(l),a.open(d),N.current={term:a,fit:l},t&&a.focus();const j=()=>{a.options.theme=$()};window.addEventListener(K,j),a.attachCustomKeyEventHandler(o=>{var F;if(o.type!=="keydown")return!0;const E=(F=o.key)==null?void 0:F.toLowerCase();if((o.ctrlKey||o.metaKey)&&E==="v")return!1;if(o.ctrlKey&&!o.shiftKey&&!o.altKey&&E==="c"&&a.hasSelection()){const T=a.textarea;return T&&(T.value=a.getSelection(),T.select()),!1}return!0});const g=x(s,r,{write:o=>a.write(o),dispose:()=>a.dispose()}),C=()=>{if(!(!w.current||!d.clientWidth||!d.clientHeight))try{l.fit(),u({type:"terminal_resize",terminalId:r,conversationId:s,cols:a.cols,rows:a.rows})}catch{}},h=requestAnimationFrame(()=>{try{l.fit()}catch{}u(f?{type:"run_command",terminalId:r,conversationId:s,command:f,cols:a.cols,rows:a.rows}:{type:"terminal_create",terminalId:r,conversationId:s,cwd:R,cols:a.cols,rows:a.rows})}),k=a.onData(o=>{u({type:"terminal_input",terminalId:r,conversationId:s,data:o})});let y=null;return typeof ResizeObserver<"u"&&(y=new ResizeObserver(()=>{d.offsetWidth>0&&d.offsetHeight>0&&C()}),y.observe(d)),()=>{cancelAnimationFrame(h),k.dispose(),window.removeEventListener(K,j),y==null||y.disconnect(),g(),a.dispose(),N.current=null}},[s,r,b,u,x]),m.useEffect(()=>{if(!t)return;const d=requestAnimationFrame(()=>{const a=N.current;if(a){try{a.fit.fit(),u({type:"terminal_resize",terminalId:r,conversationId:s,cols:a.term.cols,rows:a.term.rows})}catch{}a.term.focus()}});return()=>cancelAnimationFrame(d)},[t]),n.jsx("div",{ref:v,className:`term-xterm ${t?"":"hidden"}`})}const H={name:"",command:"",cwd:"${pwd}"};function ae({chat:s,send:r,terminal:f,active:R}){const t=P(),[u,x]=m.useState(null),[v,w]=m.useState(!1),[N,b]=m.useState(!1),[d,a]=m.useState(null),[l,j]=m.useState(H),[g,C]=m.useState(null),h=m.useRef(null);m.useEffect(()=>{s.terminals.length===0?x(null):s.terminals.some(e=>e.id===u)||x(s.terminals[s.terminals.length-1].id)},[s.terminals,u]),m.useEffect(()=>()=>{h.current&&clearTimeout(h.current)},[]);const k=e=>{var p;if(!s.ready)return;const i=Q(),c=s.activeConversationId||((p=s.state)==null?void 0:p.conversationId)||"";f.create({...e,id:i,conversationId:c,cols:e.cols??80,rows:e.rows??24,running:!0,exitCode:null}),x(i),w(!1)},y=()=>{var e;return k({title:t("terminalTitle",{n:s.terminals.length+1}),cwd:((e=s.state)==null?void 0:e.cwd)??""})},o=e=>{var p;const i=e.name||e.command,c=s.terminals.find(_=>_.title===i);if(c){f.restart(c.id),x(c.id),r({type:"run_command",terminalId:c.id,conversationId:c.conversationId,command:e,cols:80,rows:24});return}k({title:i,cwd:((p=s.state)==null?void 0:p.cwd)??"",command:e})},E=e=>{const i=s.terminals.find(c=>c.id===e);if(i&&r({type:"terminal_kill",terminalId:e,conversationId:i.conversationId}),f.close(e),u===e){const c=s.terminals.filter(p=>p.id!==e);x(c.length>0?c[c.length-1].id:null)}},F=()=>{b(!0),a(null),j(H)},T=e=>{const i=s.commands[e];i&&(b(!1),a(e),j({name:i.name,command:i.command,cwd:i.cwd??""}))},D=()=>{b(!1),a(null)},S=()=>{const e=l.name.trim(),i=l.command.trim();if(!e||!i)return;const c=l.cwd.trim(),p={name:e,command:i,cwd:c||void 0},_=N?[...s.commands,p]:d!==null?s.commands.map((z,O)=>O===d?p:z):s.commands;r({type:"save_commands",commands:_}),D()},I=e=>{if(g===e){const i=s.commands.filter((c,p)=>p!==e);r({type:"save_commands",commands:i}),C(null),h.current&&clearTimeout(h.current)}else C(e),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>C(null),2500)},M=N||d!==null;return n.jsxs("div",{className:"terminal-view",children:[n.jsxs("aside",{className:`term-side term-commands ${v?"open":""}`,children:[n.jsxs("div",{className:"panel-header",children:[n.jsx("span",{className:"panel-title",children:t("commands")}),n.jsxs("div",{className:"panel-header-actions",children:[n.jsx("button",{type:"button",className:"panel-refresh",title:t("rerun"),onClick:()=>r({type:"list_commands"}),children:n.jsx(q,{})}),n.jsx("button",{type:"button",className:"panel-new",title:t("newCommand"),onClick:F,children:n.jsx(A,{})})]})]}),n.jsx("div",{className:"panel-body",children:M?n.jsxs("div",{className:"cmd-form",children:[n.jsx("label",{htmlFor:"cmd-name",children:t("name")}),n.jsx("input",{id:"cmd-name",className:"cmd-input",value:l.name,placeholder:t("exampleName"),autoFocus:!0,onChange:e=>j({...l,name:e.target.value})}),n.jsx("label",{htmlFor:"cmd-command",children:t("command")}),n.jsx("input",{id:"cmd-command",className:"cmd-input",value:l.command,placeholder:t("exampleCommand"),onChange:e=>j({...l,command:e.target.value}),onKeyDown:e=>{e.key==="Enter"&&!e.nativeEvent.isComposing&&S()}}),n.jsxs("label",{htmlFor:"cmd-cwd",children:[t("directory")," ",n.jsx("span",{className:"cmd-hint",children:t("cwdHint")})]}),n.jsx("input",{id:"cmd-cwd",className:"cmd-input",value:l.cwd,placeholder:"${pwd}",onChange:e=>j({...l,cwd:e.target.value}),onKeyDown:e=>{e.key==="Enter"&&!e.nativeEvent.isComposing&&S()}}),n.jsxs("div",{className:"cmd-form-actions",children:[n.jsx("button",{type:"button",className:"btn",onClick:D,children:t("cancel")}),n.jsx("button",{type:"button",className:"btn primary",disabled:!l.name.trim()||!l.command.trim(),onClick:S,children:t("save")})]})]}):n.jsxs(n.Fragment,{children:[s.commands.length===0&&n.jsx("div",{className:"panel-empty",children:t("noCommands")}),s.commands.map((e,i)=>n.jsxs("div",{className:"cmd-item",children:[n.jsx("button",{type:"button",className:"cmd-run",title:t("clickToRun"),onClick:()=>o(e),children:n.jsx(L,{})}),n.jsxs("button",{type:"button",className:"cmd-main",title:t("clickToRun"),onClick:()=>o(e),children:[n.jsx("span",{className:"cmd-name",children:e.name}),n.jsx("span",{className:"cmd-command",children:e.command}),e.cwd&&n.jsx("span",{className:"cmd-cwd",children:e.cwd})]}),n.jsx("button",{type:"button",className:"cmd-act",title:t("edit"),onClick:()=>T(i),children:n.jsx(B,{})}),n.jsx("button",{type:"button",className:`cmd-act del ${g===i?"confirm":""}`,title:t("delete"),onClick:()=>I(i),children:g===i?t("confirmQ"):n.jsx(J,{})})]},i))]})}),n.jsxs("div",{className:"term-tabs-block",children:[n.jsxs("div",{className:"panel-header",children:[n.jsx("span",{className:"panel-title",children:t("terminal")}),n.jsx("button",{type:"button",className:"panel-new",title:t("newTerminal"),onClick:y,children:n.jsx(A,{})})]}),n.jsxs("div",{className:"panel-body",children:[s.terminals.length===0&&n.jsx("div",{className:"panel-empty",children:t("noTerminal")}),s.terminals.map(e=>n.jsxs("div",{className:`term-tab ${e.id===u?"active":""}`,children:[n.jsxs("button",{type:"button",className:"term-tab-main",title:`${e.cwd}${e.command?`
1
+ import{a as m,j as n}from"./markdown-BhJ_LInD.js";import{b as $,T as K,u as P,F as q,a as A,c as L,d as B,e as J,f as W,g as X,h as G,r as Q}from"./index-C5or_GAq.js";import{D as U,o as V}from"./xterm-D1D2FVe3.js";/* empty css */import"./react-BddUxV-9.js";function Y({conversationId:s,terminalId:r,command:f,cwd:R,active:t,send:u,register:x}){const v=m.useRef(null),w=m.useRef(t);w.current=t;const N=m.useRef(null),b=f?JSON.stringify(f):"";return m.useEffect(()=>{const d=v.current;if(!d)return;const a=new U({theme:$(),fontFamily:'"SF Mono", "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace',fontSize:13,cursorBlink:!0,scrollback:8e3}),l=new V;a.loadAddon(l),a.open(d),N.current={term:a,fit:l},t&&a.focus();const j=()=>{a.options.theme=$()};window.addEventListener(K,j),a.attachCustomKeyEventHandler(o=>{var F;if(o.type!=="keydown")return!0;const E=(F=o.key)==null?void 0:F.toLowerCase();if((o.ctrlKey||o.metaKey)&&E==="v")return!1;if(o.ctrlKey&&!o.shiftKey&&!o.altKey&&E==="c"&&a.hasSelection()){const T=a.textarea;return T&&(T.value=a.getSelection(),T.select()),!1}return!0});const g=x(s,r,{write:o=>a.write(o),dispose:()=>a.dispose()}),C=()=>{if(!(!w.current||!d.clientWidth||!d.clientHeight))try{l.fit(),u({type:"terminal_resize",terminalId:r,conversationId:s,cols:a.cols,rows:a.rows})}catch{}},h=requestAnimationFrame(()=>{try{l.fit()}catch{}u(f?{type:"run_command",terminalId:r,conversationId:s,command:f,cols:a.cols,rows:a.rows}:{type:"terminal_create",terminalId:r,conversationId:s,cwd:R,cols:a.cols,rows:a.rows})}),k=a.onData(o=>{u({type:"terminal_input",terminalId:r,conversationId:s,data:o})});let y=null;return typeof ResizeObserver<"u"&&(y=new ResizeObserver(()=>{d.offsetWidth>0&&d.offsetHeight>0&&C()}),y.observe(d)),()=>{cancelAnimationFrame(h),k.dispose(),window.removeEventListener(K,j),y==null||y.disconnect(),g(),a.dispose(),N.current=null}},[s,r,b,u,x]),m.useEffect(()=>{if(!t)return;const d=requestAnimationFrame(()=>{const a=N.current;if(a){try{a.fit.fit(),u({type:"terminal_resize",terminalId:r,conversationId:s,cols:a.term.cols,rows:a.term.rows})}catch{}a.term.focus()}});return()=>cancelAnimationFrame(d)},[t]),n.jsx("div",{ref:v,className:`term-xterm ${t?"":"hidden"}`})}const H={name:"",command:"",cwd:"${pwd}"};function ae({chat:s,send:r,terminal:f,active:R}){const t=P(),[u,x]=m.useState(null),[v,w]=m.useState(!1),[N,b]=m.useState(!1),[d,a]=m.useState(null),[l,j]=m.useState(H),[g,C]=m.useState(null),h=m.useRef(null);m.useEffect(()=>{s.terminals.length===0?x(null):s.terminals.some(e=>e.id===u)||x(s.terminals[s.terminals.length-1].id)},[s.terminals,u]),m.useEffect(()=>()=>{h.current&&clearTimeout(h.current)},[]);const k=e=>{var p;if(!s.ready)return;const i=Q(),c=s.activeConversationId||((p=s.state)==null?void 0:p.conversationId)||"";f.create({...e,id:i,conversationId:c,cols:e.cols??80,rows:e.rows??24,running:!0,exitCode:null}),x(i),w(!1)},y=()=>{var e;return k({title:t("terminalTitle",{n:s.terminals.length+1}),cwd:((e=s.state)==null?void 0:e.cwd)??""})},o=e=>{var p;const i=e.name||e.command,c=s.terminals.find(_=>_.title===i);if(c){f.restart(c.id),x(c.id),r({type:"run_command",terminalId:c.id,conversationId:c.conversationId,command:e,cols:80,rows:24});return}k({title:i,cwd:((p=s.state)==null?void 0:p.cwd)??"",command:e})},E=e=>{const i=s.terminals.find(c=>c.id===e);if(i&&r({type:"terminal_kill",terminalId:e,conversationId:i.conversationId}),f.close(e),u===e){const c=s.terminals.filter(p=>p.id!==e);x(c.length>0?c[c.length-1].id:null)}},F=()=>{b(!0),a(null),j(H)},T=e=>{const i=s.commands[e];i&&(b(!1),a(e),j({name:i.name,command:i.command,cwd:i.cwd??""}))},D=()=>{b(!1),a(null)},S=()=>{const e=l.name.trim(),i=l.command.trim();if(!e||!i)return;const c=l.cwd.trim(),p={name:e,command:i,cwd:c||void 0},_=N?[...s.commands,p]:d!==null?s.commands.map((z,O)=>O===d?p:z):s.commands;r({type:"save_commands",commands:_}),D()},I=e=>{if(g===e){const i=s.commands.filter((c,p)=>p!==e);r({type:"save_commands",commands:i}),C(null),h.current&&clearTimeout(h.current)}else C(e),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>C(null),2500)},M=N||d!==null;return n.jsxs("div",{className:"terminal-view",children:[n.jsxs("aside",{className:`term-side term-commands ${v?"open":""}`,children:[n.jsxs("div",{className:"panel-header",children:[n.jsx("span",{className:"panel-title",children:t("commands")}),n.jsxs("div",{className:"panel-header-actions",children:[n.jsx("button",{type:"button",className:"panel-refresh",title:t("rerun"),onClick:()=>r({type:"list_commands"}),children:n.jsx(q,{})}),n.jsx("button",{type:"button",className:"panel-new",title:t("newCommand"),onClick:F,children:n.jsx(A,{})})]})]}),n.jsx("div",{className:"panel-body",children:M?n.jsxs("div",{className:"cmd-form",children:[n.jsx("label",{htmlFor:"cmd-name",children:t("name")}),n.jsx("input",{id:"cmd-name",className:"cmd-input",value:l.name,placeholder:t("exampleName"),autoFocus:!0,onChange:e=>j({...l,name:e.target.value})}),n.jsx("label",{htmlFor:"cmd-command",children:t("command")}),n.jsx("input",{id:"cmd-command",className:"cmd-input",value:l.command,placeholder:t("exampleCommand"),onChange:e=>j({...l,command:e.target.value}),onKeyDown:e=>{e.key==="Enter"&&!e.nativeEvent.isComposing&&S()}}),n.jsxs("label",{htmlFor:"cmd-cwd",children:[t("directory")," ",n.jsx("span",{className:"cmd-hint",children:t("cwdHint")})]}),n.jsx("input",{id:"cmd-cwd",className:"cmd-input",value:l.cwd,placeholder:"${pwd}",onChange:e=>j({...l,cwd:e.target.value}),onKeyDown:e=>{e.key==="Enter"&&!e.nativeEvent.isComposing&&S()}}),n.jsxs("div",{className:"cmd-form-actions",children:[n.jsx("button",{type:"button",className:"btn",onClick:D,children:t("cancel")}),n.jsx("button",{type:"button",className:"btn primary",disabled:!l.name.trim()||!l.command.trim(),onClick:S,children:t("save")})]})]}):n.jsxs(n.Fragment,{children:[s.commands.length===0&&n.jsx("div",{className:"panel-empty",children:t("noCommands")}),s.commands.map((e,i)=>n.jsxs("div",{className:"cmd-item",children:[n.jsx("button",{type:"button",className:"cmd-run",title:t("clickToRun"),onClick:()=>o(e),children:n.jsx(L,{})}),n.jsxs("button",{type:"button",className:"cmd-main",title:t("clickToRun"),onClick:()=>o(e),children:[n.jsx("span",{className:"cmd-name",children:e.name}),n.jsx("span",{className:"cmd-command",children:e.command}),e.cwd&&n.jsx("span",{className:"cmd-cwd",children:e.cwd})]}),n.jsx("button",{type:"button",className:"cmd-act",title:t("edit"),onClick:()=>T(i),children:n.jsx(B,{})}),n.jsx("button",{type:"button",className:`cmd-act del ${g===i?"confirm":""}`,title:t("delete"),onClick:()=>I(i),children:g===i?t("confirmQ"):n.jsx(J,{})})]},i))]})}),n.jsxs("div",{className:"term-tabs-block",children:[n.jsxs("div",{className:"panel-header",children:[n.jsx("span",{className:"panel-title",children:t("terminal")}),n.jsx("button",{type:"button",className:"panel-new",title:t("newTerminal"),onClick:y,children:n.jsx(A,{})})]}),n.jsxs("div",{className:"panel-body",children:[s.terminals.length===0&&n.jsx("div",{className:"panel-empty",children:t("noTerminal")}),s.terminals.map(e=>n.jsxs("div",{className:`term-tab ${e.id===u?"active":""}`,children:[n.jsxs("button",{type:"button",className:"term-tab-main",title:`${e.cwd}${e.command?`
2
2
  > ${e.command.command}`:""}`,onClick:()=>{x(e.id),w(!1)},children:[n.jsx("span",{className:`term-tab-dot ${e.running?"run":"exit"}`}),n.jsxs("span",{className:"term-tab-title",children:[e.title,!e.running&&n.jsx("span",{className:"term-tab-exit",children:t("exited",{code:e.exitCode===null?"":` ${e.exitCode}`})})]})]}),n.jsx("button",{type:"button",className:"term-tab-close",title:t("closeTerminal"),onClick:()=>E(e.id),children:n.jsx(W,{})})]},e.id))]})]})]}),n.jsxs("div",{className:"term-main",children:[v&&n.jsx("div",{className:"drawer-backdrop",onClick:()=>w(!1)}),n.jsx("button",{type:"button",className:"term-side-toggle",title:t("commands"),onClick:()=>w(e=>!e),children:n.jsx(X,{})}),s.terminals.length===0?n.jsxs("div",{className:"term-empty",children:[n.jsx(G,{className:"term-empty-icon"}),n.jsx("div",{className:"term-empty-title",children:t("builtinTerminal")}),n.jsx("div",{className:"term-empty-sub",children:t("termEmptySub")})]}):s.terminals.map(e=>n.jsx(Y,{conversationId:e.conversationId,terminalId:e.id,command:e.command,cwd:e.cwd,active:R&&e.id===u,send:r,register:f.register},`${e.conversationId}:${e.id}`))]})]})}export{ae as TerminalPanel};
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-SVP7TREG-eQPl4UBQ.js";import{p as f}from"./chunk-JWPE2WC7-D0RPyByP.js";import{_ as n,l as o}from"./mermaid.core-B8fKGWsc.js";import{M as c,b as d}from"./cynefin-OW5HDTMX-CStWX9kE.js";import"./index-DQcpggFU.js";import"./markdown-vNTCZJ6d.js";import"./react-BNj3n7jX.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}},I={parser:R,db:a,renderer:u,styles:p};export{I as diagram};
1
+ import{g as p,r as u,d as a}from"./chunk-SVP7TREG-l2XXTr2v.js";import{p as f}from"./chunk-JWPE2WC7-CrsdBGXT.js";import{_ as n,l as o}from"./mermaid.core-CO2nrD04.js";import{M as c,b as d}from"./cynefin-OW5HDTMX-IEk8qBRq.js";import"./index-C5or_GAq.js";import"./markdown-BhJ_LInD.js";import"./react-BddUxV-9.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}},I={parser:R,db:a,renderer:u,styles:p};export{I as diagram};
@@ -1 +1 @@
1
- import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./mermaid.core-B8fKGWsc.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,C,a){var O=I-l,i=D-h,n=C-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 W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(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)*L(fn(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=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)-an,c=A.apply(this,arguments)-an,F=un(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(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(un(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<rn)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(on((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(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=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,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(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,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-rn/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
1
+ import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./mermaid.core-CO2nrD04.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,C,a){var O=I-l,i=D-h,n=C-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 W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(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)*L(fn(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=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)-an,c=A.apply(this,arguments)-an,F=un(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(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(un(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<rn)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(on((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(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=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,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(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,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-rn/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};