qodfy 0.1.0 → 0.1.2

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 (3) hide show
  1. package/README.md +104 -0
  2. package/dist/index.js +77 -5
  3. package/package.json +4 -3
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Qodfy
2
+
3
+ AI built it fast. Qodfy checks if it's ready.
4
+
5
+ Qodfy is an open-source launch-readiness scanner for AI-built apps. The first product is a local CLI focused on Next.js projects built with TypeScript, Vercel AI SDK, Cursor, Claude Code, v0, Lovable, Bolt, Replit, and similar AI coding workflows.
6
+
7
+ ## Quick Start
8
+
9
+ Run Qodfy in any local project:
10
+
11
+ ```bash
12
+ npx qodfy scan
13
+ ```
14
+
15
+ Scan a specific folder:
16
+
17
+ ```bash
18
+ npx qodfy scan --path apps/web
19
+ ```
20
+
21
+ ## What Qodfy Checks Today
22
+
23
+ Qodfy v0.1 scans locally and looks for common launch-readiness risks:
24
+
25
+ - Next.js project detection
26
+ - missing `.env.example`
27
+ - API routes in `app/api` and `pages/api`
28
+ - API routes that may be missing auth/session checks
29
+ - AI-related files using keywords like `openai`, `@ai-sdk`, `anthropic`, `gemini`, `generateText`, `streamText`, and `useChat`
30
+ - AI routes/files that may be missing rate limiting
31
+ - large generated files
32
+ - a simple launch readiness score from `0` to `100`
33
+
34
+ Qodfy does not send your code to any external server.
35
+
36
+ ## Example Output
37
+
38
+ ```txt
39
+ Qodfy is scanning your project...
40
+
41
+ Qodfy Report
42
+
43
+ Launch Readiness: 72/100
44
+
45
+ Stats
46
+ Files scanned: 42
47
+ API routes: 3
48
+ AI-related files: 2
49
+ Large files: 1
50
+
51
+ Issues
52
+
53
+ CRITICAL AI route may be missing rate limiting
54
+ AI routes can create real API costs. Add rate limiting or usage limits before launch.
55
+ File: app/api/chat/route.ts
56
+
57
+ WARNING API route may be missing authentication
58
+ This API route does not appear to contain an auth/session check.
59
+ File: app/api/admin/route.ts
60
+
61
+ Recommended next step:
62
+ Fix critical issues first, then warnings, then cleanup items.
63
+ ```
64
+
65
+ ## Commands
66
+
67
+ ```bash
68
+ qodfy scan
69
+ qodfy scan --path <project-path>
70
+ qodfy --help
71
+ qodfy --version
72
+ ```
73
+
74
+ ## Scoring
75
+
76
+ Qodfy starts at `100`.
77
+
78
+ - Critical issue: `-20`
79
+ - Warning: `-8`
80
+ - Info: no major score penalty
81
+
82
+ The score is intentionally simple in v0.1 and will become more precise as the rule set improves.
83
+
84
+ ## Roadmap
85
+
86
+ Near-term priorities:
87
+
88
+ - JSON and Markdown output
89
+ - `.env.example` coverage for `process.env.*`
90
+ - exposed secret detection
91
+ - Stripe webhook signature checks
92
+ - better auth and rate-limit heuristics
93
+ - `--ci` and `--min-score`
94
+ - GitHub Action
95
+
96
+ ## Repository
97
+
98
+ GitHub: https://github.com/yassinifguisse1/qodfy
99
+
100
+ Issues and feedback: https://github.com/yassinifguisse1/qodfy/issues
101
+
102
+ ## License
103
+
104
+ MIT
package/dist/index.js CHANGED
@@ -1,17 +1,65 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
+ import fs from "fs/promises";
5
+ import path from "path";
4
6
  import { Command } from "commander";
5
7
  import pc from "picocolors";
6
8
  import { scanProject } from "@qodfy/core";
7
9
  var program = new Command();
8
- program.name("qodfy").description("Launch readiness scanner for AI-built apps.").version("0.1.0");
10
+ program.name("qodfy").description("Launch readiness scanner for AI-built apps.").version("0.1.2");
9
11
  program.command("scan").description("Scan a project for launch readiness issues.").option("-p, --path <path>", "Project path to scan", process.cwd()).action(async (options) => {
10
- console.log(pc.cyan("Qodfy is scanning your project...\n"));
11
- const report = await scanProject(options.path);
12
- printReport(report);
12
+ const pathResult = await resolveProjectPath(options.path);
13
+ if (!pathResult.ok) {
14
+ printScanError(pathResult.reason);
15
+ process.exitCode = 1;
16
+ return;
17
+ }
18
+ try {
19
+ console.log(pc.cyan("Qodfy is scanning your project...\n"));
20
+ const report = await scanProject(pathResult.projectPath);
21
+ printReport(report);
22
+ } catch (error) {
23
+ printScanError(getErrorMessage(error));
24
+ process.exitCode = 1;
25
+ }
13
26
  });
14
- program.parse();
27
+ await program.parseAsync();
28
+ async function resolveProjectPath(projectPath) {
29
+ const inputPath = projectPath.trim() || process.cwd();
30
+ const resolvedPath = path.resolve(inputPath);
31
+ try {
32
+ const stats = await fs.stat(resolvedPath);
33
+ if (!stats.isDirectory()) {
34
+ return {
35
+ ok: false,
36
+ reason: `The path "${inputPath}" is not a directory.`
37
+ };
38
+ }
39
+ return {
40
+ ok: true,
41
+ projectPath: resolvedPath
42
+ };
43
+ } catch (error) {
44
+ const code = getErrorCode(error);
45
+ if (code === "ENOENT") {
46
+ return {
47
+ ok: false,
48
+ reason: `The path "${inputPath}" does not exist.`
49
+ };
50
+ }
51
+ if (code === "ENOTDIR") {
52
+ return {
53
+ ok: false,
54
+ reason: `The path "${inputPath}" is not a directory.`
55
+ };
56
+ }
57
+ return {
58
+ ok: false,
59
+ reason: `Qodfy could not access the path "${inputPath}".`
60
+ };
61
+ }
62
+ }
15
63
  function printReport(report) {
16
64
  console.log(pc.bold("Qodfy Report"));
17
65
  console.log("");
@@ -37,8 +85,32 @@ ${label} ${pc.bold(issue.title)}`);
37
85
  if (issue.file) {
38
86
  console.log(pc.dim(`File: ${issue.file}`));
39
87
  }
88
+ if (issue.suggestion) {
89
+ console.log(pc.dim(`Suggestion: ${issue.suggestion}`));
90
+ }
40
91
  }
41
92
  console.log("");
42
93
  console.log(pc.bold("Recommended next step:"));
43
94
  console.log("Fix critical issues first, then warnings, then cleanup items.");
44
95
  }
96
+ function printScanError(reason) {
97
+ console.error(pc.red("Qodfy could not scan this project."));
98
+ console.error("");
99
+ console.error(pc.bold("Reason:"));
100
+ console.error(reason);
101
+ console.error("");
102
+ console.error(pc.bold("Try:"));
103
+ console.error("qodfy scan --path ./my-next-app");
104
+ }
105
+ function getErrorMessage(error) {
106
+ if (error instanceof Error && error.message) {
107
+ return error.message;
108
+ }
109
+ return "An unexpected error occurred while scanning the project.";
110
+ }
111
+ function getErrorCode(error) {
112
+ if (error && typeof error === "object" && "code" in error && typeof error.code === "string") {
113
+ return error.code;
114
+ }
115
+ return void 0;
116
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qodfy",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Open-source launch readiness scanner for AI-built apps.",
5
5
  "keywords": [
6
6
  "qodfy",
@@ -38,7 +38,8 @@
38
38
  }
39
39
  },
40
40
  "files": [
41
- "dist"
41
+ "dist",
42
+ "README.md"
42
43
  ],
43
44
  "license": "MIT",
44
45
  "engines": {
@@ -50,7 +51,7 @@
50
51
  "dependencies": {
51
52
  "commander": "^14.0.3",
52
53
  "picocolors": "^1.1.1",
53
- "@qodfy/core": "^0.1.0"
54
+ "@qodfy/core": "^0.1.2"
54
55
  },
55
56
  "devDependencies": {
56
57
  "@types/node": "^25.7.0",