quillshield 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +399 -0
  2. package/dist/commands/audit.d.ts +8 -0
  3. package/dist/commands/audit.d.ts.map +1 -0
  4. package/dist/commands/audit.js +180 -0
  5. package/dist/commands/audit.js.map +1 -0
  6. package/dist/commands/config.d.ts +7 -0
  7. package/dist/commands/config.d.ts.map +1 -0
  8. package/dist/commands/config.js +63 -0
  9. package/dist/commands/config.js.map +1 -0
  10. package/dist/commands/report.d.ts +7 -0
  11. package/dist/commands/report.d.ts.map +1 -0
  12. package/dist/commands/report.js +62 -0
  13. package/dist/commands/report.js.map +1 -0
  14. package/dist/commands/status.d.ts +2 -0
  15. package/dist/commands/status.d.ts.map +1 -0
  16. package/dist/commands/status.js +83 -0
  17. package/dist/commands/status.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +54 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/utils/apiClient.d.ts +53 -0
  23. package/dist/utils/apiClient.d.ts.map +1 -0
  24. package/dist/utils/apiClient.js +72 -0
  25. package/dist/utils/apiClient.js.map +1 -0
  26. package/dist/utils/config.d.ts +10 -0
  27. package/dist/utils/config.d.ts.map +1 -0
  28. package/dist/utils/config.js +45 -0
  29. package/dist/utils/config.js.map +1 -0
  30. package/dist/utils/fileCollector.d.ts +25 -0
  31. package/dist/utils/fileCollector.d.ts.map +1 -0
  32. package/dist/utils/fileCollector.js +180 -0
  33. package/dist/utils/fileCollector.js.map +1 -0
  34. package/dist/utils/projectDetector.d.ts +16 -0
  35. package/dist/utils/projectDetector.d.ts.map +1 -0
  36. package/dist/utils/projectDetector.js +141 -0
  37. package/dist/utils/projectDetector.js.map +1 -0
  38. package/dist/utils/reportFormatter.d.ts +12 -0
  39. package/dist/utils/reportFormatter.d.ts.map +1 -0
  40. package/dist/utils/reportFormatter.js +115 -0
  41. package/dist/utils/reportFormatter.js.map +1 -0
  42. package/package.json +72 -0
package/README.md ADDED
@@ -0,0 +1,399 @@
1
+ # QuillShield
2
+
3
+ > Smart Contract Security Auditing from the Command Line
4
+
5
+ A powerful CLI tool that automatically detects your project type (Foundry/Hardhat/Truffle), collects all Solidity files, and sends them to QuillShield for comprehensive security auditing.
6
+
7
+ ---
8
+
9
+ ## Quick Start
10
+
11
+ ```bash
12
+ # Install globally
13
+ npm install -g quillshield
14
+
15
+ # Audit a single Solidity file
16
+ quillshield audit ./contracts/MyToken.sol
17
+
18
+ # Audit an entire project folder
19
+ quillshield audit ./my-foundry-project
20
+ ```
21
+
22
+ ---
23
+
24
+ ## Features
25
+
26
+ - **Audit files or folders** - Pass a single `.sol` file or an entire project directory
27
+ - **Auto-detect project type** - Foundry, Hardhat, Truffle, or raw Solidity
28
+ - **Smart file collection** - Only collects `.sol` files needed for analysis
29
+ - **Remapping support** - Automatically extracts and applies remappings
30
+ - **Dependency resolution** - Includes all imported libraries
31
+ - **Real-time progress** - Beautiful terminal UI with spinners and colors
32
+ - **Wait for results** - Optionally wait for audit completion
33
+ - **Multiple output formats** - Table or JSON format
34
+ - **Save reports** - Export reports to files
35
+
36
+ ---
37
+
38
+ ## Installation
39
+
40
+ ### From npm (recommended)
41
+
42
+ ```bash
43
+ npm install -g quillshield
44
+ ```
45
+
46
+ After installation, the `quillshield` command is available globally.
47
+
48
+ ### From source
49
+
50
+ ```bash
51
+ git clone https://github.com/quillshield/quillshield-cli.git
52
+ cd quillshield-cli
53
+ npm install
54
+ npm run build
55
+ npm link
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Usage
61
+
62
+ ### Audit a Single File
63
+
64
+ ```bash
65
+ # Audit a single Solidity file
66
+ quillshield audit ./MyToken.sol
67
+
68
+ # With a custom project name
69
+ quillshield audit ./MyToken.sol --name "My Token Audit"
70
+ ```
71
+
72
+ ### Audit a Project Folder
73
+
74
+ ```bash
75
+ # Basic audit (auto-detects project type)
76
+ quillshield audit ./my-foundry-project
77
+
78
+ # Specify analysis type
79
+ quillshield audit ./my-project --type full
80
+
81
+ # Custom project name
82
+ quillshield audit ./my-project --name "My DeFi Protocol"
83
+
84
+ # Don't wait for completion
85
+ quillshield audit ./my-project --no-wait
86
+ ```
87
+
88
+ **Analysis Types:**
89
+ - `full` - Complete AI-enhanced audit (default)
90
+ - `raw` - Raw Slither analysis only
91
+ - `semantic` - Multi-agent semantic analysis
92
+
93
+ ### Check Status
94
+
95
+ ```bash
96
+ quillshield status <project-id>
97
+ ```
98
+
99
+ ### Get Report
100
+
101
+ ```bash
102
+ # Display report in terminal (table format)
103
+ quillshield report <project-id>
104
+
105
+ # Get report as JSON
106
+ quillshield report <project-id> --format json
107
+
108
+ # Save report to file
109
+ quillshield report <project-id> --output report.json
110
+ ```
111
+
112
+ ### Configuration
113
+
114
+ ```bash
115
+ # Show current configuration
116
+ quillshield config --show
117
+
118
+ # Set API URL (for self-hosted backend)
119
+ quillshield config --url https://your-backend.com
120
+
121
+ # Interactive configuration
122
+ quillshield config
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Supported Project Types
128
+
129
+ ### Foundry Projects
130
+
131
+ ```
132
+ my-foundry-project/
133
+ ā”œā”€ā”€ foundry.toml ← Detected automatically
134
+ ā”œā”€ā”€ src/
135
+ │ ā”œā”€ā”€ Token.sol
136
+ │ └── Vault.sol
137
+ └── lib/
138
+ └── openzeppelin-contracts/
139
+ ```
140
+
141
+ **What gets collected:**
142
+ - All `.sol` files in `src/`
143
+ - All `.sol` files in `lib/` (marked as dependencies)
144
+ - Remappings from `foundry.toml`
145
+ - Compiler version from `foundry.toml`
146
+
147
+ ### Hardhat Projects
148
+
149
+ ```
150
+ my-hardhat-project/
151
+ ā”œā”€ā”€ hardhat.config.js ← Detected automatically
152
+ ā”œā”€ā”€ contracts/
153
+ │ ā”œā”€ā”€ Token.sol
154
+ │ └── NFT.sol
155
+ └── node_modules/
156
+ └── @openzeppelin/
157
+ ```
158
+
159
+ **What gets collected:**
160
+ - All `.sol` files in `contracts/`
161
+ - Common libraries from `node_modules/` (@openzeppelin, @chainlink, @uniswap)
162
+ - Standard Hardhat remappings
163
+ - Compiler version from `hardhat.config.js`
164
+
165
+ ### Truffle Projects
166
+
167
+ ```
168
+ my-truffle-project/
169
+ ā”œā”€ā”€ truffle-config.js ← Detected automatically
170
+ └── contracts/
171
+ ā”œā”€ā”€ Token.sol
172
+ └── Migrations.sol
173
+ ```
174
+
175
+ ### Single Solidity File
176
+
177
+ ```bash
178
+ quillshield audit ./MyContract.sol
179
+ ```
180
+
181
+ The compiler version is automatically extracted from the `pragma solidity` directive.
182
+
183
+ ### Raw Solidity (folder with .sol files)
184
+
185
+ ```
186
+ my-project/
187
+ ā”œā”€ā”€ Token.sol
188
+ ā”œā”€ā”€ Vault.sol
189
+ └── lib/
190
+ └── SafeMath.sol
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Configuration
196
+
197
+ ### Environment Variables
198
+
199
+ Create a `.env` file in the directory you run the command from:
200
+
201
+ ```env
202
+ # Backend API URL (defaults to production)
203
+ QUILLSHIELD_API_URL=https://quillshieldtest-production.up.railway.app
204
+
205
+ # Default analysis type
206
+ QUILLSHIELD_ANALYSIS_TYPE=full
207
+
208
+ # Polling interval (seconds)
209
+ QUILLSHIELD_POLL_INTERVAL=5
210
+
211
+ # Max wait time (seconds)
212
+ QUILLSHIELD_MAX_WAIT_TIME=600
213
+ ```
214
+
215
+ ### Config File
216
+
217
+ Configuration is stored in `~/.quillshield/config.json`:
218
+
219
+ ```json
220
+ {
221
+ "apiUrl": "https://quillshieldtest-production.up.railway.app",
222
+ "analysisType": "full",
223
+ "pollInterval": 5,
224
+ "maxWaitTime": 600
225
+ }
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Example Output
231
+
232
+ ```bash
233
+ $ quillshield audit ./my-foundry-project
234
+
235
+ ___ _ _ _ ____ _ _ _ _
236
+ / _ \ _ _ (_) | || | / ___| | |__ (_) ___ | | __| |
237
+ | | | || | | || | | || | \___ \ | '_ \ | | / _ \| | / _` |
238
+ | |_| || |_| || | | || | ___) || | | || || __/| || (_| |
239
+ \__\_\ \__,_||_| |_||_| |____/ |_| |_||_| \___||_| \__,_|
240
+
241
+ Smart Contract Security Auditing CLI
242
+
243
+ šŸ” QuillShield Audit
244
+
245
+ āœ“ Project type: FOUNDRY
246
+ āœ“ Compiler version: 0.8.20
247
+ Found 4 remapping(s)
248
+ āœ“ Collected 25 files (8 source, 17 dependencies)
249
+ Total lines: 3,450
250
+ āœ“ Project data prepared
251
+ āœ“ Project created: 65abc123def456...
252
+ āœ“ Audit started
253
+
254
+ ā³ Waiting for audit to complete...
255
+
256
+ .....āœ“ Audit completed!
257
+
258
+ ═══════════════════════════════════════════════════════════════════
259
+
260
+ Security Score: 82/100
261
+ Audited Files: 8 | Total Lines: 3,450
262
+
263
+ ───────────────────────────────────────────────────────────────────
264
+
265
+ Vulnerability Summary:
266
+
267
+ ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
268
+ │ Severity │ Count │
269
+ ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
270
+ │ High │ 2 │
271
+ │ Medium │ 3 │
272
+ │ Low │ 1 │
273
+ │ Informational │ 5 │
274
+ │ Optimization │ 2 │
275
+ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
276
+
277
+ šŸ“Š View full report: https://frontend-production-2f25.up.railway.app/project/65abc123def456...
278
+ ```
279
+
280
+ ---
281
+
282
+ ## Commands Reference
283
+
284
+ ### `quillshield audit <path>`
285
+
286
+ Audit a smart contract file or project folder.
287
+
288
+ **Arguments:**
289
+ - `<path>` - Path to a `.sol` file or project directory
290
+
291
+ **Options:**
292
+ - `-t, --type <type>` - Analysis type: `full`, `raw`, `semantic` (default: `full`)
293
+ - `-n, --name <name>` - Custom project name
294
+ - `-w, --wait` - Wait for audit completion (default: `true`)
295
+ - `--no-wait` - Don't wait for completion
296
+
297
+ **Examples:**
298
+ ```bash
299
+ quillshield audit ./MyToken.sol
300
+ quillshield audit ./my-project
301
+ quillshield audit ./my-project --type semantic
302
+ quillshield audit ./my-project --name "My Token" --no-wait
303
+ ```
304
+
305
+ ### `quillshield status <project-id>`
306
+
307
+ Check audit status for a project.
308
+
309
+ **Examples:**
310
+ ```bash
311
+ quillshield status 65abc123def456...
312
+ ```
313
+
314
+ ### `quillshield report <project-id>`
315
+
316
+ Get audit report for a project.
317
+
318
+ **Options:**
319
+ - `-o, --output <file>` - Save report to file
320
+ - `-f, --format <format>` - Output format: `json`, `table` (default: `table`)
321
+
322
+ **Examples:**
323
+ ```bash
324
+ quillshield report 65abc123def456...
325
+ quillshield report 65abc123def456... --format json
326
+ quillshield report 65abc123def456... --output report.json
327
+ ```
328
+
329
+ ### `quillshield config`
330
+
331
+ Configure QuillShield CLI.
332
+
333
+ **Options:**
334
+ - `-s, --show` - Show current configuration
335
+ - `-u, --url <url>` - Set API URL
336
+
337
+ **Examples:**
338
+ ```bash
339
+ quillshield config --show
340
+ quillshield config --url https://your-backend.com
341
+ quillshield config # Interactive mode
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Troubleshooting
347
+
348
+ ### "Path not found"
349
+
350
+ Make sure the file or directory path is correct:
351
+ ```bash
352
+ quillshield audit ./contracts/MyToken.sol
353
+ ```
354
+
355
+ ### "Only Solidity (.sol) files are supported"
356
+
357
+ When auditing a single file, it must be a `.sol` file. For non-Solidity projects, point to the project folder instead.
358
+
359
+ ### "No Solidity files found"
360
+
361
+ Check that your project has `.sol` files in the expected locations:
362
+ - Foundry: `src/`
363
+ - Hardhat: `contracts/`
364
+ - Truffle: `contracts/`
365
+
366
+ ### "Failed to connect to backend"
367
+
368
+ Check that the backend is reachable:
369
+ ```bash
370
+ curl https://quillshieldtest-production.up.railway.app/health
371
+ ```
372
+
373
+ Update API URL if using a self-hosted backend:
374
+ ```bash
375
+ quillshield config --url http://your-backend-url
376
+ ```
377
+
378
+ ### "Audit taking too long"
379
+
380
+ Large projects may take several minutes. Use `--no-wait` and check status later:
381
+ ```bash
382
+ quillshield audit my-project --no-wait
383
+ # Wait a few minutes
384
+ quillshield status <project-id>
385
+ ```
386
+
387
+ ---
388
+
389
+ ## License
390
+
391
+ MIT License
392
+
393
+ ---
394
+
395
+ **Start auditing with a single command!**
396
+
397
+ ```bash
398
+ quillshield audit ./my-contract.sol
399
+ ```
@@ -0,0 +1,8 @@
1
+ interface AuditOptions {
2
+ type: 'full' | 'raw' | 'semantic';
3
+ name?: string;
4
+ wait: boolean;
5
+ }
6
+ export declare const auditCommand: (targetPath: string, options: AuditOptions) => Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAWA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,UAAU,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,YAAY,GACvB,YAAY,MAAM,EAClB,SAAS,YAAY,kBAwMtB,CAAC"}
@@ -0,0 +1,180 @@
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.auditCommand = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const fs_extra_1 = __importDefault(require("fs-extra"));
11
+ const projectDetector_1 = require("../utils/projectDetector");
12
+ const fileCollector_1 = require("../utils/fileCollector");
13
+ const apiClient_1 = require("../utils/apiClient");
14
+ const reportFormatter_1 = require("../utils/reportFormatter");
15
+ const FRONTEND_URL = 'https://frontend-production-2f25.up.railway.app';
16
+ const auditCommand = async (targetPath, options) => {
17
+ console.log(chalk_1.default.bold('\nšŸ” QuillShield Audit\n'));
18
+ // Resolve absolute path
19
+ const absolutePath = path_1.default.resolve(targetPath);
20
+ // Check if path exists
21
+ if (!fs_extra_1.default.existsSync(absolutePath)) {
22
+ console.log(chalk_1.default.red(`āœ— Error: Path not found: ${targetPath}`));
23
+ process.exit(1);
24
+ }
25
+ const isFile = fs_extra_1.default.statSync(absolutePath).isFile();
26
+ const isDirectory = fs_extra_1.default.statSync(absolutePath).isDirectory();
27
+ // If it's a file, validate it's a .sol file
28
+ if (isFile && !absolutePath.endsWith('.sol')) {
29
+ console.log(chalk_1.default.red(`āœ— Error: Only Solidity (.sol) files are supported: ${targetPath}`));
30
+ process.exit(1);
31
+ }
32
+ try {
33
+ let files;
34
+ let projectType;
35
+ let projectInfo;
36
+ if (isFile) {
37
+ // Single file audit
38
+ const spinner = (0, ora_1.default)('Processing Solidity file...').start();
39
+ files = [(0, fileCollector_1.collectSingleFile)(absolutePath)];
40
+ projectType = 'raw';
41
+ projectInfo = {
42
+ type: 'raw',
43
+ compilerVersion: '0.8.20',
44
+ remappings: [],
45
+ configFile: undefined,
46
+ };
47
+ // Try to detect compiler version from the file's pragma
48
+ const content = files[0].content;
49
+ const pragmaMatch = content.match(/pragma\s+solidity\s+[\^~>=<]*\s*([\d.]+)/);
50
+ if (pragmaMatch) {
51
+ projectInfo.compilerVersion = pragmaMatch[1];
52
+ }
53
+ spinner.succeed(`File: ${chalk_1.default.cyan(path_1.default.basename(absolutePath))}`);
54
+ console.log(chalk_1.default.gray(` Compiler version: ${projectInfo.compilerVersion}`));
55
+ }
56
+ else if (isDirectory) {
57
+ // Directory audit (existing behavior)
58
+ const spinner = (0, ora_1.default)('Detecting project type...').start();
59
+ const detectedType = (0, projectDetector_1.detectProjectType)(absolutePath);
60
+ projectType = detectedType;
61
+ spinner.succeed(`Project type: ${chalk_1.default.cyan(detectedType.toUpperCase())}`);
62
+ spinner.start('Extracting project configuration...');
63
+ projectInfo = (0, projectDetector_1.getProjectInfo)(absolutePath);
64
+ spinner.succeed(`Compiler version: ${chalk_1.default.cyan(projectInfo.compilerVersion)}`);
65
+ if (projectInfo.remappings.length > 0) {
66
+ console.log(chalk_1.default.gray(` Found ${projectInfo.remappings.length} remapping(s)`));
67
+ }
68
+ spinner.start('Collecting Solidity files...');
69
+ files = await (0, fileCollector_1.collectSolidityFiles)(absolutePath, detectedType);
70
+ if (files.length === 0) {
71
+ spinner.fail('No Solidity files found');
72
+ process.exit(1);
73
+ }
74
+ const stats = (0, fileCollector_1.getFileStats)(files);
75
+ spinner.succeed(`Collected ${chalk_1.default.cyan(stats.total)} files (${stats.source} source, ${stats.dependencies} dependencies)`);
76
+ console.log(chalk_1.default.gray(` Total lines: ${stats.totalLines}`));
77
+ }
78
+ else {
79
+ console.log(chalk_1.default.red(`āœ— Error: Path is neither a file nor a directory: ${targetPath}`));
80
+ process.exit(1);
81
+ }
82
+ // Prepare project payload
83
+ const spinner = (0, ora_1.default)('Preparing project data...').start();
84
+ const projectName = options.name || (isFile ? path_1.default.basename(absolutePath, '.sol') : path_1.default.basename(absolutePath)) || 'Unnamed Project';
85
+ const payload = {
86
+ name: projectName,
87
+ description: `${projectType} project audited via CLI`,
88
+ entryPoint: 'all',
89
+ compilerVersion: projectInfo.compilerVersion,
90
+ projectType: projectInfo.type,
91
+ remappings: projectInfo.remappings,
92
+ configFile: projectInfo.configFile,
93
+ files: files.map((file) => ({
94
+ name: file.name,
95
+ path: file.path,
96
+ content: file.content,
97
+ dependency: file.dependency,
98
+ })),
99
+ };
100
+ spinner.succeed('Project data prepared');
101
+ // Upload to backend
102
+ spinner.start('Uploading project to QuillShield...');
103
+ const createResponse = await apiClient_1.apiClient.createProject(payload);
104
+ if (!createResponse.success) {
105
+ spinner.fail('Failed to create project');
106
+ console.log(chalk_1.default.red(`Error: ${createResponse.error}`));
107
+ process.exit(1);
108
+ }
109
+ const projectId = createResponse.data.project._id;
110
+ spinner.succeed(`Project created: ${chalk_1.default.cyan(projectId)}`);
111
+ // Start audit
112
+ spinner.start(`Starting ${options.type} audit...`);
113
+ const auditResponse = await apiClient_1.apiClient.startAudit(projectId, {
114
+ analysisType: options.type,
115
+ });
116
+ if (!auditResponse.success) {
117
+ spinner.fail('Failed to start audit');
118
+ console.log(chalk_1.default.red(`Error: ${auditResponse.error}`));
119
+ process.exit(1);
120
+ }
121
+ spinner.succeed('Audit started');
122
+ // Wait for completion (if --wait flag is set)
123
+ if (options.wait) {
124
+ console.log(chalk_1.default.gray('\nā³ Waiting for audit to complete...\n'));
125
+ let attempts = 0;
126
+ const maxAttempts = 120; // 10 minutes (5 seconds * 120)
127
+ while (attempts < maxAttempts) {
128
+ await new Promise((resolve) => setTimeout(resolve, 5000)); // Wait 5 seconds
129
+ try {
130
+ const projectStatus = await apiClient_1.apiClient.getProject(projectId);
131
+ const status = projectStatus.data.project.status;
132
+ if (status === 'completed') {
133
+ console.log(chalk_1.default.green('āœ“ Audit completed!\n'));
134
+ // Get and display report
135
+ const reportResponse = await apiClient_1.apiClient.getLatestReport(projectId);
136
+ if (reportResponse.success) {
137
+ (0, reportFormatter_1.displayReport)(reportResponse.data.report);
138
+ const reportUrl = `${FRONTEND_URL}/project/${projectId}`;
139
+ console.log(chalk_1.default.cyan(`\nšŸ“Š View full report: ${reportUrl}`));
140
+ }
141
+ break;
142
+ }
143
+ else if (status === 'failed') {
144
+ console.log(chalk_1.default.red('āœ— Audit failed'));
145
+ break;
146
+ }
147
+ else if (status === 'analyzing') {
148
+ process.stdout.write(chalk_1.default.gray('.'));
149
+ }
150
+ }
151
+ catch (error) {
152
+ // Continue waiting
153
+ }
154
+ attempts++;
155
+ }
156
+ if (attempts >= maxAttempts) {
157
+ console.log(chalk_1.default.yellow('\n⚠ Audit is taking longer than expected. Check status with:'));
158
+ console.log(chalk_1.default.cyan(` quillshield status ${projectId}`));
159
+ }
160
+ }
161
+ else {
162
+ // Don't wait, just show instructions
163
+ console.log(chalk_1.default.gray('\nšŸ“ Audit is running in the background\n'));
164
+ console.log(chalk_1.default.cyan('Check status with:'));
165
+ console.log(chalk_1.default.white(` quillshield status ${projectId}\n`));
166
+ console.log(chalk_1.default.cyan('Get report with:'));
167
+ console.log(chalk_1.default.white(` quillshield report ${projectId}\n`));
168
+ }
169
+ }
170
+ catch (error) {
171
+ console.log(chalk_1.default.red(`\nāœ— Error: ${error.message}`));
172
+ if (error.response) {
173
+ console.log(chalk_1.default.gray(` Status: ${error.response.status}`));
174
+ console.log(chalk_1.default.gray(` Message: ${error.response.data?.error || 'Unknown error'}`));
175
+ }
176
+ process.exit(1);
177
+ }
178
+ };
179
+ exports.auditCommand = auditCommand;
180
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface ConfigOptions {
2
+ show?: boolean;
3
+ url?: string;
4
+ }
5
+ export declare const configCommand: (options: ConfigOptions) => Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAIA,UAAU,aAAa;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,aAAa,GAAU,SAAS,aAAa,kBA2DzD,CAAC"}
@@ -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.configCommand = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const inquirer_1 = __importDefault(require("inquirer"));
9
+ const config_1 = require("../utils/config");
10
+ const configCommand = async (options) => {
11
+ console.log(chalk_1.default.bold('\nāš™ļø QuillShield Configuration\n'));
12
+ if (options.show) {
13
+ // Show current configuration
14
+ const config = (0, config_1.getConfig)();
15
+ console.log(chalk_1.default.cyan('Current Configuration:'));
16
+ console.log(chalk_1.default.gray('─'.repeat(50)));
17
+ console.log(` API URL: ${chalk_1.default.white(config.apiUrl)}`);
18
+ console.log(` Analysis Type: ${chalk_1.default.white(config.analysisType)}`);
19
+ console.log(` Poll Interval: ${chalk_1.default.white(config.pollInterval)}s`);
20
+ console.log(` Max Wait Time: ${chalk_1.default.white(config.maxWaitTime)}s`);
21
+ console.log(chalk_1.default.gray('─'.repeat(50) + '\n'));
22
+ return;
23
+ }
24
+ if (options.url) {
25
+ // Set API URL
26
+ (0, config_1.saveConfig)({ apiUrl: options.url });
27
+ console.log(chalk_1.default.green(`āœ“ API URL updated to: ${options.url}\n`));
28
+ return;
29
+ }
30
+ // Interactive configuration
31
+ const config = (0, config_1.getConfig)();
32
+ const answers = await inquirer_1.default.prompt([
33
+ {
34
+ type: 'input',
35
+ name: 'apiUrl',
36
+ message: 'Backend API URL:',
37
+ default: config.apiUrl,
38
+ },
39
+ {
40
+ type: 'list',
41
+ name: 'analysisType',
42
+ message: 'Default analysis type:',
43
+ choices: ['full', 'raw', 'semantic'],
44
+ default: config.analysisType,
45
+ },
46
+ {
47
+ type: 'number',
48
+ name: 'pollInterval',
49
+ message: 'Poll interval (seconds):',
50
+ default: config.pollInterval,
51
+ },
52
+ {
53
+ type: 'number',
54
+ name: 'maxWaitTime',
55
+ message: 'Max wait time (seconds):',
56
+ default: config.maxWaitTime,
57
+ },
58
+ ]);
59
+ (0, config_1.saveConfig)(answers);
60
+ console.log(chalk_1.default.green('\nāœ“ Configuration saved successfully!\n'));
61
+ };
62
+ exports.configCommand = configCommand;
63
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAC1B,wDAAgC;AAChC,4CAAwD;AAOjD,MAAM,aAAa,GAAG,KAAK,EAAE,OAAsB,EAAE,EAAE;IAC5D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;IAE7D,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,6BAA6B;QAC7B,MAAM,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;QAE3B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,uBAAuB,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjE,OAAO,CAAC,GAAG,CAAC,uBAAuB,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,uBAAuB,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,uBAAuB,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QAE/C,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,cAAc;QACd,IAAA,mBAAU,EAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,yBAAyB,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IAED,4BAA4B;IAC5B,MAAM,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;IAE3B,MAAM,OAAO,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;QACpC;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,kBAAkB;YAC3B,OAAO,EAAE,MAAM,CAAC,MAAM;SACvB;QACD;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC;YACpC,OAAO,EAAE,MAAM,CAAC,YAAY;SAC7B;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,0BAA0B;YACnC,OAAO,EAAE,MAAM,CAAC,YAAY;SAC7B;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,0BAA0B;YACnC,OAAO,EAAE,MAAM,CAAC,WAAW;SAC5B;KACF,CAAC,CAAC;IAEH,IAAA,mBAAU,EAAC,OAAO,CAAC,CAAC;IAEpB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC;AA3DW,QAAA,aAAa,iBA2DxB"}