@blogic-cz/agent-tools 1.11.1 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -43
- package/dist/credential-guard/bash.d.ts +3 -0
- package/dist/credential-guard/bash.d.ts.map +1 -0
- package/dist/credential-guard/claude-hook.d.ts.map +1 -1
- package/dist/credential-guard/engine.test.d.ts +5 -0
- package/dist/credential-guard/engine.test.d.ts.map +1 -0
- package/dist/credential-guard/index.d.ts +8 -35
- package/dist/credential-guard/index.d.ts.map +1 -1
- package/dist/credential-guard/ir.d.ts +150 -0
- package/dist/credential-guard/ir.d.ts.map +1 -0
- package/dist/credential-guard/literal-output.d.ts +2 -0
- package/dist/credential-guard/literal-output.d.ts.map +1 -0
- package/dist/credential-guard/passive-awk.d.ts +2 -0
- package/dist/credential-guard/passive-awk.d.ts.map +1 -0
- package/dist/credential-guard/passive-jq.d.ts.map +1 -1
- package/dist/credential-guard/passive-sed.d.ts +2 -0
- package/dist/credential-guard/passive-sed.d.ts.map +1 -0
- package/dist/credential-guard/passive.test.d.ts +2 -0
- package/dist/credential-guard/passive.test.d.ts.map +1 -0
- package/dist/credential-guard/paths.d.ts +14 -0
- package/dist/credential-guard/paths.d.ts.map +1 -0
- package/dist/credential-guard/policy.d.ts +47 -0
- package/dist/credential-guard/policy.d.ts.map +1 -0
- package/dist/credential-guard/powershell.d.ts +3 -0
- package/dist/credential-guard/powershell.d.ts.map +1 -0
- package/dist/credential-guard/registry.d.ts +89 -0
- package/dist/credential-guard/registry.d.ts.map +1 -0
- package/dist/credential-guard/review4.test.d.ts +2 -0
- package/dist/credential-guard/review4.test.d.ts.map +1 -0
- package/dist/credential-guard/review7.test.d.ts +2 -0
- package/dist/credential-guard/review7.test.d.ts.map +1 -0
- package/dist/credential-guard/shell-oracle.d.ts +2 -0
- package/dist/credential-guard/shell-oracle.d.ts.map +1 -0
- package/dist/credential-guard/xargs.d.ts +7 -0
- package/dist/credential-guard/xargs.d.ts.map +1 -0
- package/dist/gh-tool/pr/commands.d.ts.map +1 -1
- package/dist/gh-tool/read/api.d.ts +8 -0
- package/dist/gh-tool/read/api.d.ts.map +1 -1
- package/dist/gh-tool/read/cache.d.ts.map +1 -1
- package/dist/gh-tool/read/commands.d.ts +5 -0
- package/dist/gh-tool/read/commands.d.ts.map +1 -1
- package/dist/gh-tool/read/reads.d.ts +38 -0
- package/dist/gh-tool/read/reads.d.ts.map +1 -1
- package/dist/gh-tool/read/telemetry-command.d.ts +7 -0
- package/dist/gh-tool/read/telemetry-command.d.ts.map +1 -0
- package/dist/gh-tool/read/telemetry-store.d.ts +3 -0
- package/dist/gh-tool/read/telemetry-store.d.ts.map +1 -0
- package/dist/gh-tool/read/telemetry.d.ts +59 -0
- package/dist/gh-tool/read/telemetry.d.ts.map +1 -0
- package/dist/gh-tool/read/transport.d.ts.map +1 -1
- package/package.json +2 -1
- package/schemas/agent-tools.schema.json +1 -1
- package/src/credential-guard/bash.ts +769 -0
- package/src/credential-guard/claude-hook.ts +14 -14
- package/src/credential-guard/engine.test.ts +2050 -0
- package/src/credential-guard/index.ts +285 -4268
- package/src/credential-guard/ir.ts +139 -0
- package/src/credential-guard/literal-output.ts +8 -0
- package/src/credential-guard/passive-awk.ts +239 -0
- package/src/credential-guard/passive-jq.ts +183 -24
- package/src/credential-guard/passive-sed.ts +78 -0
- package/src/credential-guard/passive.test.ts +141 -0
- package/src/credential-guard/paths.ts +108 -0
- package/src/credential-guard/policy.ts +1576 -0
- package/src/credential-guard/powershell.ts +220 -0
- package/src/credential-guard/registry.ts +4720 -0
- package/src/credential-guard/review4.test.ts +83 -0
- package/src/credential-guard/review7.test.ts +51 -0
- package/src/credential-guard/rg-types.json +389 -0
- package/src/credential-guard/shell-oracle.ts +187 -0
- package/src/credential-guard/xargs.ts +65 -0
- package/src/gh-tool/main.ts +30 -6
- package/src/gh-tool/pr/commands.ts +9 -2
- package/src/gh-tool/pr/core.ts +2 -2
- package/src/gh-tool/read/api.ts +73 -6
- package/src/gh-tool/read/cache.ts +13 -4
- package/src/gh-tool/read/commands.ts +17 -1
- package/src/gh-tool/read/reads.ts +84 -1
- package/src/gh-tool/read/telemetry-command.ts +45 -0
- package/src/gh-tool/read/telemetry-store.ts +85 -0
- package/src/gh-tool/read/telemetry.ts +191 -0
- package/src/gh-tool/read/transport.ts +10 -5
- package/src/gh-tool/workflow.ts +2 -2
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { MAX_SCRIPT_BYTES, literalWord } from "./ir";
|
|
2
|
+
import type {
|
|
3
|
+
AndOr,
|
|
4
|
+
Assignment,
|
|
5
|
+
ParseError,
|
|
6
|
+
Pipeline,
|
|
7
|
+
Script,
|
|
8
|
+
SimpleCommand,
|
|
9
|
+
Word,
|
|
10
|
+
WordPart,
|
|
11
|
+
} from "./ir";
|
|
12
|
+
|
|
13
|
+
type Token =
|
|
14
|
+
| { readonly kind: "word"; readonly word: Word }
|
|
15
|
+
| { readonly kind: "operator"; readonly text: string; readonly start: number };
|
|
16
|
+
export function parsePowerShell(text: string): Script | ParseError {
|
|
17
|
+
const error = (start: number, code: ParseError["code"] = "syntax"): ParseError => ({
|
|
18
|
+
kind: "parse-error",
|
|
19
|
+
code,
|
|
20
|
+
span: { start, end: text.length },
|
|
21
|
+
});
|
|
22
|
+
if (
|
|
23
|
+
text.length > MAX_SCRIPT_BYTES ||
|
|
24
|
+
new TextEncoder().encode(text).byteLength > MAX_SCRIPT_BYTES
|
|
25
|
+
)
|
|
26
|
+
return error(0, "size-limit");
|
|
27
|
+
|
|
28
|
+
if (/[\u2018-\u201f]/.test(text)) return error(0);
|
|
29
|
+
const tokens: Token[] = [];
|
|
30
|
+
let position = 0;
|
|
31
|
+
while (position < text.length) {
|
|
32
|
+
const ch = text[position] ?? "";
|
|
33
|
+
if (/[ \t\r,]/.test(ch)) {
|
|
34
|
+
position++;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (ch === "#") {
|
|
38
|
+
while (position < text.length && text[position] !== "\n") position++;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (/[;|&\n]/.test(ch)) {
|
|
42
|
+
const op = text.slice(position, position + 2);
|
|
43
|
+
tokens.push({
|
|
44
|
+
kind: "operator",
|
|
45
|
+
text: op === "&&" || op === "||" ? op : ch === "\n" ? ";" : ch,
|
|
46
|
+
start: position,
|
|
47
|
+
});
|
|
48
|
+
position += op === "&&" || op === "||" ? 2 : 1;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const start = position;
|
|
52
|
+
const parts: WordPart[] = [];
|
|
53
|
+
let quote = "";
|
|
54
|
+
let buffer = "";
|
|
55
|
+
const flush = () => {
|
|
56
|
+
if (buffer) {
|
|
57
|
+
parts.push({ kind: "literal", text: buffer, quoted: Boolean(quote) });
|
|
58
|
+
buffer = "";
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
while (position < text.length) {
|
|
62
|
+
const current = text[position] ?? "";
|
|
63
|
+
if (
|
|
64
|
+
!quote &&
|
|
65
|
+
current.charCodeAt(0) > 127 &&
|
|
66
|
+
!/[\p{L}\p{M}\p{N}]/u.test(current) &&
|
|
67
|
+
(/[\p{Z}\p{C}]/u.test(current) || (position === start && /[\u2013-\u2015]/u.test(current)))
|
|
68
|
+
)
|
|
69
|
+
return error(position);
|
|
70
|
+
if (
|
|
71
|
+
!quote &&
|
|
72
|
+
((current.charCodeAt(0) < 32 && !/[\t\n\r]/.test(current)) || current.charCodeAt(0) === 127)
|
|
73
|
+
)
|
|
74
|
+
return error(position);
|
|
75
|
+
if (!quote && /[ \t\r\n,;|&]/.test(current)) break;
|
|
76
|
+
if (!quote && /[{}()[\]<>@]/.test(current)) return error(position, "unsupported-keyword");
|
|
77
|
+
if (current === "`" && quote !== "'") {
|
|
78
|
+
const next = text[position + 1];
|
|
79
|
+
if (next === undefined) return error(position);
|
|
80
|
+
buffer += next === "n" ? "\n" : next === "t" ? "\t" : next;
|
|
81
|
+
position += 2;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if ((current === "'" || current === '"') && (!quote || quote === current)) {
|
|
85
|
+
if (quote === "'" && text[position + 1] === "'") {
|
|
86
|
+
buffer += "'";
|
|
87
|
+
position += 2;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
flush();
|
|
91
|
+
if (quote) quote = "";
|
|
92
|
+
else {
|
|
93
|
+
quote = current;
|
|
94
|
+
parts.push({ kind: "literal", text: "", quoted: true });
|
|
95
|
+
}
|
|
96
|
+
position++;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (quote !== "'" && current === "$") {
|
|
100
|
+
flush();
|
|
101
|
+
const match = /^\$(?:(env):)?([A-Za-z_][A-Za-z0-9_]*)/i.exec(text.slice(position));
|
|
102
|
+
if (!match) return error(position, "unsupported-parameter-operator");
|
|
103
|
+
parts.push({
|
|
104
|
+
kind: "parameter",
|
|
105
|
+
name: match[2] ?? "",
|
|
106
|
+
ambient: Boolean(match[1]),
|
|
107
|
+
operator: "plain",
|
|
108
|
+
operand: null,
|
|
109
|
+
span: { start: position, end: position + match[0].length },
|
|
110
|
+
});
|
|
111
|
+
position += match[0].length;
|
|
112
|
+
if (text[position] === ":" || text[position] === "." || text[position] === "[")
|
|
113
|
+
return error(position, "unsupported-keyword");
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (!quote && /[*?]/.test(current)) {
|
|
117
|
+
flush();
|
|
118
|
+
parts.push({ kind: "glob", text: current });
|
|
119
|
+
position++;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
buffer += current;
|
|
123
|
+
position++;
|
|
124
|
+
}
|
|
125
|
+
if (position === start) return error(start);
|
|
126
|
+
if (quote) return error(start, "unterminated-quote");
|
|
127
|
+
flush();
|
|
128
|
+
tokens.push({ kind: "word", word: { split: false, parts, span: { start, end: position } } });
|
|
129
|
+
}
|
|
130
|
+
let cursor = 0;
|
|
131
|
+
const location = (): number => {
|
|
132
|
+
const token = tokens[cursor];
|
|
133
|
+
return token?.kind === "operator" ? token.start : (token?.word.span.start ?? text.length);
|
|
134
|
+
};
|
|
135
|
+
const isOp = (op: string): boolean => {
|
|
136
|
+
const t = tokens[cursor];
|
|
137
|
+
return t?.kind === "operator" && t.text === op;
|
|
138
|
+
};
|
|
139
|
+
const command = (): SimpleCommand | ParseError => {
|
|
140
|
+
const first = tokens[cursor];
|
|
141
|
+
const start =
|
|
142
|
+
first?.kind === "operator" ? first.start : (first?.word.span.start ?? text.length);
|
|
143
|
+
const invocation = isOp("&");
|
|
144
|
+
if (invocation) cursor++;
|
|
145
|
+
const argv: Word[] = [];
|
|
146
|
+
while (tokens[cursor]?.kind === "word") {
|
|
147
|
+
const t = tokens[cursor];
|
|
148
|
+
if (t?.kind === "word") argv.push(t.word);
|
|
149
|
+
cursor++;
|
|
150
|
+
}
|
|
151
|
+
if (!argv.length) return error(start);
|
|
152
|
+
const assignments: Assignment[] = [];
|
|
153
|
+
const variable = argv[0];
|
|
154
|
+
const part = variable?.parts[0];
|
|
155
|
+
const equals = argv[1];
|
|
156
|
+
if (
|
|
157
|
+
!invocation &&
|
|
158
|
+
variable?.parts.length === 1 &&
|
|
159
|
+
part?.kind === "parameter" &&
|
|
160
|
+
equals?.parts.length === 1 &&
|
|
161
|
+
equals.parts[0]?.kind === "literal" &&
|
|
162
|
+
equals.parts[0].text === "="
|
|
163
|
+
) {
|
|
164
|
+
if (argv.length !== 3 || part.ambient) return error(start, "unsupported-keyword");
|
|
165
|
+
assignments.push({
|
|
166
|
+
operation: "replace",
|
|
167
|
+
name: part.name.toLowerCase(),
|
|
168
|
+
value: argv[2] ?? literalWord(""),
|
|
169
|
+
exported: false,
|
|
170
|
+
});
|
|
171
|
+
argv.splice(0);
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
kind: "simple",
|
|
175
|
+
assignments,
|
|
176
|
+
argv,
|
|
177
|
+
redirects: [],
|
|
178
|
+
span: {
|
|
179
|
+
start,
|
|
180
|
+
end: location(),
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
const pipeline = (): Pipeline | ParseError => {
|
|
185
|
+
const first = command();
|
|
186
|
+
if (first.kind === "parse-error") return first;
|
|
187
|
+
const commands: SimpleCommand[] = [first];
|
|
188
|
+
while (isOp("|")) {
|
|
189
|
+
cursor++;
|
|
190
|
+
const next = command();
|
|
191
|
+
if (next.kind === "parse-error") return next;
|
|
192
|
+
commands.push(next);
|
|
193
|
+
}
|
|
194
|
+
return { negated: false, stderr: false, commands };
|
|
195
|
+
};
|
|
196
|
+
const items: AndOr[] = [];
|
|
197
|
+
while (cursor < tokens.length) {
|
|
198
|
+
while (isOp(";")) cursor++;
|
|
199
|
+
if (cursor === tokens.length) break;
|
|
200
|
+
const first = pipeline();
|
|
201
|
+
if ("kind" in first) return first;
|
|
202
|
+
const rest: { op: "&&" | "||"; pipeline: Pipeline }[] = [];
|
|
203
|
+
while (isOp("&&") || isOp("||")) {
|
|
204
|
+
const op = isOp("&&") ? "&&" : "||";
|
|
205
|
+
cursor++;
|
|
206
|
+
const next = pipeline();
|
|
207
|
+
if ("kind" in next) return next;
|
|
208
|
+
rest.push({ op, pipeline: next });
|
|
209
|
+
}
|
|
210
|
+
items.push({ first, rest, background: false });
|
|
211
|
+
if (cursor < tokens.length && !isOp(";")) return error(location());
|
|
212
|
+
}
|
|
213
|
+
return {
|
|
214
|
+
kind: "script",
|
|
215
|
+
dialect: "powershell",
|
|
216
|
+
source: text,
|
|
217
|
+
body: { items },
|
|
218
|
+
span: { start: 0, end: text.length },
|
|
219
|
+
};
|
|
220
|
+
}
|