@humanbased/crosscheck 1.2.0-beta.57 → 1.2.0-beta.71
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 +28 -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__/repo-picker.test.js +7 -1
- package/dist/__tests__/repo-picker.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 +89 -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 +100 -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 +40 -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 +36 -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/repo-picker.d.ts +3 -0
- package/dist/lib/repo-picker.d.ts.map +1 -1
- package/dist/lib/repo-picker.js +45 -9
- package/dist/lib/repo-picker.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 +177 -0
- package/dist/skills/broker.js.map +1 -0
- package/dist/skills/catalog.d.ts +28 -0
- package/dist/skills/catalog.d.ts.map +1 -0
- package/dist/skills/catalog.js +104 -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 +58 -1
- package/package.json +1 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { existsSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join, resolve, sep } from 'path';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { findCompetingSkill } from './catalog.js';
|
|
6
|
+
const BROKER_SERVER_PATH = fileURLToPath(new URL('./broker-server.js', import.meta.url));
|
|
7
|
+
const BROKER_SERVER_TS_PATH = fileURLToPath(new URL('./broker-server.ts', import.meta.url));
|
|
8
|
+
const MAX_SKILL_FILE_BYTES = 512_000;
|
|
9
|
+
function readState(sessionPath) {
|
|
10
|
+
return JSON.parse(readFileSync(sessionPath, 'utf8'));
|
|
11
|
+
}
|
|
12
|
+
function writeState(sessionPath, state) {
|
|
13
|
+
writeFileSync(sessionPath, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
|
|
14
|
+
}
|
|
15
|
+
function metadata(skill) {
|
|
16
|
+
const { path: _path, ...identity } = skill;
|
|
17
|
+
return identity;
|
|
18
|
+
}
|
|
19
|
+
function error(message) {
|
|
20
|
+
return { content: [{ type: 'text', text: message }], isError: true };
|
|
21
|
+
}
|
|
22
|
+
function stringArg(args, key) {
|
|
23
|
+
return typeof args[key] === 'string' && args[key].trim() ? args[key].trim() : null;
|
|
24
|
+
}
|
|
25
|
+
export function createSkillActivationSession(stepType, enabledNames, catalog) {
|
|
26
|
+
const enabledSet = new Set(enabledNames);
|
|
27
|
+
const enabled = catalog.filter(skill => enabledSet.has(skill.name));
|
|
28
|
+
const sessionDir = mkdtempSync(join(tmpdir(), 'crosscheck-skill-session-'));
|
|
29
|
+
const path = join(sessionDir, 'session.json');
|
|
30
|
+
writeState(path, { schemaVersion: 1, stepType, enabled, activated: [] });
|
|
31
|
+
return {
|
|
32
|
+
path,
|
|
33
|
+
stepType,
|
|
34
|
+
enabledSkills: enabled.map(metadata),
|
|
35
|
+
activations: () => {
|
|
36
|
+
const state = readState(path);
|
|
37
|
+
const activated = new Set(state.activated);
|
|
38
|
+
return state.enabled.filter(skill => activated.has(skill.name)).map(metadata);
|
|
39
|
+
},
|
|
40
|
+
close: () => rmSync(sessionDir, { recursive: true, force: true }),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function skillBrokerCommand(sessionPath) {
|
|
44
|
+
const serverArgs = existsSync(BROKER_SERVER_PATH)
|
|
45
|
+
? [BROKER_SERVER_PATH]
|
|
46
|
+
: ['--import', 'tsx', BROKER_SERVER_TS_PATH];
|
|
47
|
+
return { command: process.execPath, args: [...serverArgs, '--session', sessionPath] };
|
|
48
|
+
}
|
|
49
|
+
export function renderSkillBrokerInstructions(session) {
|
|
50
|
+
if (session.enabledSkills.length === 0)
|
|
51
|
+
return '';
|
|
52
|
+
const skills = session.enabledSkills
|
|
53
|
+
.map(skill => `- ${skill.name}: ${skill.description} (by @${skill.author}, ${skill.license})`)
|
|
54
|
+
.join('\n');
|
|
55
|
+
return [
|
|
56
|
+
'Crosscheck Agent Skills are available through the crosscheck MCP server.',
|
|
57
|
+
'Decide from each description whether a skill applies to this operation. Activate only applicable skills before following their instructions.',
|
|
58
|
+
skills,
|
|
59
|
+
].join('\n');
|
|
60
|
+
}
|
|
61
|
+
export function claudeSkillBrokerArgs(session) {
|
|
62
|
+
if (!session)
|
|
63
|
+
return [];
|
|
64
|
+
const broker = skillBrokerCommand(session.path);
|
|
65
|
+
return ['--mcp-config', JSON.stringify({
|
|
66
|
+
mcpServers: { crosscheck: { command: broker.command, args: broker.args } },
|
|
67
|
+
})];
|
|
68
|
+
}
|
|
69
|
+
export function codexSkillBrokerArgs(session) {
|
|
70
|
+
if (!session)
|
|
71
|
+
return [];
|
|
72
|
+
const broker = skillBrokerCommand(session.path);
|
|
73
|
+
return [
|
|
74
|
+
'-c', `mcp_servers.crosscheck.command=${JSON.stringify(broker.command)}`,
|
|
75
|
+
'-c', `mcp_servers.crosscheck.args=${JSON.stringify(broker.args)}`,
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
export function callSkillBrokerTool(sessionPath, toolName, rawArgs) {
|
|
79
|
+
const state = readState(sessionPath);
|
|
80
|
+
const args = rawArgs && typeof rawArgs === 'object' ? rawArgs : {};
|
|
81
|
+
if (toolName === 'list_enabled_skills') {
|
|
82
|
+
return { content: [{ type: 'text', text: JSON.stringify(state.enabled.map(metadata), null, 2) }] };
|
|
83
|
+
}
|
|
84
|
+
const name = stringArg(args, 'name');
|
|
85
|
+
if (!name)
|
|
86
|
+
return error('name is required');
|
|
87
|
+
const skill = state.enabled.find(candidate => candidate.name === name);
|
|
88
|
+
if (!skill)
|
|
89
|
+
return error(`Skill ${name} is not enabled for this operation`);
|
|
90
|
+
if (toolName === 'activate_skill') {
|
|
91
|
+
const competitor = findCompetingSkill(name, state.activated);
|
|
92
|
+
if (competitor)
|
|
93
|
+
return error(`Skill ${name} competes with activated ${competitor}; activate only one review baseline`);
|
|
94
|
+
const instructions = readFileSync(join(skill.path, 'SKILL.md'), 'utf8');
|
|
95
|
+
if (!state.activated.includes(name)) {
|
|
96
|
+
state.activated.push(name);
|
|
97
|
+
writeState(sessionPath, state);
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
content: [{
|
|
101
|
+
type: 'text',
|
|
102
|
+
text: `Activated ${name} (by @${skill.author}, ${skill.license}).\nSkill root: ${skill.path}\n\n${instructions}`,
|
|
103
|
+
}],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
if (toolName === 'read_skill_file') {
|
|
107
|
+
if (!state.activated.includes(name))
|
|
108
|
+
return error(`Activate ${name} before reading its files`);
|
|
109
|
+
const requestedPath = stringArg(args, 'path');
|
|
110
|
+
if (!requestedPath)
|
|
111
|
+
return error('path is required');
|
|
112
|
+
const root = resolve(skill.path);
|
|
113
|
+
const path = resolve(root, requestedPath);
|
|
114
|
+
if (path !== root && !path.startsWith(`${root}${sep}`))
|
|
115
|
+
return error('Skill file path must stay inside the skill package');
|
|
116
|
+
if (!existsSync(path) || !statSync(path).isFile())
|
|
117
|
+
return error(`Skill file not found: ${requestedPath}`);
|
|
118
|
+
if (statSync(path).size > MAX_SKILL_FILE_BYTES)
|
|
119
|
+
return error(`Skill file exceeds ${MAX_SKILL_FILE_BYTES} bytes`);
|
|
120
|
+
return { content: [{ type: 'text', text: readFileSync(path, 'utf8') }] };
|
|
121
|
+
}
|
|
122
|
+
return error(`Unknown skill broker tool: ${toolName}`);
|
|
123
|
+
}
|
|
124
|
+
const TOOLS = [
|
|
125
|
+
{
|
|
126
|
+
name: 'list_enabled_skills',
|
|
127
|
+
description: 'List Agent Skills enabled for the current Crosscheck operation. Metadata only; this does not activate a skill.',
|
|
128
|
+
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: 'activate_skill',
|
|
132
|
+
description: 'Activate an enabled skill when its description applies, record attribution, and load its SKILL.md instructions.',
|
|
133
|
+
inputSchema: {
|
|
134
|
+
type: 'object',
|
|
135
|
+
properties: { name: { type: 'string' } },
|
|
136
|
+
required: ['name'],
|
|
137
|
+
additionalProperties: false,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: 'read_skill_file',
|
|
142
|
+
description: 'Read a referenced file from a skill after activating it.',
|
|
143
|
+
inputSchema: {
|
|
144
|
+
type: 'object',
|
|
145
|
+
properties: { name: { type: 'string' }, path: { type: 'string' } },
|
|
146
|
+
required: ['name', 'path'],
|
|
147
|
+
additionalProperties: false,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
];
|
|
151
|
+
export function handleSkillBrokerRequest(sessionPath, request) {
|
|
152
|
+
if (request.method.startsWith('notifications/'))
|
|
153
|
+
return null;
|
|
154
|
+
const id = request.id ?? null;
|
|
155
|
+
if (request.method === 'initialize') {
|
|
156
|
+
const params = request.params && typeof request.params === 'object' ? request.params : {};
|
|
157
|
+
return {
|
|
158
|
+
jsonrpc: '2.0', id,
|
|
159
|
+
result: {
|
|
160
|
+
protocolVersion: typeof params.protocolVersion === 'string' ? params.protocolVersion : '2024-11-05',
|
|
161
|
+
capabilities: { tools: {} },
|
|
162
|
+
serverInfo: { name: 'crosscheck-skill-broker', version: '1.0.0' },
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
if (request.method === 'ping')
|
|
167
|
+
return { jsonrpc: '2.0', id, result: {} };
|
|
168
|
+
if (request.method === 'tools/list')
|
|
169
|
+
return { jsonrpc: '2.0', id, result: { tools: TOOLS } };
|
|
170
|
+
if (request.method === 'tools/call') {
|
|
171
|
+
const params = request.params && typeof request.params === 'object' ? request.params : {};
|
|
172
|
+
const name = typeof params.name === 'string' ? params.name : '';
|
|
173
|
+
return { jsonrpc: '2.0', id, result: callSkillBrokerTool(sessionPath, name, params.arguments) };
|
|
174
|
+
}
|
|
175
|
+
return { jsonrpc: '2.0', id, error: { code: -32601, message: `Method not found: ${request.method}` } };
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=broker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../../src/skills/broker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface SkillIdentity {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
author: string;
|
|
5
|
+
license: string;
|
|
6
|
+
source: string;
|
|
7
|
+
revision: string;
|
|
8
|
+
integrity: string;
|
|
9
|
+
path: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SkillFrontmatter {
|
|
12
|
+
name?: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
author?: string;
|
|
15
|
+
license?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const RECOMMENDED_SKILL_NAMES: readonly ["code-review-skill", "codebase-design", "diagnosing-bugs"];
|
|
18
|
+
export declare const BUNDLED_SKILL_RECOMMENDATIONS: Readonly<Record<string, string>>;
|
|
19
|
+
export declare function findCompetingSkill(skillName: string, selectedNames: readonly string[]): string | undefined;
|
|
20
|
+
export declare const INSTALLED_SKILLS_DIR: string;
|
|
21
|
+
export declare function readSkillFrontmatter(skillPath: string): SkillFrontmatter;
|
|
22
|
+
export declare function isValidSkillAuthor(value: unknown): value is string;
|
|
23
|
+
export declare function isValidSkillLicense(value: unknown): value is string;
|
|
24
|
+
export declare function loadBundledSkills(rootDir?: string): SkillIdentity[];
|
|
25
|
+
export declare function loadInstalledSkills(rootDir?: string): SkillIdentity[];
|
|
26
|
+
export declare function loadSkillCatalog(installedRoot?: string): SkillIdentity[];
|
|
27
|
+
export declare function formatSkillIdentity(skill: Pick<SkillIdentity, 'name' | 'author' | 'license'>): string;
|
|
28
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/skills/catalog.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,uBAAuB,sEAAuE,CAAA;AAE3G,eAAO,MAAM,6BAA6B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK1E,CAAA;AAOD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAE1G;AAGD,eAAO,MAAM,oBAAoB,QAA2C,CAAA;AAE5E,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAMxE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAElE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEnE;AAiDD,wBAAgB,iBAAiB,CAAC,OAAO,SAAqB,GAAG,aAAa,EAAE,CAE/E;AAED,wBAAgB,mBAAmB,CAAC,OAAO,SAAuB,GAAG,aAAa,EAAE,CAEnF;AAED,wBAAgB,gBAAgB,CAAC,aAAa,SAAuB,GAAG,aAAa,EAAE,CAMtF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,GAAG,MAAM,CAErG"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import yaml from 'js-yaml';
|
|
6
|
+
import { computeSkillIntegrity } from './integrity.js';
|
|
7
|
+
export const RECOMMENDED_SKILL_NAMES = ['code-review-skill', 'codebase-design', 'diagnosing-bugs'];
|
|
8
|
+
export const BUNDLED_SKILL_RECOMMENDATIONS = {
|
|
9
|
+
'code-review': 'Best for evidence-rich repositories with documented standards and a clear issue or PRD; checks Standards and Spec separately.',
|
|
10
|
+
'code-review-skill': 'Best general default for broad language, correctness, security, performance, and architecture coverage.',
|
|
11
|
+
'codebase-design': 'Best for architecture-heavy changes: deep modules, small interfaces, clean seams, and testability.',
|
|
12
|
+
'diagnosing-bugs': 'Best for hard bugs and regressions: requires a reproducible signal, ranked hypotheses, and regression evidence.',
|
|
13
|
+
};
|
|
14
|
+
const COMPETING_SKILLS = {
|
|
15
|
+
'code-review': ['code-review-skill'],
|
|
16
|
+
'code-review-skill': ['code-review'],
|
|
17
|
+
};
|
|
18
|
+
export function findCompetingSkill(skillName, selectedNames) {
|
|
19
|
+
return COMPETING_SKILLS[skillName]?.find(name => selectedNames.includes(name));
|
|
20
|
+
}
|
|
21
|
+
const BUNDLED_SKILLS_DIR = fileURLToPath(new URL('../../assets/skills/', import.meta.url));
|
|
22
|
+
export const INSTALLED_SKILLS_DIR = join(homedir(), '.crosscheck', 'skills');
|
|
23
|
+
export function readSkillFrontmatter(skillPath) {
|
|
24
|
+
const content = readFileSync(join(skillPath, 'SKILL.md'), 'utf8');
|
|
25
|
+
const match = /^---\r?\n([\s\S]*?)\r?\n---/.exec(content);
|
|
26
|
+
if (!match)
|
|
27
|
+
return {};
|
|
28
|
+
const parsed = yaml.load(match[1]);
|
|
29
|
+
return typeof parsed === 'object' && parsed !== null ? parsed : {};
|
|
30
|
+
}
|
|
31
|
+
export function isValidSkillAuthor(value) {
|
|
32
|
+
return typeof value === 'string' && /^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,37}[a-zA-Z0-9])?$/.test(value);
|
|
33
|
+
}
|
|
34
|
+
export function isValidSkillLicense(value) {
|
|
35
|
+
return typeof value === 'string' && /^[a-zA-Z0-9][a-zA-Z0-9.+() -]{0,99}$/.test(value);
|
|
36
|
+
}
|
|
37
|
+
function isSkillReceipt(value) {
|
|
38
|
+
if (typeof value !== 'object' || value === null)
|
|
39
|
+
return false;
|
|
40
|
+
const receipt = value;
|
|
41
|
+
return receipt.schemaVersion === 1
|
|
42
|
+
&& typeof receipt.name === 'string' && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(receipt.name)
|
|
43
|
+
&& isValidSkillAuthor(receipt.author)
|
|
44
|
+
&& isValidSkillLicense(receipt.license)
|
|
45
|
+
&& typeof receipt.source === 'string' && receipt.source.length > 0
|
|
46
|
+
&& typeof receipt.revision === 'string' && receipt.revision.length > 0
|
|
47
|
+
&& typeof receipt.integrity === 'string' && /^sha256:[0-9a-f]{64}$/.test(receipt.integrity);
|
|
48
|
+
}
|
|
49
|
+
function loadSkills(rootDir, skipInvalid) {
|
|
50
|
+
if (!existsSync(rootDir))
|
|
51
|
+
return [];
|
|
52
|
+
return readdirSync(rootDir, { withFileTypes: true })
|
|
53
|
+
.filter(entry => entry.isDirectory() && !entry.name.startsWith('.'))
|
|
54
|
+
.flatMap(entry => {
|
|
55
|
+
const path = join(rootDir, entry.name);
|
|
56
|
+
try {
|
|
57
|
+
const receiptPath = join(path, '.crosscheck-skill.json');
|
|
58
|
+
if (statSync(receiptPath).size > 64 * 1024)
|
|
59
|
+
throw new Error(`Invalid skill receipt: ${entry.name}`);
|
|
60
|
+
const integrity = computeSkillIntegrity(path);
|
|
61
|
+
const receipt = JSON.parse(readFileSync(receiptPath, 'utf8'));
|
|
62
|
+
const frontmatter = readSkillFrontmatter(path);
|
|
63
|
+
if (!isSkillReceipt(receipt) || receipt.name !== entry.name || frontmatter.name !== receipt.name
|
|
64
|
+
|| typeof frontmatter.description !== 'string' || !frontmatter.description.trim()
|
|
65
|
+
|| integrity !== receipt.integrity) {
|
|
66
|
+
throw new Error(`Invalid skill package: ${entry.name}`);
|
|
67
|
+
}
|
|
68
|
+
return [{
|
|
69
|
+
name: receipt.name,
|
|
70
|
+
description: frontmatter.description.trim(),
|
|
71
|
+
author: receipt.author,
|
|
72
|
+
license: receipt.license,
|
|
73
|
+
source: receipt.source,
|
|
74
|
+
revision: receipt.revision,
|
|
75
|
+
integrity: receipt.integrity,
|
|
76
|
+
path,
|
|
77
|
+
}];
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (skipInvalid)
|
|
81
|
+
return [];
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
86
|
+
}
|
|
87
|
+
export function loadBundledSkills(rootDir = BUNDLED_SKILLS_DIR) {
|
|
88
|
+
return loadSkills(rootDir, false);
|
|
89
|
+
}
|
|
90
|
+
export function loadInstalledSkills(rootDir = INSTALLED_SKILLS_DIR) {
|
|
91
|
+
return loadSkills(rootDir, true);
|
|
92
|
+
}
|
|
93
|
+
export function loadSkillCatalog(installedRoot = INSTALLED_SKILLS_DIR) {
|
|
94
|
+
const skills = new Map(loadBundledSkills().map(skill => [skill.name, skill]));
|
|
95
|
+
for (const skill of loadInstalledSkills(installedRoot)) {
|
|
96
|
+
if (!skills.has(skill.name))
|
|
97
|
+
skills.set(skill.name, skill);
|
|
98
|
+
}
|
|
99
|
+
return [...skills.values()].sort((a, b) => a.name.localeCompare(b.name));
|
|
100
|
+
}
|
|
101
|
+
export function formatSkillIdentity(skill) {
|
|
102
|
+
return `${skill.name} (by @${skill.author}, ${skill.license})`;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/skills/catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type SkillIdentity } from './catalog.js';
|
|
2
|
+
export { computeSkillIntegrity } from './integrity.js';
|
|
3
|
+
export interface InstallSkillOptions {
|
|
4
|
+
installDir?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class SkillInstallError extends Error {
|
|
7
|
+
}
|
|
8
|
+
export declare function redactSkillSource(source: string): string;
|
|
9
|
+
export declare function installSkill(source: string, opts?: InstallSkillOptions): Promise<SkillIdentity>;
|
|
10
|
+
//# sourceMappingURL=installer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installer.d.ts","sourceRoot":"","sources":["../../src/skills/installer.ts"],"names":[],"mappings":"AAIA,OAAO,EAA+H,KAAK,aAAa,EAAE,MAAM,cAAc,CAAA;AAG9K,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,iBAAkB,SAAQ,KAAK;CAAG;AAE/C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUxD;AAuCD,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,aAAa,CAAC,CAgEzG"}
|
|
@@ -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"}
|