@cleanslop/cli 0.0.0-stage → 0.1.0-beta.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -2
- package/assets/skill-core.md +62 -0
- package/dist/action.d.ts +5 -0
- package/dist/action.js +22 -0
- package/dist/action.js.map +1 -0
- package/dist/args.d.ts +4 -0
- package/dist/args.js +243 -0
- package/dist/args.js.map +1 -0
- package/dist/commands/credits.d.ts +29 -0
- package/dist/commands/credits.js +267 -0
- package/dist/commands/credits.js.map +1 -0
- package/dist/commands/email.d.ts +3 -0
- package/dist/commands/email.js +51 -0
- package/dist/commands/email.js.map +1 -0
- package/dist/commands/link-identity.d.ts +3 -0
- package/dist/commands/link-identity.js +37 -0
- package/dist/commands/link-identity.js.map +1 -0
- package/dist/commands/link-login.d.ts +3 -0
- package/dist/commands/link-login.js +63 -0
- package/dist/commands/link-login.js.map +1 -0
- package/dist/commands/login.d.ts +6 -0
- package/dist/commands/login.js +198 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.js +40 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/report.d.ts +8 -0
- package/dist/commands/report.js +55 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/scan-upload.d.ts +3 -0
- package/dist/commands/scan-upload.js +85 -0
- package/dist/commands/scan-upload.js.map +1 -0
- package/dist/commands/scan.d.ts +3 -0
- package/dist/commands/scan.js +81 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/setup.d.ts +19 -0
- package/dist/commands/setup.js +154 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.js +29 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.js +44 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config.d.ts +26 -0
- package/dist/config.js +46 -0
- package/dist/config.js.map +1 -0
- package/dist/credentials.d.ts +64 -0
- package/dist/credentials.js +220 -0
- package/dist/credentials.js.map +1 -0
- package/dist/deps.d.ts +58 -0
- package/dist/deps.js +148 -0
- package/dist/deps.js.map +1 -0
- package/dist/exit.d.ts +24 -0
- package/dist/exit.js +29 -0
- package/dist/exit.js.map +1 -0
- package/dist/git.d.ts +14 -0
- package/dist/git.js +161 -0
- package/dist/git.js.map +1 -0
- package/dist/http.d.ts +16 -0
- package/dist/http.js +210 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/link.d.ts +106 -0
- package/dist/link.js +650 -0
- package/dist/link.js.map +1 -0
- package/dist/main.d.ts +6 -0
- package/dist/main.js +75 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp-config.d.ts +13 -0
- package/dist/mcp-config.js +65 -0
- package/dist/mcp-config.js.map +1 -0
- package/dist/output.d.ts +9 -0
- package/dist/output.js +65 -0
- package/dist/output.js.map +1 -0
- package/dist/pack.d.ts +30 -0
- package/dist/pack.js +283 -0
- package/dist/pack.js.map +1 -0
- package/dist/redact.d.ts +2 -0
- package/dist/redact.js +17 -0
- package/dist/redact.js.map +1 -0
- package/dist/skill.d.ts +10 -0
- package/dist/skill.js +110 -0
- package/dist/skill.js.map +1 -0
- package/dist/types.d.ts +144 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ustar.d.ts +7 -0
- package/dist/ustar.js +128 -0
- package/dist/ustar.js.map +1 -0
- package/dist/wait.d.ts +11 -0
- package/dist/wait.js +80 -0
- package/dist/wait.js.map +1 -0
- package/package.json +30 -4
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { CLIENT_ID, DEVICE_GRANT_TYPE, PACKAGE_VERSION } from "../config.js";
|
|
2
|
+
import { deletePendingLogin, peekStoredCreds, readPendingLogin, resolveOrigin, storeToken, writePendingLogin, } from "../credentials.js";
|
|
3
|
+
import { actionError, CliError, EXIT_ACTION, EXIT_OK, EXIT_UNEXPECTED, usageError, } from "../exit.js";
|
|
4
|
+
import { detectAgentHint, gitToplevel, parseGithubRemote } from "../git.js";
|
|
5
|
+
import { asErrorBody, httpRequest } from "../http.js";
|
|
6
|
+
import { runLinkLogin } from "./link-login.js";
|
|
7
|
+
/** Matches server DEVICE_EXTEND_TTL_MS — first /connect view extends the code. */
|
|
8
|
+
export const DEVICE_POLL_GRACE_MS = 30 * 60 * 1000;
|
|
9
|
+
export function devicePollDeadline(expiresAt) {
|
|
10
|
+
return expiresAt + DEVICE_POLL_GRACE_MS;
|
|
11
|
+
}
|
|
12
|
+
async function repoHint(deps) {
|
|
13
|
+
const top = await gitToplevel(deps, deps.env.cwd());
|
|
14
|
+
if (!top)
|
|
15
|
+
return undefined;
|
|
16
|
+
const remote = await deps.git(["remote", "get-url", "origin"], top);
|
|
17
|
+
if (!remote.ok)
|
|
18
|
+
return undefined;
|
|
19
|
+
return parseGithubRemote(remote.stdout)?.fullName;
|
|
20
|
+
}
|
|
21
|
+
function printApproval(deps, device) {
|
|
22
|
+
deps.io.stderr(`${device.verificationUriComplete}\n`);
|
|
23
|
+
deps.io.stderr(`${device.userCode}\n`);
|
|
24
|
+
deps.io.stderr([
|
|
25
|
+
"CLEANSLOP_ACTION_REQUIRED: approve",
|
|
26
|
+
"",
|
|
27
|
+
`Ask the human to open ${device.verificationUriComplete} and confirm code ${device.userCode}.`,
|
|
28
|
+
"Do not open or approve it yourself.",
|
|
29
|
+
"",
|
|
30
|
+
].join("\n"));
|
|
31
|
+
}
|
|
32
|
+
async function pollDeviceToken(deps, origin, device) {
|
|
33
|
+
let intervalMs = Math.max(3, device.interval) * 1000;
|
|
34
|
+
const deadline = devicePollDeadline(device.expiresAt);
|
|
35
|
+
while (deps.clock.now() < deadline) {
|
|
36
|
+
await deps.clock.sleep(intervalMs);
|
|
37
|
+
let tokenRes;
|
|
38
|
+
try {
|
|
39
|
+
tokenRes = await httpRequest(deps, origin, "POST", "/oauth/token", {
|
|
40
|
+
body: {
|
|
41
|
+
grant_type: DEVICE_GRANT_TYPE,
|
|
42
|
+
device_code: device.deviceCode,
|
|
43
|
+
client_id: CLIENT_ID,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
if (err instanceof CliError && err.exitCode === EXIT_UNEXPECTED) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
if (tokenRes.status >= 500) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const body = asErrorBody(tokenRes.json);
|
|
57
|
+
const err = body.error;
|
|
58
|
+
if (tokenRes.status >= 200 && tokenRes.status < 300) {
|
|
59
|
+
const issued = tokenRes.json;
|
|
60
|
+
if (!issued || typeof issued.access_token !== "string") {
|
|
61
|
+
throw new CliError("Token response was missing access_token.", EXIT_UNEXPECTED);
|
|
62
|
+
}
|
|
63
|
+
const login = issued.account?.github_login ?? null;
|
|
64
|
+
const prior = peekStoredCreds(deps, origin);
|
|
65
|
+
await storeToken(deps, origin, {
|
|
66
|
+
token: issued.access_token,
|
|
67
|
+
githubLogin: login,
|
|
68
|
+
grantId: issued.grant_id ?? null,
|
|
69
|
+
});
|
|
70
|
+
if (prior?.token) {
|
|
71
|
+
try {
|
|
72
|
+
await httpRequest(deps, origin, "POST", "/oauth/revoke", {
|
|
73
|
+
token: prior.token,
|
|
74
|
+
body: { token: prior.token },
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Best-effort; the new login is already stored.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
deletePendingLogin(deps);
|
|
82
|
+
const label = login ? `@${login}` : "your GitHub account";
|
|
83
|
+
deps.io.stdout(`Connected as ${label}\n`);
|
|
84
|
+
return EXIT_OK;
|
|
85
|
+
}
|
|
86
|
+
if (err === "authorization_pending") {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (err === "slow_down") {
|
|
90
|
+
intervalMs += 5000;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (err === "access_denied" || err === "expired_token" || err === "invalid_grant") {
|
|
94
|
+
deletePendingLogin(deps);
|
|
95
|
+
throw actionError(body.error_description ?? body.message ?? err, {
|
|
96
|
+
kind: "approve",
|
|
97
|
+
humanPrompt: body.error_description ??
|
|
98
|
+
"The human denied or the code expired. Run `cleanslop login` again.",
|
|
99
|
+
url: device.verificationUriComplete,
|
|
100
|
+
code: device.userCode,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
throw new CliError(body.error_description ?? body.message ?? "Token poll failed.", EXIT_ACTION);
|
|
104
|
+
}
|
|
105
|
+
deletePendingLogin(deps);
|
|
106
|
+
throw actionError("Device login timed out.", {
|
|
107
|
+
kind: "approve",
|
|
108
|
+
humanPrompt: "The device code expired. Run `cleanslop login` again.",
|
|
109
|
+
url: device.verificationUriComplete,
|
|
110
|
+
code: device.userCode,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
export async function runLogin(deps, args) {
|
|
114
|
+
if (args.link) {
|
|
115
|
+
return runLinkLogin(deps, args);
|
|
116
|
+
}
|
|
117
|
+
if (args.noWait && args.resume) {
|
|
118
|
+
throw usageError("Use either --no-wait or --resume, not both.");
|
|
119
|
+
}
|
|
120
|
+
const origin = resolveOrigin(deps);
|
|
121
|
+
if (args.resume) {
|
|
122
|
+
const pending = readPendingLogin(deps);
|
|
123
|
+
if (!pending || pending.origin !== origin) {
|
|
124
|
+
throw actionError("No pending device login for this origin.", {
|
|
125
|
+
kind: "approve",
|
|
126
|
+
humanPrompt: "Run `cleanslop login --no-wait` and ask the human to approve the code.",
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
if (deps.clock.now() >= devicePollDeadline(pending.expiresAt)) {
|
|
130
|
+
deletePendingLogin(deps);
|
|
131
|
+
throw actionError("The pending device code expired.", {
|
|
132
|
+
kind: "approve",
|
|
133
|
+
humanPrompt: "Run `cleanslop login` again.",
|
|
134
|
+
url: pending.verificationUriComplete,
|
|
135
|
+
code: pending.userCode,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
printApproval(deps, {
|
|
139
|
+
verificationUriComplete: pending.verificationUriComplete,
|
|
140
|
+
userCode: pending.userCode,
|
|
141
|
+
});
|
|
142
|
+
return pollDeviceToken(deps, origin, {
|
|
143
|
+
deviceCode: pending.deviceCode,
|
|
144
|
+
userCode: pending.userCode,
|
|
145
|
+
verificationUriComplete: pending.verificationUriComplete,
|
|
146
|
+
interval: pending.interval,
|
|
147
|
+
expiresAt: pending.expiresAt,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
const started = await httpRequest(deps, origin, "POST", "/oauth/device_authorization", {
|
|
151
|
+
body: {
|
|
152
|
+
client_id: CLIENT_ID,
|
|
153
|
+
client: { name: CLIENT_ID, version: PACKAGE_VERSION },
|
|
154
|
+
agent: detectAgentHint(deps.env),
|
|
155
|
+
host: deps.env.hostname().slice(0, 64),
|
|
156
|
+
repo: await repoHint(deps),
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
if (started.status >= 400) {
|
|
160
|
+
const body = asErrorBody(started.json);
|
|
161
|
+
throw new CliError(body.message ?? body.error_description ?? "Could not start device login.", started.status === 503 ? EXIT_UNEXPECTED : EXIT_ACTION);
|
|
162
|
+
}
|
|
163
|
+
const device = started.json;
|
|
164
|
+
if (!device ||
|
|
165
|
+
typeof device.device_code !== "string" ||
|
|
166
|
+
typeof device.user_code !== "string" ||
|
|
167
|
+
typeof device.verification_uri_complete !== "string") {
|
|
168
|
+
throw new CliError("Device authorization response was invalid.", EXIT_UNEXPECTED);
|
|
169
|
+
}
|
|
170
|
+
const intervalSec = Math.max(3, Number(device.interval) || 5);
|
|
171
|
+
const expiresSec = Number(device.expires_in);
|
|
172
|
+
const ttlSec = Number.isFinite(expiresSec) ? expiresSec : 600;
|
|
173
|
+
const expiresAt = deps.clock.now() + ttlSec * 1000;
|
|
174
|
+
printApproval(deps, {
|
|
175
|
+
verificationUriComplete: device.verification_uri_complete,
|
|
176
|
+
userCode: device.user_code,
|
|
177
|
+
});
|
|
178
|
+
if (args.noWait) {
|
|
179
|
+
await writePendingLogin(deps, {
|
|
180
|
+
version: 1,
|
|
181
|
+
origin,
|
|
182
|
+
deviceCode: device.device_code,
|
|
183
|
+
userCode: device.user_code,
|
|
184
|
+
verificationUriComplete: device.verification_uri_complete,
|
|
185
|
+
expiresAt,
|
|
186
|
+
interval: intervalSec,
|
|
187
|
+
});
|
|
188
|
+
return EXIT_ACTION;
|
|
189
|
+
}
|
|
190
|
+
return pollDeviceToken(deps, origin, {
|
|
191
|
+
deviceCode: device.device_code,
|
|
192
|
+
userCode: device.user_code,
|
|
193
|
+
verificationUriComplete: device.verification_uri_complete,
|
|
194
|
+
interval: intervalSec,
|
|
195
|
+
expiresAt,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,WAAW,EACX,QAAQ,EACR,WAAW,EACX,OAAO,EACP,eAAe,EACf,UAAU,GACX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,kFAAkF;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEnD,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,OAAO,SAAS,GAAG,oBAAoB,CAAC;AAC1C,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,IAAa;IACnC,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IACpD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAC;IACpE,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IACjC,OAAO,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;AACpD,CAAC;AAED,SAAS,aAAa,CAAC,IAAa,EAAE,MAGrC;IACC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,uBAAuB,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,MAAM,CACZ;QACE,oCAAoC;QACpC,EAAE;QACF,yBAAyB,MAAM,CAAC,uBAAuB,qBAAqB,MAAM,CAAC,QAAQ,GAAG;QAC9F,qCAAqC;QACrC,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,IAAa,EACb,MAAc,EACd,MAMC;IAED,IAAI,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACrD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAEtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACnC,IAAI,QAAQ,CAAC;QACb,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE;gBACjE,IAAI,EAAE;oBACJ,UAAU,EAAE,iBAAiB;oBAC7B,WAAW,EAAE,MAAM,CAAC,UAAU;oBAC9B,SAAS,EAAE,SAAS;iBACrB;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;gBAChE,SAAS;YACX,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACvB,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAkC,CAAC;YAC3D,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,IAAI,QAAQ,CAAC,0CAA0C,EAAE,eAAe,CAAC,CAAC;YAClF,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,EAAE,YAAY,IAAI,IAAI,CAAC;YACnD,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC5C,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE;gBAC7B,KAAK,EAAE,MAAM,CAAC,YAAY;gBAC1B,WAAW,EAAE,KAAK;gBAClB,OAAO,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI;aACjC,CAAC,CAAC;YACH,IAAI,KAAK,EAAE,KAAK,EAAE,CAAC;gBACjB,IAAI,CAAC;oBACH,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE;wBACvD,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;qBAC7B,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,gDAAgD;gBAClD,CAAC;YACH,CAAC;YACD,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC;YAC1D,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,KAAK,IAAI,CAAC,CAAC;YAC1C,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,GAAG,KAAK,uBAAuB,EAAE,CAAC;YACpC,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACxB,UAAU,IAAI,IAAI,CAAC;YACnB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,eAAe,IAAI,GAAG,KAAK,eAAe,IAAI,GAAG,KAAK,eAAe,EAAE,CAAC;YAClF,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,MAAM,WAAW,CACf,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,OAAO,IAAI,GAAG,EAC7C;gBACE,IAAI,EAAE,SAAS;gBACf,WAAW,EACT,IAAI,CAAC,iBAAiB;oBACtB,oEAAoE;gBACtE,GAAG,EAAE,MAAM,CAAC,uBAAuB;gBACnC,IAAI,EAAE,MAAM,CAAC,QAAQ;aACtB,CACF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,QAAQ,CAChB,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,OAAO,IAAI,oBAAoB,EAC9D,WAAW,CACZ,CAAC;IACJ,CAAC;IAED,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACzB,MAAM,WAAW,CAAC,yBAAyB,EAAE;QAC3C,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,uDAAuD;QACpE,GAAG,EAAE,MAAM,CAAC,uBAAuB;QACnC,IAAI,EAAE,MAAM,CAAC,QAAQ;KACtB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAa,EACb,IAAgB;IAEhB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/B,MAAM,UAAU,CAAC,6CAA6C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC1C,MAAM,WAAW,CAAC,0CAA0C,EAAE;gBAC5D,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,wEAAwE;aACtF,CAAC,CAAC;QACL,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9D,kBAAkB,CAAC,IAAI,CAAC,CAAC;YACzB,MAAM,WAAW,CAAC,kCAAkC,EAAE;gBACpD,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,8BAA8B;gBAC3C,GAAG,EAAE,OAAO,CAAC,uBAAuB;gBACpC,IAAI,EAAE,OAAO,CAAC,QAAQ;aACvB,CAAC,CAAC;QACL,CAAC;QACD,aAAa,CAAC,IAAI,EAAE;YAClB,uBAAuB,EAAE,OAAO,CAAC,uBAAuB;YACxD,QAAQ,EAAE,OAAO,CAAC,QAAQ;SAC3B,CAAC,CAAC;QACH,OAAO,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE;YACnC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,uBAAuB,EAAE,OAAO,CAAC,uBAAuB;YACxD,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,WAAW,CAC/B,IAAI,EACJ,MAAM,EACN,MAAM,EACN,6BAA6B,EAC7B;QACE,IAAI,EAAE;YACJ,SAAS,EAAE,SAAS;YACpB,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE;YACrD,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;YAChC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC;SAC3B;KACF,CACF,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,IAAI,QAAQ,CAChB,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,iBAAiB,IAAI,+BAA+B,EACzE,OAAO,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,CACvD,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAkC,CAAC;IAC1D,IACE,CAAC,MAAM;QACP,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ;QACtC,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QACpC,OAAO,MAAM,CAAC,yBAAyB,KAAK,QAAQ,EACpD,CAAC;QACD,MAAM,IAAI,QAAQ,CAAC,4CAA4C,EAAE,eAAe,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;IAEnD,aAAa,CAAC,IAAI,EAAE;QAClB,uBAAuB,EAAE,MAAM,CAAC,yBAAyB;QACzD,QAAQ,EAAE,MAAM,CAAC,SAAS;KAC3B,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,iBAAiB,CAAC,IAAI,EAAE;YAC5B,OAAO,EAAE,CAAC;YACV,MAAM;YACN,UAAU,EAAE,MAAM,CAAC,WAAW;YAC9B,QAAQ,EAAE,MAAM,CAAC,SAAS;YAC1B,uBAAuB,EAAE,MAAM,CAAC,yBAAyB;YACzD,SAAS;YACT,QAAQ,EAAE,WAAW;SACtB,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,OAAO,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE;QACnC,UAAU,EAAE,MAAM,CAAC,WAAW;QAC9B,QAAQ,EAAE,MAAM,CAAC,SAAS;QAC1B,uBAAuB,EAAE,MAAM,CAAC,yBAAyB;QACzD,QAAQ,EAAE,WAAW;QACrB,SAAS;KACV,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { deleteOriginCreds, deletePendingLogin, resolveOrigin, resolveToken, } from "../credentials.js";
|
|
2
|
+
import { EXIT_OK, EXIT_UNEXPECTED } from "../exit.js";
|
|
3
|
+
import { httpRequest } from "../http.js";
|
|
4
|
+
export async function runLogout(deps) {
|
|
5
|
+
const origin = resolveOrigin(deps);
|
|
6
|
+
const creds = resolveToken(deps, origin);
|
|
7
|
+
let revokeFailed = false;
|
|
8
|
+
if (creds) {
|
|
9
|
+
try {
|
|
10
|
+
const result = await httpRequest(deps, origin, "POST", "/oauth/revoke", {
|
|
11
|
+
token: creds.token,
|
|
12
|
+
body: { token: creds.token },
|
|
13
|
+
});
|
|
14
|
+
if (result.status < 200 || result.status >= 300) {
|
|
15
|
+
deps.io.stderr(`Could not revoke the token (HTTP ${result.status}).\n`);
|
|
16
|
+
revokeFailed = true;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
21
|
+
deps.io.stderr(`Could not revoke the token: ${message}\n`);
|
|
22
|
+
revokeFailed = true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (creds?.source !== "env") {
|
|
26
|
+
await deleteOriginCreds(deps, origin);
|
|
27
|
+
}
|
|
28
|
+
deletePendingLogin(deps);
|
|
29
|
+
if (creds?.source === "env") {
|
|
30
|
+
deps.io.stdout("Disconnected. File credentials were left in place because CLEANSLOP_TOKEN is set.\n");
|
|
31
|
+
return EXIT_OK;
|
|
32
|
+
}
|
|
33
|
+
if (revokeFailed) {
|
|
34
|
+
deps.io.stdout("Removed local credentials, but the server did not confirm revocation. Revoke this agent under Account → Connected agents.\n");
|
|
35
|
+
return EXIT_UNEXPECTED;
|
|
36
|
+
}
|
|
37
|
+
deps.io.stdout("Disconnected.\n");
|
|
38
|
+
return EXIT_OK;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,aAAa,EACb,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAa;IAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE;gBACtE,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;aAC7B,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBAChD,IAAI,CAAC,EAAE,CAAC,MAAM,CACZ,oCAAoC,MAAM,CAAC,MAAM,MAAM,CACxD,CAAC;gBACF,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,+BAA+B,OAAO,IAAI,CAAC,CAAC;YAC3D,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IACD,IAAI,KAAK,EAAE,MAAM,KAAK,KAAK,EAAE,CAAC;QAC5B,MAAM,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IACD,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACzB,IAAI,KAAK,EAAE,MAAM,KAAK,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,EAAE,CAAC,MAAM,CACZ,qFAAqF,CACtF,CAAC;QACF,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC,EAAE,CAAC,MAAM,CACZ,6HAA6H,CAC9H,CAAC;QACF,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAClC,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CliDeps } from "../deps.js";
|
|
2
|
+
import type { ParsedArgs } from "../types.js";
|
|
3
|
+
export declare function resolveScanId(deps: CliDeps, origin: string, id: string | null): string;
|
|
4
|
+
export declare function fetchReport(deps: CliDeps, origin: string, token: string, scanId: string, format: "md" | "json", preview: boolean): Promise<{
|
|
5
|
+
markdown: string | null;
|
|
6
|
+
report: unknown | null;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function runReport(deps: CliDeps, args: ParsedArgs): Promise<number>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { requireToken, resolveOrigin, peekStoredCreds, } from "../credentials.js";
|
|
2
|
+
import { CliError, EXIT_OK, EXIT_RUNNING, usageError } from "../exit.js";
|
|
3
|
+
import { asErrorBody, httpRequest, requireOk } from "../http.js";
|
|
4
|
+
import { writeJson, writeMarkdownReport } from "../output.js";
|
|
5
|
+
import { writeResume } from "../action.js";
|
|
6
|
+
export function resolveScanId(deps, origin, id) {
|
|
7
|
+
if (id)
|
|
8
|
+
return id;
|
|
9
|
+
const stored = peekStoredCreds(deps, origin);
|
|
10
|
+
if (stored?.lastScanId)
|
|
11
|
+
return stored.lastScanId;
|
|
12
|
+
throw usageError("Pass a scan id or run a scan first.");
|
|
13
|
+
}
|
|
14
|
+
export async function fetchReport(deps, origin, token, scanId, format, preview) {
|
|
15
|
+
const params = new URLSearchParams({ format });
|
|
16
|
+
if (preview)
|
|
17
|
+
params.set("preview", "1");
|
|
18
|
+
const result = await httpRequest(deps, origin, "GET", `/api/agent/v1/scans/${encodeURIComponent(scanId)}/report?${params.toString()}`, {
|
|
19
|
+
token,
|
|
20
|
+
accept: format === "md" ? "text/markdown, application/json" : "application/json",
|
|
21
|
+
});
|
|
22
|
+
if (result.status === 409) {
|
|
23
|
+
const body = asErrorBody(result.json);
|
|
24
|
+
if (body.error === "report_not_ready") {
|
|
25
|
+
throw new CliError(body.message ?? "Report is not ready yet.", EXIT_RUNNING);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
requireOk(result);
|
|
29
|
+
if (format === "md") {
|
|
30
|
+
return { markdown: result.text, report: result.json };
|
|
31
|
+
}
|
|
32
|
+
return { markdown: null, report: result.json };
|
|
33
|
+
}
|
|
34
|
+
export async function runReport(deps, args) {
|
|
35
|
+
const origin = resolveOrigin(deps);
|
|
36
|
+
const creds = requireToken(deps, origin);
|
|
37
|
+
const scanId = resolveScanId(deps, origin, args.id);
|
|
38
|
+
try {
|
|
39
|
+
const fetched = await fetchReport(deps, origin, creds.token, scanId, args.json ? "json" : args.format, args.preview);
|
|
40
|
+
if (args.json) {
|
|
41
|
+
writeJson(deps, fetched.report);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
writeMarkdownReport(deps, fetched.markdown ?? "");
|
|
45
|
+
}
|
|
46
|
+
return EXIT_OK;
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
if (err instanceof CliError && err.exitCode === EXIT_RUNNING) {
|
|
50
|
+
writeResume(deps, scanId);
|
|
51
|
+
}
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/commands/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { writeAction, writeResume } from "../action.js";
|
|
2
|
+
import { requireToken, resolveOrigin, storeLastScanId, } from "../credentials.js";
|
|
3
|
+
import { CliError, EXIT_OK, EXIT_RUNNING, EXIT_SCAN_FAILED, EXIT_UNEXPECTED } from "../exit.js";
|
|
4
|
+
import { recoverOutOfScansIfOffered } from "./credits.js";
|
|
5
|
+
import { httpRequest, requireOk } from "../http.js";
|
|
6
|
+
import { writeJson, writeMarkdownReport, writeScanProgress } from "../output.js";
|
|
7
|
+
import { formatPackSummary, packManifest, planPack, writePackArchive, } from "../pack.js";
|
|
8
|
+
import { fetchReport } from "./report.js";
|
|
9
|
+
import { isScanFinal, waitForScan } from "../wait.js";
|
|
10
|
+
export async function runUploadScan(deps, args) {
|
|
11
|
+
const origin = resolveOrigin(deps);
|
|
12
|
+
const creds = requireToken(deps, origin);
|
|
13
|
+
const plan = await planPack(deps);
|
|
14
|
+
deps.io.stderr(formatPackSummary(plan, args.dryRun));
|
|
15
|
+
if (args.dryRun)
|
|
16
|
+
return EXIT_OK;
|
|
17
|
+
const archive = await writePackArchive(plan);
|
|
18
|
+
const uploaded = await httpRequest(deps, origin, "POST", "/api/agent/v1/uploads", {
|
|
19
|
+
token: creds.token,
|
|
20
|
+
rawBody: new Uint8Array(archive.bytes),
|
|
21
|
+
contentType: "application/gzip",
|
|
22
|
+
headers: {
|
|
23
|
+
"CleanSlop-Upload-Manifest": JSON.stringify(packManifest(plan, archive.sha256)),
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
requireOk(uploaded);
|
|
27
|
+
const rec = uploaded.json;
|
|
28
|
+
if (!rec || typeof rec.uploadId !== "string") {
|
|
29
|
+
throw new CliError("Upload response was missing uploadId.", EXIT_UNEXPECTED);
|
|
30
|
+
}
|
|
31
|
+
const headers = {};
|
|
32
|
+
if (args.force)
|
|
33
|
+
headers["Idempotency-Key"] = deps.randomId();
|
|
34
|
+
const startBody = {
|
|
35
|
+
uploadId: rec.uploadId,
|
|
36
|
+
force: args.force || undefined,
|
|
37
|
+
surface: "cli",
|
|
38
|
+
};
|
|
39
|
+
const postStart = () => httpRequest(deps, origin, "POST", "/api/agent/v1/scans", {
|
|
40
|
+
token: creds.token,
|
|
41
|
+
headers,
|
|
42
|
+
body: startBody,
|
|
43
|
+
});
|
|
44
|
+
const started = await recoverOutOfScansIfOffered(deps, args, await postStart(), postStart);
|
|
45
|
+
requireOk(started);
|
|
46
|
+
const payload = started.json;
|
|
47
|
+
if (!payload?.scan?.id) {
|
|
48
|
+
throw new CliError("Scan create response was invalid.", EXIT_UNEXPECTED);
|
|
49
|
+
}
|
|
50
|
+
const scan0 = payload.scan;
|
|
51
|
+
await storeLastScanId(deps, origin, scan0.id);
|
|
52
|
+
writeScanProgress(deps, scan0);
|
|
53
|
+
let scan = scan0;
|
|
54
|
+
if (!isScanFinal(scan) && args.wait) {
|
|
55
|
+
scan = await waitForScan(deps, origin, creds.token, scan0.id, args.waitMs);
|
|
56
|
+
writeScanProgress(deps, scan);
|
|
57
|
+
}
|
|
58
|
+
if (scan.status === "failed") {
|
|
59
|
+
throw new CliError(scan.error?.message ?? "Scan failed.", EXIT_SCAN_FAILED);
|
|
60
|
+
}
|
|
61
|
+
const wantReport = isScanFinal(scan) || args.preview;
|
|
62
|
+
if (!wantReport) {
|
|
63
|
+
writeResume(deps, scan.id);
|
|
64
|
+
throw new CliError("Scan is still running.", EXIT_RUNNING);
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const fetched = await fetchReport(deps, origin, creds.token, scan.id, args.json ? "json" : "md", args.preview && !scan.final);
|
|
68
|
+
if (args.json) {
|
|
69
|
+
writeJson(deps, { scan, report: fetched.report });
|
|
70
|
+
}
|
|
71
|
+
else if (fetched.markdown) {
|
|
72
|
+
writeMarkdownReport(deps, fetched.markdown);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
if (err instanceof CliError && err.exitCode === EXIT_RUNNING) {
|
|
77
|
+
writeResume(deps, scan.id);
|
|
78
|
+
if (err.action)
|
|
79
|
+
writeAction(deps, err.action);
|
|
80
|
+
}
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
return EXIT_OK;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=scan-upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-upload.js","sourceRoot":"","sources":["../../src/commands/scan-upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { writeAction, writeResume } from "../action.js";
|
|
2
|
+
import { requireToken, resolveOrigin, storeLastScanId, } from "../credentials.js";
|
|
3
|
+
import { CliError, EXIT_OK, EXIT_RUNNING, EXIT_SCAN_FAILED, EXIT_UNEXPECTED, } from "../exit.js";
|
|
4
|
+
import { assertGithubReady, inspectGit } from "../git.js";
|
|
5
|
+
import { recoverOutOfScansIfOffered } from "./credits.js";
|
|
6
|
+
import { httpRequest, requireOk } from "../http.js";
|
|
7
|
+
import { writeJson, writeMarkdownReport, writeScanProgress } from "../output.js";
|
|
8
|
+
import { fetchReport } from "./report.js";
|
|
9
|
+
import { runUploadScan } from "./scan-upload.js";
|
|
10
|
+
import { isScanFinal, waitForScan } from "../wait.js";
|
|
11
|
+
export async function runScan(deps, args) {
|
|
12
|
+
const origin = resolveOrigin(deps);
|
|
13
|
+
const creds = requireToken(deps, origin);
|
|
14
|
+
const meRes = await httpRequest(deps, origin, "GET", "/api/agent/v1/me", {
|
|
15
|
+
token: creds.token,
|
|
16
|
+
});
|
|
17
|
+
requireOk(meRes);
|
|
18
|
+
const me = (meRes.json ?? {});
|
|
19
|
+
if (me.uploads === true) {
|
|
20
|
+
return runUploadScan(deps, args);
|
|
21
|
+
}
|
|
22
|
+
const git = await inspectGit(deps);
|
|
23
|
+
assertGithubReady(git);
|
|
24
|
+
const headers = {};
|
|
25
|
+
if (args.force) {
|
|
26
|
+
headers["Idempotency-Key"] = deps.randomId();
|
|
27
|
+
}
|
|
28
|
+
const startBody = {
|
|
29
|
+
remote: git.remote,
|
|
30
|
+
commitSha: git.commitSha,
|
|
31
|
+
branch: git.branch,
|
|
32
|
+
force: args.force || undefined,
|
|
33
|
+
surface: "cli",
|
|
34
|
+
};
|
|
35
|
+
const postStart = () => httpRequest(deps, origin, "POST", "/api/agent/v1/scans", {
|
|
36
|
+
token: creds.token,
|
|
37
|
+
headers,
|
|
38
|
+
body: startBody,
|
|
39
|
+
});
|
|
40
|
+
const started = await recoverOutOfScansIfOffered(deps, args, await postStart(), postStart);
|
|
41
|
+
requireOk(started);
|
|
42
|
+
const payload = started.json;
|
|
43
|
+
if (!payload?.scan?.id) {
|
|
44
|
+
throw new CliError("Scan create response was invalid.", EXIT_UNEXPECTED);
|
|
45
|
+
}
|
|
46
|
+
const scan0 = payload.scan;
|
|
47
|
+
await storeLastScanId(deps, origin, scan0.id);
|
|
48
|
+
writeScanProgress(deps, scan0);
|
|
49
|
+
let scan = scan0;
|
|
50
|
+
if (!isScanFinal(scan) && args.wait) {
|
|
51
|
+
scan = await waitForScan(deps, origin, creds.token, scan0.id, args.waitMs);
|
|
52
|
+
writeScanProgress(deps, scan);
|
|
53
|
+
}
|
|
54
|
+
if (scan.status === "failed") {
|
|
55
|
+
throw new CliError(scan.error?.message ?? "Scan failed.", EXIT_SCAN_FAILED);
|
|
56
|
+
}
|
|
57
|
+
const wantReport = isScanFinal(scan) || args.preview;
|
|
58
|
+
if (!wantReport) {
|
|
59
|
+
writeResume(deps, scan.id, scan);
|
|
60
|
+
throw new CliError("Scan is still running.", EXIT_RUNNING);
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const fetched = await fetchReport(deps, origin, creds.token, scan.id, args.json ? "json" : "md", args.preview && !scan.final);
|
|
64
|
+
if (args.json) {
|
|
65
|
+
writeJson(deps, { scan, report: fetched.report });
|
|
66
|
+
}
|
|
67
|
+
else if (fetched.markdown) {
|
|
68
|
+
writeMarkdownReport(deps, fetched.markdown);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
if (err instanceof CliError && err.exitCode === EXIT_RUNNING) {
|
|
73
|
+
writeResume(deps, scan.id, scan);
|
|
74
|
+
if (err.action)
|
|
75
|
+
writeAction(deps, err.action);
|
|
76
|
+
}
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
return EXIT_OK;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../src/commands/scan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CliDeps } from "../deps.js";
|
|
2
|
+
export type SetupTarget = {
|
|
3
|
+
id: "claude" | "cursor" | "codex" | "agents";
|
|
4
|
+
label: string;
|
|
5
|
+
path: string;
|
|
6
|
+
kind: "owned" | "marker";
|
|
7
|
+
render: (core: string) => string;
|
|
8
|
+
};
|
|
9
|
+
export declare function setupTargets(deps: CliDeps, project: boolean): SetupTarget[];
|
|
10
|
+
export declare function runSetup(deps: CliDeps, args: {
|
|
11
|
+
dryRun: boolean;
|
|
12
|
+
uninstall: boolean;
|
|
13
|
+
project: boolean;
|
|
14
|
+
yes: boolean;
|
|
15
|
+
}): Promise<number>;
|
|
16
|
+
export declare const SETUP_MARKERS: {
|
|
17
|
+
begin: string;
|
|
18
|
+
end: string;
|
|
19
|
+
};
|