@gkganesh12/codecraft-cli 1.0.1
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 +99 -0
- package/dist/commands/adr.d.ts +2 -0
- package/dist/commands/adr.d.ts.map +1 -0
- package/dist/commands/adr.js +48 -0
- package/dist/commands/adr.js.map +1 -0
- package/dist/commands/architect.d.ts +2 -0
- package/dist/commands/architect.d.ts.map +1 -0
- package/dist/commands/architect.js +83 -0
- package/dist/commands/architect.js.map +1 -0
- package/dist/commands/code.d.ts +2 -0
- package/dist/commands/code.d.ts.map +1 -0
- package/dist/commands/code.js +111 -0
- package/dist/commands/code.js.map +1 -0
- package/dist/commands/config.d.ts +11 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +101 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +36 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/explain.d.ts +2 -0
- package/dist/commands/explain.d.ts.map +1 -0
- package/dist/commands/explain.js +41 -0
- package/dist/commands/explain.js.map +1 -0
- package/dist/commands/feature.d.ts +2 -0
- package/dist/commands/feature.d.ts.map +1 -0
- package/dist/commands/feature.js +49 -0
- package/dist/commands/feature.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +63 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +61 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/review.d.ts +2 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +41 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/test.d.ts +2 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +48 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +31 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +2 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +64 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +35 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +25 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +19 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/llm/client.d.ts +14 -0
- package/dist/core/llm/client.d.ts.map +1 -0
- package/dist/core/llm/client.js +28 -0
- package/dist/core/llm/client.js.map +1 -0
- package/dist/core/prompts/roles.d.ts +11 -0
- package/dist/core/prompts/roles.d.ts.map +1 -0
- package/dist/core/prompts/roles.js +238 -0
- package/dist/core/prompts/roles.js.map +1 -0
- package/dist/core/rules.d.ts +14 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +39 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/scanner.d.ts +6 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +21 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/scope.d.ts +11 -0
- package/dist/core/scope.d.ts.map +1 -0
- package/dist/core/scope.js +34 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +121 -0
- package/dist/index.js.map +1 -0
- package/dist/repl.d.ts +2 -0
- package/dist/repl.d.ts.map +1 -0
- package/dist/repl.js +148 -0
- package/dist/repl.js.map +1 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# CodeCraft CLI š
|
|
2
|
+
|
|
3
|
+
> **AI Governance & Assistant CLI for Developers**
|
|
4
|
+
> Manage your project's architecture, planning, and code quality with an AI-powered CLI.
|
|
5
|
+
|
|
6
|
+
CodeCraft is a next-generation CLI that brings LLM-powered reasoning to your terminal. It acts as a Project Manager, Architect, and QA Lead, helping you build software faster and with higher quality.
|
|
7
|
+
|
|
8
|
+
## ⨠Features
|
|
9
|
+
|
|
10
|
+
- **Interactive REPL**: A "Claude Code" style interactive shell with persistent context.
|
|
11
|
+
- **Role-Based AI**: Switch between personas (PM, Architect, Backend/Frontend Developer, QA).
|
|
12
|
+
- **Slash Commands**: Trigger workflows effortlessly (`/plan`, `/code`, `/verify`, `/doctor`).
|
|
13
|
+
- **Scope Guard**: Prevents AI from modifying files outside the allowed scope.
|
|
14
|
+
- **Rule Engine**: Enforces project-specific architectural rules.
|
|
15
|
+
|
|
16
|
+
## š¦ Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g @gkganesh12/codecraft-cli
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## š Quick Start
|
|
23
|
+
|
|
24
|
+
1. **Initialize CodeCraft** in your project:
|
|
25
|
+
```bash
|
|
26
|
+
codecraft init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
2. **Start the Interactive Mode**:
|
|
30
|
+
```bash
|
|
31
|
+
codecraft
|
|
32
|
+
```
|
|
33
|
+
You will see the `CodeCraft >` prompt.
|
|
34
|
+
|
|
35
|
+
3. **Try a Command**:
|
|
36
|
+
```text
|
|
37
|
+
/plan "Create a user authentication API with JWT"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## š ļø Usage
|
|
41
|
+
|
|
42
|
+
### Interactive Commands (REPL)
|
|
43
|
+
|
|
44
|
+
| Command | Description |
|
|
45
|
+
| :--- | :--- |
|
|
46
|
+
| `/init` | Initialize CodeCraft in the current directory. |
|
|
47
|
+
| `/plan <task>` | Create a detailed implementation plan using the **Project Manager** persona. |
|
|
48
|
+
| `/architect` | Review the current plan against architecture rules using the **Architect** persona. |
|
|
49
|
+
| `/code` | Generate code based on the approved plan using **Developer** personas. |
|
|
50
|
+
| `/verify` | Analyze risks and suggest tests using the **QA** persona. |
|
|
51
|
+
| `/feature <desc>` | Draft a comprehensive Feature Specification. |
|
|
52
|
+
| `/adr <title>` | Create an Architecture Decision Record (ADR). |
|
|
53
|
+
| `/test <file>` | Generate unit tests for a specific file. |
|
|
54
|
+
| `/review <file>` | Perform an AI code review on a file. |
|
|
55
|
+
| `/explain <file>` | Explain complex code in plain English. |
|
|
56
|
+
| `/config` | Manage CLI settings (API keys, models, verbose mode). |
|
|
57
|
+
| `/doctor` | Check environment health and dependencies. |
|
|
58
|
+
| `/update` | Check for the latest version of CodeCraft. |
|
|
59
|
+
|
|
60
|
+
### CLI Flags
|
|
61
|
+
|
|
62
|
+
You can also run commands directly without entering the REPL:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Run a specific command
|
|
66
|
+
codecraft doctor
|
|
67
|
+
|
|
68
|
+
# Run with verbose logging
|
|
69
|
+
codecraft --verbose plan "Refactor the database schema"
|
|
70
|
+
|
|
71
|
+
# Override the AI model for a session
|
|
72
|
+
codecraft --model gpt-4o code
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## āļø Configuration
|
|
76
|
+
|
|
77
|
+
CodeCraft stores its configuration in `~/.codecraft/config.json`. You can manage it via:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
codecraft config
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Supported settings:
|
|
84
|
+
- **API Key**: Your OpenAI or supported LLM provider key.
|
|
85
|
+
- **Model**: Default model to use (e.g., `gpt-4-turbo`, `gpt-4o`).
|
|
86
|
+
- **Verbose**: Enable detailed debug logs.
|
|
87
|
+
|
|
88
|
+
## š¤ Contributing
|
|
89
|
+
|
|
90
|
+
Contributions are welcome! Please look at the `Docs/` folder for architectural guidelines.
|
|
91
|
+
|
|
92
|
+
1. Fork the repository.
|
|
93
|
+
2. Create a feature branch.
|
|
94
|
+
3. Commit your changes.
|
|
95
|
+
4. Open a Pull Request.
|
|
96
|
+
|
|
97
|
+
## š License
|
|
98
|
+
|
|
99
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adr.d.ts","sourceRoot":"","sources":["../../src/commands/adr.ts"],"names":[],"mappings":"AASA,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,iBAwC7C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
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.adrCommand = adrCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const loader_1 = require("../config/loader");
|
|
11
|
+
const client_1 = require("../core/llm/client");
|
|
12
|
+
const roles_1 = require("../core/prompts/roles");
|
|
13
|
+
const ora_1 = __importDefault(require("ora"));
|
|
14
|
+
async function adrCommand(title) {
|
|
15
|
+
const spinner = (0, ora_1.default)('Drafting ADR...').start();
|
|
16
|
+
const configLoader = new loader_1.ConfigLoader();
|
|
17
|
+
const config = configLoader.load();
|
|
18
|
+
if (!config) {
|
|
19
|
+
spinner.fail('No config found.');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const apiKey = process.env.CODECRAFT_API_KEY || process.env.OPENAI_API_KEY;
|
|
23
|
+
if (!apiKey) {
|
|
24
|
+
spinner.fail('API Key missing.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const ai = new client_1.OpenAIAdapter(apiKey);
|
|
28
|
+
const prompt = [
|
|
29
|
+
{ role: 'system', content: roles_1.ADR_PROMPT },
|
|
30
|
+
{ role: 'user', content: `ADR Title/Context: ${title}` }
|
|
31
|
+
];
|
|
32
|
+
try {
|
|
33
|
+
const adr = await ai.complete(prompt);
|
|
34
|
+
// Save to docs/adr/
|
|
35
|
+
const adrDir = path_1.default.join(process.cwd(), 'docs', 'adr');
|
|
36
|
+
fs_extra_1.default.ensureDirSync(adrDir);
|
|
37
|
+
const count = fs_extra_1.default.readdirSync(adrDir).length + 1;
|
|
38
|
+
const filename = `ADR-${String(count).padStart(3, '0')}.md`;
|
|
39
|
+
const filePath = path_1.default.join(adrDir, filename);
|
|
40
|
+
fs_extra_1.default.writeFileSync(filePath, adr);
|
|
41
|
+
spinner.succeed(`ADR-${String(count).padStart(3, '0')} generated! šļø`);
|
|
42
|
+
console.log(chalk_1.default.dim(`Saved to ${filePath}`));
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
spinner.fail(`ADR generation failed: ${err.message}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=adr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adr.js","sourceRoot":"","sources":["../../src/commands/adr.ts"],"names":[],"mappings":";;;;;AASA,gCAwCC;AAhDD,kDAA0B;AAC1B,wDAA0B;AAC1B,gDAAwB;AACxB,6CAAgD;AAChD,+CAA8D;AAC9D,iDAAmD;AACnD,8CAAsB;AAEf,KAAK,UAAU,UAAU,CAAC,KAAa;IAC1C,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,iBAAiB,CAAC,CAAC,KAAK,EAAE,CAAC;IAE/C,MAAM,YAAY,GAAG,IAAI,qBAAY,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjC,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3E,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjC,OAAO;IACX,CAAC;IAED,MAAM,EAAE,GAAG,IAAI,sBAAa,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,MAAM,GAAgB;QACxB,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,kBAAU,EAAE;QACvC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,KAAK,EAAE,EAAE;KAC3D,CAAC;IAEF,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtC,oBAAoB;QACpB,MAAM,MAAM,GAAG,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACvD,kBAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAEzB,MAAM,KAAK,GAAG,kBAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC;QAC5D,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAE7C,kBAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAEhC,OAAO,CAAC,OAAO,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAC,CAAC;IAEnD,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architect.d.ts","sourceRoot":"","sources":["../../src/commands/architect.ts"],"names":[],"mappings":"AAWA,wBAAsB,gBAAgB,kBA4ErC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
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.architectCommand = architectCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const loader_1 = require("../config/loader");
|
|
11
|
+
const scope_1 = require("../core/scope");
|
|
12
|
+
const client_1 = require("../core/llm/client");
|
|
13
|
+
const roles_1 = require("../core/prompts/roles");
|
|
14
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
15
|
+
async function architectCommand() {
|
|
16
|
+
console.log(chalk_1.default.blue('Architect Role: Validating Plan... šļø'));
|
|
17
|
+
// 1. Load Config
|
|
18
|
+
const configLoader = new loader_1.ConfigLoader();
|
|
19
|
+
const config = configLoader.load();
|
|
20
|
+
if (!config) {
|
|
21
|
+
console.error(chalk_1.default.red('No config found.'));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// 2. Load Plan
|
|
25
|
+
const planPath = path_1.default.join(process.cwd(), 'plan.md');
|
|
26
|
+
if (!fs_extra_1.default.existsSync(planPath)) {
|
|
27
|
+
console.error(chalk_1.default.red('No plan.md found. Run "codecraft plan <task>" first.'));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const planContent = fs_extra_1.default.readFileSync(planPath, 'utf-8');
|
|
31
|
+
// 3. Extract Files from Plan (Simple Regex for now, upgrade later)
|
|
32
|
+
// Match any backticked content that looks like a file path
|
|
33
|
+
const fileRegex = /`([\w./-]+)`/g;
|
|
34
|
+
const matches = [...planContent.matchAll(fileRegex)].map(m => m[1]).filter((f) => !!f);
|
|
35
|
+
const uniqueFiles = [...new Set(matches)]; // Dedup
|
|
36
|
+
console.log(chalk_1.default.dim(`Found ${uniqueFiles.length} files in plan.`));
|
|
37
|
+
// 4. Validate Scope
|
|
38
|
+
const scopeManager = new scope_1.ScopeManager(config);
|
|
39
|
+
const { allowed, blocked } = scopeManager.validateScope(uniqueFiles);
|
|
40
|
+
if (blocked.length > 0) {
|
|
41
|
+
console.log(chalk_1.default.red('\nš« Scope Violation: The plan modifies protected files!'));
|
|
42
|
+
blocked.forEach(f => console.log(chalk_1.default.red(` - ${f}`)));
|
|
43
|
+
// Prompt Override
|
|
44
|
+
const confirm = await inquirer_1.default.prompt([{
|
|
45
|
+
type: 'confirm',
|
|
46
|
+
name: 'override',
|
|
47
|
+
message: 'Do you want to authorize these changes anyway??',
|
|
48
|
+
default: false
|
|
49
|
+
}]);
|
|
50
|
+
if (!confirm.override) {
|
|
51
|
+
console.log(chalk_1.default.red('Aborted by user.'));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 5. AI Architect Review
|
|
56
|
+
console.log(chalk_1.default.blue('š¤ AI Architect is reviewing the plan...'));
|
|
57
|
+
const apiKey = process.env.CODECRAFT_API_KEY || process.env.OPENAI_API_KEY;
|
|
58
|
+
if (apiKey) {
|
|
59
|
+
const ai = new client_1.OpenAIAdapter(apiKey);
|
|
60
|
+
const prompt = [
|
|
61
|
+
{ role: 'system', content: roles_1.ARCHITECT_ROLE },
|
|
62
|
+
{ role: 'user', content: `Review this implementation plan:\n\n${planContent}` }
|
|
63
|
+
];
|
|
64
|
+
try {
|
|
65
|
+
const review = await ai.complete(prompt);
|
|
66
|
+
console.log(chalk_1.default.cyan('\nš Architect Review:\n'));
|
|
67
|
+
console.log(review);
|
|
68
|
+
}
|
|
69
|
+
catch (e) {
|
|
70
|
+
console.error(chalk_1.default.red('AI Review Failed.'));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
console.log(chalk_1.default.yellow('Skipping AI Review (No API Key).'));
|
|
75
|
+
}
|
|
76
|
+
// 6. Validate Rules
|
|
77
|
+
// ideally we check if the PLAN violates rules, but that requires semantic analysis of natural language.
|
|
78
|
+
// For MVP, we assume the Architect Step validates that the plan LOOKS okay.
|
|
79
|
+
// We can suggest running "codecraft verify" after code is generated.
|
|
80
|
+
console.log(chalk_1.default.green('\nā
Architecture Check Passed.'));
|
|
81
|
+
console.log('You can now run "codecraft code" to execute this plan.');
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=architect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architect.js","sourceRoot":"","sources":["../../src/commands/architect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../src/commands/code.ts"],"names":[],"mappings":"AASA,wBAAsB,WAAW,kBA8GhC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
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.codeCommand = codeCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const loader_1 = require("../config/loader");
|
|
11
|
+
const client_1 = require("../core/llm/client");
|
|
12
|
+
const roles_1 = require("../core/prompts/roles");
|
|
13
|
+
const ora_1 = __importDefault(require("ora"));
|
|
14
|
+
async function codeCommand() {
|
|
15
|
+
const spinner = (0, ora_1.default)('Initializing Code Generator...').start();
|
|
16
|
+
// 1. Load Config & Plan
|
|
17
|
+
const configLoader = new loader_1.ConfigLoader();
|
|
18
|
+
const config = configLoader.load();
|
|
19
|
+
const planPath = path_1.default.join(process.cwd(), 'plan.md');
|
|
20
|
+
if (!config || !fs_extra_1.default.existsSync(planPath)) {
|
|
21
|
+
spinner.fail('Missing config or plan.md');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const plan = fs_extra_1.default.readFileSync(planPath, 'utf-8');
|
|
25
|
+
// 2. Read Files Context (Only those in the plan)
|
|
26
|
+
// This is the "Scope Guard" in action - we only feed relevant files.
|
|
27
|
+
// Match any backticked content that looks like a file path
|
|
28
|
+
const fileRegex = /`([\w./-]+)`/g;
|
|
29
|
+
const matches = [...plan.matchAll(fileRegex)].map(m => m[1]).filter((f) => !!f);
|
|
30
|
+
const uniqueFiles = [...new Set(matches)];
|
|
31
|
+
let fileContext = '';
|
|
32
|
+
for (const file of uniqueFiles) {
|
|
33
|
+
if (file && fs_extra_1.default.existsSync(file)) {
|
|
34
|
+
fileContext += `\n--- ${file} ---\n${fs_extra_1.default.readFileSync(file, 'utf-8')}\n`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// 3. AI Generation
|
|
38
|
+
const apiKey = process.env.CODECRAFT_API_KEY || process.env.OPENAI_API_KEY;
|
|
39
|
+
if (!apiKey) {
|
|
40
|
+
spinner.fail('API Key missing.');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const ai = new client_1.OpenAIAdapter(apiKey);
|
|
44
|
+
// Determine Role based on file extensions
|
|
45
|
+
const frontendExts = ['.tsx', '.jsx', '.css', '.scss', '.html', '.svg'];
|
|
46
|
+
const backendExts = ['.ts', '.js', '.json', '.prisma', '.sql'];
|
|
47
|
+
let isFrontend = false;
|
|
48
|
+
let isBackend = false;
|
|
49
|
+
for (const file of uniqueFiles) {
|
|
50
|
+
if (frontendExts.some(ext => file.endsWith(ext)))
|
|
51
|
+
isFrontend = true;
|
|
52
|
+
if (backendExts.some(ext => file.endsWith(ext)) && !file.endsWith('.d.ts'))
|
|
53
|
+
isBackend = true;
|
|
54
|
+
}
|
|
55
|
+
// Default to Backend if uncertain, or Frontend if only UI
|
|
56
|
+
let selectedRole = roles_1.BACKEND_DEV_ROLE;
|
|
57
|
+
let roleName = 'Backend Developer';
|
|
58
|
+
if (isFrontend && !isBackend) {
|
|
59
|
+
selectedRole = roles_1.FRONTEND_DEV_ROLE;
|
|
60
|
+
roleName = 'Frontend Developer';
|
|
61
|
+
}
|
|
62
|
+
else if (isFrontend && isBackend) {
|
|
63
|
+
// Mixed context - could use a "Full Stack" role, but for now let's stick to the stricter Backend role
|
|
64
|
+
// which usually handles the API/Data layer integration that is more critical.
|
|
65
|
+
// OR we can concat them? No, that confuses the LLM.
|
|
66
|
+
// Let's use Backend as the "Lead" who knows APIs.
|
|
67
|
+
selectedRole = roles_1.BACKEND_DEV_ROLE;
|
|
68
|
+
roleName = 'Full Stack Developer (Backend Lead)';
|
|
69
|
+
}
|
|
70
|
+
console.log(chalk_1.default.blue(`š Activating Persona: ${roleName}`));
|
|
71
|
+
const prompt = [
|
|
72
|
+
{
|
|
73
|
+
role: 'system',
|
|
74
|
+
content: selectedRole + '\n\nAdditional Instruction: You are executing the plan. Return code blocks as requested.'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
role: 'user',
|
|
78
|
+
content: `PLAN:\n${plan}\n\nEXISTING CODE:\n${fileContext}`
|
|
79
|
+
}
|
|
80
|
+
];
|
|
81
|
+
spinner.text = 'Writing code...';
|
|
82
|
+
try {
|
|
83
|
+
const response = await ai.complete(prompt);
|
|
84
|
+
// 4. Apply Changes
|
|
85
|
+
// Parse the response "### FILE: ..." syntax
|
|
86
|
+
const fileBlocks = response.split('### FILE: ');
|
|
87
|
+
for (const block of fileBlocks) {
|
|
88
|
+
if (!block.trim())
|
|
89
|
+
continue;
|
|
90
|
+
const lines = block.split('\n');
|
|
91
|
+
if (lines.length < 1)
|
|
92
|
+
continue;
|
|
93
|
+
const filenameLine = lines[0];
|
|
94
|
+
const codeParts = lines.slice(1);
|
|
95
|
+
const filename = filenameLine?.trim();
|
|
96
|
+
if (!filename)
|
|
97
|
+
continue;
|
|
98
|
+
const code = codeParts.join('\n').replace(/```\w+\n/, '').replace(/```$/, '').trim();
|
|
99
|
+
if (filename && code) {
|
|
100
|
+
fs_extra_1.default.outputFileSync(path_1.default.join(process.cwd(), filename), code);
|
|
101
|
+
console.log(chalk_1.default.green(`\nUpdated ${filename}`));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
spinner.succeed('Code generation complete! š');
|
|
105
|
+
console.log('Run "codecraft verify" to check the results.');
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
spinner.fail(`Coding Failed: ${err.message}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code.js","sourceRoot":"","sources":["../../src/commands/code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface CodeCraftConfig {
|
|
2
|
+
model?: string;
|
|
3
|
+
apiKey?: string;
|
|
4
|
+
systemPrompt?: string;
|
|
5
|
+
verbose?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function loadGlobalConfig(): CodeCraftConfig;
|
|
8
|
+
export declare function saveGlobalConfig(config: CodeCraftConfig): void;
|
|
9
|
+
export declare function configCommand(args: string[]): Promise<void>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAWA,UAAU,eAAe;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,gBAAgB,IAAI,eAAe,CASlD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,QAGvD;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,iBAqEjD"}
|
|
@@ -0,0 +1,101 @@
|
|
|
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.loadGlobalConfig = loadGlobalConfig;
|
|
7
|
+
exports.saveGlobalConfig = saveGlobalConfig;
|
|
8
|
+
exports.configCommand = configCommand;
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const os_1 = __importDefault(require("os"));
|
|
13
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
14
|
+
// Config path: ~/.codecraft/config.json
|
|
15
|
+
const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.codecraft');
|
|
16
|
+
const CONFIG_PATH = path_1.default.join(CONFIG_DIR, 'config.json');
|
|
17
|
+
function loadGlobalConfig() {
|
|
18
|
+
if (fs_extra_1.default.existsSync(CONFIG_PATH)) {
|
|
19
|
+
try {
|
|
20
|
+
return fs_extra_1.default.readJsonSync(CONFIG_PATH);
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
function saveGlobalConfig(config) {
|
|
29
|
+
fs_extra_1.default.ensureDirSync(CONFIG_DIR);
|
|
30
|
+
fs_extra_1.default.writeJsonSync(CONFIG_PATH, config, { spaces: 2 });
|
|
31
|
+
}
|
|
32
|
+
async function configCommand(args) {
|
|
33
|
+
// Usage: config --set key=value or config --get key or config --list
|
|
34
|
+
const config = loadGlobalConfig();
|
|
35
|
+
if (args.length === 0) {
|
|
36
|
+
// Interactive mode
|
|
37
|
+
console.log(chalk_1.default.bold('Current Configuration:'));
|
|
38
|
+
console.log(JSON.stringify(config, null, 2));
|
|
39
|
+
const answers = await inquirer_1.default.prompt([
|
|
40
|
+
{
|
|
41
|
+
type: 'list',
|
|
42
|
+
name: 'action',
|
|
43
|
+
message: 'What would you like to do?',
|
|
44
|
+
choices: ['Edit Configuration', 'Exit']
|
|
45
|
+
}
|
|
46
|
+
]);
|
|
47
|
+
if (answers.action === 'Edit Configuration') {
|
|
48
|
+
const editAnswers = await inquirer_1.default.prompt([
|
|
49
|
+
{
|
|
50
|
+
type: 'input',
|
|
51
|
+
name: 'apiKey',
|
|
52
|
+
message: 'API Key (leave blank to keep current):',
|
|
53
|
+
default: config.apiKey
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
type: 'list',
|
|
57
|
+
name: 'model',
|
|
58
|
+
message: 'Default Model:',
|
|
59
|
+
choices: ['gpt-4-turbo', 'gpt-4o', 'claude-3-opus', 'claude-3-sonnet'],
|
|
60
|
+
default: config.model || 'gpt-4-turbo'
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: 'confirm',
|
|
64
|
+
name: 'verbose',
|
|
65
|
+
message: 'Enable Verbose Logging?',
|
|
66
|
+
default: config.verbose || false
|
|
67
|
+
}
|
|
68
|
+
]);
|
|
69
|
+
if (editAnswers.apiKey)
|
|
70
|
+
config.apiKey = editAnswers.apiKey;
|
|
71
|
+
config.model = editAnswers.model;
|
|
72
|
+
config.verbose = editAnswers.verbose;
|
|
73
|
+
saveGlobalConfig(config);
|
|
74
|
+
console.log(chalk_1.default.green('Configuration saved!'));
|
|
75
|
+
}
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// CLI Argument mode (basic implementation)
|
|
79
|
+
const action = args[0];
|
|
80
|
+
if (action === '--list') {
|
|
81
|
+
console.log(JSON.stringify(config, null, 2));
|
|
82
|
+
}
|
|
83
|
+
else if (action === '--get' && args[1]) {
|
|
84
|
+
console.log(config[args[1]] || '(not set)');
|
|
85
|
+
}
|
|
86
|
+
else if (action === '--set' && args[1]) {
|
|
87
|
+
const [key, value] = args[1].split('=');
|
|
88
|
+
if (key && value) {
|
|
89
|
+
config[key] = value;
|
|
90
|
+
saveGlobalConfig(config);
|
|
91
|
+
console.log(chalk_1.default.green(`${key} set to ${value}`));
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.log(chalk_1.default.red('Usage: config --set key=value'));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.log(chalk_1.default.red('Usage: config [--list | --get <key> | --set <key>=<value>]'));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,kBA2BlC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
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.doctorCommand = doctorCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const config_1 = require("./config");
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
async function doctorCommand() {
|
|
11
|
+
console.log(chalk_1.default.bold('š CodeCraft Doctor\n'));
|
|
12
|
+
const steps = [
|
|
13
|
+
{ name: 'Node.js Version', check: () => process.version, required: '>= v18.0.0' },
|
|
14
|
+
{ name: 'OS Platform', check: () => os_1.default.platform(), required: 'Any' },
|
|
15
|
+
{
|
|
16
|
+
name: 'Configuration', check: async () => {
|
|
17
|
+
const config = (0, config_1.loadGlobalConfig)();
|
|
18
|
+
return config.apiKey ? 'API Key Configured ā
' : 'API Key Missing ā';
|
|
19
|
+
}, required: 'Required for AI features'
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
for (const step of steps) {
|
|
23
|
+
process.stdout.write(`Compiling ${step.name}... `);
|
|
24
|
+
try {
|
|
25
|
+
const result = await Promise.resolve(step.check());
|
|
26
|
+
console.log(chalk_1.default.green('OK'));
|
|
27
|
+
console.log(chalk_1.default.dim(` Value: ${result}`));
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
console.log(chalk_1.default.red('FAILED'));
|
|
31
|
+
}
|
|
32
|
+
await new Promise(r => setTimeout(r, 200)); // Visual pause
|
|
33
|
+
}
|
|
34
|
+
console.log(chalk_1.default.blue('\nDiagnostics complete.'));
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":";;;;;AAMA,sCA2BC;AAhCD,kDAA0B;AAE1B,qCAA4C;AAC5C,4CAAoB;AAEb,KAAK,UAAU,aAAa;IAC/B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAEjD,MAAM,KAAK,GAAG;QACV,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE;QACjF,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,YAAE,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;QACpE;YACI,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE;gBACrC,MAAM,MAAM,GAAG,IAAA,yBAAgB,GAAE,CAAC;gBAClC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,mBAAmB,CAAC;YACxE,CAAC,EAAE,QAAQ,EAAE,0BAA0B;SAC1C;KACJ,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC;QACnD,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe;IAC/D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":"AAQA,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,iBA+BhD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
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.explainCommand = explainCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const client_1 = require("../core/llm/client");
|
|
11
|
+
const roles_1 = require("../core/prompts/roles");
|
|
12
|
+
const ora_1 = __importDefault(require("ora"));
|
|
13
|
+
async function explainCommand(file) {
|
|
14
|
+
const spinner = (0, ora_1.default)('Analyzing code...').start();
|
|
15
|
+
const filePath = path_1.default.resolve(file);
|
|
16
|
+
if (!fs_extra_1.default.existsSync(filePath)) {
|
|
17
|
+
spinner.fail(`File not found: ${file}`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const apiKey = process.env.CODECRAFT_API_KEY || process.env.OPENAI_API_KEY;
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
spinner.fail('API Key missing.');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const content = fs_extra_1.default.readFileSync(filePath, 'utf-8');
|
|
26
|
+
const ai = new client_1.OpenAIAdapter(apiKey);
|
|
27
|
+
const prompt = [
|
|
28
|
+
{ role: 'system', content: roles_1.EXPLAIN_PROMPT },
|
|
29
|
+
{ role: 'user', content: `Explain this code:\n\n${content}` }
|
|
30
|
+
];
|
|
31
|
+
try {
|
|
32
|
+
const explanation = await ai.complete(prompt);
|
|
33
|
+
spinner.stop();
|
|
34
|
+
console.log(chalk_1.default.bold.hex('#3B82F6')('\nš” Code Explanation\n'));
|
|
35
|
+
console.log(explanation);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
spinner.fail(`Explanation failed: ${err.message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=explain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../src/commands/explain.ts"],"names":[],"mappings":";;;;;AAQA,wCA+BC;AAtCD,kDAA0B;AAC1B,wDAA0B;AAC1B,gDAAwB;AACxB,+CAA8D;AAC9D,iDAAuD;AACvD,8CAAsB;AAEf,KAAK,UAAU,cAAc,CAAC,IAAY;IAC7C,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,mBAAmB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEjD,MAAM,QAAQ,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,kBAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;QACxC,OAAO;IACX,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC3E,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjC,OAAO;IACX,CAAC;IAED,MAAM,OAAO,GAAG,kBAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,EAAE,GAAG,IAAI,sBAAa,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,MAAM,GAAgB;QACxB,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,sBAAc,EAAE;QAC3C,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,OAAO,EAAE,EAAE;KAChE,CAAC;IAEF,IAAI,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE7B,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,uBAAuB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature.d.ts","sourceRoot":"","sources":["../../src/commands/feature.ts"],"names":[],"mappings":"AASA,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,iBAyCvD"}
|