sdd-cli 0.1.0

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 (186) hide show
  1. package/README.md +566 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +308 -0
  4. package/dist/commands/ai-exec.d.ts +1 -0
  5. package/dist/commands/ai-exec.js +18 -0
  6. package/dist/commands/ai-status.d.ts +1 -0
  7. package/dist/commands/ai-status.js +12 -0
  8. package/dist/commands/doctor.d.ts +1 -0
  9. package/dist/commands/doctor.js +101 -0
  10. package/dist/commands/gen-architecture.d.ts +1 -0
  11. package/dist/commands/gen-architecture.js +61 -0
  12. package/dist/commands/gen-best-practices.d.ts +1 -0
  13. package/dist/commands/gen-best-practices.js +64 -0
  14. package/dist/commands/gen-functional-spec.d.ts +1 -0
  15. package/dist/commands/gen-functional-spec.js +67 -0
  16. package/dist/commands/gen-project-readme.d.ts +1 -0
  17. package/dist/commands/gen-project-readme.js +72 -0
  18. package/dist/commands/gen-requirements.d.ts +1 -0
  19. package/dist/commands/gen-requirements.js +7 -0
  20. package/dist/commands/gen-technical-spec.d.ts +1 -0
  21. package/dist/commands/gen-technical-spec.js +67 -0
  22. package/dist/commands/gen-utils.d.ts +4 -0
  23. package/dist/commands/gen-utils.js +44 -0
  24. package/dist/commands/hello.d.ts +1 -0
  25. package/dist/commands/hello.js +63 -0
  26. package/dist/commands/init.d.ts +1 -0
  27. package/dist/commands/init.js +9 -0
  28. package/dist/commands/learn-deliver.d.ts +1 -0
  29. package/dist/commands/learn-deliver.js +55 -0
  30. package/dist/commands/learn-refine.d.ts +1 -0
  31. package/dist/commands/learn-refine.js +71 -0
  32. package/dist/commands/learn-start.d.ts +1 -0
  33. package/dist/commands/learn-start.js +63 -0
  34. package/dist/commands/learn-utils.d.ts +22 -0
  35. package/dist/commands/learn-utils.js +78 -0
  36. package/dist/commands/list.d.ts +1 -0
  37. package/dist/commands/list.js +69 -0
  38. package/dist/commands/pr-audit.d.ts +1 -0
  39. package/dist/commands/pr-audit.js +59 -0
  40. package/dist/commands/pr-finish.d.ts +1 -0
  41. package/dist/commands/pr-finish.js +51 -0
  42. package/dist/commands/pr-report.d.ts +1 -0
  43. package/dist/commands/pr-report.js +59 -0
  44. package/dist/commands/pr-respond.d.ts +1 -0
  45. package/dist/commands/pr-respond.js +65 -0
  46. package/dist/commands/pr-start.d.ts +1 -0
  47. package/dist/commands/pr-start.js +79 -0
  48. package/dist/commands/pr-utils.d.ts +8 -0
  49. package/dist/commands/pr-utils.js +54 -0
  50. package/dist/commands/req-archive.d.ts +1 -0
  51. package/dist/commands/req-archive.js +33 -0
  52. package/dist/commands/req-create.d.ts +10 -0
  53. package/dist/commands/req-create.js +94 -0
  54. package/dist/commands/req-export.d.ts +1 -0
  55. package/dist/commands/req-export.js +37 -0
  56. package/dist/commands/req-finish.d.ts +1 -0
  57. package/dist/commands/req-finish.js +120 -0
  58. package/dist/commands/req-lint.d.ts +1 -0
  59. package/dist/commands/req-lint.js +58 -0
  60. package/dist/commands/req-list.d.ts +1 -0
  61. package/dist/commands/req-list.js +36 -0
  62. package/dist/commands/req-plan.d.ts +1 -0
  63. package/dist/commands/req-plan.js +200 -0
  64. package/dist/commands/req-refine.d.ts +1 -0
  65. package/dist/commands/req-refine.js +108 -0
  66. package/dist/commands/req-report.d.ts +1 -0
  67. package/dist/commands/req-report.js +44 -0
  68. package/dist/commands/req-start.d.ts +1 -0
  69. package/dist/commands/req-start.js +131 -0
  70. package/dist/commands/req-status.d.ts +1 -0
  71. package/dist/commands/req-status.js +29 -0
  72. package/dist/commands/route.d.ts +1 -0
  73. package/dist/commands/route.js +30 -0
  74. package/dist/commands/test-plan.d.ts +1 -0
  75. package/dist/commands/test-plan.js +81 -0
  76. package/dist/context/flags.d.ts +7 -0
  77. package/dist/context/flags.js +17 -0
  78. package/dist/paths.d.ts +1 -0
  79. package/dist/paths.js +10 -0
  80. package/dist/providers/codex.d.ts +7 -0
  81. package/dist/providers/codex.js +19 -0
  82. package/dist/router/flow.d.ts +1 -0
  83. package/dist/router/flow.js +17 -0
  84. package/dist/router/intent.d.ts +3 -0
  85. package/dist/router/intent.js +69 -0
  86. package/dist/router/prompt-map.d.ts +1 -0
  87. package/dist/router/prompt-map.js +20 -0
  88. package/dist/router/prompt-packs.d.ts +8 -0
  89. package/dist/router/prompt-packs.js +20 -0
  90. package/dist/router/validate-prompt-packs.d.ts +4 -0
  91. package/dist/router/validate-prompt-packs.js +16 -0
  92. package/dist/templates/render.d.ts +2 -0
  93. package/dist/templates/render.js +25 -0
  94. package/dist/templates/validate.d.ts +4 -0
  95. package/dist/templates/validate.js +58 -0
  96. package/dist/types.d.ts +7 -0
  97. package/dist/types.js +2 -0
  98. package/dist/ui/prompt.d.ts +2 -0
  99. package/dist/ui/prompt.js +49 -0
  100. package/dist/utils/list.d.ts +2 -0
  101. package/dist/utils/list.js +20 -0
  102. package/dist/validation/validate.d.ts +4 -0
  103. package/dist/validation/validate.js +20 -0
  104. package/dist/workspace/index.d.ts +21 -0
  105. package/dist/workspace/index.js +103 -0
  106. package/flows/ADMISSIONS_ADMIN.md +33 -0
  107. package/flows/ART.md +33 -0
  108. package/flows/BUG_FIX.md +32 -0
  109. package/flows/COURT_SYSTEM.md +33 -0
  110. package/flows/DATA_SCIENTIST.md +33 -0
  111. package/flows/ECOMMERCE.md +33 -0
  112. package/flows/ECONOMICS.md +33 -0
  113. package/flows/GRAPHIC_DESIGN.md +33 -0
  114. package/flows/HISTORY.md +33 -0
  115. package/flows/LAWYER.md +34 -0
  116. package/flows/PROGRAMMER.md +33 -0
  117. package/flows/PR_REVIEW.md +33 -0
  118. package/flows/README.md +29 -0
  119. package/flows/RETAIL_STORE.md +33 -0
  120. package/flows/SOCIOLOGY.md +33 -0
  121. package/flows/STATE_ADMIN.md +33 -0
  122. package/flows/STUDENT_UNIVERSITY.md +33 -0
  123. package/flows/TAXES_ADMIN.md +33 -0
  124. package/flows/TEACHER.md +33 -0
  125. package/package.json +32 -0
  126. package/router/BUG_FIX.flow.md +63 -0
  127. package/router/BUSINESS.flow.md +57 -0
  128. package/router/DATA_SCIENCE.flow.md +58 -0
  129. package/router/DESIGN.flow.md +58 -0
  130. package/router/FLOW_TEMPLATE.md +26 -0
  131. package/router/GENERIC.flow.md +37 -0
  132. package/router/HUMANITIES.flow.md +58 -0
  133. package/router/LEARN.flow.md +52 -0
  134. package/router/LEGAL.flow.md +58 -0
  135. package/router/PR_REVIEW.flow.md +55 -0
  136. package/router/README.md +23 -0
  137. package/router/SOFTWARE_FEATURE.flow.md +59 -0
  138. package/schemas/architecture.schema.json +13 -0
  139. package/schemas/decision-log.schema.json +16 -0
  140. package/schemas/diagram.schema.json +11 -0
  141. package/schemas/domain.schema.json +20 -0
  142. package/schemas/functional-spec.schema.json +15 -0
  143. package/schemas/gate.schema.json +10 -0
  144. package/schemas/learn-session.schema.json +15 -0
  145. package/schemas/pr-review.schema.json +20 -0
  146. package/schemas/progress-log.schema.json +21 -0
  147. package/schemas/project-readme.schema.json +23 -0
  148. package/schemas/project.schema.json +16 -0
  149. package/schemas/prompt-pack.schema.json +12 -0
  150. package/schemas/quality.schema.json +23 -0
  151. package/schemas/requirement.schema.json +34 -0
  152. package/schemas/role.schema.json +17 -0
  153. package/schemas/router-flow.schema.json +15 -0
  154. package/schemas/router-intent.schema.json +13 -0
  155. package/schemas/technical-spec.schema.json +15 -0
  156. package/schemas/template.schema.json +10 -0
  157. package/schemas/test-plan.schema.json +13 -0
  158. package/schemas/workspace.schema.json +12 -0
  159. package/templates/architecture.md +16 -0
  160. package/templates/changelog.md +3 -0
  161. package/templates/ci-checklist.md +14 -0
  162. package/templates/decision-log.md +16 -0
  163. package/templates/diagrams/component.mmd +3 -0
  164. package/templates/diagrams/container.mmd +3 -0
  165. package/templates/diagrams/context.mmd +3 -0
  166. package/templates/functional-spec.md +22 -0
  167. package/templates/gate-index.json +20 -0
  168. package/templates/implementation-plan.md +13 -0
  169. package/templates/pr-comment-audit.md +19 -0
  170. package/templates/pr-comment-lifecycle.md +11 -0
  171. package/templates/pr-comment-severity.md +13 -0
  172. package/templates/pr-dispute-resolution.md +16 -0
  173. package/templates/pr-metrics.md +10 -0
  174. package/templates/pr-response-generator.md +11 -0
  175. package/templates/pr-response-style.md +13 -0
  176. package/templates/pr-review-report.md +22 -0
  177. package/templates/pr-review-summary.md +16 -0
  178. package/templates/progress-log.md +6 -0
  179. package/templates/project-readme.md +19 -0
  180. package/templates/prompt-pack-index.json +127 -0
  181. package/templates/quality.yml +17 -0
  182. package/templates/requirement.md +33 -0
  183. package/templates/summary.md +10 -0
  184. package/templates/technical-spec.md +22 -0
  185. package/templates/template-index.json +212 -0
  186. package/templates/test-plan.md +16 -0
@@ -0,0 +1,69 @@
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.runList = runList;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const paths_1 = require("../paths");
10
+ const prompt_packs_1 = require("../router/prompt-packs");
11
+ const index_1 = require("../workspace/index");
12
+ function listDirectoryNames(dir, ext) {
13
+ if (!fs_1.default.existsSync(dir)) {
14
+ return [];
15
+ }
16
+ return fs_1.default
17
+ .readdirSync(dir, { withFileTypes: true })
18
+ .filter((entry) => entry.isFile() && entry.name.endsWith(ext))
19
+ .map((entry) => path_1.default.parse(entry.name).name)
20
+ .sort();
21
+ }
22
+ function runList() {
23
+ const root = (0, paths_1.getRepoRoot)();
24
+ const flows = listDirectoryNames(path_1.default.join(root, "flows"), ".md");
25
+ const routerFlows = listDirectoryNames(path_1.default.join(root, "router"), ".flow.md");
26
+ const templates = Array.from(new Set([
27
+ ...listDirectoryNames(path_1.default.join(root, "templates"), ".md"),
28
+ ...listDirectoryNames(path_1.default.join(root, "templates"), ".yml")
29
+ ])).sort();
30
+ console.log("Flows:");
31
+ if (flows.length === 0) {
32
+ console.log("- none");
33
+ }
34
+ else {
35
+ flows.forEach((flow) => console.log(`- ${flow}`));
36
+ }
37
+ console.log("Router flows:");
38
+ if (routerFlows.length === 0) {
39
+ console.log("- none");
40
+ }
41
+ else {
42
+ routerFlows.forEach((flow) => console.log(`- ${flow}`));
43
+ }
44
+ console.log("Templates:");
45
+ if (templates.length === 0) {
46
+ console.log("- none");
47
+ }
48
+ else {
49
+ templates.forEach((template) => console.log(`- ${template}`));
50
+ }
51
+ const packs = (0, prompt_packs_1.loadPromptPacks)();
52
+ console.log("Prompt packs:");
53
+ if (packs.length === 0) {
54
+ console.log("- none");
55
+ }
56
+ else {
57
+ packs.forEach((pack) => console.log(`- ${pack.id}`));
58
+ }
59
+ const workspace = (0, index_1.getWorkspaceInfo)();
60
+ (0, index_1.ensureWorkspace)(workspace);
61
+ const projects = (0, index_1.listProjects)(workspace);
62
+ console.log("Projects:");
63
+ if (projects.length === 0) {
64
+ console.log("- none");
65
+ }
66
+ else {
67
+ projects.forEach((project) => console.log(`- ${project.name} (${project.status})`));
68
+ }
69
+ }
@@ -0,0 +1 @@
1
+ export declare function runPrAudit(): Promise<void>;
@@ -0,0 +1,59 @@
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.runPrAudit = runPrAudit;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const render_1 = require("../templates/render");
11
+ const list_1 = require("../utils/list");
12
+ const pr_utils_1 = require("./pr-utils");
13
+ async function runPrAudit() {
14
+ const projectName = await (0, prompt_1.ask)("Project name: ");
15
+ if (!projectName) {
16
+ console.log("Project name is required.");
17
+ return;
18
+ }
19
+ const available = (0, pr_utils_1.listPrReviews)(projectName);
20
+ if (available.length > 0) {
21
+ console.log("Available PR reviews:");
22
+ available.forEach((item) => console.log(`- ${item}`));
23
+ }
24
+ const prId = await (0, prompt_1.ask)("PR ID: ");
25
+ if (!prId) {
26
+ console.log("PR ID is required.");
27
+ return;
28
+ }
29
+ const prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
30
+ if (!fs_1.default.existsSync(prDir)) {
31
+ console.log(`PR review not found at ${prDir}`);
32
+ return;
33
+ }
34
+ const prLink = await (0, prompt_1.ask)("PR link: ");
35
+ const prTitle = await (0, prompt_1.ask)("PR title: ");
36
+ const commentInventory = await (0, prompt_1.ask)("Comment inventory - comma separated: ");
37
+ const validComments = await (0, prompt_1.ask)("Valid comments - comma separated: ");
38
+ const debatableComments = await (0, prompt_1.ask)("Debatable comments - comma separated: ");
39
+ const recommendedResponses = await (0, prompt_1.ask)("Recommended responses - comma separated: ");
40
+ const followUps = await (0, prompt_1.ask)("Follow-ups - comma separated: ");
41
+ const lifecycleEntries = await (0, prompt_1.ask)("Comment lifecycle entries - comma separated: ");
42
+ const auditTemplate = (0, render_1.loadTemplate)("pr-comment-audit");
43
+ const audit = (0, render_1.renderTemplate)(auditTemplate, {
44
+ title: prTitle || prId,
45
+ pr_link: prLink || "N/A",
46
+ comment_inventory: (0, list_1.formatList)(commentInventory),
47
+ valid_comments: (0, list_1.formatList)(validComments),
48
+ debatable_comments: (0, list_1.formatList)(debatableComments),
49
+ recommended_responses: (0, list_1.formatList)(recommendedResponses),
50
+ follow_ups: (0, list_1.formatList)(followUps)
51
+ });
52
+ fs_1.default.writeFileSync(path_1.default.join(prDir, "pr-comment-audit.md"), audit, "utf-8");
53
+ const lifecycleTemplate = (0, render_1.loadTemplate)("pr-comment-lifecycle");
54
+ const lifecycle = (0, render_1.renderTemplate)(lifecycleTemplate, {
55
+ entries: (0, list_1.formatList)(lifecycleEntries)
56
+ });
57
+ fs_1.default.writeFileSync(path_1.default.join(prDir, "pr-comment-lifecycle.md"), lifecycle, "utf-8");
58
+ console.log(`PR audit updated in ${prDir}`);
59
+ }
@@ -0,0 +1 @@
1
+ export declare function runPrFinish(): Promise<void>;
@@ -0,0 +1,51 @@
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.runPrFinish = runPrFinish;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const render_1 = require("../templates/render");
11
+ const list_1 = require("../utils/list");
12
+ const pr_utils_1 = require("./pr-utils");
13
+ async function runPrFinish() {
14
+ const projectName = await (0, prompt_1.ask)("Project name: ");
15
+ if (!projectName) {
16
+ console.log("Project name is required.");
17
+ return;
18
+ }
19
+ const available = (0, pr_utils_1.listPrReviews)(projectName);
20
+ if (available.length > 0) {
21
+ console.log("Available PR reviews:");
22
+ available.forEach((item) => console.log(`- ${item}`));
23
+ }
24
+ const prId = await (0, prompt_1.ask)("PR ID: ");
25
+ if (!prId) {
26
+ console.log("PR ID is required.");
27
+ return;
28
+ }
29
+ const prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
30
+ if (!fs_1.default.existsSync(prDir)) {
31
+ console.log(`PR review not found at ${prDir}`);
32
+ return;
33
+ }
34
+ const prLink = await (0, prompt_1.ask)("PR link: ");
35
+ const title = await (0, prompt_1.ask)("Review title: ");
36
+ const commentAudit = await (0, prompt_1.ask)("Comment audit reference (file/path): ");
37
+ const responses = await (0, prompt_1.ask)("Responses reference (file/path): ");
38
+ const plannedFixes = await (0, prompt_1.ask)("Planned fixes - comma separated: ");
39
+ const tests = await (0, prompt_1.ask)("Tests run - comma separated: ");
40
+ const summaryTemplate = (0, render_1.loadTemplate)("pr-review-summary");
41
+ const summary = (0, render_1.renderTemplate)(summaryTemplate, {
42
+ title: title || prId,
43
+ pr_link: prLink || "N/A",
44
+ comment_audit: commentAudit || "pr-comment-audit.md",
45
+ responses: responses || "responses/",
46
+ planned_fixes: (0, list_1.formatList)(plannedFixes),
47
+ tests: (0, list_1.formatList)(tests)
48
+ });
49
+ fs_1.default.writeFileSync(path_1.default.join(prDir, "pr-review-summary.md"), summary, "utf-8");
50
+ console.log(`PR review summary written to ${path_1.default.join(prDir, "pr-review-summary.md")}`);
51
+ }
@@ -0,0 +1 @@
1
+ export declare function runPrReport(): Promise<void>;
@@ -0,0 +1,59 @@
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.runPrReport = runPrReport;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const render_1 = require("../templates/render");
11
+ const list_1 = require("../utils/list");
12
+ const pr_utils_1 = require("./pr-utils");
13
+ async function runPrReport() {
14
+ const projectName = await (0, prompt_1.ask)("Project name: ");
15
+ if (!projectName) {
16
+ console.log("Project name is required.");
17
+ return;
18
+ }
19
+ const available = (0, pr_utils_1.listPrReviews)(projectName);
20
+ if (available.length > 0) {
21
+ console.log("Available PR reviews:");
22
+ available.forEach((item) => console.log(`- ${item}`));
23
+ }
24
+ const prId = await (0, prompt_1.ask)("PR ID: ");
25
+ if (!prId) {
26
+ console.log("PR ID is required.");
27
+ return;
28
+ }
29
+ const prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
30
+ if (!fs_1.default.existsSync(prDir)) {
31
+ console.log(`PR review not found at ${prDir}`);
32
+ return;
33
+ }
34
+ const prLink = await (0, prompt_1.ask)("PR link: ");
35
+ const title = await (0, prompt_1.ask)("Report title: ");
36
+ const summary = await (0, prompt_1.ask)("Summary: ");
37
+ const totalComments = await (0, prompt_1.ask)("Total comments: ");
38
+ const resolvedComments = await (0, prompt_1.ask)("Resolved comments: ");
39
+ const openComments = await (0, prompt_1.ask)("Open comments: ");
40
+ const keyDecisions = await (0, prompt_1.ask)("Key decisions - comma separated: ");
41
+ const changesMade = await (0, prompt_1.ask)("Changes made - comma separated: ");
42
+ const testEvidence = await (0, prompt_1.ask)("Test evidence - comma separated: ");
43
+ const remainingRisks = await (0, prompt_1.ask)("Remaining risks - comma separated: ");
44
+ const reportTemplate = (0, render_1.loadTemplate)("pr-review-report");
45
+ const report = (0, render_1.renderTemplate)(reportTemplate, {
46
+ title: title || prId,
47
+ pr_link: prLink || "N/A",
48
+ summary: summary || "N/A",
49
+ total_comments: totalComments || "0",
50
+ resolved_comments: resolvedComments || "0",
51
+ open_comments: openComments || "0",
52
+ key_decisions: (0, list_1.formatList)(keyDecisions),
53
+ changes_made: (0, list_1.formatList)(changesMade),
54
+ test_evidence: (0, list_1.formatList)(testEvidence),
55
+ remaining_risks: (0, list_1.formatList)(remainingRisks)
56
+ });
57
+ fs_1.default.writeFileSync(path_1.default.join(prDir, "pr-review-report.md"), report, "utf-8");
58
+ console.log(`PR review report written to ${path_1.default.join(prDir, "pr-review-report.md")}`);
59
+ }
@@ -0,0 +1 @@
1
+ export declare function runPrRespond(): Promise<void>;
@@ -0,0 +1,65 @@
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.runPrRespond = runPrRespond;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const render_1 = require("../templates/render");
11
+ const pr_utils_1 = require("./pr-utils");
12
+ function sanitizeId(value) {
13
+ return value
14
+ .trim()
15
+ .toLowerCase()
16
+ .replace(/[^a-z0-9_-]+/g, "-")
17
+ .replace(/-+/g, "-")
18
+ .replace(/^-|-$/g, "");
19
+ }
20
+ async function runPrRespond() {
21
+ const projectName = await (0, prompt_1.ask)("Project name: ");
22
+ if (!projectName) {
23
+ console.log("Project name is required.");
24
+ return;
25
+ }
26
+ const available = (0, pr_utils_1.listPrReviews)(projectName);
27
+ if (available.length > 0) {
28
+ console.log("Available PR reviews:");
29
+ available.forEach((item) => console.log(`- ${item}`));
30
+ }
31
+ const prId = await (0, prompt_1.ask)("PR ID: ");
32
+ if (!prId) {
33
+ console.log("PR ID is required.");
34
+ return;
35
+ }
36
+ const prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
37
+ if (!fs_1.default.existsSync(prDir)) {
38
+ console.log(`PR review not found at ${prDir}`);
39
+ return;
40
+ }
41
+ const prLink = await (0, prompt_1.ask)("PR link (optional): ");
42
+ const commentId = await (0, prompt_1.ask)("Comment ID: ");
43
+ const severity = await (0, prompt_1.ask)("Severity (blocker/high/medium/low): ");
44
+ const decision = await (0, prompt_1.ask)("Decision (accept/clarify/disagree/defer): ");
45
+ const evidence = await (0, prompt_1.ask)("Evidence: ");
46
+ const responseText = await (0, prompt_1.ask)("Response text: ");
47
+ if (!commentId) {
48
+ console.log("Comment ID is required.");
49
+ return;
50
+ }
51
+ const responseTemplate = (0, render_1.loadTemplate)("pr-response-generator");
52
+ const response = (0, render_1.renderTemplate)(responseTemplate, {
53
+ pr_link: prLink || "N/A",
54
+ comment_id: commentId,
55
+ severity: severity || "N/A",
56
+ decision: decision || "N/A",
57
+ evidence: evidence || "N/A",
58
+ response_text: responseText || "N/A"
59
+ });
60
+ const responsesDir = path_1.default.join(prDir, "responses");
61
+ fs_1.default.mkdirSync(responsesDir, { recursive: true });
62
+ const fileName = `${sanitizeId(commentId)}.md`;
63
+ fs_1.default.writeFileSync(path_1.default.join(responsesDir, fileName), response, "utf-8");
64
+ console.log(`Response saved to ${path_1.default.join(responsesDir, fileName)}`);
65
+ }
@@ -0,0 +1 @@
1
+ export declare function runPrStart(): Promise<void>;
@@ -0,0 +1,79 @@
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.runPrStart = runPrStart;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const render_1 = require("../templates/render");
11
+ const list_1 = require("../utils/list");
12
+ const pr_utils_1 = require("./pr-utils");
13
+ async function runPrStart() {
14
+ const projectName = await (0, prompt_1.ask)("Project name: ");
15
+ if (!projectName) {
16
+ console.log("Project name is required.");
17
+ return;
18
+ }
19
+ const prLink = await (0, prompt_1.ask)("PR link: ");
20
+ if (!prLink) {
21
+ console.log("PR link is required.");
22
+ return;
23
+ }
24
+ const prIdInput = await (0, prompt_1.ask)("PR ID (optional): ");
25
+ const prTitle = await (0, prompt_1.ask)("PR title: ");
26
+ const approvals = await (0, prompt_1.ask)("Approvals - comma separated: ");
27
+ const commentInventory = await (0, prompt_1.ask)("Comment inventory - comma separated: ");
28
+ const validComments = await (0, prompt_1.ask)("Valid comments - comma separated: ");
29
+ const debatableComments = await (0, prompt_1.ask)("Debatable comments - comma separated: ");
30
+ const recommendedResponses = await (0, prompt_1.ask)("Recommended responses - comma separated: ");
31
+ const followUps = await (0, prompt_1.ask)("Follow-ups - comma separated: ");
32
+ const lifecycleEntries = await (0, prompt_1.ask)("Comment lifecycle entries - comma separated: ");
33
+ const totalComments = await (0, prompt_1.ask)("Total comments: ");
34
+ const blockers = await (0, prompt_1.ask)("Blockers: ");
35
+ const avgTime = await (0, prompt_1.ask)("Avg time to resolve: ");
36
+ const testsRun = await (0, prompt_1.ask)("Tests run: ");
37
+ const notes = await (0, prompt_1.ask)("Notes - comma separated: ");
38
+ const context = (0, pr_utils_1.ensurePrReviewDir)(projectName, prLink, prIdInput);
39
+ const reviewMeta = {
40
+ id: context.prId,
41
+ link: prLink,
42
+ title: prTitle || context.prId,
43
+ status: "in-review",
44
+ createdAt: new Date().toISOString()
45
+ };
46
+ fs_1.default.writeFileSync(path_1.default.join(context.prDir, "review.json"), JSON.stringify(reviewMeta, null, 2), "utf-8");
47
+ const auditTemplate = (0, render_1.loadTemplate)("pr-comment-audit");
48
+ const audit = (0, render_1.renderTemplate)(auditTemplate, {
49
+ title: prTitle || context.prId,
50
+ pr_link: prLink,
51
+ comment_inventory: (0, list_1.formatList)(commentInventory),
52
+ valid_comments: (0, list_1.formatList)(validComments),
53
+ debatable_comments: (0, list_1.formatList)(debatableComments),
54
+ recommended_responses: (0, list_1.formatList)(recommendedResponses),
55
+ follow_ups: (0, list_1.formatList)(followUps)
56
+ });
57
+ fs_1.default.writeFileSync(path_1.default.join(context.prDir, "pr-comment-audit.md"), audit, "utf-8");
58
+ const lifecycleTemplate = (0, render_1.loadTemplate)("pr-comment-lifecycle");
59
+ const lifecycle = (0, render_1.renderTemplate)(lifecycleTemplate, {
60
+ entries: (0, list_1.formatList)(lifecycleEntries)
61
+ });
62
+ fs_1.default.writeFileSync(path_1.default.join(context.prDir, "pr-comment-lifecycle.md"), lifecycle, "utf-8");
63
+ const metricsTemplate = (0, render_1.loadTemplate)("pr-metrics");
64
+ const metrics = (0, render_1.renderTemplate)(metricsTemplate, {
65
+ total_comments: totalComments || "N/A",
66
+ blockers: blockers || "N/A",
67
+ avg_time_to_resolve: avgTime || "N/A",
68
+ tests_run: testsRun || "N/A",
69
+ notes: (0, list_1.formatList)(notes)
70
+ });
71
+ fs_1.default.writeFileSync(path_1.default.join(context.prDir, "pr-metrics.md"), metrics, "utf-8");
72
+ const guidesDir = path_1.default.join(context.prDir, "guides");
73
+ fs_1.default.mkdirSync(guidesDir, { recursive: true });
74
+ const styleGuide = (0, render_1.loadTemplate)("pr-response-style");
75
+ fs_1.default.writeFileSync(path_1.default.join(guidesDir, "pr-response-style.md"), styleGuide, "utf-8");
76
+ const severityGuide = (0, render_1.loadTemplate)("pr-comment-severity");
77
+ fs_1.default.writeFileSync(path_1.default.join(guidesDir, "pr-comment-severity.md"), severityGuide, "utf-8");
78
+ console.log(`PR review initialized in ${context.prDir}`);
79
+ }
@@ -0,0 +1,8 @@
1
+ export type PrContext = {
2
+ projectName: string;
3
+ prId: string;
4
+ prDir: string;
5
+ };
6
+ export declare function ensurePrReviewDir(projectName: string, prLink: string, prIdInput?: string): PrContext;
7
+ export declare function resolvePrDir(projectName: string, prId: string): string;
8
+ export declare function listPrReviews(projectName: string): string[];
@@ -0,0 +1,54 @@
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.ensurePrReviewDir = ensurePrReviewDir;
7
+ exports.resolvePrDir = resolvePrDir;
8
+ exports.listPrReviews = listPrReviews;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const index_1 = require("../workspace/index");
12
+ function extractPrId(link) {
13
+ const match = link.match(/\/pull\/(\d+)/i);
14
+ if (match) {
15
+ return `PR-${match[1]}`;
16
+ }
17
+ return null;
18
+ }
19
+ function sanitizeId(value) {
20
+ return value
21
+ .trim()
22
+ .toUpperCase()
23
+ .replace(/[^A-Z0-9_-]+/g, "-")
24
+ .replace(/-+/g, "-")
25
+ .replace(/^-|-$/g, "");
26
+ }
27
+ function ensurePrReviewDir(projectName, prLink, prIdInput) {
28
+ const workspace = (0, index_1.getWorkspaceInfo)();
29
+ (0, index_1.ensureProject)(workspace, projectName, "software");
30
+ const derived = extractPrId(prLink);
31
+ const rawId = prIdInput?.trim() || derived || `PR-${Date.now()}`;
32
+ const prId = sanitizeId(rawId);
33
+ const prDir = path_1.default.join(workspace.root, projectName, "pr-reviews", prId);
34
+ if (!fs_1.default.existsSync(prDir)) {
35
+ fs_1.default.mkdirSync(prDir, { recursive: true });
36
+ }
37
+ return { projectName, prId, prDir };
38
+ }
39
+ function resolvePrDir(projectName, prId) {
40
+ const workspace = (0, index_1.getWorkspaceInfo)();
41
+ return path_1.default.join(workspace.root, projectName, "pr-reviews", prId);
42
+ }
43
+ function listPrReviews(projectName) {
44
+ const workspace = (0, index_1.getWorkspaceInfo)();
45
+ const root = path_1.default.join(workspace.root, projectName, "pr-reviews");
46
+ if (!fs_1.default.existsSync(root)) {
47
+ return [];
48
+ }
49
+ return fs_1.default
50
+ .readdirSync(root, { withFileTypes: true })
51
+ .filter((entry) => entry.isDirectory())
52
+ .map((entry) => entry.name)
53
+ .sort();
54
+ }
@@ -0,0 +1 @@
1
+ export declare function runReqArchive(): Promise<void>;
@@ -0,0 +1,33 @@
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.runReqArchive = runReqArchive;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const index_1 = require("../workspace/index");
11
+ function findDoneRequirement(workspaceRoot, project, reqId) {
12
+ const done = path_1.default.join(workspaceRoot, project, "requirements", "done", reqId);
13
+ return fs_1.default.existsSync(done) ? done : null;
14
+ }
15
+ async function runReqArchive() {
16
+ const projectName = await (0, prompt_1.ask)("Project name: ");
17
+ const reqId = await (0, prompt_1.ask)("Requirement ID (REQ-...): ");
18
+ if (!projectName || !reqId) {
19
+ console.log("Project name and requirement ID are required.");
20
+ return;
21
+ }
22
+ const workspace = (0, index_1.getWorkspaceInfo)();
23
+ const doneDir = findDoneRequirement(workspace.root, projectName, reqId);
24
+ if (!doneDir) {
25
+ console.log("Requirement not found in done.");
26
+ return;
27
+ }
28
+ const archiveDir = path_1.default.join(workspace.root, projectName, "requirements", "archived", reqId);
29
+ fs_1.default.mkdirSync(path_1.default.dirname(archiveDir), { recursive: true });
30
+ fs_1.default.renameSync(doneDir, archiveDir);
31
+ (0, index_1.updateProjectStatus)(workspace, projectName, "archived");
32
+ console.log(`Archived requirement in ${archiveDir}`);
33
+ }
@@ -0,0 +1,10 @@
1
+ export type RequirementDraft = {
2
+ objective?: string;
3
+ scope_in?: string;
4
+ scope_out?: string;
5
+ acceptance_criteria?: string;
6
+ nfr_security?: string;
7
+ nfr_performance?: string;
8
+ nfr_availability?: string;
9
+ };
10
+ export declare function runReqCreate(draft?: RequirementDraft): Promise<void>;
@@ -0,0 +1,94 @@
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.runReqCreate = runReqCreate;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const index_1 = require("../workspace/index");
11
+ const render_1 = require("../templates/render");
12
+ const list_1 = require("../utils/list");
13
+ const validate_1 = require("../validation/validate");
14
+ function generateId() {
15
+ const now = new Date();
16
+ const stamp = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, "0")}${String(now.getDate()).padStart(2, "0")}${String(now.getHours()).padStart(2, "0")}${String(now.getMinutes()).padStart(2, "0")}`;
17
+ return `REQ-${stamp}`;
18
+ }
19
+ async function runReqCreate(draft) {
20
+ const projectName = await (0, prompt_1.ask)("Project name: ");
21
+ const domain = await (0, prompt_1.ask)("Domain (software, legal, design, learning, etc): ");
22
+ const actors = await (0, prompt_1.ask)("Actors - comma separated: ");
23
+ const objective = draft?.objective ?? (await (0, prompt_1.ask)("Objective: "));
24
+ const scopeIn = draft?.scope_in ?? (await (0, prompt_1.ask)("Scope (in) - comma separated: "));
25
+ const scopeOut = draft?.scope_out ?? (await (0, prompt_1.ask)("Scope (out) - comma separated: "));
26
+ const acceptance = draft?.acceptance_criteria ?? (await (0, prompt_1.ask)("Acceptance criteria - comma separated: "));
27
+ const nfrSecurity = draft?.nfr_security ?? (await (0, prompt_1.ask)("NFR security: "));
28
+ const nfrPerformance = draft?.nfr_performance ?? (await (0, prompt_1.ask)("NFR performance: "));
29
+ const nfrAvailability = draft?.nfr_availability ?? (await (0, prompt_1.ask)("NFR availability: "));
30
+ const constraints = await (0, prompt_1.ask)("Constraints - comma separated: ");
31
+ const risks = await (0, prompt_1.ask)("Risks - comma separated: ");
32
+ const links = await (0, prompt_1.ask)("Links - comma separated: ");
33
+ const workspace = (0, index_1.getWorkspaceInfo)();
34
+ const metadata = (0, index_1.createProject)(workspace, projectName, domain || "software");
35
+ const reqId = generateId();
36
+ const status = "backlog";
37
+ const requirementJson = {
38
+ id: reqId,
39
+ title: projectName,
40
+ objective: objective || "N/A",
41
+ status,
42
+ actors: (0, list_1.parseList)(actors),
43
+ scope: {
44
+ in: (0, list_1.parseList)(scopeIn),
45
+ out: (0, list_1.parseList)(scopeOut)
46
+ },
47
+ acceptanceCriteria: (0, list_1.parseList)(acceptance),
48
+ nfrs: {
49
+ security: nfrSecurity || "N/A",
50
+ performance: nfrPerformance || "N/A",
51
+ availability: nfrAvailability || "N/A"
52
+ },
53
+ constraints: (0, list_1.parseList)(constraints),
54
+ risks: (0, list_1.parseList)(risks),
55
+ links: (0, list_1.parseList)(links),
56
+ updatedAt: new Date().toISOString()
57
+ };
58
+ const validation = (0, validate_1.validateJson)("requirement.schema.json", requirementJson);
59
+ if (!validation.valid) {
60
+ console.log("Requirement validation failed:");
61
+ validation.errors.forEach((error) => console.log(`- ${error}`));
62
+ return;
63
+ }
64
+ const requirementDir = path_1.default.join(workspace.root, projectName, "requirements", "backlog", reqId);
65
+ fs_1.default.mkdirSync(requirementDir, { recursive: true });
66
+ const template = (0, render_1.loadTemplate)("requirement");
67
+ const rendered = (0, render_1.renderTemplate)(template, {
68
+ title: projectName,
69
+ id: reqId,
70
+ objective: objective || "N/A",
71
+ actors: (0, list_1.formatList)(actors),
72
+ scope_in: (0, list_1.formatList)(scopeIn),
73
+ scope_out: (0, list_1.formatList)(scopeOut),
74
+ acceptance_criteria: (0, list_1.formatList)(acceptance),
75
+ nfr_security: nfrSecurity || "N/A",
76
+ nfr_performance: nfrPerformance || "N/A",
77
+ nfr_availability: nfrAvailability || "N/A",
78
+ constraints: (0, list_1.formatList)(constraints),
79
+ risks: (0, list_1.formatList)(risks),
80
+ links: (0, list_1.formatList)(links)
81
+ });
82
+ fs_1.default.writeFileSync(path_1.default.join(requirementDir, "requirement.md"), rendered, "utf-8");
83
+ fs_1.default.writeFileSync(path_1.default.join(requirementDir, "requirement.json"), JSON.stringify(requirementJson, null, 2), "utf-8");
84
+ const changelogTemplate = (0, render_1.loadTemplate)("changelog");
85
+ const changelog = (0, render_1.renderTemplate)(changelogTemplate, { date: new Date().toISOString() });
86
+ fs_1.default.writeFileSync(path_1.default.join(requirementDir, "changelog.md"), changelog, "utf-8");
87
+ const progressLogPath = path_1.default.join(requirementDir, "progress-log.md");
88
+ if (!fs_1.default.existsSync(progressLogPath)) {
89
+ fs_1.default.writeFileSync(progressLogPath, "# Progress Log\n\n", "utf-8");
90
+ }
91
+ console.log(`Created requirement in ${requirementDir}`);
92
+ console.log(`Project metadata stored in ${path_1.default.join(workspace.root, projectName, "metadata.json")}`);
93
+ console.log(`Project status: ${metadata.status}`);
94
+ }
@@ -0,0 +1 @@
1
+ export declare function runReqExport(): Promise<void>;
@@ -0,0 +1,37 @@
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.runReqExport = runReqExport;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const index_1 = require("../workspace/index");
11
+ async function runReqExport() {
12
+ const projectName = await (0, prompt_1.ask)("Project name: ");
13
+ const reqId = await (0, prompt_1.ask)("Requirement ID (REQ-...): ");
14
+ const outputDir = await (0, prompt_1.ask)("Output directory: ");
15
+ if (!projectName || !reqId || !outputDir) {
16
+ console.log("Project name, requirement ID, and output directory are required.");
17
+ return;
18
+ }
19
+ const workspace = (0, index_1.getWorkspaceInfo)();
20
+ const base = path_1.default.join(workspace.root, projectName, "requirements");
21
+ const statuses = ["backlog", "wip", "in-progress", "done", "archived"];
22
+ const sourceDir = statuses.map((status) => path_1.default.join(base, status, reqId)).find((candidate) => fs_1.default.existsSync(candidate));
23
+ if (!sourceDir) {
24
+ console.log("Requirement not found.");
25
+ return;
26
+ }
27
+ const targetDir = path_1.default.join(outputDir, `${projectName}-${reqId}`);
28
+ fs_1.default.mkdirSync(targetDir, { recursive: true });
29
+ for (const entry of fs_1.default.readdirSync(sourceDir)) {
30
+ const srcPath = path_1.default.join(sourceDir, entry);
31
+ const destPath = path_1.default.join(targetDir, entry);
32
+ if (fs_1.default.statSync(srcPath).isFile()) {
33
+ fs_1.default.copyFileSync(srcPath, destPath);
34
+ }
35
+ }
36
+ console.log(`Exported requirement artifacts to ${targetDir}`);
37
+ }
@@ -0,0 +1 @@
1
+ export declare function runReqFinish(): Promise<void>;