claude-code-memory-explorer 1.1.2 → 1.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-code-memory-explorer",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Memory explorer dashboard for Claude Code",
5
5
  "main": "server.js",
6
6
  "type": "commonjs",
package/public/app.js CHANGED
@@ -452,11 +452,29 @@ const SHORTCUT_PAIRS = [
452
452
  title: 'Hub',
453
453
  hub: true,
454
454
  rows: [
455
- { keys: ['Ctrl', 'Alt', '←/→'], combo: true, label: 'Previous / next hub app' },
456
- { keys: ['Alt', '1…9'], combo: true, label: 'Jump to hub app by number' },
457
- { keys: ['Ctrl', 'Alt', 'P'], combo: true, label: 'Project picker' },
458
- { keys: ['Ctrl', 'Alt', 'W'], combo: true, label: 'Config dir picker' },
459
- { keys: ['Ctrl', 'Alt', 'A'], combo: true, label: 'App launcher' },
455
+ {
456
+ keys: ['Ctrl', 'Alt', '←/→'],
457
+ action: ['hub.prevApp', 'hub.nextApp'],
458
+ combo: true,
459
+ hubMod: true,
460
+ label: 'Previous / next hub app',
461
+ },
462
+ {
463
+ keys: ['Alt', '1…9'],
464
+ action: 'hub.appByNumber',
465
+ combo: true,
466
+ hubMod: true,
467
+ label: 'Jump to hub app by number',
468
+ },
469
+ { keys: ['Ctrl', 'Alt', 'P'], action: 'hub.projectPicker', combo: true, hubMod: true, label: 'Project picker' },
470
+ {
471
+ keys: ['Ctrl', 'Alt', 'W'],
472
+ action: 'hub.configDirPicker',
473
+ combo: true,
474
+ hubMod: true,
475
+ label: 'Config dir picker',
476
+ },
477
+ { keys: ['Ctrl', 'Alt', 'A'], action: 'hub.appLauncher', combo: true, hubMod: true, label: 'App launcher' },
460
478
  ],
461
479
  },
462
480
  ],
@@ -464,6 +482,21 @@ const SHORTCUT_PAIRS = [
464
482
 
465
483
  const EMPTY_GROUP = { title: '', rows: [] };
466
484
 
485
+ // macOS names Control, Option and Shift by their symbols.
486
+ const IS_MAC = /^Mac/i.test(navigator.userAgentData?.platform || navigator.platform || '');
487
+ const MAC_KEYS = { Ctrl: '⌃', Alt: '⌥', Shift: '⇧' };
488
+
489
+ // The keys of a help row as they read on this system. The hub's modifier is Ctrl+Alt, and on
490
+ // macOS Control+Option for the tab numbers too (Windows and Linux use bare Alt for those). A hub
491
+ // row shows the keys the hub reports, which the user can change; row.keys until it answers.
492
+ function helpKeys(row, mac = IS_MAC, keyLabel = hub.keyLabel) {
493
+ const live = row.action && keyLabel(row.action);
494
+ if (live) return live;
495
+ if (!mac) return row.keys;
496
+ if (row.hubMod) return ['⌃', '⌥', ...row.keys.filter((k) => k !== 'Ctrl' && k !== 'Alt')];
497
+ return row.keys.map((k) => MAC_KEYS[k] || k);
498
+ }
499
+
467
500
  // Interleaves each pair's rows left-then-right so CSS grid auto-placement lands
468
501
  // them on shared row tracks (see .shortcuts in style.css).
469
502
  function buildHelpShortcuts() {
@@ -480,9 +513,10 @@ function buildHelpShortcuts() {
480
513
  for (let i = 0; i < Math.max(left.rows.length, right.rows.length); i++) {
481
514
  for (const [group, side] of sides) {
482
515
  const row = group.rows[i];
483
- if (!row) continue;
516
+ const parts = row && helpKeys(row);
517
+ if (!parts?.length) continue;
484
518
  const sep = row.combo ? '<span class="sc-plus">+</span>' : '<span class="sc-or">/</span>';
485
- const keys = row.keys.map((k) => `<kbd>${esc(k)}</kbd>`).join(sep);
519
+ const keys = parts.map((k) => `<kbd>${esc(k)}</kbd>`).join(sep);
486
520
  const cls = side + (group.hub ? ' sc-hub' : '');
487
521
  cells.push(`<dt class="${esc(cls)}">${keys}</dt><dd class="${esc(cls)}">${esc(row.label)}</dd>`);
488
522
  }
@@ -1,18 +1,51 @@
1
- // claude-hub-sdk 1.2.0 (sha256 62c7d9f477b2). Copied by npm run sdk:sync in claude-code-hub. Do not edit.
2
- // Claude Code Hub SDK stub: what an app serves when no hub runs it. Under a hub, the hub hands the
3
- // app its real SDK (client.js) in place of this file. The API must match client.js; a test checks it.
4
- ((root) => {
1
+ // claude-hub-sdk 1.4.0 (sha256 7d559a8888ce). Copied by npm run sdk:sync in claude-code-hub. Do not edit.
2
+ // Claude Code Hub SDK: the one rule that names a key press, shared by the hub page, client.js and
3
+ // stub.js. The hub serves it to its page as /sdk/keys.js; mount() and sdk:sync put it in front of
4
+ // client.js and stub.js, so an app still loads one file.
5
+ // var, not const: the hub page and an app page each load it as a classic script, and a second
6
+ // const declaration in the same page would throw.
7
+ var ClaudeHubKeys = (() => {
5
8
  'use strict';
6
9
 
7
- // A copy of client.js comboOf(); a test checks they match.
10
+ // Modifiers in ctrl, alt, shift, meta order, joined by '+' to the key. macOS composes
11
+ // Option+<key> into a character (Option+1 is '¡', Option+P is 'π') and holding Control does not
12
+ // undo it, so e.key alone cannot name these presses there. e.code is the physical key, which is
13
+ // wrong for non-US layouts, hence only as a fallback. No fallback under AltGraph: Chromium sets it
14
+ // when AltGr types a character, and that press is text. Takes a real KeyboardEvent or a forwarded
15
+ // {key, code} payload; a payload without code degrades to key. A payload needs no AltGraph: the
16
+ // SDK forwards only a press whose key already names a bound combo.
17
+ // Self-contained on purpose: cck puts its source text into a sandboxed frame.
8
18
  function comboOf(e) {
9
19
  const lower = typeof e.key === 'string' ? e.key.toLowerCase() : '';
10
- const m = /^(?:Key|Digit)([A-Z1-9])$/.exec(e.code || '');
20
+ const m = !e.getModifierState?.('AltGraph') && /^(?:Key|Digit)([A-Z1-9])$/.exec(e.code || '');
11
21
  const key = /^[a-z1-9]$/.test(lower) ? lower : m ? m[1].toLowerCase() : e.key;
12
22
  const mods = [e.ctrlKey && 'ctrl', e.altKey && 'alt', e.shiftKey && 'shift', e.metaKey && 'meta'];
13
23
  return [...mods, key].filter(Boolean).join('+');
14
24
  }
15
25
 
26
+ // The keys of a combo as a help row shows them: ['Ctrl', 'Alt', 'P'], or ['⌃', '⌥', 'P'] on macOS.
27
+ // The {n} of a numbered combo reads 1…9.
28
+ function keyParts(combo, mac) {
29
+ const mods = mac
30
+ ? { ctrl: '⌃', alt: '⌥', shift: '⇧', meta: '⌘' }
31
+ : { ctrl: 'Ctrl', alt: 'Alt', shift: 'Shift', meta: 'Win' };
32
+ const named = { '{n}': '1…9', ArrowLeft: '←', ArrowRight: '→', ArrowUp: '↑', ArrowDown: '↓' };
33
+ return combo.split('+').map((k) => mods[k] ?? named[k] ?? (k.length === 1 ? k.toUpperCase() : k));
34
+ }
35
+
36
+ return { comboOf, keyParts };
37
+ })();
38
+
39
+ if (typeof module === 'object' && module.exports) module.exports = ClaudeHubKeys;
40
+
41
+ // Claude Code Hub SDK stub: what an app serves when no hub runs it. Under a hub, the hub hands the
42
+ // app its real SDK (client.js) in place of this file. The API must match client.js; a test checks it.
43
+ ((root) => {
44
+ 'use strict';
45
+
46
+ // keys.js comes first in the synced file. Required as a module, stub.js loads it itself.
47
+ const { comboOf } = typeof ClaudeHubKeys === 'object' ? ClaudeHubKeys : require('./keys');
48
+
16
49
  function createClaudeHub(win) {
17
50
  let hub = null;
18
51
  const off = () => {};
@@ -43,6 +76,7 @@
43
76
  can: (action) => !!standaloneFn(action),
44
77
  forwards: () => false,
45
78
  forwardCombos: () => [],
79
+ keyLabel: () => null,
46
80
  closeGuard() {},
47
81
  openExternal(url) {
48
82
  win.open(url, '_blank', 'noopener');