@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.js
CHANGED
|
@@ -166,6 +166,7 @@ __export(index_exports, {
|
|
|
166
166
|
emptyWarnings: () => emptyWarnings,
|
|
167
167
|
enabledRunners: () => enabledRunners,
|
|
168
168
|
ensureDir: () => ensureDir,
|
|
169
|
+
ensureStateDirIgnored: () => ensureStateDirIgnored,
|
|
169
170
|
escapeControlCharsInStrings: () => escapeControlCharsInStrings,
|
|
170
171
|
executionLogBlock: () => executionLogBlock,
|
|
171
172
|
executionSummary: () => executionSummary,
|
|
@@ -642,13 +643,1233 @@ var AUTO_COMMANDS = [
|
|
|
642
643
|
"jq",
|
|
643
644
|
"yq"
|
|
644
645
|
];
|
|
646
|
+
var UNIVERSAL_FLAGS = ["--help", "--version"];
|
|
647
|
+
var COUNT_FLAG = /^-\d+$/;
|
|
648
|
+
var FLAG_POLICY = {
|
|
649
|
+
ls: {
|
|
650
|
+
cluster: true,
|
|
651
|
+
booleans: [
|
|
652
|
+
"-1",
|
|
653
|
+
"-a",
|
|
654
|
+
"-A",
|
|
655
|
+
"-b",
|
|
656
|
+
"-c",
|
|
657
|
+
"-C",
|
|
658
|
+
"-d",
|
|
659
|
+
"-D",
|
|
660
|
+
"-f",
|
|
661
|
+
"-F",
|
|
662
|
+
"-g",
|
|
663
|
+
"-G",
|
|
664
|
+
"-h",
|
|
665
|
+
"-H",
|
|
666
|
+
"-i",
|
|
667
|
+
"-k",
|
|
668
|
+
"-l",
|
|
669
|
+
"-L",
|
|
670
|
+
"-m",
|
|
671
|
+
"-n",
|
|
672
|
+
"-N",
|
|
673
|
+
"-o",
|
|
674
|
+
"-p",
|
|
675
|
+
"-q",
|
|
676
|
+
"-Q",
|
|
677
|
+
"-r",
|
|
678
|
+
"-R",
|
|
679
|
+
"-s",
|
|
680
|
+
"-S",
|
|
681
|
+
"-t",
|
|
682
|
+
"-u",
|
|
683
|
+
"-U",
|
|
684
|
+
"-v",
|
|
685
|
+
"-x",
|
|
686
|
+
"-X",
|
|
687
|
+
"-Z",
|
|
688
|
+
"--all",
|
|
689
|
+
"--almost-all",
|
|
690
|
+
"--author",
|
|
691
|
+
"--escape",
|
|
692
|
+
"--classify",
|
|
693
|
+
"--file-type",
|
|
694
|
+
"--full-time",
|
|
695
|
+
"--no-group",
|
|
696
|
+
"--human-readable",
|
|
697
|
+
"--si",
|
|
698
|
+
"--dereference-command-line",
|
|
699
|
+
"--inode",
|
|
700
|
+
"--kibibytes",
|
|
701
|
+
"--dereference",
|
|
702
|
+
"--numeric-uid-gid",
|
|
703
|
+
"--literal",
|
|
704
|
+
"--hide-control-chars",
|
|
705
|
+
"--show-control-chars",
|
|
706
|
+
"--quote-name",
|
|
707
|
+
"--reverse",
|
|
708
|
+
"--recursive",
|
|
709
|
+
"--size",
|
|
710
|
+
"--directory",
|
|
711
|
+
"--group-directories-first",
|
|
712
|
+
"--context",
|
|
713
|
+
"--zero"
|
|
714
|
+
],
|
|
715
|
+
values: [
|
|
716
|
+
"-w",
|
|
717
|
+
"-I",
|
|
718
|
+
"-T",
|
|
719
|
+
"--width",
|
|
720
|
+
"--ignore",
|
|
721
|
+
"--hide",
|
|
722
|
+
"--block-size",
|
|
723
|
+
"--color",
|
|
724
|
+
"--format",
|
|
725
|
+
"--sort",
|
|
726
|
+
"--time",
|
|
727
|
+
"--time-style",
|
|
728
|
+
"--indicator-style",
|
|
729
|
+
"--quoting-style",
|
|
730
|
+
"--tabsize"
|
|
731
|
+
]
|
|
732
|
+
},
|
|
733
|
+
tree: {
|
|
734
|
+
cluster: true,
|
|
735
|
+
// `-o` is absent on purpose: it is tree's write-to-a-file flag, which the
|
|
736
|
+
// redirect check never sees because there is no redirect.
|
|
737
|
+
booleans: [
|
|
738
|
+
"-a",
|
|
739
|
+
"-d",
|
|
740
|
+
"-f",
|
|
741
|
+
"-i",
|
|
742
|
+
"-l",
|
|
743
|
+
"-x",
|
|
744
|
+
"-C",
|
|
745
|
+
"-n",
|
|
746
|
+
"-p",
|
|
747
|
+
"-s",
|
|
748
|
+
"-h",
|
|
749
|
+
"-u",
|
|
750
|
+
"-g",
|
|
751
|
+
"-D",
|
|
752
|
+
"-t",
|
|
753
|
+
"-c",
|
|
754
|
+
"-r",
|
|
755
|
+
"-F",
|
|
756
|
+
"-q",
|
|
757
|
+
"-N",
|
|
758
|
+
"-Q",
|
|
759
|
+
"-v",
|
|
760
|
+
"-J",
|
|
761
|
+
"-X",
|
|
762
|
+
"-Z",
|
|
763
|
+
"--noreport",
|
|
764
|
+
"--dirsfirst",
|
|
765
|
+
"--du",
|
|
766
|
+
"--prune",
|
|
767
|
+
"--matchdirs",
|
|
768
|
+
"--inodes",
|
|
769
|
+
"--device",
|
|
770
|
+
"--si",
|
|
771
|
+
"--gitignore",
|
|
772
|
+
"--ignore-case",
|
|
773
|
+
"--filesfirst",
|
|
774
|
+
"--nolinks",
|
|
775
|
+
"--hintro"
|
|
776
|
+
],
|
|
777
|
+
values: [
|
|
778
|
+
"-L",
|
|
779
|
+
"-P",
|
|
780
|
+
"-I",
|
|
781
|
+
"-H",
|
|
782
|
+
"--filelimit",
|
|
783
|
+
"--timefmt",
|
|
784
|
+
"--charset",
|
|
785
|
+
"--sort",
|
|
786
|
+
"--gitfile",
|
|
787
|
+
"--info",
|
|
788
|
+
"--prefix"
|
|
789
|
+
]
|
|
790
|
+
},
|
|
791
|
+
git: {
|
|
792
|
+
cluster: true,
|
|
793
|
+
// Absent on purpose, and each for a reason that was demonstrated rather than
|
|
794
|
+
// guessed at:
|
|
795
|
+
// -c, --config-env set configuration inline, and several configuration
|
|
796
|
+
// keys name a program to run (`core.pager`, `core.editor`,
|
|
797
|
+
// `diff.external`), so this is an execution flag with one
|
|
798
|
+
// indirection in front of it.
|
|
799
|
+
// --exec-path redirects where git finds its helper programs; a
|
|
800
|
+
// fabricated helper ran during an ordinary remote listing.
|
|
801
|
+
// -O, --open-files-in-pager runs an arbitrary named program over search hits.
|
|
802
|
+
// --upload-pack, --receive-pack name the program run on the other end.
|
|
803
|
+
// --textconv, --ext-diff run filters the repository itself configures.
|
|
804
|
+
// --git-dir, --work-tree repoint git at a tree whose configuration is not
|
|
805
|
+
// the one the developer is looking at.
|
|
806
|
+
// -o, --output write a file. `git ls-files -o` is a legitimate spelling
|
|
807
|
+
// of `--others`, but `git archive -o` writes, and the
|
|
808
|
+
// long spelling stays available for the read.
|
|
809
|
+
booleans: [
|
|
810
|
+
"-a",
|
|
811
|
+
"-b",
|
|
812
|
+
"-E",
|
|
813
|
+
"-F",
|
|
814
|
+
"-h",
|
|
815
|
+
"-H",
|
|
816
|
+
"-i",
|
|
817
|
+
"-I",
|
|
818
|
+
"-l",
|
|
819
|
+
"-p",
|
|
820
|
+
"-P",
|
|
821
|
+
"-q",
|
|
822
|
+
"-r",
|
|
823
|
+
"-R",
|
|
824
|
+
"-s",
|
|
825
|
+
"-t",
|
|
826
|
+
"-u",
|
|
827
|
+
"-v",
|
|
828
|
+
"-w",
|
|
829
|
+
"-z",
|
|
830
|
+
"--oneline",
|
|
831
|
+
"--graph",
|
|
832
|
+
"--stat",
|
|
833
|
+
"--shortstat",
|
|
834
|
+
"--numstat",
|
|
835
|
+
"--dirstat",
|
|
836
|
+
"--summary",
|
|
837
|
+
"--name-only",
|
|
838
|
+
"--name-status",
|
|
839
|
+
"--raw",
|
|
840
|
+
"--patch",
|
|
841
|
+
"--no-patch",
|
|
842
|
+
"--patch-with-stat",
|
|
843
|
+
"--cached",
|
|
844
|
+
"--staged",
|
|
845
|
+
"--porcelain",
|
|
846
|
+
"--short",
|
|
847
|
+
"--long",
|
|
848
|
+
"--branch",
|
|
849
|
+
"--show-stash",
|
|
850
|
+
"--show-current",
|
|
851
|
+
"--all",
|
|
852
|
+
"--tags",
|
|
853
|
+
"--heads",
|
|
854
|
+
"--remotes",
|
|
855
|
+
"--list",
|
|
856
|
+
"--verbose",
|
|
857
|
+
"--quiet",
|
|
858
|
+
"--abbrev-ref",
|
|
859
|
+
"--count",
|
|
860
|
+
"--reverse",
|
|
861
|
+
"--first-parent",
|
|
862
|
+
"--no-merges",
|
|
863
|
+
"--merges",
|
|
864
|
+
"--follow",
|
|
865
|
+
"--full-history",
|
|
866
|
+
"--simplify-merges",
|
|
867
|
+
"--sparse",
|
|
868
|
+
"--dense",
|
|
869
|
+
"--ancestry-path",
|
|
870
|
+
"--left-right",
|
|
871
|
+
"--cherry",
|
|
872
|
+
"--cherry-pick",
|
|
873
|
+
"--cherry-mark",
|
|
874
|
+
"--boundary",
|
|
875
|
+
"--topo-order",
|
|
876
|
+
"--date-order",
|
|
877
|
+
"--author-date-order",
|
|
878
|
+
"--relative-date",
|
|
879
|
+
"--parents",
|
|
880
|
+
"--children",
|
|
881
|
+
"--timestamp",
|
|
882
|
+
"--no-walk",
|
|
883
|
+
"--do-walk",
|
|
884
|
+
"--decorate",
|
|
885
|
+
"--no-decorate",
|
|
886
|
+
"--abbrev-commit",
|
|
887
|
+
"--no-abbrev-commit",
|
|
888
|
+
"--abbrev",
|
|
889
|
+
"--no-abbrev",
|
|
890
|
+
"--color",
|
|
891
|
+
"--no-color",
|
|
892
|
+
"--pretty",
|
|
893
|
+
"--format",
|
|
894
|
+
"--expand-tabs",
|
|
895
|
+
"--no-expand-tabs",
|
|
896
|
+
"--numbered",
|
|
897
|
+
"--email",
|
|
898
|
+
"--no-notes",
|
|
899
|
+
"--notes",
|
|
900
|
+
"--show-signature",
|
|
901
|
+
"--find-renames",
|
|
902
|
+
"--find-copies",
|
|
903
|
+
"--find-copies-harder",
|
|
904
|
+
"--break-rewrites",
|
|
905
|
+
"--no-renames",
|
|
906
|
+
"--irreversible-delete",
|
|
907
|
+
"--full-index",
|
|
908
|
+
"--binary",
|
|
909
|
+
"--text",
|
|
910
|
+
"--check",
|
|
911
|
+
"--exit-code",
|
|
912
|
+
"--word-diff",
|
|
913
|
+
"--function-context",
|
|
914
|
+
"--ignore-all-space",
|
|
915
|
+
"--ignore-space-change",
|
|
916
|
+
"--ignore-space-at-eol",
|
|
917
|
+
"--ignore-blank-lines",
|
|
918
|
+
"--ignore-cr-at-eol",
|
|
919
|
+
"--no-prefix",
|
|
920
|
+
"--default-prefix",
|
|
921
|
+
"--no-textconv",
|
|
922
|
+
"--no-ext-diff",
|
|
923
|
+
"--submodule",
|
|
924
|
+
"--ignore-submodules",
|
|
925
|
+
"--recurse-submodules",
|
|
926
|
+
"--no-recurse-submodules",
|
|
927
|
+
"--others",
|
|
928
|
+
"--deleted",
|
|
929
|
+
"--modified",
|
|
930
|
+
"--unmerged",
|
|
931
|
+
"--stage",
|
|
932
|
+
"--killed",
|
|
933
|
+
"--ignored",
|
|
934
|
+
"--exclude-standard",
|
|
935
|
+
"--error-unmatch",
|
|
936
|
+
"--full-name",
|
|
937
|
+
"--directory",
|
|
938
|
+
"--no-empty-directory",
|
|
939
|
+
"--untracked-files",
|
|
940
|
+
"--no-optional-locks",
|
|
941
|
+
"--no-pager",
|
|
942
|
+
"--paginate",
|
|
943
|
+
"--bare",
|
|
944
|
+
"--literal-pathspecs",
|
|
945
|
+
"--glob-pathspecs",
|
|
946
|
+
"--noglob-pathspecs",
|
|
947
|
+
"--icase-pathspecs",
|
|
948
|
+
"--line-number",
|
|
949
|
+
"--column",
|
|
950
|
+
"--heading",
|
|
951
|
+
"--no-index",
|
|
952
|
+
"--untracked",
|
|
953
|
+
"--no-recursive",
|
|
954
|
+
"--name-rev",
|
|
955
|
+
"--root",
|
|
956
|
+
"--dirty",
|
|
957
|
+
"--broken",
|
|
958
|
+
"--always",
|
|
959
|
+
"--merged",
|
|
960
|
+
"--no-merged",
|
|
961
|
+
"--show-toplevel",
|
|
962
|
+
"--show-cdup",
|
|
963
|
+
"--git-common-dir",
|
|
964
|
+
"--absolute-git-dir",
|
|
965
|
+
"--is-inside-work-tree",
|
|
966
|
+
"--is-inside-git-dir",
|
|
967
|
+
"--is-bare-repository",
|
|
968
|
+
"--symbolic",
|
|
969
|
+
"--symbolic-full-name",
|
|
970
|
+
"--verify",
|
|
971
|
+
"--short-hash",
|
|
972
|
+
"--textual",
|
|
973
|
+
"--batch",
|
|
974
|
+
"--batch-check",
|
|
975
|
+
"--batch-all-objects",
|
|
976
|
+
"--buffer",
|
|
977
|
+
"--follow-symlinks",
|
|
978
|
+
"--use-mailmap"
|
|
979
|
+
],
|
|
980
|
+
values: [
|
|
981
|
+
"-n",
|
|
982
|
+
"-C",
|
|
983
|
+
"-B",
|
|
984
|
+
"-M",
|
|
985
|
+
"-L",
|
|
986
|
+
"-S",
|
|
987
|
+
"-G",
|
|
988
|
+
"-U",
|
|
989
|
+
"-e",
|
|
990
|
+
"-m",
|
|
991
|
+
"-f",
|
|
992
|
+
"-g",
|
|
993
|
+
"-x",
|
|
994
|
+
"-X",
|
|
995
|
+
"-W",
|
|
996
|
+
"--max-count",
|
|
997
|
+
"--skip",
|
|
998
|
+
"--since",
|
|
999
|
+
"--after",
|
|
1000
|
+
"--until",
|
|
1001
|
+
"--before",
|
|
1002
|
+
"--author",
|
|
1003
|
+
"--grep",
|
|
1004
|
+
"--grep-reflog",
|
|
1005
|
+
"--committer",
|
|
1006
|
+
"--date",
|
|
1007
|
+
"--diff-filter",
|
|
1008
|
+
"--unified",
|
|
1009
|
+
"--stat-width",
|
|
1010
|
+
"--stat-name-width",
|
|
1011
|
+
"--stat-count",
|
|
1012
|
+
"--word-diff-regex",
|
|
1013
|
+
"--line-prefix",
|
|
1014
|
+
"--src-prefix",
|
|
1015
|
+
"--dst-prefix",
|
|
1016
|
+
"--pickaxe-regex",
|
|
1017
|
+
"--anchored",
|
|
1018
|
+
"--color-moved",
|
|
1019
|
+
"--color-words",
|
|
1020
|
+
"--inter-hunk-context",
|
|
1021
|
+
"--max-parents",
|
|
1022
|
+
"--min-parents",
|
|
1023
|
+
"--simplify-by-decoration",
|
|
1024
|
+
"--glob",
|
|
1025
|
+
"--exclude",
|
|
1026
|
+
"--sort",
|
|
1027
|
+
"--contains",
|
|
1028
|
+
"--points-at",
|
|
1029
|
+
"--decorate-refs",
|
|
1030
|
+
"--decorate-refs-exclude",
|
|
1031
|
+
"--encoding",
|
|
1032
|
+
"--context",
|
|
1033
|
+
"--max-depth",
|
|
1034
|
+
// `--filters` is absent from this list on purpose: it runs the clean and
|
|
1035
|
+
// smudge filters the repository under research configures, which is the
|
|
1036
|
+
// same execution vector as the configuration flag above with a different
|
|
1037
|
+
// spelling.
|
|
1038
|
+
"--and",
|
|
1039
|
+
"--or",
|
|
1040
|
+
"--not",
|
|
1041
|
+
"--all-match",
|
|
1042
|
+
"--threads",
|
|
1043
|
+
"--path"
|
|
1044
|
+
],
|
|
1045
|
+
patterns: [COUNT_FLAG]
|
|
1046
|
+
},
|
|
1047
|
+
wc: {
|
|
1048
|
+
cluster: true,
|
|
1049
|
+
booleans: [
|
|
1050
|
+
"-c",
|
|
1051
|
+
"-l",
|
|
1052
|
+
"-m",
|
|
1053
|
+
"-w",
|
|
1054
|
+
"-L",
|
|
1055
|
+
"--bytes",
|
|
1056
|
+
"--chars",
|
|
1057
|
+
"--lines",
|
|
1058
|
+
"--words",
|
|
1059
|
+
"--max-line-length",
|
|
1060
|
+
"--total"
|
|
1061
|
+
]
|
|
1062
|
+
},
|
|
1063
|
+
du: {
|
|
1064
|
+
cluster: true,
|
|
1065
|
+
booleans: [
|
|
1066
|
+
"-0",
|
|
1067
|
+
"-a",
|
|
1068
|
+
"-b",
|
|
1069
|
+
"-c",
|
|
1070
|
+
"-D",
|
|
1071
|
+
"-h",
|
|
1072
|
+
"-H",
|
|
1073
|
+
"-k",
|
|
1074
|
+
"-l",
|
|
1075
|
+
"-L",
|
|
1076
|
+
"-m",
|
|
1077
|
+
"-P",
|
|
1078
|
+
"-s",
|
|
1079
|
+
"-S",
|
|
1080
|
+
"-x",
|
|
1081
|
+
"--all",
|
|
1082
|
+
"--apparent-size",
|
|
1083
|
+
"--bytes",
|
|
1084
|
+
"--total",
|
|
1085
|
+
"--dereference-args",
|
|
1086
|
+
"--human-readable",
|
|
1087
|
+
"--si",
|
|
1088
|
+
"--inodes",
|
|
1089
|
+
"--count-links",
|
|
1090
|
+
"--dereference",
|
|
1091
|
+
"--no-dereference",
|
|
1092
|
+
"--separate-dirs",
|
|
1093
|
+
"--summarize",
|
|
1094
|
+
"--one-file-system",
|
|
1095
|
+
"--null"
|
|
1096
|
+
],
|
|
1097
|
+
values: [
|
|
1098
|
+
"-d",
|
|
1099
|
+
"-t",
|
|
1100
|
+
"-B",
|
|
1101
|
+
"-X",
|
|
1102
|
+
"--max-depth",
|
|
1103
|
+
"--threshold",
|
|
1104
|
+
"--block-size",
|
|
1105
|
+
"--exclude",
|
|
1106
|
+
"--exclude-from",
|
|
1107
|
+
"--time",
|
|
1108
|
+
"--time-style",
|
|
1109
|
+
"--files0-from"
|
|
1110
|
+
]
|
|
1111
|
+
},
|
|
1112
|
+
df: {
|
|
1113
|
+
cluster: true,
|
|
1114
|
+
booleans: [
|
|
1115
|
+
"-a",
|
|
1116
|
+
"-h",
|
|
1117
|
+
"-H",
|
|
1118
|
+
"-i",
|
|
1119
|
+
"-k",
|
|
1120
|
+
"-l",
|
|
1121
|
+
"-m",
|
|
1122
|
+
"-P",
|
|
1123
|
+
"-T",
|
|
1124
|
+
"-v",
|
|
1125
|
+
"--all",
|
|
1126
|
+
"--human-readable",
|
|
1127
|
+
"--si",
|
|
1128
|
+
"--inodes",
|
|
1129
|
+
"--local",
|
|
1130
|
+
"--portability",
|
|
1131
|
+
"--print-type",
|
|
1132
|
+
"--total",
|
|
1133
|
+
"--sync",
|
|
1134
|
+
"--no-sync"
|
|
1135
|
+
],
|
|
1136
|
+
values: ["-B", "-t", "-x", "--block-size", "--type", "--exclude-type"]
|
|
1137
|
+
},
|
|
1138
|
+
file: {
|
|
1139
|
+
cluster: true,
|
|
1140
|
+
// `-C`/`--compile` is absent: it writes a compiled magic file.
|
|
1141
|
+
booleans: [
|
|
1142
|
+
"-b",
|
|
1143
|
+
"-c",
|
|
1144
|
+
"-h",
|
|
1145
|
+
"-i",
|
|
1146
|
+
"-k",
|
|
1147
|
+
"-L",
|
|
1148
|
+
"-n",
|
|
1149
|
+
"-N",
|
|
1150
|
+
"-p",
|
|
1151
|
+
"-r",
|
|
1152
|
+
"-s",
|
|
1153
|
+
"-S",
|
|
1154
|
+
"-v",
|
|
1155
|
+
"-z",
|
|
1156
|
+
"-0",
|
|
1157
|
+
"--brief",
|
|
1158
|
+
"--mime",
|
|
1159
|
+
"--mime-type",
|
|
1160
|
+
"--mime-encoding",
|
|
1161
|
+
"--dereference",
|
|
1162
|
+
"--no-dereference",
|
|
1163
|
+
"--keep-going",
|
|
1164
|
+
"--no-buffer",
|
|
1165
|
+
"--no-pad",
|
|
1166
|
+
"--raw",
|
|
1167
|
+
"--special-files",
|
|
1168
|
+
"--uncompress",
|
|
1169
|
+
"--print0",
|
|
1170
|
+
"--checking-printout"
|
|
1171
|
+
],
|
|
1172
|
+
values: [
|
|
1173
|
+
"-e",
|
|
1174
|
+
"-m",
|
|
1175
|
+
"-P",
|
|
1176
|
+
"-F",
|
|
1177
|
+
"--exclude",
|
|
1178
|
+
"--magic-file",
|
|
1179
|
+
"--separator",
|
|
1180
|
+
"--parameter",
|
|
1181
|
+
"--extension",
|
|
1182
|
+
"--files-from"
|
|
1183
|
+
]
|
|
1184
|
+
},
|
|
1185
|
+
head: {
|
|
1186
|
+
cluster: true,
|
|
1187
|
+
booleans: ["-q", "-v", "-z", "--quiet", "--silent", "--verbose", "--zero-terminated"],
|
|
1188
|
+
values: ["-c", "-n", "--bytes", "--lines"],
|
|
1189
|
+
patterns: [COUNT_FLAG]
|
|
1190
|
+
},
|
|
1191
|
+
tail: {
|
|
1192
|
+
cluster: true,
|
|
1193
|
+
booleans: [
|
|
1194
|
+
"-f",
|
|
1195
|
+
"-F",
|
|
1196
|
+
"-q",
|
|
1197
|
+
"-v",
|
|
1198
|
+
"-z",
|
|
1199
|
+
"--follow",
|
|
1200
|
+
"--retry",
|
|
1201
|
+
"--quiet",
|
|
1202
|
+
"--silent",
|
|
1203
|
+
"--verbose",
|
|
1204
|
+
"--zero-terminated"
|
|
1205
|
+
],
|
|
1206
|
+
values: [
|
|
1207
|
+
"-c",
|
|
1208
|
+
"-n",
|
|
1209
|
+
"-s",
|
|
1210
|
+
"--bytes",
|
|
1211
|
+
"--lines",
|
|
1212
|
+
"--sleep-interval",
|
|
1213
|
+
"--pid",
|
|
1214
|
+
"--max-unchanged-stats"
|
|
1215
|
+
],
|
|
1216
|
+
patterns: [COUNT_FLAG]
|
|
1217
|
+
},
|
|
1218
|
+
cat: {
|
|
1219
|
+
cluster: true,
|
|
1220
|
+
booleans: [
|
|
1221
|
+
"-A",
|
|
1222
|
+
"-b",
|
|
1223
|
+
"-e",
|
|
1224
|
+
"-E",
|
|
1225
|
+
"-n",
|
|
1226
|
+
"-s",
|
|
1227
|
+
"-t",
|
|
1228
|
+
"-T",
|
|
1229
|
+
"-u",
|
|
1230
|
+
"-v",
|
|
1231
|
+
"--show-all",
|
|
1232
|
+
"--number-nonblank",
|
|
1233
|
+
"--show-ends",
|
|
1234
|
+
"--number",
|
|
1235
|
+
"--squeeze-blank",
|
|
1236
|
+
"--show-tabs",
|
|
1237
|
+
"--show-nonprinting"
|
|
1238
|
+
]
|
|
1239
|
+
},
|
|
1240
|
+
sort: {
|
|
1241
|
+
cluster: true,
|
|
1242
|
+
// Absent on purpose: `-o`/`--output` writes a file with no redirect for the
|
|
1243
|
+
// redirect check to see, and `--compress-program` names a program that sort
|
|
1244
|
+
// runs over its own temporary files — a permitted binary as an interpreter.
|
|
1245
|
+
booleans: [
|
|
1246
|
+
"-b",
|
|
1247
|
+
"-c",
|
|
1248
|
+
"-C",
|
|
1249
|
+
"-d",
|
|
1250
|
+
"-f",
|
|
1251
|
+
"-g",
|
|
1252
|
+
"-h",
|
|
1253
|
+
"-i",
|
|
1254
|
+
"-M",
|
|
1255
|
+
"-n",
|
|
1256
|
+
"-r",
|
|
1257
|
+
"-R",
|
|
1258
|
+
"-s",
|
|
1259
|
+
"-u",
|
|
1260
|
+
"-V",
|
|
1261
|
+
"-z",
|
|
1262
|
+
"--ignore-leading-blanks",
|
|
1263
|
+
"--check",
|
|
1264
|
+
"--dictionary-order",
|
|
1265
|
+
"--ignore-case",
|
|
1266
|
+
"--general-numeric-sort",
|
|
1267
|
+
"--human-numeric-sort",
|
|
1268
|
+
"--ignore-nonprinting",
|
|
1269
|
+
"--month-sort",
|
|
1270
|
+
"--numeric-sort",
|
|
1271
|
+
"--random-sort",
|
|
1272
|
+
"--reverse",
|
|
1273
|
+
"--stable",
|
|
1274
|
+
"--unique",
|
|
1275
|
+
"--version-sort",
|
|
1276
|
+
"--zero-terminated",
|
|
1277
|
+
"--debug"
|
|
1278
|
+
],
|
|
1279
|
+
values: [
|
|
1280
|
+
"-k",
|
|
1281
|
+
"-t",
|
|
1282
|
+
"-S",
|
|
1283
|
+
"-T",
|
|
1284
|
+
"--key",
|
|
1285
|
+
"--field-separator",
|
|
1286
|
+
"--buffer-size",
|
|
1287
|
+
"--temporary-directory",
|
|
1288
|
+
"--random-source",
|
|
1289
|
+
"--batch-size",
|
|
1290
|
+
"--parallel",
|
|
1291
|
+
"--sort"
|
|
1292
|
+
]
|
|
1293
|
+
},
|
|
1294
|
+
uniq: {
|
|
1295
|
+
cluster: true,
|
|
1296
|
+
booleans: [
|
|
1297
|
+
"-c",
|
|
1298
|
+
"-d",
|
|
1299
|
+
"-D",
|
|
1300
|
+
"-i",
|
|
1301
|
+
"-u",
|
|
1302
|
+
"-z",
|
|
1303
|
+
"--count",
|
|
1304
|
+
"--repeated",
|
|
1305
|
+
"--all-repeated",
|
|
1306
|
+
"--ignore-case",
|
|
1307
|
+
"--unique",
|
|
1308
|
+
"--zero-terminated"
|
|
1309
|
+
],
|
|
1310
|
+
values: ["-f", "-s", "-w", "--skip-fields", "--skip-chars", "--check-chars", "--group"]
|
|
1311
|
+
},
|
|
1312
|
+
// No flag on either runs a program or writes a file, and the planner's
|
|
1313
|
+
// commonest use of `echo` is a section marker — `echo --- files changed ---`
|
|
1314
|
+
// is three tokens that all begin with a dash and none of them is a flag.
|
|
1315
|
+
echo: { freeform: true },
|
|
1316
|
+
printf: { freeform: true },
|
|
1317
|
+
date: {
|
|
1318
|
+
cluster: true,
|
|
1319
|
+
// `-s`/`--set` is absent: it sets the system clock.
|
|
1320
|
+
booleans: [
|
|
1321
|
+
"-u",
|
|
1322
|
+
"-R",
|
|
1323
|
+
"-I",
|
|
1324
|
+
"--utc",
|
|
1325
|
+
"--universal",
|
|
1326
|
+
"--rfc-email",
|
|
1327
|
+
"--rfc-3339",
|
|
1328
|
+
"--iso-8601",
|
|
1329
|
+
"--debug"
|
|
1330
|
+
],
|
|
1331
|
+
values: ["-d", "-f", "-r", "--date", "--file", "--reference"]
|
|
1332
|
+
},
|
|
1333
|
+
stat: {
|
|
1334
|
+
cluster: true,
|
|
1335
|
+
booleans: ["-f", "-L", "-t", "--file-system", "--terse", "--dereference"],
|
|
1336
|
+
values: ["-c", "--format", "--printf", "--cached"]
|
|
1337
|
+
},
|
|
1338
|
+
basename: {
|
|
1339
|
+
cluster: true,
|
|
1340
|
+
booleans: ["-a", "-z", "--multiple", "--zero"],
|
|
1341
|
+
values: ["-s", "--suffix"]
|
|
1342
|
+
},
|
|
1343
|
+
dirname: {
|
|
1344
|
+
cluster: true,
|
|
1345
|
+
booleans: ["-z", "--zero"]
|
|
1346
|
+
},
|
|
1347
|
+
realpath: {
|
|
1348
|
+
cluster: true,
|
|
1349
|
+
booleans: [
|
|
1350
|
+
"-e",
|
|
1351
|
+
"-m",
|
|
1352
|
+
"-L",
|
|
1353
|
+
"-P",
|
|
1354
|
+
"-q",
|
|
1355
|
+
"-s",
|
|
1356
|
+
"-z",
|
|
1357
|
+
"--canonicalize-existing",
|
|
1358
|
+
"--canonicalize-missing",
|
|
1359
|
+
"--logical",
|
|
1360
|
+
"--physical",
|
|
1361
|
+
"--quiet",
|
|
1362
|
+
"--strip",
|
|
1363
|
+
"--no-symlinks",
|
|
1364
|
+
"--zero"
|
|
1365
|
+
],
|
|
1366
|
+
values: ["--relative-to", "--relative-base"]
|
|
1367
|
+
},
|
|
1368
|
+
pwd: { cluster: true, booleans: ["-L", "-P", "--logical", "--physical"] },
|
|
1369
|
+
which: { cluster: true, booleans: ["-a", "-s", "--all"] },
|
|
1370
|
+
type: { cluster: true, booleans: ["-a", "-f", "-p", "-P", "-t"] },
|
|
1371
|
+
uname: {
|
|
1372
|
+
cluster: true,
|
|
1373
|
+
booleans: [
|
|
1374
|
+
"-a",
|
|
1375
|
+
"-i",
|
|
1376
|
+
"-m",
|
|
1377
|
+
"-n",
|
|
1378
|
+
"-o",
|
|
1379
|
+
"-p",
|
|
1380
|
+
"-r",
|
|
1381
|
+
"-s",
|
|
1382
|
+
"-v",
|
|
1383
|
+
"--all",
|
|
1384
|
+
"--kernel-name",
|
|
1385
|
+
"--nodename",
|
|
1386
|
+
"--kernel-release",
|
|
1387
|
+
"--kernel-version",
|
|
1388
|
+
"--machine",
|
|
1389
|
+
"--processor",
|
|
1390
|
+
"--hardware-platform",
|
|
1391
|
+
"--operating-system"
|
|
1392
|
+
]
|
|
1393
|
+
},
|
|
1394
|
+
whoami: {},
|
|
1395
|
+
cut: {
|
|
1396
|
+
cluster: true,
|
|
1397
|
+
// `--output-delimiter` names a separator string, not a file.
|
|
1398
|
+
booleans: ["-n", "-s", "-z", "--only-delimited", "--complement", "--zero-terminated"],
|
|
1399
|
+
values: [
|
|
1400
|
+
"-b",
|
|
1401
|
+
"-c",
|
|
1402
|
+
"-d",
|
|
1403
|
+
"-f",
|
|
1404
|
+
"--bytes",
|
|
1405
|
+
"--characters",
|
|
1406
|
+
"--delimiter",
|
|
1407
|
+
"--fields",
|
|
1408
|
+
"--output-delimiter"
|
|
1409
|
+
]
|
|
1410
|
+
},
|
|
1411
|
+
nl: {
|
|
1412
|
+
cluster: true,
|
|
1413
|
+
booleans: ["-p", "--no-renumber"],
|
|
1414
|
+
values: [
|
|
1415
|
+
"-b",
|
|
1416
|
+
"-d",
|
|
1417
|
+
"-f",
|
|
1418
|
+
"-h",
|
|
1419
|
+
"-i",
|
|
1420
|
+
"-l",
|
|
1421
|
+
"-n",
|
|
1422
|
+
"-s",
|
|
1423
|
+
"-v",
|
|
1424
|
+
"-w",
|
|
1425
|
+
"--body-numbering",
|
|
1426
|
+
"--section-delimiter",
|
|
1427
|
+
"--footer-numbering",
|
|
1428
|
+
"--header-numbering",
|
|
1429
|
+
"--join-blank-lines",
|
|
1430
|
+
"--line-increment",
|
|
1431
|
+
"--number-format",
|
|
1432
|
+
"--number-separator",
|
|
1433
|
+
"--starting-line-number",
|
|
1434
|
+
"--number-width"
|
|
1435
|
+
]
|
|
1436
|
+
},
|
|
1437
|
+
rg: {
|
|
1438
|
+
cluster: true,
|
|
1439
|
+
// `--pre` runs a named preprocessor over every file searched and
|
|
1440
|
+
// `--hostname-bin` runs a named program to resolve the hostname; both are
|
|
1441
|
+
// absent, and `--pre-glob` with them.
|
|
1442
|
+
booleans: [
|
|
1443
|
+
"-a",
|
|
1444
|
+
"-c",
|
|
1445
|
+
"-F",
|
|
1446
|
+
"-h",
|
|
1447
|
+
"-H",
|
|
1448
|
+
"-i",
|
|
1449
|
+
"-I",
|
|
1450
|
+
"-l",
|
|
1451
|
+
"-L",
|
|
1452
|
+
"-n",
|
|
1453
|
+
"-N",
|
|
1454
|
+
"-o",
|
|
1455
|
+
"-p",
|
|
1456
|
+
"-P",
|
|
1457
|
+
"-q",
|
|
1458
|
+
"-s",
|
|
1459
|
+
"-S",
|
|
1460
|
+
"-u",
|
|
1461
|
+
"-uu",
|
|
1462
|
+
"-uuu",
|
|
1463
|
+
"-U",
|
|
1464
|
+
"-v",
|
|
1465
|
+
"-V",
|
|
1466
|
+
"-w",
|
|
1467
|
+
"-x",
|
|
1468
|
+
"-z",
|
|
1469
|
+
"--text",
|
|
1470
|
+
"--count",
|
|
1471
|
+
"--count-matches",
|
|
1472
|
+
"--fixed-strings",
|
|
1473
|
+
"--files",
|
|
1474
|
+
"--files-with-matches",
|
|
1475
|
+
"--files-without-match",
|
|
1476
|
+
"--follow",
|
|
1477
|
+
"--hidden",
|
|
1478
|
+
"--no-hidden",
|
|
1479
|
+
"--ignore-case",
|
|
1480
|
+
"--case-sensitive",
|
|
1481
|
+
"--smart-case",
|
|
1482
|
+
"--invert-match",
|
|
1483
|
+
"--line-number",
|
|
1484
|
+
"--no-line-number",
|
|
1485
|
+
"--with-filename",
|
|
1486
|
+
"--no-filename",
|
|
1487
|
+
"--heading",
|
|
1488
|
+
"--no-heading",
|
|
1489
|
+
"--column",
|
|
1490
|
+
"--no-column",
|
|
1491
|
+
"--byte-offset",
|
|
1492
|
+
"--vimgrep",
|
|
1493
|
+
"--json",
|
|
1494
|
+
"--stats",
|
|
1495
|
+
"--trim",
|
|
1496
|
+
"--pretty",
|
|
1497
|
+
"--passthru",
|
|
1498
|
+
"--word-regexp",
|
|
1499
|
+
"--line-regexp",
|
|
1500
|
+
"--multiline",
|
|
1501
|
+
"--multiline-dotall",
|
|
1502
|
+
"--no-multiline",
|
|
1503
|
+
"--crlf",
|
|
1504
|
+
"--null",
|
|
1505
|
+
"--null-data",
|
|
1506
|
+
"--binary",
|
|
1507
|
+
"--search-zip",
|
|
1508
|
+
"--no-ignore",
|
|
1509
|
+
"--no-ignore-dot",
|
|
1510
|
+
"--no-ignore-exclude",
|
|
1511
|
+
"--no-ignore-files",
|
|
1512
|
+
"--no-ignore-global",
|
|
1513
|
+
"--no-ignore-parent",
|
|
1514
|
+
"--no-ignore-vcs",
|
|
1515
|
+
"--no-ignore-messages",
|
|
1516
|
+
"--no-messages",
|
|
1517
|
+
"--no-require-git",
|
|
1518
|
+
"--require-git",
|
|
1519
|
+
"--one-file-system",
|
|
1520
|
+
"--pcre2",
|
|
1521
|
+
"--no-pcre2",
|
|
1522
|
+
"--auto-hybrid-regex",
|
|
1523
|
+
"--line-buffered",
|
|
1524
|
+
"--block-buffered",
|
|
1525
|
+
"--unicode",
|
|
1526
|
+
"--no-unicode",
|
|
1527
|
+
"--unrestricted",
|
|
1528
|
+
"--type-list",
|
|
1529
|
+
"--debug",
|
|
1530
|
+
"--trace",
|
|
1531
|
+
"--include-zero",
|
|
1532
|
+
"--no-context-separator",
|
|
1533
|
+
"--stop-on-nonmatch",
|
|
1534
|
+
"--quiet",
|
|
1535
|
+
"--no-binary"
|
|
1536
|
+
],
|
|
1537
|
+
values: [
|
|
1538
|
+
"-A",
|
|
1539
|
+
"-B",
|
|
1540
|
+
"-C",
|
|
1541
|
+
"-d",
|
|
1542
|
+
"-e",
|
|
1543
|
+
"-E",
|
|
1544
|
+
"-f",
|
|
1545
|
+
"-g",
|
|
1546
|
+
"-j",
|
|
1547
|
+
"-m",
|
|
1548
|
+
"-M",
|
|
1549
|
+
"-r",
|
|
1550
|
+
"-t",
|
|
1551
|
+
"-T",
|
|
1552
|
+
"--after-context",
|
|
1553
|
+
"--before-context",
|
|
1554
|
+
"--context",
|
|
1555
|
+
"--context-separator",
|
|
1556
|
+
"--field-context-separator",
|
|
1557
|
+
"--field-match-separator",
|
|
1558
|
+
"--regexp",
|
|
1559
|
+
"--file",
|
|
1560
|
+
"--glob",
|
|
1561
|
+
"--iglob",
|
|
1562
|
+
"--glob-case-insensitive",
|
|
1563
|
+
"--type",
|
|
1564
|
+
"--type-not",
|
|
1565
|
+
"--type-add",
|
|
1566
|
+
"--type-clear",
|
|
1567
|
+
"--max-count",
|
|
1568
|
+
"--max-columns",
|
|
1569
|
+
"--max-depth",
|
|
1570
|
+
"--maxdepth",
|
|
1571
|
+
"--max-filesize",
|
|
1572
|
+
"--replace",
|
|
1573
|
+
"--threads",
|
|
1574
|
+
"--encoding",
|
|
1575
|
+
"--engine",
|
|
1576
|
+
"--sort",
|
|
1577
|
+
"--sortr",
|
|
1578
|
+
"--color",
|
|
1579
|
+
"--colors",
|
|
1580
|
+
"--path-separator",
|
|
1581
|
+
"--ignore-file",
|
|
1582
|
+
"--dfa-size-limit",
|
|
1583
|
+
"--regex-size-limit",
|
|
1584
|
+
"--binary-files",
|
|
1585
|
+
"--max-columns-preview"
|
|
1586
|
+
]
|
|
1587
|
+
},
|
|
1588
|
+
grep: {
|
|
1589
|
+
cluster: true,
|
|
1590
|
+
// `-o` here is `--only-matching`, which writes nothing. It is the same two
|
|
1591
|
+
// characters as `sort -o`, which writes a file — the reason these sets are
|
|
1592
|
+
// per-binary rather than one shared list.
|
|
1593
|
+
booleans: [
|
|
1594
|
+
"-a",
|
|
1595
|
+
"-b",
|
|
1596
|
+
"-c",
|
|
1597
|
+
"-E",
|
|
1598
|
+
"-F",
|
|
1599
|
+
"-G",
|
|
1600
|
+
"-H",
|
|
1601
|
+
"-h",
|
|
1602
|
+
"-i",
|
|
1603
|
+
"-I",
|
|
1604
|
+
"-l",
|
|
1605
|
+
"-L",
|
|
1606
|
+
"-n",
|
|
1607
|
+
"-o",
|
|
1608
|
+
"-P",
|
|
1609
|
+
"-q",
|
|
1610
|
+
"-r",
|
|
1611
|
+
"-R",
|
|
1612
|
+
"-s",
|
|
1613
|
+
"-T",
|
|
1614
|
+
"-U",
|
|
1615
|
+
"-v",
|
|
1616
|
+
"-w",
|
|
1617
|
+
"-x",
|
|
1618
|
+
"-y",
|
|
1619
|
+
"-z",
|
|
1620
|
+
"-Z",
|
|
1621
|
+
"--extended-regexp",
|
|
1622
|
+
"--fixed-strings",
|
|
1623
|
+
"--basic-regexp",
|
|
1624
|
+
"--perl-regexp",
|
|
1625
|
+
"--ignore-case",
|
|
1626
|
+
"--no-ignore-case",
|
|
1627
|
+
"--invert-match",
|
|
1628
|
+
"--word-regexp",
|
|
1629
|
+
"--line-regexp",
|
|
1630
|
+
"--count",
|
|
1631
|
+
"--files-with-matches",
|
|
1632
|
+
"--files-without-match",
|
|
1633
|
+
"--line-number",
|
|
1634
|
+
"--with-filename",
|
|
1635
|
+
"--no-filename",
|
|
1636
|
+
"--only-matching",
|
|
1637
|
+
"--quiet",
|
|
1638
|
+
"--silent",
|
|
1639
|
+
"--no-messages",
|
|
1640
|
+
"--text",
|
|
1641
|
+
"--binary",
|
|
1642
|
+
"--line-buffered",
|
|
1643
|
+
"--null",
|
|
1644
|
+
"--null-data",
|
|
1645
|
+
"--byte-offset",
|
|
1646
|
+
"--recursive",
|
|
1647
|
+
"--dereference-recursive",
|
|
1648
|
+
"--initial-tab",
|
|
1649
|
+
"--unix-byte-offsets",
|
|
1650
|
+
"--no-group-separator",
|
|
1651
|
+
"--color",
|
|
1652
|
+
"--colour"
|
|
1653
|
+
],
|
|
1654
|
+
values: [
|
|
1655
|
+
"-A",
|
|
1656
|
+
"-B",
|
|
1657
|
+
"-C",
|
|
1658
|
+
"-d",
|
|
1659
|
+
"-D",
|
|
1660
|
+
"-e",
|
|
1661
|
+
"-f",
|
|
1662
|
+
"-m",
|
|
1663
|
+
"--after-context",
|
|
1664
|
+
"--before-context",
|
|
1665
|
+
"--context",
|
|
1666
|
+
"--regexp",
|
|
1667
|
+
"--file",
|
|
1668
|
+
"--max-count",
|
|
1669
|
+
"--devices",
|
|
1670
|
+
"--directories",
|
|
1671
|
+
"--binary-files",
|
|
1672
|
+
"--include",
|
|
1673
|
+
"--exclude",
|
|
1674
|
+
"--exclude-dir",
|
|
1675
|
+
"--exclude-from",
|
|
1676
|
+
"--label",
|
|
1677
|
+
"--group-separator"
|
|
1678
|
+
]
|
|
1679
|
+
},
|
|
1680
|
+
find: {
|
|
1681
|
+
// No clustering: find spells its flags as single-dash words, so walking the
|
|
1682
|
+
// characters of `-name` would read it as five short flags. And its arguments
|
|
1683
|
+
// are an expression, so `--` does not end them.
|
|
1684
|
+
expressionArgs: true,
|
|
1685
|
+
// Absent on purpose: `-exec`, `-execdir`, `-ok` and `-okdir` run an inner
|
|
1686
|
+
// command (also caught by the named guard below, which says so more
|
|
1687
|
+
// precisely), `-delete` removes files, and `-fprint`, `-fprint0`, `-fprintf`
|
|
1688
|
+
// and `-fls` are find's write family — the same write as `> file` with no
|
|
1689
|
+
// redirect for the redirect check to see.
|
|
1690
|
+
booleans: [
|
|
1691
|
+
"-H",
|
|
1692
|
+
"-L",
|
|
1693
|
+
"-P",
|
|
1694
|
+
"-a",
|
|
1695
|
+
"-and",
|
|
1696
|
+
"-o",
|
|
1697
|
+
"-or",
|
|
1698
|
+
"-not",
|
|
1699
|
+
"-d",
|
|
1700
|
+
"-depth",
|
|
1701
|
+
"-daystart",
|
|
1702
|
+
"-empty",
|
|
1703
|
+
"-executable",
|
|
1704
|
+
"-false",
|
|
1705
|
+
"-follow",
|
|
1706
|
+
"-help",
|
|
1707
|
+
"--help",
|
|
1708
|
+
"-ignore_readdir_race",
|
|
1709
|
+
"-noignore_readdir_race",
|
|
1710
|
+
"-ls",
|
|
1711
|
+
"-mount",
|
|
1712
|
+
"-nogroup",
|
|
1713
|
+
"-noleaf",
|
|
1714
|
+
"-nouser",
|
|
1715
|
+
"-print",
|
|
1716
|
+
"-print0",
|
|
1717
|
+
"-prune",
|
|
1718
|
+
"-quit",
|
|
1719
|
+
"-readable",
|
|
1720
|
+
"-true",
|
|
1721
|
+
"-version",
|
|
1722
|
+
"-writable",
|
|
1723
|
+
"-xdev"
|
|
1724
|
+
],
|
|
1725
|
+
values: [
|
|
1726
|
+
"-maxdepth",
|
|
1727
|
+
"-mindepth",
|
|
1728
|
+
"-name",
|
|
1729
|
+
"-iname",
|
|
1730
|
+
"-path",
|
|
1731
|
+
"-ipath",
|
|
1732
|
+
"-wholename",
|
|
1733
|
+
"-iwholename",
|
|
1734
|
+
"-regex",
|
|
1735
|
+
"-iregex",
|
|
1736
|
+
"-lname",
|
|
1737
|
+
"-ilname",
|
|
1738
|
+
"-type",
|
|
1739
|
+
"-xtype",
|
|
1740
|
+
"-size",
|
|
1741
|
+
"-newer",
|
|
1742
|
+
"-anewer",
|
|
1743
|
+
"-cnewer",
|
|
1744
|
+
"-mtime",
|
|
1745
|
+
"-mmin",
|
|
1746
|
+
"-ctime",
|
|
1747
|
+
"-cmin",
|
|
1748
|
+
"-atime",
|
|
1749
|
+
"-amin",
|
|
1750
|
+
"-used",
|
|
1751
|
+
"-uid",
|
|
1752
|
+
"-gid",
|
|
1753
|
+
"-user",
|
|
1754
|
+
"-group",
|
|
1755
|
+
"-perm",
|
|
1756
|
+
"-links",
|
|
1757
|
+
"-inum",
|
|
1758
|
+
"-samefile",
|
|
1759
|
+
"-fstype",
|
|
1760
|
+
"-regextype",
|
|
1761
|
+
"-files0-from",
|
|
1762
|
+
"-printf",
|
|
1763
|
+
"-context",
|
|
1764
|
+
"-D"
|
|
1765
|
+
],
|
|
1766
|
+
// `find -O2` glues the optimisation level on, and `-newermt`/`-newerat` and
|
|
1767
|
+
// friends spell the two comparison fields into the flag name.
|
|
1768
|
+
patterns: [/^-O\d$/, /^-newer[acmBt][acmBt]$/]
|
|
1769
|
+
},
|
|
1770
|
+
jq: {
|
|
1771
|
+
cluster: true,
|
|
1772
|
+
booleans: [
|
|
1773
|
+
"-a",
|
|
1774
|
+
"-c",
|
|
1775
|
+
"-C",
|
|
1776
|
+
"-e",
|
|
1777
|
+
"-h",
|
|
1778
|
+
"-j",
|
|
1779
|
+
"-M",
|
|
1780
|
+
"-n",
|
|
1781
|
+
"-r",
|
|
1782
|
+
"-R",
|
|
1783
|
+
"-s",
|
|
1784
|
+
"-S",
|
|
1785
|
+
"--ascii-output",
|
|
1786
|
+
"--compact-output",
|
|
1787
|
+
"--color-output",
|
|
1788
|
+
"--monochrome-output",
|
|
1789
|
+
"--exit-status",
|
|
1790
|
+
"--join-output",
|
|
1791
|
+
"--null-input",
|
|
1792
|
+
"--raw-input",
|
|
1793
|
+
"--raw-output",
|
|
1794
|
+
"--raw-output0",
|
|
1795
|
+
"--slurp",
|
|
1796
|
+
"--sort-keys",
|
|
1797
|
+
"--seq",
|
|
1798
|
+
"--stream",
|
|
1799
|
+
"--stream-errors",
|
|
1800
|
+
"--tab",
|
|
1801
|
+
"--unbuffered",
|
|
1802
|
+
"--args",
|
|
1803
|
+
"--jsonargs"
|
|
1804
|
+
],
|
|
1805
|
+
values: [
|
|
1806
|
+
"-f",
|
|
1807
|
+
"-L",
|
|
1808
|
+
"--arg",
|
|
1809
|
+
"--argjson",
|
|
1810
|
+
"--slurpfile",
|
|
1811
|
+
"--rawfile",
|
|
1812
|
+
"--indent",
|
|
1813
|
+
"--from-file"
|
|
1814
|
+
]
|
|
1815
|
+
},
|
|
1816
|
+
yq: {
|
|
1817
|
+
cluster: true,
|
|
1818
|
+
// `-i`/`--inplace`/`--in-place` rewrite the file, and `-s`/`--split-exp`
|
|
1819
|
+
// writes one file per document. All absent — and all bare or near-bare
|
|
1820
|
+
// booleans, which is why exempting booleans was not an option.
|
|
1821
|
+
booleans: [
|
|
1822
|
+
"-C",
|
|
1823
|
+
"-e",
|
|
1824
|
+
"-h",
|
|
1825
|
+
"-j",
|
|
1826
|
+
"-M",
|
|
1827
|
+
"-n",
|
|
1828
|
+
"-N",
|
|
1829
|
+
"-P",
|
|
1830
|
+
"-r",
|
|
1831
|
+
"-S",
|
|
1832
|
+
"-v",
|
|
1833
|
+
"-y",
|
|
1834
|
+
"-Y",
|
|
1835
|
+
"--colors",
|
|
1836
|
+
"--no-colors",
|
|
1837
|
+
"--exit-status",
|
|
1838
|
+
"--no-doc",
|
|
1839
|
+
"--null-input",
|
|
1840
|
+
"--prettyPrint",
|
|
1841
|
+
"--raw-output",
|
|
1842
|
+
"--sort-keys",
|
|
1843
|
+
"--tojson",
|
|
1844
|
+
"--yaml-output",
|
|
1845
|
+
"--yaml-roundtrip",
|
|
1846
|
+
"--unwrapScalar",
|
|
1847
|
+
"--header-preprocess",
|
|
1848
|
+
"--no-exit-status",
|
|
1849
|
+
"--verbose",
|
|
1850
|
+
"--xml-strict-mode"
|
|
1851
|
+
],
|
|
1852
|
+
values: [
|
|
1853
|
+
"-I",
|
|
1854
|
+
"-o",
|
|
1855
|
+
"-p",
|
|
1856
|
+
"-L",
|
|
1857
|
+
"--indent",
|
|
1858
|
+
"--output-format",
|
|
1859
|
+
"--input-format",
|
|
1860
|
+
"--expression",
|
|
1861
|
+
"--width",
|
|
1862
|
+
"--xml-attribute-prefix",
|
|
1863
|
+
"--xml-content-name"
|
|
1864
|
+
]
|
|
1865
|
+
}
|
|
1866
|
+
};
|
|
645
1867
|
var GIT_READONLY_SUBCOMMANDS = [
|
|
646
1868
|
"log",
|
|
647
1869
|
"status",
|
|
648
1870
|
"diff",
|
|
649
1871
|
"show",
|
|
650
1872
|
"ls-files",
|
|
651
|
-
"ls-remote",
|
|
652
1873
|
"ls-tree",
|
|
653
1874
|
"branch",
|
|
654
1875
|
"tag",
|
|
@@ -763,6 +1984,26 @@ var REFUSED_SUBCOMMANDS = {
|
|
|
763
1984
|
az: ["login", "logout"],
|
|
764
1985
|
terraform: ["apply", "destroy"]
|
|
765
1986
|
};
|
|
1987
|
+
var SHELL_KEYWORDS = [
|
|
1988
|
+
"{",
|
|
1989
|
+
"}",
|
|
1990
|
+
"if",
|
|
1991
|
+
"then",
|
|
1992
|
+
"elif",
|
|
1993
|
+
"else",
|
|
1994
|
+
"fi",
|
|
1995
|
+
"for",
|
|
1996
|
+
"while",
|
|
1997
|
+
"until",
|
|
1998
|
+
"do",
|
|
1999
|
+
"done",
|
|
2000
|
+
"case",
|
|
2001
|
+
"esac",
|
|
2002
|
+
"select",
|
|
2003
|
+
"function",
|
|
2004
|
+
"time",
|
|
2005
|
+
"export"
|
|
2006
|
+
];
|
|
766
2007
|
var INTERPRETERS = [
|
|
767
2008
|
"sh",
|
|
768
2009
|
"bash",
|
|
@@ -1206,16 +2447,79 @@ function pathLikeArgs(command, opts = {}) {
|
|
|
1206
2447
|
return !a.startsWith("-") && looksLikePath(a) ? [a] : [];
|
|
1207
2448
|
}));
|
|
1208
2449
|
}
|
|
2450
|
+
function matchFlag(spec, booleans, values, token) {
|
|
2451
|
+
if (token.startsWith("--")) {
|
|
2452
|
+
const eq = token.indexOf("=");
|
|
2453
|
+
const name = eq > 0 ? token.slice(0, eq) : token;
|
|
2454
|
+
if (booleans.has(name)) return "boolean";
|
|
2455
|
+
if (values.has(name)) return eq > 0 ? "boolean" : "value";
|
|
2456
|
+
return void 0;
|
|
2457
|
+
}
|
|
2458
|
+
if (booleans.has(token)) return "boolean";
|
|
2459
|
+
if (values.has(token)) return "value";
|
|
2460
|
+
if (spec.patterns?.some((p) => p.test(token))) return "boolean";
|
|
2461
|
+
if (!spec.cluster) return void 0;
|
|
2462
|
+
for (let i = 1; i < token.length; i++) {
|
|
2463
|
+
const short = `-${token[i]}`;
|
|
2464
|
+
if (booleans.has(short)) continue;
|
|
2465
|
+
if (values.has(short)) return i === token.length - 1 ? "value" : "boolean";
|
|
2466
|
+
return void 0;
|
|
2467
|
+
}
|
|
2468
|
+
return "boolean";
|
|
2469
|
+
}
|
|
2470
|
+
function takesNextToken(next) {
|
|
2471
|
+
if (next === void 0) return false;
|
|
2472
|
+
return !/^-./.test(next) || /^-\d/.test(next);
|
|
2473
|
+
}
|
|
2474
|
+
function flagLabel(token) {
|
|
2475
|
+
const eq = token.startsWith("--") ? token.indexOf("=") : -1;
|
|
2476
|
+
return eq > 0 ? token.slice(0, eq) : token;
|
|
2477
|
+
}
|
|
2478
|
+
function scanFlags(seg) {
|
|
2479
|
+
const spec = FLAG_POLICY[seg.binary];
|
|
2480
|
+
if (!spec || spec.freeform) return void 0;
|
|
2481
|
+
const booleans = /* @__PURE__ */ new Set([...spec.booleans ?? [], ...UNIVERSAL_FLAGS]);
|
|
2482
|
+
const values = new Set(spec.values ?? []);
|
|
2483
|
+
const operands = [];
|
|
2484
|
+
let i = 0;
|
|
2485
|
+
while (i < seg.args.length) {
|
|
2486
|
+
const token = seg.args[i];
|
|
2487
|
+
if (token === "--" && !spec.expressionArgs) {
|
|
2488
|
+
operands.push(...seg.args.slice(i + 1));
|
|
2489
|
+
break;
|
|
2490
|
+
}
|
|
2491
|
+
if (!/^-./.test(token)) {
|
|
2492
|
+
operands.push(token);
|
|
2493
|
+
i++;
|
|
2494
|
+
continue;
|
|
2495
|
+
}
|
|
2496
|
+
const shape = matchFlag(spec, booleans, values, token);
|
|
2497
|
+
if (shape === void 0) return { unknown: flagLabel(token), operands };
|
|
2498
|
+
i += shape === "value" && takesNextToken(seg.args[i + 1]) ? 2 : 1;
|
|
2499
|
+
}
|
|
2500
|
+
return { operands };
|
|
2501
|
+
}
|
|
2502
|
+
function subcommandOf(seg) {
|
|
2503
|
+
const scan = scanFlags(seg);
|
|
2504
|
+
if (scan) return scan.operands[0];
|
|
2505
|
+
return seg.args.find((a) => !a.startsWith("-"));
|
|
2506
|
+
}
|
|
2507
|
+
var SCOPE_LEAD_ARGS = 2;
|
|
1209
2508
|
function scopeFor(seg) {
|
|
1210
2509
|
if (!MULTIPLEXERS.includes(seg.binary)) return seg.binary;
|
|
1211
|
-
const
|
|
1212
|
-
|
|
2510
|
+
const lead = [];
|
|
2511
|
+
for (const arg of seg.args) {
|
|
2512
|
+
if (arg.startsWith("-")) break;
|
|
2513
|
+
lead.push(arg);
|
|
2514
|
+
if (lead.length === SCOPE_LEAD_ARGS) break;
|
|
2515
|
+
}
|
|
2516
|
+
return [seg.binary, ...lead].join(" ");
|
|
1213
2517
|
}
|
|
1214
2518
|
function isAuto(seg) {
|
|
1215
2519
|
if (!AUTO_COMMANDS.includes(seg.binary)) return false;
|
|
1216
2520
|
if (seg.expandable) return false;
|
|
1217
2521
|
if (seg.binary !== "git") return true;
|
|
1218
|
-
const sub = seg
|
|
2522
|
+
const sub = subcommandOf(seg);
|
|
1219
2523
|
return sub !== void 0 && GIT_READONLY_SUBCOMMANDS.includes(sub);
|
|
1220
2524
|
}
|
|
1221
2525
|
function refusalFor(seg) {
|
|
@@ -1225,29 +2529,31 @@ function refusalFor(seg) {
|
|
|
1225
2529
|
if (seg.binary === "eval" || seg.binary === "exec") {
|
|
1226
2530
|
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.`;
|
|
1227
2531
|
}
|
|
2532
|
+
if (seg.binary === "source" || seg.binary === ".") {
|
|
2533
|
+
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.`;
|
|
2534
|
+
}
|
|
2535
|
+
if (SHELL_KEYWORDS.includes(seg.binary)) {
|
|
2536
|
+
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.`;
|
|
2537
|
+
}
|
|
1228
2538
|
const subs = REFUSED_SUBCOMMANDS[seg.binary];
|
|
1229
2539
|
if (subs) {
|
|
1230
|
-
const sub = seg
|
|
2540
|
+
const sub = subcommandOf(seg);
|
|
1231
2541
|
if (sub && subs.includes(sub)) {
|
|
1232
2542
|
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.`;
|
|
1233
2543
|
}
|
|
1234
2544
|
}
|
|
1235
2545
|
if (seg.binary === "git") {
|
|
1236
|
-
const sub = seg
|
|
2546
|
+
const sub = subcommandOf(seg);
|
|
1237
2547
|
if (sub === "branch" || sub === "tag") {
|
|
1238
2548
|
const flag = seg.args.find((a) => ["-D", "-d", "-m", "-M", "--delete", "--move"].includes(a));
|
|
1239
2549
|
if (flag) {
|
|
1240
2550
|
return `"git ${sub} ${flag}" mutates refs. You are a read-only planner \u2014 describe the change as a task instead.`;
|
|
1241
2551
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
if (sub === "grep") {
|
|
1248
|
-
const pagerFlag = seg.args.find((a) => a === "-O" || a === "--open-files-in-pager" || a.startsWith("--open-files-in-pager="));
|
|
1249
|
-
if (pagerFlag) {
|
|
1250
|
-
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.`;
|
|
2552
|
+
const listing = seg.args.includes("-l") || seg.args.includes("--list");
|
|
2553
|
+
const scan2 = scanFlags(seg);
|
|
2554
|
+
const target = scan2?.operands[1];
|
|
2555
|
+
if (!listing && target) {
|
|
2556
|
+
return `"git ${sub} ${target}" creates or moves a ref. You are a read-only planner \u2014 describe the change as a task instead.`;
|
|
1251
2557
|
}
|
|
1252
2558
|
}
|
|
1253
2559
|
}
|
|
@@ -1275,6 +2581,13 @@ function refusalFor(seg) {
|
|
|
1275
2581
|
if (seg.assignments.length > 0) {
|
|
1276
2582
|
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.`;
|
|
1277
2583
|
}
|
|
2584
|
+
const scan = scanFlags(seg);
|
|
2585
|
+
if (scan?.unknown) {
|
|
2586
|
+
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.`;
|
|
2587
|
+
}
|
|
2588
|
+
if (seg.binary === "uniq" && scan && scan.operands.length > 1) {
|
|
2589
|
+
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.`;
|
|
2590
|
+
}
|
|
1278
2591
|
return void 0;
|
|
1279
2592
|
}
|
|
1280
2593
|
function withWrapperNote(reason, wrappers) {
|
|
@@ -1661,6 +2974,139 @@ It is outside the auto-allowed read-only set (${scope}). Continue with the read-
|
|
|
1661
2974
|
}
|
|
1662
2975
|
};
|
|
1663
2976
|
|
|
2977
|
+
// src/utils/redactSecrets.ts
|
|
2978
|
+
var REDACTION_MARKER = "REDACTED";
|
|
2979
|
+
function marker(kind, length) {
|
|
2980
|
+
return `[${REDACTION_MARKER} ${kind}: ${length} chars]`;
|
|
2981
|
+
}
|
|
2982
|
+
var LINE_PREFIX = String.raw`(?:[ \t]*\d+\||[^\s:]*:\d+:|)[ \t]*`;
|
|
2983
|
+
var LINE_PREFIX_ANCHORED = new RegExp("^" + LINE_PREFIX);
|
|
2984
|
+
var CREDENTIAL_WORD = String.raw`(?:api[_-]?keys?|secrets?|passwords?|passwd|passphrase|tokens?|access[_-]?keys?|private[_-]?keys?|client[_-]?secrets?|credentials?|auth)(?![a-z])`;
|
|
2985
|
+
var NAMED_CREDENTIAL = new RegExp(
|
|
2986
|
+
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`,
|
|
2987
|
+
"gi"
|
|
2988
|
+
);
|
|
2989
|
+
var DOTENV_CREDENTIAL = new RegExp(
|
|
2990
|
+
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]*$`,
|
|
2991
|
+
"gm"
|
|
2992
|
+
);
|
|
2993
|
+
var PROVIDER_KEY_PATTERNS = [
|
|
2994
|
+
// OpenAI / Anthropic / OpenRouter and the many `sk-` derivatives
|
|
2995
|
+
/(?<![A-Za-z0-9])sk-(?:ant-|proj-|or-v1-|live-|test-)?[A-Za-z0-9_-]{20,}/g,
|
|
2996
|
+
// GitHub personal-access, OAuth, app and refresh tokens
|
|
2997
|
+
/(?<![A-Za-z0-9])(?:gh[pousr]|github_pat)_[A-Za-z0-9_]{22,}/g,
|
|
2998
|
+
// Slack bot / user / app tokens
|
|
2999
|
+
/(?<![A-Za-z0-9])xox[abprse]-[A-Za-z0-9-]{10,}/g,
|
|
3000
|
+
// Stripe secret and restricted keys
|
|
3001
|
+
/(?<![A-Za-z0-9])[sr]k_(?:live|test)_[A-Za-z0-9]{16,}/g,
|
|
3002
|
+
// Google API keys and OAuth access tokens
|
|
3003
|
+
/(?<![A-Za-z0-9])AIza[A-Za-z0-9_-]{30,}/g,
|
|
3004
|
+
/(?<![A-Za-z0-9])ya29\.[A-Za-z0-9_-]{20,}/g,
|
|
3005
|
+
// npm, Hugging Face, Groq, GitLab, DigitalOcean, Shopify
|
|
3006
|
+
/(?<![A-Za-z0-9])(?:npm|hf|gsk|glpat|dop_v1|shpat|shpss)[_-][A-Za-z0-9]{20,}/g,
|
|
3007
|
+
/(?<![A-Za-z0-9])xai-[A-Za-z0-9]{20,}/g,
|
|
3008
|
+
// Three-segment JWTs, whose payload segment is base64 for `{"`
|
|
3009
|
+
/(?<![A-Za-z0-9])eyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}/g
|
|
3010
|
+
];
|
|
3011
|
+
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;
|
|
3012
|
+
var PEM_BEGIN = /-----BEGIN ((?:[A-Z0-9]+ )*PRIVATE KEY(?: BLOCK)?)-----/;
|
|
3013
|
+
var PEM_BODY_LINE = /^[A-Za-z0-9+/=:,.\- \t]*$/;
|
|
3014
|
+
function redactPrivateKeyBlocks(text) {
|
|
3015
|
+
if (!PEM_BEGIN.test(text)) return text;
|
|
3016
|
+
const out = [];
|
|
3017
|
+
let label = null;
|
|
3018
|
+
let bodyChars = 0;
|
|
3019
|
+
const closeBlock = () => {
|
|
3020
|
+
if (label === null) return;
|
|
3021
|
+
out.push(marker("private key", bodyChars));
|
|
3022
|
+
label = null;
|
|
3023
|
+
bodyChars = 0;
|
|
3024
|
+
};
|
|
3025
|
+
for (const line of text.split("\n")) {
|
|
3026
|
+
if (label === null) {
|
|
3027
|
+
out.push(line);
|
|
3028
|
+
const begun = PEM_BEGIN.exec(line);
|
|
3029
|
+
if (begun) label = begun[1];
|
|
3030
|
+
continue;
|
|
3031
|
+
}
|
|
3032
|
+
const content = line.replace(LINE_PREFIX_ANCHORED, "");
|
|
3033
|
+
if (content.includes(`-----END ${label}-----`)) {
|
|
3034
|
+
closeBlock();
|
|
3035
|
+
out.push(line);
|
|
3036
|
+
} else if (PEM_BODY_LINE.test(content)) {
|
|
3037
|
+
bodyChars += content.trim().length;
|
|
3038
|
+
} else {
|
|
3039
|
+
closeBlock();
|
|
3040
|
+
out.push(line);
|
|
3041
|
+
}
|
|
3042
|
+
}
|
|
3043
|
+
closeBlock();
|
|
3044
|
+
return out.join("\n");
|
|
3045
|
+
}
|
|
3046
|
+
var NUMERIC = /^[-+]?\d+(?:\.\d+)?$/;
|
|
3047
|
+
var IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
3048
|
+
var MEMBER_EXPRESSION = /^[A-Za-z_$][A-Za-z0-9_$]*(?:\.[A-Za-z_$][A-Za-z0-9_$]*)+$/;
|
|
3049
|
+
var SLUG = /^[a-z]+(?:[-_][a-z]+)+$/;
|
|
3050
|
+
var PATHISH = /^(?:\.{0,2}\/|~\/)/;
|
|
3051
|
+
var URLISH = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
3052
|
+
var CODE_KEYWORDS = /* @__PURE__ */ new Set([
|
|
3053
|
+
"true",
|
|
3054
|
+
"false",
|
|
3055
|
+
"null",
|
|
3056
|
+
"none",
|
|
3057
|
+
"nil",
|
|
3058
|
+
"undefined",
|
|
3059
|
+
"void",
|
|
3060
|
+
"string",
|
|
3061
|
+
"number",
|
|
3062
|
+
"boolean",
|
|
3063
|
+
"object",
|
|
3064
|
+
"any",
|
|
3065
|
+
"unknown",
|
|
3066
|
+
"bool",
|
|
3067
|
+
"str",
|
|
3068
|
+
"int"
|
|
3069
|
+
]);
|
|
3070
|
+
var UNAMBIGUOUS_CREDENTIAL_NAME = /(?:password|passwd|passphrase|secret|credentials?|private[_-]?key)/i;
|
|
3071
|
+
function looksLikeKeyMaterial(value) {
|
|
3072
|
+
const hasDigit = /\d/.test(value);
|
|
3073
|
+
const hasAlpha = /[A-Za-z]/.test(value);
|
|
3074
|
+
const mixedCase = /[a-z]/.test(value) && /[A-Z]/.test(value);
|
|
3075
|
+
return hasDigit && hasAlpha || mixedCase || value.length >= 24;
|
|
3076
|
+
}
|
|
3077
|
+
function looksLikeCode(value) {
|
|
3078
|
+
return NUMERIC.test(value) || CODE_KEYWORDS.has(value.toLowerCase()) || MEMBER_EXPRESSION.test(value) || PATHISH.test(value) || URLISH.test(value);
|
|
3079
|
+
}
|
|
3080
|
+
function trimTrailingPunctuation(value) {
|
|
3081
|
+
const match = /[.:!]+$/.exec(value);
|
|
3082
|
+
if (!match || match.index === 0) return { value, tail: "" };
|
|
3083
|
+
return { value: value.slice(0, match.index), tail: match[0] };
|
|
3084
|
+
}
|
|
3085
|
+
function redactSecrets(text) {
|
|
3086
|
+
if (!text) return text;
|
|
3087
|
+
let out = redactPrivateKeyBlocks(text);
|
|
3088
|
+
out = out.replace(DOTENV_CREDENTIAL, (full, head, quote, value) => {
|
|
3089
|
+
if (looksLikeCode(value) || value.startsWith("$")) return full;
|
|
3090
|
+
return `${head}${quote}${marker("credential", value.length)}${quote}`;
|
|
3091
|
+
});
|
|
3092
|
+
out = out.replace(NAMED_CREDENTIAL, (full, head, quote, raw) => {
|
|
3093
|
+
const { value, tail } = trimTrailingPunctuation(raw);
|
|
3094
|
+
if (value.length < 8) return full;
|
|
3095
|
+
if (looksLikeCode(value) || value.startsWith("$")) return full;
|
|
3096
|
+
if (UNAMBIGUOUS_CREDENTIAL_NAME.test(head) && /\d/.test(value)) {
|
|
3097
|
+
return `${head}${quote}${marker("credential", value.length)}${quote}${tail}`;
|
|
3098
|
+
}
|
|
3099
|
+
if (IDENTIFIER.test(value) || SLUG.test(value)) return full;
|
|
3100
|
+
if (!UNAMBIGUOUS_CREDENTIAL_NAME.test(head) && !looksLikeKeyMaterial(value)) return full;
|
|
3101
|
+
return `${head}${quote}${marker("credential", value.length)}${quote}${tail}`;
|
|
3102
|
+
});
|
|
3103
|
+
for (const pattern of PROVIDER_KEY_PATTERNS) {
|
|
3104
|
+
out = out.replace(pattern, (hit) => marker("api key", hit.length));
|
|
3105
|
+
}
|
|
3106
|
+
out = out.replace(CLOUD_ACCESS_KEY_ID, (hit) => marker("access key id", hit.length));
|
|
3107
|
+
return out;
|
|
3108
|
+
}
|
|
3109
|
+
|
|
1664
3110
|
// src/services/executeTool.ts
|
|
1665
3111
|
var GREP_OUTPUT_MODES = ["content", "files", "count"];
|
|
1666
3112
|
function num(value) {
|
|
@@ -1687,6 +3133,10 @@ function grepOptions(args) {
|
|
|
1687
3133
|
}
|
|
1688
3134
|
var STOPPED_TOOL_RESULT = "Stopped by the user \u2014 this call was not executed, and no further tool calls will run this turn.";
|
|
1689
3135
|
async function executeTool(name, args, fs10, fetcher, signal) {
|
|
3136
|
+
const outcome = await runTool(name, args, fs10, fetcher, signal);
|
|
3137
|
+
return { ...outcome, output: redactSecrets(outcome.output) };
|
|
3138
|
+
}
|
|
3139
|
+
async function runTool(name, args, fs10, fetcher, signal) {
|
|
1690
3140
|
if (signal?.aborted) return { success: false, output: STOPPED_TOOL_RESULT, truncated: false };
|
|
1691
3141
|
switch (name) {
|
|
1692
3142
|
case "read_file": {
|
|
@@ -5955,11 +7405,11 @@ function composeAugmentedPrompt(task, allTasks, opts) {
|
|
|
5955
7405
|
if (isHitlTask(task)) {
|
|
5956
7406
|
blocks.push(renderCheckpointInstruction());
|
|
5957
7407
|
}
|
|
5958
|
-
const
|
|
5959
|
-
if (blocks.length === 0) return basePrompt +
|
|
7408
|
+
const marker2 = renderCompletionMarker(task);
|
|
7409
|
+
if (blocks.length === 0) return basePrompt + marker2;
|
|
5960
7410
|
return `${blocks.join("\n\n")}
|
|
5961
7411
|
|
|
5962
|
-
${basePrompt}${
|
|
7412
|
+
${basePrompt}${marker2}`;
|
|
5963
7413
|
}
|
|
5964
7414
|
|
|
5965
7415
|
// src/services/VerdictEngine.ts
|
|
@@ -8906,7 +10356,7 @@ function assertWorkspaceIsProject(workspace, deps = {}) {
|
|
|
8906
10356
|
throw new WorkspaceNotAProjectError(workspace);
|
|
8907
10357
|
}
|
|
8908
10358
|
const hasMarker = [...PROJECT_MARKER_DIRS, ...PROJECT_MARKER_FILES].some(
|
|
8909
|
-
(
|
|
10359
|
+
(marker2) => exists(path9.join(resolved, marker2))
|
|
8910
10360
|
);
|
|
8911
10361
|
if (!hasMarker) throw new WorkspaceNotAProjectError(workspace);
|
|
8912
10362
|
}
|
|
@@ -10126,7 +11576,8 @@ var CliAgentAiService = class {
|
|
|
10126
11576
|
let stepIndex = 0;
|
|
10127
11577
|
const truncate = (value) => value.length > LOG_MAX_CHARS ? `${value.slice(0, LOG_MAX_CHARS)}
|
|
10128
11578
|
[... truncated, total ${value.length} chars]` : value;
|
|
10129
|
-
const settle = (id,
|
|
11579
|
+
const settle = (id, rawOutput, success, outcome) => {
|
|
11580
|
+
const output = redactSecrets(rawOutput);
|
|
10130
11581
|
const call = pendingCalls.get(id);
|
|
10131
11582
|
pendingCalls.delete(id);
|
|
10132
11583
|
const step = {
|
|
@@ -10657,6 +12108,16 @@ function ensureDir(dir) {
|
|
|
10657
12108
|
function getStateDir(baseDir) {
|
|
10658
12109
|
return path10.join(baseDir ?? process.cwd(), STATE_DIR);
|
|
10659
12110
|
}
|
|
12111
|
+
var IGNORE_FILE = ".gitignore";
|
|
12112
|
+
function ensureStateDirIgnored(baseDir) {
|
|
12113
|
+
const dir = getStateDir(baseDir);
|
|
12114
|
+
ensureDir(dir);
|
|
12115
|
+
try {
|
|
12116
|
+
fs4.writeFileSync(path10.join(dir, IGNORE_FILE), "*\n", { flag: "wx" });
|
|
12117
|
+
} catch (err) {
|
|
12118
|
+
if (err.code !== "EEXIST") throw err;
|
|
12119
|
+
}
|
|
12120
|
+
}
|
|
10660
12121
|
|
|
10661
12122
|
// src/utils/sessionId.ts
|
|
10662
12123
|
var import_crypto = require("crypto");
|
|
@@ -10686,6 +12147,7 @@ function sessionFilename(session) {
|
|
|
10686
12147
|
function saveSession(plan, goal, baseDir, id) {
|
|
10687
12148
|
const sessionsDir = getSessionsDir(baseDir);
|
|
10688
12149
|
ensureDir(sessionsDir);
|
|
12150
|
+
ensureStateDirIgnored(baseDir);
|
|
10689
12151
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
10690
12152
|
const meta = {
|
|
10691
12153
|
id: id || mintSessionId(),
|
|
@@ -13765,6 +15227,7 @@ var PlannerModelMemory = class {
|
|
|
13765
15227
|
emptyWarnings,
|
|
13766
15228
|
enabledRunners,
|
|
13767
15229
|
ensureDir,
|
|
15230
|
+
ensureStateDirIgnored,
|
|
13768
15231
|
escapeControlCharsInStrings,
|
|
13769
15232
|
executionLogBlock,
|
|
13770
15233
|
executionSummary,
|