@fnndsc/brasa 0.1.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/dist/builtins/debug.d.ts +8 -0
- package/dist/builtins/debug.js +39 -0
- package/dist/builtins/debug.js.map +1 -0
- package/dist/builtins/executable.d.ts +22 -0
- package/dist/builtins/executable.js +115 -0
- package/dist/builtins/executable.js.map +1 -0
- package/dist/builtins/fs/cat.d.ts +16 -0
- package/dist/builtins/fs/cat.js +266 -0
- package/dist/builtins/fs/cat.js.map +1 -0
- package/dist/builtins/fs/cd.d.ts +42 -0
- package/dist/builtins/fs/cd.js +193 -0
- package/dist/builtins/fs/cd.js.map +1 -0
- package/dist/builtins/fs/cp.d.ts +10 -0
- package/dist/builtins/fs/cp.js +86 -0
- package/dist/builtins/fs/cp.js.map +1 -0
- package/dist/builtins/fs/download.d.ts +6 -0
- package/dist/builtins/fs/download.js +45 -0
- package/dist/builtins/fs/download.js.map +1 -0
- package/dist/builtins/fs/du.d.ts +58 -0
- package/dist/builtins/fs/du.js +210 -0
- package/dist/builtins/fs/du.js.map +1 -0
- package/dist/builtins/fs/edit.d.ts +7 -0
- package/dist/builtins/fs/edit.js +104 -0
- package/dist/builtins/fs/edit.js.map +1 -0
- package/dist/builtins/fs/ls.d.ts +8 -0
- package/dist/builtins/fs/ls.js +68 -0
- package/dist/builtins/fs/ls.js.map +1 -0
- package/dist/builtins/fs/mkdir.d.ts +9 -0
- package/dist/builtins/fs/mkdir.js +52 -0
- package/dist/builtins/fs/mkdir.js.map +1 -0
- package/dist/builtins/fs/mv.d.ts +10 -0
- package/dist/builtins/fs/mv.js +88 -0
- package/dist/builtins/fs/mv.js.map +1 -0
- package/dist/builtins/fs/pull.args.d.ts +22 -0
- package/dist/builtins/fs/pull.args.js +30 -0
- package/dist/builtins/fs/pull.args.js.map +1 -0
- package/dist/builtins/fs/pull.d.ts +26 -0
- package/dist/builtins/fs/pull.js +445 -0
- package/dist/builtins/fs/pull.js.map +1 -0
- package/dist/builtins/fs/pwd.d.ts +10 -0
- package/dist/builtins/fs/pwd.js +73 -0
- package/dist/builtins/fs/pwd.js.map +1 -0
- package/dist/builtins/fs/rm.d.ts +37 -0
- package/dist/builtins/fs/rm.js +197 -0
- package/dist/builtins/fs/rm.js.map +1 -0
- package/dist/builtins/fs/touch.d.ts +9 -0
- package/dist/builtins/fs/touch.js +76 -0
- package/dist/builtins/fs/touch.js.map +1 -0
- package/dist/builtins/fs/tree.d.ts +15 -0
- package/dist/builtins/fs/tree.js +84 -0
- package/dist/builtins/fs/tree.js.map +1 -0
- package/dist/builtins/fs/upload.d.ts +6 -0
- package/dist/builtins/fs/upload.js +48 -0
- package/dist/builtins/fs/upload.js.map +1 -0
- package/dist/builtins/help.d.ts +74 -0
- package/dist/builtins/help.js +1217 -0
- package/dist/builtins/help.js.map +1 -0
- package/dist/builtins/index.d.ts +45 -0
- package/dist/builtins/index.js +45 -0
- package/dist/builtins/index.js.map +1 -0
- package/dist/builtins/net/connect.d.ts +7 -0
- package/dist/builtins/net/connect.js +42 -0
- package/dist/builtins/net/connect.js.map +1 -0
- package/dist/builtins/net/cubepath.d.ts +18 -0
- package/dist/builtins/net/cubepath.js +102 -0
- package/dist/builtins/net/cubepath.js.map +1 -0
- package/dist/builtins/net/logout.d.ts +6 -0
- package/dist/builtins/net/logout.js +24 -0
- package/dist/builtins/net/logout.js.map +1 -0
- package/dist/builtins/net/pacs.d.ts +24 -0
- package/dist/builtins/net/pacs.js +121 -0
- package/dist/builtins/net/pacs.js.map +1 -0
- package/dist/builtins/net/pacsUtils.d.ts +85 -0
- package/dist/builtins/net/pacsUtils.js +184 -0
- package/dist/builtins/net/pacsUtils.js.map +1 -0
- package/dist/builtins/net/query.d.ts +60 -0
- package/dist/builtins/net/query.js +324 -0
- package/dist/builtins/net/query.js.map +1 -0
- package/dist/builtins/parametersofplugin.d.ts +13 -0
- package/dist/builtins/parametersofplugin.js +43 -0
- package/dist/builtins/parametersofplugin.js.map +1 -0
- package/dist/builtins/pluginExecute.d.ts +27 -0
- package/dist/builtins/pluginExecute.js +165 -0
- package/dist/builtins/pluginExecute.js.map +1 -0
- package/dist/builtins/proc.d.ts +6 -0
- package/dist/builtins/proc.helpers.d.ts +68 -0
- package/dist/builtins/proc.helpers.js +102 -0
- package/dist/builtins/proc.helpers.js.map +1 -0
- package/dist/builtins/proc.js +289 -0
- package/dist/builtins/proc.js.map +1 -0
- package/dist/builtins/res/compute.d.ts +6 -0
- package/dist/builtins/res/compute.js +55 -0
- package/dist/builtins/res/compute.js.map +1 -0
- package/dist/builtins/res/feed.d.ts +6 -0
- package/dist/builtins/res/feed.js +244 -0
- package/dist/builtins/res/feed.js.map +1 -0
- package/dist/builtins/res/feed.notes.d.ts +28 -0
- package/dist/builtins/res/feed.notes.js +24 -0
- package/dist/builtins/res/feed.notes.js.map +1 -0
- package/dist/builtins/res/files.d.ts +18 -0
- package/dist/builtins/res/files.js +85 -0
- package/dist/builtins/res/files.js.map +1 -0
- package/dist/builtins/res/group.d.ts +6 -0
- package/dist/builtins/res/group.js +54 -0
- package/dist/builtins/res/group.js.map +1 -0
- package/dist/builtins/res/pipeline.args.d.ts +22 -0
- package/dist/builtins/res/pipeline.args.js +28 -0
- package/dist/builtins/res/pipeline.args.js.map +1 -0
- package/dist/builtins/res/pipeline.d.ts +20 -0
- package/dist/builtins/res/pipeline.js +252 -0
- package/dist/builtins/res/pipeline.js.map +1 -0
- package/dist/builtins/res/plugin.d.ts +13 -0
- package/dist/builtins/res/plugin.js +140 -0
- package/dist/builtins/res/plugin.js.map +1 -0
- package/dist/builtins/res/plugininstance.d.ts +6 -0
- package/dist/builtins/res/plugininstance.js +53 -0
- package/dist/builtins/res/plugininstance.js.map +1 -0
- package/dist/builtins/res/pluginmeta.d.ts +6 -0
- package/dist/builtins/res/pluginmeta.js +53 -0
- package/dist/builtins/res/pluginmeta.js.map +1 -0
- package/dist/builtins/res/tag.d.ts +6 -0
- package/dist/builtins/res/tag.js +53 -0
- package/dist/builtins/res/tag.js.map +1 -0
- package/dist/builtins/res/workflow.d.ts +6 -0
- package/dist/builtins/res/workflow.js +53 -0
- package/dist/builtins/res/workflow.js.map +1 -0
- package/dist/builtins/store.d.ts +6 -0
- package/dist/builtins/store.js +107 -0
- package/dist/builtins/store.js.map +1 -0
- package/dist/builtins/sys/context.d.ts +6 -0
- package/dist/builtins/sys/context.js +50 -0
- package/dist/builtins/sys/context.js.map +1 -0
- package/dist/builtins/sys/physicalmode.d.ts +8 -0
- package/dist/builtins/sys/physicalmode.js +34 -0
- package/dist/builtins/sys/physicalmode.js.map +1 -0
- package/dist/builtins/sys/timing.d.ts +8 -0
- package/dist/builtins/sys/timing.js +34 -0
- package/dist/builtins/sys/timing.js.map +1 -0
- package/dist/builtins/sys/version.d.ts +15 -0
- package/dist/builtins/sys/version.js +23 -0
- package/dist/builtins/sys/version.js.map +1 -0
- package/dist/builtins/sys/whoami.d.ts +17 -0
- package/dist/builtins/sys/whoami.js +44 -0
- package/dist/builtins/sys/whoami.js.map +1 -0
- package/dist/builtins/utils.d.ts +55 -0
- package/dist/builtins/utils.js +145 -0
- package/dist/builtins/utils.js.map +1 -0
- package/dist/builtins/wildcard.d.ts +26 -0
- package/dist/builtins/wildcard.js +120 -0
- package/dist/builtins/wildcard.js.map +1 -0
- package/dist/command-keys.d.ts +8 -0
- package/dist/command-keys.js +32 -0
- package/dist/command-keys.js.map +1 -0
- package/dist/config/storeConfig.d.ts +57 -0
- package/dist/config/storeConfig.js +78 -0
- package/dist/config/storeConfig.js.map +1 -0
- package/dist/core/chiliDelegate.d.ts +21 -0
- package/dist/core/chiliDelegate.js +32 -0
- package/dist/core/chiliDelegate.js.map +1 -0
- package/dist/core/connect.d.ts +38 -0
- package/dist/core/connect.js +46 -0
- package/dist/core/connect.js.map +1 -0
- package/dist/core/dispatch.d.ts +95 -0
- package/dist/core/dispatch.js +618 -0
- package/dist/core/dispatch.js.map +1 -0
- package/dist/core/engine.d.ts +91 -0
- package/dist/core/engine.js +222 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/preprocess.d.ts +46 -0
- package/dist/core/preprocess.js +146 -0
- package/dist/core/preprocess.js.map +1 -0
- package/dist/core/progress.d.ts +50 -0
- package/dist/core/progress.js +21 -0
- package/dist/core/progress.js.map +1 -0
- package/dist/core/promptContext.d.ts +49 -0
- package/dist/core/promptContext.js +39 -0
- package/dist/core/promptContext.js.map +1 -0
- package/dist/core/question.d.ts +27 -0
- package/dist/core/question.js +33 -0
- package/dist/core/question.js.map +1 -0
- package/dist/core/sink.d.ts +207 -0
- package/dist/core/sink.js +329 -0
- package/dist/core/sink.js.map +1 -0
- package/dist/core/surface.d.ts +172 -0
- package/dist/core/surface.js +105 -0
- package/dist/core/surface.js.map +1 -0
- package/dist/core/version.d.ts +20 -0
- package/dist/core/version.js +82 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/completer/index.d.ts +15 -0
- package/dist/lib/completer/index.js +212 -0
- package/dist/lib/completer/index.js.map +1 -0
- package/dist/lib/completer/pathComplete.helpers.d.ts +22 -0
- package/dist/lib/completer/pathComplete.helpers.js +49 -0
- package/dist/lib/completer/pathComplete.helpers.js.map +1 -0
- package/dist/lib/parser.d.ts +13 -0
- package/dist/lib/parser.js +52 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/pipe.d.ts +11 -0
- package/dist/lib/pipe.js +90 -0
- package/dist/lib/pipe.js.map +1 -0
- package/dist/lib/prefetch.d.ts +25 -0
- package/dist/lib/prefetch.js +64 -0
- package/dist/lib/prefetch.js.map +1 -0
- package/dist/lib/semicolonParser.d.ts +22 -0
- package/dist/lib/semicolonParser.js +53 -0
- package/dist/lib/semicolonParser.js.map +1 -0
- package/dist/lib/spinner.d.ts +23 -0
- package/dist/lib/spinner.js +71 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/vfs/providers/static.d.ts +65 -0
- package/dist/lib/vfs/providers/static.js +164 -0
- package/dist/lib/vfs/providers/static.js.map +1 -0
- package/dist/lib/vfs/providers/static_content.d.ts +27 -0
- package/dist/lib/vfs/providers/static_content.js +180 -0
- package/dist/lib/vfs/providers/static_content.js.map +1 -0
- package/dist/lib/vfs/vfs.d.ts +59 -0
- package/dist/lib/vfs/vfs.js +202 -0
- package/dist/lib/vfs/vfs.js.map +1 -0
- package/dist/session/index.d.ts +76 -0
- package/dist/session/index.js +120 -0
- package/dist/session/index.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file REPL Autocompletion.
|
|
3
|
+
*
|
|
4
|
+
* Provides tab-completion logic for the REPL, including built-in commands
|
|
5
|
+
* and path completion.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { session } from '../../session/index.js';
|
|
10
|
+
import { plugins_listAll, vfsDispatcher, context_getSingle } from '@fnndsc/salsa';
|
|
11
|
+
import { partialPath_split, completions_build } from './pathComplete.helpers.js';
|
|
12
|
+
import { listCache_get } from '@fnndsc/cumin';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import { builtinCommands_list } from '../../builtins/help.js';
|
|
15
|
+
import { args_tokenize } from '../parser.js';
|
|
16
|
+
function completionWord_get(line) {
|
|
17
|
+
let start = 0;
|
|
18
|
+
let quote = null;
|
|
19
|
+
let escapeNext = false;
|
|
20
|
+
for (let index = 0; index < line.length; index++) {
|
|
21
|
+
const char = line[index];
|
|
22
|
+
if (escapeNext) {
|
|
23
|
+
escapeNext = false;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (char === '\\' && quote !== "'") {
|
|
27
|
+
escapeNext = true;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if ((char === "'" || char === '"') && (!quote || quote === char)) {
|
|
31
|
+
quote = quote ? null : char;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (!quote && /\s/.test(char)) {
|
|
35
|
+
start = index + 1;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const raw = line.substring(start);
|
|
39
|
+
const tokens = args_tokenize(raw);
|
|
40
|
+
const value = tokens.length > 0 ? tokens[0] : '';
|
|
41
|
+
const openingQuote = raw.startsWith("'") ? "'" : raw.startsWith('"') ? '"' : null;
|
|
42
|
+
return { raw, value, quote: openingQuote };
|
|
43
|
+
}
|
|
44
|
+
function completion_format(completion, word) {
|
|
45
|
+
if (word.quote === "'") {
|
|
46
|
+
return `'${completion.replace(/'/g, `'\\''`)}`;
|
|
47
|
+
}
|
|
48
|
+
if (word.quote === '"') {
|
|
49
|
+
return `"${completion.replace(/(["\\])/g, '\\$1')}`;
|
|
50
|
+
}
|
|
51
|
+
return completion.replace(/([\\\s'"`])/g, '\\$1');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Fetches available plugin names from /bin in the format: name-vVersion.
|
|
55
|
+
* This matches the display format used in /bin listings.
|
|
56
|
+
* Uses cache first for fast completion.
|
|
57
|
+
* @returns Array of plugin names with version suffixes.
|
|
58
|
+
*/
|
|
59
|
+
async function plugins_getNames() {
|
|
60
|
+
try {
|
|
61
|
+
// Check cache first for /bin
|
|
62
|
+
const listCache = listCache_get();
|
|
63
|
+
const cached = listCache.cache_get('/bin');
|
|
64
|
+
if (cached && cached.data) {
|
|
65
|
+
// Return cached plugin names immediately
|
|
66
|
+
return cached.data.map((item) => item.name);
|
|
67
|
+
}
|
|
68
|
+
// Cache miss - fetch from API (only on first tab completion)
|
|
69
|
+
const plugins = await plugins_listAll({});
|
|
70
|
+
if (plugins && plugins.tableData) {
|
|
71
|
+
const pluginNames = plugins.tableData.map((p) => {
|
|
72
|
+
const name = typeof p.name === 'string' ? p.name : String(p.name ?? '');
|
|
73
|
+
const version = typeof p.version === 'string' ? p.version : String(p.version ?? '');
|
|
74
|
+
// Format as name-vVersion to match /bin display format
|
|
75
|
+
return version ? `${name}-v${version}` : name;
|
|
76
|
+
});
|
|
77
|
+
// Cache it for next time
|
|
78
|
+
const lsItems = plugins.tableData.map((p) => {
|
|
79
|
+
const name = typeof p.name === 'string' ? p.name : String(p.name ?? '');
|
|
80
|
+
const version = typeof p.version === 'string' ? p.version : String(p.version ?? '');
|
|
81
|
+
return {
|
|
82
|
+
name: version ? `${name}-v${version}` : name,
|
|
83
|
+
type: 'plugin',
|
|
84
|
+
size: 0,
|
|
85
|
+
owner: 'system',
|
|
86
|
+
date: p.creation_date ? String(p.creation_date) : '',
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
listCache.cache_set('/bin', lsItems);
|
|
90
|
+
return pluginNames;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
// Silently fail if plugins cannot be fetched
|
|
95
|
+
}
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Computes autocomplete suggestions for a given input line.
|
|
100
|
+
* Uses the callback style to support asynchronous operations (fetching files).
|
|
101
|
+
*
|
|
102
|
+
* @param line - The current input line.
|
|
103
|
+
* @param callback - The callback function to return results.
|
|
104
|
+
*/
|
|
105
|
+
export function input_complete(line, callback) {
|
|
106
|
+
const trimmed = line.trimStart();
|
|
107
|
+
const args = args_tokenize(trimmed);
|
|
108
|
+
// Case 1: Command Completion (First word)
|
|
109
|
+
// If we have only one token and the line doesn't end with space, we are typing the command
|
|
110
|
+
// Or if line is empty
|
|
111
|
+
const isCommandCompletion = args.length === 0 || (args.length === 1 && !line.endsWith(' '));
|
|
112
|
+
if (isCommandCompletion) {
|
|
113
|
+
// Check builtins first (instant, no async)
|
|
114
|
+
const builtinHits = builtinCommands_list().filter((c) => c.startsWith(trimmed));
|
|
115
|
+
// Always check plugins and combine results
|
|
116
|
+
plugins_getNames().then((pluginNames) => {
|
|
117
|
+
const pluginHits = pluginNames.filter((c) => c.startsWith(trimmed));
|
|
118
|
+
// Combine both builtins and plugins
|
|
119
|
+
const allHits = [...builtinHits, ...pluginHits];
|
|
120
|
+
callback(null, [allHits, trimmed]);
|
|
121
|
+
}).catch(() => {
|
|
122
|
+
// On error, return only builtin matches
|
|
123
|
+
callback(null, [builtinHits, trimmed]);
|
|
124
|
+
});
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// Case 2: Path Completion (Argument to specific commands)
|
|
128
|
+
const cmd = args[0];
|
|
129
|
+
if (['cd', 'ls', 'mkdir', 'touch', 'cat', 'edit', 'cp', 'mv', 'rm', 'upload', 'download', 'du', 'tree', 'pull', 'cubepath', 'query'].includes(cmd)) {
|
|
130
|
+
const word = completionWord_get(line);
|
|
131
|
+
path_complete(word.value).then((matches) => {
|
|
132
|
+
callback(null, [matches.map((match) => completion_format(match, word)), word.raw]);
|
|
133
|
+
}).catch((err) => {
|
|
134
|
+
// On error, return no matches, don't crash REPL
|
|
135
|
+
callback(null, [[], word.raw]);
|
|
136
|
+
});
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
// Default: no completion
|
|
140
|
+
callback(null, [[], line]);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Resolves directory contents for completion.
|
|
144
|
+
* @param partial - The partial path string typed so far.
|
|
145
|
+
*/
|
|
146
|
+
async function path_complete(partial) {
|
|
147
|
+
// 1. Handle ~ expansion for the partial path base
|
|
148
|
+
let effectivePartial = partial;
|
|
149
|
+
if (partial.startsWith('~')) {
|
|
150
|
+
const context = await context_getSingle();
|
|
151
|
+
const user = context.user;
|
|
152
|
+
const home = user ? `/home/${user}` : '/';
|
|
153
|
+
if (partial === '~' || partial === '~/') {
|
|
154
|
+
effectivePartial = home + (partial.endsWith('/') ? '/' : '');
|
|
155
|
+
}
|
|
156
|
+
else if (partial.startsWith('~/')) {
|
|
157
|
+
effectivePartial = path.posix.join(home, partial.substring(2));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Resolve the directory to list and the prefix to match
|
|
161
|
+
const { dirToList, prefix } = partialPath_split(effectivePartial);
|
|
162
|
+
// 2. Resolve absolute path for listing
|
|
163
|
+
let absDirToList;
|
|
164
|
+
if (dirToList.startsWith('/')) {
|
|
165
|
+
absDirToList = dirToList;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const cwd = await session.getCWD();
|
|
169
|
+
absDirToList = dirToList ? path.posix.resolve(cwd, dirToList) : cwd;
|
|
170
|
+
}
|
|
171
|
+
// 3. Fetch contents (check cache first)
|
|
172
|
+
let items = [];
|
|
173
|
+
const listCache = listCache_get();
|
|
174
|
+
// Check cache first
|
|
175
|
+
const cached = listCache.cache_get(absDirToList);
|
|
176
|
+
if (cached) {
|
|
177
|
+
items = cached.data;
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
try {
|
|
181
|
+
// Use vfsDispatcher for all path types — handles /pacs, /bin, native, etc.
|
|
182
|
+
const vfsResult = await vfsDispatcher.list(absDirToList);
|
|
183
|
+
if (vfsResult.ok) {
|
|
184
|
+
items = vfsResult.value;
|
|
185
|
+
}
|
|
186
|
+
// Inject virtual directories at root if missing
|
|
187
|
+
if (absDirToList === '/' || absDirToList === '') {
|
|
188
|
+
const hasItem = (name) => items.some((i) => i.name === name);
|
|
189
|
+
if (!hasItem('bin')) {
|
|
190
|
+
items.push({ name: 'bin', type: 'vfs', size: 0, owner: 'root', date: new Date().toISOString() });
|
|
191
|
+
}
|
|
192
|
+
if (!hasItem('usr')) {
|
|
193
|
+
items.push({ name: 'usr', type: 'vfs', size: 0, owner: 'root', date: new Date().toISOString() });
|
|
194
|
+
}
|
|
195
|
+
if (!hasItem('pacs')) {
|
|
196
|
+
items.push({ name: 'pacs', type: 'vfs', size: 0, owner: 'root', date: new Date().toISOString() });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Cache the results
|
|
200
|
+
if (items.length > 0) {
|
|
201
|
+
listCache.cache_set(absDirToList, items);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (e) {
|
|
205
|
+
// Ignore errors (e.g., perms, not a dir)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// 4. Filter and format matches, preserving the original partial's style
|
|
209
|
+
// (tilde/relative) and appending "/" to directory-like entries.
|
|
210
|
+
return completions_build(items, prefix, partial);
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/completer/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ListingItem } from '@fnndsc/chili/models/listing.js';
|
|
2
|
+
/**
|
|
3
|
+
* Splits an (already tilde-expanded) partial path into the directory to list
|
|
4
|
+
* and the basename prefix to match against.
|
|
5
|
+
*
|
|
6
|
+
* @param effectivePartial - The tilde-expanded partial path.
|
|
7
|
+
* @returns The directory to list (empty = cwd) and the prefix.
|
|
8
|
+
*/
|
|
9
|
+
export declare function partialPath_split(effectivePartial: string): {
|
|
10
|
+
dirToList: string;
|
|
11
|
+
prefix: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Builds completion strings from listing items, preserving the original
|
|
15
|
+
* partial's style (tilde/relative) and appending `/` to directory-like entries.
|
|
16
|
+
*
|
|
17
|
+
* @param items - The listing items in the target directory.
|
|
18
|
+
* @param prefix - The basename prefix being completed.
|
|
19
|
+
* @param partial - The original (unexpanded) partial the user typed.
|
|
20
|
+
* @returns The completion strings for matching items.
|
|
21
|
+
*/
|
|
22
|
+
export declare function completions_build(items: ListingItem[], prefix: string, partial: string): string[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pure helpers for filesystem path tab-completion.
|
|
3
|
+
*
|
|
4
|
+
* Splits a partial path into the directory to list and the prefix to match, and
|
|
5
|
+
* reconstructs completion strings from matching listing items. Dependency-free
|
|
6
|
+
* (path module only) for easy unit testing.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import path from 'path';
|
|
11
|
+
/**
|
|
12
|
+
* Splits an (already tilde-expanded) partial path into the directory to list
|
|
13
|
+
* and the basename prefix to match against.
|
|
14
|
+
*
|
|
15
|
+
* @param effectivePartial - The tilde-expanded partial path.
|
|
16
|
+
* @returns The directory to list (empty = cwd) and the prefix.
|
|
17
|
+
*/
|
|
18
|
+
export function partialPath_split(effectivePartial) {
|
|
19
|
+
if (effectivePartial.endsWith('/')) {
|
|
20
|
+
return { dirToList: effectivePartial, prefix: '' };
|
|
21
|
+
}
|
|
22
|
+
let dirToList = path.posix.dirname(effectivePartial);
|
|
23
|
+
const prefix = path.posix.basename(effectivePartial);
|
|
24
|
+
if (dirToList === '.')
|
|
25
|
+
dirToList = ''; // Relative current dir
|
|
26
|
+
return { dirToList, prefix };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds completion strings from listing items, preserving the original
|
|
30
|
+
* partial's style (tilde/relative) and appending `/` to directory-like entries.
|
|
31
|
+
*
|
|
32
|
+
* @param items - The listing items in the target directory.
|
|
33
|
+
* @param prefix - The basename prefix being completed.
|
|
34
|
+
* @param partial - The original (unexpanded) partial the user typed.
|
|
35
|
+
* @returns The completion strings for matching items.
|
|
36
|
+
*/
|
|
37
|
+
export function completions_build(items, prefix, partial) {
|
|
38
|
+
return items
|
|
39
|
+
.filter((i) => i.name.startsWith(prefix))
|
|
40
|
+
.map((hit) => {
|
|
41
|
+
const remainingSegment = hit.name.substring(prefix.length);
|
|
42
|
+
let completion = partial + remainingSegment;
|
|
43
|
+
if (hit.type === 'dir' || hit.type === 'vfs' || hit.type === 'link') {
|
|
44
|
+
completion += '/';
|
|
45
|
+
}
|
|
46
|
+
return completion;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=pathComplete.helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathComplete.helpers.js","sourceRoot":"","sources":["../../../src/lib/completer/pathComplete.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,gBAAwB;IACxD,IAAI,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACrD,CAAC;IACD,IAAI,SAAS,GAAW,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAW,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAC7D,IAAI,SAAS,KAAK,GAAG;QAAE,SAAS,GAAG,EAAE,CAAC,CAAC,uBAAuB;IAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAoB,EAAE,MAAc,EAAE,OAAe;IACrF,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;SACrD,GAAG,CAAC,CAAC,GAAgB,EAAE,EAAE;QACxB,MAAM,gBAAgB,GAAW,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACnE,IAAI,UAAU,GAAW,OAAO,GAAG,gBAAgB,CAAC;QACpD,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACpE,UAAU,IAAI,GAAG,CAAC;QACpB,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Command line argument tokenizer.
|
|
3
|
+
*
|
|
4
|
+
* Splits a command line into tokens while respecting single/double quotes
|
|
5
|
+
* and backslash escapes. Quotes are stripped from the resulting tokens.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Tokenizes a command line preserving quoted segments with spaces.
|
|
9
|
+
*
|
|
10
|
+
* @param line - Raw command line input.
|
|
11
|
+
* @returns Array of tokens with quotes removed.
|
|
12
|
+
*/
|
|
13
|
+
export declare function args_tokenize(line: string): string[];
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Command line argument tokenizer.
|
|
3
|
+
*
|
|
4
|
+
* Splits a command line into tokens while respecting single/double quotes
|
|
5
|
+
* and backslash escapes. Quotes are stripped from the resulting tokens.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Tokenizes a command line preserving quoted segments with spaces.
|
|
9
|
+
*
|
|
10
|
+
* @param line - Raw command line input.
|
|
11
|
+
* @returns Array of tokens with quotes removed.
|
|
12
|
+
*/
|
|
13
|
+
export function args_tokenize(line) {
|
|
14
|
+
const tokens = [];
|
|
15
|
+
let current = '';
|
|
16
|
+
let inSingle = false;
|
|
17
|
+
let inDouble = false;
|
|
18
|
+
let escapeNext = false;
|
|
19
|
+
for (let i = 0; i < line.length; i++) {
|
|
20
|
+
const char = line[i];
|
|
21
|
+
if (escapeNext) {
|
|
22
|
+
current += char;
|
|
23
|
+
escapeNext = false;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (char === '\\') {
|
|
27
|
+
escapeNext = true;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (char === "'" && !inDouble) {
|
|
31
|
+
inSingle = !inSingle;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (char === '"' && !inSingle) {
|
|
35
|
+
inDouble = !inDouble;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (!inSingle && !inDouble && /\s/.test(char)) {
|
|
39
|
+
if (current.length > 0) {
|
|
40
|
+
tokens.push(current);
|
|
41
|
+
current = '';
|
|
42
|
+
}
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
current += char;
|
|
46
|
+
}
|
|
47
|
+
if (current.length > 0) {
|
|
48
|
+
tokens.push(current);
|
|
49
|
+
}
|
|
50
|
+
return tokens;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAW,EAAE,CAAC;IACzB,IAAI,QAAQ,GAAY,KAAK,CAAC;IAC9B,IAAI,QAAQ,GAAY,KAAK,CAAC;IAC9B,IAAI,UAAU,GAAY,KAAK,CAAC;IAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAW,IAAI,CAAC,CAAC,CAAC,CAAC;QAE7B,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,IAAI,CAAC;YAChB,UAAU,GAAG,KAAK,CAAC;YACnB,SAAS;QACX,CAAC;QAED,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,UAAU,GAAG,IAAI,CAAC;YAClB,SAAS;QACX,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,QAAQ,GAAG,CAAC,QAAQ,CAAC;YACrB,SAAS;QACX,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,QAAQ,GAAG,CAAC,QAAQ,CAAC;YACrB,SAAS;QACX,CAAC;QAED,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACrB,OAAO,GAAG,EAAE,CAAC;YACf,CAAC;YACD,SAAS;QACX,CAAC;QAED,OAAO,IAAI,IAAI,CAAC;IAClB,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipes an input buffer through a spawned shell command and captures its stdout.
|
|
3
|
+
*
|
|
4
|
+
* Writes the input to the child's stdin with drain-aware backpressure handling,
|
|
5
|
+
* tolerates early-close EPIPE, and rejects on non-zero exit or spawn error.
|
|
6
|
+
*
|
|
7
|
+
* @param segment - The shell command to run (executed with `shell: true`).
|
|
8
|
+
* @param input - The data to write to the command's stdin.
|
|
9
|
+
* @returns The command's captured stdout.
|
|
10
|
+
*/
|
|
11
|
+
export declare function segment_pipeThrough(segment: string, input: Buffer): Promise<Buffer>;
|
package/dist/lib/pipe.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Process piping helper for shell command chains.
|
|
3
|
+
*
|
|
4
|
+
* Spawns a single shell segment, feeds it an input buffer (with backpressure
|
|
5
|
+
* handling), and resolves with its captured stdout.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { spawn } from 'child_process';
|
|
10
|
+
/**
|
|
11
|
+
* Pipes an input buffer through a spawned shell command and captures its stdout.
|
|
12
|
+
*
|
|
13
|
+
* Writes the input to the child's stdin with drain-aware backpressure handling,
|
|
14
|
+
* tolerates early-close EPIPE, and rejects on non-zero exit or spawn error.
|
|
15
|
+
*
|
|
16
|
+
* @param segment - The shell command to run (executed with `shell: true`).
|
|
17
|
+
* @param input - The data to write to the command's stdin.
|
|
18
|
+
* @returns The command's captured stdout.
|
|
19
|
+
*/
|
|
20
|
+
export function segment_pipeThrough(segment, input) {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
const chunks = [];
|
|
23
|
+
// When using shell: true, pass the entire command as a single string
|
|
24
|
+
const child = spawn(segment, {
|
|
25
|
+
stdio: ['pipe', 'pipe', 'inherit'],
|
|
26
|
+
shell: true,
|
|
27
|
+
});
|
|
28
|
+
child.stdout.on('data', (chunk) => {
|
|
29
|
+
chunks.push(chunk);
|
|
30
|
+
});
|
|
31
|
+
child.on('close', (code) => {
|
|
32
|
+
if (code !== 0 && code !== null) {
|
|
33
|
+
reject(new Error(`Command '${segment}' exited with code ${code}`));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
resolve(Buffer.concat(chunks));
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
child.on('error', (err) => {
|
|
40
|
+
reject(err);
|
|
41
|
+
});
|
|
42
|
+
// Handle EPIPE errors when child closes stdin early
|
|
43
|
+
child.stdin.on('error', (err) => {
|
|
44
|
+
if (err.code === 'EPIPE') {
|
|
45
|
+
// Child closed stdin, this is normal if it exits early — handled by 'close'.
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
reject(err);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* Writes all buffered data to child stdin with backpressure handling.
|
|
53
|
+
* Splits large buffers into chunks and waits for drain events when needed.
|
|
54
|
+
*/
|
|
55
|
+
const data_writeAll = async () => {
|
|
56
|
+
if (input.length === 0) {
|
|
57
|
+
child.stdin.end();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
return new Promise((resolveWrite, rejectWrite) => {
|
|
61
|
+
let offset = 0;
|
|
62
|
+
const chunkSize = 64 * 1024; // 64KB chunks
|
|
63
|
+
const chunk_writeNext = () => {
|
|
64
|
+
try {
|
|
65
|
+
while (offset < input.length) {
|
|
66
|
+
const end = Math.min(offset + chunkSize, input.length);
|
|
67
|
+
const chunk = input.subarray(offset, end);
|
|
68
|
+
offset = end;
|
|
69
|
+
const canContinue = child.stdin.write(chunk);
|
|
70
|
+
if (!canContinue) {
|
|
71
|
+
child.stdin.once('drain', chunk_writeNext);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
child.stdin.end();
|
|
76
|
+
resolveWrite();
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
rejectWrite(err);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
chunk_writeNext();
|
|
83
|
+
});
|
|
84
|
+
};
|
|
85
|
+
// Start writing in parallel with reading output; ignore write errors if the
|
|
86
|
+
// child already closed (EPIPE is handled by the stdin error handler).
|
|
87
|
+
data_writeAll().catch(() => { });
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=pipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipe.js","sourceRoot":"","sources":["../../src/lib/pipe.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,KAAK,EAAqB,MAAM,eAAe,CAAC;AAEzD;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe,EAAE,KAAa;IAChE,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,qEAAqE;QACrE,MAAM,KAAK,GAAiB,KAAK,CAAC,OAAO,EAAE;YACzC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC;YAClC,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,KAAK,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAmB,EAAE,EAAE;YACxC,IAAI,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,OAAO,sBAAsB,IAAI,EAAE,CAAC,CAAC,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;YACjC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAC/B,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,oDAAoD;QACpD,KAAK,CAAC,KAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;YACtD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACzB,6EAA6E;YAC/E,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;QAEH;;;WAGG;QACH,MAAM,aAAa,GAAG,KAAK,IAAmB,EAAE;YAC9C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,KAAK,CAAC,KAAM,CAAC,GAAG,EAAE,CAAC;gBACnB,OAAO;YACT,CAAC;YAED,OAAO,IAAI,OAAO,CAAO,CAAC,YAAmC,EAAE,WAAoC,EAAE,EAAE;gBACrG,IAAI,MAAM,GAAW,CAAC,CAAC;gBACvB,MAAM,SAAS,GAAW,EAAE,GAAG,IAAI,CAAC,CAAC,cAAc;gBAEnD,MAAM,eAAe,GAAG,GAAS,EAAE;oBACjC,IAAI,CAAC;wBACH,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;4BAC7B,MAAM,GAAG,GAAW,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;4BAC/D,MAAM,KAAK,GAAW,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;4BAClD,MAAM,GAAG,GAAG,CAAC;4BAEb,MAAM,WAAW,GAAY,KAAK,CAAC,KAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;4BACvD,IAAI,CAAC,WAAW,EAAE,CAAC;gCACjB,KAAK,CAAC,KAAM,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gCAC5C,OAAO;4BACT,CAAC;wBACH,CAAC;wBACD,KAAK,CAAC,KAAM,CAAC,GAAG,EAAE,CAAC;wBACnB,YAAY,EAAE,CAAC;oBACjB,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACtB,WAAW,CAAC,GAAY,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC,CAAC;gBAEF,eAAe,EAAE,CAAC;YACpB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,4EAA4E;QAC5E,sEAAsE;QACtE,aAAa,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Outcome of a prefetch operation (counts and status).
|
|
3
|
+
*/
|
|
4
|
+
export interface PrefetchResult {
|
|
5
|
+
ok: boolean;
|
|
6
|
+
count?: number;
|
|
7
|
+
pipelineCount?: number;
|
|
8
|
+
message?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Prefetch a VFS path into the list cache.
|
|
12
|
+
*
|
|
13
|
+
* @param target - Absolute VFS path to prefetch.
|
|
14
|
+
* @returns Count of items cached on success, error message on failure.
|
|
15
|
+
*/
|
|
16
|
+
export declare function prefetch_path(target: string): Promise<PrefetchResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Run a prefetch action behind a spinner (interactive) or plain log (non-interactive).
|
|
19
|
+
*
|
|
20
|
+
* @param label - Short label shown in the spinner column (padded to 12 chars).
|
|
21
|
+
* @param message - Descriptive message shown next to the label.
|
|
22
|
+
* @param isInteractive - Whether the session is interactive (controls spinner vs plain log).
|
|
23
|
+
* @param action - Async work to run; returns a PrefetchResult.
|
|
24
|
+
*/
|
|
25
|
+
export declare function prefetch_withSpinner(label: string, message: string, isInteractive: boolean, action: () => Promise<PrefetchResult>): Promise<PrefetchResult>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Boot-time prefetch helpers for warming the VFS cache.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from chell_start() to keep that fn focused on orchestration.
|
|
5
|
+
* All functions are pure top-level — no closure over session state.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import { errorStack } from '@fnndsc/cumin';
|
|
10
|
+
import { vfs } from './vfs/vfs.js';
|
|
11
|
+
import { spinner } from './spinner.js';
|
|
12
|
+
import { error_stripDebugPrefix } from '../builtins/index.js';
|
|
13
|
+
/**
|
|
14
|
+
* Prefetch a VFS path into the list cache.
|
|
15
|
+
*
|
|
16
|
+
* @param target - Absolute VFS path to prefetch.
|
|
17
|
+
* @returns Count of items cached on success, error message on failure.
|
|
18
|
+
*/
|
|
19
|
+
export async function prefetch_path(target) {
|
|
20
|
+
try {
|
|
21
|
+
const result = await vfs.data_get(target);
|
|
22
|
+
if (result.ok) {
|
|
23
|
+
return { ok: true, count: result.value.length };
|
|
24
|
+
}
|
|
25
|
+
const err = errorStack.stack_pop();
|
|
26
|
+
return { ok: false, message: err ? error_stripDebugPrefix(err.message) : `Prefetch failed for ${target}` };
|
|
27
|
+
}
|
|
28
|
+
catch (e) {
|
|
29
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
30
|
+
return { ok: false, message: msg };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Run a prefetch action behind a spinner (interactive) or plain log (non-interactive).
|
|
35
|
+
*
|
|
36
|
+
* @param label - Short label shown in the spinner column (padded to 12 chars).
|
|
37
|
+
* @param message - Descriptive message shown next to the label.
|
|
38
|
+
* @param isInteractive - Whether the session is interactive (controls spinner vs plain log).
|
|
39
|
+
* @param action - Async work to run; returns a PrefetchResult.
|
|
40
|
+
*/
|
|
41
|
+
export async function prefetch_withSpinner(label, message, isInteractive, action) {
|
|
42
|
+
const paddedLabel = label.padEnd(12);
|
|
43
|
+
// Spinner adds its own glyph and a following space. Pad so the label column
|
|
44
|
+
// aligns with the fixed-width status logs (e.g., "[ OK ] " = 7 chars).
|
|
45
|
+
const spinnerPrefix = ' '.repeat(5); // 1 glyph + 1 space + 5 = 7
|
|
46
|
+
const spinnerMessage = `${spinnerPrefix}${paddedLabel} ${message}`;
|
|
47
|
+
const showSpinner = isInteractive && process.stdout.isTTY;
|
|
48
|
+
if (showSpinner) {
|
|
49
|
+
spinner.start(spinnerMessage, true);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.log(spinnerMessage);
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
return await action();
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
if (showSpinner) {
|
|
59
|
+
spinner.stop();
|
|
60
|
+
process.stdout.write('\r\x1b[K');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=prefetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prefetch.js","sourceRoot":"","sources":["../../src/lib/prefetch.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAY9D;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAc;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAClD,CAAC;QACD,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;QACnC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,uBAAuB,MAAM,EAAE,EAAE,CAAC;IAC7G,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,MAAM,GAAG,GAAW,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IACrC,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAa,EACb,OAAe,EACf,aAAsB,EACtB,MAAqC;IAErC,MAAM,WAAW,GAAW,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC7C,4EAA4E;IAC5E,uEAAuE;IACvE,MAAM,aAAa,GAAW,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,4BAA4B;IACzE,MAAM,cAAc,GAAW,GAAG,aAAa,GAAG,WAAW,IAAI,OAAO,EAAE,CAAC;IAC3E,MAAM,WAAW,GAAY,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IAEnE,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,EAAE,CAAC;IACxB,CAAC;YAAS,CAAC;QACT,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Semicolon command parser
|
|
3
|
+
*
|
|
4
|
+
* Parses semicolon-separated commands while respecting quotes.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Parses a command line for semicolon separators and returns individual commands.
|
|
10
|
+
* Respects quoted strings - semicolons inside quotes are not treated as separators.
|
|
11
|
+
*
|
|
12
|
+
* @param line - The full command line.
|
|
13
|
+
* @returns An array of individual commands.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* semicolons_parse("ls; pwd") // Returns: ["ls", "pwd"]
|
|
18
|
+
* semicolons_parse("echo 'a;b'; pwd") // Returns: ["echo 'a;b'", "pwd"]
|
|
19
|
+
* semicolons_parse("cd /tmp; ls; cat file.txt") // Returns: ["cd /tmp", "ls", "cat file.txt"]
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function semicolons_parse(line: string): string[];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Semicolon command parser
|
|
3
|
+
*
|
|
4
|
+
* Parses semicolon-separated commands while respecting quotes.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Parses a command line for semicolon separators and returns individual commands.
|
|
10
|
+
* Respects quoted strings - semicolons inside quotes are not treated as separators.
|
|
11
|
+
*
|
|
12
|
+
* @param line - The full command line.
|
|
13
|
+
* @returns An array of individual commands.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* semicolons_parse("ls; pwd") // Returns: ["ls", "pwd"]
|
|
18
|
+
* semicolons_parse("echo 'a;b'; pwd") // Returns: ["echo 'a;b'", "pwd"]
|
|
19
|
+
* semicolons_parse("cd /tmp; ls; cat file.txt") // Returns: ["cd /tmp", "ls", "cat file.txt"]
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export function semicolons_parse(line) {
|
|
23
|
+
const commands = [];
|
|
24
|
+
let currentCommand = '';
|
|
25
|
+
let inSingleQuote = false;
|
|
26
|
+
let inDoubleQuote = false;
|
|
27
|
+
for (let i = 0; i < line.length; i++) {
|
|
28
|
+
const char = line[i];
|
|
29
|
+
if (char === "'" && !inDoubleQuote) {
|
|
30
|
+
inSingleQuote = !inSingleQuote;
|
|
31
|
+
currentCommand += char;
|
|
32
|
+
}
|
|
33
|
+
else if (char === '"' && !inSingleQuote) {
|
|
34
|
+
inDoubleQuote = !inDoubleQuote;
|
|
35
|
+
currentCommand += char;
|
|
36
|
+
}
|
|
37
|
+
else if (char === ';' && !inSingleQuote && !inDoubleQuote) {
|
|
38
|
+
const trimmed = currentCommand.trim();
|
|
39
|
+
if (trimmed)
|
|
40
|
+
commands.push(trimmed);
|
|
41
|
+
currentCommand = '';
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
currentCommand += char;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Add final command
|
|
48
|
+
const trimmed = currentCommand.trim();
|
|
49
|
+
if (trimmed)
|
|
50
|
+
commands.push(trimmed);
|
|
51
|
+
return commands;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=semicolonParser.js.map
|