@shahmarasy/prodo 0.1.4 → 0.1.6

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 (205) hide show
  1. package/README.md +201 -97
  2. package/bin/prodo.cjs +6 -6
  3. package/dist/agents/agent-registry.d.ts +13 -0
  4. package/dist/agents/agent-registry.js +79 -0
  5. package/dist/agents/anthropic/index.d.ts +9 -0
  6. package/dist/agents/anthropic/index.js +55 -0
  7. package/dist/agents/base.d.ts +25 -0
  8. package/dist/agents/base.js +71 -0
  9. package/dist/agents/google/index.d.ts +9 -0
  10. package/dist/agents/google/index.js +53 -0
  11. package/dist/agents/mock/index.d.ts +11 -0
  12. package/dist/agents/mock/index.js +26 -0
  13. package/dist/agents/openai/index.d.ts +9 -0
  14. package/dist/agents/openai/index.js +57 -0
  15. package/dist/agents/system-prompts.d.ts +3 -0
  16. package/dist/agents/system-prompts.js +32 -0
  17. package/dist/cli/agent-command-installer.d.ts +4 -0
  18. package/dist/cli/agent-command-installer.js +148 -0
  19. package/dist/cli/agent-ids.d.ts +15 -0
  20. package/dist/cli/agent-ids.js +49 -0
  21. package/dist/cli/doctor.d.ts +1 -0
  22. package/dist/cli/doctor.js +144 -0
  23. package/dist/cli/fix-tui.d.ts +4 -0
  24. package/dist/cli/fix-tui.js +79 -0
  25. package/dist/cli/index.d.ts +9 -0
  26. package/dist/cli/index.js +467 -0
  27. package/dist/cli/init-tui.d.ts +23 -0
  28. package/dist/cli/init-tui.js +183 -0
  29. package/dist/cli/init.d.ts +12 -0
  30. package/dist/cli/init.js +335 -0
  31. package/dist/cli/normalize-interactive.d.ts +8 -0
  32. package/dist/cli/normalize-interactive.js +167 -0
  33. package/dist/cli/preset-loader.d.ts +4 -0
  34. package/dist/cli/preset-loader.js +210 -0
  35. package/dist/core/artifact-registry.d.ts +11 -0
  36. package/dist/core/artifact-registry.js +49 -0
  37. package/dist/core/artifacts.d.ts +10 -0
  38. package/dist/core/artifacts.js +892 -0
  39. package/dist/core/clean.d.ts +10 -0
  40. package/dist/core/clean.js +74 -0
  41. package/dist/core/consistency.d.ts +8 -0
  42. package/dist/core/consistency.js +328 -0
  43. package/dist/core/constants.d.ts +7 -0
  44. package/dist/core/constants.js +64 -0
  45. package/dist/core/errors.d.ts +3 -0
  46. package/dist/core/errors.js +10 -0
  47. package/dist/core/fix.d.ts +31 -0
  48. package/dist/core/fix.js +188 -0
  49. package/dist/core/hook-executor.d.ts +1 -0
  50. package/dist/core/hook-executor.js +175 -0
  51. package/dist/core/markdown.d.ts +16 -0
  52. package/dist/core/markdown.js +81 -0
  53. package/dist/core/normalize.d.ts +8 -0
  54. package/dist/core/normalize.js +125 -0
  55. package/dist/core/normalized-brief.d.ts +48 -0
  56. package/dist/core/normalized-brief.js +182 -0
  57. package/dist/core/output-index.d.ts +13 -0
  58. package/dist/core/output-index.js +55 -0
  59. package/dist/core/paths.d.ts +17 -0
  60. package/dist/core/paths.js +80 -0
  61. package/dist/core/project-config.d.ts +14 -0
  62. package/dist/core/project-config.js +69 -0
  63. package/dist/core/registry.d.ts +13 -0
  64. package/dist/core/registry.js +115 -0
  65. package/dist/core/settings.d.ts +8 -0
  66. package/dist/core/settings.js +43 -0
  67. package/dist/core/template-engine.d.ts +3 -0
  68. package/dist/core/template-engine.js +43 -0
  69. package/dist/core/template-resolver.d.ts +15 -0
  70. package/dist/core/template-resolver.js +46 -0
  71. package/dist/core/templates.d.ts +33 -0
  72. package/dist/core/templates.js +440 -0
  73. package/dist/core/terminology.d.ts +21 -0
  74. package/dist/core/terminology.js +143 -0
  75. package/dist/core/tracing.d.ts +21 -0
  76. package/dist/core/tracing.js +74 -0
  77. package/dist/core/types.d.ts +35 -0
  78. package/dist/core/types.js +5 -0
  79. package/dist/core/utils.d.ts +7 -0
  80. package/dist/core/utils.js +66 -0
  81. package/dist/core/validate.d.ts +10 -0
  82. package/dist/core/validate.js +226 -0
  83. package/dist/core/validator.d.ts +5 -0
  84. package/dist/core/validator.js +76 -0
  85. package/dist/core/version.d.ts +1 -0
  86. package/dist/core/version.js +30 -0
  87. package/dist/core/workflow-commands.d.ts +7 -0
  88. package/dist/core/workflow-commands.js +29 -0
  89. package/dist/i18n/en.json +45 -0
  90. package/dist/i18n/index.d.ts +5 -0
  91. package/dist/i18n/index.js +63 -0
  92. package/dist/i18n/tr.json +45 -0
  93. package/dist/providers/index.d.ts +2 -1
  94. package/dist/providers/index.js +20 -6
  95. package/dist/providers/mock-provider.d.ts +1 -1
  96. package/dist/providers/mock-provider.js +12 -11
  97. package/dist/providers/openai-provider.d.ts +1 -1
  98. package/dist/providers/openai-provider.js +13 -13
  99. package/dist/skill-engine/context.d.ts +7 -0
  100. package/dist/skill-engine/context.js +76 -0
  101. package/dist/skill-engine/discovery.d.ts +2 -0
  102. package/dist/skill-engine/discovery.js +52 -0
  103. package/dist/skill-engine/graph.d.ts +4 -0
  104. package/dist/skill-engine/graph.js +114 -0
  105. package/dist/skill-engine/index.d.ts +11 -0
  106. package/dist/skill-engine/index.js +49 -0
  107. package/dist/skill-engine/pipeline.d.ts +9 -0
  108. package/dist/skill-engine/pipeline.js +84 -0
  109. package/dist/skill-engine/registry.d.ts +12 -0
  110. package/dist/skill-engine/registry.js +74 -0
  111. package/dist/skill-engine/types.d.ts +66 -0
  112. package/dist/skill-engine/types.js +2 -0
  113. package/dist/skill-engine/validator.d.ts +4 -0
  114. package/dist/skill-engine/validator.js +90 -0
  115. package/dist/skills/engine.d.ts +10 -0
  116. package/dist/skills/engine.js +75 -0
  117. package/dist/skills/fix-skill.d.ts +2 -0
  118. package/dist/skills/fix-skill.js +38 -0
  119. package/dist/skills/fix.d.ts +2 -0
  120. package/dist/skills/fix.js +41 -0
  121. package/dist/skills/generate-artifact-skill.d.ts +2 -0
  122. package/dist/skills/generate-artifact-skill.js +32 -0
  123. package/dist/skills/generate-artifact.d.ts +2 -0
  124. package/dist/skills/generate-artifact.js +42 -0
  125. package/dist/skills/generate-pipeline-skill.d.ts +2 -0
  126. package/dist/skills/generate-pipeline-skill.js +45 -0
  127. package/dist/skills/normalize-skill.d.ts +2 -0
  128. package/dist/skills/normalize-skill.js +29 -0
  129. package/dist/skills/normalize.d.ts +2 -0
  130. package/dist/skills/normalize.js +29 -0
  131. package/dist/skills/register-core.d.ts +2 -0
  132. package/dist/skills/register-core.js +21 -0
  133. package/dist/skills/types.d.ts +28 -0
  134. package/dist/skills/types.js +2 -0
  135. package/dist/skills/validate-skill.d.ts +2 -0
  136. package/dist/skills/validate-skill.js +29 -0
  137. package/dist/skills/validate.d.ts +2 -0
  138. package/dist/skills/validate.js +37 -0
  139. package/package.json +72 -45
  140. package/src/agents/agent-registry.ts +93 -0
  141. package/src/agents/anthropic/index.ts +86 -0
  142. package/src/agents/anthropic/manifest.json +7 -0
  143. package/src/agents/base.ts +77 -0
  144. package/src/agents/google/index.ts +79 -0
  145. package/src/agents/google/manifest.json +7 -0
  146. package/src/agents/mock/index.ts +32 -0
  147. package/src/agents/mock/manifest.json +7 -0
  148. package/src/agents/openai/index.ts +83 -0
  149. package/src/agents/openai/manifest.json +7 -0
  150. package/src/agents/system-prompts.ts +35 -0
  151. package/src/{agent-command-installer.ts → cli/agent-command-installer.ts} +164 -164
  152. package/src/{agents.ts → cli/agent-ids.ts} +58 -58
  153. package/src/{doctor.ts → cli/doctor.ts} +157 -137
  154. package/src/cli/fix-tui.ts +111 -0
  155. package/src/{cli.ts → cli/index.ts} +463 -410
  156. package/src/{init-tui.ts → cli/init-tui.ts} +49 -37
  157. package/src/{init.ts → cli/init.ts} +399 -398
  158. package/src/cli/normalize-interactive.ts +241 -0
  159. package/src/{preset-loader.ts → cli/preset-loader.ts} +237 -237
  160. package/src/{artifact-registry.ts → core/artifact-registry.ts} +69 -69
  161. package/src/{artifacts.ts → core/artifacts.ts} +1081 -1072
  162. package/src/core/clean.ts +88 -0
  163. package/src/{consistency.ts → core/consistency.ts} +374 -303
  164. package/src/{constants.ts → core/constants.ts} +72 -72
  165. package/src/{errors.ts → core/errors.ts} +7 -7
  166. package/src/core/fix.ts +253 -0
  167. package/src/{hook-executor.ts → core/hook-executor.ts} +196 -196
  168. package/src/{markdown.ts → core/markdown.ts} +93 -73
  169. package/src/{normalize.ts → core/normalize.ts} +145 -137
  170. package/src/{normalized-brief.ts → core/normalized-brief.ts} +227 -206
  171. package/src/{output-index.ts → core/output-index.ts} +59 -59
  172. package/src/{paths.ts → core/paths.ts} +75 -71
  173. package/src/{project-config.ts → core/project-config.ts} +78 -78
  174. package/src/{registry.ts → core/registry.ts} +119 -119
  175. package/src/{settings.ts → core/settings.ts} +8 -2
  176. package/src/core/template-engine.ts +45 -0
  177. package/src/{template-resolver.ts → core/template-resolver.ts} +54 -54
  178. package/src/{templates.ts → core/templates.ts} +452 -452
  179. package/src/core/terminology.ts +177 -0
  180. package/src/core/tracing.ts +110 -0
  181. package/src/{types.ts → core/types.ts} +46 -46
  182. package/src/{utils.ts → core/utils.ts} +64 -64
  183. package/src/{validate.ts → core/validate.ts} +252 -246
  184. package/src/{validator.ts → core/validator.ts} +92 -92
  185. package/src/{version.ts → core/version.ts} +24 -24
  186. package/src/{workflow-commands.ts → core/workflow-commands.ts} +32 -32
  187. package/src/i18n/en.json +45 -0
  188. package/src/i18n/index.ts +58 -0
  189. package/src/i18n/tr.json +45 -0
  190. package/src/providers/index.ts +29 -12
  191. package/src/providers/mock-provider.ts +200 -199
  192. package/src/providers/openai-provider.ts +88 -88
  193. package/src/skill-engine/context.ts +90 -0
  194. package/src/skill-engine/discovery.ts +57 -0
  195. package/src/skill-engine/graph.ts +136 -0
  196. package/src/skill-engine/index.ts +55 -0
  197. package/src/skill-engine/pipeline.ts +112 -0
  198. package/src/skill-engine/registry.ts +75 -0
  199. package/src/skill-engine/types.ts +81 -0
  200. package/src/skill-engine/validator.ts +135 -0
  201. package/src/skills/fix.ts +45 -0
  202. package/src/skills/generate-artifact.ts +48 -0
  203. package/src/skills/normalize.ts +32 -0
  204. package/src/skills/register-core.ts +27 -0
  205. package/src/skills/validate.ts +40 -0
@@ -0,0 +1,135 @@
1
+ import { fileExists } from "../core/utils";
2
+ import type { SkillError, SkillManifest } from "./types";
3
+
4
+ function makeError(
5
+ skillName: string,
6
+ phase: SkillError["phase"],
7
+ message: string,
8
+ hints: string[] = []
9
+ ): SkillError {
10
+ return {
11
+ skillName,
12
+ phase,
13
+ message,
14
+ recoveryHints: hints
15
+ };
16
+ }
17
+
18
+ function checkType(value: unknown, expectedType: string, fieldName: string): string | null {
19
+ switch (expectedType) {
20
+ case "string":
21
+ if (typeof value !== "string") return `"${fieldName}" must be a string, got ${typeof value}`;
22
+ return null;
23
+
24
+ case "path":
25
+ if (typeof value !== "string") return `"${fieldName}" must be a path (string), got ${typeof value}`;
26
+ return null;
27
+
28
+ case "boolean":
29
+ if (typeof value !== "boolean") return `"${fieldName}" must be a boolean, got ${typeof value}`;
30
+ return null;
31
+
32
+ case "number":
33
+ if (typeof value !== "number" || !Number.isFinite(value)) {
34
+ return `"${fieldName}" must be a finite number, got ${typeof value}`;
35
+ }
36
+ return null;
37
+
38
+ case "json":
39
+ if (typeof value === "string") {
40
+ try {
41
+ JSON.parse(value);
42
+ } catch {
43
+ return `"${fieldName}" must be valid JSON string`;
44
+ }
45
+ }
46
+ return null;
47
+
48
+ default:
49
+ return null;
50
+ }
51
+ }
52
+
53
+ export function validateInputs(
54
+ manifest: SkillManifest,
55
+ inputs: Record<string, unknown>
56
+ ): SkillError | null {
57
+ for (const input of manifest.inputs) {
58
+ const value = inputs[input.name];
59
+
60
+ if (input.required && (value === undefined || value === null)) {
61
+ if (input.default !== undefined) continue;
62
+ return makeError(
63
+ manifest.name,
64
+ "input_validation",
65
+ `Required input "${input.name}" is missing`,
66
+ [`Provide "${input.name}" (${input.type}): ${input.description ?? ""}`]
67
+ );
68
+ }
69
+
70
+ if (value === undefined || value === null) continue;
71
+
72
+ const typeError = checkType(value, input.type, input.name);
73
+ if (typeError) {
74
+ return makeError(
75
+ manifest.name,
76
+ "input_validation",
77
+ typeError,
78
+ [`Expected type: ${input.type}`]
79
+ );
80
+ }
81
+ }
82
+
83
+ return null;
84
+ }
85
+
86
+ export async function validateInputPaths(
87
+ manifest: SkillManifest,
88
+ inputs: Record<string, unknown>
89
+ ): Promise<SkillError | null> {
90
+ for (const input of manifest.inputs) {
91
+ if (input.type !== "path") continue;
92
+ const value = inputs[input.name];
93
+ if (typeof value !== "string") continue;
94
+
95
+ if (input.required && !(await fileExists(value))) {
96
+ return makeError(
97
+ manifest.name,
98
+ "input_validation",
99
+ `Path "${input.name}" does not exist: ${value}`,
100
+ [`Ensure the file or directory exists: ${value}`]
101
+ );
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+
107
+ export function validateOutputs(
108
+ manifest: SkillManifest,
109
+ outputs: Record<string, unknown>
110
+ ): SkillError | null {
111
+ for (const output of manifest.outputs) {
112
+ const value = outputs[output.name];
113
+
114
+ if (value === undefined || value === null) {
115
+ return makeError(
116
+ manifest.name,
117
+ "output_validation",
118
+ `Expected output "${output.name}" was not produced`,
119
+ [`Skill "${manifest.name}" should return "${output.name}" (${output.type})`]
120
+ );
121
+ }
122
+
123
+ const typeError = checkType(value, output.type, output.name);
124
+ if (typeError) {
125
+ return makeError(
126
+ manifest.name,
127
+ "output_validation",
128
+ typeError,
129
+ [`Skill "${manifest.name}" returned wrong type for "${output.name}"`]
130
+ );
131
+ }
132
+ }
133
+
134
+ return null;
135
+ }
@@ -0,0 +1,45 @@
1
+ import { runFix } from "../core/fix";
2
+ import type { Skill } from "../skill-engine/types";
3
+
4
+ export const fixSkill: Skill = {
5
+ manifest: {
6
+ name: "fix",
7
+ version: "2.0.0",
8
+ description: "Auto-regenerate failing artifacts with backup, proposal, and validation",
9
+ category: "validation",
10
+ depends_on: [],
11
+ inputs: [
12
+ { name: "cwd", type: "path", required: true, description: "Project working directory" }
13
+ ],
14
+ outputs: [
15
+ { name: "validationResult", type: "json", description: "Final validation result after fix" }
16
+ ],
17
+ tags: ["fix", "repair", "validation"]
18
+ },
19
+
20
+ async execute(context, inputs) {
21
+ const cwd = (inputs.cwd as string) ?? context.state.cwd;
22
+ context.progress(1, 3, "Running fix pipeline...");
23
+
24
+ const result = await runFix({
25
+ cwd,
26
+ agent: context.agent,
27
+ log: context.log
28
+ });
29
+
30
+ context.progress(3, 3, result.finalPass ? "Fix complete." : "Fix applied, issues remain.");
31
+
32
+ context.state.validationResult = result.finalPass
33
+ ? { pass: true, reportPath: result.reportPath, issues: [] }
34
+ : undefined;
35
+
36
+ return {
37
+ validationResult: {
38
+ pass: result.finalPass,
39
+ reportPath: result.reportPath,
40
+ applied: result.applied,
41
+ targetCount: result.proposal.targets.length
42
+ }
43
+ };
44
+ }
45
+ };
@@ -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
+ }
@@ -0,0 +1,32 @@
1
+ import { runNormalize } from "../core/normalize";
2
+ import type { Skill } from "../skill-engine/types";
3
+
4
+ export const normalizeSkill: Skill = {
5
+ manifest: {
6
+ name: "normalize",
7
+ version: "2.0.0",
8
+ description: "Normalize a product brief into structured JSON with contracts and confidence scores",
9
+ category: "core",
10
+ depends_on: [],
11
+ inputs: [
12
+ { name: "cwd", type: "path", required: true, description: "Project working directory" }
13
+ ],
14
+ outputs: [
15
+ { name: "normalizedBriefPath", type: "path", description: "Path to normalized-brief.json" }
16
+ ],
17
+ tags: ["brief", "normalization"]
18
+ },
19
+
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.");
27
+ context.log(`Normalized brief written to: ${outPath}`);
28
+ context.state.normalizedBriefPath = outPath;
29
+
30
+ return { normalizedBriefPath: outPath };
31
+ }
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
+ }