co-maintainer 0.4.1 → 0.4.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
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# co-maintainer
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/co-maintainer)
|
|
4
|
+
|
|
3
5
|
`co-maintainer` analyzes a GitHub repository and writes repository-specific
|
|
4
6
|
`SKILL.md` guidance that helps developers contribute changes more reliably.
|
|
5
7
|
|
package/dist/package.json
CHANGED
|
@@ -314,9 +314,12 @@ export function extractFacts(source, options) {
|
|
|
314
314
|
.join("; ")}.`, "commit history", 2));
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
317
|
+
const currentPaths = new Set(source.tree);
|
|
318
|
+
const changedFiles = source.pullRequests
|
|
319
|
+
.flatMap((pr) => pr.changedFiles)
|
|
320
|
+
.filter((path) => currentPaths.has(path));
|
|
321
|
+
if (options.includePullRequestChanges && changedFiles.length) {
|
|
322
|
+
const files = counts(changedFiles).slice(0, 10);
|
|
320
323
|
add(facts, fact("review-bar", `Frequently changed files include ${files
|
|
321
324
|
.map(([path]) => `\`${path}\``)
|
|
322
325
|
.join(", ")}; check nearby tests and workflows before editing.`, "pull request files", 2));
|
|
@@ -2,5 +2,6 @@ import type { Source } from "./types.ts";
|
|
|
2
2
|
export type ValidationResult = {
|
|
3
3
|
valid: boolean;
|
|
4
4
|
errors: string[];
|
|
5
|
+
warnings: string[];
|
|
5
6
|
};
|
|
6
|
-
export declare function validateSkill(markdown: string, outputDirectory: string, source?: Source): Promise<ValidationResult>;
|
|
7
|
+
export declare function validateSkill(markdown: string, outputDirectory: string, source?: Source, referenceIssues?: "error" | "warning"): Promise<ValidationResult>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { stat } from "../util/runtime.js";
|
|
2
|
-
export async function validateSkill(markdown, outputDirectory, source) {
|
|
2
|
+
export async function validateSkill(markdown, outputDirectory, source, referenceIssues = "error") {
|
|
3
3
|
const errors = [];
|
|
4
|
+
const warnings = [];
|
|
5
|
+
const referenceProblems = referenceIssues === "error" ? errors : warnings;
|
|
4
6
|
if (!markdown.startsWith("---\n"))
|
|
5
7
|
errors.push("missing YAML frontmatter");
|
|
6
8
|
if (!/^name:\s+\S+/m.test(markdown))
|
|
@@ -104,14 +106,14 @@ export async function validateSkill(markdown, outputDirectory, source) {
|
|
|
104
106
|
![...paths].some((path) => wildcardPattern
|
|
105
107
|
? wildcardPattern.test(path)
|
|
106
108
|
: path.startsWith(`${normalized}/`))) {
|
|
107
|
-
|
|
109
|
+
referenceProblems.push(`referenced path is absent from source: ${reference}`);
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
if (/^(?:npm|pnpm|yarn|bun|deno|cargo|make|go|python|node|git)\s/.test(reference) &&
|
|
111
113
|
![...commands].some((command) => reference === command ||
|
|
112
114
|
reference.startsWith(`${command} `) ||
|
|
113
115
|
command.startsWith(`${reference} `))) {
|
|
114
|
-
|
|
116
|
+
referenceProblems.push(`referenced command is absent from source: ${reference}`);
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
}
|
|
@@ -130,5 +132,5 @@ export async function validateSkill(markdown, outputDirectory, source) {
|
|
|
130
132
|
errors.push(`linked file does not exist: ${link}`);
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
|
-
return { valid: errors.length === 0, errors };
|
|
135
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
134
136
|
}
|
|
@@ -211,7 +211,10 @@ export async function runInitOrRemake(options) {
|
|
|
211
211
|
result = await timed("reassemble valid skill", options.logTime, () => assembleSkill(options.repo, facts, previousMarkdown, previous?.sectionHashes ?? {}, overrides));
|
|
212
212
|
result.markdown = addReviewLink(result.markdown, reviewDocuments);
|
|
213
213
|
}
|
|
214
|
-
const finalValidation = await timed("final skill validation", options.logTime, () => validateSkill(result.markdown, `${reposDir()}/${options.repo}`, source));
|
|
214
|
+
const finalValidation = await timed("final skill validation", options.logTime, () => validateSkill(result.markdown, `${reposDir()}/${options.repo}`, source, "warning"));
|
|
215
|
+
if (finalValidation.warnings.length) {
|
|
216
|
+
log("validate", `stale references kept: ${finalValidation.warnings.join(", ")}`);
|
|
217
|
+
}
|
|
215
218
|
if (!finalValidation.valid) {
|
|
216
219
|
throw new Error(`generated skill is invalid: ${finalValidation.errors.join("; ")}`);
|
|
217
220
|
}
|