claude-code-kanban 7.2.0 → 7.4.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/public/index.html CHANGED
@@ -138,6 +138,7 @@
138
138
  class="pf-input"
139
139
  placeholder="Any project"
140
140
  autocomplete="off"
141
+ data-bwignore data-1p-ignore data-lpignore="true"
141
142
  spellcheck="false"
142
143
  role="combobox"
143
144
  aria-expanded="true"
@@ -169,6 +170,8 @@
169
170
  type="text"
170
171
  class="search-input"
171
172
  placeholder="Search tasks, sessions, projects..."
173
+ autocomplete="off"
174
+ data-bwignore data-1p-ignore data-lpignore="true"
172
175
  oninput="handleSearch(this.value)"
173
176
  />
174
177
  <button id="search-clear-btn" class="search-clear" onclick="clearSearch()" title="Clear search" aria-label="Clear search">
@@ -503,7 +506,7 @@
503
506
  </div>
504
507
  <div class="help-bar">
505
508
  <div class="help-tabs" id="help-tabs" role="tablist" aria-label="Shortcut groups"></div>
506
- <input type="search" id="help-filter" class="form-input help-filter" placeholder="Filter shortcuts" aria-label="Filter shortcuts" autocomplete="off" spellcheck="false">
509
+ <input type="search" id="help-filter" class="form-input help-filter" placeholder="Filter shortcuts" aria-label="Filter shortcuts" autocomplete="off" data-bwignore data-1p-ignore data-lpignore="true" spellcheck="false">
507
510
  </div>
508
511
  <div class="modal-body">
509
512
  <dl class="shortcuts" id="help-shortcuts"></dl>
@@ -802,7 +805,7 @@
802
805
  <label class="ns-label" for="ns-folder">Folder</label>
803
806
  <div class="ns-field ns-folder-field">
804
807
  <div class="ns-inline">
805
- <input type="text" id="ns-folder" class="form-input" placeholder="Type to find a project" autocomplete="off" spellcheck="false" role="combobox" aria-expanded="false" aria-controls="ns-folder-list">
808
+ <input type="text" id="ns-folder" class="form-input" placeholder="Type to find a project" autocomplete="off" data-bwignore data-1p-ignore data-lpignore="true" spellcheck="false" role="combobox" aria-expanded="false" aria-controls="ns-folder-list">
806
809
  <button type="button" id="ns-browse" class="btn btn-secondary ns-browse" onclick="browseNewSessionFolder()">Browse…</button>
807
810
  </div>
808
811
  <div id="ns-folder-list" class="ns-dropdown" role="listbox" hidden></div>
@@ -811,7 +814,7 @@
811
814
  <div class="ns-row ns-extra">
812
815
  <label class="ns-label" for="ns-name">Name</label>
813
816
  <div class="ns-field">
814
- <input type="text" id="ns-name" class="form-input" placeholder="Optional" maxlength="80" autocomplete="off" spellcheck="false">
817
+ <input type="text" id="ns-name" class="form-input" placeholder="Optional" maxlength="80" autocomplete="off" data-bwignore data-1p-ignore data-lpignore="true" spellcheck="false">
815
818
  </div>
816
819
  </div>
817
820
  <div class="ns-row ns-extra">
@@ -828,7 +831,7 @@
828
831
  <div class="ns-field">
829
832
  <div class="ns-inline">
830
833
  <label class="ns-check"><input type="checkbox" id="ns-wt"> New worktree</label>
831
- <input type="text" id="ns-wt-name" class="form-input" placeholder="Name (optional)" maxlength="64" autocomplete="off" spellcheck="false" disabled aria-label="Worktree name">
834
+ <input type="text" id="ns-wt-name" class="form-input" placeholder="Name (optional)" maxlength="64" autocomplete="off" data-bwignore data-1p-ignore data-lpignore="true" spellcheck="false" disabled aria-label="Worktree name">
832
835
  </div>
833
836
  <div id="ns-wt-hint" class="ns-hint" hidden></div>
834
837
  </div>
@@ -849,6 +852,7 @@
849
852
  </div>
850
853
  <div class="modal-footer ns-footer">
851
854
  <label class="ns-check ns-stay" title="Start in the background and keep the current view"><input type="checkbox" id="ns-stay"> Stay here</label>
855
+ <label class="ns-check ns-edit" title="Open a shell in the folder with the claude command typed in. Press Enter to run it."><input type="checkbox" id="ns-edit"> Edit before run</label>
852
856
  <button type="button" class="btn btn-secondary" onclick="closeNewSession()">Cancel</button>
853
857
  <button type="button" id="ns-start" class="btn btn-primary" onclick="startNewSession()" disabled>Start</button>
854
858
  </div>
@@ -863,7 +867,7 @@
863
867
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>
864
868
  </button>
865
869
  </div>
866
- <input id="pane-pop-input" class="form-input" placeholder="Search linked docs, or paste a URL or a file path" autocomplete="off" spellcheck="false">
870
+ <input id="pane-pop-input" class="form-input" placeholder="Search linked docs, or paste a URL or a file path" autocomplete="off" data-bwignore data-1p-ignore data-lpignore="true" spellcheck="false">
867
871
  <div id="pane-pop-detect" class="pane-pop-detect"></div>
868
872
  <div class="pane-pop-label">Linked docs</div>
869
873
  <div id="pane-pop-docs" class="pane-pop-docs"></div>
@@ -873,7 +877,7 @@
873
877
 
874
878
  <div id="session-picker-modal" class="modal-overlay top-aligned" onclick="closeSessionPicker()">
875
879
  <div class="modal session-picker" onclick="event.stopPropagation()">
876
- <input type="text" id="session-picker-input" class="form-input sp-input" placeholder="Jump to session..." autocomplete="off" spellcheck="false">
880
+ <input type="text" id="session-picker-input" class="form-input sp-input" placeholder="Jump to session..." autocomplete="off" data-bwignore data-1p-ignore data-lpignore="true" spellcheck="false">
877
881
  <div class="sp-body">
878
882
  <div id="session-picker-list" class="sp-list"></div>
879
883
  <div id="session-picker-peek" class="sp-peek"></div>
@@ -884,7 +888,7 @@
884
888
 
885
889
  <div id="project-picker-modal" class="modal-overlay top-aligned" onclick="closeProjectPicker()">
886
890
  <div class="modal session-picker" onclick="event.stopPropagation()">
887
- <input type="text" id="project-picker-input" class="form-input sp-input" placeholder="Filter by project..." autocomplete="off" spellcheck="false">
891
+ <input type="text" id="project-picker-input" class="form-input sp-input" placeholder="Filter by project..." autocomplete="off" data-bwignore data-1p-ignore data-lpignore="true" spellcheck="false">
888
892
  <div class="pp-chips">
889
893
  <button type="button" class="pf-recent" id="pp-recent-chip" aria-pressed="false" title="List only projects active in the last 24h" onclick="ppToggleRecentOnly()">Recent</button>
890
894
  </div>
package/public/style.css CHANGED
@@ -3909,6 +3909,49 @@ code.language-tree .hljs-title {
3909
3909
  background: #fff;
3910
3910
  }
3911
3911
 
3912
+ .pane-url-bar {
3913
+ position: absolute;
3914
+ right: 12px;
3915
+ bottom: 12px;
3916
+ display: flex;
3917
+ align-items: center;
3918
+ gap: 2px;
3919
+ padding: 3px;
3920
+ border: 1px solid var(--border);
3921
+ border-radius: 8px;
3922
+ background: var(--bg-elevated);
3923
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
3924
+ font-family: var(--font-mono);
3925
+ font-size: 12px;
3926
+ opacity: 0;
3927
+ pointer-events: none;
3928
+ transition: opacity 0.15s;
3929
+ }
3930
+
3931
+ .pane-view:hover > .pane-url-bar,
3932
+ .pane-view.frame-focus > .pane-url-bar {
3933
+ opacity: 1;
3934
+ pointer-events: auto;
3935
+ }
3936
+
3937
+ .pane-url-bar .icon-btn {
3938
+ width: auto;
3939
+ min-width: 26px;
3940
+ height: 24px;
3941
+ padding: 0 6px;
3942
+ border-color: transparent;
3943
+ font: inherit;
3944
+ }
3945
+
3946
+ .pane-url-bar .pane-keys {
3947
+ display: none;
3948
+ color: var(--accent);
3949
+ }
3950
+
3951
+ .pane-view.frame-focus .pane-keys {
3952
+ display: flex;
3953
+ }
3954
+
3912
3955
  .pane-doc {
3913
3956
  flex: 1;
3914
3957
  min-height: 0;
@@ -7100,7 +7143,8 @@ select.form-input option:checked {
7100
7143
 
7101
7144
  /* #region SESSION_PICKER */
7102
7145
  .modal.session-picker {
7103
- max-height: 70vh;
7146
+ max-width: 920px;
7147
+ max-height: 74vh;
7104
7148
  padding: 12px;
7105
7149
  display: flex;
7106
7150
  flex-direction: column;
@@ -7109,9 +7153,9 @@ select.form-input option:checked {
7109
7153
  }
7110
7154
 
7111
7155
  .sp-input {
7112
- padding: 9px 12px;
7156
+ padding: 10px 12px;
7113
7157
  background: var(--bg-deep);
7114
- font-size: 13px;
7158
+ font-size: 14px;
7115
7159
  }
7116
7160
 
7117
7161
  .modal.session-picker.peeking {
@@ -7154,7 +7198,7 @@ select.form-input option:checked {
7154
7198
  gap: 8px;
7155
7199
  margin-bottom: 6px;
7156
7200
  font-family: var(--mono);
7157
- font-size: 11px;
7201
+ font-size: 11.5px;
7158
7202
  color: var(--text-muted);
7159
7203
  white-space: nowrap;
7160
7204
  overflow: hidden;
@@ -7172,13 +7216,13 @@ select.form-input option:checked {
7172
7216
  align-items: center;
7173
7217
  gap: 8px;
7174
7218
  width: 100%;
7175
- padding: 6px 8px;
7219
+ padding: 7px 8px;
7176
7220
  background: none;
7177
7221
  border: 1px solid transparent;
7178
7222
  border-radius: 5px;
7179
7223
  color: var(--text-secondary);
7180
7224
  font-family: var(--mono);
7181
- font-size: 12px;
7225
+ font-size: 13px;
7182
7226
  text-align: left;
7183
7227
  cursor: pointer;
7184
7228
  }
@@ -7287,14 +7331,14 @@ select.form-input option:checked {
7287
7331
  border-radius: 3px;
7288
7332
  background: var(--bg-hover);
7289
7333
  color: var(--text-tertiary);
7290
- font-size: 11px;
7334
+ font-size: 11.5px;
7291
7335
  }
7292
7336
 
7293
7337
  .sp-count,
7294
7338
  .sp-time {
7295
7339
  flex: none;
7296
7340
  color: var(--text-muted);
7297
- font-size: 11px;
7341
+ font-size: 11.5px;
7298
7342
  white-space: nowrap;
7299
7343
  }
7300
7344
 
@@ -7333,7 +7377,7 @@ select.form-input option:checked {
7333
7377
 
7334
7378
  /* #region NEW_SESSION */
7335
7379
  .modal.new-session-modal {
7336
- width: 520px;
7380
+ width: 640px;
7337
7381
  max-width: calc(100vw - 32px);
7338
7382
  overflow: visible;
7339
7383
  }
@@ -7462,7 +7506,8 @@ select.form-input option:checked {
7462
7506
  accent-color: var(--accent);
7463
7507
  }
7464
7508
 
7465
- .ns-inline .form-input:disabled {
7509
+ .ns-inline .form-input:disabled,
7510
+ .ns-check:has(input:disabled) {
7466
7511
  opacity: 0.5;
7467
7512
  cursor: not-allowed;
7468
7513
  }
@@ -7545,15 +7590,27 @@ select.form-input option:checked {
7545
7590
  border-top: 1px solid var(--border);
7546
7591
  }
7547
7592
 
7548
- .ns-stay {
7549
- margin-right: auto;
7593
+ .ns-stay,
7594
+ .ns-edit {
7550
7595
  color: var(--text-tertiary);
7551
7596
  }
7552
7597
 
7553
- .new-session-modal.ns-resume .ns-stay {
7598
+ .ns-edit {
7599
+ margin-right: auto;
7600
+ }
7601
+
7602
+ .new-session-modal.ns-resume .ns-stay,
7603
+ .new-session-modal.ns-resume .ns-edit {
7554
7604
  visibility: hidden;
7555
7605
  }
7556
7606
 
7607
+ .ns-footer .btn-primary {
7608
+ min-width: 0;
7609
+ overflow: hidden;
7610
+ text-overflow: ellipsis;
7611
+ white-space: nowrap;
7612
+ }
7613
+
7557
7614
  .ns-footer .btn-primary:disabled {
7558
7615
  opacity: 0.5;
7559
7616
  cursor: not-allowed;
@@ -11,12 +11,14 @@
11
11
  const modsOf = (e) =>
12
12
  [e.ctrlKey && 'ctrl', e.altKey && 'alt', e.shiftKey && 'shift', e.metaKey && 'meta'].filter(Boolean).join('+');
13
13
 
14
- // A claim names a key by its physical code, or by its character when the layout moves it.
14
+ // A claim names a key by its physical code, or by its character when the layout moves it. A press
15
+ // that AltGr turns into a character (Polish AltGr+S is 'ś') is matched by its character only.
15
16
  function keySigs(e) {
16
17
  const mods = modsOf(e);
17
- return [e.code && `${mods}|c:${e.code}`, typeof e.key === 'string' && `${mods}|k:${e.key.toLowerCase()}`].filter(
18
- Boolean,
19
- );
18
+ return [
19
+ e.code && !e.getModifierState?.('AltGraph') && `${mods}|c:${e.code}`,
20
+ typeof e.key === 'string' && `${mods}|k:${e.key.toLowerCase()}`,
21
+ ].filter(Boolean);
20
22
  }
21
23
 
22
24
  const claimSig = (c) => keySigs(c)[0];
@@ -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');