ai-developer-skill-os 8.1.10 → 8.2.0
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/CHANGELOG.md +18 -0
- package/.agents/README.md +17 -13
- package/.agents/blueprints/coding/project.yaml.tpl +39 -0
- package/.agents/blueprints/rag/project.yaml.tpl +45 -0
- package/.agents/blueprints/workflow/project.yaml.tpl +38 -0
- package/.agents/knowledge/domain-patterns/construction/ddc-construction-ai-blueprint.md +103 -0
- package/.agents/registry/graph.json +526 -0
- package/.agents/registry/index.yaml +259 -0
- package/.agents/skills/_template/capability.yaml +20 -0
- package/.agents/skills/_template/evals/scorecard.yaml +19 -0
- package/.agents/skills/qk-agent-observability/SKILL.md +11 -0
- package/.agents/skills/qk-ai-builder/SKILL.md +13 -10
- package/.agents/skills/qk-project-bootstrap/SKILL.md +55 -51
- package/.agents/skills/qk-validation-gate/SKILL.md +15 -8
- package/CHANGELOG.md +18 -0
- package/README.md +17 -13
- package/package.json +9 -4
- package/tooling/build-registry.js +186 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-registry.js
|
|
3
|
+
* V8.2 Governed Capability Metadata & Eval Platform
|
|
4
|
+
* Generates registry/index.yaml (lightweight lookup) and registry/graph.json (O(1) graph & cycle check)
|
|
5
|
+
*
|
|
6
|
+
* Usage: node tooling/build-registry.js
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import { fileURLToPath } from 'url';
|
|
12
|
+
import yaml from 'js-yaml';
|
|
13
|
+
|
|
14
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
|
|
16
|
+
const SKILLS_DIR = path.join(__dirname, '../.agents/skills');
|
|
17
|
+
const REGISTRY_DIR = path.join(__dirname, '../.agents/registry');
|
|
18
|
+
const INDEX_YAML = path.join(REGISTRY_DIR, 'index.yaml');
|
|
19
|
+
const GRAPH_JSON = path.join(REGISTRY_DIR, 'graph.json');
|
|
20
|
+
|
|
21
|
+
function parseYamlFile(filePath) {
|
|
22
|
+
try {
|
|
23
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
24
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
25
|
+
if (match) {
|
|
26
|
+
return yaml.load(match[1]);
|
|
27
|
+
}
|
|
28
|
+
return yaml.load(content);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
console.error(`[WARN] Failed to parse YAML from ${filePath}: ${e.message}`);
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function buildRegistry() {
|
|
36
|
+
console.log('🔄 Building V8.2 Governed Capability Registry & O(1) Runtime Graph...');
|
|
37
|
+
|
|
38
|
+
if (!fs.existsSync(SKILLS_DIR)) {
|
|
39
|
+
console.error('❌ Skills directory not found:', SKILLS_DIR);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
fs.mkdirSync(REGISTRY_DIR, { recursive: true });
|
|
44
|
+
|
|
45
|
+
const dirs = fs.readdirSync(SKILLS_DIR).filter(d =>
|
|
46
|
+
!d.startsWith('_') && fs.statSync(path.join(SKILLS_DIR, d)).isDirectory()
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const capabilities = {};
|
|
50
|
+
const adjacency = {};
|
|
51
|
+
const reverseAdjacency = {};
|
|
52
|
+
|
|
53
|
+
for (const dir of dirs) {
|
|
54
|
+
const capYamlPath = path.join(SKILLS_DIR, dir, 'capability.yaml');
|
|
55
|
+
const skillMdPath = path.join(SKILLS_DIR, dir, 'SKILL.md');
|
|
56
|
+
|
|
57
|
+
let meta = null;
|
|
58
|
+
let fromCapabilityYaml = false;
|
|
59
|
+
|
|
60
|
+
if (fs.existsSync(capYamlPath)) {
|
|
61
|
+
meta = parseYamlFile(capYamlPath);
|
|
62
|
+
fromCapabilityYaml = true;
|
|
63
|
+
} else if (fs.existsSync(skillMdPath)) {
|
|
64
|
+
meta = parseYamlFile(skillMdPath);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!meta) continue;
|
|
68
|
+
|
|
69
|
+
const id = meta.id || meta.name || dir;
|
|
70
|
+
const version = meta.version || '8.2.0';
|
|
71
|
+
const description = meta.description || '';
|
|
72
|
+
|
|
73
|
+
// Normalize tags
|
|
74
|
+
let tags = meta.tags || meta.keywords || [];
|
|
75
|
+
if (!Array.isArray(tags) || tags.length === 0) {
|
|
76
|
+
// Derive simple tags from dir words
|
|
77
|
+
tags = dir.replace(/^qk-/, '').split('-');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Normalize dependencies
|
|
81
|
+
let dependencies = meta.dependencies || [];
|
|
82
|
+
if (!fromCapabilityYaml) {
|
|
83
|
+
// Derive from V8.1 skill frontmatter decision_boundary / workflow
|
|
84
|
+
const deps = new Set();
|
|
85
|
+
if (meta.workflow && typeof meta.workflow === 'string') deps.add(meta.workflow);
|
|
86
|
+
if (meta.decision_boundary?.delegates_to) {
|
|
87
|
+
meta.decision_boundary.delegates_to.forEach(d => deps.add(d));
|
|
88
|
+
}
|
|
89
|
+
dependencies = Array.from(deps);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
capabilities[id] = {
|
|
93
|
+
path: `.agents/skills/${dir}`,
|
|
94
|
+
version,
|
|
95
|
+
tags,
|
|
96
|
+
dependencies
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
adjacency[id] = dependencies;
|
|
100
|
+
if (!reverseAdjacency[id]) reverseAdjacency[id] = [];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Populate reverse adjacency for orphan detection
|
|
104
|
+
for (const [id, deps] of Object.entries(adjacency)) {
|
|
105
|
+
for (const dep of deps) {
|
|
106
|
+
if (!reverseAdjacency[dep]) reverseAdjacency[dep] = [];
|
|
107
|
+
reverseAdjacency[dep].push(id);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Detect cycles using DFS
|
|
112
|
+
let hasCycles = false;
|
|
113
|
+
const visited = {};
|
|
114
|
+
const recursionStack = {};
|
|
115
|
+
|
|
116
|
+
function detectCycle(node) {
|
|
117
|
+
visited[node] = true;
|
|
118
|
+
recursionStack[node] = true;
|
|
119
|
+
|
|
120
|
+
const deps = adjacency[node] || [];
|
|
121
|
+
for (const dep of deps) {
|
|
122
|
+
if (!visited[dep]) {
|
|
123
|
+
if (detectCycle(dep)) return true;
|
|
124
|
+
} else if (recursionStack[dep]) {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
recursionStack[node] = false;
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
for (const node of Object.keys(adjacency)) {
|
|
134
|
+
if (!visited[node]) {
|
|
135
|
+
if (detectCycle(node)) {
|
|
136
|
+
hasCycles = true;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Build Graph JSON (O(1) Runtime lookups)
|
|
143
|
+
const graphNodes = {};
|
|
144
|
+
for (const [id, data] of Object.entries(capabilities)) {
|
|
145
|
+
const dependents = reverseAdjacency[id] || [];
|
|
146
|
+
const isOrphan = data.dependencies.length === 0 && dependents.length === 0 && id !== 'qk-orchestrator' && id !== 'qk-help';
|
|
147
|
+
|
|
148
|
+
graphNodes[id] = {
|
|
149
|
+
path: data.path,
|
|
150
|
+
version: data.version,
|
|
151
|
+
tags: data.tags,
|
|
152
|
+
dependencies: data.dependencies,
|
|
153
|
+
dependents,
|
|
154
|
+
is_orphan: isOrphan
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const graphJsonData = {
|
|
159
|
+
schema_version: 1,
|
|
160
|
+
manifest_version: '8.2',
|
|
161
|
+
generated_at: new Date().toISOString(),
|
|
162
|
+
nodes: graphNodes,
|
|
163
|
+
adjacency,
|
|
164
|
+
stats: {
|
|
165
|
+
total_capabilities: Object.keys(capabilities).length,
|
|
166
|
+
has_cycles: hasCycles
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// Build Registry Index YAML (Lightweight lookup)
|
|
171
|
+
const indexYamlContent = `# AUTO-GENERATED BY registry-builder (tooling/build-registry.js)\n# DO NOT EDIT MANUALLY. THIS IS A GENERATED RUNTIME ARTIFACT.\n` +
|
|
172
|
+
yaml.dump({
|
|
173
|
+
schema_version: 1,
|
|
174
|
+
manifest_version: '8.2',
|
|
175
|
+
generated_at: new Date().toISOString(),
|
|
176
|
+
capabilities
|
|
177
|
+
}, { indent: 2 });
|
|
178
|
+
|
|
179
|
+
fs.writeFileSync(INDEX_YAML, indexYamlContent, 'utf8');
|
|
180
|
+
fs.writeFileSync(GRAPH_JSON, JSON.stringify(graphJsonData, null, 2), 'utf8');
|
|
181
|
+
|
|
182
|
+
console.log(`✅ Generated lightweight registry index at .agents/registry/index.yaml (${Object.keys(capabilities).length} capabilities)`);
|
|
183
|
+
console.log(`✅ Generated O(1) adjacency graph at .agents/registry/graph.json (has_cycles: ${hasCycles})`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
buildRegistry();
|