shellwise 0.2.5 → 0.2.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.
package/README.md CHANGED
@@ -34,10 +34,13 @@ Tab/Shift+Tab to navigate, Enter to select, Esc to dismiss
34
34
  > **Important:** This is a CLI tool — install it **globally**.
35
35
 
36
36
  ```bash
37
- # Recommended
37
+ # Homebrew
38
+ brew install kurovu146/tap/shellwise
39
+
40
+ # Bun
38
41
  bun install -g shellwise
39
42
 
40
- # Or with npm
43
+ # npm
41
44
  npm install -g shellwise
42
45
  ```
43
46
 
@@ -55,6 +58,19 @@ eval "$(shellwise init zsh)"
55
58
  eval "$(shellwise init bash)"
56
59
  ```
57
60
 
61
+ ## Update
62
+
63
+ ```bash
64
+ # Homebrew
65
+ brew upgrade shellwise
66
+
67
+ # Bun
68
+ bun install -g shellwise@latest
69
+
70
+ # npm
71
+ npm install -g shellwise@latest
72
+ ```
73
+
58
74
  ## Usage
59
75
 
60
76
  ### Auto-suggest (while typing)
@@ -87,12 +103,14 @@ Both `shellwise` and `sw` work as the command name:
87
103
  ```bash
88
104
  shellwise search [--query <text>] # Interactive fuzzy search (Ctrl+R)
89
105
  shellwise suggest --query <text> # Get top suggestion (used by shell hook)
90
- shellwise add --command <cmd> # Save a command to history
106
+ shellwise add <cmd> # Save a command to history
107
+ shellwise delete [query] # Interactive search & delete a command
91
108
  shellwise init <zsh|bash> # Output shell integration script
92
109
  shellwise import [zsh|bash] # Import existing shell history
93
110
  shellwise stats # Show usage statistics
94
111
  shellwise prune --days <n> # Remove entries older than n days
95
112
  shellwise daemon start|stop|status # Manage background daemon
113
+ shellwise version # Show current version
96
114
  ```
97
115
 
98
116
  ### Import existing history
@@ -139,8 +157,14 @@ shellwise import bash # Import from ~/.bash_history
139
157
  ## Uninstall
140
158
 
141
159
  ```bash
160
+ # Homebrew
161
+ brew uninstall shellwise
162
+
163
+ # Bun
142
164
  bun remove -g shellwise
143
- # or: npm uninstall -g shellwise
165
+
166
+ # npm
167
+ npm uninstall -g shellwise
144
168
  ```
145
169
 
146
170
  Shell integration is automatically removed on uninstall. If you still see errors after uninstalling, manually remove these lines from your `~/.zshrc` (or `~/.bashrc`):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shellwise",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Smart command history with inline auto-suggest and fuzzy search for your terminal",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli/add.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { insertCommand } from "../db/queries";
2
2
  import { getHostname } from "../utils/platform";
3
- import { IGNORED_COMMANDS } from "../utils/constants";
4
3
 
5
4
  interface AddOptions {
6
5
  command: string;
@@ -14,7 +13,7 @@ interface AddOptions {
14
13
  export function runAdd(opts: AddOptions): void {
15
14
  const cmd = opts.command.trim();
16
15
 
17
- // Skip empty, very short, or ignored commands
16
+ // Skip empty or very short commands
18
17
  if (!cmd || cmd.length < 2) return;
19
18
 
20
19
  // Skip commands starting with space (convention)
@@ -23,10 +22,6 @@ export function runAdd(opts: AddOptions): void {
23
22
  // Only save successful commands (exit code 0)
24
23
  if (opts.exitCode !== undefined && opts.exitCode !== 0) return;
25
24
 
26
- // Skip ignored commands (only the base command, not arguments)
27
- const baseCmd = cmd.split(/\s+/)[0];
28
- if (IGNORED_COMMANDS.has(baseCmd)) return;
29
-
30
25
  insertCommand({
31
26
  command: cmd,
32
27
  cwd: opts.cwd,
package/src/cli/search.ts CHANGED
@@ -25,7 +25,7 @@ interface SearchState {
25
25
  renderedLines: number;
26
26
  }
27
27
 
28
- export function runSearch(initialQuery: string = ""): void {
28
+ export function pickCommand(initialQuery: string = ""): string | null {
29
29
  const cwd = process.env.PWD || process.cwd();
30
30
 
31
31
  const state: SearchState = {
@@ -78,22 +78,18 @@ export function runSearch(initialQuery: string = ""): void {
78
78
 
79
79
  if (key.type === "special" && key.key === "escape") {
80
80
  cleanup();
81
- return;
81
+ return null;
82
82
  }
83
83
 
84
84
  if (key.type === "ctrl" && key.char === "c") {
85
85
  cleanup();
86
- return;
86
+ return null;
87
87
  }
88
88
 
89
89
  if (key.type === "special" && key.key === "enter") {
90
90
  const selected = state.results[state.selectedIndex];
91
91
  cleanup();
92
- if (selected) {
93
- // Output to stdout (fd 1) for shell to capture
94
- writeSync(1, selected.command);
95
- }
96
- return;
92
+ return selected?.command ?? null;
97
93
  }
98
94
 
99
95
  let needsSearch = false;
@@ -197,6 +193,13 @@ export function runSearch(initialQuery: string = ""): void {
197
193
  }
198
194
  }
199
195
 
196
+ export function runSearch(initialQuery: string = ""): void {
197
+ const selected = pickCommand(initialQuery);
198
+ if (selected) {
199
+ writeSync(1, selected);
200
+ }
201
+ }
202
+
200
203
  function getVisibleCount(): number {
201
204
  const { rows } = getTerminalSize();
202
205
  return Math.min(Math.max(rows - 4, 3), 15); // 3 minimum, 15 max
@@ -2,7 +2,6 @@ import { getDb, closeDb } from "../db/connection";
2
2
  import { insertCommand } from "../db/queries";
3
3
  import { getHostname } from "../utils/platform";
4
4
  import { getCommonSuggestions } from "../data/common-commands";
5
- import { IGNORED_COMMANDS } from "../utils/constants";
6
5
  import { parseRequest, getSocketPath, getPidPath, getDaemonPort } from "./protocol";
7
6
  import { unlinkSync, writeFileSync, existsSync } from "fs";
8
7
  import type { Socket } from "bun";
@@ -95,9 +94,6 @@ function handleRequest(raw: string): string {
95
94
  const cmd = req.command.trim();
96
95
  if (!cmd || cmd.length < 2 || cmd.startsWith(" ")) return "OK\n\n";
97
96
  if (req.exitCode !== 0) return "OK\n\n"; // Only save successful commands
98
- const baseCmd = cmd.split(/\s+/)[0];
99
- if (IGNORED_COMMANDS.has(baseCmd)) return "OK\n\n";
100
-
101
97
  insertCommand({
102
98
  command: cmd,
103
99
  cwd: req.cwd || undefined,
package/src/db/queries.ts CHANGED
@@ -166,6 +166,16 @@ export function pruneOlderThan(days: number): number {
166
166
  return result.changes;
167
167
  }
168
168
 
169
+ export function deleteCommand(command: string): boolean {
170
+ const db = getDb();
171
+ const hash = hashCommand(command);
172
+
173
+ const result = db.run("DELETE FROM commands WHERE command_hash = ?", [hash]);
174
+ db.run("DELETE FROM command_stats WHERE command_hash = ?", [hash]);
175
+
176
+ return result.changes > 0;
177
+ }
178
+
169
179
  export function getExistingHashes(): Set<string> {
170
180
  const db = getDb();
171
181
  const rows = db
package/src/index.ts CHANGED
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
3
  import { runAdd } from "./cli/add";
4
- import { runSearch } from "./cli/search";
4
+ import { runSearch, pickCommand } from "./cli/search";
5
5
  import { runSuggest } from "./cli/suggest";
6
6
  import { runInit } from "./cli/init";
7
7
  import { runImport } from "./cli/import";
8
8
  import { runStats } from "./cli/stats";
9
9
  import { runPrune } from "./cli/prune";
10
+ import { deleteCommand } from "./db/queries";
10
11
  import { closeDb } from "./db/connection";
11
12
  import { startServer, isDaemonRunning, getDaemonInfo } from "./daemon/server";
12
13
  import { daemonRequest } from "./daemon/client";
@@ -34,12 +35,14 @@ Usage: shellwise <command> [options] (or: sw <command>)
34
35
  Commands:
35
36
  search [--query <text>] Interactive fuzzy search (Ctrl+R)
36
37
  suggest --query <text> Get top suggestion (used by shell hook)
37
- add --command <cmd> Save a command to history
38
+ add <cmd> Save a command to history
39
+ delete <cmd> Delete a command from history
38
40
  init <zsh|bash> Output shell integration script
39
41
  import [zsh|bash] Import existing shell history
40
42
  stats Show usage statistics
41
43
  prune --days <n> Remove entries older than n days
42
44
  daemon start|stop|status Manage background daemon (faster suggest)
45
+ version Show current version
43
46
 
44
47
  Setup:
45
48
  Add to ~/.zshrc: eval "$(shellwise init zsh)"
@@ -79,20 +82,21 @@ async function main(): Promise<void> {
79
82
 
80
83
  case "add": {
81
84
  const flags = parseFlags(args.slice(1));
82
- if (!flags.command) {
83
- console.error("Usage: shellwise add --command <cmd>");
85
+ const addCmd = flags.command || args.slice(1).filter(a => !a.startsWith("--")).join(" ");
86
+ if (!addCmd) {
87
+ console.error("Usage: shellwise add <cmd>");
84
88
  process.exit(1);
85
89
  }
86
90
 
87
91
  // Try daemon first
88
92
  // Strip tabs from command to avoid breaking protocol delimiter
89
- const safeCommand = flags.command.replace(/\t/g, " ");
93
+ const safeCommand = addCmd.replace(/\t/g, " ");
90
94
  const addMsg = `ADD\t${safeCommand}\t${flags.cwd || ""}\t${flags["exit-code"] || "0"}\t${flags.duration || "0"}\t${flags.session || ""}\t${flags.shell || ""}\n`;
91
95
  const addResult = await daemonRequest(addMsg);
92
96
  if (!addResult) {
93
97
  // Fallback: direct
94
98
  runAdd({
95
- command: flags.command,
99
+ command: addCmd,
96
100
  cwd: flags.cwd,
97
101
  exitCode: flags["exit-code"] ? parseInt(flags["exit-code"]) : undefined,
98
102
  duration: flags.duration ? parseInt(flags.duration) : undefined,
@@ -185,6 +189,28 @@ async function main(): Promise<void> {
185
189
  break;
186
190
  }
187
191
 
192
+ case "delete": {
193
+ const delQuery = args.slice(1).join(" ");
194
+ const delCmd = pickCommand(delQuery);
195
+ if (delCmd) {
196
+ const deleted = deleteCommand(delCmd);
197
+ if (deleted) {
198
+ console.log(`Deleted: ${delCmd}`);
199
+ } else {
200
+ console.log("Command not found in history.");
201
+ }
202
+ }
203
+ break;
204
+ }
205
+
206
+ case "version":
207
+ case "--version":
208
+ case "-v": {
209
+ const pkg = require("../package.json");
210
+ console.log(pkg.version);
211
+ break;
212
+ }
213
+
188
214
  case "help":
189
215
  case "--help":
190
216
  case "-h":
@@ -1 +0,0 @@
1
- export const IGNORED_COMMANDS = new Set(["ls", "cd", "pwd", "exit", "clear", "sw"]);