@squads-sh/validator 0.1.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.
Files changed (53) hide show
  1. package/dist/adapters/filesystem.d.ts +11 -0
  2. package/dist/adapters/filesystem.d.ts.map +1 -0
  3. package/dist/adapters/filesystem.js +37 -0
  4. package/dist/adapters/filesystem.js.map +1 -0
  5. package/dist/categories/agents.d.ts +21 -0
  6. package/dist/categories/agents.d.ts.map +1 -0
  7. package/dist/categories/agents.js +214 -0
  8. package/dist/categories/agents.js.map +1 -0
  9. package/dist/categories/cross-refs.d.ts +13 -0
  10. package/dist/categories/cross-refs.d.ts.map +1 -0
  11. package/dist/categories/cross-refs.js +88 -0
  12. package/dist/categories/cross-refs.js.map +1 -0
  13. package/dist/categories/manifest.d.ts +19 -0
  14. package/dist/categories/manifest.d.ts.map +1 -0
  15. package/dist/categories/manifest.js +150 -0
  16. package/dist/categories/manifest.js.map +1 -0
  17. package/dist/categories/structure.d.ts +14 -0
  18. package/dist/categories/structure.d.ts.map +1 -0
  19. package/dist/categories/structure.js +76 -0
  20. package/dist/categories/structure.js.map +1 -0
  21. package/dist/categories/tasks.d.ts +20 -0
  22. package/dist/categories/tasks.d.ts.map +1 -0
  23. package/dist/categories/tasks.js +195 -0
  24. package/dist/categories/tasks.js.map +1 -0
  25. package/dist/categories/workflows.d.ts +17 -0
  26. package/dist/categories/workflows.d.ts.map +1 -0
  27. package/dist/categories/workflows.js +125 -0
  28. package/dist/categories/workflows.js.map +1 -0
  29. package/dist/index.d.ts +14 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +62 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/parser.d.ts +20 -0
  34. package/dist/parser.d.ts.map +1 -0
  35. package/dist/parser.js +58 -0
  36. package/dist/parser.js.map +1 -0
  37. package/dist/scoring.d.ts +22 -0
  38. package/dist/scoring.d.ts.map +1 -0
  39. package/dist/scoring.js +57 -0
  40. package/dist/scoring.js.map +1 -0
  41. package/dist/types.d.ts +101 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +19 -0
  44. package/dist/types.js.map +1 -0
  45. package/dist/utils/enums.d.ts +9 -0
  46. package/dist/utils/enums.d.ts.map +1 -0
  47. package/dist/utils/enums.js +37 -0
  48. package/dist/utils/enums.js.map +1 -0
  49. package/dist/utils/patterns.d.ts +11 -0
  50. package/dist/utils/patterns.d.ts.map +1 -0
  51. package/dist/utils/patterns.js +11 -0
  52. package/dist/utils/patterns.js.map +1 -0
  53. package/package.json +34 -0
@@ -0,0 +1,76 @@
1
+ const CAT = "structure";
2
+ /**
3
+ * Category 2: Structure validation
4
+ * Weight: 15%
5
+ *
6
+ * Validates:
7
+ * - agents/ directory exists with at least 1 .md file
8
+ * - tasks/ directory exists (warning if missing)
9
+ * - workflows/ directory exists (warning if missing)
10
+ * - config/ directory exists (warning if missing)
11
+ * - Each file listed in components.* exists in the FileTree
12
+ */
13
+ export function validateStructure(fileTree, manifest) {
14
+ const findings = [];
15
+ const dirs = new Set();
16
+ for (const path of fileTree.keys()) {
17
+ const firstSegment = path.split("/")[0];
18
+ if (firstSegment)
19
+ dirs.add(firstSegment);
20
+ }
21
+ // Check agents/ directory
22
+ const agentFiles = [...fileTree.keys()].filter((p) => p.startsWith("agents/") && p.endsWith(".md"));
23
+ if (agentFiles.length === 0) {
24
+ findings.push({
25
+ severity: "error",
26
+ category: CAT,
27
+ message: "agents/ directory must contain at least one .md file",
28
+ });
29
+ }
30
+ // Optional directories (warnings)
31
+ for (const dir of ["tasks", "workflows", "config"]) {
32
+ const hasFiles = [...fileTree.keys()].some((p) => p.startsWith(`${dir}/`));
33
+ if (!hasFiles) {
34
+ findings.push({
35
+ severity: "warning",
36
+ category: CAT,
37
+ message: `Optional directory ${dir}/ not found`,
38
+ });
39
+ }
40
+ }
41
+ // Validate components.* entries exist in FileTree
42
+ if (manifest?.components) {
43
+ const componentSections = [
44
+ ["agents", "agents/"],
45
+ ["tasks", "tasks/"],
46
+ ["workflows", "workflows/"],
47
+ ];
48
+ for (const [key, prefix] of componentSections) {
49
+ const list = manifest.components[key];
50
+ if (Array.isArray(list)) {
51
+ for (const item of list) {
52
+ if (typeof item !== "string")
53
+ continue;
54
+ // Try with and without extension
55
+ const candidates = [
56
+ `${prefix}${item}`,
57
+ `${prefix}${item}.md`,
58
+ `${prefix}${item}.yaml`,
59
+ `${prefix}${item}.yml`,
60
+ ];
61
+ const found = candidates.some((c) => fileTree.has(c));
62
+ if (!found) {
63
+ findings.push({
64
+ severity: "error",
65
+ category: CAT,
66
+ message: `Component '${key}.${item}' listed in squad.yaml but file not found in ${prefix}`,
67
+ file: "squad.yaml",
68
+ });
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ return findings;
75
+ }
76
+ //# sourceMappingURL=structure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structure.js","sourceRoot":"","sources":["../../src/categories/structure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { FileTree, ValidationFinding, ParsedTask } from "../types.js";
2
+ /**
3
+ * Category 4: Tasks validation
4
+ * Weight: 15%
5
+ *
6
+ * Validates:
7
+ * - YAML frontmatter exists
8
+ * - task (camelCase with parentheses)
9
+ * - responsavel (non-empty)
10
+ * - responsavel_type in {Agente, Worker, Humano, Clone}
11
+ * - atomic_layer in {Atom, Molecule, Organism, Template, Page}
12
+ * - Entrada (array with at least 1 item, each with 4 fields)
13
+ * - Saida (array with at least 1 item, each with 4 fields)
14
+ * - Checklist (non-empty)
15
+ */
16
+ export declare function validateTasks(fileTree: FileTree): {
17
+ findings: ValidationFinding[];
18
+ tasks: ParsedTask[];
19
+ };
20
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/categories/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO3E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,QAAQ,GACjB;IAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAAC,KAAK,EAAE,UAAU,EAAE,CAAA;CAAE,CAuIxD"}
@@ -0,0 +1,195 @@
1
+ import { extractFrontmatter, hasFrontmatter } from "../parser.js";
2
+ import { CAMEL_CASE_PAREN } from "../utils/patterns.js";
3
+ import { ATOMIC_LAYERS, RESPONSAVEL_TYPES } from "../utils/enums.js";
4
+ const CAT = "tasks";
5
+ /**
6
+ * Category 4: Tasks validation
7
+ * Weight: 15%
8
+ *
9
+ * Validates:
10
+ * - YAML frontmatter exists
11
+ * - task (camelCase with parentheses)
12
+ * - responsavel (non-empty)
13
+ * - responsavel_type in {Agente, Worker, Humano, Clone}
14
+ * - atomic_layer in {Atom, Molecule, Organism, Template, Page}
15
+ * - Entrada (array with at least 1 item, each with 4 fields)
16
+ * - Saida (array with at least 1 item, each with 4 fields)
17
+ * - Checklist (non-empty)
18
+ */
19
+ export function validateTasks(fileTree) {
20
+ const findings = [];
21
+ const tasks = [];
22
+ const taskFiles = [...fileTree.keys()].filter((p) => p.startsWith("tasks/") && p.endsWith(".md"));
23
+ if (taskFiles.length === 0) {
24
+ return { findings, tasks };
25
+ }
26
+ for (const file of taskFiles) {
27
+ const content = fileTree.get(file);
28
+ if (!hasFrontmatter(content)) {
29
+ findings.push({
30
+ severity: "error",
31
+ category: CAT,
32
+ message: "Task file missing YAML frontmatter block (--- ... ---)",
33
+ file,
34
+ });
35
+ tasks.push({ file });
36
+ continue;
37
+ }
38
+ const fm = extractFrontmatter(content);
39
+ if (!fm) {
40
+ findings.push({
41
+ severity: "error",
42
+ category: CAT,
43
+ message: "Task file has invalid YAML in frontmatter",
44
+ file,
45
+ });
46
+ tasks.push({ file });
47
+ continue;
48
+ }
49
+ const parsed = {
50
+ file,
51
+ task: fm["task"],
52
+ responsavel: fm["responsavel"],
53
+ responsavel_type: fm["responsavel_type"],
54
+ atomic_layer: fm["atomic_layer"],
55
+ Entrada: fm["Entrada"],
56
+ Saida: fm["Saida"],
57
+ Checklist: fm["Checklist"],
58
+ };
59
+ tasks.push(parsed);
60
+ // task identifier
61
+ if (!parsed.task) {
62
+ findings.push({
63
+ severity: "error",
64
+ category: CAT,
65
+ message: "Missing 'task' field",
66
+ file,
67
+ });
68
+ }
69
+ else if (typeof parsed.task === "string" && !CAMEL_CASE_PAREN.test(parsed.task)) {
70
+ findings.push({
71
+ severity: "warning",
72
+ category: CAT,
73
+ message: `'task' should be camelCase with parentheses (e.g. myTask()), got: "${parsed.task}"`,
74
+ file,
75
+ });
76
+ }
77
+ // responsavel
78
+ if (!parsed.responsavel) {
79
+ findings.push({
80
+ severity: "error",
81
+ category: CAT,
82
+ message: "Missing 'responsavel' field",
83
+ file,
84
+ });
85
+ }
86
+ // responsavel_type
87
+ if (!parsed.responsavel_type) {
88
+ findings.push({
89
+ severity: "error",
90
+ category: CAT,
91
+ message: "Missing 'responsavel_type' field",
92
+ file,
93
+ });
94
+ }
95
+ else if (typeof parsed.responsavel_type === "string" &&
96
+ !RESPONSAVEL_TYPES.has(parsed.responsavel_type)) {
97
+ findings.push({
98
+ severity: "error",
99
+ category: CAT,
100
+ message: `'responsavel_type' must be one of {${[...RESPONSAVEL_TYPES].join(", ")}}, got: "${parsed.responsavel_type}"`,
101
+ file,
102
+ });
103
+ }
104
+ // atomic_layer
105
+ if (!parsed.atomic_layer) {
106
+ findings.push({
107
+ severity: "warning",
108
+ category: CAT,
109
+ message: "Missing 'atomic_layer' field",
110
+ file,
111
+ });
112
+ }
113
+ else if (typeof parsed.atomic_layer === "string" &&
114
+ !ATOMIC_LAYERS.has(parsed.atomic_layer)) {
115
+ findings.push({
116
+ severity: "warning",
117
+ category: CAT,
118
+ message: `'atomic_layer' should be one of {${[...ATOMIC_LAYERS].join(", ")}}, got: "${parsed.atomic_layer}"`,
119
+ file,
120
+ });
121
+ }
122
+ // Entrada
123
+ validateContractArray(parsed.Entrada, "Entrada", file, findings);
124
+ // Saida
125
+ validateContractArray(parsed.Saida, "Saida", file, findings);
126
+ // Checklist
127
+ if (!parsed.Checklist) {
128
+ findings.push({
129
+ severity: "error",
130
+ category: CAT,
131
+ message: "Missing 'Checklist' field",
132
+ file,
133
+ });
134
+ }
135
+ }
136
+ return { findings, tasks };
137
+ }
138
+ function validateContractArray(arr, name, file, findings) {
139
+ if (!arr || !Array.isArray(arr)) {
140
+ findings.push({
141
+ severity: "error",
142
+ category: CAT,
143
+ message: `Missing '${name}' field (must be an array)`,
144
+ file,
145
+ });
146
+ return;
147
+ }
148
+ if (arr.length === 0) {
149
+ findings.push({
150
+ severity: "error",
151
+ category: CAT,
152
+ message: `'${name}' must have at least 1 item`,
153
+ file,
154
+ });
155
+ return;
156
+ }
157
+ // Required fields with accepted aliases
158
+ const fieldChecks = [
159
+ { canonical: "nome", aliases: ["nome", "campo"] },
160
+ { canonical: "tipo", aliases: ["tipo"] },
161
+ { canonical: "obrigatorio", aliases: ["obrigatorio", "persistido"] },
162
+ ];
163
+ // "descricao" is recommended but optional — aliases: origen, destino
164
+ const optionalWithAliases = [
165
+ { canonical: "descricao", aliases: ["descricao", "origen", "destino"] },
166
+ ];
167
+ for (let i = 0; i < arr.length; i++) {
168
+ const item = arr[i];
169
+ if (!item || typeof item !== "object") {
170
+ findings.push({
171
+ severity: "warning",
172
+ category: CAT,
173
+ message: `'${name}[${i}]' is not a valid object`,
174
+ file,
175
+ });
176
+ continue;
177
+ }
178
+ const keys = Object.keys(item);
179
+ // Check required fields (with alias support)
180
+ const missing = fieldChecks
181
+ .filter((check) => !check.aliases.some((alias) => keys.includes(alias)))
182
+ .map((check) => check.canonical);
183
+ if (missing.length > 0) {
184
+ findings.push({
185
+ severity: "warning",
186
+ category: CAT,
187
+ message: `'${name}[${i}]' missing fields: ${missing.join(", ")}`,
188
+ file,
189
+ });
190
+ }
191
+ // Check optional fields (just a hint, no finding)
192
+ // "descricao" or its aliases (origen/destino) are recommended but not required
193
+ }
194
+ }
195
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/categories/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { FileTree, ValidationFinding, ParsedWorkflow } from "../types.js";
2
+ /**
3
+ * Category 5: Workflows validation
4
+ * Weight: 10%
5
+ *
6
+ * Validates:
7
+ * - Valid YAML
8
+ * - workflow_name (snake_case)
9
+ * - description (non-empty)
10
+ * - agent_sequence (array with at least 1 entry)
11
+ * - success_indicators (array with at least 1 entry)
12
+ */
13
+ export declare function validateWorkflows(fileTree: FileTree): {
14
+ findings: ValidationFinding[];
15
+ workflows: ParsedWorkflow[];
16
+ };
17
+ //# sourceMappingURL=workflows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows.d.ts","sourceRoot":"","sources":["../../src/categories/workflows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAM/E;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,QAAQ,GACjB;IAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAAC,SAAS,EAAE,cAAc,EAAE,CAAA;CAAE,CAuHhE"}
@@ -0,0 +1,125 @@
1
+ import { parseYaml } from "../parser.js";
2
+ import { SNAKE_CASE } from "../utils/patterns.js";
3
+ const CAT = "workflows";
4
+ /**
5
+ * Category 5: Workflows validation
6
+ * Weight: 10%
7
+ *
8
+ * Validates:
9
+ * - Valid YAML
10
+ * - workflow_name (snake_case)
11
+ * - description (non-empty)
12
+ * - agent_sequence (array with at least 1 entry)
13
+ * - success_indicators (array with at least 1 entry)
14
+ */
15
+ export function validateWorkflows(fileTree) {
16
+ const findings = [];
17
+ const workflows = [];
18
+ const workflowFiles = [...fileTree.keys()].filter((p) => p.startsWith("workflows/") &&
19
+ (p.endsWith(".yaml") || p.endsWith(".yml")));
20
+ if (workflowFiles.length === 0) {
21
+ return { findings, workflows };
22
+ }
23
+ for (const file of workflowFiles) {
24
+ const content = fileTree.get(file);
25
+ const parsed = parseYaml(content);
26
+ if (!parsed) {
27
+ findings.push({
28
+ severity: "error",
29
+ category: CAT,
30
+ message: "Workflow file contains invalid YAML",
31
+ file,
32
+ });
33
+ workflows.push({ file });
34
+ continue;
35
+ }
36
+ const wf = {
37
+ file,
38
+ workflow_name: parsed["workflow_name"],
39
+ description: parsed["description"],
40
+ agent_sequence: parsed["agent_sequence"],
41
+ success_indicators: parsed["success_indicators"],
42
+ transitions: parsed["transitions"],
43
+ };
44
+ workflows.push(wf);
45
+ // workflow_name
46
+ if (!wf.workflow_name) {
47
+ findings.push({
48
+ severity: "error",
49
+ category: CAT,
50
+ message: "Missing 'workflow_name' field",
51
+ file,
52
+ });
53
+ }
54
+ else if (typeof wf.workflow_name === "string" &&
55
+ !SNAKE_CASE.test(wf.workflow_name)) {
56
+ findings.push({
57
+ severity: "warning",
58
+ category: CAT,
59
+ message: `'workflow_name' should be snake_case, got: "${wf.workflow_name}"`,
60
+ file,
61
+ });
62
+ }
63
+ // description
64
+ if (!wf.description) {
65
+ findings.push({
66
+ severity: "warning",
67
+ category: CAT,
68
+ message: "Missing 'description' field",
69
+ file,
70
+ });
71
+ }
72
+ // agent_sequence
73
+ if (!wf.agent_sequence) {
74
+ findings.push({
75
+ severity: "error",
76
+ category: CAT,
77
+ message: "Missing 'agent_sequence' field",
78
+ file,
79
+ });
80
+ }
81
+ else if (!Array.isArray(wf.agent_sequence)) {
82
+ findings.push({
83
+ severity: "error",
84
+ category: CAT,
85
+ message: "'agent_sequence' must be an array",
86
+ file,
87
+ });
88
+ }
89
+ else if (wf.agent_sequence.length === 0) {
90
+ findings.push({
91
+ severity: "error",
92
+ category: CAT,
93
+ message: "'agent_sequence' must have at least 1 entry",
94
+ file,
95
+ });
96
+ }
97
+ // success_indicators
98
+ if (!wf.success_indicators) {
99
+ findings.push({
100
+ severity: "error",
101
+ category: CAT,
102
+ message: "Missing 'success_indicators' field",
103
+ file,
104
+ });
105
+ }
106
+ else if (!Array.isArray(wf.success_indicators)) {
107
+ findings.push({
108
+ severity: "error",
109
+ category: CAT,
110
+ message: "'success_indicators' must be an array",
111
+ file,
112
+ });
113
+ }
114
+ else if (wf.success_indicators.length === 0) {
115
+ findings.push({
116
+ severity: "error",
117
+ category: CAT,
118
+ message: "'success_indicators' must have at least 1 entry",
119
+ file,
120
+ });
121
+ }
122
+ }
123
+ return { findings, workflows };
124
+ }
125
+ //# sourceMappingURL=workflows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflows.js","sourceRoot":"","sources":["../../src/categories/workflows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { FileTree, ValidationReport } from "./types.js";
2
+ /**
3
+ * Validate an AIOS Squad from a FileTree.
4
+ *
5
+ * The FileTree is a Map<string, string> of relative paths to file contents.
6
+ * The validator is isomorphic — it works in Node.js, Deno, browsers, etc.
7
+ *
8
+ * @param fileTree Map of relative file paths to their contents
9
+ * @returns ValidationReport with score, status, and per-category results
10
+ */
11
+ export declare function validateSquad(fileTree: FileTree): ValidationReport;
12
+ export type { FileTree, ValidationReport, ValidationStatus, ValidationFinding, CategoryResult, CategoryName, Severity, ParsedManifest, ParsedAgent, ParsedTask, ParsedWorkflow, } from "./types.js";
13
+ export { CATEGORY_WEIGHTS, CATEGORY_LABELS } from "./types.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,gBAAgB,EAGjB,MAAM,YAAY,CAAC;AAcpB;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,gBAAgB,CA0DlE;AAGD,YAAY,EACV,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,cAAc,EACd,WAAW,EACX,UAAU,EACV,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,62 @@
1
+ import { validateManifest } from "./categories/manifest.js";
2
+ import { validateStructure } from "./categories/structure.js";
3
+ import { validateAgents } from "./categories/agents.js";
4
+ import { validateTasks } from "./categories/tasks.js";
5
+ import { validateWorkflows } from "./categories/workflows.js";
6
+ import { validateCrossReferences } from "./categories/cross-refs.js";
7
+ import { buildCategoryResult, computeWeightedScore, computeStatus, } from "./scoring.js";
8
+ /**
9
+ * Validate an AIOS Squad from a FileTree.
10
+ *
11
+ * The FileTree is a Map<string, string> of relative paths to file contents.
12
+ * The validator is isomorphic — it works in Node.js, Deno, browsers, etc.
13
+ *
14
+ * @param fileTree Map of relative file paths to their contents
15
+ * @returns ValidationReport with score, status, and per-category results
16
+ */
17
+ export function validateSquad(fileTree) {
18
+ const allFindings = [];
19
+ // Category 1: Manifest
20
+ const { findings: manifestFindings, parsed: manifest } = validateManifest(fileTree);
21
+ allFindings.push(...manifestFindings);
22
+ // Category 2: Structure
23
+ const structureFindings = validateStructure(fileTree, manifest);
24
+ allFindings.push(...structureFindings);
25
+ // Category 3: Agents
26
+ const { findings: agentFindings, agents } = validateAgents(fileTree);
27
+ allFindings.push(...agentFindings);
28
+ // Category 4: Tasks
29
+ const { findings: taskFindings, tasks } = validateTasks(fileTree);
30
+ allFindings.push(...taskFindings);
31
+ // Category 5: Workflows
32
+ const { findings: workflowFindings, workflows } = validateWorkflows(fileTree);
33
+ allFindings.push(...workflowFindings);
34
+ // Category 6: Cross-references
35
+ const crossRefFindings = validateCrossReferences(agents, tasks, workflows);
36
+ allFindings.push(...crossRefFindings);
37
+ // Build category results
38
+ const categoryNames = [
39
+ "manifest",
40
+ "structure",
41
+ "agents",
42
+ "tasks",
43
+ "workflows",
44
+ "cross-refs",
45
+ ];
46
+ const categories = categoryNames.map((name) => buildCategoryResult(name, allFindings));
47
+ const totalErrors = allFindings.filter((f) => f.severity === "error").length;
48
+ const totalWarnings = allFindings.filter((f) => f.severity === "warning").length;
49
+ return {
50
+ score: computeWeightedScore(categories),
51
+ status: computeStatus(totalErrors, totalWarnings),
52
+ categories,
53
+ findings: allFindings,
54
+ summary: {
55
+ totalErrors,
56
+ totalWarnings,
57
+ fileCount: fileTree.size,
58
+ },
59
+ };
60
+ }
61
+ export { CATEGORY_WEIGHTS, CATEGORY_LABELS } from "./types.js";
62
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,QAAkB;IAC9C,MAAM,WAAW,GAAwB,EAAE,CAAC;IAE5C,uBAAuB;IACvB,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,GACpD,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC7B,WAAW,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;IAEtC,wBAAwB;IACxB,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAChE,WAAW,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,CAAC;IAEvC,qBAAqB;IACrB,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACrE,WAAW,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;IAEnC,oBAAoB;IACpB,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAClE,WAAW,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;IAElC,wBAAwB;IACxB,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,EAAE,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC9E,WAAW,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;IAEtC,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAC3E,WAAW,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC;IAEtC,yBAAyB;IACzB,MAAM,aAAa,GAAmB;QACpC,UAAU;QACV,WAAW;QACX,QAAQ;QACR,OAAO;QACP,WAAW;QACX,YAAY;KACb,CAAC;IAEF,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC5C,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC,CACvC,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;IAC7E,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAChC,CAAC,MAAM,CAAC;IAET,OAAO;QACL,KAAK,EAAE,oBAAoB,CAAC,UAAU,CAAC;QACvC,MAAM,EAAE,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC;QACjD,UAAU;QACV,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE;YACP,WAAW;YACX,aAAa;YACb,SAAS,EAAE,QAAQ,CAAC,IAAI;SACzB;KACF,CAAC;AACJ,CAAC;AAiBD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Extract YAML frontmatter from a Markdown file.
3
+ * Returns the parsed object or null if no frontmatter found.
4
+ */
5
+ export declare function extractFrontmatter(content: string): Record<string, unknown> | null;
6
+ /**
7
+ * Parse a YAML string into an object.
8
+ * Returns null on parse failure.
9
+ */
10
+ export declare function parseYaml(content: string): Record<string, unknown> | null;
11
+ /**
12
+ * Deep get a nested value by dot-separated path.
13
+ * e.g. getNestedValue(obj, "aios.minVersion")
14
+ */
15
+ export declare function getNestedValue(obj: Record<string, unknown>, path: string): unknown;
16
+ /**
17
+ * Check if content has YAML frontmatter block.
18
+ */
19
+ export declare function hasFrontmatter(content: string): boolean;
20
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAalF;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUzE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQlF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvD"}
package/dist/parser.js ADDED
@@ -0,0 +1,58 @@
1
+ import yaml from "js-yaml";
2
+ import { FRONTMATTER_BLOCK } from "./utils/patterns.js";
3
+ /**
4
+ * Extract YAML frontmatter from a Markdown file.
5
+ * Returns the parsed object or null if no frontmatter found.
6
+ */
7
+ export function extractFrontmatter(content) {
8
+ const match = content.match(FRONTMATTER_BLOCK);
9
+ if (!match || !match[1])
10
+ return null;
11
+ try {
12
+ const parsed = yaml.load(match[1]);
13
+ if (parsed && typeof parsed === "object") {
14
+ return parsed;
15
+ }
16
+ return null;
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ /**
23
+ * Parse a YAML string into an object.
24
+ * Returns null on parse failure.
25
+ */
26
+ export function parseYaml(content) {
27
+ try {
28
+ const parsed = yaml.load(content);
29
+ if (parsed && typeof parsed === "object") {
30
+ return parsed;
31
+ }
32
+ return null;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ /**
39
+ * Deep get a nested value by dot-separated path.
40
+ * e.g. getNestedValue(obj, "aios.minVersion")
41
+ */
42
+ export function getNestedValue(obj, path) {
43
+ const keys = path.split(".");
44
+ let current = obj;
45
+ for (const key of keys) {
46
+ if (current == null || typeof current !== "object")
47
+ return undefined;
48
+ current = current[key];
49
+ }
50
+ return current;
51
+ }
52
+ /**
53
+ * Check if content has YAML frontmatter block.
54
+ */
55
+ export function hasFrontmatter(content) {
56
+ return FRONTMATTER_BLOCK.test(content);
57
+ }
58
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC/C,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzC,OAAO,MAAiC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzC,OAAO,MAAiC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAA4B,EAAE,IAAY;IACvE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,OAAO,GAAY,GAAG,CAAC;IAC3B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,OAAO,IAAI,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QACrE,OAAO,GAAI,OAAmC,CAAC,GAAG,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC"}