@codyswann/lisa 4.84.5 → 4.84.7
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/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +21 -4
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/hooks/block-host-name-leak.mjs +130 -40
- package/plugins/lisa/hooks/block-host-name-leak.sh +5 -0
- package/plugins/lisa/hooks/host-name-command-context.mjs +409 -0
- package/plugins/lisa-agy/hooks/block-host-name-leak.mjs +130 -40
- package/plugins/lisa-agy/hooks/block-host-name-leak.sh +5 -0
- package/plugins/lisa-agy/hooks/host-name-command-context.mjs +409 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/hooks/block-host-name-leak.mjs +130 -40
- package/plugins/lisa-copilot/hooks/block-host-name-leak.sh +5 -0
- package/plugins/lisa-copilot/hooks/host-name-command-context.mjs +409 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/block-host-name-leak.mjs +130 -40
- package/plugins/lisa-cursor/hooks/block-host-name-leak.sh +5 -0
- package/plugins/lisa-cursor/hooks/host-name-command-context.mjs +409 -0
- package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/hooks/block-host-name-leak.mjs +130 -40
- package/plugins/lisa-devin/hooks/block-host-name-leak.sh +5 -0
- package/plugins/lisa-devin/hooks/host-name-command-context.mjs +409 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/src/base/hooks/block-host-name-leak.mjs +130 -40
- package/plugins/src/base/hooks/block-host-name-leak.sh +5 -0
- package/plugins/src/base/hooks/host-name-command-context.mjs +409 -0
- package/scripts/generate-agy-plugin-artifacts.mjs +7 -3
- package/scripts/lib/host-name-expanded-command-cases.mjs +286 -0
- package/scripts/lib/host-name-field-occurrence-cases.mjs +60 -0
- package/scripts/lib/host-name-review-cases.mjs +354 -0
- package/scripts/lib/host-name-target-cases.mjs +298 -0
- package/scripts/two-channel-couplings.json +29 -6
- package/scripts/verify-host-name-target-scope.mjs +373 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
/** Direct expanded command-name regressions; all identities are synthetic. */
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { boundedExecFileSync } from "./bounded-spawn.mjs";
|
|
4
|
+
|
|
5
|
+
/** @param {object} context Isolated actual-wrapper fixtures. @returns {Array[]} Named cases. */
|
|
6
|
+
export function hostNameExpandedCommandCases(context) {
|
|
7
|
+
const { lisaCwd, unknownCwd, hostCwd, lisa, host, fixtureName, body } =
|
|
8
|
+
context;
|
|
9
|
+
const cases = [];
|
|
10
|
+
for (const [target, cwd, repo] of [
|
|
11
|
+
["protected", lisaCwd, ` --repo ${lisa}`],
|
|
12
|
+
["unknown", unknownCwd, ""],
|
|
13
|
+
]) {
|
|
14
|
+
for (const [name, noun] of [
|
|
15
|
+
["unquoted", "$N"],
|
|
16
|
+
["double quoted", '"$N"'],
|
|
17
|
+
["braced", '"${N}"'],
|
|
18
|
+
["concatenated", 'is"$SUFFIX"'],
|
|
19
|
+
]) {
|
|
20
|
+
cases.push([
|
|
21
|
+
`expanded noun ${name} ${target} write`,
|
|
22
|
+
cwd,
|
|
23
|
+
`gh ${noun} create${repo} --body '${fixtureName}'`,
|
|
24
|
+
2,
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
for (const [name, verb] of [
|
|
28
|
+
["unquoted", "$V"],
|
|
29
|
+
["double quoted", '"$V"'],
|
|
30
|
+
["braced", '"${V}"'],
|
|
31
|
+
["concatenated", 'cre"$TAIL"'],
|
|
32
|
+
]) {
|
|
33
|
+
cases.push([
|
|
34
|
+
`expanded verb ${name} ${target} write`,
|
|
35
|
+
cwd,
|
|
36
|
+
`gh issue ${verb}${repo} --body '${fixtureName}'`,
|
|
37
|
+
2,
|
|
38
|
+
]);
|
|
39
|
+
}
|
|
40
|
+
for (const [name, prefix] of [
|
|
41
|
+
["multiple-word noun", "gh $N"],
|
|
42
|
+
["multiple-word verb", "gh issue $V"],
|
|
43
|
+
["noun before read-looking word", "gh $N view"],
|
|
44
|
+
["verb before read-looking word", "gh issue $V view"],
|
|
45
|
+
]) {
|
|
46
|
+
cases.push([
|
|
47
|
+
`expanded ${name} ${target} write`,
|
|
48
|
+
cwd,
|
|
49
|
+
`${prefix}${repo} --body '${fixtureName}'`,
|
|
50
|
+
2,
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
for (const [name, args] of [
|
|
54
|
+
["API field text", `-F body=${fixtureName}`],
|
|
55
|
+
["API field file", `-F body=@${body}`],
|
|
56
|
+
["API attached field file", `-Fbody=@${body}`],
|
|
57
|
+
["API raw field", `-f body=${fixtureName}`],
|
|
58
|
+
["API input file", `--input ${body}`],
|
|
59
|
+
]) {
|
|
60
|
+
cases.push([
|
|
61
|
+
`expanded noun possible ${name} ${target} write`,
|
|
62
|
+
cwd,
|
|
63
|
+
`gh "$N" repos/${lisa}/issues ${args}`,
|
|
64
|
+
2,
|
|
65
|
+
]);
|
|
66
|
+
}
|
|
67
|
+
cases.push(
|
|
68
|
+
[
|
|
69
|
+
`expanded noun issue body-file ${target} write`,
|
|
70
|
+
cwd,
|
|
71
|
+
`gh "$N" create${repo} -F ${body}`,
|
|
72
|
+
2,
|
|
73
|
+
],
|
|
74
|
+
[
|
|
75
|
+
`expanded both command positions ${target} write`,
|
|
76
|
+
cwd,
|
|
77
|
+
`gh${repo} "$N" "$V" --body '${fixtureName}'`,
|
|
78
|
+
2,
|
|
79
|
+
]
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
cases.push(
|
|
83
|
+
[
|
|
84
|
+
"expanded PR verb protected body-file write",
|
|
85
|
+
lisaCwd,
|
|
86
|
+
`gh pr "$V" --repo ${lisa} --body-file ${body}`,
|
|
87
|
+
2,
|
|
88
|
+
],
|
|
89
|
+
[
|
|
90
|
+
"expanded PR verb unknown body-file write",
|
|
91
|
+
unknownCwd,
|
|
92
|
+
`gh pr "$V" --body-file ${body}`,
|
|
93
|
+
2,
|
|
94
|
+
],
|
|
95
|
+
[
|
|
96
|
+
"expanded noun literal host flag cannot certify target",
|
|
97
|
+
hostCwd,
|
|
98
|
+
`gh "$N" create --repo ${host} --body '${fixtureName}'`,
|
|
99
|
+
2,
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
"expanded-name API GET prose with dynamic filter control",
|
|
103
|
+
lisaCwd,
|
|
104
|
+
`gh api repos/${lisa}/issues -X GET -F body=${fixtureName} -q "$FILTER"`,
|
|
105
|
+
0,
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
"expanded-name API GET input with dynamic filter control",
|
|
109
|
+
lisaCwd,
|
|
110
|
+
`gh api repos/${lisa}/issues -X GET --input ${body} -q "$FILTER"`,
|
|
111
|
+
0,
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
"expanded-name literal host control",
|
|
115
|
+
hostCwd,
|
|
116
|
+
`gh issue create --repo ${host} --body '${fixtureName}'`,
|
|
117
|
+
0,
|
|
118
|
+
],
|
|
119
|
+
[
|
|
120
|
+
"expanded-name literal protected control",
|
|
121
|
+
lisaCwd,
|
|
122
|
+
`gh issue create --repo ${lisa} --body '${fixtureName}'`,
|
|
123
|
+
2,
|
|
124
|
+
],
|
|
125
|
+
[
|
|
126
|
+
"expanded-name literal unknown control",
|
|
127
|
+
unknownCwd,
|
|
128
|
+
`gh issue create --body '${fixtureName}'`,
|
|
129
|
+
2,
|
|
130
|
+
],
|
|
131
|
+
[
|
|
132
|
+
"expanded-name dynamic read filter control",
|
|
133
|
+
lisaCwd,
|
|
134
|
+
`gh issue list --repo ${lisa} --json title --jq "$FILTER"`,
|
|
135
|
+
0,
|
|
136
|
+
],
|
|
137
|
+
[
|
|
138
|
+
"expanded-name dynamic read selector control",
|
|
139
|
+
lisaCwd,
|
|
140
|
+
`gh issue view "$NUMBER" --repo ${lisa} --json title --jq '${fixtureName}'`,
|
|
141
|
+
0,
|
|
142
|
+
],
|
|
143
|
+
[
|
|
144
|
+
"expanded-name API GET dynamic filter control",
|
|
145
|
+
lisaCwd,
|
|
146
|
+
`gh api repos/${lisa}/issues -X GET -q "$FILTER"`,
|
|
147
|
+
0,
|
|
148
|
+
],
|
|
149
|
+
[
|
|
150
|
+
"expanded-name single-quoted noun control",
|
|
151
|
+
lisaCwd,
|
|
152
|
+
`gh '$N' create --repo ${lisa} --body '${fixtureName}'`,
|
|
153
|
+
0,
|
|
154
|
+
],
|
|
155
|
+
[
|
|
156
|
+
"expanded-name single-quoted verb control",
|
|
157
|
+
lisaCwd,
|
|
158
|
+
`gh issue '$V' --repo ${lisa} --body '${fixtureName}'`,
|
|
159
|
+
0,
|
|
160
|
+
],
|
|
161
|
+
[
|
|
162
|
+
"expanded-name escaped noun control",
|
|
163
|
+
lisaCwd,
|
|
164
|
+
`gh \\$N create --repo ${lisa} --body '${fixtureName}'`,
|
|
165
|
+
0,
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
"expanded-name quoted non-command control",
|
|
169
|
+
lisaCwd,
|
|
170
|
+
`printf '%s' 'gh $N create --repo ${lisa} --body ${fixtureName}'`,
|
|
171
|
+
0,
|
|
172
|
+
],
|
|
173
|
+
[
|
|
174
|
+
"expanded-name clean prose control",
|
|
175
|
+
lisaCwd,
|
|
176
|
+
`gh "$N" create --repo ${lisa} --body 'A clean report.'`,
|
|
177
|
+
0,
|
|
178
|
+
],
|
|
179
|
+
[
|
|
180
|
+
"expanded-name options before noun preserve prose boundaries",
|
|
181
|
+
lisaCwd,
|
|
182
|
+
`gh --repo ${lisa} --title 'view list' "$N" create --body '${fixtureName}'`,
|
|
183
|
+
2,
|
|
184
|
+
],
|
|
185
|
+
[
|
|
186
|
+
"expanded-name literal host API control",
|
|
187
|
+
hostCwd,
|
|
188
|
+
`gh api repos/${host}/issues -F body=${fixtureName}`,
|
|
189
|
+
0,
|
|
190
|
+
]
|
|
191
|
+
);
|
|
192
|
+
return cases;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Establish expansion premises with a Bash function that only prints argv.
|
|
197
|
+
* @param {object} context Synthetic fixtures.
|
|
198
|
+
* @param {object} env Isolated child environment.
|
|
199
|
+
* @returns {void}
|
|
200
|
+
*/
|
|
201
|
+
export function verifyExpandedCommandArgv(context, env) {
|
|
202
|
+
const { lisaCwd, lisa, fixtureName, body } = context;
|
|
203
|
+
const suffix = ` --repo ${lisa} --body '${fixtureName}'`;
|
|
204
|
+
for (const [name, command, values, expected] of [
|
|
205
|
+
[
|
|
206
|
+
"unquoted noun",
|
|
207
|
+
`gh $N create${suffix}`,
|
|
208
|
+
{ N: "issue" },
|
|
209
|
+
["issue", "create", "--repo", lisa, "--body", fixtureName],
|
|
210
|
+
],
|
|
211
|
+
[
|
|
212
|
+
"quoted braced noun",
|
|
213
|
+
`gh "${"${N}"}" create${suffix}`,
|
|
214
|
+
{ N: "issue" },
|
|
215
|
+
["issue", "create", "--repo", lisa, "--body", fixtureName],
|
|
216
|
+
],
|
|
217
|
+
[
|
|
218
|
+
"concatenated noun",
|
|
219
|
+
`gh is"$SUFFIX" create${suffix}`,
|
|
220
|
+
{ SUFFIX: "sue" },
|
|
221
|
+
["issue", "create", "--repo", lisa, "--body", fixtureName],
|
|
222
|
+
],
|
|
223
|
+
[
|
|
224
|
+
"concatenated verb",
|
|
225
|
+
`gh issue cre"$TAIL"${suffix}`,
|
|
226
|
+
{ TAIL: "ate" },
|
|
227
|
+
["issue", "create", "--repo", lisa, "--body", fixtureName],
|
|
228
|
+
],
|
|
229
|
+
[
|
|
230
|
+
"multiword noun before read-looking word",
|
|
231
|
+
`gh $N view${suffix}`,
|
|
232
|
+
{ N: "issue create --title" },
|
|
233
|
+
[
|
|
234
|
+
"issue",
|
|
235
|
+
"create",
|
|
236
|
+
"--title",
|
|
237
|
+
"view",
|
|
238
|
+
"--repo",
|
|
239
|
+
lisa,
|
|
240
|
+
"--body",
|
|
241
|
+
fixtureName,
|
|
242
|
+
],
|
|
243
|
+
],
|
|
244
|
+
[
|
|
245
|
+
"multiword verb before read-looking word",
|
|
246
|
+
`gh issue $V view${suffix}`,
|
|
247
|
+
{ V: "create --title" },
|
|
248
|
+
[
|
|
249
|
+
"issue",
|
|
250
|
+
"create",
|
|
251
|
+
"--title",
|
|
252
|
+
"view",
|
|
253
|
+
"--repo",
|
|
254
|
+
lisa,
|
|
255
|
+
"--body",
|
|
256
|
+
fixtureName,
|
|
257
|
+
],
|
|
258
|
+
],
|
|
259
|
+
[
|
|
260
|
+
"possible API field file",
|
|
261
|
+
`gh "$N" repos/${lisa}/issues -F body=@${body}`,
|
|
262
|
+
{ N: "api" },
|
|
263
|
+
["api", `repos/${lisa}/issues`, "-F", `body=@${body}`],
|
|
264
|
+
],
|
|
265
|
+
]) {
|
|
266
|
+
const argv = boundedExecFileSync(
|
|
267
|
+
"/bin/bash",
|
|
268
|
+
["-c", `gh() { printf '%s\\0' "$@"; }; ${command}`],
|
|
269
|
+
{ cwd: lisaCwd, env: { ...env, ...values }, encoding: "utf8" }
|
|
270
|
+
)
|
|
271
|
+
.split("\0")
|
|
272
|
+
.slice(0, -1);
|
|
273
|
+
assert.deepEqual(argv, expected, name);
|
|
274
|
+
console.log(
|
|
275
|
+
JSON.stringify({
|
|
276
|
+
localExpandedArgvControl: {
|
|
277
|
+
name,
|
|
278
|
+
command,
|
|
279
|
+
argv,
|
|
280
|
+
inspectedTrackerWriteExecuted: false,
|
|
281
|
+
ghImplementation: "Bash argv-only printer",
|
|
282
|
+
},
|
|
283
|
+
})
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Repeated typed API fields must not hide an earlier unresolved prose file. */
|
|
2
|
+
export function hostNameFieldOccurrenceCases({ lisaCwd, lisa, relative }) {
|
|
3
|
+
const prefix = 'cd "$D" && gh',
|
|
4
|
+
endpoint = `repos/${lisa}/issues`,
|
|
5
|
+
clean = `${lisaCwd}/body.md`,
|
|
6
|
+
refusal = "BLOCKED: the working directory";
|
|
7
|
+
const unknown = (name, command) => [name, lisaCwd, command, 2, {}, refusal];
|
|
8
|
+
return [
|
|
9
|
+
unknown(
|
|
10
|
+
"expanded repeated field retains earlier relative prose file",
|
|
11
|
+
`${prefix} "$N" ${endpoint} --field body=@body.md --field title=clean`
|
|
12
|
+
),
|
|
13
|
+
unknown(
|
|
14
|
+
"literal API repeated field retains earlier relative prose file",
|
|
15
|
+
`${prefix} api ${endpoint} --field body=@body.md --field title=clean`
|
|
16
|
+
),
|
|
17
|
+
unknown(
|
|
18
|
+
"literal API repeated F before absolute clean field retains relative file",
|
|
19
|
+
`${prefix} api ${endpoint} -F body=@body.md -F title=@${clean}`
|
|
20
|
+
),
|
|
21
|
+
unknown(
|
|
22
|
+
"expanded repeated F union retains unresolved file control",
|
|
23
|
+
`${prefix} "$N" ${endpoint} -F body=@body.md -F title=@${clean}`
|
|
24
|
+
),
|
|
25
|
+
unknown(
|
|
26
|
+
"expanded repeated field body-last control",
|
|
27
|
+
`${prefix} "$N" ${endpoint} --field title=clean --field body=@body.md`
|
|
28
|
+
),
|
|
29
|
+
[
|
|
30
|
+
"literal API repeated fields known cwd reads original prose file",
|
|
31
|
+
lisaCwd,
|
|
32
|
+
`cd '${relative}' && gh api ${endpoint} --field body=@body.md --field title=clean`,
|
|
33
|
+
2,
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
"literal API repeated fields GET remains read-only",
|
|
37
|
+
lisaCwd,
|
|
38
|
+
`${prefix} api ${endpoint} -X GET --field body=@body.md --field title=clean -q "$FILTER"`,
|
|
39
|
+
0,
|
|
40
|
+
],
|
|
41
|
+
[
|
|
42
|
+
"nonadditive body-file last value remains authoritative",
|
|
43
|
+
lisaCwd,
|
|
44
|
+
`${prefix} issue create --repo ${lisa} --body-file missing.md --body-file ${clean}`,
|
|
45
|
+
0,
|
|
46
|
+
],
|
|
47
|
+
unknown(
|
|
48
|
+
"expanded mixed field aliases retain earlier relative file control",
|
|
49
|
+
`${prefix} "$N" ${endpoint} --field body=@body.md -F title=@${clean}`
|
|
50
|
+
),
|
|
51
|
+
unknown(
|
|
52
|
+
"expanded repeated equal field retains earlier relative file",
|
|
53
|
+
`${prefix} "$N" ${endpoint} --field=body=@body.md --field=title=clean`
|
|
54
|
+
),
|
|
55
|
+
unknown(
|
|
56
|
+
"literal API repeated attached F retains earlier relative file",
|
|
57
|
+
`${prefix} api ${endpoint} -Fbody=@body.md -Ftitle=@${clean}`
|
|
58
|
+
),
|
|
59
|
+
];
|
|
60
|
+
}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/** Actual-wrapper regressions for independently reproduced target/context findings. */
|
|
2
|
+
export function hostNameReviewCases({
|
|
3
|
+
hostCwd,
|
|
4
|
+
lisaCwd,
|
|
5
|
+
unknownCwd,
|
|
6
|
+
body,
|
|
7
|
+
cdStart,
|
|
8
|
+
cdSearch,
|
|
9
|
+
cdHost,
|
|
10
|
+
fixtureName,
|
|
11
|
+
lisa,
|
|
12
|
+
host,
|
|
13
|
+
}) {
|
|
14
|
+
const continuation = "\\\n";
|
|
15
|
+
const cases = [
|
|
16
|
+
[
|
|
17
|
+
"continuation before the noun retains protected inspection",
|
|
18
|
+
hostCwd,
|
|
19
|
+
`gh ${continuation} issue create --repo ${lisa} --body ${fixtureName}`,
|
|
20
|
+
2,
|
|
21
|
+
],
|
|
22
|
+
[
|
|
23
|
+
"continuation between noun and verb retains protected inspection",
|
|
24
|
+
hostCwd,
|
|
25
|
+
`gh issue ${continuation} create --repo ${lisa} --body ${fixtureName}`,
|
|
26
|
+
2,
|
|
27
|
+
],
|
|
28
|
+
[
|
|
29
|
+
"continuation before body text retains protected inspection",
|
|
30
|
+
hostCwd,
|
|
31
|
+
`gh issue create --repo ${lisa} --body ${continuation} ${fixtureName}`,
|
|
32
|
+
2,
|
|
33
|
+
],
|
|
34
|
+
[
|
|
35
|
+
"continuation before a host API endpoint preserves exemption",
|
|
36
|
+
lisaCwd,
|
|
37
|
+
`gh api ${continuation} repos/${host}/issues -f body=${fixtureName}`,
|
|
38
|
+
0,
|
|
39
|
+
],
|
|
40
|
+
[
|
|
41
|
+
"continuation before a protected API endpoint retains inspection",
|
|
42
|
+
hostCwd,
|
|
43
|
+
`gh api ${continuation} repos/${lisa}/issues -f body=${fixtureName}`,
|
|
44
|
+
2,
|
|
45
|
+
],
|
|
46
|
+
[
|
|
47
|
+
"continuation before explicit host repository preserves exemption",
|
|
48
|
+
lisaCwd,
|
|
49
|
+
`gh issue create --repo ${continuation} ${host} --body ${fixtureName}`,
|
|
50
|
+
0,
|
|
51
|
+
],
|
|
52
|
+
[
|
|
53
|
+
"continuation before explicit protected repository retains inspection",
|
|
54
|
+
hostCwd,
|
|
55
|
+
`gh issue create --repo ${continuation} ${lisa} --body ${fixtureName}`,
|
|
56
|
+
2,
|
|
57
|
+
],
|
|
58
|
+
[
|
|
59
|
+
"continuation between noun and verb keeps unknown target guarded",
|
|
60
|
+
unknownCwd,
|
|
61
|
+
`gh issue ${continuation} create --body ${fixtureName}`,
|
|
62
|
+
2,
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
"continuation between noun and verb keeps known host allowed",
|
|
66
|
+
hostCwd,
|
|
67
|
+
`gh issue ${continuation} create --repo ${host} --body ${fixtureName}`,
|
|
68
|
+
0,
|
|
69
|
+
],
|
|
70
|
+
[
|
|
71
|
+
"continuation before an API field value retains protected inspection",
|
|
72
|
+
hostCwd,
|
|
73
|
+
`gh api repos/${lisa}/issues -f ${continuation} body=${fixtureName}`,
|
|
74
|
+
2,
|
|
75
|
+
],
|
|
76
|
+
[
|
|
77
|
+
"continuation within an existing verb preserves the word",
|
|
78
|
+
hostCwd,
|
|
79
|
+
`gh issue cre${continuation}ate --repo ${lisa} --body ${fixtureName}`,
|
|
80
|
+
2,
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
"double quoted continuation preserves existing body text",
|
|
84
|
+
hostCwd,
|
|
85
|
+
`gh issue create --repo ${lisa} --body "${fixtureName.slice(0, 8)}${continuation}${fixtureName.slice(8)}"`,
|
|
86
|
+
2,
|
|
87
|
+
],
|
|
88
|
+
[
|
|
89
|
+
"a real quoted empty verb stays distinct from continuation whitespace",
|
|
90
|
+
hostCwd,
|
|
91
|
+
`gh issue "" create --repo ${lisa} --body ${fixtureName}`,
|
|
92
|
+
0,
|
|
93
|
+
],
|
|
94
|
+
[
|
|
95
|
+
"continuation after a quoted empty body preserves the empty value",
|
|
96
|
+
hostCwd,
|
|
97
|
+
`gh issue create --repo ${lisa} --body ""${continuation} ${fixtureName}`,
|
|
98
|
+
0,
|
|
99
|
+
],
|
|
100
|
+
[
|
|
101
|
+
"continuation preserves nonliteral argument uncertainty",
|
|
102
|
+
hostCwd,
|
|
103
|
+
`gh issue create --repo ${host} --title "$TITLE${continuation}" --body ${fixtureName}`,
|
|
104
|
+
2,
|
|
105
|
+
{ TITLE: "Unresolved title" },
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
"CDPATH inherited lookup cannot certify a host target",
|
|
109
|
+
cdStart,
|
|
110
|
+
`cd target && gh issue create --body ${fixtureName}`,
|
|
111
|
+
2,
|
|
112
|
+
{ CDPATH: cdSearch },
|
|
113
|
+
],
|
|
114
|
+
[
|
|
115
|
+
"CDPATH export lookup cannot certify a host target",
|
|
116
|
+
cdStart,
|
|
117
|
+
`export CDPATH='${cdSearch}'; cd target && gh issue create --body ${fixtureName}`,
|
|
118
|
+
2,
|
|
119
|
+
],
|
|
120
|
+
[
|
|
121
|
+
"CDPATH command assignment cannot certify a host target",
|
|
122
|
+
cdStart,
|
|
123
|
+
`CDPATH='${cdSearch}' cd target && gh issue create --body ${fixtureName}`,
|
|
124
|
+
2,
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
"CDPATH standalone assignment cannot certify a host target",
|
|
128
|
+
cdStart,
|
|
129
|
+
`CDPATH='${cdSearch}'; cd target && gh issue create --body ${fixtureName}`,
|
|
130
|
+
2,
|
|
131
|
+
],
|
|
132
|
+
[
|
|
133
|
+
"CDPATH relative body must not be read from the wrong directory",
|
|
134
|
+
cdStart,
|
|
135
|
+
`cd target && gh issue create --repo ${lisa} --body-file body.md`,
|
|
136
|
+
2,
|
|
137
|
+
{ CDPATH: cdSearch },
|
|
138
|
+
"BLOCKED: the working directory",
|
|
139
|
+
],
|
|
140
|
+
[
|
|
141
|
+
"uncertain CDPATH export cannot certify relative body location",
|
|
142
|
+
cdStart,
|
|
143
|
+
`export CDPATH="$SEARCH_PATH"; cd target && gh issue create --repo ${lisa} --body-file body.md`,
|
|
144
|
+
2,
|
|
145
|
+
{ SEARCH_PATH: cdSearch },
|
|
146
|
+
"BLOCKED: the working directory",
|
|
147
|
+
],
|
|
148
|
+
[
|
|
149
|
+
"dot relative cd bypasses CDPATH lookup",
|
|
150
|
+
cdStart,
|
|
151
|
+
`cd ./target && gh issue create --body ${fixtureName}`,
|
|
152
|
+
0,
|
|
153
|
+
{ CDPATH: cdSearch },
|
|
154
|
+
],
|
|
155
|
+
[
|
|
156
|
+
"parent relative cd bypasses CDPATH lookup",
|
|
157
|
+
cdHost,
|
|
158
|
+
`cd ../target && gh issue create --body ${fixtureName}`,
|
|
159
|
+
0,
|
|
160
|
+
{ CDPATH: cdSearch },
|
|
161
|
+
],
|
|
162
|
+
[
|
|
163
|
+
"absolute cd bypasses CDPATH lookup",
|
|
164
|
+
cdStart,
|
|
165
|
+
`cd '${cdHost}' && gh issue create --body ${fixtureName}`,
|
|
166
|
+
0,
|
|
167
|
+
{ CDPATH: cdSearch },
|
|
168
|
+
],
|
|
169
|
+
[
|
|
170
|
+
"empty CDPATH preserves literal relative cd",
|
|
171
|
+
cdStart,
|
|
172
|
+
`cd target && gh issue create --body ${fixtureName}`,
|
|
173
|
+
0,
|
|
174
|
+
],
|
|
175
|
+
[
|
|
176
|
+
"unquoted argv expansion cannot add an unseen winning repo",
|
|
177
|
+
hostCwd,
|
|
178
|
+
`gh issue comment 1 --repo ${host} $ROUTING --body ${fixtureName}`,
|
|
179
|
+
2,
|
|
180
|
+
{ ROUTING: `--repo ${lisa}` },
|
|
181
|
+
],
|
|
182
|
+
[
|
|
183
|
+
"nonliteral consumed option value cannot earn target exemption",
|
|
184
|
+
hostCwd,
|
|
185
|
+
`gh issue create --repo ${host} --title "$TITLE" --body ${fixtureName}`,
|
|
186
|
+
2,
|
|
187
|
+
{ TITLE: "Unresolved title" },
|
|
188
|
+
],
|
|
189
|
+
[
|
|
190
|
+
"literal numeric selector keeps explicit host target",
|
|
191
|
+
lisaCwd,
|
|
192
|
+
`gh issue comment 1 --repo ${host} --body ${fixtureName}`,
|
|
193
|
+
0,
|
|
194
|
+
],
|
|
195
|
+
[
|
|
196
|
+
"standalone unexported repository assignment cannot certify a target",
|
|
197
|
+
lisaCwd,
|
|
198
|
+
`GH_REPO=${host}; gh issue create --body ${fixtureName}`,
|
|
199
|
+
2,
|
|
200
|
+
],
|
|
201
|
+
[
|
|
202
|
+
"API input alone defaults to inspected POST",
|
|
203
|
+
hostCwd,
|
|
204
|
+
`gh api repos/${lisa}/issues --input '${body}'`,
|
|
205
|
+
2,
|
|
206
|
+
],
|
|
207
|
+
[
|
|
208
|
+
"API input explicit POST remains inspected",
|
|
209
|
+
hostCwd,
|
|
210
|
+
`gh api repos/${lisa}/issues --method POST --input '${body}'`,
|
|
211
|
+
2,
|
|
212
|
+
],
|
|
213
|
+
[
|
|
214
|
+
"API input explicit GET remains read only",
|
|
215
|
+
hostCwd,
|
|
216
|
+
`gh api repos/${lisa}/issues --method GET --input '${body}'`,
|
|
217
|
+
0,
|
|
218
|
+
],
|
|
219
|
+
[
|
|
220
|
+
"API input to verified host remains allowed",
|
|
221
|
+
lisaCwd,
|
|
222
|
+
`gh api repos/${host}/issues --input '${body}'`,
|
|
223
|
+
0,
|
|
224
|
+
],
|
|
225
|
+
[
|
|
226
|
+
"mixed host and Lisa issue URLs retain protection",
|
|
227
|
+
hostCwd,
|
|
228
|
+
`gh issue edit https://github.com/${host}/issues/1 https://github.com/${lisa}/issues/2 --body ${fixtureName}`,
|
|
229
|
+
2,
|
|
230
|
+
],
|
|
231
|
+
[
|
|
232
|
+
"host URL and numeric selectors select the common host",
|
|
233
|
+
hostCwd,
|
|
234
|
+
`gh issue edit https://github.com/${host}/issues/1 2 --body ${fixtureName}`,
|
|
235
|
+
0,
|
|
236
|
+
],
|
|
237
|
+
[
|
|
238
|
+
"same-host URL selectors select the common host",
|
|
239
|
+
hostCwd,
|
|
240
|
+
`gh issue edit https://github.com/${host}/issues/1 https://github.com/${host}/issues/2 --body ${fixtureName}`,
|
|
241
|
+
0,
|
|
242
|
+
],
|
|
243
|
+
[
|
|
244
|
+
"host URL batch outranks conflicting Lisa repo flag",
|
|
245
|
+
lisaCwd,
|
|
246
|
+
`gh issue edit https://github.com/${host}/issues/1 https://github.com/${host}/issues/2 --repo ${lisa} --body ${fixtureName}`,
|
|
247
|
+
0,
|
|
248
|
+
],
|
|
249
|
+
[
|
|
250
|
+
"host URL with numeric selector outranks Lisa repo flag",
|
|
251
|
+
lisaCwd,
|
|
252
|
+
`gh issue edit https://github.com/${host}/issues/1 2 --repo ${lisa} --body ${fixtureName}`,
|
|
253
|
+
0,
|
|
254
|
+
],
|
|
255
|
+
[
|
|
256
|
+
"numeric selector before host URL inherits the URL repository",
|
|
257
|
+
lisaCwd,
|
|
258
|
+
`gh issue edit 2 https://github.com/${host}/issues/1 --repo ${lisa} --body ${fixtureName}`,
|
|
259
|
+
0,
|
|
260
|
+
],
|
|
261
|
+
[
|
|
262
|
+
"protected URL batch outranks conflicting host repo flag",
|
|
263
|
+
hostCwd,
|
|
264
|
+
`gh issue edit https://github.com/${lisa}/issues/1 https://github.com/${lisa}/issues/2 --repo ${host} --body ${fixtureName}`,
|
|
265
|
+
2,
|
|
266
|
+
],
|
|
267
|
+
[
|
|
268
|
+
"protected URL with numeric selector outranks host repo flag",
|
|
269
|
+
hostCwd,
|
|
270
|
+
`gh issue edit https://github.com/${lisa}/issues/1 '#2' --repo ${host} --body ${fixtureName}`,
|
|
271
|
+
2,
|
|
272
|
+
],
|
|
273
|
+
[
|
|
274
|
+
"numeric-only issue batch retains explicit host fallback",
|
|
275
|
+
lisaCwd,
|
|
276
|
+
`gh issue edit 1 2 --repo ${host} --body ${fixtureName}`,
|
|
277
|
+
0,
|
|
278
|
+
],
|
|
279
|
+
[
|
|
280
|
+
"numeric-only issue batch retains protected fallback",
|
|
281
|
+
hostCwd,
|
|
282
|
+
`gh issue edit 1 2 --repo ${lisa} --body ${fixtureName}`,
|
|
283
|
+
2,
|
|
284
|
+
],
|
|
285
|
+
[
|
|
286
|
+
"same owner and repository on different URL hosts stay unknown",
|
|
287
|
+
hostCwd,
|
|
288
|
+
`gh issue edit https://github.com/${host}/issues/1 https://other.example/${host}/issues/2 --body ${fixtureName}`,
|
|
289
|
+
2,
|
|
290
|
+
],
|
|
291
|
+
[
|
|
292
|
+
"issue URL repository suffixes remain distinct batch identities",
|
|
293
|
+
hostCwd,
|
|
294
|
+
`gh issue edit https://github.com/${host}/issues/1 https://github.com/${host}.git/issues/2 --body ${fixtureName}`,
|
|
295
|
+
2,
|
|
296
|
+
],
|
|
297
|
+
[
|
|
298
|
+
"invalid selector cannot inherit a host URL repository",
|
|
299
|
+
hostCwd,
|
|
300
|
+
`gh issue edit https://github.com/${host}/issues/1 not-an-issue --body ${fixtureName}`,
|
|
301
|
+
2,
|
|
302
|
+
],
|
|
303
|
+
[
|
|
304
|
+
"nonliteral batch selector cannot inherit a host URL repository",
|
|
305
|
+
hostCwd,
|
|
306
|
+
`gh issue edit https://github.com/${host}/issues/1 $ISSUE_NUMBERS --body ${fixtureName}`,
|
|
307
|
+
2,
|
|
308
|
+
{ ISSUE_NUMBERS: "2" },
|
|
309
|
+
],
|
|
310
|
+
[
|
|
311
|
+
"issue comment retains single-selector boundary",
|
|
312
|
+
hostCwd,
|
|
313
|
+
`gh issue comment https://github.com/${host}/issues/1 https://github.com/${host}/issues/2 --body ${fixtureName}`,
|
|
314
|
+
2,
|
|
315
|
+
],
|
|
316
|
+
[
|
|
317
|
+
"PR edit retains single-selector boundary",
|
|
318
|
+
hostCwd,
|
|
319
|
+
`gh pr edit https://github.com/${host}/pull/1 https://github.com/${host}/pull/2 --body ${fixtureName}`,
|
|
320
|
+
2,
|
|
321
|
+
],
|
|
322
|
+
[
|
|
323
|
+
"unanimous host URL batch compares repository case insensitively",
|
|
324
|
+
lisaCwd,
|
|
325
|
+
`gh issue edit https://github.com/${host}/issues/1 https://github.com/${host.toUpperCase()}/issues/2 --repo ${lisa} --body ${fixtureName}`,
|
|
326
|
+
0,
|
|
327
|
+
],
|
|
328
|
+
];
|
|
329
|
+
for (const noun of ["issue", "pr"])
|
|
330
|
+
for (const verb of ["comment", "edit"]) {
|
|
331
|
+
const kind = noun === "issue" ? "issues" : "pull";
|
|
332
|
+
cases.push(
|
|
333
|
+
[
|
|
334
|
+
`${noun} ${verb} positional Lisa URL outranks host origin`,
|
|
335
|
+
hostCwd,
|
|
336
|
+
`gh ${noun} ${verb} https://github.com/${lisa}/${kind}/1 --body ${fixtureName}`,
|
|
337
|
+
2,
|
|
338
|
+
],
|
|
339
|
+
[
|
|
340
|
+
`${noun} ${verb} positional Lisa URL outranks host repo flag`,
|
|
341
|
+
hostCwd,
|
|
342
|
+
`gh ${noun} ${verb} https://github.com/${lisa}/${kind}/1 --repo ${host} --body ${fixtureName}`,
|
|
343
|
+
2,
|
|
344
|
+
],
|
|
345
|
+
[
|
|
346
|
+
`${noun} ${verb} positional host URL outranks Lisa repo flag`,
|
|
347
|
+
lisaCwd,
|
|
348
|
+
`gh ${noun} ${verb} https://github.com/${host}/${kind}/1 --repo ${lisa} --body ${fixtureName}`,
|
|
349
|
+
0,
|
|
350
|
+
]
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
return cases;
|
|
354
|
+
}
|