@openspecui/web 1.5.0 → 1.6.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/dist/assets/{BufferResource-Bn1UWy0D.js → BufferResource-LpIscPOh.js} +1 -1
- package/dist/assets/{CanvasRenderer-D8NiU8la.js → CanvasRenderer-hdBAgk8Z.js} +1 -1
- package/dist/assets/{Filter-CRwq487x.js → Filter-DJVBXWdE.js} +1 -1
- package/dist/assets/{RenderTargetSystem-CtoB_qTm.js → RenderTargetSystem-CEuUrT8d.js} +1 -1
- package/dist/assets/{WebGLRenderer-BgKO8R0a.js → WebGLRenderer-DUSFltAk.js} +1 -1
- package/dist/assets/{WebGPURenderer-CQeL2efC.js → WebGPURenderer-DafJULoy.js} +1 -1
- package/dist/assets/{browserAll-DP6sOYev.js → browserAll-DYvdsmhE.js} +1 -1
- package/dist/assets/{ghostty-web-evxujSxm.js → ghostty-web-BitlvuYh.js} +1 -1
- package/dist/assets/{index-BnT52DZ8.js → index-5zLYkWge.js} +1 -1
- package/dist/assets/{index-B0IbsqHi.js → index-B8AH-4mO.js} +1 -1
- package/dist/assets/{index-D2Tp4F9B.js → index-BXlwoClD.js} +1 -1
- package/dist/assets/{index-dSf1u0YV.js → index-BhxOfd1V.js} +1 -1
- package/dist/assets/{index-f0QdJSzm.js → index-BwqUcS4o.js} +1 -1
- package/dist/assets/{index-DTeOcXKn.js → index-CGTRVPmS.js} +1 -1
- package/dist/assets/{index-T8xoxmUb.js → index-CKfGQiMr.js} +236 -205
- package/dist/assets/{index-BejnsZfY.js → index-CYTyn82I.js} +1 -1
- package/dist/assets/{index-DJqmTRAR.js → index-CjHce-bH.js} +1 -1
- package/dist/assets/{index-B147AOgf.js → index-CuiBRRWA.js} +1 -1
- package/dist/assets/{index-BPZ3nG0r.js → index-DEgCfC-b.js} +1 -1
- package/dist/assets/{index-DcXyAs0z.js → index-DbrGteUX.js} +1 -1
- package/dist/assets/{index-BMashGQn.js → index-Dge9ymDE.js} +1 -1
- package/dist/assets/{index-CBCPR3Qb.js → index-DtJ1xKq6.js} +1 -1
- package/dist/assets/index-USotIqwU.css +1 -0
- package/dist/assets/{index-D6ardy54.js → index-gPPYc26D.js} +1 -1
- package/dist/assets/{index-4MAU81Qk.js → index-hXwe0Xwc.js} +1 -1
- package/dist/assets/{webworkerAll-DA2HufNb.js → webworkerAll-CFbGR7bA.js} +1 -1
- package/dist/index.html +2 -2
- package/dist-ssg/client/.vite/ssr-manifest.json +25 -23
- package/dist-ssg/client/assets/{index-nXK46PJX.js → index-BTlc4gRd.js} +1 -1
- package/dist-ssg/client/assets/{index-CkIJT9VM.js → index-BWss1-RY.js} +1 -1
- package/dist-ssg/client/assets/{index-neDlRvdc.js → index-BiJDZ6HF.js} +1 -1
- package/dist-ssg/client/assets/{index-C1d9Zuhl.js → index-CXPcc7SN.js} +1 -1
- package/dist-ssg/client/assets/{index-CsRZVfC5.js → index-CZlM3xpa.js} +1 -1
- package/dist-ssg/client/assets/{index-BNvK4AuA.js → index-ChGuHVYh.js} +1 -1
- package/dist-ssg/client/assets/{index-DuI28swy.js → index-D05l7owO.js} +1 -1
- package/dist-ssg/client/assets/{index-lmUf9UYl.js → index-DDs25DSq.js} +1 -1
- package/dist-ssg/client/assets/{index-DaAYjM02.js → index-DGbspcQI.js} +1 -1
- package/dist-ssg/client/assets/{index-DoT0nwXT.js → index-DMgvGt5z.js} +1 -1
- package/dist-ssg/client/assets/{index-CfKJRsCY.js → index-DRxWBSjo.js} +1 -1
- package/dist-ssg/client/assets/{index-Qc9PpyXL.js → index-DbUWuKU6.js} +1 -1
- package/dist-ssg/client/assets/index-Di6aqhqv.css +1 -0
- package/dist-ssg/client/assets/{index-Bts5PKwE.js → index-Dw5LFumn.js} +1 -1
- package/dist-ssg/client/assets/{index-BKuRbAoU.js → index-JFh0HIYc.js} +1 -1
- package/dist-ssg/client/assets/{index-BPqe-tty.js → index-LZFdJ_jX.js} +1 -1
- package/dist-ssg/client/assets/index.ssg-2R4_pvpx.js +631 -0
- package/dist-ssg/client/index.ssg.html +2 -2
- package/dist-ssg/server/entry-server.js +829 -321
- package/dist-ssg/ssg-cli.mjs +27 -2
- package/package.json +2 -2
- package/dist/assets/index-Ys2MTD3W.css +0 -1
- package/dist-ssg/client/assets/index-42NXIrUL.css +0 -1
- package/dist-ssg/client/assets/index.ssg-B7Yw_6vy.js +0 -600
|
@@ -36333,23 +36333,23 @@ const createLucideIcon = (iconName, iconNode) => {
|
|
|
36333
36333
|
Component.displayName = `${iconName}`;
|
|
36334
36334
|
return Component;
|
|
36335
36335
|
};
|
|
36336
|
-
const __iconNode$
|
|
36336
|
+
const __iconNode$P = [
|
|
36337
36337
|
["rect", { width: "20", height: "5", x: "2", y: "3", rx: "1", key: "1wp1u1" }],
|
|
36338
36338
|
["path", { d: "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8", key: "1s80jp" }],
|
|
36339
36339
|
["path", { d: "M10 12h4", key: "a56b0p" }]
|
|
36340
36340
|
];
|
|
36341
|
-
const Archive = createLucideIcon("Archive", __iconNode$
|
|
36342
|
-
const __iconNode$
|
|
36341
|
+
const Archive = createLucideIcon("Archive", __iconNode$P);
|
|
36342
|
+
const __iconNode$O = [
|
|
36343
36343
|
["path", { d: "m12 19-7-7 7-7", key: "1l729n" }],
|
|
36344
36344
|
["path", { d: "M19 12H5", key: "x3x0zl" }]
|
|
36345
36345
|
];
|
|
36346
|
-
const ArrowLeft = createLucideIcon("ArrowLeft", __iconNode$
|
|
36347
|
-
const __iconNode$
|
|
36346
|
+
const ArrowLeft = createLucideIcon("ArrowLeft", __iconNode$O);
|
|
36347
|
+
const __iconNode$N = [
|
|
36348
36348
|
["path", { d: "M5 12h14", key: "1ays0h" }],
|
|
36349
36349
|
["path", { d: "m12 5 7 7-7 7", key: "xquz4c" }]
|
|
36350
36350
|
];
|
|
36351
|
-
const ArrowRight = createLucideIcon("ArrowRight", __iconNode$
|
|
36352
|
-
const __iconNode$
|
|
36351
|
+
const ArrowRight = createLucideIcon("ArrowRight", __iconNode$N);
|
|
36352
|
+
const __iconNode$M = [
|
|
36353
36353
|
[
|
|
36354
36354
|
"path",
|
|
36355
36355
|
{
|
|
@@ -36359,63 +36359,63 @@ const __iconNode$L = [
|
|
|
36359
36359
|
],
|
|
36360
36360
|
["circle", { cx: "12", cy: "13", r: "3", key: "1vg3eu" }]
|
|
36361
36361
|
];
|
|
36362
|
-
const Camera = createLucideIcon("Camera", __iconNode$
|
|
36363
|
-
const __iconNode$
|
|
36364
|
-
const Check = createLucideIcon("Check", __iconNode$
|
|
36365
|
-
const __iconNode$
|
|
36366
|
-
const ChevronDown = createLucideIcon("ChevronDown", __iconNode$
|
|
36367
|
-
const __iconNode$
|
|
36368
|
-
const ChevronRight = createLucideIcon("ChevronRight", __iconNode$
|
|
36369
|
-
const __iconNode$
|
|
36362
|
+
const Camera = createLucideIcon("Camera", __iconNode$M);
|
|
36363
|
+
const __iconNode$L = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
|
|
36364
|
+
const Check = createLucideIcon("Check", __iconNode$L);
|
|
36365
|
+
const __iconNode$K = [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]];
|
|
36366
|
+
const ChevronDown = createLucideIcon("ChevronDown", __iconNode$K);
|
|
36367
|
+
const __iconNode$J = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
|
|
36368
|
+
const ChevronRight = createLucideIcon("ChevronRight", __iconNode$J);
|
|
36369
|
+
const __iconNode$I = [
|
|
36370
36370
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
36371
36371
|
["line", { x1: "12", x2: "12", y1: "8", y2: "12", key: "1pkeuh" }],
|
|
36372
36372
|
["line", { x1: "12", x2: "12.01", y1: "16", y2: "16", key: "4dfq90" }]
|
|
36373
36373
|
];
|
|
36374
|
-
const CircleAlert = createLucideIcon("CircleAlert", __iconNode$
|
|
36375
|
-
const __iconNode$
|
|
36374
|
+
const CircleAlert = createLucideIcon("CircleAlert", __iconNode$I);
|
|
36375
|
+
const __iconNode$H = [
|
|
36376
36376
|
["path", { d: "M21.801 10A10 10 0 1 1 17 3.335", key: "yps3ct" }],
|
|
36377
36377
|
["path", { d: "m9 11 3 3L22 4", key: "1pflzl" }]
|
|
36378
36378
|
];
|
|
36379
|
-
const CircleCheckBig = createLucideIcon("CircleCheckBig", __iconNode$
|
|
36380
|
-
const __iconNode$
|
|
36379
|
+
const CircleCheckBig = createLucideIcon("CircleCheckBig", __iconNode$H);
|
|
36380
|
+
const __iconNode$G = [
|
|
36381
36381
|
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
36382
36382
|
["path", { d: "m9 12 2 2 4-4", key: "dzmm74" }]
|
|
36383
36383
|
];
|
|
36384
|
-
const CircleCheck = createLucideIcon("CircleCheck", __iconNode$
|
|
36385
|
-
const __iconNode$
|
|
36386
|
-
const Circle = createLucideIcon("Circle", __iconNode$
|
|
36387
|
-
const __iconNode$
|
|
36384
|
+
const CircleCheck = createLucideIcon("CircleCheck", __iconNode$G);
|
|
36385
|
+
const __iconNode$F = [["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }]];
|
|
36386
|
+
const Circle = createLucideIcon("Circle", __iconNode$F);
|
|
36387
|
+
const __iconNode$E = [
|
|
36388
36388
|
["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
|
|
36389
36389
|
["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
|
|
36390
36390
|
];
|
|
36391
|
-
const Copy = createLucideIcon("Copy", __iconNode$
|
|
36392
|
-
const __iconNode$
|
|
36391
|
+
const Copy = createLucideIcon("Copy", __iconNode$E);
|
|
36392
|
+
const __iconNode$D = [
|
|
36393
36393
|
["circle", { cx: "12", cy: "12", r: "1", key: "41hilf" }],
|
|
36394
36394
|
["circle", { cx: "12", cy: "5", r: "1", key: "gxeob9" }],
|
|
36395
36395
|
["circle", { cx: "12", cy: "19", r: "1", key: "lyex9k" }]
|
|
36396
36396
|
];
|
|
36397
|
-
const EllipsisVertical = createLucideIcon("EllipsisVertical", __iconNode$
|
|
36398
|
-
const __iconNode$
|
|
36397
|
+
const EllipsisVertical = createLucideIcon("EllipsisVertical", __iconNode$D);
|
|
36398
|
+
const __iconNode$C = [
|
|
36399
36399
|
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
36400
36400
|
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
|
|
36401
36401
|
["path", { d: "M9 15h6", key: "cctwl0" }],
|
|
36402
36402
|
["path", { d: "M12 18v-6", key: "17g6i2" }]
|
|
36403
36403
|
];
|
|
36404
|
-
const FilePlus = createLucideIcon("FilePlus", __iconNode$
|
|
36405
|
-
const __iconNode$
|
|
36404
|
+
const FilePlus = createLucideIcon("FilePlus", __iconNode$C);
|
|
36405
|
+
const __iconNode$B = [
|
|
36406
36406
|
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
36407
36407
|
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
|
|
36408
36408
|
["path", { d: "M10 9H8", key: "b1mrlr" }],
|
|
36409
36409
|
["path", { d: "M16 13H8", key: "t4e002" }],
|
|
36410
36410
|
["path", { d: "M16 17H8", key: "z1uh3a" }]
|
|
36411
36411
|
];
|
|
36412
|
-
const FileText = createLucideIcon("FileText", __iconNode$
|
|
36413
|
-
const __iconNode$
|
|
36412
|
+
const FileText = createLucideIcon("FileText", __iconNode$B);
|
|
36413
|
+
const __iconNode$A = [
|
|
36414
36414
|
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
36415
36415
|
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }]
|
|
36416
36416
|
];
|
|
36417
|
-
const File = createLucideIcon("File", __iconNode$
|
|
36418
|
-
const __iconNode$
|
|
36417
|
+
const File = createLucideIcon("File", __iconNode$A);
|
|
36418
|
+
const __iconNode$z = [
|
|
36419
36419
|
[
|
|
36420
36420
|
"path",
|
|
36421
36421
|
{
|
|
@@ -36424,8 +36424,8 @@ const __iconNode$y = [
|
|
|
36424
36424
|
}
|
|
36425
36425
|
]
|
|
36426
36426
|
];
|
|
36427
|
-
const FolderOpen = createLucideIcon("FolderOpen", __iconNode$
|
|
36428
|
-
const __iconNode$
|
|
36427
|
+
const FolderOpen = createLucideIcon("FolderOpen", __iconNode$z);
|
|
36428
|
+
const __iconNode$y = [
|
|
36429
36429
|
["path", { d: "M12 10v6", key: "1bos4e" }],
|
|
36430
36430
|
["path", { d: "M9 13h6", key: "1uhe8q" }],
|
|
36431
36431
|
[
|
|
@@ -36436,8 +36436,8 @@ const __iconNode$x = [
|
|
|
36436
36436
|
}
|
|
36437
36437
|
]
|
|
36438
36438
|
];
|
|
36439
|
-
const FolderPlus = createLucideIcon("FolderPlus", __iconNode$
|
|
36440
|
-
const __iconNode$
|
|
36439
|
+
const FolderPlus = createLucideIcon("FolderPlus", __iconNode$y);
|
|
36440
|
+
const __iconNode$x = [
|
|
36441
36441
|
[
|
|
36442
36442
|
"path",
|
|
36443
36443
|
{
|
|
@@ -36455,8 +36455,8 @@ const __iconNode$w = [
|
|
|
36455
36455
|
["path", { d: "M3 5a2 2 0 0 0 2 2h3", key: "f2jnh7" }],
|
|
36456
36456
|
["path", { d: "M3 3v13a2 2 0 0 0 2 2h3", key: "k8epm1" }]
|
|
36457
36457
|
];
|
|
36458
|
-
const FolderTree = createLucideIcon("FolderTree", __iconNode$
|
|
36459
|
-
const __iconNode$
|
|
36458
|
+
const FolderTree = createLucideIcon("FolderTree", __iconNode$x);
|
|
36459
|
+
const __iconNode$w = [
|
|
36460
36460
|
[
|
|
36461
36461
|
"path",
|
|
36462
36462
|
{
|
|
@@ -36465,20 +36465,31 @@ const __iconNode$v = [
|
|
|
36465
36465
|
}
|
|
36466
36466
|
]
|
|
36467
36467
|
];
|
|
36468
|
-
const Folder = createLucideIcon("Folder", __iconNode$
|
|
36469
|
-
const __iconNode$
|
|
36468
|
+
const Folder = createLucideIcon("Folder", __iconNode$w);
|
|
36469
|
+
const __iconNode$v = [
|
|
36470
36470
|
["line", { x1: "6", x2: "6", y1: "3", y2: "15", key: "17qcm7" }],
|
|
36471
36471
|
["circle", { cx: "18", cy: "6", r: "3", key: "1h7g24" }],
|
|
36472
36472
|
["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
|
|
36473
36473
|
["path", { d: "M18 9a9 9 0 0 1-9 9", key: "n2h4wq" }]
|
|
36474
36474
|
];
|
|
36475
|
-
const GitBranch = createLucideIcon("GitBranch", __iconNode$
|
|
36476
|
-
const __iconNode$
|
|
36475
|
+
const GitBranch = createLucideIcon("GitBranch", __iconNode$v);
|
|
36476
|
+
const __iconNode$u = [
|
|
36477
36477
|
["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }],
|
|
36478
36478
|
["line", { x1: "3", x2: "9", y1: "12", y2: "12", key: "1dyftd" }],
|
|
36479
36479
|
["line", { x1: "15", x2: "21", y1: "12", y2: "12", key: "oup4p8" }]
|
|
36480
36480
|
];
|
|
36481
|
-
const GitCommitHorizontal = createLucideIcon("GitCommitHorizontal", __iconNode$
|
|
36481
|
+
const GitCommitHorizontal = createLucideIcon("GitCommitHorizontal", __iconNode$u);
|
|
36482
|
+
const __iconNode$t = [
|
|
36483
|
+
[
|
|
36484
|
+
"path",
|
|
36485
|
+
{
|
|
36486
|
+
d: "M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4",
|
|
36487
|
+
key: "tonef"
|
|
36488
|
+
}
|
|
36489
|
+
],
|
|
36490
|
+
["path", { d: "M9 18c-4.51 2-5-2-7-2", key: "9comsn" }]
|
|
36491
|
+
];
|
|
36492
|
+
const Github = createLucideIcon("Github", __iconNode$t);
|
|
36482
36493
|
const __iconNode$s = [
|
|
36483
36494
|
["circle", { cx: "9", cy: "12", r: "1", key: "1vctgf" }],
|
|
36484
36495
|
["circle", { cx: "9", cy: "5", r: "1", key: "hp0tcf" }],
|
|
@@ -39512,6 +39523,80 @@ Click to copy`,
|
|
|
39512
39523
|
}
|
|
39513
39524
|
);
|
|
39514
39525
|
}
|
|
39526
|
+
const VIRTUAL_PROJECT_DIRNAME = "project";
|
|
39527
|
+
const WINDOWS_DRIVE_PREFIX = /^[A-Za-z]:\//;
|
|
39528
|
+
function normalizeFsPath$1(path2) {
|
|
39529
|
+
return path2.replace(/\\/g, "/").replace(/\/+$/g, "");
|
|
39530
|
+
}
|
|
39531
|
+
function isAbsolutePath(path2) {
|
|
39532
|
+
return path2.startsWith("/") || WINDOWS_DRIVE_PREFIX.test(path2);
|
|
39533
|
+
}
|
|
39534
|
+
function stripRelativePrefix(path2) {
|
|
39535
|
+
return path2.replace(/^\.?\//, "");
|
|
39536
|
+
}
|
|
39537
|
+
function splitSegments(path2) {
|
|
39538
|
+
return normalizeFsPath$1(path2).split("/").filter(Boolean);
|
|
39539
|
+
}
|
|
39540
|
+
function toNpmSpecifier(path2) {
|
|
39541
|
+
const normalized = normalizeFsPath$1(path2);
|
|
39542
|
+
const match = /(?:^|\/)node_modules\/(?:\.pnpm\/[^/]+\/node_modules\/)?(@[^/]+\/[^/]+|[^/]+)(\/.*)?/.exec(
|
|
39543
|
+
normalized
|
|
39544
|
+
);
|
|
39545
|
+
const pkgName = match?.[1];
|
|
39546
|
+
if (!pkgName) return null;
|
|
39547
|
+
const rest = match[2] ?? "";
|
|
39548
|
+
return `npm:${pkgName}${rest}`;
|
|
39549
|
+
}
|
|
39550
|
+
function toVirtualProjectPath(path2) {
|
|
39551
|
+
const normalized = stripRelativePrefix(path2);
|
|
39552
|
+
return `${VIRTUAL_PROJECT_DIRNAME}:${normalized}`;
|
|
39553
|
+
}
|
|
39554
|
+
function isPathInside$1(root2, target) {
|
|
39555
|
+
const normalizedRoot = normalizeFsPath$1(root2);
|
|
39556
|
+
const normalizedTarget = normalizeFsPath$1(target);
|
|
39557
|
+
const rootLower = normalizedRoot.toLowerCase();
|
|
39558
|
+
const targetLower = normalizedTarget.toLowerCase();
|
|
39559
|
+
return targetLower === rootLower || targetLower.startsWith(`${rootLower}/`);
|
|
39560
|
+
}
|
|
39561
|
+
function toRelativeFromRoot$1(root2, target) {
|
|
39562
|
+
const rootSegments = splitSegments(root2);
|
|
39563
|
+
const targetSegments = splitSegments(target);
|
|
39564
|
+
let index2 = 0;
|
|
39565
|
+
while (index2 < rootSegments.length && index2 < targetSegments.length) {
|
|
39566
|
+
if (rootSegments[index2]?.toLowerCase() !== targetSegments[index2]?.toLowerCase()) {
|
|
39567
|
+
break;
|
|
39568
|
+
}
|
|
39569
|
+
index2 += 1;
|
|
39570
|
+
}
|
|
39571
|
+
return targetSegments.slice(index2).join("/");
|
|
39572
|
+
}
|
|
39573
|
+
function findOpspecSlice(path2) {
|
|
39574
|
+
const segments = splitSegments(path2);
|
|
39575
|
+
const idx = segments.lastIndexOf("openspec");
|
|
39576
|
+
if (idx < 0) return null;
|
|
39577
|
+
return segments.slice(idx).join("/");
|
|
39578
|
+
}
|
|
39579
|
+
function toOpsxDisplayPath(absoluteOrRelativePath, options) {
|
|
39580
|
+
const normalized = normalizeFsPath$1(absoluteOrRelativePath);
|
|
39581
|
+
const npmSpecifier = toNpmSpecifier(normalized);
|
|
39582
|
+
if (options?.source === "package" || npmSpecifier) {
|
|
39583
|
+
if (npmSpecifier) return npmSpecifier;
|
|
39584
|
+
}
|
|
39585
|
+
if (!isAbsolutePath(normalized)) {
|
|
39586
|
+
return toVirtualProjectPath(normalized);
|
|
39587
|
+
}
|
|
39588
|
+
if (options?.projectDir && isPathInside$1(options.projectDir, normalized)) {
|
|
39589
|
+
const relativePath = toRelativeFromRoot$1(options.projectDir, normalized);
|
|
39590
|
+
return toVirtualProjectPath(relativePath);
|
|
39591
|
+
}
|
|
39592
|
+
const openspecSlice = findOpspecSlice(normalized);
|
|
39593
|
+
if (openspecSlice) {
|
|
39594
|
+
return toVirtualProjectPath(openspecSlice);
|
|
39595
|
+
}
|
|
39596
|
+
const segments = splitSegments(normalized);
|
|
39597
|
+
const tail = segments.slice(-4).join("/");
|
|
39598
|
+
return toVirtualProjectPath(tail);
|
|
39599
|
+
}
|
|
39515
39600
|
var dist$1 = {};
|
|
39516
39601
|
var composer = {};
|
|
39517
39602
|
var directives = {};
|
|
@@ -39972,7 +40057,7 @@ function requireAnchors() {
|
|
|
39972
40057
|
anchors.findNewAnchor = findNewAnchor;
|
|
39973
40058
|
return anchors;
|
|
39974
40059
|
}
|
|
39975
|
-
var Node = {};
|
|
40060
|
+
var Node$1 = {};
|
|
39976
40061
|
var applyReviver = {};
|
|
39977
40062
|
var hasRequiredApplyReviver;
|
|
39978
40063
|
function requireApplyReviver() {
|
|
@@ -40055,7 +40140,7 @@ function requireToJS() {
|
|
|
40055
40140
|
}
|
|
40056
40141
|
var hasRequiredNode;
|
|
40057
40142
|
function requireNode() {
|
|
40058
|
-
if (hasRequiredNode) return Node;
|
|
40143
|
+
if (hasRequiredNode) return Node$1;
|
|
40059
40144
|
hasRequiredNode = 1;
|
|
40060
40145
|
var applyReviver2 = requireApplyReviver();
|
|
40061
40146
|
var identity2 = requireIdentity();
|
|
@@ -40090,8 +40175,8 @@ function requireNode() {
|
|
|
40090
40175
|
return typeof reviver === "function" ? applyReviver2.applyReviver(reviver, { "": res }, "", res) : res;
|
|
40091
40176
|
}
|
|
40092
40177
|
}
|
|
40093
|
-
Node.NodeBase = NodeBase;
|
|
40094
|
-
return Node;
|
|
40178
|
+
Node$1.NodeBase = NodeBase;
|
|
40179
|
+
return Node$1;
|
|
40095
40180
|
}
|
|
40096
40181
|
var hasRequiredAlias;
|
|
40097
40182
|
function requireAlias() {
|
|
@@ -46870,15 +46955,14 @@ function parseDatedIdTimestamp(id2) {
|
|
|
46870
46955
|
return Number.isFinite(ts) ? ts : null;
|
|
46871
46956
|
}
|
|
46872
46957
|
function normalizeTrendEvents(events, pointLimit) {
|
|
46873
|
-
return events.filter((event) => Number.isFinite(event.ts) && event.ts > 0 && Number.isFinite(event.value)).sort((a, b) => a.ts - b.ts).slice(-
|
|
46874
|
-
}
|
|
46875
|
-
function
|
|
46876
|
-
|
|
46877
|
-
|
|
46878
|
-
|
|
46879
|
-
|
|
46880
|
-
const
|
|
46881
|
-
const probeStart = normalizedEvents[0].ts;
|
|
46958
|
+
return events.filter((event) => Number.isFinite(event.ts) && event.ts > 0 && Number.isFinite(event.value)).sort((a, b) => a.ts - b.ts).slice(-pointLimit);
|
|
46959
|
+
}
|
|
46960
|
+
function buildTimeWindow(probeEvents, rightEdgeTs) {
|
|
46961
|
+
if (probeEvents.length === 0) return null;
|
|
46962
|
+
const probeEnd = probeEvents[probeEvents.length - 1].ts;
|
|
46963
|
+
const hasRightEdge = typeof rightEdgeTs === "number" && Number.isFinite(rightEdgeTs) && rightEdgeTs > 0;
|
|
46964
|
+
const end = hasRightEdge ? Math.max(probeEnd, rightEdgeTs) : probeEnd;
|
|
46965
|
+
const probeStart = probeEvents[0].ts;
|
|
46882
46966
|
const rangeMs = Math.max(1, end - probeStart);
|
|
46883
46967
|
const bucketMs = rangeMs >= DAY_MS ? Math.max(DAY_MS, Math.ceil(rangeMs / DASHBOARD_TREND_BAR_COUNT / DAY_MS) * DAY_MS) : Math.max(1, Math.ceil(rangeMs / DASHBOARD_TREND_BAR_COUNT));
|
|
46884
46968
|
const windowStart = end - bucketMs * DASHBOARD_TREND_BAR_COUNT;
|
|
@@ -46886,6 +46970,16 @@ function buildBucketedTrend(events, pointLimit, mode) {
|
|
|
46886
46970
|
{ length: DASHBOARD_TREND_BAR_COUNT },
|
|
46887
46971
|
(_, index2) => windowStart + bucketMs * (index2 + 1)
|
|
46888
46972
|
);
|
|
46973
|
+
return { windowStart, bucketMs, bucketEnds };
|
|
46974
|
+
}
|
|
46975
|
+
function buildBucketedTrend(events, pointLimit, mode, rightEdgeTs) {
|
|
46976
|
+
const normalizedEvents = normalizeTrendEvents(events, pointLimit);
|
|
46977
|
+
if (normalizedEvents.length === 0) {
|
|
46978
|
+
return [];
|
|
46979
|
+
}
|
|
46980
|
+
const timeWindow = buildTimeWindow(normalizedEvents, rightEdgeTs);
|
|
46981
|
+
if (!timeWindow) return [];
|
|
46982
|
+
const { windowStart, bucketMs, bucketEnds } = timeWindow;
|
|
46889
46983
|
const sums = Array.from({ length: bucketEnds.length }, () => 0);
|
|
46890
46984
|
for (const event of normalizedEvents) {
|
|
46891
46985
|
if (event.ts <= windowStart) {
|
|
@@ -46899,7 +46993,7 @@ function buildBucketedTrend(events, pointLimit, mode) {
|
|
|
46899
46993
|
return { ts, value: sums[index2] };
|
|
46900
46994
|
});
|
|
46901
46995
|
}
|
|
46902
|
-
function buildStaticObjectiveTrends(snapshot) {
|
|
46996
|
+
function buildStaticObjectiveTrends(snapshot, pointLimit, rightEdgeTs) {
|
|
46903
46997
|
const trends = createEmptyTrends();
|
|
46904
46998
|
const requirementEvents = snapshot.specs.flatMap((spec) => {
|
|
46905
46999
|
const ts = resolveTrendTimestamp(spec.updatedAt, spec.createdAt);
|
|
@@ -46909,14 +47003,20 @@ function buildStaticObjectiveTrends(snapshot) {
|
|
|
46909
47003
|
snapshot.specs.flatMap((spec) => {
|
|
46910
47004
|
const ts = resolveTrendTimestamp(spec.createdAt, spec.updatedAt);
|
|
46911
47005
|
return ts === null ? [] : [{ ts, value: 1 }];
|
|
46912
|
-
})
|
|
47006
|
+
}),
|
|
47007
|
+
pointLimit,
|
|
47008
|
+
"sum",
|
|
47009
|
+
rightEdgeTs
|
|
46913
47010
|
);
|
|
46914
|
-
trends.requirements = buildBucketedTrend(requirementEvents);
|
|
47011
|
+
trends.requirements = buildBucketedTrend(requirementEvents, pointLimit, "sum", rightEdgeTs);
|
|
46915
47012
|
trends.completedChanges = buildBucketedTrend(
|
|
46916
47013
|
snapshot.archives.flatMap((archive) => {
|
|
46917
47014
|
const ts = parseDatedIdTimestamp(archive.id) ?? resolveTrendTimestamp(archive.updatedAt, archive.createdAt);
|
|
46918
47015
|
return ts === null ? [] : [{ ts, value: archive.parsedTasks.length }];
|
|
46919
|
-
})
|
|
47016
|
+
}),
|
|
47017
|
+
pointLimit,
|
|
47018
|
+
"sum",
|
|
47019
|
+
rightEdgeTs
|
|
46920
47020
|
);
|
|
46921
47021
|
return trends;
|
|
46922
47022
|
}
|
|
@@ -46926,6 +47026,34 @@ function isGlobPattern$1(path2) {
|
|
|
46926
47026
|
function normalizePath(path2) {
|
|
46927
47027
|
return path2.replace(/\\/g, "/").replace(/^\.?\//, "");
|
|
46928
47028
|
}
|
|
47029
|
+
function normalizeFsPath(path2) {
|
|
47030
|
+
return path2.replace(/\\/g, "/");
|
|
47031
|
+
}
|
|
47032
|
+
function isAbsoluteFsPath(path2) {
|
|
47033
|
+
return /^(?:[A-Za-z]:\/|\/)/.test(path2);
|
|
47034
|
+
}
|
|
47035
|
+
function isPathInside(root2, target) {
|
|
47036
|
+
const normalizedRoot = normalizeFsPath(root2).replace(/\/+$/, "").toLowerCase();
|
|
47037
|
+
const normalizedTarget = normalizeFsPath(target).toLowerCase();
|
|
47038
|
+
return normalizedTarget === normalizedRoot || normalizedTarget.startsWith(`${normalizedRoot}/`);
|
|
47039
|
+
}
|
|
47040
|
+
function toRelativeFromRoot(root2, target) {
|
|
47041
|
+
const normalizedRoot = normalizeFsPath(root2).replace(/\/+$/, "");
|
|
47042
|
+
const normalizedTarget = normalizeFsPath(target);
|
|
47043
|
+
return normalizedTarget.slice(normalizedRoot.length + 1);
|
|
47044
|
+
}
|
|
47045
|
+
function toSchemaRelativePath(inputPath, schemaRoot) {
|
|
47046
|
+
const path2 = normalizeFsPath(inputPath);
|
|
47047
|
+
if (!isAbsoluteFsPath(path2)) return normalizePath(path2);
|
|
47048
|
+
if (schemaRoot && isPathInside(schemaRoot, path2)) {
|
|
47049
|
+
return normalizePath(toRelativeFromRoot(schemaRoot, path2));
|
|
47050
|
+
}
|
|
47051
|
+
const templatesIdx = path2.lastIndexOf("/templates/");
|
|
47052
|
+
if (templatesIdx >= 0) {
|
|
47053
|
+
return normalizePath(path2.slice(templatesIdx + 1));
|
|
47054
|
+
}
|
|
47055
|
+
return getPathBasename(path2);
|
|
47056
|
+
}
|
|
46929
47057
|
function getPathBasename(path2) {
|
|
46930
47058
|
const normalized = normalizePath(path2);
|
|
46931
47059
|
const parts = normalized.split("/");
|
|
@@ -47086,6 +47214,48 @@ function buildChangeStatus(snapshot, change, preferredSchema) {
|
|
|
47086
47214
|
artifacts
|
|
47087
47215
|
};
|
|
47088
47216
|
}
|
|
47217
|
+
function buildStaticGitSnapshot(snapshot) {
|
|
47218
|
+
const defaultBranch = snapshot.git?.defaultBranch || "main";
|
|
47219
|
+
const repositoryUrl = snapshot.git?.repositoryUrl?.trim() || null;
|
|
47220
|
+
const recentCommits = snapshot.git?.recentCommits ?? [];
|
|
47221
|
+
if (recentCommits.length === 0) {
|
|
47222
|
+
return {
|
|
47223
|
+
defaultBranch,
|
|
47224
|
+
worktrees: []
|
|
47225
|
+
};
|
|
47226
|
+
}
|
|
47227
|
+
const commitEntries = recentCommits.slice(0, 5).map((commit) => ({
|
|
47228
|
+
type: "commit",
|
|
47229
|
+
hash: commit.hash,
|
|
47230
|
+
title: commit.title,
|
|
47231
|
+
relatedChanges: commit.relatedChanges,
|
|
47232
|
+
diff: commit.diff
|
|
47233
|
+
}));
|
|
47234
|
+
const aggregateDiff = commitEntries.reduce(
|
|
47235
|
+
(acc, entry) => {
|
|
47236
|
+
acc.files += entry.diff.files;
|
|
47237
|
+
acc.insertions += entry.diff.insertions;
|
|
47238
|
+
acc.deletions += entry.diff.deletions;
|
|
47239
|
+
return acc;
|
|
47240
|
+
},
|
|
47241
|
+
{ files: 0, insertions: 0, deletions: 0 }
|
|
47242
|
+
);
|
|
47243
|
+
return {
|
|
47244
|
+
defaultBranch,
|
|
47245
|
+
worktrees: [
|
|
47246
|
+
{
|
|
47247
|
+
path: repositoryUrl ?? "Repository URL unavailable",
|
|
47248
|
+
relativePath: "repo",
|
|
47249
|
+
branchName: "(snapshot)",
|
|
47250
|
+
isCurrent: true,
|
|
47251
|
+
ahead: 0,
|
|
47252
|
+
behind: 0,
|
|
47253
|
+
diff: aggregateDiff,
|
|
47254
|
+
entries: commitEntries
|
|
47255
|
+
}
|
|
47256
|
+
]
|
|
47257
|
+
};
|
|
47258
|
+
}
|
|
47089
47259
|
async function loadSnapshot() {
|
|
47090
47260
|
if (snapshotCache) {
|
|
47091
47261
|
return snapshotCache;
|
|
@@ -47175,6 +47345,14 @@ async function getDashboardOverview() {
|
|
|
47175
47345
|
}
|
|
47176
47346
|
};
|
|
47177
47347
|
}
|
|
47348
|
+
const trendPointLimit = Math.max(
|
|
47349
|
+
20,
|
|
47350
|
+
Math.min(
|
|
47351
|
+
500,
|
|
47352
|
+
Math.trunc(snapshot.config?.dashboard?.trendPointLimit ?? DASHBOARD_TREND_POINT_LIMIT)
|
|
47353
|
+
)
|
|
47354
|
+
);
|
|
47355
|
+
const rightEdgeTs = snapshot.git?.latestCommitTs ?? null;
|
|
47178
47356
|
const specifications = snapshot.specs.map((spec) => ({
|
|
47179
47357
|
id: spec.id,
|
|
47180
47358
|
name: spec.name,
|
|
@@ -47198,7 +47376,7 @@ async function getDashboardOverview() {
|
|
|
47198
47376
|
const inProgressChanges = activeChanges.filter(
|
|
47199
47377
|
(change) => change.progress.total > 0 && change.progress.completed < change.progress.total
|
|
47200
47378
|
).length;
|
|
47201
|
-
const trends = buildStaticObjectiveTrends(snapshot);
|
|
47379
|
+
const trends = buildStaticObjectiveTrends(snapshot, trendPointLimit, rightEdgeTs);
|
|
47202
47380
|
const hasObjectiveSpecificationTrend = trends.specifications.length > 0 || specifications.length === 0;
|
|
47203
47381
|
const hasObjectiveRequirementTrend = trends.requirements.length > 0 || requirements === 0;
|
|
47204
47382
|
const hasObjectiveCompletedTrend = trends.completedChanges.length > 0 || snapshot.archives.length === 0;
|
|
@@ -47223,15 +47401,12 @@ async function getDashboardOverview() {
|
|
|
47223
47401
|
hasObjectiveCompletedTrend
|
|
47224
47402
|
}),
|
|
47225
47403
|
trendMeta: {
|
|
47226
|
-
pointLimit:
|
|
47404
|
+
pointLimit: trendPointLimit,
|
|
47227
47405
|
lastUpdatedAt: Date.now()
|
|
47228
47406
|
},
|
|
47229
47407
|
specifications,
|
|
47230
47408
|
activeChanges,
|
|
47231
|
-
git:
|
|
47232
|
-
defaultBranch: "main",
|
|
47233
|
-
worktrees: []
|
|
47234
|
-
}
|
|
47409
|
+
git: buildStaticGitSnapshot(snapshot)
|
|
47235
47410
|
};
|
|
47236
47411
|
}
|
|
47237
47412
|
async function getSpec(id2) {
|
|
@@ -47345,9 +47520,35 @@ async function getOpsxTemplates(schema2) {
|
|
|
47345
47520
|
if (!snapshot?.opsx?.templates) return null;
|
|
47346
47521
|
if (!schema2) {
|
|
47347
47522
|
const first = Object.keys(snapshot.opsx.templates)[0];
|
|
47348
|
-
|
|
47523
|
+
if (!first) return null;
|
|
47524
|
+
const templates2 = snapshot.opsx.templates[first];
|
|
47525
|
+
return Object.fromEntries(
|
|
47526
|
+
Object.entries(templates2).map(([artifactId, template]) => [
|
|
47527
|
+
artifactId,
|
|
47528
|
+
{
|
|
47529
|
+
...template,
|
|
47530
|
+
displayPath: template.displayPath ?? toOpsxDisplayPath(template.path, {
|
|
47531
|
+
source: template.source,
|
|
47532
|
+
projectDir: snapshot.meta.projectDir
|
|
47533
|
+
})
|
|
47534
|
+
}
|
|
47535
|
+
])
|
|
47536
|
+
);
|
|
47349
47537
|
}
|
|
47350
|
-
|
|
47538
|
+
const templates = snapshot.opsx.templates[schema2];
|
|
47539
|
+
if (!templates) return null;
|
|
47540
|
+
return Object.fromEntries(
|
|
47541
|
+
Object.entries(templates).map(([artifactId, template]) => [
|
|
47542
|
+
artifactId,
|
|
47543
|
+
{
|
|
47544
|
+
...template,
|
|
47545
|
+
displayPath: template.displayPath ?? toOpsxDisplayPath(template.path, {
|
|
47546
|
+
source: template.source,
|
|
47547
|
+
projectDir: snapshot.meta.projectDir
|
|
47548
|
+
})
|
|
47549
|
+
}
|
|
47550
|
+
])
|
|
47551
|
+
);
|
|
47351
47552
|
}
|
|
47352
47553
|
async function getOpsxSchemaFiles(name2) {
|
|
47353
47554
|
const snapshot = await loadSnapshot();
|
|
@@ -47359,6 +47560,9 @@ async function getOpsxSchemaFiles(name2) {
|
|
|
47359
47560
|
if (!schemaName) return null;
|
|
47360
47561
|
const entries = [];
|
|
47361
47562
|
const seen = /* @__PURE__ */ new Set();
|
|
47563
|
+
const schemaRoot = snapshot.opsx.schemaResolutions?.[schemaName]?.path;
|
|
47564
|
+
const schemaYamlContent = snapshot.opsx.schemaYamls?.[schemaName];
|
|
47565
|
+
const templateContentsByArtifact = snapshot.opsx.templateContents?.[schemaName] ?? {};
|
|
47362
47566
|
const addEntry = (entry) => {
|
|
47363
47567
|
if (seen.has(entry.path)) return;
|
|
47364
47568
|
seen.add(entry.path);
|
|
@@ -47372,19 +47576,44 @@ async function getOpsxSchemaFiles(name2) {
|
|
|
47372
47576
|
}
|
|
47373
47577
|
};
|
|
47374
47578
|
if (snapshot.opsx.schemaDetails?.[schemaName]) {
|
|
47375
|
-
addEntry({ path: "schema.yaml", type: "file" });
|
|
47579
|
+
addEntry({ path: "schema.yaml", type: "file", content: schemaYamlContent });
|
|
47376
47580
|
}
|
|
47377
47581
|
const templates = snapshot.opsx.templates?.[schemaName];
|
|
47378
47582
|
if (templates) {
|
|
47379
|
-
Object.
|
|
47380
|
-
|
|
47381
|
-
|
|
47583
|
+
Object.entries(templates).forEach(([artifactId, template]) => {
|
|
47584
|
+
const relativePath = toSchemaRelativePath(template.path, schemaRoot);
|
|
47585
|
+
const templateContent = templateContentsByArtifact[artifactId]?.content ?? void 0;
|
|
47586
|
+
addDirEntries(relativePath);
|
|
47587
|
+
addEntry({ path: relativePath, type: "file", content: templateContent });
|
|
47382
47588
|
});
|
|
47383
47589
|
}
|
|
47384
47590
|
return entries;
|
|
47385
47591
|
}
|
|
47386
|
-
async function getOpsxTemplateContents() {
|
|
47387
|
-
|
|
47592
|
+
async function getOpsxTemplateContents(schema2) {
|
|
47593
|
+
const snapshot = await loadSnapshot();
|
|
47594
|
+
if (!snapshot?.opsx) return null;
|
|
47595
|
+
const targetSchema = schema2 ?? snapshot.opsx.schemas?.[0]?.name ?? Object.keys(snapshot.opsx.templates ?? {})[0] ?? null;
|
|
47596
|
+
if (!targetSchema) return null;
|
|
47597
|
+
const templates = snapshot.opsx.templates?.[targetSchema] ?? {};
|
|
47598
|
+
const contents = snapshot.opsx.templateContents?.[targetSchema] ?? {};
|
|
47599
|
+
const merged = Object.fromEntries(
|
|
47600
|
+
Object.entries(templates).map(([artifactId, template]) => {
|
|
47601
|
+
const contentInfo = contents[artifactId];
|
|
47602
|
+
return [
|
|
47603
|
+
artifactId,
|
|
47604
|
+
{
|
|
47605
|
+
content: contentInfo?.content ?? null,
|
|
47606
|
+
path: template.path,
|
|
47607
|
+
displayPath: contentInfo?.displayPath ?? template.displayPath ?? toOpsxDisplayPath(template.path, {
|
|
47608
|
+
source: template.source,
|
|
47609
|
+
projectDir: snapshot.meta.projectDir
|
|
47610
|
+
}),
|
|
47611
|
+
source: template.source
|
|
47612
|
+
}
|
|
47613
|
+
];
|
|
47614
|
+
})
|
|
47615
|
+
);
|
|
47616
|
+
return merged;
|
|
47388
47617
|
}
|
|
47389
47618
|
async function getOpsxChangeList() {
|
|
47390
47619
|
const snapshot = await loadSnapshot();
|
|
@@ -47435,10 +47664,17 @@ async function getOpsxGlobArtifactFiles(changeId, outputPath) {
|
|
|
47435
47664
|
}
|
|
47436
47665
|
function StatusIndicator() {
|
|
47437
47666
|
if (isStaticMode()) {
|
|
47438
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
47439
|
-
|
|
47440
|
-
|
|
47441
|
-
|
|
47667
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
47668
|
+
"div",
|
|
47669
|
+
{
|
|
47670
|
+
className: "status-indicator flex items-center gap-1.5 text-xs",
|
|
47671
|
+
title: "Live features disabled (no file watching, task toggling, or AI integration)",
|
|
47672
|
+
children: [
|
|
47673
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Camera, { className: "h-3.5 w-3.5 text-blue-500" }),
|
|
47674
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "status-text text-blue-600", children: "Static" })
|
|
47675
|
+
]
|
|
47676
|
+
}
|
|
47677
|
+
);
|
|
47442
47678
|
}
|
|
47443
47679
|
const status = useServerStatus();
|
|
47444
47680
|
const reconnect = useManualReconnect();
|
|
@@ -47472,7 +47708,7 @@ function StatusIndicator() {
|
|
|
47472
47708
|
function DesktopStatusBar() {
|
|
47473
47709
|
const staticMode = isStaticMode();
|
|
47474
47710
|
const [generatedAt, setGeneratedAt] = reactExports.useState("Unknown");
|
|
47475
|
-
const [
|
|
47711
|
+
const [snapshotRepositoryUrl, setSnapshotRepositoryUrl] = reactExports.useState(null);
|
|
47476
47712
|
reactExports.useEffect(() => {
|
|
47477
47713
|
if (!staticMode) return;
|
|
47478
47714
|
void loadSnapshot().then((snapshot) => {
|
|
@@ -47481,35 +47717,32 @@ function DesktopStatusBar() {
|
|
|
47481
47717
|
} else {
|
|
47482
47718
|
setGeneratedAt("Unknown");
|
|
47483
47719
|
}
|
|
47484
|
-
|
|
47720
|
+
setSnapshotRepositoryUrl(snapshot?.git?.repositoryUrl ?? null);
|
|
47485
47721
|
}).catch(() => {
|
|
47486
47722
|
setGeneratedAt("Unknown");
|
|
47487
|
-
|
|
47723
|
+
setSnapshotRepositoryUrl(null);
|
|
47488
47724
|
});
|
|
47489
47725
|
}, [staticMode]);
|
|
47490
47726
|
if (staticMode) {
|
|
47491
|
-
return /* @__PURE__ */ jsxRuntimeExports.
|
|
47492
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
47493
|
-
|
|
47494
|
-
|
|
47495
|
-
|
|
47496
|
-
generatedAt
|
|
47497
|
-
] }),
|
|
47498
|
-
snapshotProjectDir && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
47499
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(FolderOpen, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
47500
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
47501
|
-
PathMarquee,
|
|
47502
|
-
{
|
|
47503
|
-
children: snapshotProjectDir,
|
|
47504
|
-
maxWidth: 280,
|
|
47505
|
-
duration: 12,
|
|
47506
|
-
className: "text-xs"
|
|
47507
|
-
}
|
|
47508
|
-
)
|
|
47509
|
-
] })
|
|
47727
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "desktop-status border-border bg-muted/30 text-muted-foreground flex h-8 items-center justify-between gap-4 border-t px-4 text-xs", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-4", children: [
|
|
47728
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(StatusIndicator, {}),
|
|
47729
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "truncate", children: [
|
|
47730
|
+
"Generated: ",
|
|
47731
|
+
generatedAt
|
|
47510
47732
|
] }),
|
|
47511
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
47512
|
-
|
|
47733
|
+
snapshotRepositoryUrl && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
47734
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Github, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
47735
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
47736
|
+
PathMarquee,
|
|
47737
|
+
{
|
|
47738
|
+
children: snapshotRepositoryUrl,
|
|
47739
|
+
maxWidth: 280,
|
|
47740
|
+
duration: 12,
|
|
47741
|
+
className: "text-xs"
|
|
47742
|
+
}
|
|
47743
|
+
)
|
|
47744
|
+
] })
|
|
47745
|
+
] }) });
|
|
47513
47746
|
}
|
|
47514
47747
|
const status = useServerStatus();
|
|
47515
47748
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "desktop-status border-border bg-muted/30 text-muted-foreground flex h-8 items-center justify-between gap-4 border-t px-4 text-xs", children: [
|
|
@@ -47766,7 +47999,7 @@ function Dialog({
|
|
|
47766
47999
|
"div",
|
|
47767
48000
|
{
|
|
47768
48001
|
ref: panelRef,
|
|
47769
|
-
className: `bg-background relative flex h-
|
|
48002
|
+
className: `bg-background relative flex h-fit w-[calc(100%-0.5rem)] max-w-2xl flex-col overflow-hidden rounded-[var(--openspec-dialog-radius,0.75rem)] border shadow-xl ${borderClass} ${className}`,
|
|
47770
48003
|
style: { maxHeight },
|
|
47771
48004
|
children: [
|
|
47772
48005
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-border flex flex-none shrink-0 items-center justify-between border-b px-4 py-3", children: [
|
|
@@ -104582,55 +104815,140 @@ function CodeEditor({
|
|
|
104582
104815
|
}
|
|
104583
104816
|
);
|
|
104584
104817
|
}
|
|
104585
|
-
function
|
|
104818
|
+
function resolveAnchorPosition(anchor) {
|
|
104819
|
+
if (!anchor) return null;
|
|
104820
|
+
if (anchor.type === "point") return { x: anchor.x, y: anchor.y };
|
|
104821
|
+
const element2 = anchor.element;
|
|
104822
|
+
if (!element2) return null;
|
|
104823
|
+
const rect = element2.getBoundingClientRect();
|
|
104824
|
+
const placement = anchor.placement ?? "bottom-start";
|
|
104825
|
+
switch (placement) {
|
|
104826
|
+
case "bottom-end":
|
|
104827
|
+
return { x: rect.right, y: rect.bottom };
|
|
104828
|
+
case "top-start":
|
|
104829
|
+
return { x: rect.left, y: rect.top };
|
|
104830
|
+
case "top-end":
|
|
104831
|
+
return { x: rect.right, y: rect.top };
|
|
104832
|
+
case "bottom-start":
|
|
104833
|
+
default:
|
|
104834
|
+
return { x: rect.left, y: rect.bottom };
|
|
104835
|
+
}
|
|
104836
|
+
}
|
|
104837
|
+
function clampWithinBounds(position2, menuRect, boundaryRect) {
|
|
104838
|
+
const margin = 12;
|
|
104839
|
+
const left = boundaryRect?.left ?? 0;
|
|
104840
|
+
const top2 = boundaryRect?.top ?? 0;
|
|
104841
|
+
const right = boundaryRect?.right ?? window.innerWidth;
|
|
104842
|
+
const bottom = boundaryRect?.bottom ?? window.innerHeight;
|
|
104843
|
+
const minX = left + margin;
|
|
104844
|
+
const minY = top2 + margin;
|
|
104845
|
+
const maxX = Math.max(minX, right - menuRect.width - margin);
|
|
104846
|
+
const maxY = Math.max(minY, bottom - menuRect.height - margin);
|
|
104847
|
+
return {
|
|
104848
|
+
x: Math.max(minX, Math.min(position2.x, maxX)),
|
|
104849
|
+
y: Math.max(minY, Math.min(position2.y, maxY))
|
|
104850
|
+
};
|
|
104851
|
+
}
|
|
104852
|
+
function toLocalPointStyle(point2, wrapperElement) {
|
|
104853
|
+
if (!wrapperElement) {
|
|
104854
|
+
return { position: "fixed", left: point2.x, top: point2.y };
|
|
104855
|
+
}
|
|
104856
|
+
const rect = wrapperElement.getBoundingClientRect();
|
|
104857
|
+
return {
|
|
104858
|
+
position: "absolute",
|
|
104859
|
+
left: point2.x - rect.left + wrapperElement.scrollLeft,
|
|
104860
|
+
top: point2.y - rect.top + wrapperElement.scrollTop
|
|
104861
|
+
};
|
|
104862
|
+
}
|
|
104863
|
+
function getPlacement(anchor) {
|
|
104864
|
+
if (anchor?.type === "target") return anchor.placement ?? "bottom-start";
|
|
104865
|
+
return "bottom-start";
|
|
104866
|
+
}
|
|
104867
|
+
function ContextMenu({
|
|
104868
|
+
open,
|
|
104869
|
+
items,
|
|
104870
|
+
anchor,
|
|
104871
|
+
wrapperElement,
|
|
104872
|
+
boundaryElement,
|
|
104873
|
+
position: position2,
|
|
104874
|
+
onClose
|
|
104875
|
+
}) {
|
|
104586
104876
|
const menuRef = reactExports.useRef(null);
|
|
104587
|
-
const
|
|
104877
|
+
const fallbackAnchor = reactExports.useMemo(
|
|
104878
|
+
() => position2 ? { type: "point", x: position2.x, y: position2.y } : null,
|
|
104879
|
+
[position2]
|
|
104880
|
+
);
|
|
104881
|
+
const activeAnchor = anchor ?? fallbackAnchor;
|
|
104882
|
+
const hostElement = wrapperElement ?? boundaryElement ?? null;
|
|
104883
|
+
const anchorPosition = reactExports.useMemo(() => resolveAnchorPosition(activeAnchor), [activeAnchor]);
|
|
104588
104884
|
const [adjustedPosition, setAdjustedPosition] = reactExports.useState(null);
|
|
104885
|
+
const menuId = reactExports.useId().replace(/[^a-zA-Z0-9_-]/g, "");
|
|
104886
|
+
const anchorName = `--context-menu-anchor-${menuId}`;
|
|
104887
|
+
const menuDataId = `context-menu-${menuId}`;
|
|
104888
|
+
const placement = getPlacement(activeAnchor);
|
|
104589
104889
|
const visibleItems = reactExports.useMemo(() => items.filter((item) => item.label.length > 0), [items]);
|
|
104590
|
-
const shouldRender = open && !!
|
|
104890
|
+
const shouldRender = open && !!anchorPosition && visibleItems.length > 0;
|
|
104591
104891
|
reactExports.useLayoutEffect(() => {
|
|
104592
|
-
if (!open || !
|
|
104892
|
+
if (!open || !anchorPosition) {
|
|
104593
104893
|
setAdjustedPosition(null);
|
|
104594
104894
|
return;
|
|
104595
104895
|
}
|
|
104596
104896
|
const menu = menuRef.current;
|
|
104597
104897
|
if (!menu) {
|
|
104598
|
-
setAdjustedPosition(
|
|
104898
|
+
setAdjustedPosition(anchorPosition);
|
|
104599
104899
|
return;
|
|
104600
104900
|
}
|
|
104601
|
-
const
|
|
104602
|
-
const
|
|
104603
|
-
|
|
104604
|
-
|
|
104605
|
-
const x = Math.max(margin, Math.min(position2.x, maxX));
|
|
104606
|
-
const y = Math.max(margin, Math.min(position2.y, maxY));
|
|
104607
|
-
setAdjustedPosition({ x, y });
|
|
104608
|
-
}, [open, position2]);
|
|
104901
|
+
const boundaryRect = hostElement?.getBoundingClientRect() ?? null;
|
|
104902
|
+
const clamped = clampWithinBounds(anchorPosition, menu.getBoundingClientRect(), boundaryRect);
|
|
104903
|
+
setAdjustedPosition(clamped);
|
|
104904
|
+
}, [anchorPosition, hostElement, open]);
|
|
104609
104905
|
reactExports.useEffect(() => {
|
|
104610
|
-
const menu = menuRef.current;
|
|
104611
|
-
if (!menu || !open) return;
|
|
104612
|
-
const handleToggle = (event) => {
|
|
104613
|
-
if (!(event instanceof Event)) return;
|
|
104614
|
-
const target = event.target;
|
|
104615
|
-
if (target instanceof HTMLElement && !target.matches(":popover-open")) {
|
|
104616
|
-
onClose();
|
|
104617
|
-
}
|
|
104618
|
-
};
|
|
104619
104906
|
const handleScroll = () => onClose();
|
|
104620
|
-
menu.addEventListener("toggle", handleToggle);
|
|
104621
104907
|
window.addEventListener("scroll", handleScroll, true);
|
|
104622
104908
|
window.addEventListener("resize", handleScroll);
|
|
104623
104909
|
return () => {
|
|
104624
|
-
menu.removeEventListener("toggle", handleToggle);
|
|
104625
104910
|
window.removeEventListener("scroll", handleScroll, true);
|
|
104626
104911
|
window.removeEventListener("resize", handleScroll);
|
|
104627
104912
|
};
|
|
104628
104913
|
}, [open, onClose]);
|
|
104629
|
-
|
|
104630
|
-
|
|
104631
|
-
|
|
104632
|
-
|
|
104633
|
-
|
|
104914
|
+
reactExports.useEffect(() => {
|
|
104915
|
+
if (!shouldRender) return;
|
|
104916
|
+
const handlePointerDown = (event) => {
|
|
104917
|
+
if (event.button === 2) return;
|
|
104918
|
+
const target = event.target;
|
|
104919
|
+
if (!(target instanceof Node)) return;
|
|
104920
|
+
const menu = menuRef.current;
|
|
104921
|
+
if (menu?.contains(target)) return;
|
|
104922
|
+
if (activeAnchor?.type === "target" && activeAnchor.element?.contains(target)) return;
|
|
104923
|
+
onClose();
|
|
104924
|
+
};
|
|
104925
|
+
const handleKeyDown = (event) => {
|
|
104926
|
+
if (event.key === "Escape") onClose();
|
|
104927
|
+
};
|
|
104928
|
+
window.addEventListener("pointerdown", handlePointerDown, true);
|
|
104929
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
104930
|
+
return () => {
|
|
104931
|
+
window.removeEventListener("pointerdown", handlePointerDown, true);
|
|
104932
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
104933
|
+
};
|
|
104934
|
+
}, [activeAnchor, onClose, shouldRender]);
|
|
104935
|
+
reactExports.useEffect(() => {
|
|
104936
|
+
if (!open || activeAnchor?.type !== "target" || !activeAnchor.element) return;
|
|
104937
|
+
const target = activeAnchor.element;
|
|
104938
|
+
const previousAnchorName = target.style.getPropertyValue("anchor-name");
|
|
104939
|
+
const previousPriority = target.style.getPropertyPriority("anchor-name");
|
|
104940
|
+
target.style.setProperty("anchor-name", anchorName);
|
|
104941
|
+
return () => {
|
|
104942
|
+
if (previousAnchorName) {
|
|
104943
|
+
target.style.setProperty("anchor-name", previousAnchorName, previousPriority);
|
|
104944
|
+
} else {
|
|
104945
|
+
target.style.removeProperty("anchor-name");
|
|
104946
|
+
}
|
|
104947
|
+
};
|
|
104948
|
+
}, [activeAnchor, anchorName, open]);
|
|
104949
|
+
const resolvedPosition = adjustedPosition ?? anchorPosition;
|
|
104950
|
+
const fallbackStyle = resolvedPosition === null ? { left: 0, top: 0 } : { left: resolvedPosition.x, top: resolvedPosition.y };
|
|
104951
|
+
const syntheticAnchorStyle = activeAnchor?.type === "point" && anchorPosition ? toLocalPointStyle(anchorPosition, hostElement) : null;
|
|
104634
104952
|
reactExports.useEffect(() => {
|
|
104635
104953
|
const menu = menuRef.current;
|
|
104636
104954
|
if (!menu) return;
|
|
@@ -104638,44 +104956,83 @@ function ContextMenu({ open, items, position: position2, onClose }) {
|
|
|
104638
104956
|
if (!menu.matches(":popover-open")) {
|
|
104639
104957
|
menu.showPopover?.();
|
|
104640
104958
|
}
|
|
104641
|
-
} else {
|
|
104642
|
-
|
|
104643
|
-
menu.hidePopover?.();
|
|
104644
|
-
}
|
|
104959
|
+
} else if (menu.matches(":popover-open")) {
|
|
104960
|
+
menu.hidePopover?.();
|
|
104645
104961
|
}
|
|
104646
|
-
}, [shouldRender
|
|
104647
|
-
const styles = String.raw;
|
|
104962
|
+
}, [shouldRender]);
|
|
104648
104963
|
if (!shouldRender) return null;
|
|
104964
|
+
const styles = String.raw;
|
|
104965
|
+
const anchorPlacementCSS = placement === "top-start" ? "bottom: anchor(top); left: anchor(left); top: auto; right: auto;" : placement === "top-end" ? "bottom: anchor(top); left: anchor(right); top: auto; right: auto;" : placement === "bottom-end" ? "top: anchor(bottom); left: anchor(right); bottom: auto; right: auto;" : "top: anchor(bottom); left: anchor(left); bottom: auto; right: auto;";
|
|
104649
104966
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
104650
104967
|
/* @__PURE__ */ jsxRuntimeExports.jsx("style", { children: styles`
|
|
104651
|
-
.context-menu-anchor {
|
|
104652
|
-
position: fixed;
|
|
104968
|
+
.context-menu-anchor[data-context-menu-id='${menuDataId}'] {
|
|
104653
104969
|
width: 1px;
|
|
104654
104970
|
height: 1px;
|
|
104655
|
-
anchor-name: --context-menu-anchor;
|
|
104656
104971
|
pointer-events: none;
|
|
104657
104972
|
z-index: 50;
|
|
104973
|
+
anchor-name: ${anchorName};
|
|
104658
104974
|
}
|
|
104659
|
-
.context-menu-popover {
|
|
104660
|
-
position:
|
|
104975
|
+
.context-menu-popover[data-context-menu-id='${menuDataId}'] {
|
|
104976
|
+
position: absolute;
|
|
104661
104977
|
inset: auto;
|
|
104662
104978
|
}
|
|
104663
|
-
@supports (position-anchor:
|
|
104664
|
-
.context-menu-popover {
|
|
104665
|
-
position-anchor:
|
|
104979
|
+
@supports (position-anchor: ${anchorName}) {
|
|
104980
|
+
.context-menu-popover[data-context-menu-id='${menuDataId}'] {
|
|
104981
|
+
position-anchor: ${anchorName};
|
|
104982
|
+
${anchorPlacementCSS}
|
|
104983
|
+
}
|
|
104984
|
+
}
|
|
104985
|
+
@supports (position-try-fallbacks: --context-menu-right-bottom) {
|
|
104986
|
+
@position-try --context-menu-right-bottom {
|
|
104666
104987
|
top: anchor(bottom);
|
|
104667
|
-
left: anchor(
|
|
104988
|
+
left: anchor(right);
|
|
104989
|
+
right: auto;
|
|
104990
|
+
bottom: auto;
|
|
104991
|
+
}
|
|
104992
|
+
@position-try --context-menu-left-bottom {
|
|
104993
|
+
top: anchor(bottom);
|
|
104994
|
+
right: anchor(left);
|
|
104995
|
+
left: auto;
|
|
104996
|
+
bottom: auto;
|
|
104997
|
+
}
|
|
104998
|
+
@position-try --context-menu-left-top {
|
|
104999
|
+
bottom: anchor(top);
|
|
105000
|
+
right: anchor(left);
|
|
105001
|
+
left: auto;
|
|
105002
|
+
top: auto;
|
|
105003
|
+
}
|
|
105004
|
+
@position-try --context-menu-right-top {
|
|
105005
|
+
bottom: anchor(top);
|
|
105006
|
+
left: anchor(right);
|
|
105007
|
+
right: auto;
|
|
105008
|
+
top: auto;
|
|
105009
|
+
}
|
|
105010
|
+
.context-menu-popover[data-context-menu-id='${menuDataId}'] {
|
|
105011
|
+
position-try-fallbacks:
|
|
105012
|
+
--context-menu-right-bottom,
|
|
105013
|
+
--context-menu-left-bottom,
|
|
105014
|
+
--context-menu-left-top,
|
|
105015
|
+
--context-menu-right-top;
|
|
104668
105016
|
}
|
|
104669
105017
|
}
|
|
104670
105018
|
` }),
|
|
104671
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105019
|
+
syntheticAnchorStyle && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105020
|
+
"div",
|
|
105021
|
+
{
|
|
105022
|
+
"data-context-menu-id": menuDataId,
|
|
105023
|
+
className: "context-menu-anchor",
|
|
105024
|
+
style: syntheticAnchorStyle,
|
|
105025
|
+
"aria-hidden": true
|
|
105026
|
+
}
|
|
105027
|
+
),
|
|
104672
105028
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
104673
105029
|
"div",
|
|
104674
105030
|
{
|
|
104675
105031
|
ref: menuRef,
|
|
104676
|
-
popover: "
|
|
105032
|
+
popover: "manual",
|
|
105033
|
+
"data-context-menu-id": menuDataId,
|
|
104677
105034
|
className: "context-menu-popover border-border bg-card text-foreground z-50 min-w-[180px] rounded-md border p-1 shadow-lg",
|
|
104678
|
-
style:
|
|
105035
|
+
style: fallbackStyle,
|
|
104679
105036
|
children: visibleItems.map((item) => {
|
|
104680
105037
|
const isDisabled = item.disabled;
|
|
104681
105038
|
const toneClass = item.tone === "destructive" ? "text-destructive hover:bg-destructive/10" : "";
|
|
@@ -104702,6 +105059,36 @@ function ContextMenu({ open, items, position: position2, onClose }) {
|
|
|
104702
105059
|
)
|
|
104703
105060
|
] });
|
|
104704
105061
|
}
|
|
105062
|
+
const ContextMenuWrapper = reactExports.forwardRef(
|
|
105063
|
+
function ContextMenuWrapper2({ children, className, ...props }, ref) {
|
|
105064
|
+
const mergedClassName = className ? `relative ${className}` : "relative";
|
|
105065
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, "data-context-menu-wrapper": "", className: mergedClassName, ...props, children });
|
|
105066
|
+
}
|
|
105067
|
+
);
|
|
105068
|
+
const ContextMenuTargeter = reactExports.forwardRef(
|
|
105069
|
+
function ContextMenuTargeter2({ children, className, ...props }, ref) {
|
|
105070
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105071
|
+
"span",
|
|
105072
|
+
{
|
|
105073
|
+
ref,
|
|
105074
|
+
"data-context-menu-targeter": "",
|
|
105075
|
+
className: className ?? "inline-flex",
|
|
105076
|
+
...props,
|
|
105077
|
+
children
|
|
105078
|
+
}
|
|
105079
|
+
);
|
|
105080
|
+
}
|
|
105081
|
+
);
|
|
105082
|
+
function toContextMenuItems(items) {
|
|
105083
|
+
return items.map((item) => ({
|
|
105084
|
+
id: item.id,
|
|
105085
|
+
label: item.label,
|
|
105086
|
+
icon: item.icon,
|
|
105087
|
+
disabled: item.disabled,
|
|
105088
|
+
tone: item.tone,
|
|
105089
|
+
onSelect: item.onSelect
|
|
105090
|
+
}));
|
|
105091
|
+
}
|
|
104705
105092
|
const css = String.raw;
|
|
104706
105093
|
const layoutStyles = css`
|
|
104707
105094
|
/* 窄屏:单列布局 */
|
|
@@ -104728,7 +105115,7 @@ const layoutStyles = css`
|
|
|
104728
105115
|
@container (min-width: 768px) {
|
|
104729
105116
|
.fev-layout {
|
|
104730
105117
|
display: grid;
|
|
104731
|
-
grid-template-columns: 1fr 240px;
|
|
105118
|
+
grid-template-columns: minmax(0, 1fr) minmax(240px, clamp(240px, 30%, 420px));
|
|
104732
105119
|
gap: 1rem;
|
|
104733
105120
|
}
|
|
104734
105121
|
.fev-sidebar-tabs {
|
|
@@ -104776,72 +105163,145 @@ function getParentPath$1(path2) {
|
|
|
104776
105163
|
const parts = path2.split("/");
|
|
104777
105164
|
return parts.slice(0, -1).join("/");
|
|
104778
105165
|
}
|
|
105166
|
+
function splitBreadcrumbRoot(rootPath) {
|
|
105167
|
+
const normalized = (rootPath ?? "").trim().replace(/\/+$/g, "");
|
|
105168
|
+
if (!normalized) return [];
|
|
105169
|
+
const scopedMatch = /^([A-Za-z][A-Za-z0-9+.-]*:)(.*)$/.exec(normalized);
|
|
105170
|
+
if (!scopedMatch) {
|
|
105171
|
+
return normalized.split("/").filter(Boolean);
|
|
105172
|
+
}
|
|
105173
|
+
const prefix2 = scopedMatch[1];
|
|
105174
|
+
const suffix = scopedMatch[2].replace(/^\/+/g, "");
|
|
105175
|
+
const segments = [prefix2];
|
|
105176
|
+
if (suffix.length > 0) {
|
|
105177
|
+
segments.push(...suffix.split("/").filter(Boolean));
|
|
105178
|
+
}
|
|
105179
|
+
return segments;
|
|
105180
|
+
}
|
|
104779
105181
|
function Breadcrumb({
|
|
104780
105182
|
path: path2,
|
|
105183
|
+
rootPath,
|
|
104781
105184
|
entries,
|
|
104782
105185
|
onNavigate
|
|
104783
105186
|
}) {
|
|
104784
|
-
const
|
|
105187
|
+
const rootSegments = splitBreadcrumbRoot(rootPath).map((name2, index2) => ({
|
|
105188
|
+
key: `root-${index2}-${name2}`,
|
|
105189
|
+
kind: "root",
|
|
105190
|
+
name: name2
|
|
105191
|
+
}));
|
|
105192
|
+
const parts = path2.split("/").filter(Boolean);
|
|
104785
105193
|
const isMarkdown = path2.endsWith(".md");
|
|
104786
|
-
const
|
|
105194
|
+
const fileSegments = [];
|
|
104787
105195
|
for (let i = 0; i < parts.length; i++) {
|
|
104788
105196
|
const segmentPath = parts.slice(0, i + 1).join("/");
|
|
104789
105197
|
const isFile = i === parts.length - 1;
|
|
104790
|
-
|
|
105198
|
+
fileSegments.push({ key: `path-${segmentPath}`, name: parts[i], path: segmentPath, isFile });
|
|
104791
105199
|
}
|
|
105200
|
+
const segments = [...rootSegments, ...fileSegments];
|
|
105201
|
+
const rootCount = rootSegments.length;
|
|
104792
105202
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-border/50 bg-muted/20 flex items-center gap-1 overflow-x-auto border-b px-3 py-2 text-xs", children: segments.map((segment, i) => {
|
|
104793
105203
|
const isLast = i === segments.length - 1;
|
|
104794
|
-
const
|
|
105204
|
+
const isRootSegment = i < rootCount;
|
|
105205
|
+
const canNavigate = !isRootSegment && !isLast && entries.some(
|
|
105206
|
+
(e) => e.type === "file" && e.path.startsWith(fileSegments[i - rootCount].path + "/")
|
|
105207
|
+
);
|
|
104795
105208
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [
|
|
104796
105209
|
i > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "text-muted-foreground/50 h-3 w-3" }),
|
|
104797
|
-
|
|
104798
|
-
|
|
105210
|
+
isRootSegment ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground flex items-center gap-1.5", children: [
|
|
105211
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "h-3.5 w-3.5" }),
|
|
105212
|
+
segment.name
|
|
105213
|
+
] }) : isLast ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-foreground flex items-center gap-1.5", children: [
|
|
105214
|
+
fileSegments[i - rootCount].isFile ? isMarkdown ? /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(File, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "h-3.5 w-3.5" }),
|
|
104799
105215
|
segment.name
|
|
104800
105216
|
] }) : canNavigate ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
104801
105217
|
"button",
|
|
104802
105218
|
{
|
|
104803
105219
|
onClick: () => {
|
|
104804
105220
|
const firstFile = entries.find(
|
|
104805
|
-
(e) => e.type === "file" && e.path.startsWith(
|
|
105221
|
+
(e) => e.type === "file" && e.path.startsWith(fileSegments[i - rootCount].path + "/")
|
|
104806
105222
|
);
|
|
104807
105223
|
if (firstFile) onNavigate(firstFile.path);
|
|
104808
105224
|
},
|
|
104809
105225
|
className: "text-muted-foreground hover:text-foreground flex items-center gap-1.5 transition-colors",
|
|
104810
105226
|
children: [
|
|
104811
105227
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "h-3.5 w-3.5" }),
|
|
104812
|
-
|
|
105228
|
+
fileSegments[i - rootCount].name
|
|
104813
105229
|
]
|
|
104814
105230
|
}
|
|
104815
105231
|
) : /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-muted-foreground flex items-center gap-1.5", children: [
|
|
104816
105232
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "h-3.5 w-3.5" }),
|
|
104817
|
-
|
|
105233
|
+
fileSegments[i - rootCount].name
|
|
104818
105234
|
] })
|
|
104819
|
-
] }, segment.
|
|
105235
|
+
] }, segment.key);
|
|
104820
105236
|
}) });
|
|
104821
105237
|
}
|
|
104822
105238
|
function FileTabs({
|
|
104823
105239
|
entries,
|
|
104824
105240
|
selectedPath,
|
|
104825
|
-
onSelect
|
|
105241
|
+
onSelect,
|
|
105242
|
+
entryActions
|
|
104826
105243
|
}) {
|
|
105244
|
+
const wrapperRef = reactExports.useRef(null);
|
|
105245
|
+
const [menuAnchor, setMenuAnchor] = reactExports.useState(null);
|
|
104827
105246
|
const files = entries.filter((e) => e.type === "file");
|
|
104828
|
-
|
|
104829
|
-
|
|
104830
|
-
|
|
104831
|
-
|
|
104832
|
-
|
|
104833
|
-
|
|
104834
|
-
|
|
104835
|
-
|
|
104836
|
-
className:
|
|
104837
|
-
|
|
104838
|
-
isMarkdown
|
|
104839
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
104840
|
-
|
|
104841
|
-
|
|
104842
|
-
|
|
104843
|
-
|
|
104844
|
-
|
|
105247
|
+
const selectedFile = files.find((entry) => entry.path === selectedPath) ?? files[0] ?? null;
|
|
105248
|
+
const selectedActions = selectedFile && entryActions ? toContextMenuItems(entryActions(selectedFile)) : [];
|
|
105249
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105250
|
+
ContextMenuWrapper,
|
|
105251
|
+
{
|
|
105252
|
+
ref: wrapperRef,
|
|
105253
|
+
className: "border-border bg-muted/30 flex items-stretch overflow-hidden rounded-md border",
|
|
105254
|
+
children: [
|
|
105255
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "scrollbar-thin scrollbar-track-transparent flex min-w-0 flex-1 gap-1 overflow-x-auto px-1 py-1", children: files.map((entry) => {
|
|
105256
|
+
const isActive = entry.path === selectedPath;
|
|
105257
|
+
const isMarkdown = entry.path.endsWith(".md");
|
|
105258
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105259
|
+
"button",
|
|
105260
|
+
{
|
|
105261
|
+
onClick: () => onSelect(entry.path),
|
|
105262
|
+
title: entry.path,
|
|
105263
|
+
className: `flex shrink-0 items-center gap-1.5 rounded px-2.5 py-1.5 text-xs transition-colors ${isActive ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:bg-background/50 hover:text-foreground"}`,
|
|
105264
|
+
children: [
|
|
105265
|
+
isMarkdown ? /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(File, { className: "h-3.5 w-3.5" }),
|
|
105266
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "max-w-[120px] truncate", children: getFileName(entry.path) })
|
|
105267
|
+
]
|
|
105268
|
+
},
|
|
105269
|
+
entry.path
|
|
105270
|
+
);
|
|
105271
|
+
}) }),
|
|
105272
|
+
selectedActions.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuTargeter, { className: "text-muted-foreground inline-flex items-center", children: [
|
|
105273
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { "aria-hidden": "true", className: "bg-border/80 block w-px self-stretch" }),
|
|
105274
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105275
|
+
"button",
|
|
105276
|
+
{
|
|
105277
|
+
type: "button",
|
|
105278
|
+
onClick: (event) => {
|
|
105279
|
+
setMenuAnchor({
|
|
105280
|
+
type: "target",
|
|
105281
|
+
element: event.currentTarget,
|
|
105282
|
+
placement: "bottom-end"
|
|
105283
|
+
});
|
|
105284
|
+
},
|
|
105285
|
+
className: "text-muted-foreground hover:text-foreground hover:bg-background/80 inline-flex h-7 w-7 shrink-0 items-center justify-center rounded",
|
|
105286
|
+
"aria-label": "Current file actions",
|
|
105287
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(EllipsisVertical, { className: "h-4 w-4" })
|
|
105288
|
+
}
|
|
105289
|
+
)
|
|
105290
|
+
] }),
|
|
105291
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105292
|
+
ContextMenu,
|
|
105293
|
+
{
|
|
105294
|
+
open: menuAnchor !== null,
|
|
105295
|
+
items: selectedActions,
|
|
105296
|
+
anchor: menuAnchor,
|
|
105297
|
+
wrapperElement: wrapperRef.current,
|
|
105298
|
+
boundaryElement: wrapperRef.current,
|
|
105299
|
+
onClose: () => setMenuAnchor(null)
|
|
105300
|
+
}
|
|
105301
|
+
)
|
|
105302
|
+
]
|
|
105303
|
+
}
|
|
105304
|
+
);
|
|
104845
105305
|
}
|
|
104846
105306
|
function FileTree({
|
|
104847
105307
|
entries,
|
|
@@ -104852,6 +105312,7 @@ function FileTree({
|
|
|
104852
105312
|
entryActions
|
|
104853
105313
|
}) {
|
|
104854
105314
|
const [menuState, setMenuState] = reactExports.useState(null);
|
|
105315
|
+
const wrapperRef = reactExports.useRef(null);
|
|
104855
105316
|
const getIndentLevel = (entry) => {
|
|
104856
105317
|
const parentPath = getParentPath$1(entry.path);
|
|
104857
105318
|
if (!parentPath) return 0;
|
|
@@ -104862,90 +105323,94 @@ function FileTree({
|
|
|
104862
105323
|
}
|
|
104863
105324
|
return entry.path.split("/").length - 1;
|
|
104864
105325
|
};
|
|
104865
|
-
const openMenu = (
|
|
104866
|
-
const mapped = items
|
|
104867
|
-
id: item.id,
|
|
104868
|
-
label: item.label,
|
|
104869
|
-
icon: item.icon,
|
|
104870
|
-
disabled: item.disabled,
|
|
104871
|
-
tone: item.tone,
|
|
104872
|
-
onSelect: item.onSelect
|
|
104873
|
-
}));
|
|
105326
|
+
const openMenu = (anchor, items) => {
|
|
105327
|
+
const mapped = toContextMenuItems(items);
|
|
104874
105328
|
if (mapped.length === 0) return;
|
|
104875
|
-
setMenuState({
|
|
105329
|
+
setMenuState({ anchor, items: mapped });
|
|
104876
105330
|
};
|
|
104877
105331
|
const closeMenu = () => setMenuState(null);
|
|
104878
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
104879
|
-
|
|
104880
|
-
|
|
104881
|
-
|
|
104882
|
-
|
|
104883
|
-
|
|
104884
|
-
|
|
104885
|
-
|
|
104886
|
-
|
|
104887
|
-
|
|
104888
|
-
|
|
104889
|
-
|
|
104890
|
-
|
|
104891
|
-
|
|
104892
|
-
|
|
104893
|
-
|
|
104894
|
-
|
|
104895
|
-
|
|
104896
|
-
|
|
104897
|
-
|
|
104898
|
-
|
|
104899
|
-
|
|
104900
|
-
|
|
104901
|
-
|
|
104902
|
-
|
|
104903
|
-
|
|
104904
|
-
|
|
104905
|
-
|
|
104906
|
-
|
|
104907
|
-
|
|
104908
|
-
|
|
104909
|
-
|
|
104910
|
-
|
|
104911
|
-
|
|
104912
|
-
|
|
104913
|
-
|
|
104914
|
-
|
|
104915
|
-
|
|
104916
|
-
|
|
104917
|
-
|
|
104918
|
-
|
|
104919
|
-
|
|
104920
|
-
|
|
104921
|
-
|
|
104922
|
-
|
|
104923
|
-
|
|
104924
|
-
|
|
104925
|
-
|
|
104926
|
-
|
|
104927
|
-
|
|
104928
|
-
|
|
104929
|
-
|
|
104930
|
-
|
|
104931
|
-
|
|
104932
|
-
|
|
104933
|
-
|
|
104934
|
-
|
|
104935
|
-
|
|
104936
|
-
|
|
104937
|
-
|
|
104938
|
-
|
|
104939
|
-
|
|
104940
|
-
|
|
104941
|
-
|
|
104942
|
-
|
|
104943
|
-
|
|
105332
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105333
|
+
ContextMenuWrapper,
|
|
105334
|
+
{
|
|
105335
|
+
ref: wrapperRef,
|
|
105336
|
+
className: "border-border bg-muted/30 flex h-full flex-col rounded-md border",
|
|
105337
|
+
children: [
|
|
105338
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-border/50 text-muted-foreground flex items-center justify-between border-b px-3 py-2 text-xs font-medium", children: [
|
|
105339
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "min-w-0 truncate", children: headerLabel }),
|
|
105340
|
+
headerActions
|
|
105341
|
+
] }),
|
|
105342
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "scrollbar-thin scrollbar-track-transparent flex-1 overflow-y-auto", children: entries.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground px-3 py-2 text-xs", children: "No files yet." }) : entries.map((entry) => {
|
|
105343
|
+
const depth = getIndentLevel(entry);
|
|
105344
|
+
const isActive = entry.path === selectedPath;
|
|
105345
|
+
const isFile = entry.type === "file";
|
|
105346
|
+
const actions = entryActions ? entryActions(entry) : [];
|
|
105347
|
+
const showActions = actions.length > 0;
|
|
105348
|
+
const icon = isFile ? entry.path.endsWith(".md") ? /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "h-4 w-4 shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(File, { className: "h-4 w-4 shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Folder, { className: "h-4 w-4 shrink-0" });
|
|
105349
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105350
|
+
"div",
|
|
105351
|
+
{
|
|
105352
|
+
className: `group flex w-full items-center gap-2 px-2 py-1 text-sm transition-colors ${isActive ? "bg-primary/10 text-foreground" : isFile ? "text-muted-foreground hover:bg-muted/50 hover:text-foreground" : "text-muted-foreground"}`,
|
|
105353
|
+
onContextMenu: (event) => {
|
|
105354
|
+
if (!showActions) return;
|
|
105355
|
+
event.preventDefault();
|
|
105356
|
+
if (isFile) onSelect(entry.path);
|
|
105357
|
+
openMenu({ type: "point", x: event.clientX, y: event.clientY }, actions);
|
|
105358
|
+
},
|
|
105359
|
+
children: [
|
|
105360
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
105361
|
+
"button",
|
|
105362
|
+
{
|
|
105363
|
+
type: "button",
|
|
105364
|
+
disabled: !isFile,
|
|
105365
|
+
onClick: () => isFile && onSelect(entry.path),
|
|
105366
|
+
className: `flex flex-1 items-center gap-2 text-left ${!isFile ? "cursor-default" : ""}`,
|
|
105367
|
+
style: { paddingLeft: 4 + depth * 14 },
|
|
105368
|
+
children: [
|
|
105369
|
+
icon,
|
|
105370
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `truncate ${!isFile ? "text-foreground font-medium" : ""}`, children: getFileName(entry.path) })
|
|
105371
|
+
]
|
|
105372
|
+
}
|
|
105373
|
+
),
|
|
105374
|
+
showActions && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuTargeter, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105375
|
+
"button",
|
|
105376
|
+
{
|
|
105377
|
+
type: "button",
|
|
105378
|
+
onClick: (event) => {
|
|
105379
|
+
event.stopPropagation();
|
|
105380
|
+
openMenu(
|
|
105381
|
+
{ type: "target", element: event.currentTarget, placement: "bottom-end" },
|
|
105382
|
+
actions
|
|
105383
|
+
);
|
|
105384
|
+
},
|
|
105385
|
+
className: "hover:bg-muted text-muted-foreground flex h-7 w-7 items-center justify-center rounded-md",
|
|
105386
|
+
"aria-label": "File actions",
|
|
105387
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(EllipsisVertical, { className: "h-4 w-4" })
|
|
105388
|
+
}
|
|
105389
|
+
) })
|
|
105390
|
+
]
|
|
105391
|
+
},
|
|
105392
|
+
entry.path
|
|
105393
|
+
);
|
|
105394
|
+
}) }),
|
|
105395
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105396
|
+
ContextMenu,
|
|
105397
|
+
{
|
|
105398
|
+
open: !!menuState,
|
|
105399
|
+
items: menuState?.items ?? [],
|
|
105400
|
+
anchor: menuState?.anchor ?? null,
|
|
105401
|
+
boundaryElement: wrapperRef.current,
|
|
105402
|
+
onClose: closeMenu
|
|
105403
|
+
}
|
|
105404
|
+
)
|
|
105405
|
+
]
|
|
105406
|
+
}
|
|
105407
|
+
);
|
|
104944
105408
|
}
|
|
104945
105409
|
function FileExplorer({
|
|
104946
105410
|
entries,
|
|
104947
105411
|
selectedPath,
|
|
104948
105412
|
onSelect,
|
|
105413
|
+
breadcrumbRoot,
|
|
104949
105414
|
headerLabel = "Files",
|
|
104950
105415
|
headerActions,
|
|
104951
105416
|
entryActions,
|
|
@@ -104960,7 +105425,15 @@ function FileExplorer({
|
|
|
104960
105425
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "@container-[size] h-full", children: [
|
|
104961
105426
|
/* @__PURE__ */ jsxRuntimeExports.jsx("style", { children: layoutStyles }),
|
|
104962
105427
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fev-layout", children: [
|
|
104963
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fev-sidebar-tabs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105428
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fev-sidebar-tabs", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105429
|
+
FileTabs,
|
|
105430
|
+
{
|
|
105431
|
+
entries: sortedEntries,
|
|
105432
|
+
selectedPath,
|
|
105433
|
+
onSelect,
|
|
105434
|
+
entryActions
|
|
105435
|
+
}
|
|
105436
|
+
) }),
|
|
104964
105437
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fev-sidebar-tree", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
104965
105438
|
FileTree,
|
|
104966
105439
|
{
|
|
@@ -104973,7 +105446,15 @@ function FileExplorer({
|
|
|
104973
105446
|
}
|
|
104974
105447
|
) }),
|
|
104975
105448
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fev-editor-wrapper border-border bg-background overflow-hidden rounded-md border shadow-sm", children: activeFile ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
104976
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105449
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
105450
|
+
Breadcrumb,
|
|
105451
|
+
{
|
|
105452
|
+
path: activeFile.path,
|
|
105453
|
+
rootPath: breadcrumbRoot,
|
|
105454
|
+
entries: sortedEntries,
|
|
105455
|
+
onNavigate: onSelect
|
|
105456
|
+
}
|
|
105457
|
+
),
|
|
104977
105458
|
renderEditor(activeFile)
|
|
104978
105459
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground flex h-full items-center justify-center", children: sortedEntries.length > 0 ? "Select a file to view" : emptyState ?? "No files found." }) })
|
|
104979
105460
|
] })
|
|
@@ -105421,7 +105902,7 @@ function useOpsxTemplateContentsSubscription(schema2) {
|
|
|
105421
105902
|
);
|
|
105422
105903
|
return useSubscription(
|
|
105423
105904
|
subscribe2,
|
|
105424
|
-
() => getOpsxTemplateContents(),
|
|
105905
|
+
() => getOpsxTemplateContents(schema2),
|
|
105425
105906
|
[schema2],
|
|
105426
105907
|
`opsx.subscribeTemplateContents:${schema2 ?? ""}`
|
|
105427
105908
|
);
|
|
@@ -105962,11 +106443,10 @@ function Config() {
|
|
|
105962
106443
|
const [createEntryParent, setCreateEntryParent] = reactExports.useState(null);
|
|
105963
106444
|
const [createEntryName, setCreateEntryName] = reactExports.useState("");
|
|
105964
106445
|
const [activeEntry, setActiveEntry] = reactExports.useState(null);
|
|
105965
|
-
const [
|
|
105966
|
-
|
|
105967
|
-
);
|
|
105968
|
-
const
|
|
105969
|
-
const [viewMenuPosition, setViewMenuPosition] = reactExports.useState(null);
|
|
106446
|
+
const [headerMenuAnchor, setHeaderMenuAnchor] = reactExports.useState(null);
|
|
106447
|
+
const [fileMenuAnchor, setFileMenuAnchor] = reactExports.useState(null);
|
|
106448
|
+
const [viewMenuAnchor, setViewMenuAnchor] = reactExports.useState(null);
|
|
106449
|
+
const schemaMenuWrapperRef = reactExports.useRef(null);
|
|
105970
106450
|
const [schemaEditorWrap, setSchemaEditorWrap] = reactExports.useState(true);
|
|
105971
106451
|
const [newSchemaName, setNewSchemaName] = reactExports.useState("");
|
|
105972
106452
|
const [newSchemaMode, setNewSchemaMode] = reactExports.useState("init");
|
|
@@ -106047,9 +106527,9 @@ function Config() {
|
|
|
106047
106527
|
setDirtyFiles({});
|
|
106048
106528
|
setSchemaEntryError(null);
|
|
106049
106529
|
setActiveEntry(null);
|
|
106050
|
-
|
|
106051
|
-
|
|
106052
|
-
|
|
106530
|
+
setHeaderMenuAnchor(null);
|
|
106531
|
+
setFileMenuAnchor(null);
|
|
106532
|
+
setViewMenuAnchor(null);
|
|
106053
106533
|
}, [selectedSchema]);
|
|
106054
106534
|
reactExports.useEffect(() => {
|
|
106055
106535
|
if (!schemaFiles || schemaFiles.length === 0) {
|
|
@@ -106142,14 +106622,20 @@ function Config() {
|
|
|
106142
106622
|
const isRoot = activeEntry.path === "/";
|
|
106143
106623
|
const childCount = activeEntry.type === "directory" ? isRoot ? schemaEntries.length : schemaEntries.filter((entry) => entry.path.startsWith(activeEntry.path + "/")).length : void 0;
|
|
106144
106624
|
return {
|
|
106145
|
-
path: isRoot ? schemaResolution?.path ?? "/" : activeEntry.path,
|
|
106625
|
+
path: isRoot ? schemaResolution?.displayPath ?? schemaResolution?.path ?? "/" : activeEntry.path,
|
|
106146
106626
|
type: activeEntry.type,
|
|
106147
106627
|
source: schemaResolution?.source ?? "unknown",
|
|
106148
106628
|
sizeBytes,
|
|
106149
106629
|
childCount
|
|
106150
106630
|
};
|
|
106151
106631
|
}, [activeEntry, schemaEntries, schemaResolution]);
|
|
106152
|
-
const schemaRootLabel =
|
|
106632
|
+
const schemaRootLabel = reactExports.useMemo(() => {
|
|
106633
|
+
if (schemaResolution?.displayPath) return schemaResolution.displayPath;
|
|
106634
|
+
if (schemaResolution?.path) {
|
|
106635
|
+
return toOpsxDisplayPath(schemaResolution.path, { source: schemaResolution.source });
|
|
106636
|
+
}
|
|
106637
|
+
return "project:openspec/schemas";
|
|
106638
|
+
}, [schemaResolution]);
|
|
106153
106639
|
const schemaRootEntry = reactExports.useMemo(() => ({ path: "/", type: "directory" }), []);
|
|
106154
106640
|
const saveConfigMutation = useMutation({
|
|
106155
106641
|
mutationFn: async () => {
|
|
@@ -106553,11 +107039,12 @@ function Config() {
|
|
|
106553
107039
|
] }),
|
|
106554
107040
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "truncate", children: [
|
|
106555
107041
|
"Path: ",
|
|
106556
|
-
schemaResolution.path
|
|
107042
|
+
schemaResolution.displayPath ?? schemaResolution.path
|
|
106557
107043
|
] }),
|
|
106558
107044
|
schemaResolution.shadows.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
106559
|
-
"Shadows:
|
|
106560
|
-
|
|
107045
|
+
"Shadows:",
|
|
107046
|
+
" ",
|
|
107047
|
+
schemaResolution.shadows.map((s) => `${s.source}(${s.displayPath ?? s.path})`).join(", ")
|
|
106561
107048
|
] })
|
|
106562
107049
|
] })
|
|
106563
107050
|
] }),
|
|
@@ -106574,6 +107061,7 @@ function Config() {
|
|
|
106574
107061
|
const rawArtifact = rawArtifactMap.get(artifact.id);
|
|
106575
107062
|
const templateInfo = templateContents?.[artifact.id] ?? (templates?.[artifact.id] ? { ...templates[artifact.id], content: null } : null);
|
|
106576
107063
|
const templatePath = templateInfo?.path ?? (typeof rawArtifact?.template === "string" ? rawArtifact.template : void 0);
|
|
107064
|
+
const templateDisplayPath = templateInfo?.displayPath ?? templatePath ?? null;
|
|
106577
107065
|
const draftTemplateContent = templatePath !== void 0 ? draftByPath.get(templatePath) : void 0;
|
|
106578
107066
|
const templateBody = draftTemplateContent !== void 0 ? draftTemplateContent : templateInfo ? templateInfo.content : null;
|
|
106579
107067
|
const rawKnownFields = [
|
|
@@ -106632,7 +107120,7 @@ function Config() {
|
|
|
106632
107120
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground text-xs font-semibold uppercase tracking-wide", children: "Template" }),
|
|
106633
107121
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-muted-foreground pl-4 text-xs", children: [
|
|
106634
107122
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mr-1", children: "Template:" }),
|
|
106635
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "bg-muted rounded px-1", children:
|
|
107123
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "bg-muted rounded px-1", children: templateDisplayPath }),
|
|
106636
107124
|
templateInfo?.source ? ` (${templateInfo.source})` : null
|
|
106637
107125
|
] }),
|
|
106638
107126
|
templateBody !== null && templateBody !== void 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pl-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-muted/30 rounded-lg p-4 [zoom:0.86]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -106662,7 +107150,7 @@ function Config() {
|
|
|
106662
107150
|
] });
|
|
106663
107151
|
}
|
|
106664
107152
|
}
|
|
106665
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
107153
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuWrapper, { ref: schemaMenuWrapperRef, className: "h-full space-y-4", children: [
|
|
106666
107154
|
schemaFilesError && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-destructive text-xs", children: [
|
|
106667
107155
|
"Failed to load schema files: ",
|
|
106668
107156
|
schemaFilesError.message
|
|
@@ -106673,6 +107161,7 @@ function Config() {
|
|
|
106673
107161
|
entries: schemaEntries,
|
|
106674
107162
|
selectedPath: selectedSchemaPath,
|
|
106675
107163
|
onSelect: setSelectedSchemaPath,
|
|
107164
|
+
breadcrumbRoot: schemaRootLabel,
|
|
106676
107165
|
headerLabel: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
106677
107166
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "uppercase tracking-wide", children: "Files" }),
|
|
106678
107167
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -106684,42 +107173,50 @@ function Config() {
|
|
|
106684
107173
|
}
|
|
106685
107174
|
)
|
|
106686
107175
|
] }),
|
|
106687
|
-
headerActions: headerMenuItems.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107176
|
+
headerActions: headerMenuItems.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuTargeter, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106688
107177
|
"button",
|
|
106689
107178
|
{
|
|
106690
107179
|
type: "button",
|
|
106691
107180
|
onClick: (event) => {
|
|
106692
|
-
|
|
106693
|
-
|
|
106694
|
-
|
|
106695
|
-
|
|
107181
|
+
setFileMenuAnchor(null);
|
|
107182
|
+
setViewMenuAnchor(null);
|
|
107183
|
+
setHeaderMenuAnchor({
|
|
107184
|
+
type: "target",
|
|
107185
|
+
element: event.currentTarget,
|
|
107186
|
+
placement: "bottom-end"
|
|
107187
|
+
});
|
|
106696
107188
|
},
|
|
106697
107189
|
className: "hover:bg-muted rounded-md p-1",
|
|
106698
107190
|
"aria-label": "Schema menu",
|
|
106699
107191
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(EllipsisVertical, { className: "h-4 w-4" })
|
|
106700
107192
|
}
|
|
106701
|
-
) : void 0,
|
|
106702
|
-
entryActions:
|
|
107193
|
+
) }) : void 0,
|
|
107194
|
+
entryActions: (entry) => {
|
|
107195
|
+
const propertiesAction = {
|
|
107196
|
+
id: "properties",
|
|
107197
|
+
label: "Properties",
|
|
107198
|
+
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Info$1, { className: "h-3.5 w-3.5" }),
|
|
107199
|
+
onSelect: () => handleOpenEntryInfo(entry)
|
|
107200
|
+
};
|
|
107201
|
+
if (schemaMode !== "edit" || !canManageEntries) {
|
|
107202
|
+
return [propertiesAction];
|
|
107203
|
+
}
|
|
106703
107204
|
const parent = entry.type === "directory" ? entry.path : getParentPath(entry.path);
|
|
107205
|
+
const isDirectory = entry.type === "directory";
|
|
106704
107206
|
return [
|
|
106705
107207
|
{
|
|
106706
107208
|
id: "new-file",
|
|
106707
|
-
label: "New file",
|
|
107209
|
+
label: isDirectory ? "New file inside" : "New sibling file",
|
|
106708
107210
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FilePlus, { className: "h-3.5 w-3.5" }),
|
|
106709
107211
|
onSelect: () => handleOpenCreateEntry("file", parent)
|
|
106710
107212
|
},
|
|
106711
107213
|
{
|
|
106712
107214
|
id: "new-folder",
|
|
106713
|
-
label: "New folder",
|
|
107215
|
+
label: isDirectory ? "New folder inside" : "New sibling folder",
|
|
106714
107216
|
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(FolderPlus, { className: "h-3.5 w-3.5" }),
|
|
106715
107217
|
onSelect: () => handleOpenCreateEntry("directory", parent)
|
|
106716
107218
|
},
|
|
106717
|
-
|
|
106718
|
-
id: "properties",
|
|
106719
|
-
label: "Properties",
|
|
106720
|
-
icon: /* @__PURE__ */ jsxRuntimeExports.jsx(Info$1, { className: "h-3.5 w-3.5" }),
|
|
106721
|
-
onSelect: () => handleOpenEntryInfo(entry)
|
|
106722
|
-
},
|
|
107219
|
+
propertiesAction,
|
|
106723
107220
|
{
|
|
106724
107221
|
id: "delete",
|
|
106725
107222
|
label: "Delete",
|
|
@@ -106728,39 +107225,45 @@ function Config() {
|
|
|
106728
107225
|
onSelect: () => handleOpenDeleteEntry(entry)
|
|
106729
107226
|
}
|
|
106730
107227
|
];
|
|
106731
|
-
}
|
|
107228
|
+
},
|
|
106732
107229
|
emptyState: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "No files found for this schema." }),
|
|
106733
107230
|
renderEditor: (activeFile) => activeFile ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex min-h-0 flex-1 flex-col", children: [
|
|
106734
107231
|
schemaMode === "edit" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-border/50 flex items-center justify-between border-b px-3 py-2 text-xs", children: [
|
|
106735
107232
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
106736
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107233
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuTargeter, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106737
107234
|
"button",
|
|
106738
107235
|
{
|
|
106739
107236
|
type: "button",
|
|
106740
107237
|
onClick: (event) => {
|
|
106741
|
-
|
|
106742
|
-
|
|
106743
|
-
|
|
106744
|
-
|
|
107238
|
+
setHeaderMenuAnchor(null);
|
|
107239
|
+
setViewMenuAnchor(null);
|
|
107240
|
+
setFileMenuAnchor({
|
|
107241
|
+
type: "target",
|
|
107242
|
+
element: event.currentTarget,
|
|
107243
|
+
placement: "bottom-start"
|
|
107244
|
+
});
|
|
106745
107245
|
},
|
|
106746
107246
|
className: "hover:bg-muted rounded-md px-2 py-1 text-xs font-semibold",
|
|
106747
107247
|
children: "File"
|
|
106748
107248
|
}
|
|
106749
|
-
),
|
|
106750
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
107249
|
+
) }),
|
|
107250
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuTargeter, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106751
107251
|
"button",
|
|
106752
107252
|
{
|
|
106753
107253
|
type: "button",
|
|
106754
107254
|
onClick: (event) => {
|
|
106755
|
-
|
|
106756
|
-
|
|
106757
|
-
|
|
106758
|
-
|
|
107255
|
+
setHeaderMenuAnchor(null);
|
|
107256
|
+
setFileMenuAnchor(null);
|
|
107257
|
+
setViewMenuAnchor({
|
|
107258
|
+
type: "target",
|
|
107259
|
+
element: event.currentTarget,
|
|
107260
|
+
placement: "bottom-start"
|
|
107261
|
+
});
|
|
106759
107262
|
},
|
|
106760
107263
|
className: "hover:bg-muted rounded-md px-2 py-1 text-xs font-semibold",
|
|
106761
107264
|
children: "View"
|
|
106762
107265
|
}
|
|
106763
|
-
)
|
|
107266
|
+
) })
|
|
106764
107267
|
] }),
|
|
106765
107268
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
106766
107269
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -106807,28 +107310,31 @@ function Config() {
|
|
|
106807
107310
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106808
107311
|
ContextMenu,
|
|
106809
107312
|
{
|
|
106810
|
-
open: !!
|
|
107313
|
+
open: !!headerMenuAnchor,
|
|
106811
107314
|
items: headerMenuItems,
|
|
106812
|
-
|
|
106813
|
-
|
|
107315
|
+
anchor: headerMenuAnchor,
|
|
107316
|
+
boundaryElement: schemaMenuWrapperRef.current,
|
|
107317
|
+
onClose: () => setHeaderMenuAnchor(null)
|
|
106814
107318
|
}
|
|
106815
107319
|
),
|
|
106816
107320
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106817
107321
|
ContextMenu,
|
|
106818
107322
|
{
|
|
106819
|
-
open: !!
|
|
107323
|
+
open: !!fileMenuAnchor,
|
|
106820
107324
|
items: fileMenuItems,
|
|
106821
|
-
|
|
106822
|
-
|
|
107325
|
+
anchor: fileMenuAnchor,
|
|
107326
|
+
boundaryElement: schemaMenuWrapperRef.current,
|
|
107327
|
+
onClose: () => setFileMenuAnchor(null)
|
|
106823
107328
|
}
|
|
106824
107329
|
),
|
|
106825
107330
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
106826
107331
|
ContextMenu,
|
|
106827
107332
|
{
|
|
106828
|
-
open: !!
|
|
107333
|
+
open: !!viewMenuAnchor,
|
|
106829
107334
|
items: viewMenuItems,
|
|
106830
|
-
|
|
106831
|
-
|
|
107335
|
+
anchor: viewMenuAnchor,
|
|
107336
|
+
boundaryElement: schemaMenuWrapperRef.current,
|
|
107337
|
+
onClose: () => setViewMenuAnchor(null)
|
|
106832
107338
|
}
|
|
106833
107339
|
)
|
|
106834
107340
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground text-sm", children: "Select a schema to view details." })
|
|
@@ -107552,6 +108058,9 @@ function formatArtifactLabel(id2) {
|
|
|
107552
108058
|
if (!id2) return "Unknown";
|
|
107553
108059
|
return id2.split(/[-_]/g).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
107554
108060
|
}
|
|
108061
|
+
function isHttpUrl(value) {
|
|
108062
|
+
return /^https?:\/\//.test(value);
|
|
108063
|
+
}
|
|
107555
108064
|
function sortArtifactIdsForSchema(schemaName, artifactIds) {
|
|
107556
108065
|
if (schemaName !== "spec-driven") return artifactIds;
|
|
107557
108066
|
const rank = /* @__PURE__ */ new Map();
|
|
@@ -107761,6 +108270,8 @@ function Dashboard() {
|
|
|
107761
108270
|
defaultBranch: "main",
|
|
107762
108271
|
worktrees: []
|
|
107763
108272
|
};
|
|
108273
|
+
const staticMode = isStaticMode();
|
|
108274
|
+
const showGitSnapshot = !staticMode || git.worktrees.some((worktree) => worktree.entries.length > 0);
|
|
107764
108275
|
const hasChanges = activeChanges.length > 0;
|
|
107765
108276
|
const currentWorktree = git.worktrees.find((worktree) => worktree.isCurrent) ?? null;
|
|
107766
108277
|
const otherWorktrees = git.worktrees.filter((worktree) => !worktree.isCurrent);
|
|
@@ -107792,7 +108303,7 @@ function Dashboard() {
|
|
|
107792
108303
|
}
|
|
107793
108304
|
)
|
|
107794
108305
|
] });
|
|
107795
|
-
const renderExecutionSnapshot = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className:
|
|
108306
|
+
const renderExecutionSnapshot = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `grid min-w-0 gap-3 ${showGitSnapshot ? "xl:grid-cols-2" : "xl:grid-cols-1"}`, children: [
|
|
107796
108307
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "@container min-w-0 space-y-2", children: [
|
|
107797
108308
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
107798
108309
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "font-medium", children: "Workflow Progress" }),
|
|
@@ -107860,7 +108371,7 @@ function Dashboard() {
|
|
|
107860
108371
|
schema2.schemaName
|
|
107861
108372
|
)) })
|
|
107862
108373
|
] }),
|
|
107863
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "min-w-0 space-y-2", children: [
|
|
108374
|
+
showGitSnapshot ? /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "min-w-0 space-y-2", children: [
|
|
107864
108375
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
107865
108376
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
|
|
107866
108377
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "font-medium", children: "Git Snapshot" }),
|
|
@@ -107869,7 +108380,7 @@ function Dashboard() {
|
|
|
107869
108380
|
git.defaultBranch
|
|
107870
108381
|
] })
|
|
107871
108382
|
] }),
|
|
107872
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
108383
|
+
!staticMode ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
107873
108384
|
"button",
|
|
107874
108385
|
{
|
|
107875
108386
|
type: "button",
|
|
@@ -107888,7 +108399,7 @@ function Dashboard() {
|
|
|
107888
108399
|
"Refresh"
|
|
107889
108400
|
]
|
|
107890
108401
|
}
|
|
107891
|
-
)
|
|
108402
|
+
) : null
|
|
107892
108403
|
] }),
|
|
107893
108404
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-border/80 min-w-0 rounded-lg border p-3", children: [
|
|
107894
108405
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2 flex items-center gap-1.5", children: [
|
|
@@ -107913,7 +108424,7 @@ function Dashboard() {
|
|
|
107913
108424
|
otherWorktrees.map((worktree) => /* @__PURE__ */ jsxRuntimeExports.jsx(WorktreeRow, { worktree, emphasize: false }, worktree.path))
|
|
107914
108425
|
] })
|
|
107915
108426
|
] })
|
|
107916
|
-
] })
|
|
108427
|
+
] }) : null
|
|
107917
108428
|
] });
|
|
107918
108429
|
const renderSpecificationsSection = () => /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-border min-w-0 rounded-lg border", children: [
|
|
107919
108430
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-border flex flex-wrap items-center justify-between gap-1.5 border-b px-4 py-3", children: [
|
|
@@ -108085,6 +108596,7 @@ function WorktreeRow({
|
|
|
108085
108596
|
worktree,
|
|
108086
108597
|
emphasize
|
|
108087
108598
|
}) {
|
|
108599
|
+
const pathLabel = isHttpUrl(worktree.path) ? worktree.path : `${worktree.relativePath} | ${worktree.path}`;
|
|
108088
108600
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
108089
108601
|
"div",
|
|
108090
108602
|
{
|
|
@@ -108095,11 +108607,7 @@ function WorktreeRow({
|
|
|
108095
108607
|
/* @__PURE__ */ jsxRuntimeExports.jsx(GitBranch, { className: "h-3.5 w-3.5" }),
|
|
108096
108608
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate", children: worktree.branchName })
|
|
108097
108609
|
] }),
|
|
108098
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
108099
|
-
worktree.relativePath,
|
|
108100
|
-
" | ",
|
|
108101
|
-
worktree.path
|
|
108102
|
-
] })
|
|
108610
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-muted-foreground truncate text-xs", children: pathLabel })
|
|
108103
108611
|
] }),
|
|
108104
108612
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shrink-0 text-right", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-1", children: [
|
|
108105
108613
|
/* @__PURE__ */ jsxRuntimeExports.jsx(GitAheadBehindBadge, { ahead: worktree.ahead, behind: worktree.behind }),
|