@arthony/keybook 0.8.0 → 0.8.1

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 (2) hide show
  1. package/dist/cli.js +35 -6
  2. package/package.json +21 -33
package/dist/cli.js CHANGED
@@ -1030,6 +1030,35 @@ function fieldValue(d, focused) {
1030
1030
  return "";
1031
1031
  }
1032
1032
  //#endregion
1033
+ //#region src/tui/useTerminalSize.ts
1034
+ /**
1035
+ * The terminal's current size, re-read whenever stdout fires `resize`.
1036
+ *
1037
+ * Ink reacts to a resize by re-running Yoga layout and repainting, but it
1038
+ * never re-renders React, so any width or height computed from
1039
+ * `stdout.columns`/`stdout.rows` during render would stay frozen at the last
1040
+ * keystroke. Holding the size in state turns a resize into a render.
1041
+ */
1042
+ function useTerminalSize() {
1043
+ const { stdout } = useStdout();
1044
+ const [size, setSize] = useState(() => ({
1045
+ columns: stdout?.columns,
1046
+ rows: stdout?.rows
1047
+ }));
1048
+ useEffect(() => {
1049
+ if (!stdout) return;
1050
+ const onResize = () => setSize({
1051
+ columns: stdout.columns,
1052
+ rows: stdout.rows
1053
+ });
1054
+ stdout.on("resize", onResize);
1055
+ return () => {
1056
+ stdout.off("resize", onResize);
1057
+ };
1058
+ }, [stdout]);
1059
+ return size;
1060
+ }
1061
+ //#endregion
1033
1062
  //#region src/tui/AddEntryForm.tsx
1034
1063
  const TYPES = [
1035
1064
  "shortcut",
@@ -1039,7 +1068,7 @@ const TYPES = [
1039
1068
  const LAST_FIELD = 5;
1040
1069
  function AddEntryForm({ apps, existingTags, onSubmit, onComplete, onCancel, resolveTarget, initial, initialFocus, title }) {
1041
1070
  const { draft, update, setDraft } = useAddForm(initial ?? { app: apps[0] ?? "" });
1042
- const { stdout } = useStdout();
1071
+ const { columns } = useTerminalSize();
1043
1072
  const [focused, setFocused] = useState(initialFocus ?? 0);
1044
1073
  const [pos, setPos] = useState(() => [...fieldValue(draft, initialFocus ?? 0)].length);
1045
1074
  const [stepCursor, setStepCursor] = useState(initial?.steps?.length ?? 0);
@@ -1401,7 +1430,7 @@ function AddEntryForm({ apps, existingTags, onSubmit, onComplete, onCancel, reso
1401
1430
  appIndex,
1402
1431
  focused,
1403
1432
  pos,
1404
- width: formFieldWidth(stdout?.columns),
1433
+ width: formFieldWidth(columns),
1405
1434
  existingTags,
1406
1435
  stepCursor,
1407
1436
  grabbed,
@@ -1757,7 +1786,7 @@ function SearchInput({ query, pos, width, filterLabel }) {
1757
1786
  const sameApp = (a, b) => a.trim().toLowerCase() === b.trim().toLowerCase();
1758
1787
  function App({ entries: initial, errorCount = 0, dataDir, onCopy = copyToClipboard }) {
1759
1788
  const { exit } = useApp();
1760
- const { stdout } = useStdout();
1789
+ const { columns, rows } = useTerminalSize();
1761
1790
  const [entries, setEntries] = useState(initial);
1762
1791
  const [mode, setMode] = useState("search");
1763
1792
  const [filter, setFilter] = useState({ type: "all" });
@@ -1786,8 +1815,8 @@ function App({ entries: initial, errorCount = 0, dataDir, onCopy = copyToClipboa
1786
1815
  const sel = results.length ? Math.min(selected, results.length - 1) : 0;
1787
1816
  const current = results[sel];
1788
1817
  currentRef.current = current;
1789
- const listHeight = visibleListHeight(stdout?.rows);
1790
- const { left, right } = columnWidths(stdout?.columns);
1818
+ const listHeight = visibleListHeight(rows);
1819
+ const { left, right } = columnWidths(columns);
1791
1820
  useInput((input, key) => {
1792
1821
  if (key.ctrl && input === "c") {
1793
1822
  exit();
@@ -1919,7 +1948,7 @@ function App({ entries: initial, errorCount = 0, dataDir, onCopy = copyToClipboa
1919
1948
  /* @__PURE__ */ jsx(SearchInput, {
1920
1949
  query: query.text,
1921
1950
  pos: query.pos,
1922
- width: searchFieldWidth(stdout?.columns, filterLabelText?.length ?? 0),
1951
+ width: searchFieldWidth(columns, filterLabelText?.length ?? 0),
1923
1952
  filterLabel: filterLabelText
1924
1953
  }),
1925
1954
  /* @__PURE__ */ jsxs(Box, { children: [/* @__PURE__ */ jsx(ResultList, {
package/package.json CHANGED
@@ -1,9 +1,7 @@
1
1
  {
2
2
  "name": "@arthony/keybook",
3
- "version": "0.8.0",
4
- "publishConfig": {
5
- "access": "public"
6
- },
3
+ "version": "0.8.1",
4
+ "publishConfig": { "access": "public" },
7
5
  "description": "A macOS TUI for searching keyboard shortcuts and recipes of your favorite apps",
8
6
  "keywords": [
9
7
  "cli",
@@ -17,27 +15,23 @@
17
15
  "productivity"
18
16
  ],
19
17
  "homepage": "https://github.com/Ariyapong/keybook#readme",
20
- "repository": {
21
- "type": "git",
22
- "url": "git+https://github.com/Ariyapong/keybook.git"
23
- },
24
- "bugs": {
25
- "url": "https://github.com/Ariyapong/keybook/issues"
26
- },
18
+ "repository": { "type": "git", "url": "git+https://github.com/Ariyapong/keybook.git" },
19
+ "bugs": { "url": "https://github.com/Ariyapong/keybook/issues" },
27
20
  "author": "Ariyapong Wimolnoch",
28
21
  "type": "module",
29
- "bin": {
30
- "keybook": "dist/cli.js",
31
- "kb": "dist/cli.js"
32
- },
33
- "files": [
34
- "dist",
35
- "seed",
36
- "README.md",
37
- "LICENSE"
38
- ],
39
- "engines": {
40
- "node": ">=22"
22
+ "bin": { "keybook": "dist/cli.js", "kb": "dist/cli.js" },
23
+ "files": ["dist", "seed", "README.md", "LICENSE"],
24
+ "engines": { "node": ">=22" },
25
+ "scripts": {
26
+ "build": "tsdown",
27
+ "dev": "tsx src/cli.ts",
28
+ "test": "vitest run",
29
+ "test:watch": "vitest",
30
+ "typecheck": "tsc --noEmit",
31
+ "lint": "biome check .",
32
+ "format": "biome format --write .",
33
+ "prepublishOnly": "pnpm build",
34
+ "bump-tap": "./scripts/bump-tap.sh"
41
35
  },
42
36
  "dependencies": {
43
37
  "commander": "^12.1.0",
@@ -58,14 +52,8 @@
58
52
  "vitest": "^2.1.0"
59
53
  },
60
54
  "license": "MIT",
61
- "scripts": {
62
- "build": "tsdown",
63
- "dev": "tsx src/cli.ts",
64
- "test": "vitest run",
65
- "test:watch": "vitest",
66
- "typecheck": "tsc --noEmit",
67
- "lint": "biome check .",
68
- "format": "biome format --write .",
69
- "bump-tap": "./scripts/bump-tap.sh"
55
+ "packageManager": "pnpm@10.25.0",
56
+ "pnpm": {
57
+ "onlyBuiltDependencies": ["@biomejs/biome", "esbuild"]
70
58
  }
71
- }
59
+ }