patchdrill 0.1.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 (169) hide show
  1. package/.patchdrill.yml +33 -0
  2. package/CHANGELOG.md +150 -0
  3. package/CONTRIBUTING.md +59 -0
  4. package/LICENSE +21 -0
  5. package/README.md +601 -0
  6. package/SECURITY.md +28 -0
  7. package/action.yml +338 -0
  8. package/dist/baseline.d.ts +9 -0
  9. package/dist/baseline.js +38 -0
  10. package/dist/baseline.js.map +1 -0
  11. package/dist/cli.d.ts +19 -0
  12. package/dist/cli.js +662 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/codeowners.d.ts +14 -0
  15. package/dist/codeowners.js +104 -0
  16. package/dist/codeowners.js.map +1 -0
  17. package/dist/command-plan.d.ts +3 -0
  18. package/dist/command-plan.js +26 -0
  19. package/dist/command-plan.js.map +1 -0
  20. package/dist/demo.d.ts +5 -0
  21. package/dist/demo.js +525 -0
  22. package/dist/demo.js.map +1 -0
  23. package/dist/dependency.d.ts +4 -0
  24. package/dist/dependency.js +1424 -0
  25. package/dist/dependency.js.map +1 -0
  26. package/dist/doctor.d.ts +26 -0
  27. package/dist/doctor.js +183 -0
  28. package/dist/doctor.js.map +1 -0
  29. package/dist/evidence.d.ts +64 -0
  30. package/dist/evidence.js +352 -0
  31. package/dist/evidence.js.map +1 -0
  32. package/dist/git.d.ts +16 -0
  33. package/dist/git.js +349 -0
  34. package/dist/git.js.map +1 -0
  35. package/dist/i18n-catalog.d.ts +8 -0
  36. package/dist/i18n-catalog.js +446 -0
  37. package/dist/i18n-catalog.js.map +1 -0
  38. package/dist/i18n.d.ts +20 -0
  39. package/dist/i18n.js +67 -0
  40. package/dist/i18n.js.map +1 -0
  41. package/dist/init.d.ts +13 -0
  42. package/dist/init.js +312 -0
  43. package/dist/init.js.map +1 -0
  44. package/dist/markdown-links.d.ts +18 -0
  45. package/dist/markdown-links.js +180 -0
  46. package/dist/markdown-links.js.map +1 -0
  47. package/dist/package-scripts.d.ts +3 -0
  48. package/dist/package-scripts.js +55 -0
  49. package/dist/package-scripts.js.map +1 -0
  50. package/dist/planner.d.ts +8 -0
  51. package/dist/planner.js +2351 -0
  52. package/dist/planner.js.map +1 -0
  53. package/dist/policy.d.ts +12 -0
  54. package/dist/policy.js +255 -0
  55. package/dist/policy.js.map +1 -0
  56. package/dist/project.d.ts +2 -0
  57. package/dist/project.js +1085 -0
  58. package/dist/project.js.map +1 -0
  59. package/dist/release-readiness.d.ts +25 -0
  60. package/dist/release-readiness.js +426 -0
  61. package/dist/release-readiness.js.map +1 -0
  62. package/dist/report-annotations.d.ts +3 -0
  63. package/dist/report-annotations.js +28 -0
  64. package/dist/report-annotations.js.map +1 -0
  65. package/dist/report-contract.d.ts +2 -0
  66. package/dist/report-contract.js +82 -0
  67. package/dist/report-contract.js.map +1 -0
  68. package/dist/report-html.d.ts +7 -0
  69. package/dist/report-html.js +706 -0
  70. package/dist/report-html.js.map +1 -0
  71. package/dist/report-sarif.d.ts +2 -0
  72. package/dist/report-sarif.js +90 -0
  73. package/dist/report-sarif.js.map +1 -0
  74. package/dist/report.d.ts +14 -0
  75. package/dist/report.js +310 -0
  76. package/dist/report.js.map +1 -0
  77. package/dist/risk.d.ts +19 -0
  78. package/dist/risk.js +1226 -0
  79. package/dist/risk.js.map +1 -0
  80. package/dist/runner.d.ts +8 -0
  81. package/dist/runner.js +113 -0
  82. package/dist/runner.js.map +1 -0
  83. package/dist/scan.d.ts +2 -0
  84. package/dist/scan.js +195 -0
  85. package/dist/scan.js.map +1 -0
  86. package/dist/schema.d.ts +12 -0
  87. package/dist/schema.js +30 -0
  88. package/dist/schema.js.map +1 -0
  89. package/dist/stack-coverage.d.ts +8 -0
  90. package/dist/stack-coverage.js +94 -0
  91. package/dist/stack-coverage.js.map +1 -0
  92. package/dist/types.d.ts +206 -0
  93. package/dist/types.js +2 -0
  94. package/dist/types.js.map +1 -0
  95. package/dist/verification.d.ts +11 -0
  96. package/dist/verification.js +108 -0
  97. package/dist/verification.js.map +1 -0
  98. package/docs/ANNOTATIONS.md +34 -0
  99. package/docs/ARCHITECTURE.md +79 -0
  100. package/docs/BASELINES.md +32 -0
  101. package/docs/CASE_STUDIES.md +106 -0
  102. package/docs/CODEOWNERS.md +23 -0
  103. package/docs/DASHBOARD.md +87 -0
  104. package/docs/EVIDENCE.md +55 -0
  105. package/docs/LAUNCH_PLAYBOOK.md +103 -0
  106. package/docs/MONOREPOS.md +74 -0
  107. package/docs/POLICY.md +98 -0
  108. package/docs/PROOF_PACKS.md +57 -0
  109. package/docs/PR_COMMENTS.md +56 -0
  110. package/docs/RELEASE.md +35 -0
  111. package/docs/ROADMAP.md +152 -0
  112. package/docs/RULE_CATALOG.md +90 -0
  113. package/docs/SARIF.md +74 -0
  114. package/docs/SCHEMAS.md +49 -0
  115. package/docs/SECURITY_POSTURE.md +32 -0
  116. package/docs/STACK_COVERAGE.md +20 -0
  117. package/docs/assets/patchdrill-demo.svg +21 -0
  118. package/docs/media/patchdrill-dashboard.png +0 -0
  119. package/docs/media/patchdrill-demo.gif +0 -0
  120. package/examples/case-studies/README.md +20 -0
  121. package/examples/demo/README.md +21 -0
  122. package/examples/demo/patchdrill-demo-summary.md +35 -0
  123. package/examples/demo/patchdrill-demo.html +623 -0
  124. package/examples/demo/patchdrill-demo.json +355 -0
  125. package/examples/demo/patchdrill-demo.md +120 -0
  126. package/examples/demo/patchdrill-demo.sarif +195 -0
  127. package/examples/report.md +128 -0
  128. package/examples/risky-agent-pr/README.md +15 -0
  129. package/examples/risky-agent-pr/patchdrill-demo-summary.md +41 -0
  130. package/examples/risky-agent-pr/patchdrill-demo.html +681 -0
  131. package/examples/risky-agent-pr/patchdrill-demo.json +483 -0
  132. package/examples/risky-agent-pr/patchdrill-demo.md +140 -0
  133. package/examples/risky-agent-pr/patchdrill-demo.sarif +398 -0
  134. package/fixtures/stacks/README.md +4 -0
  135. package/fixtures/stacks/android-gradle/fixture.json +33 -0
  136. package/fixtures/stacks/aspnet-core-service/fixture.json +36 -0
  137. package/fixtures/stacks/bazel-workspace/fixture.json +30 -0
  138. package/fixtures/stacks/buck2-workspace/fixture.json +30 -0
  139. package/fixtures/stacks/cargo-workspace/fixture.json +48 -0
  140. package/fixtures/stacks/django-app/fixture.json +25 -0
  141. package/fixtures/stacks/docker-compose/fixture.json +17 -0
  142. package/fixtures/stacks/dockerfile-service/fixture.json +17 -0
  143. package/fixtures/stacks/dotnet-service/fixture.json +36 -0
  144. package/fixtures/stacks/dotnet-solution-filter/fixture.json +62 -0
  145. package/fixtures/stacks/fastapi-app/fixture.json +29 -0
  146. package/fixtures/stacks/go-workspace/fixture.json +48 -0
  147. package/fixtures/stacks/java-gradle/fixture.json +29 -0
  148. package/fixtures/stacks/java-maven/fixture.json +32 -0
  149. package/fixtures/stacks/kubernetes-helm/fixture.json +25 -0
  150. package/fixtures/stacks/kubernetes-kustomize/fixture.json +21 -0
  151. package/fixtures/stacks/nested-go-workspace/fixture.json +51 -0
  152. package/fixtures/stacks/nextjs-app/fixture.json +34 -0
  153. package/fixtures/stacks/node-turbo-workspace/fixture.json +39 -0
  154. package/fixtures/stacks/pants-python/fixture.json +33 -0
  155. package/fixtures/stacks/php-composer/fixture.json +31 -0
  156. package/fixtures/stacks/python-service/fixture.json +21 -0
  157. package/fixtures/stacks/rails-app/fixture.json +25 -0
  158. package/fixtures/stacks/spring-boot-gradle/fixture.json +29 -0
  159. package/fixtures/stacks/spring-boot-maven/fixture.json +43 -0
  160. package/fixtures/stacks/swift-package/fixture.json +21 -0
  161. package/fixtures/stacks/terraform-module/fixture.json +17 -0
  162. package/fixtures/stacks/uv-python-service/fixture.json +47 -0
  163. package/fixtures/stacks/xcode-app/fixture.json +72 -0
  164. package/package.json +80 -0
  165. package/schemas/patchdrill-doctor.schema.json +171 -0
  166. package/schemas/patchdrill-evidence.schema.json +239 -0
  167. package/schemas/patchdrill-policy.schema.json +170 -0
  168. package/schemas/patchdrill-release-check.schema.json +78 -0
  169. package/schemas/patchdrill-report.schema.json +647 -0
@@ -0,0 +1,180 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
2
+ import { dirname, extname, relative, resolve } from "node:path";
3
+ export function checkMarkdownLinks(root, paths = defaultMarkdownLinkPaths(root)) {
4
+ const failures = [];
5
+ let linkCount = 0;
6
+ for (const file of paths) {
7
+ const absoluteFile = resolve(root, file);
8
+ const contents = readFileSync(absoluteFile, "utf8");
9
+ const lines = contents.split(/\r?\n/);
10
+ let inFence = false;
11
+ for (const [index, line] of lines.entries()) {
12
+ if (/^\s*(```|~~~)/.test(line)) {
13
+ inFence = !inFence;
14
+ continue;
15
+ }
16
+ if (inFence)
17
+ continue;
18
+ for (const target of extractMarkdownLinkTargets(line)) {
19
+ const normalized = normalizeMarkdownTarget(target);
20
+ if (!normalized || shouldSkipTarget(normalized))
21
+ continue;
22
+ linkCount += 1;
23
+ const failure = checkMarkdownTarget(root, file, absoluteFile, index + 1, normalized);
24
+ if (failure)
25
+ failures.push(failure);
26
+ }
27
+ }
28
+ }
29
+ return {
30
+ summary: {
31
+ fileCount: paths.length,
32
+ linkCount,
33
+ failureCount: failures.length
34
+ },
35
+ failures
36
+ };
37
+ }
38
+ export function defaultMarkdownLinkPaths(root) {
39
+ const paths = new Set();
40
+ if (existsSync(resolve(root, "README.md")))
41
+ paths.add("README.md");
42
+ for (const directory of ["docs", "examples"]) {
43
+ const absoluteDirectory = resolve(root, directory);
44
+ if (!existsSync(absoluteDirectory))
45
+ continue;
46
+ for (const path of walkMarkdownFiles(root, absoluteDirectory))
47
+ paths.add(path);
48
+ }
49
+ return [...paths].sort((a, b) => a.localeCompare(b));
50
+ }
51
+ function checkMarkdownTarget(root, file, absoluteFile, line, target) {
52
+ const [pathPart, anchorPart] = splitAnchor(target);
53
+ const targetPath = pathPart ? decodePathPart(pathPart) : file;
54
+ const absoluteTarget = pathPart ? resolve(dirname(absoluteFile), targetPath) : absoluteFile;
55
+ const relativeTarget = relative(root, absoluteTarget).replaceAll("\\", "/");
56
+ if (relativeTarget.startsWith("../") || relativeTarget === "..") {
57
+ return {
58
+ file,
59
+ line,
60
+ target,
61
+ reason: "Local link points outside the repository.",
62
+ resolvedPath: relativeTarget
63
+ };
64
+ }
65
+ if (!existsSync(absoluteTarget)) {
66
+ return {
67
+ file,
68
+ line,
69
+ target,
70
+ reason: "Local link target does not exist.",
71
+ resolvedPath: relativeTarget
72
+ };
73
+ }
74
+ if (anchorPart) {
75
+ const stat = statSync(absoluteTarget);
76
+ if (stat.isDirectory())
77
+ return undefined;
78
+ if (!isMarkdownPath(absoluteTarget)) {
79
+ return {
80
+ file,
81
+ line,
82
+ target,
83
+ reason: "Anchor links can only be verified for Markdown files.",
84
+ resolvedPath: relativeTarget
85
+ };
86
+ }
87
+ const anchors = markdownAnchors(readFileSync(absoluteTarget, "utf8"));
88
+ const anchor = slugAnchor(anchorPart);
89
+ if (!anchors.has(anchor)) {
90
+ return {
91
+ file,
92
+ line,
93
+ target,
94
+ reason: "Markdown anchor was not found in the target file.",
95
+ resolvedPath: relativeTarget
96
+ };
97
+ }
98
+ }
99
+ return undefined;
100
+ }
101
+ function extractMarkdownLinkTargets(line) {
102
+ const targets = [];
103
+ const pattern = /!?\[[^\]\n]*\]\(([^)\n]+)\)/g;
104
+ let match;
105
+ while ((match = pattern.exec(line)) !== null) {
106
+ if (match[1])
107
+ targets.push(match[1]);
108
+ }
109
+ return targets;
110
+ }
111
+ function normalizeMarkdownTarget(value) {
112
+ let target = value.trim();
113
+ if (!target)
114
+ return undefined;
115
+ const angle = /^<([^>]+)>/.exec(target);
116
+ if (angle?.[1])
117
+ target = angle[1].trim();
118
+ target = target.replace(/\s+["'][^"']*["']\s*$/, "").trim();
119
+ return target || undefined;
120
+ }
121
+ function shouldSkipTarget(target) {
122
+ return target.startsWith("//") || /^[a-z][a-z0-9+.-]*:/i.test(target);
123
+ }
124
+ function splitAnchor(target) {
125
+ const hashIndex = target.indexOf("#");
126
+ const withoutHash = hashIndex >= 0 ? target.slice(0, hashIndex) : target;
127
+ const withoutQuery = withoutHash.split("?", 1)[0] ?? "";
128
+ return [withoutQuery, hashIndex >= 0 ? target.slice(hashIndex + 1) : undefined];
129
+ }
130
+ function decodePathPart(path) {
131
+ try {
132
+ return decodeURIComponent(path);
133
+ }
134
+ catch {
135
+ return path;
136
+ }
137
+ }
138
+ function markdownAnchors(contents) {
139
+ const anchors = new Set();
140
+ const seen = new Map();
141
+ for (const line of contents.split(/\r?\n/)) {
142
+ const match = /^(#{1,6})\s+(.+?)\s*$/.exec(line);
143
+ if (!match?.[2])
144
+ continue;
145
+ const base = slugAnchor(match[2]);
146
+ const count = seen.get(base) ?? 0;
147
+ seen.set(base, count + 1);
148
+ anchors.add(count === 0 ? base : `${base}-${count}`);
149
+ }
150
+ return anchors;
151
+ }
152
+ function slugAnchor(value) {
153
+ return value
154
+ .trim()
155
+ .replace(/`([^`]+)`/g, "$1")
156
+ .toLowerCase()
157
+ .replace(/&amp;/g, "")
158
+ .replace(/[^a-z0-9가-힣 _-]/g, "")
159
+ .trim()
160
+ .replace(/\s+/g, "-");
161
+ }
162
+ function walkMarkdownFiles(root, directory) {
163
+ const results = [];
164
+ for (const entry of readdirSync(directory, { withFileTypes: true, encoding: "utf8" })) {
165
+ const absolutePath = resolve(directory, entry.name);
166
+ if (entry.isDirectory()) {
167
+ for (const match of walkMarkdownFiles(root, absolutePath))
168
+ results.push(match);
169
+ continue;
170
+ }
171
+ if (entry.isFile() && isMarkdownPath(entry.name)) {
172
+ results.push(relative(root, absolutePath).replaceAll("\\", "/"));
173
+ }
174
+ }
175
+ return results;
176
+ }
177
+ function isMarkdownPath(path) {
178
+ return [".md", ".markdown"].includes(extname(path).toLowerCase());
179
+ }
180
+ //# sourceMappingURL=markdown-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-links.js","sourceRoot":"","sources":["../src/markdown-links.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type GitDiffOptions } from "./git.js";
2
+ import type { ChangedFile, PackageScriptChange } from "./types.js";
3
+ export declare function analyzePackageScriptChanges(options: GitDiffOptions, changedFiles: ChangedFile[]): PackageScriptChange[];
@@ -0,0 +1,55 @@
1
+ import { readFilePair } from "./git.js";
2
+ export function analyzePackageScriptChanges(options, changedFiles) {
3
+ const changes = [];
4
+ for (const file of changedFiles.filter((candidate) => candidate.path.endsWith("package.json"))) {
5
+ const pair = readFilePair(options, file.path);
6
+ const before = parsePackageScripts(pair.before);
7
+ const after = parsePackageScripts(pair.after);
8
+ if (!before && !after)
9
+ continue;
10
+ changes.push(...diffPackageScripts(file.path, before ?? {}, after ?? {}));
11
+ }
12
+ return changes.sort((a, b) => `${a.file}:${a.scriptName}`.localeCompare(`${b.file}:${b.scriptName}`));
13
+ }
14
+ function diffPackageScripts(file, before, after) {
15
+ const changes = [];
16
+ const scriptNames = new Set([...Object.keys(before), ...Object.keys(after)]);
17
+ for (const scriptName of scriptNames) {
18
+ const beforeScript = before[scriptName];
19
+ const afterScript = after[scriptName];
20
+ if (beforeScript === afterScript)
21
+ continue;
22
+ if (beforeScript === undefined && afterScript !== undefined) {
23
+ changes.push({ file, scriptName, changeType: "added", after: afterScript });
24
+ }
25
+ else if (beforeScript !== undefined && afterScript === undefined) {
26
+ changes.push({ file, scriptName, changeType: "removed", before: beforeScript });
27
+ }
28
+ else if (beforeScript !== undefined && afterScript !== undefined) {
29
+ changes.push({ file, scriptName, changeType: "updated", before: beforeScript, after: afterScript });
30
+ }
31
+ }
32
+ return changes;
33
+ }
34
+ function parsePackageScripts(value) {
35
+ if (!value)
36
+ return undefined;
37
+ try {
38
+ const parsed = JSON.parse(value);
39
+ if (!parsed || typeof parsed !== "object")
40
+ return undefined;
41
+ const scriptsValue = parsed.scripts;
42
+ if (!scriptsValue || typeof scriptsValue !== "object")
43
+ return undefined;
44
+ const scripts = {};
45
+ for (const [scriptName, command] of Object.entries(scriptsValue)) {
46
+ if (typeof command === "string")
47
+ scripts[scriptName] = command;
48
+ }
49
+ return scripts;
50
+ }
51
+ catch {
52
+ return undefined;
53
+ }
54
+ }
55
+ //# sourceMappingURL=package-scripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-scripts.js","sourceRoot":"","sources":["../src/package-scripts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ChangedFile, CommandPlan, ProjectSignal, WorkspacePackage } from "./types.js";
2
+ export interface PlannerOptions {
3
+ changedSince?: string;
4
+ }
5
+ export declare function planCommands(root: string, changedFiles: ChangedFile[], signals: ProjectSignal[], options?: PlannerOptions): CommandPlan[];
6
+ export declare function supportedPlannerEcosystems(): ProjectSignal["ecosystem"][];
7
+ export declare function nodeTaskAliases(id: string): string[];
8
+ export declare function findAffectedWorkspacePackages(changedFiles: ChangedFile[], signals: ProjectSignal[]): WorkspacePackage[];