aliasmate 2.0.0 → 2.4.0
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/CHANGELOG.md +53 -3
- package/README.md +98 -10
- package/dist/cli/completion.js +4 -4
- package/dist/cli/completion.js.map +1 -1
- package/dist/cli/extras.d.ts +5 -0
- package/dist/cli/extras.d.ts.map +1 -0
- package/dist/cli/extras.js +73 -0
- package/dist/cli/extras.js.map +1 -0
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +140 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/manage.d.ts +2 -3
- package/dist/cli/manage.d.ts.map +1 -1
- package/dist/cli/manage.js +47 -27
- package/dist/cli/manage.js.map +1 -1
- package/dist/cli/project.d.ts +2 -0
- package/dist/cli/project.d.ts.map +1 -0
- package/dist/cli/project.js +105 -0
- package/dist/cli/project.js.map +1 -0
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +90 -16
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/save.d.ts +7 -8
- package/dist/cli/save.d.ts.map +1 -1
- package/dist/cli/save.js +71 -33
- package/dist/cli/save.js.map +1 -1
- package/dist/cli/sync.d.ts +2 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +122 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/transfer.d.ts +1 -0
- package/dist/cli/transfer.d.ts.map +1 -1
- package/dist/cli/transfer.js +40 -59
- package/dist/cli/transfer.js.map +1 -1
- package/dist/core/clipboard.d.ts +3 -0
- package/dist/core/clipboard.d.ts.map +1 -0
- package/dist/core/clipboard.js +57 -0
- package/dist/core/clipboard.js.map +1 -0
- package/dist/core/commands.d.ts +8 -1
- package/dist/core/commands.d.ts.map +1 -1
- package/dist/core/commands.js +59 -4
- package/dist/core/commands.js.map +1 -1
- package/dist/core/project.d.ts +21 -0
- package/dist/core/project.d.ts.map +1 -0
- package/dist/core/project.js +130 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/recent.d.ts +6 -1
- package/dist/core/recent.d.ts.map +1 -1
- package/dist/core/recent.js +11 -2
- package/dist/core/recent.js.map +1 -1
- package/dist/core/runner.d.ts +22 -4
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +72 -8
- package/dist/core/runner.js.map +1 -1
- package/dist/core/suggest.d.ts +12 -0
- package/dist/core/suggest.d.ts.map +1 -0
- package/dist/core/suggest.js +109 -0
- package/dist/core/suggest.js.map +1 -0
- package/dist/core/transfer.d.ts +20 -0
- package/dist/core/transfer.d.ts.map +1 -0
- package/dist/core/transfer.js +115 -0
- package/dist/core/transfer.js.map +1 -0
- package/dist/core/types.d.ts +8 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/undo.d.ts +7 -0
- package/dist/core/undo.d.ts.map +1 -0
- package/dist/core/undo.js +34 -0
- package/dist/core/undo.js.map +1 -0
- package/dist/index.js +53 -15
- package/dist/index.js.map +1 -1
- package/dist/ui/format.d.ts +6 -1
- package/dist/ui/format.d.ts.map +1 -1
- package/dist/ui/format.js +64 -18
- package/dist/ui/format.js.map +1 -1
- package/dist/ui/interactive.d.ts +63 -3
- package/dist/ui/interactive.d.ts.map +1 -1
- package/dist/ui/interactive.js +701 -95
- package/dist/ui/interactive.js.map +1 -1
- package/dist/ui/onboarding.d.ts.map +1 -1
- package/dist/ui/onboarding.js +27 -7
- package/dist/ui/onboarding.js.map +1 -1
- package/dist/ui/prompts.d.ts +1 -12
- package/dist/ui/prompts.d.ts.map +1 -1
- package/dist/ui/prompts.js +45 -91
- package/dist/ui/prompts.js.map +1 -1
- package/dist/ui/table.d.ts +18 -0
- package/dist/ui/table.d.ts.map +1 -0
- package/dist/ui/table.js +54 -0
- package/dist/ui/table.js.map +1 -0
- package/dist/ui/theme.d.ts +8 -6
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +33 -18
- package/dist/ui/theme.js.map +1 -1
- package/package.json +7 -7
package/dist/ui/interactive.js
CHANGED
|
@@ -32,116 +32,722 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Tui = void 0;
|
|
37
|
+
exports.fuzzyMatch = fuzzyMatch;
|
|
39
38
|
exports.interactiveHome = interactiveHome;
|
|
40
|
-
const
|
|
39
|
+
const readline = __importStar(require("readline"));
|
|
41
40
|
const commands_1 = require("../core/commands");
|
|
42
41
|
const recent_1 = require("../core/recent");
|
|
42
|
+
const project_1 = require("../core/project");
|
|
43
|
+
const suggest_1 = require("../core/suggest");
|
|
44
|
+
const clipboard_1 = require("../core/clipboard");
|
|
45
|
+
const undo_1 = require("../core/undo");
|
|
46
|
+
const transfer_1 = require("../core/transfer");
|
|
47
|
+
const env_1 = require("../core/env");
|
|
43
48
|
const format_1 = require("./format");
|
|
44
49
|
const theme_1 = require("./theme");
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
/** Simple subsequence fuzzy match: every query char appears in order. */
|
|
51
|
+
function fuzzyMatch(query, text) {
|
|
52
|
+
const q = query.toLowerCase();
|
|
53
|
+
const t = text.toLowerCase();
|
|
54
|
+
let i = 0;
|
|
55
|
+
for (const ch of t) {
|
|
56
|
+
if (ch === q[i])
|
|
57
|
+
i++;
|
|
58
|
+
if (i === q.length)
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
return q.length === 0;
|
|
50
62
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
63
|
+
/** Shared caret editing for form fields and single-line inputs. */
|
|
64
|
+
function editText(field, str, key) {
|
|
65
|
+
if (key.name === 'left') {
|
|
66
|
+
field.cursor = Math.max(0, field.cursor - 1);
|
|
67
|
+
}
|
|
68
|
+
else if (key.name === 'right') {
|
|
69
|
+
field.cursor = Math.min(field.value.length, field.cursor + 1);
|
|
70
|
+
}
|
|
71
|
+
else if (key.name === 'home' || (key.ctrl && key.name === 'a')) {
|
|
72
|
+
field.cursor = 0;
|
|
73
|
+
}
|
|
74
|
+
else if (key.name === 'end' || (key.ctrl && key.name === 'e')) {
|
|
75
|
+
field.cursor = field.value.length;
|
|
76
|
+
}
|
|
77
|
+
else if (key.ctrl && key.name === 'u') {
|
|
78
|
+
field.value = field.value.slice(field.cursor);
|
|
79
|
+
field.cursor = 0;
|
|
80
|
+
}
|
|
81
|
+
else if (key.name === 'backspace') {
|
|
82
|
+
if (field.cursor > 0) {
|
|
83
|
+
field.value = field.value.slice(0, field.cursor - 1) + field.value.slice(field.cursor);
|
|
84
|
+
field.cursor -= 1;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else if (key.name === 'delete') {
|
|
88
|
+
field.value = field.value.slice(0, field.cursor) + field.value.slice(field.cursor + 1);
|
|
89
|
+
}
|
|
90
|
+
else if (str && str.length === 1 && !key.ctrl && !key.meta && str >= ' ') {
|
|
91
|
+
field.value = field.value.slice(0, field.cursor) + str + field.value.slice(field.cursor);
|
|
92
|
+
field.cursor += 1;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
80
98
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
99
|
+
const ALT_SCREEN_ON = '\x1b[?1049h\x1b[?25l';
|
|
100
|
+
const ALT_SCREEN_OFF = '\x1b[?1049l\x1b[?25h';
|
|
101
|
+
const CLEAR = '\x1b[2J\x1b[H';
|
|
102
|
+
function loadRows() {
|
|
103
|
+
const effective = (0, project_1.listEffectiveCommands)();
|
|
104
|
+
const commands = effective.commands;
|
|
105
|
+
const stats = (0, recent_1.getUsageStats)();
|
|
106
|
+
const counts = new Map(stats.map((s) => [s.name, s.runCount]));
|
|
107
|
+
const lastRuns = new Map(stats.map((s) => [s.name, s.lastRunAt]));
|
|
108
|
+
return Object.keys(commands)
|
|
109
|
+
.sort((a, b) => (counts.get(b) ?? 0) - (counts.get(a) ?? 0) || a.localeCompare(b))
|
|
110
|
+
.map((name) => {
|
|
111
|
+
const last = (0, recent_1.getLastExecution)(name);
|
|
112
|
+
return {
|
|
113
|
+
name,
|
|
114
|
+
cmd: commands[name],
|
|
115
|
+
runs: counts.get(name) ?? 0,
|
|
116
|
+
lastRun: lastRuns.get(name),
|
|
117
|
+
project: effective.projectNames.has(name),
|
|
118
|
+
lastFailed: last?.exitCode !== undefined && last.exitCode !== 0,
|
|
119
|
+
};
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
class Tui {
|
|
123
|
+
constructor(out = (t) => process.stdout.write(t)) {
|
|
124
|
+
this.out = out;
|
|
125
|
+
this.mode = 'browse';
|
|
126
|
+
this.filter = '';
|
|
127
|
+
this.selected = 0;
|
|
128
|
+
this.rows = loadRows();
|
|
129
|
+
this.form = null;
|
|
130
|
+
this.input = null;
|
|
131
|
+
this.suggestion = null;
|
|
132
|
+
this.message = '';
|
|
133
|
+
this.resolve = null;
|
|
134
|
+
}
|
|
135
|
+
get width() {
|
|
136
|
+
return process.stdout.columns || 100;
|
|
137
|
+
}
|
|
138
|
+
get height() {
|
|
139
|
+
return process.stdout.rows || 30;
|
|
140
|
+
}
|
|
141
|
+
visibleRows() {
|
|
142
|
+
if (!this.filter)
|
|
143
|
+
return this.rows;
|
|
144
|
+
// Name matches rank above matches in the command text or directory.
|
|
145
|
+
const byName = this.rows.filter((r) => fuzzyMatch(this.filter, r.name));
|
|
146
|
+
const byContent = this.rows.filter((r) => !byName.includes(r) && fuzzyMatch(this.filter, `${r.cmd.command} ${r.cmd.directory}`));
|
|
147
|
+
return [...byName, ...byContent];
|
|
148
|
+
}
|
|
149
|
+
refresh() {
|
|
150
|
+
this.rows = loadRows();
|
|
151
|
+
this.selected = Math.min(this.selected, Math.max(0, this.visibleRows().length - 1));
|
|
117
152
|
try {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
153
|
+
this.suggestion = (0, suggest_1.getSuggestion)();
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
this.suggestion = null;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
openForm(seed = {}) {
|
|
160
|
+
this.form = {
|
|
161
|
+
fields: [
|
|
162
|
+
{ key: 'name', label: 'name', value: seed.name ?? '' },
|
|
163
|
+
{ key: 'command', label: 'command', value: seed.command ?? '' },
|
|
164
|
+
{ key: 'directory', label: 'directory', value: seed.directory ?? process.cwd() },
|
|
165
|
+
{ key: 'description', label: 'note', value: seed.description ?? '' },
|
|
166
|
+
].map((f) => ({ ...f, cursor: f.value.length })),
|
|
167
|
+
pathMode: seed.pathMode ?? 'saved',
|
|
168
|
+
envChoice: seed.env && Object.keys(seed.env).length > 0 ? 'keep' : 'none',
|
|
169
|
+
keepEnv: seed.env,
|
|
170
|
+
keepTags: seed.tags,
|
|
171
|
+
keepSteps: seed.steps,
|
|
172
|
+
editing: seed.editing,
|
|
173
|
+
active: seed.editing || seed.name ? 1 : 0,
|
|
174
|
+
error: '',
|
|
175
|
+
};
|
|
176
|
+
this.mode = 'form';
|
|
177
|
+
}
|
|
178
|
+
// --- rendering -------------------------------------------------------------
|
|
179
|
+
header(subtitle) {
|
|
180
|
+
const left = `${theme_1.icons.dot} ${theme_1.theme.heading('aliasmate')} ${theme_1.theme.dim(subtitle)}`;
|
|
181
|
+
const totalRuns = this.rows.reduce((s, r) => s + r.runs, 0);
|
|
182
|
+
const rightText = `${this.rows.length} commands · ${totalRuns} runs`;
|
|
183
|
+
const leftText = `● aliasmate ${subtitle}`;
|
|
184
|
+
const pad = Math.max(1, this.width - leftText.length - rightText.length - 3);
|
|
185
|
+
return ['', ` ${left}${' '.repeat(pad)}${theme_1.theme.faint(rightText)}`, ''];
|
|
186
|
+
}
|
|
187
|
+
listPane(maxLines) {
|
|
188
|
+
const rows = this.visibleRows();
|
|
189
|
+
if (rows.length === 0) {
|
|
190
|
+
return this.rows.length === 0
|
|
191
|
+
? [
|
|
192
|
+
'',
|
|
193
|
+
theme_1.theme.dim(' No commands yet — press ') +
|
|
194
|
+
theme_1.theme.accent('n') +
|
|
195
|
+
theme_1.theme.dim(' to create your first one.'),
|
|
196
|
+
]
|
|
197
|
+
: ['', theme_1.theme.dim(` Nothing matches "${this.filter}"`)];
|
|
198
|
+
}
|
|
199
|
+
const nameW = Math.min(Math.max(...rows.map((r) => r.name.length), 4) + 1, 22);
|
|
200
|
+
const cmdW = Math.max(20, Math.min(56, this.width - nameW - 30));
|
|
201
|
+
const start = Math.max(0, Math.min(this.selected - Math.floor(maxLines / 2), rows.length - maxLines));
|
|
202
|
+
return rows.slice(start, start + maxLines).map((row, i) => {
|
|
203
|
+
const index = start + i;
|
|
204
|
+
const active = index === this.selected;
|
|
205
|
+
const marker = active ? theme_1.theme.accent('›') : ' ';
|
|
206
|
+
const name = active
|
|
207
|
+
? theme_1.theme.selected(row.name.padEnd(nameW))
|
|
208
|
+
: theme_1.theme.name(row.name.padEnd(nameW));
|
|
209
|
+
const cmdText = row.cmd.steps?.length ? `⛓ ${row.cmd.steps.join(' → ')}` : row.cmd.command;
|
|
210
|
+
const cmd = (0, format_1.truncate)(cmdText, cmdW).padEnd(cmdW + 1);
|
|
211
|
+
const badges = [
|
|
212
|
+
row.project ? theme_1.theme.accent('⌂') : '',
|
|
213
|
+
row.lastFailed ? theme_1.theme.error('✗') : '',
|
|
214
|
+
row.runs > 0 ? theme_1.theme.dim(`${theme_1.icons.fire} ${row.runs}`) : theme_1.theme.faint('·'),
|
|
215
|
+
]
|
|
216
|
+
.filter(Boolean)
|
|
217
|
+
.join(' ');
|
|
218
|
+
return ` ${marker} ${name} ${active ? cmd : theme_1.theme.dim(cmd)} ${badges}`;
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
detailPane() {
|
|
222
|
+
const row = this.visibleRows()[this.selected];
|
|
223
|
+
if (!row)
|
|
224
|
+
return [];
|
|
225
|
+
const label = (t) => theme_1.theme.faint(t.padEnd(11));
|
|
226
|
+
const where = (row.cmd.pathMode ?? 'saved') === 'current'
|
|
227
|
+
? 'current directory'
|
|
228
|
+
: (0, format_1.prettyPath)(row.cmd.directory);
|
|
229
|
+
const env = Object.entries(row.cmd.env ?? {})
|
|
230
|
+
.map(([k, v]) => `${k}=${(0, env_1.isSensitive)(k) ? (0, env_1.maskValue)(v) : v}`)
|
|
231
|
+
.join(theme_1.theme.faint(' · '));
|
|
232
|
+
const lines = [theme_1.theme.faint(` ${'─'.repeat(Math.max(10, this.width - 2))}`)];
|
|
233
|
+
if (row.cmd.steps?.length) {
|
|
234
|
+
lines.push(` ${label('chain')}${row.cmd.steps.join(theme_1.theme.faint(' → '))}`);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
lines.push(` ${label('command')}${(0, format_1.truncate)(row.cmd.command, this.width - 14)}`);
|
|
238
|
+
}
|
|
239
|
+
lines.push(` ${label('where')}${theme_1.theme.dim((0, format_1.truncate)(where, this.width - 14))}`);
|
|
240
|
+
if (row.cmd.description) {
|
|
241
|
+
lines.push(` ${label('note')}${theme_1.theme.dim((0, format_1.truncate)(row.cmd.description, this.width - 14))}`);
|
|
242
|
+
}
|
|
243
|
+
if (row.cmd.tags?.length) {
|
|
244
|
+
lines.push(` ${label('tags')}${row.cmd.tags.map((t) => theme_1.theme.accent(`#${t}`)).join(' ')}`);
|
|
245
|
+
}
|
|
246
|
+
if (env)
|
|
247
|
+
lines.push(` ${label('env')}${theme_1.theme.dim((0, format_1.truncate)(env, this.width - 14))}`);
|
|
248
|
+
if (row.project)
|
|
249
|
+
lines.push(` ${label('source')}${theme_1.theme.dim('project (.aliasmate.json)')}`);
|
|
250
|
+
const last = (0, recent_1.getLastExecution)(row.name);
|
|
251
|
+
const status = row.runs === 0
|
|
252
|
+
? 'never'
|
|
253
|
+
: `${row.runs} · last ${(0, format_1.timeAgo)(row.lastRun)}${last?.exitCode !== undefined
|
|
254
|
+
? last.exitCode === 0
|
|
255
|
+
? ` ${theme_1.theme.success('✓')}`
|
|
256
|
+
: ` ${theme_1.theme.error(`✗ exit ${last.exitCode}`)}`
|
|
257
|
+
: ''}`;
|
|
258
|
+
lines.push(` ${label('runs')}${theme_1.theme.dim(status)}`);
|
|
259
|
+
return lines;
|
|
260
|
+
}
|
|
261
|
+
statsPane() {
|
|
262
|
+
const top = this.rows.filter((r) => r.runs > 0).slice(0, 12);
|
|
263
|
+
const lines = [];
|
|
264
|
+
if (top.length === 0) {
|
|
265
|
+
lines.push(theme_1.theme.dim(' Nothing run yet.'));
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
const max = Math.max(...top.map((r) => r.runs));
|
|
269
|
+
const nameW = Math.min(Math.max(...top.map((r) => r.name.length)) + 1, 22);
|
|
270
|
+
for (const row of top) {
|
|
271
|
+
const bar = theme_1.theme.accent('▮'.repeat(Math.max(1, Math.round((row.runs / max) * 24))));
|
|
272
|
+
lines.push(` ${theme_1.theme.name(row.name.padEnd(nameW))} ${bar} ${theme_1.theme.dim(String(row.runs))} ${theme_1.theme.faint((0, format_1.timeAgo)(row.lastRun))}`);
|
|
130
273
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
274
|
+
}
|
|
275
|
+
return lines;
|
|
276
|
+
}
|
|
277
|
+
formPane() {
|
|
278
|
+
const form = this.form;
|
|
279
|
+
const label = (t, active) => (active ? theme_1.theme.accent('› ') : ' ') + theme_1.theme.faint(t.padEnd(11));
|
|
280
|
+
const lines = [];
|
|
281
|
+
form.fields.forEach((field, i) => {
|
|
282
|
+
const active = form.active === i;
|
|
283
|
+
const renamed = field.key === 'name' && form.editing !== undefined && field.value !== form.editing;
|
|
284
|
+
const value = active
|
|
285
|
+
? `${field.value.slice(0, field.cursor)}${theme_1.theme.accent('▏')}${field.value.slice(field.cursor)}`
|
|
286
|
+
: field.value;
|
|
287
|
+
lines.push(` ${label(field.label, active)}${value}${renamed ? theme_1.theme.faint(` · renames ${form.editing}`) : ''}`);
|
|
288
|
+
});
|
|
289
|
+
const pmActive = form.active === 4;
|
|
290
|
+
const pmText = form.pathMode === 'saved'
|
|
291
|
+
? 'saved directory (project command)'
|
|
292
|
+
: 'current directory (utility)';
|
|
293
|
+
lines.push(` ${label('runs in', pmActive)}${pmActive ? pmText : theme_1.theme.dim(pmText)}${pmActive ? theme_1.theme.faint(' · space to toggle') : ''}`);
|
|
294
|
+
const envActive = form.active === 5;
|
|
295
|
+
const keptCount = form.keepEnv ? Object.keys(form.keepEnv).length : 0;
|
|
296
|
+
const envLabels = {
|
|
297
|
+
none: 'none',
|
|
298
|
+
keep: `keep saved (${keptCount} var${keptCount === 1 ? '' : 's'})`,
|
|
299
|
+
capture: `capture current shell (${Object.keys((0, env_1.captureUserEnv)()).length} vars, secrets masked on export)`,
|
|
300
|
+
};
|
|
301
|
+
lines.push(` ${label('env', envActive)}${envActive ? envLabels[form.envChoice] : theme_1.theme.dim(envLabels[form.envChoice])}${envActive ? theme_1.theme.faint(' · space to cycle') : ''}`);
|
|
302
|
+
if (form.error) {
|
|
303
|
+
lines.push('');
|
|
304
|
+
lines.push(` ${theme_1.theme.error(form.error)}`);
|
|
305
|
+
}
|
|
306
|
+
return lines;
|
|
307
|
+
}
|
|
308
|
+
inputPane() {
|
|
309
|
+
const input = this.input;
|
|
310
|
+
const value = `${input.value.slice(0, input.cursor)}${theme_1.theme.accent('▏')}${input.value.slice(input.cursor)}`;
|
|
311
|
+
const lines = [` ${theme_1.theme.accent('› ')}${theme_1.theme.faint(input.label.padEnd(11))}${value}`];
|
|
312
|
+
if (input.kind === 'export') {
|
|
313
|
+
lines.push('');
|
|
314
|
+
lines.push(theme_1.theme.faint(' includes real secret env values — keep the file safe'));
|
|
315
|
+
}
|
|
316
|
+
if (input.error) {
|
|
317
|
+
lines.push('');
|
|
318
|
+
lines.push(` ${theme_1.theme.error(input.error)}`);
|
|
319
|
+
}
|
|
320
|
+
return lines;
|
|
321
|
+
}
|
|
322
|
+
footer() {
|
|
323
|
+
const key = (k, label) => `${theme_1.theme.accent(k)} ${theme_1.theme.faint(label)}`;
|
|
324
|
+
const sep = theme_1.theme.faint(' ');
|
|
325
|
+
switch (this.mode) {
|
|
326
|
+
case 'confirm-delete': {
|
|
327
|
+
const row = this.visibleRows()[this.selected];
|
|
328
|
+
return ` ${theme_1.theme.warning(`delete "${row?.name}"?`)} ${key('y', 'yes')}${sep}${key('n', 'no')}`;
|
|
135
329
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
330
|
+
case 'filter':
|
|
331
|
+
return ` ${theme_1.theme.accent('/')} ${this.filter}${theme_1.theme.accent('▏')} ${theme_1.theme.faint('esc clear · enter run · ↑↓ move')}`;
|
|
332
|
+
case 'form':
|
|
333
|
+
return ` ${[key('↑↓/tab', 'field'), key('←→', 'cursor'), key('enter', 'next/save'), key('esc', 'cancel')].join(sep)}`;
|
|
334
|
+
case 'input':
|
|
335
|
+
return ` ${[key('enter', this.input?.kind === 'export' ? 'export' : 'import'), key('esc', 'cancel')].join(sep)}`;
|
|
336
|
+
case 'stats':
|
|
337
|
+
return ` ${theme_1.theme.faint('any key to go back')}`;
|
|
338
|
+
default:
|
|
339
|
+
return ` ${[
|
|
340
|
+
key('↑↓', 'move'),
|
|
341
|
+
key('enter', 'run'),
|
|
342
|
+
key('/', 'filter'),
|
|
343
|
+
key('n', 'new'),
|
|
344
|
+
key('e', 'edit'),
|
|
345
|
+
key('d', 'delete'),
|
|
346
|
+
key('s', 'stats'),
|
|
347
|
+
key('c', 'copy'),
|
|
348
|
+
key('u', 'undo'),
|
|
349
|
+
key('x', 'export'),
|
|
350
|
+
key('i', 'import'),
|
|
351
|
+
key('q', 'quit'),
|
|
352
|
+
].join(sep)}`;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
render() {
|
|
356
|
+
const subtitle = this.mode === 'form'
|
|
357
|
+
? this.form?.editing
|
|
358
|
+
? `· edit ${this.form.editing}`
|
|
359
|
+
: '· new command'
|
|
360
|
+
: this.mode === 'stats'
|
|
361
|
+
? '· stats'
|
|
362
|
+
: this.mode === 'input'
|
|
363
|
+
? this.input?.kind === 'export'
|
|
364
|
+
? '· export backup'
|
|
365
|
+
: '· import'
|
|
366
|
+
: '';
|
|
367
|
+
const out = [...this.header(subtitle)];
|
|
368
|
+
if (this.mode === 'stats') {
|
|
369
|
+
out.push(...this.statsPane());
|
|
370
|
+
}
|
|
371
|
+
else if (this.mode === 'form') {
|
|
372
|
+
out.push(...this.formPane());
|
|
373
|
+
}
|
|
374
|
+
else if (this.mode === 'input') {
|
|
375
|
+
out.push(...this.inputPane());
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
if (this.suggestion) {
|
|
379
|
+
out.push(` ${theme_1.theme.accent('✦')} ${theme_1.theme.dim(`you've run`)} ${(0, format_1.truncate)(this.suggestion.command, 48)} ${theme_1.theme.dim(`${this.suggestion.count}× — press`)} ${theme_1.theme.accent('a')} ${theme_1.theme.dim('to save it')}`);
|
|
380
|
+
out.push('');
|
|
140
381
|
}
|
|
382
|
+
const detail = this.detailPane();
|
|
383
|
+
const listLines = Math.max(3, this.height - out.length - detail.length - 4);
|
|
384
|
+
out.push(...this.listPane(listLines));
|
|
385
|
+
out.push('');
|
|
386
|
+
out.push(...detail);
|
|
387
|
+
}
|
|
388
|
+
while (out.length < this.height - 2)
|
|
389
|
+
out.push('');
|
|
390
|
+
out.push(this.message ? ` ${this.message}` : '');
|
|
391
|
+
out.push(this.footer());
|
|
392
|
+
this.out(CLEAR + out.slice(0, this.height).join('\n'));
|
|
393
|
+
this.message = '';
|
|
394
|
+
}
|
|
395
|
+
// --- input -----------------------------------------------------------------
|
|
396
|
+
/** Clear the filter but keep the same row highlighted. */
|
|
397
|
+
clearFilter() {
|
|
398
|
+
const current = this.visibleRows()[this.selected]?.name;
|
|
399
|
+
this.filter = '';
|
|
400
|
+
const index = current ? this.visibleRows().findIndex((r) => r.name === current) : -1;
|
|
401
|
+
this.selected = Math.max(0, index);
|
|
402
|
+
}
|
|
403
|
+
move(delta) {
|
|
404
|
+
const count = this.visibleRows().length;
|
|
405
|
+
if (count === 0)
|
|
406
|
+
return;
|
|
407
|
+
this.selected = (this.selected + delta + count) % count;
|
|
408
|
+
}
|
|
409
|
+
openInput(kind) {
|
|
410
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
411
|
+
const value = kind === 'export' ? `~/aliasmate-backup-${today}.json` : '~/';
|
|
412
|
+
this.input = { kind, label: 'file', value, cursor: value.length, error: '' };
|
|
413
|
+
this.mode = 'input';
|
|
414
|
+
}
|
|
415
|
+
handleInputKey(str, key) {
|
|
416
|
+
const input = this.input;
|
|
417
|
+
if (key.name === 'escape') {
|
|
418
|
+
this.input = null;
|
|
419
|
+
this.mode = 'browse';
|
|
420
|
+
this.message = theme_1.theme.faint('cancelled');
|
|
421
|
+
return this.render();
|
|
422
|
+
}
|
|
423
|
+
if (key.name === 'return')
|
|
424
|
+
return this.submitInput();
|
|
425
|
+
if (editText(input, str, key))
|
|
426
|
+
input.error = '';
|
|
427
|
+
this.render();
|
|
428
|
+
}
|
|
429
|
+
submitInput() {
|
|
430
|
+
const input = this.input;
|
|
431
|
+
const file = input.value.trim();
|
|
432
|
+
if (!file) {
|
|
433
|
+
input.error = 'File path cannot be empty';
|
|
434
|
+
return this.render();
|
|
435
|
+
}
|
|
436
|
+
try {
|
|
437
|
+
if (input.kind === 'export') {
|
|
438
|
+
const count = (0, transfer_1.exportToFile)(file, { full: true });
|
|
439
|
+
this.message = `${theme_1.icons.ok} ${theme_1.theme.dim(`exported ${count} command${count === 1 ? '' : 's'} to ${file}`)}`;
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
const result = (0, transfer_1.importFromFile)(file);
|
|
443
|
+
this.refresh();
|
|
444
|
+
const extras = [
|
|
445
|
+
result.skipped.length > 0 ? `${result.skipped.length} skipped (already exist)` : '',
|
|
446
|
+
result.invalid.length > 0 ? `${result.invalid.length} invalid` : '',
|
|
447
|
+
]
|
|
448
|
+
.filter(Boolean)
|
|
449
|
+
.join(' · ');
|
|
450
|
+
this.message = `${theme_1.icons.ok} ${theme_1.theme.dim(`imported ${result.imported}${extras ? ` · ${extras}` : ''}`)}`;
|
|
451
|
+
}
|
|
452
|
+
this.input = null;
|
|
453
|
+
this.mode = 'browse';
|
|
454
|
+
}
|
|
455
|
+
catch (error) {
|
|
456
|
+
input.error = error.message;
|
|
457
|
+
}
|
|
458
|
+
this.render();
|
|
459
|
+
}
|
|
460
|
+
submitForm() {
|
|
461
|
+
const form = this.form;
|
|
462
|
+
const [name, command, directory, description] = form.fields.map((f) => f.value.trim());
|
|
463
|
+
const renaming = form.editing !== undefined && name !== form.editing;
|
|
464
|
+
const nameCheck = (0, commands_1.validateCommandName)(name);
|
|
465
|
+
if (nameCheck !== true) {
|
|
466
|
+
form.error = nameCheck;
|
|
467
|
+
form.active = 0;
|
|
468
|
+
return this.render();
|
|
469
|
+
}
|
|
470
|
+
if ((!form.editing || renaming) && (0, commands_1.commandExists)(name)) {
|
|
471
|
+
form.error = `"${name}" already exists — pick another name or edit it instead`;
|
|
472
|
+
form.active = 0;
|
|
473
|
+
return this.render();
|
|
474
|
+
}
|
|
475
|
+
if (!command) {
|
|
476
|
+
form.error = 'Command cannot be empty';
|
|
477
|
+
form.active = 1;
|
|
478
|
+
return this.render();
|
|
479
|
+
}
|
|
480
|
+
if (!directory) {
|
|
481
|
+
form.error = 'Directory cannot be empty';
|
|
482
|
+
form.active = 2;
|
|
483
|
+
return this.render();
|
|
484
|
+
}
|
|
485
|
+
const env = form.envChoice === 'none'
|
|
486
|
+
? undefined
|
|
487
|
+
: form.envChoice === 'keep'
|
|
488
|
+
? form.keepEnv
|
|
489
|
+
: (0, env_1.captureUserEnv)();
|
|
490
|
+
try {
|
|
491
|
+
if (renaming)
|
|
492
|
+
(0, commands_1.renameCommand)(form.editing, name);
|
|
493
|
+
(0, commands_1.saveCommand)({
|
|
494
|
+
name,
|
|
495
|
+
command,
|
|
496
|
+
directory,
|
|
497
|
+
description,
|
|
498
|
+
pathMode: form.pathMode,
|
|
499
|
+
env,
|
|
500
|
+
tags: form.keepTags,
|
|
501
|
+
steps: form.keepSteps,
|
|
502
|
+
});
|
|
503
|
+
(0, suggest_1.clearFromRawLog)(command);
|
|
504
|
+
this.message = `${theme_1.icons.ok} ${theme_1.theme.dim(renaming ? `renamed ${form.editing} → ${name}` : `saved ${name}`)}`;
|
|
505
|
+
const finalName = name;
|
|
506
|
+
this.form = null;
|
|
507
|
+
this.mode = 'browse';
|
|
508
|
+
this.refresh();
|
|
509
|
+
const index = this.visibleRows().findIndex((r) => r.name === finalName);
|
|
510
|
+
if (index >= 0)
|
|
511
|
+
this.selected = index;
|
|
141
512
|
}
|
|
142
513
|
catch (error) {
|
|
143
|
-
|
|
514
|
+
form.error = error.message;
|
|
144
515
|
}
|
|
516
|
+
this.render();
|
|
517
|
+
}
|
|
518
|
+
handleFormKey(str, key) {
|
|
519
|
+
const form = this.form;
|
|
520
|
+
const fieldCount = 6;
|
|
521
|
+
const isTextField = form.active < 4;
|
|
522
|
+
if (key.name === 'escape') {
|
|
523
|
+
this.form = null;
|
|
524
|
+
this.mode = 'browse';
|
|
525
|
+
this.message = theme_1.theme.faint('cancelled');
|
|
526
|
+
return this.render();
|
|
527
|
+
}
|
|
528
|
+
if (key.name === 'return') {
|
|
529
|
+
if (form.active < fieldCount - 1) {
|
|
530
|
+
form.active += 1;
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
return this.submitForm();
|
|
534
|
+
}
|
|
535
|
+
return this.render();
|
|
536
|
+
}
|
|
537
|
+
if (key.name === 'up' || (key.name === 'tab' && key.shift)) {
|
|
538
|
+
form.active = (form.active - 1 + fieldCount) % fieldCount;
|
|
539
|
+
return this.render();
|
|
540
|
+
}
|
|
541
|
+
if (key.name === 'down' || key.name === 'tab') {
|
|
542
|
+
form.active = (form.active + 1) % fieldCount;
|
|
543
|
+
return this.render();
|
|
544
|
+
}
|
|
545
|
+
if (isTextField) {
|
|
546
|
+
editText(form.fields[form.active], str, key);
|
|
547
|
+
form.error = '';
|
|
548
|
+
return this.render();
|
|
549
|
+
}
|
|
550
|
+
if (key.name === 'space' || key.name === 'left' || key.name === 'right') {
|
|
551
|
+
if (form.active === 4) {
|
|
552
|
+
form.pathMode = form.pathMode === 'saved' ? 'current' : 'saved';
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
const cycle = form.keepEnv ? ['keep', 'capture', 'none'] : ['none', 'capture'];
|
|
556
|
+
const next = (cycle.indexOf(form.envChoice) + 1) % cycle.length;
|
|
557
|
+
form.envChoice = cycle[next];
|
|
558
|
+
}
|
|
559
|
+
return this.render();
|
|
560
|
+
}
|
|
561
|
+
this.render();
|
|
562
|
+
}
|
|
563
|
+
handleKey(str, key) {
|
|
564
|
+
if (key.ctrl && key.name === 'c')
|
|
565
|
+
return this.finish(null);
|
|
566
|
+
if (this.mode === 'form')
|
|
567
|
+
return this.handleFormKey(str, key);
|
|
568
|
+
if (this.mode === 'input')
|
|
569
|
+
return this.handleInputKey(str, key);
|
|
570
|
+
if (this.mode === 'stats') {
|
|
571
|
+
this.mode = 'browse';
|
|
572
|
+
return this.render();
|
|
573
|
+
}
|
|
574
|
+
if (this.mode === 'confirm-delete') {
|
|
575
|
+
if (str === 'y') {
|
|
576
|
+
const row = this.visibleRows()[this.selected];
|
|
577
|
+
if (row) {
|
|
578
|
+
(0, commands_1.deleteCommand)(row.name);
|
|
579
|
+
this.message = `${theme_1.icons.ok} ${theme_1.theme.dim(`deleted ${row.name}`)}`;
|
|
580
|
+
this.refresh();
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
this.mode = 'browse';
|
|
584
|
+
return this.render();
|
|
585
|
+
}
|
|
586
|
+
if (this.mode === 'filter') {
|
|
587
|
+
if (key.name === 'escape') {
|
|
588
|
+
this.clearFilter();
|
|
589
|
+
this.mode = 'browse';
|
|
590
|
+
}
|
|
591
|
+
else if (key.name === 'return') {
|
|
592
|
+
this.mode = 'browse';
|
|
593
|
+
return this.selectRun();
|
|
594
|
+
}
|
|
595
|
+
else if (key.name === 'backspace') {
|
|
596
|
+
this.filter = this.filter.slice(0, -1);
|
|
597
|
+
}
|
|
598
|
+
else if (key.name === 'up')
|
|
599
|
+
this.move(-1);
|
|
600
|
+
else if (key.name === 'down')
|
|
601
|
+
this.move(1);
|
|
602
|
+
else if (str && str.length === 1 && !key.ctrl && !key.meta) {
|
|
603
|
+
this.filter += str;
|
|
604
|
+
this.selected = 0;
|
|
605
|
+
}
|
|
606
|
+
return this.render();
|
|
607
|
+
}
|
|
608
|
+
// browse mode
|
|
609
|
+
switch (key.name) {
|
|
610
|
+
case 'up':
|
|
611
|
+
case 'k':
|
|
612
|
+
this.move(-1);
|
|
613
|
+
break;
|
|
614
|
+
case 'down':
|
|
615
|
+
case 'j':
|
|
616
|
+
this.move(1);
|
|
617
|
+
break;
|
|
618
|
+
case 'return':
|
|
619
|
+
return this.selectRun();
|
|
620
|
+
case 'escape':
|
|
621
|
+
if (this.filter) {
|
|
622
|
+
this.clearFilter();
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
return this.finish(null);
|
|
626
|
+
default:
|
|
627
|
+
if (str === '/')
|
|
628
|
+
this.mode = 'filter';
|
|
629
|
+
else if (str === 'q')
|
|
630
|
+
return this.finish(null);
|
|
631
|
+
else if (str === 'n')
|
|
632
|
+
this.openForm();
|
|
633
|
+
else if (str === 'e') {
|
|
634
|
+
const row = this.visibleRows()[this.selected];
|
|
635
|
+
if (row?.project) {
|
|
636
|
+
this.message = theme_1.theme.warning(`⌂ project command — edit .aliasmate.json directly`);
|
|
637
|
+
}
|
|
638
|
+
else if (row) {
|
|
639
|
+
this.openForm({
|
|
640
|
+
name: row.name,
|
|
641
|
+
command: row.cmd.command,
|
|
642
|
+
directory: row.cmd.directory,
|
|
643
|
+
description: row.cmd.description,
|
|
644
|
+
pathMode: row.cmd.pathMode ?? 'saved',
|
|
645
|
+
env: row.cmd.env,
|
|
646
|
+
tags: row.cmd.tags,
|
|
647
|
+
steps: row.cmd.steps,
|
|
648
|
+
editing: row.name,
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
else if (str === 'd' && this.visibleRows().length > 0) {
|
|
653
|
+
if (this.visibleRows()[this.selected]?.project) {
|
|
654
|
+
this.message = theme_1.theme.warning(`⌂ project command — edit .aliasmate.json directly`);
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
this.mode = 'confirm-delete';
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
else if (str === 'a' && this.suggestion) {
|
|
661
|
+
this.openForm({ command: this.suggestion.command, directory: process.cwd() });
|
|
662
|
+
}
|
|
663
|
+
else if (str === 'c') {
|
|
664
|
+
const row = this.visibleRows()[this.selected];
|
|
665
|
+
if (row) {
|
|
666
|
+
const copied = (0, clipboard_1.copyToClipboard)(row.cmd.command);
|
|
667
|
+
this.message = copied
|
|
668
|
+
? `${theme_1.icons.ok} ${theme_1.theme.dim(`copied ${row.name}`)}`
|
|
669
|
+
: theme_1.theme.warning('no clipboard tool found');
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
else if (str === 'u') {
|
|
673
|
+
const label = (0, undo_1.undoLast)();
|
|
674
|
+
if (label) {
|
|
675
|
+
this.refresh();
|
|
676
|
+
this.message = `${theme_1.icons.ok} ${theme_1.theme.dim(`undid ${label}`)}`;
|
|
677
|
+
}
|
|
678
|
+
else {
|
|
679
|
+
this.message = theme_1.theme.faint('nothing to undo');
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
else if (str === 's')
|
|
683
|
+
this.mode = 'stats';
|
|
684
|
+
else if (str === 'x')
|
|
685
|
+
this.openInput('export');
|
|
686
|
+
else if (str === 'i')
|
|
687
|
+
this.openInput('import');
|
|
688
|
+
}
|
|
689
|
+
this.render();
|
|
690
|
+
}
|
|
691
|
+
selectRun() {
|
|
692
|
+
const row = this.visibleRows()[this.selected];
|
|
693
|
+
if (!row) {
|
|
694
|
+
this.message = theme_1.theme.dim('nothing selected');
|
|
695
|
+
return this.render();
|
|
696
|
+
}
|
|
697
|
+
this.finish({ kind: 'run', name: row.name });
|
|
698
|
+
}
|
|
699
|
+
finish(action) {
|
|
700
|
+
const resolve = this.resolve;
|
|
701
|
+
this.resolve = null;
|
|
702
|
+
resolve?.(action);
|
|
703
|
+
}
|
|
704
|
+
/** Show the TUI until the user runs a command or quits (null). */
|
|
705
|
+
waitForAction() {
|
|
706
|
+
return new Promise((resolve) => {
|
|
707
|
+
this.resolve = resolve;
|
|
708
|
+
this.render();
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
exports.Tui = Tui;
|
|
713
|
+
function enterScreen(onKey) {
|
|
714
|
+
process.stdout.write(ALT_SCREEN_ON);
|
|
715
|
+
readline.emitKeypressEvents(process.stdin);
|
|
716
|
+
if (process.stdin.isTTY)
|
|
717
|
+
process.stdin.setRawMode(true);
|
|
718
|
+
process.stdin.on('keypress', onKey);
|
|
719
|
+
process.stdin.resume();
|
|
720
|
+
return () => {
|
|
721
|
+
process.stdin.off('keypress', onKey);
|
|
722
|
+
if (process.stdin.isTTY)
|
|
723
|
+
process.stdin.setRawMode(false);
|
|
724
|
+
process.stdin.pause();
|
|
725
|
+
process.stdout.write(ALT_SCREEN_OFF);
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
/**
|
|
729
|
+
* The full-screen home: everything (browse, create, edit, delete, stats)
|
|
730
|
+
* happens in the TUI. Only running a command hands the terminal back so
|
|
731
|
+
* output lands in normal scrollback.
|
|
732
|
+
*/
|
|
733
|
+
async function interactiveHome(seed) {
|
|
734
|
+
const tui = new Tui();
|
|
735
|
+
if (seed)
|
|
736
|
+
tui.openForm(seed);
|
|
737
|
+
const onResize = () => tui.render();
|
|
738
|
+
const leave = enterScreen((s, k) => tui.handleKey(s, k));
|
|
739
|
+
process.stdout.on('resize', onResize);
|
|
740
|
+
let action;
|
|
741
|
+
try {
|
|
742
|
+
action = await tui.waitForAction();
|
|
743
|
+
}
|
|
744
|
+
finally {
|
|
745
|
+
process.stdout.off('resize', onResize);
|
|
746
|
+
leave();
|
|
747
|
+
}
|
|
748
|
+
if (action?.kind === 'run') {
|
|
749
|
+
const { runHandler } = await Promise.resolve().then(() => __importStar(require('../cli/run')));
|
|
750
|
+
await runHandler(action.name, undefined, {});
|
|
145
751
|
}
|
|
146
752
|
}
|
|
147
753
|
//# sourceMappingURL=interactive.js.map
|