@shahmarasy/prodo 0.1.3 → 0.1.5

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/agents.js +4 -2
  18. package/dist/artifacts.d.ts +1 -0
  19. package/dist/artifacts.js +265 -31
  20. package/dist/cli/agent-command-installer.d.ts +4 -0
  21. package/dist/cli/agent-command-installer.js +148 -0
  22. package/dist/cli/agent-ids.d.ts +15 -0
  23. package/dist/cli/agent-ids.js +49 -0
  24. package/dist/cli/doctor.d.ts +1 -0
  25. package/dist/cli/doctor.js +144 -0
  26. package/dist/cli/fix-tui.d.ts +4 -0
  27. package/dist/cli/fix-tui.js +79 -0
  28. package/dist/cli/index.d.ts +9 -0
  29. package/dist/cli/index.js +465 -0
  30. package/dist/cli/init-tui.d.ts +23 -0
  31. package/dist/cli/init-tui.js +176 -0
  32. package/dist/cli/init.d.ts +11 -0
  33. package/dist/cli/init.js +334 -0
  34. package/dist/cli/normalize-interactive.d.ts +8 -0
  35. package/dist/cli/normalize-interactive.js +167 -0
  36. package/dist/cli/preset-loader.d.ts +4 -0
  37. package/dist/cli/preset-loader.js +210 -0
  38. package/dist/cli.js +80 -3
  39. package/dist/core/artifact-registry.d.ts +11 -0
  40. package/dist/core/artifact-registry.js +49 -0
  41. package/dist/core/artifacts.d.ts +10 -0
  42. package/dist/core/artifacts.js +892 -0
  43. package/dist/core/clean.d.ts +10 -0
  44. package/dist/core/clean.js +74 -0
  45. package/dist/core/consistency.d.ts +8 -0
  46. package/dist/core/consistency.js +328 -0
  47. package/dist/core/constants.d.ts +7 -0
  48. package/dist/core/constants.js +64 -0
  49. package/dist/core/errors.d.ts +3 -0
  50. package/dist/core/errors.js +10 -0
  51. package/dist/core/fix.d.ts +31 -0
  52. package/dist/core/fix.js +188 -0
  53. package/dist/core/hook-executor.d.ts +1 -0
  54. package/dist/core/hook-executor.js +175 -0
  55. package/dist/core/markdown.d.ts +16 -0
  56. package/dist/core/markdown.js +81 -0
  57. package/dist/core/normalize.d.ts +8 -0
  58. package/dist/core/normalize.js +125 -0
  59. package/dist/core/normalized-brief.d.ts +48 -0
  60. package/dist/core/normalized-brief.js +182 -0
  61. package/dist/core/output-index.d.ts +13 -0
  62. package/dist/core/output-index.js +55 -0
  63. package/dist/core/paths.d.ts +17 -0
  64. package/dist/core/paths.js +80 -0
  65. package/dist/core/project-config.d.ts +14 -0
  66. package/dist/core/project-config.js +69 -0
  67. package/dist/core/registry.d.ts +13 -0
  68. package/dist/core/registry.js +115 -0
  69. package/dist/core/settings.d.ts +7 -0
  70. package/dist/core/settings.js +35 -0
  71. package/dist/core/template-engine.d.ts +3 -0
  72. package/dist/core/template-engine.js +43 -0
  73. package/dist/core/template-resolver.d.ts +15 -0
  74. package/dist/core/template-resolver.js +46 -0
  75. package/dist/core/templates.d.ts +33 -0
  76. package/dist/core/templates.js +440 -0
  77. package/dist/core/terminology.d.ts +21 -0
  78. package/dist/core/terminology.js +143 -0
  79. package/dist/core/tracing.d.ts +21 -0
  80. package/dist/core/tracing.js +74 -0
  81. package/dist/core/types.d.ts +35 -0
  82. package/dist/core/types.js +5 -0
  83. package/dist/core/utils.d.ts +7 -0
  84. package/dist/core/utils.js +66 -0
  85. package/dist/core/validate.d.ts +10 -0
  86. package/dist/core/validate.js +226 -0
  87. package/dist/core/validator.d.ts +5 -0
  88. package/dist/core/validator.js +76 -0
  89. package/dist/core/version.d.ts +1 -0
  90. package/dist/core/version.js +30 -0
  91. package/dist/core/workflow-commands.d.ts +7 -0
  92. package/dist/core/workflow-commands.js +29 -0
  93. package/dist/i18n/en.json +45 -0
  94. package/dist/i18n/index.d.ts +5 -0
  95. package/dist/i18n/index.js +63 -0
  96. package/dist/i18n/tr.json +45 -0
  97. package/dist/init-tui.d.ts +3 -0
  98. package/dist/init-tui.js +28 -1
  99. package/dist/init.d.ts +1 -0
  100. package/dist/init.js +9 -3
  101. package/dist/normalize.js +55 -7
  102. package/dist/providers/index.d.ts +2 -1
  103. package/dist/providers/index.js +20 -6
  104. package/dist/providers/mock-provider.d.ts +1 -1
  105. package/dist/providers/mock-provider.js +7 -6
  106. package/dist/providers/openai-provider.d.ts +1 -1
  107. package/dist/providers/openai-provider.js +3 -2
  108. package/dist/settings.d.ts +1 -0
  109. package/dist/settings.js +2 -1
  110. package/dist/skills/engine.d.ts +10 -0
  111. package/dist/skills/engine.js +75 -0
  112. package/dist/skills/fix-skill.d.ts +2 -0
  113. package/dist/skills/fix-skill.js +38 -0
  114. package/dist/skills/generate-artifact-skill.d.ts +2 -0
  115. package/dist/skills/generate-artifact-skill.js +32 -0
  116. package/dist/skills/generate-pipeline-skill.d.ts +2 -0
  117. package/dist/skills/generate-pipeline-skill.js +45 -0
  118. package/dist/skills/normalize-skill.d.ts +2 -0
  119. package/dist/skills/normalize-skill.js +29 -0
  120. package/dist/skills/types.d.ts +28 -0
  121. package/dist/skills/types.js +2 -0
  122. package/dist/skills/validate-skill.d.ts +2 -0
  123. package/dist/skills/validate-skill.js +29 -0
  124. package/dist/templates.d.ts +1 -1
  125. package/dist/templates.js +2 -0
  126. package/dist/utils.d.ts +1 -0
  127. package/dist/utils.js +13 -0
  128. package/dist/validator.js +0 -4
  129. package/dist/workflow-commands.js +2 -1
  130. package/package.json +74 -45
  131. package/presets/fintech/preset.json +48 -1
  132. package/presets/fintech/prompts/prd.md +99 -2
  133. package/presets/marketplace/preset.json +51 -1
  134. package/presets/marketplace/prompts/prd.md +140 -2
  135. package/presets/saas/preset.json +53 -1
  136. package/presets/saas/prompts/prd.md +150 -2
  137. package/src/agents/agent-registry.ts +93 -0
  138. package/src/agents/anthropic/index.ts +86 -0
  139. package/src/agents/anthropic/manifest.json +7 -0
  140. package/src/agents/base.ts +77 -0
  141. package/src/agents/google/index.ts +79 -0
  142. package/src/agents/google/manifest.json +7 -0
  143. package/src/agents/mock/index.ts +32 -0
  144. package/src/agents/mock/manifest.json +7 -0
  145. package/src/agents/openai/index.ts +83 -0
  146. package/src/agents/openai/manifest.json +7 -0
  147. package/src/agents/system-prompts.ts +35 -0
  148. package/src/{agent-command-installer.ts → cli/agent-command-installer.ts} +164 -164
  149. package/src/{agents.ts → cli/agent-ids.ts} +58 -56
  150. package/src/{doctor.ts → cli/doctor.ts} +157 -137
  151. package/src/cli/fix-tui.ts +111 -0
  152. package/src/{cli.ts → cli/index.ts} +459 -319
  153. package/src/{init-tui.ts → cli/init-tui.ts} +208 -179
  154. package/src/{init.ts → cli/init.ts} +398 -391
  155. package/src/cli/normalize-interactive.ts +241 -0
  156. package/src/{preset-loader.ts → cli/preset-loader.ts} +237 -237
  157. package/src/{artifact-registry.ts → core/artifact-registry.ts} +69 -69
  158. package/src/{artifacts.ts → core/artifacts.ts} +1081 -777
  159. package/src/core/clean.ts +88 -0
  160. package/src/{consistency.ts → core/consistency.ts} +374 -303
  161. package/src/{constants.ts → core/constants.ts} +72 -72
  162. package/src/{errors.ts → core/errors.ts} +7 -7
  163. package/src/core/fix.ts +253 -0
  164. package/src/{hook-executor.ts → core/hook-executor.ts} +196 -196
  165. package/src/{markdown.ts → core/markdown.ts} +93 -73
  166. package/src/core/normalize.ts +145 -0
  167. package/src/{normalized-brief.ts → core/normalized-brief.ts} +227 -206
  168. package/src/{output-index.ts → core/output-index.ts} +59 -59
  169. package/src/{paths.ts → core/paths.ts} +75 -71
  170. package/src/{project-config.ts → core/project-config.ts} +78 -78
  171. package/src/{registry.ts → core/registry.ts} +119 -119
  172. package/src/{settings.ts → core/settings.ts} +35 -34
  173. package/src/core/template-engine.ts +45 -0
  174. package/src/{template-resolver.ts → core/template-resolver.ts} +54 -54
  175. package/src/{templates.ts → core/templates.ts} +452 -450
  176. package/src/core/terminology.ts +177 -0
  177. package/src/core/tracing.ts +110 -0
  178. package/src/{types.ts → core/types.ts} +46 -46
  179. package/src/{utils.ts → core/utils.ts} +64 -50
  180. package/src/{validate.ts → core/validate.ts} +252 -246
  181. package/src/{validator.ts → core/validator.ts} +92 -96
  182. package/src/{version.ts → core/version.ts} +24 -24
  183. package/src/{workflow-commands.ts → core/workflow-commands.ts} +32 -31
  184. package/src/i18n/en.json +45 -0
  185. package/src/i18n/index.ts +58 -0
  186. package/src/i18n/tr.json +45 -0
  187. package/src/providers/index.ts +29 -12
  188. package/src/providers/mock-provider.ts +200 -199
  189. package/src/providers/openai-provider.ts +88 -87
  190. package/src/skills/engine.ts +94 -0
  191. package/src/skills/fix-skill.ts +38 -0
  192. package/src/skills/generate-artifact-skill.ts +32 -0
  193. package/src/skills/generate-pipeline-skill.ts +49 -0
  194. package/src/skills/normalize-skill.ts +29 -0
  195. package/src/skills/types.ts +36 -0
  196. package/src/skills/validate-skill.ts +29 -0
  197. package/templates/commands/prodo-fix.md +46 -0
  198. package/templates/commands/prodo-normalize.md +118 -23
  199. package/templates/commands/prodo-prd.md +138 -17
  200. package/templates/commands/prodo-stories.md +153 -17
  201. package/templates/commands/prodo-techspec.md +167 -17
  202. package/templates/commands/prodo-validate.md +184 -26
  203. package/templates/commands/prodo-wireframe.md +188 -17
  204. package/templates/commands/prodo-workflow.md +200 -17
  205. package/src/normalize.ts +0 -89
@@ -0,0 +1,94 @@
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
+ }
@@ -0,0 +1,38 @@
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
+ };
@@ -0,0 +1,32 @@
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
+ };
@@ -0,0 +1,49 @@
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
+ };
@@ -0,0 +1,29 @@
1
+ import { runNormalize } from "../core/normalize";
2
+ import type { Skill } from "./types";
3
+
4
+ export const normalizeSkill: Skill = {
5
+ manifest: {
6
+ name: "normalize",
7
+ description: "Normalize a product brief into structured JSON with contracts and confidence scores",
8
+ category: "core",
9
+ 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" }
13
+ ],
14
+ outputs: [
15
+ { name: "normalizedBriefPath", type: "path", description: "Path to normalized-brief.json" }
16
+ ]
17
+ },
18
+
19
+ async execute(context, inputs): Promise<Record<string, unknown>> {
20
+ const cwd = (inputs.cwd as string) ?? context.cwd;
21
+ const outPath = await runNormalize({
22
+ cwd,
23
+ brief: inputs.brief as string | undefined,
24
+ out: inputs.out as string | undefined
25
+ });
26
+ context.log(`Normalized brief written to: ${outPath}`);
27
+ return { normalizedBriefPath: outPath };
28
+ }
29
+ };
@@ -0,0 +1,36 @@
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
+ };
@@ -0,0 +1,29 @@
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
+ };
@@ -0,0 +1,46 @@
1
+ ---
2
+ description: Fix failing artifacts using latest validation report and brief-aligned regeneration.
3
+ agent-role: "Recovery Engineer"
4
+ ---
5
+
6
+ ## User Input
7
+
8
+ ```text
9
+ $ARGUMENTS
10
+ ```
11
+
12
+ ## Execution Policy
13
+
14
+ - Execute-first, diagnose-second.
15
+ - Do not run shell commands or CLI commands from inside the agent.
16
+ - Never invoke `prodo-fix`, `prodo fix`, or any `prodo ...` command in shell.
17
+ - Input files are read-only; never modify `brief.md`.
18
+ - Write outputs only under `product-docs/` and `.prodo/`.
19
+ - Do not print full artifact bodies in chat.
20
+
21
+ ## Execution
22
+
23
+ 1. Minimum prerequisites only:
24
+ - `.prodo/` exists
25
+ - `brief.md` exists
26
+ - `.prodo/briefs/normalized-brief.json` exists (refresh if stale)
27
+ - Validation report exists in `product-docs/reports/`
28
+
29
+ 2. Execute fix process immediately:
30
+ - Read latest validation report.
31
+ - Identify failing artifact types and regenerate only impacted chain.
32
+ - Use normalized brief + active templates for regeneration.
33
+
34
+ 3. Verify result:
35
+ - Re-run validation.
36
+ - Confirm report status is PASS.
37
+ - Confirm `brief.md` remained unchanged.
38
+
39
+ 4. Diagnose only on failure:
40
+ - Inspect internal hooks/scripts only after fix attempt fails.
41
+ - Return concise root cause + next repair action.
42
+
43
+ ## Handoff
44
+
45
+ If pass: suggest next command `/prodo-validate`.
46
+ If fail: suggest highest-priority artifact command to regenerate manually.
@@ -1,31 +1,126 @@
1
1
  ---
2
- description: Normalize product brief.
2
+ description: >
3
+ Transform product brief into normalized, standardized JSON schema for downstream artifact generation.
4
+ Validates structure, enriches metadata, and ensures semantic consistency across all product definitions.
5
+ agent-role: "Data Processor & Validator"
6
+ agent-profile: |
7
+ **Character**: Meticulous Data Architect
8
+ - **Personality**: Precise, methodical, quality-focused
9
+ - **Specialization**: Schema validation, data normalization, integrity auditing
10
+ - **Decision Style**: Rule-based, deterministic (no guessing)
11
+ - **Tolerance**: Zero tolerance for data corruption or inconsistency
12
+
13
+ agent-skills: |
14
+ ✓ **Core Skills**:
15
+ - JSON schema validation & transformation
16
+ - Data normalization & standardization
17
+ - Metadata enrichment (timestamps, hashing, versioning)
18
+ - Deterministic output generation
19
+ - Integrity verification & audit trail
20
+
21
+ ✓ **Performance Metrics**:
22
+ - Speed: Fast (one-pass processing)
23
+ - Accuracy: 100% deterministic
24
+ - Safety: Immutable input protection
25
+ - Reliability: No side effects
26
+
27
+ ✓ **Problem-Solving Approach**:
28
+ - Fail-fast on validation errors
29
+ - Detect corruption early
30
+ - Auto-correct when possible
31
+ - Provide clear diagnostics on failure
32
+
33
+ agent-decision-strategy: |
34
+ **Decision Tree**:
35
+ 1. Prerequisites valid? → Continue | Fail-fast
36
+ 2. Input corrupted? → Report error | Auto-correct if safe
37
+ 3. Output format invalid? → Rewrite as pure JSON | Report conversion
38
+ 4. Integrity compromised? → Report issue with remediation | Block output
39
+
40
+ **When to Escalate**:
41
+ - Input file missing or unreadable → User must provide
42
+ - Normalization logic ambiguous → Recommend upstream clarification
43
+ - Multiple corruption patterns detected → Suggest expert review
44
+
45
+ agent-efficiency-tips: |
46
+ ⚡ **For Maximum Efficiency**:
47
+ - Run FIRST in pipeline (all others depend on this)
48
+ - Cache results: normalized-brief.json rarely changes
49
+ - Single pass: read once, validate, write
50
+ - No re-processing: output is deterministic
51
+ - Early validation: catch brief issues immediately
3
52
  ---
4
53
 
5
- ## User Input
54
+ ## Context
55
+
56
+ **Purpose**: Convert unstructured or semi-structured product brief into a machine-readable normalized format.
57
+
58
+ **Upstream Dependencies**: `brief.md` must exist in project root.
59
+
60
+ **Downstream Impact**: All artifact generation commands (PRD, stories, techspec, workflow, wireframe) depend on normalized-brief.json for consistency.
61
+
62
+ **User Input**
6
63
 
7
64
  ```text
8
65
  $ARGUMENTS
9
66
  ```
10
67
 
11
- Execution policy:
12
- - Execute-first, diagnose-second.
13
- - Do not run shell/CLI commands from inside the agent.
14
- - Never run `prodo-normalize`, `prodo normalize`, or `prodo ...` in shell.
15
- - Input files are read-only; never modify or rewrite `brief.md`.
16
- - Never print full normalized JSON in chat.
17
- - Write `.prodo/briefs/normalized-brief.json`, then reply with short status + file path.
18
-
19
- ## Execution
20
-
21
- 1. Verify minimal prerequisites (`.prodo/`, `brief.md`).
22
- 2. Read only `brief.md` and normalize it into `.prodo/briefs/normalized-brief.json`.
23
- 3. Confirm `.prodo/briefs/normalized-brief.json` exists.
24
- 4. Verify normalized file is strict JSON only:
25
- - first non-space char is `{`
26
- - no markdown fences like ```json or ```
27
- - JSON parses successfully as an object
28
- 5. If format is not strict JSON, rewrite the same file as pure JSON object only.
29
- 6. Confirm `brief.md` content did not change.
30
- 7. Do not create any manual files under `.prodo/` except expected runtime outputs.
31
- 8. Diagnose internals only if command fails.
68
+ ## Execution Policy
69
+
70
+ **Safety & Integrity**:
71
+ - Execute-first, diagnose-second (fail fast on validation errors).
72
+ - Do not execute shell/CLI commands from inside the agent.
73
+ - Never invoke `prodo-normalize`, `prodo normalize`, or `prodo ...` commands recursively in shell.
74
+ - **Input files are read-only**: Never modify, rewrite, or transform `brief.md`. Treat it as immutable source of truth.
75
+ - Never print full normalized JSON to chat; return only status + file path.
76
+
77
+ **Output Quality**:
78
+ - Write `.prodo/briefs/normalized-brief.json` with validated strict JSON format.
79
+ - Normalized output must be deterministic (same input always produces identical output).
80
+ - Include metadata: normalized timestamp, schema version, input hash for audit trail.
81
+
82
+ ## Execution Steps
83
+
84
+ 1. **Verify Minimal Prerequisites**
85
+ - Confirm `.prodo/` directory exists (initialized by `prodo init`).
86
+ - Confirm `brief.md` exists and is readable.
87
+ - Check no corrupt `.prodo/briefs/` state exists.
88
+
89
+ 2. **Parse and Normalize `brief.md`**
90
+ - Read `brief.md` without modification.
91
+ - Extract and validate core product attributes (name, description, goals, target audience, scope, constraints).
92
+ - Normalize field types: trim whitespace, standardize arrays, convert dates to ISO-8601.
93
+ - Enrich with derived metadata (section count, complexity score, validation flags).
94
+
95
+ 3. **Validate Normalized Format**
96
+ - Confirm `.prodo/briefs/normalized-brief.json` was created.
97
+ - Verify strict JSON compliance:
98
+ - First non-space character must be `{`.
99
+ - No markdown fences (no \`\`\`json or \`\`\`).
100
+ - File must parse successfully as a valid JSON object.
101
+ - No trailing commas, unquoted keys, or comments.
102
+ - If format is invalid, rewrite file as pure JSON object only (auto-correct).
103
+
104
+ 4. **Audit & Verify Integrity**
105
+ - Confirm original `brief.md` was not modified (compare timestamps or file hash).
106
+ - Verify normalized output contains no executable code or shell injections.
107
+ - Log schema version and normalized metadata.
108
+
109
+ 5. **Safety Constraints**
110
+ - Do not create manual fallback files under `.prodo/` outside expected outputs.
111
+ - Do not write to `.prodo/templates/`, `.prodo/config/`, or other reserved directories.
112
+ - Do not modify or create `.gitignore` or hidden system files.
113
+
114
+ 6. **Diagnosis & Error Handling**
115
+ - If `brief.md` is missing: report clear error with recovery instructions.
116
+ - If `brief.md` syntax is invalid: report line numbers and invalid fields.
117
+ - If normalization fails: include schema mismatch details and sample valid structure.
118
+ - If `.prodo/briefs/` cannot be written: report file system permissions issue.
119
+
120
+ ## Success Criteria
121
+
122
+ - ✅ `.prodo/briefs/normalized-brief.json` exists and is valid JSON.
123
+ - ✅ Original `brief.md` remains unchanged.
124
+ - ✅ Normalized file includes schema version and timestamp.
125
+ - ✅ All required product attributes are present and validated.
126
+ - ✅ Ready for downstream artifact generation.