shellwise 0.2.6 → 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
@@ -103,12 +103,14 @@ Both `shellwise` and `sw` work as the command name:
103
103
  ```bash
104
104
  shellwise search [--query <text>] # Interactive fuzzy search (Ctrl+R)
105
105
  shellwise suggest --query <text> # Get top suggestion (used by shell hook)
106
- 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
107
108
  shellwise init <zsh|bash> # Output shell integration script
108
109
  shellwise import [zsh|bash] # Import existing shell history
109
110
  shellwise stats # Show usage statistics
110
111
  shellwise prune --days <n> # Remove entries older than n days
111
112
  shellwise daemon start|stop|status # Manage background daemon
113
+ shellwise version # Show current version
112
114
  ```
113
115
 
114
116
  ### Import existing history
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shellwise",
3
- "version": "0.2.6",
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/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
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":