@fabiofiorita/porcelain 0.60.2 → 0.61.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @fabiofiorita/porcelain (0.60.2)
1
+ # @fabiofiorita/porcelain (0.61.1)
2
2
 
3
3
  Headless **Porcelain** backend — the Electron-free daemon + renderer, packaged for
4
4
  plain Node on any machine (Linux mini-PC, cloud VM, laptop). Same credential-gated
@@ -9628,6 +9628,7 @@ function toHubProject(environmentId, stored, live) {
9628
9628
  }
9629
9629
  function createHubInventoryOperations(options) {
9630
9630
  const createId = options.createId ?? import_node_crypto12.randomUUID;
9631
+ let registeredDiscoveries = /* @__PURE__ */ new Map();
9631
9632
  async function loadEnvironment() {
9632
9633
  const record = await options.environment.read();
9633
9634
  if (!record.ok) return unavailable6();
@@ -9647,19 +9648,22 @@ function createHubInventoryOperations(options) {
9647
9648
  const rematched = rematchWorktrees(stored.worktrees, listed.value, createId);
9648
9649
  return { stored: { ...stored, worktrees: rematched }, live: listed.value };
9649
9650
  }
9650
- async function registerDiscovered(working, discovered) {
9651
- const existence = /* @__PURE__ */ new Map();
9652
- await Promise.all(
9653
- working.map(async (project) => {
9654
- existence.set(project.commonGitDir, await options.git.pathExists(project.commonGitDir));
9655
- })
9651
+ async function projectExistence(projects) {
9652
+ const entries = await Promise.all(
9653
+ projects.map(
9654
+ async (project) => [project.commonGitDir, await options.git.pathExists(project.commonGitDir)]
9655
+ )
9656
9656
  );
9657
+ return new Map(entries);
9658
+ }
9659
+ function registerDiscovered(working, discovered, existence) {
9657
9660
  const rematched = rematchProject(
9658
9661
  working,
9659
9662
  discovered,
9660
9663
  (commonGitDir) => existence.get(commonGitDir) === true,
9661
9664
  createId
9662
9665
  );
9666
+ existence.set(discovered.commonGitDir, true);
9663
9667
  return upsertProject(working, rematched);
9664
9668
  }
9665
9669
  async function rebuild() {
@@ -9669,18 +9673,44 @@ function createHubInventoryOperations(options) {
9669
9673
  if (!storedResult.ok) return unavailable6();
9670
9674
  const recents = await options.recents.readPaths();
9671
9675
  if (!recents.ok) return unavailable6();
9676
+ const handoffs = registeredDiscoveries;
9677
+ registeredDiscoveries = /* @__PURE__ */ new Map();
9678
+ const recentDiscoveries = await Promise.all(
9679
+ recents.value.map(async (path) => {
9680
+ const allowed = allowedPath(path, options.pathAllowed);
9681
+ if (allowed === null) return null;
9682
+ const handedOff = handoffs.get(allowed);
9683
+ handoffs.delete(allowed);
9684
+ if (handedOff !== void 0) return { discovered: handedOff };
9685
+ const discovered = await options.git.discoverProject(allowed);
9686
+ return discovered.ok ? { discovered: discovered.value } : null;
9687
+ })
9688
+ );
9672
9689
  let working = [...storedResult.value];
9673
- for (const path of recents.value) {
9674
- const allowed = allowedPath(path, options.pathAllowed);
9675
- if (allowed === null) continue;
9676
- const discovered = await options.git.discoverProject(allowed);
9677
- if (!discovered.ok) continue;
9678
- working = await registerDiscovered(working, discovered.value);
9690
+ const discoveredWorktrees = /* @__PURE__ */ new Map();
9691
+ if (recentDiscoveries.some((entry) => entry !== null)) {
9692
+ const existence = await projectExistence(working);
9693
+ for (const entry of recentDiscoveries) {
9694
+ if (entry === null) continue;
9695
+ working = registerDiscovered(working, entry.discovered, existence);
9696
+ discoveredWorktrees.set(entry.discovered.commonGitDir, entry.discovered.worktrees);
9697
+ }
9679
9698
  }
9699
+ const refreshedProjects = await Promise.all(
9700
+ working.map(async (project) => {
9701
+ const discovered = discoveredWorktrees.get(project.commonGitDir);
9702
+ if (discovered !== void 0) {
9703
+ return {
9704
+ stored: project,
9705
+ live: discovered
9706
+ };
9707
+ }
9708
+ return await refreshProject(project);
9709
+ })
9710
+ );
9680
9711
  const live = [];
9681
9712
  const nextStored = [];
9682
- for (const project of working) {
9683
- const refreshed = await refreshProject(project);
9713
+ for (const refreshed of refreshedProjects) {
9684
9714
  const allowedLive = refreshed.live.flatMap((worktree) => {
9685
9715
  const path = allowedPath(worktree.path, options.pathAllowed);
9686
9716
  return path === null ? [] : [{ ...worktree, path }];
@@ -9807,8 +9837,13 @@ function createHubInventoryOperations(options) {
9807
9837
  if (!discovered.ok) return;
9808
9838
  const stored = await options.inventory.readProjects();
9809
9839
  if (!stored.ok) return;
9810
- const next = await registerDiscovered(stored.value, discovered.value);
9811
- await options.inventory.writeProjects(next);
9840
+ const next = registerDiscovered(
9841
+ stored.value,
9842
+ discovered.value,
9843
+ await projectExistence(stored.value)
9844
+ );
9845
+ const written = await options.inventory.writeProjects(next);
9846
+ if (written.ok) registeredDiscoveries.set(allowed, discovered.value);
9812
9847
  }
9813
9848
  });
9814
9849
  }
@@ -9924,7 +9959,6 @@ function createProjectsOperations(options) {
9924
9959
  }
9925
9960
 
9926
9961
  // ../daemon/src/features/projects/projects-ports.ts
9927
- var import_node_fs3 = require("node:fs");
9928
9962
  var import_promises23 = require("node:fs/promises");
9929
9963
  var import_node_os3 = require("node:os");
9930
9964
  var import_node_path34 = require("node:path");
@@ -9939,8 +9973,40 @@ function mapHostError(error) {
9939
9973
  if (code === "ENOTDIR") return "not-a-directory";
9940
9974
  return "unavailable";
9941
9975
  }
9976
+ var REPOSITORY_MARKER_CONCURRENCY = 8;
9977
+ async function mapWithConcurrency(values, concurrency, map) {
9978
+ const results = new Array(values.length);
9979
+ let nextIndex = 0;
9980
+ async function worker() {
9981
+ while (nextIndex < values.length) {
9982
+ const index = nextIndex;
9983
+ nextIndex += 1;
9984
+ const value = values[index];
9985
+ if (value === void 0) continue;
9986
+ results[index] = await map(value);
9987
+ }
9988
+ }
9989
+ await Promise.all(Array.from({ length: Math.min(concurrency, values.length) }, () => worker()));
9990
+ return results;
9991
+ }
9992
+ async function defaultRepositoryMarkerExists(path) {
9993
+ try {
9994
+ await (0, import_promises23.stat)(path);
9995
+ return true;
9996
+ } catch {
9997
+ return false;
9998
+ }
9999
+ }
10000
+ async function isRepositoryMarker(repositoryMarkerExists, path) {
10001
+ try {
10002
+ return await repositoryMarkerExists(path);
10003
+ } catch {
10004
+ return false;
10005
+ }
10006
+ }
9942
10007
  function createNodeProjectsPort(options = {}) {
9943
10008
  const showHidden = options.showHidden ?? false;
10009
+ const repositoryMarkerExists = options.repositoryMarkerExists ?? defaultRepositoryMarkerExists;
9944
10010
  return Object.freeze({
9945
10011
  async inspectProject(path) {
9946
10012
  try {
@@ -9955,14 +10021,11 @@ function createNodeProjectsPort(options = {}) {
9955
10021
  const target2 = path ?? (0, import_node_os3.homedir)();
9956
10022
  try {
9957
10023
  const dirents = await (0, import_promises23.readdir)(target2, { withFileTypes: true });
9958
- const entries = dirents.filter((entry) => entry.isDirectory() && (showHidden || !entry.name.startsWith("."))).map((entry) => {
9959
- const entryPath = (0, import_node_path34.join)(target2, entry.name);
9960
- return {
9961
- name: entry.name,
9962
- path: entryPath,
9963
- isRepo: (0, import_node_fs3.existsSync)((0, import_node_path34.join)(entryPath, ".git"))
9964
- };
9965
- }).sort((a, b) => a.name.localeCompare(b.name, void 0, { sensitivity: "accent" }));
10024
+ const directories = dirents.filter((entry) => entry.isDirectory() && (showHidden || !entry.name.startsWith("."))).map((entry) => ({ name: entry.name, path: (0, import_node_path34.join)(target2, entry.name) }));
10025
+ const entries = (await mapWithConcurrency(directories, REPOSITORY_MARKER_CONCURRENCY, async (entry) => ({
10026
+ ...entry,
10027
+ isRepo: await isRepositoryMarker(repositoryMarkerExists, (0, import_node_path34.join)(entry.path, ".git"))
10028
+ }))).sort((a, b) => a.name.localeCompare(b.name, void 0, { sensitivity: "accent" }));
9966
10029
  const parentPath = (0, import_node_path34.dirname)(target2);
9967
10030
  return {
9968
10031
  ok: true,
@@ -13188,7 +13251,7 @@ var import_promises30 = require("node:fs/promises");
13188
13251
  var import_node_path45 = require("node:path");
13189
13252
 
13190
13253
  // ../daemon/src/review/review-watch.ts
13191
- var import_node_fs4 = require("node:fs");
13254
+ var import_node_fs3 = require("node:fs");
13192
13255
  var import_promises29 = require("node:fs/promises");
13193
13256
  var import_node_path44 = require("node:path");
13194
13257
 
@@ -14360,7 +14423,7 @@ async function watchRepo(repoPath) {
14360
14423
  try {
14361
14424
  const dir = projectActiveReviewDir(repoPath);
14362
14425
  if (!(await (0, import_promises29.stat)(dir)).isDirectory()) return;
14363
- const watcher = (0, import_node_fs4.watch)(dir, (_event, filename) => {
14426
+ const watcher = (0, import_node_fs3.watch)(dir, (_event, filename) => {
14364
14427
  const name = typeof filename === "string" ? (0, import_node_path44.basename)(filename) : null;
14365
14428
  const kind = name === null ? void 0 : FILE_CHANGES[name];
14366
14429
  if (kind) publish(kind, repoPath);
@@ -15006,11 +15069,11 @@ function daemonIdentity(host = process.env.PORCELAIN_DAEMON_HOST?.trim() || (0,
15006
15069
 
15007
15070
  // ../daemon/src/net/daemon-version.ts
15008
15071
  function daemonVersion() {
15009
- return "0.60.2";
15072
+ return "0.61.1";
15010
15073
  }
15011
15074
 
15012
15075
  // ../daemon/src/stores/review-store.ts
15013
- var import_node_fs5 = require("node:fs");
15076
+ var import_node_fs4 = require("node:fs");
15014
15077
  var import_promises33 = require("node:fs/promises");
15015
15078
  var import_node_path48 = require("node:path");
15016
15079
  var import_zod50 = require("zod");
@@ -15080,22 +15143,22 @@ function sanitizeReview(repoPath, set) {
15080
15143
  function projectIdentity(repoPath) {
15081
15144
  try {
15082
15145
  const dotGit = (0, import_node_path48.resolve)(repoPath, ".git");
15083
- const dotGitStat = (0, import_node_fs5.statSync)(dotGit);
15146
+ const dotGitStat = (0, import_node_fs4.statSync)(dotGit);
15084
15147
  const gitDir = dotGitStat.isFile() ? (0, import_node_path48.resolve)(
15085
15148
  repoPath,
15086
- (0, import_node_fs5.readFileSync)(dotGit, "utf8").trim().replace(/^gitdir:\s*/i, "")
15149
+ (0, import_node_fs4.readFileSync)(dotGit, "utf8").trim().replace(/^gitdir:\s*/i, "")
15087
15150
  ) : dotGit;
15088
15151
  const commonDirFile = (0, import_node_path48.resolve)(gitDir, "commondir");
15089
15152
  const commonDir = (() => {
15090
15153
  try {
15091
- return (0, import_node_path48.resolve)(gitDir, (0, import_node_fs5.readFileSync)(commonDirFile, "utf8").trim());
15154
+ return (0, import_node_path48.resolve)(gitDir, (0, import_node_fs4.readFileSync)(commonDirFile, "utf8").trim());
15092
15155
  } catch {
15093
15156
  return gitDir;
15094
15157
  }
15095
15158
  })();
15096
- const commonGitDir = (0, import_node_fs5.realpathSync)(commonDir);
15159
+ const commonGitDir = (0, import_node_fs4.realpathSync)(commonDir);
15097
15160
  const inventory = JSON.parse(
15098
- (0, import_node_fs5.readFileSync)((0, import_node_path48.join)(porcelainHome(), "hub-inventory.json"), "utf8")
15161
+ (0, import_node_fs4.readFileSync)((0, import_node_path48.join)(porcelainHome(), "hub-inventory.json"), "utf8")
15099
15162
  );
15100
15163
  const projects = inventory.value?.projects ?? [];
15101
15164
  const project = projects.find(
@@ -15104,7 +15167,7 @@ function projectIdentity(repoPath) {
15104
15167
  if (project === void 0) return null;
15105
15168
  const worktree = project.worktrees?.find((entry) => {
15106
15169
  try {
15107
- return (0, import_node_fs5.realpathSync)(entry.gitDir) === (0, import_node_fs5.realpathSync)(gitDir);
15170
+ return (0, import_node_fs4.realpathSync)(entry.gitDir) === (0, import_node_fs4.realpathSync)(gitDir);
15108
15171
  } catch {
15109
15172
  return false;
15110
15173
  }
@@ -15263,7 +15326,7 @@ function createDaemonOperations(options) {
15263
15326
  }
15264
15327
 
15265
15328
  // ../daemon/src/dev-config.ts
15266
- var import_node_fs6 = require("node:fs");
15329
+ var import_node_fs5 = require("node:fs");
15267
15330
  var import_promises34 = require("node:fs/promises");
15268
15331
  var import_node_os8 = require("node:os");
15269
15332
  var import_node_path49 = require("node:path");
@@ -15277,7 +15340,7 @@ function recognizedDevPlaygroundPath(path, primaryPath) {
15277
15340
  const suffix = [];
15278
15341
  while (true) {
15279
15342
  try {
15280
- const root = import_node_fs6.realpathSync.native(cursor);
15343
+ const root = import_node_fs5.realpathSync.native(cursor);
15281
15344
  return suffix.length === 0 ? root : (0, import_node_path49.resolve)(root, ...suffix.reverse());
15282
15345
  } catch {
15283
15346
  const parent = (0, import_node_path49.dirname)(cursor);
@@ -15291,7 +15354,7 @@ function recognizedDevPlaygroundPath(path, primaryPath) {
15291
15354
  const primary = canonical(primaryPath);
15292
15355
  if (candidate === null || primary === null) return null;
15293
15356
  try {
15294
- if ((0, import_node_fs6.realpathSync)((0, import_node_path49.resolve)(primaryPath)) !== (0, import_node_path49.resolve)(primaryPath)) return null;
15357
+ if ((0, import_node_fs5.realpathSync)((0, import_node_path49.resolve)(primaryPath)) !== (0, import_node_path49.resolve)(primaryPath)) return null;
15295
15358
  } catch {
15296
15359
  }
15297
15360
  if (candidate === primary) return candidate;
@@ -15305,7 +15368,7 @@ function recognizedDevPlaygroundPath(path, primaryPath) {
15305
15368
  for (const managedRoot of managedRoots) {
15306
15369
  let canonicalRoot;
15307
15370
  try {
15308
- canonicalRoot = import_node_fs6.realpathSync.native(managedRoot);
15371
+ canonicalRoot = import_node_fs5.realpathSync.native(managedRoot);
15309
15372
  } catch {
15310
15373
  const unresolved = canonical(managedRoot);
15311
15374
  if (unresolved === null || unresolved !== (0, import_node_path49.resolve)(managedRoot)) continue;
@@ -15544,13 +15607,13 @@ async function handleFilePreviewRequest(req, res, deps) {
15544
15607
  }
15545
15608
 
15546
15609
  // ../daemon/src/net/static-server.ts
15547
- var import_node_fs7 = require("node:fs");
15610
+ var import_node_fs6 = require("node:fs");
15548
15611
  var import_promises36 = require("node:fs/promises");
15549
15612
  var import_node_path51 = require("node:path");
15550
15613
  var import_node_zlib = require("node:zlib");
15551
15614
  var RENDERER_ROOT = (0, import_node_path51.resolve)(__dirname, "..", "..", "renderer");
15552
15615
  function rendererDistExists() {
15553
- return (0, import_node_fs7.existsSync)((0, import_node_path51.join)(RENDERER_ROOT, "index.html"));
15616
+ return (0, import_node_fs6.existsSync)((0, import_node_path51.join)(RENDERER_ROOT, "index.html"));
15554
15617
  }
15555
15618
  var CONTENT_TYPES = {
15556
15619
  html: "text/html; charset=utf-8",
@@ -15670,7 +15733,7 @@ async function serveStatic(req, res, root = RENDERER_ROOT) {
15670
15733
  res.end(body);
15671
15734
  return;
15672
15735
  }
15673
- const stream = (0, import_node_fs7.createReadStream)(filePath);
15736
+ const stream = (0, import_node_fs6.createReadStream)(filePath);
15674
15737
  stream.once("error", () => {
15675
15738
  if (!res.headersSent) res.writeHead(404);
15676
15739
  res.end();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabiofiorita/porcelain",
3
- "version": "0.60.2",
3
+ "version": "0.61.1",
4
4
  "description": "Headless Porcelain daemon — plain Node backend for remote machines (npx @fabiofiorita/porcelain@latest serve)",
5
5
  "license": "MIT",
6
6
  "author": "Fabio Fiorita <fabiolfp@gmail.com>",
@@ -0,0 +1 @@
1
+ import{Z as X,r,aC as ve,aD as Re,aE as te,aF as _,aG as oe,aH as me,aI as fe,aJ as ce,j as e,aK as Te,aL as ke,aM as be,aN as Me,aO as Ee,aP as xe,aQ as ze,aR as Se,aS as Ie,aT as pe,aU as he,aV as Ve,aW as De,aX as Le,aY as Ae,aZ as Oe,a_ as Pe,a$ as Be,m as ae,b0 as _e,c as $e,ah as $,B as Fe,x as He,y as Ue,z as We,b1 as Je,aw as Ke,T as G,b2 as Ye,b3 as Ge,b4 as Xe,b5 as Ze,b6 as qe,b7 as Qe,b8 as et}from"./index-B7RkrSLU.js";import{M as le}from"./markdown-view-DJGgLy5g.js";const tt=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12",key:"1pkeuh"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16",key:"4dfq90"}]],at=X("circle-alert",tt);const st=[["path",{d:"M4 12.15V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.706.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2h-3.35",key:"1wthlu"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["path",{d:"m5 16-3 3 3 3",key:"331omg"}],["path",{d:"m9 22 3-3-3-3",key:"lsp7cz"}]],nt=X("file-code-corner",st);const rt=[["path",{d:"m12 14 4-4",key:"9kzdfg"}],["path",{d:"M3.34 19a10 10 0 1 1 17.32 0",key:"19p75a"}]],it=X("gauge",rt);const ot=[["path",{d:"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5",key:"1gvzjb"}],["path",{d:"M9 18h6",key:"x1upvd"}],["path",{d:"M10 22h4",key:"ceow96"}]],lt=X("lightbulb",ot);const ct=[["path",{d:"M12 3v18",key:"108xh3"}],["path",{d:"m19 8 3 8a5 5 0 0 1-6 0zV7",key:"zcdpyk"}],["path",{d:"M3 7h1a17 17 0 0 0 8-2 17 17 0 0 0 8 2h1",key:"1yorad"}],["path",{d:"m5 8 3 8a5 5 0 0 1-6 0zV7",key:"eua70x"}],["path",{d:"M7 21h10",key:"1b0cd5"}]],dt=X("scale",ct),je=r.createContext(void 0);function de(){const t=r.useContext(je);if(t===void 0)throw new Error(ve(64));return t}let ut=(function(t){return t.activationDirection="data-activation-direction",t.orientation="data-orientation",t})({});const ue={tabActivationDirection:t=>({[ut.activationDirection]:t})},mt=r.forwardRef(function(a,n){const{className:o,defaultValue:s=0,onValueChange:i,orientation:d="horizontal",render:v,value:h,style:b,...w}=a,E=a.defaultValue!==void 0,L=r.useRef([]),[z,T]=r.useState(()=>new Map),[l,C]=Re({controlled:h,default:s,name:"Tabs",state:"value"}),S=h!==void 0,[m,j]=r.useState(()=>new Map),y=r.useCallback(c=>{if(c===void 0)return null;for(const[x,g]of m.entries())if(g!=null&&c===(g.value??g.index))return x;return null},[m]),[V,I]=r.useState(()=>({previousValue:l,tabActivationDirection:"none"})),{previousValue:N,tabActivationDirection:R}=V;let f=R,k=!1;N!==l&&(f=ge(N,l,d,m),k=N!=null&&l!=null&&y(l)==null);const u=k?N:l,M=N!==u||R!==f;te(()=>{M&&I({previousValue:u,tabActivationDirection:f})},[u,M,f]);const Z=_((c,x)=>{const g=ge(l,c,d,m);x.activationDirection=g,i?.(c,x),!x.isCanceled&&C(c)}),J=_((c,x)=>{i?.(c,oe(x,void 0,void 0,{activationDirection:"none"}))}),A=_((c,x)=>{T(g=>{if(g.get(c)===x)return g;const D=new Map(g);return D.set(c,x),D})}),F=_((c,x)=>{T(g=>{if(!g.has(c)||g.get(c)!==x)return g;const D=new Map(g);return D.delete(c),D})}),q=r.useCallback(c=>z.get(c),[z]),Q=r.useCallback(c=>{for(const x of m.values())if(c===x?.value)return x?.id},[m]),se=r.useMemo(()=>({getTabElementBySelectedValue:y,getTabIdByPanelValue:Q,getTabPanelIdByValue:q,onValueChange:Z,orientation:d,registerMountedTabPanel:A,setTabMap:j,unregisterMountedTabPanel:F,tabActivationDirection:f,value:l}),[y,Q,q,Z,d,A,j,F,f,l]),K=r.useMemo(()=>{for(const c of m.values())if(c!=null&&c.value===l)return c},[m,l]),ne=r.useMemo(()=>{for(const c of m.values())if(c!=null&&!c.disabled)return c.value},[m]),p=r.useRef(!E),O=r.useRef(E),re=r.useRef(!1);te(()=>{if(S)return;function c(P,Y){C(P),I(ie=>ie.previousValue===P&&ie.tabActivationDirection==="none"?ie:{previousValue:P,tabActivationDirection:"none"}),J(P,Y),p.current=!1}if(m.size===0){if(!re.current||l===null)return;c(null,fe);return}re.current=!0;const x=K?.disabled,g=K==null&&l!==null;if(!x&&l===s&&(O.current=!1),O.current&&x&&l===s)return;const D=p.current;if(x||g){const P=ne??null;if(l===P){p.current=!1;return}let Y=fe;D?Y=me:x&&(Y=ke),c(P,Y);return}D&&K!=null&&(J(l,me),p.current=!1)},[s,ne,S,J,K,C,m,l]);const Ce=ce("div",a,{state:{orientation:d,tabActivationDirection:f},ref:n,props:w,stateAttributesMapping:ue});return e.jsx(je.Provider,{value:se,children:e.jsx(Te,{elementsRef:L,children:Ce})})});function ge(t,a,n,o){if(t==null||a==null)return"none";let s=null,i=null;for(const[h,b]of o.entries()){if(b==null)continue;const w=b.value??b.index;if(t===w&&(s=h),a===w&&(i=h),s!=null&&i!=null)break}if(s==null||i==null)return s!==i&&(typeof t=="number"||typeof t=="string")&&typeof t==typeof a?n==="horizontal"?a>t?"right":"left":a>t?"down":"up":"none";const d=s.getBoundingClientRect(),v=i.getBoundingClientRect();if(n==="horizontal"){if(v.left<d.left)return"left";if(v.left>d.left)return"right"}else{if(v.top<d.top)return"up";if(v.top>d.top)return"down"}return"none"}const ye=r.createContext(void 0);function ft(){const t=r.useContext(ye);if(t===void 0)throw new Error(ve(65));return t}const xt=r.forwardRef(function(a,n){const{className:o,disabled:s=!1,render:i,value:d,id:v,nativeButton:h=!0,style:b,...w}=a,{value:E,getTabPanelIdByValue:L,orientation:z}=de(),{activateOnFocus:T,highlightedTabIndex:l,onTabActivation:C,registerTabResizeObserverElement:S,setHighlightedTabIndex:m,tabsListElement:j}=ft(),y=be(v),V=r.useMemo(()=>({disabled:s,id:y,value:d}),[s,y,d]),{compositeProps:I,compositeRef:N,index:R}=Me({metadata:V}),f=d===E,k=r.useRef(!1),u=r.useRef(null);r.useEffect(()=>{const p=u.current;if(p)return S(p)},[S]),te(()=>{if(k.current){k.current=!1;return}if(!(f&&R>-1&&l!==R))return;const p=j;if(p!=null){const O=Ee(xe(p));if(O&&ze(p,O))return}s||m(R)},[f,R,l,m,s,j]);const{getButtonProps:M,buttonRef:Z}=Se({disabled:s,native:h,focusableWhenDisabled:!0}),J=L(d),A=r.useRef(!1),F=r.useRef(!1);function q(p){f||s||C(d,oe(pe,p.nativeEvent,void 0,{activationDirection:"none"}))}function Q(p){f||(R>-1&&!s&&m(R),!s&&T&&(!A.current||A.current&&F.current)&&C(d,oe(pe,p.nativeEvent,void 0,{activationDirection:"none"})))}function se(p){if(f||s)return;A.current=!0;function O(){A.current=!1,F.current=!1}(!p.button||p.button===0)&&(F.current=!0,xe(p.currentTarget).addEventListener("pointerup",O,{once:!0}))}return ce("button",a,{state:{disabled:s,active:f,orientation:z},ref:[n,Z,N,u],props:[I,{role:"tab","aria-controls":J,"aria-selected":f,id:y,onClick:q,onFocus:Q,onPointerDown:se,[Ie]:f?"":void 0,onKeyDownCapture(){k.current=!0}},w,M]})});let pt=(function(t){return t.index="data-index",t.activationDirection="data-activation-direction",t.orientation="data-orientation",t.hidden="data-hidden",t[t.startingStyle=he.startingStyle]="startingStyle",t[t.endingStyle=he.endingStyle]="endingStyle",t})({});const ht={...ue,...Oe},gt=r.forwardRef(function(a,n){const{className:o,value:s,render:i,keepMounted:d=!1,style:v,...h}=a,{value:b,getTabIdByPanelValue:w,orientation:E,tabActivationDirection:L,registerMountedTabPanel:z,unregisterMountedTabPanel:T}=de(),l=be(),C=r.useMemo(()=>({id:l,value:s}),[l,s]),{ref:S,index:m}=Ve({metadata:C}),j=s===b,{mounted:y,transitionStatus:V,setMounted:I}=De(j),N=!y,R=w(s),f={hidden:N,orientation:E,tabActivationDirection:L,transitionStatus:V},k=r.useRef(null),u=ce("div",a,{state:f,ref:[n,S,k],props:[{"aria-labelledby":R,hidden:N,id:l,role:"tabpanel",tabIndex:j?0:-1,inert:Le(!j),[pt.index]:m},h],stateAttributesMapping:ht});return Ae({open:j,ref:k,onComplete(){j||I(!1)}}),te(()=>{if(!(N&&!d)&&l!=null)return z(s,l),()=>{T(s,l)}},[N,d,s,l,z,T]),d||y?u:null}),vt=r.forwardRef(function(a,n){const{activateOnFocus:o=!1,className:s,loopFocus:i=!0,render:d,style:v,...h}=a,{onValueChange:b,orientation:w,value:E,setTabMap:L,tabActivationDirection:z}=de(),[T,l]=r.useState(0),[C,S]=r.useState(null),m=r.useRef(new Set),j=r.useRef(new Set),y=r.useRef(null);r.useEffect(()=>{if(typeof ResizeObserver>"u")return;const u=new ResizeObserver(()=>{m.current.forEach(M=>{M()})});return y.current=u,C&&u.observe(C),j.current.forEach(M=>{u.observe(M)}),()=>{u.disconnect(),y.current=null}},[C]);const V=_(u=>(m.current.add(u),()=>{m.current.delete(u)})),I=_(u=>(j.current.add(u),y.current?.observe(u),()=>{j.current.delete(u),y.current?.unobserve(u)})),N=_((u,M)=>{u!==E&&b(u,M)}),R={orientation:w,tabActivationDirection:z},f={"aria-orientation":w==="vertical"?"vertical":void 0,role:"tablist"},k=r.useMemo(()=>({activateOnFocus:o,highlightedTabIndex:T,registerIndicatorUpdateListener:V,registerTabResizeObserverElement:I,onTabActivation:N,setHighlightedTabIndex:l,tabsListElement:C}),[o,T,V,I,N,l,C]);return e.jsx(ye.Provider,{value:k,children:e.jsx(Pe,{render:d,className:s,style:v,state:R,refs:[n,S],props:[f,h],stateAttributesMapping:ue,highlightedIndex:T,enableHomeAndEndKeys:!0,loopFocus:i,orientation:w,onHighlightedIndexChange:l,onMapChange:L,disabledIndices:Be})})});function Ne({className:t,orientation:a="horizontal",...n}){return e.jsx(mt,{"data-slot":"tabs","data-orientation":a,className:ae("group/tabs flex gap-2 data-horizontal:flex-col",t),...n})}const bt=_e("group/tabs-list inline-flex w-fit items-center justify-center rounded-2xl p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col group-data-vertical/tabs:p-1 data-[variant=line]:rounded-none",{variants:{variant:{default:"bg-muted",line:"gap-1 bg-transparent"}},defaultVariants:{variant:"default"}});function we({className:t,variant:a="default",...n}){return e.jsx(vt,{"data-slot":"tabs-list","data-variant":a,className:ae(bt({variant:a}),t),...n})}function H({className:t,...a}){return e.jsx(xt,{"data-slot":"tabs-trigger",className:ae("relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-2xl border border-transparent! px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start group-data-vertical/tabs:px-3 group-data-vertical/tabs:py-0.5 hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4","group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent","data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground","after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100",t),...a})}function U({className:t,...a}){return e.jsx(gt,{"data-slot":"tabs-content",className:ae("flex-1 text-sm outline-none",t),...a})}function B({title:t,children:a}){return e.jsxs("section",{className:"space-y-3",children:[e.jsx("h2",{className:"text-base font-semibold tracking-tight",children:t}),a]})}function W({items:t,empty:a}){return t.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:a}):e.jsx("ul",{className:"space-y-2 text-sm leading-6",children:t.map(n=>e.jsxs("li",{className:"flex gap-2",children:[e.jsx("span",{"aria-hidden":"true",className:"mt-2 size-1.5 shrink-0 rounded-full bg-current"}),e.jsx("span",{children:n})]},n))})}function ee({references:t,onOpen:a}){return t.length===0?null:e.jsxs("fieldset",{className:"flex flex-wrap gap-2",children:[e.jsx("legend",{className:"sr-only",children:"Repository references"}),t.map(n=>e.jsxs(Fe,{type:"button",variant:"outline",size:"sm",className:"h-auto min-h-8 max-w-full justify-start gap-2 py-1.5 font-mono text-xs",onClick:()=>a(n),children:[e.jsx(nt,{className:"size-3.5 shrink-0"}),e.jsxs("span",{className:"truncate",children:[n.label??n.path,n.line===void 0?"":`:${n.line}`]})]},`${n.path}:${n.line??""}`))]})}function jt({option:t,onOpen:a}){return e.jsxs("article",{className:"mx-auto w-full max-w-5xl space-y-8 p-5 sm:p-8",children:[e.jsxs("header",{className:"space-y-3",children:[e.jsx($,{variant:"secondary",children:"Option"}),e.jsx("h1",{className:"text-2xl font-semibold tracking-tight sm:text-3xl",children:t.name}),e.jsx("p",{className:"max-w-3xl text-base leading-7 text-muted-foreground",children:t.summary}),e.jsx(ee,{references:t.references,onOpen:a})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-xl border bg-card p-5",children:[e.jsxs("h2",{className:"mb-3 flex items-center gap-2 font-medium",children:[e.jsx(Je,{className:"size-4 text-emerald-600 dark:text-emerald-400"})," Pros"]}),e.jsx(W,{items:t.pros,empty:"No advantages recorded."})]}),e.jsxs("div",{className:"rounded-xl border bg-card p-5",children:[e.jsxs("h2",{className:"mb-3 flex items-center gap-2 font-medium",children:[e.jsx(Ke,{className:"size-4 text-rose-600 dark:text-rose-400"})," Cons"]}),e.jsx(W,{items:t.cons,empty:"No disadvantages recorded."})]})]}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2",children:[e.jsx(B,{title:"Risks",children:t.risks.length===0?e.jsx("p",{className:"text-sm text-muted-foreground",children:"No risks recorded."}):e.jsx("div",{className:"space-y-3",children:t.risks.map(n=>e.jsxs("div",{className:"rounded-lg border bg-muted/20 p-4 text-sm",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsx("p",{className:"font-medium",children:n.summary}),n.severity===void 0?null:e.jsx($,{variant:"outline",className:"capitalize",children:n.severity})]}),n.mitigation===void 0?null:e.jsxs("p",{className:"mt-2 leading-6 text-muted-foreground",children:["Mitigation: ",n.mitigation]})]},n.summary))})}),e.jsx(B,{title:"Effort",children:e.jsx("p",{className:"rounded-lg border bg-muted/20 p-4 text-sm leading-6",children:t.effort??"No effort assessment recorded."})})]})]})}const yt={poor:"border-rose-500/30 bg-rose-500/10",fair:"border-amber-500/30 bg-amber-500/10",good:"border-sky-500/30 bg-sky-500/10",strong:"border-emerald-500/30 bg-emerald-500/10"};function Nt({document:t}){return e.jsxs("div",{className:"mx-auto w-full max-w-7xl space-y-7 p-5 sm:p-8",children:[e.jsxs("header",{className:"space-y-2",children:[e.jsxs($,{variant:"secondary",className:"gap-1.5",children:[e.jsx(dt,{className:"size-3.5"})," Comparison"]}),e.jsx("h1",{className:"text-2xl font-semibold tracking-tight sm:text-3xl",children:"Compare the options"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Assessments are explanatory signals, not code truth or review state."})]}),t.criteria.map(a=>e.jsxs("section",{className:"space-y-3 rounded-xl border bg-card p-4 sm:p-5",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"font-semibold",children:a.label}),a.description===void 0?null:e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:a.description})]}),e.jsx("div",{"data-testid":`decision-comparison-${a.id}`,className:"grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3",children:t.options.map(n=>{const o=t.assessments.find(s=>s.optionId===n.id&&s.criterionId===a.id);return e.jsxs("article",{className:`min-w-0 rounded-lg border p-4 ${o===void 0?"bg-muted/20":yt[o.rating]}`,children:[e.jsx("h3",{className:"truncate text-sm font-semibold",children:n.name}),o===void 0?e.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:"Not assessed"}):e.jsxs(e.Fragment,{children:[e.jsx($,{variant:"outline",className:"mt-2 capitalize",children:o.rating}),e.jsx("p",{className:"mt-3 text-sm leading-6",children:o.note})]})]},n.id)})})]},a.id))]})}function wt({document:t,repoPath:a}){const n=$e(i=>i.openTab),o=i=>{a!==void 0&&n(He("file",`${a}/${i.path}`,{title:We(i.path),...i.line===void 0?{}:{line:i.line}},Ue()))},s=t.decision===void 0?"Recommendation":"Decision";return e.jsxs(Ne,{defaultValue:"summary",className:"flex h-full min-h-0 flex-col gap-0",children:[e.jsx("div",{className:"shrink-0 overflow-x-auto border-b px-3 py-2 sm:px-5",children:e.jsxs(we,{variant:"line","aria-label":"Decision Canvas views",className:"w-max min-w-full justify-start",children:[e.jsx(H,{value:"summary",children:"Summary"}),t.options.map(i=>e.jsx(H,{value:`option-${i.id}`,children:i.name},i.id)),e.jsx(H,{value:"compare",children:"Compare"}),e.jsx(H,{value:"recommendation",children:s})]})}),e.jsx(U,{value:"summary",className:"min-h-0 flex-1 overflow-y-auto",children:e.jsxs("article",{className:"mx-auto w-full max-w-5xl space-y-8 p-5 sm:p-8",children:[e.jsxs("header",{className:"space-y-4",children:[e.jsxs($,{variant:"secondary",className:"gap-1.5",children:[e.jsx(lt,{className:"size-3.5"})," Decision / RFC"]}),e.jsx("h1",{className:"text-3xl font-semibold tracking-tight sm:text-4xl",children:t.title}),e.jsx("p",{className:"max-w-3xl text-lg leading-8 text-muted-foreground",children:t.summary}),e.jsx(ee,{references:t.references,onOpen:o})]}),t.context===void 0?null:e.jsx(B,{title:"Context",children:e.jsx("p",{className:"max-w-3xl whitespace-pre-wrap text-sm leading-7",children:t.context})}),e.jsx(B,{title:"Options at a glance",children:e.jsx("div",{className:"grid gap-3 md:grid-cols-2 xl:grid-cols-3",children:t.options.map(i=>e.jsxs("div",{className:"rounded-xl border bg-card p-4",children:[e.jsx("h3",{className:"font-semibold",children:i.name}),e.jsx("p",{className:"mt-2 text-sm leading-6 text-muted-foreground",children:i.summary})]},i.id))})})]})}),t.options.map(i=>e.jsx(U,{value:`option-${i.id}`,className:"min-h-0 flex-1 overflow-y-auto",children:e.jsx(jt,{option:i,onOpen:o})},i.id)),e.jsx(U,{value:"compare",className:"min-h-0 flex-1 overflow-y-auto",children:e.jsx(Nt,{document:t})}),e.jsx(U,{value:"recommendation",className:"min-h-0 flex-1 overflow-y-auto",children:e.jsxs("article",{className:"mx-auto w-full max-w-5xl space-y-8 p-5 sm:p-8",children:[e.jsxs("header",{className:"space-y-3",children:[e.jsxs($,{variant:"secondary",className:"gap-1.5",children:[e.jsx(it,{className:"size-3.5"})," ",s]}),e.jsx("h1",{className:"text-2xl font-semibold tracking-tight sm:text-3xl",children:t.recommendation.summary}),e.jsxs($,{variant:"outline",className:"capitalize",children:[t.recommendation.confidence," confidence"]})]}),e.jsx(B,{title:"Rationale",children:e.jsx(W,{items:t.recommendation.rationale,empty:"No rationale recorded."})}),e.jsxs("div",{className:"grid gap-6 md:grid-cols-2",children:[e.jsx(B,{title:"Assumptions",children:e.jsx(W,{items:t.recommendation.assumptions,empty:"No assumptions recorded."})}),e.jsx(B,{title:"What would change this",children:e.jsx(W,{items:t.recommendation.changeConditions,empty:"No change conditions recorded."})})]}),e.jsx(ee,{references:t.recommendation.references,onOpen:o}),t.decision===void 0?null:e.jsxs("section",{className:"space-y-4 rounded-xl border border-primary/30 bg-primary/5 p-5 sm:p-6",children:[e.jsxs("h2",{className:"flex items-center gap-2 text-lg font-semibold",children:[e.jsx(at,{className:"size-5"})," Recorded final decision"]}),e.jsx("p",{className:"text-base leading-7",children:t.decision.summary}),e.jsx(W,{items:t.decision.rationale,empty:"No additional rationale recorded."}),e.jsx(ee,{references:t.decision.references,onOpen:o})]})]})})]})}function Ct({content:t,repoPath:a}){let n;try{n=JSON.parse(t)}catch(s){return e.jsxs("div",{"data-testid":G.structuredCanvasInvalid,className:"p-6 text-sm text-destructive",children:["Invalid structured Canvas: ",s instanceof Error?s.message:"invalid JSON"]})}const o=Ye.safeParse(n);return o.success?o.data.template==="review"?e.jsxs(Ne,{"data-testid":G.structuredCanvas,defaultValue:"why",className:"flex h-full min-h-0 flex-col gap-0",children:[e.jsx("div",{className:"shrink-0 border-b px-4 py-2",children:e.jsxs(we,{variant:"line",children:[e.jsx(H,{value:"why",children:"Why"}),e.jsx(H,{value:"how",children:"How"})]})}),e.jsx(U,{value:"why",className:"min-h-0 flex-1 overflow-y-auto",children:e.jsx(le,{content:o.data.why})}),e.jsx(U,{value:"how",className:"min-h-0 flex-1 overflow-y-auto",children:e.jsx(le,{content:o.data.how})})]}):e.jsx("div",{"data-testid":G.structuredCanvas,className:"h-full min-h-0",children:e.jsx(wt,{document:o.data,repoPath:a})}):e.jsxs("div",{"data-testid":G.structuredCanvasInvalid,className:"p-6 text-sm text-destructive",children:["Invalid structured Canvas: ",Ge(o.error)]})}function Rt(t){if(typeof t!="object"||t===null)return null;const a=t;return a.source!=="porcelain-canvas"?null:typeof a.href=="string"?a.href:null}function Tt({projectId:t,canvasId:a,worktreePath:n,environmentId:o}){const{mint:s}=Ze(),d=qe(o??null)?.session.baseUrl()??Qe(),[v,h]=r.useState(null);return r.useEffect(()=>{let b=!1;h(null);const w={projectId:t,canvasId:a,...n===void 0?{}:{worktreePath:n},...o===void 0?{}:{environmentId:o}};return et(s(w).then(E=>{b||h(`${d}/canvas/${E}`)}),"fallback"),()=>{b=!0}},[t,a,n,o,d,s]),v}function kt({projectId:t,canvasId:a,title:n,worktreePath:o,environmentId:s}){const i=Tt({projectId:t,canvasId:a,worktreePath:o,environmentId:s}),d=r.useRef(null);return r.useEffect(()=>{function v(h){if(h.source!==d.current?.contentWindow)return;const b=Rt(h.data);b!==null&&window.open(b,"_blank","noopener,noreferrer")}return window.addEventListener("message",v),()=>window.removeEventListener("message",v)},[]),i===null?e.jsx("div",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"}):e.jsx("iframe",{ref:d,"data-testid":G.canvasIframe,title:n,src:i,sandbox:"allow-scripts",className:"h-full w-full flex-1 border-0 bg-background"})}function St({projectId:t,canvasId:a,worktreePath:n,environmentId:o}){const{canvas:s,isLoading:i}=Xe(t,a,n??null,o??null);return i||s===void 0?e.jsx("div",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"}):s.record.kind==="markdown"?e.jsx(le,{content:s.content}):s.record.kind==="structured"?e.jsx(Ct,{content:s.content,repoPath:n}):e.jsx(kt,{projectId:t,canvasId:a,title:s.record.title,worktreePath:n,environmentId:o})}export{St as CanvasView};
@@ -0,0 +1 @@
1
+ import{Q as _,U as G,V as Q,r as f,W as O,j as e,T as N,m as F,v as Y,w as J,c as Z,u as ee,L as se,e as te,f as ne,g as ae,h as oe,D as re,B as x,X as le,Y as ie,i as u,k as g,S as B,l as U,n as j,M as T,F as ce,o as de,C as xe,p as he,q as pe,s as y,t as me,x as ue,y as ge,z as je,A as fe,E as ve,G as Ce,H as Ne}from"./index-B7RkrSLU.js";import{K as De}from"./index-B7RkrSLU.js";import{a as ke}from"./line-selection-XRkDh5Ju.js";import{H as be}from"./hunks-view-Cof-l5Oa.js";import{U as we,F as Se}from"./unfold-vertical-Bx-_TYkq.js";import"./virtual-rows-BVkLwG2o.js";function D(s,n,o,r){const a=new Set(s[n]??[]);return r?a.add(o):a.delete(o),{...s,[n]:[...a]}}const L=_(s=>({collapsedByScope:{},toggle:(n,o)=>s(r=>{const a=!(r.collapsedByScope[n]??[]).includes(o);return{collapsedByScope:D(r.collapsedByScope,n,o,a)}}),collapse:(n,o)=>s(r=>({collapsedByScope:D(r.collapsedByScope,n,o,!0)})),clear:()=>s({collapsedByScope:{}})}));function Te(s,n){if(!s||s.path!==n||s.startLine===void 0)return;const o=new Set,r=s.endLine??s.startLine;for(let a=s.startLine;a<=r;a++)o.add(a);return o}function ye({file:s,collapseScope:n,reviewable:o,commentAnchor:r,onComment:a}){const c=L(t=>(t.collapsedByScope[n]??[]).includes(s.path)),M=L(t=>t.toggle),k=L(t=>t.collapse),[i,h]=f.useState(null),l=O(t=>t.project),P=Z(t=>t.openTab),A=ee(t=>t.setSidebarTab),I=se(t=>t.reveal),V=te(),{mark:W,unmark:$}=ne(),q=ae(s.path),d=V.has(s.path),z=s.status!=="deleted",H=f.useMemo(()=>Te(r,s.path),[r,s.path]),[v,b]=f.useState([]),w=f.useMemo(()=>oe(s.hunks??[],{context:re,revealed:v}),[s.hunks,v]),E=w.gaps.some(t=>t.expandable),S=E||v.length>0,K=(t,p)=>{const C=p==="up"?fe(t):p==="down"?ve(t):Ce(t);b(m=>Ne(m,C))},X=()=>{if(!l||!z)return;const t=`${l.path}/${s.path}`;P(ue("file",t,{title:je(s.path),preview:!0},ge())),A("files"),I(t)},R=()=>{if(d){$(s.path);return}W(s.path),k(n,s.path)};return e.jsxs("div",{"data-testid":N.changesetCard(s.path),className:F(me,"flex flex-col"),children:[e.jsxs("div",{className:"flex h-9 shrink-0 items-center gap-2 border-b px-3",children:[e.jsx(x,{variant:"ghost",size:"icon-2xs",className:"shrink-0 text-muted-foreground hover:text-foreground",onClick:()=>M(n,s.path),"aria-expanded":!c,"aria-label":c?"Expand diff":"Collapse diff","data-testid":N.diffCollapse(s.path),children:c?e.jsx(le,{}):e.jsx(ie,{})}),e.jsx("span",{className:"min-w-0 flex-1 truncate font-mono text-xs font-medium",children:s.path}),s.additions?e.jsxs("span",{className:"font-mono text-2xs text-success",children:["+",s.additions]}):null,s.deletions?e.jsxs("span",{className:"font-mono text-2xs text-destructive",children:["−",s.deletions]}):null,o&&e.jsxs(u,{children:[e.jsx(g,{render:e.jsx(x,{variant:"ghost",size:"icon-2xs",onClick:R,className:F("shrink-0",d?"text-success":"text-muted-foreground hover:text-foreground"),"aria-label":d?"Unmark reviewed":"Mark reviewed","data-testid":N.diffReviewed(s.path),children:d?e.jsx(B,{className:"size-3.5"}):e.jsx(U,{className:"size-3.5"})})}),e.jsx(j,{children:d?"Unmark reviewed":"Mark reviewed"})]}),e.jsxs(u,{children:[e.jsx(g,{render:e.jsx(x,{variant:"ghost",size:"icon-2xs",onClick:()=>a({path:s.path}),className:"shrink-0 text-muted-foreground hover:text-foreground","aria-label":"Comment on file",children:e.jsx(T,{className:"size-3.5"})})}),e.jsx(j,{children:"Comment on file"})]}),z&&e.jsxs(u,{children:[e.jsx(g,{render:e.jsx(x,{variant:"ghost",size:"icon-2xs",onClick:X,className:"shrink-0 text-muted-foreground hover:text-foreground","aria-label":"Open file",children:e.jsx(ce,{className:"size-3.5"})})}),e.jsx(j,{children:"Open file"})]}),E&&e.jsxs(u,{children:[e.jsx(g,{render:e.jsx(x,{variant:"ghost",size:"icon-2xs",onClick:()=>b(de()),className:"shrink-0 text-muted-foreground hover:text-foreground","aria-label":"Expand all context",children:e.jsx(we,{className:"size-3.5"})})}),e.jsx(j,{children:"Expand all context"})]}),v.length>0&&e.jsxs(u,{children:[e.jsx(g,{render:e.jsx(x,{variant:"ghost",size:"icon-2xs",onClick:()=>b([]),className:"shrink-0 text-muted-foreground hover:text-foreground","aria-label":"Collapse context",children:e.jsx(Se,{className:"size-3.5"})})}),e.jsx(j,{children:"Collapse context"})]})]}),!c&&s.hunks&&s.hunks.length>0&&e.jsxs(xe,{onOpenChange:t=>{t||h(null)},children:[e.jsx(he,{className:"block select-text",onContextMenu:t=>{const p=ke(s.path);if(p){h(p);return}const C=t.target.closest("[data-line]"),m=C?Number.parseInt(C.getAttribute("data-line")??"",10):Number.NaN;h(Number.isFinite(m)?{startLine:m,endLine:m,text:""}:null)},children:e.jsx(be,{hunks:S?w.hunks:s.hunks??[],gaps:S?w.gaps:void 0,onExpand:S?K:void 0,filePath:s.path,diffMode:"unified",layout:"content",commentIndex:q,pendingLines:H})}),e.jsxs(pe,{className:"w-52",children:[i?e.jsxs(y,{onClick:()=>a({path:s.path,startLine:i.startLine,endLine:i.endLine,anchorText:i.text.slice(0,2e3)}),children:[e.jsx(T,{})," Add comment"]}):e.jsxs(y,{onClick:()=>a({path:s.path}),children:[e.jsx(T,{})," Comment on file"]}),o&&e.jsxs(y,{onClick:R,children:[d?e.jsx(U,{}):e.jsx(B,{}),d?"Unmark reviewed":"Mark reviewed"]})]})]})]})}function Re({path:s}){const n=G(s),{reading:o,error:r}=Q(n),[a,c]=f.useState(null),k=`${O(l=>l.project?.path??"")}\0${s}`;if(r)return e.jsx("p",{className:"p-4 text-sm text-destructive",children:r.message});if(o===void 0)return e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"});const i=o.groups.flatMap(l=>l.files);if(i.length===0)return e.jsx("div",{className:"flex h-full items-center justify-center p-6",children:e.jsxs("div",{className:"max-w-sm text-center",children:[e.jsx("p",{className:"text-sm font-medium text-foreground",children:n.type==="commit"?"Empty commit":"No changes to review"}),e.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:n.type==="commit"?"This commit doesn’t touch any files.":"Nothing to walk through in this range yet."})]})});const h=n.type==="working"?"Working tree":n.type==="branch"?"Branch range":`Commit ${n.hash.slice(0,7)}`;return e.jsxs("div",{className:"flex h-full min-h-0 flex-col",children:[e.jsxs("div",{className:"flex shrink-0 items-center gap-2 border-b border-border/60 px-4 py-2 text-2xs text-muted-foreground",children:[e.jsx("span",{className:"font-medium text-foreground",children:"All changes"}),e.jsx("span",{className:"text-muted-foreground/40",children:"·"}),e.jsx("span",{children:h}),e.jsx("span",{className:"text-muted-foreground/40",children:"·"}),e.jsxs("span",{className:"tabular-nums",children:[i.length," file",i.length===1?"":"s"]})]}),e.jsx("div",{"data-testid":N.codeWell,className:F(Y,"overflow-auto"),children:e.jsx("div",{className:"flex flex-col gap-3",children:i.map(l=>e.jsx(ye,{file:l,collapseScope:k,reviewable:n.type!=="commit",commentAnchor:a,onComment:c},l.path))})}),e.jsx(J,{anchor:a,open:a!==null,onOpenChange:l=>{l||c(null)}})]})}export{Re as ChangesetView,De as changesetTabKey,G as parseChangesetTabKey};
@@ -0,0 +1,2 @@
1
+ import{r as k,I as A,J as D,b as L,c as y,j as e,T as h,i as b,k as C,B as v,R as P,n as N,m as p,t as T,F as M,v as $,K as z,x as j,y as g,u as S,L as E,z as F,C as O,p as R,q as H,s as w,M as I,w as q,N as B}from"./index-B7RkrSLU.js";import{D as K}from"./diff-mode-toggle-DnkFtatM.js";import{H as V}from"./hunks-view-Cof-l5Oa.js";import"./virtual-rows-BVkLwG2o.js";function W({file:s,repoPath:c,selected:d,onSelect:l}){const o=y(a=>a.openTab),i=S(a=>a.setSidebarTab),m=E(a=>a.reveal),r=F(s.path),[n,u]=k.useState(null),f=()=>{const a=`${c}/${s.path}`;o(j("file",a,{title:r},g())),i("files"),m(a)};return e.jsxs(O,{children:[e.jsx(R,{render:e.jsx("button",{type:"button",onClick:()=>l(s.path),className:p("block w-full truncate px-3 py-1 text-left font-mono text-xs",d?"bg-accent text-accent-foreground":"text-muted-foreground hover:bg-accent/50")}),children:r}),e.jsxs(H,{children:[e.jsxs(w,{onClick:()=>u({path:s.path}),children:[e.jsx(I,{}),"Comment on file"]}),s.status!=="deleted"&&e.jsxs(w,{onClick:f,children:[e.jsx(M,{}),"Open file"]})]}),e.jsx(q,{anchor:n,open:n!==null,onOpenChange:a=>{a||u(null)}})]})}function J({hash:s,filePath:c}){const d=S(i=>i.diffMode),{hunks:l,error:o}=B(s,c);return o?e.jsx("p",{className:"p-4 text-sm text-destructive",children:o.message}):l===void 0?e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"}):e.jsx("div",{className:"flex h-full flex-col",children:e.jsx(O,{children:e.jsx(R,{className:"block min-h-0 flex-1 select-text",children:e.jsx(V,{hunks:l,filePath:c,diffMode:d})})})})}function Y({hash:s}){const[c,d]=k.useState(null),{groups:l}=A(s),o=D(s),i=L(),m=y(t=>t.openTab);if(i===null||l===void 0)return e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"});const r=l.flatMap(t=>t.files),n=c??r[0]?.path??null,u=r.find(t=>t.path===n)?.status,f=()=>{if(!n)return;const t=`${i}/${n}`;m(j("file",t,{title:F(n),preview:!0},g()))},a=()=>{const t=z({type:"commit",hash:s}),x=(o??s.slice(0,12)).split(`
2
+ `)[0]?.trim()||s.slice(0,12);m(j("changeset",t,{title:x},g()))};return e.jsxs("div",{"data-testid":h.codeWell,className:p($,"flex gap-3"),children:[e.jsxs("div",{"data-testid":h.commitListCard,className:p(T,"flex w-64 shrink-0 flex-col overflow-y-auto"),children:[e.jsxs("div",{className:"border-b px-3 py-2",children:[e.jsxs("div",{className:"flex items-start justify-between gap-2",children:[e.jsx("p",{className:"min-w-0 flex-1 whitespace-pre-wrap break-words text-sm-minus text-foreground",children:o??"…"}),r.length>0&&e.jsxs(b,{children:[e.jsx(C,{render:e.jsx(v,{variant:"ghost",size:"icon-xs",className:"shrink-0 text-muted-foreground",onClick:a,"aria-label":"All changes",children:e.jsx(P,{})})}),e.jsx(N,{children:"All changes"})]})]}),e.jsx("p",{className:"mt-1 font-mono text-xs-minus text-muted-foreground",children:s.slice(0,12)})]}),l.map(t=>e.jsxs("div",{children:[e.jsx("p",{className:"flex h-6 items-center px-3 text-2xs font-bold uppercase tracking-[0.08em] text-muted-foreground",children:t.layer}),t.files.map(x=>e.jsx(W,{file:x,repoPath:i,selected:x.path===n,onSelect:d},x.path))]},t.layer)),r.length===0&&e.jsx("p",{className:"px-3 py-2 text-xs text-muted-foreground",children:"No files changed"})]}),e.jsx("div",{className:"min-w-0 min-h-0 flex-1",children:e.jsxs("div",{"data-testid":h.codeCard,className:p(T,"flex h-full min-h-0 flex-col"),children:[e.jsxs("div",{className:"flex shrink-0 items-center justify-between gap-2 border-b px-3 py-1",children:[e.jsx("span",{className:"truncate font-mono text-xs text-muted-foreground",children:n}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[n&&u!=="deleted"&&e.jsxs(b,{children:[e.jsx(C,{render:e.jsx(v,{variant:"ghost",size:"icon-xs",className:"text-muted-foreground",onClick:f,"aria-label":"Open file",children:e.jsx(M,{})})}),e.jsx(N,{children:"Open file"})]}),e.jsx(K,{})]})]}),e.jsx("div",{className:"min-h-0 flex-1",children:n?e.jsx(J,{hash:s,filePath:n}):e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"Empty commit"})})]})})]})}export{Y as CommitView};
@@ -0,0 +1 @@
1
+ import{u as o,a as t,j as i,O as r,P as n}from"./index-B7RkrSLU.js";function a(){const f=o(e=>e.diffMode),l=o(e=>e.setDiffMode);return t()?null:i.jsxs(r,{value:[f],onValueChange:e=>{const s=e[0];(s==="unified"||s==="split")&&l(s)},children:[i.jsx(n,{value:"unified",size:"sm",children:"Unified"}),i.jsx(n,{value:"split",size:"sm",children:"Split"})]})}export{a as D};
@@ -0,0 +1 @@
1
+ import{u as _,a as G,b as K,c as X,d as J,e as Q,f as Y,r as o,g as Z,h as P,j as e,v as ee,T,i as d,k as c,B as x,S as se,l as ne,m as D,n as m,M,F as te,o as ae,C as re,p as oe,q as ie,s as E,t as le,w as de,D as ce,x as xe,y as me,z as ue,A as fe,E as pe,G as he,H as je}from"./index-B7RkrSLU.js";import{l as ge}from"./line-selection-XRkDh5Ju.js";import{D as ve}from"./diff-mode-toggle-DnkFtatM.js";import{H as Ce}from"./hunks-view-Cof-l5Oa.js";import{U as be,F as Ne}from"./unfold-vertical-Bx-_TYkq.js";import"./virtual-rows-BVkLwG2o.js";function De({filePath:n,base:L}){const R=_(s=>s.diffMode),y=G()?"unified":R,S=K(),I=X(s=>s.openTab),{hunks:j,status:g,image:u,binary:v,error:F}=J(n,L),U=Q(),{mark:z,unmark:A}=Y(),i=U.has(n),[f,C]=o.useState(null),[t,p]=o.useState(null),O=Z(n),[b,h]=o.useState([]),N=`${n}\0${L??""}`,[H,q]=o.useState(N);H!==N&&(q(N),h([]));const k=o.useMemo(()=>P(j??[],{context:ce,revealed:b}),[j,b]),V=(s,r)=>{const a=r==="up"?fe(s):r==="down"?pe(s):he(s);h(l=>je(l,a))},$=k.gaps.some(s=>s.expandable),B=o.useMemo(()=>{if(!t||t.path!==n||t.startLine===void 0)return;const s=new Set,r=t.endLine??t.startLine;for(let a=t.startLine;a<=r;a++)s.add(a);return s},[t,n]),W=()=>{if(S===null)return;const s=`${S}/${n}`;I(xe("file",s,{title:ue(n),preview:!0},me()))};if(F)return e.jsx("p",{className:"p-4 text-sm text-destructive",children:F.message});if(j===void 0&&u===void 0&&!v)return e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"});const w=u!==void 0||v;return e.jsxs("div",{"data-testid":T.codeWell,className:ee,children:[e.jsxs("div",{"data-testid":T.codeCard,className:D(le,"flex h-full min-h-0 flex-col"),children:[e.jsxs("div",{className:"flex shrink-0 items-center justify-between gap-2 border-b px-3 py-1",children:[e.jsx("span",{className:"truncate font-mono text-xs text-muted-foreground",children:n}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[e.jsxs(d,{children:[e.jsx(c,{render:e.jsx(x,{variant:"ghost",size:"icon-xs",className:D(i?"text-success":"text-muted-foreground hover:text-foreground"),onClick:()=>{i?A(n):z(n)},"aria-label":i?"Unmark reviewed":"Mark reviewed","data-testid":T.diffReviewed(n),children:i?e.jsx(se,{}):e.jsx(ne,{})})}),e.jsx(m,{children:i?"Unmark reviewed":"Mark reviewed"})]}),e.jsxs(d,{children:[e.jsx(c,{render:e.jsx(x,{variant:"ghost",size:"icon-xs",className:"text-muted-foreground hover:text-foreground",onClick:()=>p({path:n}),"aria-label":"Comment on file",children:e.jsx(M,{})})}),e.jsx(m,{children:"Comment on file"})]}),g!=="deleted"&&e.jsxs(d,{children:[e.jsx(c,{render:e.jsx(x,{variant:"ghost",size:"icon-xs",className:"text-muted-foreground",onClick:W,"aria-label":"Open file",children:e.jsx(te,{})})}),e.jsx(m,{children:"Open file"})]}),!w&&$&&e.jsxs(d,{children:[e.jsx(c,{render:e.jsx(x,{variant:"ghost",size:"icon-xs",className:"text-muted-foreground hover:text-foreground",onClick:()=>h(ae()),"aria-label":"Expand all context",children:e.jsx(be,{})})}),e.jsx(m,{children:"Expand all context"})]}),!w&&b.length>0&&e.jsxs(d,{children:[e.jsx(c,{render:e.jsx(x,{variant:"ghost",size:"icon-xs",className:"text-muted-foreground hover:text-foreground",onClick:()=>h([]),"aria-label":"Collapse context",children:e.jsx(Ne,{})})}),e.jsx(m,{children:"Collapse context"})]}),!w&&e.jsx(ve,{})]})]}),u!==void 0?e.jsxs("div",{className:"flex min-h-0 flex-1 flex-col items-center justify-center gap-3 overflow-auto p-8",children:[e.jsx("img",{src:u.dataUrl,alt:n,className:"max-h-full max-w-full object-contain"}),e.jsxs("p",{className:"text-2xs text-muted-foreground",children:[g==="untracked"||g==="added"?"New image":"Image changed"," · binary diff"]})]}):v?e.jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"Binary file"}):e.jsxs(re,{onOpenChange:s=>{s||C(null)},children:[e.jsx(oe,{className:"block min-h-0 flex-1 select-text",onContextMenu:s=>{const r=ge();if(r){C(r);return}const a=s.target.closest("[data-line]"),l=a?Number.parseInt(a.getAttribute("data-line")??"",10):Number.NaN;C(Number.isFinite(l)?{startLine:l,endLine:l,text:""}:null)},children:e.jsx(Ce,{hunks:k.hunks,gaps:k.gaps,onExpand:V,filePath:n,diffMode:y,commentIndex:O,pendingLines:B})}),e.jsx(ie,{className:"w-52",children:f?e.jsxs(E,{onClick:()=>p({path:n,startLine:f.startLine,endLine:f.endLine,anchorText:f.text.slice(0,2e3)}),children:[e.jsx(M,{})," Add comment"]}):e.jsxs(E,{onClick:()=>p({path:n}),children:[e.jsx(M,{})," Comment on file"]})})]})]}),e.jsx(de,{anchor:t,open:t!==null,onOpenChange:s=>{s||p(null)}})]})}export{De as DiffView};
@@ -0,0 +1,5 @@
1
+ import{Z as Fe,r as o,j as e,T as U,$ as ue,ab as xe,ac as me,ad as Pe,ae as fe,b as se,af as ne,C as he,p as pe,a4 as je,m as R,ag as Ae,ah as Q,ai as H,q as ge,s as g,aj as _,ak as B,al as J,am as ve,an as ze,ao as re,M as E,ap as ee,aq as we,ar as Ce,as as be,w as oe,a6 as ke,c as te,at as Ie,au as q,av as He,B as D,a9 as De,Y as Oe,aw as Ke,a5 as Ve,u as F,g as _e,ax as Be,ay as qe,v as Ue,i as We,k as Ge,n as Xe,t as $e,O as ye,P as W,az as Ye,aA as Qe}from"./index-B7RkrSLU.js";import{i as Ze,M as Je}from"./markdown-view-DJGgLy5g.js";import{b as et,l as tt,c as st}from"./line-selection-XRkDh5Ju.js";import{R as nt,V as rt}from"./virtual-rows-BVkLwG2o.js";const ot=[["circle",{cx:"6",cy:"6",r:"3",key:"1lh9wr"}],["path",{d:"M8.12 8.12 12 12",key:"1alkpv"}],["path",{d:"M20 4 8.12 15.88",key:"xgtan2"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M14.8 14.8 20 20",key:"ptml3r"}]],it=Fe("scissors",ot),at=["html","htm"];function lt(s){const n=s.split(".").at(-1)?.toLowerCase()??"";return at.includes(n)}function ct({src:s,title:n,onSelection:r}){const a=o.useRef(null);return o.useEffect(()=>{const i=l=>{if(l.source!==a.current?.contentWindow)return;const d=l.data;if(d?.source!=="porcelain-file-preview"||d.type!=="selection"||typeof d.text!="string")return;const f=d.text.trim().slice(0,2e3);f!==""&&r?.(f)};return window.addEventListener("message",i),()=>window.removeEventListener("message",i)},[r]),e.jsx("iframe",{ref:a,"data-testid":U.htmlPreviewIframe,title:n,src:s,sandbox:"allow-scripts",className:"min-h-0 h-full w-full flex-1 border-0 bg-white"})}function Se(s,n){return!n||n.length===0?!1:n.some(r=>s>=r.start&&s<=r.end)}const dt=5e3,ut=800,Z="pointer-events-none absolute bottom-2 right-3 rounded-md border-transparent bg-muted/80 text-2xs",xt=o.memo(ke),mt=8;function ft({path:s,initialContent:n,highlightLine:r,highlightRanges:a,commentsByLine:i}){const[l,d]=o.useState(n),[f,m]=o.useState(n),[x,w]=o.useState(""),[u,C]=o.useState(!1),[h,b]=o.useState(null),[p,L]=o.useState(null),k=o.useRef(null),N=o.useRef(null),S=o.useRef(null),T=ue(s),M=o.useDeferredValue(l),P=xe(M,T),{findReferences:O,copyPath:K,copyRelativePath:V,reveal:G}=me(s),{save:A,isSaving:X,error:z}=Pe(s),v=fe(),y=se()??void 0,ie=ne(y,s),Le=o.useMemo(()=>{if(!h||h.startLine===void 0)return null;const t=new Set,c=h.endLine??h.startLine;for(let j=h.startLine;j<=c;j++)t.add(j);return t},[h]),Ne=o.useMemo(()=>{if(!u||x===""||!p)return null;const t=new Set;for(let c=p.startLine;c<=p.endLine;c++)t.add(c);return t},[u,x,p]),$=o.useEffectEvent(()=>{if(S.current&&clearTimeout(S.current),l===f)return;const t=l;A(t,()=>m(t))}),ae=t=>{d(t);const c=te.getState().panes.flatMap(j=>j.tabs).find(j=>j.kind==="file"&&j.path===s);te.getState().pinTab(c?.id??Ie("file",s)),S.current&&clearTimeout(S.current),S.current=setTimeout(()=>$(),ut)};o.useEffect(()=>()=>{S.current&&clearTimeout(S.current),$()},[]);const le=o.useRef(n);o.useEffect(()=>{n!==le.current&&l===f&&(le.current=n,d(n),m(n))},[n,l,f]),o.useEffect(()=>{const t=N.current;!t||r===void 0||(t.scrollTop=Math.max(0,(r-1)*20-t.clientHeight/2+10))},[r]);const ce=t=>{const c=k.current;if(!c)return;const{selectionStart:j,selectionEnd:Y,value:I}=c;ae(I.slice(0,j)+t+I.slice(Y)),requestAnimationFrame(()=>{c.focus(),c.selectionStart=c.selectionEnd=j+t.length})},Me=()=>{const t=k.current;return t?t.value.slice(t.selectionStart,t.selectionEnd):""},Te=()=>{navigator.clipboard?.readText&&B(async()=>{ce(await navigator.clipboard.readText())},t=>{q("Paste",t)})},Ee=l!==f;return e.jsxs(e.Fragment,{children:[e.jsxs(he,{onOpenChange:t=>{if(C(t),t){w(Me());const c=k.current;L(c?et(c.value,c.selectionStart,c.selectionEnd):null)}},children:[e.jsxs(pe,{className:"relative block h-full select-text overflow-hidden",children:[e.jsx("div",{ref:N,className:"h-full overflow-auto",children:e.jsxs("div",{className:"relative min-h-full w-max min-w-full",children:[e.jsx("div",{"aria-hidden":!0,className:"pointer-events-none absolute inset-0 z-0 px-4 py-2 font-mono text-xs leading-5",children:e.jsx("div",{className:"w-max min-w-full",children:l.split(`
2
+ `).map((t,c)=>{const j=c+1,Y=(Le?.has(j)??!1)||(Ne?.has(j)??!1),I=je(i?.get(j),Y)??(j===r?"bg-primary/15":void 0),Re=!I&&Se(j,a);return e.jsxs("div",{className:R("flex",I,Re&&"border-l-2 border-l-diff-add bg-diff-add/10"),children:[e.jsx("span",{className:"w-10 shrink-0 select-none pr-3 text-right text-muted-foreground/50",children:j}),e.jsx(xt,{tokens:P?.[c]??null,text:t})]},c)})})}),i&&i.size>0&&e.jsx("div",{className:"pointer-events-none absolute inset-0 z-20 font-mono text-xs leading-5",children:[...i.entries()].map(([t,c])=>e.jsx("div",{className:"pointer-events-auto absolute left-1 flex h-5 items-center",style:{top:mt+(t-1)*nt},children:e.jsx(Ae,{comments:c})},t))}),e.jsx("textarea",{ref:k,value:l,onChange:t=>ae(t.target.value),onKeyDown:t=>{t.key==="s"&&(t.metaKey||t.ctrlKey)&&(t.preventDefault(),$())},spellCheck:!1,wrap:"off","aria-label":`Edit ${s}`,"data-testid":U.fileEditor,className:"relative z-10 block min-h-full min-w-full resize-none whitespace-pre bg-transparent py-2 pl-14 pr-4 font-mono text-xs leading-5 text-transparent caret-foreground outline-none field-sizing-content"})]})}),z?e.jsx(Q,{variant:"outline",className:R(Z,"text-destructive"),children:z.message}):X?e.jsx(Q,{variant:"outline",className:R(Z,"text-muted-foreground"),children:"Saving…"}):Ee?e.jsxs(Q,{variant:"outline",className:R(Z,"text-muted-foreground"),children:["Unsaved ",e.jsx(H,{className:"[@media(hover:none)]:hidden",tokens:["mod","S"]})]}):null]}),e.jsxs(ge,{className:"w-60",children:[e.jsxs(g,{disabled:x==="",onClick:()=>{B(async()=>{await J(x),ce("")},t=>{q("Cut",t)})},children:[e.jsx(it,{})," Cut",e.jsx(_,{children:e.jsx(H,{tokens:["mod","X"]})})]}),e.jsxs(g,{disabled:x==="",onClick:()=>{B(()=>J(x),t=>{q("Copy",t)})},children:[e.jsx(ve,{})," Copy",e.jsx(_,{children:e.jsx(H,{tokens:["mod","C"]})})]}),e.jsxs(g,{onClick:()=>Te(),children:[e.jsx(ze,{})," Paste",e.jsx(_,{children:e.jsx(H,{tokens:["mod","V"]})})]}),e.jsxs(g,{disabled:x.trim()==="",onClick:()=>O(x),children:[e.jsx(re,{})," Find references"]}),e.jsxs(g,{disabled:x==="",onClick:()=>{p&&b({path:ie,startLine:p.startLine,endLine:p.endLine,anchorText:x.slice(0,2e3)})},children:[e.jsx(E,{})," Add comment"]}),e.jsx(ee,{}),e.jsxs(g,{onClick:()=>b({path:ie}),children:[e.jsx(E,{})," Comment on file"]}),e.jsxs(g,{onClick:()=>{K()},children:[e.jsx(we,{})," Copy path"]}),e.jsxs(g,{onClick:()=>{V()},children:[e.jsx(Ce,{})," Copy relative path"]}),v&&e.jsxs(g,{onClick:()=>{G()},children:[e.jsx(be,{})," Reveal in Finder"]})]})]}),e.jsx(oe,{anchor:h,open:h!==null,onOpenChange:t=>{t||b(null)}})]})}function ht({content:s,onClose:n,onMatchLine:r}){const[a,i]=o.useState(""),[l,d]=o.useState(0),f=o.useRef(null),m=o.useMemo(()=>{const u=a.toLowerCase();if(u==="")return[];const C=[];return s.split(`
3
+ `).forEach((h,b)=>{h.toLowerCase().includes(u)&&C.push(b+1)}),C},[s,a]),x=m.length===0?0:(l%m.length+m.length)%m.length,w=m.length===0?void 0:m[x];return o.useEffect(()=>{r(w)},[w,r]),o.useEffect(()=>{f.current?.focus()},[]),e.jsxs("div",{className:"absolute right-3 top-3 z-30 flex items-center gap-1 rounded-lg border bg-popover px-2 py-1 shadow-lg",children:[e.jsx(re,{className:"size-3.5 shrink-0 text-muted-foreground"}),e.jsx(He,{ref:f,value:a,onChange:u=>{i(u.target.value),d(0)},onKeyDown:u=>{u.key==="Escape"&&n(),u.key==="Enter"&&d(C=>C+(u.shiftKey?-1:1))},placeholder:"Find in file…","aria-label":"Find in file",className:"h-6 max-w-64 border-none bg-transparent text-xs shadow-none focus-visible:ring-0"}),e.jsx("span",{className:"shrink-0 text-2xs text-muted-foreground tabular-nums",children:a===""?"":m.length===0?"No results":`${x+1}/${m.length}`}),e.jsx(D,{variant:"ghost",size:"icon-xs",disabled:m.length===0,onClick:()=>d(u=>u-1),"aria-label":"Previous match",children:e.jsx(De,{})}),e.jsx(D,{variant:"ghost",size:"icon-xs",disabled:m.length===0,onClick:()=>d(u=>u+1),"aria-label":"Next match",children:e.jsx(Oe,{})}),e.jsx(D,{variant:"ghost",size:"icon-xs",onClick:n,"aria-label":"Close find bar",children:e.jsx(Ke,{})})]})}function de({path:s,children:n}){const[r,a]=o.useState(""),[i,l]=o.useState(null),[d,f]=o.useState(null),m=se()??void 0,{copyPath:x,copyRelativePath:w,reveal:u,findReferences:C}=me(s),h=fe(),b=ne(m,s);return e.jsxs(e.Fragment,{children:[e.jsxs(he,{onOpenChange:p=>{if(!p){l(null);return}a(window.getSelection()?.toString()??"")},children:[e.jsx(pe,{className:"block h-full select-text",onContextMenu:p=>{const L=tt();if(L){l(L);return}const k=p.target.closest("[data-line]"),N=k?Number.parseInt(k.getAttribute("data-line")??"",10):Number.NaN;l(Number.isFinite(N)?{startLine:N,endLine:N,text:""}:null)},children:n}),e.jsx(ge,{className:"w-56",children:r!==""?e.jsxs(e.Fragment,{children:[e.jsxs(g,{onClick:()=>{B(()=>J(r),p=>{q("Copy",p)})},children:[e.jsx(ve,{})," Copy",e.jsx(_,{children:e.jsx(H,{tokens:["mod","C"]})})]}),e.jsxs(g,{disabled:r.trim()==="",onClick:()=>C(r),children:[e.jsx(re,{})," Find references"]}),i&&e.jsxs(g,{onClick:()=>f({path:b,startLine:i.startLine,endLine:i.endLine,anchorText:i.text.slice(0,2e3)}),children:[e.jsx(E,{})," Add comment"]})]}):e.jsxs(e.Fragment,{children:[i?e.jsxs(g,{onClick:()=>f({path:b,startLine:i.startLine,endLine:i.endLine}),children:[e.jsx(E,{})," Add comment"]}):e.jsxs(g,{onClick:()=>f({path:b}),children:[e.jsx(E,{})," Comment on file"]}),e.jsx(ee,{}),e.jsxs(g,{onClick:()=>{x()},children:[e.jsx(we,{})," Copy path"]}),e.jsxs(g,{onClick:()=>{w()},children:[e.jsx(Ce,{})," Copy relative path"]}),h&&e.jsxs(e.Fragment,{children:[e.jsx(ee,{}),e.jsxs(g,{onClick:()=>{u()},children:[e.jsx(be,{})," Reveal in Finder"]})]})]})})]}),e.jsx(oe,{anchor:d,open:d!==null,onOpenChange:p=>{p||f(null)}})]})}function pt({path:s,content:n,highlightLine:r,highlightRanges:a,commentsByLine:i}){const l=ue(s),d=n.split(`
4
+ `),f=xe(n,l);return e.jsx(rt,{rows:d,className:"px-4 py-2 leading-5",scrollToLine:r,renderRow:(m,x)=>{const w=x+1,u=i?.get(w),C=je(u),h=!C&&Se(w,a);return e.jsxs("div",{"data-line":w,className:R("relative flex",!C&&w===r&&"bg-primary/15",C,h&&"border-l-2 border-l-diff-add bg-diff-add/10"),children:[e.jsx(Ve,{comments:u}),e.jsx("span",{className:"w-10 shrink-0 select-none pr-3 text-right text-muted-foreground/50",children:w}),e.jsx(ke,{tokens:f?.[x]??null,text:m})]})}})}function jt(){const s=F(r=>r.markdownMode),n=F(r=>r.setMarkdownMode);return e.jsxs(ye,{value:[s],onValueChange:r=>{const a=r[0];(a==="reader"||a==="source")&&n(a)},children:[e.jsx(W,{value:"reader",size:"sm",children:"Reader"}),e.jsx(W,{value:"source",size:"sm",children:"Source"})]})}function gt(){const s=F(r=>r.htmlMode)??"preview",n=F(r=>r.setHtmlMode);return e.jsxs(ye,{value:[s],onValueChange:r=>{const a=r[0];(a==="preview"||a==="source")&&n(a)},children:[e.jsx(W,{value:"preview",size:"sm",children:"Preview"}),e.jsx(W,{value:"source",size:"sm",children:"Source"})]})}function vt({path:s,content:n,line:r,highlightRanges:a,paneIndex:i}){const l=se()??void 0,d=F(v=>v.markdownMode),f=F(v=>v.htmlMode)??"preview",[m,x]=o.useState(!1),[w,u]=o.useState(void 0),[C,h]=o.useState(null),[b,p]=o.useState(null),L=ne(l,s),k=_e(L),N=Ze(s),S=lt(s),T=N&&d==="reader",M=S&&f==="preview",{html:P,error:O}=Be(s,M),K=qe(s,M&&P!==null),V=n.split(`
5
+ `).length,G=!T&&!M&&V<=dt,A=a&&a.reduce((v,y)=>v+(y.end-y.start+1),0)/V>=.9?void 0:a,X=r??A?.[0]?.start,z=m&&w!==void 0?w:X;return o.useEffect(()=>{const v=y=>{if(te.getState().activePaneIndex===i&&y.key==="f"&&(y.metaKey||y.ctrlKey)&&!y.shiftKey&&!y.altKey){if(T||M)return;y.preventDefault(),x(!0)}};return window.addEventListener("keydown",v),()=>window.removeEventListener("keydown",v)},[i,T,M]),e.jsxs("div",{"data-testid":U.codeWell,className:Ue,children:[e.jsxs("div",{"data-testid":U.codeCard,className:R($e,"flex h-full min-h-0 flex-col"),children:[e.jsxs("div",{className:"flex h-9 shrink-0 items-center justify-between gap-2 border-b px-3",children:[e.jsx("span",{className:"truncate font-mono text-xs text-muted-foreground",children:L}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[e.jsxs(We,{children:[e.jsx(Ge,{render:e.jsx(D,{variant:"ghost",size:"icon-xs",className:"text-muted-foreground hover:text-foreground",onClick:()=>h({path:L}),"aria-label":"Comment on file",children:e.jsx(E,{})})}),e.jsx(Xe,{children:"Comment on file"})]}),N&&e.jsx(jt,{}),S&&e.jsx(gt,{})]})]}),e.jsxs("div",{className:"relative min-h-0 flex-1",children:[m&&!T&&!M&&e.jsx(ht,{content:n,onClose:()=>x(!1),onMatchLine:u}),T?e.jsx(de,{path:s,children:e.jsx(Je,{content:n,commentsByLine:k.byLine})}):M?O?e.jsx("p",{className:"p-4 text-sm text-destructive",children:O.message}):P===void 0?e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"}):P===null?e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"HTML preview unavailable (missing or too large). Switch to Source to edit the raw file."}):K===null?e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"}):e.jsxs("div",{className:"relative h-full",children:[e.jsx(ct,{src:K,title:s.split("/").at(-1)??"HTML preview",onSelection:p}),b!==null&&e.jsx("div",{className:"absolute bottom-4 left-1/2 z-20 -translate-x-1/2 rounded-lg border bg-popover p-1 shadow-lg",children:e.jsxs(D,{size:"sm",onClick:()=>{const v=st(n,b);h({path:L,anchorText:b,...v?{startLine:v.startLine,endLine:v.endLine}:{}}),p(null)},children:[e.jsx(E,{})," Add comment"]})})]}):G?e.jsx(ft,{path:s,initialContent:n,highlightLine:z,highlightRanges:A,commentsByLine:k.byLine}):e.jsx(de,{path:s,children:e.jsx(pt,{path:s,content:n,highlightLine:z,highlightRanges:A,commentsByLine:k.byLine})})]})]}),e.jsx(oe,{anchor:C,open:C!==null,onOpenChange:v=>{v||h(null)}})]})}function yt({path:s,line:n,highlight:r,paneIndex:a}){const{view:i,error:l}=Ye(s),d=Qe();return o.useEffect(()=>{i?.type==="not-found"&&d()},[i,d]),l?e.jsx("p",{className:"p-4 text-sm text-destructive",children:l.message}):i===void 0?e.jsx("p",{className:"p-4 text-sm text-muted-foreground",children:"Loading…"}):i.type==="not-found"?e.jsx("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:"This file no longer exists."}):i.type==="image"?e.jsx("div",{className:"flex h-full items-center justify-center p-8",children:e.jsx("img",{src:i.dataUrl,alt:s,className:"max-h-full max-w-full object-contain"})}):i.type==="binary"?e.jsxs("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:["Binary file · ",(i.size/1024).toFixed(1)," KB"]}):i.type==="too-large"?e.jsxs("div",{className:"flex h-full items-center justify-center text-sm text-muted-foreground",children:["File too large to preview · ",(i.size/(1024*1024)).toFixed(1)," MB"]}):e.jsx(vt,{path:s,content:i.content,line:n,highlightRanges:r,paneIndex:a})}export{yt as FileContent};
@@ -0,0 +1 @@
1
+ import{_ as E,$ as H,a0 as R,a1 as D,r as v,a2 as M,a3 as P,j as t,a4 as L,a5 as b,a6 as $,m as C,a7 as _,a8 as z,a9 as G,Y as O}from"./index-B7RkrSLU.js";import{V}from"./virtual-rows-BVkLwG2o.js";function A(e){const n=e.match(/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@\s*(.*)$/);return n?{oldStart:Number(n[1]),oldCount:n[2]===void 0?1:Number(n[2]),newStart:Number(n[3]),newCount:n[4]===void 0?1:Number(n[4]),context:n[5]?.trim()||null}:null}function c(e,n){return n<=1?`Line ${e}`:`Lines ${e}–${e+n-1}`}function B(e){const n=A(e);if(!n)return e;const s=n.oldStart===n.newStart&&n.oldCount===n.newCount;let i;return s?i=c(n.newStart,n.newCount):n.oldCount===0?i=`${c(n.newStart,n.newCount)} added`:n.newCount===0?i=`${c(n.oldStart,n.oldCount)} removed`:i=`${c(n.oldStart,n.oldCount)} → ${c(n.newStart,n.newCount).toLowerCase()}`,n.context?`${n.context} · ${i.toLowerCase()}`:i}const F=new Map,T=new Set,U=[],w={add:"bg-diff-add",del:"bg-diff-del",context:""},y={add:"rounded-sm bg-diff-add-emphasis",del:"rounded-sm bg-diff-del-emphasis",context:""};function h({value:e}){return t.jsx("span",{className:"w-10 shrink-0 select-none pr-2 text-right text-muted-foreground/60",children:e??""})}function I(e,n){return n==="right"?e.newLine??void 0:e.kind==="del"?e.oldLine??void 0:void 0}function W(e,n,s){const i=[],o=a=>{for(const d of s)d.beforeHunk===a&&i.push({type:"gap",gap:d})};return e.forEach((a,d)=>{if(o(d),a.header!==""&&i.push({type:"header",text:a.header}),n==="unified")for(const l of a.lines)i.push({type:"unified",line:l});else for(const l of Y(a))i.push({type:"split",...l})}),o(e.length),i}function X({gap:e,onExpand:n}){const s=`${e.count} unchanged ${e.count===1?"line":"lines"}`,i=e.expandable&&n!==void 0;return t.jsxs("div",{className:"flex h-5 items-center gap-1 bg-muted/40 px-2 text-muted-foreground",children:[i&&(e.count<=_?t.jsx("button",{type:"button","aria-label":`Expand ${s}`,className:"rounded-sm px-0.5 hover:bg-accent hover:text-foreground",onClick:()=>n(e,"whole"),children:t.jsx(z,{className:"size-3"})}):t.jsxs(t.Fragment,{children:[t.jsx("button",{type:"button","aria-label":`Expand up from line ${e.endNew}`,className:"rounded-sm px-0.5 hover:bg-accent hover:text-foreground",onClick:()=>n(e,"up"),children:t.jsx(G,{className:"size-3"})}),t.jsx("button",{type:"button","aria-label":`Expand down from line ${e.startNew}`,className:"rounded-sm px-0.5 hover:bg-accent hover:text-foreground",onClick:()=>n(e,"down"),children:t.jsx(O,{className:"size-3"})})]})),t.jsx("span",{className:"select-none",children:`⋯ ${s}`})]})}function N({row:e,ctx:n}){if(e.type==="gap")return t.jsx(X,{gap:e.gap,onExpand:n.onExpand});if(e.type==="header")return t.jsx("p",{className:"h-5 bg-muted/40 px-2 text-muted-foreground",children:B(e.text)});if(e.type==="unified"){const s=e.line.newLine??e.line.oldLine??void 0,i=n.emphasis.get(e.line),o=s!==void 0?n.commentsByLine.get(s):void 0,a=s!==void 0&&n.pendingLines.has(s),d=L(o,a);return t.jsxs("div",{"data-file":n.filePath,"data-line":s,className:C("relative flex px-2",d??w[e.line.kind]),children:[t.jsx(b,{comments:o}),t.jsx(h,{value:e.line.oldLine}),t.jsx(h,{value:e.line.newLine}),t.jsx($,{tokens:n.tokens.get(e.line)??null,text:e.line.text,emphasis:i?{ranges:i,className:y[e.line.kind]}:void 0,wrap:!0})]})}return t.jsxs("div",{className:"flex divide-x divide-border",children:[t.jsx(j,{line:e.left,side:"left",ctx:n}),t.jsx(j,{line:e.right,side:"right",ctx:n})]})}function Y(e){const n=[];let s=[];const i=()=>{for(const o of s)n.push({left:o,right:null});s=[]};for(const o of e.lines)if(o.kind==="del")s.push(o);else if(o.kind==="add"){const a=s.shift();n.push({left:a??null,right:o})}else i(),n.push({left:o,right:o});return i(),n}function j({line:e,side:n,ctx:s}){const i=e?s.emphasis.get(e):void 0,o=e?I(e,n):void 0,a=o!==void 0?s.commentsByLine.get(o):void 0,d=o!==void 0&&s.pendingLines.has(o),l=L(a,d);return t.jsxs("div",{"data-file":s.filePath,"data-line":o,className:C("relative flex min-w-0 flex-1",l??(e?w[e.kind]:"")),children:[t.jsx(b,{comments:a}),t.jsx(h,{value:e?e.kind==="add"?e.newLine:e.oldLine:null}),e?t.jsx($,{tokens:s.tokens.get(e)??null,text:e.text,emphasis:i?{ranges:i,className:y[e.kind]}:void 0,wrap:!0}):t.jsx("pre",{className:"flex-1",children:" "})]})}function K({hunks:e,filePath:n,diffMode:s,layout:i="pane",commentIndex:o,pendingLines:a,gaps:d,onExpand:l}){const f=E(),m=H(n),p=R(D()),S=v.useMemo(()=>f&&m?M(f,e,m,p):new Map,[f,m,e,p]),k=v.useMemo(()=>P(e),[e]),x={tokens:S,emphasis:k,commentsByLine:o?.byLine??F,pendingLines:a??T,filePath:n,onExpand:l};if(e.length===0&&(d===void 0||d.length===0))return t.jsx("p",{className:"p-4 font-mono text-xs text-muted-foreground",children:"No changes"});const g=W(e,s,d??U);return i==="content"?t.jsx("div",{className:"text-xs leading-5",children:g.map((r,u)=>t.jsx(N,{row:r,ctx:x},r.type==="gap"?`g:${r.gap.startNew}:${u}`:r.type==="header"?`h:${r.text}:${u}`:r.type==="unified"?`u:${r.line.oldLine}:${r.line.newLine}:${u}`:`s:${r.left?.oldLine}:${r.right?.newLine}:${u}`))}):t.jsx(V,{rows:g,className:"leading-5",fitWidth:!0,dynamicHeight:!0,renderRow:r=>t.jsx(N,{row:r,ctx:x})})}export{K as H};