@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.
Files changed (96) hide show
  1. package/README.md +86 -2
  2. package/assets/skill-core.md +62 -0
  3. package/dist/action.d.ts +5 -0
  4. package/dist/action.js +22 -0
  5. package/dist/action.js.map +1 -0
  6. package/dist/args.d.ts +4 -0
  7. package/dist/args.js +243 -0
  8. package/dist/args.js.map +1 -0
  9. package/dist/commands/credits.d.ts +29 -0
  10. package/dist/commands/credits.js +267 -0
  11. package/dist/commands/credits.js.map +1 -0
  12. package/dist/commands/email.d.ts +3 -0
  13. package/dist/commands/email.js +51 -0
  14. package/dist/commands/email.js.map +1 -0
  15. package/dist/commands/link-identity.d.ts +3 -0
  16. package/dist/commands/link-identity.js +37 -0
  17. package/dist/commands/link-identity.js.map +1 -0
  18. package/dist/commands/link-login.d.ts +3 -0
  19. package/dist/commands/link-login.js +63 -0
  20. package/dist/commands/link-login.js.map +1 -0
  21. package/dist/commands/login.d.ts +6 -0
  22. package/dist/commands/login.js +198 -0
  23. package/dist/commands/login.js.map +1 -0
  24. package/dist/commands/logout.d.ts +2 -0
  25. package/dist/commands/logout.js +40 -0
  26. package/dist/commands/logout.js.map +1 -0
  27. package/dist/commands/report.d.ts +8 -0
  28. package/dist/commands/report.js +55 -0
  29. package/dist/commands/report.js.map +1 -0
  30. package/dist/commands/scan-upload.d.ts +3 -0
  31. package/dist/commands/scan-upload.js +85 -0
  32. package/dist/commands/scan-upload.js.map +1 -0
  33. package/dist/commands/scan.d.ts +3 -0
  34. package/dist/commands/scan.js +81 -0
  35. package/dist/commands/scan.js.map +1 -0
  36. package/dist/commands/setup.d.ts +19 -0
  37. package/dist/commands/setup.js +154 -0
  38. package/dist/commands/setup.js.map +1 -0
  39. package/dist/commands/status.d.ts +3 -0
  40. package/dist/commands/status.js +29 -0
  41. package/dist/commands/status.js.map +1 -0
  42. package/dist/commands/whoami.d.ts +3 -0
  43. package/dist/commands/whoami.js +44 -0
  44. package/dist/commands/whoami.js.map +1 -0
  45. package/dist/config.d.ts +26 -0
  46. package/dist/config.js +46 -0
  47. package/dist/config.js.map +1 -0
  48. package/dist/credentials.d.ts +64 -0
  49. package/dist/credentials.js +220 -0
  50. package/dist/credentials.js.map +1 -0
  51. package/dist/deps.d.ts +58 -0
  52. package/dist/deps.js +148 -0
  53. package/dist/deps.js.map +1 -0
  54. package/dist/exit.d.ts +24 -0
  55. package/dist/exit.js +29 -0
  56. package/dist/exit.js.map +1 -0
  57. package/dist/git.d.ts +14 -0
  58. package/dist/git.js +161 -0
  59. package/dist/git.js.map +1 -0
  60. package/dist/http.d.ts +16 -0
  61. package/dist/http.js +210 -0
  62. package/dist/http.js.map +1 -0
  63. package/dist/index.d.ts +2 -0
  64. package/dist/index.js +10 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/link.d.ts +106 -0
  67. package/dist/link.js +650 -0
  68. package/dist/link.js.map +1 -0
  69. package/dist/main.d.ts +6 -0
  70. package/dist/main.js +75 -0
  71. package/dist/main.js.map +1 -0
  72. package/dist/mcp-config.d.ts +13 -0
  73. package/dist/mcp-config.js +65 -0
  74. package/dist/mcp-config.js.map +1 -0
  75. package/dist/output.d.ts +9 -0
  76. package/dist/output.js +65 -0
  77. package/dist/output.js.map +1 -0
  78. package/dist/pack.d.ts +30 -0
  79. package/dist/pack.js +283 -0
  80. package/dist/pack.js.map +1 -0
  81. package/dist/redact.d.ts +2 -0
  82. package/dist/redact.js +17 -0
  83. package/dist/redact.js.map +1 -0
  84. package/dist/skill.d.ts +10 -0
  85. package/dist/skill.js +110 -0
  86. package/dist/skill.js.map +1 -0
  87. package/dist/types.d.ts +144 -0
  88. package/dist/types.js +2 -0
  89. package/dist/types.js.map +1 -0
  90. package/dist/ustar.d.ts +7 -0
  91. package/dist/ustar.js +128 -0
  92. package/dist/ustar.js.map +1 -0
  93. package/dist/wait.d.ts +11 -0
  94. package/dist/wait.js +80 -0
  95. package/dist/wait.js.map +1 -0
  96. package/package.json +30 -4
@@ -0,0 +1,154 @@
1
+ import { dirname, join } from "node:path";
2
+ import { SKILL_MARKER_BEGIN, SKILL_MARKER_END } from "../config.js";
3
+ import { resolveOrigin } from "../credentials.js";
4
+ import { EXIT_OK } from "../exit.js";
5
+ import { claudeMcpAddCommand, codexMcpAddCommand, codexMcpLoginCommand, mcpEndpoint, mergeMcpServers, removeMcpServer, writeMcpJson, } from "../mcp-config.js";
6
+ import { loadSkillCore, removeMarkerBlock, renderAgentsSnippet, renderCursorMdc, renderSkillMd, upsertMarkerBlock, } from "../skill.js";
7
+ export function setupTargets(deps, project) {
8
+ const home = deps.env.homeDir();
9
+ const cwd = deps.env.cwd();
10
+ const coreRender = {
11
+ skill: renderSkillMd,
12
+ mdc: renderCursorMdc,
13
+ agents: renderAgentsSnippet,
14
+ };
15
+ if (project) {
16
+ return [
17
+ {
18
+ id: "cursor",
19
+ label: "Cursor project rule",
20
+ path: join(cwd, ".cursor", "rules", "cleanslop.mdc"),
21
+ kind: "owned",
22
+ render: coreRender.mdc,
23
+ },
24
+ {
25
+ id: "agents",
26
+ label: "AGENTS.md (project)",
27
+ path: join(cwd, "AGENTS.md"),
28
+ kind: "marker",
29
+ render: coreRender.agents,
30
+ },
31
+ ];
32
+ }
33
+ return [
34
+ {
35
+ id: "claude",
36
+ label: "Claude Code skill",
37
+ path: join(home, ".claude", "skills", "cleanslop", "SKILL.md"),
38
+ kind: "owned",
39
+ render: coreRender.skill,
40
+ },
41
+ {
42
+ id: "cursor",
43
+ label: "Cursor user rule",
44
+ path: join(home, ".cursor", "rules", "cleanslop.mdc"),
45
+ kind: "owned",
46
+ render: coreRender.mdc,
47
+ },
48
+ {
49
+ id: "codex",
50
+ label: "Codex AGENTS.md",
51
+ path: join(home, ".codex", "AGENTS.md"),
52
+ kind: "marker",
53
+ render: coreRender.agents,
54
+ },
55
+ ];
56
+ }
57
+ function mcpConfigPaths(deps, project) {
58
+ const home = deps.env.homeDir();
59
+ const cwd = deps.env.cwd();
60
+ return {
61
+ cursor: project
62
+ ? join(cwd, ".cursor", "mcp.json")
63
+ : join(home, ".cursor", "mcp.json"),
64
+ };
65
+ }
66
+ function planLine(target, uninstall) {
67
+ const verb = uninstall ? "remove" : "write";
68
+ return ` ${verb} ${target.label}: ${target.path}`;
69
+ }
70
+ function writeOwned(deps, path, body) {
71
+ deps.fs.mkdir(dirname(path), 0o755);
72
+ const text = body.endsWith("\n") ? body : `${body}\n`;
73
+ deps.fs.write(path, text, 0o644);
74
+ }
75
+ function writeMarker(deps, path, block) {
76
+ const existing = deps.fs.exists(path) ? deps.fs.read(path) : "";
77
+ const next = upsertMarkerBlock(existing, block);
78
+ deps.fs.mkdir(dirname(path), 0o755);
79
+ deps.fs.write(path, next.endsWith("\n") ? next : `${next}\n`, 0o644);
80
+ }
81
+ function uninstallTarget(deps, target) {
82
+ if (!deps.fs.exists(target.path))
83
+ return;
84
+ if (target.kind === "owned") {
85
+ deps.fs.rm(target.path);
86
+ return;
87
+ }
88
+ const next = removeMarkerBlock(deps.fs.read(target.path));
89
+ if (next.trim().length === 0) {
90
+ deps.fs.rm(target.path);
91
+ return;
92
+ }
93
+ deps.fs.write(target.path, next.endsWith("\n") ? next : `${next}\n`, 0o644);
94
+ }
95
+ export async function runSetup(deps, args) {
96
+ const targets = setupTargets(deps, args.project);
97
+ const writeAllowed = args.yes || deps.io.stdinIsTTY;
98
+ const dry = args.dryRun || !writeAllowed;
99
+ deps.io.stdout(args.uninstall
100
+ ? "CleanSlop setup uninstall plan\n"
101
+ : "CleanSlop setup plan\n");
102
+ const origin = resolveOrigin(deps);
103
+ const mcpPaths = mcpConfigPaths(deps, args.project);
104
+ for (const target of targets) {
105
+ deps.io.stdout(`${planLine(target, args.uninstall)}\n`);
106
+ }
107
+ deps.io.stdout(args.uninstall
108
+ ? ` remove MCP: ${mcpPaths.cursor}\n`
109
+ : ` register MCP: ${mcpPaths.cursor} -> ${mcpEndpoint(origin)}\n`);
110
+ if (!args.project && !args.uninstall) {
111
+ deps.io.stdout(` ${claudeMcpAddCommand(origin)}\n`);
112
+ deps.io.stdout(` ${codexMcpAddCommand(origin)}\n`);
113
+ deps.io.stdout(` ${codexMcpLoginCommand()}\n`);
114
+ }
115
+ deps.io.stdout(" This command never logs in and never writes a token.\n");
116
+ if (dry) {
117
+ if (!args.dryRun && !writeAllowed) {
118
+ deps.io.stderr("Non-TTY setup prints the plan only. Re-run with --yes to write.\n");
119
+ }
120
+ return EXIT_OK;
121
+ }
122
+ if (args.uninstall) {
123
+ for (const target of targets) {
124
+ uninstallTarget(deps, target);
125
+ }
126
+ if (deps.fs.exists(mcpPaths.cursor)) {
127
+ writeMcpJson(deps, mcpPaths.cursor, (current) => removeMcpServer(current, "cleanslop"));
128
+ }
129
+ deps.io.stdout("Removed CleanSlop skill/rules markers.\n");
130
+ return EXIT_OK;
131
+ }
132
+ const core = loadSkillCore((path) => {
133
+ if (deps.fs.exists(path))
134
+ return deps.fs.read(path);
135
+ throw new Error(`Missing skill source: ${path}`);
136
+ });
137
+ for (const target of targets) {
138
+ const rendered = target.render(core);
139
+ if (target.kind === "owned") {
140
+ writeOwned(deps, target.path, rendered);
141
+ }
142
+ else {
143
+ writeMarker(deps, target.path, rendered);
144
+ }
145
+ }
146
+ writeMcpJson(deps, mcpPaths.cursor, (current) => mergeMcpServers(current, "cleanslop", { url: mcpEndpoint(origin) }));
147
+ deps.io.stdout("Installed CleanSlop skill/rules and registered MCP.\n");
148
+ return EXIT_OK;
149
+ }
150
+ export const SETUP_MARKERS = {
151
+ begin: SKILL_MARKER_BEGIN,
152
+ end: SKILL_MARKER_END,
153
+ };
154
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CliDeps } from "../deps.js";
2
+ import type { ParsedArgs } from "../types.js";
3
+ export declare function runStatus(deps: CliDeps, args: ParsedArgs): Promise<number>;
@@ -0,0 +1,29 @@
1
+ import { writeResume } from "../action.js";
2
+ import { requireToken, resolveOrigin, } from "../credentials.js";
3
+ import { CliError, EXIT_OK, EXIT_RUNNING, EXIT_SCAN_FAILED } from "../exit.js";
4
+ import { writeJson, writeScanProgress } from "../output.js";
5
+ import { resolveScanId } from "./report.js";
6
+ import { fetchScan, waitForScan } from "../wait.js";
7
+ export async function runStatus(deps, args) {
8
+ const origin = resolveOrigin(deps);
9
+ const creds = requireToken(deps, origin);
10
+ const scanId = resolveScanId(deps, origin, args.id);
11
+ const scan = args.wait
12
+ ? await waitForScan(deps, origin, creds.token, scanId, args.waitMs)
13
+ : await fetchScan(deps, origin, creds.token, scanId, 0);
14
+ if (args.json) {
15
+ writeJson(deps, { scan });
16
+ }
17
+ else {
18
+ writeScanProgress(deps, scan);
19
+ }
20
+ if (scan.status === "failed") {
21
+ throw new CliError(scan.error?.message ?? "Scan failed.", EXIT_SCAN_FAILED);
22
+ }
23
+ if (!scan.final && args.wait) {
24
+ writeResume(deps, scan.id, scan);
25
+ throw new CliError("Scan is still running.", EXIT_RUNNING);
26
+ }
27
+ return EXIT_OK;
28
+ }
29
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAa,EACb,IAAgB;IAEhB,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;QACpB,CAAC,CAAC,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;QACnE,CAAC,CAAC,MAAM,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAE1D,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,SAAS,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5B,CAAC;SAAM,CAAC;QACN,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,cAAc,EAAE,gBAAgB,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QAC7B,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACjC,MAAM,IAAI,QAAQ,CAAC,wBAAwB,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CliDeps } from "../deps.js";
2
+ import type { ParsedArgs } from "../types.js";
3
+ export declare function runWhoami(deps: CliDeps, args: ParsedArgs): Promise<number>;
@@ -0,0 +1,44 @@
1
+ import { requireToken, resolveOrigin } from "../credentials.js";
2
+ import { EXIT_OK } from "../exit.js";
3
+ import { httpRequest, requireOk } from "../http.js";
4
+ import { writeJson } from "../output.js";
5
+ export async function runWhoami(deps, args) {
6
+ const origin = resolveOrigin(deps);
7
+ const creds = requireToken(deps, origin);
8
+ const result = await httpRequest(deps, origin, "GET", "/api/agent/v1/me", {
9
+ token: creds.token,
10
+ });
11
+ requireOk(result);
12
+ const me = (result.json ?? {});
13
+ const login = me.user?.githubLogin ?? creds.githubLogin;
14
+ const emailMasked = me.user?.emailMasked ?? me.link?.emailMasked ?? null;
15
+ const payload = {
16
+ origin,
17
+ githubLogin: login ?? null,
18
+ emailMasked,
19
+ uploads: me.uploads === true,
20
+ grantId: me.grant?.id ?? creds.grantId,
21
+ tokenLast4: creds.last4,
22
+ source: creds.source,
23
+ quota: me.quota ?? null,
24
+ };
25
+ if (args.json) {
26
+ writeJson(deps, payload);
27
+ return EXIT_OK;
28
+ }
29
+ const label = login
30
+ ? `@${login}`
31
+ : emailMasked
32
+ ? `${emailMasked} (Link)`
33
+ : "unknown account";
34
+ deps.io.stdout(`Connected as ${label}\n`);
35
+ deps.io.stdout(`origin ${origin}\n`);
36
+ deps.io.stdout(`token …${creds.last4}\n`);
37
+ if (payload.grantId)
38
+ deps.io.stdout(`grant ${payload.grantId}\n`);
39
+ if (me.quota && typeof me.quota.remaining === "number") {
40
+ deps.io.stdout(`quota ${me.quota.remaining} remaining\n`);
41
+ }
42
+ return EXIT_OK;
43
+ }
44
+ //# sourceMappingURL=whoami.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAa,EACb,IAAgB;IAEhB,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE;QACxE,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC,CAAC;IACH,SAAS,CAAC,MAAM,CAAC,CAAC;IAClB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAe,CAAC;IAC7C,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC;IACxD,MAAM,WAAW,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,IAAI,EAAE,CAAC,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC;IACzE,MAAM,OAAO,GAAG;QACd,MAAM;QACN,WAAW,EAAE,KAAK,IAAI,IAAI;QAC1B,WAAW;QACX,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,IAAI;QAC5B,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,IAAI,KAAK,CAAC,OAAO;QACtC,UAAU,EAAE,KAAK,CAAC,KAAK;QACvB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI;KACxB,CAAC;IACF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,KAAK,GAAG,KAAK;QACjB,CAAC,CAAC,IAAI,KAAK,EAAE;QACb,CAAC,CAAC,WAAW;YACX,CAAC,CAAC,GAAG,WAAW,SAAS;YACzB,CAAC,CAAC,iBAAiB,CAAC;IACxB,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,KAAK,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,MAAM,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;IAC1C,IAAI,OAAO,CAAC,OAAO;QAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;IAClE,IAAI,EAAE,CAAC,KAAK,IAAI,OAAO,EAAE,CAAC,KAAK,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACvD,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,CAAC,SAAS,cAAc,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,26 @@
1
+ export declare const PACKAGE_NAME = "@cleanslop/cli";
2
+ export declare const PACKAGE_VERSION = "0.1.0-beta.1.2";
3
+ export declare const CLIENT_ID = "cleanslop-cli";
4
+ export declare const DEFAULT_ORIGIN = "https://cleanslop.com";
5
+ export declare const DEFAULT_WAIT_MS: number;
6
+ export declare const MIN_POLL_MS = 3000;
7
+ export declare const LONGPOLL_MAX_SEC = 45;
8
+ export declare const DEVICE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
9
+ export declare const USER_AGENT = "cleanslop-cli/0.1.0-beta.1.2";
10
+ export declare const CREDENTIALS_FILE = "credentials.json";
11
+ export declare const PENDING_LOGIN_FILE = "pending-login.json";
12
+ export declare const PENDING_SPEND_FILE = "pending-spend-request.json";
13
+ export declare const SKILL_MARKER_BEGIN = "<!-- cleanslop:begin v1 -->";
14
+ export declare const SKILL_MARKER_END = "<!-- cleanslop:end -->";
15
+ export declare const TOKEN_RE: RegExp;
16
+ /** Must match `EN_TERMS.updatedOn` on the server. */
17
+ export declare const TERMS_UPDATED_ON = "2026-10-09";
18
+ export declare const LINK_CLI_TIMEOUT_MS = 15000;
19
+ /** Used when `link-cli` is not on PATH. Pinned: the CLI parses its JSON. */
20
+ export declare const LINK_CLI_PACKAGE = "@stripe/link-cli@0.27.3";
21
+ export declare const LINK_CLI_NPX_TIMEOUT_MS = 180000;
22
+ export declare const PACK_MAX_FILE_BYTES: number;
23
+ /** Same default as `AGENT_UPLOAD_MAX_COMPRESSED_BYTES` on the server. */
24
+ export declare const PACK_MAX_ARCHIVE_BYTES: number;
25
+ export declare function defaultOrigin(): string;
26
+ export declare function parseOrigin(raw: string): string | null;
package/dist/config.js ADDED
@@ -0,0 +1,46 @@
1
+ export const PACKAGE_NAME = "@cleanslop/cli";
2
+ export const PACKAGE_VERSION = "0.1.0-beta.1.2";
3
+ export const CLIENT_ID = "cleanslop-cli";
4
+ export const DEFAULT_ORIGIN = "https://cleanslop.com";
5
+ export const DEFAULT_WAIT_MS = 8 * 60 * 1000;
6
+ export const MIN_POLL_MS = 3000;
7
+ export const LONGPOLL_MAX_SEC = 45;
8
+ export const DEVICE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
9
+ export const USER_AGENT = `${CLIENT_ID}/${PACKAGE_VERSION}`;
10
+ export const CREDENTIALS_FILE = "credentials.json";
11
+ export const PENDING_LOGIN_FILE = "pending-login.json";
12
+ export const PENDING_SPEND_FILE = "pending-spend-request.json";
13
+ export const SKILL_MARKER_BEGIN = "<!-- cleanslop:begin v1 -->";
14
+ export const SKILL_MARKER_END = "<!-- cleanslop:end -->";
15
+ export const TOKEN_RE = /cslop_(?:agt|mat|mrt)_[A-Za-z0-9]+/g;
16
+ /** Must match `EN_TERMS.updatedOn` on the server. */
17
+ export const TERMS_UPDATED_ON = "2026-10-09";
18
+ export const LINK_CLI_TIMEOUT_MS = 15_000;
19
+ /** Used when `link-cli` is not on PATH. Pinned: the CLI parses its JSON. */
20
+ export const LINK_CLI_PACKAGE = "@stripe/link-cli@0.27.3";
21
+ export const LINK_CLI_NPX_TIMEOUT_MS = 180_000;
22
+ export const PACK_MAX_FILE_BYTES = 2 * 1024 * 1024;
23
+ /** Same default as `AGENT_UPLOAD_MAX_COMPRESSED_BYTES` on the server. */
24
+ export const PACK_MAX_ARCHIVE_BYTES = 100 * 1024 * 1024;
25
+ export function defaultOrigin() {
26
+ return DEFAULT_ORIGIN;
27
+ }
28
+ export function parseOrigin(raw) {
29
+ const trimmed = raw.trim().replace(/\/+$/, "");
30
+ if (!trimmed)
31
+ return null;
32
+ try {
33
+ const url = new URL(trimmed);
34
+ if (url.protocol !== "http:" && url.protocol !== "https:")
35
+ return null;
36
+ if (url.username || url.password || url.search || url.hash)
37
+ return null;
38
+ if (url.pathname && url.pathname !== "/")
39
+ return null;
40
+ return `${url.protocol}//${url.host}`;
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAC7C,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAChD,MAAM,CAAC,MAAM,SAAS,GAAG,eAAe,CAAC;AACzC,MAAM,CAAC,MAAM,cAAc,GAAG,uBAAuB,CAAC;AACtD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAC7C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC;AAChC,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AACnC,MAAM,CAAC,MAAM,iBAAiB,GAC5B,8CAA8C,CAAC;AACjD,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,SAAS,IAAI,eAAe,EAAE,CAAC;AAC5D,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AACnD,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AACvD,MAAM,CAAC,MAAM,kBAAkB,GAAG,4BAA4B,CAAC;AAC/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,6BAA6B,CAAC;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AACzD,MAAM,CAAC,MAAM,QAAQ,GAAG,qCAAqC,CAAC;AAC9D,qDAAqD;AACrD,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAC7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAC1C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;AAC1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAC/C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AACnD,yEAAyE;AACzE,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAExD,MAAM,UAAU,aAAa;IAC3B,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACvE,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACxE,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;QACtD,OAAO,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type { CliDeps } from "./deps.js";
2
+ export type OriginCreds = {
3
+ token: string;
4
+ last4: string;
5
+ githubLogin?: string | null;
6
+ grantId?: string | null;
7
+ lastScanId?: string | null;
8
+ };
9
+ export type CredentialsFile = {
10
+ version: 1;
11
+ origins: Record<string, OriginCreds>;
12
+ };
13
+ export declare function resolveOrigin(deps: CliDeps): string;
14
+ export declare function configDir(deps: CliDeps): string;
15
+ export declare function credentialsPath(deps: CliDeps): string;
16
+ export declare function pendingLoginPath(deps: CliDeps): string;
17
+ export declare function pendingSpendPath(deps: CliDeps): string;
18
+ export type PendingSpendRequest = {
19
+ version: 1;
20
+ origin: string;
21
+ spendRequestId: string;
22
+ pack: string;
23
+ amount: number;
24
+ currency: string;
25
+ networkId: string;
26
+ purchaseUrl: string;
27
+ createdAt: number;
28
+ };
29
+ export declare function readPendingSpend(deps: CliDeps): PendingSpendRequest | null;
30
+ export declare function writePendingSpend(deps: CliDeps, pending: PendingSpendRequest): Promise<void>;
31
+ export declare function deletePendingSpend(deps: CliDeps): void;
32
+ export type PendingLogin = {
33
+ version: 1;
34
+ origin: string;
35
+ deviceCode: string;
36
+ userCode: string;
37
+ verificationUriComplete: string;
38
+ expiresAt: number;
39
+ interval: number;
40
+ };
41
+ export declare function readPendingLogin(deps: CliDeps): PendingLogin | null;
42
+ export declare function writePendingLogin(deps: CliDeps, pending: PendingLogin): Promise<void>;
43
+ export declare function deletePendingLogin(deps: CliDeps): void;
44
+ export declare function assertNotInWorktree(deps: CliDeps, targetPath: string): Promise<void>;
45
+ export declare function readCredentialsFile(deps: CliDeps): CredentialsFile;
46
+ export declare function writeCredentialsFile(deps: CliDeps, file: CredentialsFile): Promise<void>;
47
+ export type ResolvedToken = {
48
+ token: string;
49
+ last4: string;
50
+ githubLogin: string | null;
51
+ grantId: string | null;
52
+ lastScanId: string | null;
53
+ source: "env" | "file";
54
+ };
55
+ export declare function peekStoredCreds(deps: CliDeps, origin: string): OriginCreds | null;
56
+ export declare function resolveToken(deps: CliDeps, origin: string): ResolvedToken | null;
57
+ export declare function requireToken(deps: CliDeps, origin: string): ResolvedToken;
58
+ export declare function storeToken(deps: CliDeps, origin: string, input: {
59
+ token: string;
60
+ githubLogin?: string | null;
61
+ grantId?: string | null;
62
+ }): Promise<OriginCreds>;
63
+ export declare function storeLastScanId(deps: CliDeps, origin: string, scanId: string): Promise<void>;
64
+ export declare function deleteOriginCreds(deps: CliDeps, origin: string): Promise<void>;
@@ -0,0 +1,220 @@
1
+ import { join } from "node:path";
2
+ import { CREDENTIALS_FILE, PENDING_LOGIN_FILE, PENDING_SPEND_FILE, parseOrigin, } from "./config.js";
3
+ import { CliError, EXIT_ACTION, EXIT_USAGE, usageError } from "./exit.js";
4
+ import { gitToplevel, isPathInsideWorktree } from "./git.js";
5
+ import { tokenLast4 } from "./redact.js";
6
+ export function resolveOrigin(deps) {
7
+ const override = deps.env.get("CLEANSLOP_ORIGIN");
8
+ if (override && override.trim()) {
9
+ const parsed = parseOrigin(override);
10
+ if (!parsed) {
11
+ throw usageError("CLEANSLOP_ORIGIN must be an absolute http(s) origin (no path).");
12
+ }
13
+ return parsed;
14
+ }
15
+ return deps.defaultOrigin;
16
+ }
17
+ export function configDir(deps) {
18
+ const xdg = deps.env.get("XDG_CONFIG_HOME")?.trim();
19
+ if (xdg)
20
+ return join(xdg, "cleanslop");
21
+ if (deps.env.platform === "win32") {
22
+ const appdata = deps.env.get("APPDATA")?.trim();
23
+ if (appdata)
24
+ return join(appdata, "cleanslop");
25
+ }
26
+ return join(deps.env.homeDir(), ".config", "cleanslop");
27
+ }
28
+ export function credentialsPath(deps) {
29
+ return join(configDir(deps), CREDENTIALS_FILE);
30
+ }
31
+ export function pendingLoginPath(deps) {
32
+ return join(configDir(deps), PENDING_LOGIN_FILE);
33
+ }
34
+ export function pendingSpendPath(deps) {
35
+ return join(configDir(deps), PENDING_SPEND_FILE);
36
+ }
37
+ function isPendingSpend(value) {
38
+ if (!value || typeof value !== "object")
39
+ return false;
40
+ const rec = value;
41
+ return (rec.version === 1 &&
42
+ typeof rec.origin === "string" &&
43
+ typeof rec.spendRequestId === "string" &&
44
+ typeof rec.pack === "string" &&
45
+ typeof rec.amount === "number" &&
46
+ typeof rec.currency === "string" &&
47
+ typeof rec.networkId === "string" &&
48
+ typeof rec.purchaseUrl === "string" &&
49
+ typeof rec.createdAt === "number");
50
+ }
51
+ export function readPendingSpend(deps) {
52
+ const path = pendingSpendPath(deps);
53
+ if (!deps.fs.exists(path))
54
+ return null;
55
+ try {
56
+ const parsed = JSON.parse(deps.fs.read(path));
57
+ return isPendingSpend(parsed) ? parsed : null;
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ export async function writePendingSpend(deps, pending) {
64
+ const dir = configDir(deps);
65
+ const path = pendingSpendPath(deps);
66
+ await assertNotInWorktree(deps, path);
67
+ deps.fs.mkdir(dir, 0o700);
68
+ deps.fs.write(path, `${JSON.stringify(pending, null, 2)}\n`, 0o600);
69
+ }
70
+ export function deletePendingSpend(deps) {
71
+ const path = pendingSpendPath(deps);
72
+ if (deps.fs.exists(path))
73
+ deps.fs.rm(path);
74
+ }
75
+ function isPendingLogin(value) {
76
+ if (!value || typeof value !== "object")
77
+ return false;
78
+ const rec = value;
79
+ return (rec.version === 1 &&
80
+ typeof rec.origin === "string" &&
81
+ typeof rec.deviceCode === "string" &&
82
+ typeof rec.userCode === "string" &&
83
+ typeof rec.verificationUriComplete === "string" &&
84
+ typeof rec.expiresAt === "number" &&
85
+ typeof rec.interval === "number");
86
+ }
87
+ export function readPendingLogin(deps) {
88
+ const path = pendingLoginPath(deps);
89
+ if (!deps.fs.exists(path))
90
+ return null;
91
+ try {
92
+ const parsed = JSON.parse(deps.fs.read(path));
93
+ return isPendingLogin(parsed) ? parsed : null;
94
+ }
95
+ catch {
96
+ return null;
97
+ }
98
+ }
99
+ export async function writePendingLogin(deps, pending) {
100
+ const dir = configDir(deps);
101
+ const path = pendingLoginPath(deps);
102
+ await assertNotInWorktree(deps, path);
103
+ deps.fs.mkdir(dir, 0o700);
104
+ deps.fs.write(path, `${JSON.stringify(pending, null, 2)}\n`, 0o600);
105
+ }
106
+ export function deletePendingLogin(deps) {
107
+ const path = pendingLoginPath(deps);
108
+ if (deps.fs.exists(path))
109
+ deps.fs.rm(path);
110
+ }
111
+ export async function assertNotInWorktree(deps, targetPath) {
112
+ const top = await gitToplevel(deps, deps.env.cwd());
113
+ if (!top)
114
+ return;
115
+ if (isPathInsideWorktree(targetPath, top)) {
116
+ throw new CliError(`Refusing to write credentials inside the git worktree (${targetPath}). Set XDG_CONFIG_HOME outside this repo.`, EXIT_USAGE);
117
+ }
118
+ }
119
+ function emptyFile() {
120
+ return { version: 1, origins: {} };
121
+ }
122
+ export function readCredentialsFile(deps) {
123
+ const path = credentialsPath(deps);
124
+ if (!deps.fs.exists(path))
125
+ return emptyFile();
126
+ try {
127
+ const parsed = JSON.parse(deps.fs.read(path));
128
+ if (!parsed || typeof parsed !== "object")
129
+ return emptyFile();
130
+ const rec = parsed;
131
+ if (rec.version !== 1 || !rec.origins || typeof rec.origins !== "object") {
132
+ return emptyFile();
133
+ }
134
+ return { version: 1, origins: rec.origins };
135
+ }
136
+ catch {
137
+ return emptyFile();
138
+ }
139
+ }
140
+ export async function writeCredentialsFile(deps, file) {
141
+ const dir = configDir(deps);
142
+ const path = credentialsPath(deps);
143
+ await assertNotInWorktree(deps, path);
144
+ deps.fs.mkdir(dir, 0o700);
145
+ deps.fs.write(path, `${JSON.stringify(file, null, 2)}\n`, 0o600);
146
+ }
147
+ export function peekStoredCreds(deps, origin) {
148
+ return readCredentialsFile(deps).origins[origin] ?? null;
149
+ }
150
+ export function resolveToken(deps, origin) {
151
+ const envToken = deps.env.get("CLEANSLOP_TOKEN")?.trim();
152
+ const stored = peekStoredCreds(deps, origin);
153
+ if (envToken) {
154
+ return {
155
+ token: envToken,
156
+ last4: tokenLast4(envToken),
157
+ githubLogin: stored?.githubLogin ?? null,
158
+ grantId: stored?.grantId ?? null,
159
+ lastScanId: stored?.lastScanId ?? null,
160
+ source: "env",
161
+ };
162
+ }
163
+ if (!stored?.token)
164
+ return null;
165
+ return {
166
+ token: stored.token,
167
+ last4: stored.last4 || tokenLast4(stored.token),
168
+ githubLogin: stored.githubLogin ?? null,
169
+ grantId: stored.grantId ?? null,
170
+ lastScanId: stored.lastScanId ?? null,
171
+ source: "file",
172
+ };
173
+ }
174
+ export function requireToken(deps, origin) {
175
+ const resolved = resolveToken(deps, origin);
176
+ if (!resolved) {
177
+ throw new CliError("Not connected. Run `cleanslop login`.", EXIT_ACTION, {
178
+ kind: "approve",
179
+ humanPrompt: "Run `cleanslop login` and ask the human to approve the device code.",
180
+ });
181
+ }
182
+ return resolved;
183
+ }
184
+ export async function storeToken(deps, origin, input) {
185
+ const file = readCredentialsFile(deps);
186
+ const prev = file.origins[origin];
187
+ const next = {
188
+ token: input.token,
189
+ last4: tokenLast4(input.token),
190
+ githubLogin: input.githubLogin ?? prev?.githubLogin ?? null,
191
+ grantId: input.grantId ?? prev?.grantId ?? null,
192
+ lastScanId: prev?.lastScanId ?? null,
193
+ };
194
+ file.origins[origin] = next;
195
+ await writeCredentialsFile(deps, file);
196
+ return next;
197
+ }
198
+ export async function storeLastScanId(deps, origin, scanId) {
199
+ const file = readCredentialsFile(deps);
200
+ const prev = file.origins[origin];
201
+ if (!prev)
202
+ return;
203
+ file.origins[origin] = { ...prev, lastScanId: scanId };
204
+ await writeCredentialsFile(deps, file);
205
+ }
206
+ export async function deleteOriginCreds(deps, origin) {
207
+ const file = readCredentialsFile(deps);
208
+ if (!file.origins[origin]) {
209
+ return;
210
+ }
211
+ delete file.origins[origin];
212
+ if (Object.keys(file.origins).length === 0) {
213
+ const path = credentialsPath(deps);
214
+ if (deps.fs.exists(path))
215
+ deps.fs.rm(path);
216
+ return;
217
+ }
218
+ await writeCredentialsFile(deps, file);
219
+ }
220
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}