@shahmarasy/prodo 0.1.4 → 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 (173) 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 +465 -0
  27. package/dist/cli/init-tui.d.ts +23 -0
  28. package/dist/cli/init-tui.js +176 -0
  29. package/dist/cli/init.d.ts +11 -0
  30. package/dist/cli/init.js +334 -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 +7 -0
  66. package/dist/core/settings.js +35 -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 +7 -6
  97. package/dist/providers/openai-provider.d.ts +1 -1
  98. package/dist/providers/openai-provider.js +1 -1
  99. package/dist/skills/engine.d.ts +10 -0
  100. package/dist/skills/engine.js +75 -0
  101. package/dist/skills/fix-skill.d.ts +2 -0
  102. package/dist/skills/fix-skill.js +38 -0
  103. package/dist/skills/generate-artifact-skill.d.ts +2 -0
  104. package/dist/skills/generate-artifact-skill.js +32 -0
  105. package/dist/skills/generate-pipeline-skill.d.ts +2 -0
  106. package/dist/skills/generate-pipeline-skill.js +45 -0
  107. package/dist/skills/normalize-skill.d.ts +2 -0
  108. package/dist/skills/normalize-skill.js +29 -0
  109. package/dist/skills/types.d.ts +28 -0
  110. package/dist/skills/types.js +2 -0
  111. package/dist/skills/validate-skill.d.ts +2 -0
  112. package/dist/skills/validate-skill.js +29 -0
  113. package/package.json +74 -45
  114. package/src/agents/agent-registry.ts +93 -0
  115. package/src/agents/anthropic/index.ts +86 -0
  116. package/src/agents/anthropic/manifest.json +7 -0
  117. package/src/agents/base.ts +77 -0
  118. package/src/agents/google/index.ts +79 -0
  119. package/src/agents/google/manifest.json +7 -0
  120. package/src/agents/mock/index.ts +32 -0
  121. package/src/agents/mock/manifest.json +7 -0
  122. package/src/agents/openai/index.ts +83 -0
  123. package/src/agents/openai/manifest.json +7 -0
  124. package/src/agents/system-prompts.ts +35 -0
  125. package/src/{agent-command-installer.ts → cli/agent-command-installer.ts} +164 -164
  126. package/src/{agents.ts → cli/agent-ids.ts} +58 -58
  127. package/src/{doctor.ts → cli/doctor.ts} +157 -137
  128. package/src/cli/fix-tui.ts +111 -0
  129. package/src/{cli.ts → cli/index.ts} +459 -410
  130. package/src/{init-tui.ts → cli/init-tui.ts} +208 -208
  131. package/src/{init.ts → cli/init.ts} +398 -398
  132. package/src/cli/normalize-interactive.ts +241 -0
  133. package/src/{preset-loader.ts → cli/preset-loader.ts} +237 -237
  134. package/src/{artifact-registry.ts → core/artifact-registry.ts} +69 -69
  135. package/src/{artifacts.ts → core/artifacts.ts} +1081 -1072
  136. package/src/core/clean.ts +88 -0
  137. package/src/{consistency.ts → core/consistency.ts} +374 -303
  138. package/src/{constants.ts → core/constants.ts} +72 -72
  139. package/src/{errors.ts → core/errors.ts} +7 -7
  140. package/src/core/fix.ts +253 -0
  141. package/src/{hook-executor.ts → core/hook-executor.ts} +196 -196
  142. package/src/{markdown.ts → core/markdown.ts} +93 -73
  143. package/src/{normalize.ts → core/normalize.ts} +145 -137
  144. package/src/{normalized-brief.ts → core/normalized-brief.ts} +227 -206
  145. package/src/{output-index.ts → core/output-index.ts} +59 -59
  146. package/src/{paths.ts → core/paths.ts} +75 -71
  147. package/src/{project-config.ts → core/project-config.ts} +78 -78
  148. package/src/{registry.ts → core/registry.ts} +119 -119
  149. package/src/{settings.ts → core/settings.ts} +35 -35
  150. package/src/core/template-engine.ts +45 -0
  151. package/src/{template-resolver.ts → core/template-resolver.ts} +54 -54
  152. package/src/{templates.ts → core/templates.ts} +452 -452
  153. package/src/core/terminology.ts +177 -0
  154. package/src/core/tracing.ts +110 -0
  155. package/src/{types.ts → core/types.ts} +46 -46
  156. package/src/{utils.ts → core/utils.ts} +64 -64
  157. package/src/{validate.ts → core/validate.ts} +252 -246
  158. package/src/{validator.ts → core/validator.ts} +92 -92
  159. package/src/{version.ts → core/version.ts} +24 -24
  160. package/src/{workflow-commands.ts → core/workflow-commands.ts} +32 -32
  161. package/src/i18n/en.json +45 -0
  162. package/src/i18n/index.ts +58 -0
  163. package/src/i18n/tr.json +45 -0
  164. package/src/providers/index.ts +29 -12
  165. package/src/providers/mock-provider.ts +200 -199
  166. package/src/providers/openai-provider.ts +88 -88
  167. package/src/skills/engine.ts +94 -0
  168. package/src/skills/fix-skill.ts +38 -0
  169. package/src/skills/generate-artifact-skill.ts +32 -0
  170. package/src/skills/generate-pipeline-skill.ts +49 -0
  171. package/src/skills/normalize-skill.ts +29 -0
  172. package/src/skills/types.ts +36 -0
  173. package/src/skills/validate-skill.ts +29 -0
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.t = t;
7
+ exports.loadTranslations = loadTranslations;
8
+ exports.availableLanguages = availableLanguages;
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const cache = new Map();
12
+ function loadJson(lang) {
13
+ if (cache.has(lang))
14
+ return cache.get(lang);
15
+ const filePath = node_path_1.default.resolve(__dirname, `${lang}.json`);
16
+ try {
17
+ const raw = node_fs_1.default.readFileSync(filePath, "utf8");
18
+ const parsed = JSON.parse(raw);
19
+ cache.set(lang, parsed);
20
+ return parsed;
21
+ }
22
+ catch {
23
+ cache.set(lang, {});
24
+ return {};
25
+ }
26
+ }
27
+ function normalizeLang(lang) {
28
+ if (!lang)
29
+ return "en";
30
+ const code = lang.toLowerCase().trim();
31
+ if (code.startsWith("tr"))
32
+ return "tr";
33
+ if (code.startsWith("en"))
34
+ return "en";
35
+ return code;
36
+ }
37
+ function t(key, lang) {
38
+ const normalized = normalizeLang(lang);
39
+ const translations = loadJson(normalized);
40
+ if (key in translations)
41
+ return translations[key];
42
+ if (normalized !== "en") {
43
+ const fallback = loadJson("en");
44
+ if (key in fallback)
45
+ return fallback[key];
46
+ }
47
+ return key;
48
+ }
49
+ function loadTranslations(lang) {
50
+ return { ...loadJson(normalizeLang(lang)) };
51
+ }
52
+ function availableLanguages() {
53
+ const dir = node_path_1.default.resolve(__dirname);
54
+ try {
55
+ return node_fs_1.default.readdirSync(dir)
56
+ .filter((f) => f.endsWith(".json"))
57
+ .map((f) => f.replace(".json", ""))
58
+ .sort();
59
+ }
60
+ catch {
61
+ return ["en"];
62
+ }
63
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "user_action": "Kullanıcı işlemi",
3
+ "main_flow": "Ana Akış",
4
+ "user": "Kullanıcı",
5
+ "success": "Başarı",
6
+ "error": "Hata",
7
+ "flow_focus": "Akış Odağı",
8
+ "initial_version": "İlk sürüm",
9
+ "fix_revision": "Doğrulama sonrası düzeltme revizyonu",
10
+ "primary_user": "Birincil kullanıcı",
11
+ "back": "Geri",
12
+ "next": "Devam",
13
+ "save": "Kaydet",
14
+ "content": "İçerik",
15
+ "primary_info_area": "Birincil bilgi alanı",
16
+ "status_indicator": "Durum göstergesi",
17
+ "form": "Form",
18
+ "field": "Alan",
19
+ "description": "Açıklama",
20
+ "contract": "Kontrat",
21
+ "actor": "Aktör",
22
+ "detailed_input_area": "Detaylı Giriş Alanı",
23
+ "upload_area": "Dosya Alanı",
24
+ "low_fidelity_wireframe": "Düşük sadakatli wireframe.",
25
+ "confirmation_text": "Onay metni",
26
+ "header_and_navigation": "Başlık ve gezinme",
27
+ "content_section": "İçerik bölümü",
28
+ "form_section": "Form bölümü",
29
+ "text_input": "Metin alanı",
30
+ "to_be_refined": "Detay daha sonra netleştirilecek.",
31
+ "note": "Not",
32
+ "requirement_item": "Gereksinim maddesi",
33
+ "contract_coverage": "Kontrat kapsamı",
34
+ "screen": "Ekran",
35
+ "for_artifact": "için",
36
+ "fix_proposal": "Düzeltme Önerisi",
37
+ "fix_complete": "Düzeltme tamamlandı — doğrulama geçti.",
38
+ "fix_still_failing": "Düzeltme uygulandı ama doğrulama hâlâ başarısız.",
39
+ "fix_cancelled": "Düzeltme iptal edildi.",
40
+ "no_issues": "Engel teşkil eden sorun bulunamadı. Düzeltilecek bir şey yok.",
41
+ "issues_found": "Bulunan sorunlar",
42
+ "artifacts_to_regenerate": "Yeniden oluşturulacak artefaktlar",
43
+ "general": "Genel",
44
+ "suggestion_prefix": "→"
45
+ }
@@ -1,2 +1,3 @@
1
- import type { LLMProvider } from "../types";
1
+ import type { LLMProvider } from "../core/types";
2
2
  export declare function createProvider(): LLMProvider;
3
+ export { getGlobalRegistry } from "../agents/agent-registry";
@@ -1,12 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGlobalRegistry = void 0;
3
4
  exports.createProvider = createProvider;
4
- const mock_provider_1 = require("./mock-provider");
5
- const openai_provider_1 = require("./openai-provider");
5
+ const agent_registry_1 = require("../agents/agent-registry");
6
+ let cachedProvider = null;
7
+ let cachedAgentName = null;
6
8
  function createProvider() {
7
- const provider = (process.env.PRODO_LLM_PROVIDER ?? "mock").toLowerCase();
8
- if (provider === "openai") {
9
- return new openai_provider_1.OpenAIProvider();
9
+ const agentName = process.env.PRODO_AGENT ??
10
+ process.env.PRODO_LLM_PROVIDER ??
11
+ "mock";
12
+ if (cachedProvider && cachedAgentName === agentName) {
13
+ return cachedProvider;
10
14
  }
11
- return new mock_provider_1.MockProvider();
15
+ const registry = (0, agent_registry_1.getGlobalRegistry)();
16
+ const agent = registry.get(agentName);
17
+ if (!agent) {
18
+ const available = registry.list().map((a) => a.name).join(", ");
19
+ throw new Error(`Unknown agent: "${agentName}". Available: ${available}`);
20
+ }
21
+ cachedProvider = registry.toProvider(agent);
22
+ cachedAgentName = agentName;
23
+ return cachedProvider;
12
24
  }
25
+ var agent_registry_2 = require("../agents/agent-registry");
26
+ Object.defineProperty(exports, "getGlobalRegistry", { enumerable: true, get: function () { return agent_registry_2.getGlobalRegistry; } });
@@ -1,4 +1,4 @@
1
- import type { LLMProvider, ProviderSchemaHint } from "../types";
1
+ import type { LLMProvider, ProviderSchemaHint } from "../core/types";
2
2
  export declare class MockProvider implements LLMProvider {
3
3
  generate(_prompt: string, inputContext: Record<string, unknown>, schemaHint: ProviderSchemaHint): Promise<{
4
4
  body: string;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MockProvider = void 0;
4
+ const i18n_1 = require("../i18n");
4
5
  function asStringArray(value) {
5
6
  if (!Array.isArray(value))
6
7
  return [];
@@ -107,18 +108,18 @@ function buildArtifactBody(schemaHint, inputContext) {
107
108
  const lang = typeof inputContext.outputLanguage === "string" ? inputContext.outputLanguage.toLowerCase() : "en";
108
109
  const items = normalizeSectionItems(inputContext);
109
110
  const coverage = coverageItems(schemaHint, inputContext);
110
- const localizedItems = lang === "tr" ? items.map((_, index) => `Gereksinim maddesi ${index + 1}`) : items;
111
+ const localizedItems = lang === "tr" ? items.map((_, index) => `${(0, i18n_1.t)("requirement_item", lang)} ${index + 1}`) : items;
111
112
  const localizedCoverage = lang === "tr"
112
113
  ? coverage.map((item, index) => ({
113
114
  id: item.id,
114
- text: `Kontrat kapsami ${index + 1}`
115
+ text: `${(0, i18n_1.t)("contract_coverage", lang)} ${index + 1}`
115
116
  }))
116
117
  : coverage;
117
- const fallback = lang === "tr" ? "Detay daha sonra netlestirilecek." : "To be refined.";
118
+ const fallback = (0, i18n_1.t)("to_be_refined", lang);
118
119
  const sections = schemaHint.requiredHeadings.map((heading) => headingBlock(heading, localizedItems, fallback, localizedCoverage));
119
120
  const title = lang === "tr"
120
- ? `# ${productName} icin ${schemaHint.artifactType.toUpperCase()}`
121
- : `# ${schemaHint.artifactType.toUpperCase()} for ${productName}`;
121
+ ? `# ${productName} ${(0, i18n_1.t)("for_artifact", lang)} ${schemaHint.artifactType.toUpperCase()}`
122
+ : `# ${schemaHint.artifactType.toUpperCase()} ${(0, i18n_1.t)("for_artifact", lang)} ${productName}`;
122
123
  if (schemaHint.artifactType === "workflow") {
123
124
  return `${title}\n\n${sections.join("\n")}\n\n\`\`\`mermaid
124
125
  flowchart TD
@@ -127,7 +128,7 @@ flowchart TD
127
128
  C --> D[Done]
128
129
  \`\`\``.trim();
129
130
  }
130
- return `${title}\n\n${sections.join("\n")}\n\n${lang === "tr" ? "Not" : "Note"}: ${fallback}`.trim();
131
+ return `${title}\n\n${sections.join("\n")}\n\n${(0, i18n_1.t)("note", lang)}: ${fallback}`.trim();
131
132
  }
132
133
  function semanticIssuesWithMock(inputContext) {
133
134
  const pair = inputContext.pair;
@@ -1,4 +1,4 @@
1
- import type { LLMProvider, ProviderSchemaHint } from "../types";
1
+ import type { LLMProvider, ProviderSchemaHint } from "../core/types";
2
2
  export declare class OpenAIProvider implements LLMProvider {
3
3
  private readonly apiKey;
4
4
  private readonly model;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OpenAIProvider = void 0;
4
- const errors_1 = require("../errors");
4
+ const errors_1 = require("../core/errors");
5
5
  class OpenAIProvider {
6
6
  apiKey;
7
7
  model;
@@ -0,0 +1,10 @@
1
+ import type { Skill, SkillContext, SkillManifest } from "./types";
2
+ export type SkillEngine = {
3
+ register(skill: Skill): void;
4
+ getSkill(name: string): Skill | undefined;
5
+ listSkills(): SkillManifest[];
6
+ execute(name: string, context: SkillContext, inputs: Record<string, unknown>): Promise<Record<string, unknown>>;
7
+ };
8
+ export declare function createSkillEngine(): SkillEngine;
9
+ export declare function getGlobalSkillEngine(): SkillEngine;
10
+ export declare function resetGlobalSkillEngine(): void;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSkillEngine = createSkillEngine;
4
+ exports.getGlobalSkillEngine = getGlobalSkillEngine;
5
+ exports.resetGlobalSkillEngine = resetGlobalSkillEngine;
6
+ const errors_1 = require("../core/errors");
7
+ function validateInputs(skill, inputs) {
8
+ for (const input of skill.manifest.inputs) {
9
+ if (input.required && !(input.name in inputs)) {
10
+ throw new errors_1.UserError(`Skill "${skill.manifest.name}" requires input "${input.name}" (${input.description})`);
11
+ }
12
+ }
13
+ }
14
+ function createSkillEngine() {
15
+ const skills = new Map();
16
+ return {
17
+ register(skill) {
18
+ skills.set(skill.manifest.name, skill);
19
+ },
20
+ getSkill(name) {
21
+ return skills.get(name);
22
+ },
23
+ listSkills() {
24
+ return Array.from(skills.values()).map((s) => s.manifest);
25
+ },
26
+ async execute(name, context, inputs) {
27
+ const skill = skills.get(name);
28
+ if (!skill) {
29
+ const available = Array.from(skills.keys()).join(", ");
30
+ throw new errors_1.UserError(`Unknown skill: "${name}". Available: ${available}`);
31
+ }
32
+ validateInputs(skill, inputs);
33
+ return skill.execute(context, inputs);
34
+ }
35
+ };
36
+ }
37
+ let globalEngine = null;
38
+ function getGlobalSkillEngine() {
39
+ if (!globalEngine) {
40
+ globalEngine = createSkillEngine();
41
+ loadBuiltinSkills(globalEngine);
42
+ }
43
+ return globalEngine;
44
+ }
45
+ function resetGlobalSkillEngine() {
46
+ globalEngine = null;
47
+ }
48
+ function loadBuiltinSkills(engine) {
49
+ // Lazy-load to avoid circular dependencies
50
+ try {
51
+ const { normalizeSkill } = require("./normalize-skill");
52
+ engine.register(normalizeSkill);
53
+ }
54
+ catch { /* skill not available */ }
55
+ try {
56
+ const { validateSkill } = require("./validate-skill");
57
+ engine.register(validateSkill);
58
+ }
59
+ catch { /* skill not available */ }
60
+ try {
61
+ const { fixSkill } = require("./fix-skill");
62
+ engine.register(fixSkill);
63
+ }
64
+ catch { /* skill not available */ }
65
+ try {
66
+ const { generateArtifactSkill } = require("./generate-artifact-skill");
67
+ engine.register(generateArtifactSkill);
68
+ }
69
+ catch { /* skill not available */ }
70
+ try {
71
+ const { generatePipelineSkill } = require("./generate-pipeline-skill");
72
+ engine.register(generatePipelineSkill);
73
+ }
74
+ catch { /* skill not available */ }
75
+ }
@@ -0,0 +1,2 @@
1
+ import type { Skill } from "./types";
2
+ export declare const fixSkill: Skill;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fixSkill = void 0;
4
+ const fix_1 = require("../core/fix");
5
+ exports.fixSkill = {
6
+ manifest: {
7
+ name: "fix",
8
+ description: "Auto-regenerate artifacts that failed validation with backup and rollback",
9
+ category: "validation",
10
+ inputs: [
11
+ { name: "cwd", type: "path", required: true, description: "Project working directory" },
12
+ { name: "agent", type: "string", required: false, description: "Agent profile name" },
13
+ { name: "strict", type: "boolean", required: false, description: "Treat warnings as errors" },
14
+ { name: "dryRun", type: "boolean", required: false, description: "Preview without applying" }
15
+ ],
16
+ outputs: [
17
+ { name: "applied", type: "string", description: "Whether fix was applied" },
18
+ { name: "finalPass", type: "string", description: "Whether validation passed after fix" },
19
+ { name: "reportPath", type: "path", description: "Path to validation report" }
20
+ ]
21
+ },
22
+ async execute(context, inputs) {
23
+ const cwd = inputs.cwd ?? context.cwd;
24
+ const result = await (0, fix_1.runFix)({
25
+ cwd,
26
+ agent: inputs.agent ?? 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,2 @@
1
+ import type { Skill } from "./types";
2
+ export declare const generateArtifactSkill: Skill;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateArtifactSkill = void 0;
4
+ const artifacts_1 = require("../core/artifacts");
5
+ exports.generateArtifactSkill = {
6
+ manifest: {
7
+ name: "generate-artifact",
8
+ description: "Generate a single artifact (PRD, workflow, wireframe, stories, techspec)",
9
+ category: "artifact",
10
+ inputs: [
11
+ { name: "cwd", type: "path", required: true, description: "Project working directory" },
12
+ { name: "artifactType", type: "string", required: true, description: "Artifact type to generate" },
13
+ { name: "from", type: "path", required: false, description: "Override path to normalized-brief.json" },
14
+ { name: "out", type: "path", required: false, description: "Override output path" }
15
+ ],
16
+ outputs: [
17
+ { name: "filePath", type: "path", description: "Path to generated artifact" }
18
+ ]
19
+ },
20
+ async execute(context, inputs) {
21
+ const cwd = inputs.cwd ?? context.cwd;
22
+ const filePath = await (0, artifacts_1.generateArtifact)({
23
+ artifactType: inputs.artifactType,
24
+ cwd,
25
+ normalizedBriefOverride: inputs.from,
26
+ outPath: inputs.out,
27
+ agent: context.agent
28
+ });
29
+ context.log(`${inputs.artifactType.toUpperCase()} generated: ${filePath}`);
30
+ return { filePath };
31
+ }
32
+ };
@@ -0,0 +1,2 @@
1
+ import type { Skill } from "./types";
2
+ export declare const generatePipelineSkill: Skill;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generatePipelineSkill = void 0;
4
+ const artifact_registry_1 = require("../core/artifact-registry");
5
+ const artifacts_1 = require("../core/artifacts");
6
+ const normalize_1 = require("../core/normalize");
7
+ const validate_1 = require("../core/validate");
8
+ exports.generatePipelineSkill = {
9
+ manifest: {
10
+ name: "generate-pipeline",
11
+ description: "Run end-to-end pipeline: normalize → generate all artifacts → validate",
12
+ category: "core",
13
+ inputs: [
14
+ { name: "cwd", type: "path", required: true, description: "Project working directory" },
15
+ { name: "strict", type: "boolean", required: false, description: "Treat warnings as errors" }
16
+ ],
17
+ outputs: [
18
+ { name: "pass", type: "string", description: "Whether validation passed" },
19
+ { name: "reportPath", type: "path", description: "Path to validation report" },
20
+ { name: "artifactCount", type: "string", description: "Number of artifacts generated" }
21
+ ]
22
+ },
23
+ async execute(context, inputs) {
24
+ const cwd = inputs.cwd ?? context.cwd;
25
+ const normalizedPath = await (0, normalize_1.runNormalize)({ cwd });
26
+ context.log(`Normalized brief: ${normalizedPath}`);
27
+ const artifactTypes = await (0, artifact_registry_1.listArtifactTypes)(cwd);
28
+ for (const type of artifactTypes) {
29
+ const file = await (0, artifacts_1.generateArtifact)({
30
+ artifactType: type,
31
+ cwd,
32
+ normalizedBriefOverride: normalizedPath,
33
+ agent: context.agent
34
+ });
35
+ context.log(`${type.toUpperCase()} generated: ${file}`);
36
+ }
37
+ const result = await (0, validate_1.runValidate)(cwd, { strict: Boolean(inputs.strict) });
38
+ context.log(`Validation ${result.pass ? "passed" : "failed"}: ${result.reportPath}`);
39
+ return {
40
+ pass: result.pass,
41
+ reportPath: result.reportPath,
42
+ artifactCount: artifactTypes.length
43
+ };
44
+ }
45
+ };
@@ -0,0 +1,2 @@
1
+ import type { Skill } from "./types";
2
+ export declare const normalizeSkill: Skill;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeSkill = void 0;
4
+ const normalize_1 = require("../core/normalize");
5
+ exports.normalizeSkill = {
6
+ manifest: {
7
+ name: "normalize",
8
+ description: "Normalize a product brief into structured JSON with contracts and confidence scores",
9
+ category: "core",
10
+ inputs: [
11
+ { name: "cwd", type: "path", required: true, description: "Project working directory" },
12
+ { name: "brief", type: "path", required: false, description: "Override path to brief.md" },
13
+ { name: "out", type: "path", required: false, description: "Override output path" }
14
+ ],
15
+ outputs: [
16
+ { name: "normalizedBriefPath", type: "path", description: "Path to normalized-brief.json" }
17
+ ]
18
+ },
19
+ async execute(context, inputs) {
20
+ const cwd = inputs.cwd ?? context.cwd;
21
+ const outPath = await (0, normalize_1.runNormalize)({
22
+ cwd,
23
+ brief: inputs.brief,
24
+ out: inputs.out
25
+ });
26
+ context.log(`Normalized brief written to: ${outPath}`);
27
+ return { normalizedBriefPath: outPath };
28
+ }
29
+ };
@@ -0,0 +1,28 @@
1
+ export type SkillInput = {
2
+ name: string;
3
+ type: "path" | "string" | "boolean" | "json";
4
+ required: boolean;
5
+ description: string;
6
+ };
7
+ export type SkillOutput = {
8
+ name: string;
9
+ type: "path" | "string" | "json";
10
+ description: string;
11
+ };
12
+ export type SkillManifest = {
13
+ name: string;
14
+ description: string;
15
+ category: "core" | "artifact" | "validation" | "custom";
16
+ inputs: SkillInput[];
17
+ outputs: SkillOutput[];
18
+ };
19
+ export type SkillContext = {
20
+ cwd: string;
21
+ log: (message: string) => void;
22
+ agent?: string;
23
+ };
24
+ export type SkillFunction = (context: SkillContext, inputs: Record<string, unknown>) => Promise<Record<string, unknown>>;
25
+ export type Skill = {
26
+ manifest: SkillManifest;
27
+ execute: SkillFunction;
28
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ import type { Skill } from "./types";
2
+ export declare const validateSkill: Skill;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateSkill = void 0;
4
+ const validate_1 = require("../core/validate");
5
+ exports.validateSkill = {
6
+ manifest: {
7
+ name: "validate",
8
+ description: "Run cross-artifact validation and generate a report",
9
+ category: "validation",
10
+ inputs: [
11
+ { name: "cwd", type: "path", required: true, description: "Project working directory" },
12
+ { name: "strict", type: "boolean", required: false, description: "Treat warnings as errors" },
13
+ { name: "report", type: "path", required: false, description: "Override report output path" }
14
+ ],
15
+ outputs: [
16
+ { name: "pass", type: "string", description: "Whether validation passed" },
17
+ { name: "reportPath", type: "path", description: "Path to validation report" }
18
+ ]
19
+ },
20
+ async execute(context, inputs) {
21
+ const cwd = inputs.cwd ?? context.cwd;
22
+ const result = await (0, validate_1.runValidate)(cwd, {
23
+ strict: Boolean(inputs.strict),
24
+ report: inputs.report
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
+ };
package/package.json CHANGED
@@ -1,45 +1,74 @@
1
- {
2
- "name": "@shahmarasy/prodo",
3
- "version": "0.1.4",
4
- "description": "CLI-first, prompt-powered product artifact kit",
5
- "main": "dist/cli.js",
6
- "types": "dist/cli.d.ts",
7
- "bin": {
8
- "prodo": "bin/prodo.cjs"
9
- },
10
- "files": [
11
- "bin/",
12
- "dist/",
13
- "templates/",
14
- "presets/",
15
- "src/",
16
- "README.md"
17
- ],
18
- "publishConfig": {
19
- "access": "public"
20
- },
21
- "engines": {
22
- "node": ">=20"
23
- },
24
- "scripts": {
25
- "build": "tsc -p tsconfig.json",
26
- "test": "npm run build && node --test tests/*.test.cjs",
27
- "verify:release": "npm run build && node scripts/verify-release-build.cjs"
28
- },
29
- "keywords": [],
30
- "author": "",
31
- "license": "ISC",
32
- "dependencies": {
33
- "@clack/prompts": "^1.1.0",
34
- "ajv": "^8.18.0",
35
- "ajv-formats": "^3.0.1",
36
- "commander": "^14.0.3",
37
- "gray-matter": "^4.0.3",
38
- "js-yaml": "^4.1.1"
39
- },
40
- "devDependencies": {
41
- "@types/js-yaml": "^4.0.9",
42
- "@types/node": "^25.5.0",
43
- "typescript": "^5.9.3"
44
- }
45
- }
1
+ {
2
+ "name": "@shahmarasy/prodo",
3
+ "version": "0.1.5",
4
+ "description": "CLI-first, prompt-powered product artifact kit",
5
+ "main": "dist/cli/index.js",
6
+ "types": "dist/cli/index.d.ts",
7
+ "bin": {
8
+ "prodo": "bin/prodo.cjs"
9
+ },
10
+ "files": [
11
+ "bin/",
12
+ "dist/",
13
+ "templates/",
14
+ "presets/",
15
+ "src/",
16
+ "README.md"
17
+ ],
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "engines": {
22
+ "node": ">=20"
23
+ },
24
+ "scripts": {
25
+ "build:ts": "tsc -p tsconfig.json",
26
+ "build:i18n": "node -e \"const fs=require('fs');const p=require('path');['en','tr'].forEach(l=>{const s=p.join('src','i18n',l+'.json');const d=p.join('dist','i18n',l+'.json');fs.copyFileSync(s,d)})\"",
27
+ "build": "npm run build:ts && npm run build:i18n",
28
+ "test": "npm run build && node --test tests/*.test.cjs",
29
+ "verify:release": "npm run build && node scripts/verify-release-build.cjs"
30
+ },
31
+ "keywords": [
32
+ "product-management",
33
+ "prd",
34
+ "ai-agents",
35
+ "codex",
36
+ "claude",
37
+ "gemini",
38
+ "document-generation",
39
+ "cli"
40
+ ],
41
+ "author": "Shahmarasy",
42
+ "license": "MIT",
43
+ "dependencies": {
44
+ "@clack/prompts": "^1.1.0",
45
+ "ajv": "^8.18.0",
46
+ "ajv-formats": "^3.0.1",
47
+ "commander": "^14.0.3",
48
+ "gray-matter": "^4.0.3",
49
+ "js-yaml": "^4.1.1",
50
+ "nunjucks": "^3.2.4"
51
+ },
52
+ "peerDependencies": {
53
+ "openai": ">=4.0.0",
54
+ "@anthropic-ai/sdk": ">=0.20.0",
55
+ "@google/generative-ai": ">=0.1.0"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "openai": {
59
+ "optional": true
60
+ },
61
+ "@anthropic-ai/sdk": {
62
+ "optional": true
63
+ },
64
+ "@google/generative-ai": {
65
+ "optional": true
66
+ }
67
+ },
68
+ "devDependencies": {
69
+ "@types/js-yaml": "^4.0.9",
70
+ "@types/node": "^25.5.0",
71
+ "@types/nunjucks": "^3.2.6",
72
+ "typescript": "^5.9.3"
73
+ }
74
+ }