@fiete/drift 1.0.3 → 1.0.4

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.
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  AddForm
4
- } from "./chunk-VCY3CRYL.js";
5
- import "./chunk-V6RC35DD.js";
4
+ } from "./chunk-ZMUIDCTO.js";
5
+ import "./chunk-CRXU4OLG.js";
6
6
  export {
7
7
  AddForm
8
8
  };
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  AddForm,
4
4
  useStore
5
- } from "./chunk-VCY3CRYL.js";
6
- import "./chunk-V6RC35DD.js";
5
+ } from "./chunk-ZMUIDCTO.js";
6
+ import "./chunk-CRXU4OLG.js";
7
7
 
8
8
  // src/ui/Browser.tsx
9
9
  import { useState as useState3, useCallback as useCallback2 } from "react";
@@ -470,13 +470,13 @@ function Browser({ onExecute, forceOnboarding = false }) {
470
470
  return;
471
471
  }
472
472
  if (key.return && selected) {
473
- const full = selected.directory ? `cd ${selected.directory} && ${selected.command}` : selected.command;
473
+ const full = selected.directory ? `cd "${selected.directory}" && ${selected.command}` : selected.command;
474
474
  onExecute(full);
475
475
  exit();
476
476
  return;
477
477
  }
478
478
  if (key.ctrl && input === "e" && selected) {
479
- const full = selected.directory ? `cd ${selected.directory} && ${selected.command}` : selected.command;
479
+ const full = selected.directory ? `cd "${selected.directory}" && ${selected.command}` : selected.command;
480
480
  clipboard.writeSync(full);
481
481
  flash("Copied!");
482
482
  return;
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  FileStore
4
- } from "./chunk-V6RC35DD.js";
4
+ } from "./chunk-CRXU4OLG.js";
5
5
  export {
6
6
  FileStore
7
7
  };
@@ -30,6 +30,9 @@ var FileStore = class {
30
30
  getAll() {
31
31
  return this.data.commands;
32
32
  }
33
+ getById(id) {
34
+ return this.data.commands.find((c) => c.id === id);
35
+ }
33
36
  addCommand(input) {
34
37
  const now = (/* @__PURE__ */ new Date()).toISOString();
35
38
  const cmd = { ...input, id: nanoid(), createdAt: now, updatedAt: now };
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  FileStore
4
- } from "./chunk-V6RC35DD.js";
4
+ } from "./chunk-CRXU4OLG.js";
5
5
 
6
6
  // src/ui/AddForm.tsx
7
7
  import { useState as useState2, useCallback as useCallback2 } from "react";
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import React from "react";
7
7
  import { execa } from "execa";
8
8
  program.name("drift").description("cmdvault \u2014 A TUI command vault for your shell").version("1.0.0");
9
9
  program.command("list", { isDefault: true }).description("Browse saved commands (default)").option("--onboarding", "Force the onboarding screen (debug)").action(async (opts) => {
10
- const { Browser } = await import("./Browser-UPOZVAV4.js");
10
+ const { Browser } = await import("./Browser-GYSQENKK.js");
11
11
  let commandToRun;
12
12
  const { waitUntilExit } = render(
13
13
  React.createElement(Browser, {
@@ -25,19 +25,20 @@ program.command("list", { isDefault: true }).description("Browse saved commands
25
25
  }
26
26
  process.exit(0);
27
27
  });
28
- program.command("add [command]").description("Add a command. Pass it as a quoted argument, or open the interactive form.").option("-d, --desc <description>", "Description for the command").option("-t, --tags <tags>", "Comma-separated tags").addHelpText("after", '\nExamples:\n drift add "git log --oneline -20"\n drift add "cd /project && npm run dev" --desc "Start dev server" --tags "node,dev"\n drift add (opens interactive form)').action(async (command, opts) => {
28
+ program.command("add [command]").description("Add a command. Pass it as a quoted argument, or open the interactive form.").option("-d, --desc <description>", "Description for the command").option("-t, --tags <tags>", "Comma-separated tags").option("--dir <directory>", "Working directory").addHelpText("after", '\nExamples:\n drift add "git log --oneline -20"\n drift add "cd /project && npm run dev" --desc "Start dev server" --tags "node,dev"\n drift add (opens interactive form)').action(async (command, opts) => {
29
29
  if (command && opts.desc !== void 0 && opts.tags !== void 0) {
30
- const { FileStore } = await import("./FileStore-VX4RYNIH.js");
30
+ const { FileStore } = await import("./FileStore-5LGMICIM.js");
31
31
  const store = new FileStore();
32
32
  store.addCommand({
33
33
  command: command.trim(),
34
34
  description: opts.desc.trim(),
35
- tags: opts.tags.split(",").map((t) => t.trim()).filter(Boolean)
35
+ tags: opts.tags.split(",").map((t) => t.trim()).filter(Boolean),
36
+ directory: opts.dir?.trim() || void 0
36
37
  });
37
38
  console.log("Saved!");
38
39
  process.exit(0);
39
40
  }
40
- const { AddForm } = await import("./AddForm-BXHHRR2V.js");
41
+ const { AddForm } = await import("./AddForm-R45F2RCQ.js");
41
42
  const initialValues = {
42
43
  command: command ?? "",
43
44
  description: opts.desc ?? "",
@@ -50,7 +51,7 @@ program.command("add [command]").description("Add a command. Pass it as a quoted
50
51
  process.exit(0);
51
52
  });
52
53
  program.command("remove <id>").description("Remove a command by ID").action(async (id) => {
53
- const { FileStore } = await import("./FileStore-VX4RYNIH.js");
54
+ const { FileStore } = await import("./FileStore-5LGMICIM.js");
54
55
  const store = new FileStore();
55
56
  const removed = store.removeCommand(id);
56
57
  if (removed) {
@@ -60,4 +61,112 @@ program.command("remove <id>").description("Remove a command by ID").action(asyn
60
61
  process.exit(1);
61
62
  }
62
63
  });
64
+ program.command("ls").description("List all saved commands").option("--json", "Output as JSON").action(async (opts) => {
65
+ const { FileStore } = await import("./FileStore-5LGMICIM.js");
66
+ const store = new FileStore();
67
+ const commands = store.getAll();
68
+ if (opts.json) {
69
+ console.log(JSON.stringify(commands, null, 2));
70
+ } else {
71
+ if (commands.length === 0) {
72
+ console.log("No commands saved yet. Run `drift add` to add one.");
73
+ } else {
74
+ for (const cmd of commands) {
75
+ const tags = cmd.tags.length ? ` [${cmd.tags.join(", ")}]` : "";
76
+ console.log(`${cmd.id} ${cmd.description}${tags}`);
77
+ console.log(` ${cmd.command}`);
78
+ if (cmd.directory) console.log(` dir: ${cmd.directory}`);
79
+ }
80
+ }
81
+ }
82
+ process.exit(0);
83
+ });
84
+ program.command("search <query>").description("Search saved commands (fuzzy)").option("--json", "Output as JSON").action(async (query, opts) => {
85
+ const { FileStore } = await import("./FileStore-5LGMICIM.js");
86
+ const { searchCommands } = await import("./search-HZEMV67M.js");
87
+ const store = new FileStore();
88
+ const results = searchCommands(store.getAll(), query);
89
+ if (opts.json) {
90
+ console.log(JSON.stringify(results, null, 2));
91
+ } else {
92
+ if (results.length === 0) {
93
+ console.log(`No commands matching "${query}"`);
94
+ } else {
95
+ for (const cmd of results) {
96
+ const tags = cmd.tags.length ? ` [${cmd.tags.join(", ")}]` : "";
97
+ console.log(`${cmd.id} ${cmd.description}${tags}`);
98
+ console.log(` ${cmd.command}`);
99
+ if (cmd.directory) console.log(` dir: ${cmd.directory}`);
100
+ }
101
+ }
102
+ }
103
+ process.exit(0);
104
+ });
105
+ program.command("get <id>").description("Get a single command by ID").option("--json", "Output as JSON").action(async (id, opts) => {
106
+ const { FileStore } = await import("./FileStore-5LGMICIM.js");
107
+ const store = new FileStore();
108
+ const cmd = store.getById(id);
109
+ if (!cmd) {
110
+ console.error(`No command found with ID: ${id}`);
111
+ process.exit(1);
112
+ }
113
+ if (opts.json) {
114
+ console.log(JSON.stringify(cmd, null, 2));
115
+ } else {
116
+ const tags = cmd.tags.length ? ` [${cmd.tags.join(", ")}]` : "";
117
+ console.log(`${cmd.id} ${cmd.description}${tags}`);
118
+ console.log(` ${cmd.command}`);
119
+ if (cmd.directory) console.log(` dir: ${cmd.directory}`);
120
+ }
121
+ process.exit(0);
122
+ });
123
+ program.command("execute <id>").description("Execute a saved command by ID").action(async (id) => {
124
+ const { FileStore } = await import("./FileStore-5LGMICIM.js");
125
+ const store = new FileStore();
126
+ const cmd = store.getById(id);
127
+ if (!cmd) {
128
+ console.error(`No command found with ID: ${id}`);
129
+ process.exit(1);
130
+ }
131
+ const toRun = cmd.directory ? `cd "${cmd.directory}" && ${cmd.command}` : cmd.command;
132
+ await execa(toRun, { shell: true, stdio: "inherit" }).catch(() => process.exit(1));
133
+ process.exit(0);
134
+ });
135
+ program.command("copy <id>").description("Copy a saved command to the clipboard").action(async (id) => {
136
+ const { FileStore } = await import("./FileStore-5LGMICIM.js");
137
+ const { default: clipboardy } = await import("clipboardy");
138
+ const store = new FileStore();
139
+ const cmd = store.getById(id);
140
+ if (!cmd) {
141
+ console.error(`No command found with ID: ${id}`);
142
+ process.exit(1);
143
+ }
144
+ await clipboardy.write(cmd.command);
145
+ console.log(`Copied: ${cmd.command}`);
146
+ process.exit(0);
147
+ });
148
+ program.command("edit <id>").description("Edit a saved command by ID").option("-c, --command <command>", "New command string").option("-d, --desc <description>", "New description").option("-t, --tags <tags>", "New comma-separated tags").option("--dir <directory>", "New working directory").option("--json", "Output updated command as JSON").action(async (id, opts) => {
149
+ const { FileStore } = await import("./FileStore-5LGMICIM.js");
150
+ const store = new FileStore();
151
+ const patch = {};
152
+ if (opts.command !== void 0) patch.command = opts.command.trim();
153
+ if (opts.desc !== void 0) patch.description = opts.desc.trim();
154
+ if (opts.tags !== void 0) patch.tags = opts.tags.split(",").map((t) => t.trim()).filter(Boolean);
155
+ if (opts.dir !== void 0) patch.directory = opts.dir.trim() || void 0;
156
+ if (Object.keys(patch).length === 0) {
157
+ console.error("No fields to update. Use --command, --desc, --tags, or --dir.");
158
+ process.exit(1);
159
+ }
160
+ const updated = store.updateCommand(id, patch);
161
+ if (!updated) {
162
+ console.error(`No command found with ID: ${id}`);
163
+ process.exit(1);
164
+ }
165
+ if (opts.json) {
166
+ console.log(JSON.stringify(store.getById(id), null, 2));
167
+ } else {
168
+ console.log(`Updated command ${id}`);
169
+ }
170
+ process.exit(0);
171
+ });
63
172
  program.parse();
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/search.ts
4
+ import Fuse from "fuse.js";
5
+ var FUSE_OPTIONS = {
6
+ keys: [
7
+ { name: "command", weight: 0.5 },
8
+ { name: "description", weight: 0.3 },
9
+ { name: "tags", weight: 0.2 }
10
+ ],
11
+ threshold: 0.35,
12
+ includeScore: false,
13
+ minMatchCharLength: 1,
14
+ shouldSort: true
15
+ };
16
+ function searchCommands(commands, query) {
17
+ if (!query.trim()) return commands;
18
+ const fuse = new Fuse(commands, FUSE_OPTIONS);
19
+ return fuse.search(query).map((r) => r.item);
20
+ }
21
+ export {
22
+ searchCommands
23
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fiete/drift",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "A TUI command vault for your shell",
5
5
  "type": "module",
6
6
  "preferGlobal": true,