@shahmarasy/prodo 0.1.5 → 0.1.7
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/dist/agents/system-prompts.js +12 -12
- package/dist/cli/agent-command-installer.d.ts +1 -1
- package/dist/cli/agent-command-installer.js +125 -19
- package/dist/cli/doctor.js +2 -2
- package/dist/cli/index.js +32 -30
- package/dist/cli/init-tui.d.ts +2 -2
- package/dist/cli/init-tui.js +43 -36
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.js +3 -2
- package/dist/core/artifacts.js +72 -72
- package/dist/core/settings.d.ts +1 -0
- package/dist/core/settings.js +10 -2
- package/dist/core/templates.js +248 -248
- package/dist/i18n/en.json +45 -45
- package/dist/i18n/tr.json +45 -45
- package/dist/providers/mock-provider.js +5 -5
- package/dist/providers/openai-provider.js +12 -12
- package/dist/skill-engine/context.d.ts +7 -0
- package/dist/skill-engine/context.js +76 -0
- package/dist/skill-engine/discovery.d.ts +2 -0
- package/dist/skill-engine/discovery.js +52 -0
- package/dist/skill-engine/graph.d.ts +4 -0
- package/dist/skill-engine/graph.js +114 -0
- package/dist/skill-engine/index.d.ts +11 -0
- package/dist/skill-engine/index.js +49 -0
- package/dist/skill-engine/pipeline.d.ts +9 -0
- package/dist/skill-engine/pipeline.js +84 -0
- package/dist/skill-engine/registry.d.ts +12 -0
- package/dist/skill-engine/registry.js +74 -0
- package/dist/skill-engine/types.d.ts +66 -0
- package/dist/skill-engine/types.js +2 -0
- package/dist/skill-engine/validator.d.ts +4 -0
- package/dist/skill-engine/validator.js +90 -0
- package/dist/skills/fix.d.ts +2 -0
- package/dist/skills/fix.js +41 -0
- package/dist/skills/generate-artifact.d.ts +2 -0
- package/dist/skills/generate-artifact.js +42 -0
- package/dist/skills/normalize.d.ts +2 -0
- package/dist/skills/normalize.js +29 -0
- package/dist/skills/register-core.d.ts +2 -0
- package/dist/skills/register-core.js +21 -0
- package/dist/skills/validate.d.ts +2 -0
- package/dist/skills/validate.js +37 -0
- package/package.json +4 -6
- package/src/cli/agent-command-installer.ts +115 -1
- package/src/cli/doctor.ts +2 -2
- package/src/cli/index.ts +35 -31
- package/src/cli/init-tui.ts +220 -208
- package/src/cli/init.ts +4 -3
- package/src/core/settings.ts +41 -35
- package/src/skill-engine/context.ts +90 -0
- package/src/skill-engine/discovery.ts +57 -0
- package/src/skill-engine/graph.ts +136 -0
- package/src/skill-engine/index.ts +55 -0
- package/src/skill-engine/pipeline.ts +112 -0
- package/src/skill-engine/registry.ts +75 -0
- package/src/skill-engine/types.ts +81 -0
- package/src/skill-engine/validator.ts +135 -0
- package/src/skills/fix.ts +45 -0
- package/src/skills/generate-artifact.ts +48 -0
- package/src/skills/{normalize-skill.ts → normalize.ts} +15 -12
- package/src/skills/register-core.ts +27 -0
- package/src/skills/validate.ts +40 -0
- package/src/skills/engine.ts +0 -94
- package/src/skills/fix-skill.ts +0 -38
- package/src/skills/generate-artifact-skill.ts +0 -32
- package/src/skills/generate-pipeline-skill.ts +0 -49
- package/src/skills/types.ts +0 -36
- package/src/skills/validate-skill.ts +0 -29
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { generateArtifact } from "../core/artifacts";
|
|
2
|
+
import { defaultUpstreamByArtifact } from "../core/constants";
|
|
3
|
+
import type { Skill, SkillManifest } from "../skill-engine/types";
|
|
4
|
+
|
|
5
|
+
export function createArtifactSkill(artifactType: string, upstream?: string[]): Skill {
|
|
6
|
+
const resolvedUpstream = upstream ?? defaultUpstreamByArtifact(artifactType);
|
|
7
|
+
const depends_on = ["normalize", ...resolvedUpstream];
|
|
8
|
+
|
|
9
|
+
const manifest: SkillManifest = {
|
|
10
|
+
name: artifactType,
|
|
11
|
+
version: "2.0.0",
|
|
12
|
+
description: `Generate ${artifactType} artifact from normalized brief`,
|
|
13
|
+
category: "artifact",
|
|
14
|
+
depends_on,
|
|
15
|
+
inputs: [
|
|
16
|
+
{ name: "cwd", type: "path", required: true, description: "Project working directory" },
|
|
17
|
+
{ name: "normalizedBriefPath", type: "path", required: false, description: "Path to normalized brief" }
|
|
18
|
+
],
|
|
19
|
+
outputs: [
|
|
20
|
+
{ name: "artifactPath", type: "path", description: `Path to generated ${artifactType}` }
|
|
21
|
+
],
|
|
22
|
+
tags: ["artifact", artifactType]
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
manifest,
|
|
27
|
+
async execute(context, inputs) {
|
|
28
|
+
const cwd = (inputs.cwd as string) ?? context.state.cwd;
|
|
29
|
+
const normalizedBriefOverride =
|
|
30
|
+
(inputs.normalizedBriefPath as string) ?? context.state.normalizedBriefPath;
|
|
31
|
+
|
|
32
|
+
context.progress(1, 2, `Generating ${artifactType}...`);
|
|
33
|
+
|
|
34
|
+
const filePath = await generateArtifact({
|
|
35
|
+
artifactType,
|
|
36
|
+
cwd,
|
|
37
|
+
normalizedBriefOverride,
|
|
38
|
+
agent: context.agent
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
context.progress(2, 2, `${artifactType} generated.`);
|
|
42
|
+
context.log(`${artifactType.toUpperCase()} generated: ${filePath}`);
|
|
43
|
+
context.state.generatedArtifacts.set(artifactType, filePath);
|
|
44
|
+
|
|
45
|
+
return { artifactPath: filePath };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
import { runNormalize } from "../core/normalize";
|
|
2
|
-
import type { Skill } from "
|
|
2
|
+
import type { Skill } from "../skill-engine/types";
|
|
3
3
|
|
|
4
4
|
export const normalizeSkill: Skill = {
|
|
5
5
|
manifest: {
|
|
6
6
|
name: "normalize",
|
|
7
|
+
version: "2.0.0",
|
|
7
8
|
description: "Normalize a product brief into structured JSON with contracts and confidence scores",
|
|
8
9
|
category: "core",
|
|
10
|
+
depends_on: [],
|
|
9
11
|
inputs: [
|
|
10
|
-
{ name: "cwd", type: "path", required: true, description: "Project working directory" }
|
|
11
|
-
{ name: "brief", type: "path", required: false, description: "Override path to brief.md" },
|
|
12
|
-
{ name: "out", type: "path", required: false, description: "Override output path" }
|
|
12
|
+
{ name: "cwd", type: "path", required: true, description: "Project working directory" }
|
|
13
13
|
],
|
|
14
14
|
outputs: [
|
|
15
15
|
{ name: "normalizedBriefPath", type: "path", description: "Path to normalized-brief.json" }
|
|
16
|
-
]
|
|
16
|
+
],
|
|
17
|
+
tags: ["brief", "normalization"]
|
|
17
18
|
},
|
|
18
19
|
|
|
19
|
-
async execute(context, inputs)
|
|
20
|
-
const cwd = (inputs.cwd as string) ?? context.cwd;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
async execute(context, inputs) {
|
|
21
|
+
const cwd = (inputs.cwd as string) ?? context.state.cwd;
|
|
22
|
+
context.progress(1, 2, "Normalizing brief...");
|
|
23
|
+
|
|
24
|
+
const outPath = await runNormalize({ cwd });
|
|
25
|
+
|
|
26
|
+
context.progress(2, 2, "Brief normalized.");
|
|
26
27
|
context.log(`Normalized brief written to: ${outPath}`);
|
|
28
|
+
context.state.normalizedBriefPath = outPath;
|
|
29
|
+
|
|
27
30
|
return { normalizedBriefPath: outPath };
|
|
28
31
|
}
|
|
29
32
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { listArtifactDefinitions } from "../core/artifact-registry";
|
|
2
|
+
import type { SkillRegistry } from "../skill-engine/registry";
|
|
3
|
+
import { createArtifactSkill } from "./generate-artifact";
|
|
4
|
+
import { fixSkill } from "./fix";
|
|
5
|
+
import { normalizeSkill } from "./normalize";
|
|
6
|
+
import { createValidateSkill } from "./validate";
|
|
7
|
+
|
|
8
|
+
export async function registerCoreSkills(
|
|
9
|
+
registry: SkillRegistry,
|
|
10
|
+
cwd: string
|
|
11
|
+
): Promise<void> {
|
|
12
|
+
registry.register(normalizeSkill);
|
|
13
|
+
|
|
14
|
+
const definitions = await listArtifactDefinitions(cwd);
|
|
15
|
+
const artifactNames: string[] = [];
|
|
16
|
+
|
|
17
|
+
for (const def of definitions) {
|
|
18
|
+
const skill = createArtifactSkill(def.name, def.upstream);
|
|
19
|
+
registry.register(skill);
|
|
20
|
+
artifactNames.push(def.name);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const validateSkill = createValidateSkill(artifactNames);
|
|
24
|
+
registry.register(validateSkill);
|
|
25
|
+
|
|
26
|
+
registry.register(fixSkill);
|
|
27
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { runValidate } from "../core/validate";
|
|
2
|
+
import type { Skill } from "../skill-engine/types";
|
|
3
|
+
|
|
4
|
+
export function createValidateSkill(artifactTypes: string[]): Skill {
|
|
5
|
+
return {
|
|
6
|
+
manifest: {
|
|
7
|
+
name: "validate",
|
|
8
|
+
version: "2.0.0",
|
|
9
|
+
description: "Run 7-gate cross-artifact validation and generate report",
|
|
10
|
+
category: "validation",
|
|
11
|
+
depends_on: [...artifactTypes],
|
|
12
|
+
inputs: [
|
|
13
|
+
{ name: "cwd", type: "path", required: true, description: "Project working directory" }
|
|
14
|
+
],
|
|
15
|
+
outputs: [
|
|
16
|
+
{ name: "validationResult", type: "json", description: "Validation result with pass/fail and issues" }
|
|
17
|
+
],
|
|
18
|
+
tags: ["validation", "consistency"]
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
async execute(context, inputs) {
|
|
22
|
+
const cwd = (inputs.cwd as string) ?? context.state.cwd;
|
|
23
|
+
context.progress(1, 2, "Validating artifacts...");
|
|
24
|
+
|
|
25
|
+
const result = await runValidate(cwd, {});
|
|
26
|
+
|
|
27
|
+
context.progress(2, 2, `Validation ${result.pass ? "passed" : "failed"}.`);
|
|
28
|
+
context.log(`Validation ${result.pass ? "passed" : "failed"}: ${result.reportPath}`);
|
|
29
|
+
context.state.validationResult = result;
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
validationResult: {
|
|
33
|
+
pass: result.pass,
|
|
34
|
+
reportPath: result.reportPath,
|
|
35
|
+
issueCount: result.issues.length
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
package/src/skills/engine.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { UserError } from "../core/errors";
|
|
2
|
-
import type { Skill, SkillContext, SkillManifest } from "./types";
|
|
3
|
-
|
|
4
|
-
export type SkillEngine = {
|
|
5
|
-
register(skill: Skill): void;
|
|
6
|
-
getSkill(name: string): Skill | undefined;
|
|
7
|
-
listSkills(): SkillManifest[];
|
|
8
|
-
execute(name: string, context: SkillContext, inputs: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
function validateInputs(skill: Skill, inputs: Record<string, unknown>): void {
|
|
12
|
-
for (const input of skill.manifest.inputs) {
|
|
13
|
-
if (input.required && !(input.name in inputs)) {
|
|
14
|
-
throw new UserError(
|
|
15
|
-
`Skill "${skill.manifest.name}" requires input "${input.name}" (${input.description})`
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function createSkillEngine(): SkillEngine {
|
|
22
|
-
const skills = new Map<string, Skill>();
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
register(skill: Skill): void {
|
|
26
|
-
skills.set(skill.manifest.name, skill);
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
getSkill(name: string): Skill | undefined {
|
|
30
|
-
return skills.get(name);
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
listSkills(): SkillManifest[] {
|
|
34
|
-
return Array.from(skills.values()).map((s) => s.manifest);
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
async execute(
|
|
38
|
-
name: string,
|
|
39
|
-
context: SkillContext,
|
|
40
|
-
inputs: Record<string, unknown>
|
|
41
|
-
): Promise<Record<string, unknown>> {
|
|
42
|
-
const skill = skills.get(name);
|
|
43
|
-
if (!skill) {
|
|
44
|
-
const available = Array.from(skills.keys()).join(", ");
|
|
45
|
-
throw new UserError(`Unknown skill: "${name}". Available: ${available}`);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
validateInputs(skill, inputs);
|
|
49
|
-
return skill.execute(context, inputs);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
let globalEngine: SkillEngine | null = null;
|
|
55
|
-
|
|
56
|
-
export function getGlobalSkillEngine(): SkillEngine {
|
|
57
|
-
if (!globalEngine) {
|
|
58
|
-
globalEngine = createSkillEngine();
|
|
59
|
-
loadBuiltinSkills(globalEngine);
|
|
60
|
-
}
|
|
61
|
-
return globalEngine;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function resetGlobalSkillEngine(): void {
|
|
65
|
-
globalEngine = null;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function loadBuiltinSkills(engine: SkillEngine): void {
|
|
69
|
-
// Lazy-load to avoid circular dependencies
|
|
70
|
-
try {
|
|
71
|
-
const { normalizeSkill } = require("./normalize-skill") as { normalizeSkill: Skill };
|
|
72
|
-
engine.register(normalizeSkill);
|
|
73
|
-
} catch { /* skill not available */ }
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
const { validateSkill } = require("./validate-skill") as { validateSkill: Skill };
|
|
77
|
-
engine.register(validateSkill);
|
|
78
|
-
} catch { /* skill not available */ }
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
const { fixSkill } = require("./fix-skill") as { fixSkill: Skill };
|
|
82
|
-
engine.register(fixSkill);
|
|
83
|
-
} catch { /* skill not available */ }
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
const { generateArtifactSkill } = require("./generate-artifact-skill") as { generateArtifactSkill: Skill };
|
|
87
|
-
engine.register(generateArtifactSkill);
|
|
88
|
-
} catch { /* skill not available */ }
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
const { generatePipelineSkill } = require("./generate-pipeline-skill") as { generatePipelineSkill: Skill };
|
|
92
|
-
engine.register(generatePipelineSkill);
|
|
93
|
-
} catch { /* skill not available */ }
|
|
94
|
-
}
|
package/src/skills/fix-skill.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { runFix } from "../core/fix";
|
|
2
|
-
import type { Skill } from "./types";
|
|
3
|
-
|
|
4
|
-
export const fixSkill: Skill = {
|
|
5
|
-
manifest: {
|
|
6
|
-
name: "fix",
|
|
7
|
-
description: "Auto-regenerate artifacts that failed validation with backup and rollback",
|
|
8
|
-
category: "validation",
|
|
9
|
-
inputs: [
|
|
10
|
-
{ name: "cwd", type: "path", required: true, description: "Project working directory" },
|
|
11
|
-
{ name: "agent", type: "string", required: false, description: "Agent profile name" },
|
|
12
|
-
{ name: "strict", type: "boolean", required: false, description: "Treat warnings as errors" },
|
|
13
|
-
{ name: "dryRun", type: "boolean", required: false, description: "Preview without applying" }
|
|
14
|
-
],
|
|
15
|
-
outputs: [
|
|
16
|
-
{ name: "applied", type: "string", description: "Whether fix was applied" },
|
|
17
|
-
{ name: "finalPass", type: "string", description: "Whether validation passed after fix" },
|
|
18
|
-
{ name: "reportPath", type: "path", description: "Path to validation report" }
|
|
19
|
-
]
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
async execute(context, inputs): Promise<Record<string, unknown>> {
|
|
23
|
-
const cwd = (inputs.cwd as string) ?? context.cwd;
|
|
24
|
-
const result = await runFix({
|
|
25
|
-
cwd,
|
|
26
|
-
agent: (inputs.agent as string) ?? context.agent,
|
|
27
|
-
strict: Boolean(inputs.strict),
|
|
28
|
-
dryRun: Boolean(inputs.dryRun),
|
|
29
|
-
log: context.log
|
|
30
|
-
});
|
|
31
|
-
return {
|
|
32
|
-
applied: result.applied,
|
|
33
|
-
finalPass: result.finalPass,
|
|
34
|
-
reportPath: result.reportPath,
|
|
35
|
-
targetCount: result.proposal.targets.length
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
};
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { generateArtifact } from "../core/artifacts";
|
|
2
|
-
import type { Skill } from "./types";
|
|
3
|
-
|
|
4
|
-
export const generateArtifactSkill: Skill = {
|
|
5
|
-
manifest: {
|
|
6
|
-
name: "generate-artifact",
|
|
7
|
-
description: "Generate a single artifact (PRD, workflow, wireframe, stories, techspec)",
|
|
8
|
-
category: "artifact",
|
|
9
|
-
inputs: [
|
|
10
|
-
{ name: "cwd", type: "path", required: true, description: "Project working directory" },
|
|
11
|
-
{ name: "artifactType", type: "string", required: true, description: "Artifact type to generate" },
|
|
12
|
-
{ name: "from", type: "path", required: false, description: "Override path to normalized-brief.json" },
|
|
13
|
-
{ name: "out", type: "path", required: false, description: "Override output path" }
|
|
14
|
-
],
|
|
15
|
-
outputs: [
|
|
16
|
-
{ name: "filePath", type: "path", description: "Path to generated artifact" }
|
|
17
|
-
]
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
async execute(context, inputs): Promise<Record<string, unknown>> {
|
|
21
|
-
const cwd = (inputs.cwd as string) ?? context.cwd;
|
|
22
|
-
const filePath = await generateArtifact({
|
|
23
|
-
artifactType: inputs.artifactType as string,
|
|
24
|
-
cwd,
|
|
25
|
-
normalizedBriefOverride: inputs.from as string | undefined,
|
|
26
|
-
outPath: inputs.out as string | undefined,
|
|
27
|
-
agent: context.agent
|
|
28
|
-
});
|
|
29
|
-
context.log(`${(inputs.artifactType as string).toUpperCase()} generated: ${filePath}`);
|
|
30
|
-
return { filePath };
|
|
31
|
-
}
|
|
32
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { listArtifactTypes } from "../core/artifact-registry";
|
|
2
|
-
import { generateArtifact } from "../core/artifacts";
|
|
3
|
-
import { runNormalize } from "../core/normalize";
|
|
4
|
-
import { runValidate } from "../core/validate";
|
|
5
|
-
import type { Skill } from "./types";
|
|
6
|
-
|
|
7
|
-
export const generatePipelineSkill: Skill = {
|
|
8
|
-
manifest: {
|
|
9
|
-
name: "generate-pipeline",
|
|
10
|
-
description: "Run end-to-end pipeline: normalize → generate all artifacts → validate",
|
|
11
|
-
category: "core",
|
|
12
|
-
inputs: [
|
|
13
|
-
{ name: "cwd", type: "path", required: true, description: "Project working directory" },
|
|
14
|
-
{ name: "strict", type: "boolean", required: false, description: "Treat warnings as errors" }
|
|
15
|
-
],
|
|
16
|
-
outputs: [
|
|
17
|
-
{ name: "pass", type: "string", description: "Whether validation passed" },
|
|
18
|
-
{ name: "reportPath", type: "path", description: "Path to validation report" },
|
|
19
|
-
{ name: "artifactCount", type: "string", description: "Number of artifacts generated" }
|
|
20
|
-
]
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
async execute(context, inputs): Promise<Record<string, unknown>> {
|
|
24
|
-
const cwd = (inputs.cwd as string) ?? context.cwd;
|
|
25
|
-
|
|
26
|
-
const normalizedPath = await runNormalize({ cwd });
|
|
27
|
-
context.log(`Normalized brief: ${normalizedPath}`);
|
|
28
|
-
|
|
29
|
-
const artifactTypes = await listArtifactTypes(cwd);
|
|
30
|
-
for (const type of artifactTypes) {
|
|
31
|
-
const file = await generateArtifact({
|
|
32
|
-
artifactType: type,
|
|
33
|
-
cwd,
|
|
34
|
-
normalizedBriefOverride: normalizedPath,
|
|
35
|
-
agent: context.agent
|
|
36
|
-
});
|
|
37
|
-
context.log(`${type.toUpperCase()} generated: ${file}`);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const result = await runValidate(cwd, { strict: Boolean(inputs.strict) });
|
|
41
|
-
context.log(`Validation ${result.pass ? "passed" : "failed"}: ${result.reportPath}`);
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
pass: result.pass,
|
|
45
|
-
reportPath: result.reportPath,
|
|
46
|
-
artifactCount: artifactTypes.length
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
};
|
package/src/skills/types.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export type SkillInput = {
|
|
2
|
-
name: string;
|
|
3
|
-
type: "path" | "string" | "boolean" | "json";
|
|
4
|
-
required: boolean;
|
|
5
|
-
description: string;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export type SkillOutput = {
|
|
9
|
-
name: string;
|
|
10
|
-
type: "path" | "string" | "json";
|
|
11
|
-
description: string;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export type SkillManifest = {
|
|
15
|
-
name: string;
|
|
16
|
-
description: string;
|
|
17
|
-
category: "core" | "artifact" | "validation" | "custom";
|
|
18
|
-
inputs: SkillInput[];
|
|
19
|
-
outputs: SkillOutput[];
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export type SkillContext = {
|
|
23
|
-
cwd: string;
|
|
24
|
-
log: (message: string) => void;
|
|
25
|
-
agent?: string;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export type SkillFunction = (
|
|
29
|
-
context: SkillContext,
|
|
30
|
-
inputs: Record<string, unknown>
|
|
31
|
-
) => Promise<Record<string, unknown>>;
|
|
32
|
-
|
|
33
|
-
export type Skill = {
|
|
34
|
-
manifest: SkillManifest;
|
|
35
|
-
execute: SkillFunction;
|
|
36
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { runValidate } from "../core/validate";
|
|
2
|
-
import type { Skill } from "./types";
|
|
3
|
-
|
|
4
|
-
export const validateSkill: Skill = {
|
|
5
|
-
manifest: {
|
|
6
|
-
name: "validate",
|
|
7
|
-
description: "Run cross-artifact validation and generate a report",
|
|
8
|
-
category: "validation",
|
|
9
|
-
inputs: [
|
|
10
|
-
{ name: "cwd", type: "path", required: true, description: "Project working directory" },
|
|
11
|
-
{ name: "strict", type: "boolean", required: false, description: "Treat warnings as errors" },
|
|
12
|
-
{ name: "report", type: "path", required: false, description: "Override report output path" }
|
|
13
|
-
],
|
|
14
|
-
outputs: [
|
|
15
|
-
{ name: "pass", type: "string", description: "Whether validation passed" },
|
|
16
|
-
{ name: "reportPath", type: "path", description: "Path to validation report" }
|
|
17
|
-
]
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
async execute(context, inputs): Promise<Record<string, unknown>> {
|
|
21
|
-
const cwd = (inputs.cwd as string) ?? context.cwd;
|
|
22
|
-
const result = await runValidate(cwd, {
|
|
23
|
-
strict: Boolean(inputs.strict),
|
|
24
|
-
report: inputs.report as string | undefined
|
|
25
|
-
});
|
|
26
|
-
context.log(`Validation ${result.pass ? "passed" : "failed"}: ${result.reportPath}`);
|
|
27
|
-
return { pass: result.pass, reportPath: result.reportPath, issueCount: result.issues.length };
|
|
28
|
-
}
|
|
29
|
-
};
|