@ssebastien/tcmd 0.1.4 → 0.1.7

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.
Files changed (105) hide show
  1. package/README.md +169 -58
  2. package/desktop/dist/index.html +13 -0
  3. package/desktop/dist/main.js +20298 -0
  4. package/desktop/dist/style.css +1515 -0
  5. package/desktop/frontend/index.html +13 -0
  6. package/package.json +17 -5
  7. package/public/fonts/OFL.txt +93 -0
  8. package/public/licenses/LUCIDE.txt +43 -0
  9. package/public/main.js +5066 -1888
  10. package/public/style.css +660 -46
  11. package/scripts/build-desktop.js +31 -0
  12. package/src/js/tcmd/components/App.html +56 -6
  13. package/src/js/tcmd/components/App.js +233 -58
  14. package/src/js/tcmd/components/App.xml +27 -22
  15. package/src/js/tcmd/components/BookmarkList.html +4 -5
  16. package/src/js/tcmd/components/BookmarkList.js +14 -40
  17. package/src/js/tcmd/components/BookmarkList.xml +1 -2
  18. package/src/js/tcmd/components/BookmarkRow.html +2 -1
  19. package/src/js/tcmd/components/BookmarkRow.js +14 -9
  20. package/src/js/tcmd/components/BookmarkRow.xml +1 -1
  21. package/src/js/tcmd/components/CommandArgRow.html +18 -7
  22. package/src/js/tcmd/components/CommandArgRow.js +100 -44
  23. package/src/js/tcmd/components/CommandArgRow.xml +39 -15
  24. package/src/js/tcmd/components/CommandBar.html +1 -1
  25. package/src/js/tcmd/components/CommandBar.js +31 -25
  26. package/src/js/tcmd/components/CommandBar.xml +2 -2
  27. package/src/js/tcmd/components/CommandItem.js +24 -25
  28. package/src/js/tcmd/components/CommandItem.xml +2 -2
  29. package/src/js/tcmd/components/CommandPanel.html +13 -13
  30. package/src/js/tcmd/components/CommandPanel.js +57 -33
  31. package/src/js/tcmd/components/CommandPanel.xml +30 -20
  32. package/src/js/tcmd/components/Confirm.html +2 -2
  33. package/src/js/tcmd/components/EntryDetail.js +21 -7
  34. package/src/js/tcmd/components/FilePicker.html +10 -0
  35. package/src/js/tcmd/components/FilePicker.js +43 -0
  36. package/src/js/tcmd/components/FilePicker.xml +13 -0
  37. package/src/js/tcmd/components/FilePickerRow.html +6 -0
  38. package/src/js/tcmd/components/FilePickerRow.js +27 -0
  39. package/src/js/tcmd/components/FilePickerRow.xml +10 -0
  40. package/src/js/tcmd/components/FilePreview.html +1 -2
  41. package/src/js/tcmd/components/FilePreview.js +40 -4
  42. package/src/js/tcmd/components/FilePreview.xml +17 -10
  43. package/src/js/tcmd/components/FileRow.html +1 -0
  44. package/src/js/tcmd/components/FileRow.js +60 -9
  45. package/src/js/tcmd/components/Frame.js +57 -31
  46. package/src/js/tcmd/components/Help.html +12 -4
  47. package/src/js/tcmd/components/Help.js +198 -47
  48. package/src/js/tcmd/components/Help.xml +13 -4
  49. package/src/js/tcmd/components/HelpRow.html +8 -0
  50. package/src/js/tcmd/components/HelpRow.xml +7 -0
  51. package/src/js/tcmd/components/OverlayList.html +8 -0
  52. package/src/js/tcmd/components/OverlayList.js +69 -0
  53. package/src/js/tcmd/components/OverlayList.xml +13 -0
  54. package/src/js/tcmd/components/OverlayRow.html +5 -0
  55. package/src/js/tcmd/components/OverlayRow.js +47 -0
  56. package/src/js/tcmd/components/OverlayRow.xml +9 -0
  57. package/src/js/tcmd/components/format.js +4 -23
  58. package/src/js/tcmd/components/icons.js +137 -0
  59. package/src/js/tcmd/components/index.js +8 -3
  60. package/src/js/tcmd/components/rows.js +149 -25
  61. package/src/js/tcmd/core/base64.js +64 -0
  62. package/src/js/tcmd/core/bookmarks.js +45 -8
  63. package/src/js/tcmd/core/commands.js +612 -136
  64. package/src/js/tcmd/core/concurrency.js +59 -0
  65. package/src/js/tcmd/core/decompress.js +117 -0
  66. package/src/js/tcmd/core/directory.js +81 -5
  67. package/src/js/tcmd/core/format.js +36 -0
  68. package/src/js/tcmd/core/fs.js +410 -53
  69. package/src/js/tcmd/core/journal.js +93 -0
  70. package/src/js/tcmd/core/keymap.js +39 -3
  71. package/src/js/tcmd/core/operations.js +735 -63
  72. package/src/js/tcmd/core/os.js +29 -3
  73. package/src/js/tcmd/core/pane.js +4 -2
  74. package/src/js/tcmd/core/panel.js +179 -93
  75. package/src/js/tcmd/core/path.js +30 -3
  76. package/src/js/tcmd/core/permissions.js +107 -0
  77. package/src/js/tcmd/core/picker.js +156 -0
  78. package/src/js/tcmd/core/preview.js +102 -0
  79. package/src/js/tcmd/core/session.js +286 -116
  80. package/src/js/tcmd/core/watch.js +153 -0
  81. package/src/js/tcmd/desktop/backend/api.js +165 -0
  82. package/src/js/tcmd/desktop/backend/fs.js +626 -0
  83. package/src/js/tcmd/desktop/backend/main.ts +9 -0
  84. package/src/js/tcmd/desktop/bookmarks.js +23 -0
  85. package/src/js/tcmd/desktop/fs.js +91 -0
  86. package/src/js/tcmd/desktop/main.js +194 -0
  87. package/src/js/tcmd/desktop/os.js +33 -0
  88. package/src/js/tcmd/tui/app.js +111 -74
  89. package/src/js/tcmd/tui/catalogue.js +232 -23
  90. package/src/js/tcmd/tui/index.js +18 -4
  91. package/src/js/tcmd/tui/opentui.js +33 -0
  92. package/src/js/tcmd/tui/syntax.js +91 -0
  93. package/src/js/tcmd/tui/theme.js +27 -2
  94. package/src/js/tcmd/vendor/bzip2.js +276 -0
  95. package/src/js/tcmd/web/app.js +114 -56
  96. package/src/js/tcmd/web/catalogue.js +41 -4
  97. package/src/js/tcmd/web/effects.js +94 -14
  98. package/src/js/tcmd/web/header.html +1 -1
  99. package/src/js/tcmd/web/http.js +13 -0
  100. package/src/js/tcmd/web/index.js +2 -2
  101. package/src/js/tcmd/web/opfs.js +297 -30
  102. package/src/js/tcmd/web/seed.js +1 -1
  103. package/src/js/tcmd/web/server.js +118 -17
  104. package/src/js/tcmd/web/theme.js +3 -0
  105. package/tinyjs.json +16 -0
package/README.md CHANGED
@@ -15,29 +15,68 @@ TinyCommand `tcmd` is a midnight-commander-like CLI and desktop tool:
15
15
  the two-pane commander (the left is the source, the right the destination),
16
16
  with `t` toggling between the two views. Clicking any column, preview
17
17
  included, gives it the focus.
18
- - Named bookmarks: `b` records the cursor entry (or the pane directory) under
19
- a name defaulting to its basename, remembering whether it is a file or a
20
- directory; `g` opens a fzf-style picker over bookmark names and paths. A
21
- directory bookmark opens to show its contents, a file bookmark is selected
22
- and previewed in its directory.
23
- - Operations over the current panes: copy, move, delete/erase, stat, touch,
24
- selection buffers, edit/view/open and shell commands
18
+ - Named bookmarks: `b` opens one bookmarks panel. Type to filter the stored
19
+ bookmarks by name or path; when the filter is empty and the cursor entry (or
20
+ the pane directory) is not bookmarked yet, a first row adds it under a
21
+ basename-derived name. `Enter` opens the selected bookmark, `⌫`/`Delete`
22
+ removes it. A directory bookmark opens to show its contents, a file bookmark
23
+ is selected and previewed in its directory.
24
+ - Undo/redo (`⌃Z` / `⌃⇧Z` or `⌃Y`) over recorded filesystem changes (mkdir,
25
+ copies to new destinations, move, rename, trashed delete), with a history list
26
+ (`u`); a delete reports the trash directory it used and can be undone or
27
+ restored from the trash browser
28
+ (`⇧T`), which lists trashed entries by their original path. A double click on
29
+ a row opens it like `Enter`.
30
+ - Operations over the current panes: copy, move, mkdir/new, hardlink/symlink,
31
+ chmod/chown, delete/erase/unlink, stat, du/df, touch, selection buffers,
32
+ edit/view/open and shell commands; `abspath` and `realpath` show
33
+ copy-pasteable absolute paths and copy them to the clipboard, with the latter
34
+ following symlinks. `unlink` removes links only, never their targets.
25
35
  - Command panel (`:`), the one entry point, a two-pane palette: the left pane
26
- filters (`:xxx`) over the CLI operations (copy, move, rename, delete… — the
27
- internal TinyCmd actions live on their own keys, not the panel). The right
28
- pane lists the selected command's arguments under its name — each row an
29
- aligned label and its value in a boxed field (a text field to fill in), or a
30
- checkbox (multiple) / radio (single) list of the selected paths wrapped in its
31
- own border, with a lone path shown read-only — and the resolved command at its
32
- foot. `Tab` cycles the filter and the argument rows; `Enter` runs a complete
33
- command or jumps to the next missing argument. `!` lands straight on the shell
36
+ filters (`:xxx`) over CLI operations grouped by purpose: **Command**,
37
+ **File**, **Info**, **Create**, **Edit** (amber), and **Delete** (red). The
38
+ Command group also has the workspace-view toggle and Quit; File's `view`
39
+ previews the selected path; Info holds `stat`, `du` and `df`; amber Edit also
40
+ holds `copy` and the metadata changes. Bold section
41
+ titles head indented command names, alphabetized within each category. The right
42
+ pane lists the selected command's arguments under its name — editable values
43
+ use filled fields, while read-only values are plain and muted; `new`/`mkdir`
44
+ show the current `PATH` above a `NAME`, and `chmod`/`chown` list `PATH`
45
+ first. Selections use
46
+ a checkbox (multiple) / radio (single)
47
+ list of the selected paths wrapped in its own border, with a lone path shown
48
+ read-only. `chmod`'s `MODE` is a compact u/g/o grid of clickable R/W/X cells
49
+ (arrow keys move between cells, Space toggles), seeded from the selected
50
+ file's current mode. Labels and values sit one space in from the pane border
51
+ (` PATH`, ` [value]`), and `[Run]` follows the last field after a
52
+ blank line, aligned left in the command category's color. Amber (Edit) and
53
+ red (Delete) actions take two steps: the first Run turns the action into
54
+ `[Confirm]` and prints the command below it in the risk colour, the second
55
+ executes. A failed run shows `[Retry]` with a framed error block below it,
56
+ while a
57
+ successful result briefly replaces the command bar at the bottom. A selection
58
+ argument draws from the *focused* column, so in the explorer focusing the parent mirror
59
+ selects the directory under its cursor. `Tab` cycles the filter, arguments and
60
+ Run button; `Enter` runs a complete command or jumps to the next missing
61
+ argument, and a `[Close Esc]` close button sits in the dialog's top border,
62
+ upper right. `!` lands straight on the shell
34
63
  command. A destination/path argument browses the filesystem in a file picker
35
- (`⌃O`): explorer mode has no destination pane, so a move or copy there asks
36
- where to. A `rename` operation replaces a literal `FIND` with `REPLACE` across
37
- the selection — one file replaces its whole name — previewing each
38
- `old → new` before it runs.
64
+ (`⌃O`): its path is editable as a string, the matching entries sit below and
65
+ render like a file panel (icons, aligned sizes, scrollbar), with `..` pinned
66
+ at the top. Explorer mode has no destination pane, so a move or copy there
67
+ asks where to. A `replace` operation replaces a literal `FIND` with `REPLACE`
68
+ across the selection — one file replaces its whole name — previewing each
69
+ `old → new` mapping before it runs. Exact `rename FROM TO PATH` renames one named
70
+ child inside `PATH`.
39
71
  - Keyboard and mouse navigation, inline file previews — a previewed directory
40
- renders as a pane (its breadcrumbs over its own listing), in both views
72
+ renders as a pane (its breadcrumbs over its own listing), in both views, a
73
+ source file highlights with tree-sitter (JavaScript, TypeScript, Markdown and
74
+ Zig today) through the same `code` renderable, and an image draws in place
75
+ through the terminal's graphics protocol (Kitty/sixel, half-block fallback),
76
+ the metadata card staying for formats with no decoder. `.gz` and `.bz2`
77
+ entries preview their decompressed contents: the inner name drives the kind
78
+ and highlighter (`notes.txt.gz` heads as `<GZ · TXT>`), and a body that
79
+ decompresses to binary stays a card
41
80
  - Symlinks are shown *and* followed: a link row prints `name -> target`
42
81
  (`notes.md -> notes.txt`, `docs/ -> ../shared`), a link to a directory is a
43
82
  directory (it sorts, opens and previews as one), and the preview reads
@@ -67,47 +106,61 @@ bun run tcmd # open cwd (left) and ~ (right)
67
106
  bun run tcmd /tmp ~ # open specific directories
68
107
  ```
69
108
 
70
- Keys: `↑/↓` move (`^↑/^↓` jump a few lines), `Enter/→` open (re-entering a
71
- directory restores the cursor it was left with), `←/Bksp` parent (the cursor
109
+ Keys: `↑/↓` move (`^↑/^↓` jump a few lines), `Enter/→` open (a directory
110
+ re-opens with the cursor it was left with, a text file opens in `$EDITOR`, and
111
+ anything that cannot be edited — an image, media, a binary, or any file on a
112
+ host with no editor — opens the fullscreen viewer), `←/Bksp` parent (the cursor
72
113
  lands on the directory you left), `Esc`/`⇧Esc` history back/forward, `Tab`/`⇧Tab` switch panes
73
114
  (`⇧Tab` goes back), `t` toggle the commander/explorer view, `Space` mark, `b`
74
- bookmark the cursor entry (or the pane
75
- directory) under a basename-defaulted name, `g` jump to a bookmark, `:` open the
76
- command panel (the one entry point: CLI operations and TinyCmd actions, their
77
- arguments, the live resolved command, and the inline file picker on `⌃O`), `v` preview (fullscreen viewer when
115
+ open the bookmarks panel (filter, add the current path, `Enter` open,
116
+ `⌫`/`Del` remove), `:` open the
117
+ command panel (the one entry point for CLI operations, grouped by risk with
118
+ editable arguments, an explicit Run button and the inline file picker on `⌃O`),
119
+ `v` preview (fullscreen viewer when
78
120
  the terminal is narrow), `⇧V` maximize the preview over the columns and back
79
- again, `O`/`E` open/edit the previewed file, `/` fuzzy-filter
121
+ again (in either full view, `↑`/`↓` scroll a file preview and `←`/`→` step to
122
+ the previous/next entry), `O`/`E` open/edit the previewed file, `/` fuzzy-filter
80
123
  the active pane (`Enter` keeps it, `Esc` clears), `!` open the panel on the
81
- shell command, `^R` reload, `?` key reference, `q` quit.
124
+ shell command, `F5`/`r`/`^R` reload, `?` key reference, `q` quit.
125
+
126
+ Listings refresh themselves when the filesystem changes: the TUI and desktop
127
+ views watch the displayed directories natively, while the web view polls them
128
+ every few seconds. Hidden columns pause their watcher and re-read when shown.
129
+ A refresh keeps the selected entry selected, so files written by other
130
+ programs appear without moving the cursor. The keys above (and the web toolbar
131
+ button) remain for a forced re-read.
82
132
 
83
133
  The workspace opens in explorer mode with a slim identity bar (`TinyCmd -
84
134
  HOST`) — the view mode and version trailing at its right, the mode word drawn
85
135
  letter by letter along the logo's own gradients (`explorer` in the Tiny blues,
86
- `commander` in the Cmd oranges) and the version dim after it — over an
136
+ `commander` in the Cmd oranges, clicking it toggles the view) and the version
137
+ dim after it — over an
87
138
  unframed tiling of pane boxes (the two middle edges sit side by side) labelled
88
139
  **SRC** (left, source) / **DST** (right, destination) in commander, with a
89
140
  header row (label + clickable breadcrumbs — collapsed to first letters like
90
141
  `/h/s/W/Perso/tcmd` when the width demands — + the inline filter) separated by a
91
- rule from the listing, an entry-detail line for the selected entry, and one
92
- summary row, so the columns stay aligned. The detail line shows
142
+ rule from the listing, and an entry-detail line for the selected entry. The
143
+ detail line shows
93
144
  `date · type · size · rights` with the rights right-aligned, the date and size
94
- bright, and the size/rights dropping out when the pane is too narrow; the
95
- summary row is indented to match. The active pane's border and header
96
- rule are highlighted and its cursor row uses the strong cursor colour, while
97
- the inactive pane stays dim with a muted cursor. Rows lead with a yazi-style
145
+ bright, and the size/rights dropping out when the pane is too narrow. The active
146
+ pane's border and header rule take the view mode's colour — the Tiny blue in
147
+ explorer, the gold accent in commander — and its cursor row uses the strong
148
+ cursor colour, while
149
+ the inactive pane stays dim with a muted cursor. TUI rows lead with a yazi-style
98
150
  Nerd Font icon (folder/link kind icons plus a per-extension icon, `Makefile`,
99
- `Dockerfile` and dotfiles included), on unless `TCMD_ICONS=0` — it needs a
100
- Nerd-Font-patched terminal font, and the web view never shows icons. The
101
- command panel marks its entries the same way — a glyph in the TUI, a `cli`/`app`
102
- tag on the web. A
151
+ `Dockerfile` and dotfiles included), on unless `TCMD_ICONS=0`; it needs a
152
+ Nerd-Font-patched terminal font. The web and desktop views use local Lucide SVG
153
+ icons for toolbar actions, file kinds, bookmarks, and Help key badges; command
154
+ panel entries show a chevron to indicate their argument pane. A
103
155
  context-aware inspector sits
104
156
  on the right when the terminal is at least 100 columns wide, and becomes a
105
157
  fullscreen viewer below that; `⇧V` expands it over the whole pane row —
106
158
  parent and current included — and brings the previous layout back on the next
107
- press. The status bar lists every binding as a bracket
108
- shorthand (`[Open ⏎]`) wrapping over as many rows as the width demands — the
109
- marked count trails the list, and a notice or error swaps the keys for a
110
- one-line status. Below 64×16
159
+ press. The status bar keeps its fixed bracket shorthands on one line
160
+ (`[Commands :]`, `[Mark Spc]`, `[Filter /]`, `[Switch ⇥]`, `[Bookmarks b]`,
161
+ `[Toggle Mode t]`, `[Help ?]`) and elides entries behind `…` when the width
162
+ runs out — the marked count trails the list, and a notice or error swaps the
163
+ keys for a one-line status. Below 64×16
111
164
  the app shows a resize hint instead of the workspace.
112
165
 
113
166
  ### View modes
@@ -182,12 +235,67 @@ only supports OPFS); the server binds to loopback by default (`HOST`
182
235
  overrides it) and requires a per-process token injected into `index.html`.
183
236
  `TCMD_WEB_ROOT=/some/dir` confines the API
184
237
  (default `/`, the same access as `bun run tcmd`), but it is not a sandbox:
185
- don't expose the port. With OPFS, deleting moves entries to `/.trash`; the API
186
- uses the desktop trash. Open/edit/run are unavailable in the browser either
187
- way (the null host adapter reports it in the command bar); everything else —
188
- navigation, marks, scripting, copy/move/erase — works on either
238
+ don't expose the port. Symlinks that resolve outside the root are rejected;
239
+ root and destination checks are not race-proof against another local process
240
+ changing the filesystem during a request. With OPFS, deleting moves entries to `/.trash`;
241
+ the API uses the desktop trash. OPFS coordination across tabs uses Web Locks
242
+ when available; without them, writes are coordinated per adapter only.
243
+ Open/edit/run are unavailable in the browser
244
+ either way (the null host adapter reports it in the command bar); everything
245
+ else — navigation, marks, scripting, copy/move/erase — works on either
189
246
  backend. `public/index.html` is the host page; `public/main.js` is generated.
190
247
 
248
+ ### Desktop app (tinyjs)
249
+
250
+ The native desktop target reuses the web presentation and shared session, but
251
+ uses a tinyjs backend for real filesystem access. It runs without Bun/Node in
252
+ the shipped app and does not start an HTTP server or open a port.
253
+
254
+ Install [tinyjs](https://tinyjs.app/) and the project dependencies, then run:
255
+
256
+ ```sh
257
+ bun install
258
+ bun run desktop:dev # bundle the webview UI, then open the native window
259
+ bun run desktop:build # tinyjs build; emits a platform-native app/package
260
+ ```
261
+
262
+ `tinyjs.json` configures the app. `tinyjs build` bundles the desktop frontend
263
+ through `desktop:bundle`; the source page is `desktop/frontend/index.html`.
264
+ For frontend changes during development, rerun `bun run desktop:bundle` before
265
+ reloading the window. The desktop uses the system webview and requires tinyjs
266
+ 0.57.0 or newer.
267
+
268
+ The desktop window keeps the native title bar, hides the native menu, and uses
269
+ an in-app toolbar for folder navigation, refresh, view/preview toggles, commands
270
+ and help. Its toolbar replaces the TinyCmd identity header; the browser UI keeps
271
+ that header. Press F6 to move focus between the workspace and toolbar; toolbar
272
+ buttons use native Tab/Enter/Space keys, and Escape returns to the workspace.
273
+
274
+ The web UI uses the system sans-serif font for controls and chrome, with the
275
+ M+1Code Nerd Font Mono bundled for filenames, paths, and file content. The
276
+ font is from Nerd Fonts v3.5.1 and is distributed under SIL OFL 1.1; its license
277
+ is included in `public/fonts/OFL.txt`.
278
+ The UI icons are from Lucide and distributed under ISC (with the listed Feather
279
+ icons under MIT); the license is included in `public/licenses/LUCIDE.txt`.
280
+
281
+ On Linux, the tinyjs launcher also needs the Ayatana AppIndicator runtime. On
282
+ Fedora install it with `sudo dnf install libayatana-appindicator-gtk3`; on
283
+ Debian/Ubuntu use `sudo apt install libayatana-appindicator3-1`. Install the
284
+ WebKitGTK runtime required by tinyjs as well.
285
+
286
+ Filesystem operations are performed by the backend using txiki.js APIs. Text
287
+ files open in the operating system's default editor; `!` / shell commands run
288
+ in a non-interactive shell and display captured output in a native dialog.
289
+ Trash uses the Freedesktop trash under `$XDG_DATA_HOME` (or
290
+ `~/.local/share/Trash`), including undo/restore. The current desktop adapter
291
+ supports POSIX paths on Linux and macOS. Windows drive/UNC paths are not yet
292
+ supported; the app reports this rather than attempting file operations.
293
+
294
+ The desktop backend has full access to the current user's files, and the
295
+ command panel intentionally exposes shell execution. Treat commands and
296
+ filesystem prompts accordingly. Browser and TUI builds remain separate and
297
+ continue to use their existing backends.
298
+
191
299
  ## Architecture
192
300
 
193
301
  MVC with a presentation-agnostic core, so a web UI can share the same model
@@ -204,7 +312,7 @@ src/js/tcmd/
204
312
  directory.js one pane's directory: path, entries, view, cursor, marks
205
313
  pane.js one directory, proxying its cells + currentPane resolution
206
314
  bookmarks.js named bookmarks (path + file/dir kind) + the memory/file stores
207
- panel.js command panel: CLI ops + TinyCmd actions, args bound from context
315
+ panel.js grouped CLI command panel, with arguments bound from context
208
316
  session.js two panes + parent/preview mirrors, view mode, active pane, preview, panel, dispatch
209
317
  keymap.js key chords -> command ids
210
318
  commands.js command registry; commands are `run(session, payload)`
@@ -217,7 +325,7 @@ src/js/tcmd/
217
325
  FileList.js … one `.js` per component (behaviors + pure helpers)
218
326
  FileRow.js … row behaviors shared by both engines
219
327
  Frame.js workspace chrome, breakpoints and command-bar geometry
220
- Help.js key-reference overlay behaviors + the grouped key text
328
+ Help.js key-reference overlay behaviors + the two-column key text
221
329
  format.js presentation helpers (sizes/counts)
222
330
  tui/ View (select.tui templates on OpenTUI)
223
331
  app.js binds App.js + App.xml + TUI environment; size/help cells
@@ -258,8 +366,9 @@ of use.
258
366
 
259
367
  `components/Frame.js` holds the renderer-free workspace chrome (brand bar,
260
368
  responsive breakpoints, pane borders, command-bar geometry) and
261
- `components/Help.js` holds the key reference — behaviours and the grouped key
262
- text — used by both views. Web-only components live under `web/` (`header.js` +
369
+ `components/Help.js` holds the key reference — behaviours and the two-column
370
+ key text, with every distinct keymap chord shown in the command bar's bracket
371
+ style — used by both views. Web-only components live under `web/` (`header.js` +
263
372
  `header.html`, plus the DOM effects in `effects.js` and the bookmark store in
264
373
  `bookmarks.js`). Shared
265
374
  behaviors only ever grow additively (a new key for a new presentation),
@@ -288,8 +397,8 @@ Decoupling rules:
288
397
  see `src/js/tcmd/vendor/`)
289
398
  - Bun as the runtime
290
399
 
291
- `deps/` symlinks to sibling checkouts; `scripts/link-deps.sh` (run as
292
- postinstall) re-links `node_modules` so upstream edits propagate.
400
+ `deps/` symlinks to sibling checkouts; run `scripts/link-deps.sh` after
401
+ `bun install` to re-link `node_modules` so upstream edits propagate.
293
402
 
294
403
  ## Tests
295
404
 
@@ -307,12 +416,14 @@ tests run the shared logic through select.js on a happy-dom document.
307
416
  bar, command panel, text preview
308
417
  - [x] File operations (copy/move/delete/erase/stat/touch/sel), with the
309
418
  `$A`/`$B` pane filesets and `$FILE` still resolving in any argument
310
- - [x] Unified command panel (`:`): the CLI operations and the TinyCmd actions in
311
- one filtered list, each marked by its namespace, with editable arguments
312
- and a resolved-command preview; `!` lands on the shell command
419
+ - [x] Grouped command panel (`:`): white / amber / red risk sections, editable
420
+ arguments, an explicit Run action and an inline picker; `!` lands on shell
313
421
  - [x] Pane fuzzy filtering (`/` to filter, `Enter` to keep, `Esc` to clear)
314
- - [x] Named bookmarks (`b` records, `g` jumps, persisted to a JSON file)
422
+ - [x] Named bookmarks (`b` opens the panel to add, filter, open or remove them,
423
+ persisted to a JSON file)
315
424
  - [ ] Quick find, grep
316
- - [ ] Image/PDF/audio/video previews
425
+ - [x] Image previews (terminal graphics protocol) and tree-sitter source
426
+ highlighting in the inspector
427
+ - [ ] PDF/audio/video previews
317
428
  - [x] Web view on the same core (shared components rendered by select.js)
318
429
  - [x] Pane navigation history (`Esc`/`⇧Esc` back/forward)
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>TinyCommand</title>
7
+ <link rel="stylesheet" href="./style.css" />
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="./main.js"></script>
12
+ </body>
13
+ </html>