@fiete/drift 1.0.3 → 1.0.5
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/dist/{AddForm-BXHHRR2V.js → AddForm-NVOWLCPV.js} +2 -2
- package/dist/{Browser-UPOZVAV4.js → Browser-6Q6XF5D4.js} +4 -4
- package/dist/{FileStore-VX4RYNIH.js → FileStore-5LGMICIM.js} +1 -1
- package/dist/{chunk-V6RC35DD.js → chunk-CRXU4OLG.js} +3 -0
- package/dist/{chunk-VCY3CRYL.js → chunk-GUH6BVED.js} +4 -4
- package/dist/index.js +115 -6
- package/dist/search-HZEMV67M.js +23 -0
- package/package.json +1 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import {
|
|
3
3
|
AddForm,
|
|
4
4
|
useStore
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-GUH6BVED.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 && selected.command ? `cd "${selected.directory}" && ${selected.command}` : selected.directory ? `cd "${selected.directory}"` : 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 && selected.command ? `cd "${selected.directory}" && ${selected.command}` : selected.directory ? `cd "${selected.directory}"` : selected.command;
|
|
480
480
|
clipboard.writeSync(full);
|
|
481
481
|
flash("Copied!");
|
|
482
482
|
return;
|
|
@@ -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-
|
|
4
|
+
} from "./chunk-CRXU4OLG.js";
|
|
5
5
|
|
|
6
6
|
// src/ui/AddForm.tsx
|
|
7
7
|
import { useState as useState2, useCallback as useCallback2 } from "react";
|
|
@@ -53,7 +53,7 @@ var FIELD_ORDER = ["description", "command", "directory", "tags"];
|
|
|
53
53
|
var LABELS = {
|
|
54
54
|
description: "Description",
|
|
55
55
|
command: "Command",
|
|
56
|
-
directory: "Directory
|
|
56
|
+
directory: "Directory",
|
|
57
57
|
tags: "Tags (comma-separated)"
|
|
58
58
|
};
|
|
59
59
|
var PLACEHOLDERS = {
|
|
@@ -104,8 +104,8 @@ function AddForm({ initialValues, onSave, onCancel }) {
|
|
|
104
104
|
if (fieldIndex < FIELD_ORDER.length - 1) {
|
|
105
105
|
setFieldIndex((i) => i + 1);
|
|
106
106
|
} else {
|
|
107
|
-
if (!updated.command.trim()) {
|
|
108
|
-
|
|
107
|
+
if (!updated.command.trim() && !updated.directory.trim()) {
|
|
108
|
+
setFieldIndex(1);
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
111
111
|
addCommand({
|
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-
|
|
10
|
+
const { Browser } = await import("./Browser-6Q6XF5D4.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-
|
|
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-
|
|
41
|
+
const { AddForm } = await import("./AddForm-NVOWLCPV.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-
|
|
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 && cmd.command ? `cd "${cmd.directory}" && ${cmd.command}` : cmd.directory ? `cd "${cmd.directory}"` : 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
|
+
};
|