@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.
Files changed (159) hide show
  1. package/README.md +26 -0
  2. package/assets/skills/code-review/.crosscheck-skill.json +9 -0
  3. package/assets/skills/code-review/LICENSE +21 -0
  4. package/assets/skills/code-review/SKILL.md +89 -0
  5. package/assets/skills/code-review/agents/openai.yaml +3 -0
  6. package/assets/skills/code-review-skill/.crosscheck-skill.json +9 -0
  7. package/assets/skills/code-review-skill/LICENSE +21 -0
  8. package/assets/skills/code-review-skill/SKILL.md +231 -0
  9. package/assets/skills/code-review-skill/assets/pr-review-template.md +137 -0
  10. package/assets/skills/code-review-skill/assets/review-checklist.md +123 -0
  11. package/assets/skills/code-review-skill/reference/angular.md +768 -0
  12. package/assets/skills/code-review-skill/reference/architecture-review-guide.md +472 -0
  13. package/assets/skills/code-review-skill/reference/c.md +890 -0
  14. package/assets/skills/code-review-skill/reference/code-quality-universal.md +488 -0
  15. package/assets/skills/code-review-skill/reference/code-review-best-practices.md +136 -0
  16. package/assets/skills/code-review-skill/reference/common-bugs-checklist.md +286 -0
  17. package/assets/skills/code-review-skill/reference/cpp.md +893 -0
  18. package/assets/skills/code-review-skill/reference/cross-cutting/async-concurrency-patterns.md +515 -0
  19. package/assets/skills/code-review-skill/reference/cross-cutting/error-handling-principles.md +492 -0
  20. package/assets/skills/code-review-skill/reference/cross-cutting/n-plus-one-queries.md +309 -0
  21. package/assets/skills/code-review-skill/reference/cross-cutting/sql-injection-prevention.md +308 -0
  22. package/assets/skills/code-review-skill/reference/cross-cutting/xss-prevention.md +264 -0
  23. package/assets/skills/code-review-skill/reference/csharp.md +525 -0
  24. package/assets/skills/code-review-skill/reference/css-less-sass.md +661 -0
  25. package/assets/skills/code-review-skill/reference/django.md +985 -0
  26. package/assets/skills/code-review-skill/reference/fastapi.md +580 -0
  27. package/assets/skills/code-review-skill/reference/go.md +993 -0
  28. package/assets/skills/code-review-skill/reference/java.md +409 -0
  29. package/assets/skills/code-review-skill/reference/java8.md +586 -0
  30. package/assets/skills/code-review-skill/reference/kotlin.md +1018 -0
  31. package/assets/skills/code-review-skill/reference/nestjs.md +593 -0
  32. package/assets/skills/code-review-skill/reference/performance-review-guide.md +816 -0
  33. package/assets/skills/code-review-skill/reference/php.md +684 -0
  34. package/assets/skills/code-review-skill/reference/python.md +1073 -0
  35. package/assets/skills/code-review-skill/reference/qt.md +757 -0
  36. package/assets/skills/code-review-skill/reference/react.md +871 -0
  37. package/assets/skills/code-review-skill/reference/ruby.md +964 -0
  38. package/assets/skills/code-review-skill/reference/rust.md +846 -0
  39. package/assets/skills/code-review-skill/reference/security-review-guide.md +494 -0
  40. package/assets/skills/code-review-skill/reference/svelte.md +1064 -0
  41. package/assets/skills/code-review-skill/reference/swift.md +936 -0
  42. package/assets/skills/code-review-skill/reference/typescript.md +1016 -0
  43. package/assets/skills/code-review-skill/reference/vue.md +924 -0
  44. package/assets/skills/code-review-skill/reference/zig.md +440 -0
  45. package/assets/skills/code-review-skill/scripts/pr-analyzer.py +435 -0
  46. package/assets/skills/code-review-skill/scripts/test_pr_analyzer.py +380 -0
  47. package/assets/skills/codebase-design/.crosscheck-skill.json +9 -0
  48. package/assets/skills/codebase-design/DEEPENING.md +37 -0
  49. package/assets/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
  50. package/assets/skills/codebase-design/LICENSE +21 -0
  51. package/assets/skills/codebase-design/SKILL.md +114 -0
  52. package/assets/skills/codebase-design/agents/openai.yaml +3 -0
  53. package/assets/skills/diagnosing-bugs/.crosscheck-skill.json +9 -0
  54. package/assets/skills/diagnosing-bugs/LICENSE +21 -0
  55. package/assets/skills/diagnosing-bugs/SKILL.md +134 -0
  56. package/assets/skills/diagnosing-bugs/agents/openai.yaml +3 -0
  57. package/assets/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  58. package/crosscheck.config.example.yml +10 -0
  59. package/dist/__tests__/conflict-resolve.test.js +44 -1
  60. package/dist/__tests__/conflict-resolve.test.js.map +1 -1
  61. package/dist/__tests__/fix.test.js +31 -0
  62. package/dist/__tests__/fix.test.js.map +1 -1
  63. package/dist/__tests__/onboard-preservation.test.js +5 -0
  64. package/dist/__tests__/onboard-preservation.test.js.map +1 -1
  65. package/dist/__tests__/optimize.test.js +1 -0
  66. package/dist/__tests__/optimize.test.js.map +1 -1
  67. package/dist/__tests__/repository-guidance.test.d.ts +2 -0
  68. package/dist/__tests__/repository-guidance.test.d.ts.map +1 -0
  69. package/dist/__tests__/repository-guidance.test.js +88 -0
  70. package/dist/__tests__/repository-guidance.test.js.map +1 -0
  71. package/dist/__tests__/skill-attribution.test.d.ts +2 -0
  72. package/dist/__tests__/skill-attribution.test.d.ts.map +1 -0
  73. package/dist/__tests__/skill-attribution.test.js +37 -0
  74. package/dist/__tests__/skill-attribution.test.js.map +1 -0
  75. package/dist/__tests__/skill-broker.test.d.ts +2 -0
  76. package/dist/__tests__/skill-broker.test.d.ts.map +1 -0
  77. package/dist/__tests__/skill-broker.test.js +92 -0
  78. package/dist/__tests__/skill-broker.test.js.map +1 -0
  79. package/dist/__tests__/skill-catalog.test.d.ts +2 -0
  80. package/dist/__tests__/skill-catalog.test.d.ts.map +1 -0
  81. package/dist/__tests__/skill-catalog.test.js +35 -0
  82. package/dist/__tests__/skill-catalog.test.js.map +1 -0
  83. package/dist/__tests__/skill-installer.test.d.ts +2 -0
  84. package/dist/__tests__/skill-installer.test.d.ts.map +1 -0
  85. package/dist/__tests__/skill-installer.test.js +96 -0
  86. package/dist/__tests__/skill-installer.test.js.map +1 -0
  87. package/dist/__tests__/skills-config.test.d.ts +2 -0
  88. package/dist/__tests__/skills-config.test.d.ts.map +1 -0
  89. package/dist/__tests__/skills-config.test.js +12 -0
  90. package/dist/__tests__/skills-config.test.js.map +1 -0
  91. package/dist/cli.js +7 -0
  92. package/dist/cli.js.map +1 -1
  93. package/dist/commands/onboard.d.ts +1 -0
  94. package/dist/commands/onboard.d.ts.map +1 -1
  95. package/dist/commands/onboard.js +25 -1
  96. package/dist/commands/onboard.js.map +1 -1
  97. package/dist/commands/review.d.ts.map +1 -1
  98. package/dist/commands/review.js +15 -4
  99. package/dist/commands/review.js.map +1 -1
  100. package/dist/commands/skill.d.ts +2 -0
  101. package/dist/commands/skill.d.ts.map +1 -0
  102. package/dist/commands/skill.js +16 -0
  103. package/dist/commands/skill.js.map +1 -0
  104. package/dist/commands/status.d.ts.map +1 -1
  105. package/dist/commands/status.js +10 -0
  106. package/dist/commands/status.js.map +1 -1
  107. package/dist/config/schema.d.ts +21 -0
  108. package/dist/config/schema.d.ts.map +1 -1
  109. package/dist/config/schema.js +4 -0
  110. package/dist/config/schema.js.map +1 -1
  111. package/dist/lib/repository-guidance.d.ts +2 -0
  112. package/dist/lib/repository-guidance.d.ts.map +1 -0
  113. package/dist/lib/repository-guidance.js +55 -0
  114. package/dist/lib/repository-guidance.js.map +1 -0
  115. package/dist/lib/runner.d.ts.map +1 -1
  116. package/dist/lib/runner.js +50 -19
  117. package/dist/lib/runner.js.map +1 -1
  118. package/dist/reviewers/claude.d.ts +2 -1
  119. package/dist/reviewers/claude.d.ts.map +1 -1
  120. package/dist/reviewers/claude.js +21 -3
  121. package/dist/reviewers/claude.js.map +1 -1
  122. package/dist/reviewers/codex.d.ts +2 -1
  123. package/dist/reviewers/codex.d.ts.map +1 -1
  124. package/dist/reviewers/codex.js +7 -3
  125. package/dist/reviewers/codex.js.map +1 -1
  126. package/dist/reviewers/conflict-resolve.d.ts +2 -1
  127. package/dist/reviewers/conflict-resolve.d.ts.map +1 -1
  128. package/dist/reviewers/conflict-resolve.js +12 -3
  129. package/dist/reviewers/conflict-resolve.js.map +1 -1
  130. package/dist/reviewers/fix.d.ts +3 -2
  131. package/dist/reviewers/fix.d.ts.map +1 -1
  132. package/dist/reviewers/fix.js +15 -6
  133. package/dist/reviewers/fix.js.map +1 -1
  134. package/dist/skills/attribution.d.ts +4 -0
  135. package/dist/skills/attribution.d.ts.map +1 -0
  136. package/dist/skills/attribution.js +10 -0
  137. package/dist/skills/attribution.js.map +1 -0
  138. package/dist/skills/broker-server.d.ts +2 -0
  139. package/dist/skills/broker-server.d.ts.map +1 -0
  140. package/dist/skills/broker-server.js +30 -0
  141. package/dist/skills/broker-server.js.map +1 -0
  142. package/dist/skills/broker.d.ts +42 -0
  143. package/dist/skills/broker.d.ts.map +1 -0
  144. package/dist/skills/broker.js +173 -0
  145. package/dist/skills/broker.js.map +1 -0
  146. package/dist/skills/catalog.d.ts +26 -0
  147. package/dist/skills/catalog.d.ts.map +1 -0
  148. package/dist/skills/catalog.js +91 -0
  149. package/dist/skills/catalog.js.map +1 -0
  150. package/dist/skills/installer.d.ts +10 -0
  151. package/dist/skills/installer.d.ts.map +1 -0
  152. package/dist/skills/installer.js +136 -0
  153. package/dist/skills/installer.js.map +1 -0
  154. package/dist/skills/integrity.d.ts +4 -0
  155. package/dist/skills/integrity.d.ts.map +1 -0
  156. package/dist/skills/integrity.js +36 -0
  157. package/dist/skills/integrity.js.map +1 -0
  158. package/get-started.md +55 -1
  159. 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,4 @@
1
+ export declare const MAX_SKILL_PACKAGE_FILES = 1000;
2
+ export declare const MAX_SKILL_PACKAGE_BYTES: number;
3
+ export declare function computeSkillIntegrity(rootDir: string): string;
4
+ //# sourceMappingURL=integrity.d.ts.map
@@ -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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanbased/crosscheck",
3
- "version": "1.2.0-beta.57",
3
+ "version": "1.2.0-beta.68",
4
4
  "description": "AI code review pipeline that turns agent-written PRs into merge-ready patches",
5
5
  "bin": {
6
6
  "crosscheck": "dist/cli.js",