@youtyan/code-viewer 0.5.5 → 0.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/README.md +389 -13
- package/dist/code-viewer.js +15568 -9512
- package/package.json +1 -1
- package/skills/code-viewer-query/SKILL.md +159 -14
- package/skills/code-viewer-snapshot/SKILL.md +59 -2
- package/web/app.js +771 -147
- package/web/index.html +1 -1
- package/web/style.css +12 -0
package/web/app.js
CHANGED
|
@@ -400,7 +400,8 @@
|
|
|
400
400
|
{ action: "start-g-sequence", key: "g", scope: "main" },
|
|
401
401
|
{ action: "layout-unified", key: "u" },
|
|
402
402
|
{ action: "layout-split", key: "s" },
|
|
403
|
-
{ action: "toggle-theme", key: "t" }
|
|
403
|
+
{ action: "toggle-theme", key: "t" },
|
|
404
|
+
{ action: "open-help", key: "?", shift: true }
|
|
404
405
|
];
|
|
405
406
|
function resolveKeymapAction(event, context) {
|
|
406
407
|
const key = event.key.toLowerCase();
|
|
@@ -20235,6 +20236,20 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20235
20236
|
const b2 = Math.max(1, Math.floor(Math.max(start, end)));
|
|
20236
20237
|
return a2 === b2 ? `@${path}#${a2}` : `@${path}#${a2}-${b2}`;
|
|
20237
20238
|
}
|
|
20239
|
+
function fileReferenceWithCodeClipboardText(path, start, end, lines, lang) {
|
|
20240
|
+
const ref = fileReferenceClipboardText(path, start, end);
|
|
20241
|
+
if (!ref)
|
|
20242
|
+
return "";
|
|
20243
|
+
if (!lines || lines.length === 0)
|
|
20244
|
+
return ref;
|
|
20245
|
+
const fence2 = (lang || "").trim();
|
|
20246
|
+
return `${ref}
|
|
20247
|
+
|
|
20248
|
+
\`\`\`${fence2}
|
|
20249
|
+
${lines.join(`
|
|
20250
|
+
`)}
|
|
20251
|
+
\`\`\``;
|
|
20252
|
+
}
|
|
20238
20253
|
|
|
20239
20254
|
// web-src/core/ws-highlight.ts
|
|
20240
20255
|
function isWhitespaceOnlyInlineHighlight(text2) {
|
|
@@ -20265,6 +20280,16 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20265
20280
|
function shouldRenderDiffSidebar(listSame, domIntact) {
|
|
20266
20281
|
return !listSame || !domIntact;
|
|
20267
20282
|
}
|
|
20283
|
+
function findDirectDiffCardByKey(target, key) {
|
|
20284
|
+
for (const child of Array.from(target.children)) {
|
|
20285
|
+
if (!child.classList.contains("gdp-file-shell"))
|
|
20286
|
+
continue;
|
|
20287
|
+
const card = child;
|
|
20288
|
+
if (card.dataset.key === key)
|
|
20289
|
+
return card;
|
|
20290
|
+
}
|
|
20291
|
+
return null;
|
|
20292
|
+
}
|
|
20268
20293
|
function createDiffView(deps) {
|
|
20269
20294
|
const {
|
|
20270
20295
|
$,
|
|
@@ -20480,11 +20505,17 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20480
20505
|
let CLIENT_REQ_SEQ = 0;
|
|
20481
20506
|
const LOAD_QUEUE = [];
|
|
20482
20507
|
let ACTIVE_LOADS = 0;
|
|
20508
|
+
let LOAD_EPOCH = 0;
|
|
20483
20509
|
const MAX_PARALLEL = 2;
|
|
20484
20510
|
let lazyObserver = null;
|
|
20485
20511
|
let scrollSpyInstalled = false;
|
|
20486
20512
|
let prevListSignature = "";
|
|
20487
20513
|
let prevCardSignatures = new Map;
|
|
20514
|
+
function resetLoadScheduling() {
|
|
20515
|
+
LOAD_EPOCH++;
|
|
20516
|
+
LOAD_QUEUE.length = 0;
|
|
20517
|
+
ACTIVE_LOADS = 0;
|
|
20518
|
+
}
|
|
20488
20519
|
function fileKey(f2) {
|
|
20489
20520
|
return f2.key || f2.path;
|
|
20490
20521
|
}
|
|
@@ -20534,11 +20565,12 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20534
20565
|
}
|
|
20535
20566
|
}
|
|
20536
20567
|
function invalidateLoadedCard(card, file, changedPaths) {
|
|
20537
|
-
if (!card.classList.contains("loaded"))
|
|
20568
|
+
if (!card.classList.contains("loaded") && !card.classList.contains("loading"))
|
|
20538
20569
|
return false;
|
|
20539
20570
|
if (changedPaths && !changedPaths.has(file.path))
|
|
20540
20571
|
return false;
|
|
20541
|
-
card.
|
|
20572
|
+
card.dataset.reqId = String(++CLIENT_REQ_SEQ);
|
|
20573
|
+
card.classList.remove("loaded", "loading", "error");
|
|
20542
20574
|
card.classList.add("pending");
|
|
20543
20575
|
card._diffData = null;
|
|
20544
20576
|
const body = card.querySelector(".gdp-shell-body");
|
|
@@ -20568,6 +20600,25 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20568
20600
|
}
|
|
20569
20601
|
}
|
|
20570
20602
|
}
|
|
20603
|
+
function resetReusableCard(card, file) {
|
|
20604
|
+
card.classList.remove("loaded", "loading", "error", "manual-load");
|
|
20605
|
+
card.classList.add("pending");
|
|
20606
|
+
card.replaceChildren();
|
|
20607
|
+
const tmp = createPlaceholder(file);
|
|
20608
|
+
while (tmp.firstChild)
|
|
20609
|
+
card.appendChild(tmp.firstChild);
|
|
20610
|
+
card.dataset.path = file.path;
|
|
20611
|
+
card.dataset.key = fileKey(file);
|
|
20612
|
+
card.dataset.sizeClass = file.size_class || "small";
|
|
20613
|
+
card.dataset.status = file.status || "M";
|
|
20614
|
+
card.dataset.reqId = String(++CLIENT_REQ_SEQ);
|
|
20615
|
+
delete card.dataset.manualRendered;
|
|
20616
|
+
delete card.dataset.manualLoad;
|
|
20617
|
+
delete card.dataset.manualMode;
|
|
20618
|
+
card.style.minHeight = `${file.estimated_height_px || 80}px`;
|
|
20619
|
+
card._diffData = null;
|
|
20620
|
+
card._file = null;
|
|
20621
|
+
}
|
|
20571
20622
|
function renderShell(meta, changedPaths) {
|
|
20572
20623
|
const newFiles = meta.files || [];
|
|
20573
20624
|
const newListSig = computeListSignature(newFiles);
|
|
@@ -20596,7 +20647,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20596
20647
|
empty.classList.remove("hidden");
|
|
20597
20648
|
target.replaceChildren();
|
|
20598
20649
|
}
|
|
20599
|
-
|
|
20650
|
+
resetLoadScheduling();
|
|
20600
20651
|
return {
|
|
20601
20652
|
structureChanged: sidebarNeedsRender,
|
|
20602
20653
|
invalidatedCards: 0,
|
|
@@ -20608,39 +20659,33 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20608
20659
|
for (const f2 of newFiles) {
|
|
20609
20660
|
newCardSigs.set(fileKey(f2), computeCardSignature(f2));
|
|
20610
20661
|
}
|
|
20662
|
+
const pathsUnknown = !changedPaths;
|
|
20663
|
+
const contentMayNeedReload = !listSame || pathsUnknown || (changedPaths ? newFiles.some((file) => {
|
|
20664
|
+
const key = fileKey(file);
|
|
20665
|
+
return prevCardSignatures.get(key) !== newCardSigs.get(key) || changedPaths.has(file.path);
|
|
20666
|
+
}) : false);
|
|
20667
|
+
if (contentMayNeedReload)
|
|
20668
|
+
resetLoadScheduling();
|
|
20611
20669
|
let invalidatedCards = 0;
|
|
20612
20670
|
if (listSame && domIntact) {
|
|
20613
|
-
const
|
|
20671
|
+
const pathsUnknown2 = !changedPaths;
|
|
20614
20672
|
let sidebarNeedsStatsUpdate = false;
|
|
20615
20673
|
for (const f2 of newFiles) {
|
|
20616
20674
|
const key = fileKey(f2);
|
|
20617
20675
|
const oldSig = prevCardSignatures.get(key);
|
|
20618
|
-
const newSig = newCardSigs.get(key);
|
|
20676
|
+
const newSig = newCardSigs.get(key) ?? computeCardSignature(f2);
|
|
20619
20677
|
const sigChanged = oldSig !== newSig;
|
|
20620
|
-
const pathHint =
|
|
20678
|
+
const pathHint = pathsUnknown2 || changedPaths.has(f2.path);
|
|
20621
20679
|
if (!sigChanged && !pathHint) {
|
|
20622
20680
|
continue;
|
|
20623
20681
|
}
|
|
20624
|
-
const card = target
|
|
20682
|
+
const card = findDirectDiffCardByKey(target, key);
|
|
20625
20683
|
if (!card)
|
|
20626
20684
|
continue;
|
|
20627
20685
|
const sizeChanged = card.dataset.sizeClass !== (f2.size_class || "small");
|
|
20628
20686
|
const statusChanged = card.dataset.status !== (f2.status || "M");
|
|
20629
20687
|
if (sizeChanged || statusChanged) {
|
|
20630
|
-
card
|
|
20631
|
-
card.classList.add("pending");
|
|
20632
|
-
card.replaceChildren();
|
|
20633
|
-
const tmp = createPlaceholder(f2);
|
|
20634
|
-
while (tmp.firstChild)
|
|
20635
|
-
card.appendChild(tmp.firstChild);
|
|
20636
|
-
card.dataset.sizeClass = f2.size_class || "small";
|
|
20637
|
-
card.dataset.status = f2.status || "M";
|
|
20638
|
-
delete card.dataset.manualRendered;
|
|
20639
|
-
delete card.dataset.manualLoad;
|
|
20640
|
-
delete card.dataset.manualMode;
|
|
20641
|
-
card.style.minHeight = `${f2.estimated_height_px || 80}px`;
|
|
20642
|
-
card._diffData = null;
|
|
20643
|
-
card._file = null;
|
|
20688
|
+
resetReusableCard(card, f2);
|
|
20644
20689
|
activatePendingCard(card, f2);
|
|
20645
20690
|
invalidatedCards++;
|
|
20646
20691
|
sidebarNeedsStatsUpdate = true;
|
|
@@ -20653,6 +20698,9 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20653
20698
|
const didInvalidate = sigChanged ? invalidateLoadedCard(card, f2, null) : invalidateLoadedCard(card, f2, changedPaths);
|
|
20654
20699
|
if (didInvalidate)
|
|
20655
20700
|
invalidatedCards++;
|
|
20701
|
+
else if ((sigChanged || pathHint) && card.classList.contains("pending")) {
|
|
20702
|
+
activatePendingCard(card, f2);
|
|
20703
|
+
}
|
|
20656
20704
|
if (sigChanged)
|
|
20657
20705
|
sidebarNeedsStatsUpdate = true;
|
|
20658
20706
|
}
|
|
@@ -20687,21 +20735,11 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20687
20735
|
oldByKey.delete(key);
|
|
20688
20736
|
const sizeChanged = old.dataset.sizeClass !== (f2.size_class || "small");
|
|
20689
20737
|
const statusChanged = old.dataset.status !== (f2.status || "M");
|
|
20690
|
-
|
|
20691
|
-
|
|
20692
|
-
|
|
20693
|
-
|
|
20694
|
-
|
|
20695
|
-
while (tmp.firstChild)
|
|
20696
|
-
old.appendChild(tmp.firstChild);
|
|
20697
|
-
old.dataset.sizeClass = f2.size_class || "small";
|
|
20698
|
-
old.dataset.status = f2.status || "M";
|
|
20699
|
-
delete old.dataset.manualRendered;
|
|
20700
|
-
delete old.dataset.manualLoad;
|
|
20701
|
-
delete old.dataset.manualMode;
|
|
20702
|
-
old.style.minHeight = `${f2.estimated_height_px || 80}px`;
|
|
20703
|
-
old._diffData = null;
|
|
20704
|
-
old._file = null;
|
|
20738
|
+
const oldSig = prevCardSignatures.get(key);
|
|
20739
|
+
const newSig = newCardSigs.get(key) ?? computeCardSignature(f2);
|
|
20740
|
+
const sigChanged = oldSig !== newSig;
|
|
20741
|
+
if (sizeChanged || statusChanged || sigChanged) {
|
|
20742
|
+
resetReusableCard(old, f2);
|
|
20705
20743
|
invalidatedCards++;
|
|
20706
20744
|
} else {
|
|
20707
20745
|
const stats = old.querySelector(".gdp-shell-header .stats");
|
|
@@ -20793,20 +20831,29 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
20793
20831
|
renderManualLoadPlaceholder(card, file);
|
|
20794
20832
|
return;
|
|
20795
20833
|
}
|
|
20796
|
-
if (LOAD_QUEUE.find((item) => item.card === card))
|
|
20834
|
+
if (LOAD_QUEUE.find((item) => item.card === card && item.epoch === LOAD_EPOCH))
|
|
20797
20835
|
return;
|
|
20798
|
-
LOAD_QUEUE.push({
|
|
20836
|
+
LOAD_QUEUE.push({
|
|
20837
|
+
file,
|
|
20838
|
+
card,
|
|
20839
|
+
priority: priority || 0,
|
|
20840
|
+
epoch: LOAD_EPOCH
|
|
20841
|
+
});
|
|
20799
20842
|
LOAD_QUEUE.sort((a2, b2) => b2.priority - a2.priority);
|
|
20800
20843
|
pumpQueue();
|
|
20801
20844
|
}
|
|
20802
20845
|
function pumpQueue() {
|
|
20803
20846
|
while (ACTIVE_LOADS < MAX_PARALLEL && LOAD_QUEUE.length) {
|
|
20804
20847
|
const item = LOAD_QUEUE.shift();
|
|
20848
|
+
if (item.epoch !== LOAD_EPOCH)
|
|
20849
|
+
continue;
|
|
20805
20850
|
if (item.card.classList.contains("loaded") || item.card.classList.contains("loading"))
|
|
20806
20851
|
continue;
|
|
20807
20852
|
ACTIVE_LOADS++;
|
|
20808
20853
|
loadFile(item.file, item.card).finally(() => {
|
|
20809
|
-
|
|
20854
|
+
if (item.epoch === LOAD_EPOCH) {
|
|
20855
|
+
ACTIVE_LOADS = Math.max(0, ACTIVE_LOADS - 1);
|
|
20856
|
+
}
|
|
20810
20857
|
pumpQueue();
|
|
20811
20858
|
});
|
|
20812
20859
|
}
|
|
@@ -21451,7 +21498,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
21451
21498
|
});
|
|
21452
21499
|
}
|
|
21453
21500
|
function clearLoadQueue() {
|
|
21454
|
-
|
|
21501
|
+
resetLoadScheduling();
|
|
21455
21502
|
}
|
|
21456
21503
|
return {
|
|
21457
21504
|
renderMeta,
|
|
@@ -21937,6 +21984,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
21937
21984
|
let hasMore = false;
|
|
21938
21985
|
let loading = false;
|
|
21939
21986
|
let generation = 0;
|
|
21987
|
+
let selectionGeneration = 0;
|
|
21940
21988
|
let selectedSha = "";
|
|
21941
21989
|
let query = "";
|
|
21942
21990
|
let mode = "history";
|
|
@@ -22197,11 +22245,12 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22197
22245
|
return page.commits.length > 0;
|
|
22198
22246
|
}
|
|
22199
22247
|
async function selectCommit(commit, options = {}) {
|
|
22248
|
+
const selectionGen = ++selectionGeneration;
|
|
22200
22249
|
const gen = generation;
|
|
22201
22250
|
selectedSha = commit.sha;
|
|
22202
22251
|
updateActiveRow();
|
|
22203
22252
|
await updateCommitInfo(commit);
|
|
22204
|
-
if (gen !== generation)
|
|
22253
|
+
if (selectionGen !== selectionGeneration || gen !== generation)
|
|
22205
22254
|
return;
|
|
22206
22255
|
if (options.updateUrl !== false) {
|
|
22207
22256
|
const range = commitDiffRange(commit);
|
|
@@ -22218,13 +22267,14 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22218
22267
|
deps.setRoute({ screen: "history", ref, commit: commit.sha, range }, true);
|
|
22219
22268
|
}
|
|
22220
22269
|
}
|
|
22221
|
-
if (gen !== generation)
|
|
22270
|
+
if (selectionGen !== selectionGeneration || gen !== generation)
|
|
22222
22271
|
return;
|
|
22223
22272
|
await deps.applyCommitRange(commitDiffRange(commit), pathFilter || undefined);
|
|
22224
|
-
if (gen !== generation)
|
|
22273
|
+
if (selectionGen !== selectionGeneration || gen !== generation)
|
|
22225
22274
|
return;
|
|
22226
22275
|
}
|
|
22227
22276
|
async function selectWorktree(options = {}) {
|
|
22277
|
+
const selectionGen = ++selectionGeneration;
|
|
22228
22278
|
const gen = generation;
|
|
22229
22279
|
selectedSha = HISTORY_WORKTREE_COMMIT;
|
|
22230
22280
|
updateActiveRow();
|
|
@@ -22244,10 +22294,10 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22244
22294
|
deps.setRoute({ screen: "history", ref, commit: selectedSha, range }, true);
|
|
22245
22295
|
}
|
|
22246
22296
|
}
|
|
22247
|
-
if (gen !== generation)
|
|
22297
|
+
if (selectionGen !== selectionGeneration || gen !== generation)
|
|
22248
22298
|
return;
|
|
22249
22299
|
await deps.applyCommitRange(range, pathFilter || undefined);
|
|
22250
|
-
if (gen !== generation)
|
|
22300
|
+
if (selectionGen !== selectionGeneration || gen !== generation)
|
|
22251
22301
|
return;
|
|
22252
22302
|
}
|
|
22253
22303
|
let lookupFailed = false;
|
|
@@ -22344,6 +22394,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22344
22394
|
hasMore = false;
|
|
22345
22395
|
loading = false;
|
|
22346
22396
|
inFlight = null;
|
|
22397
|
+
selectionGeneration++;
|
|
22347
22398
|
selectedSha = "";
|
|
22348
22399
|
setBanner("");
|
|
22349
22400
|
await updateCommitInfo(null);
|
|
@@ -22360,6 +22411,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22360
22411
|
if (scope2.commit) {
|
|
22361
22412
|
await resolveDeepLink(scope2.commit);
|
|
22362
22413
|
} else {
|
|
22414
|
+
selectionGeneration++;
|
|
22363
22415
|
selectedSha = "";
|
|
22364
22416
|
updateActiveRow();
|
|
22365
22417
|
await updateCommitInfo(null);
|
|
@@ -22389,6 +22441,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22389
22441
|
generation++;
|
|
22390
22442
|
loading = false;
|
|
22391
22443
|
inFlight = null;
|
|
22444
|
+
selectionGeneration++;
|
|
22392
22445
|
selectedSha = "";
|
|
22393
22446
|
setBanner("");
|
|
22394
22447
|
setStatusText("");
|
|
@@ -22413,6 +22466,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22413
22466
|
return;
|
|
22414
22467
|
query = value;
|
|
22415
22468
|
generation++;
|
|
22469
|
+
selectionGeneration++;
|
|
22416
22470
|
commits = [];
|
|
22417
22471
|
hasMore = false;
|
|
22418
22472
|
loading = false;
|
|
@@ -22575,6 +22629,308 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22575
22629
|
};
|
|
22576
22630
|
}
|
|
22577
22631
|
|
|
22632
|
+
// web-src/views/help-keybindings.ts
|
|
22633
|
+
var HIDDEN_HELP_KEYBINDING_ACTIONS = new Set([
|
|
22634
|
+
"start-g-sequence"
|
|
22635
|
+
]);
|
|
22636
|
+
var HELP_KEYBINDING_GROUPS = [
|
|
22637
|
+
{
|
|
22638
|
+
title: { en: "Global", ja: "グローバル" },
|
|
22639
|
+
rows: [
|
|
22640
|
+
{
|
|
22641
|
+
selectors: [{ action: "open-file-palette" }],
|
|
22642
|
+
description: {
|
|
22643
|
+
en: "Open file palette",
|
|
22644
|
+
ja: "ファイルパレットを開く"
|
|
22645
|
+
}
|
|
22646
|
+
},
|
|
22647
|
+
{
|
|
22648
|
+
selectors: [{ action: "open-grep-palette" }],
|
|
22649
|
+
description: {
|
|
22650
|
+
en: "Open grep palette",
|
|
22651
|
+
ja: "grep パレットを開く"
|
|
22652
|
+
}
|
|
22653
|
+
},
|
|
22654
|
+
{
|
|
22655
|
+
selectors: [{ action: "focus-file-filter" }],
|
|
22656
|
+
description: {
|
|
22657
|
+
en: "Focus file filter",
|
|
22658
|
+
ja: "ファイルフィルターへフォーカス"
|
|
22659
|
+
}
|
|
22660
|
+
},
|
|
22661
|
+
{
|
|
22662
|
+
selectors: [{ action: "open-help" }],
|
|
22663
|
+
description: {
|
|
22664
|
+
en: "Open this help (keybindings)",
|
|
22665
|
+
ja: "このヘルプ(キーバインド)を開く"
|
|
22666
|
+
}
|
|
22667
|
+
},
|
|
22668
|
+
{
|
|
22669
|
+
selectors: [{ action: "toggle-theme" }],
|
|
22670
|
+
description: { en: "Toggle theme", ja: "テーマ切り替え" }
|
|
22671
|
+
},
|
|
22672
|
+
{
|
|
22673
|
+
selectors: [
|
|
22674
|
+
{ action: "annotation-previous" },
|
|
22675
|
+
{ action: "annotation-next" }
|
|
22676
|
+
],
|
|
22677
|
+
description: {
|
|
22678
|
+
en: "Previous / next annotation",
|
|
22679
|
+
ja: "前 / 次の注釈へ移動"
|
|
22680
|
+
}
|
|
22681
|
+
},
|
|
22682
|
+
{
|
|
22683
|
+
selectors: [{ action: "layout-unified" }, { action: "layout-split" }],
|
|
22684
|
+
description: {
|
|
22685
|
+
en: "Switch unified / split layout",
|
|
22686
|
+
ja: "統合 / 分割レイアウトへ切り替え"
|
|
22687
|
+
}
|
|
22688
|
+
},
|
|
22689
|
+
{
|
|
22690
|
+
selectors: [{ action: "cancel-source-load" }],
|
|
22691
|
+
description: {
|
|
22692
|
+
en: "Cancel active source load",
|
|
22693
|
+
ja: "進行中のソース読み込みを中断"
|
|
22694
|
+
}
|
|
22695
|
+
}
|
|
22696
|
+
]
|
|
22697
|
+
},
|
|
22698
|
+
{
|
|
22699
|
+
title: { en: "Panels", ja: "パネル" },
|
|
22700
|
+
rows: [
|
|
22701
|
+
{
|
|
22702
|
+
selectors: [{ action: "focus-sidebar" }],
|
|
22703
|
+
description: { en: "Focus sidebar", ja: "サイドバーへフォーカス" }
|
|
22704
|
+
},
|
|
22705
|
+
{
|
|
22706
|
+
selectors: [{ action: "focus-main" }],
|
|
22707
|
+
description: {
|
|
22708
|
+
en: "Focus main panel",
|
|
22709
|
+
ja: "メインパネルへフォーカス"
|
|
22710
|
+
}
|
|
22711
|
+
}
|
|
22712
|
+
]
|
|
22713
|
+
},
|
|
22714
|
+
{
|
|
22715
|
+
title: { en: "Sidebar", ja: "サイドバー" },
|
|
22716
|
+
rows: [
|
|
22717
|
+
{
|
|
22718
|
+
selectors: [{ action: "sidebar-next" }, { action: "sidebar-previous" }],
|
|
22719
|
+
description: {
|
|
22720
|
+
en: "Move selection down / up",
|
|
22721
|
+
ja: "選択を下 / 上へ移動"
|
|
22722
|
+
}
|
|
22723
|
+
},
|
|
22724
|
+
{
|
|
22725
|
+
selectors: [
|
|
22726
|
+
{ action: "sidebar-page-down" },
|
|
22727
|
+
{ action: "sidebar-page-up" }
|
|
22728
|
+
],
|
|
22729
|
+
description: {
|
|
22730
|
+
en: "Move selection by half a page",
|
|
22731
|
+
ja: "半ページ分選択を移動"
|
|
22732
|
+
}
|
|
22733
|
+
},
|
|
22734
|
+
{
|
|
22735
|
+
selectors: [
|
|
22736
|
+
{ action: "goto-top", pendingG: true },
|
|
22737
|
+
{ action: "goto-bottom", shift: true, pendingG: false }
|
|
22738
|
+
],
|
|
22739
|
+
description: { en: "Move to top / bottom", ja: "先頭 / 末尾へ移動" }
|
|
22740
|
+
},
|
|
22741
|
+
{
|
|
22742
|
+
selectors: [{ action: "open-sidebar-item" }],
|
|
22743
|
+
description: { en: "Open selected item", ja: "選択項目を開く" }
|
|
22744
|
+
},
|
|
22745
|
+
{
|
|
22746
|
+
selectors: [
|
|
22747
|
+
{ action: "sidebar-collapse" },
|
|
22748
|
+
{ action: "sidebar-expand" }
|
|
22749
|
+
],
|
|
22750
|
+
description: {
|
|
22751
|
+
en: "Collapse / expand directory",
|
|
22752
|
+
ja: "ディレクトリを閉じる / 開く"
|
|
22753
|
+
}
|
|
22754
|
+
}
|
|
22755
|
+
]
|
|
22756
|
+
},
|
|
22757
|
+
{
|
|
22758
|
+
title: { en: "Main Panel", ja: "メインパネル" },
|
|
22759
|
+
rows: [
|
|
22760
|
+
{
|
|
22761
|
+
selectors: [
|
|
22762
|
+
{ action: "scroll-main-down", scope: "main" },
|
|
22763
|
+
{ action: "scroll-main-up", scope: "main" }
|
|
22764
|
+
],
|
|
22765
|
+
description: {
|
|
22766
|
+
en: "Move code cursor down / up",
|
|
22767
|
+
ja: "コードカーソルを下 / 上へ移動"
|
|
22768
|
+
}
|
|
22769
|
+
},
|
|
22770
|
+
{
|
|
22771
|
+
selectors: [
|
|
22772
|
+
{
|
|
22773
|
+
action: "scroll-main-page-down",
|
|
22774
|
+
scope: "main",
|
|
22775
|
+
key: "d",
|
|
22776
|
+
ctrl: true
|
|
22777
|
+
},
|
|
22778
|
+
{
|
|
22779
|
+
action: "scroll-main-page-up",
|
|
22780
|
+
scope: "main",
|
|
22781
|
+
key: "u",
|
|
22782
|
+
ctrl: true
|
|
22783
|
+
}
|
|
22784
|
+
],
|
|
22785
|
+
description: {
|
|
22786
|
+
en: "Move code cursor by half a page",
|
|
22787
|
+
ja: "コードカーソルを半ページ分移動"
|
|
22788
|
+
}
|
|
22789
|
+
},
|
|
22790
|
+
{
|
|
22791
|
+
selectors: [
|
|
22792
|
+
{ action: "scroll-main-page-down", scope: "main", key: "pagedown" },
|
|
22793
|
+
{ action: "scroll-main-page-up", scope: "main", key: "pageup" }
|
|
22794
|
+
],
|
|
22795
|
+
description: {
|
|
22796
|
+
en: "Move code cursor by a page",
|
|
22797
|
+
ja: "コードカーソルを1ページ分移動"
|
|
22798
|
+
}
|
|
22799
|
+
},
|
|
22800
|
+
{
|
|
22801
|
+
selectors: [
|
|
22802
|
+
{
|
|
22803
|
+
action: "scroll-main-page-down",
|
|
22804
|
+
scope: "main",
|
|
22805
|
+
key: "arrowdown",
|
|
22806
|
+
ctrl: true
|
|
22807
|
+
},
|
|
22808
|
+
{
|
|
22809
|
+
action: "scroll-main-page-up",
|
|
22810
|
+
scope: "main",
|
|
22811
|
+
key: "arrowup",
|
|
22812
|
+
ctrl: true
|
|
22813
|
+
}
|
|
22814
|
+
],
|
|
22815
|
+
description: {
|
|
22816
|
+
en: "Move code cursor by a page",
|
|
22817
|
+
ja: "コードカーソルを1ページ分移動"
|
|
22818
|
+
}
|
|
22819
|
+
},
|
|
22820
|
+
{
|
|
22821
|
+
selectors: [
|
|
22822
|
+
{ action: "goto-top", pendingG: true },
|
|
22823
|
+
{ action: "goto-bottom", shift: true, pendingG: false }
|
|
22824
|
+
],
|
|
22825
|
+
description: {
|
|
22826
|
+
en: "Move code cursor to top / bottom",
|
|
22827
|
+
ja: "コードカーソルを先頭 / 末尾へ移動"
|
|
22828
|
+
}
|
|
22829
|
+
},
|
|
22830
|
+
{
|
|
22831
|
+
selectors: [
|
|
22832
|
+
{ action: "tab-preview", scope: "main", pendingG: true },
|
|
22833
|
+
{ action: "tab-code", scope: "main", pendingG: true }
|
|
22834
|
+
],
|
|
22835
|
+
description: {
|
|
22836
|
+
en: "Switch to Preview / Code tab",
|
|
22837
|
+
ja: "Preview / Code タブへ切り替え"
|
|
22838
|
+
}
|
|
22839
|
+
}
|
|
22840
|
+
]
|
|
22841
|
+
}
|
|
22842
|
+
];
|
|
22843
|
+
function matchesSelector(binding, selector) {
|
|
22844
|
+
if (binding.action !== selector.action)
|
|
22845
|
+
return false;
|
|
22846
|
+
if (selector.key !== undefined && binding.key !== selector.key)
|
|
22847
|
+
return false;
|
|
22848
|
+
if (selector.scope !== undefined && binding.scope !== selector.scope)
|
|
22849
|
+
return false;
|
|
22850
|
+
if (selector.ctrl !== undefined && !!binding.ctrl !== selector.ctrl)
|
|
22851
|
+
return false;
|
|
22852
|
+
if (selector.meta !== undefined && !!binding.meta !== selector.meta)
|
|
22853
|
+
return false;
|
|
22854
|
+
if (selector.alt !== undefined && !!binding.alt !== selector.alt)
|
|
22855
|
+
return false;
|
|
22856
|
+
if (selector.shift !== undefined && !!binding.shift !== selector.shift)
|
|
22857
|
+
return false;
|
|
22858
|
+
if (selector.pendingG !== undefined && !!binding.pendingG !== selector.pendingG)
|
|
22859
|
+
return false;
|
|
22860
|
+
return true;
|
|
22861
|
+
}
|
|
22862
|
+
function formatKeyName(key, shifted) {
|
|
22863
|
+
const lower = key.toLowerCase();
|
|
22864
|
+
if (lower === "escape")
|
|
22865
|
+
return "Escape";
|
|
22866
|
+
if (lower === "enter")
|
|
22867
|
+
return "Enter";
|
|
22868
|
+
if (lower === "pagedown")
|
|
22869
|
+
return "PageDown";
|
|
22870
|
+
if (lower === "pageup")
|
|
22871
|
+
return "PageUp";
|
|
22872
|
+
if (lower === "arrowdown")
|
|
22873
|
+
return "ArrowDown";
|
|
22874
|
+
if (lower === "arrowup")
|
|
22875
|
+
return "ArrowUp";
|
|
22876
|
+
if (key === "?")
|
|
22877
|
+
return "?";
|
|
22878
|
+
if (shifted && key.length === 1)
|
|
22879
|
+
return key.toUpperCase();
|
|
22880
|
+
return key;
|
|
22881
|
+
}
|
|
22882
|
+
function formatKeyBinding(binding) {
|
|
22883
|
+
const key = formatKeyName(binding.key, !!binding.shift || !!binding.ctrl || !!binding.meta || !!binding.alt);
|
|
22884
|
+
if (binding.pendingG && !binding.ctrl && !binding.meta && !binding.alt && !binding.shift && binding.key.length === 1)
|
|
22885
|
+
return `g${key}`;
|
|
22886
|
+
const parts = [];
|
|
22887
|
+
if (binding.pendingG)
|
|
22888
|
+
parts.push("g");
|
|
22889
|
+
if (binding.ctrl)
|
|
22890
|
+
parts.push("Ctrl");
|
|
22891
|
+
if (binding.meta)
|
|
22892
|
+
parts.push("Meta");
|
|
22893
|
+
if (binding.alt)
|
|
22894
|
+
parts.push("Alt");
|
|
22895
|
+
if (binding.shift && binding.key !== "?")
|
|
22896
|
+
parts.push("Shift");
|
|
22897
|
+
parts.push(key);
|
|
22898
|
+
return parts.join("+");
|
|
22899
|
+
}
|
|
22900
|
+
function addUnique(values, next) {
|
|
22901
|
+
if (!values.includes(next))
|
|
22902
|
+
values.push(next);
|
|
22903
|
+
}
|
|
22904
|
+
function collectRowCoverage(row, bindings) {
|
|
22905
|
+
const coverage = [];
|
|
22906
|
+
const seen = new Set;
|
|
22907
|
+
for (const selector of row.selectors) {
|
|
22908
|
+
for (const binding of bindings) {
|
|
22909
|
+
if (!matchesSelector(binding, selector))
|
|
22910
|
+
continue;
|
|
22911
|
+
const label = formatKeyBinding(binding);
|
|
22912
|
+
const key = `${binding.action}\x00${binding.scope || ""}\x00${label}`;
|
|
22913
|
+
if (seen.has(key))
|
|
22914
|
+
continue;
|
|
22915
|
+
seen.add(key);
|
|
22916
|
+
coverage.push({ action: selector.action, binding, label });
|
|
22917
|
+
}
|
|
22918
|
+
}
|
|
22919
|
+
return coverage;
|
|
22920
|
+
}
|
|
22921
|
+
function buildRow(row, language, bindings) {
|
|
22922
|
+
const labels = [];
|
|
22923
|
+
for (const item of collectRowCoverage(row, bindings))
|
|
22924
|
+
addUnique(labels, item.label);
|
|
22925
|
+
return [labels.join(" / "), row.description[language]];
|
|
22926
|
+
}
|
|
22927
|
+
function buildHelpKeybindingGroups(language, bindings = DEFAULT_KEY_BINDINGS) {
|
|
22928
|
+
return HELP_KEYBINDING_GROUPS.map((group) => ({
|
|
22929
|
+
title: group.title[language],
|
|
22930
|
+
rows: group.rows.map((row) => buildRow(row, language, bindings))
|
|
22931
|
+
}));
|
|
22932
|
+
}
|
|
22933
|
+
|
|
22578
22934
|
// web-src/views/help-page.ts
|
|
22579
22935
|
var HELP_LANGUAGES = ["en", "ja"];
|
|
22580
22936
|
var HELP_SECTIONS = [
|
|
@@ -22583,6 +22939,7 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22583
22939
|
"annotations",
|
|
22584
22940
|
"database",
|
|
22585
22941
|
"skills",
|
|
22942
|
+
"mcp",
|
|
22586
22943
|
"keybindings"
|
|
22587
22944
|
];
|
|
22588
22945
|
var HELP_CONTENT = {
|
|
@@ -22670,6 +23027,21 @@ ${entry.message}` : entry.detail ?? entry.message ?? "";
|
|
|
22670
23027
|
{
|
|
22671
23028
|
kind: "paragraph",
|
|
22672
23029
|
text: "Each row reports OK / WARN / ERROR with a remediation hint when relevant. The check groups are Runtime (Node / Bun / NODE_MODULE_VERSION), Package (version + execution origin including npx cache), SQLite driver, Snapshot store, Git, Discovery summary, Docker / Compose (CLI / v2 plugin / daemon / compose config dry-parse / compose ps health per discovered service), and Server. The most common hint is the npx cache fix for better-sqlite3 NODE_MODULE_VERSION mismatch (rm -rf ~/.npm/_npx then re-run with npx -y @youtyan/code-viewer@latest)."
|
|
23030
|
+
},
|
|
23031
|
+
{
|
|
23032
|
+
kind: "paragraph",
|
|
23033
|
+
text: 'From the terminal — and for AI agents or CI — the same report is available without a browser. `code-viewer doctor` prints a status summary; add `--json` for the full DoctorReport (matches the /_doctor endpoint). Exit code is 1 when worstStatus is "error", so it doubles as a CI gate.'
|
|
23034
|
+
},
|
|
23035
|
+
{
|
|
23036
|
+
kind: "command",
|
|
23037
|
+
title: "Doctor summary in the terminal",
|
|
23038
|
+
command: "code-viewer doctor"
|
|
23039
|
+
},
|
|
23040
|
+
{
|
|
23041
|
+
kind: "command",
|
|
23042
|
+
title: "Doctor JSON for agents and CI",
|
|
23043
|
+
command: `code-viewer doctor --json
|
|
23044
|
+
code-viewer doctor --cwd /path/to/repo --port 64160 --json`
|
|
22673
23045
|
}
|
|
22674
23046
|
]
|
|
22675
23047
|
}
|
|
@@ -22985,7 +23357,7 @@ code-viewer query clear --db app.db`
|
|
|
22985
23357
|
{
|
|
22986
23358
|
kind: "command",
|
|
22987
23359
|
title: "Search across all tables",
|
|
22988
|
-
command: 'code-viewer query search --db app.db --term "
|
|
23360
|
+
command: 'code-viewer query search --db app.db --term "sample@example.com" \\\n --tables users,orders --include-non-text --max-hits 20'
|
|
22989
23361
|
},
|
|
22990
23362
|
{
|
|
22991
23363
|
kind: "command",
|
|
@@ -23002,16 +23374,12 @@ code-viewer query snapshot delete --id snap-abc123`
|
|
|
23002
23374
|
{
|
|
23003
23375
|
kind: "command",
|
|
23004
23376
|
title: "Diff two snapshots",
|
|
23005
|
-
command:
|
|
23006
|
-
--note "User registration test"
|
|
23007
|
-
code-viewer query diff list --db app.db --json
|
|
23008
|
-
code-viewer query diff delete --id diff-xyz789`
|
|
23377
|
+
command: "code-viewer query diff tables --before snap-abc123 --after snap-def456 --json"
|
|
23009
23378
|
},
|
|
23010
23379
|
{
|
|
23011
23380
|
kind: "command",
|
|
23012
23381
|
title: "Inspect a diff",
|
|
23013
|
-
command:
|
|
23014
|
-
code-viewer query diff rows --id diff-xyz789 --table users --type inserted --limit 50`
|
|
23382
|
+
command: "code-viewer query diff rows --before snap-abc123 --after snap-def456 --table users --limit 50"
|
|
23015
23383
|
},
|
|
23016
23384
|
{
|
|
23017
23385
|
kind: "command",
|
|
@@ -23097,63 +23465,120 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
23097
23465
|
}
|
|
23098
23466
|
]
|
|
23099
23467
|
},
|
|
23100
|
-
|
|
23101
|
-
nav: "
|
|
23102
|
-
title: "
|
|
23103
|
-
intro: "
|
|
23468
|
+
mcp: {
|
|
23469
|
+
nav: "MCP Server",
|
|
23470
|
+
title: "MCP Server",
|
|
23471
|
+
intro: "While code-viewer is running, the same server also exposes a local, read-only MCP endpoint at /_mcp so AI agents can call status, file, search, and datastore tools directly over JSON-RPC instead of spawning code-viewer CLI subprocesses.",
|
|
23104
23472
|
groups: [
|
|
23105
23473
|
{
|
|
23106
|
-
title: "
|
|
23474
|
+
title: "Connect to the endpoint",
|
|
23107
23475
|
blocks: [
|
|
23108
23476
|
{
|
|
23109
|
-
kind: "
|
|
23110
|
-
|
|
23111
|
-
|
|
23112
|
-
["Ctrl+G", "Open grep palette"],
|
|
23113
|
-
["/", "Focus file filter"],
|
|
23114
|
-
["t", "Toggle theme"],
|
|
23115
|
-
["[ / ]", "Previous / next annotation"]
|
|
23116
|
-
]
|
|
23117
|
-
}
|
|
23118
|
-
]
|
|
23119
|
-
},
|
|
23120
|
-
{
|
|
23121
|
-
title: "Panels",
|
|
23122
|
-
blocks: [
|
|
23477
|
+
kind: "paragraph",
|
|
23478
|
+
text: "The endpoint speaks JSON-RPC 2.0 over the Streamable HTTP transport (initialize, ping, tools/list, tools/call). It accepts POST requests with an application/json body only, and is guarded by the same localhost / same-origin check as every other route."
|
|
23479
|
+
},
|
|
23123
23480
|
{
|
|
23124
|
-
kind: "
|
|
23125
|
-
|
|
23126
|
-
|
|
23127
|
-
["Ctrl+L", "Focus main panel"]
|
|
23128
|
-
]
|
|
23481
|
+
kind: "command",
|
|
23482
|
+
title: "Endpoint URL (port from the printed startup URL)",
|
|
23483
|
+
command: "http://127.0.0.1:<port>/_mcp"
|
|
23129
23484
|
}
|
|
23130
23485
|
]
|
|
23131
23486
|
},
|
|
23132
23487
|
{
|
|
23133
|
-
title: "
|
|
23488
|
+
title: "Available tools",
|
|
23134
23489
|
blocks: [
|
|
23135
23490
|
{
|
|
23136
23491
|
kind: "table",
|
|
23137
23492
|
rows: [
|
|
23138
|
-
[
|
|
23139
|
-
|
|
23140
|
-
|
|
23141
|
-
|
|
23142
|
-
[
|
|
23493
|
+
[
|
|
23494
|
+
"code_viewer_agent_help",
|
|
23495
|
+
"Index of every AI-facing CLI subcommand."
|
|
23496
|
+
],
|
|
23497
|
+
[
|
|
23498
|
+
"code_viewer_status",
|
|
23499
|
+
"Branch, remote, changed files, and recent commits."
|
|
23500
|
+
],
|
|
23501
|
+
[
|
|
23502
|
+
"code_viewer_file_show",
|
|
23503
|
+
"Read a file (optionally a line range) at any ref."
|
|
23504
|
+
],
|
|
23505
|
+
[
|
|
23506
|
+
"code_viewer_file_blame",
|
|
23507
|
+
"Per-line blame (sha / author / time / summary)."
|
|
23508
|
+
],
|
|
23509
|
+
[
|
|
23510
|
+
"code_viewer_file_history",
|
|
23511
|
+
"Commit history for one path (follows renames)."
|
|
23512
|
+
],
|
|
23513
|
+
[
|
|
23514
|
+
"code_viewer_file_diff",
|
|
23515
|
+
"Unified diff for one path (preview-capped by default)."
|
|
23516
|
+
],
|
|
23517
|
+
[
|
|
23518
|
+
"code_viewer_search_files",
|
|
23519
|
+
"Rank repository paths by fuzzy or glob match."
|
|
23520
|
+
],
|
|
23521
|
+
[
|
|
23522
|
+
"code_viewer_search_code",
|
|
23523
|
+
"Grep the repository (rg / git grep / fallback)."
|
|
23524
|
+
],
|
|
23525
|
+
[
|
|
23526
|
+
"code_viewer_datastore_sources",
|
|
23527
|
+
"Discover read-only datastore source ids."
|
|
23528
|
+
],
|
|
23529
|
+
[
|
|
23530
|
+
"code_viewer_datastore_schemas",
|
|
23531
|
+
"List schemas for one SQL datastore."
|
|
23532
|
+
],
|
|
23533
|
+
[
|
|
23534
|
+
"code_viewer_datastore_schema",
|
|
23535
|
+
"Inspect tables, indexes, FKs, and columns."
|
|
23536
|
+
],
|
|
23537
|
+
[
|
|
23538
|
+
"code_viewer_datastore_columns",
|
|
23539
|
+
"Inspect columns for one SQL table."
|
|
23540
|
+
],
|
|
23541
|
+
[
|
|
23542
|
+
"code_viewer_datastore_ddl",
|
|
23543
|
+
"Inspect the CREATE statement and triggers."
|
|
23544
|
+
],
|
|
23545
|
+
[
|
|
23546
|
+
"code_viewer_datastore_query",
|
|
23547
|
+
"Run a read-only SELECT / PRAGMA / EXPLAIN / WITH."
|
|
23548
|
+
],
|
|
23549
|
+
[
|
|
23550
|
+
"code_viewer_datastore_history",
|
|
23551
|
+
"Inspect saved query history."
|
|
23552
|
+
]
|
|
23143
23553
|
]
|
|
23144
23554
|
}
|
|
23145
23555
|
]
|
|
23146
|
-
}
|
|
23556
|
+
}
|
|
23557
|
+
]
|
|
23558
|
+
},
|
|
23559
|
+
keybindings: {
|
|
23560
|
+
nav: "Keybindings",
|
|
23561
|
+
title: "Keyboard Shortcuts",
|
|
23562
|
+
intro: "Use these shortcuts to move between panels and navigate files without leaving the keyboard.",
|
|
23563
|
+
groups: [
|
|
23147
23564
|
{
|
|
23148
|
-
title: "
|
|
23565
|
+
title: "Line selection",
|
|
23149
23566
|
blocks: [
|
|
23150
23567
|
{
|
|
23151
23568
|
kind: "table",
|
|
23152
23569
|
rows: [
|
|
23153
|
-
[
|
|
23154
|
-
|
|
23155
|
-
|
|
23156
|
-
|
|
23570
|
+
[
|
|
23571
|
+
"Drag on line numbers",
|
|
23572
|
+
"Highlight a range; the floating copy pill prepares @path#L1-L9"
|
|
23573
|
+
],
|
|
23574
|
+
[
|
|
23575
|
+
"Click the pill",
|
|
23576
|
+
"Copy @path#L1-L9 to the clipboard for pasting into Claude Code / Codex"
|
|
23577
|
+
],
|
|
23578
|
+
[
|
|
23579
|
+
"Shift+Click the pill",
|
|
23580
|
+
"Copy @path#L1-L9 plus a fenced code block of the selected lines — paste straight to an AI without re-fetching the file"
|
|
23581
|
+
]
|
|
23157
23582
|
]
|
|
23158
23583
|
}
|
|
23159
23584
|
]
|
|
@@ -23246,6 +23671,21 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
23246
23671
|
{
|
|
23247
23672
|
kind: "paragraph",
|
|
23248
23673
|
text: "各項目は OK / WARN / ERROR で表示され、必要に応じて対処手順のヒントが付きます。診断グループは Runtime (Node / Bun / NODE_MODULE_VERSION)、Package (バージョン + 実行元: npx cache / global / local / bunx)、SQLite driver、Snapshot store、Git、Discovery summary、Docker / Compose (CLI / v2 plugin / daemon / compose config dry parse / compose ps による各サービスのヘルス)、Server (待ち受けポート) の 8 つ。よくあるヒントは npx キャッシュ起因の better-sqlite3 NODE_MODULE_VERSION 不一致で、rm -rf ~/.npm/_npx の後に npx -y @youtyan/code-viewer@latest を再実行する手順を表示します。"
|
|
23674
|
+
},
|
|
23675
|
+
{
|
|
23676
|
+
kind: "paragraph",
|
|
23677
|
+
text: 'ターミナルからは `code-viewer doctor` で同じレポートを取得できます。AI エージェントや CI からは `--json` で /_doctor と同じ DoctorReport を受け取れます。worstStatus が "error" なら exit code 1 を返すので CI ガードに直接使えます。'
|
|
23678
|
+
},
|
|
23679
|
+
{
|
|
23680
|
+
kind: "command",
|
|
23681
|
+
title: "ターミナル用 doctor サマリー",
|
|
23682
|
+
command: "code-viewer doctor"
|
|
23683
|
+
},
|
|
23684
|
+
{
|
|
23685
|
+
kind: "command",
|
|
23686
|
+
title: "AI / CI 用 doctor JSON",
|
|
23687
|
+
command: `code-viewer doctor --json
|
|
23688
|
+
code-viewer doctor --cwd /path/to/repo --port 64160 --json`
|
|
23249
23689
|
}
|
|
23250
23690
|
]
|
|
23251
23691
|
}
|
|
@@ -23561,7 +24001,7 @@ code-viewer query clear --db app.db`
|
|
|
23561
24001
|
{
|
|
23562
24002
|
kind: "command",
|
|
23563
24003
|
title: "テーブル横断の全文検索",
|
|
23564
|
-
command: 'code-viewer query search --db app.db --term "
|
|
24004
|
+
command: 'code-viewer query search --db app.db --term "sample@example.com" \\\n --tables users,orders --include-non-text --max-hits 20'
|
|
23565
24005
|
},
|
|
23566
24006
|
{
|
|
23567
24007
|
kind: "command",
|
|
@@ -23578,16 +24018,12 @@ code-viewer query snapshot delete --id snap-abc123`
|
|
|
23578
24018
|
{
|
|
23579
24019
|
kind: "command",
|
|
23580
24020
|
title: "2 つのスナップショットを diff",
|
|
23581
|
-
command:
|
|
23582
|
-
--note "ユーザー登録テストの差分"
|
|
23583
|
-
code-viewer query diff list --db app.db --json
|
|
23584
|
-
code-viewer query diff delete --id diff-xyz789`
|
|
24021
|
+
command: "code-viewer query diff tables --before snap-abc123 --after snap-def456 --json"
|
|
23585
24022
|
},
|
|
23586
24023
|
{
|
|
23587
24024
|
kind: "command",
|
|
23588
24025
|
title: "diff の中身を確認",
|
|
23589
|
-
command:
|
|
23590
|
-
code-viewer query diff rows --id diff-xyz789 --table users --type inserted --limit 50`
|
|
24026
|
+
command: "code-viewer query diff rows --before snap-abc123 --after snap-def456 --table users --limit 50"
|
|
23591
24027
|
},
|
|
23592
24028
|
{
|
|
23593
24029
|
kind: "command",
|
|
@@ -23673,63 +24109,117 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
23673
24109
|
}
|
|
23674
24110
|
]
|
|
23675
24111
|
},
|
|
23676
|
-
|
|
23677
|
-
nav: "
|
|
23678
|
-
title: "
|
|
23679
|
-
intro: "
|
|
24112
|
+
mcp: {
|
|
24113
|
+
nav: "MCPサーバー",
|
|
24114
|
+
title: "MCPサーバー",
|
|
24115
|
+
intro: "code-viewer を起動している間、同じサーバーがローカルの read-only な MCP エンドポイント (/_mcp) も公開します。AI エージェントは code-viewer の CLI をサブプロセスとして起動する代わりに、status / file / search / datastore の各ツールを JSON-RPC 経由で直接呼び出せます。",
|
|
23680
24116
|
groups: [
|
|
23681
24117
|
{
|
|
23682
|
-
title: "
|
|
24118
|
+
title: "エンドポイントへの接続",
|
|
23683
24119
|
blocks: [
|
|
23684
24120
|
{
|
|
23685
|
-
kind: "
|
|
23686
|
-
|
|
23687
|
-
|
|
23688
|
-
["Ctrl+G", "grep パレットを開く"],
|
|
23689
|
-
["/", "ファイルフィルターへフォーカス"],
|
|
23690
|
-
["t", "テーマ切り替え"],
|
|
23691
|
-
["[ / ]", "前 / 次の注釈へ移動"]
|
|
23692
|
-
]
|
|
23693
|
-
}
|
|
23694
|
-
]
|
|
23695
|
-
},
|
|
23696
|
-
{
|
|
23697
|
-
title: "パネル",
|
|
23698
|
-
blocks: [
|
|
24121
|
+
kind: "paragraph",
|
|
24122
|
+
text: "エンドポイントは JSON-RPC 2.0 の Streamable HTTP トランスポート (initialize / ping / tools/list / tools/call) で応答します。受け付けるのは application/json ボディの POST リクエストのみで、他のルートと同じ localhost / 同一オリジンチェックで保護されています。"
|
|
24123
|
+
},
|
|
23699
24124
|
{
|
|
23700
|
-
kind: "
|
|
23701
|
-
|
|
23702
|
-
|
|
23703
|
-
["Ctrl+L", "メインパネルへフォーカス"]
|
|
23704
|
-
]
|
|
24125
|
+
kind: "command",
|
|
24126
|
+
title: "エンドポイント URL (port は起動時に表示される URL と同じ)",
|
|
24127
|
+
command: "http://127.0.0.1:<port>/_mcp"
|
|
23705
24128
|
}
|
|
23706
24129
|
]
|
|
23707
24130
|
},
|
|
23708
24131
|
{
|
|
23709
|
-
title: "
|
|
24132
|
+
title: "利用できるツール",
|
|
23710
24133
|
blocks: [
|
|
23711
24134
|
{
|
|
23712
24135
|
kind: "table",
|
|
23713
24136
|
rows: [
|
|
23714
|
-
[
|
|
23715
|
-
|
|
23716
|
-
|
|
23717
|
-
|
|
23718
|
-
[
|
|
24137
|
+
[
|
|
24138
|
+
"code_viewer_agent_help",
|
|
24139
|
+
"AI 向け CLI サブコマンドの一覧索引。"
|
|
24140
|
+
],
|
|
24141
|
+
[
|
|
24142
|
+
"code_viewer_status",
|
|
24143
|
+
"ブランチ、remote、変更ファイル、直近のコミット。"
|
|
24144
|
+
],
|
|
24145
|
+
[
|
|
24146
|
+
"code_viewer_file_show",
|
|
24147
|
+
"任意の ref でファイル(または行範囲)を読む。"
|
|
24148
|
+
],
|
|
24149
|
+
[
|
|
24150
|
+
"code_viewer_file_blame",
|
|
24151
|
+
"行単位の blame (sha / author / time / summary)。"
|
|
24152
|
+
],
|
|
24153
|
+
[
|
|
24154
|
+
"code_viewer_file_history",
|
|
24155
|
+
"1ファイルのコミット履歴(リネーム追跡あり)。"
|
|
24156
|
+
],
|
|
24157
|
+
[
|
|
24158
|
+
"code_viewer_file_diff",
|
|
24159
|
+
"1ファイルの unified diff(既定はプレビュー上限あり)。"
|
|
24160
|
+
],
|
|
24161
|
+
[
|
|
24162
|
+
"code_viewer_search_files",
|
|
24163
|
+
"ファジー / glob マッチでリポジトリのパスを順位付け。"
|
|
24164
|
+
],
|
|
24165
|
+
[
|
|
24166
|
+
"code_viewer_search_code",
|
|
24167
|
+
"リポジトリを grep する (rg / git grep / フォールバック)。"
|
|
24168
|
+
],
|
|
24169
|
+
[
|
|
24170
|
+
"code_viewer_datastore_sources",
|
|
24171
|
+
"read-only なデータストアの source id を発見。"
|
|
24172
|
+
],
|
|
24173
|
+
[
|
|
24174
|
+
"code_viewer_datastore_schemas",
|
|
24175
|
+
"SQL データストア1件のスキーマ一覧。"
|
|
24176
|
+
],
|
|
24177
|
+
[
|
|
24178
|
+
"code_viewer_datastore_schema",
|
|
24179
|
+
"テーブル、インデックス、外部キー、カラムを調査。"
|
|
24180
|
+
],
|
|
24181
|
+
[
|
|
24182
|
+
"code_viewer_datastore_columns",
|
|
24183
|
+
"SQL テーブル1件のカラムを調査。"
|
|
24184
|
+
],
|
|
24185
|
+
["code_viewer_datastore_ddl", "CREATE 文とトリガーを調査。"],
|
|
24186
|
+
[
|
|
24187
|
+
"code_viewer_datastore_query",
|
|
24188
|
+
"read-only な SELECT / PRAGMA / EXPLAIN / WITH を実行。"
|
|
24189
|
+
],
|
|
24190
|
+
[
|
|
24191
|
+
"code_viewer_datastore_history",
|
|
24192
|
+
"保存済みのクエリ履歴を調査。"
|
|
24193
|
+
]
|
|
23719
24194
|
]
|
|
23720
24195
|
}
|
|
23721
24196
|
]
|
|
23722
|
-
}
|
|
24197
|
+
}
|
|
24198
|
+
]
|
|
24199
|
+
},
|
|
24200
|
+
keybindings: {
|
|
24201
|
+
nav: "キーバインド",
|
|
24202
|
+
title: "キーバインド",
|
|
24203
|
+
intro: "キーボードだけでパネル移動、ファイル選択、スクロールを行うためのショートカットです。",
|
|
24204
|
+
groups: [
|
|
23723
24205
|
{
|
|
23724
|
-
title: "
|
|
24206
|
+
title: "行選択",
|
|
23725
24207
|
blocks: [
|
|
23726
24208
|
{
|
|
23727
24209
|
kind: "table",
|
|
23728
24210
|
rows: [
|
|
23729
|
-
[
|
|
23730
|
-
|
|
23731
|
-
|
|
23732
|
-
|
|
24211
|
+
[
|
|
24212
|
+
"行番号でドラッグ",
|
|
24213
|
+
"範囲をハイライトし、フロートする Copy ピルが @path#L1-L9 を用意"
|
|
24214
|
+
],
|
|
24215
|
+
[
|
|
24216
|
+
"ピルをクリック",
|
|
24217
|
+
"@path#L1-L9 をコピー(Claude Code / Codex への貼り付け用)"
|
|
24218
|
+
],
|
|
24219
|
+
[
|
|
24220
|
+
"Shift+ピルをクリック",
|
|
24221
|
+
"@path#L1-L9 と選択行の実コード(フェンス付き)をまとめてコピー — AI へ直接貼れて、ファイル再取得不要"
|
|
24222
|
+
]
|
|
23733
24223
|
]
|
|
23734
24224
|
}
|
|
23735
24225
|
]
|
|
@@ -23745,6 +24235,19 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
23745
24235
|
function helpSectionFromRoute(route) {
|
|
23746
24236
|
return route.screen === "help" && HELP_SECTIONS.includes(route.section) ? route.section : "overview";
|
|
23747
24237
|
}
|
|
24238
|
+
function openHelpKeybindings(deps) {
|
|
24239
|
+
const route = deps.getRoute();
|
|
24240
|
+
deps.cancelActiveSourceLoad("navigation");
|
|
24241
|
+
deps.setRoute({
|
|
24242
|
+
screen: "help",
|
|
24243
|
+
lang: route.screen === "help" ? helpLanguageFromRoute(route) : deps.getLanguage(),
|
|
24244
|
+
section: "keybindings",
|
|
24245
|
+
range: deps.currentRange()
|
|
24246
|
+
});
|
|
24247
|
+
deps.setPageMode();
|
|
24248
|
+
deps.renderHelpPage();
|
|
24249
|
+
deps.setStatus("live");
|
|
24250
|
+
}
|
|
23748
24251
|
function renderHelpCommand(block2) {
|
|
23749
24252
|
const wrap = document.createElement("div");
|
|
23750
24253
|
wrap.className = "gdp-help-command";
|
|
@@ -23813,6 +24316,13 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
23813
24316
|
const section = helpSectionFromRoute(deps.getRoute());
|
|
23814
24317
|
const content = HELP_CONTENT[lang];
|
|
23815
24318
|
const sectionContent = content.sections[section];
|
|
24319
|
+
const sectionGroups = section === "keybindings" ? [
|
|
24320
|
+
...buildHelpKeybindingGroups(lang).map((group) => ({
|
|
24321
|
+
title: group.title,
|
|
24322
|
+
blocks: [{ kind: "table", rows: group.rows }]
|
|
24323
|
+
})),
|
|
24324
|
+
...sectionContent.groups
|
|
24325
|
+
] : sectionContent.groups;
|
|
23816
24326
|
const shell = document.createElement("section");
|
|
23817
24327
|
shell.className = "gdp-help-shell";
|
|
23818
24328
|
const header = document.createElement("header");
|
|
@@ -23862,7 +24372,7 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
23862
24372
|
const intro = document.createElement("p");
|
|
23863
24373
|
intro.textContent = sectionContent.intro;
|
|
23864
24374
|
article.append(h2, intro);
|
|
23865
|
-
|
|
24375
|
+
sectionGroups.forEach((group) => {
|
|
23866
24376
|
const groupSection = document.createElement("section");
|
|
23867
24377
|
groupSection.className = "gdp-help-group";
|
|
23868
24378
|
const groupTitle = document.createElement("h3");
|
|
@@ -24270,39 +24780,109 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
24270
24780
|
return { setupHunkExpand };
|
|
24271
24781
|
}
|
|
24272
24782
|
|
|
24783
|
+
// web-src/core/html-escape.ts
|
|
24784
|
+
function escapeHtml2(value) {
|
|
24785
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
24786
|
+
}
|
|
24787
|
+
|
|
24273
24788
|
// web-src/views/line-ref-pill.ts
|
|
24274
24789
|
var COPY_ICON = '<svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true" fill="currentColor">' + '<path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"/>' + '<path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"/>' + "</svg>";
|
|
24275
24790
|
var CHECK_ICON = '<svg viewBox="0 0 16 16" width="14" height="14" aria-hidden="true" fill="currentColor">' + '<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 0 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z"/>' + "</svg>";
|
|
24276
|
-
function
|
|
24277
|
-
|
|
24791
|
+
function langFromPath(path) {
|
|
24792
|
+
const m = path.match(/\.([^./]+)$/);
|
|
24793
|
+
if (!m)
|
|
24794
|
+
return "";
|
|
24795
|
+
return EXT_TO_LANG[m[1].toLowerCase()] || "";
|
|
24796
|
+
}
|
|
24797
|
+
function readRenderedLines(path, start, end) {
|
|
24798
|
+
const card = document.querySelector(`.gdp-file-shell[data-path="${CSS.escape(path)}"]`);
|
|
24799
|
+
if (!card)
|
|
24800
|
+
return [];
|
|
24801
|
+
const out = [];
|
|
24802
|
+
for (let line = start;line <= end; line++) {
|
|
24803
|
+
const sourceRow = card.querySelector(`.gdp-source-table tr[data-line="${String(line)}"]`);
|
|
24804
|
+
if (sourceRow) {
|
|
24805
|
+
const code2 = sourceRow.querySelector(".gdp-source-line-code");
|
|
24806
|
+
out.push(code2?.textContent ?? "");
|
|
24807
|
+
}
|
|
24808
|
+
}
|
|
24809
|
+
if (out.length > 0 && out.some((value) => value.length > 0))
|
|
24810
|
+
return out;
|
|
24811
|
+
const diffRows = card.querySelectorAll("table.d2h-diff-table tr");
|
|
24812
|
+
if (diffRows.length === 0)
|
|
24813
|
+
return [];
|
|
24814
|
+
const collected = new Map;
|
|
24815
|
+
diffRows.forEach((row) => {
|
|
24816
|
+
const sideCell = row.querySelector("td.d2h-code-linenumber, td.d2h-code-side-linenumber");
|
|
24817
|
+
if (!sideCell)
|
|
24818
|
+
return;
|
|
24819
|
+
const side = sideCell.closest(".d2h-file-side-diff");
|
|
24820
|
+
const wrapper = sideCell.closest(".d2h-file-wrapper");
|
|
24821
|
+
if (side && wrapper) {
|
|
24822
|
+
const sides = wrapper.querySelectorAll(".d2h-file-side-diff");
|
|
24823
|
+
if (sides.length >= 2 && side !== sides[1])
|
|
24824
|
+
return;
|
|
24825
|
+
}
|
|
24826
|
+
const numText = sideCell.querySelector(".line-num2")?.textContent ?? sideCell.textContent ?? "";
|
|
24827
|
+
const line = Number(numText.trim());
|
|
24828
|
+
if (!Number.isInteger(line) || line < start || line > end)
|
|
24829
|
+
return;
|
|
24830
|
+
const codeCell = row.querySelector(".d2h-code-line-ctn");
|
|
24831
|
+
if (codeCell)
|
|
24832
|
+
collected.set(line, codeCell.textContent ?? "");
|
|
24833
|
+
});
|
|
24834
|
+
if (collected.size === 0)
|
|
24835
|
+
return [];
|
|
24836
|
+
const ordered = [];
|
|
24837
|
+
for (let line = start;line <= end; line++) {
|
|
24838
|
+
ordered.push(collected.get(line) ?? "");
|
|
24839
|
+
}
|
|
24840
|
+
return ordered;
|
|
24278
24841
|
}
|
|
24279
24842
|
function createLineRefPill() {
|
|
24280
24843
|
const pill = document.createElement("button");
|
|
24281
24844
|
pill.id = "line-ref-pill";
|
|
24282
24845
|
pill.type = "button";
|
|
24283
|
-
pill.title = "選択行の参照をコピー(Claude Code / Codex
|
|
24846
|
+
pill.title = "選択行の参照をコピー(Claude Code / Codex に貼り付け用)。Shift+Click でコード本体も添付。";
|
|
24284
24847
|
pill.hidden = true;
|
|
24285
24848
|
document.body.appendChild(pill);
|
|
24286
24849
|
let refText = "";
|
|
24850
|
+
let currentPath = "";
|
|
24851
|
+
let currentStart = 0;
|
|
24852
|
+
let currentEnd = 0;
|
|
24287
24853
|
let feedbackTimer = null;
|
|
24288
24854
|
function render(state) {
|
|
24289
|
-
pill.classList.toggle("copied", state === "copied");
|
|
24855
|
+
pill.classList.toggle("copied", state === "copied" || state === "copied-code");
|
|
24290
24856
|
if (state === "copied") {
|
|
24291
24857
|
pill.innerHTML = `${CHECK_ICON}<span class="lrp-label">Copied!</span>`;
|
|
24292
24858
|
return;
|
|
24293
24859
|
}
|
|
24860
|
+
if (state === "copied-code") {
|
|
24861
|
+
pill.innerHTML = `${CHECK_ICON}<span class="lrp-label">Copied + code</span>`;
|
|
24862
|
+
return;
|
|
24863
|
+
}
|
|
24294
24864
|
if (state === "failed") {
|
|
24295
24865
|
pill.innerHTML = `${COPY_ICON}<span class="lrp-label">copy failed</span>`;
|
|
24296
24866
|
return;
|
|
24297
24867
|
}
|
|
24298
24868
|
pill.innerHTML = `${COPY_ICON}<span class="lrp-label">Copy</span>` + `<span class="lrp-ref">${escapeHtml2(refText)}</span>`;
|
|
24299
24869
|
}
|
|
24300
|
-
pill.addEventListener("click", async () => {
|
|
24870
|
+
pill.addEventListener("click", async (event) => {
|
|
24301
24871
|
if (!refText)
|
|
24302
24872
|
return;
|
|
24873
|
+
const withCode = event.shiftKey;
|
|
24874
|
+
let payload = refText;
|
|
24875
|
+
let copiedCode = false;
|
|
24876
|
+
if (withCode && currentPath) {
|
|
24877
|
+
const lines = readRenderedLines(currentPath, currentStart, currentEnd);
|
|
24878
|
+
if (lines.length > 0) {
|
|
24879
|
+
payload = fileReferenceWithCodeClipboardText(currentPath, currentStart, currentEnd, lines, langFromPath(currentPath));
|
|
24880
|
+
copiedCode = true;
|
|
24881
|
+
}
|
|
24882
|
+
}
|
|
24303
24883
|
try {
|
|
24304
|
-
await navigator.clipboard.writeText(
|
|
24305
|
-
render("copied");
|
|
24884
|
+
await navigator.clipboard.writeText(payload);
|
|
24885
|
+
render(copiedCode ? "copied-code" : "copied");
|
|
24306
24886
|
} catch {
|
|
24307
24887
|
render("failed");
|
|
24308
24888
|
}
|
|
@@ -24321,6 +24901,9 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
24321
24901
|
return;
|
|
24322
24902
|
const changed = next !== refText;
|
|
24323
24903
|
refText = next;
|
|
24904
|
+
currentPath = path;
|
|
24905
|
+
currentStart = Math.max(1, Math.floor(Math.min(start, end)));
|
|
24906
|
+
currentEnd = Math.max(1, Math.floor(Math.max(start, end)));
|
|
24324
24907
|
if (feedbackTimer) {
|
|
24325
24908
|
clearTimeout(feedbackTimer);
|
|
24326
24909
|
feedbackTimer = null;
|
|
@@ -24335,6 +24918,9 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
24335
24918
|
},
|
|
24336
24919
|
hide() {
|
|
24337
24920
|
refText = "";
|
|
24921
|
+
currentPath = "";
|
|
24922
|
+
currentStart = 0;
|
|
24923
|
+
currentEnd = 0;
|
|
24338
24924
|
pill.hidden = true;
|
|
24339
24925
|
}
|
|
24340
24926
|
};
|
|
@@ -24600,6 +25186,11 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
24600
25186
|
wireRefSelectorInput(refToInput, () => deps.setRange(refFromInput.value, refToInput.value));
|
|
24601
25187
|
wireRefSelectorInput(deps.$("#repo-target"), (ref) => {
|
|
24602
25188
|
const route = deps.getRoute();
|
|
25189
|
+
if (route.screen === "repo") {
|
|
25190
|
+
deps.setRoute({ ...route, ref, range: deps.currentRange() });
|
|
25191
|
+
deps.loadRepo();
|
|
25192
|
+
return;
|
|
25193
|
+
}
|
|
24603
25194
|
if (route.screen !== "file")
|
|
24604
25195
|
return;
|
|
24605
25196
|
const nextRoute = {
|
|
@@ -25563,6 +26154,13 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
25563
26154
|
function renderSidebar(files, onFileClick) {
|
|
25564
26155
|
const ul = $("#filelist");
|
|
25565
26156
|
const repoSidebar = !!onFileClick;
|
|
26157
|
+
if (!repoSidebar) {
|
|
26158
|
+
const repoTarget = document.querySelector("#repo-target-wrap");
|
|
26159
|
+
if (repoTarget) {
|
|
26160
|
+
repoTarget.hidden = true;
|
|
26161
|
+
repoTarget.style.display = "none";
|
|
26162
|
+
}
|
|
26163
|
+
}
|
|
25566
26164
|
const treeMode = STATE.sbView === "tree" || repoSidebar;
|
|
25567
26165
|
ul.innerHTML = "";
|
|
25568
26166
|
ul.classList.toggle("tree", treeMode);
|
|
@@ -26211,8 +26809,10 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
26211
26809
|
const wrap = document.querySelector("#repo-target-wrap");
|
|
26212
26810
|
if (!input || !wrap)
|
|
26213
26811
|
return;
|
|
26214
|
-
|
|
26215
|
-
|
|
26812
|
+
const activeRef = activeRepoTreeRef();
|
|
26813
|
+
input.value = activeRef || ref || "worktree";
|
|
26814
|
+
wrap.hidden = activeRef == null;
|
|
26815
|
+
wrap.style.display = activeRef == null ? "none" : "";
|
|
26216
26816
|
syncSidebarHeaderHeight();
|
|
26217
26817
|
}
|
|
26218
26818
|
function activeRepoTreeRef() {
|
|
@@ -29998,8 +30598,8 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
29998
30598
|
view: "view",
|
|
29999
30599
|
tree: "tree",
|
|
30000
30600
|
flat: "flat",
|
|
30001
|
-
filter: "Filter files
|
|
30002
|
-
filterTitle: "Filter files. Use /pattern/ for regex. Cmd/Ctrl+K
|
|
30601
|
+
filter: "Filter files… / ⌘K",
|
|
30602
|
+
filterTitle: "Filter files. Use /pattern/ for regex. Press / to focus this field, Cmd/Ctrl+K for the full-file palette, Ctrl+G for grep, ? for help.",
|
|
30003
30603
|
hide: "hide sidebar"
|
|
30004
30604
|
},
|
|
30005
30605
|
history: {
|
|
@@ -30104,8 +30704,8 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
30104
30704
|
view: "表示",
|
|
30105
30705
|
tree: "ツリー",
|
|
30106
30706
|
flat: "一覧",
|
|
30107
|
-
filter: "
|
|
30108
|
-
filterTitle: "
|
|
30707
|
+
filter: "ファイル絞り込み… / ⌘K",
|
|
30708
|
+
filterTitle: "ファイルを絞り込みます。/pattern/ は正規表現。/ でこの欄にフォーカス、Cmd/Ctrl+K で全ファイルパレット、Ctrl+G で grep、? でヘルプ。",
|
|
30109
30709
|
hide: "サイドバーを隠す"
|
|
30110
30710
|
},
|
|
30111
30711
|
history: {
|
|
@@ -30841,13 +31441,21 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
30841
31441
|
function setPageMode() {
|
|
30842
31442
|
const historyPanelRoute = STATE.route.screen === "history";
|
|
30843
31443
|
const fileHistoryRoute = isFileHistoryRoute(STATE.route);
|
|
31444
|
+
const fileRepoBlobRoute = STATE.route.screen === "file" && (STATE.route.view === "blob" || STATE.route.view === "blame" || STATE.route.view === "history");
|
|
31445
|
+
const repoSidebarRoute = STATE.route.screen === "repo" || fileRepoBlobRoute;
|
|
30844
31446
|
document.body.classList.toggle("gdp-file-detail-page", STATE.route.screen === "file");
|
|
30845
|
-
document.body.classList.toggle("gdp-repo-blob-page",
|
|
31447
|
+
document.body.classList.toggle("gdp-repo-blob-page", fileRepoBlobRoute);
|
|
30846
31448
|
document.body.classList.toggle("gdp-repo-page", STATE.route.screen === "repo");
|
|
31449
|
+
document.body.classList.toggle("gdp-diff-page", STATE.route.screen === "diff");
|
|
30847
31450
|
document.body.classList.toggle("gdp-help-page", STATE.route.screen === "help");
|
|
30848
31451
|
document.body.classList.toggle("gdp-history-page", historyPanelRoute);
|
|
30849
31452
|
document.body.classList.toggle("gdp-file-history-page", fileHistoryRoute);
|
|
30850
31453
|
document.body.classList.toggle("gdp-database-page", STATE.route.screen === "database");
|
|
31454
|
+
const repoTargetWrap = document.querySelector("#repo-target-wrap");
|
|
31455
|
+
if (!repoSidebarRoute && repoTargetWrap) {
|
|
31456
|
+
repoTargetWrap.hidden = true;
|
|
31457
|
+
repoTargetWrap.style.display = "none";
|
|
31458
|
+
}
|
|
30851
31459
|
placeSidebarToggle();
|
|
30852
31460
|
syncSidebarHeaderHeight();
|
|
30853
31461
|
const historyPanel = $("#history-panel");
|
|
@@ -31442,6 +32050,19 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
31442
32050
|
$("#theme").click();
|
|
31443
32051
|
return true;
|
|
31444
32052
|
}
|
|
32053
|
+
if (action === "open-help") {
|
|
32054
|
+
openHelpKeybindings({
|
|
32055
|
+
getRoute: () => STATE.route,
|
|
32056
|
+
getLanguage: () => STATE.language,
|
|
32057
|
+
currentRange,
|
|
32058
|
+
setRoute,
|
|
32059
|
+
setPageMode,
|
|
32060
|
+
renderHelpPage,
|
|
32061
|
+
setStatus,
|
|
32062
|
+
cancelActiveSourceLoad
|
|
32063
|
+
});
|
|
32064
|
+
return true;
|
|
32065
|
+
}
|
|
31445
32066
|
return false;
|
|
31446
32067
|
}
|
|
31447
32068
|
document.addEventListener("keydown", handleVirtualSourcePagingKeydown, {
|
|
@@ -31612,6 +32233,8 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
31612
32233
|
getRoute: () => STATE.route,
|
|
31613
32234
|
setRoute,
|
|
31614
32235
|
applyCommitRange: (range, pathFilter) => {
|
|
32236
|
+
cancelInFlightRequests();
|
|
32237
|
+
DIFF_VIEW.clearLoadQueue();
|
|
31615
32238
|
STATE.from = range.from;
|
|
31616
32239
|
STATE.to = range.to;
|
|
31617
32240
|
activeHistoryPathFilter = pathFilter || null;
|
|
@@ -31743,6 +32366,7 @@ code-viewer query diff rows --id diff-xyz789 --table users --type inserted --lim
|
|
|
31743
32366
|
currentRange,
|
|
31744
32367
|
setRange,
|
|
31745
32368
|
setRoute,
|
|
32369
|
+
loadRepo,
|
|
31746
32370
|
renderStandaloneSource,
|
|
31747
32371
|
getFrom: () => STATE.from,
|
|
31748
32372
|
getTo: () => STATE.to,
|