sdd-cli 0.1.19 → 0.1.21

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 (60) hide show
  1. package/README.md +41 -0
  2. package/dist/cli.js +58 -3
  3. package/dist/commands/ai-exec.js +3 -2
  4. package/dist/commands/ai-status.js +2 -1
  5. package/dist/commands/doctor.d.ts +1 -1
  6. package/dist/commands/doctor.js +218 -10
  7. package/dist/commands/gen-architecture.js +6 -5
  8. package/dist/commands/gen-best-practices.js +6 -5
  9. package/dist/commands/gen-functional-spec.js +6 -5
  10. package/dist/commands/gen-project-readme.js +6 -5
  11. package/dist/commands/gen-technical-spec.js +6 -5
  12. package/dist/commands/gen-utils.js +2 -1
  13. package/dist/commands/hello.js +27 -9
  14. package/dist/commands/import-issue.js +3 -2
  15. package/dist/commands/import-jira.d.ts +1 -0
  16. package/dist/commands/import-jira.js +127 -0
  17. package/dist/commands/learn-deliver.js +6 -5
  18. package/dist/commands/learn-refine.js +8 -7
  19. package/dist/commands/learn-start.js +3 -2
  20. package/dist/commands/list.js +19 -4
  21. package/dist/commands/pr-audit.js +6 -5
  22. package/dist/commands/pr-bridge-check.d.ts +1 -0
  23. package/dist/commands/pr-bridge-check.js +88 -0
  24. package/dist/commands/pr-bridge.d.ts +1 -0
  25. package/dist/commands/pr-bridge.js +124 -0
  26. package/dist/commands/pr-finish.js +6 -5
  27. package/dist/commands/pr-report.js +6 -5
  28. package/dist/commands/pr-respond.js +7 -6
  29. package/dist/commands/pr-risk.d.ts +1 -0
  30. package/dist/commands/pr-risk.js +112 -0
  31. package/dist/commands/pr-start.js +4 -3
  32. package/dist/commands/quickstart.js +10 -1
  33. package/dist/commands/req-archive.js +4 -3
  34. package/dist/commands/req-create.js +8 -7
  35. package/dist/commands/req-export.js +4 -3
  36. package/dist/commands/req-finish.js +9 -8
  37. package/dist/commands/req-lint.js +16 -6
  38. package/dist/commands/req-list.js +4 -3
  39. package/dist/commands/req-plan.js +12 -11
  40. package/dist/commands/req-refine.js +9 -8
  41. package/dist/commands/req-report.js +10 -9
  42. package/dist/commands/req-start.js +10 -9
  43. package/dist/commands/req-status.js +4 -3
  44. package/dist/commands/route.js +19 -4
  45. package/dist/commands/scope-list.d.ts +1 -0
  46. package/dist/commands/scope-list.js +16 -0
  47. package/dist/commands/scope-status.d.ts +1 -0
  48. package/dist/commands/scope-status.js +33 -0
  49. package/dist/commands/status.js +16 -7
  50. package/dist/commands/test-plan.js +6 -5
  51. package/dist/context/flags.d.ts +2 -0
  52. package/dist/context/flags.js +9 -1
  53. package/dist/errors.d.ts +2 -0
  54. package/dist/errors.js +10 -0
  55. package/dist/paths.js +4 -0
  56. package/dist/telemetry/local-metrics.d.ts +2 -0
  57. package/dist/telemetry/local-metrics.js +85 -0
  58. package/dist/workspace/index.d.ts +4 -0
  59. package/dist/workspace/index.js +129 -27
  60. package/package.json +24 -2
@@ -0,0 +1,124 @@
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.runPrBridge = runPrBridge;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const gen_utils_1 = require("./gen-utils");
11
+ const pr_utils_1 = require("./pr-utils");
12
+ const errors_1 = require("../errors");
13
+ const PR_ARTIFACTS = [
14
+ "review.json",
15
+ "pr-comment-audit.md",
16
+ "pr-comment-lifecycle.md",
17
+ "pr-metrics.md",
18
+ "pr-review-summary.md",
19
+ "pr-review-report.md",
20
+ "responses"
21
+ ];
22
+ function copyPrArtifacts(prDir, targetDir) {
23
+ const copied = [];
24
+ fs_1.default.mkdirSync(targetDir, { recursive: true });
25
+ for (const name of PR_ARTIFACTS) {
26
+ const source = path_1.default.join(prDir, name);
27
+ if (!fs_1.default.existsSync(source)) {
28
+ continue;
29
+ }
30
+ const target = path_1.default.join(targetDir, name);
31
+ fs_1.default.cpSync(source, target, { recursive: true });
32
+ copied.push(name);
33
+ }
34
+ return copied;
35
+ }
36
+ function upsertPrLinks(requirementDir, entry) {
37
+ const linksPath = path_1.default.join(requirementDir, "pr-links.json");
38
+ let links = [];
39
+ if (fs_1.default.existsSync(linksPath)) {
40
+ try {
41
+ const raw = fs_1.default.readFileSync(linksPath, "utf-8");
42
+ const parsed = JSON.parse(raw);
43
+ if (Array.isArray(parsed)) {
44
+ links = parsed;
45
+ }
46
+ }
47
+ catch {
48
+ links = [];
49
+ }
50
+ }
51
+ const next = links.filter((item) => item.prId !== entry.prId);
52
+ next.push(entry);
53
+ fs_1.default.writeFileSync(linksPath, JSON.stringify(next, null, 2), "utf-8");
54
+ }
55
+ function appendChangelog(requirementDir, message) {
56
+ const changelogPath = path_1.default.join(requirementDir, "changelog.md");
57
+ if (!fs_1.default.existsSync(changelogPath)) {
58
+ fs_1.default.writeFileSync(changelogPath, "# Changelog\n\n", "utf-8");
59
+ }
60
+ fs_1.default.appendFileSync(changelogPath, `\n- ${new Date().toISOString()} ${message}\n`, "utf-8");
61
+ }
62
+ async function runPrBridge() {
63
+ const projectName = await (0, prompt_1.askProjectName)();
64
+ if (!projectName) {
65
+ (0, errors_1.printError)("SDD-1311", "Project name is required.");
66
+ return;
67
+ }
68
+ let available = [];
69
+ try {
70
+ available = (0, pr_utils_1.listPrReviews)(projectName);
71
+ }
72
+ catch (error) {
73
+ (0, errors_1.printError)("SDD-1312", error.message);
74
+ return;
75
+ }
76
+ if (available.length > 0) {
77
+ console.log("Available PR reviews:");
78
+ available.forEach((item) => console.log(`- ${item}`));
79
+ }
80
+ const prId = await (0, prompt_1.ask)("PR ID: ");
81
+ if (!prId) {
82
+ (0, errors_1.printError)("SDD-1313", "PR ID is required.");
83
+ return;
84
+ }
85
+ let prDir;
86
+ try {
87
+ prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
88
+ }
89
+ catch (error) {
90
+ (0, errors_1.printError)("SDD-1314", error.message);
91
+ return;
92
+ }
93
+ if (!fs_1.default.existsSync(prDir)) {
94
+ (0, errors_1.printError)("SDD-1315", `PR review not found at ${prDir}`);
95
+ return;
96
+ }
97
+ const reqId = await (0, prompt_1.ask)("Requirement ID (REQ-...): ");
98
+ if (!reqId) {
99
+ (0, errors_1.printError)("SDD-1316", "Requirement ID is required.");
100
+ return;
101
+ }
102
+ const requirementDir = (0, gen_utils_1.findRequirementDir)(projectName, reqId);
103
+ if (!requirementDir) {
104
+ (0, errors_1.printError)("SDD-1317", `Requirement not found: ${reqId}`);
105
+ return;
106
+ }
107
+ const bridgeDir = path_1.default.join(requirementDir, "pr-review", prId);
108
+ const copiedArtifacts = copyPrArtifacts(prDir, bridgeDir);
109
+ const linkedAt = new Date().toISOString();
110
+ upsertPrLinks(requirementDir, {
111
+ prId,
112
+ prDir,
113
+ requirementDir,
114
+ copiedArtifacts,
115
+ linkedAt
116
+ });
117
+ const summary = copiedArtifacts.length > 0
118
+ ? `linked PR review ${prId} into ${reqId}: ${copiedArtifacts.join(", ")}`
119
+ : `linked PR review ${prId} into ${reqId} (no known artifacts copied)`;
120
+ (0, gen_utils_1.appendProgress)(requirementDir, summary);
121
+ appendChangelog(requirementDir, summary);
122
+ console.log(`PR review ${prId} linked to requirement ${reqId}.`);
123
+ console.log(`Bridge directory: ${bridgeDir}`);
124
+ }
@@ -10,10 +10,11 @@ const prompt_1 = require("../ui/prompt");
10
10
  const render_1 = require("../templates/render");
11
11
  const list_1 = require("../utils/list");
12
12
  const pr_utils_1 = require("./pr-utils");
13
+ const errors_1 = require("../errors");
13
14
  async function runPrFinish() {
14
15
  const projectName = await (0, prompt_1.askProjectName)();
15
16
  if (!projectName) {
16
- console.log("Project name is required.");
17
+ (0, errors_1.printError)("SDD-1351", "Project name is required.");
17
18
  return;
18
19
  }
19
20
  let available = [];
@@ -21,7 +22,7 @@ async function runPrFinish() {
21
22
  available = (0, pr_utils_1.listPrReviews)(projectName);
22
23
  }
23
24
  catch (error) {
24
- console.log(error.message);
25
+ (0, errors_1.printError)("SDD-1352", error.message);
25
26
  return;
26
27
  }
27
28
  if (available.length > 0) {
@@ -30,7 +31,7 @@ async function runPrFinish() {
30
31
  }
31
32
  const prId = await (0, prompt_1.ask)("PR ID: ");
32
33
  if (!prId) {
33
- console.log("PR ID is required.");
34
+ (0, errors_1.printError)("SDD-1353", "PR ID is required.");
34
35
  return;
35
36
  }
36
37
  let prDir;
@@ -38,11 +39,11 @@ async function runPrFinish() {
38
39
  prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
39
40
  }
40
41
  catch (error) {
41
- console.log(error.message);
42
+ (0, errors_1.printError)("SDD-1354", error.message);
42
43
  return;
43
44
  }
44
45
  if (!fs_1.default.existsSync(prDir)) {
45
- console.log(`PR review not found at ${prDir}`);
46
+ (0, errors_1.printError)("SDD-1355", `PR review not found at ${prDir}`);
46
47
  return;
47
48
  }
48
49
  const prLink = await (0, prompt_1.ask)("PR link: ");
@@ -10,10 +10,11 @@ const prompt_1 = require("../ui/prompt");
10
10
  const render_1 = require("../templates/render");
11
11
  const list_1 = require("../utils/list");
12
12
  const pr_utils_1 = require("./pr-utils");
13
+ const errors_1 = require("../errors");
13
14
  async function runPrReport() {
14
15
  const projectName = await (0, prompt_1.askProjectName)();
15
16
  if (!projectName) {
16
- console.log("Project name is required.");
17
+ (0, errors_1.printError)("SDD-1341", "Project name is required.");
17
18
  return;
18
19
  }
19
20
  let available = [];
@@ -21,7 +22,7 @@ async function runPrReport() {
21
22
  available = (0, pr_utils_1.listPrReviews)(projectName);
22
23
  }
23
24
  catch (error) {
24
- console.log(error.message);
25
+ (0, errors_1.printError)("SDD-1342", error.message);
25
26
  return;
26
27
  }
27
28
  if (available.length > 0) {
@@ -30,7 +31,7 @@ async function runPrReport() {
30
31
  }
31
32
  const prId = await (0, prompt_1.ask)("PR ID: ");
32
33
  if (!prId) {
33
- console.log("PR ID is required.");
34
+ (0, errors_1.printError)("SDD-1343", "PR ID is required.");
34
35
  return;
35
36
  }
36
37
  let prDir;
@@ -38,11 +39,11 @@ async function runPrReport() {
38
39
  prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
39
40
  }
40
41
  catch (error) {
41
- console.log(error.message);
42
+ (0, errors_1.printError)("SDD-1344", error.message);
42
43
  return;
43
44
  }
44
45
  if (!fs_1.default.existsSync(prDir)) {
45
- console.log(`PR review not found at ${prDir}`);
46
+ (0, errors_1.printError)("SDD-1345", `PR review not found at ${prDir}`);
46
47
  return;
47
48
  }
48
49
  const prLink = await (0, prompt_1.ask)("PR link: ");
@@ -9,6 +9,7 @@ const path_1 = __importDefault(require("path"));
9
9
  const prompt_1 = require("../ui/prompt");
10
10
  const render_1 = require("../templates/render");
11
11
  const pr_utils_1 = require("./pr-utils");
12
+ const errors_1 = require("../errors");
12
13
  function sanitizeId(value) {
13
14
  return value
14
15
  .trim()
@@ -20,7 +21,7 @@ function sanitizeId(value) {
20
21
  async function runPrRespond() {
21
22
  const projectName = await (0, prompt_1.askProjectName)();
22
23
  if (!projectName) {
23
- console.log("Project name is required.");
24
+ (0, errors_1.printError)("SDD-1356", "Project name is required.");
24
25
  return;
25
26
  }
26
27
  let available = [];
@@ -28,7 +29,7 @@ async function runPrRespond() {
28
29
  available = (0, pr_utils_1.listPrReviews)(projectName);
29
30
  }
30
31
  catch (error) {
31
- console.log(error.message);
32
+ (0, errors_1.printError)("SDD-1357", error.message);
32
33
  return;
33
34
  }
34
35
  if (available.length > 0) {
@@ -37,7 +38,7 @@ async function runPrRespond() {
37
38
  }
38
39
  const prId = await (0, prompt_1.ask)("PR ID: ");
39
40
  if (!prId) {
40
- console.log("PR ID is required.");
41
+ (0, errors_1.printError)("SDD-1358", "PR ID is required.");
41
42
  return;
42
43
  }
43
44
  let prDir;
@@ -45,11 +46,11 @@ async function runPrRespond() {
45
46
  prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
46
47
  }
47
48
  catch (error) {
48
- console.log(error.message);
49
+ (0, errors_1.printError)("SDD-1359", error.message);
49
50
  return;
50
51
  }
51
52
  if (!fs_1.default.existsSync(prDir)) {
52
- console.log(`PR review not found at ${prDir}`);
53
+ (0, errors_1.printError)("SDD-1360", `PR review not found at ${prDir}`);
53
54
  return;
54
55
  }
55
56
  const prLink = await (0, prompt_1.ask)("PR link (optional): ");
@@ -59,7 +60,7 @@ async function runPrRespond() {
59
60
  const evidence = await (0, prompt_1.ask)("Evidence: ");
60
61
  const responseText = await (0, prompt_1.ask)("Response text: ");
61
62
  if (!commentId) {
62
- console.log("Comment ID is required.");
63
+ (0, errors_1.printError)("SDD-1361", "Comment ID is required.");
63
64
  return;
64
65
  }
65
66
  const responseTemplate = (0, render_1.loadTemplate)("pr-response-generator");
@@ -0,0 +1 @@
1
+ export declare function runPrRisk(): Promise<void>;
@@ -0,0 +1,112 @@
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.runPrRisk = runPrRisk;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const prompt_1 = require("../ui/prompt");
10
+ const pr_utils_1 = require("./pr-utils");
11
+ const errors_1 = require("../errors");
12
+ function parseResponseFile(filePath) {
13
+ const raw = fs_1.default.readFileSync(filePath, "utf-8");
14
+ const severityMatch = raw.match(/- Severity:\s*([^\n\r]+)/i);
15
+ const decisionMatch = raw.match(/- Decision:\s*([^\n\r]+)/i);
16
+ if (!severityMatch && !decisionMatch) {
17
+ return null;
18
+ }
19
+ return {
20
+ file: path_1.default.basename(filePath),
21
+ severity: (severityMatch?.[1] || "unknown").trim().toLowerCase(),
22
+ decision: (decisionMatch?.[1] || "unknown").trim().toLowerCase()
23
+ };
24
+ }
25
+ async function runPrRisk() {
26
+ const projectName = await (0, prompt_1.askProjectName)();
27
+ if (!projectName) {
28
+ (0, errors_1.printError)("SDD-1321", "Project name is required.");
29
+ return;
30
+ }
31
+ let available = [];
32
+ try {
33
+ available = (0, pr_utils_1.listPrReviews)(projectName);
34
+ }
35
+ catch (error) {
36
+ (0, errors_1.printError)("SDD-1322", error.message);
37
+ return;
38
+ }
39
+ if (available.length > 0) {
40
+ console.log("Available PR reviews:");
41
+ available.forEach((item) => console.log(`- ${item}`));
42
+ }
43
+ const prId = await (0, prompt_1.ask)("PR ID: ");
44
+ if (!prId) {
45
+ (0, errors_1.printError)("SDD-1323", "PR ID is required.");
46
+ return;
47
+ }
48
+ let prDir;
49
+ try {
50
+ prDir = (0, pr_utils_1.resolvePrDir)(projectName, prId);
51
+ }
52
+ catch (error) {
53
+ (0, errors_1.printError)("SDD-1324", error.message);
54
+ return;
55
+ }
56
+ if (!fs_1.default.existsSync(prDir)) {
57
+ (0, errors_1.printError)("SDD-1325", `PR review not found at ${prDir}`);
58
+ return;
59
+ }
60
+ const responsesDir = path_1.default.join(prDir, "responses");
61
+ if (!fs_1.default.existsSync(responsesDir)) {
62
+ (0, errors_1.printError)("SDD-1326", "No responses directory found. Run `pr respond` first.");
63
+ return;
64
+ }
65
+ const responseFiles = fs_1.default
66
+ .readdirSync(responsesDir, { withFileTypes: true })
67
+ .filter((entry) => entry.isFile() && entry.name.endsWith(".md"))
68
+ .map((entry) => path_1.default.join(responsesDir, entry.name));
69
+ const parsed = responseFiles
70
+ .map((filePath) => parseResponseFile(filePath))
71
+ .filter((item) => Boolean(item));
72
+ const severityCounts = parsed.reduce((acc, item) => {
73
+ acc[item.severity] = (acc[item.severity] || 0) + 1;
74
+ return acc;
75
+ }, {});
76
+ const decisionCounts = parsed.reduce((acc, item) => {
77
+ acc[item.decision] = (acc[item.decision] || 0) + 1;
78
+ return acc;
79
+ }, {});
80
+ const unresolved = parsed.filter((item) => ["defer", "disagree", "unknown"].includes(item.decision));
81
+ const riskJson = {
82
+ prId,
83
+ generatedAt: new Date().toISOString(),
84
+ responsesAnalyzed: parsed.length,
85
+ severityCounts,
86
+ decisionCounts,
87
+ unresolved: unresolved.map((item) => ({ file: item.file, severity: item.severity, decision: item.decision }))
88
+ };
89
+ fs_1.default.writeFileSync(path_1.default.join(prDir, "pr-risk-summary.json"), JSON.stringify(riskJson, null, 2), "utf-8");
90
+ const lines = [
91
+ `# PR Risk Summary: ${prId}`,
92
+ "",
93
+ `- Responses analyzed: ${parsed.length}`,
94
+ `- Blocker: ${severityCounts.blocker || 0}`,
95
+ `- High: ${severityCounts.high || 0}`,
96
+ `- Medium: ${severityCounts.medium || 0}`,
97
+ `- Low: ${severityCounts.low || 0}`,
98
+ `- Unresolved comments: ${unresolved.length}`,
99
+ "",
100
+ "## Unresolved details"
101
+ ];
102
+ if (unresolved.length === 0) {
103
+ lines.push("- None");
104
+ }
105
+ else {
106
+ unresolved.forEach((item) => {
107
+ lines.push(`- ${item.file}: severity=${item.severity}, decision=${item.decision}`);
108
+ });
109
+ }
110
+ fs_1.default.writeFileSync(path_1.default.join(prDir, "pr-risk-summary.md"), `${lines.join("\n")}\n`, "utf-8");
111
+ console.log(`PR risk summary written to ${path_1.default.join(prDir, "pr-risk-summary.md")}`);
112
+ }
@@ -10,15 +10,16 @@ const prompt_1 = require("../ui/prompt");
10
10
  const render_1 = require("../templates/render");
11
11
  const list_1 = require("../utils/list");
12
12
  const pr_utils_1 = require("./pr-utils");
13
+ const errors_1 = require("../errors");
13
14
  async function runPrStart() {
14
15
  const projectName = await (0, prompt_1.askProjectName)();
15
16
  if (!projectName) {
16
- console.log("Project name is required.");
17
+ (0, errors_1.printError)("SDD-1301", "Project name is required.");
17
18
  return;
18
19
  }
19
20
  const prLink = await (0, prompt_1.ask)("PR link: ");
20
21
  if (!prLink) {
21
- console.log("PR link is required.");
22
+ (0, errors_1.printError)("SDD-1302", "PR link is required.");
22
23
  return;
23
24
  }
24
25
  const prIdInput = await (0, prompt_1.ask)("PR ID (optional): ");
@@ -40,7 +41,7 @@ async function runPrStart() {
40
41
  context = (0, pr_utils_1.ensurePrReviewDir)(projectName, prLink, prIdInput);
41
42
  }
42
43
  catch (error) {
43
- console.log(error.message);
44
+ (0, errors_1.printError)("SDD-1303", error.message);
44
45
  return;
45
46
  }
46
47
  const reviewMeta = {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runQuickstart = runQuickstart;
4
4
  const flags_1 = require("../context/flags");
5
5
  const hello_1 = require("./hello");
6
+ const errors_1 = require("../errors");
6
7
  const QUICKSTART_EXAMPLES = {
7
8
  saas: "Build a SaaS onboarding workflow for first-time users",
8
9
  bugfix: "Fix a high-priority login failure with reproducible steps and tests",
@@ -12,7 +13,10 @@ const QUICKSTART_EXAMPLES = {
12
13
  };
13
14
  function normalizeExample(example) {
14
15
  const value = (example || "saas").trim().toLowerCase();
15
- return QUICKSTART_EXAMPLES[value] ? value : "saas";
16
+ if (!example) {
17
+ return "saas";
18
+ }
19
+ return QUICKSTART_EXAMPLES[value] ? value : null;
16
20
  }
17
21
  async function runQuickstart(example, listExamples) {
18
22
  if (listExamples) {
@@ -23,6 +27,11 @@ async function runQuickstart(example, listExamples) {
23
27
  return;
24
28
  }
25
29
  const selected = normalizeExample(example);
30
+ if (!selected) {
31
+ (0, errors_1.printError)("SDD-1011", `Invalid quickstart example: ${example}`);
32
+ (0, errors_1.printError)("SDD-1011", `Available examples: ${Object.keys(QUICKSTART_EXAMPLES).join(", ")}`);
33
+ return;
34
+ }
26
35
  const seed = QUICKSTART_EXAMPLES[selected];
27
36
  console.log(`Running quickstart example: ${selected}`);
28
37
  (0, flags_1.setFlags)({ nonInteractive: true });
@@ -8,6 +8,7 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const prompt_1 = require("../ui/prompt");
10
10
  const index_1 = require("../workspace/index");
11
+ const errors_1 = require("../errors");
11
12
  function findDoneRequirement(projectRoot, reqId) {
12
13
  const done = path_1.default.join(projectRoot, "requirements", "done", reqId);
13
14
  return fs_1.default.existsSync(done) ? done : null;
@@ -16,7 +17,7 @@ async function runReqArchive() {
16
17
  const projectName = await (0, prompt_1.askProjectName)();
17
18
  const reqId = await (0, prompt_1.ask)("Requirement ID (REQ-...): ");
18
19
  if (!projectName || !reqId) {
19
- console.log("Project name and requirement ID are required.");
20
+ (0, errors_1.printError)("SDD-1241", "Project name and requirement ID are required.");
20
21
  return;
21
22
  }
22
23
  const workspace = (0, index_1.getWorkspaceInfo)();
@@ -25,12 +26,12 @@ async function runReqArchive() {
25
26
  project = (0, index_1.getProjectInfo)(workspace, projectName);
26
27
  }
27
28
  catch (error) {
28
- console.log(error.message);
29
+ (0, errors_1.printError)("SDD-1242", error.message);
29
30
  return;
30
31
  }
31
32
  const doneDir = findDoneRequirement(project.root, reqId);
32
33
  if (!doneDir) {
33
- console.log("Requirement not found in done.");
34
+ (0, errors_1.printError)("SDD-1243", "Requirement not found in done.");
34
35
  return;
35
36
  }
36
37
  const archiveDir = path_1.default.join(project.root, "requirements", "archived", reqId);
@@ -12,6 +12,7 @@ const render_1 = require("../templates/render");
12
12
  const list_1 = require("../utils/list");
13
13
  const gates_1 = require("../validation/gates");
14
14
  const validate_1 = require("../validation/validate");
15
+ const errors_1 = require("../errors");
15
16
  function generateId() {
16
17
  const now = new Date();
17
18
  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")}`;
@@ -21,7 +22,7 @@ async function runReqCreate(draft, options) {
21
22
  const auto = Boolean(options?.autofill);
22
23
  const projectName = draft?.project_name?.trim() || (await (0, prompt_1.askProjectName)());
23
24
  if (!projectName) {
24
- console.log("Project name is required.");
25
+ (0, errors_1.printError)("SDD-1201", "Project name is required.");
25
26
  return null;
26
27
  }
27
28
  const domain = draft?.domain ?? (auto ? "software" : await (0, prompt_1.ask)("Domain (software, legal, design, learning, etc): "));
@@ -43,7 +44,7 @@ async function runReqCreate(draft, options) {
43
44
  project = (0, index_1.getProjectInfo)(workspace, projectName);
44
45
  }
45
46
  catch (error) {
46
- console.log(error.message);
47
+ (0, errors_1.printError)("SDD-1202", error.message);
47
48
  return null;
48
49
  }
49
50
  const metadata = (0, index_1.createProject)(workspace, project.name, domain || "software");
@@ -72,7 +73,7 @@ async function runReqCreate(draft, options) {
72
73
  };
73
74
  let gates = (0, gates_1.checkRequirementGates)(requirementJson);
74
75
  if (!gates.ok) {
75
- console.log("Requirement gates failed. Please provide missing fields:");
76
+ (0, errors_1.printError)("SDD-1205", "Requirement gates failed. Please provide missing fields.");
76
77
  if (auto) {
77
78
  if (gates.missing.includes("objective"))
78
79
  objective = "Initial requirement draft from user intent.";
@@ -125,15 +126,15 @@ async function runReqCreate(draft, options) {
125
126
  };
126
127
  gates = (0, gates_1.checkRequirementGates)(requirementJson);
127
128
  if (!gates.ok) {
128
- console.log("Requirement gates still failing. Missing:");
129
- gates.missing.forEach((field) => console.log(`- ${field}`));
129
+ (0, errors_1.printError)("SDD-1203", "Requirement gates still failing.");
130
+ gates.missing.forEach((field) => (0, errors_1.printError)("SDD-1203", field));
130
131
  return null;
131
132
  }
132
133
  }
133
134
  const validation = (0, validate_1.validateJson)("requirement.schema.json", requirementJson);
134
135
  if (!validation.valid) {
135
- console.log("Requirement validation failed:");
136
- validation.errors.forEach((error) => console.log(`- ${error}`));
136
+ (0, errors_1.printError)("SDD-1204", "Requirement validation failed.");
137
+ validation.errors.forEach((error) => (0, errors_1.printError)("SDD-1204", error));
137
138
  return null;
138
139
  }
139
140
  const requirementDir = path_1.default.join(project.root, "requirements", "backlog", reqId);
@@ -8,12 +8,13 @@ const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const prompt_1 = require("../ui/prompt");
10
10
  const index_1 = require("../workspace/index");
11
+ const errors_1 = require("../errors");
11
12
  async function runReqExport() {
12
13
  const projectName = await (0, prompt_1.askProjectName)();
13
14
  const reqId = await (0, prompt_1.ask)("Requirement ID (REQ-...): ");
14
15
  const outputDir = await (0, prompt_1.ask)("Output directory: ");
15
16
  if (!projectName || !reqId || !outputDir) {
16
- console.log("Project name, requirement ID, and output directory are required.");
17
+ (0, errors_1.printError)("SDD-1244", "Project name, requirement ID, and output directory are required.");
17
18
  return;
18
19
  }
19
20
  const workspace = (0, index_1.getWorkspaceInfo)();
@@ -22,14 +23,14 @@ async function runReqExport() {
22
23
  project = (0, index_1.getProjectInfo)(workspace, projectName);
23
24
  }
24
25
  catch (error) {
25
- console.log(error.message);
26
+ (0, errors_1.printError)("SDD-1245", error.message);
26
27
  return;
27
28
  }
28
29
  const base = path_1.default.join(project.root, "requirements");
29
30
  const statuses = ["backlog", "wip", "in-progress", "done", "archived"];
30
31
  const sourceDir = statuses.map((status) => path_1.default.join(base, status, reqId)).find((candidate) => fs_1.default.existsSync(candidate));
31
32
  if (!sourceDir) {
32
- console.log("Requirement not found.");
33
+ (0, errors_1.printError)("SDD-1246", "Requirement not found.");
33
34
  return;
34
35
  }
35
36
  const targetDir = path_1.default.join(outputDir, `${project.name}-${reqId}`);
@@ -10,6 +10,7 @@ const prompt_1 = require("../ui/prompt");
10
10
  const index_1 = require("../workspace/index");
11
11
  const render_1 = require("../templates/render");
12
12
  const validate_1 = require("../validation/validate");
13
+ const errors_1 = require("../errors");
13
14
  function findRequirementDir(projectRoot, reqId) {
14
15
  const backlog = path_1.default.join(projectRoot, "requirements", "backlog", reqId);
15
16
  const wip = path_1.default.join(projectRoot, "requirements", "wip", reqId);
@@ -27,7 +28,7 @@ async function runReqFinish(options) {
27
28
  const projectName = options?.projectName ?? (await (0, prompt_1.askProjectName)());
28
29
  const reqId = options?.reqId ?? (await (0, prompt_1.ask)("Requirement ID (REQ-...): "));
29
30
  if (!projectName || !reqId) {
30
- console.log("Project name and requirement ID are required.");
31
+ (0, errors_1.printError)("SDD-1231", "Project name and requirement ID are required.");
31
32
  return null;
32
33
  }
33
34
  const workspace = (0, index_1.getWorkspaceInfo)();
@@ -36,12 +37,12 @@ async function runReqFinish(options) {
36
37
  project = (0, index_1.getProjectInfo)(workspace, projectName);
37
38
  }
38
39
  catch (error) {
39
- console.log(error.message);
40
+ (0, errors_1.printError)("SDD-1232", error.message);
40
41
  return null;
41
42
  }
42
43
  const requirementDir = findRequirementDir(project.root, reqId);
43
44
  if (!requirementDir) {
44
- console.log("Requirement not found.");
45
+ (0, errors_1.printError)("SDD-1233", "Requirement not found.");
45
46
  return null;
46
47
  }
47
48
  const jsonFiles = fs_1.default.readdirSync(requirementDir).filter((file) => file.endsWith(".json"));
@@ -60,8 +61,8 @@ async function runReqFinish(options) {
60
61
  const data = JSON.parse(fs_1.default.readFileSync(path_1.default.join(requirementDir, file), "utf-8"));
61
62
  const result = (0, validate_1.validateJson)(schema, data);
62
63
  if (!result.valid) {
63
- console.log(`Validation failed for ${file}:`);
64
- result.errors.forEach((error) => console.log(`- ${error}`));
64
+ (0, errors_1.printError)("SDD-1234", `Validation failed for ${file}.`);
65
+ result.errors.forEach((error) => (0, errors_1.printError)("SDD-1234", error));
65
66
  return null;
66
67
  }
67
68
  }
@@ -97,8 +98,8 @@ async function runReqFinish(options) {
97
98
  };
98
99
  const readmeValidation = (0, validate_1.validateJson)("project-readme.schema.json", readmeJson);
99
100
  if (!readmeValidation.valid) {
100
- console.log("Project README validation failed:");
101
- readmeValidation.errors.forEach((error) => console.log(`- ${error}`));
101
+ (0, errors_1.printError)("SDD-1235", "Project README validation failed.");
102
+ readmeValidation.errors.forEach((error) => (0, errors_1.printError)("SDD-1235", error));
102
103
  return null;
103
104
  }
104
105
  const sourceDir = requirementDir;
@@ -148,7 +149,7 @@ async function runReqFinish(options) {
148
149
  if (sourceStatus && sourceStatus !== "done") {
149
150
  (0, index_1.updateProjectStatus)(workspace, project.name, sourceStatus);
150
151
  }
151
- console.log(`Failed to finish requirement: ${error.message}`);
152
+ (0, errors_1.printError)("SDD-1236", `Failed to finish requirement: ${error.message}`);
152
153
  return null;
153
154
  }
154
155
  console.log(`Moved requirement to ${doneDir}`);