@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.
- package/LICENSE +1 -1
- package/dist/server/agent-service.js +87 -7
- package/dist/server/control-socket.js +1 -0
- package/dist/server/extensions-worker.js +3 -2
- package/dist/server/files-service.js +8 -16
- package/dist/server/index.js +7 -3
- package/dist/server/node-agent.js +262 -0
- package/dist/server/node-workbench.js +62 -1
- package/dist/server/plan/extension.js +4 -4
- package/dist/server/plan/state.js +11 -1
- package/dist/server/slash-commands.js +6 -0
- package/dist/server/wiki-routes.js +8 -1
- package/dist/server/wiki-service.js +13 -0
- package/package.json +1 -1
- package/web/dist/assets/NodeWorkbench-BiP2ktQP.js +3 -0
- package/web/dist/assets/{TerminalPanel-CWh6vw_N.js → TerminalPanel-CKaSUsN-.js} +1 -1
- package/web/dist/assets/{abnfDiagram-VCTEODGH-D5Ti0Kpa.js → abnfDiagram-VCTEODGH-CnwRJDRL.js} +1 -1
- package/web/dist/assets/{arc-DKJilLd6.js → arc-CG4Q7-W_.js} +1 -1
- package/web/dist/assets/{architectureDiagram-5GKGNRK7-Cf0w38g-.js → architectureDiagram-5GKGNRK7-BrGqX_Rg.js} +1 -1
- package/web/dist/assets/{blockDiagram-I7D4REHJ-BOTLWLIL.js → blockDiagram-I7D4REHJ-C2t0PjZT.js} +1 -1
- package/web/dist/assets/{c4Diagram-7LVT6UL2-CLCCoJs3.js → c4Diagram-7LVT6UL2-CadrcgGL.js} +1 -1
- package/web/dist/assets/channel-C27Jizb6.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-BHjga2Ge.js → chunk-2Q5K7J3B-CC3V2ITZ.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-CQJ5VfDZ.js → chunk-5VM5RSS4-DqKSbGmE.js} +1 -1
- package/web/dist/assets/{chunk-F27PBJKO-C67qoPJH.js → chunk-F27PBJKO-_CDr3JbY.js} +1 -1
- package/web/dist/assets/{chunk-IMKFNOWR-CgXXGwI8.js → chunk-IMKFNOWR-BIR4H4fX.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-D0RPyByP.js → chunk-JWPE2WC7-CrsdBGXT.js} +1 -1
- package/web/dist/assets/{chunk-POPQ4Y6H-BeYC9s9x.js → chunk-POPQ4Y6H-C6q9kQmf.js} +1 -1
- package/web/dist/assets/{chunk-SVP7TREG-eQPl4UBQ.js → chunk-SVP7TREG-l2XXTr2v.js} +1 -1
- package/web/dist/assets/{chunk-TICWLB2K-DT73arPU.js → chunk-TICWLB2K-29I_mZgB.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-B4FwQcP-.js → chunk-XXDRQBXY-htV9FBqi.js} +1 -1
- package/web/dist/assets/classDiagram-ZZMXUADV-DYTBrAEP.js +1 -0
- package/web/dist/assets/classDiagram-v2-VYDZK3BY-DYTBrAEP.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-Bnn5nlQN.js → cose-bilkent-JH36ORCC-Cop-ihyx.js} +1 -1
- package/web/dist/assets/{cynefin-OW5HDTMX-CStWX9kE.js → cynefin-OW5HDTMX-IEk8qBRq.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-5FMLGOSQ-BMVHC03f.js → cynefinDiagram-5FMLGOSQ-Bmzt6Qb5.js} +1 -1
- package/web/dist/assets/{dagre-GXQ25YYZ-ClSaO4ml.js → dagre-GXQ25YYZ-DiXTJYYU.js} +1 -1
- package/web/dist/assets/{diagram-S7CK7UJ4-C43LL08C.js → diagram-S7CK7UJ4-BT7CLuNk.js} +1 -1
- package/web/dist/assets/{diagram-UQ7AKVKN-BPVn_ySW.js → diagram-UQ7AKVKN-BZZ3nTCO.js} +1 -1
- package/web/dist/assets/{diagram-VSXAHHWV-C34FFhRi.js → diagram-VSXAHHWV-Dal8LeZh.js} +1 -1
- package/web/dist/assets/{diagram-VX7I27RA-BRk4bncf.js → diagram-VX7I27RA-D6V9FfNA.js} +1 -1
- package/web/dist/assets/{diagram-Z3DM3KII-O5hYPLEd.js → diagram-Z3DM3KII-KUAIcFiD.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-PWID7BFC-DVGEBm99.js → ebnfDiagram-PWID7BFC-s0FEPZrV.js} +1 -1
- package/web/dist/assets/{erDiagram-RLTQ6QDP-M-BLpTEV.js → erDiagram-RLTQ6QDP-CiIQPFCD.js} +1 -1
- package/web/dist/assets/{flowDiagram-HODETNUW-BwdLopEx.js → flowDiagram-HODETNUW-CvG4MYWn.js} +1 -1
- package/web/dist/assets/{ganttDiagram-EL5Y4UJY-DYxx2ppA.js → ganttDiagram-EL5Y4UJY-CUf115ii.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-WWUBYQGX-DUU0wMYB.js → gitGraphDiagram-WWUBYQGX-o3K1r6fL.js} +1 -1
- package/web/dist/assets/index-C3vDFSEV.css +10 -0
- package/web/dist/assets/index-C5or_GAq.js +276 -0
- package/web/dist/assets/{infoDiagram-27XIBGKW-CFaW5C0C.js → infoDiagram-27XIBGKW-BxiBeQ8E.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-5VMMS53U--ENP1MTB.js → ishikawaDiagram-5VMMS53U-B1ONuCkH.js} +1 -1
- package/web/dist/assets/{journeyDiagram-3NMN7TZE-DgnAzSTj.js → journeyDiagram-3NMN7TZE-DwmuoXcX.js} +1 -1
- package/web/dist/assets/{kanban-definition-UXKFOSKX-_STZN1vU.js → kanban-definition-UXKFOSKX-pMKHubxH.js} +1 -1
- package/web/dist/assets/{layout-CkUClkXt.js → layout-CEwfjQR0.js} +1 -1
- package/web/dist/assets/{linear-sYHiUOxa.js → linear-D22Gdbt1.js} +1 -1
- package/web/dist/assets/{markdown-vNTCZJ6d.js → markdown-BhJ_LInD.js} +1 -1
- package/web/dist/assets/{mermaid.core-B8fKGWsc.js → mermaid.core-CO2nrD04.js} +5 -5
- package/web/dist/assets/{mindmap-definition-YA3MSWOX-DP0BYOEx.js → mindmap-definition-YA3MSWOX-9MQn9ZAp.js} +1 -1
- package/web/dist/assets/{pegDiagram-XKGWAZYB-DkWTmZre.js → pegDiagram-XKGWAZYB-Dy6fLjM-.js} +1 -1
- package/web/dist/assets/{pieDiagram-E7YTZNPT-DfZgMV4u.js → pieDiagram-E7YTZNPT-EDLez6nA.js} +1 -1
- package/web/dist/assets/{quadrantDiagram-AXDQQJYC-Djl4TT7q.js → quadrantDiagram-AXDQQJYC-Cgcd9mvy.js} +1 -1
- package/web/dist/assets/{railroadDiagram-O6MQD6OU-DbKF6zXn.js → railroadDiagram-O6MQD6OU-B4Td0tjj.js} +1 -1
- package/web/dist/assets/{react-BNj3n7jX.js → react-BddUxV-9.js} +1 -1
- package/web/dist/assets/{requirementDiagram-BXWQKSXE-idola5qb.js → requirementDiagram-BXWQKSXE-aF2QNZ78.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-P5KCCOFB-KA0hQOle.js → sankeyDiagram-P5KCCOFB-DgTYwYMa.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-WJ2MYXX4-BXSKvxzP.js → sequenceDiagram-WJ2MYXX4-EUcddWUc.js} +1 -1
- package/web/dist/assets/{sizeCapture-INFHLROL-C_Ewv3S5.js → sizeCapture-INFHLROL-CXHOv9Sx.js} +1 -1
- package/web/dist/assets/{stateDiagram-D77RDMKH-DIf5X8oo.js → stateDiagram-D77RDMKH-B-xlgfaK.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-MP3YSRHH-kwAwAlWX.js +1 -0
- package/web/dist/assets/{swimlanes-42K2YHIH-Cx_Rc8M2.js → swimlanes-42K2YHIH-BtFBOCDh.js} +1 -1
- package/web/dist/assets/swimlanesDiagram-VR7AAH4N-D5j5Cj3S.js +8 -0
- package/web/dist/assets/{timeline-definition-24CTP7MA-BRrDhWVz.js → timeline-definition-24CTP7MA-CZlQY6pb.js} +1 -1
- package/web/dist/assets/{vennDiagram-4TSXK5OY-Ad6G0YwD.js → vennDiagram-4TSXK5OY-Cn61dJvL.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-VM6X3IG4-X6-ENpSi.js → wardleyDiagram-VM6X3IG4-fiMNrWpr.js} +1 -1
- package/web/dist/assets/{xychartDiagram-S5SC5T6Z-DhegNS6d.js → xychartDiagram-S5SC5T6Z-CuzM_sof.js} +1 -1
- package/web/dist/index.html +4 -4
- package/web/dist/assets/NodeWorkbench-C4U1PldE.js +0 -3
- package/web/dist/assets/channel-D8Hd7T4P.js +0 -1
- package/web/dist/assets/classDiagram-ZZMXUADV-B_btgYRB.js +0 -1
- package/web/dist/assets/classDiagram-v2-VYDZK3BY-B_btgYRB.js +0 -1
- package/web/dist/assets/index-CI2KfVSr.css +0 -10
- package/web/dist/assets/index-DQcpggFU.js +0 -275
- package/web/dist/assets/stateDiagram-v2-MP3YSRHH-DYwe_2mB.js +0 -1
- 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,
|
|
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 =
|
|
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.
|
|
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-
|
|
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};
|
package/web/dist/assets/{abnfDiagram-VCTEODGH-D5Ti0Kpa.js → abnfDiagram-VCTEODGH-CnwRJDRL.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-SVP7TREG-
|
|
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-
|
|
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};
|