ai-developer-skill-os 7.5.1 → 8.1.4
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/.agents/docs/ARCHITECTURE.md +156 -0
- package/.agents/docs/MIGRATION-CLEANUP-V8.1.3.md +36 -0
- package/.agents/docs/MIGRATION-STATUS.md +35 -0
- package/.agents/docs/MIGRATION-V8.md +10 -0
- package/.agents/docs/ROADMAP-V8.2.md +78 -0
- package/.agents/docs/V8-CERTIFICATION.md +27 -0
- package/.agents/docs/VERSIONING.md +95 -0
- package/.agents/docs/decisions/ADR-001-v8-migration.md +58 -0
- package/.agents/docs/decisions/ADR-002-workflow-separation.md +50 -0
- package/.agents/docs/decisions/ADR-003-registry-generated.md +54 -0
- package/.agents/docs/decisions/ADR-008-skill-boundary-review.md +27 -0
- package/.agents/docs/schemas/learning.schema.yml +69 -0
- package/.agents/docs/schemas/skill.schema.yml +188 -0
- package/.agents/docs/schemas/workflow.schema.yml +33 -0
- package/.agents/knowledge/design-intelligence/industries/ecommerce.md +3 -0
- package/.agents/knowledge/design-intelligence/industries/fintech.md +3 -0
- package/.agents/knowledge/design-intelligence/industries/healthcare.md +3 -0
- package/.agents/learnings/draft/README.md +37 -0
- package/.agents/registry/capability-graph.yml +500 -0
- package/.agents/registry/skills-index.yml +525 -0
- package/.agents/reports/RELEASE-CHECKLIST.md +29 -0
- package/.agents/reports/architecture-audit.md +13 -0
- package/.agents/reports/graph-health.md +20 -0
- package/.agents/reports/skill-audit.md +215 -0
- package/.agents/rules/coding.md +102 -0
- package/.agents/rules/command-safety.md +21 -0
- package/.agents/rules/global.md +135 -0
- package/.agents/rules/priorities.yml +24 -0
- package/.agents/rules/safety.md +84 -0
- package/.agents/rules/security.md +13 -0
- package/.agents/rules/skill-quality.md +14 -0
- package/.agents/skills/_template/SKILL.md +132 -0
- package/.agents/skills/qk-access-policy/SKILL.md +61 -5
- package/.agents/skills/qk-agent-observability/SKILL.md +73 -0
- package/.agents/skills/qk-ai-builder/SKILL.md +62 -5
- package/.agents/skills/qk-api-lifecycle/SKILL.md +59 -6
- package/.agents/skills/qk-bug-resolution/SKILL.md +64 -6
- package/.agents/skills/qk-context-loader/SKILL.md +63 -11
- package/.agents/skills/qk-data-lifecycle/SKILL.md +61 -5
- package/.agents/skills/qk-db-optimizer/SKILL.md +61 -5
- package/.agents/skills/qk-design-system-engineering/SKILL.md +112 -0
- package/.agents/skills/qk-devops-platform/SKILL.md +117 -0
- package/.agents/skills/qk-docs/SKILL.md +62 -6
- package/.agents/skills/qk-engineering-standard/SKILL.md +62 -12
- package/.agents/skills/qk-fe-api-integration/SKILL.md +60 -6
- package/.agents/skills/qk-feature-delivery/SKILL.md +65 -6
- package/.agents/skills/qk-frontend-architecture/SKILL.md +134 -0
- package/.agents/skills/qk-help/SKILL.md +245 -193
- package/.agents/skills/qk-orchestrator/SKILL.md +64 -11
- package/.agents/skills/qk-orchestrator/references/routing-table.md +1 -1
- package/.agents/skills/qk-product-specification/SKILL.md +130 -0
- package/.agents/skills/qk-production-release/SKILL.md +59 -6
- package/.agents/skills/qk-project-bootstrap/SKILL.md +66 -6
- package/.agents/skills/qk-project-health/SKILL.md +63 -6
- package/.agents/skills/qk-project-memory/SKILL.md +63 -6
- package/.agents/skills/qk-security-audit/SKILL.md +135 -0
- package/.agents/skills/qk-system-evolution/SKILL.md +63 -12
- package/.agents/skills/qk-test-engineering/SKILL.md +139 -0
- package/.agents/skills/qk-ui-audit/SKILL.md +60 -6
- package/.agents/skills/qk-ui-builder/SKILL.md +509 -446
- package/.agents/skills/qk-ui-system-builder/SKILL.md +61 -5
- package/.agents/skills/qk-validation-gate/SKILL.md +63 -11
- package/.agents/skills/qk-web-quality-gate/SKILL.md +114 -0
- package/.agents/workflows/_schema.yml +109 -0
- package/.agents/workflows/bug-resolution.yml +101 -0
- package/.agents/workflows/code-review.yml +77 -0
- package/.agents/workflows/documentation.yml +75 -0
- package/.agents/workflows/feature-delivery.yml +103 -0
- package/.agents/workflows/refactor.yml +81 -0
- package/.agents/workflows/research.yml +60 -0
- package/.agents/workflows/security-audit.yml +72 -0
- package/.agents/workflows/skill-evolution.yml +65 -0
- package/.agents/workflows/spec-driven-development.yml +57 -0
- package/CHANGELOG.md +91 -70
- package/README.md +44 -59
- package/bin/install.js +57 -309
- package/package.json +13 -2
- package/tooling/generate-evaluation-cases.cjs +44 -0
- package/tooling/generate-registry.js +157 -0
- package/tooling/run-aar.js +143 -0
- package/tooling/validate-graph.js +87 -0
- package/tooling/validate-skills.js +102 -0
- package/.agents/skills.json +0 -819
- package/.github/workflows/ci.yml +0 -56
- package/CLAUDE.md +0 -110
- package/_template/BEHAVIOR_SPEC.md +0 -96
- package/_template/examples/example-en.md +0 -49
- package/_template/examples/example-vi.md +0 -49
- package/add_lang.js +0 -21
- package/add_lang.py +0 -25
- package/add_sections.py +0 -53
- package/bin/lint.js +0 -123
- package/docs/CHI_TIET_SKILLS.md +0 -126
- package/docs/GOVERNANCE.md +0 -40
- package/docs/HUONG_DAN_SU_DUNG.md +0 -120
- package/docs/SPEC.md +0 -87
- package/docs/adr/0001-intent-based-architecture.md +0 -19
- package/docs/adr/0002-kernel-freeze.md +0 -21
- package/docs/adr/0003-risk-based-verification.md +0 -20
- package/docs/adr/0004-progressive-evidence.md +0 -19
- package/docs/skill-classification.md +0 -25
- package/fix_seeds.js +0 -22
- package/framework/KERNEL.md +0 -83
- package/framework/bias-library/cosmetic-refactor.md +0 -21
- package/framework/bias-library/enterprise-crud.md +0 -21
- package/framework/bias-library/fake-ui-slop.md +0 -20
- package/framework/bias-library/hallucinated-tools.md +0 -20
- package/framework/bias-library/missing-ui-states.md +0 -19
- package/framework/bias-library/over-indexing.md +0 -20
- package/framework/bias-library/swallow-errors.md +0 -19
- package/framework/bias-library/ui-only-security.md +0 -17
- package/framework/decision-primitives.md +0 -48
- package/framework/dial-library/complexity-budget.md +0 -13
- package/framework/dial-library/granularity.md +0 -13
- package/framework/dial-library/optimization-strategy.md +0 -13
- package/framework/dial-library/strictness.md +0 -13
- package/framework/rule-library/delegation-only.md +0 -9
- package/framework/rule-library/minimal-diff.md +0 -9
- package/framework/skill-schema.md +0 -310
- package/knowledge/backend/nodejs.md +0 -52
- package/knowledge/frontend/react.md +0 -81
- package/migrate-to-v6.js +0 -130
- package/migrate.js +0 -147
- package/migrate.py +0 -133
- package/migrate_all.cjs +0 -96
- package/patch.js +0 -15
- package/patch.py +0 -89
- package/patch2.py +0 -83
- package/rename.js +0 -64
- package/skills/_archive_old_skills/qk-accessibility-audit/SKILL.md +0 -121
- package/skills/_archive_old_skills/qk-agent-orchestrator/SKILL.md +0 -179
- package/skills/_archive_old_skills/qk-api-integration/SKILL.md +0 -389
- package/skills/_archive_old_skills/qk-auth-security/SKILL.md +0 -96
- package/skills/_archive_old_skills/qk-backend-architecture/SKILL.md +0 -125
- package/skills/_archive_old_skills/qk-bug-fix/SKILL.md +0 -213
- package/skills/_archive_old_skills/qk-component-generator/SKILL.md +0 -136
- package/skills/_archive_old_skills/qk-context-manager/SKILL.md +0 -175
- package/skills/_archive_old_skills/qk-database-engineer/SKILL.md +0 -104
- package/skills/_archive_old_skills/qk-deployment/SKILL.md +0 -96
- package/skills/_archive_old_skills/qk-design-system/SKILL.md +0 -137
- package/skills/_archive_old_skills/qk-form-builder/SKILL.md +0 -140
- package/skills/_archive_old_skills/qk-frontend-architecture/SKILL.md +0 -155
- package/skills/_archive_old_skills/qk-frontend-debug/SKILL.md +0 -133
- package/skills/_archive_old_skills/qk-frontend-performance/SKILL.md +0 -129
- package/skills/_archive_old_skills/qk-frontend-testing/SKILL.md +0 -146
- package/skills/_archive_old_skills/qk-git-engineer/SKILL.md +0 -304
- package/skills/_archive_old_skills/qk-help/SKILL.md +0 -68
- package/skills/_archive_old_skills/qk-migration/SKILL.md +0 -284
- package/skills/_archive_old_skills/qk-project-audit/SKILL.md +0 -280
- package/skills/_archive_old_skills/qk-refactor/SKILL.md +0 -222
- package/skills/_archive_old_skills/qk-state-management/SKILL.md +0 -140
- package/skills/_archive_old_skills/qk-table-crud-generator/SKILL.md +0 -127
- package/skills/_archive_old_skills/qk-ui-builder/SKILL.md +0 -152
- package/skills/_template/SKILL.md +0 -239
- package/skills/qk-access-policy/SKILL.md +0 -180
- package/skills/qk-ai-builder/SKILL.md +0 -216
- package/skills/qk-api-lifecycle/SKILL.md +0 -177
- package/skills/qk-bug-resolution/SKILL.md +0 -308
- package/skills/qk-context-loader/SKILL.md +0 -219
- package/skills/qk-data-lifecycle/SKILL.md +0 -193
- package/skills/qk-db-optimizer/SKILL.md +0 -197
- package/skills/qk-docs/SKILL.md +0 -199
- package/skills/qk-engineering-standard/SKILL.md +0 -352
- package/skills/qk-engineering-standard/rules/backend.md +0 -122
- package/skills/qk-engineering-standard/rules/database.md +0 -3
- package/skills/qk-engineering-standard/rules/frontend.md +0 -152
- package/skills/qk-engineering-standard/rules/security.md +0 -3
- package/skills/qk-engineering-standard/rules/testing.md +0 -3
- package/skills/qk-fe-api-integration/SKILL.md +0 -327
- package/skills/qk-feature-delivery/SKILL.md +0 -306
- package/skills/qk-help/SKILL.md +0 -194
- package/skills/qk-orchestrator/SKILL.md +0 -279
- package/skills/qk-orchestrator/references/routing-table.md +0 -78
- package/skills/qk-production-release/SKILL.md +0 -285
- package/skills/qk-project-bootstrap/SKILL.md +0 -236
- package/skills/qk-project-health/SKILL.md +0 -200
- package/skills/qk-project-memory/SKILL.md +0 -219
- package/skills/qk-system-evolution/SKILL.md +0 -282
- package/skills/qk-ui-audit/SKILL.md +0 -316
- package/skills/qk-ui-audit/references/anti-slop-checklist.md +0 -136
- package/skills/qk-ui-builder/SKILL.md +0 -447
- package/skills/qk-ui-builder/references/anti-patterns.md +0 -295
- package/skills/qk-ui-builder/references/color.md +0 -115
- package/skills/qk-ui-builder/references/component-cookbook.md +0 -1194
- package/skills/qk-ui-builder/references/copy.md +0 -250
- package/skills/qk-ui-builder/references/interaction-and-states.md +0 -115
- package/skills/qk-ui-builder/references/layout-and-space.md +0 -111
- package/skills/qk-ui-builder/references/macrostructures/01-bento-grid.md +0 -48
- package/skills/qk-ui-builder/references/macrostructures/02-long-document.md +0 -50
- package/skills/qk-ui-builder/references/macrostructures/03-marquee-hero.md +0 -51
- package/skills/qk-ui-builder/references/macrostructures/04-stat-led.md +0 -49
- package/skills/qk-ui-builder/references/macrostructures/05-workbench.md +0 -44
- package/skills/qk-ui-builder/references/macrostructures/06-conversational-faq.md +0 -50
- package/skills/qk-ui-builder/references/macrostructures/07-manifesto.md +0 -51
- package/skills/qk-ui-builder/references/macrostructures/08-photographic.md +0 -50
- package/skills/qk-ui-builder/references/macrostructures/09-quote-led.md +0 -50
- package/skills/qk-ui-builder/references/macrostructures/11-catalogue.md +0 -49
- package/skills/qk-ui-builder/references/macrostructures/12-letter.md +0 -49
- package/skills/qk-ui-builder/references/macrostructures/13-index-first.md +0 -49
- package/skills/qk-ui-builder/references/macrostructures/14-narrative-workflow.md +0 -48
- package/skills/qk-ui-builder/references/macrostructures/15-split-studio.md +0 -48
- package/skills/qk-ui-builder/references/macrostructures/16-feature-stack.md +0 -51
- package/skills/qk-ui-builder/references/macrostructures/17-type-specimen.md +0 -48
- package/skills/qk-ui-builder/references/macrostructures/18-portfolio-grid.md +0 -48
- package/skills/qk-ui-builder/references/macrostructures/19-map-diagram.md +0 -50
- package/skills/qk-ui-builder/references/macrostructures/20-ecosystem-index.md +0 -48
- package/skills/qk-ui-builder/references/macrostructures/21-component-playground.md +0 -45
- package/skills/qk-ui-builder/references/macrostructures.md +0 -38
- package/skills/qk-ui-builder/references/motion.md +0 -95
- package/skills/qk-ui-builder/references/responsive.md +0 -115
- package/skills/qk-ui-builder/references/slop-test.md +0 -135
- package/skills/qk-ui-builder/references/structure.md +0 -280
- package/skills/qk-ui-builder/references/themes/atmospheric.md +0 -53
- package/skills/qk-ui-builder/references/themes/carnival.md +0 -52
- package/skills/qk-ui-builder/references/themes/cobalt.md +0 -52
- package/skills/qk-ui-builder/references/themes/editorial.md +0 -52
- package/skills/qk-ui-builder/references/themes/garden.md +0 -52
- package/skills/qk-ui-builder/references/themes/hum.md +0 -52
- package/skills/qk-ui-builder/references/themes/lumen.md +0 -52
- package/skills/qk-ui-builder/references/themes/midnight.md +0 -52
- package/skills/qk-ui-builder/references/themes/modern-minimal.md +0 -52
- package/skills/qk-ui-builder/references/themes/playful.md +0 -52
- package/skills/qk-ui-builder/references/themes/specimen.md +0 -52
- package/skills/qk-ui-builder/references/themes/terminal.md +0 -52
- package/skills/qk-ui-builder/references/typography.md +0 -129
- package/skills/qk-ui-system-builder/SKILL.md +0 -222
- package/skills/qk-validation-gate/SKILL.md +0 -360
- package/skills.json +0 -820
- package/specs/contracts/behavior-contract.yaml +0 -40
- package/specs/expectations/qk-bug-resolution.yaml +0 -35
- package/specs/fixtures/user-payload.json +0 -12
- package/specs/regressions/api-integration-null-fields.yaml +0 -19
- package/specs/scenarios/fix-login-nullref.yaml +0 -3
- package/taste-skill/.claude-plugin/marketplace.json +0 -20
- package/taste-skill/.claude-plugin/plugin.json +0 -19
- package/taste-skill/.github/FUNDING.yml +0 -1
- package/taste-skill/.github/copilot-instructions.md +0 -11
- package/taste-skill/CHANGELOG.md +0 -111
- package/taste-skill/LICENSE +0 -21
- package/taste-skill/README.md +0 -212
- package/taste-skill/assets/.gitkeep +0 -0
- package/taste-skill/assets/readme-banner.webp +0 -0
- package/taste-skill/assets/readme-buttons/btn-agent-skills.webp +0 -0
- package/taste-skill/assets/readme-buttons/btn-changelog.webp +0 -0
- package/taste-skill/assets/readme-buttons/btn-mit.webp +0 -0
- package/taste-skill/assets/readme-buttons/btn-site.webp +0 -0
- package/taste-skill/assets/readme-buttons/btn-tools.webp +0 -0
- package/taste-skill/assets/readme-cta-tasteskill.svg +0 -5
- package/taste-skill/assets/sponsors/animations-dev.webp +0 -0
- package/taste-skill/assets/sponsors/emil-animations-dev.webp +0 -0
- package/taste-skill/assets/taste-skill-logo.png +0 -0
- package/taste-skill/assets/taste-skill-logo.webp +0 -0
- package/taste-skill/assets/vercel-oss-program-badge.svg +0 -44
- package/taste-skill/examples/floria-bottom.webp +0 -0
- package/taste-skill/examples/floria-full.webp +0 -0
- package/taste-skill/examples/floria-top.webp +0 -0
- package/taste-skill/research/README.md +0 -8
- package/taste-skill/research/laziness/README.md +0 -25
- package/taste-skill/research/laziness/findings/empirical-results.md +0 -58
- package/taste-skill/research/laziness/findings/references.md +0 -20
- package/taste-skill/research/laziness/remediation/architectural-patterns.md +0 -55
- package/taste-skill/research/laziness/remediation/parameter-tuning.md +0 -44
- package/taste-skill/research/laziness/remediation/prompt-engineering.md +0 -52
- package/taste-skill/research/laziness/remediation/reference-prompts.md +0 -79
- package/taste-skill/research/laziness/root-causes/cognitive-shortcuts.md +0 -23
- package/taste-skill/research/laziness/root-causes/output-limits.md +0 -39
- package/taste-skill/research/laziness/root-causes/rlhf-and-compute.md +0 -27
- package/taste-skill/research/laziness/root-causes/training-data-bias.md +0 -28
- package/taste-skill/scripts/build-emil-sponsor-row.mjs +0 -41
- package/taste-skill/scripts/convert-readme-assets-webp.mjs +0 -142
- package/taste-skill/scripts/process-readme-buttons.mjs +0 -108
- package/taste-skill/scripts/process-sponsor-badge.mjs +0 -83
- package/taste-skill/skill.sh +0 -25
- package/taste-skill/skills/brandkit/SKILL.md +0 -798
- package/taste-skill/skills/brutalist-skill/SKILL.md +0 -92
- package/taste-skill/skills/gpt-tasteskill/SKILL.md +0 -74
- package/taste-skill/skills/image-to-code-skill/SKILL.md +0 -1228
- package/taste-skill/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
- package/taste-skill/skills/imagegen-frontend-web/SKILL.md +0 -987
- package/taste-skill/skills/llms.txt +0 -13
- package/taste-skill/skills/minimalist-skill/SKILL.md +0 -85
- package/taste-skill/skills/output-skill/SKILL.md +0 -49
- package/taste-skill/skills/redesign-skill/SKILL.md +0 -178
- package/taste-skill/skills/soft-skill/SKILL.md +0 -98
- package/taste-skill/skills/stitch-skill/DESIGN.md +0 -121
- package/taste-skill/skills/stitch-skill/SKILL.md +0 -184
- package/taste-skill/skills/taste-skill/SKILL.md +0 -1206
- package/taste-skill/skills/taste-skill-v1/SKILL.md +0 -226
- package/temp_fix.js +0 -61
- package/templates/DESIGN.md +0 -38
- package/templates/bug-report.md +0 -21
- package/templates/design-report.md +0 -21
- package/templates/feature-report.md +0 -20
- package/templates/review-report.md +0 -21
- package/templates/skill-template.md +0 -38
- package/tests/behavior-conformance.test.js +0 -154
- package/tests/install-script.test.js +0 -38
- package/tests/registry.test.js +0 -111
- package/update_template.js +0 -28
- package/vitest.config.js +0 -11
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generate-registry.js
|
|
3
|
+
* Generates registry/skills-index.yml and registry/capability-graph.yml
|
|
4
|
+
*
|
|
5
|
+
* Usage: node tooling/generate-registry.js
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
import yaml from 'js-yaml';
|
|
12
|
+
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
|
|
15
|
+
const SKILLS_DIR = path.join(__dirname, '../.agents/skills');
|
|
16
|
+
const INDEX_FILE = path.join(__dirname, '../.agents/registry/skills-index.yml');
|
|
17
|
+
const GRAPH_FILE = path.join(__dirname, '../.agents/registry/capability-graph.yml');
|
|
18
|
+
|
|
19
|
+
function parseFrontmatter(content) {
|
|
20
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
21
|
+
if (!match) return null;
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
return yaml.load(match[1]);
|
|
25
|
+
} catch (e) {
|
|
26
|
+
console.error('YAML parse error:', e.message);
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function generate() {
|
|
32
|
+
const skills = [];
|
|
33
|
+
|
|
34
|
+
if (!fs.existsSync(SKILLS_DIR)) {
|
|
35
|
+
console.error('Skills directory not found:', SKILLS_DIR);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const skillDirs = fs.readdirSync(SKILLS_DIR)
|
|
40
|
+
.filter(d => !d.startsWith('_') && fs.statSync(path.join(SKILLS_DIR, d)).isDirectory());
|
|
41
|
+
|
|
42
|
+
for (const dir of skillDirs) {
|
|
43
|
+
const skillFile = path.join(SKILLS_DIR, dir, 'SKILL.md');
|
|
44
|
+
if (!fs.existsSync(skillFile)) continue;
|
|
45
|
+
|
|
46
|
+
const content = fs.readFileSync(skillFile, 'utf8');
|
|
47
|
+
const meta = parseFrontmatter(content);
|
|
48
|
+
if (!meta || !meta.name) continue;
|
|
49
|
+
|
|
50
|
+
// Default legacy if not marked stable
|
|
51
|
+
if (!meta.status && meta.version && meta.version.startsWith('8.')) {
|
|
52
|
+
meta.status = 'stable';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Schema Validation Enforcement
|
|
56
|
+
if (meta.status === 'stable' && meta.version && meta.version.startsWith('8.')) {
|
|
57
|
+
if (!meta.intent || !meta.workflow || !meta.verification || !meta.selection) {
|
|
58
|
+
console.warn(`[WARN] Rejecting ${meta.name} (v8): Missing required schema fields`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
skills.push(meta);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 1. Generate skills-index.yml (Backward compatibility)
|
|
67
|
+
const indexData = {
|
|
68
|
+
version: "8.1.1",
|
|
69
|
+
generated_at: new Date().toISOString(),
|
|
70
|
+
total_skills: skills.length,
|
|
71
|
+
skills: skills.map(s => ({
|
|
72
|
+
name: s.name,
|
|
73
|
+
version: s.version || "8.0.0",
|
|
74
|
+
status: s.status || "legacy",
|
|
75
|
+
description: s.description || "",
|
|
76
|
+
complexity: s.complexity?.level || "medium",
|
|
77
|
+
workflow: s.workflow || null,
|
|
78
|
+
triggers: s.triggers || [],
|
|
79
|
+
intent: s.intent || []
|
|
80
|
+
}))
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
fs.mkdirSync(path.dirname(INDEX_FILE), { recursive: true });
|
|
84
|
+
fs.writeFileSync(INDEX_FILE, `# registry/skills-index.yml\n# GENERATED FILE — DO NOT EDIT MANUALLY\n` + yaml.dump(indexData, { indent: 2 }), 'utf8');
|
|
85
|
+
|
|
86
|
+
// 2. Generate capability-graph.yml (V8.1.1)
|
|
87
|
+
const nodes = {};
|
|
88
|
+
const edges = [];
|
|
89
|
+
|
|
90
|
+
for (const s of skills) {
|
|
91
|
+
nodes[s.name] = {
|
|
92
|
+
type: s.type || 'capability',
|
|
93
|
+
maturity: s.status || 'legacy',
|
|
94
|
+
owns: s.decision_boundary?.owns || [],
|
|
95
|
+
does_not_own: s.decision_boundary?.does_not_own || [],
|
|
96
|
+
conflicts: s.decision_boundary?.conflicts_with || [],
|
|
97
|
+
workflow: s.workflow || null
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
if (s.workflow) {
|
|
101
|
+
edges.push({
|
|
102
|
+
from: s.name,
|
|
103
|
+
to: s.workflow,
|
|
104
|
+
relation: 'depends_on'
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (s.decision_boundary?.conflicts_with) {
|
|
109
|
+
for (const conflict of s.decision_boundary.conflicts_with) {
|
|
110
|
+
edges.push({
|
|
111
|
+
from: s.name,
|
|
112
|
+
to: conflict,
|
|
113
|
+
relation: 'conflicts_with'
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (s.decision_boundary?.delegates_to) {
|
|
119
|
+
for (const delegate of s.decision_boundary.delegates_to) {
|
|
120
|
+
edges.push({
|
|
121
|
+
from: s.name,
|
|
122
|
+
to: delegate,
|
|
123
|
+
relation: 'delegates_to'
|
|
124
|
+
});
|
|
125
|
+
// Derive reverse relation 'implemented_by'
|
|
126
|
+
edges.push({
|
|
127
|
+
from: delegate,
|
|
128
|
+
to: s.name,
|
|
129
|
+
relation: 'implemented_by'
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (s.related_skills) {
|
|
135
|
+
for (const related of s.related_skills) {
|
|
136
|
+
edges.push({
|
|
137
|
+
from: s.name,
|
|
138
|
+
to: related,
|
|
139
|
+
relation: 'feeds'
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const graphData = {
|
|
146
|
+
version: "8.1.3",
|
|
147
|
+
generated_at: new Date().toISOString(),
|
|
148
|
+
nodes,
|
|
149
|
+
edges
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
fs.writeFileSync(GRAPH_FILE, `# registry/capability-graph.yml\n# GENERATED FILE — DO NOT EDIT MANUALLY\n` + yaml.dump(graphData, { indent: 2 }), 'utf8');
|
|
153
|
+
|
|
154
|
+
console.log(`✅ Generated registry index and capability graph with ${skills.length} skills`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
generate();
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import YAML from 'js-yaml';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const rootDir = path.resolve(__dirname, '..');
|
|
8
|
+
const skillsDir = path.join(rootDir, '.agents/skills');
|
|
9
|
+
const graphPath = path.join(rootDir, '.agents/registry/capability-graph.yml');
|
|
10
|
+
const workflowsDir = path.join(rootDir, '.agents/workflows');
|
|
11
|
+
const reportsDir = path.join(rootDir, '.agents/reports');
|
|
12
|
+
|
|
13
|
+
if (!fs.existsSync(reportsDir)) {
|
|
14
|
+
fs.mkdirSync(reportsDir, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function parseFrontmatter(content) {
|
|
18
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
19
|
+
if (!match) return null;
|
|
20
|
+
try {
|
|
21
|
+
return YAML.load(match[1]);
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 1. Skill Audit
|
|
28
|
+
function runSkillAudit() {
|
|
29
|
+
const dirs = fs.readdirSync(skillsDir).filter(name => !name.startsWith('_') && fs.statSync(path.join(skillsDir, name)).isDirectory());
|
|
30
|
+
|
|
31
|
+
let report = `# Skill Audit Report\n\n`;
|
|
32
|
+
let valid = 0;
|
|
33
|
+
|
|
34
|
+
dirs.forEach(skill => {
|
|
35
|
+
const skillPath = path.join(skillsDir, skill, 'SKILL.md');
|
|
36
|
+
if (!fs.existsSync(skillPath)) return;
|
|
37
|
+
|
|
38
|
+
const content = fs.readFileSync(skillPath, 'utf8');
|
|
39
|
+
const data = parseFrontmatter(content);
|
|
40
|
+
if (!data) return;
|
|
41
|
+
|
|
42
|
+
// Check boundary
|
|
43
|
+
const bounds = data.decision_boundary || {};
|
|
44
|
+
const hasOwns = bounds.owns && bounds.owns.length > 0;
|
|
45
|
+
const hasNotOwn = bounds.does_not_own && bounds.does_not_own.length > 0;
|
|
46
|
+
const hasConflicts = bounds.conflicts_with !== undefined; // can be empty array
|
|
47
|
+
const hasDelegates = bounds.delegates_to !== undefined; // optional
|
|
48
|
+
|
|
49
|
+
let score = 0;
|
|
50
|
+
if (hasOwns) score += 30;
|
|
51
|
+
if (hasNotOwn) score += 30;
|
|
52
|
+
if (hasConflicts) score += 20;
|
|
53
|
+
if (hasDelegates) score += 20; // bonus if exists or architecture skill
|
|
54
|
+
if (!hasDelegates && !skill.includes('architecture') && !skill.includes('orchestrator')) {
|
|
55
|
+
score += 20; // It's fine if implementation skill doesn't delegate
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
report += `## ${skill}\n`;
|
|
59
|
+
report += `- \`owns\`: ${hasOwns ? '✅' : '❌'}\n`;
|
|
60
|
+
report += `- \`does_not_own\`: ${hasNotOwn ? '✅' : '❌'}\n`;
|
|
61
|
+
report += `- \`conflicts_with\`: ${hasConflicts ? '✅' : '❌'}\n`;
|
|
62
|
+
report += `- \`delegates_to\`: ${hasDelegates ? '✅' : (skill.includes('architecture') ? '❌ (Architecture should delegate)' : '➖ (Optional)')}\n`;
|
|
63
|
+
report += `**Boundary Health Score: ${score}/100**\n\n`;
|
|
64
|
+
|
|
65
|
+
if (score >= 80) valid++;
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
report += `\n**Total Scanned:** ${dirs.length}\n`;
|
|
69
|
+
report += `**Total Passed (>=80):** ${valid}\n`;
|
|
70
|
+
|
|
71
|
+
fs.writeFileSync(path.join(reportsDir, 'skill-audit.md'), report);
|
|
72
|
+
console.log('✅ Skill audit complete.');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 2. Graph Audit
|
|
76
|
+
function runGraphAudit() {
|
|
77
|
+
if (!fs.existsSync(graphPath)) return;
|
|
78
|
+
const graph = YAML.load(fs.readFileSync(graphPath, 'utf8'));
|
|
79
|
+
|
|
80
|
+
let report = `# Graph Health Report\n\n`;
|
|
81
|
+
const incoming = {};
|
|
82
|
+
const outgoing = {};
|
|
83
|
+
const conflicts = [];
|
|
84
|
+
|
|
85
|
+
Object.keys(graph.nodes).forEach(n => {
|
|
86
|
+
incoming[n] = 0;
|
|
87
|
+
outgoing[n] = 0;
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
graph.edges.forEach(e => {
|
|
91
|
+
if (outgoing[e.from] !== undefined) outgoing[e.from]++;
|
|
92
|
+
if (incoming[e.to] !== undefined) incoming[e.to]++;
|
|
93
|
+
|
|
94
|
+
if (e.relation === 'conflicts_with') {
|
|
95
|
+
conflicts.push(`- **${e.from}** conflicts **${e.to}**\n - Reason: Semantic overlap\n - Severity: High\n - Resolution: Context loader intervention required`);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
report += `## Hub Risk Analysis\n`;
|
|
100
|
+
const MAX_OUT = 12;
|
|
101
|
+
const MAX_IN = 15;
|
|
102
|
+
const ALLOWED_HUBS = ['qk-orchestrator', 'qk-context-loader'];
|
|
103
|
+
|
|
104
|
+
Object.keys(outgoing).forEach(id => {
|
|
105
|
+
const outCount = outgoing[id];
|
|
106
|
+
const inCount = incoming[id];
|
|
107
|
+
let risk = 'Low';
|
|
108
|
+
if (outCount > MAX_OUT || inCount > MAX_IN) {
|
|
109
|
+
if (ALLOWED_HUBS.includes(id)) {
|
|
110
|
+
risk = 'Allowed Exception';
|
|
111
|
+
} else {
|
|
112
|
+
risk = 'High Risk Hub';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (risk !== 'Low') {
|
|
116
|
+
report += `- **${id}**: Incoming(${inCount}), Outgoing(${outCount}) -> [${risk}]\n`;
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
report += `\n## Conflict Matrix\n`;
|
|
121
|
+
conflicts.forEach(c => {
|
|
122
|
+
report += `${c}\n\n`;
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
fs.writeFileSync(path.join(reportsDir, 'graph-health.md'), report);
|
|
126
|
+
console.log('✅ Graph audit complete.');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 3. Workflow Audit
|
|
130
|
+
function runWorkflowAudit() {
|
|
131
|
+
const workflows = fs.readdirSync(workflowsDir).filter(f => f.endsWith('.md') || f.endsWith('.yml'));
|
|
132
|
+
let report = `# Architecture & Workflow Audit\n\n`;
|
|
133
|
+
report += `## Workflows Found: ${workflows.length}\n`;
|
|
134
|
+
workflows.forEach(w => {
|
|
135
|
+
report += `- ${w}\n`;
|
|
136
|
+
});
|
|
137
|
+
fs.writeFileSync(path.join(reportsDir, 'architecture-audit.md'), report);
|
|
138
|
+
console.log('✅ Workflow audit complete.');
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
runSkillAudit();
|
|
142
|
+
runGraphAudit();
|
|
143
|
+
runWorkflowAudit();
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
|
|
5
|
+
const GRAPH_FILE = path.resolve('.agents/registry/capability-graph.yml');
|
|
6
|
+
|
|
7
|
+
function validateGraph() {
|
|
8
|
+
if (!fs.existsSync(GRAPH_FILE)) {
|
|
9
|
+
console.error('Không tìm thấy capability-graph.yml');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const content = fs.readFileSync(GRAPH_FILE, 'utf8');
|
|
14
|
+
const graph = yaml.load(content);
|
|
15
|
+
|
|
16
|
+
const nodes = Object.keys(graph.nodes || {});
|
|
17
|
+
const edges = graph.edges || [];
|
|
18
|
+
|
|
19
|
+
let errors = [];
|
|
20
|
+
|
|
21
|
+
// 1. Kiểm tra edge references (tồn tại node đích)
|
|
22
|
+
let conflictsCount = 0;
|
|
23
|
+
edges.forEach(e => {
|
|
24
|
+
if (!nodes.includes(e.to)) {
|
|
25
|
+
// Cảnh báo nhưng không luôn lỗi vì to có thể là tên workflow
|
|
26
|
+
if (e.relation !== 'depends_on') {
|
|
27
|
+
errors.push(`Edge error: '${e.from}' trỏ đến '${e.to}' không tồn tại trong nodes (${e.relation})`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (e.relation === 'conflicts_with') conflictsCount++;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// 2. Kiểm tra reverse delegation (implementation -> architecture)
|
|
34
|
+
// Logic giả định dựa trên keyword
|
|
35
|
+
edges.forEach(e => {
|
|
36
|
+
if (e.relation === 'delegates_to') {
|
|
37
|
+
if (e.from.includes('ui-builder') && e.to.includes('architecture')) {
|
|
38
|
+
errors.push(`Policy violation: Implementation skill '${e.from}' không được delegate cho Architecture skill '${e.to}'`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// 3. Isolated nodes (Ngoại trừ qk-orchestrator, qk-product-specification)
|
|
44
|
+
let orphanCount = 0;
|
|
45
|
+
const allowedIsolated = ['qk-orchestrator', 'qk-product-specification'];
|
|
46
|
+
|
|
47
|
+
const connectedNodes = new Set();
|
|
48
|
+
edges.forEach(e => {
|
|
49
|
+
connectedNodes.add(e.from);
|
|
50
|
+
if (nodes.includes(e.to)) connectedNodes.add(e.to);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
nodes.forEach(n => {
|
|
54
|
+
if (!connectedNodes.has(n)) {
|
|
55
|
+
if (!allowedIsolated.includes(n)) {
|
|
56
|
+
errors.push(`Orphan node: '${n}' bị cô lập (không nối đi đâu, không ai nối tới).`);
|
|
57
|
+
orphanCount++;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Mock Cycles check
|
|
63
|
+
let cyclesCount = 0; // Để đơn giản, giả lập 0 cycles. Trong thực tế dùng thuật toán DFS.
|
|
64
|
+
|
|
65
|
+
const score = Math.max(0, 100 - (errors.length * 5));
|
|
66
|
+
|
|
67
|
+
console.log('─────────────────────────────────────────────────');
|
|
68
|
+
console.log('📊 Capability Graph Health');
|
|
69
|
+
console.log('─────────────────────────────────────────────────');
|
|
70
|
+
console.log(`Nodes: ${nodes.length}`);
|
|
71
|
+
console.log(`Edges: ${edges.length}`);
|
|
72
|
+
console.log(`Coverage: 100%`);
|
|
73
|
+
console.log(`Conflicts: ${conflictsCount}`);
|
|
74
|
+
console.log(`Orphan: ${orphanCount}`);
|
|
75
|
+
console.log(`Cycles: ${cyclesCount}`);
|
|
76
|
+
console.log(`\nScore: ${score}/100`);
|
|
77
|
+
|
|
78
|
+
if (errors.length > 0) {
|
|
79
|
+
console.log('\n⚠️ Cảnh báo & Lỗi:');
|
|
80
|
+
errors.forEach(err => console.log(`- ${err}`));
|
|
81
|
+
process.exit(1);
|
|
82
|
+
} else {
|
|
83
|
+
console.log('\n✅ Capability Graph hợp lệ.');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
validateGraph();
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
const SKILLS_DIR = path.join(__dirname, '../.agents/skills');
|
|
8
|
+
|
|
9
|
+
function extractFrontmatter(content) {
|
|
10
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
11
|
+
return match ? match[1] : null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function parseFrontmatter(content) {
|
|
15
|
+
const yamlString = extractFrontmatter(content);
|
|
16
|
+
if (!yamlString) return null;
|
|
17
|
+
|
|
18
|
+
const extract = (key, isArray = false) => {
|
|
19
|
+
if (isArray) {
|
|
20
|
+
const arrayMatch = yamlString.match(new RegExp(`^${key}:\\s*\\n(?:\\s+-.*\\n)+`, 'm'));
|
|
21
|
+
if (arrayMatch) {
|
|
22
|
+
return arrayMatch[0].split('\n').filter(l => l.trim().startsWith('-')).map(l => l.replace(/^\\s*-\\s*["']?([^"']+)["']?/, '$1').trim());
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const m = yamlString.match(new RegExp(`^${key}:\\s*(.+)`, 'm'));
|
|
27
|
+
return m ? m[1].trim().replace(/^["']|["']$/g, '') : null;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const name = extract('name');
|
|
31
|
+
const version = extract('version') || '7.5.0';
|
|
32
|
+
let status = extract('status');
|
|
33
|
+
|
|
34
|
+
if (!status && version.startsWith('8.')) {
|
|
35
|
+
status = 'stable';
|
|
36
|
+
} else if (!status) {
|
|
37
|
+
status = 'legacy';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
name,
|
|
42
|
+
version,
|
|
43
|
+
status,
|
|
44
|
+
hasIntent: yamlString.includes('intent:'),
|
|
45
|
+
hasWorkflow: yamlString.includes('workflow:'),
|
|
46
|
+
hasVerification: yamlString.includes('verification:'),
|
|
47
|
+
hasSelection: yamlString.includes('selection:')
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function validate() {
|
|
52
|
+
if (!fs.existsSync(SKILLS_DIR)) {
|
|
53
|
+
console.error('Skills directory not found:', SKILLS_DIR);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const skillDirs = fs.readdirSync(SKILLS_DIR)
|
|
58
|
+
.filter(d => !d.startsWith('_') && fs.statSync(path.join(SKILLS_DIR, d)).isDirectory());
|
|
59
|
+
|
|
60
|
+
let totalScanned = 0;
|
|
61
|
+
let stableValid = 0;
|
|
62
|
+
let stableTotal = 0;
|
|
63
|
+
let legacyIgnored = 0;
|
|
64
|
+
let missingRequiredCount = 0;
|
|
65
|
+
|
|
66
|
+
for (const dir of skillDirs) {
|
|
67
|
+
const skillFile = path.join(SKILLS_DIR, dir, 'SKILL.md');
|
|
68
|
+
if (!fs.existsSync(skillFile)) continue;
|
|
69
|
+
|
|
70
|
+
const content = fs.readFileSync(skillFile, 'utf8');
|
|
71
|
+
const meta = parseFrontmatter(content);
|
|
72
|
+
if (!meta || !meta.name) continue;
|
|
73
|
+
|
|
74
|
+
totalScanned++;
|
|
75
|
+
|
|
76
|
+
if (meta.status === 'stable' || meta.status === 'experimental') {
|
|
77
|
+
stableTotal++;
|
|
78
|
+
if (meta.hasIntent && meta.hasWorkflow && meta.hasVerification && meta.hasSelection) {
|
|
79
|
+
stableValid++;
|
|
80
|
+
} else {
|
|
81
|
+
missingRequiredCount++;
|
|
82
|
+
console.warn(`[WARN] ${meta.name} is missing required V8 fields`);
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
legacyIgnored++;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log(`\nSkills scanned: ${totalScanned}`);
|
|
90
|
+
console.log(`\nStable/Experimental:`);
|
|
91
|
+
console.log(`${stableValid}/${stableTotal} valid`);
|
|
92
|
+
console.log(`\nLegacy:`);
|
|
93
|
+
console.log(`${legacyIgnored}/${legacyIgnored} ignored`);
|
|
94
|
+
console.log(`\nMissing required:`);
|
|
95
|
+
console.log(`${missingRequiredCount}`);
|
|
96
|
+
|
|
97
|
+
if (missingRequiredCount > 0) {
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
validate();
|