@ordewell/core 0.4.8 → 0.4.9
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/index.d.mts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +1483 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1484 -22
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -118,13 +118,1233 @@ var AUTO_COMMANDS = [
|
|
|
118
118
|
"jq",
|
|
119
119
|
"yq"
|
|
120
120
|
];
|
|
121
|
+
var UNIVERSAL_FLAGS = ["--help", "--version"];
|
|
122
|
+
var COUNT_FLAG = /^-\d+$/;
|
|
123
|
+
var FLAG_POLICY = {
|
|
124
|
+
ls: {
|
|
125
|
+
cluster: true,
|
|
126
|
+
booleans: [
|
|
127
|
+
"-1",
|
|
128
|
+
"-a",
|
|
129
|
+
"-A",
|
|
130
|
+
"-b",
|
|
131
|
+
"-c",
|
|
132
|
+
"-C",
|
|
133
|
+
"-d",
|
|
134
|
+
"-D",
|
|
135
|
+
"-f",
|
|
136
|
+
"-F",
|
|
137
|
+
"-g",
|
|
138
|
+
"-G",
|
|
139
|
+
"-h",
|
|
140
|
+
"-H",
|
|
141
|
+
"-i",
|
|
142
|
+
"-k",
|
|
143
|
+
"-l",
|
|
144
|
+
"-L",
|
|
145
|
+
"-m",
|
|
146
|
+
"-n",
|
|
147
|
+
"-N",
|
|
148
|
+
"-o",
|
|
149
|
+
"-p",
|
|
150
|
+
"-q",
|
|
151
|
+
"-Q",
|
|
152
|
+
"-r",
|
|
153
|
+
"-R",
|
|
154
|
+
"-s",
|
|
155
|
+
"-S",
|
|
156
|
+
"-t",
|
|
157
|
+
"-u",
|
|
158
|
+
"-U",
|
|
159
|
+
"-v",
|
|
160
|
+
"-x",
|
|
161
|
+
"-X",
|
|
162
|
+
"-Z",
|
|
163
|
+
"--all",
|
|
164
|
+
"--almost-all",
|
|
165
|
+
"--author",
|
|
166
|
+
"--escape",
|
|
167
|
+
"--classify",
|
|
168
|
+
"--file-type",
|
|
169
|
+
"--full-time",
|
|
170
|
+
"--no-group",
|
|
171
|
+
"--human-readable",
|
|
172
|
+
"--si",
|
|
173
|
+
"--dereference-command-line",
|
|
174
|
+
"--inode",
|
|
175
|
+
"--kibibytes",
|
|
176
|
+
"--dereference",
|
|
177
|
+
"--numeric-uid-gid",
|
|
178
|
+
"--literal",
|
|
179
|
+
"--hide-control-chars",
|
|
180
|
+
"--show-control-chars",
|
|
181
|
+
"--quote-name",
|
|
182
|
+
"--reverse",
|
|
183
|
+
"--recursive",
|
|
184
|
+
"--size",
|
|
185
|
+
"--directory",
|
|
186
|
+
"--group-directories-first",
|
|
187
|
+
"--context",
|
|
188
|
+
"--zero"
|
|
189
|
+
],
|
|
190
|
+
values: [
|
|
191
|
+
"-w",
|
|
192
|
+
"-I",
|
|
193
|
+
"-T",
|
|
194
|
+
"--width",
|
|
195
|
+
"--ignore",
|
|
196
|
+
"--hide",
|
|
197
|
+
"--block-size",
|
|
198
|
+
"--color",
|
|
199
|
+
"--format",
|
|
200
|
+
"--sort",
|
|
201
|
+
"--time",
|
|
202
|
+
"--time-style",
|
|
203
|
+
"--indicator-style",
|
|
204
|
+
"--quoting-style",
|
|
205
|
+
"--tabsize"
|
|
206
|
+
]
|
|
207
|
+
},
|
|
208
|
+
tree: {
|
|
209
|
+
cluster: true,
|
|
210
|
+
// `-o` is absent on purpose: it is tree's write-to-a-file flag, which the
|
|
211
|
+
// redirect check never sees because there is no redirect.
|
|
212
|
+
booleans: [
|
|
213
|
+
"-a",
|
|
214
|
+
"-d",
|
|
215
|
+
"-f",
|
|
216
|
+
"-i",
|
|
217
|
+
"-l",
|
|
218
|
+
"-x",
|
|
219
|
+
"-C",
|
|
220
|
+
"-n",
|
|
221
|
+
"-p",
|
|
222
|
+
"-s",
|
|
223
|
+
"-h",
|
|
224
|
+
"-u",
|
|
225
|
+
"-g",
|
|
226
|
+
"-D",
|
|
227
|
+
"-t",
|
|
228
|
+
"-c",
|
|
229
|
+
"-r",
|
|
230
|
+
"-F",
|
|
231
|
+
"-q",
|
|
232
|
+
"-N",
|
|
233
|
+
"-Q",
|
|
234
|
+
"-v",
|
|
235
|
+
"-J",
|
|
236
|
+
"-X",
|
|
237
|
+
"-Z",
|
|
238
|
+
"--noreport",
|
|
239
|
+
"--dirsfirst",
|
|
240
|
+
"--du",
|
|
241
|
+
"--prune",
|
|
242
|
+
"--matchdirs",
|
|
243
|
+
"--inodes",
|
|
244
|
+
"--device",
|
|
245
|
+
"--si",
|
|
246
|
+
"--gitignore",
|
|
247
|
+
"--ignore-case",
|
|
248
|
+
"--filesfirst",
|
|
249
|
+
"--nolinks",
|
|
250
|
+
"--hintro"
|
|
251
|
+
],
|
|
252
|
+
values: [
|
|
253
|
+
"-L",
|
|
254
|
+
"-P",
|
|
255
|
+
"-I",
|
|
256
|
+
"-H",
|
|
257
|
+
"--filelimit",
|
|
258
|
+
"--timefmt",
|
|
259
|
+
"--charset",
|
|
260
|
+
"--sort",
|
|
261
|
+
"--gitfile",
|
|
262
|
+
"--info",
|
|
263
|
+
"--prefix"
|
|
264
|
+
]
|
|
265
|
+
},
|
|
266
|
+
git: {
|
|
267
|
+
cluster: true,
|
|
268
|
+
// Absent on purpose, and each for a reason that was demonstrated rather than
|
|
269
|
+
// guessed at:
|
|
270
|
+
// -c, --config-env set configuration inline, and several configuration
|
|
271
|
+
// keys name a program to run (`core.pager`, `core.editor`,
|
|
272
|
+
// `diff.external`), so this is an execution flag with one
|
|
273
|
+
// indirection in front of it.
|
|
274
|
+
// --exec-path redirects where git finds its helper programs; a
|
|
275
|
+
// fabricated helper ran during an ordinary remote listing.
|
|
276
|
+
// -O, --open-files-in-pager runs an arbitrary named program over search hits.
|
|
277
|
+
// --upload-pack, --receive-pack name the program run on the other end.
|
|
278
|
+
// --textconv, --ext-diff run filters the repository itself configures.
|
|
279
|
+
// --git-dir, --work-tree repoint git at a tree whose configuration is not
|
|
280
|
+
// the one the developer is looking at.
|
|
281
|
+
// -o, --output write a file. `git ls-files -o` is a legitimate spelling
|
|
282
|
+
// of `--others`, but `git archive -o` writes, and the
|
|
283
|
+
// long spelling stays available for the read.
|
|
284
|
+
booleans: [
|
|
285
|
+
"-a",
|
|
286
|
+
"-b",
|
|
287
|
+
"-E",
|
|
288
|
+
"-F",
|
|
289
|
+
"-h",
|
|
290
|
+
"-H",
|
|
291
|
+
"-i",
|
|
292
|
+
"-I",
|
|
293
|
+
"-l",
|
|
294
|
+
"-p",
|
|
295
|
+
"-P",
|
|
296
|
+
"-q",
|
|
297
|
+
"-r",
|
|
298
|
+
"-R",
|
|
299
|
+
"-s",
|
|
300
|
+
"-t",
|
|
301
|
+
"-u",
|
|
302
|
+
"-v",
|
|
303
|
+
"-w",
|
|
304
|
+
"-z",
|
|
305
|
+
"--oneline",
|
|
306
|
+
"--graph",
|
|
307
|
+
"--stat",
|
|
308
|
+
"--shortstat",
|
|
309
|
+
"--numstat",
|
|
310
|
+
"--dirstat",
|
|
311
|
+
"--summary",
|
|
312
|
+
"--name-only",
|
|
313
|
+
"--name-status",
|
|
314
|
+
"--raw",
|
|
315
|
+
"--patch",
|
|
316
|
+
"--no-patch",
|
|
317
|
+
"--patch-with-stat",
|
|
318
|
+
"--cached",
|
|
319
|
+
"--staged",
|
|
320
|
+
"--porcelain",
|
|
321
|
+
"--short",
|
|
322
|
+
"--long",
|
|
323
|
+
"--branch",
|
|
324
|
+
"--show-stash",
|
|
325
|
+
"--show-current",
|
|
326
|
+
"--all",
|
|
327
|
+
"--tags",
|
|
328
|
+
"--heads",
|
|
329
|
+
"--remotes",
|
|
330
|
+
"--list",
|
|
331
|
+
"--verbose",
|
|
332
|
+
"--quiet",
|
|
333
|
+
"--abbrev-ref",
|
|
334
|
+
"--count",
|
|
335
|
+
"--reverse",
|
|
336
|
+
"--first-parent",
|
|
337
|
+
"--no-merges",
|
|
338
|
+
"--merges",
|
|
339
|
+
"--follow",
|
|
340
|
+
"--full-history",
|
|
341
|
+
"--simplify-merges",
|
|
342
|
+
"--sparse",
|
|
343
|
+
"--dense",
|
|
344
|
+
"--ancestry-path",
|
|
345
|
+
"--left-right",
|
|
346
|
+
"--cherry",
|
|
347
|
+
"--cherry-pick",
|
|
348
|
+
"--cherry-mark",
|
|
349
|
+
"--boundary",
|
|
350
|
+
"--topo-order",
|
|
351
|
+
"--date-order",
|
|
352
|
+
"--author-date-order",
|
|
353
|
+
"--relative-date",
|
|
354
|
+
"--parents",
|
|
355
|
+
"--children",
|
|
356
|
+
"--timestamp",
|
|
357
|
+
"--no-walk",
|
|
358
|
+
"--do-walk",
|
|
359
|
+
"--decorate",
|
|
360
|
+
"--no-decorate",
|
|
361
|
+
"--abbrev-commit",
|
|
362
|
+
"--no-abbrev-commit",
|
|
363
|
+
"--abbrev",
|
|
364
|
+
"--no-abbrev",
|
|
365
|
+
"--color",
|
|
366
|
+
"--no-color",
|
|
367
|
+
"--pretty",
|
|
368
|
+
"--format",
|
|
369
|
+
"--expand-tabs",
|
|
370
|
+
"--no-expand-tabs",
|
|
371
|
+
"--numbered",
|
|
372
|
+
"--email",
|
|
373
|
+
"--no-notes",
|
|
374
|
+
"--notes",
|
|
375
|
+
"--show-signature",
|
|
376
|
+
"--find-renames",
|
|
377
|
+
"--find-copies",
|
|
378
|
+
"--find-copies-harder",
|
|
379
|
+
"--break-rewrites",
|
|
380
|
+
"--no-renames",
|
|
381
|
+
"--irreversible-delete",
|
|
382
|
+
"--full-index",
|
|
383
|
+
"--binary",
|
|
384
|
+
"--text",
|
|
385
|
+
"--check",
|
|
386
|
+
"--exit-code",
|
|
387
|
+
"--word-diff",
|
|
388
|
+
"--function-context",
|
|
389
|
+
"--ignore-all-space",
|
|
390
|
+
"--ignore-space-change",
|
|
391
|
+
"--ignore-space-at-eol",
|
|
392
|
+
"--ignore-blank-lines",
|
|
393
|
+
"--ignore-cr-at-eol",
|
|
394
|
+
"--no-prefix",
|
|
395
|
+
"--default-prefix",
|
|
396
|
+
"--no-textconv",
|
|
397
|
+
"--no-ext-diff",
|
|
398
|
+
"--submodule",
|
|
399
|
+
"--ignore-submodules",
|
|
400
|
+
"--recurse-submodules",
|
|
401
|
+
"--no-recurse-submodules",
|
|
402
|
+
"--others",
|
|
403
|
+
"--deleted",
|
|
404
|
+
"--modified",
|
|
405
|
+
"--unmerged",
|
|
406
|
+
"--stage",
|
|
407
|
+
"--killed",
|
|
408
|
+
"--ignored",
|
|
409
|
+
"--exclude-standard",
|
|
410
|
+
"--error-unmatch",
|
|
411
|
+
"--full-name",
|
|
412
|
+
"--directory",
|
|
413
|
+
"--no-empty-directory",
|
|
414
|
+
"--untracked-files",
|
|
415
|
+
"--no-optional-locks",
|
|
416
|
+
"--no-pager",
|
|
417
|
+
"--paginate",
|
|
418
|
+
"--bare",
|
|
419
|
+
"--literal-pathspecs",
|
|
420
|
+
"--glob-pathspecs",
|
|
421
|
+
"--noglob-pathspecs",
|
|
422
|
+
"--icase-pathspecs",
|
|
423
|
+
"--line-number",
|
|
424
|
+
"--column",
|
|
425
|
+
"--heading",
|
|
426
|
+
"--no-index",
|
|
427
|
+
"--untracked",
|
|
428
|
+
"--no-recursive",
|
|
429
|
+
"--name-rev",
|
|
430
|
+
"--root",
|
|
431
|
+
"--dirty",
|
|
432
|
+
"--broken",
|
|
433
|
+
"--always",
|
|
434
|
+
"--merged",
|
|
435
|
+
"--no-merged",
|
|
436
|
+
"--show-toplevel",
|
|
437
|
+
"--show-cdup",
|
|
438
|
+
"--git-common-dir",
|
|
439
|
+
"--absolute-git-dir",
|
|
440
|
+
"--is-inside-work-tree",
|
|
441
|
+
"--is-inside-git-dir",
|
|
442
|
+
"--is-bare-repository",
|
|
443
|
+
"--symbolic",
|
|
444
|
+
"--symbolic-full-name",
|
|
445
|
+
"--verify",
|
|
446
|
+
"--short-hash",
|
|
447
|
+
"--textual",
|
|
448
|
+
"--batch",
|
|
449
|
+
"--batch-check",
|
|
450
|
+
"--batch-all-objects",
|
|
451
|
+
"--buffer",
|
|
452
|
+
"--follow-symlinks",
|
|
453
|
+
"--use-mailmap"
|
|
454
|
+
],
|
|
455
|
+
values: [
|
|
456
|
+
"-n",
|
|
457
|
+
"-C",
|
|
458
|
+
"-B",
|
|
459
|
+
"-M",
|
|
460
|
+
"-L",
|
|
461
|
+
"-S",
|
|
462
|
+
"-G",
|
|
463
|
+
"-U",
|
|
464
|
+
"-e",
|
|
465
|
+
"-m",
|
|
466
|
+
"-f",
|
|
467
|
+
"-g",
|
|
468
|
+
"-x",
|
|
469
|
+
"-X",
|
|
470
|
+
"-W",
|
|
471
|
+
"--max-count",
|
|
472
|
+
"--skip",
|
|
473
|
+
"--since",
|
|
474
|
+
"--after",
|
|
475
|
+
"--until",
|
|
476
|
+
"--before",
|
|
477
|
+
"--author",
|
|
478
|
+
"--grep",
|
|
479
|
+
"--grep-reflog",
|
|
480
|
+
"--committer",
|
|
481
|
+
"--date",
|
|
482
|
+
"--diff-filter",
|
|
483
|
+
"--unified",
|
|
484
|
+
"--stat-width",
|
|
485
|
+
"--stat-name-width",
|
|
486
|
+
"--stat-count",
|
|
487
|
+
"--word-diff-regex",
|
|
488
|
+
"--line-prefix",
|
|
489
|
+
"--src-prefix",
|
|
490
|
+
"--dst-prefix",
|
|
491
|
+
"--pickaxe-regex",
|
|
492
|
+
"--anchored",
|
|
493
|
+
"--color-moved",
|
|
494
|
+
"--color-words",
|
|
495
|
+
"--inter-hunk-context",
|
|
496
|
+
"--max-parents",
|
|
497
|
+
"--min-parents",
|
|
498
|
+
"--simplify-by-decoration",
|
|
499
|
+
"--glob",
|
|
500
|
+
"--exclude",
|
|
501
|
+
"--sort",
|
|
502
|
+
"--contains",
|
|
503
|
+
"--points-at",
|
|
504
|
+
"--decorate-refs",
|
|
505
|
+
"--decorate-refs-exclude",
|
|
506
|
+
"--encoding",
|
|
507
|
+
"--context",
|
|
508
|
+
"--max-depth",
|
|
509
|
+
// `--filters` is absent from this list on purpose: it runs the clean and
|
|
510
|
+
// smudge filters the repository under research configures, which is the
|
|
511
|
+
// same execution vector as the configuration flag above with a different
|
|
512
|
+
// spelling.
|
|
513
|
+
"--and",
|
|
514
|
+
"--or",
|
|
515
|
+
"--not",
|
|
516
|
+
"--all-match",
|
|
517
|
+
"--threads",
|
|
518
|
+
"--path"
|
|
519
|
+
],
|
|
520
|
+
patterns: [COUNT_FLAG]
|
|
521
|
+
},
|
|
522
|
+
wc: {
|
|
523
|
+
cluster: true,
|
|
524
|
+
booleans: [
|
|
525
|
+
"-c",
|
|
526
|
+
"-l",
|
|
527
|
+
"-m",
|
|
528
|
+
"-w",
|
|
529
|
+
"-L",
|
|
530
|
+
"--bytes",
|
|
531
|
+
"--chars",
|
|
532
|
+
"--lines",
|
|
533
|
+
"--words",
|
|
534
|
+
"--max-line-length",
|
|
535
|
+
"--total"
|
|
536
|
+
]
|
|
537
|
+
},
|
|
538
|
+
du: {
|
|
539
|
+
cluster: true,
|
|
540
|
+
booleans: [
|
|
541
|
+
"-0",
|
|
542
|
+
"-a",
|
|
543
|
+
"-b",
|
|
544
|
+
"-c",
|
|
545
|
+
"-D",
|
|
546
|
+
"-h",
|
|
547
|
+
"-H",
|
|
548
|
+
"-k",
|
|
549
|
+
"-l",
|
|
550
|
+
"-L",
|
|
551
|
+
"-m",
|
|
552
|
+
"-P",
|
|
553
|
+
"-s",
|
|
554
|
+
"-S",
|
|
555
|
+
"-x",
|
|
556
|
+
"--all",
|
|
557
|
+
"--apparent-size",
|
|
558
|
+
"--bytes",
|
|
559
|
+
"--total",
|
|
560
|
+
"--dereference-args",
|
|
561
|
+
"--human-readable",
|
|
562
|
+
"--si",
|
|
563
|
+
"--inodes",
|
|
564
|
+
"--count-links",
|
|
565
|
+
"--dereference",
|
|
566
|
+
"--no-dereference",
|
|
567
|
+
"--separate-dirs",
|
|
568
|
+
"--summarize",
|
|
569
|
+
"--one-file-system",
|
|
570
|
+
"--null"
|
|
571
|
+
],
|
|
572
|
+
values: [
|
|
573
|
+
"-d",
|
|
574
|
+
"-t",
|
|
575
|
+
"-B",
|
|
576
|
+
"-X",
|
|
577
|
+
"--max-depth",
|
|
578
|
+
"--threshold",
|
|
579
|
+
"--block-size",
|
|
580
|
+
"--exclude",
|
|
581
|
+
"--exclude-from",
|
|
582
|
+
"--time",
|
|
583
|
+
"--time-style",
|
|
584
|
+
"--files0-from"
|
|
585
|
+
]
|
|
586
|
+
},
|
|
587
|
+
df: {
|
|
588
|
+
cluster: true,
|
|
589
|
+
booleans: [
|
|
590
|
+
"-a",
|
|
591
|
+
"-h",
|
|
592
|
+
"-H",
|
|
593
|
+
"-i",
|
|
594
|
+
"-k",
|
|
595
|
+
"-l",
|
|
596
|
+
"-m",
|
|
597
|
+
"-P",
|
|
598
|
+
"-T",
|
|
599
|
+
"-v",
|
|
600
|
+
"--all",
|
|
601
|
+
"--human-readable",
|
|
602
|
+
"--si",
|
|
603
|
+
"--inodes",
|
|
604
|
+
"--local",
|
|
605
|
+
"--portability",
|
|
606
|
+
"--print-type",
|
|
607
|
+
"--total",
|
|
608
|
+
"--sync",
|
|
609
|
+
"--no-sync"
|
|
610
|
+
],
|
|
611
|
+
values: ["-B", "-t", "-x", "--block-size", "--type", "--exclude-type"]
|
|
612
|
+
},
|
|
613
|
+
file: {
|
|
614
|
+
cluster: true,
|
|
615
|
+
// `-C`/`--compile` is absent: it writes a compiled magic file.
|
|
616
|
+
booleans: [
|
|
617
|
+
"-b",
|
|
618
|
+
"-c",
|
|
619
|
+
"-h",
|
|
620
|
+
"-i",
|
|
621
|
+
"-k",
|
|
622
|
+
"-L",
|
|
623
|
+
"-n",
|
|
624
|
+
"-N",
|
|
625
|
+
"-p",
|
|
626
|
+
"-r",
|
|
627
|
+
"-s",
|
|
628
|
+
"-S",
|
|
629
|
+
"-v",
|
|
630
|
+
"-z",
|
|
631
|
+
"-0",
|
|
632
|
+
"--brief",
|
|
633
|
+
"--mime",
|
|
634
|
+
"--mime-type",
|
|
635
|
+
"--mime-encoding",
|
|
636
|
+
"--dereference",
|
|
637
|
+
"--no-dereference",
|
|
638
|
+
"--keep-going",
|
|
639
|
+
"--no-buffer",
|
|
640
|
+
"--no-pad",
|
|
641
|
+
"--raw",
|
|
642
|
+
"--special-files",
|
|
643
|
+
"--uncompress",
|
|
644
|
+
"--print0",
|
|
645
|
+
"--checking-printout"
|
|
646
|
+
],
|
|
647
|
+
values: [
|
|
648
|
+
"-e",
|
|
649
|
+
"-m",
|
|
650
|
+
"-P",
|
|
651
|
+
"-F",
|
|
652
|
+
"--exclude",
|
|
653
|
+
"--magic-file",
|
|
654
|
+
"--separator",
|
|
655
|
+
"--parameter",
|
|
656
|
+
"--extension",
|
|
657
|
+
"--files-from"
|
|
658
|
+
]
|
|
659
|
+
},
|
|
660
|
+
head: {
|
|
661
|
+
cluster: true,
|
|
662
|
+
booleans: ["-q", "-v", "-z", "--quiet", "--silent", "--verbose", "--zero-terminated"],
|
|
663
|
+
values: ["-c", "-n", "--bytes", "--lines"],
|
|
664
|
+
patterns: [COUNT_FLAG]
|
|
665
|
+
},
|
|
666
|
+
tail: {
|
|
667
|
+
cluster: true,
|
|
668
|
+
booleans: [
|
|
669
|
+
"-f",
|
|
670
|
+
"-F",
|
|
671
|
+
"-q",
|
|
672
|
+
"-v",
|
|
673
|
+
"-z",
|
|
674
|
+
"--follow",
|
|
675
|
+
"--retry",
|
|
676
|
+
"--quiet",
|
|
677
|
+
"--silent",
|
|
678
|
+
"--verbose",
|
|
679
|
+
"--zero-terminated"
|
|
680
|
+
],
|
|
681
|
+
values: [
|
|
682
|
+
"-c",
|
|
683
|
+
"-n",
|
|
684
|
+
"-s",
|
|
685
|
+
"--bytes",
|
|
686
|
+
"--lines",
|
|
687
|
+
"--sleep-interval",
|
|
688
|
+
"--pid",
|
|
689
|
+
"--max-unchanged-stats"
|
|
690
|
+
],
|
|
691
|
+
patterns: [COUNT_FLAG]
|
|
692
|
+
},
|
|
693
|
+
cat: {
|
|
694
|
+
cluster: true,
|
|
695
|
+
booleans: [
|
|
696
|
+
"-A",
|
|
697
|
+
"-b",
|
|
698
|
+
"-e",
|
|
699
|
+
"-E",
|
|
700
|
+
"-n",
|
|
701
|
+
"-s",
|
|
702
|
+
"-t",
|
|
703
|
+
"-T",
|
|
704
|
+
"-u",
|
|
705
|
+
"-v",
|
|
706
|
+
"--show-all",
|
|
707
|
+
"--number-nonblank",
|
|
708
|
+
"--show-ends",
|
|
709
|
+
"--number",
|
|
710
|
+
"--squeeze-blank",
|
|
711
|
+
"--show-tabs",
|
|
712
|
+
"--show-nonprinting"
|
|
713
|
+
]
|
|
714
|
+
},
|
|
715
|
+
sort: {
|
|
716
|
+
cluster: true,
|
|
717
|
+
// Absent on purpose: `-o`/`--output` writes a file with no redirect for the
|
|
718
|
+
// redirect check to see, and `--compress-program` names a program that sort
|
|
719
|
+
// runs over its own temporary files — a permitted binary as an interpreter.
|
|
720
|
+
booleans: [
|
|
721
|
+
"-b",
|
|
722
|
+
"-c",
|
|
723
|
+
"-C",
|
|
724
|
+
"-d",
|
|
725
|
+
"-f",
|
|
726
|
+
"-g",
|
|
727
|
+
"-h",
|
|
728
|
+
"-i",
|
|
729
|
+
"-M",
|
|
730
|
+
"-n",
|
|
731
|
+
"-r",
|
|
732
|
+
"-R",
|
|
733
|
+
"-s",
|
|
734
|
+
"-u",
|
|
735
|
+
"-V",
|
|
736
|
+
"-z",
|
|
737
|
+
"--ignore-leading-blanks",
|
|
738
|
+
"--check",
|
|
739
|
+
"--dictionary-order",
|
|
740
|
+
"--ignore-case",
|
|
741
|
+
"--general-numeric-sort",
|
|
742
|
+
"--human-numeric-sort",
|
|
743
|
+
"--ignore-nonprinting",
|
|
744
|
+
"--month-sort",
|
|
745
|
+
"--numeric-sort",
|
|
746
|
+
"--random-sort",
|
|
747
|
+
"--reverse",
|
|
748
|
+
"--stable",
|
|
749
|
+
"--unique",
|
|
750
|
+
"--version-sort",
|
|
751
|
+
"--zero-terminated",
|
|
752
|
+
"--debug"
|
|
753
|
+
],
|
|
754
|
+
values: [
|
|
755
|
+
"-k",
|
|
756
|
+
"-t",
|
|
757
|
+
"-S",
|
|
758
|
+
"-T",
|
|
759
|
+
"--key",
|
|
760
|
+
"--field-separator",
|
|
761
|
+
"--buffer-size",
|
|
762
|
+
"--temporary-directory",
|
|
763
|
+
"--random-source",
|
|
764
|
+
"--batch-size",
|
|
765
|
+
"--parallel",
|
|
766
|
+
"--sort"
|
|
767
|
+
]
|
|
768
|
+
},
|
|
769
|
+
uniq: {
|
|
770
|
+
cluster: true,
|
|
771
|
+
booleans: [
|
|
772
|
+
"-c",
|
|
773
|
+
"-d",
|
|
774
|
+
"-D",
|
|
775
|
+
"-i",
|
|
776
|
+
"-u",
|
|
777
|
+
"-z",
|
|
778
|
+
"--count",
|
|
779
|
+
"--repeated",
|
|
780
|
+
"--all-repeated",
|
|
781
|
+
"--ignore-case",
|
|
782
|
+
"--unique",
|
|
783
|
+
"--zero-terminated"
|
|
784
|
+
],
|
|
785
|
+
values: ["-f", "-s", "-w", "--skip-fields", "--skip-chars", "--check-chars", "--group"]
|
|
786
|
+
},
|
|
787
|
+
// No flag on either runs a program or writes a file, and the planner's
|
|
788
|
+
// commonest use of `echo` is a section marker — `echo --- files changed ---`
|
|
789
|
+
// is three tokens that all begin with a dash and none of them is a flag.
|
|
790
|
+
echo: { freeform: true },
|
|
791
|
+
printf: { freeform: true },
|
|
792
|
+
date: {
|
|
793
|
+
cluster: true,
|
|
794
|
+
// `-s`/`--set` is absent: it sets the system clock.
|
|
795
|
+
booleans: [
|
|
796
|
+
"-u",
|
|
797
|
+
"-R",
|
|
798
|
+
"-I",
|
|
799
|
+
"--utc",
|
|
800
|
+
"--universal",
|
|
801
|
+
"--rfc-email",
|
|
802
|
+
"--rfc-3339",
|
|
803
|
+
"--iso-8601",
|
|
804
|
+
"--debug"
|
|
805
|
+
],
|
|
806
|
+
values: ["-d", "-f", "-r", "--date", "--file", "--reference"]
|
|
807
|
+
},
|
|
808
|
+
stat: {
|
|
809
|
+
cluster: true,
|
|
810
|
+
booleans: ["-f", "-L", "-t", "--file-system", "--terse", "--dereference"],
|
|
811
|
+
values: ["-c", "--format", "--printf", "--cached"]
|
|
812
|
+
},
|
|
813
|
+
basename: {
|
|
814
|
+
cluster: true,
|
|
815
|
+
booleans: ["-a", "-z", "--multiple", "--zero"],
|
|
816
|
+
values: ["-s", "--suffix"]
|
|
817
|
+
},
|
|
818
|
+
dirname: {
|
|
819
|
+
cluster: true,
|
|
820
|
+
booleans: ["-z", "--zero"]
|
|
821
|
+
},
|
|
822
|
+
realpath: {
|
|
823
|
+
cluster: true,
|
|
824
|
+
booleans: [
|
|
825
|
+
"-e",
|
|
826
|
+
"-m",
|
|
827
|
+
"-L",
|
|
828
|
+
"-P",
|
|
829
|
+
"-q",
|
|
830
|
+
"-s",
|
|
831
|
+
"-z",
|
|
832
|
+
"--canonicalize-existing",
|
|
833
|
+
"--canonicalize-missing",
|
|
834
|
+
"--logical",
|
|
835
|
+
"--physical",
|
|
836
|
+
"--quiet",
|
|
837
|
+
"--strip",
|
|
838
|
+
"--no-symlinks",
|
|
839
|
+
"--zero"
|
|
840
|
+
],
|
|
841
|
+
values: ["--relative-to", "--relative-base"]
|
|
842
|
+
},
|
|
843
|
+
pwd: { cluster: true, booleans: ["-L", "-P", "--logical", "--physical"] },
|
|
844
|
+
which: { cluster: true, booleans: ["-a", "-s", "--all"] },
|
|
845
|
+
type: { cluster: true, booleans: ["-a", "-f", "-p", "-P", "-t"] },
|
|
846
|
+
uname: {
|
|
847
|
+
cluster: true,
|
|
848
|
+
booleans: [
|
|
849
|
+
"-a",
|
|
850
|
+
"-i",
|
|
851
|
+
"-m",
|
|
852
|
+
"-n",
|
|
853
|
+
"-o",
|
|
854
|
+
"-p",
|
|
855
|
+
"-r",
|
|
856
|
+
"-s",
|
|
857
|
+
"-v",
|
|
858
|
+
"--all",
|
|
859
|
+
"--kernel-name",
|
|
860
|
+
"--nodename",
|
|
861
|
+
"--kernel-release",
|
|
862
|
+
"--kernel-version",
|
|
863
|
+
"--machine",
|
|
864
|
+
"--processor",
|
|
865
|
+
"--hardware-platform",
|
|
866
|
+
"--operating-system"
|
|
867
|
+
]
|
|
868
|
+
},
|
|
869
|
+
whoami: {},
|
|
870
|
+
cut: {
|
|
871
|
+
cluster: true,
|
|
872
|
+
// `--output-delimiter` names a separator string, not a file.
|
|
873
|
+
booleans: ["-n", "-s", "-z", "--only-delimited", "--complement", "--zero-terminated"],
|
|
874
|
+
values: [
|
|
875
|
+
"-b",
|
|
876
|
+
"-c",
|
|
877
|
+
"-d",
|
|
878
|
+
"-f",
|
|
879
|
+
"--bytes",
|
|
880
|
+
"--characters",
|
|
881
|
+
"--delimiter",
|
|
882
|
+
"--fields",
|
|
883
|
+
"--output-delimiter"
|
|
884
|
+
]
|
|
885
|
+
},
|
|
886
|
+
nl: {
|
|
887
|
+
cluster: true,
|
|
888
|
+
booleans: ["-p", "--no-renumber"],
|
|
889
|
+
values: [
|
|
890
|
+
"-b",
|
|
891
|
+
"-d",
|
|
892
|
+
"-f",
|
|
893
|
+
"-h",
|
|
894
|
+
"-i",
|
|
895
|
+
"-l",
|
|
896
|
+
"-n",
|
|
897
|
+
"-s",
|
|
898
|
+
"-v",
|
|
899
|
+
"-w",
|
|
900
|
+
"--body-numbering",
|
|
901
|
+
"--section-delimiter",
|
|
902
|
+
"--footer-numbering",
|
|
903
|
+
"--header-numbering",
|
|
904
|
+
"--join-blank-lines",
|
|
905
|
+
"--line-increment",
|
|
906
|
+
"--number-format",
|
|
907
|
+
"--number-separator",
|
|
908
|
+
"--starting-line-number",
|
|
909
|
+
"--number-width"
|
|
910
|
+
]
|
|
911
|
+
},
|
|
912
|
+
rg: {
|
|
913
|
+
cluster: true,
|
|
914
|
+
// `--pre` runs a named preprocessor over every file searched and
|
|
915
|
+
// `--hostname-bin` runs a named program to resolve the hostname; both are
|
|
916
|
+
// absent, and `--pre-glob` with them.
|
|
917
|
+
booleans: [
|
|
918
|
+
"-a",
|
|
919
|
+
"-c",
|
|
920
|
+
"-F",
|
|
921
|
+
"-h",
|
|
922
|
+
"-H",
|
|
923
|
+
"-i",
|
|
924
|
+
"-I",
|
|
925
|
+
"-l",
|
|
926
|
+
"-L",
|
|
927
|
+
"-n",
|
|
928
|
+
"-N",
|
|
929
|
+
"-o",
|
|
930
|
+
"-p",
|
|
931
|
+
"-P",
|
|
932
|
+
"-q",
|
|
933
|
+
"-s",
|
|
934
|
+
"-S",
|
|
935
|
+
"-u",
|
|
936
|
+
"-uu",
|
|
937
|
+
"-uuu",
|
|
938
|
+
"-U",
|
|
939
|
+
"-v",
|
|
940
|
+
"-V",
|
|
941
|
+
"-w",
|
|
942
|
+
"-x",
|
|
943
|
+
"-z",
|
|
944
|
+
"--text",
|
|
945
|
+
"--count",
|
|
946
|
+
"--count-matches",
|
|
947
|
+
"--fixed-strings",
|
|
948
|
+
"--files",
|
|
949
|
+
"--files-with-matches",
|
|
950
|
+
"--files-without-match",
|
|
951
|
+
"--follow",
|
|
952
|
+
"--hidden",
|
|
953
|
+
"--no-hidden",
|
|
954
|
+
"--ignore-case",
|
|
955
|
+
"--case-sensitive",
|
|
956
|
+
"--smart-case",
|
|
957
|
+
"--invert-match",
|
|
958
|
+
"--line-number",
|
|
959
|
+
"--no-line-number",
|
|
960
|
+
"--with-filename",
|
|
961
|
+
"--no-filename",
|
|
962
|
+
"--heading",
|
|
963
|
+
"--no-heading",
|
|
964
|
+
"--column",
|
|
965
|
+
"--no-column",
|
|
966
|
+
"--byte-offset",
|
|
967
|
+
"--vimgrep",
|
|
968
|
+
"--json",
|
|
969
|
+
"--stats",
|
|
970
|
+
"--trim",
|
|
971
|
+
"--pretty",
|
|
972
|
+
"--passthru",
|
|
973
|
+
"--word-regexp",
|
|
974
|
+
"--line-regexp",
|
|
975
|
+
"--multiline",
|
|
976
|
+
"--multiline-dotall",
|
|
977
|
+
"--no-multiline",
|
|
978
|
+
"--crlf",
|
|
979
|
+
"--null",
|
|
980
|
+
"--null-data",
|
|
981
|
+
"--binary",
|
|
982
|
+
"--search-zip",
|
|
983
|
+
"--no-ignore",
|
|
984
|
+
"--no-ignore-dot",
|
|
985
|
+
"--no-ignore-exclude",
|
|
986
|
+
"--no-ignore-files",
|
|
987
|
+
"--no-ignore-global",
|
|
988
|
+
"--no-ignore-parent",
|
|
989
|
+
"--no-ignore-vcs",
|
|
990
|
+
"--no-ignore-messages",
|
|
991
|
+
"--no-messages",
|
|
992
|
+
"--no-require-git",
|
|
993
|
+
"--require-git",
|
|
994
|
+
"--one-file-system",
|
|
995
|
+
"--pcre2",
|
|
996
|
+
"--no-pcre2",
|
|
997
|
+
"--auto-hybrid-regex",
|
|
998
|
+
"--line-buffered",
|
|
999
|
+
"--block-buffered",
|
|
1000
|
+
"--unicode",
|
|
1001
|
+
"--no-unicode",
|
|
1002
|
+
"--unrestricted",
|
|
1003
|
+
"--type-list",
|
|
1004
|
+
"--debug",
|
|
1005
|
+
"--trace",
|
|
1006
|
+
"--include-zero",
|
|
1007
|
+
"--no-context-separator",
|
|
1008
|
+
"--stop-on-nonmatch",
|
|
1009
|
+
"--quiet",
|
|
1010
|
+
"--no-binary"
|
|
1011
|
+
],
|
|
1012
|
+
values: [
|
|
1013
|
+
"-A",
|
|
1014
|
+
"-B",
|
|
1015
|
+
"-C",
|
|
1016
|
+
"-d",
|
|
1017
|
+
"-e",
|
|
1018
|
+
"-E",
|
|
1019
|
+
"-f",
|
|
1020
|
+
"-g",
|
|
1021
|
+
"-j",
|
|
1022
|
+
"-m",
|
|
1023
|
+
"-M",
|
|
1024
|
+
"-r",
|
|
1025
|
+
"-t",
|
|
1026
|
+
"-T",
|
|
1027
|
+
"--after-context",
|
|
1028
|
+
"--before-context",
|
|
1029
|
+
"--context",
|
|
1030
|
+
"--context-separator",
|
|
1031
|
+
"--field-context-separator",
|
|
1032
|
+
"--field-match-separator",
|
|
1033
|
+
"--regexp",
|
|
1034
|
+
"--file",
|
|
1035
|
+
"--glob",
|
|
1036
|
+
"--iglob",
|
|
1037
|
+
"--glob-case-insensitive",
|
|
1038
|
+
"--type",
|
|
1039
|
+
"--type-not",
|
|
1040
|
+
"--type-add",
|
|
1041
|
+
"--type-clear",
|
|
1042
|
+
"--max-count",
|
|
1043
|
+
"--max-columns",
|
|
1044
|
+
"--max-depth",
|
|
1045
|
+
"--maxdepth",
|
|
1046
|
+
"--max-filesize",
|
|
1047
|
+
"--replace",
|
|
1048
|
+
"--threads",
|
|
1049
|
+
"--encoding",
|
|
1050
|
+
"--engine",
|
|
1051
|
+
"--sort",
|
|
1052
|
+
"--sortr",
|
|
1053
|
+
"--color",
|
|
1054
|
+
"--colors",
|
|
1055
|
+
"--path-separator",
|
|
1056
|
+
"--ignore-file",
|
|
1057
|
+
"--dfa-size-limit",
|
|
1058
|
+
"--regex-size-limit",
|
|
1059
|
+
"--binary-files",
|
|
1060
|
+
"--max-columns-preview"
|
|
1061
|
+
]
|
|
1062
|
+
},
|
|
1063
|
+
grep: {
|
|
1064
|
+
cluster: true,
|
|
1065
|
+
// `-o` here is `--only-matching`, which writes nothing. It is the same two
|
|
1066
|
+
// characters as `sort -o`, which writes a file — the reason these sets are
|
|
1067
|
+
// per-binary rather than one shared list.
|
|
1068
|
+
booleans: [
|
|
1069
|
+
"-a",
|
|
1070
|
+
"-b",
|
|
1071
|
+
"-c",
|
|
1072
|
+
"-E",
|
|
1073
|
+
"-F",
|
|
1074
|
+
"-G",
|
|
1075
|
+
"-H",
|
|
1076
|
+
"-h",
|
|
1077
|
+
"-i",
|
|
1078
|
+
"-I",
|
|
1079
|
+
"-l",
|
|
1080
|
+
"-L",
|
|
1081
|
+
"-n",
|
|
1082
|
+
"-o",
|
|
1083
|
+
"-P",
|
|
1084
|
+
"-q",
|
|
1085
|
+
"-r",
|
|
1086
|
+
"-R",
|
|
1087
|
+
"-s",
|
|
1088
|
+
"-T",
|
|
1089
|
+
"-U",
|
|
1090
|
+
"-v",
|
|
1091
|
+
"-w",
|
|
1092
|
+
"-x",
|
|
1093
|
+
"-y",
|
|
1094
|
+
"-z",
|
|
1095
|
+
"-Z",
|
|
1096
|
+
"--extended-regexp",
|
|
1097
|
+
"--fixed-strings",
|
|
1098
|
+
"--basic-regexp",
|
|
1099
|
+
"--perl-regexp",
|
|
1100
|
+
"--ignore-case",
|
|
1101
|
+
"--no-ignore-case",
|
|
1102
|
+
"--invert-match",
|
|
1103
|
+
"--word-regexp",
|
|
1104
|
+
"--line-regexp",
|
|
1105
|
+
"--count",
|
|
1106
|
+
"--files-with-matches",
|
|
1107
|
+
"--files-without-match",
|
|
1108
|
+
"--line-number",
|
|
1109
|
+
"--with-filename",
|
|
1110
|
+
"--no-filename",
|
|
1111
|
+
"--only-matching",
|
|
1112
|
+
"--quiet",
|
|
1113
|
+
"--silent",
|
|
1114
|
+
"--no-messages",
|
|
1115
|
+
"--text",
|
|
1116
|
+
"--binary",
|
|
1117
|
+
"--line-buffered",
|
|
1118
|
+
"--null",
|
|
1119
|
+
"--null-data",
|
|
1120
|
+
"--byte-offset",
|
|
1121
|
+
"--recursive",
|
|
1122
|
+
"--dereference-recursive",
|
|
1123
|
+
"--initial-tab",
|
|
1124
|
+
"--unix-byte-offsets",
|
|
1125
|
+
"--no-group-separator",
|
|
1126
|
+
"--color",
|
|
1127
|
+
"--colour"
|
|
1128
|
+
],
|
|
1129
|
+
values: [
|
|
1130
|
+
"-A",
|
|
1131
|
+
"-B",
|
|
1132
|
+
"-C",
|
|
1133
|
+
"-d",
|
|
1134
|
+
"-D",
|
|
1135
|
+
"-e",
|
|
1136
|
+
"-f",
|
|
1137
|
+
"-m",
|
|
1138
|
+
"--after-context",
|
|
1139
|
+
"--before-context",
|
|
1140
|
+
"--context",
|
|
1141
|
+
"--regexp",
|
|
1142
|
+
"--file",
|
|
1143
|
+
"--max-count",
|
|
1144
|
+
"--devices",
|
|
1145
|
+
"--directories",
|
|
1146
|
+
"--binary-files",
|
|
1147
|
+
"--include",
|
|
1148
|
+
"--exclude",
|
|
1149
|
+
"--exclude-dir",
|
|
1150
|
+
"--exclude-from",
|
|
1151
|
+
"--label",
|
|
1152
|
+
"--group-separator"
|
|
1153
|
+
]
|
|
1154
|
+
},
|
|
1155
|
+
find: {
|
|
1156
|
+
// No clustering: find spells its flags as single-dash words, so walking the
|
|
1157
|
+
// characters of `-name` would read it as five short flags. And its arguments
|
|
1158
|
+
// are an expression, so `--` does not end them.
|
|
1159
|
+
expressionArgs: true,
|
|
1160
|
+
// Absent on purpose: `-exec`, `-execdir`, `-ok` and `-okdir` run an inner
|
|
1161
|
+
// command (also caught by the named guard below, which says so more
|
|
1162
|
+
// precisely), `-delete` removes files, and `-fprint`, `-fprint0`, `-fprintf`
|
|
1163
|
+
// and `-fls` are find's write family — the same write as `> file` with no
|
|
1164
|
+
// redirect for the redirect check to see.
|
|
1165
|
+
booleans: [
|
|
1166
|
+
"-H",
|
|
1167
|
+
"-L",
|
|
1168
|
+
"-P",
|
|
1169
|
+
"-a",
|
|
1170
|
+
"-and",
|
|
1171
|
+
"-o",
|
|
1172
|
+
"-or",
|
|
1173
|
+
"-not",
|
|
1174
|
+
"-d",
|
|
1175
|
+
"-depth",
|
|
1176
|
+
"-daystart",
|
|
1177
|
+
"-empty",
|
|
1178
|
+
"-executable",
|
|
1179
|
+
"-false",
|
|
1180
|
+
"-follow",
|
|
1181
|
+
"-help",
|
|
1182
|
+
"--help",
|
|
1183
|
+
"-ignore_readdir_race",
|
|
1184
|
+
"-noignore_readdir_race",
|
|
1185
|
+
"-ls",
|
|
1186
|
+
"-mount",
|
|
1187
|
+
"-nogroup",
|
|
1188
|
+
"-noleaf",
|
|
1189
|
+
"-nouser",
|
|
1190
|
+
"-print",
|
|
1191
|
+
"-print0",
|
|
1192
|
+
"-prune",
|
|
1193
|
+
"-quit",
|
|
1194
|
+
"-readable",
|
|
1195
|
+
"-true",
|
|
1196
|
+
"-version",
|
|
1197
|
+
"-writable",
|
|
1198
|
+
"-xdev"
|
|
1199
|
+
],
|
|
1200
|
+
values: [
|
|
1201
|
+
"-maxdepth",
|
|
1202
|
+
"-mindepth",
|
|
1203
|
+
"-name",
|
|
1204
|
+
"-iname",
|
|
1205
|
+
"-path",
|
|
1206
|
+
"-ipath",
|
|
1207
|
+
"-wholename",
|
|
1208
|
+
"-iwholename",
|
|
1209
|
+
"-regex",
|
|
1210
|
+
"-iregex",
|
|
1211
|
+
"-lname",
|
|
1212
|
+
"-ilname",
|
|
1213
|
+
"-type",
|
|
1214
|
+
"-xtype",
|
|
1215
|
+
"-size",
|
|
1216
|
+
"-newer",
|
|
1217
|
+
"-anewer",
|
|
1218
|
+
"-cnewer",
|
|
1219
|
+
"-mtime",
|
|
1220
|
+
"-mmin",
|
|
1221
|
+
"-ctime",
|
|
1222
|
+
"-cmin",
|
|
1223
|
+
"-atime",
|
|
1224
|
+
"-amin",
|
|
1225
|
+
"-used",
|
|
1226
|
+
"-uid",
|
|
1227
|
+
"-gid",
|
|
1228
|
+
"-user",
|
|
1229
|
+
"-group",
|
|
1230
|
+
"-perm",
|
|
1231
|
+
"-links",
|
|
1232
|
+
"-inum",
|
|
1233
|
+
"-samefile",
|
|
1234
|
+
"-fstype",
|
|
1235
|
+
"-regextype",
|
|
1236
|
+
"-files0-from",
|
|
1237
|
+
"-printf",
|
|
1238
|
+
"-context",
|
|
1239
|
+
"-D"
|
|
1240
|
+
],
|
|
1241
|
+
// `find -O2` glues the optimisation level on, and `-newermt`/`-newerat` and
|
|
1242
|
+
// friends spell the two comparison fields into the flag name.
|
|
1243
|
+
patterns: [/^-O\d$/, /^-newer[acmBt][acmBt]$/]
|
|
1244
|
+
},
|
|
1245
|
+
jq: {
|
|
1246
|
+
cluster: true,
|
|
1247
|
+
booleans: [
|
|
1248
|
+
"-a",
|
|
1249
|
+
"-c",
|
|
1250
|
+
"-C",
|
|
1251
|
+
"-e",
|
|
1252
|
+
"-h",
|
|
1253
|
+
"-j",
|
|
1254
|
+
"-M",
|
|
1255
|
+
"-n",
|
|
1256
|
+
"-r",
|
|
1257
|
+
"-R",
|
|
1258
|
+
"-s",
|
|
1259
|
+
"-S",
|
|
1260
|
+
"--ascii-output",
|
|
1261
|
+
"--compact-output",
|
|
1262
|
+
"--color-output",
|
|
1263
|
+
"--monochrome-output",
|
|
1264
|
+
"--exit-status",
|
|
1265
|
+
"--join-output",
|
|
1266
|
+
"--null-input",
|
|
1267
|
+
"--raw-input",
|
|
1268
|
+
"--raw-output",
|
|
1269
|
+
"--raw-output0",
|
|
1270
|
+
"--slurp",
|
|
1271
|
+
"--sort-keys",
|
|
1272
|
+
"--seq",
|
|
1273
|
+
"--stream",
|
|
1274
|
+
"--stream-errors",
|
|
1275
|
+
"--tab",
|
|
1276
|
+
"--unbuffered",
|
|
1277
|
+
"--args",
|
|
1278
|
+
"--jsonargs"
|
|
1279
|
+
],
|
|
1280
|
+
values: [
|
|
1281
|
+
"-f",
|
|
1282
|
+
"-L",
|
|
1283
|
+
"--arg",
|
|
1284
|
+
"--argjson",
|
|
1285
|
+
"--slurpfile",
|
|
1286
|
+
"--rawfile",
|
|
1287
|
+
"--indent",
|
|
1288
|
+
"--from-file"
|
|
1289
|
+
]
|
|
1290
|
+
},
|
|
1291
|
+
yq: {
|
|
1292
|
+
cluster: true,
|
|
1293
|
+
// `-i`/`--inplace`/`--in-place` rewrite the file, and `-s`/`--split-exp`
|
|
1294
|
+
// writes one file per document. All absent — and all bare or near-bare
|
|
1295
|
+
// booleans, which is why exempting booleans was not an option.
|
|
1296
|
+
booleans: [
|
|
1297
|
+
"-C",
|
|
1298
|
+
"-e",
|
|
1299
|
+
"-h",
|
|
1300
|
+
"-j",
|
|
1301
|
+
"-M",
|
|
1302
|
+
"-n",
|
|
1303
|
+
"-N",
|
|
1304
|
+
"-P",
|
|
1305
|
+
"-r",
|
|
1306
|
+
"-S",
|
|
1307
|
+
"-v",
|
|
1308
|
+
"-y",
|
|
1309
|
+
"-Y",
|
|
1310
|
+
"--colors",
|
|
1311
|
+
"--no-colors",
|
|
1312
|
+
"--exit-status",
|
|
1313
|
+
"--no-doc",
|
|
1314
|
+
"--null-input",
|
|
1315
|
+
"--prettyPrint",
|
|
1316
|
+
"--raw-output",
|
|
1317
|
+
"--sort-keys",
|
|
1318
|
+
"--tojson",
|
|
1319
|
+
"--yaml-output",
|
|
1320
|
+
"--yaml-roundtrip",
|
|
1321
|
+
"--unwrapScalar",
|
|
1322
|
+
"--header-preprocess",
|
|
1323
|
+
"--no-exit-status",
|
|
1324
|
+
"--verbose",
|
|
1325
|
+
"--xml-strict-mode"
|
|
1326
|
+
],
|
|
1327
|
+
values: [
|
|
1328
|
+
"-I",
|
|
1329
|
+
"-o",
|
|
1330
|
+
"-p",
|
|
1331
|
+
"-L",
|
|
1332
|
+
"--indent",
|
|
1333
|
+
"--output-format",
|
|
1334
|
+
"--input-format",
|
|
1335
|
+
"--expression",
|
|
1336
|
+
"--width",
|
|
1337
|
+
"--xml-attribute-prefix",
|
|
1338
|
+
"--xml-content-name"
|
|
1339
|
+
]
|
|
1340
|
+
}
|
|
1341
|
+
};
|
|
121
1342
|
var GIT_READONLY_SUBCOMMANDS = [
|
|
122
1343
|
"log",
|
|
123
1344
|
"status",
|
|
124
1345
|
"diff",
|
|
125
1346
|
"show",
|
|
126
1347
|
"ls-files",
|
|
127
|
-
"ls-remote",
|
|
128
1348
|
"ls-tree",
|
|
129
1349
|
"branch",
|
|
130
1350
|
"tag",
|
|
@@ -239,6 +1459,26 @@ var REFUSED_SUBCOMMANDS = {
|
|
|
239
1459
|
az: ["login", "logout"],
|
|
240
1460
|
terraform: ["apply", "destroy"]
|
|
241
1461
|
};
|
|
1462
|
+
var SHELL_KEYWORDS = [
|
|
1463
|
+
"{",
|
|
1464
|
+
"}",
|
|
1465
|
+
"if",
|
|
1466
|
+
"then",
|
|
1467
|
+
"elif",
|
|
1468
|
+
"else",
|
|
1469
|
+
"fi",
|
|
1470
|
+
"for",
|
|
1471
|
+
"while",
|
|
1472
|
+
"until",
|
|
1473
|
+
"do",
|
|
1474
|
+
"done",
|
|
1475
|
+
"case",
|
|
1476
|
+
"esac",
|
|
1477
|
+
"select",
|
|
1478
|
+
"function",
|
|
1479
|
+
"time",
|
|
1480
|
+
"export"
|
|
1481
|
+
];
|
|
242
1482
|
var INTERPRETERS = [
|
|
243
1483
|
"sh",
|
|
244
1484
|
"bash",
|
|
@@ -682,16 +1922,79 @@ function pathLikeArgs(command, opts = {}) {
|
|
|
682
1922
|
return !a.startsWith("-") && looksLikePath(a) ? [a] : [];
|
|
683
1923
|
}));
|
|
684
1924
|
}
|
|
1925
|
+
function matchFlag(spec, booleans, values, token) {
|
|
1926
|
+
if (token.startsWith("--")) {
|
|
1927
|
+
const eq = token.indexOf("=");
|
|
1928
|
+
const name = eq > 0 ? token.slice(0, eq) : token;
|
|
1929
|
+
if (booleans.has(name)) return "boolean";
|
|
1930
|
+
if (values.has(name)) return eq > 0 ? "boolean" : "value";
|
|
1931
|
+
return void 0;
|
|
1932
|
+
}
|
|
1933
|
+
if (booleans.has(token)) return "boolean";
|
|
1934
|
+
if (values.has(token)) return "value";
|
|
1935
|
+
if (spec.patterns?.some((p) => p.test(token))) return "boolean";
|
|
1936
|
+
if (!spec.cluster) return void 0;
|
|
1937
|
+
for (let i = 1; i < token.length; i++) {
|
|
1938
|
+
const short = `-${token[i]}`;
|
|
1939
|
+
if (booleans.has(short)) continue;
|
|
1940
|
+
if (values.has(short)) return i === token.length - 1 ? "value" : "boolean";
|
|
1941
|
+
return void 0;
|
|
1942
|
+
}
|
|
1943
|
+
return "boolean";
|
|
1944
|
+
}
|
|
1945
|
+
function takesNextToken(next) {
|
|
1946
|
+
if (next === void 0) return false;
|
|
1947
|
+
return !/^-./.test(next) || /^-\d/.test(next);
|
|
1948
|
+
}
|
|
1949
|
+
function flagLabel(token) {
|
|
1950
|
+
const eq = token.startsWith("--") ? token.indexOf("=") : -1;
|
|
1951
|
+
return eq > 0 ? token.slice(0, eq) : token;
|
|
1952
|
+
}
|
|
1953
|
+
function scanFlags(seg) {
|
|
1954
|
+
const spec = FLAG_POLICY[seg.binary];
|
|
1955
|
+
if (!spec || spec.freeform) return void 0;
|
|
1956
|
+
const booleans = /* @__PURE__ */ new Set([...spec.booleans ?? [], ...UNIVERSAL_FLAGS]);
|
|
1957
|
+
const values = new Set(spec.values ?? []);
|
|
1958
|
+
const operands = [];
|
|
1959
|
+
let i = 0;
|
|
1960
|
+
while (i < seg.args.length) {
|
|
1961
|
+
const token = seg.args[i];
|
|
1962
|
+
if (token === "--" && !spec.expressionArgs) {
|
|
1963
|
+
operands.push(...seg.args.slice(i + 1));
|
|
1964
|
+
break;
|
|
1965
|
+
}
|
|
1966
|
+
if (!/^-./.test(token)) {
|
|
1967
|
+
operands.push(token);
|
|
1968
|
+
i++;
|
|
1969
|
+
continue;
|
|
1970
|
+
}
|
|
1971
|
+
const shape = matchFlag(spec, booleans, values, token);
|
|
1972
|
+
if (shape === void 0) return { unknown: flagLabel(token), operands };
|
|
1973
|
+
i += shape === "value" && takesNextToken(seg.args[i + 1]) ? 2 : 1;
|
|
1974
|
+
}
|
|
1975
|
+
return { operands };
|
|
1976
|
+
}
|
|
1977
|
+
function subcommandOf(seg) {
|
|
1978
|
+
const scan = scanFlags(seg);
|
|
1979
|
+
if (scan) return scan.operands[0];
|
|
1980
|
+
return seg.args.find((a) => !a.startsWith("-"));
|
|
1981
|
+
}
|
|
1982
|
+
var SCOPE_LEAD_ARGS = 2;
|
|
685
1983
|
function scopeFor(seg) {
|
|
686
1984
|
if (!MULTIPLEXERS.includes(seg.binary)) return seg.binary;
|
|
687
|
-
const
|
|
688
|
-
|
|
1985
|
+
const lead = [];
|
|
1986
|
+
for (const arg of seg.args) {
|
|
1987
|
+
if (arg.startsWith("-")) break;
|
|
1988
|
+
lead.push(arg);
|
|
1989
|
+
if (lead.length === SCOPE_LEAD_ARGS) break;
|
|
1990
|
+
}
|
|
1991
|
+
return [seg.binary, ...lead].join(" ");
|
|
689
1992
|
}
|
|
690
1993
|
function isAuto(seg) {
|
|
691
1994
|
if (!AUTO_COMMANDS.includes(seg.binary)) return false;
|
|
692
1995
|
if (seg.expandable) return false;
|
|
693
1996
|
if (seg.binary !== "git") return true;
|
|
694
|
-
const sub = seg
|
|
1997
|
+
const sub = subcommandOf(seg);
|
|
695
1998
|
return sub !== void 0 && GIT_READONLY_SUBCOMMANDS.includes(sub);
|
|
696
1999
|
}
|
|
697
2000
|
function refusalFor(seg) {
|
|
@@ -701,29 +2004,31 @@ function refusalFor(seg) {
|
|
|
701
2004
|
if (seg.binary === "eval" || seg.binary === "exec") {
|
|
702
2005
|
return `"${seg.binary}" runs a string as a command, which this classifier cannot inspect. Use the read-only research tools, or describe it as a task.`;
|
|
703
2006
|
}
|
|
2007
|
+
if (seg.binary === "source" || seg.binary === ".") {
|
|
2008
|
+
return `"${seg.binary}" runs a file's contents as commands, which this classifier cannot inspect. Use the read-only research tools, or describe it as a task.`;
|
|
2009
|
+
}
|
|
2010
|
+
if (SHELL_KEYWORDS.includes(seg.binary)) {
|
|
2011
|
+
return `"${seg.binary}" is a shell keyword or compound-command opener. This classifier only inspects the command that runs first, and a keyword hides the real one from it. Run the inner command directly, or describe it as a task.`;
|
|
2012
|
+
}
|
|
704
2013
|
const subs = REFUSED_SUBCOMMANDS[seg.binary];
|
|
705
2014
|
if (subs) {
|
|
706
|
-
const sub = seg
|
|
2015
|
+
const sub = subcommandOf(seg);
|
|
707
2016
|
if (sub && subs.includes(sub)) {
|
|
708
2017
|
return `"${seg.binary} ${sub}" changes state or reaches outward. You are a read-only planner \u2014 put it in the plan and let the runner do it.`;
|
|
709
2018
|
}
|
|
710
2019
|
}
|
|
711
2020
|
if (seg.binary === "git") {
|
|
712
|
-
const sub = seg
|
|
2021
|
+
const sub = subcommandOf(seg);
|
|
713
2022
|
if (sub === "branch" || sub === "tag") {
|
|
714
2023
|
const flag = seg.args.find((a) => ["-D", "-d", "-m", "-M", "--delete", "--move"].includes(a));
|
|
715
2024
|
if (flag) {
|
|
716
2025
|
return `"git ${sub} ${flag}" mutates refs. You are a read-only planner \u2014 describe the change as a task instead.`;
|
|
717
2026
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
if (sub === "grep") {
|
|
724
|
-
const pagerFlag = seg.args.find((a) => a === "-O" || a === "--open-files-in-pager" || a.startsWith("--open-files-in-pager="));
|
|
725
|
-
if (pagerFlag) {
|
|
726
|
-
return `"git grep ${pagerFlag}" opens the results in an arbitrary named program. Use the read-only research tools, or describe the change as a task.`;
|
|
2027
|
+
const listing = seg.args.includes("-l") || seg.args.includes("--list");
|
|
2028
|
+
const scan2 = scanFlags(seg);
|
|
2029
|
+
const target = scan2?.operands[1];
|
|
2030
|
+
if (!listing && target) {
|
|
2031
|
+
return `"git ${sub} ${target}" creates or moves a ref. You are a read-only planner \u2014 describe the change as a task instead.`;
|
|
727
2032
|
}
|
|
728
2033
|
}
|
|
729
2034
|
}
|
|
@@ -751,6 +2056,13 @@ function refusalFor(seg) {
|
|
|
751
2056
|
if (seg.assignments.length > 0) {
|
|
752
2057
|
return `The environment assignment "${seg.assignments[0]}" decides what "${seg.binary}" actually does, and this classifier cannot judge the value. Re-run the command without the assignment.`;
|
|
753
2058
|
}
|
|
2059
|
+
const scan = scanFlags(seg);
|
|
2060
|
+
if (scan?.unknown) {
|
|
2061
|
+
return `"${scan.unknown}" is not a flag this classifier knows to be read-only on "${seg.binary}", and flags on otherwise read-only binaries can run a helper program or write a file. Re-run with read-only flags only, or describe the work as a task.`;
|
|
2062
|
+
}
|
|
2063
|
+
if (seg.binary === "uniq" && scan && scan.operands.length > 1) {
|
|
2064
|
+
return `"uniq" writes to its second file argument ("${scan.operands[1]}"). You are a read-only planner \u2014 pipe the output instead of naming an output file, or describe the write as a task.`;
|
|
2065
|
+
}
|
|
754
2066
|
return void 0;
|
|
755
2067
|
}
|
|
756
2068
|
function withWrapperNote(reason, wrappers) {
|
|
@@ -1137,6 +2449,139 @@ It is outside the auto-allowed read-only set (${scope}). Continue with the read-
|
|
|
1137
2449
|
}
|
|
1138
2450
|
};
|
|
1139
2451
|
|
|
2452
|
+
// src/utils/redactSecrets.ts
|
|
2453
|
+
var REDACTION_MARKER = "REDACTED";
|
|
2454
|
+
function marker(kind, length) {
|
|
2455
|
+
return `[${REDACTION_MARKER} ${kind}: ${length} chars]`;
|
|
2456
|
+
}
|
|
2457
|
+
var LINE_PREFIX = String.raw`(?:[ \t]*\d+\||[^\s:]*:\d+:|)[ \t]*`;
|
|
2458
|
+
var LINE_PREFIX_ANCHORED = new RegExp("^" + LINE_PREFIX);
|
|
2459
|
+
var CREDENTIAL_WORD = String.raw`(?:api[_-]?keys?|secrets?|passwords?|passwd|passphrase|tokens?|access[_-]?keys?|private[_-]?keys?|client[_-]?secrets?|credentials?|auth)(?![a-z])`;
|
|
2460
|
+
var NAMED_CREDENTIAL = new RegExp(
|
|
2461
|
+
String.raw`((?:^|[^A-Za-z0-9_])["']?[A-Za-z0-9_.\-]*` + CREDENTIAL_WORD + String.raw`[A-Za-z0-9_.\-]*["']?[ \t]*(?:=>|[:=])[ \t]*)(["'\x60]?)([A-Za-z0-9_\-./+=:~!@#%^&*]{8,})\2`,
|
|
2462
|
+
"gi"
|
|
2463
|
+
);
|
|
2464
|
+
var DOTENV_CREDENTIAL = new RegExp(
|
|
2465
|
+
String.raw`^(` + LINE_PREFIX + String.raw`(?:export[ \t]+)?[A-Z0-9_]*` + CREDENTIAL_WORD.toUpperCase() + String.raw`[A-Z0-9_]*[ \t]*=[ \t]*)(["'\x60]?)([^\s"'\x60]{3,})\2[ \t]*$`,
|
|
2466
|
+
"gm"
|
|
2467
|
+
);
|
|
2468
|
+
var PROVIDER_KEY_PATTERNS = [
|
|
2469
|
+
// OpenAI / Anthropic / OpenRouter and the many `sk-` derivatives
|
|
2470
|
+
/(?<![A-Za-z0-9])sk-(?:ant-|proj-|or-v1-|live-|test-)?[A-Za-z0-9_-]{20,}/g,
|
|
2471
|
+
// GitHub personal-access, OAuth, app and refresh tokens
|
|
2472
|
+
/(?<![A-Za-z0-9])(?:gh[pousr]|github_pat)_[A-Za-z0-9_]{22,}/g,
|
|
2473
|
+
// Slack bot / user / app tokens
|
|
2474
|
+
/(?<![A-Za-z0-9])xox[abprse]-[A-Za-z0-9-]{10,}/g,
|
|
2475
|
+
// Stripe secret and restricted keys
|
|
2476
|
+
/(?<![A-Za-z0-9])[sr]k_(?:live|test)_[A-Za-z0-9]{16,}/g,
|
|
2477
|
+
// Google API keys and OAuth access tokens
|
|
2478
|
+
/(?<![A-Za-z0-9])AIza[A-Za-z0-9_-]{30,}/g,
|
|
2479
|
+
/(?<![A-Za-z0-9])ya29\.[A-Za-z0-9_-]{20,}/g,
|
|
2480
|
+
// npm, Hugging Face, Groq, GitLab, DigitalOcean, Shopify
|
|
2481
|
+
/(?<![A-Za-z0-9])(?:npm|hf|gsk|glpat|dop_v1|shpat|shpss)[_-][A-Za-z0-9]{20,}/g,
|
|
2482
|
+
/(?<![A-Za-z0-9])xai-[A-Za-z0-9]{20,}/g,
|
|
2483
|
+
// Three-segment JWTs, whose payload segment is base64 for `{"`
|
|
2484
|
+
/(?<![A-Za-z0-9])eyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g
|
|
2485
|
+
];
|
|
2486
|
+
var CLOUD_ACCESS_KEY_ID = /(?<![A-Za-z0-9])(?:A3T[A-Z0-9]{2}|AKIA|ASIA|ABIA|ACCA|AGPA|AIDA|AIPA|ANPA|ANVA|AROA)[A-Z0-9]{16}(?![A-Za-z0-9])/g;
|
|
2487
|
+
var PEM_BEGIN = /-----BEGIN ((?:[A-Z0-9]+ )*PRIVATE KEY(?: BLOCK)?)-----/;
|
|
2488
|
+
var PEM_BODY_LINE = /^[A-Za-z0-9+/=:,.\- \t]*$/;
|
|
2489
|
+
function redactPrivateKeyBlocks(text) {
|
|
2490
|
+
if (!PEM_BEGIN.test(text)) return text;
|
|
2491
|
+
const out = [];
|
|
2492
|
+
let label = null;
|
|
2493
|
+
let bodyChars = 0;
|
|
2494
|
+
const closeBlock = () => {
|
|
2495
|
+
if (label === null) return;
|
|
2496
|
+
out.push(marker("private key", bodyChars));
|
|
2497
|
+
label = null;
|
|
2498
|
+
bodyChars = 0;
|
|
2499
|
+
};
|
|
2500
|
+
for (const line of text.split("\n")) {
|
|
2501
|
+
if (label === null) {
|
|
2502
|
+
out.push(line);
|
|
2503
|
+
const begun = PEM_BEGIN.exec(line);
|
|
2504
|
+
if (begun) label = begun[1];
|
|
2505
|
+
continue;
|
|
2506
|
+
}
|
|
2507
|
+
const content = line.replace(LINE_PREFIX_ANCHORED, "");
|
|
2508
|
+
if (content.includes(`-----END ${label}-----`)) {
|
|
2509
|
+
closeBlock();
|
|
2510
|
+
out.push(line);
|
|
2511
|
+
} else if (PEM_BODY_LINE.test(content)) {
|
|
2512
|
+
bodyChars += content.trim().length;
|
|
2513
|
+
} else {
|
|
2514
|
+
closeBlock();
|
|
2515
|
+
out.push(line);
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
closeBlock();
|
|
2519
|
+
return out.join("\n");
|
|
2520
|
+
}
|
|
2521
|
+
var NUMERIC = /^[-+]?\d+(?:\.\d+)?$/;
|
|
2522
|
+
var IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
2523
|
+
var MEMBER_EXPRESSION = /^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)+$/;
|
|
2524
|
+
var SLUG = /^[a-z]+(?:[-_][a-z]+)+$/;
|
|
2525
|
+
var PATHISH = /^(?:\.{0,2}\/|~\/)/;
|
|
2526
|
+
var URLISH = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
2527
|
+
var CODE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2528
|
+
"true",
|
|
2529
|
+
"false",
|
|
2530
|
+
"null",
|
|
2531
|
+
"none",
|
|
2532
|
+
"nil",
|
|
2533
|
+
"undefined",
|
|
2534
|
+
"void",
|
|
2535
|
+
"string",
|
|
2536
|
+
"number",
|
|
2537
|
+
"boolean",
|
|
2538
|
+
"object",
|
|
2539
|
+
"any",
|
|
2540
|
+
"unknown",
|
|
2541
|
+
"bool",
|
|
2542
|
+
"str",
|
|
2543
|
+
"int"
|
|
2544
|
+
]);
|
|
2545
|
+
var UNAMBIGUOUS_CREDENTIAL_NAME = /(?:password|passwd|passphrase|secret|credentials?|private[_-]?key)/i;
|
|
2546
|
+
function looksLikeKeyMaterial(value) {
|
|
2547
|
+
const hasDigit = /\d/.test(value);
|
|
2548
|
+
const hasAlpha = /[A-Za-z]/.test(value);
|
|
2549
|
+
const mixedCase = /[a-z]/.test(value) && /[A-Z]/.test(value);
|
|
2550
|
+
return hasDigit && hasAlpha || mixedCase || value.length >= 24;
|
|
2551
|
+
}
|
|
2552
|
+
function looksLikeCode(value) {
|
|
2553
|
+
return NUMERIC.test(value) || CODE_KEYWORDS.has(value.toLowerCase()) || MEMBER_EXPRESSION.test(value) || PATHISH.test(value) || URLISH.test(value);
|
|
2554
|
+
}
|
|
2555
|
+
function trimTrailingPunctuation(value) {
|
|
2556
|
+
const match = /[.:!]+$/.exec(value);
|
|
2557
|
+
if (!match || match.index === 0) return { value, tail: "" };
|
|
2558
|
+
return { value: value.slice(0, match.index), tail: match[0] };
|
|
2559
|
+
}
|
|
2560
|
+
function redactSecrets(text) {
|
|
2561
|
+
if (!text) return text;
|
|
2562
|
+
let out = redactPrivateKeyBlocks(text);
|
|
2563
|
+
out = out.replace(DOTENV_CREDENTIAL, (full, head, quote, value) => {
|
|
2564
|
+
if (looksLikeCode(value) || value.startsWith("$")) return full;
|
|
2565
|
+
return `${head}${quote}${marker("credential", value.length)}${quote}`;
|
|
2566
|
+
});
|
|
2567
|
+
out = out.replace(NAMED_CREDENTIAL, (full, head, quote, raw) => {
|
|
2568
|
+
const { value, tail } = trimTrailingPunctuation(raw);
|
|
2569
|
+
if (value.length < 8) return full;
|
|
2570
|
+
if (looksLikeCode(value) || value.startsWith("$")) return full;
|
|
2571
|
+
if (UNAMBIGUOUS_CREDENTIAL_NAME.test(head) && /\d/.test(value)) {
|
|
2572
|
+
return `${head}${quote}${marker("credential", value.length)}${quote}${tail}`;
|
|
2573
|
+
}
|
|
2574
|
+
if (IDENTIFIER.test(value) || SLUG.test(value)) return full;
|
|
2575
|
+
if (!UNAMBIGUOUS_CREDENTIAL_NAME.test(head) && !looksLikeKeyMaterial(value)) return full;
|
|
2576
|
+
return `${head}${quote}${marker("credential", value.length)}${quote}${tail}`;
|
|
2577
|
+
});
|
|
2578
|
+
for (const pattern of PROVIDER_KEY_PATTERNS) {
|
|
2579
|
+
out = out.replace(pattern, (hit) => marker("api key", hit.length));
|
|
2580
|
+
}
|
|
2581
|
+
out = out.replace(CLOUD_ACCESS_KEY_ID, (hit) => marker("access key id", hit.length));
|
|
2582
|
+
return out;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
1140
2585
|
// src/services/executeTool.ts
|
|
1141
2586
|
var GREP_OUTPUT_MODES = ["content", "files", "count"];
|
|
1142
2587
|
function num(value) {
|
|
@@ -1163,6 +2608,10 @@ function grepOptions(args) {
|
|
|
1163
2608
|
}
|
|
1164
2609
|
var STOPPED_TOOL_RESULT = "Stopped by the user \u2014 this call was not executed, and no further tool calls will run this turn.";
|
|
1165
2610
|
async function executeTool(name, args, fs10, fetcher, signal) {
|
|
2611
|
+
const outcome = await runTool(name, args, fs10, fetcher, signal);
|
|
2612
|
+
return { ...outcome, output: redactSecrets(outcome.output) };
|
|
2613
|
+
}
|
|
2614
|
+
async function runTool(name, args, fs10, fetcher, signal) {
|
|
1166
2615
|
if (signal?.aborted) return { success: false, output: STOPPED_TOOL_RESULT, truncated: false };
|
|
1167
2616
|
switch (name) {
|
|
1168
2617
|
case "read_file": {
|
|
@@ -4498,11 +5947,11 @@ function composeAugmentedPrompt(task, allTasks, opts) {
|
|
|
4498
5947
|
if (isHitlTask(task)) {
|
|
4499
5948
|
blocks.push(renderCheckpointInstruction());
|
|
4500
5949
|
}
|
|
4501
|
-
const
|
|
4502
|
-
if (blocks.length === 0) return basePrompt +
|
|
5950
|
+
const marker2 = renderCompletionMarker(task);
|
|
5951
|
+
if (blocks.length === 0) return basePrompt + marker2;
|
|
4503
5952
|
return `${blocks.join("\n\n")}
|
|
4504
5953
|
|
|
4505
|
-
${basePrompt}${
|
|
5954
|
+
${basePrompt}${marker2}`;
|
|
4506
5955
|
}
|
|
4507
5956
|
|
|
4508
5957
|
// src/services/VerdictEngine.ts
|
|
@@ -7449,7 +8898,7 @@ function assertWorkspaceIsProject(workspace, deps = {}) {
|
|
|
7449
8898
|
throw new WorkspaceNotAProjectError(workspace);
|
|
7450
8899
|
}
|
|
7451
8900
|
const hasMarker = [...PROJECT_MARKER_DIRS, ...PROJECT_MARKER_FILES].some(
|
|
7452
|
-
(
|
|
8901
|
+
(marker2) => exists(path9.join(resolved, marker2))
|
|
7453
8902
|
);
|
|
7454
8903
|
if (!hasMarker) throw new WorkspaceNotAProjectError(workspace);
|
|
7455
8904
|
}
|
|
@@ -8669,7 +10118,8 @@ var CliAgentAiService = class {
|
|
|
8669
10118
|
let stepIndex = 0;
|
|
8670
10119
|
const truncate = (value) => value.length > LOG_MAX_CHARS ? `${value.slice(0, LOG_MAX_CHARS)}
|
|
8671
10120
|
[... truncated, total ${value.length} chars]` : value;
|
|
8672
|
-
const settle = (id,
|
|
10121
|
+
const settle = (id, rawOutput, success, outcome) => {
|
|
10122
|
+
const output = redactSecrets(rawOutput);
|
|
8673
10123
|
const call = pendingCalls.get(id);
|
|
8674
10124
|
pendingCalls.delete(id);
|
|
8675
10125
|
const step = {
|
|
@@ -9200,6 +10650,16 @@ function ensureDir(dir) {
|
|
|
9200
10650
|
function getStateDir(baseDir) {
|
|
9201
10651
|
return path10.join(baseDir ?? process.cwd(), STATE_DIR);
|
|
9202
10652
|
}
|
|
10653
|
+
var IGNORE_FILE = ".gitignore";
|
|
10654
|
+
function ensureStateDirIgnored(baseDir) {
|
|
10655
|
+
const dir = getStateDir(baseDir);
|
|
10656
|
+
ensureDir(dir);
|
|
10657
|
+
try {
|
|
10658
|
+
fs4.writeFileSync(path10.join(dir, IGNORE_FILE), "*\n", { flag: "wx" });
|
|
10659
|
+
} catch (err) {
|
|
10660
|
+
if (err.code !== "EEXIST") throw err;
|
|
10661
|
+
}
|
|
10662
|
+
}
|
|
9203
10663
|
|
|
9204
10664
|
// src/utils/sessionId.ts
|
|
9205
10665
|
import { randomBytes } from "crypto";
|
|
@@ -9229,6 +10689,7 @@ function sessionFilename(session) {
|
|
|
9229
10689
|
function saveSession(plan, goal, baseDir, id) {
|
|
9230
10690
|
const sessionsDir = getSessionsDir(baseDir);
|
|
9231
10691
|
ensureDir(sessionsDir);
|
|
10692
|
+
ensureStateDirIgnored(baseDir);
|
|
9232
10693
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
9233
10694
|
const meta = {
|
|
9234
10695
|
id: id || mintSessionId(),
|
|
@@ -10781,7 +12242,7 @@ import { execFile as execFile2 } from "child_process";
|
|
|
10781
12242
|
import { promisify as promisify4 } from "util";
|
|
10782
12243
|
import { tmpdir } from "os";
|
|
10783
12244
|
import { join as join10 } from "path";
|
|
10784
|
-
import { existsSync as existsSync6, readFileSync as readFileSync4, unlinkSync as unlinkSync2, writeFileSync as
|
|
12245
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
10785
12246
|
|
|
10786
12247
|
// src/utils/tmux.ts
|
|
10787
12248
|
import { execSync as execSync2 } from "child_process";
|
|
@@ -10872,7 +12333,7 @@ var TmuxSession = class extends AbstractTerminalSession {
|
|
|
10872
12333
|
* lets the user keep poking at a finished task's terminal.
|
|
10873
12334
|
*/
|
|
10874
12335
|
async start(command, args, cwd, env) {
|
|
10875
|
-
|
|
12336
|
+
writeFileSync6(this.logPath, "");
|
|
10876
12337
|
const envAssignments = Object.entries(env ?? {}).map(([k, v]) => `${k}=${posixShellQuote(v)}`).join(" ");
|
|
10877
12338
|
const inner = [command, ...args].map(posixShellQuote).join(" ");
|
|
10878
12339
|
const prefix = envAssignments ? `env ${envAssignments} ` : "";
|
|
@@ -12245,6 +13706,7 @@ export {
|
|
|
12245
13706
|
emptyWarnings,
|
|
12246
13707
|
enabledRunners,
|
|
12247
13708
|
ensureDir,
|
|
13709
|
+
ensureStateDirIgnored,
|
|
12248
13710
|
escapeControlCharsInStrings,
|
|
12249
13711
|
executionLogBlock,
|
|
12250
13712
|
executionSummary,
|