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.
- package/README.md +566 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +308 -0
- package/dist/commands/ai-exec.d.ts +1 -0
- package/dist/commands/ai-exec.js +18 -0
- package/dist/commands/ai-status.d.ts +1 -0
- package/dist/commands/ai-status.js +12 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +101 -0
- package/dist/commands/gen-architecture.d.ts +1 -0
- package/dist/commands/gen-architecture.js +61 -0
- package/dist/commands/gen-best-practices.d.ts +1 -0
- package/dist/commands/gen-best-practices.js +64 -0
- package/dist/commands/gen-functional-spec.d.ts +1 -0
- package/dist/commands/gen-functional-spec.js +67 -0
- package/dist/commands/gen-project-readme.d.ts +1 -0
- package/dist/commands/gen-project-readme.js +72 -0
- package/dist/commands/gen-requirements.d.ts +1 -0
- package/dist/commands/gen-requirements.js +7 -0
- package/dist/commands/gen-technical-spec.d.ts +1 -0
- package/dist/commands/gen-technical-spec.js +67 -0
- package/dist/commands/gen-utils.d.ts +4 -0
- package/dist/commands/gen-utils.js +44 -0
- package/dist/commands/hello.d.ts +1 -0
- package/dist/commands/hello.js +63 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +9 -0
- package/dist/commands/learn-deliver.d.ts +1 -0
- package/dist/commands/learn-deliver.js +55 -0
- package/dist/commands/learn-refine.d.ts +1 -0
- package/dist/commands/learn-refine.js +71 -0
- package/dist/commands/learn-start.d.ts +1 -0
- package/dist/commands/learn-start.js +63 -0
- package/dist/commands/learn-utils.d.ts +22 -0
- package/dist/commands/learn-utils.js +78 -0
- package/dist/commands/list.d.ts +1 -0
- package/dist/commands/list.js +69 -0
- package/dist/commands/pr-audit.d.ts +1 -0
- package/dist/commands/pr-audit.js +59 -0
- package/dist/commands/pr-finish.d.ts +1 -0
- package/dist/commands/pr-finish.js +51 -0
- package/dist/commands/pr-report.d.ts +1 -0
- package/dist/commands/pr-report.js +59 -0
- package/dist/commands/pr-respond.d.ts +1 -0
- package/dist/commands/pr-respond.js +65 -0
- package/dist/commands/pr-start.d.ts +1 -0
- package/dist/commands/pr-start.js +79 -0
- package/dist/commands/pr-utils.d.ts +8 -0
- package/dist/commands/pr-utils.js +54 -0
- package/dist/commands/req-archive.d.ts +1 -0
- package/dist/commands/req-archive.js +33 -0
- package/dist/commands/req-create.d.ts +10 -0
- package/dist/commands/req-create.js +94 -0
- package/dist/commands/req-export.d.ts +1 -0
- package/dist/commands/req-export.js +37 -0
- package/dist/commands/req-finish.d.ts +1 -0
- package/dist/commands/req-finish.js +120 -0
- package/dist/commands/req-lint.d.ts +1 -0
- package/dist/commands/req-lint.js +58 -0
- package/dist/commands/req-list.d.ts +1 -0
- package/dist/commands/req-list.js +36 -0
- package/dist/commands/req-plan.d.ts +1 -0
- package/dist/commands/req-plan.js +200 -0
- package/dist/commands/req-refine.d.ts +1 -0
- package/dist/commands/req-refine.js +108 -0
- package/dist/commands/req-report.d.ts +1 -0
- package/dist/commands/req-report.js +44 -0
- package/dist/commands/req-start.d.ts +1 -0
- package/dist/commands/req-start.js +131 -0
- package/dist/commands/req-status.d.ts +1 -0
- package/dist/commands/req-status.js +29 -0
- package/dist/commands/route.d.ts +1 -0
- package/dist/commands/route.js +30 -0
- package/dist/commands/test-plan.d.ts +1 -0
- package/dist/commands/test-plan.js +81 -0
- package/dist/context/flags.d.ts +7 -0
- package/dist/context/flags.js +17 -0
- package/dist/paths.d.ts +1 -0
- package/dist/paths.js +10 -0
- package/dist/providers/codex.d.ts +7 -0
- package/dist/providers/codex.js +19 -0
- package/dist/router/flow.d.ts +1 -0
- package/dist/router/flow.js +17 -0
- package/dist/router/intent.d.ts +3 -0
- package/dist/router/intent.js +69 -0
- package/dist/router/prompt-map.d.ts +1 -0
- package/dist/router/prompt-map.js +20 -0
- package/dist/router/prompt-packs.d.ts +8 -0
- package/dist/router/prompt-packs.js +20 -0
- package/dist/router/validate-prompt-packs.d.ts +4 -0
- package/dist/router/validate-prompt-packs.js +16 -0
- package/dist/templates/render.d.ts +2 -0
- package/dist/templates/render.js +25 -0
- package/dist/templates/validate.d.ts +4 -0
- package/dist/templates/validate.js +58 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.js +2 -0
- package/dist/ui/prompt.d.ts +2 -0
- package/dist/ui/prompt.js +49 -0
- package/dist/utils/list.d.ts +2 -0
- package/dist/utils/list.js +20 -0
- package/dist/validation/validate.d.ts +4 -0
- package/dist/validation/validate.js +20 -0
- package/dist/workspace/index.d.ts +21 -0
- package/dist/workspace/index.js +103 -0
- package/flows/ADMISSIONS_ADMIN.md +33 -0
- package/flows/ART.md +33 -0
- package/flows/BUG_FIX.md +32 -0
- package/flows/COURT_SYSTEM.md +33 -0
- package/flows/DATA_SCIENTIST.md +33 -0
- package/flows/ECOMMERCE.md +33 -0
- package/flows/ECONOMICS.md +33 -0
- package/flows/GRAPHIC_DESIGN.md +33 -0
- package/flows/HISTORY.md +33 -0
- package/flows/LAWYER.md +34 -0
- package/flows/PROGRAMMER.md +33 -0
- package/flows/PR_REVIEW.md +33 -0
- package/flows/README.md +29 -0
- package/flows/RETAIL_STORE.md +33 -0
- package/flows/SOCIOLOGY.md +33 -0
- package/flows/STATE_ADMIN.md +33 -0
- package/flows/STUDENT_UNIVERSITY.md +33 -0
- package/flows/TAXES_ADMIN.md +33 -0
- package/flows/TEACHER.md +33 -0
- package/package.json +32 -0
- package/router/BUG_FIX.flow.md +63 -0
- package/router/BUSINESS.flow.md +57 -0
- package/router/DATA_SCIENCE.flow.md +58 -0
- package/router/DESIGN.flow.md +58 -0
- package/router/FLOW_TEMPLATE.md +26 -0
- package/router/GENERIC.flow.md +37 -0
- package/router/HUMANITIES.flow.md +58 -0
- package/router/LEARN.flow.md +52 -0
- package/router/LEGAL.flow.md +58 -0
- package/router/PR_REVIEW.flow.md +55 -0
- package/router/README.md +23 -0
- package/router/SOFTWARE_FEATURE.flow.md +59 -0
- package/schemas/architecture.schema.json +13 -0
- package/schemas/decision-log.schema.json +16 -0
- package/schemas/diagram.schema.json +11 -0
- package/schemas/domain.schema.json +20 -0
- package/schemas/functional-spec.schema.json +15 -0
- package/schemas/gate.schema.json +10 -0
- package/schemas/learn-session.schema.json +15 -0
- package/schemas/pr-review.schema.json +20 -0
- package/schemas/progress-log.schema.json +21 -0
- package/schemas/project-readme.schema.json +23 -0
- package/schemas/project.schema.json +16 -0
- package/schemas/prompt-pack.schema.json +12 -0
- package/schemas/quality.schema.json +23 -0
- package/schemas/requirement.schema.json +34 -0
- package/schemas/role.schema.json +17 -0
- package/schemas/router-flow.schema.json +15 -0
- package/schemas/router-intent.schema.json +13 -0
- package/schemas/technical-spec.schema.json +15 -0
- package/schemas/template.schema.json +10 -0
- package/schemas/test-plan.schema.json +13 -0
- package/schemas/workspace.schema.json +12 -0
- package/templates/architecture.md +16 -0
- package/templates/changelog.md +3 -0
- package/templates/ci-checklist.md +14 -0
- package/templates/decision-log.md +16 -0
- package/templates/diagrams/component.mmd +3 -0
- package/templates/diagrams/container.mmd +3 -0
- package/templates/diagrams/context.mmd +3 -0
- package/templates/functional-spec.md +22 -0
- package/templates/gate-index.json +20 -0
- package/templates/implementation-plan.md +13 -0
- package/templates/pr-comment-audit.md +19 -0
- package/templates/pr-comment-lifecycle.md +11 -0
- package/templates/pr-comment-severity.md +13 -0
- package/templates/pr-dispute-resolution.md +16 -0
- package/templates/pr-metrics.md +10 -0
- package/templates/pr-response-generator.md +11 -0
- package/templates/pr-response-style.md +13 -0
- package/templates/pr-review-report.md +22 -0
- package/templates/pr-review-summary.md +16 -0
- package/templates/progress-log.md +6 -0
- package/templates/project-readme.md +19 -0
- package/templates/prompt-pack-index.json +127 -0
- package/templates/quality.yml +17 -0
- package/templates/requirement.md +33 -0
- package/templates/summary.md +10 -0
- package/templates/technical-spec.md +22 -0
- package/templates/template-index.json +212 -0
- package/templates/test-plan.md +16 -0
|
@@ -0,0 +1,72 @@
|
|
|
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.runGenProjectReadme = runGenProjectReadme;
|
|
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 validate_1 = require("../validation/validate");
|
|
12
|
+
const gen_utils_1 = require("./gen-utils");
|
|
13
|
+
const flags_1 = require("../context/flags");
|
|
14
|
+
async function runGenProjectReadme() {
|
|
15
|
+
const projectName = await (0, prompt_1.ask)("Project name: ");
|
|
16
|
+
const reqId = await (0, prompt_1.ask)("Requirement ID (REQ-...): ");
|
|
17
|
+
if (!projectName || !reqId) {
|
|
18
|
+
console.log("Project name and requirement ID are required.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const requirementDir = (0, gen_utils_1.findRequirementDir)(projectName, reqId);
|
|
22
|
+
if (!requirementDir) {
|
|
23
|
+
console.log("Requirement not found.");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const overview = await (0, prompt_1.ask)("Project overview: ");
|
|
27
|
+
const howToRun = await (0, prompt_1.ask)("How to run: ");
|
|
28
|
+
const architectureSummary = await (0, prompt_1.ask)("Architecture summary: ");
|
|
29
|
+
const requirementsLink = await (0, prompt_1.ask)("Requirements link/path: ");
|
|
30
|
+
const functionalSpecLink = await (0, prompt_1.ask)("Functional spec link/path: ");
|
|
31
|
+
const technicalSpecLink = await (0, prompt_1.ask)("Technical spec link/path: ");
|
|
32
|
+
const architectureLink = await (0, prompt_1.ask)("Architecture link/path: ");
|
|
33
|
+
const testingNotes = await (0, prompt_1.ask)("Testing notes: ");
|
|
34
|
+
const flags = (0, flags_1.getFlags)();
|
|
35
|
+
const improveNote = flags.improve ? await (0, prompt_1.ask)("Improve focus (optional): ") : "";
|
|
36
|
+
const projectReadmeJson = {
|
|
37
|
+
projectName,
|
|
38
|
+
overview: overview || "N/A",
|
|
39
|
+
howToRun: howToRun || "N/A",
|
|
40
|
+
architectureSummary: architectureSummary || "N/A",
|
|
41
|
+
specs: {
|
|
42
|
+
requirements: requirementsLink || "requirements/requirement.md",
|
|
43
|
+
functionalSpec: functionalSpecLink || "requirements/functional-spec.md",
|
|
44
|
+
technicalSpec: technicalSpecLink || "requirements/technical-spec.md",
|
|
45
|
+
architecture: architectureLink || "requirements/architecture.md"
|
|
46
|
+
},
|
|
47
|
+
testingNotes: testingNotes || "N/A"
|
|
48
|
+
};
|
|
49
|
+
const validation = (0, validate_1.validateJson)("project-readme.schema.json", projectReadmeJson);
|
|
50
|
+
if (!validation.valid) {
|
|
51
|
+
console.log("Project README validation failed:");
|
|
52
|
+
validation.errors.forEach((error) => console.log(`- ${error}`));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const template = (0, render_1.loadTemplate)("project-readme");
|
|
56
|
+
const rendered = (0, render_1.renderTemplate)(template, {
|
|
57
|
+
project_name: projectName,
|
|
58
|
+
overview: projectReadmeJson.overview,
|
|
59
|
+
how_to_run: projectReadmeJson.howToRun,
|
|
60
|
+
architecture_summary: projectReadmeJson.architectureSummary,
|
|
61
|
+
requirements_link: projectReadmeJson.specs.requirements,
|
|
62
|
+
functional_spec_link: projectReadmeJson.specs.functionalSpec,
|
|
63
|
+
technical_spec_link: projectReadmeJson.specs.technicalSpec,
|
|
64
|
+
architecture_link: projectReadmeJson.specs.architecture,
|
|
65
|
+
testing_notes: projectReadmeJson.testingNotes
|
|
66
|
+
});
|
|
67
|
+
fs_1.default.writeFileSync(path_1.default.join(requirementDir, "project-readme.md"), rendered, "utf-8");
|
|
68
|
+
fs_1.default.writeFileSync(path_1.default.join(requirementDir, "project-readme.json"), JSON.stringify(projectReadmeJson, null, 2), "utf-8");
|
|
69
|
+
(0, gen_utils_1.appendProgress)(requirementDir, `generated project readme for ${reqId}`);
|
|
70
|
+
(0, gen_utils_1.appendImprove)(requirementDir, improveNote);
|
|
71
|
+
console.log(`Project README generated in ${requirementDir}`);
|
|
72
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runGenRequirements(): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runGenTechnicalSpec(): Promise<void>;
|
|
@@ -0,0 +1,67 @@
|
|
|
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.runGenTechnicalSpec = runGenTechnicalSpec;
|
|
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 validate_1 = require("../validation/validate");
|
|
13
|
+
const gen_utils_1 = require("./gen-utils");
|
|
14
|
+
const flags_1 = require("../context/flags");
|
|
15
|
+
async function runGenTechnicalSpec() {
|
|
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 requirementDir = (0, gen_utils_1.findRequirementDir)(projectName, reqId);
|
|
23
|
+
if (!requirementDir) {
|
|
24
|
+
console.log("Requirement not found.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const stack = await (0, prompt_1.ask)("Tech stack - comma separated: ");
|
|
28
|
+
const interfaces = await (0, prompt_1.ask)("Interfaces - comma separated: ");
|
|
29
|
+
const dataModel = await (0, prompt_1.ask)("Data model - comma separated: ");
|
|
30
|
+
const security = await (0, prompt_1.ask)("Security - comma separated: ");
|
|
31
|
+
const errors = await (0, prompt_1.ask)("Error handling - comma separated: ");
|
|
32
|
+
const performance = await (0, prompt_1.ask)("Performance - comma separated: ");
|
|
33
|
+
const observability = await (0, prompt_1.ask)("Observability - comma separated: ");
|
|
34
|
+
const flags = (0, flags_1.getFlags)();
|
|
35
|
+
const improveNote = flags.improve ? await (0, prompt_1.ask)("Improve focus (optional): ") : "";
|
|
36
|
+
const technicalJson = {
|
|
37
|
+
stack: (0, list_1.parseList)(stack),
|
|
38
|
+
interfaces: (0, list_1.parseList)(interfaces),
|
|
39
|
+
dataModel: (0, list_1.parseList)(dataModel),
|
|
40
|
+
security: (0, list_1.parseList)(security),
|
|
41
|
+
errors: (0, list_1.parseList)(errors),
|
|
42
|
+
performance: (0, list_1.parseList)(performance),
|
|
43
|
+
observability: (0, list_1.parseList)(observability)
|
|
44
|
+
};
|
|
45
|
+
const validation = (0, validate_1.validateJson)("technical-spec.schema.json", technicalJson);
|
|
46
|
+
if (!validation.valid) {
|
|
47
|
+
console.log("Technical spec validation failed:");
|
|
48
|
+
validation.errors.forEach((error) => console.log(`- ${error}`));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const template = (0, render_1.loadTemplate)("technical-spec");
|
|
52
|
+
const rendered = (0, render_1.renderTemplate)(template, {
|
|
53
|
+
title: projectName,
|
|
54
|
+
stack: (0, list_1.formatList)(stack),
|
|
55
|
+
interfaces: (0, list_1.formatList)(interfaces),
|
|
56
|
+
data_model: (0, list_1.formatList)(dataModel),
|
|
57
|
+
security: (0, list_1.formatList)(security),
|
|
58
|
+
errors: (0, list_1.formatList)(errors),
|
|
59
|
+
performance: (0, list_1.formatList)(performance),
|
|
60
|
+
observability: (0, list_1.formatList)(observability)
|
|
61
|
+
});
|
|
62
|
+
fs_1.default.writeFileSync(path_1.default.join(requirementDir, "technical-spec.md"), rendered, "utf-8");
|
|
63
|
+
fs_1.default.writeFileSync(path_1.default.join(requirementDir, "technical-spec.json"), JSON.stringify(technicalJson, null, 2), "utf-8");
|
|
64
|
+
(0, gen_utils_1.appendProgress)(requirementDir, `generated technical spec for ${reqId}`);
|
|
65
|
+
(0, gen_utils_1.appendImprove)(requirementDir, improveNote);
|
|
66
|
+
console.log(`Technical spec generated in ${requirementDir}`);
|
|
67
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function findRequirementDir(projectName: string, reqId: string): string | null;
|
|
2
|
+
export declare function ensureProgressLog(dir: string): void;
|
|
3
|
+
export declare function appendProgress(dir: string, message: string): void;
|
|
4
|
+
export declare function appendImprove(dir: string, note?: string): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
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.findRequirementDir = findRequirementDir;
|
|
7
|
+
exports.ensureProgressLog = ensureProgressLog;
|
|
8
|
+
exports.appendProgress = appendProgress;
|
|
9
|
+
exports.appendImprove = appendImprove;
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const index_1 = require("../workspace/index");
|
|
13
|
+
const flags_1 = require("../context/flags");
|
|
14
|
+
function findRequirementDir(projectName, reqId) {
|
|
15
|
+
const workspace = (0, index_1.getWorkspaceInfo)();
|
|
16
|
+
const base = path_1.default.join(workspace.root, projectName, "requirements");
|
|
17
|
+
const statuses = ["backlog", "wip", "in-progress", "done", "archived"];
|
|
18
|
+
for (const status of statuses) {
|
|
19
|
+
const candidate = path_1.default.join(base, status, reqId);
|
|
20
|
+
if (fs_1.default.existsSync(candidate)) {
|
|
21
|
+
return candidate;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function ensureProgressLog(dir) {
|
|
27
|
+
const progressLog = path_1.default.join(dir, "progress-log.md");
|
|
28
|
+
if (!fs_1.default.existsSync(progressLog)) {
|
|
29
|
+
fs_1.default.writeFileSync(progressLog, "# Progress Log\n\n", "utf-8");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function appendProgress(dir, message) {
|
|
33
|
+
ensureProgressLog(dir);
|
|
34
|
+
const logEntry = `\n- ${new Date().toISOString()} ${message}\n`;
|
|
35
|
+
fs_1.default.appendFileSync(path_1.default.join(dir, "progress-log.md"), logEntry, "utf-8");
|
|
36
|
+
}
|
|
37
|
+
function appendImprove(dir, note) {
|
|
38
|
+
const flags = (0, flags_1.getFlags)();
|
|
39
|
+
if (!flags.improve) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const message = note && note.trim().length > 0 ? `improve: ${note.trim()}` : "improve: refinement requested";
|
|
43
|
+
appendProgress(dir, message);
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runHello(input: string, runQuestions?: boolean): Promise<void>;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runHello = runHello;
|
|
4
|
+
const intent_1 = require("../router/intent");
|
|
5
|
+
const index_1 = require("../workspace/index");
|
|
6
|
+
const prompt_1 = require("../ui/prompt");
|
|
7
|
+
const prompt_packs_1 = require("../router/prompt-packs");
|
|
8
|
+
const prompt_map_1 = require("../router/prompt-map");
|
|
9
|
+
const req_create_1 = require("./req-create");
|
|
10
|
+
async function runHello(input, runQuestions) {
|
|
11
|
+
const workspace = (0, index_1.getWorkspaceInfo)();
|
|
12
|
+
(0, index_1.ensureWorkspace)(workspace);
|
|
13
|
+
const projects = (0, index_1.listProjects)(workspace);
|
|
14
|
+
console.log("Hello from sdd-tool.");
|
|
15
|
+
console.log(`Workspace: ${workspace.root}`);
|
|
16
|
+
if (projects.length > 0) {
|
|
17
|
+
console.log("Active projects:");
|
|
18
|
+
projects.forEach((project) => {
|
|
19
|
+
console.log(`- ${project.name} (${project.status})`);
|
|
20
|
+
});
|
|
21
|
+
const choice = await (0, prompt_1.ask)("Start new or continue? (new/continue) ");
|
|
22
|
+
console.log(`Selected: ${choice || "new"}`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
console.log("No active projects found.");
|
|
26
|
+
}
|
|
27
|
+
const text = input || (await (0, prompt_1.ask)("Describe what you want to do: "));
|
|
28
|
+
if (!text) {
|
|
29
|
+
console.log("No input provided. Try again with a short description.");
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const intent = (0, intent_1.classifyIntent)(text);
|
|
33
|
+
console.log(`Detected intent: ${intent.intent} -> ${intent.flow}`);
|
|
34
|
+
console.log("Next: run `sdd-tool route <your input>` to view details.");
|
|
35
|
+
if (runQuestions) {
|
|
36
|
+
const packs = (0, prompt_packs_1.loadPromptPacks)();
|
|
37
|
+
const packIds = intent_1.FLOW_PROMPT_PACKS[intent.flow] ?? [];
|
|
38
|
+
const answers = {};
|
|
39
|
+
for (const packId of packIds) {
|
|
40
|
+
const pack = (0, prompt_packs_1.getPromptPackById)(packs, packId);
|
|
41
|
+
if (!pack)
|
|
42
|
+
continue;
|
|
43
|
+
console.log(`\n[${pack.id}]`);
|
|
44
|
+
for (const question of pack.questions) {
|
|
45
|
+
const response = await (0, prompt_1.ask)(`${question} `);
|
|
46
|
+
answers[question] = response;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
console.log("\nCaptured answers:");
|
|
50
|
+
Object.entries(answers).forEach(([question, response]) => {
|
|
51
|
+
console.log(`- ${question} -> ${response}`);
|
|
52
|
+
});
|
|
53
|
+
if (runQuestions && Object.keys(answers).length > 0) {
|
|
54
|
+
const mapped = (0, prompt_map_1.mapAnswersToRequirement)(answers);
|
|
55
|
+
console.log("\nDraft requirement fields:");
|
|
56
|
+
console.log(JSON.stringify(mapped, null, 2));
|
|
57
|
+
const ok = await (0, prompt_1.confirm)("Generate requirement draft now? (y/n) ");
|
|
58
|
+
if (ok) {
|
|
59
|
+
await (0, req_create_1.runReqCreate)(mapped);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runInit(): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runInit = runInit;
|
|
4
|
+
const index_1 = require("../workspace/index");
|
|
5
|
+
function runInit() {
|
|
6
|
+
const workspace = (0, index_1.getWorkspaceInfo)();
|
|
7
|
+
(0, index_1.ensureWorkspace)(workspace);
|
|
8
|
+
console.log(`Workspace initialized at: ${workspace.root}`);
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runLearnDeliver(): Promise<void>;
|
|
@@ -0,0 +1,55 @@
|
|
|
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.runLearnDeliver = runLearnDeliver;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const prompt_1 = require("../ui/prompt");
|
|
10
|
+
const list_1 = require("../utils/list");
|
|
11
|
+
const learn_utils_1 = require("./learn-utils");
|
|
12
|
+
async function runLearnDeliver() {
|
|
13
|
+
const projectName = await (0, prompt_1.ask)("Project name: ");
|
|
14
|
+
if (!projectName) {
|
|
15
|
+
console.log("Project name is required.");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const sessions = (0, learn_utils_1.listLearnSessions)(projectName);
|
|
19
|
+
if (sessions.length > 0) {
|
|
20
|
+
console.log("Available sessions:");
|
|
21
|
+
sessions.forEach((session) => console.log(`- ${session}`));
|
|
22
|
+
}
|
|
23
|
+
const sessionId = await (0, prompt_1.ask)("Session ID: ");
|
|
24
|
+
if (!sessionId) {
|
|
25
|
+
console.log("Session ID is required.");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const loaded = (0, learn_utils_1.loadLearnSession)(projectName, sessionId);
|
|
29
|
+
if (!loaded) {
|
|
30
|
+
console.log("Learning session not found.");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const brief = await (0, prompt_1.ask)("Brief summary: ");
|
|
34
|
+
const deepDive = await (0, prompt_1.ask)("Deep dive notes: ");
|
|
35
|
+
const readingList = await (0, prompt_1.ask)("Reading list - comma separated: ");
|
|
36
|
+
const questions = await (0, prompt_1.ask)("Questions - comma separated: ");
|
|
37
|
+
const answers = await (0, prompt_1.ask)("Answers - comma separated (aligned by order): ");
|
|
38
|
+
const qList = (0, list_1.parseList)(questions);
|
|
39
|
+
const aList = (0, list_1.parseList)(answers);
|
|
40
|
+
const qaItems = qList.map((question, index) => {
|
|
41
|
+
const answer = aList[index] ?? "TBD";
|
|
42
|
+
return `- Q: ${question}\n A: ${answer}`;
|
|
43
|
+
});
|
|
44
|
+
fs_1.default.writeFileSync(path_1.default.join(loaded.dir, "brief.md"), `# Brief: ${loaded.session.topic}\n\n${brief || "N/A"}\n`, "utf-8");
|
|
45
|
+
fs_1.default.writeFileSync(path_1.default.join(loaded.dir, "deep-dive.md"), `# Deep Dive: ${loaded.session.topic}\n\n${deepDive || "N/A"}\n`, "utf-8");
|
|
46
|
+
fs_1.default.writeFileSync(path_1.default.join(loaded.dir, "reading-list.md"), `# Reading List: ${loaded.session.topic}\n\n${(0, list_1.formatList)(readingList)}\n`, "utf-8");
|
|
47
|
+
fs_1.default.writeFileSync(path_1.default.join(loaded.dir, "qa.md"), `# Q&A: ${loaded.session.topic}\n\n${qaItems.join("\n")}\n`, "utf-8");
|
|
48
|
+
const progressLog = path_1.default.join(loaded.dir, "progress-log.md");
|
|
49
|
+
if (!fs_1.default.existsSync(progressLog)) {
|
|
50
|
+
fs_1.default.writeFileSync(progressLog, "# Progress Log\n\n", "utf-8");
|
|
51
|
+
}
|
|
52
|
+
const logEntry = `\n- ${new Date().toISOString()} delivered learning outputs for ${loaded.session.id}\n`;
|
|
53
|
+
fs_1.default.appendFileSync(progressLog, logEntry, "utf-8");
|
|
54
|
+
console.log(`Learning outputs written to ${loaded.dir}`);
|
|
55
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runLearnRefine(): Promise<void>;
|
|
@@ -0,0 +1,71 @@
|
|
|
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.runLearnRefine = runLearnRefine;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const prompt_1 = require("../ui/prompt");
|
|
10
|
+
const list_1 = require("../utils/list");
|
|
11
|
+
const learn_utils_1 = require("./learn-utils");
|
|
12
|
+
async function runLearnRefine() {
|
|
13
|
+
const projectName = await (0, prompt_1.ask)("Project name: ");
|
|
14
|
+
if (!projectName) {
|
|
15
|
+
console.log("Project name is required.");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const sessions = (0, learn_utils_1.listLearnSessions)(projectName);
|
|
19
|
+
if (sessions.length > 0) {
|
|
20
|
+
console.log("Available sessions:");
|
|
21
|
+
sessions.forEach((session) => console.log(`- ${session}`));
|
|
22
|
+
}
|
|
23
|
+
const sessionId = await (0, prompt_1.ask)("Session ID: ");
|
|
24
|
+
if (!sessionId) {
|
|
25
|
+
console.log("Session ID is required.");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const loaded = (0, learn_utils_1.loadLearnSession)(projectName, sessionId);
|
|
29
|
+
if (!loaded) {
|
|
30
|
+
console.log("Learning session not found.");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const purpose = await (0, prompt_1.ask)(`Purpose (${loaded.session.purpose}): `);
|
|
34
|
+
const depth = await (0, prompt_1.ask)(`Depth (${loaded.session.depth}): `);
|
|
35
|
+
const format = await (0, prompt_1.ask)(`Format (${loaded.session.format}): `);
|
|
36
|
+
const focusAreas = await (0, prompt_1.ask)("Focus areas - comma separated: ");
|
|
37
|
+
const timeAvailable = await (0, prompt_1.ask)(`Time available (${loaded.session.timeAvailable}): `);
|
|
38
|
+
const constraints = await (0, prompt_1.ask)("Constraints - comma separated: ");
|
|
39
|
+
const updated = (0, learn_utils_1.updateLearnSession)(projectName, sessionId, {
|
|
40
|
+
purpose: purpose || loaded.session.purpose,
|
|
41
|
+
depth: depth || loaded.session.depth,
|
|
42
|
+
format: format || loaded.session.format,
|
|
43
|
+
focusAreas: focusAreas ? (0, list_1.parseList)(focusAreas) : loaded.session.focusAreas,
|
|
44
|
+
timeAvailable: timeAvailable || loaded.session.timeAvailable,
|
|
45
|
+
constraints: constraints ? (0, list_1.parseList)(constraints) : loaded.session.constraints
|
|
46
|
+
});
|
|
47
|
+
if (!updated) {
|
|
48
|
+
console.log("Failed to update session.");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const sessionMd = [
|
|
52
|
+
`# Learning Session: ${updated.topic}`,
|
|
53
|
+
"",
|
|
54
|
+
`- Purpose: ${updated.purpose}`,
|
|
55
|
+
`- Depth: ${updated.depth}`,
|
|
56
|
+
`- Format: ${updated.format}`,
|
|
57
|
+
`- Focus areas:`,
|
|
58
|
+
`${(0, list_1.formatList)(updated.focusAreas.join(", "))}`,
|
|
59
|
+
`- Time available: ${updated.timeAvailable}`,
|
|
60
|
+
`- Constraints:`,
|
|
61
|
+
`${(0, list_1.formatList)(updated.constraints.join(", "))}`
|
|
62
|
+
].join("\n");
|
|
63
|
+
fs_1.default.writeFileSync(path_1.default.join(loaded.dir, "session.md"), sessionMd, "utf-8");
|
|
64
|
+
const progressLog = path_1.default.join(loaded.dir, "progress-log.md");
|
|
65
|
+
if (!fs_1.default.existsSync(progressLog)) {
|
|
66
|
+
fs_1.default.writeFileSync(progressLog, "# Progress Log\n\n", "utf-8");
|
|
67
|
+
}
|
|
68
|
+
const logEntry = `\n- ${new Date().toISOString()} refined learning session ${updated.id}\n`;
|
|
69
|
+
fs_1.default.appendFileSync(progressLog, logEntry, "utf-8");
|
|
70
|
+
console.log(`Learning session updated at ${loaded.dir}`);
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runLearnStart(): Promise<void>;
|
|
@@ -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.runLearnStart = runLearnStart;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const prompt_1 = require("../ui/prompt");
|
|
10
|
+
const list_1 = require("../utils/list");
|
|
11
|
+
const learn_utils_1 = require("./learn-utils");
|
|
12
|
+
async function runLearnStart() {
|
|
13
|
+
const projectName = await (0, prompt_1.ask)("Project name: ");
|
|
14
|
+
const topic = await (0, prompt_1.ask)("Topic to learn: ");
|
|
15
|
+
if (!projectName || !topic) {
|
|
16
|
+
console.log("Project name and topic are required.");
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const purpose = await (0, prompt_1.ask)("Why do you want to learn this? ");
|
|
20
|
+
const depth = await (0, prompt_1.ask)("Depth (overview/academic/expert): ");
|
|
21
|
+
const format = await (0, prompt_1.ask)("Preferred format (summary/syllabus/report/Q&A): ");
|
|
22
|
+
const focusAreas = await (0, prompt_1.ask)("Focus areas - comma separated: ");
|
|
23
|
+
const timeAvailable = await (0, prompt_1.ask)("Time available: ");
|
|
24
|
+
const constraints = await (0, prompt_1.ask)("Constraints - comma separated: ");
|
|
25
|
+
const created = (0, learn_utils_1.createLearnSession)(projectName, topic, "learning");
|
|
26
|
+
(0, learn_utils_1.updateLearnSession)(projectName, created.session.id, {
|
|
27
|
+
purpose: purpose || "N/A",
|
|
28
|
+
depth: depth || "N/A",
|
|
29
|
+
format: format || "N/A",
|
|
30
|
+
focusAreas: (0, list_1.parseList)(focusAreas),
|
|
31
|
+
timeAvailable: timeAvailable || "N/A",
|
|
32
|
+
constraints: (0, list_1.parseList)(constraints)
|
|
33
|
+
});
|
|
34
|
+
const sessionDir = created.dir;
|
|
35
|
+
const brief = `# Brief: ${topic}\n\n${purpose || "N/A"}\n`;
|
|
36
|
+
const deepDive = `# Deep Dive: ${topic}\n\nDepth: ${depth || "N/A"}\n\nFocus areas:\n${(0, list_1.formatList)(focusAreas)}\n`;
|
|
37
|
+
const readingList = `# Reading List: ${topic}\n\n${(0, list_1.formatList)("TBD")}\n`;
|
|
38
|
+
const qa = `# Q&A: ${topic}\n\n${(0, list_1.formatList)("TBD")}\n`;
|
|
39
|
+
const sessionMd = [
|
|
40
|
+
`# Learning Session: ${topic}`,
|
|
41
|
+
"",
|
|
42
|
+
`- Purpose: ${purpose || "N/A"}`,
|
|
43
|
+
`- Depth: ${depth || "N/A"}`,
|
|
44
|
+
`- Format: ${format || "N/A"}`,
|
|
45
|
+
`- Focus areas:`,
|
|
46
|
+
`${(0, list_1.formatList)(focusAreas)}`,
|
|
47
|
+
`- Time available: ${timeAvailable || "N/A"}`,
|
|
48
|
+
`- Constraints:`,
|
|
49
|
+
`${(0, list_1.formatList)(constraints)}`
|
|
50
|
+
].join("\n");
|
|
51
|
+
fs_1.default.writeFileSync(path_1.default.join(sessionDir, "brief.md"), brief, "utf-8");
|
|
52
|
+
fs_1.default.writeFileSync(path_1.default.join(sessionDir, "deep-dive.md"), deepDive, "utf-8");
|
|
53
|
+
fs_1.default.writeFileSync(path_1.default.join(sessionDir, "reading-list.md"), readingList, "utf-8");
|
|
54
|
+
fs_1.default.writeFileSync(path_1.default.join(sessionDir, "qa.md"), qa, "utf-8");
|
|
55
|
+
fs_1.default.writeFileSync(path_1.default.join(sessionDir, "session.md"), sessionMd, "utf-8");
|
|
56
|
+
const progressLog = path_1.default.join(sessionDir, "progress-log.md");
|
|
57
|
+
if (!fs_1.default.existsSync(progressLog)) {
|
|
58
|
+
fs_1.default.writeFileSync(progressLog, "# Progress Log\n\n", "utf-8");
|
|
59
|
+
}
|
|
60
|
+
const logEntry = `\n- ${new Date().toISOString()} started learning session ${created.session.id}\n`;
|
|
61
|
+
fs_1.default.appendFileSync(progressLog, logEntry, "utf-8");
|
|
62
|
+
console.log(`Learning session created at ${sessionDir}`);
|
|
63
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type LearnSession = {
|
|
2
|
+
id: string;
|
|
3
|
+
topic: string;
|
|
4
|
+
purpose: string;
|
|
5
|
+
depth: string;
|
|
6
|
+
format: string;
|
|
7
|
+
focusAreas: string[];
|
|
8
|
+
timeAvailable: string;
|
|
9
|
+
constraints: string[];
|
|
10
|
+
createdAt: string;
|
|
11
|
+
updatedAt: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function createLearnSession(projectName: string, topic: string, domain?: string): {
|
|
14
|
+
session: LearnSession;
|
|
15
|
+
dir: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function loadLearnSession(projectName: string, sessionId: string): {
|
|
18
|
+
session: LearnSession;
|
|
19
|
+
dir: string;
|
|
20
|
+
} | null;
|
|
21
|
+
export declare function listLearnSessions(projectName: string): string[];
|
|
22
|
+
export declare function updateLearnSession(projectName: string, sessionId: string, next: Partial<LearnSession>): LearnSession | null;
|
|
@@ -0,0 +1,78 @@
|
|
|
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.createLearnSession = createLearnSession;
|
|
7
|
+
exports.loadLearnSession = loadLearnSession;
|
|
8
|
+
exports.listLearnSessions = listLearnSessions;
|
|
9
|
+
exports.updateLearnSession = updateLearnSession;
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const index_1 = require("../workspace/index");
|
|
13
|
+
function sanitizeId(value) {
|
|
14
|
+
return value
|
|
15
|
+
.trim()
|
|
16
|
+
.toLowerCase()
|
|
17
|
+
.replace(/[^a-z0-9_-]+/g, "-")
|
|
18
|
+
.replace(/-+/g, "-")
|
|
19
|
+
.replace(/^-|-$/g, "");
|
|
20
|
+
}
|
|
21
|
+
function createLearnSession(projectName, topic, domain = "learning") {
|
|
22
|
+
const workspace = (0, index_1.getWorkspaceInfo)();
|
|
23
|
+
(0, index_1.ensureProject)(workspace, projectName, domain);
|
|
24
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "").slice(0, 13);
|
|
25
|
+
const id = `LEARN-${sanitizeId(topic)}-${stamp}`;
|
|
26
|
+
const now = new Date().toISOString();
|
|
27
|
+
const session = {
|
|
28
|
+
id,
|
|
29
|
+
topic,
|
|
30
|
+
purpose: "N/A",
|
|
31
|
+
depth: "N/A",
|
|
32
|
+
format: "N/A",
|
|
33
|
+
focusAreas: [],
|
|
34
|
+
timeAvailable: "N/A",
|
|
35
|
+
constraints: [],
|
|
36
|
+
createdAt: now,
|
|
37
|
+
updatedAt: now
|
|
38
|
+
};
|
|
39
|
+
const sessionDir = path_1.default.join(workspace.root, projectName, "learning", id);
|
|
40
|
+
fs_1.default.mkdirSync(sessionDir, { recursive: true });
|
|
41
|
+
fs_1.default.writeFileSync(path_1.default.join(sessionDir, "session.json"), JSON.stringify(session, null, 2), "utf-8");
|
|
42
|
+
return { session, dir: sessionDir };
|
|
43
|
+
}
|
|
44
|
+
function loadLearnSession(projectName, sessionId) {
|
|
45
|
+
const workspace = (0, index_1.getWorkspaceInfo)();
|
|
46
|
+
const sessionDir = path_1.default.join(workspace.root, projectName, "learning", sessionId);
|
|
47
|
+
const sessionPath = path_1.default.join(sessionDir, "session.json");
|
|
48
|
+
if (!fs_1.default.existsSync(sessionPath)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const session = JSON.parse(fs_1.default.readFileSync(sessionPath, "utf-8"));
|
|
52
|
+
return { session, dir: sessionDir };
|
|
53
|
+
}
|
|
54
|
+
function listLearnSessions(projectName) {
|
|
55
|
+
const workspace = (0, index_1.getWorkspaceInfo)();
|
|
56
|
+
const root = path_1.default.join(workspace.root, projectName, "learning");
|
|
57
|
+
if (!fs_1.default.existsSync(root)) {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
return fs_1.default
|
|
61
|
+
.readdirSync(root, { withFileTypes: true })
|
|
62
|
+
.filter((entry) => entry.isDirectory())
|
|
63
|
+
.map((entry) => entry.name)
|
|
64
|
+
.sort();
|
|
65
|
+
}
|
|
66
|
+
function updateLearnSession(projectName, sessionId, next) {
|
|
67
|
+
const loaded = loadLearnSession(projectName, sessionId);
|
|
68
|
+
if (!loaded) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const updated = {
|
|
72
|
+
...loaded.session,
|
|
73
|
+
...next,
|
|
74
|
+
updatedAt: new Date().toISOString()
|
|
75
|
+
};
|
|
76
|
+
fs_1.default.writeFileSync(path_1.default.join(loaded.dir, "session.json"), JSON.stringify(updated, null, 2), "utf-8");
|
|
77
|
+
return updated;
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runList(): void;
|