@devkitvault/recall 1.2.7 → 1.2.10
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 +35 -39
- package/dist/commands/ask.js +15 -2
- package/dist/commands/delete.js +9 -25
- package/dist/commands/import.js +155 -45
- package/dist/commands/list.js +33 -52
- package/dist/commands/pin.js +10 -16
- package/dist/commands/run.js +23 -37
- package/dist/commands/save.js +49 -52
- package/dist/commands/search.js +31 -46
- package/dist/commands/sync.js +92 -54
- package/dist/commands/upgrade.js +5 -6
- package/dist/commands/whoami.js +7 -8
- package/dist/lib/config.js +1 -1
- package/dist/lib/local-vault.js +251 -0
- package/dist/lib/shell-history.js +239 -0
- package/package.json +4 -5
package/dist/commands/run.js
CHANGED
|
@@ -8,48 +8,34 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
8
8
|
const child_process_1 = require("child_process");
|
|
9
9
|
const commander_1 = require("commander");
|
|
10
10
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
11
|
-
const
|
|
12
|
-
const api_1 = require("../lib/api");
|
|
13
|
-
const auth_1 = require("../lib/auth");
|
|
11
|
+
const local_vault_1 = require("../lib/local-vault");
|
|
14
12
|
exports.runCommand = new commander_1.Command('run')
|
|
15
|
-
.description('Run a saved command by name
|
|
16
|
-
.argument('<name>', 'Command name
|
|
13
|
+
.description('Run a saved local command by name')
|
|
14
|
+
.argument('<name>', 'Command name')
|
|
17
15
|
.option('-d, --dry-run', 'Print command without running it')
|
|
18
16
|
.option('-c, --confirm', 'Ask for confirmation before running')
|
|
19
17
|
.action(async (name, opts) => {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
const cmd = (0, local_vault_1.findLocalByName)(name);
|
|
19
|
+
if (!cmd) {
|
|
20
|
+
console.log(chalk_1.default.red(`\n Command "${name}" not found in local vault.\n`));
|
|
21
|
+
console.log(chalk_1.default.dim(' List: recall list'));
|
|
22
|
+
console.log(chalk_1.default.dim(' Sync from cloud (Pro): recall sync\n'));
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
console.log(chalk_1.default.dim(`\n $ ${cmd.command}\n`));
|
|
26
|
+
if (opts.dryRun)
|
|
27
|
+
return;
|
|
28
|
+
if (opts.confirm) {
|
|
29
|
+
const { ok } = await inquirer_1.default.prompt([{
|
|
30
|
+
type: 'confirm',
|
|
31
|
+
name: 'ok',
|
|
32
|
+
message: 'Run this command?',
|
|
33
|
+
default: true,
|
|
34
|
+
}]);
|
|
35
|
+
if (!ok) {
|
|
36
|
+
console.log(chalk_1.default.dim(' Cancelled.\n'));
|
|
34
37
|
return;
|
|
35
|
-
// Confirm if --confirm flag or command has confirm flag
|
|
36
|
-
if (opts.confirm) {
|
|
37
|
-
const { ok } = await inquirer_1.default.prompt([{
|
|
38
|
-
type: 'confirm',
|
|
39
|
-
name: 'ok',
|
|
40
|
-
message: 'Run this command?',
|
|
41
|
-
default: true,
|
|
42
|
-
}]);
|
|
43
|
-
if (!ok) {
|
|
44
|
-
console.log(chalk_1.default.dim(' Cancelled.\n'));
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
38
|
}
|
|
48
|
-
// Log the run
|
|
49
|
-
api_1.ApiClient.post(`/commands/${cmd.id}/run`, {}, token).catch(() => { });
|
|
50
|
-
(0, child_process_1.execSync)(cmd.command, { stdio: 'inherit' });
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
spinner.fail(chalk_1.default.red(`Command "${name}" not found`));
|
|
54
39
|
}
|
|
40
|
+
(0, child_process_1.execSync)(cmd.command, { stdio: 'inherit' });
|
|
55
41
|
});
|
package/dist/commands/save.js
CHANGED
|
@@ -6,68 +6,65 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.saveCommand = void 0;
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const commander_1 = require("commander");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
9
|
+
const shell_history_1 = require("../lib/shell-history");
|
|
10
|
+
const tags_1 = require("../lib/tags");
|
|
11
|
+
const local_vault_1 = require("../lib/local-vault");
|
|
12
12
|
exports.saveCommand = new commander_1.Command('save')
|
|
13
|
-
.description('Save a command to your vault')
|
|
14
|
-
.argument('
|
|
13
|
+
.description('Save a command to your local vault (no account required)')
|
|
14
|
+
.argument('[command]', 'The shell command to save (omit when using --last)')
|
|
15
|
+
.option('-L, --last', 'Save the last command from your shell history')
|
|
15
16
|
.option('-n, --name <name>', 'Short memorable name')
|
|
16
17
|
.option('-t, --tags <tags>', 'Comma-separated tags')
|
|
17
|
-
.option('-g, --group <group>', '
|
|
18
|
-
.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
.option('-g, --group <group>', 'Group (Pro / cloud — ignored for local save)')
|
|
19
|
+
.addHelpText('after', `
|
|
20
|
+
Examples:
|
|
21
|
+
$ recall save "docker compose up -d" -n start-stack -t docker
|
|
22
|
+
$ recall save --last
|
|
23
|
+
$ recall save --last -n start-stack -t docker
|
|
24
|
+
|
|
25
|
+
Saves to the local vault (~/.recall/commands.json). No login required.
|
|
26
|
+
Sync to the cloud with Pro: recall auth login && recall sync
|
|
27
|
+
|
|
28
|
+
--last reads zsh/bash/PowerShell history (not cmd.exe).
|
|
29
|
+
Bash tip: if the command is missing, run: history -a && recall save --last
|
|
30
|
+
`)
|
|
31
|
+
.action(async (commandArg, opts) => {
|
|
32
|
+
let command = commandArg?.trim();
|
|
33
|
+
if (opts.last) {
|
|
34
|
+
if (command) {
|
|
35
|
+
console.log(chalk_1.default.yellow(' Ignoring the command argument because --last was set.'));
|
|
36
|
+
}
|
|
24
37
|
try {
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
38
|
+
const last = (0, shell_history_1.getLastShellCommand)();
|
|
39
|
+
command = last.command;
|
|
40
|
+
console.log(chalk_1.default.dim(` From ${last.shell} history: ${command}`));
|
|
28
41
|
}
|
|
29
42
|
catch (err) {
|
|
30
|
-
if (err instanceof
|
|
31
|
-
|
|
32
|
-
console.log(chalk_1.default.yellow('\n Groups require a Pro plan.'));
|
|
33
|
-
console.log(chalk_1.default.dim(' Run: recall upgrade\n'));
|
|
34
|
-
process.exit(1);
|
|
35
|
-
}
|
|
36
|
-
if (err instanceof api_1.ApiError && err.status === 404) {
|
|
37
|
-
// Auto-create the group
|
|
38
|
-
spinner.text = `Creating group "${opts.group}"...`;
|
|
39
|
-
try {
|
|
40
|
-
const newGroup = await api_1.ApiClient.post('/groups', { name: opts.group }, token);
|
|
41
|
-
groupId = newGroup.id;
|
|
42
|
-
spinner.succeed(chalk_1.default.green(`Created group "${opts.group}"`));
|
|
43
|
-
}
|
|
44
|
-
catch (createErr) {
|
|
45
|
-
spinner.fail(chalk_1.default.red(`Failed to create group "${opts.group}"`));
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
spinner.fail(chalk_1.default.red(`Failed to look up group "${opts.group}"`));
|
|
43
|
+
if (err instanceof shell_history_1.LastCommandError) {
|
|
44
|
+
console.log(chalk_1.default.red(`\n ${err.message}\n`));
|
|
51
45
|
process.exit(1);
|
|
52
46
|
}
|
|
47
|
+
throw err;
|
|
53
48
|
}
|
|
54
49
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
groupId,
|
|
62
|
-
}, token);
|
|
63
|
-
spinner.succeed(chalk_1.default.green(`Saved${saved.name ? ` as "${saved.name}"` : ''}` +
|
|
64
|
-
(opts.group ? chalk_1.default.dim(` → group "${opts.group}"`) : '')));
|
|
50
|
+
if (!command) {
|
|
51
|
+
console.log(chalk_1.default.red('\n Provide a command, or use --last to take it from shell history.\n'));
|
|
52
|
+
console.log(chalk_1.default.dim(' Examples:'));
|
|
53
|
+
console.log(chalk_1.default.dim(' recall save "docker compose up -d"'));
|
|
54
|
+
console.log(chalk_1.default.dim(' recall save --last\n'));
|
|
55
|
+
process.exit(1);
|
|
65
56
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
console.log(chalk_1.default.yellow('\n This feature requires an upgrade.'));
|
|
70
|
-
console.log(chalk_1.default.dim(` Upgrade at ${chalk_1.default.white(err.body.upgrade)}\n`));
|
|
71
|
-
}
|
|
57
|
+
if (opts.group) {
|
|
58
|
+
console.log(chalk_1.default.yellow(' Groups sync with Pro cloud vault. Saved locally without a group.'));
|
|
59
|
+
console.log(chalk_1.default.dim(' After upgrading: recall sync\n'));
|
|
72
60
|
}
|
|
61
|
+
const tags = (0, tags_1.parseTags)(opts.tags);
|
|
62
|
+
const saved = (0, local_vault_1.saveLocalCommand)({
|
|
63
|
+
command,
|
|
64
|
+
name: opts.name,
|
|
65
|
+
tags,
|
|
66
|
+
});
|
|
67
|
+
console.log(chalk_1.default.green(` Saved locally${saved.name ? ` as "${saved.name}"` : ''}`));
|
|
68
|
+
console.log(chalk_1.default.dim(` Vault: ${local_vault_1.VAULT_FILE}`));
|
|
69
|
+
console.log(chalk_1.default.dim(' Sync to cloud (Pro): recall sync\n'));
|
|
73
70
|
});
|
package/dist/commands/search.js
CHANGED
|
@@ -7,9 +7,7 @@ exports.searchCommand = void 0;
|
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
9
9
|
const commander_1 = require("commander");
|
|
10
|
-
const
|
|
11
|
-
const api_1 = require("../lib/api");
|
|
12
|
-
const auth_1 = require("../lib/auth");
|
|
10
|
+
const local_vault_1 = require("../lib/local-vault");
|
|
13
11
|
function highlight(text, query) {
|
|
14
12
|
if (!query)
|
|
15
13
|
return text;
|
|
@@ -19,10 +17,8 @@ function highlight(text, query) {
|
|
|
19
17
|
function fuzzyMatch(text, query) {
|
|
20
18
|
const t = text.toLowerCase();
|
|
21
19
|
const q = query.toLowerCase();
|
|
22
|
-
// exact substring match
|
|
23
20
|
if (t.includes(q))
|
|
24
21
|
return true;
|
|
25
|
-
// fuzzy — all chars of query appear in order in text
|
|
26
22
|
let i = 0;
|
|
27
23
|
for (const ch of t) {
|
|
28
24
|
if (ch === q[i])
|
|
@@ -33,50 +29,39 @@ function fuzzyMatch(text, query) {
|
|
|
33
29
|
return false;
|
|
34
30
|
}
|
|
35
31
|
exports.searchCommand = new commander_1.Command('search')
|
|
36
|
-
.description('Search your
|
|
32
|
+
.description('Search your local vault')
|
|
37
33
|
.argument('<query>', 'Search query')
|
|
38
34
|
.option('-t, --tag <tag>', 'Filter by tag')
|
|
39
35
|
.action(async (query, opts) => {
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const results = commands.filter((cmd) => {
|
|
50
|
-
return (fuzzyMatch(cmd.command, query) ||
|
|
51
|
-
(cmd.name && fuzzyMatch(cmd.name, query)) ||
|
|
52
|
-
(cmd.tags && cmd.tags.some((t) => fuzzyMatch(t, query))));
|
|
53
|
-
});
|
|
54
|
-
if (!results.length) {
|
|
55
|
-
console.log(chalk_1.default.dim(`\n No commands found matching "${query}".\n`));
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
console.log(chalk_1.default.dim(`\n ${results.length} result${results.length === 1 ? '' : 's'} for "${chalk_1.default.white(query)}"\n`));
|
|
59
|
-
const table = new cli_table3_1.default({
|
|
60
|
-
head: [chalk_1.default.cyan('Name'), chalk_1.default.cyan('Command'), chalk_1.default.cyan('Tags')],
|
|
61
|
-
style: { head: [], border: ['grey'] },
|
|
62
|
-
colWidths: [20, 46, 18],
|
|
63
|
-
wordWrap: true,
|
|
64
|
-
});
|
|
65
|
-
for (const cmd of results) {
|
|
66
|
-
const name = cmd.name ?? '—';
|
|
67
|
-
const command = cmd.command.length > 44
|
|
68
|
-
? cmd.command.slice(0, 44) + '…'
|
|
69
|
-
: cmd.command;
|
|
70
|
-
const tags = (cmd.tags ?? []).join(', ') || '—';
|
|
71
|
-
table.push([
|
|
72
|
-
highlight(name, query),
|
|
73
|
-
highlight(command, query),
|
|
74
|
-
highlight(tags, query),
|
|
75
|
-
]);
|
|
76
|
-
}
|
|
77
|
-
console.log(table.toString());
|
|
36
|
+
const commands = (0, local_vault_1.listLocalCommands)({ tag: opts.tag });
|
|
37
|
+
const results = commands.filter((cmd) => {
|
|
38
|
+
return (fuzzyMatch(cmd.command, query) ||
|
|
39
|
+
(cmd.name ? fuzzyMatch(cmd.name, query) : false) ||
|
|
40
|
+
(cmd.tags ?? []).some((t) => fuzzyMatch(t, query)));
|
|
41
|
+
});
|
|
42
|
+
if (!results.length) {
|
|
43
|
+
console.log(chalk_1.default.dim(`\n No local commands matching "${query}".\n`));
|
|
44
|
+
return;
|
|
78
45
|
}
|
|
79
|
-
|
|
80
|
-
|
|
46
|
+
console.log(chalk_1.default.dim(`\n ${results.length} result${results.length === 1 ? '' : 's'} for "${chalk_1.default.white(query)}"\n`));
|
|
47
|
+
const table = new cli_table3_1.default({
|
|
48
|
+
head: [chalk_1.default.cyan('Name'), chalk_1.default.cyan('Command'), chalk_1.default.cyan('Tags')],
|
|
49
|
+
style: { head: [], border: ['grey'] },
|
|
50
|
+
colWidths: [20, 46, 18],
|
|
51
|
+
wordWrap: true,
|
|
52
|
+
});
|
|
53
|
+
for (const cmd of results) {
|
|
54
|
+
const name = cmd.name ?? '—';
|
|
55
|
+
const command = cmd.command.length > 44
|
|
56
|
+
? cmd.command.slice(0, 44) + '…'
|
|
57
|
+
: cmd.command;
|
|
58
|
+
const tags = (cmd.tags ?? []).join(', ') || '—';
|
|
59
|
+
table.push([
|
|
60
|
+
highlight(name, query),
|
|
61
|
+
highlight(command, query),
|
|
62
|
+
highlight(tags, query),
|
|
63
|
+
]);
|
|
81
64
|
}
|
|
65
|
+
console.log(table.toString());
|
|
66
|
+
console.log();
|
|
82
67
|
});
|
package/dist/commands/sync.js
CHANGED
|
@@ -7,74 +7,112 @@ exports.syncCommand = void 0;
|
|
|
7
7
|
exports.getCachedCommands = getCachedCommands;
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const commander_1 = require("commander");
|
|
10
|
-
const fs_1 = __importDefault(require("fs"));
|
|
11
10
|
const ora_1 = __importDefault(require("ora"));
|
|
12
|
-
const os_1 = __importDefault(require("os"));
|
|
13
|
-
const path_1 = __importDefault(require("path"));
|
|
14
11
|
const api_1 = require("../lib/api");
|
|
15
12
|
const auth_1 = require("../lib/auth");
|
|
16
|
-
const
|
|
17
|
-
const CACHE_FILE = path_1.default.join(CACHE_DIR, 'commands.json');
|
|
18
|
-
function writeCache(commands) {
|
|
19
|
-
fs_1.default.mkdirSync(CACHE_DIR, { recursive: true });
|
|
20
|
-
fs_1.default.writeFileSync(CACHE_FILE, JSON.stringify({
|
|
21
|
-
syncedAt: new Date().toISOString(),
|
|
22
|
-
commands,
|
|
23
|
-
}, null, 2));
|
|
24
|
-
}
|
|
25
|
-
function readCache() {
|
|
26
|
-
try {
|
|
27
|
-
if (!fs_1.default.existsSync(CACHE_FILE))
|
|
28
|
-
return null;
|
|
29
|
-
return JSON.parse(fs_1.default.readFileSync(CACHE_FILE, 'utf-8'));
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
return null;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
function getCachedCommands() {
|
|
36
|
-
const cache = readCache();
|
|
37
|
-
return cache?.commands ?? [];
|
|
38
|
-
}
|
|
13
|
+
const local_vault_1 = require("../lib/local-vault");
|
|
39
14
|
exports.syncCommand = new commander_1.Command('sync')
|
|
40
|
-
.description('Sync
|
|
41
|
-
.option('-s, --status', 'Show last sync status
|
|
15
|
+
.description('Sync local vault ↔ cloud (Pro/Team)')
|
|
16
|
+
.option('-s, --status', 'Show local vault + last sync status')
|
|
17
|
+
.option('--pull', 'Pull cloud → local only')
|
|
18
|
+
.option('--push', 'Push local-only commands → cloud only')
|
|
42
19
|
.action(async (opts) => {
|
|
43
|
-
|
|
20
|
+
const vault = (0, local_vault_1.readVault)();
|
|
44
21
|
if (opts.status) {
|
|
45
|
-
const cache = readCache();
|
|
46
|
-
if (!cache) {
|
|
47
|
-
console.log(chalk_1.default.dim('\n Never synced. Run: recall sync\n'));
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const ago = Math.round((Date.now() - new Date(cache.syncedAt).getTime()) / 1000 / 60);
|
|
51
22
|
console.log();
|
|
52
|
-
console.log(`
|
|
53
|
-
console.log(`
|
|
54
|
-
|
|
23
|
+
console.log(` Local commands: ${chalk_1.default.white(vault.commands.length)}`);
|
|
24
|
+
console.log(` Vault file: ${chalk_1.default.dim(local_vault_1.VAULT_FILE)}`);
|
|
25
|
+
if (!vault.syncedAt) {
|
|
26
|
+
console.log(chalk_1.default.dim(' Never synced to cloud.'));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const ago = Math.round((Date.now() - new Date(vault.syncedAt).getTime()) / 1000 / 60);
|
|
30
|
+
console.log(` Last synced: ${chalk_1.default.white(ago < 1 ? 'just now' : `${ago} minutes ago`)}`);
|
|
31
|
+
}
|
|
32
|
+
const pending = (0, local_vault_1.localCommandsNeedingPush)().length;
|
|
33
|
+
if (pending) {
|
|
34
|
+
console.log(` Not on cloud: ${chalk_1.default.yellow(String(pending))} (recall sync --push)`);
|
|
35
|
+
}
|
|
55
36
|
console.log();
|
|
56
37
|
return;
|
|
57
38
|
}
|
|
39
|
+
const doPull = opts.pull || (!opts.pull && !opts.push);
|
|
40
|
+
const doPush = opts.push || (!opts.pull && !opts.push);
|
|
58
41
|
const token = await (0, auth_1.requireAuth)();
|
|
59
|
-
const spinner = (0, ora_1.default)('
|
|
42
|
+
const spinner = (0, ora_1.default)('Checking plan...').start();
|
|
60
43
|
try {
|
|
61
|
-
const {
|
|
62
|
-
|
|
63
|
-
spinner.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
console.log();
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
44
|
+
const { user } = await api_1.ApiClient.get('/auth/me', token);
|
|
45
|
+
const plan = (user.plan ?? 'free');
|
|
46
|
+
spinner.stop();
|
|
47
|
+
if (plan !== 'pro' && plan !== 'team') {
|
|
48
|
+
console.log(chalk_1.default.yellow('\n Cloud sync requires Pro or Team.'));
|
|
49
|
+
console.log(chalk_1.default.dim(' Local vault still works without sync.'));
|
|
50
|
+
console.log(chalk_1.default.dim(' Upgrade: recall upgrade\n'));
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
spinner.fail(chalk_1.default.red('Could not verify plan'));
|
|
56
|
+
if (err instanceof api_1.ApiError && err.status === 401) {
|
|
57
|
+
console.log(chalk_1.default.red('\n Session expired. Run: recall auth login\n'));
|
|
58
|
+
}
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
let pulled = 0;
|
|
62
|
+
let pushed = 0;
|
|
63
|
+
if (doPull) {
|
|
64
|
+
const pullSpinner = (0, ora_1.default)('Pulling from cloud...').start();
|
|
65
|
+
try {
|
|
66
|
+
const { commands } = await api_1.ApiClient.get('/commands', token);
|
|
67
|
+
const { added, updated } = (0, local_vault_1.mergeCloudIntoLocal)(commands);
|
|
68
|
+
pulled = added + updated;
|
|
69
|
+
pullSpinner.succeed(chalk_1.default.green(`Pulled cloud vault (${added} new, ${updated} updated)`));
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
pullSpinner.fail(chalk_1.default.red('Pull failed'));
|
|
73
|
+
if (err instanceof api_1.ApiError && err.status === 403) {
|
|
74
|
+
console.log(chalk_1.default.yellow('\n Cloud vault requires Pro.\n'));
|
|
75
|
+
}
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (doPush) {
|
|
80
|
+
const pending = (0, local_vault_1.localCommandsNeedingPush)();
|
|
81
|
+
if (!pending.length) {
|
|
82
|
+
console.log(chalk_1.default.dim(' Nothing new to push.'));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const pushSpinner = (0, ora_1.default)(`Pushing ${pending.length} local command(s)...`).start();
|
|
86
|
+
try {
|
|
87
|
+
for (const cmd of pending) {
|
|
88
|
+
const saved = await api_1.ApiClient.post('/commands', {
|
|
89
|
+
command: cmd.command,
|
|
90
|
+
name: cmd.name,
|
|
91
|
+
tags: cmd.tags,
|
|
92
|
+
}, token);
|
|
93
|
+
if (saved?.id)
|
|
94
|
+
(0, local_vault_1.attachCloudId)(cmd.id, saved.id);
|
|
95
|
+
pushed++;
|
|
96
|
+
}
|
|
97
|
+
pushSpinner.succeed(chalk_1.default.green(`Pushed ${pushed} command${pushed === 1 ? '' : 's'} to cloud`));
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
pushSpinner.fail(chalk_1.default.red('Push failed'));
|
|
101
|
+
if (err instanceof api_1.ApiError && err.status === 403) {
|
|
102
|
+
console.log(chalk_1.default.yellow('\n Cloud save requires Pro. Local vault is unchanged.\n'));
|
|
103
|
+
}
|
|
104
|
+
process.exit(1);
|
|
72
105
|
}
|
|
73
106
|
}
|
|
74
|
-
console.log();
|
|
75
107
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
108
|
+
console.log();
|
|
109
|
+
console.log(` ${chalk_1.default.dim('Local vault:')} ${chalk_1.default.dim(local_vault_1.VAULT_FILE)}`);
|
|
110
|
+
if (doPull || doPush) {
|
|
111
|
+
console.log(chalk_1.default.dim(` pull≈${pulled} · push=${pushed}`));
|
|
79
112
|
}
|
|
113
|
+
console.log();
|
|
80
114
|
});
|
|
115
|
+
/** @deprecated kept for any imports — use readVault */
|
|
116
|
+
function getCachedCommands() {
|
|
117
|
+
return (0, local_vault_1.readVault)().commands;
|
|
118
|
+
}
|
package/dist/commands/upgrade.js
CHANGED
|
@@ -16,18 +16,17 @@ const PLANS = {
|
|
|
16
16
|
label: 'Free',
|
|
17
17
|
price: '$0/month',
|
|
18
18
|
features: [
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
'Export as JSON or shell script',
|
|
24
|
-
'Cross-machine sync',
|
|
19
|
+
'Fully local vault (no account)',
|
|
20
|
+
'Save, list, search, run on your machine',
|
|
21
|
+
'No cloud sync',
|
|
22
|
+
'No AI Ask (Pro)',
|
|
25
23
|
],
|
|
26
24
|
},
|
|
27
25
|
pro: {
|
|
28
26
|
label: 'Pro',
|
|
29
27
|
price: '$6/month',
|
|
30
28
|
features: [
|
|
29
|
+
'Sync local ↔ cloud',
|
|
31
30
|
'500 AI asks / month',
|
|
32
31
|
'Unlimited playbooks',
|
|
33
32
|
'Unlimited commands',
|
package/dist/commands/whoami.js
CHANGED
|
@@ -16,13 +16,13 @@ const PLAN_LABELS = {
|
|
|
16
16
|
};
|
|
17
17
|
const PLAN_FEATURES = {
|
|
18
18
|
free: [
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'Cross-machine sync',
|
|
19
|
+
'Fully local vault (no cloud)',
|
|
20
|
+
'Save, list, search, run offline',
|
|
21
|
+
'No Ask / no sync',
|
|
23
22
|
],
|
|
24
23
|
pro: [
|
|
25
|
-
'
|
|
24
|
+
'Sync local ↔ cloud',
|
|
25
|
+
'Ask (NL, print-only)',
|
|
26
26
|
'Command groups',
|
|
27
27
|
'Share commands via link',
|
|
28
28
|
],
|
|
@@ -30,7 +30,6 @@ const PLAN_FEATURES = {
|
|
|
30
30
|
'Everything in Pro',
|
|
31
31
|
'Org-level vaults',
|
|
32
32
|
'Role-based access',
|
|
33
|
-
'SSO / SAML',
|
|
34
33
|
'Audit log',
|
|
35
34
|
],
|
|
36
35
|
};
|
|
@@ -59,8 +58,8 @@ exports.whoamiCommand = new commander_1.Command('whoami')
|
|
|
59
58
|
}
|
|
60
59
|
if (plan === 'free') {
|
|
61
60
|
console.log();
|
|
62
|
-
console.log(chalk_1.default.dim(' Upgrade to Pro for
|
|
63
|
-
console.log(chalk_1.default.dim(' https://devkitvault.com/
|
|
61
|
+
console.log(chalk_1.default.dim(' Upgrade to Pro for sync + Ask:'));
|
|
62
|
+
console.log(chalk_1.default.dim(' https://recall.devkitvault.com/dashboard/upgrade'));
|
|
64
63
|
}
|
|
65
64
|
console.log();
|
|
66
65
|
}
|
package/dist/lib/config.js
CHANGED
|
@@ -11,7 +11,7 @@ const os_1 = __importDefault(require("os"));
|
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
12
|
const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.recall');
|
|
13
13
|
const CONFIG_FILE = path_1.default.join(CONFIG_DIR, 'config.json');
|
|
14
|
-
exports.APP_VERSION =
|
|
14
|
+
exports.APP_VERSION = '1.2.10';
|
|
15
15
|
exports.ENVIRONMENTS = {
|
|
16
16
|
production: 'https://api.devkitvault.com',
|
|
17
17
|
local: 'http://127.0.0.1:3001',
|