@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
@@ -1,34 +1,35 @@
1
- import fs from "node:fs/promises";
2
- import { settingsPath } from "./paths";
3
- import { fileExists } from "./utils";
4
-
5
- export type ProdoSettings = {
6
- lang: string;
7
- ai?: string;
8
- };
9
-
10
- const DEFAULT_SETTINGS: ProdoSettings = {
11
- lang: "en"
12
- };
13
-
14
- export async function readSettings(cwd: string): Promise<ProdoSettings> {
15
- const path = settingsPath(cwd);
16
- if (!(await fileExists(path))) return { ...DEFAULT_SETTINGS };
17
- try {
18
- const raw = await fs.readFile(path, "utf8");
19
- const parsed = JSON.parse(raw) as Partial<ProdoSettings>;
20
- return {
21
- lang: typeof parsed.lang === "string" && parsed.lang.trim() ? parsed.lang.trim() : "en",
22
- ai: typeof parsed.ai === "string" && parsed.ai.trim() ? parsed.ai.trim() : undefined
23
- };
24
- } catch {
25
- return { ...DEFAULT_SETTINGS };
26
- }
27
- }
28
-
29
- export async function writeSettings(cwd: string, settings: ProdoSettings): Promise<string> {
30
- const path = settingsPath(cwd);
31
- await fs.writeFile(path, `${JSON.stringify(settings, null, 2)}\n`, "utf8");
32
- return path;
33
- }
34
-
1
+ import fs from "node:fs/promises";
2
+ import { settingsPath } from "./paths";
3
+ import { fileExists } from "./utils";
4
+
5
+ export type ProdoSettings = {
6
+ lang: string;
7
+ ai?: string;
8
+ author?: string;
9
+ };
10
+
11
+ const DEFAULT_SETTINGS: ProdoSettings = {
12
+ lang: "en"
13
+ };
14
+
15
+ export async function readSettings(cwd: string): Promise<ProdoSettings> {
16
+ const path = settingsPath(cwd);
17
+ if (!(await fileExists(path))) return { ...DEFAULT_SETTINGS };
18
+ try {
19
+ const raw = await fs.readFile(path, "utf8");
20
+ const parsed = JSON.parse(raw) as Partial<ProdoSettings>;
21
+ return {
22
+ lang: typeof parsed.lang === "string" && parsed.lang.trim() ? parsed.lang.trim() : "en",
23
+ ai: typeof parsed.ai === "string" && parsed.ai.trim() ? parsed.ai.trim() : undefined,
24
+ author: typeof parsed.author === "string" && parsed.author.trim() ? parsed.author.trim() : undefined
25
+ };
26
+ } catch {
27
+ return { ...DEFAULT_SETTINGS };
28
+ }
29
+ }
30
+
31
+ export async function writeSettings(cwd: string, settings: ProdoSettings): Promise<string> {
32
+ const path = settingsPath(cwd);
33
+ await fs.writeFile(path, `${JSON.stringify(settings, null, 2)}\n`, "utf8");
34
+ return path;
35
+ }
@@ -0,0 +1,45 @@
1
+ import nunjucks from "nunjucks";
2
+
3
+ const env = new nunjucks.Environment(null, {
4
+ autoescape: false,
5
+ throwOnUndefined: false,
6
+ trimBlocks: false,
7
+ lstripBlocks: false
8
+ });
9
+
10
+ env.addFilter("slug", (value: string): string => {
11
+ return (value || "")
12
+ .toLowerCase()
13
+ .replace(/[^a-z0-9]+/g, "-")
14
+ .replace(/^-+|-+$/g, "") || "item";
15
+ });
16
+
17
+ env.addFilter("bold", (value: string): string => {
18
+ return `**${value ?? ""}**`;
19
+ });
20
+
21
+ env.addFilter("dateFormat", (value: string | Date | undefined): string => {
22
+ if (!value) return new Date().toISOString().split("T")[0];
23
+ const d = typeof value === "string" ? new Date(value) : value;
24
+ return d.toISOString().split("T")[0];
25
+ });
26
+
27
+ env.addFilter("upper", (value: string): string => {
28
+ return (value ?? "").toUpperCase();
29
+ });
30
+
31
+ env.addFilter("default", (value: unknown, fallback: string): string => {
32
+ if (value === null || value === undefined || value === "") return fallback;
33
+ return String(value);
34
+ });
35
+
36
+ export function renderTemplate(
37
+ content: string,
38
+ context: Record<string, unknown>
39
+ ): string {
40
+ return env.renderString(content, context);
41
+ }
42
+
43
+ export function getTemplateEnv(): nunjucks.Environment {
44
+ return env;
45
+ }
@@ -1,54 +1,54 @@
1
- import fs from "node:fs/promises";
2
- import {
3
- overrideTemplateCandidatePaths,
4
- templateCandidatePaths
5
- } from "./paths";
6
- import { extractRequiredHeadings } from "./markdown";
7
- import type { ArtifactType } from "./types";
8
- import { fileExists } from "./utils";
9
-
10
- type ResolveOptions = {
11
- cwd: string;
12
- artifactType: ArtifactType;
13
- };
14
-
15
- export async function resolveTemplate(options: ResolveOptions): Promise<{ path: string; content: string } | null> {
16
- const { cwd, artifactType } = options;
17
- const candidates: string[] = [
18
- ...overrideTemplateCandidatePaths(cwd, artifactType),
19
- ...templateCandidatePaths(cwd, artifactType)
20
- ];
21
-
22
- for (const filePath of candidates) {
23
- if (await fileExists(filePath)) {
24
- const content = await fs.readFile(filePath, "utf8");
25
- return { path: filePath, content };
26
- }
27
- }
28
- return null;
29
- }
30
-
31
- export async function resolveCompanionTemplate(
32
- options: ResolveOptions
33
- ): Promise<{ path: string; content: string } | null> {
34
- const { cwd, artifactType } = options;
35
- const nativeExt = artifactType === "workflow" ? ".mmd" : artifactType === "wireframe" ? ".html" : null;
36
- if (!nativeExt) return null;
37
-
38
- const candidates: string[] = [
39
- ...overrideTemplateCandidatePaths(cwd, artifactType),
40
- ...templateCandidatePaths(cwd, artifactType)
41
- ].filter((candidate) => candidate.toLowerCase().endsWith(nativeExt));
42
-
43
- for (const filePath of candidates) {
44
- if (await fileExists(filePath)) {
45
- const content = await fs.readFile(filePath, "utf8");
46
- return { path: filePath, content };
47
- }
48
- }
49
- return null;
50
- }
51
-
52
- export function extractRequiredHeadingsFromTemplate(content: string): string[] {
53
- return extractRequiredHeadings(content);
54
- }
1
+ import fs from "node:fs/promises";
2
+ import {
3
+ overrideTemplateCandidatePaths,
4
+ templateCandidatePaths
5
+ } from "./paths";
6
+ import { extractRequiredHeadings } from "./markdown";
7
+ import type { ArtifactType } from "./types";
8
+ import { fileExists } from "./utils";
9
+
10
+ type ResolveOptions = {
11
+ cwd: string;
12
+ artifactType: ArtifactType;
13
+ };
14
+
15
+ export async function resolveTemplate(options: ResolveOptions): Promise<{ path: string; content: string } | null> {
16
+ const { cwd, artifactType } = options;
17
+ const candidates: string[] = [
18
+ ...overrideTemplateCandidatePaths(cwd, artifactType),
19
+ ...templateCandidatePaths(cwd, artifactType)
20
+ ];
21
+
22
+ for (const filePath of candidates) {
23
+ if (await fileExists(filePath)) {
24
+ const content = await fs.readFile(filePath, "utf8");
25
+ return { path: filePath, content };
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+
31
+ export async function resolveCompanionTemplate(
32
+ options: ResolveOptions
33
+ ): Promise<{ path: string; content: string } | null> {
34
+ const { cwd, artifactType } = options;
35
+ const nativeExt = artifactType === "workflow" ? ".mmd" : artifactType === "wireframe" ? ".html" : null;
36
+ if (!nativeExt) return null;
37
+
38
+ const candidates: string[] = [
39
+ ...overrideTemplateCandidatePaths(cwd, artifactType),
40
+ ...templateCandidatePaths(cwd, artifactType)
41
+ ].filter((candidate) => candidate.toLowerCase().endsWith(nativeExt));
42
+
43
+ for (const filePath of candidates) {
44
+ if (await fileExists(filePath)) {
45
+ const content = await fs.readFile(filePath, "utf8");
46
+ return { path: filePath, content };
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+
52
+ export function extractRequiredHeadingsFromTemplate(content: string): string[] {
53
+ return extractRequiredHeadings(content);
54
+ }