@humanbased/crosscheck 1.2.0-beta.57 → 1.2.0-beta.68
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 +26 -0
- package/assets/skills/code-review/.crosscheck-skill.json +9 -0
- package/assets/skills/code-review/LICENSE +21 -0
- package/assets/skills/code-review/SKILL.md +89 -0
- package/assets/skills/code-review/agents/openai.yaml +3 -0
- package/assets/skills/code-review-skill/.crosscheck-skill.json +9 -0
- package/assets/skills/code-review-skill/LICENSE +21 -0
- package/assets/skills/code-review-skill/SKILL.md +231 -0
- package/assets/skills/code-review-skill/assets/pr-review-template.md +137 -0
- package/assets/skills/code-review-skill/assets/review-checklist.md +123 -0
- package/assets/skills/code-review-skill/reference/angular.md +768 -0
- package/assets/skills/code-review-skill/reference/architecture-review-guide.md +472 -0
- package/assets/skills/code-review-skill/reference/c.md +890 -0
- package/assets/skills/code-review-skill/reference/code-quality-universal.md +488 -0
- package/assets/skills/code-review-skill/reference/code-review-best-practices.md +136 -0
- package/assets/skills/code-review-skill/reference/common-bugs-checklist.md +286 -0
- package/assets/skills/code-review-skill/reference/cpp.md +893 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/async-concurrency-patterns.md +515 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/error-handling-principles.md +492 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/n-plus-one-queries.md +309 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/sql-injection-prevention.md +308 -0
- package/assets/skills/code-review-skill/reference/cross-cutting/xss-prevention.md +264 -0
- package/assets/skills/code-review-skill/reference/csharp.md +525 -0
- package/assets/skills/code-review-skill/reference/css-less-sass.md +661 -0
- package/assets/skills/code-review-skill/reference/django.md +985 -0
- package/assets/skills/code-review-skill/reference/fastapi.md +580 -0
- package/assets/skills/code-review-skill/reference/go.md +993 -0
- package/assets/skills/code-review-skill/reference/java.md +409 -0
- package/assets/skills/code-review-skill/reference/java8.md +586 -0
- package/assets/skills/code-review-skill/reference/kotlin.md +1018 -0
- package/assets/skills/code-review-skill/reference/nestjs.md +593 -0
- package/assets/skills/code-review-skill/reference/performance-review-guide.md +816 -0
- package/assets/skills/code-review-skill/reference/php.md +684 -0
- package/assets/skills/code-review-skill/reference/python.md +1073 -0
- package/assets/skills/code-review-skill/reference/qt.md +757 -0
- package/assets/skills/code-review-skill/reference/react.md +871 -0
- package/assets/skills/code-review-skill/reference/ruby.md +964 -0
- package/assets/skills/code-review-skill/reference/rust.md +846 -0
- package/assets/skills/code-review-skill/reference/security-review-guide.md +494 -0
- package/assets/skills/code-review-skill/reference/svelte.md +1064 -0
- package/assets/skills/code-review-skill/reference/swift.md +936 -0
- package/assets/skills/code-review-skill/reference/typescript.md +1016 -0
- package/assets/skills/code-review-skill/reference/vue.md +924 -0
- package/assets/skills/code-review-skill/reference/zig.md +440 -0
- package/assets/skills/code-review-skill/scripts/pr-analyzer.py +435 -0
- package/assets/skills/code-review-skill/scripts/test_pr_analyzer.py +380 -0
- package/assets/skills/codebase-design/.crosscheck-skill.json +9 -0
- package/assets/skills/codebase-design/DEEPENING.md +37 -0
- package/assets/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
- package/assets/skills/codebase-design/LICENSE +21 -0
- package/assets/skills/codebase-design/SKILL.md +114 -0
- package/assets/skills/codebase-design/agents/openai.yaml +3 -0
- package/assets/skills/diagnosing-bugs/.crosscheck-skill.json +9 -0
- package/assets/skills/diagnosing-bugs/LICENSE +21 -0
- package/assets/skills/diagnosing-bugs/SKILL.md +134 -0
- package/assets/skills/diagnosing-bugs/agents/openai.yaml +3 -0
- package/assets/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
- package/crosscheck.config.example.yml +10 -0
- package/dist/__tests__/conflict-resolve.test.js +44 -1
- package/dist/__tests__/conflict-resolve.test.js.map +1 -1
- package/dist/__tests__/fix.test.js +31 -0
- package/dist/__tests__/fix.test.js.map +1 -1
- package/dist/__tests__/onboard-preservation.test.js +5 -0
- package/dist/__tests__/onboard-preservation.test.js.map +1 -1
- package/dist/__tests__/optimize.test.js +1 -0
- package/dist/__tests__/optimize.test.js.map +1 -1
- package/dist/__tests__/repository-guidance.test.d.ts +2 -0
- package/dist/__tests__/repository-guidance.test.d.ts.map +1 -0
- package/dist/__tests__/repository-guidance.test.js +88 -0
- package/dist/__tests__/repository-guidance.test.js.map +1 -0
- package/dist/__tests__/skill-attribution.test.d.ts +2 -0
- package/dist/__tests__/skill-attribution.test.d.ts.map +1 -0
- package/dist/__tests__/skill-attribution.test.js +37 -0
- package/dist/__tests__/skill-attribution.test.js.map +1 -0
- package/dist/__tests__/skill-broker.test.d.ts +2 -0
- package/dist/__tests__/skill-broker.test.d.ts.map +1 -0
- package/dist/__tests__/skill-broker.test.js +92 -0
- package/dist/__tests__/skill-broker.test.js.map +1 -0
- package/dist/__tests__/skill-catalog.test.d.ts +2 -0
- package/dist/__tests__/skill-catalog.test.d.ts.map +1 -0
- package/dist/__tests__/skill-catalog.test.js +35 -0
- package/dist/__tests__/skill-catalog.test.js.map +1 -0
- package/dist/__tests__/skill-installer.test.d.ts +2 -0
- package/dist/__tests__/skill-installer.test.d.ts.map +1 -0
- package/dist/__tests__/skill-installer.test.js +96 -0
- package/dist/__tests__/skill-installer.test.js.map +1 -0
- package/dist/__tests__/skills-config.test.d.ts +2 -0
- package/dist/__tests__/skills-config.test.d.ts.map +1 -0
- package/dist/__tests__/skills-config.test.js +12 -0
- package/dist/__tests__/skills-config.test.js.map +1 -0
- package/dist/cli.js +7 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/onboard.d.ts +1 -0
- package/dist/commands/onboard.d.ts.map +1 -1
- package/dist/commands/onboard.js +25 -1
- package/dist/commands/onboard.js.map +1 -1
- package/dist/commands/review.d.ts.map +1 -1
- package/dist/commands/review.js +15 -4
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/skill.d.ts +2 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +16 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +10 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/config/schema.d.ts +21 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +4 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/lib/repository-guidance.d.ts +2 -0
- package/dist/lib/repository-guidance.d.ts.map +1 -0
- package/dist/lib/repository-guidance.js +55 -0
- package/dist/lib/repository-guidance.js.map +1 -0
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/runner.js +50 -19
- package/dist/lib/runner.js.map +1 -1
- package/dist/reviewers/claude.d.ts +2 -1
- package/dist/reviewers/claude.d.ts.map +1 -1
- package/dist/reviewers/claude.js +21 -3
- package/dist/reviewers/claude.js.map +1 -1
- package/dist/reviewers/codex.d.ts +2 -1
- package/dist/reviewers/codex.d.ts.map +1 -1
- package/dist/reviewers/codex.js +7 -3
- package/dist/reviewers/codex.js.map +1 -1
- package/dist/reviewers/conflict-resolve.d.ts +2 -1
- package/dist/reviewers/conflict-resolve.d.ts.map +1 -1
- package/dist/reviewers/conflict-resolve.js +12 -3
- package/dist/reviewers/conflict-resolve.js.map +1 -1
- package/dist/reviewers/fix.d.ts +3 -2
- package/dist/reviewers/fix.d.ts.map +1 -1
- package/dist/reviewers/fix.js +15 -6
- package/dist/reviewers/fix.js.map +1 -1
- package/dist/skills/attribution.d.ts +4 -0
- package/dist/skills/attribution.d.ts.map +1 -0
- package/dist/skills/attribution.js +10 -0
- package/dist/skills/attribution.js.map +1 -0
- package/dist/skills/broker-server.d.ts +2 -0
- package/dist/skills/broker-server.d.ts.map +1 -0
- package/dist/skills/broker-server.js +30 -0
- package/dist/skills/broker-server.js.map +1 -0
- package/dist/skills/broker.d.ts +42 -0
- package/dist/skills/broker.d.ts.map +1 -0
- package/dist/skills/broker.js +173 -0
- package/dist/skills/broker.js.map +1 -0
- package/dist/skills/catalog.d.ts +26 -0
- package/dist/skills/catalog.d.ts.map +1 -0
- package/dist/skills/catalog.js +91 -0
- package/dist/skills/catalog.js.map +1 -0
- package/dist/skills/installer.d.ts +10 -0
- package/dist/skills/installer.d.ts.map +1 -0
- package/dist/skills/installer.js +136 -0
- package/dist/skills/installer.js.map +1 -0
- package/dist/skills/integrity.d.ts +4 -0
- package/dist/skills/integrity.d.ts.map +1 -0
- package/dist/skills/integrity.js +36 -0
- package/dist/skills/integrity.js.map +1 -0
- package/get-started.md +55 -1
- package/package.json +1 -1
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { cpSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
2
|
+
import { basename, join, resolve } from 'path';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { execa } from 'execa';
|
|
5
|
+
import { INSTALLED_SKILLS_DIR, isValidSkillAuthor, isValidSkillLicense, loadBundledSkills, loadInstalledSkills, readSkillFrontmatter } from './catalog.js';
|
|
6
|
+
import { computeSkillIntegrity } from './integrity.js';
|
|
7
|
+
export { computeSkillIntegrity } from './integrity.js';
|
|
8
|
+
export class SkillInstallError extends Error {
|
|
9
|
+
}
|
|
10
|
+
export function redactSkillSource(source) {
|
|
11
|
+
if (existsSync(source))
|
|
12
|
+
return resolve(source);
|
|
13
|
+
try {
|
|
14
|
+
const url = new URL(source);
|
|
15
|
+
url.username = '';
|
|
16
|
+
url.password = '';
|
|
17
|
+
return url.toString();
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return source;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function detectLicense(rootDir, declared) {
|
|
24
|
+
if (typeof declared === 'string' && declared.trim())
|
|
25
|
+
return declared.trim();
|
|
26
|
+
const licenseName = ['LICENSE', 'LICENSE.md', 'COPYING'].find(name => existsSync(join(rootDir, name)));
|
|
27
|
+
if (!licenseName)
|
|
28
|
+
return 'UNKNOWN';
|
|
29
|
+
const license = readFileSync(join(rootDir, licenseName), 'utf8');
|
|
30
|
+
if (/MIT License/i.test(license))
|
|
31
|
+
return 'MIT';
|
|
32
|
+
if (/Apache License[\s\S]*Version 2\.0/i.test(license))
|
|
33
|
+
return 'Apache-2.0';
|
|
34
|
+
if (/BSD 3-Clause/i.test(license))
|
|
35
|
+
return 'BSD-3-Clause';
|
|
36
|
+
if (/ISC License/i.test(license))
|
|
37
|
+
return 'ISC';
|
|
38
|
+
return 'UNKNOWN';
|
|
39
|
+
}
|
|
40
|
+
function detectAuthor(source, declared) {
|
|
41
|
+
if (typeof declared === 'string' && declared.trim())
|
|
42
|
+
return declared.trim().replace(/^@/, '');
|
|
43
|
+
return /github\.com[/:]([^/]+)/i.exec(source)?.[1] ?? 'local';
|
|
44
|
+
}
|
|
45
|
+
async function checkoutSource(source) {
|
|
46
|
+
if (existsSync(source)) {
|
|
47
|
+
const path = resolve(source);
|
|
48
|
+
if (lstatSync(path).isSymbolicLink())
|
|
49
|
+
throw new SkillInstallError('Skill source cannot be a symbolic link');
|
|
50
|
+
if (!statSync(path).isDirectory())
|
|
51
|
+
throw new SkillInstallError(`Skill source is not a directory: ${source}`);
|
|
52
|
+
return { path, revision: 'local' };
|
|
53
|
+
}
|
|
54
|
+
const cleanup = mkdtempSync(join(tmpdir(), 'crosscheck-skill-clone-'));
|
|
55
|
+
const path = join(cleanup, 'source');
|
|
56
|
+
try {
|
|
57
|
+
await execa('git', ['clone', '--depth', '1', source, path]);
|
|
58
|
+
const revision = (await execa('git', ['-C', path, 'rev-parse', 'HEAD'])).stdout.trim();
|
|
59
|
+
return { path, revision, cleanup };
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
rmSync(cleanup, { recursive: true, force: true });
|
|
63
|
+
throw new SkillInstallError(`Could not clone skill source: ${err instanceof Error ? err.message : String(err)}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function installSkill(source, opts = {}) {
|
|
67
|
+
const installDir = resolve(opts.installDir ?? INSTALLED_SKILLS_DIR);
|
|
68
|
+
const checkout = await checkoutSource(source);
|
|
69
|
+
try {
|
|
70
|
+
if (!existsSync(join(checkout.path, 'SKILL.md'))) {
|
|
71
|
+
throw new SkillInstallError('Skill package must contain SKILL.md');
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
computeSkillIntegrity(checkout.path);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
throw new SkillInstallError(err instanceof Error ? err.message : String(err));
|
|
78
|
+
}
|
|
79
|
+
let frontmatter;
|
|
80
|
+
try {
|
|
81
|
+
frontmatter = readSkillFrontmatter(checkout.path);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
throw new SkillInstallError(`Invalid SKILL.md frontmatter: ${err instanceof Error ? err.message : String(err)}`);
|
|
85
|
+
}
|
|
86
|
+
const name = typeof frontmatter.name === 'string' ? frontmatter.name : '';
|
|
87
|
+
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) {
|
|
88
|
+
throw new SkillInstallError(`Invalid skill name: ${name || '(missing)'}`);
|
|
89
|
+
}
|
|
90
|
+
if (typeof frontmatter.description !== 'string' || !frontmatter.description.trim()) {
|
|
91
|
+
throw new SkillInstallError('Skill frontmatter must include a description');
|
|
92
|
+
}
|
|
93
|
+
if (loadBundledSkills().some(skill => skill.name === name)) {
|
|
94
|
+
throw new SkillInstallError(`Skill ${name} is already bundled with Crosscheck`);
|
|
95
|
+
}
|
|
96
|
+
mkdirSync(installDir, { recursive: true });
|
|
97
|
+
const target = join(installDir, name);
|
|
98
|
+
if (existsSync(target)) {
|
|
99
|
+
throw new SkillInstallError(`Skill ${name} is already installed`);
|
|
100
|
+
}
|
|
101
|
+
const pendingTarget = join(installDir, `.install-${name}-${process.pid}`);
|
|
102
|
+
try {
|
|
103
|
+
cpSync(checkout.path, pendingTarget, {
|
|
104
|
+
recursive: true,
|
|
105
|
+
filter: path => basename(path) !== '.git' && basename(path) !== '.crosscheck-skill.json',
|
|
106
|
+
});
|
|
107
|
+
const author = detectAuthor(source, frontmatter.author);
|
|
108
|
+
const license = detectLicense(checkout.path, frontmatter.license);
|
|
109
|
+
if (!isValidSkillAuthor(author))
|
|
110
|
+
throw new SkillInstallError(`Invalid skill author: ${author}`);
|
|
111
|
+
if (!isValidSkillLicense(license))
|
|
112
|
+
throw new SkillInstallError(`Invalid skill license: ${license}`);
|
|
113
|
+
const receipt = {
|
|
114
|
+
schemaVersion: 1,
|
|
115
|
+
name,
|
|
116
|
+
author,
|
|
117
|
+
license,
|
|
118
|
+
source: redactSkillSource(source),
|
|
119
|
+
revision: checkout.revision,
|
|
120
|
+
integrity: computeSkillIntegrity(pendingTarget),
|
|
121
|
+
};
|
|
122
|
+
writeFileSync(join(pendingTarget, '.crosscheck-skill.json'), `${JSON.stringify(receipt, null, 2)}\n`);
|
|
123
|
+
renameSync(pendingTarget, target);
|
|
124
|
+
return loadInstalledSkills(installDir).find(skill => skill.name === name);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
rmSync(pendingTarget, { recursive: true, force: true });
|
|
128
|
+
throw err;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
if (checkout.cleanup)
|
|
133
|
+
rmSync(checkout.cleanup, { recursive: true, force: true });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/skills/installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.d.ts","sourceRoot":"","sources":["../../src/skills/integrity.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB,OAAQ,CAAA;AAC5C,eAAO,MAAM,uBAAuB,QAAmB,CAAA;AAevD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAc7D"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import { lstatSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
3
|
+
import { join, relative, sep } from 'path';
|
|
4
|
+
export const MAX_SKILL_PACKAGE_FILES = 1_000;
|
|
5
|
+
export const MAX_SKILL_PACKAGE_BYTES = 10 * 1024 * 1024;
|
|
6
|
+
function packageFiles(rootDir, currentDir, files) {
|
|
7
|
+
for (const entry of readdirSync(currentDir, { withFileTypes: true })) {
|
|
8
|
+
if (entry.name === '.git' || entry.name === '.crosscheck-skill.json')
|
|
9
|
+
continue;
|
|
10
|
+
const path = join(currentDir, entry.name);
|
|
11
|
+
if (lstatSync(path).isSymbolicLink())
|
|
12
|
+
throw new Error('Skill packages cannot contain symbolic links');
|
|
13
|
+
if (entry.isDirectory())
|
|
14
|
+
packageFiles(rootDir, path, files);
|
|
15
|
+
else if (entry.isFile()) {
|
|
16
|
+
files.push(path);
|
|
17
|
+
if (files.length > MAX_SKILL_PACKAGE_FILES)
|
|
18
|
+
throw new Error(`Skill packages cannot contain more than ${MAX_SKILL_PACKAGE_FILES} files`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function computeSkillIntegrity(rootDir) {
|
|
23
|
+
const files = [];
|
|
24
|
+
packageFiles(rootDir, rootDir, files);
|
|
25
|
+
files.sort((a, b) => relative(rootDir, a).localeCompare(relative(rootDir, b)));
|
|
26
|
+
const totalBytes = files.reduce((sum, path) => sum + statSync(path).size, 0);
|
|
27
|
+
if (totalBytes > MAX_SKILL_PACKAGE_BYTES)
|
|
28
|
+
throw new Error('Skill packages cannot exceed 10 MiB');
|
|
29
|
+
const hash = createHash('sha256');
|
|
30
|
+
for (const path of files) {
|
|
31
|
+
hash.update(relative(rootDir, path).split(sep).join('/')).update('\0');
|
|
32
|
+
hash.update(readFileSync(path)).update('\0');
|
|
33
|
+
}
|
|
34
|
+
return `sha256:${hash.digest('hex')}`;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../../src/skills/integrity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;AACnE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,MAAM,CAAA;AAE1C,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,CAAA;AAC5C,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAA;AAEvD,SAAS,YAAY,CAAC,OAAe,EAAE,UAAkB,EAAE,KAAe;IACxE,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QACrE,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,wBAAwB;YAAE,SAAQ;QAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;QACzC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;QACrG,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;aACtD,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAChB,IAAI,KAAK,CAAC,MAAM,GAAG,uBAAuB;gBAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,uBAAuB,QAAQ,CAAC,CAAA;QACzI,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;IACrC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;IAE9E,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAC5E,IAAI,UAAU,GAAG,uBAAuB;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAA;IAEhG,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACtE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,UAAU,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAA;AACvC,CAAC"}
|
package/get-started.md
CHANGED
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
- [Multi-PR syntax](#multi-pr-syntax)
|
|
23
23
|
- [watch](#crosscheck-watch)
|
|
24
24
|
- [status](#crosscheck-status)
|
|
25
|
+
- [skill install](#crosscheck-skill-install-source)
|
|
25
26
|
- [diagnose](#crosscheck-diagnose)
|
|
26
27
|
- [optimize](#crosscheck-optimize)
|
|
27
28
|
- [impact](#crosscheck-impact)
|
|
@@ -391,6 +392,8 @@ crosscheck onboard --reconfigure # re-run setup even if config already exists
|
|
|
391
392
|
|
|
392
393
|
**Step 6 — Review quality.** Choose the speed/thoroughness tier for review prompts and reviewer timeouts.
|
|
393
394
|
|
|
395
|
+
**Step 6.5 — Agent skills.** Choose which preloaded or custom-installed skills are enabled for coding agents. New setups preselect `code-review-skill (by @awesome-skills, MIT)` and `diagnosing-bugs (by @mattpocock, MIT)`. Matt Pocock's `code-review` and `codebase-design` are available but off by default. Re-running onboard preserves your selection. Skills are made available across workflow operations, and each skill's description plus the coding agent decides when it applies.
|
|
396
|
+
|
|
394
397
|
**Step 7 — Workflow pipeline.** Choose what happens after a review:
|
|
395
398
|
|
|
396
399
|
```
|
|
@@ -444,6 +447,9 @@ crosscheck onboard
|
|
|
444
447
|
[1] fast [2] balanced [3] thorough
|
|
445
448
|
Choice [2]: 2
|
|
446
449
|
|
|
450
|
+
Step 6.5 — agent skills
|
|
451
|
+
[x] code-review-skill (by @awesome-skills, MIT)
|
|
452
|
+
|
|
447
453
|
Step 7 — workflow pipeline
|
|
448
454
|
[1] review only [2] review → fix [3] review → fix → re-check
|
|
449
455
|
Choice [2]: 3
|
|
@@ -767,6 +773,8 @@ crosscheck status
|
|
|
767
773
|
Config
|
|
768
774
|
mode cross-vendor
|
|
769
775
|
quality tier balanced
|
|
776
|
+
installed skills code-review (by @mattpocock, MIT), code-review-skill (by @awesome-skills, MIT), codebase-design (by @mattpocock, MIT), diagnosing-bugs (by @mattpocock, MIT)
|
|
777
|
+
enabled skills code-review-skill (by @awesome-skills, MIT), diagnosing-bugs (by @mattpocock, MIT)
|
|
770
778
|
codex auth subscription
|
|
771
779
|
claude model sonnet
|
|
772
780
|
per-review budget $2.00/review
|
|
@@ -790,6 +798,39 @@ crosscheck status
|
|
|
790
798
|
|
|
791
799
|
---
|
|
792
800
|
|
|
801
|
+
### `crosscheck skill install <source>`
|
|
802
|
+
|
|
803
|
+
Installs an Agent Skill from a Git URL or local directory into `~/.crosscheck/skills`. Crosscheck validates `SKILL.md`, rejects unsafe names and symbolic links, and records source, revision, author, license, and package integrity. Installation does not enable a skill automatically.
|
|
804
|
+
|
|
805
|
+
Crosscheck itself ships with this preloaded catalog:
|
|
806
|
+
|
|
807
|
+
| Skill | Onboarding default | Best fit |
|
|
808
|
+
|---|---:|---|
|
|
809
|
+
| [`code-review-skill`](https://github.com/awesome-skills/code-review-skill) (by `@awesome-skills`, MIT) | On | Broad code review |
|
|
810
|
+
| [`diagnosing-bugs`](https://github.com/mattpocock/skills/tree/main/skills/engineering/diagnosing-bugs) (by `@mattpocock`, MIT) | On | Bug diagnosis and repair |
|
|
811
|
+
| [`code-review`](https://github.com/mattpocock/skills/tree/main/skills/engineering/code-review) (by `@mattpocock`, MIT) | Off | Standards-versus-spec review |
|
|
812
|
+
| [`codebase-design`](https://github.com/mattpocock/skills/tree/main/skills/engineering/codebase-design) (by `@mattpocock`, MIT) | Off | Architectural review and substantial fixes |
|
|
813
|
+
|
|
814
|
+
The two Matt Pocock opt-ins are deliberately available without being imposed on every repository. Choose them during onboarding when their practice matches your workflow.
|
|
815
|
+
|
|
816
|
+
```bash
|
|
817
|
+
crosscheck skill install https://github.com/owner/my-skill.git
|
|
818
|
+
crosscheck skill install /path/to/my-skill
|
|
819
|
+
crosscheck onboard # enable installed skills
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
The Git repository or local directory must have `SKILL.md` at its root. For a skill nested in a monorepo, clone it and pass the nested local directory.
|
|
823
|
+
|
|
824
|
+
`crosscheck status` distinguishes the full installed catalog from the enabled selection and renders attributed identities as `skill-name (by @author, license)`.
|
|
825
|
+
|
|
826
|
+
At runtime, Crosscheck distinguishes three states: **installed** skills are in the catalog, **enabled** skills are available to agents, and **activated** skills were actually loaded for one workflow step. The terminal and each PR comment attribute only that step's activated skills, for example: `code-review-skill (by @awesome-skills, MIT)`.
|
|
827
|
+
|
|
828
|
+
Upgrading from an earlier Crosscheck release is opt-in: existing configs default to `skills.enabled: []`. Re-run `crosscheck onboard` to choose the recommended bundle or any additional installed skills.
|
|
829
|
+
|
|
830
|
+
Review and recheck also honor repository practices in `AGENTS.md` and `CLAUDE.md`. Crosscheck reads the root files plus any nested files whose directory contains a changed path, orders them from broadest to most specific, and lets nested guidance override root guidance. It reads these files from the PR's base branch and disables vendor-native discovery for the run, so guidance added or modified by the PR cannot influence its own review.
|
|
831
|
+
|
|
832
|
+
---
|
|
833
|
+
|
|
793
834
|
### `crosscheck diagnose`
|
|
794
835
|
|
|
795
836
|
Reads `~/.crosscheck/logs/` and surfaces failure patterns, reviewer performance, and improvement suggestions.
|
|
@@ -1011,7 +1052,7 @@ If no errors are found in recent logs, crosscheck prints `No errors found in rec
|
|
|
1011
1052
|
|
|
1012
1053
|
On re-runs, `onboard` updates only the fields it collected answers for. Everything else survives unchanged.
|
|
1013
1054
|
|
|
1014
|
-
**Updated on every run:** `deployment`, `orgs`, `repos`, `mode`, `clone_protocol`, `vendors.*.enabled`, `vendors.*.effort`, `quality.tier`, `tunnel.*`, `post_review.auto_fix.*`
|
|
1055
|
+
**Updated on every run:** `deployment`, `orgs`, `repos`, `mode`, `clone_protocol`, `vendors.*.enabled`, `vendors.*.effort`, `quality.tier`, `skills.enabled`, `tunnel.*`, `post_review.auto_fix.*`
|
|
1015
1056
|
|
|
1016
1057
|
**Never touched by onboard:** per-repo overrides in `~/.crosscheck/workflows/` (owned by `crosscheck alter`), and `~/.crosscheck/workflow.yml` after its first write
|
|
1017
1058
|
|
|
@@ -1081,6 +1122,16 @@ quality:
|
|
|
1081
1122
|
custom_prompt: | # appended to every review prompt
|
|
1082
1123
|
Be concise. Flag only issues that would block a merge.
|
|
1083
1124
|
|
|
1125
|
+
# ── Agent skills ──────────────────────────────────────────────────────────────
|
|
1126
|
+
# Enabled means available to every coding-agent operation. The skill description
|
|
1127
|
+
# and agent decide whether to activate it for a particular step.
|
|
1128
|
+
skills:
|
|
1129
|
+
enabled:
|
|
1130
|
+
- code-review-skill # recommended · @awesome-skills, MIT
|
|
1131
|
+
- diagnosing-bugs # recommended · @mattpocock, MIT
|
|
1132
|
+
# - code-review # preloaded, opt-in · @mattpocock, MIT
|
|
1133
|
+
# - codebase-design # preloaded, opt-in · @mattpocock, MIT
|
|
1134
|
+
|
|
1084
1135
|
# ── Budget ────────────────────────────────────────────────────────────────────
|
|
1085
1136
|
budget:
|
|
1086
1137
|
codex_monthly_usd: 20 # null = unlimited; only applies when auth: api-key
|
|
@@ -1376,6 +1427,9 @@ The fix (file lock for same-machine + GitHub commit status for cross-machine) is
|
|
|
1376
1427
|
- **Temp isolation** — each PR cloned into a fresh temp dir, deleted after review
|
|
1377
1428
|
- **Read-only tools** — Claude restricted to `git diff` and `git log` only
|
|
1378
1429
|
- **Temp credential isolation** — with `clone_protocol: ssh` (default) no tokens touch disk; with `clone_protocol: https` a short-lived token is embedded in the temp clone's remote URL and removed when the temp dir is deleted after review
|
|
1430
|
+
- **Skill package validation** — installs reject unsafe names, attribution injection, symbolic links, packages over 1,000 files or 10 MiB, and collisions; Git sources record their checked-out commit
|
|
1431
|
+
- **Skill integrity** — Crosscheck verifies every installed package against its SHA-256 receipt before exposing it to agents; modified or malformed packages fail closed and appear as unavailable in `crosscheck status`
|
|
1432
|
+
- **Skill execution boundary** — the activation broker exposes instructions and referenced files but never executes bundled scripts itself. Skills are third-party instructions: inspect their source and license before enabling them; the selected coding agent still operates under its normal sandbox and permissions
|
|
1379
1433
|
|
|
1380
1434
|
---
|
|
1381
1435
|
|