@fraction12/deepclean 0.1.0-alpha.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +21 -0
  3. package/README.md +171 -0
  4. package/dist/args.d.ts +9 -0
  5. package/dist/args.js +105 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/candidates.d.ts +6 -0
  8. package/dist/candidates.js +319 -0
  9. package/dist/candidates.js.map +1 -0
  10. package/dist/cli.d.ts +2 -0
  11. package/dist/cli.js +521 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/clusters.d.ts +7 -0
  14. package/dist/clusters.js +399 -0
  15. package/dist/clusters.js.map +1 -0
  16. package/dist/defaults.d.ts +5 -0
  17. package/dist/defaults.js +130 -0
  18. package/dist/defaults.js.map +1 -0
  19. package/dist/discovery.d.ts +10 -0
  20. package/dist/discovery.js +48 -0
  21. package/dist/discovery.js.map +1 -0
  22. package/dist/evidence.d.ts +16 -0
  23. package/dist/evidence.js +853 -0
  24. package/dist/evidence.js.map +1 -0
  25. package/dist/ids.d.ts +4 -0
  26. package/dist/ids.js +16 -0
  27. package/dist/ids.js.map +1 -0
  28. package/dist/json.d.ts +3 -0
  29. package/dist/json.js +12 -0
  30. package/dist/json.js.map +1 -0
  31. package/dist/plans.d.ts +3 -0
  32. package/dist/plans.js +171 -0
  33. package/dist/plans.js.map +1 -0
  34. package/dist/reporting.d.ts +13 -0
  35. package/dist/reporting.js +227 -0
  36. package/dist/reporting.js.map +1 -0
  37. package/dist/reviewers.d.ts +22 -0
  38. package/dist/reviewers.js +461 -0
  39. package/dist/reviewers.js.map +1 -0
  40. package/dist/state.d.ts +41 -0
  41. package/dist/state.js +211 -0
  42. package/dist/state.js.map +1 -0
  43. package/dist/synthesis.d.ts +17 -0
  44. package/dist/synthesis.js +396 -0
  45. package/dist/synthesis.js.map +1 -0
  46. package/dist/types.d.ts +389 -0
  47. package/dist/types.js +236 -0
  48. package/dist/types.js.map +1 -0
  49. package/dist/verification.d.ts +11 -0
  50. package/dist/verification.js +111 -0
  51. package/dist/verification.js.map +1 -0
  52. package/docs/privacy-and-trust.md +33 -0
  53. package/docs/public-readiness.md +19 -0
  54. package/docs/reviewer-references.md +33 -0
  55. package/docs/troubleshooting.md +80 -0
  56. package/package.json +55 -0
@@ -0,0 +1,111 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ export async function inferVerificationProfile(root) {
4
+ const [rootPackage, frontendPackage, adminPackage, makefile] = await Promise.all([
5
+ readPackageJson(path.join(root, "package.json")),
6
+ readPackageJson(path.join(root, "frontend", "package.json")),
7
+ readPackageJson(path.join(root, "admin", "package.json")),
8
+ readText(path.join(root, "Makefile")),
9
+ ]);
10
+ const rootCommands = packageCommands("", rootPackage);
11
+ const frontendCommands = packageCommands("frontend", frontendPackage);
12
+ const adminCommands = packageCommands("admin", adminPackage);
13
+ const pythonCommands = makefile
14
+ ? makeCommands(makefile)
15
+ : [];
16
+ return {
17
+ defaultCommands: unique([
18
+ ...rootCommands,
19
+ ...pythonCommands,
20
+ ...frontendCommands,
21
+ ...adminCommands,
22
+ ]).slice(0, 8),
23
+ pythonCommands: pythonCommands.length > 0 ? pythonCommands : rootCommands,
24
+ frontendCommands: frontendCommands.length > 0 ? frontendCommands : rootCommands,
25
+ adminCommands: adminCommands.length > 0 ? adminCommands : rootCommands,
26
+ };
27
+ }
28
+ export function commandsForFiles(profile, files, fallback = []) {
29
+ const commands = [];
30
+ const paths = files.map((file) => file.path);
31
+ if (paths.some((filePath) => filePath.startsWith("admin/"))) {
32
+ commands.push(...profile.adminCommands);
33
+ }
34
+ if (paths.some((filePath) => filePath.startsWith("frontend/"))) {
35
+ commands.push(...profile.frontendCommands);
36
+ }
37
+ if (paths.some((filePath) => (filePath.endsWith(".py")
38
+ || filePath.startsWith("backend/")
39
+ || filePath.startsWith("core/")
40
+ || filePath.startsWith("tests/")))) {
41
+ commands.push(...profile.pythonCommands);
42
+ }
43
+ const scoped = unique(commands).filter(Boolean);
44
+ if (scoped.length > 0) {
45
+ return scoped.slice(0, 6);
46
+ }
47
+ const defaults = profile.defaultCommands.length > 0 ? profile.defaultCommands : fallback;
48
+ return unique(defaults.length > 0 ? defaults : fallback).slice(0, 6);
49
+ }
50
+ export function mergeVerificationCommands(inferred, existing) {
51
+ const generic = new Set(["npm test", "npm run typecheck", "make test", "make typecheck"]);
52
+ const specific = existing.filter((command) => !generic.has(command));
53
+ const preferred = inferred.length > 0 ? inferred : existing;
54
+ return unique([...preferred, ...specific]).slice(0, 8);
55
+ }
56
+ function packageCommands(prefix, packageJson) {
57
+ const scripts = packageJson?.scripts;
58
+ if (!scripts) {
59
+ return [];
60
+ }
61
+ const commands = [];
62
+ if (scripts["typecheck"]) {
63
+ commands.push(npmCommand(prefix, "typecheck"));
64
+ }
65
+ if (scripts["lint"]) {
66
+ commands.push(npmCommand(prefix, "lint"));
67
+ }
68
+ if (scripts["test:run"]) {
69
+ commands.push(npmCommand(prefix, "test:run"));
70
+ }
71
+ else if (scripts["test"]) {
72
+ commands.push(npmCommand(prefix, "test"));
73
+ }
74
+ if (scripts["build"]) {
75
+ commands.push(npmCommand(prefix, "build"));
76
+ }
77
+ return commands;
78
+ }
79
+ function npmCommand(prefix, script) {
80
+ const command = `npm run ${script}`;
81
+ return prefix ? `cd ${prefix} && ${command}` : command;
82
+ }
83
+ function makeCommands(makefile) {
84
+ const targets = new Set(makefile
85
+ .split("\n")
86
+ .map((line) => line.match(/^([a-zA-Z0-9_-]+):/)?.[1])
87
+ .filter((value) => Boolean(value)));
88
+ return ["lint", "typecheck", "test"]
89
+ .filter((target) => targets.has(target))
90
+ .map((target) => `make ${target}`);
91
+ }
92
+ async function readPackageJson(filePath) {
93
+ try {
94
+ return JSON.parse(await readFile(filePath, "utf8"));
95
+ }
96
+ catch {
97
+ return undefined;
98
+ }
99
+ }
100
+ async function readText(filePath) {
101
+ try {
102
+ return await readFile(filePath, "utf8");
103
+ }
104
+ catch {
105
+ return undefined;
106
+ }
107
+ }
108
+ function unique(values) {
109
+ return [...new Set(values)];
110
+ }
111
+ //# sourceMappingURL=verification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verification.js","sourceRoot":"","sources":["../src/verification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ # Privacy And Trust
2
+
3
+ Deepclean public alpha is report-first. It does not edit application source code.
4
+
5
+ ## Writes
6
+
7
+ Deepclean writes state and artifacts under `.deepclean/` in the target repository:
8
+
9
+ - `.deepclean/config.json`
10
+ - `.deepclean/runs/`
11
+ - `.deepclean/evidence/`
12
+ - `.deepclean/candidates/`
13
+ - `.deepclean/clusters/`
14
+ - `.deepclean/reports/`
15
+ - `.deepclean/plans/`
16
+ - `.deepclean/handoffs/`
17
+ - `.deepclean/triage/`
18
+
19
+ Add `.deepclean/` to `.gitignore` unless a repo deliberately wants to share reports.
20
+
21
+ ## Local Evidence
22
+
23
+ `deepclean scan` reads source files and repository metadata locally. It records structured evidence such as file metrics, duplicate windows, import graph summaries, TypeScript/Python structure, git churn, and test-discovery signals.
24
+
25
+ ## Codex Synthesis
26
+
27
+ `deepclean scan --synthesize` invokes the local `codex` command in read-only mode. By default the prompt includes structured evidence and redacts source samples. It does not dynamically load OpenClaw skills or arbitrary local agent instructions; the built-in reviewer pack is recorded in candidate provenance.
28
+
29
+ Use `--allow-source-in-model` only when the target repo and configured provider are allowed to receive source excerpts. This may include snippets from files that triggered local evidence.
30
+
31
+ ## Network
32
+
33
+ Deepclean does not do web research in public alpha. `privacy.allowWebResearch` is reserved for a future explicit feature and defaults to `false`.
@@ -0,0 +1,19 @@
1
+ # Public Readiness Notes
2
+
3
+ Deepclean is now shaped like a public CLI rather than a local experiment:
4
+
5
+ - `.deepclean/`, local agent folders, logs, tarballs, dependencies, and build output are ignored.
6
+ - CI runs typecheck, tests, build, package smoke, and optional OpenSpec validation.
7
+ - `npm run release:check` validates the packed tarball and rejects private artifacts.
8
+ - Reports are source-safe by default and source excerpts are not sent to Codex unless explicitly enabled.
9
+ - External analyzer evidence can be ingested through SARIF and optional `jscpd`.
10
+ - Codex synthesis now uses a built-in reviewer pack informed by a vendored MIT-licensed Matt Pocock skills snapshot, while keeping runtime prompts reproducible and source-safe.
11
+ - Reports now separate the agent queue from raw candidate evidence, return explicit artifact paths in JSON, and infer verification commands from the target repository's Makefile and package scripts.
12
+
13
+ ## Still Deliberately Deferred
14
+
15
+ - Naming and brand decisions.
16
+ - Fix/recheck/open-pr loop.
17
+ - npm publish.
18
+
19
+ Those are product/release decisions, not accidental implementation gaps.
@@ -0,0 +1,33 @@
1
+ # Reviewer References
2
+
3
+ Deepclean keeps its synthesis reviewer pack built in, but it now uses a vendored Matt Pocock skills snapshot as a reference source for reviewer design.
4
+
5
+ ## Matt Pocock Skills Snapshot
6
+
7
+ - Source: <https://github.com/mattpocock/skills>
8
+ - Snapshot: `third_party/matt-pocock-skills/`
9
+ - License: MIT, Copyright (c) 2026 Matt Pocock
10
+ - Snapshot commit: recorded in `third_party/matt-pocock-skills/SNAPSHOT.md`
11
+
12
+ The snapshot is not loaded dynamically during public-alpha scans. Runtime synthesis uses distilled reviewer rubrics in `src/reviewers.ts` so outputs are reproducible and package installs do not depend on private agent workspaces or live network access.
13
+
14
+ ## Distilled Reviewer Additions
15
+
16
+ The default reviewer pack now includes Matt Pocock-inspired rubrics for:
17
+
18
+ - deep module discipline
19
+ - feedback loop discipline
20
+ - agent-ready cleanup slices
21
+
22
+ These complement the existing Deepclean reviewers for architecture, duplication, dependency graph shape, testability, domain language, AI-slop patterns, and critic pass.
23
+
24
+ ## Update Policy
25
+
26
+ When refreshing the snapshot:
27
+
28
+ 1. Run `npm run sync:matt-skills`.
29
+ 2. Review upstream license and repository shape before copying any new guidance into reviewer rubrics.
30
+ 3. Keep the upstream MIT license and copyright notice.
31
+ 4. Confirm `third_party/matt-pocock-skills/SNAPSHOT.md` records the new commit.
32
+ 5. Distill useful engineering principles into built-in rubrics instead of dumping the full upstream skill text into every prompt.
33
+ 6. Run `npm run release:check` and `npm run spec:validate`.
@@ -0,0 +1,80 @@
1
+ # Troubleshooting
2
+
3
+ ## Codex Is Missing
4
+
5
+ Run:
6
+
7
+ ```bash
8
+ codex --version
9
+ ```
10
+
11
+ If that fails, install or configure the Codex CLI before using `deepclean scan --synthesize`. Plain `deepclean scan` still works without Codex.
12
+
13
+ ## Codex Auth Fails
14
+
15
+ If synthesis reports an auth or login warning, re-authenticate Codex in the local environment and rerun:
16
+
17
+ ```bash
18
+ deepclean scan --synthesize --json
19
+ ```
20
+
21
+ Deepclean preserves local evidence and local candidates when synthesis fails.
22
+
23
+ ## Codex Times Out
24
+
25
+ Increase `.deepclean/config.json`:
26
+
27
+ ```json
28
+ {
29
+ "reviewSynthesis": {
30
+ "timeoutMs": 180000
31
+ }
32
+ }
33
+ ```
34
+
35
+ Large repos should also tune `candidateCaps` and `clusters` before synthesis.
36
+
37
+ ## Missing Git History
38
+
39
+ The git-history adapter is skipped when the target directory is not a git repository. The rest of the scan still runs.
40
+
41
+ ## Noisy Reports
42
+
43
+ Use candidate caps and broad-theme controls:
44
+
45
+ ```json
46
+ {
47
+ "candidateCaps": {
48
+ "byKind": {
49
+ "duplicate-cluster": 8
50
+ },
51
+ "byKindAndArea": {
52
+ "large-file": 4
53
+ }
54
+ },
55
+ "clusters": {
56
+ "maxCandidates": 10,
57
+ "maxFiles": 12,
58
+ "splitBroad": true
59
+ }
60
+ }
61
+ ```
62
+
63
+ Themes marked `too-broad` should be split or triaged before handing work to an agent.
64
+
65
+ ## External Analyzer Evidence
66
+
67
+ Deepclean can ingest SARIF files from tools such as Semgrep when they are present at configured paths:
68
+
69
+ ```bash
70
+ semgrep scan --sarif --output semgrep.sarif
71
+ deepclean scan --json
72
+ ```
73
+
74
+ Optional `jscpd` evidence is disabled by default because it requires the `jscpd` command locally:
75
+
76
+ ```bash
77
+ npm install -g jscpd
78
+ ```
79
+
80
+ Then enable it in `.deepclean/config.json`.
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@fraction12/deepclean",
3
+ "version": "0.1.0-alpha.0",
4
+ "private": false,
5
+ "description": "Clawpatch-style cleanup reports for working-but-sloppy codebases.",
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/fraction12/deepclean#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/fraction12/deepclean.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/fraction12/deepclean/issues"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "!dist/**/*.test.js",
19
+ "!dist/**/*.test.js.map",
20
+ "!dist/**/*.test.d.ts",
21
+ "README.md",
22
+ "LICENSE",
23
+ "CHANGELOG.md",
24
+ "docs/privacy-and-trust.md",
25
+ "docs/public-readiness.md",
26
+ "docs/reviewer-references.md",
27
+ "docs/troubleshooting.md"
28
+ ],
29
+ "bin": {
30
+ "deepclean": "dist/cli.js"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc -p tsconfig.json",
34
+ "typecheck": "tsc -p tsconfig.json --noEmit",
35
+ "ci": "npm run typecheck && npm test && npm run build && npm run smoke:package",
36
+ "dev": "tsx src/cli.ts",
37
+ "release:check": "npm run ci && node scripts/release-check.mjs",
38
+ "spec:validate": "node scripts/spec-validate.mjs",
39
+ "sync:matt-skills": "node scripts/sync-matt-pocock-skills.mjs",
40
+ "test": "vitest run src/cli.test.ts",
41
+ "smoke:package": "npm run build && node scripts/package-smoke.mjs"
42
+ },
43
+ "engines": {
44
+ "node": ">=22"
45
+ },
46
+ "dependencies": {
47
+ "typescript": "^6.0.3",
48
+ "zod": "^4.4.3"
49
+ },
50
+ "devDependencies": {
51
+ "@types/node": "^25.8.0",
52
+ "tsx": "^4.22.3",
53
+ "vitest": "^4.1.6"
54
+ }
55
+ }