@youweichen/pi-web-ui 0.45.1 → 0.46.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/README.md +7 -0
- package/dist/server/agent-service.js +135 -4
- package/dist/server/index.js +6 -0
- package/dist/server/plugin-updater.js +20 -1
- package/package.json +1 -1
- package/web/dist/assets/{TerminalPanel-D4AktsEn.js → TerminalPanel-CL7_iOws.js} +1 -1
- package/web/dist/assets/{abnfDiagram-VCTEODGH-Ct5StJwt.js → abnfDiagram-VCTEODGH-BKPpCrz_.js} +1 -1
- package/web/dist/assets/{arc-pkuxEN8A.js → arc-C23hgJIX.js} +1 -1
- package/web/dist/assets/{architectureDiagram-5GKGNRK7-C6P6yn4y.js → architectureDiagram-5GKGNRK7-dhOJ0tIS.js} +1 -1
- package/web/dist/assets/{blockDiagram-I7D4REHJ-BmgfH1jt.js → blockDiagram-I7D4REHJ-T5jRCGjd.js} +1 -1
- package/web/dist/assets/{c4Diagram-7LVT6UL2-CgmwTFsK.js → c4Diagram-7LVT6UL2-mWuNh2dO.js} +1 -1
- package/web/dist/assets/channel-BCfi_Ba5.js +1 -0
- package/web/dist/assets/{chunk-2Q5K7J3B-DX_NqAiH.js → chunk-2Q5K7J3B-DOE-hNOM.js} +1 -1
- package/web/dist/assets/{chunk-5VM5RSS4-gLeuQuYv.js → chunk-5VM5RSS4-EtaQHwdB.js} +1 -1
- package/web/dist/assets/{chunk-F27PBJKO-D4WX4mhI.js → chunk-F27PBJKO-BEVAlITo.js} +1 -1
- package/web/dist/assets/{chunk-IMKFNOWR-DBpDxGQD.js → chunk-IMKFNOWR-LS0UAssg.js} +1 -1
- package/web/dist/assets/{chunk-JWPE2WC7-DIQ8iZN5.js → chunk-JWPE2WC7-BxQUQ7dH.js} +1 -1
- package/web/dist/assets/{chunk-POPQ4Y6H-F_YTNoGz.js → chunk-POPQ4Y6H-BPk8DcZO.js} +1 -1
- package/web/dist/assets/{chunk-SVP7TREG-CmDIvX-r.js → chunk-SVP7TREG-BOWUorML.js} +1 -1
- package/web/dist/assets/{chunk-TICWLB2K-BQUzHQyS.js → chunk-TICWLB2K-OJjESJUC.js} +1 -1
- package/web/dist/assets/{chunk-XXDRQBXY-DqR9iffH.js → chunk-XXDRQBXY-COOAF-eP.js} +1 -1
- package/web/dist/assets/classDiagram-ZZMXUADV-yqBppQ5u.js +1 -0
- package/web/dist/assets/classDiagram-v2-VYDZK3BY-yqBppQ5u.js +1 -0
- package/web/dist/assets/{cose-bilkent-JH36ORCC-Dl67W4Dx.js → cose-bilkent-JH36ORCC-C1JwoJmN.js} +1 -1
- package/web/dist/assets/{cynefin-OW5HDTMX-fWdqaCpX.js → cynefin-OW5HDTMX-DmSGPBbN.js} +1 -1
- package/web/dist/assets/{cynefinDiagram-5FMLGOSQ-CSUAXbaP.js → cynefinDiagram-5FMLGOSQ-CIsEXfZy.js} +1 -1
- package/web/dist/assets/{dagre-GXQ25YYZ-CqUVwu1X.js → dagre-GXQ25YYZ-BsHrnq08.js} +1 -1
- package/web/dist/assets/{diagram-S7CK7UJ4-bRce-WYV.js → diagram-S7CK7UJ4-B9G0tgH2.js} +1 -1
- package/web/dist/assets/{diagram-UQ7AKVKN-CiqPtPBE.js → diagram-UQ7AKVKN-_JgVa7Wv.js} +1 -1
- package/web/dist/assets/{diagram-VSXAHHWV-CbEA05LX.js → diagram-VSXAHHWV-CKhfNWNM.js} +1 -1
- package/web/dist/assets/{diagram-VX7I27RA-CRcY9MD-.js → diagram-VX7I27RA-BrMgRfub.js} +1 -1
- package/web/dist/assets/{diagram-Z3DM3KII-DmTwvZdS.js → diagram-Z3DM3KII-BKlCUZG7.js} +1 -1
- package/web/dist/assets/{ebnfDiagram-PWID7BFC-DbwmiGVj.js → ebnfDiagram-PWID7BFC-BhS-laX7.js} +1 -1
- package/web/dist/assets/{erDiagram-RLTQ6QDP-Cxiaf87y.js → erDiagram-RLTQ6QDP-Bicr1cgA.js} +1 -1
- package/web/dist/assets/{flowDiagram-HODETNUW-BQiecP1I.js → flowDiagram-HODETNUW-CwN50VFN.js} +1 -1
- package/web/dist/assets/{ganttDiagram-EL5Y4UJY-CSr8RRNw.js → ganttDiagram-EL5Y4UJY-DdGF6wOu.js} +1 -1
- package/web/dist/assets/{gitGraphDiagram-WWUBYQGX-C4Tdis3g.js → gitGraphDiagram-WWUBYQGX-CQWE0duT.js} +1 -1
- package/web/dist/assets/index-C-XJ-ly_.js +26 -0
- package/web/dist/assets/index-DPHpyI7l.css +10 -0
- package/web/dist/assets/{infoDiagram-27XIBGKW-ij_5A0pY.js → infoDiagram-27XIBGKW-DSiF9D9z.js} +1 -1
- package/web/dist/assets/{ishikawaDiagram-5VMMS53U-C8-tm2LV.js → ishikawaDiagram-5VMMS53U-Dmwa_H3U.js} +1 -1
- package/web/dist/assets/{journeyDiagram-3NMN7TZE-ZJedkNel.js → journeyDiagram-3NMN7TZE-xSKoWUXW.js} +1 -1
- package/web/dist/assets/{kanban-definition-UXKFOSKX-BEuoM53n.js → kanban-definition-UXKFOSKX-BjdQTjeP.js} +1 -1
- package/web/dist/assets/{layout-zq_9DigZ.js → layout-BihLpYDs.js} +1 -1
- package/web/dist/assets/{linear-D-QXJ5Wc.js → linear-BEtuTZH6.js} +1 -1
- package/web/dist/assets/{mermaid.core-CCiG-bOm.js → mermaid.core-DDk4A0BP.js} +5 -5
- package/web/dist/assets/{mindmap-definition-YA3MSWOX-VaAisUIe.js → mindmap-definition-YA3MSWOX-vyLVeeNj.js} +1 -1
- package/web/dist/assets/{pegDiagram-XKGWAZYB-D5vmRtkn.js → pegDiagram-XKGWAZYB-CiJBX8pg.js} +1 -1
- package/web/dist/assets/{pieDiagram-E7YTZNPT-loD6V8fn.js → pieDiagram-E7YTZNPT-pjZ_fcHc.js} +1 -1
- package/web/dist/assets/{quadrantDiagram-AXDQQJYC-B7E4mH1-.js → quadrantDiagram-AXDQQJYC-Cp-mghRB.js} +1 -1
- package/web/dist/assets/{railroadDiagram-O6MQD6OU-DTALHvDa.js → railroadDiagram-O6MQD6OU-DJbRWcUS.js} +1 -1
- package/web/dist/assets/{requirementDiagram-BXWQKSXE-ZjJKuEcR.js → requirementDiagram-BXWQKSXE-DNLHnruR.js} +1 -1
- package/web/dist/assets/{sankeyDiagram-P5KCCOFB-DufTudDP.js → sankeyDiagram-P5KCCOFB-DjOj5iQU.js} +1 -1
- package/web/dist/assets/{sequenceDiagram-WJ2MYXX4-B-Zk4alI.js → sequenceDiagram-WJ2MYXX4-CVGakqCw.js} +1 -1
- package/web/dist/assets/{sizeCapture-INFHLROL-B1pjlxXN.js → sizeCapture-INFHLROL-X3bYvvQk.js} +1 -1
- package/web/dist/assets/{stateDiagram-D77RDMKH-BeWg6PIR.js → stateDiagram-D77RDMKH-8o65SNy_.js} +1 -1
- package/web/dist/assets/stateDiagram-v2-MP3YSRHH-B-PRjFjM.js +1 -0
- package/web/dist/assets/{swimlanes-42K2YHIH-4J4jmMmO.js → swimlanes-42K2YHIH-D0YDGlUe.js} +1 -1
- package/web/dist/assets/swimlanesDiagram-VR7AAH4N-CmQs4l8c.js +8 -0
- package/web/dist/assets/{timeline-definition-24CTP7MA-ByqLfxqe.js → timeline-definition-24CTP7MA-CGmS1IQy.js} +1 -1
- package/web/dist/assets/{vennDiagram-4TSXK5OY-B_EqVW4R.js → vennDiagram-4TSXK5OY-DtcOF61-.js} +1 -1
- package/web/dist/assets/{wardleyDiagram-VM6X3IG4-Bu7sA6F8.js → wardleyDiagram-VM6X3IG4-DnEMdzmM.js} +1 -1
- package/web/dist/assets/{xychartDiagram-S5SC5T6Z-w1KPVGKk.js → xychartDiagram-S5SC5T6Z-aX9QskX7.js} +1 -1
- package/web/dist/index.html +2 -2
- package/web/dist/assets/channel-0Y__6sq2.js +0 -1
- package/web/dist/assets/classDiagram-ZZMXUADV-BEfGIpzu.js +0 -1
- package/web/dist/assets/classDiagram-v2-VYDZK3BY-BEfGIpzu.js +0 -1
- package/web/dist/assets/index-CniHcFxT.js +0 -22
- package/web/dist/assets/index-DYz2iP_B.css +0 -10
- package/web/dist/assets/stateDiagram-v2-MP3YSRHH-DagWhIFJ.js +0 -1
- package/web/dist/assets/swimlanesDiagram-VR7AAH4N-Dsi9x540.js +0 -8
package/README.md
CHANGED
|
@@ -2171,6 +2171,13 @@ export class ClientSession {
|
|
|
2171
2171
|
cwd: conv.cwd,
|
|
2172
2172
|
messageCount,
|
|
2173
2173
|
isStreaming,
|
|
2174
|
+
// resolve() so it is byte-comparable with the paths
|
|
2175
|
+
// SessionManager.list() reports to the client — the two are
|
|
2176
|
+
// compared as plain strings there, and an unnormalized form
|
|
2177
|
+
// here would make the dedup silently miss.
|
|
2178
|
+
sessionFile: conv.session.sessionFile
|
|
2179
|
+
? resolve(conv.session.sessionFile)
|
|
2180
|
+
: undefined,
|
|
2174
2181
|
});
|
|
2175
2182
|
}
|
|
2176
2183
|
this.emit({
|
|
@@ -2190,8 +2197,6 @@ export class ClientSession {
|
|
|
2190
2197
|
await this.pushSessions();
|
|
2191
2198
|
}
|
|
2192
2199
|
async pushSessions() {
|
|
2193
|
-
if (!this.sessionsRequested)
|
|
2194
|
-
return;
|
|
2195
2200
|
if (!this.sessionsRequested)
|
|
2196
2201
|
return;
|
|
2197
2202
|
try {
|
|
@@ -2201,8 +2206,14 @@ export class ClientSession {
|
|
|
2201
2206
|
const infos = await SessionManager.list(this.cwd);
|
|
2202
2207
|
const sessions = new Map();
|
|
2203
2208
|
for (const s of infos) {
|
|
2204
|
-
|
|
2205
|
-
|
|
2209
|
+
// Normalized to the same form as ConversationSummary.sessionFile:
|
|
2210
|
+
// the client compares the two as plain strings to hide a running
|
|
2211
|
+
// conversation from this list. resolve() only makes absolute and
|
|
2212
|
+
// collapses ./.. — it does not follow symlinks, so identity is
|
|
2213
|
+
// unchanged for switch/delete/rename, which resolve() anyway.
|
|
2214
|
+
const path = resolve(s.path);
|
|
2215
|
+
sessions.set(path, {
|
|
2216
|
+
path,
|
|
2206
2217
|
name: s.name,
|
|
2207
2218
|
firstMessage: s.firstMessage,
|
|
2208
2219
|
messageCount: s.messageCount,
|
|
@@ -2261,6 +2272,99 @@ export class ClientSession {
|
|
|
2261
2272
|
});
|
|
2262
2273
|
}
|
|
2263
2274
|
}
|
|
2275
|
+
/** List subdirectories for the workspace picker (`browse_dirs`).
|
|
2276
|
+
*
|
|
2277
|
+
* Deliberately NOT routed through FilesService.listFiles(), which pins
|
|
2278
|
+
* every listing inside the current workspace — choosing a new workspace
|
|
2279
|
+
* is exactly the case that has to look outside it. Scope is kept narrow
|
|
2280
|
+
* instead: directory *names* only, never file contents, and the same
|
|
2281
|
+
* loopback binding + PI_WEB_TOKEN auth as every other message guards it.
|
|
2282
|
+
* (The agent can already shell out with bash, so this exposes nothing it
|
|
2283
|
+
* could not already reach — it just makes it clickable.)
|
|
2284
|
+
*/
|
|
2285
|
+
async browseDirs(path) {
|
|
2286
|
+
const { homedir } = await import("node:os");
|
|
2287
|
+
const fs = await import("node:fs/promises");
|
|
2288
|
+
const { dirname } = await import("node:path");
|
|
2289
|
+
const MAX = 500;
|
|
2290
|
+
const target = resolve(path?.trim() || homedir());
|
|
2291
|
+
try {
|
|
2292
|
+
const dirents = await fs.readdir(target, { withFileTypes: true });
|
|
2293
|
+
const dirs = [];
|
|
2294
|
+
for (const d of dirents) {
|
|
2295
|
+
// Symlinked directories are worth following (project checkouts
|
|
2296
|
+
// are often symlinked), but a broken link must not abort the
|
|
2297
|
+
// whole listing — isDirectory() is false for those, which is
|
|
2298
|
+
// the behaviour we want anyway.
|
|
2299
|
+
if (!d.isDirectory())
|
|
2300
|
+
continue;
|
|
2301
|
+
if (d.name.startsWith("."))
|
|
2302
|
+
continue; // dotfolders: noise here
|
|
2303
|
+
dirs.push(d.name);
|
|
2304
|
+
if (dirs.length >= MAX)
|
|
2305
|
+
break;
|
|
2306
|
+
}
|
|
2307
|
+
dirs.sort((a, b) => a.localeCompare(b));
|
|
2308
|
+
const parent = dirname(target);
|
|
2309
|
+
this.emit({
|
|
2310
|
+
type: "dir_browse",
|
|
2311
|
+
path: target,
|
|
2312
|
+
parent: parent === target ? null : parent,
|
|
2313
|
+
dirs,
|
|
2314
|
+
truncated: dirs.length >= MAX,
|
|
2315
|
+
drives: await listWindowsDrives(),
|
|
2316
|
+
});
|
|
2317
|
+
}
|
|
2318
|
+
catch (err) {
|
|
2319
|
+
this.emit({
|
|
2320
|
+
type: "notice",
|
|
2321
|
+
level: "error",
|
|
2322
|
+
text: `无法读取目录:${err.message}`,
|
|
2323
|
+
});
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
/** Rename a persisted session (history list ✎).
|
|
2327
|
+
*
|
|
2328
|
+
* The display name lives in the transcript itself as a `session_info`
|
|
2329
|
+
* entry, so renaming means appending one via the SDK rather than touching
|
|
2330
|
+
* any sidecar state — `SessionManager.list()` already surfaces the latest
|
|
2331
|
+
* one as `SessionInfo.name`, which is what the panel renders. An empty
|
|
2332
|
+
* name clears it and the list falls back to the first user message.
|
|
2333
|
+
*/
|
|
2334
|
+
async renameSession(path, name) {
|
|
2335
|
+
try {
|
|
2336
|
+
const abs = resolve(path);
|
|
2337
|
+
// Same guardrail as deleteSession: only transcripts under the
|
|
2338
|
+
// shared sessions root may be written, never arbitrary files.
|
|
2339
|
+
const sessionsRoot = resolve(this.agentDir, "sessions");
|
|
2340
|
+
if (!abs.startsWith(sessionsRoot + sep)) {
|
|
2341
|
+
this.emit({
|
|
2342
|
+
type: "notice",
|
|
2343
|
+
level: "error",
|
|
2344
|
+
text: "只能重命名会话目录中的对话记录",
|
|
2345
|
+
});
|
|
2346
|
+
return;
|
|
2347
|
+
}
|
|
2348
|
+
const trimmed = name.trim().slice(0, 120);
|
|
2349
|
+
// A live conversation holds its own SessionManager on this file;
|
|
2350
|
+
// append through that one so the two don't fight over the tail.
|
|
2351
|
+
const liveConv = [...this.convs.values()].find((conv) => conv.session.sessionFile === abs);
|
|
2352
|
+
if (liveConv) {
|
|
2353
|
+
liveConv.session.sessionManager.appendSessionInfo(trimmed);
|
|
2354
|
+
}
|
|
2355
|
+
else {
|
|
2356
|
+
SessionManager.open(abs).appendSessionInfo(trimmed);
|
|
2357
|
+
}
|
|
2358
|
+
await this.refreshSessions();
|
|
2359
|
+
}
|
|
2360
|
+
catch (err) {
|
|
2361
|
+
this.emit({
|
|
2362
|
+
type: "notice",
|
|
2363
|
+
level: "error",
|
|
2364
|
+
text: `重命名会话失败:${err.message}`,
|
|
2365
|
+
});
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2264
2368
|
/** Open a persisted session as the active conversation (from listSessions).
|
|
2265
2369
|
*
|
|
2266
2370
|
* A persisted-session click must follow the same ownership rule as
|
|
@@ -2779,6 +2883,33 @@ export class ClientSession {
|
|
|
2779
2883
|
}
|
|
2780
2884
|
}
|
|
2781
2885
|
}
|
|
2886
|
+
/**
|
|
2887
|
+
* Windows drive roots that currently exist ("C:\\", "D:\\", …); empty on
|
|
2888
|
+
* POSIX (where "/" already reaches everything).
|
|
2889
|
+
*
|
|
2890
|
+
* Needed because Windows has no unified filesystem root: dirname("C:\\") is
|
|
2891
|
+
* "C:\\", so the picker's walk-up hits a ceiling on the boot drive and can
|
|
2892
|
+
* never reach D:. Probing A–Z with access() avoids shelling out to wmic /
|
|
2893
|
+
* PowerShell (both slow to spawn, and wmic is gone on recent Windows).
|
|
2894
|
+
* Missing/empty drives simply reject, so they drop out.
|
|
2895
|
+
*/
|
|
2896
|
+
async function listWindowsDrives() {
|
|
2897
|
+
if (process.platform !== "win32")
|
|
2898
|
+
return undefined;
|
|
2899
|
+
const fs = await import("node:fs/promises");
|
|
2900
|
+
const letters = Array.from({ length: 26 }, (_, i) => String.fromCharCode(65 + i));
|
|
2901
|
+
const found = await Promise.all(letters.map(async (letter) => {
|
|
2902
|
+
const root = `${letter}:\\`;
|
|
2903
|
+
try {
|
|
2904
|
+
await fs.access(root);
|
|
2905
|
+
return root;
|
|
2906
|
+
}
|
|
2907
|
+
catch {
|
|
2908
|
+
return null;
|
|
2909
|
+
}
|
|
2910
|
+
}));
|
|
2911
|
+
return found.filter((d) => d !== null);
|
|
2912
|
+
}
|
|
2782
2913
|
export class AgentService {
|
|
2783
2914
|
cwd;
|
|
2784
2915
|
/** index.ts 注入:SDK 工具执行事件的插件转发钩子,attach 时拷贝到每个新会话。 */
|
package/dist/server/index.js
CHANGED
|
@@ -558,6 +558,12 @@ wss.on("connection", (ws) => {
|
|
|
558
558
|
case "delete_session":
|
|
559
559
|
void cs.deleteSession(msg.path);
|
|
560
560
|
break;
|
|
561
|
+
case "rename_session":
|
|
562
|
+
void cs.renameSession(msg.path, msg.name);
|
|
563
|
+
break;
|
|
564
|
+
case "browse_dirs":
|
|
565
|
+
void cs.browseDirs(msg.path);
|
|
566
|
+
break;
|
|
561
567
|
case "switch_session":
|
|
562
568
|
void cs.switchSession(msg.path);
|
|
563
569
|
break;
|
|
@@ -215,8 +215,27 @@ export async function checkPluginUpdates(dataDir, exec = execGit) {
|
|
|
215
215
|
}
|
|
216
216
|
return out;
|
|
217
217
|
}
|
|
218
|
+
/** Last stamp handed out, so the next one is always strictly greater. */
|
|
219
|
+
let lastStampMs = 0;
|
|
220
|
+
/**
|
|
221
|
+
* Backup directory name: `YYYYMMDD-HHMMSSmmm`.
|
|
222
|
+
*
|
|
223
|
+
* Monotonic on purpose. The name is the backup's only identity — two calls
|
|
224
|
+
* landing in the same millisecond produced the same directory, so the second
|
|
225
|
+
* cpSync() merged into the first instead of creating a new backup, silently
|
|
226
|
+
* losing one and leaving pruneBackups() keeping fewer than `keep`. Taking
|
|
227
|
+
* several backups in a row is fast enough that this is not theoretical: eight
|
|
228
|
+
* consecutive calls routinely share a millisecond.
|
|
229
|
+
*
|
|
230
|
+
* Colliding calls are pushed to the next millisecond rather than given a
|
|
231
|
+
* disambiguating suffix, because listBackups() matches names against a strict
|
|
232
|
+
* `\d{8}-\d{9}$` pattern — a suffixed backup would be invisible to it, and
|
|
233
|
+
* therefore never pruned either.
|
|
234
|
+
*/
|
|
218
235
|
function stamp() {
|
|
219
|
-
const
|
|
236
|
+
const now = Math.max(Date.now(), lastStampMs + 1);
|
|
237
|
+
lastStampMs = now;
|
|
238
|
+
const d = new Date(now);
|
|
220
239
|
const p = (x, n = 2) => String(x).padStart(n, "0");
|
|
221
240
|
return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}-${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}${p(d.getMilliseconds(), 3)}`;
|
|
222
241
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@youweichen/pi-web-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.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": {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as d,j as t}from"./markdown-CUPbftfV.js";import{u as H,F as O,a as R,b as P,c as q,d as L,e as G,f as J,g as V,r as W}from"./index-
|
|
1
|
+
import{a as d,j as t}from"./markdown-CUPbftfV.js";import{u as H,F as O,a as R,b as P,c as q,d as L,e as G,f as J,g as V,r as W}from"./index-C-XJ-ly_.js";import{D as X,o as Y}from"./xterm-D1D2FVe3.js";import"./react-ZkKJMDQQ.js";const $="pi-web-ui:theme-change";function A(){const s=getComputedStyle(document.documentElement),n=(f,r)=>s.getPropertyValue(f).trim()||r;return{background:n("--term-bg","#1b1f24"),foreground:n("--term-fg","#e6e8ef"),cursor:n("--term-cursor","#3b49df"),cursorAccent:n("--term-cursor-accent","#1b1f24"),selectionBackground:n("--term-selection","rgba(59, 73, 223, 0.35)"),black:n("--term-black","#2a2f37"),red:n("--term-red","#f87171"),green:n("--term-green","#34d399"),yellow:n("--term-yellow","#fbbf24"),blue:n("--term-blue","#60a5fa"),magenta:n("--term-magenta","#c084fc"),cyan:n("--term-cyan","#22d3ee"),white:n("--term-white","#e6e8ef"),brightBlack:n("--term-bright-black","#6b7284"),brightRed:n("--term-bright-red","#f87171"),brightGreen:n("--term-bright-green","#34d399"),brightYellow:n("--term-bright-yellow","#fbbf24"),brightBlue:n("--term-bright-blue","#60a5fa"),brightMagenta:n("--term-bright-magenta","#c084fc"),brightCyan:n("--term-bright-cyan","#22d3ee"),brightWhite:n("--term-bright-white","#ffffff")}}function Q({conversationId:s,terminalId:n,command:f,cwd:r,active:p,send:o,register:j}){const g=d.useRef(null),y=d.useRef(null),N=f?JSON.stringify(f):"";return d.useEffect(()=>{const h=g.current;if(!h)return;const a=new X({theme:A(),fontFamily:'"SF Mono", "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace',fontSize:13,cursorBlink:!0,scrollback:8e3}),l=new Y;a.loadAddon(l),a.open(h),y.current={term:a,fit:l},p&&a.focus();const x=()=>{a.options.theme=A()};window.addEventListener($,x),a.attachCustomKeyEventHandler(m=>{var F;if(m.type!=="keydown")return!0;const E=(F=m.key)==null?void 0:F.toLowerCase();if((m.ctrlKey||m.metaKey)&&E==="v")return!1;if(m.ctrlKey&&!m.shiftKey&&!m.altKey&&E==="c"&&a.hasSelection()){const k=a.textarea;return k&&(k.value=a.getSelection(),k.select()),!1}return!0});const v=j(s,n,{write:m=>a.write(m),dispose:()=>a.dispose()}),C=()=>{try{l.fit(),o({type:"terminal_resize",terminalId:n,conversationId:s,cols:a.cols,rows:a.rows})}catch{}},b=requestAnimationFrame(()=>{try{l.fit()}catch{}o(f?{type:"run_command",terminalId:n,conversationId:s,command:f,cols:a.cols,rows:a.rows}:{type:"terminal_create",terminalId:n,conversationId:s,cwd:r,cols:a.cols,rows:a.rows})}),T=a.onData(m=>{o({type:"terminal_input",terminalId:n,conversationId:s,data:m})});let w=null;return typeof ResizeObserver<"u"&&(w=new ResizeObserver(()=>{h.offsetWidth>0&&h.offsetHeight>0&&C()}),w.observe(h)),()=>{cancelAnimationFrame(b),T.dispose(),window.removeEventListener($,x),w==null||w.disconnect(),v(),a.dispose(),y.current=null}},[s,n,N,o,j]),d.useEffect(()=>{if(!p)return;const h=requestAnimationFrame(()=>{const a=y.current;if(a){try{a.fit.fit(),o({type:"terminal_resize",terminalId:n,conversationId:s,cols:a.term.cols,rows:a.term.rows})}catch{}a.term.focus()}});return()=>cancelAnimationFrame(h)},[p]),t.jsx("div",{ref:g,className:`term-xterm ${p?"":"hidden"}`})}const K={name:"",command:"",cwd:"${pwd}"};function ne({chat:s,send:n,terminal:f}){const r=H(),[p,o]=d.useState(null),[j,g]=d.useState(!1),[y,N]=d.useState(!1),[h,a]=d.useState(null),[l,x]=d.useState(K),[v,C]=d.useState(null),b=d.useRef(null);d.useEffect(()=>{s.terminals.length===0?o(null):s.terminals.some(e=>e.id===p)||o(s.terminals[s.terminals.length-1].id)},[s.terminals,p]),d.useEffect(()=>()=>{b.current&&clearTimeout(b.current)},[]);const T=e=>{var u;if(!s.ready)return;const i=W(),c=s.activeConversationId||((u=s.state)==null?void 0:u.conversationId)||"";f.create({...e,id:i,conversationId:c,cols:e.cols??80,rows:e.rows??24,running:!0,exitCode:null}),o(i),g(!1)},w=()=>{var e;return T({title:r("terminalTitle",{n:s.terminals.length+1}),cwd:((e=s.state)==null?void 0:e.cwd)??""})},m=e=>{var u;const i=e.name||e.command,c=s.terminals.find(_=>_.title===i);if(c){f.restart(c.id),o(c.id),n({type:"run_command",terminalId:c.id,conversationId:c.conversationId,command:e,cols:80,rows:24});return}T({title:i,cwd:((u=s.state)==null?void 0:u.cwd)??"",command:e})},E=e=>{const i=s.terminals.find(c=>c.id===e);if(i&&n({type:"terminal_kill",terminalId:e,conversationId:i.conversationId}),f.close(e),p===e){const c=s.terminals.filter(u=>u.id!==e);o(c.length>0?c[c.length-1].id:null)}},F=()=>{N(!0),a(null),x(K)},k=e=>{const i=s.commands[e];i&&(N(!1),a(e),x({name:i.name,command:i.command,cwd:i.cwd??""}))},D=()=>{N(!1),a(null)},S=()=>{const e=l.name.trim(),i=l.command.trim();if(!e||!i)return;const c=l.cwd.trim(),u={name:e,command:i,cwd:c||void 0},_=y?[...s.commands,u]:h!==null?s.commands.map((z,B)=>B===h?u:z):s.commands;n({type:"save_commands",commands:_}),D()},M=e=>{if(v===e){const i=s.commands.filter((c,u)=>u!==e);n({type:"save_commands",commands:i}),C(null),b.current&&clearTimeout(b.current)}else C(e),b.current&&clearTimeout(b.current),b.current=setTimeout(()=>C(null),2500)},I=y||h!==null;return t.jsxs("div",{className:"terminal-view",children:[t.jsxs("aside",{className:`term-side term-commands ${j?"open":""}`,children:[t.jsxs("div",{className:"panel-header",children:[t.jsx("span",{className:"panel-title",children:r("commands")}),t.jsxs("div",{className:"panel-header-actions",children:[t.jsx("button",{type:"button",className:"panel-refresh",title:r("rerun"),onClick:()=>n({type:"list_commands"}),children:t.jsx(O,{})}),t.jsx("button",{type:"button",className:"panel-new",title:r("newCommand"),onClick:F,children:t.jsx(R,{})})]})]}),t.jsx("div",{className:"panel-body",children:I?t.jsxs("div",{className:"cmd-form",children:[t.jsx("label",{htmlFor:"cmd-name",children:r("name")}),t.jsx("input",{id:"cmd-name",className:"cmd-input",value:l.name,placeholder:r("exampleName"),autoFocus:!0,onChange:e=>x({...l,name:e.target.value})}),t.jsx("label",{htmlFor:"cmd-command",children:r("command")}),t.jsx("input",{id:"cmd-command",className:"cmd-input",value:l.command,placeholder:r("exampleCommand"),onChange:e=>x({...l,command:e.target.value}),onKeyDown:e=>{e.key==="Enter"&&!e.nativeEvent.isComposing&&S()}}),t.jsxs("label",{htmlFor:"cmd-cwd",children:[r("directory")," ",t.jsx("span",{className:"cmd-hint",children:r("cwdHint")})]}),t.jsx("input",{id:"cmd-cwd",className:"cmd-input",value:l.cwd,placeholder:"${pwd}",onChange:e=>x({...l,cwd:e.target.value}),onKeyDown:e=>{e.key==="Enter"&&!e.nativeEvent.isComposing&&S()}}),t.jsxs("div",{className:"cmd-form-actions",children:[t.jsx("button",{type:"button",className:"btn",onClick:D,children:r("cancel")}),t.jsx("button",{type:"button",className:"btn primary",disabled:!l.name.trim()||!l.command.trim(),onClick:S,children:r("save")})]})]}):t.jsxs(t.Fragment,{children:[s.commands.length===0&&t.jsx("div",{className:"panel-empty",children:r("noCommands")}),s.commands.map((e,i)=>t.jsxs("div",{className:"cmd-item",children:[t.jsx("button",{type:"button",className:"cmd-run",title:r("clickToRun"),onClick:()=>m(e),children:t.jsx(P,{})}),t.jsxs("button",{type:"button",className:"cmd-main",title:r("clickToRun"),onClick:()=>m(e),children:[t.jsx("span",{className:"cmd-name",children:e.name}),t.jsx("span",{className:"cmd-command",children:e.command}),e.cwd&&t.jsx("span",{className:"cmd-cwd",children:e.cwd})]}),t.jsx("button",{type:"button",className:"cmd-act",title:r("edit"),onClick:()=>k(i),children:t.jsx(q,{})}),t.jsx("button",{type:"button",className:`cmd-act del ${v===i?"confirm":""}`,title:r("delete"),onClick:()=>M(i),children:v===i?r("confirmQ"):t.jsx(L,{})})]},i))]})}),t.jsxs("div",{className:"term-tabs-block",children:[t.jsxs("div",{className:"panel-header",children:[t.jsx("span",{className:"panel-title",children:r("terminal")}),t.jsx("button",{type:"button",className:"panel-new",title:r("newTerminal"),onClick:w,children:t.jsx(R,{})})]}),t.jsxs("div",{className:"panel-body",children:[s.terminals.length===0&&t.jsx("div",{className:"panel-empty",children:r("noTerminal")}),s.terminals.map(e=>t.jsxs("div",{className:`term-tab ${e.id===p?"active":""}`,children:[t.jsxs("button",{type:"button",className:"term-tab-main",title:`${e.cwd}${e.command?`
|
|
2
2
|
> ${e.command.command}`:""}`,onClick:()=>{o(e.id),g(!1)},children:[t.jsx("span",{className:`term-tab-dot ${e.running?"run":"exit"}`}),t.jsxs("span",{className:"term-tab-title",children:[e.title,!e.running&&t.jsx("span",{className:"term-tab-exit",children:r("exited",{code:e.exitCode===null?"":` ${e.exitCode}`})})]})]}),t.jsx("button",{type:"button",className:"term-tab-close",title:r("closeTerminal"),onClick:()=>E(e.id),children:t.jsx(G,{})})]},e.id))]})]})]}),t.jsxs("div",{className:"term-main",children:[j&&t.jsx("div",{className:"drawer-backdrop",onClick:()=>g(!1)}),t.jsx("button",{type:"button",className:"term-side-toggle",title:r("commands"),onClick:()=>g(e=>!e),children:t.jsx(J,{})}),s.terminals.length===0?t.jsxs("div",{className:"term-empty",children:[t.jsx(V,{className:"term-empty-icon"}),t.jsx("div",{className:"term-empty-title",children:r("builtinTerminal")}),t.jsx("div",{className:"term-empty-sub",children:r("termEmptySub")})]}):s.terminals.map(e=>t.jsx(Q,{conversationId:e.conversationId,terminalId:e.id,command:e.command,cwd:e.cwd,active:e.id===p,send:n,register:f.register},`${e.conversationId}:${e.id}`))]})]})}export{ne as TerminalPanel};
|
package/web/dist/assets/{abnfDiagram-VCTEODGH-Ct5StJwt.js → abnfDiagram-VCTEODGH-BKPpCrz_.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-BOWUorML.js";import{p as f}from"./chunk-JWPE2WC7-BxQUQ7dH.js";import{_ as n,l as o}from"./mermaid.core-DDk4A0BP.js";import{M as c,b as d}from"./cynefin-OW5HDTMX-DmSGPBbN.js";import"./index-C-XJ-ly_.js";import"./markdown-CUPbftfV.js";import"./react-ZkKJMDQQ.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-DDk4A0BP.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};
|