fauxnix-cli 0.9.3 → 0.12.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/README.md +84 -26
- package/dist/ast.d.ts +38 -3
- package/dist/ast.js +22 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +84 -20
- package/dist/commands/archive.d.ts +2 -1
- package/dist/commands/archive.js +169 -25
- package/dist/commands/install-all.js +4 -2
- package/dist/commands/net.d.ts +9 -0
- package/dist/commands/net.js +51 -15
- package/dist/commands/sysinfo.d.ts +2 -1
- package/dist/commands/sysinfo.js +610 -82
- package/dist/commands/text-filters.d.ts +1 -0
- package/dist/commands/text-filters.js +99 -13
- package/dist/commands/text-io.js +72 -43
- package/dist/doctor.d.ts +21 -0
- package/dist/doctor.js +292 -0
- package/dist/errors.js +14 -4
- package/dist/executor.d.ts +4 -1
- package/dist/executor.js +194 -51
- package/dist/install.d.ts +15 -0
- package/dist/install.js +247 -0
- package/dist/mcp.d.ts +19 -0
- package/dist/mcp.js +49 -26
- package/dist/parser.js +432 -35
- package/dist/powershell.d.ts +22 -0
- package/dist/powershell.js +129 -0
- package/dist/ps-host.d.ts +41 -13
- package/dist/ps-host.js +302 -40
- package/dist/qwen-launch.d.ts +12 -0
- package/dist/qwen-launch.js +29 -0
- package/dist/registry.d.ts +22 -0
- package/dist/registry.js +109 -1
- package/dist/translator.d.ts +42 -9
- package/dist/translator.js +697 -95
- package/package.json +3 -1
package/dist/registry.js
CHANGED
|
@@ -154,6 +154,92 @@ export function parseWords(args, shortValues = [], longValues = []) {
|
|
|
154
154
|
return { flags, longs, values, missingValue, operandWords };
|
|
155
155
|
}
|
|
156
156
|
const specs = new Map();
|
|
157
|
+
/**
|
|
158
|
+
* C-5's curated agent-daily command set. Keep this explicit: a raw count of
|
|
159
|
+
* CommandSpecs is not enough to prove that the commands agents use every day
|
|
160
|
+
* are the ones protected by fail-loud option validation.
|
|
161
|
+
*/
|
|
162
|
+
export const AGENT_DAILY_60 = [
|
|
163
|
+
'basename',
|
|
164
|
+
'cat',
|
|
165
|
+
'cd',
|
|
166
|
+
'chmod',
|
|
167
|
+
'chown',
|
|
168
|
+
'clear',
|
|
169
|
+
'command',
|
|
170
|
+
'cp',
|
|
171
|
+
'cut',
|
|
172
|
+
'date',
|
|
173
|
+
'df',
|
|
174
|
+
'diff',
|
|
175
|
+
'dirname',
|
|
176
|
+
'du',
|
|
177
|
+
'echo',
|
|
178
|
+
'env',
|
|
179
|
+
'export',
|
|
180
|
+
'file',
|
|
181
|
+
'free',
|
|
182
|
+
'grep',
|
|
183
|
+
'groups',
|
|
184
|
+
'gunzip',
|
|
185
|
+
'gzip',
|
|
186
|
+
'head',
|
|
187
|
+
'hostname',
|
|
188
|
+
'id',
|
|
189
|
+
'll',
|
|
190
|
+
'ln',
|
|
191
|
+
'ls',
|
|
192
|
+
'mkdir',
|
|
193
|
+
'mktemp',
|
|
194
|
+
'mv',
|
|
195
|
+
'nproc',
|
|
196
|
+
'printenv',
|
|
197
|
+
'printf',
|
|
198
|
+
'ps',
|
|
199
|
+
'pwd',
|
|
200
|
+
'readlink',
|
|
201
|
+
'realpath',
|
|
202
|
+
'rm',
|
|
203
|
+
'rmdir',
|
|
204
|
+
'sleep',
|
|
205
|
+
'sort',
|
|
206
|
+
'stat',
|
|
207
|
+
'tail',
|
|
208
|
+
'tee',
|
|
209
|
+
'timeout',
|
|
210
|
+
'touch',
|
|
211
|
+
'tr',
|
|
212
|
+
'type',
|
|
213
|
+
'uname',
|
|
214
|
+
'uniq',
|
|
215
|
+
'unset',
|
|
216
|
+
'unzip',
|
|
217
|
+
'uptime',
|
|
218
|
+
'wc',
|
|
219
|
+
'which',
|
|
220
|
+
'whoami',
|
|
221
|
+
'zcat',
|
|
222
|
+
'zip',
|
|
223
|
+
];
|
|
224
|
+
/** Commands deliberately kept outside generic CommandSpec option walking. */
|
|
225
|
+
export const COMMAND_SPEC_EXCLUSIONS = [
|
|
226
|
+
{
|
|
227
|
+
names: ['find'],
|
|
228
|
+
reason: 'option-looking predicates are parsed by the find expression compiler; generic short-option bundling would misread -name',
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
names: ['sed', 'awk'],
|
|
232
|
+
reason: 'program text and option grammar require command-specific parsing; any remaining unchecked options must be fixed there rather than treated as generic flags',
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
names: ['egrep'],
|
|
236
|
+
reason: 'semantic alias injects grep -E through its own handler; it must not be wrapped as an independent generic option parser',
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
names: ['tar'],
|
|
240
|
+
reason: 'argv is passed to Windows bsdtar; rejecting unlisted GNU/bsdtar options before native dispatch would reduce compatibility',
|
|
241
|
+
},
|
|
242
|
+
];
|
|
157
243
|
/** Register a spec'd command. Unknown/unsupported options become GNU-style usage errors. */
|
|
158
244
|
export function registerSpec(spec) {
|
|
159
245
|
for (const name of spec.names) {
|
|
@@ -188,11 +274,30 @@ export function registeredSpecs() {
|
|
|
188
274
|
}
|
|
189
275
|
/** Markdown dump of every CommandSpec — source for docs/command-specs.md. */
|
|
190
276
|
export function specsMarkdown() {
|
|
277
|
+
const dailySpecd = AGENT_DAILY_60.filter((name) => lookupSpec(name));
|
|
278
|
+
const dailyMissing = AGENT_DAILY_60.filter((name) => !lookupSpec(name));
|
|
191
279
|
const lines = [
|
|
192
280
|
'# Command specs',
|
|
193
281
|
'',
|
|
194
282
|
'Generated from `CommandSpec`. Unlisted commands still use unchecked `parseWords` (unknown flags ignored). Spec\'d commands fail loud on unknown or unsupported options.',
|
|
195
283
|
'',
|
|
284
|
+
'## Agent-daily 60 (C-5)',
|
|
285
|
+
'',
|
|
286
|
+
'Curated command names: ' + AGENT_DAILY_60.map((name) => '`' + name + '`').join(', '),
|
|
287
|
+
'',
|
|
288
|
+
'Coverage: **' + dailySpecd.length + ' / ' + AGENT_DAILY_60.length + ' spec\'d**.',
|
|
289
|
+
'',
|
|
290
|
+
...(dailyMissing.length
|
|
291
|
+
? ['Missing specs: ' + dailyMissing.map((name) => '`' + name + '`').join(', '), '']
|
|
292
|
+
: []),
|
|
293
|
+
'## Intentional CommandSpec exclusions',
|
|
294
|
+
'',
|
|
295
|
+
'These commands stay outside the generic option walker by design. This is a structural rationale, not a claim that every command-specific option path is already strict.',
|
|
296
|
+
'',
|
|
297
|
+
'| Command | Rationale |',
|
|
298
|
+
'| --- | --- |',
|
|
299
|
+
...COMMAND_SPEC_EXCLUSIONS.map((entry) => '| ' + entry.names.map((name) => '`' + name + '`').join(', ') + ' | ' + entry.reason + ' |'),
|
|
300
|
+
'',
|
|
196
301
|
];
|
|
197
302
|
for (const spec of registeredSpecs()) {
|
|
198
303
|
lines.push('## `' + spec.names.join('` / `') + '`');
|
|
@@ -296,7 +401,10 @@ export function specOptionError(spec, args, cmdName) {
|
|
|
296
401
|
i++;
|
|
297
402
|
continue;
|
|
298
403
|
}
|
|
299
|
-
|
|
404
|
+
const firstShort = t.slice(1, 2);
|
|
405
|
+
if (t.startsWith('-') &&
|
|
406
|
+
t.length > 1 &&
|
|
407
|
+
(!/^\d$/.test(firstShort) || shorts.has(firstShort))) {
|
|
300
408
|
const body = t.slice(1);
|
|
301
409
|
for (let c = 0; c < body.length; c++) {
|
|
302
410
|
const ch = body[c];
|
package/dist/translator.d.ts
CHANGED
|
@@ -1,12 +1,42 @@
|
|
|
1
|
-
import { Assignment, CommandList, Redirect, SimpleCommand, IfCommand, ForCommand, Word, WordPart } from './ast.js';
|
|
1
|
+
import { Assignment, CommandList, Redirect, SimpleCommand, IfCommand, ForCommand, WhileCommand, CaseCommand, Word, WordPart } from './ast.js';
|
|
2
2
|
import { PipelineCtx } from './registry.js';
|
|
3
|
+
export interface TranslationContext {
|
|
4
|
+
/** `pure` renders a script without consulting command operands on disk. */
|
|
5
|
+
mode: 'execute' | 'pure';
|
|
6
|
+
}
|
|
7
|
+
export declare const EXECUTE_TRANSLATION: TranslationContext;
|
|
8
|
+
export declare const PURE_TRANSLATION: TranslationContext;
|
|
9
|
+
export declare const PURE_SED_FILE_MESSAGE = "fauxnix: translate does not read sed script files; use -e with the script text, or run the command to use -f";
|
|
3
10
|
/** `${name:-word}` and friends using case-exact fx-scalar0. */
|
|
4
11
|
export declare function paramExpr(name: string, op: ':-' | ':=' | ':+' | ':?' | '-' | '+' | '?', word: string): string;
|
|
12
|
+
export declare function varExtraOf(p: WordPart): {
|
|
13
|
+
replace?: {
|
|
14
|
+
global: boolean;
|
|
15
|
+
pat: string;
|
|
16
|
+
repl: string;
|
|
17
|
+
};
|
|
18
|
+
slice?: {
|
|
19
|
+
offset: string;
|
|
20
|
+
length?: string;
|
|
21
|
+
};
|
|
22
|
+
} | undefined;
|
|
5
23
|
/** Map a bash $VAR name to a PowerShell expression (usable inside $(...)). */
|
|
6
24
|
export declare function varExpr(name: string, index?: string, param?: {
|
|
7
25
|
op: ':-' | ':=' | ':+' | ':?' | '-' | '+' | '?';
|
|
8
26
|
word: string;
|
|
9
|
-
}, length?: boolean
|
|
27
|
+
}, length?: boolean, extra?: {
|
|
28
|
+
replace?: {
|
|
29
|
+
global: boolean;
|
|
30
|
+
pat: string;
|
|
31
|
+
repl: string;
|
|
32
|
+
};
|
|
33
|
+
slice?: {
|
|
34
|
+
offset: string;
|
|
35
|
+
length?: string;
|
|
36
|
+
};
|
|
37
|
+
}): string;
|
|
38
|
+
/** `$?` `$$` `$0`–`$n` `$#` `$@` `$*` — not ordinary `$env:` names. */
|
|
39
|
+
export declare function isSpecialShellVar(name: string): boolean;
|
|
10
40
|
/** Escape text destined for the inside of a PS double-quoted string. */
|
|
11
41
|
export declare function escapeDq(s: string): string;
|
|
12
42
|
/** Normalize a literal POSIX-ish path to its Windows equivalent. */
|
|
@@ -39,6 +69,7 @@ export declare function operandExpr(w: Word): string;
|
|
|
39
69
|
/**
|
|
40
70
|
* `${name[@]}` / `"pre${name[@]}post"` — one argv per element.
|
|
41
71
|
* Unquoted `${name[*]}` also splats (bash); quoted `"${name[*]}"` stays one join.
|
|
72
|
+
* `$@` / unquoted `$*` splat like `${arr[@]}`; quoted `"$@"` still splats.
|
|
42
73
|
*/
|
|
43
74
|
export declare function splatSpec(w: Word): {
|
|
44
75
|
name: string;
|
|
@@ -53,9 +84,11 @@ export declare function argListExpr(words: Word[], fn?: (w: Word) => string): st
|
|
|
53
84
|
* Unquoted command words join non-empty lines with a space (IFS
|
|
54
85
|
* word-split approximation). Handlers often emit one string object, so
|
|
55
86
|
* a bare `$(…)` interpolation would keep those newlines.
|
|
87
|
+
* Lists (`;` `&&` `||`) reuse translateListInline inside the fx-csub
|
|
88
|
+
* scriptblock so the newline contract is unchanged.
|
|
56
89
|
*/
|
|
57
|
-
export declare function translateCmdSub(cmdText: string, keepNl?: boolean): string;
|
|
58
|
-
export declare function translateSimple(cmd: SimpleCommand, position: PipelineCtx['position'], hasStdin: boolean): string;
|
|
90
|
+
export declare function translateCmdSub(cmdText: string, keepNl?: boolean, translation?: TranslationContext): string;
|
|
91
|
+
export declare function translateSimple(cmd: SimpleCommand, position: PipelineCtx['position'], hasStdin: boolean, translation?: TranslationContext): string;
|
|
59
92
|
/** PS expr: encode a string so SETVALS records can stay newline-delimited. */
|
|
60
93
|
export declare function encodeSetValExpr(srcExpr: string): string;
|
|
61
94
|
/**
|
|
@@ -76,11 +109,11 @@ export interface PipelineParts {
|
|
|
76
109
|
call: string;
|
|
77
110
|
}
|
|
78
111
|
export declare function translatePipelineBody(p: {
|
|
79
|
-
commands: Array<SimpleCommand | IfCommand | ForCommand>;
|
|
80
|
-
}): PipelineParts;
|
|
112
|
+
commands: Array<SimpleCommand | IfCommand | ForCommand | WhileCommand | CaseCommand>;
|
|
113
|
+
}, translation?: TranslationContext): PipelineParts;
|
|
81
114
|
export interface SegmentPlan {
|
|
82
115
|
op: ';' | '&&' | '||';
|
|
83
|
-
/** Spawn-mode wrapScript (
|
|
116
|
+
/** Spawn-mode wrapScript (`translate` output for a one-shot PowerShell process). */
|
|
84
117
|
script: string;
|
|
85
118
|
/** Pipeline body before wrapScript — executor host mode re-wraps this. */
|
|
86
119
|
body: string;
|
|
@@ -91,7 +124,7 @@ export interface SegmentPlan {
|
|
|
91
124
|
/** First-stage `<` only — FAUXNIX_STDIN_FILE feed. */
|
|
92
125
|
stdinRedirects: Redirect[];
|
|
93
126
|
}
|
|
94
|
-
export declare function translateCommandList(list: CommandList): SegmentPlan[];
|
|
127
|
+
export declare function translateCommandList(list: CommandList, translation?: TranslationContext): SegmentPlan[];
|
|
95
128
|
export type WrapMode = 'spawn' | 'host';
|
|
96
129
|
export interface WrapScriptOptions {
|
|
97
130
|
/** spawn (default): one-shot process, `exit` at the end. host: no `exit`, no helper re-emit. */
|
|
@@ -106,6 +139,6 @@ export interface WrapScriptOptions {
|
|
|
106
139
|
export declare function wrapScript(body: string, opts?: WrapScriptOptions): string;
|
|
107
140
|
/**
|
|
108
141
|
* Resident-host bootstrap: encoding + full fx-* catalog + JSON-line RPC loop.
|
|
109
|
-
* Loaded once via
|
|
142
|
+
* Loaded once via the selected PowerShell's `-File`. Must never `exit` a successful frame.
|
|
110
143
|
*/
|
|
111
144
|
export declare function hostBootstrapScript(): string;
|