@deftai/directive-core 0.105.0 → 0.107.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/dist/authz/classify.js +591 -34
- package/dist/check/gate-lists.js +2 -0
- package/dist/check/named-cause.js +1 -1
- package/dist/design-critique/exclusive-chip.d.ts +33 -0
- package/dist/design-critique/exclusive-chip.js +68 -0
- package/dist/design-critique/parent-audit.d.ts +59 -0
- package/dist/design-critique/parent-audit.js +121 -0
- package/dist/doctor/checks.d.ts +6 -0
- package/dist/doctor/checks.js +35 -0
- package/dist/forward-coverage/diff-coverage.d.ts +39 -0
- package/dist/forward-coverage/diff-coverage.js +112 -0
- package/dist/forward-coverage/diff-lines.d.ts +19 -0
- package/dist/forward-coverage/diff-lines.js +173 -0
- package/dist/forward-coverage/evaluate.d.ts +24 -9
- package/dist/forward-coverage/evaluate.js +125 -19
- package/dist/hooks/dest-form.d.ts +46 -0
- package/dist/hooks/dest-form.js +575 -0
- package/dist/hooks/dispatcher.d.ts +17 -1
- package/dist/hooks/dispatcher.js +82 -11
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/init-deposit/agent-hooks.d.ts +1 -1
- package/dist/init-deposit/agent-hooks.js +1 -1
- package/dist/intake/clause-derivation.d.ts +9 -0
- package/dist/intake/clause-derivation.js +30 -3
- package/dist/intake/github-auth-modes-cli.js +14 -2
- package/dist/intake/github-auth-modes.d.ts +54 -9
- package/dist/intake/github-auth-modes.js +326 -123
- package/dist/lifecycle/completed-tracked-on-delivery.d.ts +26 -0
- package/dist/lifecycle/completed-tracked-on-delivery.js +37 -14
- package/dist/lifecycle/completed-write-guard.d.ts +48 -0
- package/dist/lifecycle/completed-write-guard.js +373 -0
- package/dist/lifecycle/index.d.ts +1 -0
- package/dist/lifecycle/index.js +1 -0
- package/dist/lifecycle-visible/evaluate.d.ts +98 -0
- package/dist/lifecycle-visible/evaluate.js +710 -0
- package/dist/lifecycle-visible/index.d.ts +2 -0
- package/dist/lifecycle-visible/index.js +2 -0
- package/dist/literal-acceptance/capture.d.ts +16 -0
- package/dist/literal-acceptance/capture.js +78 -10
- package/dist/literal-acceptance/evaluate.js +25 -3
- package/dist/literal-acceptance/index.d.ts +2 -2
- package/dist/literal-acceptance/index.js +2 -2
- package/dist/literal-acceptance/run.js +9 -3
- package/dist/literal-acceptance/types.d.ts +6 -0
- package/dist/literal-acceptance/types.js +6 -0
- package/dist/orchestration/judgment-policy.d.ts +13 -0
- package/dist/orchestration/judgment-policy.js +15 -0
- package/dist/orchestration/probe-session.js +13 -8
- package/dist/orchestration/verify-judgment-gates.d.ts +4 -0
- package/dist/orchestration/verify-judgment-gates.js +43 -11
- package/dist/policy/ceremony-dial.js +7 -7
- package/dist/policy/host-hooks.d.ts +20 -0
- package/dist/policy/host-hooks.js +121 -2
- package/dist/policy/org-force-on-migration.js +2 -1
- package/dist/policy/plan-extensions.d.ts +1 -1
- package/dist/policy/plan-extensions.js +2 -0
- package/dist/policy/product-signal.js +6 -7
- package/dist/policy/require-human-merge.js +8 -6
- package/dist/policy/resolve.d.ts +7 -2
- package/dist/policy/resolve.js +25 -8
- package/dist/policy/runtime-authority.d.ts +18 -0
- package/dist/policy/runtime-authority.js +11 -0
- package/dist/policy/value-feedback.js +7 -8
- package/dist/policy/write-fence.js +3 -0
- package/dist/preflight-cache/evaluate.d.ts +12 -0
- package/dist/preflight-cache/evaluate.js +24 -4
- package/dist/preflight-cache/index.d.ts +1 -1
- package/dist/preflight-cache/index.js +1 -1
- package/dist/product-first-done-gate/evaluate.d.ts +4 -0
- package/dist/product-first-done-gate/evaluate.js +82 -10
- package/dist/release/closed-verb-gate.d.ts +12 -0
- package/dist/release/closed-verb-gate.js +51 -0
- package/dist/release/index.d.ts +1 -0
- package/dist/release/index.js +1 -0
- package/dist/release/pipeline.js +7 -0
- package/dist/release/types.d.ts +12 -0
- package/dist/render/constants.d.ts +2 -1
- package/dist/render/constants.js +2 -1
- package/dist/render/framework-commands.js +4 -0
- package/dist/render/spec-validate.js +23 -12
- package/dist/run-summary/types.d.ts +4 -0
- package/dist/scm/design-critique-chip.d.ts +37 -0
- package/dist/scm/design-critique-chip.js +171 -0
- package/dist/scm/index.d.ts +1 -0
- package/dist/scm/index.js +1 -0
- package/dist/scm/main.d.ts +3 -0
- package/dist/scm/main.js +15 -1
- package/dist/scm/readiness-cli.d.ts +2 -0
- package/dist/scm/readiness-cli.js +42 -1
- package/dist/scm/readiness.d.ts +2 -1
- package/dist/scm/readiness.js +7 -1
- package/dist/scope/decompose.js +2 -1
- package/dist/scope/delivery-evidence.d.ts +27 -1
- package/dist/scope/index.d.ts +1 -0
- package/dist/scope/index.js +1 -0
- package/dist/scope/lifecycle-write.d.ts +24 -0
- package/dist/scope/lifecycle-write.js +64 -0
- package/dist/scope/main.js +18 -6
- package/dist/scope/promote-from-issue.js +5 -5
- package/dist/scope/transition.js +90 -11
- package/dist/scope-provenance/evaluate.js +8 -4
- package/dist/session/ac-pass-banking.d.ts +5 -0
- package/dist/session/ac-pass-banking.js +3 -2
- package/dist/session/git.d.ts +18 -0
- package/dist/session/git.js +81 -1
- package/dist/session/occupancy.d.ts +2 -1
- package/dist/session/occupancy.js +11 -4
- package/dist/session/process-cost.d.ts +32 -10
- package/dist/session/process-cost.js +189 -1
- package/dist/session/product-state-hash.js +41 -24
- package/dist/session/ritual-entrypoint.js +16 -1
- package/dist/session/session-start.d.ts +18 -0
- package/dist/session/session-start.js +49 -2
- package/dist/session/verify-session-ritual.d.ts +46 -4
- package/dist/session/verify-session-ritual.js +118 -10
- package/dist/swarm/finalize-cohort-cli.d.ts +7 -2
- package/dist/swarm/finalize-cohort-cli.js +165 -35
- package/dist/swarm/finalize-cohort.d.ts +1 -0
- package/dist/swarm/finalize-cohort.js +14 -2
- package/dist/swarm/launch.d.ts +69 -0
- package/dist/swarm/launch.js +191 -1
- package/dist/swarm/routing-set-cli.js +2 -0
- package/dist/swarm/routing-verify.d.ts +1 -1
- package/dist/swarm/routing-verify.js +2 -2
- package/dist/triage/actions/index.d.ts +4 -0
- package/dist/triage/actions/index.js +6 -0
- package/dist/triage/bootstrap/index.js +6 -6
- package/dist/triage/evaluate/evaluate.d.ts +11 -0
- package/dist/triage/evaluate/evaluate.js +169 -0
- package/dist/triage/evaluate/github.d.ts +16 -0
- package/dist/triage/evaluate/github.js +153 -0
- package/dist/triage/evaluate/index.d.ts +9 -0
- package/dist/triage/evaluate/index.js +8 -0
- package/dist/triage/evaluate/paths.d.ts +7 -0
- package/dist/triage/evaluate/paths.js +25 -0
- package/dist/triage/evaluate/sink.d.ts +5 -0
- package/dist/triage/evaluate/sink.js +52 -0
- package/dist/triage/evaluate/types.d.ts +93 -0
- package/dist/triage/evaluate/types.js +13 -0
- package/dist/triage/evaluate/validity.d.ts +8 -0
- package/dist/triage/evaluate/validity.js +87 -0
- package/dist/triage/evaluate/value.d.ts +12 -0
- package/dist/triage/evaluate/value.js +33 -0
- package/dist/triage/evaluate/wip-census.d.ts +5 -0
- package/dist/triage/evaluate/wip-census.js +39 -0
- package/dist/triage/evaluate/worktrees.d.ts +8 -0
- package/dist/triage/evaluate/worktrees.js +68 -0
- package/dist/triage/evaluate/xbrief-refs.d.ts +8 -0
- package/dist/triage/evaluate/xbrief-refs.js +60 -0
- package/dist/triage/help/registry-data.d.ts +22 -8
- package/dist/triage/help/registry-data.js +54 -6
- package/dist/triage/index.d.ts +1 -0
- package/dist/triage/index.js +1 -0
- package/dist/triage/welcome/writers.d.ts +1 -1
- package/dist/triage/welcome/writers.js +10 -5
- package/dist/value/feedback-file.d.ts +17 -2
- package/dist/value/feedback-file.js +80 -6
- package/dist/value/readback.d.ts +4 -1
- package/dist/value/readback.js +51 -12
- package/dist/vbrief-reconcile/labels.d.ts +1 -0
- package/dist/vbrief-reconcile/labels.js +30 -0
- package/dist/vbrief-validate/schema.d.ts +4 -0
- package/dist/vbrief-validate/schema.js +1 -1
- package/dist/vbrief-validation/story-quality.d.ts +7 -0
- package/dist/vbrief-validation/story-quality.js +8 -1
- package/dist/verify-env/agent-hook-readiness.d.ts +2 -2
- package/dist/verify-env/agent-hook-readiness.js +12 -8
- package/dist/verify-env/agent-hooks-live-probe.d.ts +5 -1
- package/dist/verify-env/agent-hooks-live-probe.js +26 -5
- package/dist/verify-env/agent-hooks.js +3 -4
- package/dist/xbrief-migrate/agents-header.js +69 -7
- package/package.json +7 -3
|
@@ -1,67 +1,181 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { EXIT_CONFIG_ERROR, EXIT_OK } from "./constants.js";
|
|
3
4
|
import { finalizeCohort } from "./finalize-cohort.js";
|
|
5
|
+
export const FINALIZE_COHORT_USAGE = `Usage: task swarm:finalize-cohort -- [--pr <n>[,<n>...]] [--stories <ids|paths>] [options]
|
|
6
|
+
|
|
7
|
+
After cohort PRs merge, sweep story briefs active/ -> completed/ and open the lifecycle PR.
|
|
8
|
+
|
|
9
|
+
Options:
|
|
10
|
+
--pr <n>[,<n>...] Merged PR numbers (closing issues map to active stories)
|
|
11
|
+
--stories <ids|paths> Explicit story tokens (repeatable)
|
|
12
|
+
--repo OWNER/REPO GitHub repo (or $GH_REPO)
|
|
13
|
+
--project-root <path> Project root (default: cwd)
|
|
14
|
+
--base-branch <name> Sweep/PR base (default: resolved delivery branch)
|
|
15
|
+
--delivery-branch <name> Delivery-branch override when policy is untyped
|
|
16
|
+
--label <name> Feature-branch label
|
|
17
|
+
--dry-run Print plan; no git mutation
|
|
18
|
+
--no-commit Sweep without committing / opening a PR
|
|
19
|
+
--no-open-pr Commit without opening a PR
|
|
20
|
+
--json Machine-readable result
|
|
21
|
+
-h, --help Show this help
|
|
22
|
+
`;
|
|
23
|
+
function equalsValue(arg, flag) {
|
|
24
|
+
return arg.slice(flag.length + 1);
|
|
25
|
+
}
|
|
26
|
+
function parsePrList(raw, flag, prNumbers, reject) {
|
|
27
|
+
if (raw.trim().length === 0) {
|
|
28
|
+
reject(flag);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
for (const piece of raw.split(",")) {
|
|
32
|
+
const trimmed = piece.trim();
|
|
33
|
+
if (trimmed.length === 0) {
|
|
34
|
+
reject(flag);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
38
|
+
reject(flag);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
prNumbers.push(Number.parseInt(trimmed, 10));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
4
44
|
export function parseFinalizeCohortArgv(argv) {
|
|
5
45
|
const prNumbers = [];
|
|
6
46
|
const storyTokens = [];
|
|
7
47
|
let repo = null;
|
|
8
48
|
let projectRoot = ".";
|
|
9
|
-
let baseBranch
|
|
49
|
+
let baseBranch;
|
|
10
50
|
let deliveryBranch = null;
|
|
11
51
|
let label = null;
|
|
12
52
|
let dryRun = false;
|
|
13
53
|
let noCommit = false;
|
|
14
54
|
let noOpenPr = false;
|
|
15
55
|
let emitJson = false;
|
|
56
|
+
let help = false;
|
|
57
|
+
let error = null;
|
|
58
|
+
const reject = (arg) => {
|
|
59
|
+
error ??= `unrecognized argument: ${arg}`;
|
|
60
|
+
};
|
|
61
|
+
const takeValue = (flag, nextValue) => {
|
|
62
|
+
if (nextValue === undefined || nextValue.startsWith("-")) {
|
|
63
|
+
reject(flag);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
return nextValue;
|
|
67
|
+
};
|
|
16
68
|
for (let i = 0; i < argv.length; i += 1) {
|
|
17
69
|
const arg = argv[i];
|
|
18
70
|
const next = argv[i + 1];
|
|
19
|
-
if (arg === "--
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
71
|
+
if (arg === "--help" || arg === "-h") {
|
|
72
|
+
help = true;
|
|
73
|
+
}
|
|
74
|
+
else if (arg === "--pr") {
|
|
75
|
+
const value = takeValue(arg, next);
|
|
76
|
+
if (value !== null) {
|
|
77
|
+
parsePrList(value, arg, prNumbers, reject);
|
|
78
|
+
i += 1;
|
|
25
79
|
}
|
|
26
|
-
i += 1;
|
|
27
80
|
}
|
|
28
81
|
else if (arg?.startsWith("--pr=")) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
82
|
+
parsePrList(equalsValue(arg, "--pr"), arg, prNumbers, reject);
|
|
83
|
+
}
|
|
84
|
+
else if (arg === "--stories") {
|
|
85
|
+
const value = takeValue(arg, next);
|
|
86
|
+
if (value !== null) {
|
|
87
|
+
storyTokens.push(value);
|
|
88
|
+
i += 1;
|
|
34
89
|
}
|
|
35
90
|
}
|
|
36
|
-
else if (arg
|
|
37
|
-
|
|
38
|
-
|
|
91
|
+
else if (arg?.startsWith("--stories=")) {
|
|
92
|
+
const value = equalsValue(arg, "--stories");
|
|
93
|
+
if (value.length === 0) {
|
|
94
|
+
reject(arg);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
storyTokens.push(value);
|
|
98
|
+
}
|
|
39
99
|
}
|
|
40
|
-
else if (arg === "--repo"
|
|
41
|
-
|
|
42
|
-
|
|
100
|
+
else if (arg === "--repo") {
|
|
101
|
+
const value = takeValue(arg, next);
|
|
102
|
+
if (value !== null) {
|
|
103
|
+
repo = value;
|
|
104
|
+
i += 1;
|
|
105
|
+
}
|
|
43
106
|
}
|
|
44
107
|
else if (arg?.startsWith("--repo=")) {
|
|
45
|
-
|
|
108
|
+
const value = equalsValue(arg, "--repo");
|
|
109
|
+
if (value.length === 0) {
|
|
110
|
+
reject(arg);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
repo = value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (arg === "--project-root") {
|
|
117
|
+
const value = takeValue(arg, next);
|
|
118
|
+
if (value !== null) {
|
|
119
|
+
projectRoot = value;
|
|
120
|
+
i += 1;
|
|
121
|
+
}
|
|
46
122
|
}
|
|
47
|
-
else if (arg
|
|
48
|
-
|
|
49
|
-
|
|
123
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
124
|
+
const value = equalsValue(arg, "--project-root");
|
|
125
|
+
if (value.length === 0) {
|
|
126
|
+
reject(arg);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
projectRoot = value;
|
|
130
|
+
}
|
|
50
131
|
}
|
|
51
|
-
else if (arg === "--base-branch"
|
|
52
|
-
|
|
53
|
-
|
|
132
|
+
else if (arg === "--base-branch") {
|
|
133
|
+
const value = takeValue(arg, next);
|
|
134
|
+
if (value !== null) {
|
|
135
|
+
baseBranch = value;
|
|
136
|
+
i += 1;
|
|
137
|
+
}
|
|
54
138
|
}
|
|
55
|
-
else if (arg
|
|
56
|
-
|
|
57
|
-
|
|
139
|
+
else if (arg?.startsWith("--base-branch=")) {
|
|
140
|
+
const value = equalsValue(arg, "--base-branch");
|
|
141
|
+
if (value.length === 0) {
|
|
142
|
+
reject(arg);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
baseBranch = value;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else if (arg === "--delivery-branch") {
|
|
149
|
+
const value = takeValue(arg, next);
|
|
150
|
+
if (value !== null) {
|
|
151
|
+
deliveryBranch = value;
|
|
152
|
+
i += 1;
|
|
153
|
+
}
|
|
58
154
|
}
|
|
59
155
|
else if (arg?.startsWith("--delivery-branch=")) {
|
|
60
|
-
|
|
156
|
+
const value = equalsValue(arg, "--delivery-branch");
|
|
157
|
+
if (value.length === 0) {
|
|
158
|
+
reject(arg);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
deliveryBranch = value;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else if (arg === "--label") {
|
|
165
|
+
const value = takeValue(arg, next);
|
|
166
|
+
if (value !== null) {
|
|
167
|
+
label = value;
|
|
168
|
+
i += 1;
|
|
169
|
+
}
|
|
61
170
|
}
|
|
62
|
-
else if (arg
|
|
63
|
-
|
|
64
|
-
|
|
171
|
+
else if (arg?.startsWith("--label=")) {
|
|
172
|
+
const value = equalsValue(arg, "--label");
|
|
173
|
+
if (value.length === 0) {
|
|
174
|
+
reject(arg);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
label = value;
|
|
178
|
+
}
|
|
65
179
|
}
|
|
66
180
|
else if (arg === "--dry-run") {
|
|
67
181
|
dryRun = true;
|
|
@@ -78,23 +192,37 @@ export function parseFinalizeCohortArgv(argv) {
|
|
|
78
192
|
else if (arg !== undefined && !arg.startsWith("-")) {
|
|
79
193
|
storyTokens.push(arg);
|
|
80
194
|
}
|
|
195
|
+
else if (arg !== undefined) {
|
|
196
|
+
reject(arg);
|
|
197
|
+
}
|
|
81
198
|
}
|
|
82
199
|
return {
|
|
83
200
|
prNumbers,
|
|
84
201
|
storyTokens,
|
|
85
202
|
repo,
|
|
86
203
|
projectRoot,
|
|
87
|
-
baseBranch,
|
|
204
|
+
...(baseBranch !== undefined ? { baseBranch } : {}),
|
|
88
205
|
deliveryBranch,
|
|
89
206
|
label,
|
|
90
207
|
dryRun,
|
|
91
208
|
noCommit,
|
|
92
209
|
noOpenPr,
|
|
93
210
|
emitJson,
|
|
211
|
+
help,
|
|
212
|
+
error,
|
|
94
213
|
};
|
|
95
214
|
}
|
|
96
215
|
export function finalizeCohortMain(argv = process.argv.slice(2)) {
|
|
97
|
-
const
|
|
216
|
+
const parsed = parseFinalizeCohortArgv(argv);
|
|
217
|
+
if (parsed.help) {
|
|
218
|
+
process.stdout.write(FINALIZE_COHORT_USAGE);
|
|
219
|
+
return EXIT_OK;
|
|
220
|
+
}
|
|
221
|
+
if (parsed.error !== null) {
|
|
222
|
+
process.stderr.write(`${parsed.error}\n`);
|
|
223
|
+
return EXIT_CONFIG_ERROR;
|
|
224
|
+
}
|
|
225
|
+
const result = finalizeCohort(parsed);
|
|
98
226
|
if (result.stdout.length > 0) {
|
|
99
227
|
process.stdout.write(result.stdout);
|
|
100
228
|
}
|
|
@@ -103,7 +231,9 @@ export function finalizeCohortMain(argv = process.argv.slice(2)) {
|
|
|
103
231
|
}
|
|
104
232
|
return result.exitCode;
|
|
105
233
|
}
|
|
234
|
+
/* v8 ignore start -- entry guard */
|
|
106
235
|
if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
107
236
|
process.exit(finalizeCohortMain());
|
|
108
237
|
}
|
|
238
|
+
/* v8 ignore stop */
|
|
109
239
|
//# sourceMappingURL=finalize-cohort-cli.js.map
|
|
@@ -13,6 +13,7 @@ export interface FinalizeCohortResult {
|
|
|
13
13
|
readonly branch: string | null;
|
|
14
14
|
readonly pr_url: string | null;
|
|
15
15
|
readonly delivery_branch: string | null;
|
|
16
|
+
readonly sweep_base: string;
|
|
16
17
|
readonly delivery_errors: readonly string[];
|
|
17
18
|
readonly errors: readonly string[];
|
|
18
19
|
readonly warnings: readonly string[];
|
|
@@ -327,8 +327,6 @@ export function finalizeCohort(args) {
|
|
|
327
327
|
const prNumbers = [...(args.prNumbers ?? [])].sort((a, b) => a - b);
|
|
328
328
|
const storyTokens = splitCsv(args.storyTokens ?? []);
|
|
329
329
|
const repo = args.repo ?? process.env.GH_REPO ?? null;
|
|
330
|
-
// baseBranch is for the lifecycle sweep PR only — not delivery proof (#3041).
|
|
331
|
-
const baseBranch = args.baseBranch ?? "master";
|
|
332
330
|
const dryRun = args.dryRun ?? false;
|
|
333
331
|
const noCommit = args.noCommit ?? false;
|
|
334
332
|
const noOpenPr = args.noOpenPr ?? false;
|
|
@@ -351,6 +349,12 @@ export function finalizeCohort(args) {
|
|
|
351
349
|
const deliveryBranch = policyDelivery.source === "typed"
|
|
352
350
|
? policyDelivery.branch
|
|
353
351
|
: (cliDelivery ?? policyDelivery.branch);
|
|
352
|
+
// Sweep/PR base is distinct from delivery proof (#3041). Default via the resolved
|
|
353
|
+
// delivery branch — never a hardcoded "master". --base-branch remains the override.
|
|
354
|
+
const explicitSweepBase = args.baseBranch !== undefined && args.baseBranch !== null && args.baseBranch.trim().length > 0
|
|
355
|
+
? args.baseBranch.trim()
|
|
356
|
+
: null;
|
|
357
|
+
const baseBranch = explicitSweepBase ?? deliveryBranch;
|
|
354
358
|
if (!existsSync(projectRoot)) {
|
|
355
359
|
return buildResponse({
|
|
356
360
|
projectRoot,
|
|
@@ -364,6 +368,7 @@ export function finalizeCohort(args) {
|
|
|
364
368
|
branch: null,
|
|
365
369
|
prUrl: null,
|
|
366
370
|
deliveryBranch,
|
|
371
|
+
sweepBase: baseBranch,
|
|
367
372
|
deliveryErrors: [],
|
|
368
373
|
errors: [`project root does not exist: ${projectRoot}`],
|
|
369
374
|
warnings: [],
|
|
@@ -385,6 +390,7 @@ export function finalizeCohort(args) {
|
|
|
385
390
|
branch: null,
|
|
386
391
|
prUrl: null,
|
|
387
392
|
deliveryBranch,
|
|
393
|
+
sweepBase: baseBranch,
|
|
388
394
|
deliveryErrors: [],
|
|
389
395
|
errors: [`no xbrief/ directory under project root: ${projectRoot}`],
|
|
390
396
|
warnings: [],
|
|
@@ -546,6 +552,7 @@ export function finalizeCohort(args) {
|
|
|
546
552
|
branch: null,
|
|
547
553
|
prUrl: null,
|
|
548
554
|
deliveryBranch,
|
|
555
|
+
sweepBase: baseBranch,
|
|
549
556
|
deliveryErrors,
|
|
550
557
|
errors,
|
|
551
558
|
warnings,
|
|
@@ -572,6 +579,7 @@ export function finalizeCohort(args) {
|
|
|
572
579
|
branch: null,
|
|
573
580
|
prUrl: null,
|
|
574
581
|
deliveryBranch,
|
|
582
|
+
sweepBase: baseBranch,
|
|
575
583
|
deliveryErrors,
|
|
576
584
|
errors,
|
|
577
585
|
warnings,
|
|
@@ -673,6 +681,7 @@ export function finalizeCohort(args) {
|
|
|
673
681
|
branch: null,
|
|
674
682
|
prUrl: null,
|
|
675
683
|
deliveryBranch,
|
|
684
|
+
sweepBase: baseBranch,
|
|
676
685
|
deliveryErrors,
|
|
677
686
|
errors,
|
|
678
687
|
warnings,
|
|
@@ -712,6 +721,7 @@ export function finalizeCohort(args) {
|
|
|
712
721
|
branch,
|
|
713
722
|
prUrl,
|
|
714
723
|
deliveryBranch,
|
|
724
|
+
sweepBase: baseBranch,
|
|
715
725
|
deliveryErrors,
|
|
716
726
|
errors,
|
|
717
727
|
warnings,
|
|
@@ -733,6 +743,7 @@ function buildResponse(input) {
|
|
|
733
743
|
branch: input.branch,
|
|
734
744
|
pr_url: input.prUrl,
|
|
735
745
|
delivery_branch: input.deliveryBranch,
|
|
746
|
+
sweep_base: input.sweepBase,
|
|
736
747
|
delivery_errors: input.deliveryErrors,
|
|
737
748
|
errors: input.errors,
|
|
738
749
|
warnings: input.warnings,
|
|
@@ -754,6 +765,7 @@ function buildResponse(input) {
|
|
|
754
765
|
if (input.deliveryBranch !== null) {
|
|
755
766
|
lines.push(` Delivery branch: ${input.deliveryBranch}`);
|
|
756
767
|
}
|
|
768
|
+
lines.push(` Sweep base: ${input.sweepBase}`);
|
|
757
769
|
if (input.prNumbers.length > 0) {
|
|
758
770
|
lines.push(` PRs: ${input.prNumbers.map((n) => `#${n}`).join(", ")}`);
|
|
759
771
|
}
|
package/dist/swarm/launch.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ExpectedGithubWorkerPrincipal, type GhRunner, GITHUB_AUTH_MODE_HOST_GH, GITHUB_AUTH_MODE_INJECTED_TOKEN } from "../intake/github-auth-modes.js";
|
|
1
2
|
import { EXIT_CONFIG_ERROR, EXIT_GATE_FAILED, EXIT_OK } from "./constants.js";
|
|
2
3
|
import { type WorktreeRecord } from "./worktrees.js";
|
|
3
4
|
export interface ResolvedStory {
|
|
@@ -21,6 +22,70 @@ export type RuntimeAuthProbeFn = () => [string, string];
|
|
|
21
22
|
export declare const defaultPreflightGate: PreflightGateFn;
|
|
22
23
|
export declare const defaultReadinessGate: ReadinessGateFn;
|
|
23
24
|
export declare const defaultRuntimeAuthProbe: RuntimeAuthProbeFn;
|
|
25
|
+
export type WorkerCredentialDispatchPath = "grok-build" | "local-hybrid";
|
|
26
|
+
/**
|
|
27
|
+
* Dispatch-envelope half of the runtime / GitHub auth-mode contract (#1557 / #1351).
|
|
28
|
+
* Policy labels only — never a token value.
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatDispatchAuthEnvelope(fields: {
|
|
31
|
+
runtimeMode: string;
|
|
32
|
+
githubAuthMode: string;
|
|
33
|
+
expectedGithubLogin?: string | null;
|
|
34
|
+
}): string;
|
|
35
|
+
export interface WorkerCredentialInjectionRequest {
|
|
36
|
+
environ?: NodeJS.ProcessEnv;
|
|
37
|
+
githubAuthMode: string;
|
|
38
|
+
runtimeMode?: string | null;
|
|
39
|
+
dispatchPath?: WorkerCredentialDispatchPath;
|
|
40
|
+
expectedPrincipal?: ExpectedGithubWorkerPrincipal | null;
|
|
41
|
+
repo?: string;
|
|
42
|
+
runGh?: GhRunner;
|
|
43
|
+
cwd?: string;
|
|
44
|
+
}
|
|
45
|
+
export type WorkerCredentialInjectionResult = {
|
|
46
|
+
ok: true;
|
|
47
|
+
injected: true;
|
|
48
|
+
githubAuthMode: typeof GITHUB_AUTH_MODE_INJECTED_TOKEN;
|
|
49
|
+
runtimeMode: string | null;
|
|
50
|
+
expectedLogin: string;
|
|
51
|
+
spawnEnv: {
|
|
52
|
+
GH_TOKEN: string;
|
|
53
|
+
GITHUB_TOKEN: string;
|
|
54
|
+
GH_ENTERPRISE_TOKEN: string;
|
|
55
|
+
DEFT_EXPECTED_GITHUB_LOGIN: string;
|
|
56
|
+
};
|
|
57
|
+
envelopeSection: string;
|
|
58
|
+
} | {
|
|
59
|
+
ok: true;
|
|
60
|
+
injected: false;
|
|
61
|
+
githubAuthMode: typeof GITHUB_AUTH_MODE_HOST_GH;
|
|
62
|
+
runtimeMode: string | null;
|
|
63
|
+
expectedLogin: string | null;
|
|
64
|
+
spawnEnv: Record<string, never>;
|
|
65
|
+
envelopeSection: string;
|
|
66
|
+
} | {
|
|
67
|
+
ok: false;
|
|
68
|
+
blocked: true;
|
|
69
|
+
githubAuthMode: string;
|
|
70
|
+
runtimeMode: string | null;
|
|
71
|
+
missingCredential: string;
|
|
72
|
+
remedy: string;
|
|
73
|
+
detail: string;
|
|
74
|
+
failureKind: string | null;
|
|
75
|
+
envelopeSection: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Validate a held user-bearing worker credential and prepare spawn-time injection (#1351).
|
|
79
|
+
*
|
|
80
|
+
* Comparison is opt-in on the validator. This path always stamps
|
|
81
|
+
* `DEFT_EXPECTED_GITHUB_LOGIN` after a successful user-principal check so the
|
|
82
|
+
* worker envelope does not inherit "any user token is approved."
|
|
83
|
+
*
|
|
84
|
+
* Installation credentials fail closed via the existing validator (#3693).
|
|
85
|
+
* Token values belong only in the returned `spawnEnv` — never in prompts,
|
|
86
|
+
* transcripts, or manifest entries.
|
|
87
|
+
*/
|
|
88
|
+
export declare function prepareWorkerCredentialInjection(request: WorkerCredentialInjectionRequest): WorkerCredentialInjectionResult;
|
|
24
89
|
/**
|
|
25
90
|
* True when a brief in `xbrief/completed/` (or the legacy `vbrief/completed/`)
|
|
26
91
|
* references the given issue number in its `references[]` / `Traces`. Used by
|
|
@@ -74,6 +139,7 @@ export declare function buildManifest(resolved: readonly ResolvedStory[], option
|
|
|
74
139
|
modelSource?: string | null;
|
|
75
140
|
runtimeMode?: string | null;
|
|
76
141
|
githubAuthMode?: string | null;
|
|
142
|
+
expectedGithubLogin?: string | null;
|
|
77
143
|
occupancySessionId?: string | null;
|
|
78
144
|
}): Record<string, unknown>[];
|
|
79
145
|
export declare function orderCohort(resolved: readonly ResolvedStory[], _projectRoot: string): ResolvedStory[];
|
|
@@ -103,6 +169,9 @@ export interface LaunchArgs {
|
|
|
103
169
|
* Defaults to `process.env` when unset.
|
|
104
170
|
*/
|
|
105
171
|
environ?: NodeJS.ProcessEnv;
|
|
172
|
+
/** Optional gh runner for identity-bound credential injection (#1351). */
|
|
173
|
+
runGh?: GhRunner;
|
|
174
|
+
expectedPrincipal?: ExpectedGithubWorkerPrincipal | null;
|
|
106
175
|
}
|
|
107
176
|
export declare function swarmLaunch(args: LaunchArgs): {
|
|
108
177
|
exitCode: number;
|
package/dist/swarm/launch.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
|
|
2
2
|
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
3
3
|
import { containedWrite } from "../fs/contained-write.js";
|
|
4
|
-
import { inferGithubAuthMode } from "../intake/github-auth-modes.js";
|
|
4
|
+
import { ENV_EXPECTED_GITHUB_LOGIN, FAILURE_INSTALLATION_IDENTITY_UNVERIFIABLE, FAILURE_MISSING_INJECTED_TOKEN, findInjectedToken, GITHUB_AUTH_MODE_HOST_GH, GITHUB_AUTH_MODE_INJECTED_TOKEN, inferGithubAuthMode, validateGithubAuthForWorker, } from "../intake/github-auth-modes.js";
|
|
5
5
|
import { getPlatformCapabilities } from "../intake/platform-capabilities.js";
|
|
6
6
|
import { hasArtifactSuffix, resolveLifecycleFolder, stripArtifactSuffix, } from "../layout/resolve.js";
|
|
7
7
|
import { evaluate as preflightEvaluate } from "../preflight/evaluate.js";
|
|
@@ -25,6 +25,164 @@ export const defaultRuntimeAuthProbe = () => {
|
|
|
25
25
|
const report = getPlatformCapabilities();
|
|
26
26
|
return [report.runtimeMode, inferGithubAuthMode(report)];
|
|
27
27
|
};
|
|
28
|
+
const CREDENTIAL_VALUE_PATTERN = /^(ghp_|gho_|ghu_|ghs_|github_pat_)/i;
|
|
29
|
+
const INJECTION_MISSING_CREDENTIAL = "GH_TOKEN (or GITHUB_TOKEN / GH_ENTERPRISE_TOKEN)";
|
|
30
|
+
const INJECTION_DISPATCHER_REMEDY = "Dispatcher-side remedy: load an approved user-bearing worker credential into the dispatcher environment, then call prepareWorkerCredentialInjection before spawn. Do not fall back to the host gh token or continue under the maintainer identity. Installation credentials are not injectable; see #3693.";
|
|
31
|
+
const HELD_WORKER_TOKEN_VARS = [
|
|
32
|
+
"GH_TOKEN",
|
|
33
|
+
"GITHUB_TOKEN",
|
|
34
|
+
"GH_ENTERPRISE_TOKEN",
|
|
35
|
+
"GITHUB_ENTERPRISE_TOKEN",
|
|
36
|
+
];
|
|
37
|
+
function looksLikeCredentialValue(value) {
|
|
38
|
+
return CREDENTIAL_VALUE_PATTERN.test(value.trim());
|
|
39
|
+
}
|
|
40
|
+
function assertNoCredentialValue(value, label) {
|
|
41
|
+
if (looksLikeCredentialValue(value)) {
|
|
42
|
+
throw new Error(`${label} must not contain a credential value`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function sanitizeEnvelopeField(value, label) {
|
|
46
|
+
const cleaned = value.replace(/\r?\n/g, " ").trim();
|
|
47
|
+
assertNoCredentialValue(cleaned, label);
|
|
48
|
+
return cleaned;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Bind validation to the selected token. Stamp it into every gh token slot and
|
|
52
|
+
* drop GH_CONFIG_DIR so a host/enterprise config cannot authenticate as someone
|
|
53
|
+
* else. GH_HOST stays: it selects the API host, not the secret.
|
|
54
|
+
*/
|
|
55
|
+
function isolateHeldWorkerToken(environ, token) {
|
|
56
|
+
const isolated = { ...environ };
|
|
57
|
+
for (const name of HELD_WORKER_TOKEN_VARS) {
|
|
58
|
+
isolated[name] = token;
|
|
59
|
+
}
|
|
60
|
+
delete isolated.GH_CONFIG_DIR;
|
|
61
|
+
return isolated;
|
|
62
|
+
}
|
|
63
|
+
function boundWorkerSpawnEnv(token, expectedLogin) {
|
|
64
|
+
return {
|
|
65
|
+
GH_TOKEN: token,
|
|
66
|
+
GITHUB_TOKEN: token,
|
|
67
|
+
GH_ENTERPRISE_TOKEN: token,
|
|
68
|
+
[ENV_EXPECTED_GITHUB_LOGIN]: expectedLogin,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Dispatch-envelope half of the runtime / GitHub auth-mode contract (#1557 / #1351).
|
|
73
|
+
* Policy labels only — never a token value.
|
|
74
|
+
*/
|
|
75
|
+
export function formatDispatchAuthEnvelope(fields) {
|
|
76
|
+
const runtimeMode = sanitizeEnvelopeField(fields.runtimeMode, "runtime_mode");
|
|
77
|
+
const githubAuthMode = sanitizeEnvelopeField(fields.githubAuthMode, "github_auth_mode");
|
|
78
|
+
const lines = [
|
|
79
|
+
"## Runtime and GitHub auth mode",
|
|
80
|
+
"",
|
|
81
|
+
`- runtime_mode: ${runtimeMode}`,
|
|
82
|
+
`- github_auth_mode: ${githubAuthMode}`,
|
|
83
|
+
];
|
|
84
|
+
if (fields.expectedGithubLogin !== undefined && fields.expectedGithubLogin !== null) {
|
|
85
|
+
const login = sanitizeEnvelopeField(fields.expectedGithubLogin, "expected_github_login");
|
|
86
|
+
if (login.length > 0) {
|
|
87
|
+
lines.push(`- expected_github_login: ${login}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return `${lines.join("\n")}\n`;
|
|
91
|
+
}
|
|
92
|
+
function blockedInjection(fields) {
|
|
93
|
+
const detail = fields.detail.startsWith("BLOCKED") ? fields.detail : `BLOCKED: ${fields.detail}`;
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
blocked: true,
|
|
97
|
+
githubAuthMode: fields.githubAuthMode,
|
|
98
|
+
runtimeMode: fields.runtimeMode,
|
|
99
|
+
missingCredential: fields.missingCredential ?? INJECTION_MISSING_CREDENTIAL,
|
|
100
|
+
remedy: INJECTION_DISPATCHER_REMEDY,
|
|
101
|
+
detail,
|
|
102
|
+
failureKind: fields.failureKind,
|
|
103
|
+
envelopeSection: formatDispatchAuthEnvelope({
|
|
104
|
+
runtimeMode: fields.runtimeMode ?? "unknown",
|
|
105
|
+
githubAuthMode: fields.githubAuthMode,
|
|
106
|
+
}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Validate a held user-bearing worker credential and prepare spawn-time injection (#1351).
|
|
111
|
+
*
|
|
112
|
+
* Comparison is opt-in on the validator. This path always stamps
|
|
113
|
+
* `DEFT_EXPECTED_GITHUB_LOGIN` after a successful user-principal check so the
|
|
114
|
+
* worker envelope does not inherit "any user token is approved."
|
|
115
|
+
*
|
|
116
|
+
* Installation credentials fail closed via the existing validator (#3693).
|
|
117
|
+
* Token values belong only in the returned `spawnEnv` — never in prompts,
|
|
118
|
+
* transcripts, or manifest entries.
|
|
119
|
+
*/
|
|
120
|
+
export function prepareWorkerCredentialInjection(request) {
|
|
121
|
+
const environ = request.environ ?? process.env;
|
|
122
|
+
const runtimeMode = request.runtimeMode ?? null;
|
|
123
|
+
const token = findInjectedToken(environ);
|
|
124
|
+
const grokBuild = request.dispatchPath === "grok-build";
|
|
125
|
+
const effectiveMode = grokBuild || token !== null ? GITHUB_AUTH_MODE_INJECTED_TOKEN : request.githubAuthMode;
|
|
126
|
+
if (effectiveMode === GITHUB_AUTH_MODE_HOST_GH && token === null) {
|
|
127
|
+
return {
|
|
128
|
+
ok: true,
|
|
129
|
+
injected: false,
|
|
130
|
+
githubAuthMode: GITHUB_AUTH_MODE_HOST_GH,
|
|
131
|
+
runtimeMode,
|
|
132
|
+
expectedLogin: null,
|
|
133
|
+
spawnEnv: {},
|
|
134
|
+
envelopeSection: formatDispatchAuthEnvelope({
|
|
135
|
+
runtimeMode: runtimeMode ?? "local-unsandboxed",
|
|
136
|
+
githubAuthMode: GITHUB_AUTH_MODE_HOST_GH,
|
|
137
|
+
}),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (token === null) {
|
|
141
|
+
return blockedInjection({
|
|
142
|
+
githubAuthMode: GITHUB_AUTH_MODE_INJECTED_TOKEN,
|
|
143
|
+
runtimeMode,
|
|
144
|
+
failureKind: FAILURE_MISSING_INJECTED_TOKEN,
|
|
145
|
+
missingCredential: INJECTION_MISSING_CREDENTIAL,
|
|
146
|
+
detail: "missing worker credential GH_TOKEN (or GITHUB_TOKEN / GH_ENTERPRISE_TOKEN) for a write-requiring injected-token dispatch",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
const isolatedEnviron = isolateHeldWorkerToken(environ, token);
|
|
150
|
+
const validated = validateGithubAuthForWorker(GITHUB_AUTH_MODE_INJECTED_TOKEN, {
|
|
151
|
+
environ: isolatedEnviron,
|
|
152
|
+
runtimeReport: { runtimeMode: runtimeMode ?? "cloud-headless" },
|
|
153
|
+
repo: request.repo,
|
|
154
|
+
runGh: request.runGh,
|
|
155
|
+
expectedPrincipal: request.expectedPrincipal,
|
|
156
|
+
cwd: request.cwd,
|
|
157
|
+
});
|
|
158
|
+
if (!validated.ok || validated.login === null || validated.login.trim().length === 0) {
|
|
159
|
+
const installation = validated.failureKind === FAILURE_INSTALLATION_IDENTITY_UNVERIFIABLE;
|
|
160
|
+
return blockedInjection({
|
|
161
|
+
githubAuthMode: GITHUB_AUTH_MODE_INJECTED_TOKEN,
|
|
162
|
+
runtimeMode,
|
|
163
|
+
failureKind: validated.failureKind,
|
|
164
|
+
detail: installation
|
|
165
|
+
? `${validated.detail} Installation credentials are not injectable (#3693).`
|
|
166
|
+
: validated.detail,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
const expectedLogin = validated.login.trim();
|
|
170
|
+
assertNoCredentialValue(expectedLogin, "expected_github_login");
|
|
171
|
+
const spawnEnv = boundWorkerSpawnEnv(token, expectedLogin);
|
|
172
|
+
return {
|
|
173
|
+
ok: true,
|
|
174
|
+
injected: true,
|
|
175
|
+
githubAuthMode: GITHUB_AUTH_MODE_INJECTED_TOKEN,
|
|
176
|
+
runtimeMode,
|
|
177
|
+
expectedLogin,
|
|
178
|
+
spawnEnv,
|
|
179
|
+
envelopeSection: formatDispatchAuthEnvelope({
|
|
180
|
+
runtimeMode: runtimeMode ?? "cloud-headless",
|
|
181
|
+
githubAuthMode: GITHUB_AUTH_MODE_INJECTED_TOKEN,
|
|
182
|
+
expectedGithubLogin: expectedLogin,
|
|
183
|
+
}),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
28
186
|
function loadJson(path) {
|
|
29
187
|
try {
|
|
30
188
|
const data = JSON.parse(readFileSync(path, "utf8"));
|
|
@@ -498,6 +656,10 @@ export function buildManifest(resolved, options) {
|
|
|
498
656
|
if (options.githubAuthMode !== undefined && options.githubAuthMode !== null) {
|
|
499
657
|
entry.github_auth_mode = options.githubAuthMode;
|
|
500
658
|
}
|
|
659
|
+
if (options.expectedGithubLogin !== undefined && options.expectedGithubLogin !== null) {
|
|
660
|
+
assertNoCredentialValue(options.expectedGithubLogin, "expected_github_login");
|
|
661
|
+
entry.expected_github_login = options.expectedGithubLogin;
|
|
662
|
+
}
|
|
501
663
|
manifest.push(entry);
|
|
502
664
|
}
|
|
503
665
|
return manifest;
|
|
@@ -692,6 +854,33 @@ export function swarmLaunch(args) {
|
|
|
692
854
|
stderr: `${occupancy.message}\n`,
|
|
693
855
|
};
|
|
694
856
|
}
|
|
857
|
+
const launchEnviron = args.environ ?? process.env;
|
|
858
|
+
let expectedGithubLogin = null;
|
|
859
|
+
// Only the injected-token launch path auto-validates (and fail-closes on a
|
|
860
|
+
// missing token). An ambient GH_TOKEN on a host-gh probe is often the
|
|
861
|
+
// maintainer workaround, not a worker credential; local-hybrid injection is
|
|
862
|
+
// the explicit prepareWorkerCredentialInjection call.
|
|
863
|
+
if (githubAuthMode === GITHUB_AUTH_MODE_INJECTED_TOKEN) {
|
|
864
|
+
const injection = prepareWorkerCredentialInjection({
|
|
865
|
+
environ: launchEnviron,
|
|
866
|
+
githubAuthMode,
|
|
867
|
+
runtimeMode,
|
|
868
|
+
dispatchPath: "grok-build",
|
|
869
|
+
runGh: args.runGh,
|
|
870
|
+
expectedPrincipal: args.expectedPrincipal,
|
|
871
|
+
cwd: projectRoot,
|
|
872
|
+
});
|
|
873
|
+
if (!injection.ok) {
|
|
874
|
+
return {
|
|
875
|
+
exitCode: EXIT_GATE_FAILED,
|
|
876
|
+
stdout: "",
|
|
877
|
+
stderr: `${injection.detail}\n${injection.remedy}\n`,
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
if (injection.injected) {
|
|
881
|
+
expectedGithubLogin = injection.expectedLogin;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
695
884
|
const manifest = buildManifest(ordered, {
|
|
696
885
|
projectRoot,
|
|
697
886
|
group: args.group ?? null,
|
|
@@ -708,6 +897,7 @@ export function swarmLaunch(args) {
|
|
|
708
897
|
modelSource,
|
|
709
898
|
runtimeMode,
|
|
710
899
|
githubAuthMode,
|
|
900
|
+
expectedGithubLogin,
|
|
711
901
|
occupancySessionId: occupancy.sessionId,
|
|
712
902
|
});
|
|
713
903
|
const rendered = `${JSON.stringify(manifest, null, 2)}\n`;
|
|
@@ -22,6 +22,8 @@ export function routingSetMain(argv = process.argv.slice(2), environ = process.e
|
|
|
22
22
|
let harnessDefault = false;
|
|
23
23
|
for (let i = 0; i < argv.length; i += 1) {
|
|
24
24
|
const arg = argv[i];
|
|
25
|
+
if (arg === "--")
|
|
26
|
+
continue;
|
|
25
27
|
if (arg === "--project-root" && argv[i + 1] !== undefined) {
|
|
26
28
|
projectRoot = argv[i + 1] ?? ".";
|
|
27
29
|
i += 1;
|