@cleanslop/cli 0.0.0-stage → 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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
package/dist/skill.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { SKILL_MARKER_BEGIN, SKILL_MARKER_END } from "./config.js";
|
|
5
|
+
export const SKILL_HEADINGS = [
|
|
6
|
+
"When to scan",
|
|
7
|
+
"Git preconditions",
|
|
8
|
+
"Transport",
|
|
9
|
+
"Connect with Link",
|
|
10
|
+
"Relay human actions",
|
|
11
|
+
"Waiting",
|
|
12
|
+
"Reading the report",
|
|
13
|
+
"Fix loop",
|
|
14
|
+
"Stop conditions",
|
|
15
|
+
"Report back",
|
|
16
|
+
"Email",
|
|
17
|
+
"Never print tokens",
|
|
18
|
+
];
|
|
19
|
+
export function skillCorePath() {
|
|
20
|
+
return join(dirname(fileURLToPath(import.meta.url)), "..", "assets", "skill-core.md");
|
|
21
|
+
}
|
|
22
|
+
export function loadSkillCore(readFile = defaultRead) {
|
|
23
|
+
return readFile(skillCorePath()).replace(/\s+$/, "") + "\n";
|
|
24
|
+
}
|
|
25
|
+
function defaultRead(path) {
|
|
26
|
+
return readFileSync(path, "utf8");
|
|
27
|
+
}
|
|
28
|
+
export function renderSkillMd(core) {
|
|
29
|
+
const body = core.trim();
|
|
30
|
+
return [
|
|
31
|
+
"---",
|
|
32
|
+
"name: cleanslop",
|
|
33
|
+
"description: Run a CleanSlop readiness scan before claiming a change is done. Use at milestones, before a PR, or when asked to scan.",
|
|
34
|
+
"---",
|
|
35
|
+
"",
|
|
36
|
+
"# CleanSlop",
|
|
37
|
+
"",
|
|
38
|
+
body,
|
|
39
|
+
"",
|
|
40
|
+
].join("\n");
|
|
41
|
+
}
|
|
42
|
+
export function renderCursorMdc(core) {
|
|
43
|
+
const body = core.trim();
|
|
44
|
+
return [
|
|
45
|
+
"---",
|
|
46
|
+
"description: CleanSlop readiness scan — run before claiming work is done",
|
|
47
|
+
"alwaysApply: true",
|
|
48
|
+
"---",
|
|
49
|
+
"",
|
|
50
|
+
body,
|
|
51
|
+
"",
|
|
52
|
+
].join("\n");
|
|
53
|
+
}
|
|
54
|
+
export function renderAgentsSnippet(core) {
|
|
55
|
+
const body = core.trim();
|
|
56
|
+
return [
|
|
57
|
+
SKILL_MARKER_BEGIN,
|
|
58
|
+
"",
|
|
59
|
+
"## CleanSlop readiness scan",
|
|
60
|
+
"",
|
|
61
|
+
body,
|
|
62
|
+
"",
|
|
63
|
+
SKILL_MARKER_END,
|
|
64
|
+
"",
|
|
65
|
+
].join("\n");
|
|
66
|
+
}
|
|
67
|
+
export function wrapOwnedFile(content) {
|
|
68
|
+
const trimmed = content.replace(/\s+$/, "");
|
|
69
|
+
if (trimmed.includes(SKILL_MARKER_BEGIN) && trimmed.includes(SKILL_MARKER_END)) {
|
|
70
|
+
return `${trimmed}\n`;
|
|
71
|
+
}
|
|
72
|
+
return `${SKILL_MARKER_BEGIN}\n${trimmed}\n${SKILL_MARKER_END}\n`;
|
|
73
|
+
}
|
|
74
|
+
export function upsertMarkerBlock(existing, block) {
|
|
75
|
+
const begin = existing.indexOf(SKILL_MARKER_BEGIN);
|
|
76
|
+
const end = existing.indexOf(SKILL_MARKER_END);
|
|
77
|
+
if (begin >= 0 && end > begin) {
|
|
78
|
+
const afterEnd = end + SKILL_MARKER_END.length;
|
|
79
|
+
const before = existing.slice(0, begin);
|
|
80
|
+
let after = existing.slice(afterEnd);
|
|
81
|
+
if (after.startsWith("\n"))
|
|
82
|
+
after = after.slice(1);
|
|
83
|
+
const prefix = before.endsWith("\n") || before.length === 0 ? before : `${before}\n`;
|
|
84
|
+
return `${prefix}${block}${after.startsWith("\n") || after.length === 0 ? after : `\n${after}`}`;
|
|
85
|
+
}
|
|
86
|
+
const prefix = existing.length === 0 || existing.endsWith("\n") ? existing : `${existing}\n`;
|
|
87
|
+
const spacer = prefix.length === 0 || prefix.endsWith("\n\n") ? "" : "\n";
|
|
88
|
+
return `${prefix}${spacer}${block}`;
|
|
89
|
+
}
|
|
90
|
+
export function removeMarkerBlock(existing) {
|
|
91
|
+
const begin = existing.indexOf(SKILL_MARKER_BEGIN);
|
|
92
|
+
const end = existing.indexOf(SKILL_MARKER_END);
|
|
93
|
+
if (begin < 0 || end < begin)
|
|
94
|
+
return existing;
|
|
95
|
+
const afterEnd = end + SKILL_MARKER_END.length;
|
|
96
|
+
const before = existing.slice(0, begin);
|
|
97
|
+
let after = existing.slice(afterEnd);
|
|
98
|
+
if (after.startsWith("\n"))
|
|
99
|
+
after = after.slice(1);
|
|
100
|
+
return `${before}${after}`.replace(/\n{3,}/g, "\n\n");
|
|
101
|
+
}
|
|
102
|
+
export function assertSkillCoreComplete(core) {
|
|
103
|
+
const missing = [];
|
|
104
|
+
for (const heading of SKILL_HEADINGS) {
|
|
105
|
+
if (!core.includes(`## ${heading}`))
|
|
106
|
+
missing.push(heading);
|
|
107
|
+
}
|
|
108
|
+
return missing;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export type CommandName = "scan" | "login" | "logout" | "whoami" | "status" | "report" | "setup" | "email" | "link-identity" | "credits";
|
|
2
|
+
export type ReportFormat = "md" | "json";
|
|
3
|
+
export type ParsedArgs = {
|
|
4
|
+
command: CommandName;
|
|
5
|
+
help: boolean;
|
|
6
|
+
version: boolean;
|
|
7
|
+
id: string | null;
|
|
8
|
+
json: boolean;
|
|
9
|
+
wait: boolean;
|
|
10
|
+
waitMs: number;
|
|
11
|
+
noWait: boolean;
|
|
12
|
+
resume: boolean;
|
|
13
|
+
force: boolean;
|
|
14
|
+
preview: boolean;
|
|
15
|
+
format: ReportFormat;
|
|
16
|
+
dryRun: boolean;
|
|
17
|
+
uninstall: boolean;
|
|
18
|
+
project: boolean;
|
|
19
|
+
yes: boolean;
|
|
20
|
+
consent: string | null;
|
|
21
|
+
reply: string | null;
|
|
22
|
+
link: boolean;
|
|
23
|
+
acceptTerms: boolean;
|
|
24
|
+
yesShareEmail: boolean;
|
|
25
|
+
pack: string | null;
|
|
26
|
+
amount: number | null;
|
|
27
|
+
networkId: string | null;
|
|
28
|
+
spendRequestId: string | null;
|
|
29
|
+
};
|
|
30
|
+
export type AgentScan = {
|
|
31
|
+
id: string;
|
|
32
|
+
status: string;
|
|
33
|
+
final: boolean;
|
|
34
|
+
source?: string;
|
|
35
|
+
project?: {
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
};
|
|
39
|
+
commitSha?: string | null;
|
|
40
|
+
findingCount?: number;
|
|
41
|
+
elapsedSec?: number;
|
|
42
|
+
eta?: {
|
|
43
|
+
minSec: number;
|
|
44
|
+
maxSec: number;
|
|
45
|
+
} | null;
|
|
46
|
+
progress?: {
|
|
47
|
+
phase: string;
|
|
48
|
+
label: string;
|
|
49
|
+
percent?: number;
|
|
50
|
+
step?: number;
|
|
51
|
+
steps?: number;
|
|
52
|
+
} | null;
|
|
53
|
+
error?: {
|
|
54
|
+
code: string;
|
|
55
|
+
message: string;
|
|
56
|
+
} | null;
|
|
57
|
+
pollAfterSec?: number;
|
|
58
|
+
next?: {
|
|
59
|
+
action: string;
|
|
60
|
+
afterSec: number;
|
|
61
|
+
message: string;
|
|
62
|
+
};
|
|
63
|
+
links?: {
|
|
64
|
+
report_md?: string;
|
|
65
|
+
report_json?: string;
|
|
66
|
+
web?: string;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export type AgentErrorBody = {
|
|
70
|
+
error?: string;
|
|
71
|
+
message?: string;
|
|
72
|
+
error_description?: string;
|
|
73
|
+
action?: {
|
|
74
|
+
kind?: string;
|
|
75
|
+
url?: string;
|
|
76
|
+
retryAfterSec?: number;
|
|
77
|
+
humanPrompt?: string;
|
|
78
|
+
};
|
|
79
|
+
[key: string]: unknown;
|
|
80
|
+
};
|
|
81
|
+
export type MeResponse = {
|
|
82
|
+
user?: {
|
|
83
|
+
githubLogin?: string | null;
|
|
84
|
+
emailMasked?: string | null;
|
|
85
|
+
emailVerified?: boolean;
|
|
86
|
+
};
|
|
87
|
+
grant?: {
|
|
88
|
+
id?: string;
|
|
89
|
+
label?: string;
|
|
90
|
+
scopes?: string;
|
|
91
|
+
};
|
|
92
|
+
quota?: {
|
|
93
|
+
plan?: string;
|
|
94
|
+
remaining?: number;
|
|
95
|
+
monthlyLeft?: number;
|
|
96
|
+
credits?: number;
|
|
97
|
+
};
|
|
98
|
+
links?: {
|
|
99
|
+
account?: string;
|
|
100
|
+
topUp?: string;
|
|
101
|
+
};
|
|
102
|
+
uploads?: boolean;
|
|
103
|
+
link?: {
|
|
104
|
+
verified?: boolean;
|
|
105
|
+
emailMasked?: string | null;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
export type DeviceStartResponse = {
|
|
109
|
+
device_code: string;
|
|
110
|
+
user_code: string;
|
|
111
|
+
verification_uri: string;
|
|
112
|
+
verification_uri_complete: string;
|
|
113
|
+
expires_in: number;
|
|
114
|
+
interval: number;
|
|
115
|
+
};
|
|
116
|
+
export type DeviceTokenResponse = {
|
|
117
|
+
access_token: string;
|
|
118
|
+
token_type?: string;
|
|
119
|
+
scope?: string;
|
|
120
|
+
grant_id?: string;
|
|
121
|
+
account?: {
|
|
122
|
+
github_login?: string | null;
|
|
123
|
+
email_masked?: string | null;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
export type StartScanResponse = {
|
|
127
|
+
scan: AgentScan;
|
|
128
|
+
created?: boolean;
|
|
129
|
+
deduped?: boolean;
|
|
130
|
+
charged?: string | null;
|
|
131
|
+
};
|
|
132
|
+
export type GitSnapshot = {
|
|
133
|
+
toplevel: string;
|
|
134
|
+
remote: string;
|
|
135
|
+
commitSha: string;
|
|
136
|
+
branch: string;
|
|
137
|
+
dirty: boolean;
|
|
138
|
+
unpushed: boolean;
|
|
139
|
+
github: {
|
|
140
|
+
owner: string;
|
|
141
|
+
repo: string;
|
|
142
|
+
fullName: string;
|
|
143
|
+
} | null;
|
|
144
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/ustar.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type UstarFile = {
|
|
2
|
+
name: string;
|
|
3
|
+
content: Buffer;
|
|
4
|
+
};
|
|
5
|
+
export declare function createUstar(files: readonly UstarFile[]): Buffer;
|
|
6
|
+
/** gzipSync with mtime 0 and OS=255 so the bytes match on every platform. */
|
|
7
|
+
export declare function gzipDeterministic(data: Buffer): Buffer;
|
package/dist/ustar.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { gzipSync } from "node:zlib";
|
|
2
|
+
const BLOCK = 512;
|
|
3
|
+
const USTAR_NAME = 100;
|
|
4
|
+
const USTAR_PREFIX = 155;
|
|
5
|
+
function writeOctal(buf, offset, length, value) {
|
|
6
|
+
const digits = length - 1;
|
|
7
|
+
const body = value.toString(8).padStart(digits, "0");
|
|
8
|
+
if (body.length > digits) {
|
|
9
|
+
throw new Error(`octal field overflow: ${value} needs more than ${digits} digits`);
|
|
10
|
+
}
|
|
11
|
+
buf.write(body, offset, digits, "ascii");
|
|
12
|
+
buf[offset + digits] = 0;
|
|
13
|
+
}
|
|
14
|
+
function writeBytes(buf, offset, max, value) {
|
|
15
|
+
const bytes = Buffer.from(value, "utf8");
|
|
16
|
+
if (bytes.length > max) {
|
|
17
|
+
throw new Error(`ustar field too long (${bytes.length} > ${max})`);
|
|
18
|
+
}
|
|
19
|
+
bytes.copy(buf, offset);
|
|
20
|
+
}
|
|
21
|
+
function paxRecord(keyword, value) {
|
|
22
|
+
const suffix = ` ${keyword}=${value}\n`;
|
|
23
|
+
let len = Buffer.byteLength(`${suffix.length}${suffix}`, "utf8");
|
|
24
|
+
for (let i = 0; i < 8; i += 1) {
|
|
25
|
+
const rec = `${len}${suffix}`;
|
|
26
|
+
const actual = Buffer.byteLength(rec, "utf8");
|
|
27
|
+
if (actual === len)
|
|
28
|
+
return Buffer.from(rec, "utf8");
|
|
29
|
+
len = actual;
|
|
30
|
+
}
|
|
31
|
+
throw new Error("pax record length did not converge");
|
|
32
|
+
}
|
|
33
|
+
function padToBlock(data) {
|
|
34
|
+
const rem = data.length % BLOCK;
|
|
35
|
+
if (rem === 0)
|
|
36
|
+
return data;
|
|
37
|
+
return Buffer.concat([data, Buffer.alloc(BLOCK - rem)]);
|
|
38
|
+
}
|
|
39
|
+
function splitUstarName(posixPath) {
|
|
40
|
+
const pathBytes = Buffer.byteLength(posixPath, "utf8");
|
|
41
|
+
if (pathBytes <= USTAR_NAME)
|
|
42
|
+
return { name: posixPath, prefix: "" };
|
|
43
|
+
const parts = posixPath.split("/");
|
|
44
|
+
for (let i = 1; i < parts.length; i += 1) {
|
|
45
|
+
const prefix = parts.slice(0, i).join("/");
|
|
46
|
+
const name = parts.slice(i).join("/");
|
|
47
|
+
if (Buffer.byteLength(prefix, "utf8") <= USTAR_PREFIX &&
|
|
48
|
+
Buffer.byteLength(name, "utf8") <= USTAR_NAME) {
|
|
49
|
+
return { name, prefix };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function ustarHeader(opts) {
|
|
55
|
+
const header = Buffer.alloc(BLOCK);
|
|
56
|
+
writeBytes(header, 0, USTAR_NAME, opts.name);
|
|
57
|
+
writeOctal(header, 100, 8, opts.mode);
|
|
58
|
+
writeOctal(header, 108, 8, 0);
|
|
59
|
+
writeOctal(header, 116, 8, 0);
|
|
60
|
+
writeOctal(header, 124, 12, opts.size);
|
|
61
|
+
writeOctal(header, 136, 12, 0);
|
|
62
|
+
header.fill(0x20, 148, 156);
|
|
63
|
+
header.write(opts.typeflag, 156, 1, "ascii");
|
|
64
|
+
header.write("ustar\0", 257, 6, "ascii");
|
|
65
|
+
header.write("00", 263, 2, "ascii");
|
|
66
|
+
writeBytes(header, 345, USTAR_PREFIX, opts.prefix);
|
|
67
|
+
let sum = 0;
|
|
68
|
+
for (let i = 0; i < BLOCK; i += 1)
|
|
69
|
+
sum += header[i];
|
|
70
|
+
const chk = `${sum.toString(8).padStart(6, "0")}\0 `;
|
|
71
|
+
header.write(chk, 148, 8, "ascii");
|
|
72
|
+
return header;
|
|
73
|
+
}
|
|
74
|
+
function shortNameForPax(posixPath, index) {
|
|
75
|
+
const base = posixPath.split("/").pop() || "file";
|
|
76
|
+
if (Buffer.byteLength(base, "utf8") <= USTAR_NAME)
|
|
77
|
+
return base;
|
|
78
|
+
return `file-${index}`;
|
|
79
|
+
}
|
|
80
|
+
function fileBlocks(file, index) {
|
|
81
|
+
const chunks = [];
|
|
82
|
+
const split = splitUstarName(file.name);
|
|
83
|
+
let name;
|
|
84
|
+
let prefix;
|
|
85
|
+
if (split) {
|
|
86
|
+
name = split.name;
|
|
87
|
+
prefix = split.prefix;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
const pax = paxRecord("path", file.name);
|
|
91
|
+
const paxName = `PaxHeader/${index}`;
|
|
92
|
+
chunks.push(ustarHeader({
|
|
93
|
+
name: paxName,
|
|
94
|
+
prefix: "",
|
|
95
|
+
size: pax.length,
|
|
96
|
+
typeflag: "x",
|
|
97
|
+
// Regular files and PAX headers are 0644. No directory / 0755 entries.
|
|
98
|
+
mode: 0o644,
|
|
99
|
+
}), padToBlock(pax));
|
|
100
|
+
name = shortNameForPax(file.name, index);
|
|
101
|
+
prefix = "";
|
|
102
|
+
}
|
|
103
|
+
chunks.push(ustarHeader({
|
|
104
|
+
name,
|
|
105
|
+
prefix,
|
|
106
|
+
size: file.content.length,
|
|
107
|
+
typeflag: "0",
|
|
108
|
+
mode: 0o644, // files only; no 0755 / directory entries
|
|
109
|
+
}), padToBlock(file.content));
|
|
110
|
+
return chunks;
|
|
111
|
+
}
|
|
112
|
+
export function createUstar(files) {
|
|
113
|
+
const sorted = [...files].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
114
|
+
const chunks = [];
|
|
115
|
+
sorted.forEach((file, index) => {
|
|
116
|
+
chunks.push(...fileBlocks(file, index));
|
|
117
|
+
});
|
|
118
|
+
chunks.push(Buffer.alloc(BLOCK), Buffer.alloc(BLOCK));
|
|
119
|
+
return Buffer.concat(chunks);
|
|
120
|
+
}
|
|
121
|
+
/** gzipSync with mtime 0 and OS=255 so the bytes match on every platform. */
|
|
122
|
+
export function gzipDeterministic(data) {
|
|
123
|
+
const gz = gzipSync(data, { level: 6 });
|
|
124
|
+
gz.writeUInt32LE(0, 4);
|
|
125
|
+
gz[9] = 255;
|
|
126
|
+
return gz;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=ustar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ustar.js","sourceRoot":"","sources":["../src/ustar.ts"],"names":[],"mappings":"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"}
|
package/dist/wait.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CliDeps } from "./deps.js";
|
|
2
|
+
import type { AgentScan } from "./types.js";
|
|
3
|
+
export declare function isScanFinal(scan: AgentScan): boolean;
|
|
4
|
+
export declare function clampPollMs(pollAfterSec: number | undefined, minPollMs: number): number;
|
|
5
|
+
export declare function fetchScan(deps: CliDeps, origin: string, token: string, scanId: string, waitSec: number): Promise<AgentScan>;
|
|
6
|
+
export declare function waitForScan(deps: CliDeps, origin: string, token: string, scanId: string, budgetMs: number): Promise<AgentScan>;
|
|
7
|
+
export declare function backoffSleep(deps: CliDeps, attempt: number, result?: {
|
|
8
|
+
status: number;
|
|
9
|
+
headers: Headers;
|
|
10
|
+
json: unknown;
|
|
11
|
+
}): Promise<void>;
|
package/dist/wait.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { LONGPOLL_MAX_SEC } from "./config.js";
|
|
2
|
+
import { CliError, EXIT_RUNNING, EXIT_UNEXPECTED } from "./exit.js";
|
|
3
|
+
import { httpRequest, requireOk, retryAfterMs } from "./http.js";
|
|
4
|
+
import { formatEtaLine, writeScanNext } from "./output.js";
|
|
5
|
+
export function isScanFinal(scan) {
|
|
6
|
+
return scan.final === true;
|
|
7
|
+
}
|
|
8
|
+
export function clampPollMs(pollAfterSec, minPollMs) {
|
|
9
|
+
const fromServer = (pollAfterSec ?? 10) * 1000;
|
|
10
|
+
return Math.max(minPollMs, fromServer);
|
|
11
|
+
}
|
|
12
|
+
export async function fetchScan(deps, origin, token, scanId, waitSec) {
|
|
13
|
+
const q = waitSec > 0 ? `?waitSec=${waitSec}` : "";
|
|
14
|
+
const result = await httpRequest(deps, origin, "GET", `/api/agent/v1/scans/${encodeURIComponent(scanId)}${q}`, { token });
|
|
15
|
+
if (result.status === 429) {
|
|
16
|
+
throw new CliError("Rate limited while waiting for the scan.", EXIT_RUNNING);
|
|
17
|
+
}
|
|
18
|
+
requireOk(result);
|
|
19
|
+
const rec = result.json;
|
|
20
|
+
if (!rec || typeof rec !== "object" || typeof rec.id !== "string") {
|
|
21
|
+
throw new CliError("Scan status response was not valid JSON.", EXIT_UNEXPECTED);
|
|
22
|
+
}
|
|
23
|
+
return rec;
|
|
24
|
+
}
|
|
25
|
+
export async function waitForScan(deps, origin, token, scanId, budgetMs) {
|
|
26
|
+
const deadline = deps.clock.now() + budgetMs;
|
|
27
|
+
let last = null;
|
|
28
|
+
let first = true;
|
|
29
|
+
while (first || deps.clock.now() < deadline) {
|
|
30
|
+
first = false;
|
|
31
|
+
const remainingMs = Math.max(0, deadline - deps.clock.now());
|
|
32
|
+
const waitSec = Math.min(LONGPOLL_MAX_SEC, Math.max(0, Math.floor(remainingMs / 1000)));
|
|
33
|
+
try {
|
|
34
|
+
last = await fetchScan(deps, origin, token, scanId, waitSec);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err instanceof CliError && err.exitCode === EXIT_RUNNING) {
|
|
38
|
+
const remaining = deadline - deps.clock.now();
|
|
39
|
+
if (remaining <= 0)
|
|
40
|
+
break;
|
|
41
|
+
await deps.clock.sleep(Math.min(deps.minPollMs, remaining));
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
if (isScanFinal(last)) {
|
|
47
|
+
return last;
|
|
48
|
+
}
|
|
49
|
+
if (last.progress) {
|
|
50
|
+
deps.io.stderr(`${last.progress.label}\n`);
|
|
51
|
+
}
|
|
52
|
+
const eta = formatEtaLine(last);
|
|
53
|
+
if (eta) {
|
|
54
|
+
deps.io.stderr(`${eta}\n`);
|
|
55
|
+
}
|
|
56
|
+
writeScanNext(deps, last);
|
|
57
|
+
const remaining = deadline - deps.clock.now();
|
|
58
|
+
if (remaining <= 0)
|
|
59
|
+
break;
|
|
60
|
+
const gap = clampPollMs(last.pollAfterSec, deps.minPollMs);
|
|
61
|
+
await deps.clock.sleep(Math.min(gap, remaining));
|
|
62
|
+
}
|
|
63
|
+
if (last)
|
|
64
|
+
return last;
|
|
65
|
+
throw new CliError("Timed out waiting for the scan.", EXIT_RUNNING);
|
|
66
|
+
}
|
|
67
|
+
export async function backoffSleep(deps, attempt, result) {
|
|
68
|
+
const base = Math.min(30_000, 2000 * 2 ** Math.min(attempt, 4));
|
|
69
|
+
if (result && result.status === 429) {
|
|
70
|
+
await deps.clock.sleep(retryAfterMs({
|
|
71
|
+
status: result.status,
|
|
72
|
+
headers: result.headers,
|
|
73
|
+
text: "",
|
|
74
|
+
json: result.json,
|
|
75
|
+
}, base));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
await deps.clock.sleep(base);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=wait.js.map
|
package/dist/wait.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wait.js","sourceRoot":"","sources":["../src/wait.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleanslop/cli",
|
|
3
|
-
"version": "0.0.0
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"description": "CleanSlop CLI — readiness scans from your coding agent",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cleanslop": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"assets",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=20"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc -p tsconfig.json",
|
|
22
|
+
"test": "c8 --config c8.config.json node --import tsx --test --test-reporter spec 'test/**/*.test.ts'",
|
|
23
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
24
|
+
},
|
|
25
|
+
"license": "UNLICENSED",
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.19.25",
|
|
28
|
+
"c8": "^12.0.0",
|
|
29
|
+
"tsx": "^4.20.6",
|
|
30
|
+
"typescript": "^5.9.3"
|
|
31
|
+
}
|
|
32
|
+
}
|