approval-md 0.4.3 → 0.4.6
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/SPEC.md +13 -2
- package/dist/src/channels/telegram.d.ts +105 -31
- package/dist/src/channels/telegram.js +157 -81
- package/dist/src/channels/telegram.js.map +1 -1
- package/dist/src/cli/channel-telegram.d.ts +100 -35
- package/dist/src/cli/channel-telegram.js +216 -119
- package/dist/src/cli/channel-telegram.js.map +1 -1
- package/dist/src/cli/doctor.js +33 -13
- package/dist/src/cli/doctor.js.map +1 -1
- package/dist/src/cli/help.js +3 -3
- package/dist/src/cli/hook-exec-code.d.ts +150 -0
- package/dist/src/cli/hook-exec-code.js +357 -0
- package/dist/src/cli/hook-exec-code.js.map +1 -0
- package/dist/src/cli/hook.d.ts +125 -1
- package/dist/src/cli/hook.js +2177 -107
- package/dist/src/cli/hook.js.map +1 -1
- package/dist/src/cli/wordmark.d.ts +2 -2
- package/dist/src/cli/wordmark.js +2 -2
- package/dist/src/core/command-class.d.ts +368 -1
- package/dist/src/core/command-class.js +2830 -93
- package/dist/src/core/command-class.js.map +1 -1
- package/dist/src/core/date-argv.d.ts +83 -0
- package/dist/src/core/date-argv.js +212 -0
- package/dist/src/core/date-argv.js.map +1 -0
- package/dist/src/core/exec-code.d.ts +77 -0
- package/dist/src/core/exec-code.js +60 -0
- package/dist/src/core/exec-code.js.map +1 -0
- package/dist/src/core/git-push-argv.d.ts +111 -0
- package/dist/src/core/git-push-argv.js +375 -0
- package/dist/src/core/git-push-argv.js.map +1 -0
- package/dist/src/core/harness-version.d.ts +71 -30
- package/dist/src/core/harness-version.js +101 -34
- package/dist/src/core/harness-version.js.map +1 -1
- package/dist/src/core/policy-load.d.ts +8 -0
- package/dist/src/core/policy-load.js.map +1 -1
- package/dist/src/core/read-scope.js +1 -0
- package/dist/src/core/read-scope.js.map +1 -1
- package/dist/src/core/sysinfo-argv.d.ts +48 -0
- package/dist/src/core/sysinfo-argv.js +340 -0
- package/dist/src/core/sysinfo-argv.js.map +1 -0
- package/dist/src/daemon/git-evidence.d.ts +2 -2
- package/dist/src/daemon/git-evidence.js +1 -1
- package/docs/README-extended.md +3 -2
- package/docs/cli-reference.md +20 -7
- package/package.json +2 -2
- package/schema/event.schema.json +1 -1
- package/schema/fixtures/policy/invalid/exec-code-custody-boolean.json +11 -0
- package/schema/fixtures/policy/invalid/exec-code-execute-code-value.json +11 -0
- package/schema/fixtures/policy/invalid/exec-code-unknown-key.json +12 -0
- package/schema/fixtures/policy/valid/exec-code-both.json +17 -0
- package/schema/fixtures/policy/valid/exec-code-custody.json +11 -0
- package/schema/policy.schema.json +23 -0
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `git push` read the way git 2.50's option parser reads it (APRV-517).
|
|
3
|
+
*
|
|
4
|
+
* The classifier's `git-push` row used to look for flags by exact spelling:
|
|
5
|
+
* `--delete` and `-d`, `--force` and `-f`. git's parser accepts more than
|
|
6
|
+
* that, and every extra spelling it accepts did the same thing as the one it
|
|
7
|
+
* stands for while classifying as a plain push:
|
|
8
|
+
*
|
|
9
|
+
* - a short bundle: `-ud`, `-du`, `-fd`, `-dn` carry `-d` (and `-f`);
|
|
10
|
+
* - a long-option abbreviation by unique prefix: `--de`, `--del`, `--dele`
|
|
11
|
+
* and `--delet` are `--delete`, `--m` is `--mirror`, `--pru` is `--prune`;
|
|
12
|
+
* - a deleting option the exact list never named: `--prune` removes every
|
|
13
|
+
* remote ref a wildcard refspec no longer matches;
|
|
14
|
+
* - the words after a value-taking option (`-o x`, `--repo x`) shift the
|
|
15
|
+
* positionals, and a global option in front of `push` (`git --no-pager
|
|
16
|
+
* push origin`) shifted them too.
|
|
17
|
+
*
|
|
18
|
+
* So this file is the closed rule: it walks the argv exactly as git's
|
|
19
|
+
* `parse-options.c` does over the option table of `builtin/push.c` in git
|
|
20
|
+
* 2.50, and reports what the push does rather than which words it contains.
|
|
21
|
+
* Anything it cannot walk is a refusal, never a guess:
|
|
22
|
+
*
|
|
23
|
+
* - `unreadable`: a word the shell may split or expand into words this walk
|
|
24
|
+
* never saw (`$`, a backtick, a glob, a brace expansion), a word that came
|
|
25
|
+
* out of a command substitution, or an assignment or global option in
|
|
26
|
+
* front of `push` that steers which configuration git reads (`GIT_*=`,
|
|
27
|
+
* `HOME=`, `XDG_CONFIG_HOME=`, `--git-dir=`, `--work-tree=`,
|
|
28
|
+
* `--config-env=`: `remote.origin.push=:refs/heads/main` deletes the trunk
|
|
29
|
+
* with no refspec on the command line, and `remote.<name>.mirror` turns a
|
|
30
|
+
* plain push into a mirror). Any of these can hold `-d`, `:main` or `+main`;
|
|
31
|
+
* - `unparseable`: an option git does not know, an ambiguous abbreviation, a
|
|
32
|
+
* value where none is taken, a missing value, or a global option in front
|
|
33
|
+
* of `push` this file does not know. git refuses all of these itself, so
|
|
34
|
+
* refusing them costs nothing, and a newer git that grew an option this
|
|
35
|
+
* table lacks is refused rather than read as a plain push;
|
|
36
|
+
* - `runs-program`: `--receive-pack` / `--exec` name the program git starts
|
|
37
|
+
* for the far side, which for a local or `file://` remote runs on this
|
|
38
|
+
* machine, and `git --exec-path=` picks where git finds its helpers. What it runs is a command line this classifier is not reading,
|
|
39
|
+
* the reason `find -exec` is opaque (APRV-283).
|
|
40
|
+
*
|
|
41
|
+
* Negations (`--no-delete`) never clear a flag an earlier word set: a push
|
|
42
|
+
* that both deletes and un-deletes is read as deleting, which only ever picks
|
|
43
|
+
* the stricter class for a spelling nobody writes.
|
|
44
|
+
*
|
|
45
|
+
* The walk is checked against the real binary: tests/git-push-delete-spellings
|
|
46
|
+
* runs every deleting spelling against a bare local remote and asserts the ref
|
|
47
|
+
* is gone, and the generated differential there runs the corpus through git
|
|
48
|
+
* and asserts every deletion and every forced update it observed was
|
|
49
|
+
* classified at least that strictly.
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* `git push -h` on git 2.50, in `builtin/push.c` order. Order matters only for
|
|
53
|
+
* which candidate an ambiguity error names, never for which option matches.
|
|
54
|
+
*/
|
|
55
|
+
export const GIT_PUSH_OPTIONS = [
|
|
56
|
+
{ long: "verbose", short: "v", value: "none" },
|
|
57
|
+
{ long: "quiet", short: "q", value: "none" },
|
|
58
|
+
{ long: "repo", value: "required" },
|
|
59
|
+
{ long: "all", value: "none", effect: "all" },
|
|
60
|
+
{ long: "branches", value: "none", aliasOf: "all", effect: "all" },
|
|
61
|
+
{ long: "mirror", value: "none", effect: "mirror" },
|
|
62
|
+
{ long: "delete", short: "d", value: "none", effect: "remove" },
|
|
63
|
+
{ long: "tags", value: "none", effect: "tags" },
|
|
64
|
+
{ long: "dry-run", short: "n", value: "none" },
|
|
65
|
+
{ long: "porcelain", value: "none" },
|
|
66
|
+
{ long: "force", short: "f", value: "none", effect: "force" },
|
|
67
|
+
{ long: "force-with-lease", value: "optional", effect: "force" },
|
|
68
|
+
{ long: "force-if-includes", value: "none", effect: "force" },
|
|
69
|
+
{ long: "recurse-submodules", value: "required", effect: "submodules" },
|
|
70
|
+
{ long: "thin", value: "none" },
|
|
71
|
+
{ long: "receive-pack", value: "required", effect: "program" },
|
|
72
|
+
{ long: "exec", value: "required", effect: "program" },
|
|
73
|
+
{ long: "set-upstream", short: "u", value: "none" },
|
|
74
|
+
{ long: "progress", value: "none" },
|
|
75
|
+
{ long: "prune", value: "none", effect: "prune" },
|
|
76
|
+
{ long: "no-verify", value: "none" },
|
|
77
|
+
{ long: "follow-tags", value: "none", effect: "tags" },
|
|
78
|
+
{ long: "signed", value: "optional" },
|
|
79
|
+
{ long: "atomic", value: "none" },
|
|
80
|
+
{ long: "push-option", short: "o", value: "required" },
|
|
81
|
+
{ long: "ipv4", short: "4", value: "none", noneg: true },
|
|
82
|
+
{ long: "ipv6", short: "6", value: "none", noneg: true },
|
|
83
|
+
];
|
|
84
|
+
/**
|
|
85
|
+
* The help options parse-options itself answers, by exact spelling only
|
|
86
|
+
* (`-h` is the short one): each prints usage and exits without pushing, so it
|
|
87
|
+
* adds nothing to the reading.
|
|
88
|
+
*/
|
|
89
|
+
const INTERNAL_LONG = ["help", "help-all"];
|
|
90
|
+
/**
|
|
91
|
+
* Global options in front of the subcommand (`git.c` `handle_options`, git
|
|
92
|
+
* 2.50), matched by exact spelling, as git matches them. These take no value
|
|
93
|
+
* and change nothing about what a push sends.
|
|
94
|
+
*/
|
|
95
|
+
const GIT_GLOBAL_BARE = [
|
|
96
|
+
"-p",
|
|
97
|
+
"--paginate",
|
|
98
|
+
"-P",
|
|
99
|
+
"--no-pager",
|
|
100
|
+
"--no-replace-objects",
|
|
101
|
+
"--no-lazy-fetch",
|
|
102
|
+
"--no-optional-locks",
|
|
103
|
+
"--no-advice",
|
|
104
|
+
"--bare",
|
|
105
|
+
"--literal-pathspecs",
|
|
106
|
+
"--glob-pathspecs",
|
|
107
|
+
"--noglob-pathspecs",
|
|
108
|
+
"--icase-pathspecs",
|
|
109
|
+
];
|
|
110
|
+
/** `=`-joined globals that change nothing about what a push sends either. */
|
|
111
|
+
const GIT_GLOBAL_JOINED = ["--namespace=", "--attr-source="];
|
|
112
|
+
/**
|
|
113
|
+
* `=`-joined globals that decide which configuration the push runs under:
|
|
114
|
+
* another repository's `.git/config` (`--git-dir`, `--work-tree`) or a value
|
|
115
|
+
* injected from the environment (`--config-env`). Configuration can carry a
|
|
116
|
+
* deleting refspec or `mirror = true`, so these read like a steering
|
|
117
|
+
* assignment.
|
|
118
|
+
*/
|
|
119
|
+
const GIT_GLOBAL_STEERING = ["--git-dir=", "--work-tree=", "--config-env="];
|
|
120
|
+
/** `--exec-path=` picks the directory git runs its helper programs from. */
|
|
121
|
+
const GIT_GLOBAL_PROGRAM = "--exec-path";
|
|
122
|
+
// Anything else in front of `push` is refused, the separate-value forms
|
|
123
|
+
// (`-C dir`, `-c k=v`, `--git-dir dir`) included: there the word the
|
|
124
|
+
// classifier took for the subcommand may have been that option's value.
|
|
125
|
+
/** Assignments in front of `git` that steer which configuration it reads. */
|
|
126
|
+
const STEERING_ENV = /^(?:GIT_[A-Za-z0-9_]*|HOME|XDG_CONFIG_HOME)=/u;
|
|
127
|
+
/** `$`, a backtick, or a glob character: the shell may expand the word into others. */
|
|
128
|
+
const EXPANDING_CHAR = /[$`*?[\]]/u;
|
|
129
|
+
/** A brace expansion: `{a,b}` or `{1..3}`. A reflog `@{1}` is neither. */
|
|
130
|
+
const BRACE_EXPANSION = /\{[^{}]*(?:,|\.\.)[^{}]*\}/u;
|
|
131
|
+
/** Can the shell turn this word into a different word, or into several? */
|
|
132
|
+
export function isUnreadablePushWord(word) {
|
|
133
|
+
return EXPANDING_CHAR.test(word) || BRACE_EXPANSION.test(word);
|
|
134
|
+
}
|
|
135
|
+
/** Are these two options one option under two names (`OPT_ALIAS`)? */
|
|
136
|
+
function isAlias(a, b) {
|
|
137
|
+
return a.aliasOf === b.long || b.aliasOf === a.long || (a.aliasOf !== undefined && a.aliasOf === b.aliasOf);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* `parse_long_opt` in git 2.50's `parse-options.c`, over `name` (the text
|
|
141
|
+
* after `--` and before any `=`).
|
|
142
|
+
*
|
|
143
|
+
* An exact spelling wins outright. Otherwise every option the text is a
|
|
144
|
+
* prefix of is a candidate, positively or through `no-`; two candidates that
|
|
145
|
+
* are not aliases of each other are ambiguous, which git refuses.
|
|
146
|
+
*/
|
|
147
|
+
function matchLong(name) {
|
|
148
|
+
let abbrev = null;
|
|
149
|
+
let ambiguous = false;
|
|
150
|
+
const candidate = (option, unset) => {
|
|
151
|
+
if (abbrev !== null && !isAlias(abbrev.option, option))
|
|
152
|
+
ambiguous = true;
|
|
153
|
+
abbrev = { option, unset };
|
|
154
|
+
};
|
|
155
|
+
for (const option of GIT_PUSH_OPTIONS) {
|
|
156
|
+
let long = option.long;
|
|
157
|
+
let optUnset = false;
|
|
158
|
+
if (long.startsWith("no-")) {
|
|
159
|
+
long = long.slice(3);
|
|
160
|
+
optUnset = true;
|
|
161
|
+
}
|
|
162
|
+
if (name.startsWith(long)) {
|
|
163
|
+
if (name === long)
|
|
164
|
+
return { option, unset: optUnset };
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (long.startsWith(name)) {
|
|
168
|
+
candidate(option, optUnset);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (option.noneg === true)
|
|
172
|
+
continue;
|
|
173
|
+
if ("no-".startsWith(name)) {
|
|
174
|
+
candidate(option, !optUnset);
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (!name.startsWith("no-"))
|
|
178
|
+
continue;
|
|
179
|
+
const rest = name.slice(3);
|
|
180
|
+
if (rest.startsWith(long)) {
|
|
181
|
+
if (rest === long)
|
|
182
|
+
return { option, unset: !optUnset };
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (long.startsWith(rest))
|
|
186
|
+
candidate(option, !optUnset);
|
|
187
|
+
}
|
|
188
|
+
if (ambiguous)
|
|
189
|
+
return "ambiguous";
|
|
190
|
+
return abbrev;
|
|
191
|
+
}
|
|
192
|
+
/** The option a short letter names, or `null`. */
|
|
193
|
+
function matchShort(letter) {
|
|
194
|
+
return GIT_PUSH_OPTIONS.find((option) => option.short === letter) ?? null;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Split the words after `git` at the `push` subcommand: the global options in
|
|
198
|
+
* front of it, and the push's own argv after it.
|
|
199
|
+
*/
|
|
200
|
+
export function splitGitPush(gitArgs) {
|
|
201
|
+
const at = gitArgs.findIndex((word) => !(word.startsWith("-") && word !== "-"));
|
|
202
|
+
if (at === -1 || gitArgs[at] !== "push")
|
|
203
|
+
return null;
|
|
204
|
+
return { globals: gitArgs.slice(0, at), words: gitArgs.slice(at + 1) };
|
|
205
|
+
}
|
|
206
|
+
/** The global options in front of `push`, judged; `null` when they change nothing. */
|
|
207
|
+
function judgeGlobals(globals) {
|
|
208
|
+
for (const word of globals) {
|
|
209
|
+
if (isUnreadablePushWord(word)) {
|
|
210
|
+
return { ok: false, kind: "unreadable", detail: `the shell may expand ${word} into other words` };
|
|
211
|
+
}
|
|
212
|
+
if (GIT_GLOBAL_BARE.includes(word))
|
|
213
|
+
continue;
|
|
214
|
+
if (GIT_GLOBAL_JOINED.some((prefix) => word.startsWith(prefix)))
|
|
215
|
+
continue;
|
|
216
|
+
if (GIT_GLOBAL_STEERING.some((prefix) => word.startsWith(prefix))) {
|
|
217
|
+
return {
|
|
218
|
+
ok: false,
|
|
219
|
+
kind: "unreadable",
|
|
220
|
+
detail: `git ${word.slice(0, word.indexOf("=") + 1)}… decides which configuration the push reads`,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
if (word === GIT_GLOBAL_PROGRAM || word.startsWith(`${GIT_GLOBAL_PROGRAM}=`)) {
|
|
224
|
+
return { ok: false, kind: "runs-program", detail: "git --exec-path picks the directory git runs its helpers from" };
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
ok: false,
|
|
228
|
+
kind: "unparseable",
|
|
229
|
+
detail: `git ${word} in front of push: this classifier does not read that global option`,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Walk a `git push` argv (the words after `push`) the way git does.
|
|
236
|
+
*
|
|
237
|
+
* `assignments` are the `NAME=value` words in front of `git`, `substituted`
|
|
238
|
+
* says whether any word came out of a command substitution, and `globals` are
|
|
239
|
+
* the git options in front of `push` ({@link splitGitPush}).
|
|
240
|
+
*/
|
|
241
|
+
export function parseGitPushArgv(words, assignments = [], substituted = false, globals = []) {
|
|
242
|
+
const globalRefusal = judgeGlobals(globals);
|
|
243
|
+
if (globalRefusal !== null)
|
|
244
|
+
return globalRefusal;
|
|
245
|
+
if (substituted) {
|
|
246
|
+
return { ok: false, kind: "unreadable", detail: "a word of this push is a command substitution's output" };
|
|
247
|
+
}
|
|
248
|
+
const steering = assignments.find((word) => STEERING_ENV.test(word));
|
|
249
|
+
if (steering !== undefined) {
|
|
250
|
+
return {
|
|
251
|
+
ok: false,
|
|
252
|
+
kind: "unreadable",
|
|
253
|
+
detail: `${steering.slice(0, steering.indexOf("="))}=… in front of git steers which configuration the push reads`,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
const unreadable = words.find(isUnreadablePushWord);
|
|
257
|
+
if (unreadable !== undefined) {
|
|
258
|
+
return { ok: false, kind: "unreadable", detail: `the shell may expand ${unreadable} into other words` };
|
|
259
|
+
}
|
|
260
|
+
const reading = {
|
|
261
|
+
force: false,
|
|
262
|
+
remove: false,
|
|
263
|
+
prune: false,
|
|
264
|
+
tags: false,
|
|
265
|
+
all: false,
|
|
266
|
+
positionals: [],
|
|
267
|
+
};
|
|
268
|
+
const unparseable = (detail) => ({ ok: false, kind: "unparseable", detail });
|
|
269
|
+
const apply = (option, unset, value) => {
|
|
270
|
+
if (unset)
|
|
271
|
+
return null;
|
|
272
|
+
switch (option.effect) {
|
|
273
|
+
case "force":
|
|
274
|
+
reading.force = true;
|
|
275
|
+
break;
|
|
276
|
+
case "mirror":
|
|
277
|
+
reading.force = true;
|
|
278
|
+
reading.all = true;
|
|
279
|
+
break;
|
|
280
|
+
case "remove":
|
|
281
|
+
reading.remove = true;
|
|
282
|
+
break;
|
|
283
|
+
case "prune":
|
|
284
|
+
reading.prune = true;
|
|
285
|
+
break;
|
|
286
|
+
case "tags":
|
|
287
|
+
reading.tags = true;
|
|
288
|
+
break;
|
|
289
|
+
case "all":
|
|
290
|
+
reading.all = true;
|
|
291
|
+
break;
|
|
292
|
+
case "submodules":
|
|
293
|
+
// `check` only verifies and `no` turns it off; `on-demand` and `only`
|
|
294
|
+
// push the submodules' own branches, which may be their trunks.
|
|
295
|
+
if (value !== "check" && value !== "no")
|
|
296
|
+
reading.all = true;
|
|
297
|
+
break;
|
|
298
|
+
case "program":
|
|
299
|
+
return {
|
|
300
|
+
ok: false,
|
|
301
|
+
kind: "runs-program",
|
|
302
|
+
detail: `git push --${option.long} names the program git runs for the far side`,
|
|
303
|
+
};
|
|
304
|
+
default:
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
return null;
|
|
308
|
+
};
|
|
309
|
+
for (let index = 0; index < words.length; index += 1) {
|
|
310
|
+
const word = words[index];
|
|
311
|
+
if (word === "--" || word === "--end-of-options") {
|
|
312
|
+
reading.positionals.push(...words.slice(index + 1));
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
if (word.startsWith("--")) {
|
|
316
|
+
const body = word.slice(2);
|
|
317
|
+
const equals = body.indexOf("=");
|
|
318
|
+
const name = equals === -1 ? body : body.slice(0, equals);
|
|
319
|
+
if (INTERNAL_LONG.includes(body))
|
|
320
|
+
continue;
|
|
321
|
+
const matched = matchLong(name);
|
|
322
|
+
if (matched === "ambiguous")
|
|
323
|
+
return unparseable(`git push --${name} is ambiguous`);
|
|
324
|
+
if (matched === null)
|
|
325
|
+
return unparseable(`git push has no option --${name}`);
|
|
326
|
+
const { option, unset } = matched;
|
|
327
|
+
let value;
|
|
328
|
+
if (equals !== -1) {
|
|
329
|
+
if (unset || option.value === "none")
|
|
330
|
+
return unparseable(`git push --${name} takes no value`);
|
|
331
|
+
value = body.slice(equals + 1);
|
|
332
|
+
}
|
|
333
|
+
else if (!unset && option.value === "required") {
|
|
334
|
+
if (index + 1 >= words.length)
|
|
335
|
+
return unparseable(`git push --${name} requires a value`);
|
|
336
|
+
index += 1;
|
|
337
|
+
value = words[index];
|
|
338
|
+
}
|
|
339
|
+
const refusal = apply(option, unset, value);
|
|
340
|
+
if (refusal !== null)
|
|
341
|
+
return refusal;
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (word.startsWith("-") && word !== "-") {
|
|
345
|
+
const letters = word.slice(1);
|
|
346
|
+
for (let at = 0; at < letters.length; at += 1) {
|
|
347
|
+
const letter = letters[at];
|
|
348
|
+
if (letter === "h")
|
|
349
|
+
break;
|
|
350
|
+
const option = matchShort(letter);
|
|
351
|
+
if (option === null)
|
|
352
|
+
return unparseable(`git push has no switch -${letter}`);
|
|
353
|
+
if (option.value === "required") {
|
|
354
|
+
// The rest of the bundle is the value, or else the next word.
|
|
355
|
+
if (at + 1 >= letters.length) {
|
|
356
|
+
if (index + 1 >= words.length)
|
|
357
|
+
return unparseable(`git push -${letter} requires a value`);
|
|
358
|
+
index += 1;
|
|
359
|
+
}
|
|
360
|
+
const refusal = apply(option, false, undefined);
|
|
361
|
+
if (refusal !== null)
|
|
362
|
+
return refusal;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
const refusal = apply(option, false, undefined);
|
|
366
|
+
if (refusal !== null)
|
|
367
|
+
return refusal;
|
|
368
|
+
}
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
reading.positionals.push(word);
|
|
372
|
+
}
|
|
373
|
+
return { ok: true, reading };
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=git-push-argv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-push-argv.js","sourceRoot":"","sources":["../../../src/core/git-push-argv.ts"],"names":[],"mappings":"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"}
|
|
@@ -73,19 +73,56 @@ export declare const HARNESS_BINARY: Readonly<Record<HarnessKind, string>>;
|
|
|
73
73
|
* forever. So the write boundary takes one line, printable ASCII only, capped.
|
|
74
74
|
*/
|
|
75
75
|
export declare const HARNESS_VERSION_LIMIT = 64;
|
|
76
|
+
/**
|
|
77
|
+
* The longest leading run of printable ASCII, U+0020 through U+007E.
|
|
78
|
+
*
|
|
79
|
+
* The one place the recordable-character rule lives (APRV-419). The run stops
|
|
80
|
+
* at the first character outside that range, so a non-ASCII character, a
|
|
81
|
+
* control character (a newline, a tab, a carriage return, a BEL) and EVERYTHING
|
|
82
|
+
* after any of them is cut, even when what follows would be printable again.
|
|
83
|
+
* The schema's pattern for `payload.harness_version` (`^[\u0020-\u007e]+$`)
|
|
84
|
+
* admits exactly the strings this can return, so the rule and the write
|
|
85
|
+
* boundary cannot drift apart.
|
|
86
|
+
*/
|
|
87
|
+
export declare function printableAsciiPrefix(text: string): string;
|
|
76
88
|
/**
|
|
77
89
|
* The one spelling of a harness version this runtime ever writes or compares.
|
|
78
90
|
*
|
|
79
|
-
* First line, trimmed,
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
91
|
+
* First line, trimmed, then its printable-ASCII prefix ({@link
|
|
92
|
+
* printableAsciiPrefix}), trimmed again. `claude --version` prints
|
|
93
|
+
* `2.0.14 (Claude Code)` and passes through whole; a future release may add a
|
|
94
|
+
* second line of banner, which the prefix never reaches. Both the hook (which
|
|
95
|
+
* records) and doctor (which compares) call this, so the comparison is between
|
|
96
|
+
* two values normalized identically: a row that failed because one side kept a
|
|
97
|
+
* trailing newline would be a false alarm, and a false alarm in a health check
|
|
98
|
+
* trains an operator to ignore it.
|
|
99
|
+
*
|
|
100
|
+
* ## Why a prefix rather than a refusal (APRV-419, option (c))
|
|
101
|
+
*
|
|
102
|
+
* Until APRV-419 a line holding any byte outside printable ASCII was refused
|
|
103
|
+
* whole. Hermes prints `Hermes Agent v0.21.3 (2026.9.14) · upstream 913d4098`
|
|
104
|
+
* and the separator is U+00B7, so no record ever carried a Hermes version and
|
|
105
|
+
* doctor could never compare one. Carter chose, on 2026-10-17, to record the
|
|
106
|
+
* prefix instead: for that line, `Hermes Agent v0.21.3 (2026.9.14)`. The
|
|
107
|
+
* upstream commit after the separator is lost, which is why the fail-closed
|
|
108
|
+
* floor below still reads the raw line.
|
|
109
|
+
*
|
|
110
|
+
* The SET of recordable values is unchanged. Every value returned here is a
|
|
111
|
+
* string the old rule accepted as a whole line (one line, printable ASCII,
|
|
112
|
+
* 1..64 characters), so the schema, the read side ({@link
|
|
113
|
+
* readHarnessProvenance}) and every record already written are unchanged. What
|
|
114
|
+
* moved is which part of a line is recorded: the line is cut at its first
|
|
115
|
+
* non-printable character, and the 64-character cap then applies to that prefix
|
|
116
|
+
* rather than to the whole line. So a long line whose printable-ASCII prefix
|
|
117
|
+
* fits the cap now records the prefix where the old rule refused the line, and
|
|
118
|
+
* at most 64 printable-ASCII characters of any line reach the log (SPEC.md
|
|
119
|
+
* §11.1 invariant 3).
|
|
85
120
|
*
|
|
86
121
|
* Returns `null` for anything that is not a usable version: empty output, a
|
|
87
|
-
* line
|
|
88
|
-
*
|
|
122
|
+
* line with no printable-ASCII prefix, or a prefix longer than the cap. The cut
|
|
123
|
+
* at the first non-printable character is the one truncation this applies; a
|
|
124
|
+
* prefix still over the cap after it is refused whole. Absence is always
|
|
125
|
+
* available and always honest.
|
|
89
126
|
*/
|
|
90
127
|
export declare function normalizeHarnessVersion(raw: unknown): string | null;
|
|
91
128
|
/**
|
|
@@ -109,9 +146,10 @@ export declare const HARNESS_PROBE_TIMEOUT_MS = 10000;
|
|
|
109
146
|
* the log (only {@link normalizeHarnessVersion}'s output is), and what needs the
|
|
110
147
|
* raw line is a diagnostic that must be able to read a build stamp a harness
|
|
111
148
|
* prints beside its semver. Hermes prints
|
|
112
|
-
* `Hermes Agent v0.21.3 (2026.9.14) · upstream 913d4098`, which the log
|
|
113
|
-
*
|
|
114
|
-
* characters all the same: this is
|
|
149
|
+
* `Hermes Agent v0.21.3 (2026.9.14) · upstream 913d4098`, of which the log keeps
|
|
150
|
+
* only the part before the non-ASCII separator (APRV-419), losing the upstream
|
|
151
|
+
* commit. Capped and stripped of control characters all the same: this is
|
|
152
|
+
* third-party output on its way to a terminal.
|
|
115
153
|
*/
|
|
116
154
|
export declare const HARNESS_RAW_VERSION_LIMIT = 200;
|
|
117
155
|
/**
|
|
@@ -119,38 +157,41 @@ export declare const HARNESS_RAW_VERSION_LIMIT = 200;
|
|
|
119
157
|
*
|
|
120
158
|
* One line, trimmed, control characters removed, capped. `null` for empty output
|
|
121
159
|
* or a line past the cap. It keeps non-ASCII bytes, which is the whole difference
|
|
122
|
-
* from {@link normalizeHarnessVersion}:
|
|
160
|
+
* from {@link normalizeHarnessVersion}: an upstream commit behind a typographic
|
|
123
161
|
* separator is exactly the fact a version floor has to read, and it is exactly
|
|
124
|
-
* the
|
|
125
|
-
*/
|
|
126
|
-
export declare function rawHarnessVersionLine(raw: unknown): string | null;
|
|
127
|
-
/**
|
|
128
|
-
* Run `<binary> --version` once, uncached, and return its raw first line.
|
|
162
|
+
* the part of the line the write boundary cuts.
|
|
129
163
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* third-party CLI spawned by a process that may be holding a bot token and a
|
|
136
|
-
* vault passphrase, and it has no use for either. Nothing is declared, because
|
|
137
|
-
* reading a version is not a granted action.
|
|
164
|
+
* Never the source of a RECORDED value. Removing a control character glues what
|
|
165
|
+
* followed it onto what preceded it, so text a `\r` hid on a terminal would
|
|
166
|
+
* reach the log if this line were normalized. The recordable form is read off
|
|
167
|
+
* the untouched first line instead ({@link installedHarnessVersion}), where the
|
|
168
|
+
* control character cuts exactly as it does for an event-supplied value (APRV-419).
|
|
138
169
|
*/
|
|
170
|
+
export declare function rawHarnessVersionLine(raw: unknown): string | null;
|
|
171
|
+
/** Run `<binary> --version` once, uncached, and return its first line as a diagnostic may print it. */
|
|
139
172
|
export declare function probeHarnessVersionRaw(kind: HarnessKind): string | null;
|
|
140
173
|
/**
|
|
141
174
|
* Run `<binary> --version` once, uncached, and normalize what came back.
|
|
142
175
|
*
|
|
143
|
-
* The recordable form: one line, printable
|
|
144
|
-
*
|
|
176
|
+
* The recordable form: one line, its printable-ASCII prefix, capped, read off
|
|
177
|
+
* the untouched first line so a control character cuts here as it does on the
|
|
178
|
+
* event path. Exported for the test that proves the memo below is a memo.
|
|
145
179
|
*/
|
|
146
180
|
export declare function probeHarnessVersion(kind: HarnessKind): string | null;
|
|
147
|
-
/**
|
|
181
|
+
/**
|
|
182
|
+
* The first line of `<binary> --version` as a diagnostic may print it (control
|
|
183
|
+
* characters removed, non-ASCII kept), read at most once per process. For the
|
|
184
|
+
* version floor and terminal output; never recorded.
|
|
185
|
+
*/
|
|
148
186
|
export declare function installedHarnessVersionRaw(kind: HarnessKind): string | null;
|
|
149
187
|
/**
|
|
150
188
|
* The installed version of `kind`, read at most once per process.
|
|
151
189
|
*
|
|
152
|
-
* This is the only entry point callers should use for a RECORDABLE version.
|
|
153
|
-
*
|
|
190
|
+
* This is the only entry point callers should use for a RECORDABLE version. It
|
|
191
|
+
* normalizes the untouched first line, never {@link installedHarnessVersionRaw}'s
|
|
192
|
+
* stripped one, so the recorded value follows the one rule in {@link
|
|
193
|
+
* printableAsciiPrefix} whichever path supplied it. `probeHarnessVersion` is
|
|
194
|
+
* exported for the test that proves the memo is a memo.
|
|
154
195
|
*/
|
|
155
196
|
export declare function installedHarnessVersion(kind: HarnessKind): string | null;
|
|
156
197
|
/** Drop the memo. TEST ONLY: a process reads a version once, by design. */
|