@ssebastien/tcmd 0.1.3 → 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 (134) hide show
  1. package/README.md +256 -62
  2. package/bin/tcmd +10 -2
  3. package/bin/tcmd.js +13 -2
  4. package/desktop/dist/index.html +13 -0
  5. package/desktop/dist/main.js +20298 -0
  6. package/desktop/dist/style.css +1515 -0
  7. package/desktop/frontend/index.html +13 -0
  8. package/package.json +19 -6
  9. package/public/fonts/OFL.txt +93 -0
  10. package/public/index.html +14 -0
  11. package/public/licenses/LUCIDE.txt +43 -0
  12. package/public/main.js +20679 -0
  13. package/public/style.css +1515 -0
  14. package/scripts/build-desktop.js +31 -0
  15. package/scripts/serve-web.js +61 -0
  16. package/src/js/tcmd/components/App.html +80 -14
  17. package/src/js/tcmd/components/App.js +339 -114
  18. package/src/js/tcmd/components/App.xml +76 -22
  19. package/src/js/tcmd/components/BookmarkList.html +5 -5
  20. package/src/js/tcmd/components/BookmarkList.js +15 -41
  21. package/src/js/tcmd/components/BookmarkList.xml +1 -2
  22. package/src/js/tcmd/components/BookmarkRow.html +2 -1
  23. package/src/js/tcmd/components/BookmarkRow.js +14 -9
  24. package/src/js/tcmd/components/BookmarkRow.xml +1 -1
  25. package/src/js/tcmd/components/Breadcrumbs.js +1 -1
  26. package/src/js/tcmd/components/CommandArgRow.html +28 -0
  27. package/src/js/tcmd/components/CommandArgRow.js +146 -30
  28. package/src/js/tcmd/components/CommandArgRow.xml +55 -4
  29. package/src/js/tcmd/components/CommandBar.html +2 -2
  30. package/src/js/tcmd/components/CommandBar.js +33 -27
  31. package/src/js/tcmd/components/CommandBar.xml +2 -2
  32. package/src/js/tcmd/components/CommandItem.html +1 -1
  33. package/src/js/tcmd/components/CommandItem.js +25 -25
  34. package/src/js/tcmd/components/CommandItem.xml +2 -2
  35. package/src/js/tcmd/components/CommandPanel.html +29 -0
  36. package/src/js/tcmd/components/CommandPanel.js +78 -52
  37. package/src/js/tcmd/components/CommandPanel.xml +49 -25
  38. package/src/js/tcmd/components/Confirm.html +2 -2
  39. package/src/js/tcmd/components/EntryDetail.html +7 -7
  40. package/src/js/tcmd/components/EntryDetail.js +22 -8
  41. package/src/js/tcmd/components/FileList.html +5 -1
  42. package/src/js/tcmd/components/FileList.js +2 -1
  43. package/src/js/tcmd/components/FilePicker.html +10 -0
  44. package/src/js/tcmd/components/FilePicker.js +43 -0
  45. package/src/js/tcmd/components/FilePicker.xml +13 -0
  46. package/src/js/tcmd/components/FilePickerRow.html +6 -0
  47. package/src/js/tcmd/components/FilePickerRow.js +27 -0
  48. package/src/js/tcmd/components/FilePickerRow.xml +10 -0
  49. package/src/js/tcmd/components/FilePreview.html +14 -4
  50. package/src/js/tcmd/components/FilePreview.js +111 -12
  51. package/src/js/tcmd/components/FilePreview.xml +28 -8
  52. package/src/js/tcmd/components/FileRow.html +2 -1
  53. package/src/js/tcmd/components/FileRow.js +70 -12
  54. package/src/js/tcmd/components/FilterBar.html +1 -1
  55. package/src/js/tcmd/components/FilterBar.js +14 -4
  56. package/src/js/tcmd/components/FilterBar.xml +1 -1
  57. package/src/js/tcmd/components/Frame.js +324 -0
  58. package/src/js/tcmd/components/Help.html +15 -0
  59. package/src/js/tcmd/components/Help.js +260 -0
  60. package/src/js/tcmd/components/Help.xml +13 -4
  61. package/src/js/tcmd/components/HelpRow.html +8 -0
  62. package/src/js/tcmd/components/HelpRow.xml +7 -0
  63. package/src/js/tcmd/components/OverlayList.html +8 -0
  64. package/src/js/tcmd/components/OverlayList.js +69 -0
  65. package/src/js/tcmd/components/{CommandPalette.xml → OverlayList.xml} +2 -5
  66. package/src/js/tcmd/components/OverlayRow.html +5 -0
  67. package/src/js/tcmd/components/OverlayRow.js +47 -0
  68. package/src/js/tcmd/components/OverlayRow.xml +9 -0
  69. package/src/js/tcmd/components/Summary.html +1 -1
  70. package/src/js/tcmd/components/Summary.js +1 -6
  71. package/src/js/tcmd/components/format.js +4 -23
  72. package/src/js/tcmd/components/icons.js +176 -5
  73. package/src/js/tcmd/components/index.js +9 -5
  74. package/src/js/tcmd/components/rows.js +176 -48
  75. package/src/js/tcmd/core/base64.js +64 -0
  76. package/src/js/tcmd/core/bookmarks.js +45 -8
  77. package/src/js/tcmd/core/commands.js +978 -260
  78. package/src/js/tcmd/core/concurrency.js +59 -0
  79. package/src/js/tcmd/core/decompress.js +117 -0
  80. package/src/js/tcmd/core/directory.js +219 -93
  81. package/src/js/tcmd/core/format.js +36 -0
  82. package/src/js/tcmd/core/fs.js +438 -54
  83. package/src/js/tcmd/core/history.js +58 -0
  84. package/src/js/tcmd/core/index.js +3 -9
  85. package/src/js/tcmd/core/journal.js +93 -0
  86. package/src/js/tcmd/core/keymap.js +42 -6
  87. package/src/js/tcmd/core/operations.js +813 -48
  88. package/src/js/tcmd/core/os.js +29 -3
  89. package/src/js/tcmd/core/pane.js +33 -8
  90. package/src/js/tcmd/core/panel.js +280 -104
  91. package/src/js/tcmd/core/path.js +30 -3
  92. package/src/js/tcmd/core/permissions.js +107 -0
  93. package/src/js/tcmd/core/picker.js +156 -0
  94. package/src/js/tcmd/core/preview.js +102 -0
  95. package/src/js/tcmd/core/script.js +7 -95
  96. package/src/js/tcmd/core/selection.js +9 -1
  97. package/src/js/tcmd/core/session.js +498 -200
  98. package/src/js/tcmd/core/watch.js +153 -0
  99. package/src/js/tcmd/desktop/backend/api.js +165 -0
  100. package/src/js/tcmd/desktop/backend/fs.js +626 -0
  101. package/src/js/tcmd/desktop/backend/main.ts +9 -0
  102. package/src/js/tcmd/desktop/bookmarks.js +23 -0
  103. package/src/js/tcmd/desktop/fs.js +91 -0
  104. package/src/js/tcmd/desktop/main.js +194 -0
  105. package/src/js/tcmd/desktop/os.js +33 -0
  106. package/src/js/tcmd/index.js +0 -1
  107. package/src/js/tcmd/tui/app.js +118 -60
  108. package/src/js/tcmd/tui/catalogue.js +238 -42
  109. package/src/js/tcmd/tui/index.js +18 -19
  110. package/src/js/tcmd/tui/opentui.js +33 -0
  111. package/src/js/tcmd/tui/syntax.js +91 -0
  112. package/src/js/tcmd/tui/theme.js +32 -2
  113. package/src/js/tcmd/vendor/bzip2.js +276 -0
  114. package/src/js/tcmd/web/app.js +225 -41
  115. package/src/js/tcmd/web/bookmarks.js +36 -0
  116. package/src/js/tcmd/web/catalogue.js +81 -38
  117. package/src/js/tcmd/web/effects.js +223 -0
  118. package/src/js/tcmd/web/header.html +1 -1
  119. package/src/js/tcmd/web/header.js +15 -11
  120. package/src/js/tcmd/web/http.js +13 -0
  121. package/src/js/tcmd/web/index.js +2 -2
  122. package/src/js/tcmd/web/main.js +6 -66
  123. package/src/js/tcmd/web/opfs.js +297 -30
  124. package/src/js/tcmd/web/seed.js +4 -4
  125. package/src/js/tcmd/web/server.js +124 -21
  126. package/src/js/tcmd/web/theme.js +4 -0
  127. package/tinyjs.json +16 -0
  128. package/src/js/tcmd/components/CommandPalette.html +0 -7
  129. package/src/js/tcmd/components/CommandPalette.js +0 -58
  130. package/src/js/tcmd/components/PaletteRow.html +0 -3
  131. package/src/js/tcmd/components/PaletteRow.js +0 -43
  132. package/src/js/tcmd/components/PaletteRow.xml +0 -4
  133. package/src/js/tcmd/tui/frame.js +0 -269
  134. package/src/js/tcmd/tui/help.js +0 -32
@@ -14,6 +14,7 @@ export { createNodeFs } from "./fs.js"
14
14
  export { createNullOs, createNodeOs } from "./os.js"
15
15
  export { filterEntries, rankEntries, sortEntries, viewEntries } from "./entries.js"
16
16
  export { clampCursor, currentEntry, moveCursor, toggleMark } from "./selection.js"
17
+ export { createHistory } from "./history.js"
17
18
  export { PANE_BUFFERS, PANE_LABELS, createPane } from "./pane.js"
18
19
  export { createDirectory } from "./directory.js"
19
20
  export {
@@ -26,14 +27,7 @@ export {
26
27
  export { DEFAULT_KEYMAP, matchKeymap } from "./keymap.js"
27
28
  export { createDispatch, getCommand, getCommands } from "./commands.js"
28
29
  export { expandAll, expandArg, decodePathToken, getOperation, getOperations, pathToken, runOperation } from "./operations.js"
29
- export {
30
- PANEL_FOCUS,
31
- argvFor,
32
- bindArgs,
33
- panelOperations,
34
- panelRowList,
35
- paneSelectionPaths,
36
- } from "./panel.js"
37
- export { parseLine, runLine, scriptItems, tokenize } from "./script.js"
30
+ export { PANEL_FOCUS, argvFor, bindArgs, panelEntries, panelRowList, paneSelectionPaths } from "./panel.js"
31
+ export { parseLine, runLine, tokenize } from "./script.js"
38
32
  export { createSession, load } from "./session.js"
39
33
  export { SEP, basename, extname, join, normalize, parent, prefix, split } from "./path.js"
@@ -0,0 +1,93 @@
1
+ // Project: TinyCommand
2
+ // Author: Sebastien Pierre
3
+ // License: BSD
4
+ // Created: 2026-10-17
5
+
6
+ // Module: tcmd/core/journal
7
+ // The undo/redo journal: an ordered list of applied file operations, each
8
+ // carrying an inverse (`undo`) and a forward (`redo`) action. `index` points at
9
+ // the last *applied* entry; entries after it are undone and can be redone.
10
+ // `record` appends and truncates any redo tail (a new action forks history), so
11
+ // the model is a plain linear history like a text editor's.
12
+ //
13
+ // Actions are closures over the paths an operation touched, so the journal is
14
+ // session-only (not persisted): a fresh session starts empty. `rows()` projects
15
+ // the entries for the history panel, marking which are applied and where the
16
+ // pointer sits.
17
+
18
+ import { cell } from "select/state/cells"
19
+
20
+ // Function: createJournal
21
+ // Creates an empty journal. `entries` is the ordered action list (oldest
22
+ // first); `index` is the last applied entry (-1 when nothing is applied).
23
+ function createJournal({ entries = [], index = -1 } = {}) {
24
+ const journal = {}
25
+ journal.entries = cell(entries.slice())
26
+ journal.index = cell(Math.min(index, entries.length - 1))
27
+ let sequence = entries.length
28
+
29
+ // Function: record
30
+ // Appends `entry` — `{ label, undo?, redo? }` — discarding any undone tail,
31
+ // and moves the pointer onto it. Returns the entry's id.
32
+ journal.record = (entry) => {
33
+ const kept = journal.entries.value.slice(0, journal.index.value + 1)
34
+ const recorded = { id: ++sequence, at: Date.now(), ...entry }
35
+ kept.push(recorded)
36
+ journal.entries.set(kept)
37
+ journal.index.set(kept.length - 1)
38
+ return recorded.id
39
+ }
40
+
41
+ // Function: canUndo / canRedo
42
+ journal.canUndo = () => journal.index.value >= 0
43
+ journal.canRedo = () => journal.index.value < journal.entries.value.length - 1
44
+
45
+ // Function: undo
46
+ // Runs the inverse of the entry at the pointer and steps back. Returns the
47
+ // entry, or null when there is nothing to undo.
48
+ journal.undo = async (session) => {
49
+ if (!journal.canUndo()) return null
50
+ const entry = journal.entries.value[journal.index.value]
51
+ await entry?.undo?.(session)
52
+ journal.index.set(journal.index.value - 1)
53
+ return entry
54
+ }
55
+
56
+ // Function: redo
57
+ // Re-applies the next undone entry and steps onto it. Returns the entry, or
58
+ // null when there is nothing to redo.
59
+ journal.redo = async (session) => {
60
+ if (!journal.canRedo()) return null
61
+ const next = journal.index.value + 1
62
+ const entry = journal.entries.value[next]
63
+ await entry?.redo?.(session)
64
+ journal.index.set(next)
65
+ return entry
66
+ }
67
+
68
+ // Function: goTo
69
+ // Undoes or redoes repeated until the pointer sits on `target` (-1 empties
70
+ // the applied set). Used by the history panel to jump to an entry.
71
+ journal.goTo = async (session, target) => {
72
+ while (journal.index.value > target && journal.canUndo()) await journal.undo(session)
73
+ while (journal.index.value < target && journal.canRedo()) await journal.redo(session)
74
+ }
75
+
76
+ // Function: rows
77
+ // Panel rows, oldest first: `{ id, label, at, index, applied, current }`.
78
+ journal.rows = () =>
79
+ journal.entries.value.map((entry, i) => ({
80
+ id: entry.id,
81
+ label: entry.label,
82
+ at: entry.at,
83
+ index: i,
84
+ applied: i <= journal.index.value,
85
+ current: i === journal.index.value,
86
+ }))
87
+
88
+ return journal
89
+ }
90
+
91
+ export { createJournal }
92
+
93
+ // EOF
@@ -26,18 +26,26 @@ const DEFAULT_KEYMAP = [
26
26
  { key: "tab", command: "pane.toggle" },
27
27
  { key: "tab", shift: true, command: "pane.toggle" },
28
28
  { key: "space", command: "list.mark" },
29
- { key: "b", command: "bookmark.record" },
30
- { key: "g", command: "bookmark.jump" },
31
- { key: "m", command: "panel.toggle" },
29
+ { key: "b", command: "bookmark.open" },
32
30
  { key: ":", command: "panel.open" },
33
- { key: "!", command: "palette.run" },
31
+ { key: "!", command: "panel.shell" },
34
32
  { key: "/", command: "filter.start" },
33
+ { key: "f5", command: "pane.reload" },
34
+ { key: "r", command: "pane.reload" },
35
35
  { key: "r", ctrl: true, command: "pane.reload" },
36
36
  { key: "v", command: "view.togglePreview" },
37
+ { key: "v", shift: true, command: "view.maximize" },
38
+ { key: "t", command: "view.toggleMode" },
39
+ { key: "t", shift: true, command: "trash.open" },
40
+ { key: "n", command: "file.mkdir" },
41
+ { key: "u", command: "history.open" },
42
+ { key: "z", ctrl: true, command: "history.undo" },
43
+ { key: "z", ctrl: true, shift: true, command: "history.redo" },
44
+ { key: "y", ctrl: true, command: "history.redo" },
37
45
  { key: "o", shift: true, command: "file.open" },
38
46
  { key: "e", shift: true, command: "file.edit" },
39
- { key: "p", ctrl: true, command: "palette.toggle" },
40
47
  { key: "q", command: "app.quit" },
48
+ { key: "?", command: "app.help" },
41
49
  ]
42
50
 
43
51
  // Function: matchKeymap
@@ -55,6 +63,34 @@ function matchKeymap(keymap, chord) {
55
63
  return null
56
64
  }
57
65
 
58
- export { DEFAULT_KEYMAP, matchKeymap }
66
+ // Function: keyGlyph
67
+ // Human-readable label for a keymap chord ("↑", "⇧Tab", "^W", "PgUp").
68
+ function keyGlyph(chord) {
69
+ const name = chord.key
70
+ const named = {
71
+ up: "↑",
72
+ down: "↓",
73
+ left: "←",
74
+ right: "→",
75
+ return: "↵",
76
+ enter: "↵",
77
+ space: "Space",
78
+ tab: "Tab",
79
+ pageup: "PgUp",
80
+ pagedown: "PgDn",
81
+ escape: "Esc",
82
+ backspace: "Bksp",
83
+ home: "Home",
84
+ end: "End",
85
+ f5: "F5",
86
+ }
87
+ let base = named[name] ?? (name.length === 1 ? name.toUpperCase() : `${name}`)
88
+ if (chord.ctrl) base = `^${base}`
89
+ if (chord.meta) base = `⌘${base}`
90
+ if (chord.shift) base = `⇧${base}`
91
+ return base
92
+ }
93
+
94
+ export { DEFAULT_KEYMAP, keyGlyph, matchKeymap }
59
95
 
60
96
  // EOF